From 01f8c7dc7bf71a5a28d51589f2845d9d65936275 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Fri, 20 Feb 2015 20:03:45 -0800 Subject: [PATCH] Improve how the field annotations/end field thing is parsed --- smalidea/src/main/antlr3/smalideaParser.g | 24 ++--- .../test/java/org/jf/smalidea/ParserTest.java | 2 + smalidea/testData/FieldAnnotations.smalidea | 15 +++ smalidea/testData/FieldAnnotations.txt | 91 +++++++++++++++++++ smalidea/testData/InvalidField3.smalidea | 3 + smalidea/testData/InvalidField3.txt | 22 +++++ 6 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 smalidea/testData/FieldAnnotations.smalidea create mode 100644 smalidea/testData/FieldAnnotations.txt create mode 100644 smalidea/testData/InvalidField3.smalidea create mode 100644 smalidea/testData/InvalidField3.txt diff --git a/smalidea/src/main/antlr3/smalideaParser.g b/smalidea/src/main/antlr3/smalideaParser.g index 934291f0..c278ac23 100644 --- a/smalidea/src/main/antlr3/smalideaParser.g +++ b/smalidea/src/main/antlr3/smalideaParser.g @@ -262,27 +262,27 @@ field @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 0a2c20a6..6a3dc8c6 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 class ParserTest extends LightCodeInsightParsingTestCase { } 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 00000000..37167693 --- /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 00000000..80332e59 --- /dev/null +++ b/smalidea/testData/FieldAnnotations.txt @@ -0,0 +1,91 @@ +smali.FILE + SmaliClass(CLASS) + SmaliExtendsList(EXTENDS_LIST) + + SmaliImplementsList(IMPLEMENTS_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) + + 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) + + 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) + + 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) + + 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 00000000..9de31427 --- /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 00000000..508df467 --- /dev/null +++ b/smalidea/testData/InvalidField3.txt @@ -0,0 +1,22 @@ +smali.FILE + SmaliClass(CLASS) + SmaliExtendsList(EXTENDS_LIST) + + SmaliImplementsList(IMPLEMENTS_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