[groovy] make name value pair detachable (IDEA-CR-14566)

This commit is contained in:
Daniil Ovchinnikov
2016-10-17 22:52:42 +03:00
parent c9efc8f6be
commit fa3c7ee92c
3 changed files with 45 additions and 7 deletions
@@ -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
@@ -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<GrNameValuePairStub>
@@ -97,6 +99,34 @@ public class GrAnnotationNameValuePairImpl extends GrStubElementBase<GrNameValue
return null;
}
private volatile Reference<PsiAnnotationMemberValue> 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);
@@ -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
}
}
}