Implement extends and implements list

This also includes the relevant implementations in SmaliClass
This commit is contained in:
Ben Gruver 2014-03-23 12:51:26 -07:00
parent 31aad6b5cd
commit bc200776bc
24 changed files with 684 additions and 95 deletions

View File

@ -47,7 +47,7 @@ import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.impl.SmaliFile;
import org.jf.smalidea.psi.stub.SmaliStubElementType;
import org.jf.smalidea.psi.stub.element.SmaliStubElementType;
public class SmaliParserDefinition implements ParserDefinition {
@NotNull @Override public Lexer createLexer(Project project) {

View File

@ -0,0 +1,131 @@
/*
* Copyright 2014, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.smalidea.psi.impl;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jf.smalidea.SmaliLanguage;
import org.jf.smalidea.util.NameUtils;
public class LightSmaliClassTypeElement extends LightElement implements PsiTypeElement, PsiReference {
@NotNull
private final String qualifiedName;
public LightSmaliClassTypeElement(@NotNull PsiManager manager, @NotNull String qualifiedName) {
super(manager, SmaliLanguage.INSTANCE);
this.qualifiedName = qualifiedName;
}
@Override public String toString() {
return "LightSmaliClassTypeElement:" + qualifiedName;
}
@NotNull @Override public PsiType getType() {
return new SmaliClassType(this);
}
@Nullable @Override public PsiJavaCodeReferenceElement getInnermostComponentReferenceElement() {
// Not applicable for smali
return null;
}
@Override public String getText() {
return NameUtils.javaToSmaliType(qualifiedName);
}
@Override public PsiReference getReference() {
return this;
}
@Override public PsiElement getElement() {
return this;
}
@Override public TextRange getRangeInElement() {
return new TextRange(0, getTextLength());
}
@Nullable @Override public PsiElement resolve() {
JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
return facade.findClass(getCanonicalText(), getResolveScope());
}
@NotNull @Override public String getCanonicalText() {
return qualifiedName;
}
@Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
throw new UnsupportedOperationException();
}
@Override public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
throw new UnsupportedOperationException();
}
@Override public boolean isReferenceTo(PsiElement element) {
if (!(element instanceof PsiClassType)) {
return false;
}
return element.getManager().areElementsEquivalent(element, resolve());
}
@NotNull @Override public Object[] getVariants() {
throw new RuntimeException("Variants are not available for light references");
}
@Override public boolean isSoft() {
return false;
}
@NotNull @Override public PsiAnnotation[] getAnnotations() {
return new PsiAnnotation[0];
}
@NotNull @Override public PsiAnnotation[] getApplicableAnnotations() {
return new PsiAnnotation[0];
}
@Nullable @Override public PsiAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) {
return null;
}
@NotNull @Override public PsiAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,127 @@
/*
* Copyright 2014, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.smalidea.psi.impl;
import com.google.common.collect.Lists;
import com.intellij.extapi.psi.StubBasedPsiElementBase;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.PsiReferenceList;
import com.intellij.psi.StubBasedPsiElement;
import com.intellij.psi.stubs.IStubElementType;
import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.stub.SmaliBaseReferenceListStub;
import java.util.List;
public abstract class SmaliBaseReferenceList<StubT extends SmaliBaseReferenceListStub>
extends StubBasedPsiElementBase<StubT> implements StubBasedPsiElement<StubT>, PsiReferenceList {
protected SmaliBaseReferenceList(@NotNull StubT stub, @NotNull IStubElementType nodeType) {
super(stub, nodeType);
}
protected SmaliBaseReferenceList(@NotNull ASTNode node) {
super(node);
}
@NotNull @Override public SmaliClassType[] getReferencedTypes() {
StubT stub = getStub();
if (stub != null) {
return stub.getReferencedTypes();
}
SmaliClassTypeElement[] references = getSmaliReferenceElements();
SmaliClassType[] referenceTypes = new SmaliClassType[references.length];
for (int i=0; i<references.length; i++) {
referenceTypes[i] = references[i].getType();
}
return referenceTypes;
}
@NotNull public String[] getReferenceNames() {
SmaliBaseReferenceListStub stub = getStub();
if (stub != null) {
return stub.getTypes();
}
SmaliClassTypeElement[] references = getSmaliReferenceElements();
String[] referenceNames = new String[references.length];
for (int i=0; i<references.length; i++) {
referenceNames[i] = references[i].getCanonicalText();
}
return referenceNames;
}
@Override public boolean isWritable() {
return false;
}
@NotNull @Override public PsiJavaCodeReferenceElement[] getReferenceElements() {
// Not applicable for smali
return PsiJavaCodeReferenceElement.EMPTY_ARRAY;
}
@NotNull public abstract SmaliClassTypeElement[] getSmaliReferenceElements();
protected SmaliClassTypeElement[] getImplementsElements() {
SmaliImplementsStatement[] implementsStatements = ((SmaliClass)getParent()).getImplementsStatements();
if (implementsStatements.length > 0) {
// all implemented interfaces go in the extends list for an interface
List<SmaliClassTypeElement> types = Lists.newArrayList();
for (SmaliImplementsStatement implementsStatement: implementsStatements) {
SmaliClassTypeElement classReference = implementsStatement.getClassReference();
if (classReference != null) {
types.add(classReference);
}
}
return types.toArray(new SmaliClassTypeElement[types.size()]);
}
return new SmaliClassTypeElement[0];
}
protected SmaliClassTypeElement[] getExtendsElement() {
SmaliSuperStatement superStatement = ((SmaliClass)getParent()).getSuperStatement();
if (superStatement != null) {
SmaliClassTypeElement classReference = superStatement.getClassReference();
if (classReference != null) {
return new SmaliClassTypeElement[] { classReference };
}
}
return new SmaliClassTypeElement[0];
}
}

View File

@ -35,6 +35,7 @@ import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.PsiModifier.ModifierConstant;
import com.intellij.psi.impl.PsiClassImplUtil;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
@ -100,36 +101,44 @@ public class SmaliClass extends SmaliStubBasedPsiElement<SmaliClassStub> impleme
return getModifierList().hasModifierProperty("enum");
}
@Nullable @Override public PsiReferenceList getExtendsList() {
return null;
@Nullable public SmaliSuperStatement getSuperStatement() {
return findChildByClass(SmaliSuperStatement.class);
}
@Nullable @Override public PsiReferenceList getImplementsList() {
return null;
@NotNull @Override public SmaliExtendsList getExtendsList() {
return getRequiredStubOrPsiChild(SmaliElementTypes.EXTENDS_LIST);
}
@NotNull @Override public PsiClassType[] getExtendsListTypes() {
return new PsiClassType[0];
@NotNull public SmaliImplementsStatement[] getImplementsStatements() {
return findChildrenByClass(SmaliImplementsStatement.class);
}
@NotNull @Override public PsiClassType[] getImplementsListTypes() {
return new PsiClassType[0];
@NotNull @Override public SmaliImplementsList getImplementsList() {
return getRequiredStubOrPsiChild(SmaliElementTypes.IMPLEMENTS_LIST);
}
@NotNull @Override public SmaliClassType[] getExtendsListTypes() {
return getExtendsList().getReferencedTypes();
}
@NotNull @Override public SmaliClassType[] getImplementsListTypes() {
return getImplementsList().getReferencedTypes();
}
@Nullable @Override public PsiClass getSuperClass() {
return null;
return PsiClassImplUtil.getSuperClass(this);
}
@Override public PsiClass[] getInterfaces() {
return new PsiClass[0];
return PsiClassImplUtil.getInterfaces(this);
}
@NotNull @Override public PsiClass[] getSupers() {
return new PsiClass[0];
return PsiClassImplUtil.getSupers(this);
}
@NotNull @Override public PsiClassType[] getSuperTypes() {
return new PsiClassType[0];
return PsiClassImplUtil.getSuperTypes(this);
}
@NotNull @Override public PsiField[] getFields() {
@ -276,4 +285,4 @@ public class SmaliClass extends SmaliStubBasedPsiElement<SmaliClassStub> impleme
// TODO: implement this
return null;
}
}
}

View File

@ -40,13 +40,13 @@ import org.jetbrains.annotations.Nullable;
import org.jf.smalidea.util.NameUtils;
public class SmaliClassType extends PsiClassType {
private final SmaliClassTypeElement element;
private final PsiTypeElement element;
public SmaliClassType(SmaliClassTypeElement element) {
public SmaliClassType(PsiTypeElement element) {
this(element, LanguageLevel.JDK_1_5);
}
public SmaliClassType(SmaliClassTypeElement element, LanguageLevel languageLevel) {
public SmaliClassType(PsiTypeElement element, LanguageLevel languageLevel) {
super(languageLevel);
this.element = element;
}
@ -54,7 +54,11 @@ public class SmaliClassType extends PsiClassType {
@Nullable
@Override
public PsiClass resolve() {
PsiElement resolved = element.resolve();
PsiReference reference = element.getReference();
if (reference == null) {
return null;
}
PsiElement resolved = reference.resolve();
if (resolved instanceof PsiClass) {
return (PsiClass)resolved;
}
@ -67,7 +71,7 @@ public class SmaliClassType extends PsiClassType {
if (resolved != null) {
return NameUtils.shortNameFromQualifiedName(resolved.getQualifiedName());
}
return NameUtils.shortNameFromQualifiedName(element.getCanonicalText());
return NameUtils.shortNameFromQualifiedName(element.getText());
}
@NotNull
@ -133,7 +137,7 @@ public class SmaliClassType extends PsiClassType {
@Override
public String getCanonicalText() {
return element.getCanonicalText();
return NameUtils.smaliToJavaType(element.getText());
}
@Override

View File

@ -36,7 +36,7 @@ import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.stub.SmaliExtendsListStub;
public class SmaliExtendsList extends SmaliStubBasedPsiElement<SmaliExtendsListStub> {
public class SmaliExtendsList extends SmaliBaseReferenceList<SmaliExtendsListStub> {
public SmaliExtendsList(@NotNull SmaliExtendsListStub stub) {
super(stub, SmaliElementTypes.EXTENDS_LIST);
}
@ -44,4 +44,16 @@ public class SmaliExtendsList extends SmaliStubBasedPsiElement<SmaliExtendsListS
public SmaliExtendsList(@NotNull ASTNode node) {
super(node);
}
@NotNull @Override public SmaliClassTypeElement[] getSmaliReferenceElements() {
if (((SmaliClass)getParent()).isInterface()) {
return getImplementsElements();
} else {
return getExtendsElement();
}
}
@Override public Role getRole() {
return Role.EXTENDS_LIST;
}
}

View File

@ -36,7 +36,7 @@ import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.stub.SmaliImplementsListStub;
public class SmaliImplementsList extends SmaliStubBasedPsiElement<SmaliImplementsListStub> {
public class SmaliImplementsList extends SmaliBaseReferenceList<SmaliImplementsListStub> {
public SmaliImplementsList(@NotNull SmaliImplementsListStub stub) {
super(stub, SmaliElementTypes.IMPLEMENTS_LIST);
}
@ -44,4 +44,15 @@ public class SmaliImplementsList extends SmaliStubBasedPsiElement<SmaliImplement
public SmaliImplementsList(@NotNull ASTNode node) {
super(node);
}
@NotNull @Override public SmaliClassTypeElement[] getSmaliReferenceElements() {
if (!((SmaliClass)getParent()).isInterface()) {
return getImplementsElements();
}
return new SmaliClassTypeElement[0];
}
@Override public Role getRole() {
return Role.IMPLEMENTS_LIST;
}
}

View File

@ -31,6 +31,7 @@
package org.jf.smalidea.psi.impl;
import org.jetbrains.annotations.Nullable;
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
import org.jf.smalidea.psi.SmaliElementTypes;
@ -44,4 +45,9 @@ public class SmaliImplementsStatement extends SmaliCompositeElement {
public SmaliImplementsStatement() {
super(SmaliElementTypes.IMPLEMENTS_STATEMENT);
}
@Nullable
public SmaliClassTypeElement getClassReference() {
return findChildByClass(SmaliClassTypeElement.class);
}
}

View File

@ -31,6 +31,7 @@
package org.jf.smalidea.psi.impl;
import org.jetbrains.annotations.Nullable;
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
import org.jf.smalidea.psi.SmaliElementTypes;
@ -44,4 +45,9 @@ public class SmaliSuperStatement extends SmaliCompositeElement {
public SmaliSuperStatement() {
super(SmaliElementTypes.SUPER_STATEMENT);
}
@Nullable
public SmaliClassTypeElement getClassReference() {
return findChildByClass(SmaliClassTypeElement.class);
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright 2014, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.smalidea.psi.stub;
import com.intellij.psi.PsiManager;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jf.smalidea.psi.impl.LightSmaliClassTypeElement;
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;
@Nullable private SmaliClassType[] classTypes = null;
protected SmaliBaseReferenceListStub(
@NotNull StubElement parent, @NotNull IStubElementType elementType, @NotNull String[] types) {
super(parent, elementType);
this.types = types;
}
@NotNull public String[] getTypes() {
return types;
}
@NotNull
public SmaliClassType[] getReferencedTypes() {
if (classTypes == null) {
classTypes = new SmaliClassType[types.length];
for (int i=0; i<types.length; i++) {
classTypes[i] = new SmaliClassType(
new LightSmaliClassTypeElement(PsiManager.getInstance(getProject()), types[i]));
}
}
return classTypes;
}
}

View File

@ -31,13 +31,13 @@
package org.jf.smalidea.psi.stub;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.impl.SmaliExtendsList;
public class SmaliExtendsListStub extends StubBase<SmaliExtendsList> {
public SmaliExtendsListStub(StubElement parent, IStubElementType elementType) {
super(parent, elementType);
public class SmaliExtendsListStub extends SmaliBaseReferenceListStub<SmaliExtendsList> {
public SmaliExtendsListStub(@NotNull StubElement parent, @NotNull String[] types) {
super(parent, SmaliElementTypes.EXTENDS_LIST, types);
}
}

View File

@ -31,13 +31,13 @@
package org.jf.smalidea.psi.stub;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.SmaliElementTypes;
import org.jf.smalidea.psi.impl.SmaliImplementsList;
public class SmaliImplementsListStub extends StubBase<SmaliImplementsList> {
public SmaliImplementsListStub(StubElement parent, IStubElementType elementType) {
super(parent, elementType);
public class SmaliImplementsListStub extends SmaliBaseReferenceListStub<SmaliImplementsList> {
public SmaliImplementsListStub(@NotNull StubElement parent, @NotNull String[] types) {
super(parent, SmaliElementTypes.IMPLEMENTS_LIST, types);
}
}

View File

@ -39,7 +39,6 @@ import com.intellij.psi.stubs.StubOutputStream;
import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.impl.SmaliAnnotation;
import org.jf.smalidea.psi.stub.SmaliAnnotationStub;
import org.jf.smalidea.psi.stub.SmaliStubElementType;
import java.io.IOException;

View File

@ -0,0 +1,76 @@
/*
* Copyright 2014, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.smalidea.psi.stub.element;
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.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.impl.SmaliBaseReferenceList;
import org.jf.smalidea.psi.stub.SmaliBaseReferenceListStub;
import java.io.IOException;
public abstract class SmaliBaseReferenceListElementType<StubT extends SmaliBaseReferenceListStub,
PsiT extends SmaliBaseReferenceList> extends SmaliStubElementType<StubT, PsiT> {
protected SmaliBaseReferenceListElementType(@NotNull @NonNls String debugName) {
super(debugName);
}
@Override
public void serialize(@NotNull StubT stub, @NotNull StubOutputStream dataStream)
throws IOException {
String[] references = stub.getTypes();
dataStream.writeVarInt(references.length);
for (String reference: references) {
dataStream.writeName(reference);
}
}
@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();
}
return createStub(parentStub, references);
}
protected abstract StubT createStub(StubElement parentStub, String[] types);
@Override public void indexStub(@NotNull StubT stub, @NotNull IndexSink sink) {
}
}

View File

@ -40,7 +40,6 @@ import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.impl.SmaliClass;
import org.jf.smalidea.psi.index.SmaliClassNameIndex;
import org.jf.smalidea.psi.stub.SmaliClassStub;
import org.jf.smalidea.psi.stub.SmaliStubElementType;
import java.io.IOException;

View File

@ -32,19 +32,12 @@
package org.jf.smalidea.psi.stub.element;
import com.intellij.lang.ASTNode;
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.SmaliElementTypes;
import org.jf.smalidea.psi.impl.SmaliExtendsList;
import org.jf.smalidea.psi.stub.SmaliExtendsListStub;
import org.jf.smalidea.psi.stub.SmaliStubElementType;
import java.io.IOException;
public class SmaliExtendsListElementType extends SmaliStubElementType<SmaliExtendsListStub, SmaliExtendsList> {
public class SmaliExtendsListElementType extends SmaliBaseReferenceListElementType<SmaliExtendsListStub, SmaliExtendsList> {
public static final SmaliExtendsListElementType INSTANCE = new SmaliExtendsListElementType ();
private SmaliExtendsListElementType() {
@ -55,29 +48,19 @@ public class SmaliExtendsListElementType extends SmaliStubElementType<SmaliExten
return "smali.extends_list";
}
@Override public SmaliExtendsList createPsi(@NotNull ASTNode node) {
return new SmaliExtendsList(node);
}
@Override public SmaliExtendsList createPsi(@NotNull SmaliExtendsListStub stub) {
return new SmaliExtendsList(stub);
}
@Override public SmaliExtendsList createPsi(@NotNull ASTNode node) {
return new SmaliExtendsList(node);
}
@Override protected SmaliExtendsListStub createStub(StubElement parentStub, String[] types) {
return new SmaliExtendsListStub(parentStub, types);
}
@Override public SmaliExtendsListStub createStub(@NotNull SmaliExtendsList psi, StubElement parentStub) {
return new SmaliExtendsListStub(parentStub, SmaliElementTypes.EXTENDS_LIST);
}
@Override
public void serialize(@NotNull SmaliExtendsListStub stub, @NotNull StubOutputStream dataStream)
throws IOException {
}
@NotNull @Override
public SmaliExtendsListStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub)
throws IOException {
return new SmaliExtendsListStub(parentStub, SmaliElementTypes.EXTENDS_LIST);
}
@Override public void indexStub(@NotNull SmaliExtendsListStub stub, @NotNull IndexSink sink) {
return new SmaliExtendsListStub(parentStub, psi.getReferenceNames());
}
}

View File

@ -39,7 +39,6 @@ import com.intellij.psi.stubs.StubOutputStream;
import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.impl.SmaliField;
import org.jf.smalidea.psi.stub.SmaliFieldStub;
import org.jf.smalidea.psi.stub.SmaliStubElementType;
import java.io.IOException;

View File

@ -32,20 +32,13 @@
package org.jf.smalidea.psi.stub.element;
import com.intellij.lang.ASTNode;
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.SmaliElementTypes;
import org.jf.smalidea.psi.impl.SmaliImplementsList;
import org.jf.smalidea.psi.stub.SmaliImplementsListStub;
import org.jf.smalidea.psi.stub.SmaliStubElementType;
import java.io.IOException;
public class SmaliImplementsListElementType extends
SmaliStubElementType<SmaliImplementsListStub, SmaliImplementsList> {
public class SmaliImplementsListElementType
extends SmaliBaseReferenceListElementType<SmaliImplementsListStub, SmaliImplementsList> {
public static final SmaliImplementsListElementType INSTANCE = new SmaliImplementsListElementType();
private SmaliImplementsListElementType() {
@ -56,29 +49,19 @@ public class SmaliImplementsListElementType extends
return "smali.implements_list";
}
@Override public SmaliImplementsList createPsi(@NotNull ASTNode node) {
return new SmaliImplementsList(node);
}
@Override public SmaliImplementsList createPsi(@NotNull SmaliImplementsListStub stub) {
return new SmaliImplementsList(stub);
}
@Override public SmaliImplementsList createPsi(@NotNull ASTNode node) {
return new SmaliImplementsList(node);
}
@Override protected SmaliImplementsListStub createStub(StubElement parentStub, String[] types) {
return new SmaliImplementsListStub(parentStub, types);
}
@Override public SmaliImplementsListStub createStub(@NotNull SmaliImplementsList psi, StubElement parentStub) {
return new SmaliImplementsListStub(parentStub, SmaliElementTypes.IMPLEMENTS_LIST);
}
@Override
public void serialize(@NotNull SmaliImplementsListStub stub, @NotNull StubOutputStream dataStream)
throws IOException {
}
@NotNull @Override
public SmaliImplementsListStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub)
throws IOException {
return new SmaliImplementsListStub(parentStub, SmaliElementTypes.IMPLEMENTS_LIST);
}
@Override public void indexStub(@NotNull SmaliImplementsListStub stub, @NotNull IndexSink sink) {
return new SmaliImplementsListStub(parentStub, psi.getReferenceNames());
}
}

View File

@ -39,7 +39,6 @@ import com.intellij.psi.stubs.StubOutputStream;
import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.impl.SmaliMethod;
import org.jf.smalidea.psi.stub.SmaliMethodStub;
import org.jf.smalidea.psi.stub.SmaliStubElementType;
import java.io.IOException;

View File

@ -39,7 +39,6 @@ import com.intellij.psi.stubs.StubOutputStream;
import org.jetbrains.annotations.NotNull;
import org.jf.smalidea.psi.impl.SmaliModifierList;
import org.jf.smalidea.psi.stub.SmaliModifierListStub;
import org.jf.smalidea.psi.stub.SmaliStubElementType;
import java.io.IOException;

View File

@ -29,7 +29,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.smalidea.psi.stub;
package org.jf.smalidea.psi.stub.element;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;

View File

@ -95,7 +95,7 @@ public class NameUtils {
}
}
private static String simpleJavaToSmaliType(@Nonnull String simpleJavaType) {
private static String simpleJavaToSmaliType(@NotNull String simpleJavaType) {
StringBuilder sb = new StringBuilder(simpleJavaType.length() + 2);
convertSimpleJavaToSmaliType(simpleJavaType, sb);
sb.trimToSize();
@ -103,7 +103,7 @@ public class NameUtils {
}
@NotNull
public static String smaliToJavaType(@Nonnull String smaliType) {
public static String smaliToJavaType(@NotNull String smaliType) {
if (smaliType.charAt(0) == '[') {
return convertSmaliArrayToJava(smaliType);
} else {

View File

@ -31,6 +31,7 @@
package org.jf.smalidea;
import com.intellij.psi.PsiClass;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import junit.framework.Assert;
import org.jf.smalidea.psi.impl.SmaliClass;
@ -54,4 +55,56 @@ public class SmaliClassTest extends LightCodeInsightFixtureTestCase {
Assert.assertEquals("blah", smaliClass.getQualifiedName());
Assert.assertEquals("", smaliClass.getPackageName());
}
public void testGetSuperclass() {
myFixture.addFileToProject("base.smali",
".class public interface Lbase; .super Ljava/lang/Object;");
myFixture.addFileToProject("iface.smali",
".class public interface Liface; .super Ljava/lang/Object;");
SmaliFile file = (SmaliFile)myFixture.addFileToProject("blah.smali",
".class public Lblah; .super Lbase; .implements Liface;");
SmaliClass smaliClass = file.getPsiClass();
Assert.assertEquals("blah", smaliClass.getQualifiedName());
PsiClass superClass = smaliClass.getSuperClass();
Assert.assertNotNull(superClass);
Assert.assertEquals("base", smaliClass.getSuperClass().getQualifiedName());
Assert.assertEquals(2, smaliClass.getSupers().length);
Assert.assertEquals("base", smaliClass.getSupers()[0].getQualifiedName());
Assert.assertEquals("iface", smaliClass.getSupers()[1].getQualifiedName());
Assert.assertEquals(2, smaliClass.getSuperTypes().length);
Assert.assertEquals("base", smaliClass.getSuperTypes()[0].getCanonicalText());
Assert.assertEquals("iface", smaliClass.getSuperTypes()[1].getCanonicalText());
Assert.assertEquals(1, smaliClass.getInterfaces().length);
Assert.assertEquals("iface", smaliClass.getInterfaces()[0].getQualifiedName());
}
public void testGetSuperclassForInterface() {
myFixture.addFileToProject("iface.smali",
".class public interface Liface; .super Ljava/lang/Object;");
SmaliFile file = (SmaliFile)myFixture.addFileToProject("blah.smali",
".class public interface Lblah; .super Ljava/lang/Object; .implements Liface;");
SmaliClass smaliClass = file.getPsiClass();
Assert.assertEquals("blah", smaliClass.getQualifiedName());
PsiClass superClass = smaliClass.getSuperClass();
Assert.assertNotNull(superClass);
Assert.assertEquals("java.lang.Object", smaliClass.getSuperClass().getQualifiedName());
Assert.assertEquals(2, smaliClass.getSupers().length);
Assert.assertEquals("java.lang.Object", smaliClass.getSupers()[0].getQualifiedName());
Assert.assertEquals("iface", smaliClass.getSupers()[1].getQualifiedName());
Assert.assertEquals(1, smaliClass.getSuperTypes().length);
Assert.assertEquals("iface", smaliClass.getSuperTypes()[0].getCanonicalText());
Assert.assertEquals(1, smaliClass.getInterfaces().length);
Assert.assertEquals("iface", smaliClass.getInterfaces()[0].getQualifiedName());
}
}

View File

@ -0,0 +1,124 @@
/*
* Copyright 2014, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.smalidea;
import com.intellij.psi.PsiClass;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import junit.framework.Assert;
import org.jf.smalidea.psi.impl.SmaliClass;
import org.jf.smalidea.psi.impl.SmaliExtendsList;
import org.jf.smalidea.psi.impl.SmaliFile;
import org.jf.smalidea.psi.impl.SmaliImplementsList;
public class SmaliImplementsExtendsTest extends LightCodeInsightFixtureTestCase {
public void testNormalClass() {
myFixture.addFileToProject("my/pkg/base.smali",
".class public Lmy/pkg/base; .super Ljava/lang/Object;");
myFixture.addFileToProject("my/pkg/iface.smali",
".class public Lmy/pkg/iface; .super Ljava/lang/Object;");
myFixture.addFileToProject("my/pkg/iface2.smali",
".class public Lmy/pkg/iface2; .super Ljava/lang/Object;");
SmaliFile file = (SmaliFile)myFixture.addFileToProject("my/pkg/blah.smali",
".class public Lmy/pkg/blah; .implements Lmy/pkg/iface; .super Lmy/pkg/base; " +
".implements Lmy/pkg/iface2;");
SmaliClass smaliClass = file.getPsiClass();
SmaliExtendsList extendsList = smaliClass.getExtendsList();
Assert.assertEquals(1, extendsList.getReferencedTypes().length);
Assert.assertEquals("my.pkg.base", extendsList.getReferencedTypes()[0].getCanonicalText());
Assert.assertEquals(1, extendsList.getReferenceNames().length);
Assert.assertEquals("my.pkg.base", extendsList.getReferenceNames()[0]);
Assert.assertEquals(1, smaliClass.getExtendsListTypes().length);
Assert.assertEquals("my.pkg.base", smaliClass.getExtendsListTypes()[0].getCanonicalText());
PsiClass resolvedSuper = extendsList.getReferencedTypes()[0].resolve();
Assert.assertNotNull(resolvedSuper);
Assert.assertEquals("my.pkg.base", resolvedSuper.getQualifiedName());
SmaliImplementsList implementsList = smaliClass.getImplementsList();
Assert.assertEquals(2, implementsList.getReferencedTypes().length);
Assert.assertEquals("my.pkg.iface", implementsList.getReferencedTypes()[0].getCanonicalText());
Assert.assertEquals("my.pkg.iface2", implementsList.getReferencedTypes()[1].getCanonicalText());
Assert.assertEquals(2, implementsList.getReferenceNames().length);
Assert.assertEquals("my.pkg.iface", implementsList.getReferenceNames()[0]);
Assert.assertEquals("my.pkg.iface2", implementsList.getReferenceNames()[1]);
Assert.assertEquals(2, smaliClass.getImplementsListTypes().length);
Assert.assertEquals("my.pkg.iface", smaliClass.getImplementsListTypes()[0].getCanonicalText());
Assert.assertEquals("my.pkg.iface2", smaliClass.getImplementsListTypes()[1].getCanonicalText());
PsiClass resolvedInterface = implementsList.getReferencedTypes()[0].resolve();
Assert.assertNotNull(resolvedInterface);
Assert.assertEquals("my.pkg.iface", resolvedInterface.getQualifiedName());
resolvedInterface = implementsList.getReferencedTypes()[1].resolve();
Assert.assertNotNull(resolvedInterface);
Assert.assertEquals("my.pkg.iface2", resolvedInterface.getQualifiedName());
}
public void testInterface() {
myFixture.addFileToProject("my/pkg/iface.smali",
".class public Lmy/pkg/iface; .super Ljava/lang/Object;");
myFixture.addFileToProject("my/pkg/iface2.smali",
".class public Lmy/pkg/iface2; .super Ljava/lang/Object;");
SmaliFile file = (SmaliFile)myFixture.addFileToProject("my/pkg/blah.smali",
".class public interface Lmy/pkg/blah; .implements Lmy/pkg/iface; .super Ljava/lang/Object; " +
".implements Lmy/pkg/iface2;");
SmaliClass smaliClass = file.getPsiClass();
SmaliExtendsList extendsList = smaliClass.getExtendsList();
Assert.assertEquals(2, extendsList.getReferencedTypes().length);
Assert.assertEquals("my.pkg.iface", extendsList.getReferencedTypes()[0].getCanonicalText());
Assert.assertEquals("my.pkg.iface2", extendsList.getReferencedTypes()[1].getCanonicalText());
Assert.assertEquals(2, extendsList.getReferenceNames().length);
Assert.assertEquals("my.pkg.iface", extendsList.getReferenceNames()[0]);
Assert.assertEquals("my.pkg.iface2", extendsList.getReferenceNames()[1]);
Assert.assertEquals(2, smaliClass.getExtendsListTypes().length);
Assert.assertEquals("my.pkg.iface", smaliClass.getExtendsListTypes()[0].getCanonicalText());
Assert.assertEquals("my.pkg.iface2", smaliClass.getExtendsListTypes()[1].getCanonicalText());
PsiClass resolvedInterface = extendsList.getReferencedTypes()[0].resolve();
Assert.assertNotNull(resolvedInterface);
Assert.assertEquals("my.pkg.iface", resolvedInterface.getQualifiedName());
resolvedInterface = extendsList.getReferencedTypes()[1].resolve();
Assert.assertNotNull(resolvedInterface);
Assert.assertEquals("my.pkg.iface2", resolvedInterface.getQualifiedName());
SmaliImplementsList implementsList = smaliClass.getImplementsList();
Assert.assertEquals(0, implementsList.getReferencedTypes().length);
Assert.assertEquals(0, implementsList.getReferenceNames().length);
Assert.assertEquals(0, smaliClass.getImplementsListTypes().length);
}
}