Add better error recovery for open/close braces

This commit is contained in:
Ben Gruver 2015-02-26 20:01:58 -08:00
parent d7cd293904
commit 0f597ae106
4 changed files with 80 additions and 5 deletions

View File

@ -452,6 +452,22 @@ close_paren
reportError(errorMarker, re, false);
}
open_brace
: OPEN_BRACE;
catch [RecognitionException re] {
Marker errorMarker = mark();
recover(input, re);
reportError(errorMarker, re, false);
}
close_brace
: CLOSE_BRACE;
catch [RecognitionException re] {
Marker errorMarker = mark();
recover(input, re);
reportError(errorMarker, re, false);
}
param_list_inner
: ((PARAM_LIST_START param* PARAM_LIST_END)
| (PARAM_LIST_OR_ID_START param* PARAM_LIST_OR_ID_END)
@ -656,7 +672,7 @@ string_literal
array_literal
@init { Marker marker = mark(); }
: OPEN_BRACE (literal (COMMA literal)* | ) CLOSE_BRACE
: open_brace (literal (COMMA literal)* | ) close_brace
{ marker.done(SmaliElementTypes.LITERAL); };
catch [RecognitionException re] {
recover(input, re);
@ -868,17 +884,17 @@ label_ref
}
register_list
: OPEN_BRACE (register (COMMA register)*)? CLOSE_BRACE;
: open_brace (register (COMMA register)*)? close_brace;
register_range
: OPEN_BRACE (register (DOTDOT register)?)? CLOSE_BRACE;
: open_brace (register (DOTDOT register)?)? close_brace;
verification_error_reference
: class_descriptor | fully_qualified_field | fully_qualified_method;
catch_directive
@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); };
catch [RecognitionException re] {
recover(input, re);
@ -887,7 +903,7 @@ catch_directive
catchall_directive
@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); };
catch [RecognitionException re] {
recover(input, re);

View File

@ -51,6 +51,7 @@ public class ParserTest extends LightCodeInsightParsingTestCase {
public void testInvalidField2() throws Exception { doTest(true); }
public void testInvalidField3() throws Exception { doTest(true); }
public void testInvalidField4() throws Exception { doTest(true); }
public void testInvalidInstruction() 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,4 @@
.method blah()V
.registers 1
invoke-virtual .blah v0}, Lblah;->blah()V
.end method

View File

@ -0,0 +1,54 @@
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)
<empty list>
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(REGISTERS_STATEMENT)
PsiElement(REGISTERS_DIRECTIVE)('.registers')
PsiWhiteSpace(' ')
PsiElement(LITERAL)
PsiElement(POSITIVE_INTEGER_LITERAL)('1')
PsiWhiteSpace('\n')
PsiElement(INSTRUCTION)
PsiElement(INSTRUCTION_FORMAT35c_METHOD)('invoke-virtual')
PsiWhiteSpace(' ')
PsiErrorElement:mismatched input '.blah' expecting OPEN_BRACE
PsiElement(BAD_CHARACTER)('.blah')
PsiWhiteSpace(' ')
PsiElement(REGISTER_REFERENCE)
PsiElement(REGISTER)('v0')
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')
PsiElement(END_METHOD_DIRECTIVE)('.end method')