mirror of
https://github.com/revanced/smali.git
synced 2025-05-04 08:34:25 +02:00
Improve the error recovery for parameter directives
This commit is contained in:
parent
bdbb235c6f
commit
87be840208
@ -923,22 +923,56 @@ add them to the $statements_and_directives::methodAnnotations list*/
|
||||
parameter_directive
|
||||
@init {
|
||||
Marker marker = mark();
|
||||
Marker preAnnotationMarker = null;
|
||||
Marker nameMarker = null;
|
||||
Marker annotationsMarker = null;
|
||||
boolean gotEndParam = false;
|
||||
}
|
||||
: PARAMETER_DIRECTIVE register
|
||||
(comma { nameMarker = mark(); } string_literal { nameMarker.done(SmaliElementTypes.LOCAL_NAME); })?
|
||||
{ preAnnotationMarker = mark(); }
|
||||
({input.LA(1) == ANNOTATION_DIRECTIVE}? annotation)*
|
||||
( END_PARAMETER_DIRECTIVE {
|
||||
preAnnotationMarker.drop();
|
||||
(comma local_name)?
|
||||
{ annotationsMarker = mark(); } parameter_annotations
|
||||
( end_parameter_directive { gotEndParam = true; } )?
|
||||
{
|
||||
if (gotEndParam) {
|
||||
annotationsMarker.drop();
|
||||
marker.done(SmaliElementTypes.PARAMETER_STATEMENT);
|
||||
} else {
|
||||
marker.doneBefore(SmaliElementTypes.PARAMETER_STATEMENT, annotationsMarker);
|
||||
annotationsMarker.drop();
|
||||
}
|
||||
| /*epsilon*/ {
|
||||
marker.doneBefore(SmaliElementTypes.PARAMETER_STATEMENT, preAnnotationMarker);
|
||||
preAnnotationMarker.drop();
|
||||
};
|
||||
catch [RecognitionException re] {
|
||||
if (annotationsMarker != null) {
|
||||
annotationsMarker.drop();
|
||||
}
|
||||
recover(input, re);
|
||||
reportError(marker, re, false);
|
||||
}
|
||||
|
||||
parameter_annotations
|
||||
: ((ANNOTATION_DIRECTIVE)=> annotation)*;
|
||||
catch [RecognitionException re] {
|
||||
Marker errorMarker = mark();
|
||||
recover(input, re);
|
||||
reportError(errorMarker, re, false);
|
||||
}
|
||||
|
||||
end_parameter_directive
|
||||
: END_PARAMETER_DIRECTIVE;
|
||||
|
||||
local_name
|
||||
@init {
|
||||
Marker localNameMarker = mark();
|
||||
Marker stringMarker = mark();
|
||||
}
|
||||
: STRING_LITERAL
|
||||
{
|
||||
finishToken(stringMarker, SmaliElementTypes.LITERAL);
|
||||
finishToken(localNameMarker, SmaliElementTypes.LOCAL_NAME);
|
||||
};
|
||||
catch [RecognitionException re] {
|
||||
stringMarker.drop();
|
||||
recover(input, re);
|
||||
reportError(localNameMarker, re, false);
|
||||
}
|
||||
);
|
||||
|
||||
register
|
||||
@init { Marker marker = mark(); }
|
||||
|
@ -107,7 +107,7 @@ public class SmaliMethodParameter extends SmaliStubBasedPsiElement<SmaliMethodPa
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public String getName() {
|
||||
@Nullable @Override public String getName() {
|
||||
SmaliMethodParameterStub stub = getStub();
|
||||
if (stub != null) {
|
||||
return stub.getName();
|
||||
|
@ -57,6 +57,7 @@ public class ParserTest extends LightCodeInsightParsingTestCase {
|
||||
public void testSuperClassInvalidSyntax() throws Exception { doTest(true); }
|
||||
public void testSuperClassInvalidSyntax2() throws Exception { doTest(true); }
|
||||
public void testInvalidMethodReference() throws Exception { doTest(true); }
|
||||
public void testInvalidParameter() throws Exception { doTest(true); }
|
||||
public void testInvalidMethod() throws Exception { doTest(true); }
|
||||
public void testInvalidMethod2() throws Exception { doTest(true); }
|
||||
public void testInvalidMethod3() throws Exception { doTest(true); }
|
||||
|
10
smalidea/testData/InvalidParameter.smalidea
Normal file
10
smalidea/testData/InvalidParameter.smalidea
Normal file
@ -0,0 +1,10 @@
|
||||
.method public blah()V
|
||||
.param v0, "blah"
|
||||
.a
|
||||
.end method
|
||||
|
||||
.method public blah()V
|
||||
.param v0, "blah"
|
||||
.annotation runtime Lblah; .end annotation
|
||||
.
|
||||
.end method
|
85
smalidea/testData/InvalidParameter.txt
Normal file
85
smalidea/testData/InvalidParameter.txt
Normal file
@ -0,0 +1,85 @@
|
||||
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(PARAMETER_STATEMENT)
|
||||
PsiElement(PARAMETER_DIRECTIVE)('.param')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(REGISTER_REFERENCE)
|
||||
PsiElement(REGISTER)('v0')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LOCAL_NAME)
|
||||
PsiElement(LITERAL)
|
||||
PsiElement(STRING_LITERAL)('"blah"')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiErrorElement:no viable alternative at input '.a'
|
||||
PsiElement(BAD_CHARACTER)('.a')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(END_METHOD_DIRECTIVE)('.end method')
|
||||
PsiWhiteSpace('\n\n')
|
||||
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(PARAMETER_STATEMENT)
|
||||
PsiElement(PARAMETER_DIRECTIVE)('.param')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(REGISTER_REFERENCE)
|
||||
PsiElement(REGISTER)('v0')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LOCAL_NAME)
|
||||
PsiElement(LITERAL)
|
||||
PsiElement(STRING_LITERAL)('"blah"')
|
||||
PsiWhiteSpace('\n ')
|
||||
SmaliAnnotation(ANNOTATION)
|
||||
PsiElement(ANNOTATION_DIRECTIVE)('.annotation')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(ANNOTATION_VISIBILITY)('runtime')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(CLASS_TYPE)
|
||||
PsiElement(CLASS_DESCRIPTOR)('Lblah;')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(ANNOTATION_PARAMETER_LIST)
|
||||
<empty list>
|
||||
PsiElement(END_ANNOTATION_DIRECTIVE)('.end annotation')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiErrorElement:no viable alternative at input '.'
|
||||
PsiElement(BAD_CHARACTER)('.')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(END_METHOD_DIRECTIVE)('.end method')
|
Loading…
x
Reference in New Issue
Block a user