diff options
Diffstat (limited to 'smalidea')
33 files changed, 412 insertions, 147 deletions
diff --git a/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaClassDef.java b/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaClassDef.java index 11df39c3..c954702a 100644 --- a/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaClassDef.java +++ b/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaClassDef.java @@ -97,12 +97,7 @@ public class SmalideaClassDef extends BaseTypeReference implements ClassDef { } @Nonnull @Override public String getType() { - // TODO: properly handle inner classes.. - String javaName = psiClass.getQualifiedName(); - if (javaName == null) { - throw new RuntimeException("I don't know what to do here... Is this even possible?"); - } - return NameUtils.javaToSmaliType(javaName); + return NameUtils.javaToSmaliType(psiClass); } @Nullable @Override public String getSuperclass() { @@ -110,11 +105,7 @@ public class SmalideaClassDef extends BaseTypeReference implements ClassDef { if (superClass == null) { return null; } - String javaName = superClass.getQualifiedName(); - if (javaName == null) { - throw new RuntimeException("I don't know what to do here... Is this even possible?"); - } - return NameUtils.javaToSmaliType(javaName); + return NameUtils.javaToSmaliType(superClass); } @Nonnull @Override public List<String> getInterfaces() { @@ -125,11 +116,7 @@ public class SmalideaClassDef extends BaseTypeReference implements ClassDef { } for (PsiClass psiClass: interfaces) { - String javaName = psiClass.getQualifiedName(); - if (javaName == null) { - throw new RuntimeException("I don't know what to do here... Is this even possible?"); - } - interfaceList.add(NameUtils.javaToSmaliType(javaName)); + interfaceList.add(NameUtils.javaToSmaliType(psiClass)); } return interfaceList; diff --git a/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaField.java b/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaField.java index bb022792..7b98174a 100644 --- a/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaField.java +++ b/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaField.java @@ -93,11 +93,7 @@ public class SmalideaField extends BaseFieldReference implements Field { if (containingClass == null) { throw new RuntimeException("I don't know what to do here... Is this even possible?"); } - String javaName = containingClass.getQualifiedName(); - if (javaName == null) { - throw new RuntimeException("I don't know what to do here... Is this even possible?"); - } - return NameUtils.javaToSmaliType(javaName); + return NameUtils.javaToSmaliType(containingClass); } @Nonnull @Override public String getName() { @@ -105,8 +101,7 @@ public class SmalideaField extends BaseFieldReference implements Field { } @Nonnull @Override public String getType() { - String javaName = psiField.getType().getCanonicalText(); - return NameUtils.javaToSmaliType(javaName); + return NameUtils.javaToSmaliType(psiField.getType()); } @Nullable @Override public EncodedValue getInitialValue() { diff --git a/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaMethod.java b/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaMethod.java index a6c5c88a..abc4dda8 100644 --- a/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaMethod.java +++ b/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaMethod.java @@ -67,9 +67,7 @@ public class SmalideaMethod extends BaseMethodReference implements Method { @Nonnull @Override public String getDefiningClass() { PsiClass cls = psiMethod.getContainingClass(); assert cls != null; - String qualifiedName = cls.getQualifiedName(); - assert qualifiedName != null; - return NameUtils.javaToSmaliType(qualifiedName); + return NameUtils.javaToSmaliType(cls); } @Nonnull @Override public List<? extends MethodParameter> getParameters() { diff --git a/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaMethodParameter.java b/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaMethodParameter.java index e9e26a7c..49d75c83 100644 --- a/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaMethodParameter.java +++ b/smalidea/src/main/java/org/jf/smalidea/dexlib/SmalideaMethodParameter.java @@ -59,6 +59,6 @@ public class SmalideaMethodParameter extends BaseMethodParameter { } @Nonnull @Override public String getType() { - return NameUtils.javaToSmaliType(psiParameter.getType().getCanonicalText()); + return NameUtils.javaToSmaliType(psiParameter.getType()); } } diff --git a/smalidea/src/main/java/org/jf/smalidea/dexlib/analysis/SmalideaClassProvider.java b/smalidea/src/main/java/org/jf/smalidea/dexlib/analysis/SmalideaClassProvider.java index e886a290..9d2a14ac 100644 --- a/smalidea/src/main/java/org/jf/smalidea/dexlib/analysis/SmalideaClassProvider.java +++ b/smalidea/src/main/java/org/jf/smalidea/dexlib/analysis/SmalideaClassProvider.java @@ -2,7 +2,6 @@ package org.jf.smalidea.dexlib.analysis; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.impl.ResolveScopeManager; import org.jf.dexlib2.analysis.ClassProvider; @@ -24,10 +23,7 @@ public class SmalideaClassProvider implements ClassProvider { @Nullable @Override public ClassDef getClassDef(String type) { ResolveScopeManager manager = ResolveScopeManager.getInstance(project); - - JavaPsiFacade facade = JavaPsiFacade.getInstance(project); - PsiClass psiClass = facade.findClass(NameUtils.smaliToJavaType(type), - manager.getDefaultResolveScope(file)); + PsiClass psiClass = NameUtils.resolveSmaliType(project, manager.getDefaultResolveScope(file), type); if (psiClass != null) { return new SmalideaClassDef(psiClass); } diff --git a/smalidea/src/main/java/org/jf/smalidea/dexlib/instruction/SmalideaInstruction.java b/smalidea/src/main/java/org/jf/smalidea/dexlib/instruction/SmalideaInstruction.java index 4bd1616a..b5b259a2 100644 --- a/smalidea/src/main/java/org/jf/smalidea/dexlib/instruction/SmalideaInstruction.java +++ b/smalidea/src/main/java/org/jf/smalidea/dexlib/instruction/SmalideaInstruction.java @@ -193,7 +193,7 @@ public abstract class SmalideaInstruction implements Instruction { if (psiType == null) { return null; } - return NameUtils.javaToSmaliType(psiType.getCanonicalText()); + return NameUtils.javaToSmaliType(psiType); } }); diff --git a/smalidea/src/main/java/org/jf/smalidea/findUsages/SmaliClassReferenceSearcher.java b/smalidea/src/main/java/org/jf/smalidea/findUsages/SmaliClassReferenceSearcher.java index 4642d749..63e4d6fe 100644 --- a/smalidea/src/main/java/org/jf/smalidea/findUsages/SmaliClassReferenceSearcher.java +++ b/smalidea/src/main/java/org/jf/smalidea/findUsages/SmaliClassReferenceSearcher.java @@ -55,18 +55,20 @@ public class SmaliClassReferenceSearcher extends QueryExecutorBase<PsiReference, return; } - String qualifiedName = ApplicationManager.getApplication().runReadAction( + String smaliType = ApplicationManager.getApplication().runReadAction( new Computable<String>() { @Override public String compute() { - return ((PsiClass)element).getQualifiedName(); + String qualifiedName = ((PsiClass)element).getQualifiedName(); + if (qualifiedName != null) { + return NameUtils.javaToSmaliType((PsiClass)element); + } + return null; } }); - if (qualifiedName == null) { + if (smaliType == null) { return; } - String smaliType = NameUtils.javaToSmaliType(qualifiedName); - final StringSearcher stringSearcher = new StringSearcher(smaliType, true, true, false, false); final SingleTargetRequestResultProcessor processor = new SingleTargetRequestResultProcessor(element); diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/LightSmaliClassTypeElement.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/LightSmaliClassTypeElement.java index f5dd6773..acd9a02a 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/LightSmaliClassTypeElement.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/LightSmaliClassTypeElement.java @@ -46,15 +46,15 @@ import org.jf.smalidea.util.NameUtils; public class LightSmaliClassTypeElement extends LightElement implements PsiTypeElement, PsiReference, PsiJavaCodeReferenceElement { @NotNull - private final String qualifiedName; + private final String smaliName; - public LightSmaliClassTypeElement(@NotNull PsiManager manager, @NotNull String qualifiedName) { + public LightSmaliClassTypeElement(@NotNull PsiManager manager, @NotNull String smaliName) { super(manager, SmaliLanguage.INSTANCE); - this.qualifiedName = qualifiedName; + this.smaliName = smaliName; } @Override public String toString() { - return "LightSmaliClassTypeElement:" + qualifiedName; + return "LightSmaliClassTypeElement:" + smaliName; } @NotNull @Override public PsiType getType() { @@ -66,7 +66,7 @@ public class LightSmaliClassTypeElement extends LightElement } @Override public String getText() { - return NameUtils.javaToSmaliType(qualifiedName); + return smaliName; } @Override public PsiReference getReference() { @@ -82,12 +82,11 @@ public class LightSmaliClassTypeElement extends LightElement } @Nullable @Override public PsiClass resolve() { - JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); - return facade.findClass(getCanonicalText(), getResolveScope()); + return NameUtils.resolveSmaliType(this, smaliName); } @NotNull @Override public String getCanonicalText() { - return qualifiedName; + return NameUtils.resolveSmaliToJavaType(this, smaliName); } @Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotation.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotation.java index 745416e5..e36313ba 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotation.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotation.java @@ -58,24 +58,32 @@ public class SmaliAnnotation extends SmaliStubBasedPsiElement<SmaliAnnotationStu } @Nullable @Override public String getQualifiedName() { + PsiJavaCodeReferenceElement nameElement = getNameReferenceElement(); + if (nameElement != null) { + return nameElement.getQualifiedName(); + } + return null; + } + + @Nullable public String getSmaliName() { SmaliAnnotationStub stub = getStub(); if (stub != null) { - return stub.getAnnotationType(); + return stub.getAnnotationSmaliTypeName(); } SmaliClassTypeElement classType = findChildByClass(SmaliClassTypeElement.class); if (classType == null) { return null; } - return classType.getJavaType(); + return classType.getSmaliName(); } @Nullable @Override public PsiJavaCodeReferenceElement getNameReferenceElement() { SmaliAnnotationStub stub = getStub(); if (stub != null) { - String qualifiedName = stub.getAnnotationType(); - if (qualifiedName != null) { - return new LightSmaliClassTypeElement(getManager(), qualifiedName); + String smaliName = stub.getAnnotationSmaliTypeName(); + if (smaliName != null) { + return new LightSmaliClassTypeElement(getManager(), smaliName); } } return findChildByClass(SmaliClassTypeElement.class); diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliBaseReferenceList.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliBaseReferenceList.java index b018f18f..b47d5126 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliBaseReferenceList.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliBaseReferenceList.java @@ -37,6 +37,7 @@ import com.intellij.psi.StubBasedPsiElement; import com.intellij.psi.stubs.IStubElementType; import org.jetbrains.annotations.NotNull; import org.jf.smalidea.psi.stub.SmaliBaseReferenceListStub; +import org.jf.smalidea.util.NameUtils; public abstract class SmaliBaseReferenceList<StubT extends SmaliBaseReferenceListStub> extends SmaliStubBasedPsiElement<StubT> implements StubBasedPsiElement<StubT>, PsiReferenceList { @@ -68,7 +69,14 @@ public abstract class SmaliBaseReferenceList<StubT extends SmaliBaseReferenceLis SmaliBaseReferenceListStub stub = getStub(); if (stub != null) { - return stub.getTypes(); + String[] smaliNames = stub.getSmaliTypeNames(); + String[] referenceNames = new String[smaliNames.length]; + + for (int i=0; i<smaliNames.length; i++) { + referenceNames[i] = NameUtils.resolveSmaliToJavaType(this, smaliNames[i]); + } + + return referenceNames; } SmaliClassTypeElement[] references = getReferenceElements(); @@ -81,6 +89,23 @@ public abstract class SmaliBaseReferenceList<StubT extends SmaliBaseReferenceLis return referenceNames; } + @NotNull public String[] getSmaliNames() { + SmaliBaseReferenceListStub stub = getStub(); + + if (stub != null) { + return stub.getSmaliTypeNames(); + } + + SmaliClassTypeElement[] references = getReferenceElements(); + + String[] smaliNames = new String[references.length]; + + for (int i=0; i<references.length; i++) { + smaliNames[i] = references[i].getSmaliName(); + } + return smaliNames; + } + @Override public boolean isWritable() { return false; } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassStatement.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassStatement.java index 69052e4c..add3c1b2 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassStatement.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassStatement.java @@ -39,6 +39,7 @@ import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.psi.iface.SmaliModifierListOwner; import org.jf.smalidea.psi.leaf.SmaliClassDescriptor; import org.jf.smalidea.psi.stub.SmaliClassStatementStub; +import org.jf.smalidea.util.NameUtils; public class SmaliClassStatement extends SmaliStubBasedPsiElement<SmaliClassStatementStub> implements SmaliModifierListOwner { @@ -83,7 +84,9 @@ public class SmaliClassStatement extends SmaliStubBasedPsiElement<SmaliClassStat if (classType == null) { return null; } - return classType.getJavaType(); + // Since this is a class declared in smali, we don't have to worry about handling inner classes, + // so we can do a pure textual translation of the class name + return NameUtils.smaliToJavaType(classType.getSmaliName()); } @Nullable diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassType.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassType.java index 78c0eff7..6d5bbaba 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassType.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliClassType.java @@ -131,16 +131,26 @@ public class SmaliClassType extends PsiClassType { } @Override + @NotNull public String getPresentableText() { return getCanonicalText(); } @Override + @NotNull public String getCanonicalText() { + PsiClass psiClass = resolve(); + if (psiClass != null) { + String qualifiedName = psiClass.getQualifiedName(); + if (qualifiedName != null) { + return qualifiedName; + } + } return NameUtils.smaliToJavaType(element.getText()); } @Override + @NotNull public String getInternalCanonicalText() { return getCanonicalText(); } 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 7592ea30..b491f6df 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 @@ -59,14 +59,6 @@ public class SmaliClassTypeElement extends SmaliTypeElement implements PsiJavaCo super(SmaliElementTypes.CLASS_TYPE); } - /** - * @return the fully qualified java-style name of the class in this .class statement - */ - @NotNull - public String getJavaType() { - return NameUtils.smaliToJavaType(getText()); - } - @NotNull @Override public SmaliClassType getType() { if (classType == null) { classType = new SmaliClassType(this); @@ -95,12 +87,11 @@ public class SmaliClassTypeElement extends SmaliTypeElement implements PsiJavaCo } @Nullable @Override public PsiClass resolve() { - JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); - return facade.findClass(getCanonicalText(), getResolveScope()); + return NameUtils.resolveSmaliType(this, getText()); } @NotNull @Override public String getCanonicalText() { - return NameUtils.smaliToJavaType(getText()); + return getQualifiedName(); } @Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { @@ -168,7 +159,11 @@ public class SmaliClassTypeElement extends SmaliTypeElement implements PsiJavaCo } @Override public String getQualifiedName() { - return getCanonicalText(); + PsiClass psiClass = resolve(); + if (psiClass != null) { + return psiClass.getQualifiedName(); + } + return NameUtils.smaliToJavaType(getText()); } @NotNull @Override public JavaResolveResult advancedResolve(boolean incompleteCode) { 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 b6362f11..7bef4e94 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 @@ -43,6 +43,7 @@ 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; +import org.jf.smalidea.util.NameUtils; public class SmaliField extends SmaliStubBasedPsiElement<SmaliFieldStub> implements PsiField, SmaliModifierListOwner { public SmaliField(@NotNull SmaliFieldStub stub) { @@ -93,9 +94,7 @@ public class SmaliField extends SmaliStubBasedPsiElement<SmaliFieldStub> impleme @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); + return NameUtils.resolveSmaliToPsiType(this, stub.getSmaliTypeName()); } PsiTypeElement typeElement = getTypeElement(); if (typeElement == null) { @@ -106,8 +105,8 @@ public class SmaliField extends SmaliStubBasedPsiElement<SmaliFieldStub> impleme return getTypeElement().getType(); } - @Nullable @Override public PsiTypeElement getTypeElement() { - return findChildByClass(PsiTypeElement.class); + @Nullable @Override public SmaliTypeElement getTypeElement() { + return findChildByClass(SmaliTypeElement.class); } @Nullable @Override public PsiExpression getInitializer() { diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethodParameter.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethodParameter.java index 61683a5d..93d376e8 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethodParameter.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethodParameter.java @@ -41,6 +41,7 @@ import org.jetbrains.annotations.Nullable; import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.psi.iface.SmaliModifierListOwner; import org.jf.smalidea.psi.stub.SmaliMethodParameterStub; +import org.jf.smalidea.util.NameUtils; public class SmaliMethodParameter extends SmaliStubBasedPsiElement<SmaliMethodParameterStub> implements PsiParameter, SmaliModifierListOwner { @@ -83,8 +84,7 @@ public class SmaliMethodParameter extends SmaliStubBasedPsiElement<SmaliMethodPa @NotNull @Override public PsiType getType() { SmaliMethodParameterStub stub = getStub(); if (stub != null) { - String type = stub.getType(); - return JavaPsiFacade.getInstance(getProject()).getParserFacade().createTypeFromText(type, null); + return NameUtils.resolveSmaliToPsiType(this, stub.getSmaliTypeName()); } return getTypeElement().getType(); } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethodPrototype.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethodPrototype.java index 89c7dace..3b2aae3b 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethodPrototype.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethodPrototype.java @@ -32,14 +32,12 @@ package org.jf.smalidea.psi.impl; import com.intellij.lang.ASTNode; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiElementFactory; -import com.intellij.psi.PsiType; -import com.intellij.psi.PsiTypeElement; +import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.psi.stub.SmaliMethodPrototypeStub; +import org.jf.smalidea.util.NameUtils; public class SmaliMethodPrototype extends SmaliStubBasedPsiElement<SmaliMethodPrototypeStub> { public SmaliMethodPrototype(@NotNull SmaliMethodPrototypeStub stub) { @@ -54,12 +52,11 @@ public class SmaliMethodPrototype extends SmaliStubBasedPsiElement<SmaliMethodPr public PsiType getReturnType() { SmaliMethodPrototypeStub stub = getStub(); if (stub != null) { - String returnType = stub.getReturnType(); - if (returnType == null) { + String returnSmaliTypeName = stub.getReturnSmaliTypeName(); + if (returnSmaliTypeName == null) { return null; } - PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); - return factory.createTypeFromText(returnType, this); + return NameUtils.resolveSmaliToPsiType(this, returnSmaliTypeName); } PsiTypeElement returnTypeElement = getReturnTypeElement(); @@ -69,8 +66,8 @@ public class SmaliMethodPrototype extends SmaliStubBasedPsiElement<SmaliMethodPr return returnTypeElement.getType(); } - @Nullable public PsiTypeElement getReturnTypeElement() { - return findChildByClass(PsiTypeElement.class); + @Nullable public SmaliTypeElement getReturnTypeElement() { + return findChildByClass(SmaliTypeElement.class); } @NotNull diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliTypeElement.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliTypeElement.java index c587d3f1..634cf1a8 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliTypeElement.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliTypeElement.java @@ -48,6 +48,11 @@ public abstract class SmaliTypeElement extends SmaliCompositeElement implements return null; } + @NotNull + public String getSmaliName() { + return getText(); + } + // Annotations on types are for JSR 308. Not applicable to smali. @NotNull @Override public PsiAnnotation[] getAnnotations() { diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliAnnotationStub.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliAnnotationStub.java index 241b0c80..d20882ce 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliAnnotationStub.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliAnnotationStub.java @@ -39,15 +39,15 @@ import org.jf.smalidea.psi.impl.SmaliAnnotation; public class SmaliAnnotationStub extends StubBase<SmaliAnnotation> { @Nullable - private final String annotationType; + private final String annotationSmaliTypeName; - public SmaliAnnotationStub(StubElement parent, @Nullable String annotationType) { + public SmaliAnnotationStub(StubElement parent, @Nullable String annotationSmaliTypeName) { super(parent, SmaliElementTypes.ANNOTATION); - this.annotationType = annotationType; + this.annotationSmaliTypeName = annotationSmaliTypeName; } @Nullable - public String getAnnotationType() { - return annotationType; + public String getAnnotationSmaliTypeName() { + return annotationSmaliTypeName; } } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliBaseReferenceListStub.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliBaseReferenceListStub.java index ce9dede6..8521c4b4 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliBaseReferenceListStub.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliBaseReferenceListStub.java @@ -42,26 +42,26 @@ import org.jf.smalidea.psi.impl.SmaliBaseReferenceList; import org.jf.smalidea.psi.impl.SmaliClassType; public abstract class SmaliBaseReferenceListStub<T extends SmaliBaseReferenceList> extends StubBase<T> { - @NotNull private final String[] types; + @NotNull private final String[] smaliTypeNames; @Nullable private SmaliClassType[] classTypes = null; protected SmaliBaseReferenceListStub( - @NotNull StubElement parent, @NotNull IStubElementType elementType, @NotNull String[] types) { + @NotNull StubElement parent, @NotNull IStubElementType elementType, @NotNull String[] smaliTypeNames) { super(parent, elementType); - this.types = types; + this.smaliTypeNames = smaliTypeNames; } - @NotNull public String[] getTypes() { - return types; + @NotNull public String[] getSmaliTypeNames() { + return smaliTypeNames; } @NotNull public SmaliClassType[] getReferencedTypes() { if (classTypes == null) { - classTypes = new SmaliClassType[types.length]; - for (int i=0; i<types.length; i++) { + classTypes = new SmaliClassType[smaliTypeNames.length]; + for (int i = 0; i< smaliTypeNames.length; i++) { classTypes[i] = new SmaliClassType( - new LightSmaliClassTypeElement(PsiManager.getInstance(getProject()), types[i])); + new LightSmaliClassTypeElement(PsiManager.getInstance(getProject()), smaliTypeNames[i])); } } return classTypes; diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliExtendsListStub.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliExtendsListStub.java index ff2be48d..9678a29e 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliExtendsListStub.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliExtendsListStub.java @@ -37,7 +37,7 @@ import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.psi.impl.SmaliExtendsList; public class SmaliExtendsListStub extends SmaliBaseReferenceListStub<SmaliExtendsList> { - public SmaliExtendsListStub(@NotNull StubElement parent, @NotNull String[] types) { - super(parent, SmaliElementTypes.EXTENDS_LIST, types); + public SmaliExtendsListStub(@NotNull StubElement parent, @NotNull String[] smaliTypeNames) { + super(parent, SmaliElementTypes.EXTENDS_LIST, smaliTypeNames); } } 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 9507c383..15e0fbf0 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 @@ -40,19 +40,19 @@ import org.jf.smalidea.psi.impl.SmaliField; public class SmaliFieldStub extends StubBase<SmaliField> { @Nullable private final String name; - @NotNull private final String type; + @NotNull private final String smaliTypeName; - public SmaliFieldStub(StubElement parent, @Nullable String name, @NotNull String type) { + public SmaliFieldStub(StubElement parent, @Nullable String name, @NotNull String smaliTypeName) { super(parent, SmaliElementTypes.FIELD); this.name = name; - this.type = type; + this.smaliTypeName = smaliTypeName; } @Nullable public String getName() { return name; } - @NotNull public String getType() { - return type; + @NotNull public String getSmaliTypeName() { + return smaliTypeName; } } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliImplementsListStub.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliImplementsListStub.java index c09d087f..2b762c9f 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliImplementsListStub.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliImplementsListStub.java @@ -37,7 +37,7 @@ import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.psi.impl.SmaliImplementsList; public class SmaliImplementsListStub extends SmaliBaseReferenceListStub<SmaliImplementsList> { - public SmaliImplementsListStub(@NotNull StubElement parent, @NotNull String[] types) { - super(parent, SmaliElementTypes.IMPLEMENTS_LIST, types); + public SmaliImplementsListStub(@NotNull StubElement parent, @NotNull String[] smaliTypeNames) { + super(parent, SmaliElementTypes.IMPLEMENTS_LIST, smaliTypeNames); } } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliMethodParameterStub.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliMethodParameterStub.java index d8bc099e..e6f1cf25 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliMethodParameterStub.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliMethodParameterStub.java @@ -39,17 +39,17 @@ import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.psi.impl.SmaliMethodParameter; public class SmaliMethodParameterStub extends StubBase<SmaliMethodParameter> { - @NotNull private final String type; + @NotNull private final String smaliTypeName; @Nullable private final String name; - public SmaliMethodParameterStub(@NotNull StubElement parent, @NotNull String type, @Nullable String name) { + public SmaliMethodParameterStub(@NotNull StubElement parent, @NotNull String smaliTypeName, @Nullable String name) { super(parent, SmaliElementTypes.METHOD_PARAMETER); - this.type = type; + this.smaliTypeName = smaliTypeName; this.name = name; } - @NotNull public String getType() { - return type; + @NotNull public String getSmaliTypeName() { + return smaliTypeName; } @Nullable public String getName() { diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliMethodPrototypeStub.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliMethodPrototypeStub.java index 81e42c5e..ac0b1e9a 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliMethodPrototypeStub.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/SmaliMethodPrototypeStub.java @@ -39,14 +39,14 @@ import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.psi.impl.SmaliMethodPrototype; public class SmaliMethodPrototypeStub extends StubBase<SmaliMethodPrototype> { - @Nullable private final String returnType; + @Nullable private final String returnSmaliTypeName; - public SmaliMethodPrototypeStub(@NotNull StubElement parent, @Nullable String returnType) { + public SmaliMethodPrototypeStub(@NotNull StubElement parent, @Nullable String returnSmaliTypeName) { super(parent, SmaliElementTypes.METHOD_PROTOTYPE); - this.returnType = returnType; + this.returnSmaliTypeName = returnSmaliTypeName; } - @Nullable public String getReturnType() { - return returnType; + @Nullable public String getReturnSmaliTypeName() { + return returnSmaliTypeName; } } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliAnnotationElementType.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliAnnotationElementType.java index f355ab81..7085cc0e 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliAnnotationElementType.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliAnnotationElementType.java @@ -62,12 +62,12 @@ public class SmaliAnnotationElementType extends SmaliStubElementType<SmaliAnnota } @Override public SmaliAnnotationStub createStub(@NotNull SmaliAnnotation psi, StubElement parentStub) { - return new SmaliAnnotationStub(parentStub, psi.getQualifiedName()); + return new SmaliAnnotationStub(parentStub, psi.getSmaliName()); } @Override public void serialize(@NotNull SmaliAnnotationStub stub, @NotNull StubOutputStream dataStream) throws IOException { - dataStream.writeName(stub.getAnnotationType()); + dataStream.writeName(stub.getAnnotationSmaliTypeName()); } @NotNull @Override diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliBaseReferenceListElementType.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliBaseReferenceListElementType.java index 9a6d207d..d73a33a1 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliBaseReferenceListElementType.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliBaseReferenceListElementType.java @@ -52,7 +52,7 @@ public abstract class SmaliBaseReferenceListElementType<StubT extends SmaliBaseR @Override public void serialize(@NotNull StubT stub, @NotNull StubOutputStream dataStream) throws IOException { - String[] references = stub.getTypes(); + String[] references = stub.getSmaliTypeNames(); dataStream.writeVarInt(references.length); for (String reference: references) { dataStream.writeName(reference); @@ -61,15 +61,15 @@ public abstract class SmaliBaseReferenceListElementType<StubT extends SmaliBaseR @NotNull @Override public StubT deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException { - String[] references = new String[dataStream.readVarInt()]; - for (int i=0; i<references.length; i++) { - references[i] = dataStream.readName().getString(); + String[] smaliTypeNames = new String[dataStream.readVarInt()]; + for (int i=0; i<smaliTypeNames.length; i++) { + smaliTypeNames[i] = dataStream.readName().getString(); } - return createStub(parentStub, references); + return createStub(parentStub, smaliTypeNames); } - protected abstract StubT createStub(StubElement parentStub, String[] types); + protected abstract StubT createStub(StubElement parentStub, String[] smaliTypeNames); @Override public void indexStub(@NotNull StubT stub, @NotNull IndexSink sink) { } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliExtendsListElementType.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliExtendsListElementType.java index 88be1de9..3acfd8fd 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliExtendsListElementType.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliExtendsListElementType.java @@ -56,11 +56,11 @@ public class SmaliExtendsListElementType extends SmaliBaseReferenceListElementTy return new SmaliExtendsList(node); } - @Override protected SmaliExtendsListStub createStub(StubElement parentStub, String[] types) { - return new SmaliExtendsListStub(parentStub, types); + @Override protected SmaliExtendsListStub createStub(StubElement parentStub, String[] smaliTypeNames) { + return new SmaliExtendsListStub(parentStub, smaliTypeNames); } @Override public SmaliExtendsListStub createStub(@NotNull SmaliExtendsList psi, StubElement parentStub) { - return new SmaliExtendsListStub(parentStub, psi.getReferenceNames()); + return new SmaliExtendsListStub(parentStub, psi.getSmaliNames()); } } 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 44e1d884..235e995d 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 @@ -33,13 +33,13 @@ package org.jf.smalidea.psi.stub.element; import com.intellij.lang.ASTNode; import com.intellij.openapi.project.IndexNotReadyException; -import com.intellij.psi.PsiTypeElement; import com.intellij.psi.stubs.IndexSink; import com.intellij.psi.stubs.StubElement; import com.intellij.psi.stubs.StubInputStream; import com.intellij.psi.stubs.StubOutputStream; import org.jetbrains.annotations.NotNull; import org.jf.smalidea.psi.impl.SmaliField; +import org.jf.smalidea.psi.impl.SmaliTypeElement; import org.jf.smalidea.psi.stub.SmaliFieldStub; import java.io.IOException; @@ -65,15 +65,15 @@ public class SmaliFieldElementType extends SmaliStubElementType<SmaliFieldStub, @Override public SmaliFieldStub createStub(@NotNull SmaliField psi, StubElement parentStub) { try { - String fieldType; - PsiTypeElement typeElement = psi.getTypeElement(); + String fieldSmaliTypeName; + SmaliTypeElement typeElement = psi.getTypeElement(); if (typeElement != null) { - fieldType = typeElement.getType().getCanonicalText(); + fieldSmaliTypeName = typeElement.getSmaliName(); } else { - fieldType = "java.lang.Object"; + fieldSmaliTypeName = "Ljava/lang/Object;"; } - return new SmaliFieldStub(parentStub, psi.getName(), fieldType); + return new SmaliFieldStub(parentStub, psi.getName(), fieldSmaliTypeName); } catch (IndexNotReadyException ex) { System.out.println(psi.getName()); throw ex; @@ -83,7 +83,7 @@ public class SmaliFieldElementType extends SmaliStubElementType<SmaliFieldStub, @Override public void serialize(@NotNull SmaliFieldStub stub, @NotNull StubOutputStream dataStream) throws IOException { dataStream.writeName(stub.getName()); - dataStream.writeName(stub.getType()); + dataStream.writeName(stub.getSmaliTypeName()); } @NotNull @Override diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliImplementsListElementType.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliImplementsListElementType.java index c24eef6c..3b17bc1a 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliImplementsListElementType.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliImplementsListElementType.java @@ -57,11 +57,11 @@ public class SmaliImplementsListElementType return new SmaliImplementsList(node); } - @Override protected SmaliImplementsListStub createStub(StubElement parentStub, String[] types) { - return new SmaliImplementsListStub(parentStub, types); + @Override protected SmaliImplementsListStub createStub(StubElement parentStub, String[] smaliTypeNames) { + return new SmaliImplementsListStub(parentStub, smaliTypeNames); } @Override public SmaliImplementsListStub createStub(@NotNull SmaliImplementsList psi, StubElement parentStub) { - return new SmaliImplementsListStub(parentStub, psi.getReferenceNames()); + return new SmaliImplementsListStub(parentStub, psi.getSmaliNames()); } } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliMethodParameterElementType.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliMethodParameterElementType.java index fb98f45a..ca5a0106 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliMethodParameterElementType.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliMethodParameterElementType.java @@ -63,13 +63,13 @@ public class SmaliMethodParameterElementType } @Override public SmaliMethodParameterStub createStub(@NotNull SmaliMethodParameter psi, StubElement parentStub) { - return new SmaliMethodParameterStub(parentStub, psi.getType().getCanonicalText(), psi.getName()); + return new SmaliMethodParameterStub(parentStub, psi.getTypeElement().getSmaliName(), psi.getName()); } @Override public void serialize(@NotNull SmaliMethodParameterStub stub, @NotNull StubOutputStream dataStream) throws IOException { - dataStream.writeName(stub.getType()); + dataStream.writeName(stub.getSmaliTypeName()); dataStream.writeName(stub.getName()); } diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliMethodPrototypeElementType.java b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliMethodPrototypeElementType.java index 1919209e..290b78ca 100644 --- a/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliMethodPrototypeElementType.java +++ b/smalidea/src/main/java/org/jf/smalidea/psi/stub/element/SmaliMethodPrototypeElementType.java @@ -32,13 +32,13 @@ package org.jf.smalidea.psi.stub.element; import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiType; import com.intellij.psi.stubs.IndexSink; import com.intellij.psi.stubs.StubElement; import com.intellij.psi.stubs.StubInputStream; import com.intellij.psi.stubs.StubOutputStream; import org.jetbrains.annotations.NotNull; import org.jf.smalidea.psi.impl.SmaliMethodPrototype; +import org.jf.smalidea.psi.impl.SmaliTypeElement; import org.jf.smalidea.psi.stub.SmaliMethodPrototypeStub; import java.io.IOException; @@ -64,19 +64,19 @@ public class SmaliMethodPrototypeElementType } @Override public SmaliMethodPrototypeStub createStub(@NotNull SmaliMethodPrototype psi, StubElement parentStub) { - PsiType returnType = psi.getReturnType(); - String returnTypeText = null; + SmaliTypeElement returnType = psi.getReturnTypeElement(); + String returnSmaliTypeName = null; if (returnType != null) { - returnTypeText = returnType.getCanonicalText(); + returnSmaliTypeName = returnType.getSmaliName(); } - return new SmaliMethodPrototypeStub(parentStub, returnTypeText); + return new SmaliMethodPrototypeStub(parentStub, returnSmaliTypeName); } @Override public void serialize(@NotNull SmaliMethodPrototypeStub stub, @NotNull StubOutputStream dataStream) throws IOException { - dataStream.writeName(stub.getReturnType()); + dataStream.writeName(stub.getReturnSmaliTypeName()); } @NotNull @Override diff --git a/smalidea/src/main/java/org/jf/smalidea/util/NameUtils.java b/smalidea/src/main/java/org/jf/smalidea/util/NameUtils.java index 4a3cf293..305c7f8a 100644 --- a/smalidea/src/main/java/org/jf/smalidea/util/NameUtils.java +++ b/smalidea/src/main/java/org/jf/smalidea/util/NameUtils.java @@ -32,10 +32,13 @@ package org.jf.smalidea.util; import com.google.common.collect.ImmutableMap; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.impl.ResolveScopeManager; +import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.annotation.Nonnull; import java.util.Map; public class NameUtils { @@ -50,8 +53,38 @@ public class NameUtils { .put("double", "D") .build(); - @Nonnull - public static String javaToSmaliType(@Nonnull String javaType) { + @NotNull + public static String javaToSmaliType(@NotNull PsiType psiType) { + if (psiType instanceof PsiClassType) { + PsiClass psiClass = ((PsiClassType)psiType).resolve(); + if (psiClass != null) { + return javaToSmaliType(psiClass); + } + } + return javaToSmaliType(psiType.getCanonicalText()); + } + + @NotNull + public static String javaToSmaliType(@NotNull PsiClass psiClass) { + String qualifiedName = psiClass.getQualifiedName(); + if (qualifiedName == null) { + throw new IllegalArgumentException("This method does not support anonymous classes"); + } + PsiClass parent = psiClass.getContainingClass(); + if (parent != null) { + int offset = qualifiedName.lastIndexOf('.'); + String parentName = qualifiedName.substring(0, offset); + assert parentName.equals(parent.getQualifiedName()); + String className = qualifiedName.substring(offset+1, qualifiedName.length()); + assert className.equals(psiClass.getName()); + return javaToSmaliType(parentName + '$' + className); + } else { + return javaToSmaliType(psiClass.getQualifiedName()); + } + } + + @NotNull + public static String javaToSmaliType(@NotNull String javaType) { if (javaType.charAt(javaType.length()-1) == ']') { int dimensions = 0; int firstArrayChar = -1; @@ -76,7 +109,6 @@ public class NameUtils { return simpleJavaToSmaliType(javaType); } - private static void convertSimpleJavaToSmaliType(@NotNull String javaType, @NotNull StringBuilder dest) { String smaliType = javaToSmaliPrimitiveTypes.get(javaType); if (smaliType != null) { @@ -95,6 +127,81 @@ public class NameUtils { } } + public static PsiClass resolveSmaliType(@NotNull Project project, @NotNull GlobalSearchScope scope, + @NotNull String smaliType) { + JavaPsiFacade facade = JavaPsiFacade.getInstance(project); + + String javaType = NameUtils.smaliToJavaType(smaliType); + + PsiClass psiClass = facade.findClass(javaType, scope); + if (psiClass != null) { + return psiClass; + } + + int offset = javaType.lastIndexOf('.'); + if (offset < 0) { + offset = 0; + } + // find the first $ after the last . + offset = javaType.indexOf('$', offset+1); + if (offset < 0) { + return null; + } + + while (offset > 0 && offset < javaType.length()-1) { + String left = javaType.substring(0, offset); + psiClass = facade.findClass(left, scope); + if (psiClass != null) { + psiClass = findInnerClass(psiClass, javaType.substring(offset+1, javaType.length()), facade, scope); + if (psiClass != null) { + return psiClass; + } + } + offset = javaType.indexOf('$', offset+1); + } + return null; + } + + @Nullable + public static PsiClass resolveSmaliType(@NotNull PsiElement element, @NotNull String smaliType) { + GlobalSearchScope scope = ResolveScopeManager.getElementResolveScope(element); + return resolveSmaliType(element.getProject(), scope, smaliType); + } + + @Nullable + public static PsiClass findInnerClass(@NotNull PsiClass outerClass, String innerText, JavaPsiFacade facade, + GlobalSearchScope scope) { + int offset = innerText.indexOf('$'); + if (offset < 0) { + offset = innerText.length(); + } + + while (offset > 0 && offset <= innerText.length()) { + String left = innerText.substring(0, offset); + String nextInner = outerClass.getQualifiedName() + "." + left; + PsiClass psiClass = facade.findClass(nextInner, scope); + if (psiClass != null) { + if (offset < innerText.length()) { + psiClass = findInnerClass(psiClass, innerText.substring(offset+1, innerText.length()), facade, + scope); + if (psiClass != null) { + return psiClass; + } + } else { + return psiClass; + } + } + if (offset >= innerText.length()) { + break; + } + offset = innerText.indexOf('$', offset+1); + if (offset < 0) { + offset = innerText.length(); + } + } + return null; + } + private static String simpleJavaToSmaliType(@NotNull String simpleJavaType) { StringBuilder sb = new StringBuilder(simpleJavaType.length() + 2); convertSimpleJavaToSmaliType(simpleJavaType, sb); @@ -114,6 +221,41 @@ public class NameUtils { } @NotNull + public static String resolveSmaliToJavaType(@NotNull Project project, @NotNull GlobalSearchScope scope, + @NotNull String smaliType) { + // First, try to resolve the type and get its qualified name, so that we can make sure + // to use the correct name for inner classes + PsiClass resolvedType = resolveSmaliType(project, scope, smaliType); + if (resolvedType != null) { + String qualifiedName = resolvedType.getQualifiedName(); + if (qualifiedName != null) { + return qualifiedName; + } + } + + // if we can't find it, just do a textual conversion of the name + return smaliToJavaType(smaliType); + } + + @NotNull + public static String resolveSmaliToJavaType(@NotNull PsiElement element, @NotNull String smaliType) { + return resolveSmaliToJavaType(element.getProject(), element.getResolveScope(), smaliType); + } + + @NotNull + public static PsiType resolveSmaliToPsiType(@NotNull PsiElement element, @NotNull String smaliType) { + PsiClass resolvedType = resolveSmaliType(element, smaliType); + if (resolvedType != null) { + PsiElementFactory factory = JavaPsiFacade.getInstance(element.getProject()).getElementFactory(); + return factory.createType(resolvedType); + } + + String javaType = NameUtils.smaliToJavaType(smaliType); + PsiElementFactory factory = JavaPsiFacade.getInstance(element.getProject()).getElementFactory(); + return factory.createTypeFromText(javaType, element); + } + + @NotNull private static String convertSmaliArrayToJava(@NotNull String smaliType) { int dimensions=0; while (smaliType.charAt(dimensions) == '[') { @@ -163,6 +305,9 @@ public class NameUtils { } } return; + case 'V': + dest.append("void"); + return; case 'U': if (smaliType.equals("Ujava/lang/Object;")) { dest.append("java.lang.Object"); diff --git a/smalidea/src/test/java/org/jf/smalidea/SmaliClassTypeElementTest.java b/smalidea/src/test/java/org/jf/smalidea/SmaliClassTypeElementTest.java index 7e348f12..434c959b 100644 --- a/smalidea/src/test/java/org/jf/smalidea/SmaliClassTypeElementTest.java +++ b/smalidea/src/test/java/org/jf/smalidea/SmaliClassTypeElementTest.java @@ -68,4 +68,105 @@ public class SmaliClassTypeElementTest extends LightCodeInsightFixtureTestCase { Assert.assertNotNull(resolvedClass); Assert.assertEquals("my.blarg", resolvedClass.getQualifiedName()); } + + public void testSimpleInnerClass() { + myFixture.addFileToProject("Outer.java", "" + + "public class Outer {" + + " public static class Inner {" + + " }" + + "}"); + + String text = ".class public Lsmali; " + + ".super LOuter$In<ref>ner;"; + + SmaliFile file = (SmaliFile)myFixture.addFileToProject("smali.smali", text.replace("<ref>", "")); + + SmaliClassTypeElement typeElement = + (SmaliClassTypeElement)file.findReferenceAt(text.indexOf("<ref>")); + Assert.assertNotNull(typeElement); + SmaliClassType type = typeElement.getType(); + + Assert.assertEquals("Outer.Inner", typeElement.getQualifiedName()); + Assert.assertEquals("Outer.Inner", type.getCanonicalText()); + } + + public void testInnerClassWithPackage() { + myFixture.addFileToProject("my/Outer.java", "" + + "package my;" + + "public class Outer {" + + " public static class Inner {" + + " }" + + "}"); + + String text = ".class public Lsmali; " + + ".super Lmy/Outer$In<ref>ner;"; + + SmaliFile file = (SmaliFile)myFixture.addFileToProject("smali.smali", text.replace("<ref>", "")); + + SmaliClassTypeElement typeElement = + (SmaliClassTypeElement)file.findReferenceAt(text.indexOf("<ref>")); + Assert.assertNotNull(typeElement); + SmaliClassType type = typeElement.getType(); + + Assert.assertEquals("my.Outer.Inner", typeElement.getQualifiedName()); + Assert.assertEquals("my.Outer.Inner", type.getCanonicalText()); + } + + public void testComplexInnerClass() { + myFixture.addFileToProject("my/Outer$blah.java", "" + + "package my;" + + "public class Outer$blah {" + + " public static class Inner {" + + " }" + + " public static class Inner$blah {" + + " }" + + "}"); + + String text = ".class public Lsmali; " + + ".super Lmy/Outer$blah$In<ref>ner$blah;"; + + SmaliFile file = (SmaliFile)myFixture.addFileToProject("smali.smali", text.replace("<ref>", "")); + + SmaliClassTypeElement typeElement = + (SmaliClassTypeElement)file.findReferenceAt(text.indexOf("<ref>")); + Assert.assertNotNull(typeElement); + SmaliClassType type = typeElement.getType(); + + Assert.assertEquals("my.Outer$blah.Inner$blah", typeElement.getQualifiedName()); + Assert.assertEquals("my.Outer$blah.Inner$blah", type.getCanonicalText()); + + text = ".class public Lsmali2; " + + ".super Lmy/Outer$blah$In<ref>ner;"; + + file = (SmaliFile)myFixture.addFileToProject("smali2.smali", text.replace("<ref>", "")); + + typeElement = (SmaliClassTypeElement)file.findReferenceAt(text.indexOf("<ref>")); + Assert.assertNotNull(typeElement); + type = typeElement.getType(); + + Assert.assertEquals("my.Outer$blah.Inner", typeElement.getQualifiedName()); + Assert.assertEquals("my.Outer$blah.Inner", type.getCanonicalText()); + } + + public void testInnerClassTrailingDollar() { + myFixture.addFileToProject("my/Outer$blah.java", "" + + "package my;" + + "public class Outer$ {" + + " public static class Inner$ {" + + " }" + + "}"); + + String text = ".class public Lsmali; " + + ".super Lmy/Outer$$In<ref>ner$;"; + + SmaliFile file = (SmaliFile)myFixture.addFileToProject("smali.smali", text.replace("<ref>", "")); + + SmaliClassTypeElement typeElement = + (SmaliClassTypeElement)file.findReferenceAt(text.indexOf("<ref>")); + Assert.assertNotNull(typeElement); + SmaliClassType type = typeElement.getType(); + + Assert.assertEquals("my.Outer$.Inner$", typeElement.getQualifiedName()); + Assert.assertEquals("my.Outer$.Inner$", type.getCanonicalText()); + } } |