From fa3c7ee92c7b0431ea7a6b824f6cf7cc227f0401 Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Mon, 17 Oct 2016 22:43:25 +0300 Subject: [PATCH] [groovy] make name value pair detachable (IDEA-CR-14566) --- .../annotation/GrAnnotationNameValuePair.java | 3 +- .../GrAnnotationNameValuePairImpl.java | 30 +++++++++++++++++++ .../AutoCloneTransformationSupport.kt | 19 ++++++++---- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/auxiliary/modifiers/annotation/GrAnnotationNameValuePair.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/auxiliary/modifiers/annotation/GrAnnotationNameValuePair.java index 91f81cadf143..96d5523f06f9 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/auxiliary/modifiers/annotation/GrAnnotationNameValuePair.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/api/auxiliary/modifiers/annotation/GrAnnotationNameValuePair.java @@ -25,7 +25,8 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; * @author: Dmitry.Krasilschikov * @date: 04.04.2007 */ -public interface GrAnnotationNameValuePair extends GroovyPsiElement, PsiNameValuePair { +public interface GrAnnotationNameValuePair extends GroovyPsiElement, PsiNameValuePair, PsiNameValuePair.Detachable { + GrAnnotationNameValuePair[] EMPTY_ARRAY = new GrAnnotationNameValuePair[0]; @Nullable diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java index f7d9a16ce5b7..a549bbf1cf95 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java @@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; +import com.intellij.reference.SoftReference; import com.intellij.util.ArrayUtilRt; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtilRt; @@ -42,6 +43,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.modifiers.GrAnnotati import org.jetbrains.plugins.groovy.lang.psi.stubs.GrNameValuePairStub; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; +import java.lang.ref.Reference; import java.util.List; public class GrAnnotationNameValuePairImpl extends GrStubElementBase @@ -97,6 +99,34 @@ public class GrAnnotationNameValuePairImpl extends GrStubElementBase myDetachedValue; + + @Override + @Nullable + public PsiAnnotationMemberValue getDetachedValue() { + GrNameValuePairStub stub = getGreenStub(); + if (stub != null) { + String text = stub.getValue(); + PsiAnnotationMemberValue result = SoftReference.dereference(myDetachedValue); + if (result == null) { + GrAnnotation annotation = GroovyPsiElementFactory.getInstance(getProject()).createAnnotationFromText( + "@F(" + text + ")", this + ); + PsiAnnotationMemberValue value = annotation.findAttributeValue(null); + myDetachedValue = new SoftReference<>(result = value); + } + return result; + } + + return getValue(); + } + + @Override + public void subtreeChanged() { + super.subtreeChanged(); + myDetachedValue = null; + } + @Override public GrAnnotationMemberValue getValue() { return findChildByClass(GrAnnotationMemberValue.class); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/impl/autoClone/AutoCloneTransformationSupport.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/impl/autoClone/AutoCloneTransformationSupport.kt index ebc1235b6d47..6c6990feb7a7 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/impl/autoClone/AutoCloneTransformationSupport.kt +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/impl/autoClone/AutoCloneTransformationSupport.kt @@ -15,10 +15,8 @@ */ package org.jetbrains.plugins.groovy.transformations.impl.autoClone -import com.intellij.psi.CommonClassNames -import com.intellij.psi.PsiEnumConstant -import com.intellij.psi.PsiModifier -import com.intellij.psi.PsiType +import com.intellij.codeInsight.AnnotationUtil +import com.intellij.psi.* import com.intellij.psi.impl.light.LightMethodBuilder import org.jetbrains.plugins.groovy.GroovyLanguage import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression @@ -49,12 +47,12 @@ class AutoCloneTransformationSupport : AstTransformationSupport { originInfo = ORIGIN_INFO } - val value = annotation.findDeclaredAttributeValue("style") as? GrReferenceExpression ?: return + val value = annotation.findDeclaredDetachedValue("style") as? GrReferenceExpression ?: return val constant = value.resolve() as? PsiEnumConstant ?: return if (constant.containingClass?.qualifiedName != "groovy.transform.AutoCloneStyle") return when (constant.name) { "COPY_CONSTRUCTOR" -> { - if (context.codeClass.codeConstructors.size == 0) { + if (context.codeClass.codeConstructors.isEmpty()) { context += LightMethodBuilder(context.codeClass, GroovyLanguage).apply { isConstructor = true addModifier(PsiModifier.PUBLIC) @@ -84,4 +82,13 @@ class AutoCloneTransformationSupport : AstTransformationSupport { } } } + + private fun PsiAnnotation.findDeclaredDetachedValue(attributeName: String?): PsiAnnotationMemberValue? { + val styleAttribute = AnnotationUtil.findDeclaredAttribute(this, attributeName) + return when (styleAttribute) { + null -> null + is PsiNameValuePair.Detachable -> styleAttribute.detachedValue + else -> styleAttribute.value + } + } }