[NI] Approximate captured types when set them into variable.
Also do not store type with captured type inside possible types. It is hack for now, but without it captured types can flow to resolution and exception will be thrown.
This commit is contained in:
@@ -86,6 +86,7 @@ public class DescriptorResolver {
|
|||||||
private final ModifiersChecker modifiersChecker;
|
private final ModifiersChecker modifiersChecker;
|
||||||
private final WrappedTypeFactory wrappedTypeFactory;
|
private final WrappedTypeFactory wrappedTypeFactory;
|
||||||
private final SyntheticResolveExtension syntheticResolveExtension;
|
private final SyntheticResolveExtension syntheticResolveExtension;
|
||||||
|
private final TypeApproximator typeApproximator;
|
||||||
|
|
||||||
public DescriptorResolver(
|
public DescriptorResolver(
|
||||||
@NotNull AnnotationResolver annotationResolver,
|
@NotNull AnnotationResolver annotationResolver,
|
||||||
@@ -101,7 +102,8 @@ public class DescriptorResolver {
|
|||||||
@NotNull DestructuringDeclarationResolver destructuringDeclarationResolver,
|
@NotNull DestructuringDeclarationResolver destructuringDeclarationResolver,
|
||||||
@NotNull ModifiersChecker modifiersChecker,
|
@NotNull ModifiersChecker modifiersChecker,
|
||||||
@NotNull WrappedTypeFactory wrappedTypeFactory,
|
@NotNull WrappedTypeFactory wrappedTypeFactory,
|
||||||
@NotNull Project project
|
@NotNull Project project,
|
||||||
|
TypeApproximator approximator
|
||||||
) {
|
) {
|
||||||
this.annotationResolver = annotationResolver;
|
this.annotationResolver = annotationResolver;
|
||||||
this.builtIns = builtIns;
|
this.builtIns = builtIns;
|
||||||
@@ -117,6 +119,7 @@ public class DescriptorResolver {
|
|||||||
this.modifiersChecker = modifiersChecker;
|
this.modifiersChecker = modifiersChecker;
|
||||||
this.wrappedTypeFactory = wrappedTypeFactory;
|
this.wrappedTypeFactory = wrappedTypeFactory;
|
||||||
this.syntheticResolveExtension = SyntheticResolveExtension.Companion.getInstance(project);
|
this.syntheticResolveExtension = SyntheticResolveExtension.Companion.getInstance(project);
|
||||||
|
typeApproximator = approximator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<KotlinType> resolveSupertypes(
|
public List<KotlinType> resolveSupertypes(
|
||||||
@@ -666,11 +669,12 @@ public class DescriptorResolver {
|
|||||||
BindingTrace trace,
|
BindingTrace trace,
|
||||||
@NotNull LexicalScope scope
|
@NotNull LexicalScope scope
|
||||||
) {
|
) {
|
||||||
|
UnwrappedType approximatedType = typeApproximator.approximateDeclarationType(type, true);
|
||||||
VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
|
VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
|
||||||
scope.getOwnerDescriptor(),
|
scope.getOwnerDescriptor(),
|
||||||
annotationResolver.resolveAnnotationsWithArguments(scope, parameter.getModifierList(), trace),
|
annotationResolver.resolveAnnotationsWithArguments(scope, parameter.getModifierList(), trace),
|
||||||
KtPsiUtil.safeName(parameter.getName()),
|
KtPsiUtil.safeName(parameter.getName()),
|
||||||
type,
|
approximatedType,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
KotlinSourceElementKt.toSourceElement(parameter)
|
KotlinSourceElementKt.toSourceElement(parameter)
|
||||||
|
|||||||
+13
-8
@@ -38,7 +38,8 @@ class VariableTypeAndInitializerResolver(
|
|||||||
private val typeResolver: TypeResolver,
|
private val typeResolver: TypeResolver,
|
||||||
private val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
private val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
||||||
private val delegatedPropertyResolver: DelegatedPropertyResolver,
|
private val delegatedPropertyResolver: DelegatedPropertyResolver,
|
||||||
private val wrappedTypeFactory: WrappedTypeFactory
|
private val wrappedTypeFactory: WrappedTypeFactory,
|
||||||
|
private val typeApproximator: TypeApproximator
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
@@ -76,7 +77,7 @@ class VariableTypeAndInitializerResolver(
|
|||||||
|
|
||||||
!variable.hasInitializer() && variable is KtProperty && variableDescriptor is VariableDescriptorWithAccessors &&
|
!variable.hasInitializer() && variable is KtProperty && variableDescriptor is VariableDescriptorWithAccessors &&
|
||||||
variable.hasDelegateExpression() ->
|
variable.hasDelegateExpression() ->
|
||||||
resolveDelegatedPropertyType(variable, variableDescriptor, scopeForInitializer, dataFlowInfo, trace)
|
resolveDelegatedPropertyType(variable, variableDescriptor, scopeForInitializer, dataFlowInfo, trace, local)
|
||||||
|
|
||||||
variable.hasInitializer() -> when {
|
variable.hasInitializer() -> when {
|
||||||
!local ->
|
!local ->
|
||||||
@@ -84,11 +85,11 @@ class VariableTypeAndInitializerResolver(
|
|||||||
trace
|
trace
|
||||||
) {
|
) {
|
||||||
PreliminaryDeclarationVisitor.createForDeclaration(variable, trace)
|
PreliminaryDeclarationVisitor.createForDeclaration(variable, trace)
|
||||||
val initializerType = resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace)
|
val initializerType = resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local)
|
||||||
transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace)
|
transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace)
|
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local)
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -129,7 +130,8 @@ class VariableTypeAndInitializerResolver(
|
|||||||
variableDescriptor: VariableDescriptorWithAccessors,
|
variableDescriptor: VariableDescriptorWithAccessors,
|
||||||
scopeForInitializer: LexicalScope,
|
scopeForInitializer: LexicalScope,
|
||||||
dataFlowInfo: DataFlowInfo,
|
dataFlowInfo: DataFlowInfo,
|
||||||
trace: BindingTrace
|
trace: BindingTrace,
|
||||||
|
local: Boolean
|
||||||
) = wrappedTypeFactory.createRecursionIntolerantDeferredType(trace) {
|
) = wrappedTypeFactory.createRecursionIntolerantDeferredType(trace) {
|
||||||
val delegateExpression = property.delegateExpression!!
|
val delegateExpression = property.delegateExpression!!
|
||||||
val type = delegatedPropertyResolver.resolveDelegateExpression(
|
val type = delegatedPropertyResolver.resolveDelegateExpression(
|
||||||
@@ -139,15 +141,18 @@ class VariableTypeAndInitializerResolver(
|
|||||||
variableDescriptor, delegateExpression, type, trace, scopeForInitializer, dataFlowInfo
|
variableDescriptor, delegateExpression, type, trace, scopeForInitializer, dataFlowInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
getterReturnType ?: ErrorUtils.createErrorType("Type from delegate")
|
getterReturnType?.let { approximateType(it, local) } ?: ErrorUtils.createErrorType("Type from delegate")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveInitializerType(
|
private fun resolveInitializerType(
|
||||||
scope: LexicalScope,
|
scope: LexicalScope,
|
||||||
initializer: KtExpression,
|
initializer: KtExpression,
|
||||||
dataFlowInfo: DataFlowInfo,
|
dataFlowInfo: DataFlowInfo,
|
||||||
trace: BindingTrace
|
trace: BindingTrace,
|
||||||
|
local: Boolean
|
||||||
): KotlinType {
|
): KotlinType {
|
||||||
return expressionTypingServices.safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace)
|
return approximateType(expressionTypingServices.safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace), local)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun approximateType(type: KotlinType, local: Boolean): UnwrappedType = typeApproximator.approximateDeclarationType(type, local)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -28,6 +28,8 @@ import org.jetbrains.kotlin.types.isError
|
|||||||
import org.jetbrains.kotlin.types.isFlexible
|
import org.jetbrains.kotlin.types.isFlexible
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||||
import org.jetbrains.kotlin.utils.newLinkedHashSetWithExpectedSize
|
import org.jetbrains.kotlin.utils.newLinkedHashSetWithExpectedSize
|
||||||
|
import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
internal class DelegatingDataFlowInfo private constructor(
|
internal class DelegatingDataFlowInfo private constructor(
|
||||||
@@ -329,7 +331,7 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
for (value in typeInfo.keys()) {
|
for (value in typeInfo.keys()) {
|
||||||
for (type in typeInfo[value]) {
|
for (type in typeInfo[value]) {
|
||||||
// Remove original type (see also KT-10666)
|
// Remove original type (see also KT-10666)
|
||||||
if (value.type == type) {
|
if (value.type == type || type.contains { it.constructor is NewCapturedTypeConstructor }) {
|
||||||
toDelete.put(value, type)
|
toDelete.put(value, type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.types
|
package org.jetbrains.kotlin.types
|
||||||
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.CommonSupertypeCalculator
|
import org.jetbrains.kotlin.resolve.calls.components.CommonSupertypeCalculator
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.USE_NEW_INFERENCE
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor
|
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor
|
||||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration.IntersectionStrategy.*
|
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration.IntersectionStrategy.*
|
||||||
import org.jetbrains.kotlin.types.checker.*
|
import org.jetbrains.kotlin.types.checker.*
|
||||||
@@ -58,6 +59,7 @@ open class TypeApproximatorConfiguration {
|
|||||||
|
|
||||||
object PublicDeclaration : AllFlexibleSameValue() {
|
object PublicDeclaration : AllFlexibleSameValue() {
|
||||||
override val allFlexible get() = true
|
override val allFlexible get() = true
|
||||||
|
override val errorType get() = true
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AbstractCapturedTypesApproximation(val approximatedCapturedStatus: CaptureStatus): TypeApproximatorConfiguration.AllFlexibleSameValue() {
|
abstract class AbstractCapturedTypesApproximation(val approximatedCapturedStatus: CaptureStatus): TypeApproximatorConfiguration.AllFlexibleSameValue() {
|
||||||
@@ -78,6 +80,12 @@ class TypeApproximator(private val commonSupertypeCalculator: CommonSupertypeCal
|
|||||||
private val referenceApproximateToSuperType = this::approximateToSuperType
|
private val referenceApproximateToSuperType = this::approximateToSuperType
|
||||||
private val referenceApproximateToSubType = this::approximateToSubType
|
private val referenceApproximateToSubType = this::approximateToSubType
|
||||||
|
|
||||||
|
fun approximateDeclarationType(baseType: KotlinType, local: Boolean): UnwrappedType {
|
||||||
|
if (!USE_NEW_INFERENCE) return baseType.unwrap()
|
||||||
|
|
||||||
|
val configuration = if (local) TypeApproximatorConfiguration.LocalDeclaration else TypeApproximatorConfiguration.PublicDeclaration
|
||||||
|
return approximateToSuperType(baseType.unwrap(), configuration) ?: baseType.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
// null means that this input type is the result, i.e. input type not contains not-allowed kind of types
|
// null means that this input type is the result, i.e. input type not contains not-allowed kind of types
|
||||||
// type <: resultType
|
// type <: resultType
|
||||||
|
|||||||
Reference in New Issue
Block a user