Make sure we always get a method prototype and method param list

This commit is contained in:
Ben Gruver 2015-02-14 19:40:51 -08:00
parent aa06a4c782
commit d733304122
6 changed files with 84 additions and 21 deletions

View File

@ -88,15 +88,15 @@ import javax.annotation.Nullable;
}
}
@Override
public void recover(IntStream input, RecognitionException re) {
BitSet followSet = computeErrorRecoverySet();
beginResync();
consumeUntil(input, followSet);
endResync();
}
public Marker recoverWithMarker(IntStream input, RecognitionException re) {
if ( state.lastErrorIndex==input.index() ) {
// uh oh, another error at same token index; must be a case
// where LT(1) is in the recovery token set so nothing is
// consumed; consume a single token so at least to prevent
// an infinite loop; this is a failsafe.
input.consume();
}
state.lastErrorIndex = input.index();
BitSet followSet = computeErrorRecoverySet();
beginResync();
Marker marker = mark();
@ -407,17 +407,20 @@ member_name
method_prototype
@init { Marker marker = mark(); }
: OPEN_PAREN param_list CLOSE_PAREN type_descriptor;
: open_paren param_list close_paren type_descriptor
{ marker.done(SmaliElementTypes.METHOD_PROTOTYPE); };
catch [RecognitionException re] {
recover(input, re);
reportError(re);
}
finally {
marker.done(SmaliElementTypes.METHOD_PROTOTYPE);
reportError(marker, re, false);
}
param_list
@init { Marker marker = mark(); }
open_paren
: OPEN_PAREN;
close_paren
: CLOSE_PAREN;
param_list_inner
: ((PARAM_LIST_START param* PARAM_LIST_END)
| (PARAM_LIST_OR_ID_START param* PARAM_LIST_OR_ID_END)
| (param*));
@ -425,9 +428,11 @@ param_list
Marker errorMarker = recoverWithMarker(input, re);
reportError(errorMarker, re, false);
}
finally {
marker.done(SmaliElementTypes.METHOD_PARAM_LIST);
}
param_list
@init { Marker marker = mark(); }
: param_list_inner
{ marker.done(SmaliElementTypes.METHOD_PARAM_LIST); };
param
@init {

View File

@ -52,8 +52,8 @@ public class SmaliMethodPrototype extends SmaliStubBasedPsiElement<SmaliMethodPr
return findChildByClass(PsiTypeElement.class);
}
@Nullable
@NotNull
public SmaliMethodParamList getParameterList() {
return findChildByClass(SmaliMethodParamList.class);
return getRequiredStubOrPsiChild(SmaliElementTypes.METHOD_PARAM_LIST);
}
}

View File

@ -102,4 +102,5 @@ public class ParserTest extends ParsingTestCase {
public void testSuperClassInvalidSyntax() throws Exception { doTest(true); }
public void testSuperClassInvalidSyntax2() throws Exception { doTest(true); }
public void testInvalidMethod() throws Exception { doTest(true); }
public void testInvalidMethod2() throws Exception { doTest(true); }
}

View File

@ -30,4 +30,5 @@ smali.FILE
PsiErrorElement:no viable alternative at input '.blah'
PsiElement(BAD_CHARACTER)('.blah')
SmaliMethodPrototype(METHOD_PROTOTYPE)
<empty list>
SmaliMethodParamList(METHOD_PARAM_LIST)
<empty list>

View File

@ -0,0 +1,6 @@
.class Ltest;
.super Ljava/lang/Object;
.method blah
.method

View File

@ -0,0 +1,50 @@
smali.FILE
SmaliClass(CLASS)
SmaliModifierList(MODIFIER_LIST)
<empty list>
SmaliExtendsList(EXTENDS_LIST)
<empty list>
SmaliImplementsList(IMPLEMENTS_LIST)
<empty list>
PsiElement(CLASS_STATEMENT)
PsiElement(CLASS_DIRECTIVE)('.class')
PsiWhiteSpace(' ')
PsiElement(ACCESS_LIST)
<empty list>
PsiElement(CLASS_TYPE)
PsiElement(CLASS_DESCRIPTOR)('Ltest;')
PsiWhiteSpace('\n')
PsiElement(SUPER_STATEMENT)
PsiElement(SUPER_DIRECTIVE)('.super')
PsiWhiteSpace(' ')
PsiElement(CLASS_TYPE)
PsiElement(CLASS_DESCRIPTOR)('Ljava/lang/Object;')
PsiWhiteSpace('\n\n')
SmaliMethod(METHOD)
SmaliModifierList(MODIFIER_LIST)
<empty list>
PsiElement(METHOD_DIRECTIVE)('.method')
PsiWhiteSpace(' ')
PsiElement(ACCESS_LIST)
<empty list>
PsiElement(MEMBER_NAME)
PsiElement(SIMPLE_NAME)('blah')
PsiWhiteSpace('\n\n')
SmaliMethodPrototype(METHOD_PROTOTYPE)
PsiErrorElement:mismatched input '.method' expecting OPEN_PAREN
<empty list>
SmaliMethodParamList(METHOD_PARAM_LIST)
<empty list>
PsiErrorElement:missing END_METHOD_DIRECTIVE at '.method'
<empty list>
SmaliMethod(METHOD)
SmaliModifierList(MODIFIER_LIST)
<empty list>
PsiElement(METHOD_DIRECTIVE)('.method')
PsiElement(ACCESS_LIST)
<empty list>
PsiErrorElement:no viable alternative at input '<EOF>'
<empty list>
SmaliMethodPrototype(METHOD_PROTOTYPE)
SmaliMethodParamList(METHOD_PARAM_LIST)
<empty list>