Improve how the field annotations/end field thing is parsed
diff --git a/smalidea/src/main/antlr3/smalideaParser.g b/smalidea/src/main/antlr3/smalideaParser.g
index 934291f..c278ac2 100644
--- a/smalidea/src/main/antlr3/smalideaParser.g
+++ b/smalidea/src/main/antlr3/smalideaParser.g
@@ -262,27 +262,27 @@
@init {
Marker marker = mark();
Marker annotationsMarker = null;
- boolean classAnnotations = true;
+ boolean gotEndField = false;
}
: FIELD_DIRECTIVE
access_list
member_name colon nonvoid_type_descriptor
field_initializer?
- ( end_field_directive
- | (ANNOTATION_DIRECTIVE)=> ( {annotationsMarker = mark();}
- ((ANNOTATION_DIRECTIVE)=> annotation)+
- (end_field_directive {classAnnotations = false;})?
- )
- | /*epsilon*/
- )
+ (
+ (ANNOTATION_DIRECTIVE)=> (
+ { annotationsMarker = mark(); }
+ ((ANNOTATION_DIRECTIVE)=> annotation)+
+ )
+ )?
+ ( end_field_directive { gotEndField = true; } )?
{
if (annotationsMarker != null) {
- if (classAnnotations) {
- marker.doneBefore(SmaliElementTypes.FIELD, annotationsMarker);
- annotationsMarker.drop();
- } else {
+ if (gotEndField) {
annotationsMarker.drop();
marker.done(SmaliElementTypes.FIELD);
+ } else {
+ marker.doneBefore(SmaliElementTypes.FIELD, annotationsMarker);
+ annotationsMarker.drop();
}
} else {
marker.done(SmaliElementTypes.FIELD);
diff --git a/smalidea/src/test/java/org/jf/smalidea/ParserTest.java b/smalidea/src/test/java/org/jf/smalidea/ParserTest.java
index 0a2c20a..6a3dc8c 100644
--- a/smalidea/src/test/java/org/jf/smalidea/ParserTest.java
+++ b/smalidea/src/test/java/org/jf/smalidea/ParserTest.java
@@ -42,11 +42,13 @@
}
public void testEmpty() throws Exception { doTest(true); }
+ public void testFieldAnnotations() throws Exception { doTest(true); }
public void testInvalidClassDirective() throws Exception { doTest(true); }
public void testInvalidClassDirective2() throws Exception { doTest(true); }
public void testInvalidClassDirective3() throws Exception { doTest(true); }
public void testInvalidField() throws Exception { doTest(true); }
public void testInvalidField2() throws Exception { doTest(true); }
+ public void testInvalidField3() throws Exception { doTest(true); }
public void testParamListInvalidParameter() throws Exception { doTest(true); }
public void testSuperClassInvalidSyntax() throws Exception { doTest(true); }
public void testSuperClassInvalidSyntax2() throws Exception { doTest(true); }
diff --git a/smalidea/testData/FieldAnnotations.smalidea b/smalidea/testData/FieldAnnotations.smalidea
new file mode 100644
index 0000000..3716769
--- /dev/null
+++ b/smalidea/testData/FieldAnnotations.smalidea
@@ -0,0 +1,15 @@
+.field public blah:I
+
+.field public blah2:I
+ .annotation runtime Lblah;
+ .end annotation
+ .annotation runtime Lblah;
+ .end annotation
+.end field
+
+.field public blah2:I
+
+.annotation runtime Lblah;
+.end annotation
+.annotation runtime Lblah;
+.end annotation
diff --git a/smalidea/testData/FieldAnnotations.txt b/smalidea/testData/FieldAnnotations.txt
new file mode 100644
index 0000000..80332e5
--- /dev/null
+++ b/smalidea/testData/FieldAnnotations.txt
@@ -0,0 +1,91 @@
+smali.FILE
+ SmaliClass(CLASS)
+ SmaliExtendsList(EXTENDS_LIST)
+ <empty list>
+ SmaliImplementsList(IMPLEMENTS_LIST)
+ <empty list>
+ SmaliField(FIELD)
+ PsiElement(FIELD_DIRECTIVE)('.field')
+ PsiWhiteSpace(' ')
+ SmaliModifierList(MODIFIER_LIST)
+ PsiElement(ACCESS_SPEC)('public')
+ PsiWhiteSpace(' ')
+ PsiElement(MEMBER_NAME)
+ PsiElement(SIMPLE_NAME)('blah')
+ PsiElement(COLON)(':')
+ PsiElement(PRIMITIVE_TYPE)
+ PsiElement(PRIMITIVE_TYPE)('I')
+ PsiWhiteSpace('\n\n')
+ SmaliField(FIELD)
+ PsiElement(FIELD_DIRECTIVE)('.field')
+ PsiWhiteSpace(' ')
+ SmaliModifierList(MODIFIER_LIST)
+ PsiElement(ACCESS_SPEC)('public')
+ PsiWhiteSpace(' ')
+ PsiElement(MEMBER_NAME)
+ PsiElement(SIMPLE_NAME)('blah2')
+ PsiElement(COLON)(':')
+ PsiElement(PRIMITIVE_TYPE)
+ PsiElement(PRIMITIVE_TYPE)('I')
+ PsiWhiteSpace('\n ')
+ SmaliAnnotation(ANNOTATION)
+ PsiElement(ANNOTATION_DIRECTIVE)('.annotation')
+ PsiWhiteSpace(' ')
+ PsiElement(ANNOTATION_VISIBILITY)('runtime')
+ PsiWhiteSpace(' ')
+ PsiElement(CLASS_TYPE)
+ PsiElement(CLASS_DESCRIPTOR)('Lblah;')
+ PsiWhiteSpace('\n ')
+ PsiElement(ANNOTATION_PARAMETER_LIST)
+ <empty list>
+ PsiElement(END_ANNOTATION_DIRECTIVE)('.end annotation')
+ PsiWhiteSpace('\n ')
+ SmaliAnnotation(ANNOTATION)
+ PsiElement(ANNOTATION_DIRECTIVE)('.annotation')
+ PsiWhiteSpace(' ')
+ PsiElement(ANNOTATION_VISIBILITY)('runtime')
+ PsiWhiteSpace(' ')
+ PsiElement(CLASS_TYPE)
+ PsiElement(CLASS_DESCRIPTOR)('Lblah;')
+ PsiWhiteSpace('\n ')
+ PsiElement(ANNOTATION_PARAMETER_LIST)
+ <empty list>
+ PsiElement(END_ANNOTATION_DIRECTIVE)('.end annotation')
+ PsiWhiteSpace('\n')
+ PsiElement(END_FIELD_DIRECTIVE)('.end field')
+ PsiWhiteSpace('\n\n')
+ SmaliField(FIELD)
+ PsiElement(FIELD_DIRECTIVE)('.field')
+ PsiWhiteSpace(' ')
+ SmaliModifierList(MODIFIER_LIST)
+ PsiElement(ACCESS_SPEC)('public')
+ PsiWhiteSpace(' ')
+ PsiElement(MEMBER_NAME)
+ PsiElement(SIMPLE_NAME)('blah2')
+ PsiElement(COLON)(':')
+ PsiElement(PRIMITIVE_TYPE)
+ PsiElement(PRIMITIVE_TYPE)('I')
+ PsiWhiteSpace('\n\n')
+ SmaliAnnotation(ANNOTATION)
+ PsiElement(ANNOTATION_DIRECTIVE)('.annotation')
+ PsiWhiteSpace(' ')
+ PsiElement(ANNOTATION_VISIBILITY)('runtime')
+ PsiWhiteSpace(' ')
+ PsiElement(CLASS_TYPE)
+ PsiElement(CLASS_DESCRIPTOR)('Lblah;')
+ PsiWhiteSpace('\n')
+ PsiElement(ANNOTATION_PARAMETER_LIST)
+ <empty list>
+ PsiElement(END_ANNOTATION_DIRECTIVE)('.end annotation')
+ PsiWhiteSpace('\n')
+ SmaliAnnotation(ANNOTATION)
+ PsiElement(ANNOTATION_DIRECTIVE)('.annotation')
+ PsiWhiteSpace(' ')
+ PsiElement(ANNOTATION_VISIBILITY)('runtime')
+ PsiWhiteSpace(' ')
+ PsiElement(CLASS_TYPE)
+ PsiElement(CLASS_DESCRIPTOR)('Lblah;')
+ PsiWhiteSpace('\n')
+ PsiElement(ANNOTATION_PARAMETER_LIST)
+ <empty list>
+ PsiElement(END_ANNOTATION_DIRECTIVE)('.end annotation')
\ No newline at end of file
diff --git a/smalidea/testData/InvalidField3.smalidea b/smalidea/testData/InvalidField3.smalidea
new file mode 100644
index 0000000..9de3142
--- /dev/null
+++ b/smalidea/testData/InvalidField3.smalidea
@@ -0,0 +1,3 @@
+.field public public:I
+.blah
+.end field
\ No newline at end of file
diff --git a/smalidea/testData/InvalidField3.txt b/smalidea/testData/InvalidField3.txt
new file mode 100644
index 0000000..508df46
--- /dev/null
+++ b/smalidea/testData/InvalidField3.txt
@@ -0,0 +1,22 @@
+smali.FILE
+ SmaliClass(CLASS)
+ SmaliExtendsList(EXTENDS_LIST)
+ <empty list>
+ SmaliImplementsList(IMPLEMENTS_LIST)
+ <empty list>
+ SmaliField(FIELD)
+ PsiElement(FIELD_DIRECTIVE)('.field')
+ PsiWhiteSpace(' ')
+ SmaliModifierList(MODIFIER_LIST)
+ PsiElement(ACCESS_SPEC)('public')
+ PsiWhiteSpace(' ')
+ PsiElement(MEMBER_NAME)
+ PsiElement(ACCESS_SPEC)('public')
+ PsiElement(COLON)(':')
+ PsiElement(PRIMITIVE_TYPE)
+ PsiElement(PRIMITIVE_TYPE)('I')
+ PsiWhiteSpace('\n')
+ PsiErrorElement:Unexpected tokens
+ PsiElement(BAD_CHARACTER)('.blah')
+ PsiWhiteSpace('\n')
+ PsiElement(END_FIELD_DIRECTIVE)('.end field')
\ No newline at end of file