1 /* 2 * Copyright 2014, Google Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 package org.jf.smalidea.psi.impl; 33 34 import com.intellij.lang.ASTNode; 35 import com.intellij.psi.*; 36 import com.intellij.psi.PsiModifier.ModifierConstant; 37 import com.intellij.psi.impl.PsiImplUtil; 38 import com.intellij.psi.javadoc.PsiDocComment; 39 import com.intellij.util.IncorrectOperationException; 40 import org.jetbrains.annotations.NonNls; 41 import org.jetbrains.annotations.NotNull; 42 import org.jetbrains.annotations.Nullable; 43 import org.jf.smalidea.psi.SmaliElementTypes; 44 import org.jf.smalidea.psi.iface.SmaliModifierListOwner; 45 import org.jf.smalidea.psi.stub.SmaliFieldStub; 46 import org.jf.smalidea.util.NameUtils; 47 48 public class SmaliField extends SmaliStubBasedPsiElement<SmaliFieldStub> implements PsiField, SmaliModifierListOwner { 49 public SmaliField(@NotNull SmaliFieldStub stub) { 50 super(stub, SmaliElementTypes.FIELD); 51 } 52 53 public SmaliField(@NotNull ASTNode node) { 54 super(node); 55 } 56 57 @Nullable @Override public String getName() { 58 SmaliFieldStub stub = getStub(); 59 if (stub != null) { 60 return stub.getName(); 61 } 62 63 SmaliMemberName smaliMemberName = findChildByClass(SmaliMemberName.class); 64 if (smaliMemberName == null || smaliMemberName.getText().isEmpty()) { 65 return null; 66 } 67 return smaliMemberName.getText(); 68 } 69 70 @NotNull @Override public SmaliModifierList getModifierList() { 71 SmaliModifierList modifierList = getStubOrPsiChild(SmaliElementTypes.MODIFIER_LIST); 72 assert modifierList != null; 73 return modifierList; 74 } 75 76 @NotNull @Override public SmaliMemberName getNameIdentifier() { 77 SmaliMemberName memberName = findChildByClass(SmaliMemberName.class); 78 assert memberName != null; 79 return memberName; 80 } 81 82 @Nullable @Override public PsiDocComment getDocComment() { 83 return null; 84 } 85 86 @Override public boolean isDeprecated() { 87 return PsiImplUtil.isDeprecatedByAnnotation(this); 88 } 89 90 @Nullable @Override public PsiClass getContainingClass() { 91 return (PsiClass)getParentByStub(); 92 } 93 94 @NotNull @Override public PsiType getType() { 95 SmaliFieldStub stub = getStub(); 96 if (stub != null) { 97 return NameUtils.resolveSmaliToPsiType(this, stub.getSmaliTypeName()); 98 } 99 PsiTypeElement typeElement = getTypeElement(); 100 if (typeElement == null) { 101 // If we don't have a type (i.e. syntax error), use Object as a safe-ish fallback 102 PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); 103 return factory.createTypeFromText("java.lang.Object", this); 104 } 105 return getTypeElement().getType(); 106 } 107 108 @Nullable @Override public SmaliTypeElement getTypeElement() { 109 return findChildByClass(SmaliTypeElement.class); 110 } 111 112 @Nullable @Override public PsiExpression getInitializer() { 113 // TODO: implement this 114 return null; 115 } 116 117 @Override public boolean hasInitializer() { 118 // TODO: implement this 119 return false; 120 } 121 122 @Override public void normalizeDeclaration() throws IncorrectOperationException { 123 // not applicable 124 } 125 126 @Nullable @Override public Object computeConstantValue() { 127 // TODO: implement this 128 return null; 129 } 130 131 @Override public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { 132 SmaliMemberName smaliMemberName = getNameIdentifier(); 133 smaliMemberName.setName(name); 134 return this; 135 } 136 137 @Override public boolean hasModifierProperty(@ModifierConstant @NonNls @NotNull String name) { 138 return getModifierList().hasModifierProperty(name); 139 } 140 141 @NotNull @Override public SmaliAnnotation[] getAnnotations() { 142 return getStubOrPsiChildren(SmaliElementTypes.ANNOTATION, new SmaliAnnotation[0]); 143 } 144 145 @NotNull @Override public SmaliAnnotation[] getApplicableAnnotations() { 146 return getAnnotations(); 147 } 148 149 @Nullable @Override public SmaliAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) { 150 for (SmaliAnnotation annotation: getAnnotations()) { 151 if (qualifiedName.equals(annotation.getQualifiedName())) { 152 return annotation; 153 } 154 } 155 return null; 156 } 157 158 @NotNull @Override public SmaliAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) { 159 // TODO: implement this 160 return null; 161 } 162 163 @Override public void setInitializer(@Nullable PsiExpression initializer) throws IncorrectOperationException { 164 // TODO: implement this 165 } 166 167 @Override public int getTextOffset() { 168 SmaliMemberName smaliMemberName = getNameIdentifier(); 169 if (smaliMemberName != null) { 170 return smaliMemberName.getTextOffset(); 171 } 172 return super.getTextOffset(); 173 } 174 } 175