[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 WrappedTypeFactory wrappedTypeFactory;
|
||||
private final SyntheticResolveExtension syntheticResolveExtension;
|
||||
private final TypeApproximator typeApproximator;
|
||||
|
||||
public DescriptorResolver(
|
||||
@NotNull AnnotationResolver annotationResolver,
|
||||
@@ -101,7 +102,8 @@ public class DescriptorResolver {
|
||||
@NotNull DestructuringDeclarationResolver destructuringDeclarationResolver,
|
||||
@NotNull ModifiersChecker modifiersChecker,
|
||||
@NotNull WrappedTypeFactory wrappedTypeFactory,
|
||||
@NotNull Project project
|
||||
@NotNull Project project,
|
||||
TypeApproximator approximator
|
||||
) {
|
||||
this.annotationResolver = annotationResolver;
|
||||
this.builtIns = builtIns;
|
||||
@@ -117,6 +119,7 @@ public class DescriptorResolver {
|
||||
this.modifiersChecker = modifiersChecker;
|
||||
this.wrappedTypeFactory = wrappedTypeFactory;
|
||||
this.syntheticResolveExtension = SyntheticResolveExtension.Companion.getInstance(project);
|
||||
typeApproximator = approximator;
|
||||
}
|
||||
|
||||
public List<KotlinType> resolveSupertypes(
|
||||
@@ -666,11 +669,12 @@ public class DescriptorResolver {
|
||||
BindingTrace trace,
|
||||
@NotNull LexicalScope scope
|
||||
) {
|
||||
UnwrappedType approximatedType = typeApproximator.approximateDeclarationType(type, true);
|
||||
VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
|
||||
scope.getOwnerDescriptor(),
|
||||
annotationResolver.resolveAnnotationsWithArguments(scope, parameter.getModifierList(), trace),
|
||||
KtPsiUtil.safeName(parameter.getName()),
|
||||
type,
|
||||
approximatedType,
|
||||
false,
|
||||
false,
|
||||
KotlinSourceElementKt.toSourceElement(parameter)
|
||||
|
||||
+13
-8
@@ -38,7 +38,8 @@ class VariableTypeAndInitializerResolver(
|
||||
private val typeResolver: TypeResolver,
|
||||
private val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
||||
private val delegatedPropertyResolver: DelegatedPropertyResolver,
|
||||
private val wrappedTypeFactory: WrappedTypeFactory
|
||||
private val wrappedTypeFactory: WrappedTypeFactory,
|
||||
private val typeApproximator: TypeApproximator
|
||||
) {
|
||||
companion object {
|
||||
@JvmField
|
||||
@@ -76,7 +77,7 @@ class VariableTypeAndInitializerResolver(
|
||||
|
||||
!variable.hasInitializer() && variable is KtProperty && variableDescriptor is VariableDescriptorWithAccessors &&
|
||||
variable.hasDelegateExpression() ->
|
||||
resolveDelegatedPropertyType(variable, variableDescriptor, scopeForInitializer, dataFlowInfo, trace)
|
||||
resolveDelegatedPropertyType(variable, variableDescriptor, scopeForInitializer, dataFlowInfo, trace, local)
|
||||
|
||||
variable.hasInitializer() -> when {
|
||||
!local ->
|
||||
@@ -84,11 +85,11 @@ class VariableTypeAndInitializerResolver(
|
||||
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)
|
||||
}
|
||||
|
||||
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace)
|
||||
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
@@ -129,7 +130,8 @@ class VariableTypeAndInitializerResolver(
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
scopeForInitializer: LexicalScope,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
trace: BindingTrace
|
||||
trace: BindingTrace,
|
||||
local: Boolean
|
||||
) = wrappedTypeFactory.createRecursionIntolerantDeferredType(trace) {
|
||||
val delegateExpression = property.delegateExpression!!
|
||||
val type = delegatedPropertyResolver.resolveDelegateExpression(
|
||||
@@ -139,15 +141,18 @@ class VariableTypeAndInitializerResolver(
|
||||
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(
|
||||
scope: LexicalScope,
|
||||
initializer: KtExpression,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
trace: BindingTrace
|
||||
trace: BindingTrace,
|
||||
local: Boolean
|
||||
): 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.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.utils.newLinkedHashSetWithExpectedSize
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor
|
||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||
import java.util.*
|
||||
|
||||
internal class DelegatingDataFlowInfo private constructor(
|
||||
@@ -329,7 +331,7 @@ internal class DelegatingDataFlowInfo private constructor(
|
||||
for (value in typeInfo.keys()) {
|
||||
for (type in typeInfo[value]) {
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user