Add support for java inner classes

It's now possible to reference java inner classes based on what their
name would be in smali
This commit is contained in:
Ben Gruver 2016-02-27 13:00:19 -08:00
parent 66892009f5
commit 82f031210e
33 changed files with 412 additions and 147 deletions

View File

@ -97,12 +97,7 @@ public class SmalideaClassDef extends BaseTypeReference implements ClassDef {
} }
@Nonnull @Override public String getType() { @Nonnull @Override public String getType() {
// TODO: properly handle inner classes.. return NameUtils.javaToSmaliType(psiClass);
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);
} }
@Nullable @Override public String getSuperclass() { @Nullable @Override public String getSuperclass() {
@ -110,11 +105,7 @@ public class SmalideaClassDef extends BaseTypeReference implements ClassDef {
if (superClass == null) { if (superClass == null) {
return null; return null;
} }
String javaName = superClass.getQualifiedName(); return NameUtils.javaToSmaliType(superClass);
if (javaName == null) {
throw new RuntimeException("I don't know what to do here... Is this even possible?");
}
return NameUtils.javaToSmaliType(javaName);
} }
@Nonnull @Override public List<String> getInterfaces() { @Nonnull @Override public List<String> getInterfaces() {
@ -125,11 +116,7 @@ public class SmalideaClassDef extends BaseTypeReference implements ClassDef {
} }
for (PsiClass psiClass: interfaces) { for (PsiClass psiClass: interfaces) {
String javaName = psiClass.getQualifiedName(); interfaceList.add(NameUtils.javaToSmaliType(psiClass));
if (javaName == null) {
throw new RuntimeException("I don't know what to do here... Is this even possible?");
}
interfaceList.add(NameUtils.javaToSmaliType(javaName));
} }
return interfaceList; return interfaceList;

View File

@ -93,11 +93,7 @@ public class SmalideaField extends BaseFieldReference implements Field {
if (containingClass == null) { if (containingClass == null) {
throw new RuntimeException("I don't know what to do here... Is this even possible?"); throw new RuntimeException("I don't know what to do here... Is this even possible?");
} }
String javaName = containingClass.getQualifiedName(); return NameUtils.javaToSmaliType(containingClass);
if (javaName == null) {
throw new RuntimeException("I don't know what to do here... Is this even possible?");
}
return NameUtils.javaToSmaliType(javaName);
} }
@Nonnull @Override public String getName() { @Nonnull @Override public String getName() {
@ -105,8 +101,7 @@ public class SmalideaField extends BaseFieldReference implements Field {
} }
@Nonnull @Override public String getType() { @Nonnull @Override public String getType() {
String javaName = psiField.getType().getCanonicalText(); return NameUtils.javaToSmaliType(psiField.getType());
return NameUtils.javaToSmaliType(javaName);
} }
@Nullable @Override public EncodedValue getInitialValue() { @Nullable @Override public EncodedValue getInitialValue() {

View File

@ -67,9 +67,7 @@ public class SmalideaMethod extends BaseMethodReference implements Method {
@Nonnull @Override public String getDefiningClass() { @Nonnull @Override public String getDefiningClass() {
PsiClass cls = psiMethod.getContainingClass(); PsiClass cls = psiMethod.getContainingClass();
assert cls != null; assert cls != null;
String qualifiedName = cls.getQualifiedName(); return NameUtils.javaToSmaliType(cls);
assert qualifiedName != null;
return NameUtils.javaToSmaliType(qualifiedName);
} }
@Nonnull @Override public List<? extends MethodParameter> getParameters() { @Nonnull @Override public List<? extends MethodParameter> getParameters() {

View File

@ -59,6 +59,6 @@ public class SmalideaMethodParameter extends BaseMethodParameter {
} }
@Nonnull @Override public String getType() { @Nonnull @Override public String getType() {
return NameUtils.javaToSmaliType(psiParameter.getType().getCanonicalText()); return NameUtils.javaToSmaliType(psiParameter.getType());
} }
} }

View File

@ -2,7 +2,6 @@ package org.jf.smalidea.dexlib.analysis;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClass;
import com.intellij.psi.impl.ResolveScopeManager; import com.intellij.psi.impl.ResolveScopeManager;
import org.jf.dexlib2.analysis.ClassProvider; import org.jf.dexlib2.analysis.ClassProvider;
@ -24,10 +23,7 @@ public class SmalideaClassProvider implements ClassProvider {
@Nullable @Override public ClassDef getClassDef(String type) { @Nullable @Override public ClassDef getClassDef(String type) {
ResolveScopeManager manager = ResolveScopeManager.getInstance(project); ResolveScopeManager manager = ResolveScopeManager.getInstance(project);
PsiClass psiClass = NameUtils.resolveSmaliType(project, manager.getDefaultResolveScope(file), type);
JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
PsiClass psiClass = facade.findClass(NameUtils.smaliToJavaType(type),
manager.getDefaultResolveScope(file));
if (psiClass != null) { if (psiClass != null) {
return new SmalideaClassDef(psiClass); return new SmalideaClassDef(psiClass);
} }

View File

@ -193,7 +193,7 @@ public abstract class SmalideaInstruction implements Instruction {
if (psiType == null) { if (psiType == null) {
return null; return null;
} }
return NameUtils.javaToSmaliType(psiType.getCanonicalText()); return NameUtils.javaToSmaliType(psiType);
} }
}); });

View File

@ -55,18 +55,20 @@ public class SmaliClassReferenceSearcher extends QueryExecutorBase<PsiReference,
return; return;
} }
String qualifiedName = ApplicationManager.getApplication().runReadAction( String smaliType = ApplicationManager.getApplication().runReadAction(
new Computable<String>() { new Computable<String>() {
@Override public String compute() { @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; return;
} }
String smaliType = NameUtils.javaToSmaliType(qualifiedName);
final StringSearcher stringSearcher = new StringSearcher(smaliType, true, true, false, false); final StringSearcher stringSearcher = new StringSearcher(smaliType, true, true, false, false);
final SingleTargetRequestResultProcessor processor = new SingleTargetRequestResultProcessor(element); final SingleTargetRequestResultProcessor processor = new SingleTargetRequestResultProcessor(element);

View File

@ -46,15 +46,15 @@ import org.jf.smalidea.util.NameUtils;
public class LightSmaliClassTypeElement extends LightElement public class LightSmaliClassTypeElement extends LightElement
implements PsiTypeElement, PsiReference, PsiJavaCodeReferenceElement { implements PsiTypeElement, PsiReference, PsiJavaCodeReferenceElement {
@NotNull @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); super(manager, SmaliLanguage.INSTANCE);
this.qualifiedName = qualifiedName; this.smaliName = smaliName;
} }
@Override public String toString() { @Override public String toString() {
return "LightSmaliClassTypeElement:" + qualifiedName; return "LightSmaliClassTypeElement:" + smaliName;
} }
@NotNull @Override public PsiType getType() { @NotNull @Override public PsiType getType() {
@ -66,7 +66,7 @@ public class LightSmaliClassTypeElement extends LightElement
} }
@Override public String getText() { @Override public String getText() {
return NameUtils.javaToSmaliType(qualifiedName); return smaliName;
} }
@Override public PsiReference getReference() { @Override public PsiReference getReference() {
@ -82,12 +82,11 @@ public class LightSmaliClassTypeElement extends LightElement
} }
@Nullable @Override public PsiClass resolve() { @Nullable @Override public PsiClass resolve() {
JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); return NameUtils.resolveSmaliType(this, smaliName);
return facade.findClass(getCanonicalText(), getResolveScope());
} }
@NotNull @Override public String getCanonicalText() { @NotNull @Override public String getCanonicalText() {
return qualifiedName; return NameUtils.resolveSmaliToJavaType(this, smaliName);
} }
@Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { @Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {

View File

@ -58,24 +58,32 @@ public class SmaliAnnotation extends SmaliStubBasedPsiElement<SmaliAnnotationStu
} }
@Nullable @Override public String getQualifiedName() { @Nullable @Override public String getQualifiedName() {
PsiJavaCodeReferenceElement nameElement = getNameReferenceElement();
if (nameElement != null) {
return nameElement.getQualifiedName();
}
return null;
}
@Nullable public String getSmaliName() {
SmaliAnnotationStub stub = getStub(); SmaliAnnotationStub stub = getStub();
if (stub != null) { if (stub != null) {
return stub.getAnnotationType(); return stub.getAnnotationSmaliTypeName();
} }
SmaliClassTypeElement classType = findChildByClass(SmaliClassTypeElement.class); SmaliClassTypeElement classType = findChildByClass(SmaliClassTypeElement.class);
if (classType == null) { if (classType == null) {
return null; return null;
} }
return classType.getJavaType(); return classType.getSmaliName();
} }
@Nullable @Override public PsiJavaCodeReferenceElement getNameReferenceElement() { @Nullable @Override public PsiJavaCodeReferenceElement getNameReferenceElement() {
SmaliAnnotationStub stub = getStub(); SmaliAnnotationStub stub = getStub();
if (stub != null) { if (stub != null) {
String qualifiedName = stub.getAnnotationType(); String smaliName = stub.getAnnotationSmaliTypeName();
if (qualifiedName != null) { if (smaliName != null) {
return new LightSmaliClassTypeElement(getManager(), qualifiedName); return new LightSmaliClassTypeElement(getManager(), smaliName);
} }
} }
return findChildByClass(SmaliClassTypeElement.class); return findChildByClass(SmaliClassTypeElement.class);

View File

@ -37,6 +37,7 @@ import com.intellij.psi.StubBasedPsiElement;
import com.intellij.psi.stubs.IStubElementType; import com.intellij.psi.stubs.IStubElementType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.stub.SmaliBaseReferenceListStub; import org.jf.smalidea.psi.stub.SmaliBaseReferenceListStub;
import org.jf.smalidea.util.NameUtils;
public abstract class SmaliBaseReferenceList<StubT extends SmaliBaseReferenceListStub> public abstract class SmaliBaseReferenceList<StubT extends SmaliBaseReferenceListStub>
extends SmaliStubBasedPsiElement<StubT> implements StubBasedPsiElement<StubT>, PsiReferenceList { extends SmaliStubBasedPsiElement<StubT> implements StubBasedPsiElement<StubT>, PsiReferenceList {
@ -68,7 +69,14 @@ public abstract class SmaliBaseReferenceList<StubT extends SmaliBaseReferenceLis
SmaliBaseReferenceListStub stub = getStub(); SmaliBaseReferenceListStub stub = getStub();
if (stub != null) { 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(); SmaliClassTypeElement[] references = getReferenceElements();
@ -81,6 +89,23 @@ public abstract class SmaliBaseReferenceList<StubT extends SmaliBaseReferenceLis
return referenceNames; 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() { @Override public boolean isWritable() {
return false; return false;
} }

View File

@ -39,6 +39,7 @@ import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.iface.SmaliModifierListOwner; import org.jf.smalidea.psi.iface.SmaliModifierListOwner;
import org.jf.smalidea.psi.leaf.SmaliClassDescriptor; import org.jf.smalidea.psi.leaf.SmaliClassDescriptor;
import org.jf.smalidea.psi.stub.SmaliClassStatementStub; import org.jf.smalidea.psi.stub.SmaliClassStatementStub;
import org.jf.smalidea.util.NameUtils;
public class SmaliClassStatement extends SmaliStubBasedPsiElement<SmaliClassStatementStub> public class SmaliClassStatement extends SmaliStubBasedPsiElement<SmaliClassStatementStub>
implements SmaliModifierListOwner { implements SmaliModifierListOwner {
@ -83,7 +84,9 @@ public class SmaliClassStatement extends SmaliStubBasedPsiElement<SmaliClassStat
if (classType == null) { if (classType == null) {
return 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 @Nullable

View File

@ -131,16 +131,26 @@ public class SmaliClassType extends PsiClassType {
} }
@Override @Override
@NotNull
public String getPresentableText() { public String getPresentableText() {
return getCanonicalText(); return getCanonicalText();
} }
@Override @Override
@NotNull
public String getCanonicalText() { public String getCanonicalText() {
PsiClass psiClass = resolve();
if (psiClass != null) {
String qualifiedName = psiClass.getQualifiedName();
if (qualifiedName != null) {
return qualifiedName;
}
}
return NameUtils.smaliToJavaType(element.getText()); return NameUtils.smaliToJavaType(element.getText());
} }
@Override @Override
@NotNull
public String getInternalCanonicalText() { public String getInternalCanonicalText() {
return getCanonicalText(); return getCanonicalText();
} }

View File

@ -59,14 +59,6 @@ public class SmaliClassTypeElement extends SmaliTypeElement implements PsiJavaCo
super(SmaliElementTypes.CLASS_TYPE); 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() { @NotNull @Override public SmaliClassType getType() {
if (classType == null) { if (classType == null) {
classType = new SmaliClassType(this); classType = new SmaliClassType(this);
@ -95,12 +87,11 @@ public class SmaliClassTypeElement extends SmaliTypeElement implements PsiJavaCo
} }
@Nullable @Override public PsiClass resolve() { @Nullable @Override public PsiClass resolve() {
JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); return NameUtils.resolveSmaliType(this, getText());
return facade.findClass(getCanonicalText(), getResolveScope());
} }
@NotNull @Override public String getCanonicalText() { @NotNull @Override public String getCanonicalText() {
return NameUtils.smaliToJavaType(getText()); return getQualifiedName();
} }
@Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { @Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
@ -168,7 +159,11 @@ public class SmaliClassTypeElement extends SmaliTypeElement implements PsiJavaCo
} }
@Override public String getQualifiedName() { @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) { @NotNull @Override public JavaResolveResult advancedResolve(boolean incompleteCode) {

View File

@ -43,6 +43,7 @@ import org.jetbrains.annotations.Nullable;
import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.iface.SmaliModifierListOwner; import org.jf.smalidea.psi.iface.SmaliModifierListOwner;
import org.jf.smalidea.psi.stub.SmaliFieldStub; import org.jf.smalidea.psi.stub.SmaliFieldStub;
import org.jf.smalidea.util.NameUtils;
public class SmaliField extends SmaliStubBasedPsiElement<SmaliFieldStub> implements PsiField, SmaliModifierListOwner { public class SmaliField extends SmaliStubBasedPsiElement<SmaliFieldStub> implements PsiField, SmaliModifierListOwner {
public SmaliField(@NotNull SmaliFieldStub stub) { public SmaliField(@NotNull SmaliFieldStub stub) {
@ -93,9 +94,7 @@ public class SmaliField extends SmaliStubBasedPsiElement<SmaliFieldStub> impleme
@NotNull @Override public PsiType getType() { @NotNull @Override public PsiType getType() {
SmaliFieldStub stub = getStub(); SmaliFieldStub stub = getStub();
if (stub != null) { if (stub != null) {
String type = stub.getType(); return NameUtils.resolveSmaliToPsiType(this, stub.getSmaliTypeName());
PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
return factory.createTypeFromText(type, this);
} }
PsiTypeElement typeElement = getTypeElement(); PsiTypeElement typeElement = getTypeElement();
if (typeElement == null) { if (typeElement == null) {
@ -106,8 +105,8 @@ public class SmaliField extends SmaliStubBasedPsiElement<SmaliFieldStub> impleme
return getTypeElement().getType(); return getTypeElement().getType();
} }
@Nullable @Override public PsiTypeElement getTypeElement() { @Nullable @Override public SmaliTypeElement getTypeElement() {
return findChildByClass(PsiTypeElement.class); return findChildByClass(SmaliTypeElement.class);
} }
@Nullable @Override public PsiExpression getInitializer() { @Nullable @Override public PsiExpression getInitializer() {

View File

@ -41,6 +41,7 @@ import org.jetbrains.annotations.Nullable;
import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.iface.SmaliModifierListOwner; import org.jf.smalidea.psi.iface.SmaliModifierListOwner;
import org.jf.smalidea.psi.stub.SmaliMethodParameterStub; import org.jf.smalidea.psi.stub.SmaliMethodParameterStub;
import org.jf.smalidea.util.NameUtils;
public class SmaliMethodParameter extends SmaliStubBasedPsiElement<SmaliMethodParameterStub> public class SmaliMethodParameter extends SmaliStubBasedPsiElement<SmaliMethodParameterStub>
implements PsiParameter, SmaliModifierListOwner { implements PsiParameter, SmaliModifierListOwner {
@ -83,8 +84,7 @@ public class SmaliMethodParameter extends SmaliStubBasedPsiElement<SmaliMethodPa
@NotNull @Override public PsiType getType() { @NotNull @Override public PsiType getType() {
SmaliMethodParameterStub stub = getStub(); SmaliMethodParameterStub stub = getStub();
if (stub != null) { if (stub != null) {
String type = stub.getType(); return NameUtils.resolveSmaliToPsiType(this, stub.getSmaliTypeName());
return JavaPsiFacade.getInstance(getProject()).getParserFacade().createTypeFromText(type, null);
} }
return getTypeElement().getType(); return getTypeElement().getType();
} }

View File

@ -32,14 +32,12 @@
package org.jf.smalidea.psi.impl; package org.jf.smalidea.psi.impl;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.*;
import com.intellij.psi.PsiElementFactory;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jf.smalidea.psi.SmaliElementTypes; import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.stub.SmaliMethodPrototypeStub; import org.jf.smalidea.psi.stub.SmaliMethodPrototypeStub;
import org.jf.smalidea.util.NameUtils;
public class SmaliMethodPrototype extends SmaliStubBasedPsiElement<SmaliMethodPrototypeStub> { public class SmaliMethodPrototype extends SmaliStubBasedPsiElement<SmaliMethodPrototypeStub> {
public SmaliMethodPrototype(@NotNull SmaliMethodPrototypeStub stub) { public SmaliMethodPrototype(@NotNull SmaliMethodPrototypeStub stub) {
@ -54,12 +52,11 @@ public class SmaliMethodPrototype extends SmaliStubBasedPsiElement<SmaliMethodPr
public PsiType getReturnType() { public PsiType getReturnType() {
SmaliMethodPrototypeStub stub = getStub(); SmaliMethodPrototypeStub stub = getStub();
if (stub != null) { if (stub != null) {
String returnType = stub.getReturnType(); String returnSmaliTypeName = stub.getReturnSmaliTypeName();
if (returnType == null) { if (returnSmaliTypeName == null) {
return null; return null;
} }
PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory(); return NameUtils.resolveSmaliToPsiType(this, returnSmaliTypeName);
return factory.createTypeFromText(returnType, this);
} }
PsiTypeElement returnTypeElement = getReturnTypeElement(); PsiTypeElement returnTypeElement = getReturnTypeElement();
@ -69,8 +66,8 @@ public class SmaliMethodPrototype extends SmaliStubBasedPsiElement<SmaliMethodPr
return returnTypeElement.getType(); return returnTypeElement.getType();
} }
@Nullable public PsiTypeElement getReturnTypeElement() { @Nullable public SmaliTypeElement getReturnTypeElement() {
return findChildByClass(PsiTypeElement.class); return findChildByClass(SmaliTypeElement.class);
} }
@NotNull @NotNull

View File

@ -48,6 +48,11 @@ public abstract class SmaliTypeElement extends SmaliCompositeElement implements
return null; return null;
} }
@NotNull
public String getSmaliName() {
return getText();
}
// Annotations on types are for JSR 308. Not applicable to smali. // Annotations on types are for JSR 308. Not applicable to smali.
@NotNull @Override public PsiAnnotation[] getAnnotations() { @NotNull @Override public PsiAnnotation[] getAnnotations() {

View File

@ -39,15 +39,15 @@ import org.jf.smalidea.psi.impl.SmaliAnnotation;
public class SmaliAnnotationStub extends StubBase<SmaliAnnotation> { public class SmaliAnnotationStub extends StubBase<SmaliAnnotation> {
@Nullable @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); super(parent, SmaliElementTypes.ANNOTATION);
this.annotationType = annotationType; this.annotationSmaliTypeName = annotationSmaliTypeName;
} }
@Nullable @Nullable
public String getAnnotationType() { public String getAnnotationSmaliTypeName() {
return annotationType; return annotationSmaliTypeName;
} }
} }

View File

@ -42,26 +42,26 @@ import org.jf.smalidea.psi.impl.SmaliBaseReferenceList;
import org.jf.smalidea.psi.impl.SmaliClassType; import org.jf.smalidea.psi.impl.SmaliClassType;
public abstract class SmaliBaseReferenceListStub<T extends SmaliBaseReferenceList> extends StubBase<T> { 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; @Nullable private SmaliClassType[] classTypes = null;
protected SmaliBaseReferenceListStub( protected SmaliBaseReferenceListStub(
@NotNull StubElement parent, @NotNull IStubElementType elementType, @NotNull String[] types) { @NotNull StubElement parent, @NotNull IStubElementType elementType, @NotNull String[] smaliTypeNames) {
super(parent, elementType); super(parent, elementType);
this.types = types; this.smaliTypeNames = smaliTypeNames;
} }
@NotNull public String[] getTypes() { @NotNull public String[] getSmaliTypeNames() {
return types; return smaliTypeNames;
} }
@NotNull @NotNull
public SmaliClassType[] getReferencedTypes() { public SmaliClassType[] getReferencedTypes() {
if (classTypes == null) { if (classTypes == null) {
classTypes = new SmaliClassType[types.length]; classTypes = new SmaliClassType[smaliTypeNames.length];
for (int i=0; i<types.length; i++) { for (int i = 0; i< smaliTypeNames.length; i++) {
classTypes[i] = new SmaliClassType( classTypes[i] = new SmaliClassType(
new LightSmaliClassTypeElement(PsiManager.getInstance(getProject()), types[i])); new LightSmaliClassTypeElement(PsiManager.getInstance(getProject()), smaliTypeNames[i]));
} }
} }
return classTypes; return classTypes;

View File

@ -37,7 +37,7 @@ import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.impl.SmaliExtendsList; import org.jf.smalidea.psi.impl.SmaliExtendsList;
public class SmaliExtendsListStub extends SmaliBaseReferenceListStub<SmaliExtendsList> { public class SmaliExtendsListStub extends SmaliBaseReferenceListStub<SmaliExtendsList> {
public SmaliExtendsListStub(@NotNull StubElement parent, @NotNull String[] types) { public SmaliExtendsListStub(@NotNull StubElement parent, @NotNull String[] smaliTypeNames) {
super(parent, SmaliElementTypes.EXTENDS_LIST, types); super(parent, SmaliElementTypes.EXTENDS_LIST, smaliTypeNames);
} }
} }

View File

@ -40,19 +40,19 @@ import org.jf.smalidea.psi.impl.SmaliField;
public class SmaliFieldStub extends StubBase<SmaliField> { public class SmaliFieldStub extends StubBase<SmaliField> {
@Nullable private final String name; @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); super(parent, SmaliElementTypes.FIELD);
this.name = name; this.name = name;
this.type = type; this.smaliTypeName = smaliTypeName;
} }
@Nullable public String getName() { @Nullable public String getName() {
return name; return name;
} }
@NotNull public String getType() { @NotNull public String getSmaliTypeName() {
return type; return smaliTypeName;
} }
} }

View File

@ -37,7 +37,7 @@ import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.impl.SmaliImplementsList; import org.jf.smalidea.psi.impl.SmaliImplementsList;
public class SmaliImplementsListStub extends SmaliBaseReferenceListStub<SmaliImplementsList> { public class SmaliImplementsListStub extends SmaliBaseReferenceListStub<SmaliImplementsList> {
public SmaliImplementsListStub(@NotNull StubElement parent, @NotNull String[] types) { public SmaliImplementsListStub(@NotNull StubElement parent, @NotNull String[] smaliTypeNames) {
super(parent, SmaliElementTypes.IMPLEMENTS_LIST, types); super(parent, SmaliElementTypes.IMPLEMENTS_LIST, smaliTypeNames);
} }
} }

View File

@ -39,17 +39,17 @@ import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.impl.SmaliMethodParameter; import org.jf.smalidea.psi.impl.SmaliMethodParameter;
public class SmaliMethodParameterStub extends StubBase<SmaliMethodParameter> { public class SmaliMethodParameterStub extends StubBase<SmaliMethodParameter> {
@NotNull private final String type; @NotNull private final String smaliTypeName;
@Nullable private final String name; @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); super(parent, SmaliElementTypes.METHOD_PARAMETER);
this.type = type; this.smaliTypeName = smaliTypeName;
this.name = name; this.name = name;
} }
@NotNull public String getType() { @NotNull public String getSmaliTypeName() {
return type; return smaliTypeName;
} }
@Nullable public String getName() { @Nullable public String getName() {

View File

@ -39,14 +39,14 @@ import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.impl.SmaliMethodPrototype; import org.jf.smalidea.psi.impl.SmaliMethodPrototype;
public class SmaliMethodPrototypeStub extends StubBase<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); super(parent, SmaliElementTypes.METHOD_PROTOTYPE);
this.returnType = returnType; this.returnSmaliTypeName = returnSmaliTypeName;
} }
@Nullable public String getReturnType() { @Nullable public String getReturnSmaliTypeName() {
return returnType; return returnSmaliTypeName;
} }
} }

View File

@ -62,12 +62,12 @@ public class SmaliAnnotationElementType extends SmaliStubElementType<SmaliAnnota
} }
@Override public SmaliAnnotationStub createStub(@NotNull SmaliAnnotation psi, StubElement parentStub) { @Override public SmaliAnnotationStub createStub(@NotNull SmaliAnnotation psi, StubElement parentStub) {
return new SmaliAnnotationStub(parentStub, psi.getQualifiedName()); return new SmaliAnnotationStub(parentStub, psi.getSmaliName());
} }
@Override @Override
public void serialize(@NotNull SmaliAnnotationStub stub, @NotNull StubOutputStream dataStream) throws IOException { public void serialize(@NotNull SmaliAnnotationStub stub, @NotNull StubOutputStream dataStream) throws IOException {
dataStream.writeName(stub.getAnnotationType()); dataStream.writeName(stub.getAnnotationSmaliTypeName());
} }
@NotNull @Override @NotNull @Override

View File

@ -52,7 +52,7 @@ public abstract class SmaliBaseReferenceListElementType<StubT extends SmaliBaseR
@Override @Override
public void serialize(@NotNull StubT stub, @NotNull StubOutputStream dataStream) public void serialize(@NotNull StubT stub, @NotNull StubOutputStream dataStream)
throws IOException { throws IOException {
String[] references = stub.getTypes(); String[] references = stub.getSmaliTypeNames();
dataStream.writeVarInt(references.length); dataStream.writeVarInt(references.length);
for (String reference: references) { for (String reference: references) {
dataStream.writeName(reference); dataStream.writeName(reference);
@ -61,15 +61,15 @@ public abstract class SmaliBaseReferenceListElementType<StubT extends SmaliBaseR
@NotNull @Override @NotNull @Override
public StubT deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException { public StubT deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
String[] references = new String[dataStream.readVarInt()]; String[] smaliTypeNames = new String[dataStream.readVarInt()];
for (int i=0; i<references.length; i++) { for (int i=0; i<smaliTypeNames.length; i++) {
references[i] = dataStream.readName().getString(); 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) { @Override public void indexStub(@NotNull StubT stub, @NotNull IndexSink sink) {
} }

View File

@ -56,11 +56,11 @@ public class SmaliExtendsListElementType extends SmaliBaseReferenceListElementTy
return new SmaliExtendsList(node); return new SmaliExtendsList(node);
} }
@Override protected SmaliExtendsListStub createStub(StubElement parentStub, String[] types) { @Override protected SmaliExtendsListStub createStub(StubElement parentStub, String[] smaliTypeNames) {
return new SmaliExtendsListStub(parentStub, types); return new SmaliExtendsListStub(parentStub, smaliTypeNames);
} }
@Override public SmaliExtendsListStub createStub(@NotNull SmaliExtendsList psi, StubElement parentStub) { @Override public SmaliExtendsListStub createStub(@NotNull SmaliExtendsList psi, StubElement parentStub) {
return new SmaliExtendsListStub(parentStub, psi.getReferenceNames()); return new SmaliExtendsListStub(parentStub, psi.getSmaliNames());
} }
} }

View File

@ -33,13 +33,13 @@ package org.jf.smalidea.psi.stub.element;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.psi.PsiTypeElement;
import com.intellij.psi.stubs.IndexSink; import com.intellij.psi.stubs.IndexSink;
import com.intellij.psi.stubs.StubElement; import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubInputStream; import com.intellij.psi.stubs.StubInputStream;
import com.intellij.psi.stubs.StubOutputStream; import com.intellij.psi.stubs.StubOutputStream;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.impl.SmaliField; import org.jf.smalidea.psi.impl.SmaliField;
import org.jf.smalidea.psi.impl.SmaliTypeElement;
import org.jf.smalidea.psi.stub.SmaliFieldStub; import org.jf.smalidea.psi.stub.SmaliFieldStub;
import java.io.IOException; import java.io.IOException;
@ -65,15 +65,15 @@ public class SmaliFieldElementType extends SmaliStubElementType<SmaliFieldStub,
@Override public SmaliFieldStub createStub(@NotNull SmaliField psi, StubElement parentStub) { @Override public SmaliFieldStub createStub(@NotNull SmaliField psi, StubElement parentStub) {
try { try {
String fieldType; String fieldSmaliTypeName;
PsiTypeElement typeElement = psi.getTypeElement(); SmaliTypeElement typeElement = psi.getTypeElement();
if (typeElement != null) { if (typeElement != null) {
fieldType = typeElement.getType().getCanonicalText(); fieldSmaliTypeName = typeElement.getSmaliName();
} else { } 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) { } catch (IndexNotReadyException ex) {
System.out.println(psi.getName()); System.out.println(psi.getName());
throw ex; throw ex;
@ -83,7 +83,7 @@ public class SmaliFieldElementType extends SmaliStubElementType<SmaliFieldStub,
@Override @Override
public void serialize(@NotNull SmaliFieldStub stub, @NotNull StubOutputStream dataStream) throws IOException { public void serialize(@NotNull SmaliFieldStub stub, @NotNull StubOutputStream dataStream) throws IOException {
dataStream.writeName(stub.getName()); dataStream.writeName(stub.getName());
dataStream.writeName(stub.getType()); dataStream.writeName(stub.getSmaliTypeName());
} }
@NotNull @Override @NotNull @Override

View File

@ -57,11 +57,11 @@ public class SmaliImplementsListElementType
return new SmaliImplementsList(node); return new SmaliImplementsList(node);
} }
@Override protected SmaliImplementsListStub createStub(StubElement parentStub, String[] types) { @Override protected SmaliImplementsListStub createStub(StubElement parentStub, String[] smaliTypeNames) {
return new SmaliImplementsListStub(parentStub, types); return new SmaliImplementsListStub(parentStub, smaliTypeNames);
} }
@Override public SmaliImplementsListStub createStub(@NotNull SmaliImplementsList psi, StubElement parentStub) { @Override public SmaliImplementsListStub createStub(@NotNull SmaliImplementsList psi, StubElement parentStub) {
return new SmaliImplementsListStub(parentStub, psi.getReferenceNames()); return new SmaliImplementsListStub(parentStub, psi.getSmaliNames());
} }
} }

View File

@ -63,13 +63,13 @@ public class SmaliMethodParameterElementType
} }
@Override public SmaliMethodParameterStub createStub(@NotNull SmaliMethodParameter psi, StubElement parentStub) { @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 @Override
public void serialize(@NotNull SmaliMethodParameterStub stub, @NotNull StubOutputStream dataStream) public void serialize(@NotNull SmaliMethodParameterStub stub, @NotNull StubOutputStream dataStream)
throws IOException { throws IOException {
dataStream.writeName(stub.getType()); dataStream.writeName(stub.getSmaliTypeName());
dataStream.writeName(stub.getName()); dataStream.writeName(stub.getName());
} }

View File

@ -32,13 +32,13 @@
package org.jf.smalidea.psi.stub.element; package org.jf.smalidea.psi.stub.element;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiType;
import com.intellij.psi.stubs.IndexSink; import com.intellij.psi.stubs.IndexSink;
import com.intellij.psi.stubs.StubElement; import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubInputStream; import com.intellij.psi.stubs.StubInputStream;
import com.intellij.psi.stubs.StubOutputStream; import com.intellij.psi.stubs.StubOutputStream;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.impl.SmaliMethodPrototype; import org.jf.smalidea.psi.impl.SmaliMethodPrototype;
import org.jf.smalidea.psi.impl.SmaliTypeElement;
import org.jf.smalidea.psi.stub.SmaliMethodPrototypeStub; import org.jf.smalidea.psi.stub.SmaliMethodPrototypeStub;
import java.io.IOException; import java.io.IOException;
@ -64,19 +64,19 @@ public class SmaliMethodPrototypeElementType
} }
@Override public SmaliMethodPrototypeStub createStub(@NotNull SmaliMethodPrototype psi, StubElement parentStub) { @Override public SmaliMethodPrototypeStub createStub(@NotNull SmaliMethodPrototype psi, StubElement parentStub) {
PsiType returnType = psi.getReturnType(); SmaliTypeElement returnType = psi.getReturnTypeElement();
String returnTypeText = null; String returnSmaliTypeName = null;
if (returnType != null) { if (returnType != null) {
returnTypeText = returnType.getCanonicalText(); returnSmaliTypeName = returnType.getSmaliName();
} }
return new SmaliMethodPrototypeStub(parentStub, returnTypeText); return new SmaliMethodPrototypeStub(parentStub, returnSmaliTypeName);
} }
@Override @Override
public void serialize(@NotNull SmaliMethodPrototypeStub stub, @NotNull StubOutputStream dataStream) public void serialize(@NotNull SmaliMethodPrototypeStub stub, @NotNull StubOutputStream dataStream)
throws IOException { throws IOException {
dataStream.writeName(stub.getReturnType()); dataStream.writeName(stub.getReturnSmaliTypeName());
} }
@NotNull @Override @NotNull @Override

View File

@ -32,10 +32,13 @@
package org.jf.smalidea.util; package org.jf.smalidea.util;
import com.google.common.collect.ImmutableMap; 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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import javax.annotation.Nonnull;
import java.util.Map; import java.util.Map;
public class NameUtils { public class NameUtils {
@ -50,8 +53,38 @@ public class NameUtils {
.put("double", "D") .put("double", "D")
.build(); .build();
@Nonnull @NotNull
public static String javaToSmaliType(@Nonnull String javaType) { 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) == ']') { if (javaType.charAt(javaType.length()-1) == ']') {
int dimensions = 0; int dimensions = 0;
int firstArrayChar = -1; int firstArrayChar = -1;
@ -76,7 +109,6 @@ public class NameUtils {
return simpleJavaToSmaliType(javaType); return simpleJavaToSmaliType(javaType);
} }
private static void convertSimpleJavaToSmaliType(@NotNull String javaType, @NotNull StringBuilder dest) { private static void convertSimpleJavaToSmaliType(@NotNull String javaType, @NotNull StringBuilder dest) {
String smaliType = javaToSmaliPrimitiveTypes.get(javaType); String smaliType = javaToSmaliPrimitiveTypes.get(javaType);
if (smaliType != null) { 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) { private static String simpleJavaToSmaliType(@NotNull String simpleJavaType) {
StringBuilder sb = new StringBuilder(simpleJavaType.length() + 2); StringBuilder sb = new StringBuilder(simpleJavaType.length() + 2);
convertSimpleJavaToSmaliType(simpleJavaType, sb); convertSimpleJavaToSmaliType(simpleJavaType, sb);
@ -113,6 +220,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 @NotNull
private static String convertSmaliArrayToJava(@NotNull String smaliType) { private static String convertSmaliArrayToJava(@NotNull String smaliType) {
int dimensions=0; int dimensions=0;
@ -163,6 +305,9 @@ public class NameUtils {
} }
} }
return; return;
case 'V':
dest.append("void");
return;
case 'U': case 'U':
if (smaliType.equals("Ujava/lang/Object;")) { if (smaliType.equals("Ujava/lang/Object;")) {
dest.append("java.lang.Object"); dest.append("java.lang.Object");

View File

@ -68,4 +68,105 @@ public class SmaliClassTypeElementTest extends LightCodeInsightFixtureTestCase {
Assert.assertNotNull(resolvedClass); Assert.assertNotNull(resolvedClass);
Assert.assertEquals("my.blarg", resolvedClass.getQualifiedName()); 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());
}
} }