[FIR] Create error candidate for completion instead of simple error reference
This commit is contained in:
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.isInner
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionStub
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedReifiedParameterReference
|
||||
@@ -73,13 +74,14 @@ class FirCallResolver(
|
||||
val nameReference = createResolvedNamedReference(
|
||||
functionCall.calleeReference,
|
||||
name,
|
||||
result.info,
|
||||
result.candidates,
|
||||
result.applicability,
|
||||
functionCall.explicitReceiver,
|
||||
)
|
||||
|
||||
val resultExpression = functionCall.transformCalleeReference(StoreNameReference, nameReference)
|
||||
val candidate = resultExpression.candidate()
|
||||
val candidate = (nameReference as? FirNamedReferenceWithCandidate)?.candidate
|
||||
|
||||
// We need desugaring
|
||||
val resultFunctionCall = if (candidate != null && candidate.callInfo != result.info) {
|
||||
@@ -162,6 +164,7 @@ class FirCallResolver(
|
||||
val nameReference = createResolvedNamedReference(
|
||||
callee,
|
||||
callee.name,
|
||||
result.info,
|
||||
reducedCandidates,
|
||||
result.applicability,
|
||||
qualifiedAccess.explicitReceiver,
|
||||
@@ -284,11 +287,11 @@ class FirCallResolver(
|
||||
constructorClassSymbol,
|
||||
)
|
||||
|
||||
return callResolver.selectDelegatingConstructorCall(delegatedConstructorCall, name, result)
|
||||
return callResolver.selectDelegatingConstructorCall(delegatedConstructorCall, name, result, callInfo)
|
||||
}
|
||||
|
||||
private fun selectDelegatingConstructorCall(
|
||||
call: FirDelegatedConstructorCall, name: Name, result: CandidateCollector,
|
||||
call: FirDelegatedConstructorCall, name: Name, result: CandidateCollector, callInfo: CallInfo
|
||||
): FirDelegatedConstructorCall {
|
||||
val bestCandidates = result.bestCandidates()
|
||||
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||
@@ -300,6 +303,7 @@ class FirCallResolver(
|
||||
val nameReference = createResolvedNamedReference(
|
||||
call.calleeReference,
|
||||
name,
|
||||
callInfo,
|
||||
reducedCandidates,
|
||||
result.currentApplicability,
|
||||
)
|
||||
@@ -348,29 +352,31 @@ class FirCallResolver(
|
||||
private fun createResolvedNamedReference(
|
||||
reference: FirReference,
|
||||
name: Name,
|
||||
callInfo: CallInfo,
|
||||
candidates: Collection<Candidate>,
|
||||
applicability: CandidateApplicability,
|
||||
explicitReceiver: FirExpression? = null,
|
||||
): FirNamedReference {
|
||||
val source = reference.source
|
||||
return when {
|
||||
candidates.isEmpty() -> buildErrorNamedReference {
|
||||
this.source = source
|
||||
diagnostic = ConeUnresolvedNameError(name)
|
||||
}
|
||||
candidates.isEmpty() -> buildErrorReference(
|
||||
callInfo,
|
||||
ConeUnresolvedNameError(name),
|
||||
source,
|
||||
name
|
||||
)
|
||||
applicability < CandidateApplicability.SYNTHETIC_RESOLVED -> {
|
||||
buildErrorNamedReference {
|
||||
this.source = source
|
||||
diagnostic = ConeInapplicableCandidateError(
|
||||
applicability,
|
||||
candidates.map {
|
||||
ConeInapplicableCandidateError.CandidateInfo(
|
||||
it.symbol,
|
||||
if (it.systemInitialized) it.system.diagnostics else emptyList(),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
val diagnostic = ConeInapplicableCandidateError(
|
||||
applicability,
|
||||
candidates.map {
|
||||
ConeInapplicableCandidateError.CandidateInfo(
|
||||
it.symbol,
|
||||
if (it.systemInitialized) it.system.diagnostics else emptyList(),
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
buildErrorReference(callInfo, diagnostic, source, name)
|
||||
}
|
||||
candidates.size == 1 -> {
|
||||
val candidate = candidates.single()
|
||||
@@ -396,10 +402,23 @@ class FirCallResolver(
|
||||
}
|
||||
FirNamedReferenceWithCandidate(source, name, candidate)
|
||||
}
|
||||
else -> buildErrorNamedReference {
|
||||
this.source = source
|
||||
diagnostic = ConeAmbiguityError(name, candidates.map { it.symbol })
|
||||
}
|
||||
else -> buildErrorReference(
|
||||
callInfo,
|
||||
ConeAmbiguityError(name, candidates.map { it.symbol }),
|
||||
source,
|
||||
name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildErrorReference(
|
||||
callInfo: CallInfo,
|
||||
diagnostic: ConeDiagnostic,
|
||||
source: FirSourceElement?,
|
||||
name: Name
|
||||
): FirErrorReferenceWithCandidate {
|
||||
val candidate = CandidateFactory(components, callInfo).createErrorCandidate(diagnostic)
|
||||
resolutionStageRunner.processCandidate(candidate, stopOnFirstError = false)
|
||||
return FirErrorReferenceWithCandidate(source, name, candidate, diagnostic)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
fun Candidate.resolveArgumentExpression(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: FirExpression,
|
||||
expectedType: ConeKotlinType,
|
||||
expectedTypeRef: FirTypeRef,
|
||||
expectedType: ConeKotlinType?,
|
||||
expectedTypeRef: FirTypeRef?,
|
||||
sink: CheckerSink,
|
||||
isReceiver: Boolean,
|
||||
isDispatch: Boolean
|
||||
@@ -73,7 +73,7 @@ fun Candidate.resolveArgumentExpression(
|
||||
checkApplicabilityForArgumentType(
|
||||
csBuilder,
|
||||
StandardClassIds.Unit.constructClassLikeType(emptyArray(), isNullable = false),
|
||||
expectedType.type,
|
||||
expectedType?.type,
|
||||
SimpleConstraintSystemConstraintPosition,
|
||||
isReceiver = false,
|
||||
isDispatch = false,
|
||||
@@ -122,8 +122,8 @@ fun Candidate.resolveArgumentExpression(
|
||||
private fun Candidate.resolveBlockArgument(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
block: FirBlock,
|
||||
expectedType: ConeKotlinType,
|
||||
expectedTypeRef: FirTypeRef,
|
||||
expectedType: ConeKotlinType?,
|
||||
expectedTypeRef: FirTypeRef?,
|
||||
sink: CheckerSink,
|
||||
isReceiver: Boolean,
|
||||
isDispatch: Boolean
|
||||
@@ -133,7 +133,7 @@ private fun Candidate.resolveBlockArgument(
|
||||
checkApplicabilityForArgumentType(
|
||||
csBuilder,
|
||||
block.typeRef.coneTypeUnsafe(),
|
||||
expectedType.type,
|
||||
expectedType?.type,
|
||||
SimpleConstraintSystemConstraintPosition,
|
||||
isReceiver = false,
|
||||
isDispatch = false,
|
||||
@@ -157,7 +157,7 @@ private fun Candidate.resolveBlockArgument(
|
||||
fun Candidate.resolveSubCallArgument(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: FirResolvable,
|
||||
expectedType: ConeKotlinType,
|
||||
expectedType: ConeKotlinType?,
|
||||
sink: CheckerSink,
|
||||
isReceiver: Boolean,
|
||||
isDispatch: Boolean,
|
||||
@@ -210,7 +210,7 @@ private fun Candidate.checkApplicabilityForIntegerOperatorCall(sink: CheckerSink
|
||||
fun Candidate.resolvePlainArgumentType(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argumentType: ConeKotlinType,
|
||||
expectedType: ConeKotlinType,
|
||||
expectedType: ConeKotlinType?,
|
||||
sink: CheckerSink,
|
||||
isReceiver: Boolean,
|
||||
isDispatch: Boolean,
|
||||
@@ -257,12 +257,13 @@ private fun Candidate.captureTypeFromExpressionOrNull(argumentType: ConeKotlinTy
|
||||
private fun checkApplicabilityForArgumentType(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argumentType: ConeKotlinType,
|
||||
expectedType: ConeKotlinType,
|
||||
expectedType: ConeKotlinType?,
|
||||
position: SimpleConstraintSystemConstraintPosition,
|
||||
isReceiver: Boolean,
|
||||
isDispatch: Boolean,
|
||||
sink: CheckerSink
|
||||
) {
|
||||
if (expectedType == null) return
|
||||
if (isReceiver && isDispatch) {
|
||||
if (!expectedType.isNullable && argumentType.isMarkedNullable) {
|
||||
sink.reportApplicability(CandidateApplicability.WRONG_RECEIVER)
|
||||
@@ -288,7 +289,7 @@ private fun checkApplicabilityForArgumentType(
|
||||
|
||||
internal fun Candidate.resolveArgument(
|
||||
argument: FirExpression,
|
||||
parameter: FirValueParameter,
|
||||
parameter: FirValueParameter?,
|
||||
isReceiver: Boolean,
|
||||
isSafeCall: Boolean,
|
||||
sink: CheckerSink
|
||||
@@ -299,14 +300,15 @@ internal fun Candidate.resolveArgument(
|
||||
this.system.getBuilder(),
|
||||
argument,
|
||||
expectedType,
|
||||
parameter.returnTypeRef,
|
||||
parameter?.returnTypeRef,
|
||||
sink,
|
||||
isReceiver,
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
private fun Candidate.prepareExpectedType(session: FirSession, argument: FirExpression, parameter: FirValueParameter): ConeKotlinType {
|
||||
private fun Candidate.prepareExpectedType(session: FirSession, argument: FirExpression, parameter: FirValueParameter?): ConeKotlinType? {
|
||||
if (parameter == null) return null
|
||||
if (parameter.returnTypeRef is FirILTTypeRefPlaceHolder) return argument.resultType.coneTypeUnsafe()
|
||||
val basicExpectedType = argument.getExpectedType(session, parameter/*, LanguageVersionSettings*/)
|
||||
val expectedType = getExpectedTypeWithSAMConversion(session, argument, basicExpectedType) ?: basicExpectedType
|
||||
|
||||
@@ -5,10 +5,19 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildErrorFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildErrorProperty
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.returnExpressions
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirErrorFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirErrorPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
@@ -55,6 +64,51 @@ class CandidateFactory private constructor(
|
||||
} ?: callInfo
|
||||
)
|
||||
}
|
||||
|
||||
fun createErrorCandidate(diagnostic: ConeDiagnostic): Candidate {
|
||||
val symbol: AbstractFirBasedSymbol<*> = when (callInfo.callKind) {
|
||||
CallKind.VariableAccess -> createErrorPropertySymbol(diagnostic)
|
||||
CallKind.Function,
|
||||
CallKind.DelegatingConstructorCall,
|
||||
CallKind.CallableReference -> createErrorFunctionSymbol(diagnostic)
|
||||
CallKind.SyntheticSelect -> throw IllegalStateException()
|
||||
CallKind.SyntheticIdForCallableReferencesResolution -> throw IllegalStateException()
|
||||
}
|
||||
return Candidate(
|
||||
symbol,
|
||||
dispatchReceiverValue = null,
|
||||
implicitExtensionReceiverValue = null,
|
||||
explicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||
bodyResolveComponents,
|
||||
baseSystem,
|
||||
callInfo
|
||||
)
|
||||
}
|
||||
|
||||
private fun createErrorFunctionSymbol(diagnostic: ConeDiagnostic): FirErrorFunctionSymbol {
|
||||
return FirErrorFunctionSymbol().also {
|
||||
buildErrorFunction {
|
||||
session = this@CandidateFactory.bodyResolveComponents.session
|
||||
resolvePhase = FirResolvePhase.BODY_RESOLVE
|
||||
origin = FirDeclarationOrigin.Synthetic
|
||||
this.diagnostic = diagnostic
|
||||
symbol = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createErrorPropertySymbol(diagnostic: ConeDiagnostic): FirErrorPropertySymbol {
|
||||
return FirErrorPropertySymbol(diagnostic).also {
|
||||
buildErrorProperty {
|
||||
session = this@CandidateFactory.bodyResolveComponents.session
|
||||
resolvePhase = FirResolvePhase.BODY_RESOLVE
|
||||
origin = FirDeclarationOrigin.Synthetic
|
||||
name = FirErrorPropertySymbol.NAME
|
||||
this.diagnostic = diagnostic
|
||||
symbol = it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun PostponedArgumentsAnalyzer.Context.addSubsystemFromExpression(statement: FirStatement) {
|
||||
|
||||
@@ -32,7 +32,11 @@ suspend inline fun CheckerSink.yieldApplicability(new: CandidateApplicability) {
|
||||
yieldIfNeed()
|
||||
}
|
||||
|
||||
class CheckerSinkImpl(override val components: InferenceComponents, var continuation: Continuation<Unit>? = null) : CheckerSink() {
|
||||
class CheckerSinkImpl(
|
||||
override val components: InferenceComponents,
|
||||
var continuation: Continuation<Unit>? = null,
|
||||
val stopOnFirstError: Boolean = true
|
||||
) : CheckerSink() {
|
||||
var current = CandidateApplicability.RESOLVED
|
||||
private set
|
||||
|
||||
@@ -47,6 +51,6 @@ class CheckerSinkImpl(override val components: InferenceComponents, var continua
|
||||
}
|
||||
|
||||
override val needYielding: Boolean
|
||||
get() = current < CandidateApplicability.SYNTHETIC_RESOLVED
|
||||
get() = stopOnFirstError && current < CandidateApplicability.SYNTHETIC_RESOLVED
|
||||
|
||||
}
|
||||
|
||||
+13
-1
@@ -7,16 +7,28 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@OptIn(FirImplementationDetail::class)
|
||||
class FirNamedReferenceWithCandidate(
|
||||
open class FirNamedReferenceWithCandidate(
|
||||
source: FirSourceElement?,
|
||||
name: Name,
|
||||
val candidate: Candidate
|
||||
) : FirSimpleNamedReference(source, name, candidate.symbol) {
|
||||
override val candidateSymbol: AbstractFirBasedSymbol<*>
|
||||
get() = candidate.symbol
|
||||
|
||||
open val isError: Boolean get() = false
|
||||
}
|
||||
|
||||
class FirErrorReferenceWithCandidate(
|
||||
source: FirSourceElement?,
|
||||
name: Name,
|
||||
candidate: Candidate,
|
||||
val diagnostic: ConeDiagnostic
|
||||
) : FirNamedReferenceWithCandidate(source, name, candidate) {
|
||||
override val isError: Boolean get() = true
|
||||
}
|
||||
+2
-2
@@ -13,8 +13,8 @@ import kotlin.coroutines.intrinsics.createCoroutineUnintercepted
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
class ResolutionStageRunner(val components: InferenceComponents) {
|
||||
fun processCandidate(candidate: Candidate): CandidateApplicability {
|
||||
val sink = CheckerSinkImpl(components)
|
||||
fun processCandidate(candidate: Candidate, stopOnFirstError: Boolean = true): CandidateApplicability {
|
||||
val sink = CheckerSinkImpl(components, stopOnFirstError = stopOnFirstError)
|
||||
var finished = false
|
||||
sink.continuation = suspend {
|
||||
for (stage in candidate.callInfo.callKind.resolutionSequence) {
|
||||
|
||||
@@ -186,7 +186,8 @@ internal object CheckArguments : CheckerStage() {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val argumentMapping =
|
||||
candidate.argumentMapping ?: throw IllegalStateException("Argument should be already mapped while checking arguments!")
|
||||
for ((argument, parameter) in argumentMapping) {
|
||||
for (argument in callInfo.arguments) {
|
||||
val parameter = argumentMapping[argument]
|
||||
candidate.resolveArgument(
|
||||
argument,
|
||||
parameter,
|
||||
|
||||
+3
-17
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.FirResolvable
|
||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.candidate
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
|
||||
@@ -51,24 +52,9 @@ class FirCallCompleter(
|
||||
fun <T> completeCall(call: T, expectedTypeRef: FirTypeRef?): CompletionResult<T>
|
||||
where T : FirResolvable, T : FirStatement {
|
||||
val typeRef = typeFromCallee(call)
|
||||
if (typeRef.type is ConeKotlinErrorType) {
|
||||
if (call is FirExpression) {
|
||||
call.resultType = typeRef
|
||||
}
|
||||
val errorCall = if (call is FirFunctionCall) {
|
||||
call.argumentList.transformArguments(
|
||||
transformer,
|
||||
ResolutionMode.WithExpectedType(typeRef.resolvedTypeFromPrototype(session.builtinTypes.nullableAnyType.type))
|
||||
)
|
||||
call
|
||||
} else {
|
||||
call
|
||||
}
|
||||
inferenceSession.addErrorCall(errorCall)
|
||||
return CompletionResult(errorCall, true)
|
||||
}
|
||||
|
||||
val candidate = call.candidate() ?: return CompletionResult(call, true)
|
||||
val reference = call.calleeReference as? FirNamedReferenceWithCandidate ?: return CompletionResult(call, true)
|
||||
val candidate = reference.candidate
|
||||
val initialSubstitutor = candidate.substitutor
|
||||
|
||||
val initialType = initialSubstitutor.substituteOrSelf(typeRef.type)
|
||||
|
||||
+4
-4
@@ -38,8 +38,8 @@ fun ConeKotlinType.isSuspendFunctionType(session: FirSession): Boolean {
|
||||
}
|
||||
}
|
||||
|
||||
fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef, session: FirSession): ConeKotlinType? {
|
||||
if (isBuiltinFunctionalType(session) && expectedTypeRef.isExtensionFunctionType(session)) {
|
||||
fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef?, session: FirSession): ConeKotlinType? {
|
||||
if (isBuiltinFunctionalType(session) && expectedTypeRef?.isExtensionFunctionType(session) == true) {
|
||||
return ((this as ConeClassLikeType).fullyExpandedType(session).typeArguments.first() as ConeKotlinTypeProjection).type
|
||||
}
|
||||
return null
|
||||
@@ -63,7 +63,7 @@ val FirAnonymousFunction.receiverType get() = receiverTypeRef?.coneTypeSafe<Cone
|
||||
|
||||
fun extractLambdaInfoFromFunctionalType(
|
||||
expectedType: ConeKotlinType?,
|
||||
expectedTypeRef: FirTypeRef,
|
||||
expectedTypeRef: FirTypeRef?,
|
||||
argument: FirAnonymousFunction,
|
||||
returnTypeVariable: ConeTypeVariableForLambdaReturnType?,
|
||||
components: BodyResolveComponents,
|
||||
@@ -78,7 +78,7 @@ fun extractLambdaInfoFromFunctionalType(
|
||||
|
||||
val receiverType = argument.receiverType ?: expectedType.receiverType(expectedTypeRef, session)
|
||||
val returnType = argument.returnType ?: expectedType.returnType(session) ?: return null
|
||||
val parameters = extractLambdaParameters(expectedType, argument, expectedTypeRef.isExtensionFunctionType(session), session)
|
||||
val parameters = extractLambdaParameters(expectedType, argument, expectedTypeRef?.isExtensionFunctionType(session) ?: false, session)
|
||||
|
||||
return ResolvedLambdaAtom(
|
||||
argument,
|
||||
|
||||
+3
-3
@@ -19,11 +19,11 @@ fun Candidate.preprocessLambdaArgument(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: FirAnonymousFunction,
|
||||
expectedType: ConeKotlinType?,
|
||||
expectedTypeRef: FirTypeRef,
|
||||
expectedTypeRef: FirTypeRef?,
|
||||
forceResolution: Boolean = false,
|
||||
returnTypeVariable: ConeTypeVariableForLambdaReturnType? = null
|
||||
): PostponedResolvedAtom {
|
||||
if (expectedType != null && !forceResolution && csBuilder.isTypeVariable(expectedType)) {
|
||||
if (expectedType != null && expectedTypeRef != null && !forceResolution && csBuilder.isTypeVariable(expectedType)) {
|
||||
return LambdaWithTypeVariableAsExpectedTypeAtom(argument, expectedType, expectedTypeRef, this)
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ fun Candidate.preprocessLambdaArgument(
|
||||
|
||||
fun Candidate.preprocessCallableReference(
|
||||
argument: FirCallableReferenceAccess,
|
||||
expectedType: ConeKotlinType
|
||||
expectedType: ConeKotlinType?
|
||||
) {
|
||||
val lhs = bodyResolveComponents.doubleColonExpressionResolver.resolveDoubleColonLHS(argument)
|
||||
postponedAtoms += ResolvedCallableReferenceAtom(argument, expectedType, lhs, bodyResolveComponents.session)
|
||||
|
||||
+35
-28
@@ -11,10 +11,12 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedCallableReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirErrorReferenceWithCandidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.varargElementType
|
||||
import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef
|
||||
@@ -36,6 +38,7 @@ import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.types.AbstractTypeApproximator
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import kotlin.math.min
|
||||
|
||||
class FirCallCompletionResultsWriterTransformer(
|
||||
@@ -78,11 +81,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
val result = updatedQualifiedAccess
|
||||
.transformCalleeReference(
|
||||
StoreCalleeReference,
|
||||
buildResolvedNamedReference {
|
||||
source = calleeReference.source
|
||||
name = calleeReference.name
|
||||
resolvedSymbol = calleeReference.candidateSymbol
|
||||
},
|
||||
calleeReference.toResolvedReference(),
|
||||
)
|
||||
.transformDispatchReceiver(StoreReceiver, subCandidate.dispatchReceiverExpression())
|
||||
.transformExtensionReceiver(StoreReceiver, subCandidate.extensionReceiverExpression()) as T
|
||||
@@ -131,10 +130,13 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
}
|
||||
else -> {
|
||||
resultType = typeRef.substituteTypeRef(subCandidate)
|
||||
result.argumentList.transformArguments(this, subCandidate.createArgumentsMapping())
|
||||
subCandidate.handleVarargs(result.argumentList)
|
||||
subCandidate.argumentMapping?.let {
|
||||
result.replaceArgumentList(buildResolvedArgumentList(it))
|
||||
val expectedArgumentsTypeMapping = runIf(!calleeReference.isError) { subCandidate.createArgumentsMapping() }
|
||||
result.argumentList.transformArguments(this, expectedArgumentsTypeMapping)
|
||||
if (!calleeReference.isError) {
|
||||
subCandidate.handleVarargs(result.argumentList)
|
||||
subCandidate.argumentMapping?.let {
|
||||
result.replaceArgumentList(buildResolvedArgumentList(it))
|
||||
}
|
||||
}
|
||||
result.transformExplicitReceiver(integerApproximator, null)
|
||||
}
|
||||
@@ -258,11 +260,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
val typeArguments = computeTypeArguments(variableAssignment, calleeReference.candidate)
|
||||
return variableAssignment.transformCalleeReference(
|
||||
StoreCalleeReference,
|
||||
buildResolvedNamedReference {
|
||||
source = calleeReference.source
|
||||
name = calleeReference.name
|
||||
resolvedSymbol = calleeReference.candidateSymbol
|
||||
},
|
||||
calleeReference.toResolvedReference(),
|
||||
).transformExplicitReceiver(integerApproximator, null).apply {
|
||||
replaceTypeArguments(typeArguments)
|
||||
}.compose()
|
||||
@@ -310,18 +308,17 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
delegatedConstructorCall.calleeReference as? FirNamedReferenceWithCandidate ?: return delegatedConstructorCall.compose()
|
||||
val subCandidate = calleeReference.candidate
|
||||
|
||||
delegatedConstructorCall.argumentList.transformArguments(this, calleeReference.candidate.createArgumentsMapping())
|
||||
subCandidate.handleVarargs(delegatedConstructorCall.argumentList)
|
||||
subCandidate.argumentMapping?.let {
|
||||
delegatedConstructorCall.replaceArgumentList(buildResolvedArgumentList(it))
|
||||
val argumentsMapping = runIf(!calleeReference.isError) { calleeReference.candidate.createArgumentsMapping() }
|
||||
delegatedConstructorCall.argumentList.transformArguments(this, argumentsMapping)
|
||||
if (!calleeReference.isError) {
|
||||
subCandidate.handleVarargs(delegatedConstructorCall.argumentList)
|
||||
subCandidate.argumentMapping?.let {
|
||||
delegatedConstructorCall.replaceArgumentList(buildResolvedArgumentList(it))
|
||||
}
|
||||
}
|
||||
return delegatedConstructorCall.transformCalleeReference(
|
||||
StoreCalleeReference,
|
||||
buildResolvedNamedReference {
|
||||
source = calleeReference.source
|
||||
name = calleeReference.name
|
||||
resolvedSymbol = calleeReference.candidateSymbol
|
||||
},
|
||||
calleeReference.toResolvedReference(),
|
||||
).compose()
|
||||
}
|
||||
|
||||
@@ -433,11 +430,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
|
||||
return (syntheticCall.transformCalleeReference(
|
||||
StoreCalleeReference,
|
||||
buildResolvedNamedReference {
|
||||
source = calleeReference.source
|
||||
name = calleeReference.name
|
||||
resolvedSymbol = calleeReference.candidateSymbol
|
||||
},
|
||||
calleeReference.toResolvedReference(),
|
||||
) as D).compose()
|
||||
}
|
||||
|
||||
@@ -449,6 +442,20 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
val expectedType = data?.getExpectedType(constExpression)
|
||||
return constExpression.transform(integerApproximator, expectedType)
|
||||
}
|
||||
|
||||
private fun FirNamedReferenceWithCandidate.toResolvedReference() = if (this is FirErrorReferenceWithCandidate) {
|
||||
buildErrorNamedReference {
|
||||
source = this@toResolvedReference.source
|
||||
diagnostic = this@toResolvedReference.diagnostic
|
||||
}
|
||||
} else {
|
||||
buildResolvedNamedReference {
|
||||
source = this@toResolvedReference.source
|
||||
name = this@toResolvedReference.name
|
||||
resolvedSymbol = this@toResolvedReference.candidateSymbol
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sealed class ExpectedArgumentType {
|
||||
|
||||
+1
-6
@@ -220,12 +220,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
// name.invoke() case
|
||||
callCompleter.completeCall(resultExplicitReceiver, noExpectedType)
|
||||
}
|
||||
val completionResult = callCompleter.completeCall(resultExpression, expectedTypeRef)
|
||||
|
||||
if (completionResult.result.typeRef is FirErrorTypeRef) {
|
||||
completionResult.result.argumentList.transformArguments(transformer, ResolutionMode.LambdaResolution(null))
|
||||
}
|
||||
completionResult
|
||||
callCompleter.completeCall(resultExpression, expectedTypeRef)
|
||||
} catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
} catch (e: Throwable) {
|
||||
|
||||
Reference in New Issue
Block a user