Improve error recovery for missing .. tokens

This commit is contained in:
Ben Gruver 2015-03-05 20:24:55 -08:00
parent 765f8d8a7d
commit bdbb235c6f
4 changed files with 147 additions and 3 deletions

View File

@ -476,6 +476,14 @@ colon
reportError(errorMarker, re, false); reportError(errorMarker, re, false);
} }
dotdot
: DOTDOT;
catch [RecognitionException re] {
Marker errorMarker = mark();
recover(input, re);
reportError(errorMarker, re, false);
}
param_list_inner param_list_inner
: param+; : param+;
catch [RecognitionException re] { catch [RecognitionException re] {
@ -885,14 +893,14 @@ register_list
: open_brace (register (comma register)*)? close_brace; : open_brace (register (comma register)*)? close_brace;
register_range register_range
: open_brace (register (DOTDOT register)?)? close_brace; : open_brace (register (dotdot register)?)? close_brace;
verification_error_reference verification_error_reference
: class_descriptor | fully_qualified_field | fully_qualified_method; : class_descriptor | fully_qualified_field | fully_qualified_method;
catch_directive catch_directive
@init { Marker marker = mark(); } @init { Marker marker = mark(); }
: CATCH_DIRECTIVE nonvoid_type_descriptor open_brace label_ref DOTDOT label_ref close_brace label_ref : CATCH_DIRECTIVE nonvoid_type_descriptor open_brace label_ref dotdot label_ref close_brace label_ref
{ marker.done(SmaliElementTypes.CATCH_STATEMENT); }; { marker.done(SmaliElementTypes.CATCH_STATEMENT); };
catch [RecognitionException re] { catch [RecognitionException re] {
recover(input, re); recover(input, re);
@ -901,7 +909,7 @@ catch_directive
catchall_directive catchall_directive
@init { Marker marker = mark(); } @init { Marker marker = mark(); }
: CATCHALL_DIRECTIVE open_brace label_ref DOTDOT label_ref close_brace label_ref : CATCHALL_DIRECTIVE open_brace label_ref dotdot label_ref close_brace label_ref
{ marker.done(SmaliElementTypes.CATCH_ALL_STATEMENT); }; { marker.done(SmaliElementTypes.CATCH_ALL_STATEMENT); };
catch [RecognitionException re] { catch [RecognitionException re] {
recover(input, re); recover(input, re);

View File

@ -61,4 +61,5 @@ public class ParserTest extends LightCodeInsightParsingTestCase {
public void testInvalidMethod2() throws Exception { doTest(true); } public void testInvalidMethod2() throws Exception { doTest(true); }
public void testInvalidMethod3() throws Exception { doTest(true); } public void testInvalidMethod3() throws Exception { doTest(true); }
public void testInvalidMethod4() throws Exception { doTest(true); } public void testInvalidMethod4() throws Exception { doTest(true); }
public void testMissingDotDot() throws Exception { doTest(true); }
} }

View File

@ -0,0 +1,9 @@
.method public blah()V
invoke-virtual/range {v0 v1}, Lblah;->blah()V
invoke-virtual/range {v0 .blah v1}, Lblah;->blah()V
.catch Ljava/lang/Exception; { :blah1 :blah2 } :blah3
.catch Ljava/lang/Exception; { :blah1 .blah :blah2 } :blah3
.end method

View File

@ -0,0 +1,126 @@
smali.FILE
SmaliClass(CLASS)
SmaliExtendsList(EXTENDS_LIST)
<empty list>
SmaliImplementsList(IMPLEMENTS_LIST)
<empty list>
SmaliMethod(METHOD)
SmaliThrowsList(THROWS_LIST)
<empty list>
PsiElement(METHOD_DIRECTIVE)('.method')
PsiWhiteSpace(' ')
SmaliModifierList(MODIFIER_LIST)
PsiElement(ACCESS_SPEC)('public')
PsiWhiteSpace(' ')
PsiElement(MEMBER_NAME)
PsiElement(SIMPLE_NAME)('blah')
SmaliMethodPrototype(METHOD_PROTOTYPE)
PsiElement(OPEN_PAREN)('(')
SmaliMethodParamList(METHOD_PARAM_LIST)
<empty list>
PsiElement(CLOSE_PAREN)(')')
PsiElement(VOID_TYPE)
PsiElement(VOID_TYPE)('V')
PsiWhiteSpace('\n ')
PsiElement(INSTRUCTION)
PsiElement(INSTRUCTION_FORMAT3rc_METHOD)('invoke-virtual/range')
PsiWhiteSpace(' ')
PsiElement(OPEN_BRACE)('{')
PsiElement(REGISTER_REFERENCE)
PsiElement(REGISTER)('v0')
PsiWhiteSpace(' ')
PsiErrorElement:extraneous input 'v1' expecting CLOSE_BRACE
PsiElement(REGISTER)('v1')
PsiElement(CLOSE_BRACE)('}')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
PsiElement(METHOD_REFERENCE)
PsiElement(CLASS_TYPE)
PsiElement(CLASS_DESCRIPTOR)('Lblah;')
PsiElement(ARROW)('->')
PsiElement(MEMBER_NAME)
PsiElement(SIMPLE_NAME)('blah')
PsiElement(OPEN_PAREN)('(')
PsiElement(METHOD_REFERENCE_PARAM_LIST)
<empty list>
PsiElement(CLOSE_PAREN)(')')
PsiElement(VOID_TYPE)
PsiElement(VOID_TYPE)('V')
PsiWhiteSpace('\n\n ')
PsiElement(INSTRUCTION)
PsiElement(INSTRUCTION_FORMAT3rc_METHOD)('invoke-virtual/range')
PsiWhiteSpace(' ')
PsiElement(OPEN_BRACE)('{')
PsiElement(REGISTER_REFERENCE)
PsiElement(REGISTER)('v0')
PsiWhiteSpace(' ')
PsiErrorElement:mismatched input '.blah' expecting CLOSE_BRACE
PsiElement(BAD_CHARACTER)('.blah')
PsiWhiteSpace(' ')
PsiElement(REGISTER)('v1')
PsiElement(CLOSE_BRACE)('}')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
PsiElement(METHOD_REFERENCE)
PsiElement(CLASS_TYPE)
PsiElement(CLASS_DESCRIPTOR)('Lblah;')
PsiElement(ARROW)('->')
PsiElement(MEMBER_NAME)
PsiElement(SIMPLE_NAME)('blah')
PsiElement(OPEN_PAREN)('(')
PsiElement(METHOD_REFERENCE_PARAM_LIST)
<empty list>
PsiElement(CLOSE_PAREN)(')')
PsiElement(VOID_TYPE)
PsiElement(VOID_TYPE)('V')
PsiWhiteSpace('\n\n ')
PsiElement(CATCH_STATEMENT)
PsiElement(CATCH_DIRECTIVE)('.catch')
PsiWhiteSpace(' ')
PsiElement(CLASS_TYPE)
PsiElement(CLASS_DESCRIPTOR)('Ljava/lang/Exception;')
PsiWhiteSpace(' ')
PsiElement(OPEN_BRACE)('{')
PsiWhiteSpace(' ')
PsiElement(LABEL_REFERENCE)
PsiElement(COLON)(':')
PsiElement(SIMPLE_NAME)('blah1')
PsiErrorElement:missing DOTDOT at ':'
<empty list>
PsiWhiteSpace(' ')
PsiElement(LABEL_REFERENCE)
PsiElement(COLON)(':')
PsiElement(SIMPLE_NAME)('blah2')
PsiWhiteSpace(' ')
PsiElement(CLOSE_BRACE)('}')
PsiWhiteSpace(' ')
PsiElement(LABEL_REFERENCE)
PsiElement(COLON)(':')
PsiElement(SIMPLE_NAME)('blah3')
PsiWhiteSpace('\n\n ')
PsiElement(CATCH_STATEMENT)
PsiElement(CATCH_DIRECTIVE)('.catch')
PsiWhiteSpace(' ')
PsiElement(CLASS_TYPE)
PsiElement(CLASS_DESCRIPTOR)('Ljava/lang/Exception;')
PsiWhiteSpace(' ')
PsiElement(OPEN_BRACE)('{')
PsiWhiteSpace(' ')
PsiElement(LABEL_REFERENCE)
PsiElement(COLON)(':')
PsiElement(SIMPLE_NAME)('blah1')
PsiWhiteSpace(' ')
PsiErrorElement:mismatched input '.blah' expecting DOTDOT
PsiElement(BAD_CHARACTER)('.blah')
PsiWhiteSpace(' ')
PsiElement(LABEL_REFERENCE)
PsiElement(COLON)(':')
PsiElement(SIMPLE_NAME)('blah2')
PsiWhiteSpace(' ')
PsiElement(CLOSE_BRACE)('}')
PsiWhiteSpace(' ')
PsiElement(LABEL_REFERENCE)
PsiElement(COLON)(':')
PsiElement(SIMPLE_NAME)('blah3')
PsiWhiteSpace('\n')
PsiElement(END_METHOD_DIRECTIVE)('.end method')