Improve how the field annotations/end field thing is parsed

This commit is contained in:
Ben Gruver 2015-02-20 20:03:45 -08:00
parent d5b748f4f5
commit 01f8c7dc7b
6 changed files with 145 additions and 12 deletions

View File

@ -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)=> (
{ annotationsMarker = mark(); }
((ANNOTATION_DIRECTIVE)=> annotation)+
(end_field_directive {classAnnotations = false;})?
)
| /*epsilon*/
)
)?
( 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);

View File

@ -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); }

View File

@ -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

View File

@ -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')

View File

@ -0,0 +1,3 @@
.field public public:I
.blah
.end field

View File

@ -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')