From e1624c785bbec39cd78ce9a356e3799a53d89e7c Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Tue, 10 Nov 2015 17:42:48 +0300 Subject: [PATCH] [groovy] GrTraitType: aggregate PsiIntersection type instead of inheriting --- .../com/intellij/psi/PsiIntersectionType.java | 4 +- .../groovy/lang/psi/impl/GrTraitType.java | 77 +++++++++++++++---- 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java b/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java index 3eec614acb26..c7086fc455d8 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java @@ -32,7 +32,7 @@ import java.util.*; public class PsiIntersectionType extends PsiType.Stub { private final PsiType[] myConjuncts; - protected PsiIntersectionType(@NotNull PsiType[] conjuncts) { + private PsiIntersectionType(@NotNull PsiType[] conjuncts) { super(PsiAnnotation.EMPTY_ARRAY); myConjuncts = conjuncts; } @@ -67,7 +67,7 @@ public class PsiIntersectionType extends PsiType.Stub { } } - protected static Set flatten(PsiType[] conjuncts, Set types) { + public static Set flatten(PsiType[] conjuncts, Set types) { for (PsiType conjunct : conjuncts) { if (conjunct instanceof PsiIntersectionType) { PsiIntersectionType type = (PsiIntersectionType)conjunct; diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTraitType.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTraitType.java index 3faf99eaa8d8..14919a14155d 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTraitType.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrTraitType.java @@ -16,12 +16,12 @@ package org.jetbrains.plugins.groovy.lang.psi.impl; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiClassType; -import com.intellij.psi.PsiIntersectionType; -import com.intellij.psi.PsiType; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTypesUtil; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -33,15 +33,17 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -public class GrTraitType extends PsiIntersectionType { +public class GrTraitType extends PsiType { + private final @NotNull PsiIntersectionType myDelegate; private final @NotNull PsiType myExprType; private final @NotNull List myTraitTypes; - private GrTraitType(@NotNull PsiType[] types) { - super(types); - myExprType = types[0]; - myTraitTypes = ContainerUtil.newArrayList(types, 1, types.length); + private GrTraitType(@NotNull PsiIntersectionType delegate) { + super(PsiAnnotation.EMPTY_ARRAY); + myDelegate = delegate; + myExprType = delegate.getConjuncts()[0]; + myTraitTypes = ContainerUtil.newArrayList(delegate.getConjuncts(), 1, delegate.getConjuncts().length); } @NotNull @@ -54,6 +56,11 @@ public class GrTraitType extends PsiIntersectionType { return myTraitTypes; } + @NotNull + public PsiType[] getConjuncts() { + return myDelegate.getConjuncts(); + } + @NotNull @Override public String getPresentableText() { @@ -65,6 +72,12 @@ public class GrTraitType extends PsiIntersectionType { }), ", "); } + @NotNull + @Override + public String getCanonicalText() { + return myDelegate.getCanonicalText(); + } + @NotNull @Override public String getInternalCanonicalText() { @@ -76,6 +89,33 @@ public class GrTraitType extends PsiIntersectionType { }), ", "); } + @Override + public boolean isValid() { + return myDelegate.isValid(); + } + + @Override + public boolean equalsToText(@NotNull @NonNls String text) { + return myDelegate.equalsToText(text); + } + + @Override + public A accept(@NotNull PsiTypeVisitor visitor) { + return myDelegate.accept(visitor); + } + + @Nullable + @Override + public GlobalSearchScope getResolveScope() { + return myDelegate.getResolveScope(); + } + + @NotNull + @Override + public PsiType[] getSuperTypes() { + return myDelegate.getSuperTypes(); + } + // todo move this method to org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.types.GrSafeCastExpressionImpl @Nullable public static PsiType createTraitClassType(@NotNull GrSafeCastExpression safeCastExpression) { @@ -91,20 +131,31 @@ public class GrTraitType extends PsiIntersectionType { return createTraitClassType(exprType, ContainerUtil.newSmartList(type)); } + @NotNull public static PsiType createTraitClassType(@NotNull PsiType type, @NotNull List traits) { - return createTraitClassType(ContainerUtil.prepend(traits, type)); + return createTraitClassType(ContainerUtil.prepend(traits, type instanceof GrTraitType ? ((GrTraitType)type).myDelegate : type)); } + @NotNull public static PsiType createTraitClassType(@NotNull List types) { - final Set flattened = flatten(types.toArray(createArray(types.size())), new LinkedHashSet() { + return createTraitClassType(types.toArray(PsiType.createArray(types.size()))); + } + + @NotNull + public static PsiType createTraitClassType(@NotNull PsiType[] types) { + final Set flattened = PsiIntersectionType.flatten(types, new LinkedHashSet() { @Override public boolean add(PsiType type) { remove(type); return super.add(type); } }); - final PsiType[] conjuncts = flattened.toArray(createArray(flattened.size())); - if (conjuncts.length == 1) return conjuncts[0]; - return new GrTraitType(conjuncts); + final PsiType[] conjuncts = flattened.toArray(PsiType.createArray(flattened.size())); + if (conjuncts.length == 1) { + return conjuncts[0]; + } + else { + return new GrTraitType((PsiIntersectionType)PsiIntersectionType.createIntersection(false, conjuncts)); + } } }