IDEA-93257 Groovy: good code is red when annotation attribute is named "def"

This commit is contained in:
Max Medvedev
2012-10-23 18:09:56 +04:00
parent f31fb5f5f3
commit 60d9c2cee4
6 changed files with 69 additions and 30 deletions
@@ -36,6 +36,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrLabel;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
@@ -101,6 +102,7 @@ public class GrKeywordAndDeclarationHighlighter extends TextEditorHighlightingPa
return false; //It is allowed to name packages 'as', 'in' or 'def'
}
}
else if (token == GroovyTokenTypes.kDEF && element.getParent() instanceof GrAnnotationNameValuePair) return false;
else if (parent instanceof GrReferenceExpression && element == ((GrReferenceExpression)parent).getReferenceNameElement()) {
return false; //don't highlight foo.def
}
@@ -42,7 +42,7 @@ public class AnnotationArguments implements GroovyElementTypes {
return;
}
if (ParserUtils.lookAhead(builder, mIDENT, mASSIGN)) {
if (checkIdentAndAssign(builder)) {
parsePairs(builder, parser);
}
else {
@@ -60,6 +60,11 @@ public class AnnotationArguments implements GroovyElementTypes {
annArgs.done(ANNOTATION_ARGUMENTS);
}
private static boolean checkIdentAndAssign(PsiBuilder builder) {
//def is valid name identifier
return ParserUtils.lookAhead(builder, mIDENT, mASSIGN) || ParserUtils.lookAhead(builder, kDEF, mASSIGN);
}
/*
* annotationMemberValueInitializer ::= conditionalExpression | annotation
*/
@@ -114,8 +119,10 @@ public class AnnotationArguments implements GroovyElementTypes {
private static boolean parsePair(PsiBuilder builder, GroovyParser parser) {
PsiBuilder.Marker marker = builder.mark();
if (ParserUtils.lookAhead(builder, mIDENT, mASSIGN)) {
ParserUtils.getToken(builder, mIDENT);
if (checkIdentAndAssign(builder)) {
if (!ParserUtils.getToken(builder, mIDENT)) {
ParserUtils.getToken(builder, kDEF);
}
ParserUtils.getToken(builder, mASSIGN);
ParserUtils.getToken(builder, mNLS);
}
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.PrefixMatcher;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -63,7 +64,13 @@ public class GrAnnotationNameValuePairImpl extends GroovyPsiElementImpl implemen
@Nullable
public PsiElement getNameIdentifierGroovy() {
return findChildByType(GroovyTokenTypes.mIDENT);
PsiElement child = getFirstChild();
if (child == null) return null;
IElementType type = child.getNode().getElementType();
if (type == GroovyTokenTypes.mIDENT || type == GroovyTokenTypes.kDEF) return child;
return null;
}
public PsiIdentifier getNameIdentifier() {
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
* Use is subject to license terms.
*/
package org.jetbrains.plugins.groovy.lang.parser
/**
* @author peter
*/
public class AnnotationsParsingTest extends GroovyParsingTestCase {
final String basePath = super.basePath + "annotations"
public void testAnn1() { doTest() }
public void testAnn2() { doTest() }
public void testAnn3() { doTest() }
public void testAnn4() { doTest() }
public void testAnn5() { doTest() }
public void testAnn6() { doTest() }
public void testAnn7() { doTest() }
public void testClassLiteral() { doTest() }
public void testImportAnn() { doTest() }
public void testPackageAnn() { doTest() }
public void testDefAttribute() {doTest()}
}
@@ -1,26 +0,0 @@
/*
* Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
* Use is subject to license terms.
*/
package org.jetbrains.plugins.groovy.lang.parser;
/**
* @author peter
*/
public class AnnotationsParsingTest extends GroovyParsingTestCase {
@Override
protected String getBasePath() {
return super.getBasePath() + "annotations";
}
public void testAnn1() throws Throwable { doTest(); }
public void testAnn2() throws Throwable { doTest(); }
public void testAnn3() throws Throwable { doTest(); }
public void testAnn4() throws Throwable { doTest(); }
public void testAnn5() throws Throwable { doTest(); }
public void testAnn6() throws Throwable { doTest(); }
public void testAnn7() throws Throwable { doTest(); }
public void testClassLiteral() throws Throwable { doTest(); }
public void testImportAnn() throws Throwable { doTest(); }
public void testPackageAnn() throws Throwable { doTest(); }
}
@@ -0,0 +1,25 @@
@Foo(def = 4)
def a
-----
Groovy script
Variable definitions
Modifiers
Annotation
PsiElement(@)('@')
Reference element
PsiElement(identifier)('Foo')
Annotation arguments
PsiElement(()('(')
Annotation member value pair
PsiElement(def)('def')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Literal
PsiElement(Integer)('4')
PsiElement())(')')
PsiElement(new line)('\n')
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('a')