Fix KotlinTypeCheckerTest in accordance with NI intersections

This commit is contained in:
Mikhail Glukhikh
2022-07-28 08:54:04 +02:00
committed by teamcity
parent 0198eeeafe
commit 3cb4b8ddda
3 changed files with 62 additions and 33 deletions
@@ -24,11 +24,12 @@ public class TypeResolutionContext {
public final BindingTrace trace;
public final boolean checkBounds;
public final boolean allowBareTypes;
public final boolean allowIntersectionTypes;
public final boolean isDebuggerContext;
public final boolean abbreviated;
public TypeResolutionContext(@NotNull LexicalScope scope, @NotNull BindingTrace trace, boolean checkBounds, boolean allowBareTypes, boolean isDebuggerContext) {
this(scope, trace, checkBounds, allowBareTypes, isDebuggerContext, false);
this(scope, trace, checkBounds, allowBareTypes, isDebuggerContext, false, false);
}
public TypeResolutionContext(
@@ -38,6 +39,18 @@ public class TypeResolutionContext {
boolean allowBareTypes,
boolean isDebuggerContext,
boolean abbreviated
) {
this(scope, trace, checkBounds, allowBareTypes, isDebuggerContext, abbreviated, false);
}
public TypeResolutionContext(
@NotNull LexicalScope scope,
@NotNull BindingTrace trace,
boolean checkBounds,
boolean allowBareTypes,
boolean isDebuggerContext,
boolean abbreviated,
boolean allowIntersectionTypes
) {
this.scope = scope;
this.trace = trace;
@@ -45,10 +58,11 @@ public class TypeResolutionContext {
this.allowBareTypes = allowBareTypes;
this.isDebuggerContext = isDebuggerContext;
this.abbreviated = abbreviated;
this.allowIntersectionTypes = allowIntersectionTypes;
}
@NotNull
public TypeResolutionContext noBareTypes() {
return new TypeResolutionContext(scope, trace, checkBounds, false, isDebuggerContext, abbreviated);
return new TypeResolutionContext(scope, trace, checkBounds, false, isDebuggerContext, abbreviated, allowIntersectionTypes);
}
}
@@ -86,6 +86,14 @@ class TypeResolver(
open fun transformType(kotlinType: KotlinType): KotlinType? = null
}
// Entry point for KotlinTypeCheckerTest
fun resolveTypeWithPossibleIntersections(scope: LexicalScope, typeReference: KtTypeReference, trace: BindingTrace): KotlinType {
return resolveType(
TypeResolutionContext(scope, trace, false, false, typeReference.suppressDiagnosticsInDebugMode(), false, true),
typeReference
)
}
fun resolveType(scope: LexicalScope, typeReference: KtTypeReference, trace: BindingTrace, checkBounds: Boolean): KotlinType {
// bare types are not allowed
return resolveType(
@@ -322,37 +330,41 @@ class TypeResolver(
}
}
if (!languageVersionSettings.supportsFeature(LanguageFeature.DefinitelyNonNullableTypes)) {
c.trace.report(
UNSUPPORTED_FEATURE.on(
intersectionType,
LanguageFeature.DefinitelyNonNullableTypes to languageVersionSettings
if (!c.allowIntersectionTypes) {
if (!languageVersionSettings.supportsFeature(LanguageFeature.DefinitelyNonNullableTypes)) {
c.trace.report(
UNSUPPORTED_FEATURE.on(
intersectionType,
LanguageFeature.DefinitelyNonNullableTypes to languageVersionSettings
)
)
)
return
return
}
if (!leftType.isTypeParameter() || leftType.isMarkedNullable || !leftType.isNullableOrUninitializedTypeParameter()) {
c.trace.report(INCORRECT_LEFT_COMPONENT_OF_INTERSECTION.on(intersectionType.getLeftTypeRef()!!))
return
}
if (!rightType.isAny()) {
c.trace.report(INCORRECT_RIGHT_COMPONENT_OF_INTERSECTION.on(intersectionType.getRightTypeRef()!!))
return
}
val definitelyNotNullType =
DefinitelyNotNullType.makeDefinitelyNotNull(leftType.unwrap())
?: error(
"Definitely not-nullable type is not created for type parameter with nullable upper bound ${
TypeUtils.getTypeParameterDescriptorOrNull(
leftType
)!!
}"
)
result = type(definitelyNotNullType)
} else {
result = type(IntersectionTypeConstructor(listOf(leftType, rightType)).createType())
}
if (!leftType.isTypeParameter() || leftType.isMarkedNullable || !leftType.isNullableOrUninitializedTypeParameter()) {
c.trace.report(INCORRECT_LEFT_COMPONENT_OF_INTERSECTION.on(intersectionType.getLeftTypeRef()!!))
return
}
if (!rightType.isAny()) {
c.trace.report(INCORRECT_RIGHT_COMPONENT_OF_INTERSECTION.on(intersectionType.getRightTypeRef()!!))
return
}
val definitelyNotNullType =
DefinitelyNotNullType.makeDefinitelyNotNull(leftType.unwrap())
?: error(
"Definitely not-nullable type is not created for type parameter with nullable upper bound ${
TypeUtils.getTypeParameterDescriptorOrNull(
leftType
)!!
}"
)
result = type(definitelyNotNullType)
}
private fun KotlinType.isNullableOrUninitializedTypeParameter(): Boolean {
@@ -28,8 +28,10 @@ import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl;
import org.jetbrains.kotlin.psi.KtExpression;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.psi.KtPsiFactoryKt;
import org.jetbrains.kotlin.psi.KtTypeReference;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingTraceContext;
import org.jetbrains.kotlin.resolve.TypeResolutionContext;
import org.jetbrains.kotlin.resolve.TypeResolver;
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory;
@@ -174,7 +176,7 @@ public class KotlinTypeCheckerTest extends KotlinTestWithEnvironment {
assertCommonSupertype("Derived_T<Int>", "DDerived_T<Int>", "Derived_T<Int>");
assertCommonSupertype("Derived_T<Int>", "DDerived_T<Int>", "DDerived1_T<Int>");
assertCommonSupertype("Comparable<*>", "Comparable<Int>", "Comparable<Boolean>");
assertCommonSupertype("Comparable<Boolean & Int>", "Comparable<Int>", "Comparable<Boolean>");
assertCommonSupertype("Base_T<out I>", "Base_T<AI>", "Base_T<BI>");
assertCommonSupertype("Base_T<in Int>", "Base_T<Int>", "Base_T<in Int>");
assertCommonSupertype("Base_T<in Int>", "Derived_T<Int>", "Base_T<in Int>");
@@ -585,6 +587,7 @@ public class KotlinTypeCheckerTest extends KotlinTestWithEnvironment {
}
private KotlinType makeType(LexicalScope scope, String typeStr) {
return typeResolver.resolveType(scope, KtPsiFactoryKt.KtPsiFactory(getProject()).createType(typeStr), DummyTraces.DUMMY_TRACE, true);
KtTypeReference typeReference = KtPsiFactoryKt.KtPsiFactory(getProject()).createType(typeStr);
return typeResolver.resolveTypeWithPossibleIntersections(scope, typeReference, DummyTraces.DUMMY_TRACE);
}
}