TypeIntersector: refactor it to being a static utility
Deal with intersecting empty set of types on the call site
This commit is contained in:
+4
-1
@@ -176,7 +176,10 @@ class LazyJavaTypeResolver(
|
||||
for (supertype in (classifier() as JavaTypeParameter).getUpperBounds()) {
|
||||
supertypesJet.add(transformJavaType(supertype, UPPER_BOUND.toAttributes()))
|
||||
}
|
||||
return TypeIntersector.intersectTypes(KotlinBuiltIns.getInstance(), JetTypeChecker.DEFAULT, supertypesJet)
|
||||
if (supertypesJet.isEmpty()) {
|
||||
return c.module.builtIns.nullableAnyType
|
||||
}
|
||||
return TypeIntersector.intersectTypes(JetTypeChecker.DEFAULT, supertypesJet)
|
||||
?: ErrorUtils.createErrorType("Can't intersect upper bounds of " + javaType.getPresentableText())
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -136,9 +136,8 @@ public abstract class AbstractTypeParameterDescriptor extends DeclarationDescrip
|
||||
private JetType computeUpperBoundsAsType() {
|
||||
Set<JetType> upperBounds = getUpperBounds();
|
||||
assert !upperBounds.isEmpty() : "Upper bound list is empty in " + getName();
|
||||
KotlinBuiltIns builtIns = getBuiltIns(this);
|
||||
JetType upperBoundsAsType = TypeIntersector.intersectTypes(builtIns, JetTypeChecker.DEFAULT, upperBounds);
|
||||
return upperBoundsAsType != null ? upperBoundsAsType : builtIns.getNothingType();
|
||||
JetType upperBoundsAsType = TypeIntersector.intersectTypes(JetTypeChecker.DEFAULT, upperBounds);
|
||||
return upperBoundsAsType != null ? upperBoundsAsType : getBuiltIns(this).getNothingType();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -135,9 +135,9 @@ public class TypeBoundsImpl(
|
||||
}
|
||||
|
||||
val upperBounds = filterBounds(bounds, TypeBounds.BoundKind.UPPER_BOUND, values)
|
||||
val intersectionOfUpperBounds = TypeIntersector(typeVariable.builtIns).intersect(JetTypeChecker.DEFAULT, upperBounds)
|
||||
if (!upperBounds.isEmpty() && intersectionOfUpperBounds != null) {
|
||||
if (tryPossibleAnswer(bounds, intersectionOfUpperBounds)) {
|
||||
if (upperBounds.isNotEmpty()) {
|
||||
val intersectionOfUpperBounds = TypeIntersector.intersectTypes(JetTypeChecker.DEFAULT, upperBounds)
|
||||
if (intersectionOfUpperBounds != null && tryPossibleAnswer(bounds, intersectionOfUpperBounds)) {
|
||||
return setOf(intersectionOfUpperBounds)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.types.typeUtil.TypeUtilPackage;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
|
||||
import static org.jetbrains.kotlin.types.TypeUtils.topologicallySortSuperclassesAndRecordAllInstances;
|
||||
import static org.jetbrains.kotlin.types.Variance.IN_VARIANCE;
|
||||
import static org.jetbrains.kotlin.types.Variance.OUT_VARIANCE;
|
||||
@@ -299,6 +298,7 @@ public class CommonSupertypes {
|
||||
}
|
||||
|
||||
if (outs != null) {
|
||||
assert !outs.isEmpty() : "Out projections is empty for parameter " + parameterDescriptor + ", type projections " + typeProjections;
|
||||
Variance projectionKind = variance == OUT_VARIANCE ? Variance.INVARIANT : OUT_VARIANCE;
|
||||
JetType superType = findCommonSupertype(outs, recursionDepth + 1, maxDepth);
|
||||
for (JetType upperBound: parameterDescriptor.getUpperBounds()) {
|
||||
@@ -309,7 +309,8 @@ public class CommonSupertypes {
|
||||
return new TypeProjectionImpl(projectionKind, superType);
|
||||
}
|
||||
if (ins != null) {
|
||||
JetType intersection = TypeIntersector.intersectTypes(getBuiltIns(parameterDescriptor), JetTypeChecker.DEFAULT, ins);
|
||||
assert !ins.isEmpty() : "In projections is empty for parameter " + parameterDescriptor + ", type projections " + typeProjections;
|
||||
JetType intersection = TypeIntersector.intersectTypes(JetTypeChecker.DEFAULT, ins);
|
||||
if (intersection == null) {
|
||||
return new TypeProjectionImpl(OUT_VARIANCE, findCommonSupertype(parameterDescriptor.getUpperBounds(), recursionDepth + 1, maxDepth));
|
||||
}
|
||||
|
||||
@@ -37,31 +37,16 @@ import static org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.Co
|
||||
|
||||
public class TypeIntersector {
|
||||
|
||||
private final KotlinBuiltIns builtIns;
|
||||
|
||||
public TypeIntersector(@NotNull KotlinBuiltIns builtIns) {
|
||||
this.builtIns = builtIns;
|
||||
public static boolean isIntersectionEmpty(@NotNull JetType typeA, @NotNull JetType typeB) {
|
||||
return intersectTypes(JetTypeChecker.DEFAULT, new LinkedHashSet<JetType>(Arrays.asList(typeA, typeB))) == null;
|
||||
}
|
||||
|
||||
public boolean isIntersectionEmpty(@NotNull JetType typeA, @NotNull JetType typeB) {
|
||||
return intersect(JetTypeChecker.DEFAULT, new LinkedHashSet<JetType>(Arrays.asList(typeA, typeB))) == null;
|
||||
}
|
||||
|
||||
//TODO: usages of this method should be removed
|
||||
@Nullable
|
||||
public static JetType intersectTypes(
|
||||
@NotNull KotlinBuiltIns builtIns,
|
||||
@NotNull JetTypeChecker typeChecker,
|
||||
@NotNull Set<JetType> types
|
||||
) {
|
||||
return new TypeIntersector(builtIns).intersect(typeChecker, types);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetType intersect(@NotNull JetTypeChecker typeChecker, @NotNull Set<JetType> types) {
|
||||
if (types.isEmpty()) {
|
||||
return builtIns.getNullableAnyType();
|
||||
}
|
||||
assert (!types.isEmpty()) : "Attempting to intersect empty set of types, this case should be dealt with on the call site.";
|
||||
|
||||
if (types.size() == 1) {
|
||||
return types.iterator().next();
|
||||
@@ -69,19 +54,21 @@ public class TypeIntersector {
|
||||
|
||||
// Intersection of T1..Tn is an intersection of their non-null versions,
|
||||
// made nullable is they all were nullable
|
||||
JetType nothingOrNullableNothing = null;
|
||||
boolean allNullable = true;
|
||||
boolean nothingTypePresent = false;
|
||||
List<JetType> nullabilityStripped = new ArrayList<JetType>(types.size());
|
||||
for (JetType type : types) {
|
||||
if (type.isError()) continue;
|
||||
|
||||
nothingTypePresent |= KotlinBuiltIns.isNothingOrNullableNothing(type);
|
||||
if (KotlinBuiltIns.isNothingOrNullableNothing(type)) {
|
||||
nothingOrNullableNothing = type;
|
||||
}
|
||||
allNullable &= type.isMarkedNullable();
|
||||
nullabilityStripped.add(TypeUtils.makeNotNullable(type));
|
||||
}
|
||||
|
||||
if (nothingTypePresent) {
|
||||
return allNullable ? builtIns.getNullableNothingType() : builtIns.getNothingType();
|
||||
if (nothingOrNullableNothing != null) {
|
||||
return TypeUtils.makeNullableAsSpecified(nothingOrNullableNothing, allNullable);
|
||||
}
|
||||
|
||||
if (nullabilityStripped.isEmpty()) {
|
||||
|
||||
Reference in New Issue
Block a user