aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gruver <bgruv@google.com>2015-03-14 12:26:15 -0700
committerBen Gruver <bgruv@google.com>2015-03-14 12:34:04 -0700
commit44a0c9091ff58228a57bcd5ae5c0eceb8d223f36 (patch)
tree10d10620ddd01f5bd19768859eb804f526f394f7
parent87f3e0dc7b8b4870c948ae944c4579198c714bbb (diff)
downloadsmali-44a0c9091ff58228a57bcd5ae5c0eceb8d223f36.tar.gz
Implement PsiAnnotationMethod in SmaliMethod
-rw-r--r--smalidea/src/main/antlr3/smalideaParser.g13
-rw-r--r--smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotationElement.java20
-rw-r--r--smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethod.java27
-rw-r--r--smalidea/src/test/java/org/jf/smalidea/SmaliAnnotationTest.java27
-rw-r--r--smalidea/testData/InvalidAnnotation.txt19
5 files changed, 89 insertions, 17 deletions
diff --git a/smalidea/src/main/antlr3/smalideaParser.g b/smalidea/src/main/antlr3/smalideaParser.g
index b2690cfe..ac7192d5 100644
--- a/smalidea/src/main/antlr3/smalideaParser.g
+++ b/smalidea/src/main/antlr3/smalideaParser.g
@@ -718,9 +718,16 @@ type_field_method_literal
}
subannotation
- @init { Marker marker = mark(); }
- : SUBANNOTATION_DIRECTIVE class_descriptor annotation_element* end_subannotation_directive
- { marker.done(SmaliElementTypes.LITERAL); };
+ @init {
+ Marker marker = mark();
+ Marker paramListMarker = null;
+ }
+ : SUBANNOTATION_DIRECTIVE class_descriptor
+ { paramListMarker = mark(); }
+ annotation_element*
+ { paramListMarker.done(SmaliElementTypes.ANNOTATION_PARAMETER_LIST); }
+ end_subannotation_directive
+ { marker.done(SmaliElementTypes.ANNOTATION); };
catch [RecognitionException re] {
recover(input, re);
reportError(marker, re, false);
diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotationElement.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotationElement.java
index 6137af0b..10784f8f 100644
--- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotationElement.java
+++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliAnnotationElement.java
@@ -31,10 +31,13 @@
package org.jf.smalidea.psi.impl;
+import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiAnnotationMemberValue;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNameValuePair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jf.smalidea.SmaliTokens;
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
import org.jf.smalidea.psi.SmaliElementTypes;
@@ -63,9 +66,20 @@ public class SmaliAnnotationElement extends SmaliCompositeElement implements Psi
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);
+ @Nullable @Override public PsiAnnotationMemberValue getValue() {
+ ASTNode equalNode = findChildByType(SmaliTokens.EQUAL);
+ if (equalNode == null) {
+ return null;
+ }
+
+ PsiElement nextElement = equalNode.getPsi().getNextSibling();
+ while (nextElement != null) {
+ if (nextElement instanceof PsiAnnotationMemberValue) {
+ return (PsiAnnotationMemberValue)nextElement;
+ }
+ nextElement = nextElement.getNextSibling();
+ }
+ return null;
}
@NotNull @Override public PsiAnnotationMemberValue setValue(@NotNull PsiAnnotationMemberValue newValue) {
diff --git a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethod.java b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethod.java
index 400e509c..a2894f6d 100644
--- a/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethod.java
+++ b/smalidea/src/main/java/org/jf/smalidea/psi/impl/SmaliMethod.java
@@ -62,7 +62,7 @@ import java.util.List;
import java.util.Map;
public class SmaliMethod extends SmaliStubBasedPsiElement<SmaliMethodStub>
- implements PsiMethod, SmaliModifierListOwner {
+ implements PsiMethod, SmaliModifierListOwner, PsiAnnotationMethod {
public SmaliMethod(@NotNull SmaliMethodStub stub) {
super(stub, SmaliElementTypes.METHOD);
}
@@ -252,7 +252,7 @@ public class SmaliMethod extends SmaliStubBasedPsiElement<SmaliMethodStub>
return new PsiTypeParameter[0];
}
- @Nullable @Override public PsiClass getContainingClass() {
+ @Nullable @Override public SmaliClass getContainingClass() {
return (SmaliClass)getStubOrPsiParent();
}
@@ -330,4 +330,27 @@ public class SmaliMethod extends SmaliStubBasedPsiElement<SmaliMethodStub>
}
return super.getTextOffset();
}
+
+ @Nullable @Override public PsiAnnotationMemberValue getDefaultValue() {
+ SmaliClass containingClass = getContainingClass();
+ if (containingClass == null || !containingClass.isAnnotationType()) {
+ return null;
+ }
+
+ for (SmaliAnnotation annotation: containingClass.getAnnotations()) {
+ String annotationType = annotation.getQualifiedName();
+ if (annotationType == null) {
+ continue;
+ }
+ if (annotationType.equals("dalvik.annotation.AnnotationDefault")) {
+ PsiAnnotationMemberValue value = annotation.findAttributeValue("value");
+ if (!(value instanceof SmaliAnnotation)) {
+ return null;
+ }
+ SmaliAnnotation valueSubAnnotation = (SmaliAnnotation)value;
+ return valueSubAnnotation.findAttributeValue(getName());
+ }
+ }
+ return null;
+ }
}
diff --git a/smalidea/src/test/java/org/jf/smalidea/SmaliAnnotationTest.java b/smalidea/src/test/java/org/jf/smalidea/SmaliAnnotationTest.java
index c8744829..3cd863f9 100644
--- a/smalidea/src/test/java/org/jf/smalidea/SmaliAnnotationTest.java
+++ b/smalidea/src/test/java/org/jf/smalidea/SmaliAnnotationTest.java
@@ -35,6 +35,7 @@ import com.intellij.psi.*;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jf.smalidea.psi.impl.SmaliClass;
import org.jf.smalidea.psi.impl.SmaliFile;
+import org.jf.smalidea.psi.impl.SmaliLiteral;
import org.jf.smalidea.psi.impl.SmaliMethod;
import org.junit.Assert;
@@ -243,4 +244,30 @@ public class SmaliAnnotationTest extends LightCodeInsightFixtureTestCase {
Assert.assertNotNull(parameterList);
Assert.assertEquals(0, parameterList.getAttributes().length);
}
+
+ public void testDefaultValue() {
+ SmaliFile file = (SmaliFile)myFixture.addFileToProject("AnnotationWithDefaultValue.smali", "" +
+ ".class public abstract interface annotation LAnnotationWithValues;\n" +
+ ".super Ljava/lang/Object;\n" +
+ ".implements Ljava/lang/annotation/Annotation;\n" +
+ "\n" +
+ ".method public abstract intValue()I\n" +
+ ".end method\n" +
+ "\n" +
+ ".annotation system Ldalvik/annotation/AnnotationDefault;\n" +
+ " value = .subannotation LAnnotationWithValues;\n" +
+ " intValue = 4\n" +
+ " .end subannotation\n" +
+ ".end annotation\n" +
+ "\n");
+
+ SmaliClass smaliClass = file.getPsiClass();
+ Assert.assertNotNull(smaliClass);
+ SmaliMethod method = smaliClass.getMethods()[0];
+ Assert.assertEquals("intValue", method.getName());
+
+ PsiAnnotationMemberValue defaultValue = method.getDefaultValue();
+ Assert.assertTrue(defaultValue instanceof SmaliLiteral);
+ Assert.assertEquals(4, ((SmaliLiteral)defaultValue).getIntegralValue());
+ }
}
diff --git a/smalidea/testData/InvalidAnnotation.txt b/smalidea/testData/InvalidAnnotation.txt
index ad6aca78..3799410f 100644
--- a/smalidea/testData/InvalidAnnotation.txt
+++ b/smalidea/testData/InvalidAnnotation.txt
@@ -86,20 +86,21 @@ smali.FILE
PsiWhiteSpace(' ')
PsiElement(EQUAL)('=')
PsiWhiteSpace(' ')
- PsiElement(LITERAL)
+ SmaliAnnotation(ANNOTATION)
PsiElement(SUBANNOTATION_DIRECTIVE)('.subannotation')
PsiWhiteSpace(' ')
PsiElement(CLASS_TYPE)
PsiElement(CLASS_DESCRIPTOR)('Lblah2;')
PsiWhiteSpace('\n ')
- PsiElement(ANNOTATION_ELEMENT)
- PsiElement(ANNOTATION_ELEMENT_NAME)
- PsiElement(SIMPLE_NAME)('blah')
- PsiWhiteSpace(' ')
- PsiElement(EQUAL)('=')
- PsiWhiteSpace(' ')
- PsiElement(LITERAL)
- PsiElement(STRING_LITERAL)('"blah"')
+ PsiElement(ANNOTATION_PARAMETER_LIST)
+ PsiElement(ANNOTATION_ELEMENT)
+ PsiElement(ANNOTATION_ELEMENT_NAME)
+ PsiElement(SIMPLE_NAME)('blah')
+ PsiWhiteSpace(' ')
+ PsiElement(EQUAL)('=')
+ PsiWhiteSpace(' ')
+ PsiElement(LITERAL)
+ PsiElement(STRING_LITERAL)('"blah"')
PsiWhiteSpace('\n ')
PsiErrorElement:mismatched input '.blah' expecting END_SUBANNOTATION_DIRECTIVE
PsiElement(BAD_CHARACTER)('.blah')