diff --git a/smalidea/src/main/antlr3/smalideaParser.g b/smalidea/src/main/antlr3/smalideaParser.g index 43449326..7d8d4e5d 100644 --- a/smalidea/src/main/antlr3/smalideaParser.g +++ b/smalidea/src/main/antlr3/smalideaParser.g @@ -207,6 +207,7 @@ add them to the $smali_file::classAnnotations list*/ field @init { Marker marker = mark(); + mark().done(SmaliElementTypes.MODIFIER_LIST); Marker annotationsMarker = null; Marker fieldInitializerMarker = null; boolean classAnnotations = true; diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotationElementName.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotationElementName.java index 1800830c..355e9ab5 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotationElementName.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotationElementName.java @@ -48,7 +48,7 @@ public class SmaliAnnotationElementName extends SmaliCompositeElement implements } @Override public IElementType getTokenType() { - return getNode().getElementType(); + return getElementType(); } @Override public String getName() { diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliArrayTypeElement.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliArrayTypeElement.java index 6b49dfe7..b1757956 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliArrayTypeElement.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliArrayTypeElement.java @@ -31,10 +31,16 @@ package org.jf.smalidea.psi.impl; +import com.intellij.lang.ASTNode; +import com.intellij.psi.*; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jf.smalidea.SmaliTokens; import org.jf.smalidea.psi.SmaliCompositeElementFactory; import org.jf.smalidea.psi.SmaliElementTypes; -public class SmaliArrayTypeElement extends SmaliCompositeElement { +public class SmaliArrayTypeElement extends SmaliCompositeElement implements PsiTypeElement { public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() { @Override public SmaliCompositeElement createElement() { return new SmaliArrayTypeElement(); @@ -44,4 +50,41 @@ public class SmaliArrayTypeElement extends SmaliCompositeElement { public SmaliArrayTypeElement() { super(SmaliElementTypes.ARRAY_TYPE); } + + @NotNull @Override public PsiType getType() { + ASTNode token = findChildByType(SmaliTokens.ARRAY_TYPE_PREFIX); + assert token != null; + PsiTypeElement baseType = findChildByClass(PsiTypeElement.class); + assert baseType != null; + + PsiArrayType arrayType = new PsiArrayType(baseType.getType()); + int dimensions = token.getTextLength() - 1; + while (dimensions > 0) { + arrayType = new PsiArrayType(arrayType); + dimensions--; + } + return arrayType; + } + + @Nullable @Override public SmaliClassTypeElement getInnermostComponentReferenceElement() { + return findChildByClass(SmaliClassTypeElement.class); + } + + // Annotations on types are for JSR 308. Not applicable to smali. + + @NotNull @Override public PsiAnnotation[] getAnnotations() { + return new PsiAnnotation[0]; + } + + @NotNull @Override public PsiAnnotation[] getApplicableAnnotations() { + return new PsiAnnotation[0]; + } + + @Nullable @Override public PsiAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) { + return null; + } + + @NotNull @Override public PsiAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) { + return null; + } } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClass.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClass.java index 63f9c051..6e7a838b 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClass.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClass.java @@ -161,8 +161,8 @@ public class SmaliClass extends SmaliStubBasedPsiElement impleme return PsiClassImplUtil.getSuperTypes(this); } - @NotNull @Override public PsiField[] getFields() { - return new PsiField[0]; + @NotNull @Override public SmaliField[] getFields() { + return getStubOrPsiChildren(SmaliElementTypes.FIELD, new SmaliField[0]); } @NotNull @Override public PsiMethod[] getMethods() { @@ -182,7 +182,7 @@ public class SmaliClass extends SmaliStubBasedPsiElement impleme } @NotNull @Override public PsiField[] getAllFields() { - return new PsiField[0]; + return PsiClassImplUtil.getAllFields(this); } @NotNull @Override public PsiMethod[] getAllMethods() { @@ -194,7 +194,7 @@ public class SmaliClass extends SmaliStubBasedPsiElement impleme } @Nullable @Override public PsiField findFieldByName(@NonNls String name, boolean checkBases) { - return null; + return PsiClassImplUtil.findFieldByName(this, name, checkBases); } @Nullable @Override public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) { diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassTypeElement.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassTypeElement.java index 65bc38f7..89ffda44 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassTypeElement.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassTypeElement.java @@ -43,7 +43,7 @@ import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.util.NameUtils; public class SmaliClassTypeElement extends SmaliCompositeElement - implements PsiTypeElement, PsiReference, PsiJavaCodeReferenceElement { + implements PsiTypeElement, PsiJavaCodeReferenceElement { public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() { @Override public SmaliCompositeElement createElement() { return new SmaliClassTypeElement(); diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliField.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliField.java index aefaae74..c00cad52 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliField.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliField.java @@ -32,11 +32,21 @@ package org.jf.smalidea.psi.impl; import com.intellij.lang.ASTNode; +import com.intellij.psi.*; +import com.intellij.psi.PsiModifier.ModifierConstant; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jf.smalidea.psi.SmaliElementTypes; +import org.jf.smalidea.psi.iface.SmaliModifierListOwner; import org.jf.smalidea.psi.stub.SmaliFieldStub; -public class SmaliField extends SmaliStubBasedPsiElement { +import javax.annotation.Nonnull; + +public class SmaliField extends SmaliStubBasedPsiElement implements PsiField, SmaliModifierListOwner { public SmaliField(@NotNull SmaliFieldStub stub) { super(stub, SmaliElementTypes.FIELD); } @@ -44,4 +54,113 @@ public class SmaliField extends SmaliStubBasedPsiElement { public SmaliField(@NotNull ASTNode node) { super(node); } + + @Nonnull @Override public String getName() { + SmaliFieldStub stub = getStub(); + if (stub != null) { + return stub.getName(); + } + + SmaliMemberName smaliMemberName = findChildByClass(SmaliMemberName.class); + assert smaliMemberName != null; + return smaliMemberName.getText(); + } + + @Nullable @Override public SmaliAccessList getAccessFlagsNode() { + return findChildByClass(SmaliAccessList.class); + } + + @NotNull @Override public SmaliModifierList getModifierList() { + SmaliModifierList modifierList = getStubOrPsiChild(SmaliElementTypes.MODIFIER_LIST); + assert modifierList != null; + return modifierList; + } + + @NotNull @Override public PsiIdentifier getNameIdentifier() { + SmaliMemberName memberName = findChildByClass(SmaliMemberName.class); + assert memberName != null; + return memberName; + } + + @Nullable @Override public PsiDocComment getDocComment() { + return null; + } + + @Override public boolean isDeprecated() { + return PsiImplUtil.isDeprecatedByAnnotation(this); + } + + @Nullable @Override public PsiClass getContainingClass() { + return (PsiClass)getParent(); + } + + @NotNull @Override public PsiType getType() { + SmaliFieldStub stub = getStub(); + if (stub != null) { + String type = stub.getType(); + PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); + return factory.createTypeFromText(type, this); + } + PsiTypeElement typeElement = getTypeElement(); + assert typeElement != null; + return getTypeElement().getType(); + } + + @Nullable @Override public PsiTypeElement getTypeElement() { + return findChildByClass(PsiTypeElement.class); + } + + @Nullable @Override public PsiExpression getInitializer() { + // TODO: implement this + return null; + } + + @Override public boolean hasInitializer() { + // TODO: implement this + return false; + } + + @Override public void normalizeDeclaration() throws IncorrectOperationException { + // not applicable + } + + @Nullable @Override public Object computeConstantValue() { + // TODO: implement this + return null; + } + + @Override public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { + // TODO: implement this + return null; + } + + @Override public boolean hasModifierProperty(@ModifierConstant @NonNls @NotNull String name) { + return getModifierList().hasModifierProperty(name); + } + + @NotNull @Override public SmaliAnnotation[] getAnnotations() { + return getStubOrPsiChildren(SmaliElementTypes.ANNOTATION, new SmaliAnnotation[0]); + } + + @NotNull @Override public SmaliAnnotation[] getApplicableAnnotations() { + return getAnnotations(); + } + + @Nullable @Override public SmaliAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) { + for (SmaliAnnotation annotation: getAnnotations()) { + if (qualifiedName.equals(annotation.getQualifiedName())) { + return annotation; + } + } + return null; + } + + @NotNull @Override public SmaliAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) { + // TODO: implement this + return null; + } + + @Override public void setInitializer(@Nullable PsiExpression initializer) throws IncorrectOperationException { + // TODO: implement this + } } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMemberName.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMemberName.java index a827bd11..4fbe4f6f 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMemberName.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMemberName.java @@ -31,10 +31,12 @@ package org.jf.smalidea.psi.impl; +import com.intellij.psi.PsiIdentifier; +import com.intellij.psi.tree.IElementType; import org.jf.smalidea.psi.SmaliCompositeElementFactory; import org.jf.smalidea.psi.SmaliElementTypes; -public class SmaliMemberName extends SmaliCompositeElement { +public class SmaliMemberName extends SmaliCompositeElement implements PsiIdentifier { public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() { @Override public SmaliCompositeElement createElement() { return new SmaliMemberName(); @@ -44,4 +46,8 @@ public class SmaliMemberName extends SmaliCompositeElement { public SmaliMemberName() { super(SmaliElementTypes.MEMBER_NAME); } + + @Override public IElementType getTokenType() { + return getElementType(); + } } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliPrimitiveTypeElement.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliPrimitiveTypeElement.java index 1c1ccd45..4cdcb13f 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliPrimitiveTypeElement.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliPrimitiveTypeElement.java @@ -31,10 +31,17 @@ package org.jf.smalidea.psi.impl; +import com.intellij.psi.PsiAnnotation; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiType; +import com.intellij.psi.PsiTypeElement; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jf.smalidea.psi.SmaliCompositeElementFactory; import org.jf.smalidea.psi.SmaliElementTypes; -public class SmaliPrimitiveTypeElement extends SmaliCompositeElement { +public class SmaliPrimitiveTypeElement extends SmaliCompositeElement implements PsiTypeElement { public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() { @Override public SmaliCompositeElement createElement() { return new SmaliPrimitiveTypeElement(); @@ -44,4 +51,49 @@ public class SmaliPrimitiveTypeElement extends SmaliCompositeElement { public SmaliPrimitiveTypeElement() { super(SmaliElementTypes.PRIMITIVE_TYPE); } + + @NotNull @Override public PsiType getType() { + switch (getText().charAt(0)) { + case 'Z': + return PsiType.BOOLEAN; + case 'B': + return PsiType.BYTE; + case 'S': + return PsiType.SHORT; + case 'C': + return PsiType.CHAR; + case 'I': + return PsiType.INT; + case 'J': + return PsiType.LONG; + case 'F': + return PsiType.FLOAT; + case 'D': + return PsiType.DOUBLE; + default: + throw new RuntimeException("Unexpected primitive type"); + } + } + + @Nullable @Override public PsiJavaCodeReferenceElement getInnermostComponentReferenceElement() { + return null; + } + + // Annotations on types are for JSR 308. Not applicable to smali. + + @NotNull @Override public PsiAnnotation[] getAnnotations() { + return new PsiAnnotation[0]; + } + + @NotNull @Override public PsiAnnotation[] getApplicableAnnotations() { + return new PsiAnnotation[0]; + } + + @Nullable @Override public PsiAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) { + return null; + } + + @NotNull @Override public PsiAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) { + return null; + } } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliFieldStub.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliFieldStub.java index 21b054f0..0e296243 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliFieldStub.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliFieldStub.java @@ -33,11 +33,25 @@ package org.jf.smalidea.psi.stub; import com.intellij.psi.stubs.StubBase; import com.intellij.psi.stubs.StubElement; +import org.jetbrains.annotations.NotNull; import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.psi.impl.SmaliField; public class SmaliFieldStub extends StubBase { - public SmaliFieldStub(StubElement parent) { - super(parent, SmaliElementTypes.FIELD); + @NotNull private final String name; + @NotNull private final String type; + + public SmaliFieldStub(StubElement parent, @NotNull String name, @NotNull String type) { + super(parent, SmaliElementTypes.FIELD); + this.name = name; + this.type = type; + } + + @NotNull public String getName() { + return name; + } + + @NotNull public String getType() { + return type; } } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliFieldElementType.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliFieldElementType.java index 73797d99..f97d40bb 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliFieldElementType.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliFieldElementType.java @@ -62,16 +62,18 @@ public class SmaliFieldElementType extends SmaliStubElementType