mirror of
https://github.com/revanced/smali.git
synced 2025-05-09 02:44:29 +02:00
Flesh out SmaliAnnotation and related classes/methods
This commit is contained in:
parent
6d81598612
commit
9a1db48dc5
@ -494,14 +494,24 @@ fixed_literal
|
||||
| bool_literal;
|
||||
|
||||
annotation_element
|
||||
@init { Marker marker = mark(); }
|
||||
: simple_name EQUAL literal;
|
||||
@init {
|
||||
Marker marker = mark();
|
||||
Marker nameMarker = null;
|
||||
}
|
||||
: { nameMarker = mark(); } simple_name { nameMarker.done(SmaliElementTypes.ANNOTATION_ELEMENT_NAME); }
|
||||
EQUAL literal;
|
||||
finally { marker.done(SmaliElementTypes.ANNOTATION_ELEMENT); }
|
||||
|
||||
annotation
|
||||
@init { Marker marker = mark(); }
|
||||
@init {
|
||||
Marker marker = mark();
|
||||
Marker paramListMarker = null;
|
||||
}
|
||||
: ANNOTATION_DIRECTIVE ANNOTATION_VISIBILITY class_descriptor
|
||||
annotation_element* END_ANNOTATION_DIRECTIVE;
|
||||
{ paramListMarker = mark(); }
|
||||
annotation_element*
|
||||
{ paramListMarker.done(SmaliElementTypes.ANNOTATION_PARAMETER_LIST); }
|
||||
END_ANNOTATION_DIRECTIVE;
|
||||
finally { marker.done(SmaliElementTypes.ANNOTATION); }
|
||||
|
||||
fully_qualified_method
|
||||
|
@ -68,8 +68,12 @@ public class SmaliElementTypes {
|
||||
new SmaliCompositeElementType("FIELD_INITIALIZER", SmaliFieldInitializer.FACTORY);
|
||||
public static final SmaliCompositeElementType INSTRUCTION =
|
||||
new SmaliCompositeElementType("INSTRUCTION", SmaliInstruction.FACTORY);
|
||||
public static final SmaliCompositeElementType ANNOTATION_PARAMETER_LIST =
|
||||
new SmaliCompositeElementType("ANNOTATION_PARAMETER_LIST", SmaliAnnotationParameterList.FACTORY);
|
||||
public static final SmaliCompositeElementType ANNOTATION_ELEMENT =
|
||||
new SmaliCompositeElementType("ANNOTATION_ELEMENT", SmaliAnnotationElement.FACTORY);
|
||||
public static final SmaliCompositeElementType ANNOTATION_ELEMENT_NAME =
|
||||
new SmaliCompositeElementType("ANNOTATION_ELEMENT_NAME", SmaliAnnotationElementName.FACTORY);
|
||||
public static final SmaliCompositeElementType FIELD_REFERENCE =
|
||||
new SmaliCompositeElementType("FIELD_REFERENCE", SmaliFieldReference.FACTORY);
|
||||
public static final SmaliCompositeElementType METHOD_REFERENCE =
|
||||
|
@ -34,6 +34,7 @@ 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.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -41,7 +42,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jf.smalidea.SmaliLanguage;
|
||||
import org.jf.smalidea.util.NameUtils;
|
||||
|
||||
public class LightSmaliClassTypeElement extends LightElement implements PsiTypeElement, PsiReference {
|
||||
public class LightSmaliClassTypeElement extends LightElement
|
||||
implements PsiTypeElement, PsiReference, PsiJavaCodeReferenceElement {
|
||||
@NotNull
|
||||
private final String qualifiedName;
|
||||
|
||||
@ -58,9 +60,8 @@ public class LightSmaliClassTypeElement extends LightElement implements PsiTypeE
|
||||
return new SmaliClassType(this);
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiJavaCodeReferenceElement getInnermostComponentReferenceElement() {
|
||||
// Not applicable for smali
|
||||
return null;
|
||||
@Nullable @Override public LightSmaliClassTypeElement getInnermostComponentReferenceElement() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public String getText() {
|
||||
@ -84,8 +85,6 @@ public class LightSmaliClassTypeElement extends LightElement implements PsiTypeE
|
||||
return facade.findClass(getCanonicalText(), getResolveScope());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NotNull @Override public String getCanonicalText() {
|
||||
return qualifiedName;
|
||||
}
|
||||
@ -128,4 +127,55 @@ public class LightSmaliClassTypeElement extends LightElement implements PsiTypeE
|
||||
@NotNull @Override public PsiAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// Below are the PsiJavaCodeReferenceElement-specific methods
|
||||
|
||||
@Override public void processVariants(@NotNull PsiScopeProcessor processor) {
|
||||
// TODO: maybe just do nothing?
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiElement getReferenceNameElement() {
|
||||
// TODO: implement if needed
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiReferenceParameterList getParameterList() {
|
||||
// TODO: (generics) implement this
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull @Override public PsiType[] getTypeParameters() {
|
||||
// TODO: (generics) implement this
|
||||
return new PsiType[0];
|
||||
}
|
||||
|
||||
@Override public boolean isQualified() {
|
||||
// TODO: should this return false for classes in the top level package?
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public String getQualifiedName() {
|
||||
return getCanonicalText();
|
||||
}
|
||||
|
||||
@NotNull @Override public JavaResolveResult advancedResolve(boolean incompleteCode) {
|
||||
// TODO: implement this if needed
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull @Override public JavaResolveResult[] multiResolve(boolean incompleteCode) {
|
||||
// TODO: implement this if needed
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiElement getQualifier() {
|
||||
// TODO: implement this if needed
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable @Override public String getReferenceName() {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ package org.jf.smalidea.psi.impl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.meta.PsiMetaData;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -49,15 +50,19 @@ public class SmaliAnnotation extends SmaliStubBasedPsiElement<SmaliAnnotationStu
|
||||
super(node);
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiMetaData getMetaData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull @Override public PsiAnnotationParameterList getParameterList() {
|
||||
return null;
|
||||
@NotNull @Override public SmaliAnnotationParameterList getParameterList() {
|
||||
SmaliAnnotationParameterList paramList = findChildByClass(SmaliAnnotationParameterList.class);
|
||||
// TODO: test that this is true even if there are syntax errors
|
||||
assert paramList != null;
|
||||
return paramList;
|
||||
}
|
||||
|
||||
@Nullable @Override public String getQualifiedName() {
|
||||
SmaliAnnotationStub stub = getStub();
|
||||
if (stub != null) {
|
||||
return stub.getAnnotationType();
|
||||
}
|
||||
|
||||
SmaliClassTypeElement classType = findChildByClass(SmaliClassTypeElement.class);
|
||||
if (classType == null) {
|
||||
return null;
|
||||
@ -66,24 +71,41 @@ public class SmaliAnnotation extends SmaliStubBasedPsiElement<SmaliAnnotationStu
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiJavaCodeReferenceElement getNameReferenceElement() {
|
||||
return null;
|
||||
// TODO: have SmaliClassTypeElement implement PsiJavaCodeReferenceElement?
|
||||
// TODO: we need to have a PsiAnnotationMethod implementation for methods in an annotation class (see PsiUtil.isAnnotationMethod and PsiImplUtil.findAttributeValue)
|
||||
// TODO: alternately, we should implement findAttributeValue and findAttributeValue ourselves, instead of relying on PsiImplUtil (don't forget about finding default values..)
|
||||
SmaliAnnotationStub stub = getStub();
|
||||
if (stub != null) {
|
||||
String qualifiedName = stub.getAnnotationType();
|
||||
if (qualifiedName != null) {
|
||||
return new LightSmaliClassTypeElement(getManager(), qualifiedName);
|
||||
}
|
||||
}
|
||||
return findChildByClass(SmaliClassTypeElement.class);
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiAnnotationMemberValue findAttributeValue(@Nullable @NonNls String attributeName) {
|
||||
return null;
|
||||
return PsiImplUtil.findAttributeValue(this, attributeName);
|
||||
}
|
||||
|
||||
@Nullable @Override
|
||||
public PsiAnnotationMemberValue findDeclaredAttributeValue(@Nullable @NonNls String attributeName) {
|
||||
return null;
|
||||
return PsiImplUtil.findDeclaredAttributeValue(this, attributeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends PsiAnnotationMemberValue> T setDeclaredAttributeValue(@Nullable @NonNls String attributeName, @Nullable T value) {
|
||||
return null;
|
||||
public <T extends PsiAnnotationMemberValue> T setDeclaredAttributeValue(
|
||||
@Nullable @NonNls String attributeName, @Nullable T value) {
|
||||
// TODO: implement this
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiAnnotationOwner getOwner() {
|
||||
return (PsiAnnotationOwner)getParent();
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiMetaData getMetaData() {
|
||||
// I have no idea what this is
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -31,10 +31,16 @@
|
||||
|
||||
package org.jf.smalidea.psi.impl;
|
||||
|
||||
import com.intellij.psi.PsiAnnotationMemberValue;
|
||||
import com.intellij.psi.PsiNameValuePair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
|
||||
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||
|
||||
public class SmaliAnnotationElement extends SmaliCompositeElement {
|
||||
public class SmaliAnnotationElement extends SmaliCompositeElement implements PsiNameValuePair {
|
||||
// TODO: consider making this a stub
|
||||
|
||||
public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() {
|
||||
@Override public SmaliCompositeElement createElement() {
|
||||
return new SmaliAnnotationElement();
|
||||
@ -44,4 +50,31 @@ public class SmaliAnnotationElement extends SmaliCompositeElement {
|
||||
public SmaliAnnotationElement() {
|
||||
super(SmaliElementTypes.ANNOTATION_ELEMENT);
|
||||
}
|
||||
|
||||
@Override public String getName() {
|
||||
SmaliAnnotationElementName identifier = getNameIdentifier();
|
||||
if (identifier != null) {
|
||||
return identifier.getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable @Override public SmaliAnnotationElementName getNameIdentifier() {
|
||||
return findChildByClass(SmaliAnnotationElementName.class);
|
||||
}
|
||||
|
||||
@Nullable @Override public SmaliLiteral getValue() {
|
||||
// TODO: implement the various psi expression classes that would be expected in the java stuff. Is SmaliLiteral implementing PsiLiteral and PsiExpression enough? What about method/field/enum literals?
|
||||
return findChildByClass(SmaliLiteral.class);
|
||||
}
|
||||
|
||||
@NotNull @Override public PsiAnnotationMemberValue setValue(@NotNull PsiAnnotationMemberValue newValue) {
|
||||
// TODO: implement this
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable @Override public String getLiteralValue() {
|
||||
// Not applicable for smali
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.psi.PsiIdentifier;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
|
||||
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||
|
||||
public class SmaliAnnotationElementName extends SmaliCompositeElement implements PsiIdentifier {
|
||||
public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() {
|
||||
@Override public SmaliCompositeElement createElement() {
|
||||
return new SmaliAnnotationElementName();
|
||||
}
|
||||
};
|
||||
|
||||
public SmaliAnnotationElementName() {
|
||||
super(SmaliElementTypes.ANNOTATION_ELEMENT_NAME);
|
||||
}
|
||||
|
||||
@Override public IElementType getTokenType() {
|
||||
return getNode().getElementType();
|
||||
}
|
||||
|
||||
@Override public String getName() {
|
||||
return getText();
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.psi.PsiAnnotationParameterList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
|
||||
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||
|
||||
public class SmaliAnnotationParameterList extends SmaliCompositeElement implements PsiAnnotationParameterList {
|
||||
public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() {
|
||||
@Override public SmaliCompositeElement createElement() {
|
||||
return new SmaliAnnotationParameterList();
|
||||
}
|
||||
};
|
||||
|
||||
public SmaliAnnotationParameterList() {
|
||||
super(SmaliElementTypes.ANNOTATION_PARAMETER_LIST);
|
||||
}
|
||||
|
||||
@NotNull @Override public SmaliAnnotationElement[] getAttributes() {
|
||||
return findChildrenByClass(SmaliAnnotationElement.class);
|
||||
}
|
||||
}
|
@ -34,7 +34,6 @@ 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;
|
||||
@ -59,7 +58,7 @@ public abstract class SmaliBaseReferenceList<StubT extends SmaliBaseReferenceLis
|
||||
return stub.getReferencedTypes();
|
||||
}
|
||||
|
||||
SmaliClassTypeElement[] references = getSmaliReferenceElements();
|
||||
SmaliClassTypeElement[] references = getReferenceElements();
|
||||
|
||||
SmaliClassType[] referenceTypes = new SmaliClassType[references.length];
|
||||
|
||||
@ -76,7 +75,7 @@ public abstract class SmaliBaseReferenceList<StubT extends SmaliBaseReferenceLis
|
||||
return stub.getTypes();
|
||||
}
|
||||
|
||||
SmaliClassTypeElement[] references = getSmaliReferenceElements();
|
||||
SmaliClassTypeElement[] references = getReferenceElements();
|
||||
|
||||
String[] referenceNames = new String[references.length];
|
||||
|
||||
@ -90,12 +89,7 @@ public abstract class SmaliBaseReferenceList<StubT extends SmaliBaseReferenceLis
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull @Override public PsiJavaCodeReferenceElement[] getReferenceElements() {
|
||||
// Not applicable for smali
|
||||
return PsiJavaCodeReferenceElement.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@NotNull public abstract SmaliClassTypeElement[] getSmaliReferenceElements();
|
||||
@NotNull @Override public abstract SmaliClassTypeElement[] getReferenceElements();
|
||||
|
||||
protected SmaliClassTypeElement[] getImplementsElements() {
|
||||
SmaliImplementsStatement[] implementsStatements = ((SmaliClass)getParent()).getImplementsStatements();
|
||||
|
@ -33,6 +33,7 @@ package org.jf.smalidea.psi.impl;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -41,7 +42,8 @@ import org.jf.smalidea.psi.SmaliCompositeElementFactory;
|
||||
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||
import org.jf.smalidea.util.NameUtils;
|
||||
|
||||
public class SmaliClassTypeElement extends SmaliCompositeElement implements PsiTypeElement, PsiReference {
|
||||
public class SmaliClassTypeElement extends SmaliCompositeElement
|
||||
implements PsiTypeElement, PsiReference, PsiJavaCodeReferenceElement {
|
||||
public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() {
|
||||
@Override public SmaliCompositeElement createElement() {
|
||||
return new SmaliClassTypeElement();
|
||||
@ -73,9 +75,8 @@ public class SmaliClassTypeElement extends SmaliCompositeElement implements PsiT
|
||||
return NameUtils.shortNameFromQualifiedName(getCanonicalText());
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiJavaCodeReferenceElement getInnermostComponentReferenceElement() {
|
||||
// Not applicable for smali
|
||||
return null;
|
||||
@Nullable @Override public SmaliClassTypeElement getInnermostComponentReferenceElement() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public PsiElement getElement() {
|
||||
@ -142,4 +143,55 @@ public class SmaliClassTypeElement extends SmaliCompositeElement implements PsiT
|
||||
@NotNull @Override public PsiAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// Below are the PsiJavaCodeReferenceElement-specific methods
|
||||
|
||||
@Override public void processVariants(@NotNull PsiScopeProcessor processor) {
|
||||
// TODO: maybe just do nothing?
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiElement getReferenceNameElement() {
|
||||
// TODO: implement if needed
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiReferenceParameterList getParameterList() {
|
||||
// TODO: (generics) implement this
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull @Override public PsiType[] getTypeParameters() {
|
||||
// TODO: (generics) implement this
|
||||
return new PsiType[0];
|
||||
}
|
||||
|
||||
@Override public boolean isQualified() {
|
||||
// TODO: should this return false for classes in the top level package?
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public String getQualifiedName() {
|
||||
return getCanonicalText();
|
||||
}
|
||||
|
||||
@NotNull @Override public JavaResolveResult advancedResolve(boolean incompleteCode) {
|
||||
// TODO: implement this if needed
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull @Override public JavaResolveResult[] multiResolve(boolean incompleteCode) {
|
||||
// TODO: implement this if needed
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable @Override public PsiElement getQualifier() {
|
||||
// TODO: implement this if needed
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Nullable @Override public String getReferenceName() {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public class SmaliExtendsList extends SmaliBaseReferenceList<SmaliExtendsListStu
|
||||
super(node);
|
||||
}
|
||||
|
||||
@NotNull @Override public SmaliClassTypeElement[] getSmaliReferenceElements() {
|
||||
@NotNull @Override public SmaliClassTypeElement[] getReferenceElements() {
|
||||
if (((SmaliClass)getParent()).isInterface()) {
|
||||
return getImplementsElements();
|
||||
} else {
|
||||
|
@ -45,7 +45,7 @@ public class SmaliImplementsList extends SmaliBaseReferenceList<SmaliImplementsL
|
||||
super(node);
|
||||
}
|
||||
|
||||
@NotNull @Override public SmaliClassTypeElement[] getSmaliReferenceElements() {
|
||||
@NotNull @Override public SmaliClassTypeElement[] getReferenceElements() {
|
||||
if (!((SmaliClass)getParent()).isInterface()) {
|
||||
return getImplementsElements();
|
||||
}
|
||||
|
@ -31,10 +31,11 @@
|
||||
|
||||
package org.jf.smalidea.psi.impl;
|
||||
|
||||
import com.intellij.psi.PsiAnnotationMemberValue;
|
||||
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
|
||||
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||
|
||||
public class SmaliLiteral extends SmaliCompositeElement {
|
||||
public class SmaliLiteral extends SmaliCompositeElement implements PsiAnnotationMemberValue {
|
||||
public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() {
|
||||
@Override public SmaliCompositeElement createElement() {
|
||||
return new SmaliLiteral();
|
||||
|
@ -33,11 +33,21 @@ package org.jf.smalidea.psi.stub;
|
||||
|
||||
import com.intellij.psi.stubs.StubBase;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||
import org.jf.smalidea.psi.impl.SmaliAnnotation;
|
||||
|
||||
public class SmaliAnnotationStub extends StubBase<SmaliAnnotation> {
|
||||
public SmaliAnnotationStub(StubElement parent) {
|
||||
@Nullable
|
||||
private final String annotationType;
|
||||
|
||||
public SmaliAnnotationStub(StubElement parent, @Nullable String annotationType) {
|
||||
super(parent, SmaliElementTypes.ANNOTATION);
|
||||
this.annotationType = annotationType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getAnnotationType() {
|
||||
return annotationType;
|
||||
}
|
||||
}
|
||||
|
@ -62,16 +62,17 @@ public class SmaliAnnotationElementType extends SmaliStubElementType<SmaliAnnota
|
||||
}
|
||||
|
||||
@Override public SmaliAnnotationStub createStub(@NotNull SmaliAnnotation psi, StubElement parentStub) {
|
||||
return new SmaliAnnotationStub(parentStub);
|
||||
return new SmaliAnnotationStub(parentStub, psi.getQualifiedName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(@NotNull SmaliAnnotationStub stub, @NotNull StubOutputStream dataStream) throws IOException {
|
||||
dataStream.writeName(stub.getAnnotationType());
|
||||
}
|
||||
|
||||
@NotNull @Override
|
||||
public SmaliAnnotationStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
|
||||
return new SmaliAnnotationStub(parentStub);
|
||||
return new SmaliAnnotationStub(parentStub, dataStream.readName().getString());
|
||||
}
|
||||
|
||||
@Override public void indexStub(@NotNull SmaliAnnotationStub stub, @NotNull IndexSink sink) {
|
||||
|
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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.PsiAnnotationMemberValue;
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import junit.framework.Assert;
|
||||
import org.jf.smalidea.psi.impl.SmaliAnnotation;
|
||||
import org.jf.smalidea.psi.impl.SmaliAnnotationParameterList;
|
||||
import org.jf.smalidea.psi.impl.SmaliClass;
|
||||
import org.jf.smalidea.psi.impl.SmaliFile;
|
||||
|
||||
public class SmaliClassAnnotationTest extends LightCodeInsightFixtureTestCase {
|
||||
// TODO: test default values
|
||||
|
||||
public void testClassAnnotation() {
|
||||
myFixture.addFileToProject("my/TestAnnotation.smali",
|
||||
".class public interface abstract annotation Lmy/TestAnnotation;\n" +
|
||||
".super Ljava/lang/Object;\n" +
|
||||
".implements Ljava/lang/annotation/Annotation;\n" +
|
||||
"\n" +
|
||||
".method public abstract testBooleanValue()Z\n" +
|
||||
".end method\n" +
|
||||
"\n" +
|
||||
".method public abstract testStringArrayValue()[Ljava/lang/String;\n" +
|
||||
".end method\n" +
|
||||
"\n" +
|
||||
".method public abstract testStringValue()Ljava/lang/String;\n" +
|
||||
".end method");
|
||||
|
||||
myFixture.addFileToProject("my/TestAnnotation2.smali",
|
||||
".class public interface abstract annotation Lmy/TestAnnotation2;\n" +
|
||||
".super Ljava/lang/Object;\n" +
|
||||
".implements Ljava/lang/annotation/Annotation;\n");
|
||||
|
||||
SmaliFile file = (SmaliFile)myFixture.addFileToProject("my/pkg/blah.smali",
|
||||
".class public Lmy/pkg/blah; .super Ljava/lang/Object;\n" +
|
||||
"\n" +
|
||||
".annotation runtime Lmy/TestAnnotation;\n" +
|
||||
" testBooleanValue = true\n" +
|
||||
" testStringValue = \"blah\"\n" +
|
||||
" testStringArrayValue = {\n" +
|
||||
" \"blah1\",\n" +
|
||||
" \"blah2\"\n" +
|
||||
" }\n" +
|
||||
".end annotation\n" +
|
||||
"\n" +
|
||||
".annotation runtime Lmy/TestAnnotation2;\n" +
|
||||
".end annotation");
|
||||
|
||||
SmaliClass smaliClass = file.getPsiClass();
|
||||
Assert.assertEquals("my.pkg.blah", smaliClass.getQualifiedName());
|
||||
|
||||
Assert.assertEquals(2, smaliClass.getAnnotations().length);
|
||||
|
||||
Assert.assertEquals("my.TestAnnotation", smaliClass.getAnnotations()[0].getQualifiedName());
|
||||
PsiJavaCodeReferenceElement annotationNameRef = smaliClass.getAnnotations()[0].getNameReferenceElement();
|
||||
Assert.assertNotNull(annotationNameRef);
|
||||
SmaliClass smaliAnnotationClass = (SmaliClass)annotationNameRef.resolve();
|
||||
Assert.assertNotNull(smaliAnnotationClass);
|
||||
Assert.assertEquals("my.TestAnnotation", smaliAnnotationClass.getQualifiedName());
|
||||
|
||||
Assert.assertEquals("my.TestAnnotation2", smaliClass.getAnnotations()[1].getQualifiedName());
|
||||
annotationNameRef = smaliClass.getAnnotations()[1].getNameReferenceElement();
|
||||
Assert.assertNotNull(annotationNameRef);
|
||||
smaliAnnotationClass = (SmaliClass)annotationNameRef.resolve();
|
||||
Assert.assertNotNull(smaliAnnotationClass);
|
||||
Assert.assertEquals("my.TestAnnotation2", smaliAnnotationClass.getQualifiedName());
|
||||
|
||||
SmaliAnnotation smaliAnnotation = smaliClass.findAnnotation("my.TestAnnotation");
|
||||
Assert.assertNotNull(smaliAnnotation);
|
||||
Assert.assertEquals("my.TestAnnotation", smaliAnnotation.getQualifiedName());
|
||||
SmaliClass owner = (SmaliClass)smaliAnnotation.getOwner();
|
||||
Assert.assertNotNull(owner);
|
||||
Assert.assertEquals("my.pkg.blah", owner.getQualifiedName());
|
||||
annotationNameRef = smaliAnnotation.getNameReferenceElement();
|
||||
Assert.assertNotNull(annotationNameRef);
|
||||
smaliAnnotationClass = (SmaliClass)annotationNameRef.resolve();
|
||||
Assert.assertNotNull(smaliAnnotationClass);
|
||||
Assert.assertEquals("my.TestAnnotation", smaliAnnotationClass.getQualifiedName());
|
||||
|
||||
SmaliAnnotationParameterList parameterList = smaliAnnotation.getParameterList();
|
||||
Assert.assertNotNull(parameterList);
|
||||
Assert.assertEquals(3, parameterList.getAttributes().length);
|
||||
Assert.assertEquals("testBooleanValue", parameterList.getAttributes()[0].getName());
|
||||
PsiAnnotationMemberValue value = parameterList.getAttributes()[0].getValue();
|
||||
Assert.assertNotNull(value);
|
||||
// TODO: test the values rather than the text
|
||||
Assert.assertEquals("true", value.getText());
|
||||
Assert.assertEquals("testStringValue", parameterList.getAttributes()[1].getName());
|
||||
value = parameterList.getAttributes()[1].getValue();
|
||||
Assert.assertNotNull(value);
|
||||
Assert.assertEquals("\"blah\"", value.getText());
|
||||
Assert.assertEquals("testStringArrayValue", parameterList.getAttributes()[2].getName());
|
||||
value = parameterList.getAttributes()[2].getValue();
|
||||
Assert.assertNotNull(value);
|
||||
// TODO: test the individual values, once the array literal stuff is implemented
|
||||
|
||||
value = smaliAnnotation.findAttributeValue("testBooleanValue");
|
||||
Assert.assertNotNull(value);
|
||||
Assert.assertEquals("true", value.getText());
|
||||
|
||||
value = smaliAnnotation.findAttributeValue("testStringValue");
|
||||
Assert.assertNotNull(value);
|
||||
Assert.assertEquals("\"blah\"", value.getText());
|
||||
|
||||
value = smaliAnnotation.findAttributeValue("testStringArrayValue");
|
||||
Assert.assertNotNull(value);
|
||||
|
||||
// TODO: test findAttributeValue vs findDeclaredAttributeValue for default values
|
||||
|
||||
smaliAnnotation = smaliClass.findAnnotation("my.TestAnnotation2");
|
||||
Assert.assertNotNull(smaliAnnotation);
|
||||
Assert.assertEquals("my.TestAnnotation2", smaliAnnotation.getQualifiedName());
|
||||
owner = (SmaliClass)smaliAnnotation.getOwner();
|
||||
Assert.assertNotNull(owner);
|
||||
Assert.assertEquals("my.pkg.blah", owner.getQualifiedName());
|
||||
annotationNameRef = smaliAnnotation.getNameReferenceElement();
|
||||
Assert.assertNotNull(annotationNameRef);
|
||||
smaliAnnotationClass = (SmaliClass)annotationNameRef.resolve();
|
||||
Assert.assertNotNull(smaliAnnotationClass);
|
||||
Assert.assertEquals("my.TestAnnotation2", smaliAnnotationClass.getQualifiedName());
|
||||
|
||||
parameterList = smaliAnnotation.getParameterList();
|
||||
Assert.assertNotNull(parameterList);
|
||||
Assert.assertEquals(0, parameterList.getAttributes().length);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user