Parse annotated reference expressions

This commit is contained in:
Roman Shevchenko
2013-03-13 10:23:18 +01:00
parent f06d191a9d
commit 764b2ebf4e
6 changed files with 155 additions and 3 deletions
@@ -332,7 +332,12 @@ public class ExpressionParser {
final int dotOffset = builder.getCurrentOffset();
builder.advanceLexer();
final IElementType dotTokenType = builder.getTokenType();
IElementType dotTokenType = builder.getTokenType();
if (dotTokenType == JavaTokenType.AT) {
myParser.getDeclarationParser().parseAnnotations(builder);
dotTokenType = builder.getTokenType();
}
if (dotTokenType == JavaTokenType.CLASS_KEYWORD && exprType(expr) == JavaElementType.REFERENCE_EXPRESSION) {
if (breakPoint == BreakPoint.P1 && builder.getCurrentOffset() == breakOffset) {
error(builder, JavaErrorMessages.message("expected.identifier"));
@@ -35,6 +35,7 @@ class SpecSamples {
isNonNull = myString instanceof @NonNull; // error: type omitted
m(@Vernal Date::getDay);
m(@IllegalAnnotation java.util.@Vernal Date::getDay);
m(List<@English String>::size);
m(Arrays::<@NonNegative Integer>sort);
}
@@ -49,7 +50,7 @@ class SpecSamples {
// 3. The annotation on a given array level prefixes the brackets that introduce that level ...
//
{
void m(Document @Readonly ... docs) {
@Readonly Document [][] docs1 = new @Readonly Document [2][12]; // array of arrays of read-only documents
Document @Readonly [][] docs2 = new Document @Readonly [2][12]; // read-only array of arrays of documents
Document[] @Readonly [] docs3 = new Document[2] @Readonly [12]; // array of read-only arrays of documents
@@ -653,6 +653,54 @@ PsiJavaFile:TypeAnno.java
PsiJavaToken:RPARENTH(')')
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n ')
PsiExpressionStatement
PsiMethodCallExpression:m(@IllegalAnnotation java.util.@Vernal Date::getDay)
PsiReferenceExpression:m
PsiReferenceParameterList
<empty list>
PsiIdentifier:m('m')
PsiExpressionList
PsiJavaToken:LPARENTH('(')
PsiMethodReferenceExpression:@IllegalAnnotation java.util.@Vernal Date::getDay
PsiReferenceExpression:@IllegalAnnotation java.util.@Vernal Date
PsiReferenceExpression:@IllegalAnnotation java.util
PsiReferenceExpression:@IllegalAnnotation java
PsiReferenceParameterList
<empty list>
PsiAnnotation
PsiJavaToken:AT('@')
PsiJavaCodeReferenceElement:IllegalAnnotation
PsiIdentifier:IllegalAnnotation('IllegalAnnotation')
PsiReferenceParameterList
<empty list>
PsiAnnotationParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:java('java')
PsiJavaToken:DOT('.')
PsiReferenceParameterList
<empty list>
PsiIdentifier:util('util')
PsiJavaToken:DOT('.')
PsiAnnotation
PsiJavaToken:AT('@')
PsiJavaCodeReferenceElement:Vernal
PsiIdentifier:Vernal('Vernal')
PsiReferenceParameterList
<empty list>
PsiAnnotationParameterList
<empty list>
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:Date('Date')
PsiJavaToken:DOUBLE_COLON('::')
PsiReferenceParameterList
<empty list>
PsiIdentifier:getDay('getDay')
PsiJavaToken:RPARENTH(')')
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n ')
PsiExpressionStatement
PsiMethodCallExpression:m(List<@English String>::size)
PsiReferenceExpression:m
@@ -794,9 +842,43 @@ PsiJavaFile:TypeAnno.java
PsiWhiteSpace('\n ')
PsiComment(END_OF_LINE_COMMENT)('//')
PsiWhiteSpace('\n\n ')
PsiClassInitializer
PsiMethod:m
PsiModifierList:
<empty list>
PsiTypeParameterList
<empty list>
PsiTypeElement:void
PsiKeyword:void('void')
PsiWhiteSpace(' ')
PsiIdentifier:m('m')
PsiParameterList:(Document @Readonly ... docs)
PsiJavaToken:LPARENTH('(')
PsiParameter:docs
PsiModifierList:
<empty list>
PsiTypeElement:Document @Readonly ...
PsiTypeElement:Document
PsiJavaCodeReferenceElement:Document
PsiIdentifier:Document('Document')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiAnnotation
PsiJavaToken:AT('@')
PsiJavaCodeReferenceElement:Readonly
PsiIdentifier:Readonly('Readonly')
PsiReferenceParameterList
<empty list>
PsiAnnotationParameterList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:ELLIPSIS('...')
PsiWhiteSpace(' ')
PsiIdentifier:docs('docs')
PsiJavaToken:RPARENTH(')')
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
PsiWhiteSpace('\n ')
@@ -0,0 +1,29 @@
PsiJavaFile:AnnotatedRefExpr0.java
PsiReferenceExpression:@A C1.@B() C2
PsiReferenceExpression:@A C1
PsiReferenceParameterList
<empty list>
PsiAnnotation
PsiJavaToken:AT('@')
PsiJavaCodeReferenceElement:A
PsiIdentifier:A('A')
PsiReferenceParameterList
<empty list>
PsiAnnotationParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:C1('C1')
PsiJavaToken:DOT('.')
PsiAnnotation
PsiJavaToken:AT('@')
PsiJavaCodeReferenceElement:B
PsiIdentifier:B('B')
PsiReferenceParameterList
<empty list>
PsiAnnotationParameterList
PsiJavaToken:LPARENTH('(')
PsiJavaToken:RPARENTH(')')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:C2('C2')
@@ -0,0 +1,33 @@
PsiJavaFile:AnnotatedRefExpr1.java
PsiReferenceExpression:@A C1.@B()
PsiReferenceExpression:@A C1
PsiReferenceParameterList
<empty list>
PsiAnnotation
PsiJavaToken:AT('@')
PsiJavaCodeReferenceElement:A
PsiIdentifier:A('A')
PsiReferenceParameterList
<empty list>
PsiAnnotationParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:C1('C1')
PsiJavaToken:DOT('.')
PsiAnnotation
PsiJavaToken:AT('@')
PsiJavaCodeReferenceElement:B
PsiIdentifier:B('B')
PsiReferenceParameterList
<empty list>
PsiAnnotationParameterList
PsiJavaToken:LPARENTH('(')
PsiJavaToken:RPARENTH(')')
PsiReferenceParameterList
<empty list>
PsiErrorElement:Identifier expected
<empty list>
PsiWhiteSpace(' ')
PsiErrorElement:Unparsed tokens
PsiJavaToken:LPARENTH('(')
PsiJavaToken:RPARENTH(')')
@@ -115,6 +115,8 @@ public class ExpressionParserTest extends JavaParsingTestCase {
public void testPrimitiveFieldAccess() { doParserTest("int.x"); }
public void testChainedClassObjectAccess() { doParserTest("A.class.B.class"); }
public void testChainedThisObjectAccess() { doParserTest("A.this.B.this"); }
public void testAnnotatedRefExpr0() { doParserTest("@A C1.@B() C2"); }
public void testAnnotatedRefExpr1() { doParserTest("@A C1.@B() ()"); }
public void testMethodRef0() { doParserTest("a.b.C::m"); }
public void testMethodRef1() { doParserTest("a.b.C<T>::new"); }