diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrAliasAnnotationChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrAliasAnnotationChecker.java index fc1071d13a40..d9709702eee0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrAliasAnnotationChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrAliasAnnotationChecker.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.groovy.annotator; import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.psi.PsiAnnotation; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; @@ -39,7 +40,7 @@ public class GrAliasAnnotationChecker extends CustomAnnotationChecker { @Override public boolean checkApplicability(@NotNull AnnotationHolder holder, @NotNull GrAnnotation annotation) { - final GrAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector(annotation); + final PsiAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector(annotation); if (annotationCollector == null) { return false; } @@ -62,7 +63,7 @@ public class GrAliasAnnotationChecker extends CustomAnnotationChecker { @Override public boolean checkArgumentList(@NotNull AnnotationHolder holder, @NotNull GrAnnotation annotation) { - final GrAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector(annotation); + final PsiAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector(annotation); if (annotationCollector == null) { return false; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java index 275ae1494d81..257aec45e8ff 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionUtil.java @@ -591,7 +591,7 @@ public class GroovyCompletionUtil { PsiElement resolved = ref.resolve(); if (resolved instanceof PsiClass) { - final GrAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector((PsiClass)resolved); + final PsiAnnotation annotationCollector = GrAnnotationCollector.findAnnotationCollector((PsiClass)resolved); if (annotationCollector != null) { final ArrayList annotations = ContainerUtil.newArrayList(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java index 6e4028dcf0ab..967330d4f7af 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java @@ -180,7 +180,7 @@ public class GrAnnotationNameValuePairImpl extends GroovyPsiElementImpl implemen String name = declaredName == null ? PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME : declaredName; if (resolved instanceof PsiClass) { - final GrAnnotation collector = GrAnnotationCollector.findAnnotationCollector((PsiClass)resolved); + final PsiAnnotation collector = GrAnnotationCollector.findAnnotationCollector((PsiClass)resolved); if (collector != null) { return multiResolveFromAlias(annotation, name, collector); } @@ -205,7 +205,7 @@ public class GrAnnotationNameValuePairImpl extends GroovyPsiElementImpl implemen return results; } - private static GroovyResolveResult[] multiResolveFromAlias(@NotNull GrAnnotation alias, @NotNull String name, @NotNull GrAnnotation annotationCollector) { + private static GroovyResolveResult[] multiResolveFromAlias(@NotNull GrAnnotation alias, @NotNull String name, @NotNull PsiAnnotation annotationCollector) { List result = ContainerUtilRt.newArrayList(); List annotations = ContainerUtilRt.newArrayList(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrAnnotationCollector.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrAnnotationCollector.java index 8b8a825373e5..2ddb1ef8cd6b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrAnnotationCollector.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrAnnotationCollector.java @@ -19,13 +19,13 @@ import com.intellij.psi.*; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArrayInitializer; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightAnnotation; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; @@ -36,6 +36,7 @@ import java.util.Map; import java.util.Set; public class GrAnnotationCollector { + @NotNull public static GrAnnotation[] getResolvedAnnotations(@NotNull GrModifierList modifierList) { final GrAnnotation[] rawAnnotations = modifierList.getRawAnnotations(); @@ -44,7 +45,7 @@ public class GrAnnotationCollector { List result = ContainerUtil.newArrayList(); for (GrAnnotation annotation : rawAnnotations) { - final GrAnnotation annotationCollector = findAnnotationCollector(annotation); + final PsiAnnotation annotationCollector = findAnnotationCollector(annotation); if (annotationCollector != null) { collectAnnotations(result, annotation, annotationCollector); } @@ -59,7 +60,7 @@ public class GrAnnotationCollector { private static boolean hasAliases(@NotNull GrAnnotation[] rawAnnotations) { for (GrAnnotation annotation : rawAnnotations) { - final GrAnnotation annotationCollector = findAnnotationCollector(annotation); + final PsiAnnotation annotationCollector = findAnnotationCollector(annotation); if (annotationCollector != null) { return true; } @@ -78,21 +79,19 @@ public class GrAnnotationCollector { @NotNull public static Set collectAnnotations(@NotNull List list, @NotNull GrAnnotation alias, - @NotNull GrAnnotation annotationCollector) { + @NotNull PsiAnnotation annotationCollector) { - final GrModifierList modifierList = (GrModifierList)annotationCollector.getParent(); + final PsiModifierList modifierList = (PsiModifierList)annotationCollector.getParent(); - Map> annotations = ContainerUtil.newHashMap(); - collectAliasedAnnotationsFromAnnotationCollectorValueAttribute(annotationCollector, - (HashMap>)annotations); - collectAliasedAnnotationsFromAnnotationCollectorAnnotations(modifierList, - (HashMap>)annotations); + Map> annotations = ContainerUtil.newHashMap(); + collectAliasedAnnotationsFromAnnotationCollectorValueAttribute(annotationCollector, (HashMap>)annotations); + collectAliasedAnnotationsFromAnnotationCollectorAnnotations(modifierList, (HashMap>)annotations); final PsiManager manager = alias.getManager(); final GrAnnotationNameValuePair[] attributes = alias.getParameterList().getAttributes(); Set allUsedAttrs = ContainerUtil.newHashSet(); - for (Map.Entry> entry : annotations.entrySet()) { + for (Map.Entry> entry : annotations.entrySet()) { final String qname = entry.getKey(); final PsiClass resolved = JavaPsiFacade.getInstance(alias.getProject()).findClass(qname, alias.getResolveScope()); if (resolved == null) continue; @@ -110,8 +109,8 @@ public class GrAnnotationCollector { } - final Map defaults = entry.getValue(); - for (Map.Entry defa : defaults.entrySet()) { + final Map defaults = entry.getValue(); + for (Map.Entry defa : defaults.entrySet()) { if (!usedAttrs.contains(defa.getKey())) { annotation.addAttribute(defa.getValue()); } @@ -124,16 +123,29 @@ public class GrAnnotationCollector { return allUsedAttrs; } - private static void collectAliasedAnnotationsFromAnnotationCollectorAnnotations(@NotNull GrModifierList modifierList, - @NotNull HashMap> annotations) { - for (GrAnnotation annotation : modifierList.getRawAnnotations()) { + private static void collectAliasedAnnotationsFromAnnotationCollectorAnnotations(@NotNull PsiModifierList modifierList, + @NotNull HashMap> annotations) { + PsiElement parent = modifierList.getParent(); + if (parent instanceof PsiClass && + GroovyCommonClassNames.GROOVY_TRANSFORM_COMPILE_DYNAMIC.equals(((PsiClass)parent).getQualifiedName())) { + HashMap params = ContainerUtil.newHashMap(); + annotations.put(GroovyCommonClassNames.GROOVY_TRANSFORM_COMPILE_STATIC, params); + GrAnnotation annotation = + GroovyPsiElementFactory.getInstance(modifierList.getProject()).createAnnotationFromText("@CompileStatic(TypeCheckingMode.SKIP)"); + params.put("value", annotation.getParameterList().getAttributes()[0]); + return; + } + + PsiAnnotation[] rawAnnotations = + modifierList instanceof GrModifierList ? ((GrModifierList)modifierList).getRawAnnotations() : modifierList.getAnnotations(); + for (PsiAnnotation annotation : rawAnnotations) { final String qname = annotation.getQualifiedName(); if (qname == null || qname.equals(GroovyCommonClassNames.GROOVY_TRANSFORM_ANNOTATION_COLLECTOR)) continue; - final GrAnnotationNameValuePair[] attributes = annotation.getParameterList().getAttributes(); - for (GrAnnotationNameValuePair pair : attributes) { - Map map = annotations.get(qname); + final PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); + for (PsiNameValuePair pair : attributes) { + Map map = annotations.get(qname); if (map == null) { map = ContainerUtil.newHashMap(); annotations.put(qname, map); @@ -142,14 +154,14 @@ public class GrAnnotationCollector { map.put(pair.getName() != null ? pair.getName() : "value", pair); } if (attributes.length == 0 && !annotations.containsKey(qname)) { - annotations.put(qname, ContainerUtil.newHashMap()); + annotations.put(qname, ContainerUtil.newHashMap()); } } } - private static void collectAliasedAnnotationsFromAnnotationCollectorValueAttribute(@NotNull GrAnnotation annotationCollector, - @NotNull HashMap> annotations) { + private static void collectAliasedAnnotationsFromAnnotationCollectorValueAttribute(@NotNull PsiAnnotation annotationCollector, + @NotNull HashMap> annotations) { final PsiAnnotationMemberValue annotationsFromValue = annotationCollector.findAttributeValue("value"); if (annotationsFromValue instanceof GrAnnotationArrayInitializer) { @@ -157,7 +169,7 @@ public class GrAnnotationCollector { if (member instanceof GrReferenceExpression) { final PsiElement resolved = ((GrReferenceExpression)member).resolve(); if (resolved instanceof PsiClass && ((PsiClass)resolved).isAnnotationType()) { - annotations.put(((PsiClass)resolved).getQualifiedName(), ContainerUtil.newHashMap()); + annotations.put(((PsiClass)resolved).getQualifiedName(), ContainerUtil.newHashMap()); } } } @@ -165,11 +177,12 @@ public class GrAnnotationCollector { } @Nullable - public static GrAnnotation findAnnotationCollector(@Nullable PsiClass clazz) { - if (clazz instanceof GrTypeDefinition) { - final GrModifierList modifierList = ((GrTypeDefinition)clazz).getModifierList(); + public static PsiAnnotation findAnnotationCollector(@Nullable PsiClass clazz) { + if (clazz != null) { + final PsiModifierList modifierList = clazz.getModifierList(); if (modifierList != null) { - for (GrAnnotation annotation : modifierList.getRawAnnotations()) { + PsiAnnotation[] annotations = modifierList instanceof GrModifierList ? ((GrModifierList)modifierList).getRawAnnotations() : modifierList.getAnnotations(); + for (PsiAnnotation annotation : annotations) { if (GroovyCommonClassNames.GROOVY_TRANSFORM_ANNOTATION_COLLECTOR.equals(annotation.getQualifiedName())) { return annotation; } @@ -182,7 +195,7 @@ public class GrAnnotationCollector { @Nullable - public static GrAnnotation findAnnotationCollector(@NotNull GrAnnotation annotation) { + public static PsiAnnotation findAnnotationCollector(@NotNull GrAnnotation annotation) { final GrCodeReferenceElement ref = annotation.getClassReference(); final PsiElement resolved = ref.resolve(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java index bbf33c3798c3..83894496621b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightAnnotation.java @@ -22,11 +22,13 @@ import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.light.LightClassReference; import com.intellij.psi.impl.light.LightElement; import com.intellij.psi.meta.PsiMetaData; +import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArgumentList; @@ -139,8 +141,20 @@ public class GrLightAnnotation extends LightElement implements GrAnnotation { return null; } - public void addAttribute(GrAnnotationNameValuePair attribute) { - myAnnotationArgList.addAttribute(attribute); + public void addAttribute(PsiNameValuePair attribute) { + if (attribute instanceof GrAnnotationNameValuePair) { + myAnnotationArgList.addAttribute((GrAnnotationNameValuePair)attribute); + } + else { + try { + GrAnnotation annotation = + GroovyPsiElementFactory.getInstance(getProject()).createAnnotationFromText("@Anno(" + attribute.getText() + ")"); + myAnnotationArgList.addAttribute(annotation.getParameterList().getAttributes()[0]); + } + catch (IncorrectOperationException e) { + //do nothing + } + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java index 6466f7ddd514..27f597b95f6f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java @@ -63,6 +63,7 @@ public final class GroovyCommonClassNames { @NonNls public static final String GROOVY_LANG_NEWIFY = "groovy.lang.Newify"; @NonNls public static final String GROOVY_LANG_DELEGATES_TO = "groovy.lang.DelegatesTo"; @NonNls public static final String GROOVY_LANG_DELEGATES_TO_TARGET = "groovy.lang.DelegatesTo.Target"; + @NonNls public static final String GROOVY_TRANSFORM_COMPILE_DYNAMIC = "groovy.transform.CompileDynamic"; private GroovyCommonClassNames() { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/aliasAnnotations/GrAnnotationHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/aliasAnnotations/GrAnnotationHighlightingTest.groovy index 9beb849df765..5bc936ef4cc1 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/aliasAnnotations/GrAnnotationHighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/aliasAnnotations/GrAnnotationHighlightingTest.groovy @@ -15,6 +15,7 @@ */ package org.jetbrains.plugins.groovy.lang.aliasAnnotations +import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection import org.jetbrains.plugins.groovy.lang.highlighting.GrHighlightingTestBase /** @@ -199,4 +200,24 @@ def aaa() {} def bbb() {} ''') } + + void testCompileDynamic() { + testHighlighting('''\ +import groovy.transform.CompileDynamic +import groovy.transform.CompileStatic + +@CompileStatic +class B { + B() { + println x + } + + @CompileDynamic + def foo() { + println y + } +} +''', GrUnresolvedAccessInspection) + } + } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy index b20ca795f41a..92331f6b462f 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy @@ -1120,7 +1120,7 @@ print(