[groovy] GrTraitType: aggregate PsiIntersection type instead of inheriting

This commit is contained in:
Daniil Ovchinnikov
2015-11-10 17:46:56 +03:00
parent 6a1844b043
commit e1624c785b
2 changed files with 66 additions and 15 deletions
@@ -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<PsiType> flatten(PsiType[] conjuncts, Set<PsiType> types) {
public static Set<PsiType> flatten(PsiType[] conjuncts, Set<PsiType> types) {
for (PsiType conjunct : conjuncts) {
if (conjunct instanceof PsiIntersectionType) {
PsiIntersectionType type = (PsiIntersectionType)conjunct;
@@ -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<PsiType> 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> A accept(@NotNull PsiTypeVisitor<A> 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<PsiType> 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<PsiType> types) {
final Set<PsiType> flattened = flatten(types.toArray(createArray(types.size())), new LinkedHashSet<PsiType>() {
return createTraitClassType(types.toArray(PsiType.createArray(types.size())));
}
@NotNull
public static PsiType createTraitClassType(@NotNull PsiType[] types) {
final Set<PsiType> flattened = PsiIntersectionType.flatten(types, new LinkedHashSet<PsiType>() {
@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));
}
}
}