parse annotation arguments with missed names or values

This commit is contained in:
Max Medvedev
2013-06-15 12:25:46 +04:00
parent 22c74004c2
commit 23638a53d4
6 changed files with 83 additions and 13 deletions
@@ -364,3 +364,4 @@ cannot.assign.a.value.to.final.field.0=Cannot assign a value to final field ''{0
variable.0.might.not.have.been.initialized=Variable ''{0}'' might not have been initialized
unexpected.symbol=Unexpected symbol
statement.expected=Statement expected
annotation.attribute.expected=Annotation attribute expected
@@ -1390,6 +1390,17 @@ public class GroovyAnnotator extends GroovyElementVisitor {
@Override
public void visitAnnotationNameValuePair(GrAnnotationNameValuePair nameValuePair) {
final PsiElement identifier = nameValuePair.getNameIdentifierGroovy();
if (identifier == null) {
final PsiElement parent = nameValuePair.getParent();
if (parent instanceof GrAnnotationArgumentList) {
final int count = ((GrAnnotationArgumentList)parent).getAttributes().length;
if (count > 1) {
myHolder.createErrorAnnotation(nameValuePair, GroovyBundle.message("attribute.name.expected"));
}
}
}
final GrAnnotationMemberValue value = nameValuePair.getValue();
checkAnnotationAttributeValue(value, value);
@@ -43,18 +43,9 @@ public class AnnotationArguments implements GroovyElementTypes {
return;
}
if (checkIdentAndAssign(builder)) {
if (builder.getTokenType() != mRPAREN) {
parsePairs(builder, parser);
}
else {
PsiBuilder.Marker pairMarker = builder.mark();
if (parseAnnotationMemberValueInitializer(builder, parser)) {
pairMarker.done(ANNOTATION_MEMBER_VALUE_PAIR);
}
else {
pairMarker.drop();
}
}
ParserUtils.getToken(builder, mNLS);
ParserUtils.getToken(builder, mRPAREN, GroovyBundle.message("rparen.expected"));
@@ -122,17 +113,29 @@ public class AnnotationArguments implements GroovyElementTypes {
private static boolean parsePair(PsiBuilder builder, GroovyParser parser) {
PsiBuilder.Marker marker = builder.mark();
final PsiBuilder.Marker lfMarker;
if (checkIdentAndAssign(builder)) {
ParserUtils.getToken(builder, TokenSets.CODE_REFERENCE_ELEMENT_NAME_TOKENS);
ParserUtils.getToken(builder, mASSIGN);
lfMarker = builder.mark();
ParserUtils.getToken(builder, mNLS);
}
else {
builder.error(GroovyBundle.message("attribute.name.expected"));
lfMarker = null;
}
if (!parseAnnotationMemberValueInitializer(builder, parser)) {
builder.error(GroovyBundle.message("annotation.member.value.initializer.expected"));
if (lfMarker != null) {
lfMarker.rollbackTo();
builder.error(GroovyBundle.message("annotation.member.value.initializer.expected"));
}
else {
builder.error(GroovyBundle.message("annotation.attribute.expected"));
}
}
else if (lfMarker != null) {
lfMarker.drop();
}
marker.done(ANNOTATION_MEMBER_VALUE_PAIR);
@@ -315,7 +315,9 @@ public class GenerationUtil {
while (i < parameters.length) {
PsiParameter parameter = parameters[i];
if (parameter == null) continue;
if (parameter instanceof PsiCompiledElement) parameter = (PsiParameter)((PsiCompiledElement)parameter).getMirror();
if (parameter instanceof PsiCompiledElement) {
parameter = (PsiParameter)((PsiCompiledElement)parameter).getMirror();
}
if (i > 0) text.append(", "); //append ','
if (!classNameProvider.forStubs()) {
@@ -34,4 +34,5 @@ public class AnnotationsParsingTest extends GroovyParsingTestCase {
public void testDefAttribute() {doTest()}
public void testLineFeedAfterRef() {doTest()}
public void testKeywordsAttributes() {doTest()}
public void testMess() { doTest() }
}
@@ -0,0 +1,52 @@
@A(x = '5', 'foo', , x=, , 5)
def x
-----
Groovy script
Variable definitions
Modifiers
Annotation
PsiElement(@)('@')
Reference element
PsiElement(identifier)('A')
Annotation arguments
PsiElement(()('(')
Annotation member value pair
PsiElement(identifier)('x')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Literal
PsiElement(string)(''5'')
PsiElement(,)(',')
PsiWhiteSpace(' ')
Annotation member value pair
Literal
PsiElement(string)(''foo'')
PsiElement(,)(',')
PsiWhiteSpace(' ')
Annotation member value pair
PsiErrorElement:Annotation attribute expected
<empty list>
PsiElement(,)(',')
PsiWhiteSpace(' ')
Annotation member value pair
PsiElement(identifier)('x')
PsiElement(=)('=')
PsiErrorElement:Annotation member value initializer expected
<empty list>
PsiElement(,)(',')
PsiWhiteSpace(' ')
Annotation member value pair
PsiErrorElement:Annotation attribute expected
<empty list>
PsiElement(,)(',')
PsiWhiteSpace(' ')
Annotation member value pair
Literal
PsiElement(Integer)('5')
PsiElement())(')')
PsiElement(new line)('\n')
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('x')