diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt deleted file mode 100644 index 15b503981c3..00000000000 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.resolve.calls - -import org.jetbrains.kotlin.builtins.* -import org.jetbrains.kotlin.config.LanguageFeature -import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor -import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor -import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.getBinaryWithTypeParent -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil -import org.jetbrains.kotlin.resolve.TemporaryBindingTrace -import org.jetbrains.kotlin.resolve.calls.util.* -import org.jetbrains.kotlin.resolve.calls.util.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS -import org.jetbrains.kotlin.resolve.calls.util.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS -import org.jetbrains.kotlin.resolve.calls.util.getCall -import org.jetbrains.kotlin.resolve.calls.util.isSafeCall -import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext -import org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT -import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext -import org.jetbrains.kotlin.resolve.calls.context.ResolutionResultsCache -import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache -import org.jetbrains.kotlin.resolve.calls.inference.* -import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition -import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind -import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION -import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION -import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ValidityConstraintForConstituentType -import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall -import org.jetbrains.kotlin.resolve.calls.util.makeNullableTypeIfSafeReceiver -import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus -import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE -import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.OTHER_ERROR -import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory -import org.jetbrains.kotlin.resolve.isFunctionForExpectTypeFromCastFeature -import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver -import org.jetbrains.kotlin.types.* -import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE -import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.ResolveConstruct -import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils -import org.jetbrains.kotlin.types.typeUtil.makeNullable -import org.jetbrains.kotlin.utils.addToStdlib.safeAs - -val SPECIAL_FUNCTION_NAMES = ResolveConstruct.values().map { it.specialFunctionName }.toSet() - -class GenericCandidateResolver( - private val argumentTypeResolver: ArgumentTypeResolver, - private val languageVersionSettings: LanguageVersionSettings, - private val dataFlowValueFactory: DataFlowValueFactory -) { - fun inferTypeArguments(context: CallCandidateResolutionContext): ResolutionStatus { - val candidateCall = context.candidateCall - val candidate = candidateCall.candidateDescriptor - - val builder = ConstraintSystemBuilderImpl() - builder.registerTypeVariables(candidateCall.call.toHandle(), candidate.typeParameters) - - val substituteDontCare = makeConstantSubstitutor(candidate.typeParameters, DONT_CARE) - - // Value parameters - for ((candidateParameter, resolvedValueArgument) in candidateCall.valueArguments) { - val valueParameterDescriptor = candidate.valueParameters[candidateParameter.index] - - for (valueArgument in resolvedValueArgument.arguments) { - // TODO : more attempts, with different expected types - - // Here we type check expecting an error type (DONT_CARE, substitution with substituteDontCare) - // and throw the results away - // We'll type check the arguments later, with the inferred types expected - addConstraintForValueArgument( - valueArgument, valueParameterDescriptor, substituteDontCare, builder, context, SHAPE_FUNCTION_ARGUMENTS - ) - } - } - - if (candidate is TypeAliasConstructorDescriptor) { - val substitutedReturnType = builder.compositeSubstitutor().safeSubstitute(candidate.returnType, Variance.INVARIANT) - addValidityConstraintsForConstituentTypes(builder, substitutedReturnType) - } - - // Receiver - // Error is already reported if something is missing - val receiverArgument = candidateCall.extensionReceiver - val receiverParameter = candidate.extensionReceiverParameter - if (receiverArgument != null && receiverParameter != null) { - val receiverArgumentType = receiverArgument.type - var receiverType: KotlinType? = if (context.candidateCall.call.isSafeCall()) - TypeUtils.makeNotNullable(receiverArgumentType) - else - receiverArgumentType - if (receiverArgument is ExpressionReceiver) { - receiverType = updateResultTypeForSmartCasts(receiverType, receiverArgument.expression, context) - } - builder.addSubtypeConstraint( - receiverType, - builder.compositeSubstitutor().substitute(receiverParameter.type, Variance.INVARIANT), - RECEIVER_POSITION.position() - ) - } - - val constraintSystem = builder.build() - candidateCall.setConstraintSystem(constraintSystem) - - // Solution - val hasContradiction = constraintSystem.status.hasContradiction() - if (!hasContradiction) { - addExpectedTypeForExplicitCast(context, builder) - return INCOMPLETE_TYPE_INFERENCE - } - return OTHER_ERROR - } - - private fun ConstraintSystem.Builder.typeInSystem(call: Call, type: KotlinType?): KotlinType? = - type?.let { - typeVariableSubstitutors[call.toHandle()]?.substitute(it, Variance.INVARIANT) - } - - private fun addExpectedTypeForExplicitCast( - context: CallCandidateResolutionContext<*>, - builder: ConstraintSystem.Builder - ) { - if (!languageVersionSettings.supportsFeature(LanguageFeature.ExpectedTypeFromCast)) return - - if (context.candidateCall is VariableAsFunctionResolvedCall) return - - val candidateDescriptor = context.candidateCall.candidateDescriptor.safeAs() ?: return - - val binaryParent = context.call.calleeExpression?.getBinaryWithTypeParent() ?: return - val operationType = binaryParent.operationReference.getReferencedNameElementType().takeIf { - it == KtTokens.AS_KEYWORD || it == KtTokens.AS_SAFE - } ?: return - - val leftType = context.trace.get(BindingContext.TYPE, binaryParent.right ?: return) ?: return - val expectedType = if (operationType == KtTokens.AS_SAFE) leftType.makeNullable() else leftType - - if (context.candidateCall.call.typeArgumentList != null || !candidateDescriptor.isFunctionForExpectTypeFromCastFeature()) return - - val typeInSystem = builder.typeInSystem(context.call, candidateDescriptor.returnType ?: return) ?: return - - context.trace.record(BindingContext.CAST_TYPE_USED_AS_EXPECTED_TYPE, binaryParent) - builder.addSubtypeConstraint(typeInSystem, expectedType, ConstraintPositionKind.SPECIAL.position()) - } - - private fun addValidityConstraintsForConstituentTypes(builder: ConstraintSystem.Builder, type: KotlinType) { - val typeConstructor = type.constructor - if (typeConstructor.declarationDescriptor is TypeParameterDescriptor) return - - val boundsSubstitutor = TypeSubstitutor.create(type) - - type.arguments.forEachIndexed forEachArgument@ { i, typeProjection -> - if (typeProjection.isStarProjection) return@forEachArgument // continue - - val typeParameter = typeConstructor.parameters[i] - addValidityConstraintsForTypeArgument(builder, typeProjection, typeParameter, boundsSubstitutor) - - addValidityConstraintsForConstituentTypes(builder, typeProjection.type) - } - } - - private fun addValidityConstraintsForTypeArgument( - builder: ConstraintSystem.Builder, - substitutedArgument: TypeProjection, - typeParameter: TypeParameterDescriptor, - boundsSubstitutor: TypeSubstitutor - ) { - val substitutedType = substitutedArgument.type - for (upperBound in typeParameter.upperBounds) { - val substitutedUpperBound = boundsSubstitutor.safeSubstitute(upperBound, Variance.INVARIANT).upperIfFlexible() - val constraintPosition = ValidityConstraintForConstituentType(substitutedType, typeParameter, substitutedUpperBound) - - // Do not add extra constraints if upper bound is 'Any?'; - // otherwise it will be treated incorrectly in nested calls processing. - if (KotlinBuiltIns.isNullableAny(substitutedUpperBound)) continue - - builder.addSubtypeConstraint(substitutedType, substitutedUpperBound, constraintPosition) - } - } - - // Creates a substitutor which maps types to their representation in the constraint system. - // In case when some type parameter descriptor is represented by more than one variable in the system, the behavior is undefined. - private fun ConstraintSystem.Builder.compositeSubstitutor(): TypeSubstitutor { - return TypeSubstitutor.create(object : TypeSubstitution() { - override fun get(key: KotlinType): TypeProjection? { - return typeVariableSubstitutors.values.reversed().asSequence().mapNotNull { it.substitution.get(key) }.firstOrNull() - } - }) - } - - private fun addConstraintForValueArgument( - valueArgument: ValueArgument, - valueParameterDescriptor: ValueParameterDescriptor, - substitutor: TypeSubstitutor, - builder: ConstraintSystem.Builder, - context: CallCandidateResolutionContext<*>, - resolveFunctionArgumentBodies: ResolveArgumentsMode - ) { - val effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument, context) - val argumentExpression = valueArgument.getArgumentExpression() - - val expectedType = substitutor.substitute(effectiveExpectedType, Variance.INVARIANT) - val dataFlowInfoForArgument = context.candidateCall.dataFlowInfoForArguments.getInfo(valueArgument) - val newContext = context.replaceExpectedType(expectedType).replaceDataFlowInfo(dataFlowInfoForArgument) - - val typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo( - argumentExpression, - newContext, - resolveFunctionArgumentBodies, - expectedType?.isSuspendFunctionType == true - ) - context.candidateCall.dataFlowInfoForArguments.updateInfo(valueArgument, typeInfoForCall.dataFlowInfo) - - val constraintPosition = VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.index) - - if (addConstraintForNestedCall(argumentExpression, constraintPosition, builder, newContext, effectiveExpectedType)) return - - val type = - updateResultTypeForSmartCasts(typeInfoForCall.type, argumentExpression, context.replaceDataFlowInfo(dataFlowInfoForArgument)) - - if (argumentExpression is KtCallableReferenceExpression && type == null) return - - builder.addSubtypeConstraint( - type, - builder.compositeSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT), - constraintPosition - ) - } - - private fun addConstraintForNestedCall( - argumentExpression: KtExpression?, - constraintPosition: ConstraintPosition, - builder: ConstraintSystem.Builder, - context: CallCandidateResolutionContext<*>, - effectiveExpectedType: KotlinType - ): Boolean { - val resolutionResults = getResolutionResultsCachedData(argumentExpression, context)?.resolutionResults - if (resolutionResults == null || !resolutionResults.isSingleResult) return false - - val nestedCall = resolutionResults.resultingCall - if (nestedCall.isCompleted) return false - - val nestedConstraintSystem = nestedCall.constraintSystem ?: return false - - val candidateDescriptor = nestedCall.candidateDescriptor - val returnType = candidateDescriptor.returnType ?: return false - - val nestedTypeVariables = nestedConstraintSystem.getNestedTypeVariables(returnType) - - // we add an additional type variable only if no information is inferred for it. - // otherwise we add currently inferred return type as before - if (nestedTypeVariables.any { nestedConstraintSystem.getTypeBounds(it).bounds.isNotEmpty() }) return false - - val candidateWithFreshVariables = FunctionDescriptorUtil.alphaConvertTypeParameters(candidateDescriptor) - val conversion = candidateDescriptor.typeParameters.zip(candidateWithFreshVariables.typeParameters).toMap() - - val freshVariables = returnType.getNestedTypeParameters().mapNotNull { conversion[it] } - builder.registerTypeVariables(nestedCall.call.toHandle(), freshVariables, external = true) - // Safe call result must be nullable if receiver is nullable - val argumentExpressionType = nestedCall.makeNullableTypeIfSafeReceiver(candidateWithFreshVariables.returnType, context) - - builder.addSubtypeConstraint( - argumentExpressionType, - builder.compositeSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT), - constraintPosition - ) - - return true - } - - private fun updateResultTypeForSmartCasts( - type: KotlinType?, - argumentExpression: KtExpression?, - context: ResolutionContext<*> - ): KotlinType? { - val deparenthesizedArgument = KtPsiUtil.getLastElementDeparenthesized(argumentExpression, context.statementFilter) - if (deparenthesizedArgument == null || type == null) return type - - val dataFlowValue = dataFlowValueFactory.createDataFlowValue(deparenthesizedArgument, type, context) - if (!dataFlowValue.isStable) return type - - val possibleTypes = context.dataFlowInfo.getCollectedTypes(dataFlowValue, context.languageVersionSettings) - if (possibleTypes.isEmpty()) return type - - return TypeIntersector.intersectTypes(possibleTypes + type) - } - - fun completeTypeInferenceDependentOnFunctionArgumentsForCall(context: CallCandidateResolutionContext) { - val resolvedCall = context.candidateCall - val constraintSystem = resolvedCall.constraintSystem?.toBuilder() ?: return - - // `resolvedCall` can contain wrapped call (e.g. CallForImplicitInvoke). Meanwhile, `context` contains simple call which leads - // to inconsistency and errors in inference. See definition of `effectiveExpectedTypeInSystem` in `addConstraintForFunctionLiteralArgument` - val newContext = if (resolvedCall is VariableAsFunctionResolvedCall) { - CallCandidateResolutionContext.create( - resolvedCall, context, context.trace, context.tracing, resolvedCall.functionCall.call, context.candidateResolveMode - ) - } else { - context - } - - // constraints for function literals - // Value parameters - for ((valueParameterDescriptor, resolvedValueArgument) in resolvedCall.valueArguments) { - for (valueArgument in resolvedValueArgument.arguments) { - valueArgument.getArgumentExpression()?.let { argumentExpression -> - ArgumentTypeResolver.getFunctionLiteralArgumentIfAny(argumentExpression, newContext)?.let { functionLiteral -> - addConstraintForFunctionLiteralArgument( - functionLiteral, valueArgument, valueParameterDescriptor, constraintSystem, newContext, - resolvedCall.candidateDescriptor.returnType - ) - } - - // as inference for callable references depends on expected type, - // we should postpone reporting errors on them until all types will be inferred - - // We do not replace trace for special calls (e.g. if-expressions) because of their specific analysis - // For example, type info for arguments is needed before call will be completed (See ControlStructureTypingVisitor.visitIfExpression) - val temporaryContextForCall = if (resolvedCall.candidateDescriptor.name in SPECIAL_FUNCTION_NAMES) { - newContext - } else { - val temporaryBindingTrace = TemporaryBindingTrace.create( - newContext.trace, "Trace to complete argument for call that might be not resulting call" - ) - newContext.replaceBindingTrace(temporaryBindingTrace) - } - - ArgumentTypeResolver.getCallableReferenceExpressionIfAny(argumentExpression, newContext)?.let { callableReference -> - addConstraintForCallableReference( - callableReference, - valueArgument, - valueParameterDescriptor, - constraintSystem, - temporaryContextForCall - ) - } - } - } - } - val resultingSystem = constraintSystem.build() - resolvedCall.setConstraintSystem(resultingSystem) - - val isNewInferenceEnabled = languageVersionSettings.supportsFeature(LanguageFeature.NewInference) - val resultingSubstitutor = if (isNewInferenceEnabled) { - resultingSystem.resultingSubstitutor.replaceWithContravariantApproximatingSubstitution() - } else resultingSystem.resultingSubstitutor - - resolvedCall.setSubstitutor(resultingSubstitutor) - } - - // See KT-5385 - // When literal returns T, and it's an argument of a function that also returns T, - // and we have some expected type Type, we can expected from literal to return Type - // Otherwise we do not care about literal's exact return type - private fun estimateLiteralReturnType( - context: CallCandidateResolutionContext<*>, - literalExpectedType: KotlinType, - ownerReturnType: KotlinType? - ) = if (!TypeUtils.noExpectedType(context.expectedType) && - ownerReturnType != null && - TypeUtils.isTypeParameter(ownerReturnType) && - literalExpectedType.isFunctionTypeOrSubtype && - getReturnTypeForCallable(literalExpectedType) == ownerReturnType) - context.expectedType - else DONT_CARE - - private fun addConstraintForFunctionLiteralArgument( - functionLiteral: KtFunction, - valueArgument: ValueArgument, - valueParameterDescriptor: ValueParameterDescriptor, - constraintSystem: ConstraintSystem.Builder, - context: CallCandidateResolutionContext, - argumentOwnerReturnType: KotlinType? - ) { - val argumentExpression = valueArgument.getArgumentExpression() ?: return - - val effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument, context) - - val currentSubstitutor = constraintSystem.build().currentSubstitutor - val newSubstitution = object : DelegatedTypeSubstitution(currentSubstitutor.substitution) { - override fun approximateContravariantCapturedTypes() = true - } - - var expectedType = newSubstitution.buildSubstitutor().substitute(effectiveExpectedType, Variance.IN_VARIANCE) - - if (expectedType == null || TypeUtils.isDontCarePlaceholder(expectedType)) { - expectedType = argumentTypeResolver.getShapeTypeOfFunctionLiteral( - functionLiteral, - context.scope, - context.trace, - false, - expectedType?.isSuspendFunctionType == true - ) - } - if (expectedType == null || !expectedType.isBuiltinFunctionalType || hasUnknownFunctionParameter(expectedType)) { - return - } - val dataFlowInfoForArguments = context.candidateCall.dataFlowInfoForArguments - val dataFlowInfoForArgument = dataFlowInfoForArguments.getInfo(valueArgument) - - val effectiveExpectedTypeInSystem = - constraintSystem.typeVariableSubstitutors[context.call.toHandle()]?.substitute(effectiveExpectedType, Variance.INVARIANT) - - //todo analyze function literal body once in 'dependent' mode, then complete it with respect to expected type - val hasExpectedReturnType = !hasUnknownReturnType(expectedType) - val position = VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.index) - if (hasExpectedReturnType) { - val temporaryToResolveFunctionLiteral = TemporaryTraceAndCache.create( - context, "trace to resolve function literal with expected return type", argumentExpression - ) - - val statementExpression = KtPsiUtil.getExpressionOrLastStatementInBlock(functionLiteral.bodyExpression) ?: return - val mismatch = BooleanArray(1) - val errorInterceptingTrace = ExpressionTypingUtils.makeTraceInterceptingTypeMismatch( - temporaryToResolveFunctionLiteral.trace, statementExpression, mismatch - ) - val newContext = context.replaceBindingTrace(errorInterceptingTrace).replaceExpectedType(expectedType) - .replaceDataFlowInfo(dataFlowInfoForArgument).replaceResolutionResultsCache(temporaryToResolveFunctionLiteral.cache) - .replaceContextDependency(INDEPENDENT) - val type = argumentTypeResolver.getFunctionLiteralTypeInfo( - argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS, - expectedType.isSuspendFunctionType - ).type - if (!mismatch[0]) { - constraintSystem.addSubtypeConstraint(type, effectiveExpectedTypeInSystem, position) - temporaryToResolveFunctionLiteral.commit() - return - } - } - val estimatedReturnType = estimateLiteralReturnType(context, effectiveExpectedType, argumentOwnerReturnType) - val expectedTypeWithEstimatedReturnType = replaceReturnTypeForCallable(expectedType, estimatedReturnType) - val newContext = context.replaceExpectedType(expectedTypeWithEstimatedReturnType).replaceDataFlowInfo(dataFlowInfoForArgument) - .replaceContextDependency(INDEPENDENT) - val type = - argumentTypeResolver.getFunctionLiteralTypeInfo( - argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS, - expectedType.isSuspendFunctionType - ).type - constraintSystem.addSubtypeConstraint(type, effectiveExpectedTypeInSystem, position) - } - - private fun addConstraintForCallableReference( - callableReference: KtCallableReferenceExpression, - valueArgument: ValueArgument, - valueParameterDescriptor: ValueParameterDescriptor, - constraintSystem: ConstraintSystem.Builder, - context: CallCandidateResolutionContext - ) { - val effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument, context) - val expectedType = getExpectedTypeForCallableReference(callableReference, constraintSystem, context, effectiveExpectedType) - ?: return - if (!expectedType.isApplicableExpectedTypeForCallableReference()) return - val resolvedType = getResolvedTypeForCallableReference(callableReference, context, expectedType, valueArgument) ?: return - val position = VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.index) - constraintSystem.addSubtypeConstraint( - resolvedType, - constraintSystem.typeVariableSubstitutors[context.call.toHandle()]?.substitute(effectiveExpectedType, Variance.INVARIANT), - position - ) - } - - private fun getExpectedTypeForCallableReference( - callableReference: KtCallableReferenceExpression, - constraintSystem: ConstraintSystem.Builder, - context: CallCandidateResolutionContext, - effectiveExpectedType: KotlinType - ): KotlinType? { - val substitutedType = constraintSystem.build().currentSubstitutor.substitute(effectiveExpectedType, Variance.INVARIANT) - if (substitutedType != null && !TypeUtils.isDontCarePlaceholder(substitutedType)) - return substitutedType - - val shapeType = argumentTypeResolver.getShapeTypeOfCallableReference(callableReference, context, false) - if (shapeType != null && shapeType.isFunctionTypeOrSubtype && !hasUnknownFunctionParameter(shapeType)) - return shapeType - - return null - } - - private fun getResolvedTypeForCallableReference( - callableReference: KtCallableReferenceExpression, - context: CallCandidateResolutionContext, - expectedType: KotlinType, - valueArgument: ValueArgument - ): KotlinType? { - val dataFlowInfoForArgument = context.candidateCall.dataFlowInfoForArguments.getInfo(valueArgument) - val expectedTypeWithoutReturnType = - if (!hasUnknownReturnType(expectedType)) replaceReturnTypeByUnknown(expectedType) else expectedType - val newContext = context - .replaceExpectedType(expectedTypeWithoutReturnType) - .replaceDataFlowInfo(dataFlowInfoForArgument) - .replaceContextDependency(INDEPENDENT) - return argumentTypeResolver.getCallableReferenceTypeInfo( - callableReference, callableReference, newContext, RESOLVE_FUNCTION_ARGUMENTS - ).type - } -} - -fun getResolutionResultsCachedData(expression: KtExpression?, context: ResolutionContext<*>): ResolutionResultsCache.CachedData? { - if (!ExpressionTypingUtils.dependsOnExpectedType(expression)) return null - val argumentCall = expression?.getCall(context.trace.bindingContext) ?: return null - - return context.resolutionResultsCache[argumentCall] -} - -fun makeConstantSubstitutor(typeParameterDescriptors: Collection, type: KotlinType): TypeSubstitutor { - val constructors = typeParameterDescriptors.map { it.typeConstructor }.toSet() - val projection = TypeProjectionImpl(type) - - return TypeSubstitutor.create(object : TypeConstructorSubstitution() { - override operator fun get(key: TypeConstructor) = - if (key in constructors) projection else null - - override fun isEmpty() = false - }) -} - -private fun KotlinType.isApplicableExpectedTypeForCallableReference(): Boolean { - return this.isFunctionType || - ReflectionTypes.isBaseTypeForNumberedReferenceTypes(this) || - ReflectionTypes.isNumberedKFunctionOrKSuspendFunction(this) || - ReflectionTypes.isNumberedKPropertyOrKMutablePropertyType(this) -} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ImplicitNothingAsTypeParameterCallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ImplicitNothingAsTypeParameterCallChecker.kt index 30716dc300d..f821902381b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ImplicitNothingAsTypeParameterCallChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ImplicitNothingAsTypeParameterCallChecker.kt @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnceWrtDiagnosticFactoryList import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.calls.SPECIAL_FUNCTION_NAMES import org.jetbrains.kotlin.resolve.calls.util.getParameterForArgument import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall import org.jetbrains.kotlin.resolve.calls.components.stableType @@ -21,6 +20,7 @@ import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl import org.jetbrains.kotlin.resolve.calls.tower.psiExpression import org.jetbrains.kotlin.resolve.calls.tower.psiKotlinCall +import org.jetbrains.kotlin.resolve.calls.util.SPECIAL_FUNCTION_NAMES import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind import org.jetbrains.kotlin.types.DeferredType import org.jetbrains.kotlin.types.KotlinType diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReferencingToUnderscoreNamedParameterOfCatchBlockChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReferencingToUnderscoreNamedParameterOfCatchBlockChecker.kt index d2c934195d5..0161a562656 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReferencingToUnderscoreNamedParameterOfCatchBlockChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReferencingToUnderscoreNamedParameterOfCatchBlockChecker.kt @@ -16,7 +16,6 @@ import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnceWrtDiagnosticFactory import org.jetbrains.kotlin.psi.KtNameReferenceExpression import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.calls.SPECIAL_FUNCTION_NAMES import org.jetbrains.kotlin.resolve.calls.util.getParameterForArgument import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.* diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index 6a996fe8f95..0ebede0e511 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -19,7 +19,6 @@ import org.jetbrains.kotlin.resolve.BindingContext.NEW_INFERENCE_CATCH_EXCEPTION import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.KotlinCallResolver -import org.jetbrains.kotlin.resolve.calls.SPECIAL_FUNCTION_NAMES import org.jetbrains.kotlin.resolve.calls.components.InferenceSession import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionCallbacks import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt index 6d6c061c50d..f782224c12e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/util/callUtil.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl import org.jetbrains.kotlin.resolve.calls.tower.psiKotlinCall import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils import org.jetbrains.kotlin.types.typeUtil.asTypeProjection import org.jetbrains.kotlin.types.typeUtil.contains import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -330,3 +331,5 @@ fun KotlinCall.extractCallableReferenceExpression(): KtCallableReferenceExpressi psiKotlinCall.psiCall.extractCallableReferenceExpression() fun Call.extractCallableReferenceExpression(): KtCallableReferenceExpression? = callElement.asCallableReferenceExpression() + +val SPECIAL_FUNCTION_NAMES = ControlStructureTypingUtils.ResolveConstruct.values().map { it.specialFunctionName }.toSet()