diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/auxiliary/modifiers/GrModifierList.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/auxiliary/modifiers/GrModifierList.java index 72666b163f62..0aee6fee1527 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/auxiliary/modifiers/GrModifierList.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/auxiliary/modifiers/GrModifierList.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,4 +48,6 @@ public interface GrModifierList extends GroovyPsiElement, PsiModifierList { @Override void setModifierProperty(@GrModifier.GrModifierConstant @NotNull @NonNls String name, boolean value) throws IncorrectOperationException; + @NotNull + GrAnnotation[] getRawAnnotations(); } 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 new file mode 100644 index 000000000000..9854e9db851b --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrAnnotationCollector.java @@ -0,0 +1,166 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.modifiers; + +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.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.impl.synthetic.GrLightAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class GrAnnotationCollector { + public static GrAnnotation[] getResolvedAnnotations(@NotNull GrModifierList modifierList) { + final GrAnnotation[] rawAnnotations = modifierList.getRawAnnotations(); + + if (!hasAliases(rawAnnotations)) return rawAnnotations; + + List result = ContainerUtil.newArrayList(); + for (GrAnnotation annotation : rawAnnotations) { + final PsiElement resolved = annotation.getClassReference().resolve(); + final GrAnnotation annotationCollector = findAnnotationCollector(resolved); + if (annotationCollector != null) { + collectAnnotations(result, annotation, annotationCollector); + } + else { + result.add(annotation); + } + } + + + return result.toArray(new GrAnnotation[result.size()]); + } + + private static boolean hasAliases(GrAnnotation[] rawAnnotations) { + for (GrAnnotation annotation : rawAnnotations) { + final PsiElement resolved = annotation.getClassReference().resolve(); + final GrAnnotation annotationCollector = findAnnotationCollector(resolved); + if (annotationCollector != null) { + return true; + } + } + + return false; + } + + public static void collectAnnotations(@NotNull List list, + @NotNull GrAnnotation alias, + @NotNull GrAnnotation annotationCollector) { + + final GrModifierList modifierList = (GrModifierList)annotationCollector.getParent(); + + Map> annotations = ContainerUtil.newHashMap(); + collectAliasedAnnotationsFromAnnotationCollectorValueAttribute(annotationCollector, + (HashMap>)annotations); + collectAliasedAnnotationsFromAnnotationCollectorAnnotations(modifierList, + (HashMap>)annotations); + + final PsiManager manager = alias.getManager(); + final GrAnnotationNameValuePair[] attributes = alias.getParameterList().getAttributes(); + + 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; + + final GrLightAnnotation annotation = new GrLightAnnotation(manager, alias.getLanguage(), qname, modifierList); + + Set usedAttrs = ContainerUtil.newHashSet(); + for (GrAnnotationNameValuePair attr : attributes) { + final String name = attr.getName() != null ? attr.getName() : "value"; + if (resolved.findMethodsByName(name, false).length > 0) { + annotation.addAttribute(attr); + } + + usedAttrs.add(name); + } + + + final Map defaults = entry.getValue(); + for (Map.Entry defa : defaults.entrySet()) { + if (!usedAttrs.contains(defa.getKey())) { + annotation.addAttribute(defa.getValue()); + } + } + + + list.add(annotation); + } + } + + private static void collectAliasedAnnotationsFromAnnotationCollectorAnnotations(GrModifierList modifierList, + HashMap> annotations) { + for (GrAnnotation annotation : modifierList.getRawAnnotations()) { + final String qname = annotation.getQualifiedName(); + + if (qname == null || qname.equals(GroovyCommonClassNames.GROOVY_TRANSFORM_ANNOTATION_COLLECTOR)) continue; + + for (GrAnnotationNameValuePair pair : annotation.getParameterList().getAttributes()) { + Map map = annotations.get(qname); + if (map == null) { + map = ContainerUtil.newHashMap(); + annotations.put(qname, map); + } + + map.put(pair.getName() != null ? pair.getName() : "value", pair); + } + } + } + + private static void collectAliasedAnnotationsFromAnnotationCollectorValueAttribute(GrAnnotation annotationCollector, + HashMap> annotations) { + final PsiAnnotationMemberValue annotationsFromValue = annotationCollector.findAttributeValue("value"); + + if (annotationsFromValue instanceof GrAnnotationArrayInitializer) { + for (GrAnnotationMemberValue member : ((GrAnnotationArrayInitializer)annotationsFromValue).getInitializers()) { + if (member instanceof GrReferenceExpression) { + final PsiElement resolved = ((GrReferenceExpression)member).resolve(); + if (resolved instanceof PsiClass && ((PsiClass)resolved).isAnnotationType()) { + annotations.put(((PsiClass)resolved).getQualifiedName(), ContainerUtil.newHashMap()); + } + } + } + } + } + + @Nullable + private static GrAnnotation findAnnotationCollector(PsiElement clazz) { + if (clazz instanceof GrTypeDefinition) { + final GrModifierList modifierList = ((GrTypeDefinition)clazz).getModifierList(); + if (modifierList != null) { + for (GrAnnotation annotation : modifierList.getRawAnnotations()) { + if (GroovyCommonClassNames.GROOVY_TRANSFORM_ANNOTATION_COLLECTOR.equals(annotation.getQualifiedName())) { + return annotation; + } + } + } + } + + return null; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java index 2b248a25b6a9..9eff368b816b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/modifiers/GrModifierListImpl.java @@ -19,8 +19,10 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.modifiers; import com.intellij.lang.ASTNode; import com.intellij.psi.*; import com.intellij.psi.stubs.IStubElementType; -import com.intellij.psi.stubs.StubElement; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.ArrayFactory; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; @@ -254,6 +256,12 @@ public class GrModifierListImpl extends GrStubElementBase im } } + @NotNull + @Override + public GrAnnotation[] getRawAnnotations() { + return getStubOrPsiChildren(GroovyElementTypes.ANNOTATION, ARRAY_FACTORY); + } + private void setModifierPropertyInternal(String name, boolean doSet) { if (doSet) { if (isEmptyModifierList()) { @@ -286,7 +294,7 @@ public class GrModifierListImpl extends GrStubElementBase im } private boolean isEmptyModifierList() { - return getTextLength() == 0 || getModifiers().length == 0 && getAnnotations().length == 0; + return getTextLength() == 0 || getModifiers().length == 0 && getRawAnnotations().length == 0; } @Nullable @@ -311,31 +319,26 @@ public class GrModifierListImpl extends GrStubElementBase im @NotNull public GrAnnotation[] getAnnotations() { - return getStubOrPsiChildren(GroovyElementTypes.ANNOTATION, ARRAY_FACTORY); + return CachedValuesManager.getManager(getProject()).createCachedValue(new CachedValueProvider() { + @Nullable + @Override + public Result compute() { + return Result.create(GrAnnotationCollector.getResolvedAnnotations(GrModifierListImpl.this), PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); + } + }).getValue(); } @NotNull public PsiAnnotation[] getApplicableAnnotations() { + //todo[medvedev] return getAnnotations(); } @Nullable public PsiAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) { - final GrModifierListStub stub = getStub(); - if (stub != null) { - for (StubElement stubElement : stub.getChildrenStubs()) { - final PsiElement child = stubElement.getPsi(); - if (child instanceof PsiAnnotation && qualifiedName.equals(((PsiAnnotation)child).getQualifiedName())) { - return (PsiAnnotation)child; - } - } - } else { - PsiElement child = getFirstChild(); - while (child != null) { - if (child instanceof PsiAnnotation && qualifiedName.equals(((PsiAnnotation)child).getQualifiedName())) { - return (PsiAnnotation)child; - } - child = child.getNextSibling(); + for (GrAnnotation annotation : getAnnotations()) { + if (qualifiedName.equals(annotation.getQualifiedName())) { + return annotation; } } return null; 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 1f8351fda0d6..19592353d2d9 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 @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import com.intellij.psi.PsiJavaCodeReferenceElement; import com.intellij.psi.PsiManager; import com.intellij.psi.impl.light.LightElement; import com.intellij.psi.meta.PsiMetaData; +import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -32,11 +33,13 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation. import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; +import java.util.List; + /** * @author Max Medvedev */ public class GrLightAnnotation extends LightElement implements GrAnnotation { - private final GrEmptyAnnotationArgumentList myAnnotationArgList; + private final GrLightAnnotationArgumentList myAnnotationArgList; private final String myQualifiedName; private PsiAnnotationOwner myOwner; @@ -47,7 +50,7 @@ public class GrLightAnnotation extends LightElement implements GrAnnotation { myQualifiedName = qualifiedName; myOwner = owner; - myAnnotationArgList = new GrEmptyAnnotationArgumentList(manager, language); + myAnnotationArgList = new GrLightAnnotationArgumentList(manager, language); myRef = new GrLightClassReferenceElement(qualifiedName, qualifiedName, this); } @@ -119,15 +122,34 @@ public class GrLightAnnotation extends LightElement implements GrAnnotation { return null; } - private static class GrEmptyAnnotationArgumentList extends LightElement implements GrAnnotationArgumentList { - private GrEmptyAnnotationArgumentList(PsiManager manager, Language language) { + public void addAttribute(GrAnnotationNameValuePair attribute) { + myAnnotationArgList.addAttribute(attribute); + } + + + private static class GrLightAnnotationArgumentList extends LightElement implements GrAnnotationArgumentList { + private List myAttributes = null; + private GrAnnotationNameValuePair[] myCachedAttributes = GrAnnotationNameValuePair.EMPTY_ARRAY; + + + private GrLightAnnotationArgumentList(PsiManager manager, Language language) { super(manager, language); } @NotNull @Override public GrAnnotationNameValuePair[] getAttributes() { - return GrAnnotationNameValuePair.EMPTY_ARRAY; + if (myCachedAttributes == null) { + assert myAttributes != null; + myCachedAttributes = myAttributes.toArray(new GrAnnotationNameValuePair[myAttributes.size()]); + } + return myCachedAttributes; + } + + public void addAttribute(@NotNull GrAnnotationNameValuePair attribute) { + if (myAttributes == null) myAttributes = ContainerUtilRt.newArrayList(); + myAttributes.add(attribute); + myCachedAttributes = null; } @Override @@ -137,12 +159,16 @@ public class GrLightAnnotation extends LightElement implements GrAnnotation { @Override public void acceptChildren(GroovyElementVisitor visitor) { - //todo + if (myAttributes != null) { + for (GrAnnotationNameValuePair attribute : myAttributes) { + attribute.accept(visitor); + } + } } @Override public String toString() { - return "light empty annotation argument list"; + return "light annotation argument list"; } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightModifierList.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightModifierList.java index caf41b1982df..e274d65963da 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightModifierList.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/synthetic/GrLightModifierList.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -89,6 +89,12 @@ public class GrLightModifierList extends LightElement implements GrModifierList throw new IncorrectOperationException(); } + @NotNull + @Override + public GrAnnotation[] getRawAnnotations() { + return getAnnotations(); + } + public void checkSetModifierProperty(@NotNull String name, boolean value) throws IncorrectOperationException{ throw new IncorrectOperationException(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/GrStubUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/GrStubUtils.java index c02dc8aa30cb..c635b6c699af 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/GrStubUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/GrStubUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,7 +84,7 @@ public class GrStubUtils { List annoNames = ContainerUtil.newArrayList(); final PsiModifierList modifierList = psi.getModifierList(); if (modifierList instanceof GrModifierList) { - for (GrAnnotation annotation : ((GrModifierList)modifierList).getAnnotations()) { + for (GrAnnotation annotation : ((GrModifierList)modifierList).getRawAnnotations()) { final String name = annotation.getShortName(); if (StringUtil.isNotEmpty(name)) { annoNames.add(name); 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 da4ed41de762..e21f7c55a0d0 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 @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,6 +59,7 @@ public final class GroovyCommonClassNames { public static final String GROOVY_LANG_IMMUTABLE = "groovy.lang.Immutable"; @NonNls public static final String GROOVY_LANG_META_CLASS = "groovy.lang.MetaClass"; @NonNls public static final String GROOVY_LANG_GROOVY_CALLABLE = "groovy.lang.GroovyCallable"; + @NonNls public static final String GROOVY_TRANSFORM_ANNOTATION_COLLECTOR = "groovy.transform.AnnotationCollector"; private GroovyCommonClassNames() { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/LightGroovyTestCase.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/LightGroovyTestCase.groovy index 5d46fd877663..4e8eb4cf3117 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/LightGroovyTestCase.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/LightGroovyTestCase.groovy @@ -102,6 +102,20 @@ public class LinkedHashMap extends HashMap implements Map { }""" } + protected final void addAnnotationCollector() { + myFixture.addClass '''\ +package groovy.transform; + +@java.lang.annotation.Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE}) +public @interface AnnotationCollector { + String processor() default "org.codehaus.groovy.transform.AnnotationCollectorTransform"; + Class[] value() default {}; +} +''' + } + /*void addHashMap() { myFixture.addClass('''\ package java.util; diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/aliasAnnotations/GrAnnotationCollectorTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/aliasAnnotations/GrAnnotationCollectorTest.groovy new file mode 100644 index 000000000000..703ef9c6c471 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/aliasAnnotations/GrAnnotationCollectorTest.groovy @@ -0,0 +1,128 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.lang.aliasAnnotations + +import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.annotations.NonNls +import org.jetbrains.annotations.NotNull +import org.jetbrains.plugins.groovy.LightGroovyTestCase +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.typedef.GrTypeDefinition + +/** + * @author Max Medvedev + */ +class GrAnnotationCollectorTest extends LightGroovyTestCase { + final String basePath = null + + void testAnnotatedAlias() { + doTest('''\ +import groovy.transform.* + +@AnnotationCollector([ToString, EqualsAndHashCode, Immutable]) +@interface Alias {} + +@Alias(excludes = ["a"]) +class Foo { + Integer a, b +} +''', '''\ +@ToString(excludes = ["a"]) +@EqualsAndHashCode(excludes = ["a"]) +@Immutable +''') + } + + void testAliasWithProperties() { + doTest('''\ +import groovy.transform.* + +@AnnotationCollector([ToString, EqualsAndHashCode, Immutable]) +@interface Alias {} + +@Alias(excludes = ["a"]) +class Foo { + Integer a, b +} +''', '''\ +@ToString(excludes = ["a"]) +@EqualsAndHashCode(excludes = ["a"]) +@Immutable +''') + } + + void testMixedProperties() { + doTest('''\ +import groovy.transform.* + +@ToString(excludes = ['a', 'b']) +@AnnotationCollector([EqualsAndHashCode, Immutable]) +@interface Alias {} + +@Alias(excludes = ["a"]) +class Foo { + Integer a, b +} +''', '''\ +@ToString(excludes = ["a"]) +@EqualsAndHashCode(excludes = ["a"]) +@Immutable +''') + } + + + void doTest(@NotNull String text, @NotNull String expectedAnnotations) { + addAnnotationCollector() + myFixture.configureByText('_a.groovy', text) + final atCaret = myFixture.file.findElementAt(myFixture.editor.caretModel.offset) + final clazz = PsiTreeUtil.getParentOfType(atCaret, GrTypeDefinition.class) + assertNotNull(clazz) + + final actual = getActualAnnotations(clazz) + + assertEquals(expectedAnnotations, actual) + } + + @NotNull + @NonNls + static String getActualAnnotations(@NotNull GrTypeDefinition clazz) { + StringBuilder buffer = new StringBuilder() + + for (GrAnnotation annotation : clazz.modifierList.annotations) { + buffer << '@' << annotation.shortName + + final GrAnnotationNameValuePair[] attributes = annotation.parameterList.attributes + if (attributes.length > 0) { + buffer << '(' + + for (GrAnnotationNameValuePair pair : attributes) { + final name = pair.name + if (name != null) { + buffer << name << " = " + } + + buffer << pair.value.text + } + + buffer << ')' + } + buffer << '\n' + } + + return buffer.toString() + } +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrHighlightingTestBase.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrHighlightingTestBase.groovy index 3401322835af..f022a4c015cf 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrHighlightingTestBase.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrHighlightingTestBase.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,9 @@ import org.jetbrains.plugins.groovy.util.TestUtils * @author Max Medvedev */ abstract class GrHighlightingTestBase extends LightGroovyTestCase { - final String basePath = TestUtils.testDataPath + 'highlighting/' + String getBasePath() { + TestUtils.testDataPath + 'highlighting/' + } InspectionProfileEntry[] getCustomInspections() {[]}