FIR: Rework default parameters propagation through overrides
This commit is contained in:
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
|
||||
fun FirSession.registerCommonComponents() {
|
||||
register(FirDeclaredMemberScopeProvider::class, FirDeclaredMemberScopeProvider())
|
||||
register(FirCorrespondingSupertypesCache::class, FirCorrespondingSupertypesCache(this))
|
||||
register(FirDefaultParametersResolver::class, FirDefaultParametersResolver())
|
||||
|
||||
register(FirExtensionService::class, FirExtensionService(this))
|
||||
register(FirRegisteredPluginAnnotations::class, FirRegisteredPluginAnnotations.create(this))
|
||||
|
||||
@@ -394,7 +394,8 @@ class FirCallResolver(
|
||||
if (constructorSymbol == null) return null
|
||||
val candidate = CandidateFactory(transformer.resolutionContext, callInfo).createCandidate(
|
||||
constructorSymbol!!,
|
||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||
scope = null
|
||||
)
|
||||
val applicability = components.resolutionStageRunner.processCandidate(candidate, transformer.resolutionContext)
|
||||
return ResolutionResult(callInfo, applicability, listOf(candidate))
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.fir.resolve
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
||||
|
||||
class FirDefaultParametersResolver : FirSessionComponent {
|
||||
fun declaresDefaultValue(
|
||||
valueParameter: FirValueParameter,
|
||||
function: FirFunction<*>,
|
||||
originScope: FirScope?,
|
||||
index: Int,
|
||||
): Boolean {
|
||||
if (valueParameter.defaultValue != null) return true
|
||||
if (originScope !is FirTypeScope) return false
|
||||
var result = false
|
||||
|
||||
originScope.processOverriddenFunctions(function.symbol) { overridden ->
|
||||
if (overridden.fir.valueParameters[index].defaultValue != null) {
|
||||
result = true
|
||||
return@processOverriddenFunctions ProcessorAction.STOP
|
||||
}
|
||||
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
internal val FirSession.defaultParameterResolver: FirDefaultParametersResolver by FirSession.sessionComponentAccessor()
|
||||
+6
-3
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
|
||||
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnsupportedCallableReferenceTarget
|
||||
@@ -106,7 +107,8 @@ private fun buildReflectionType(
|
||||
is FirFunction -> {
|
||||
val unboundReferenceTarget = if (receiverType != null) 1 else 0
|
||||
val callableReferenceAdaptation =
|
||||
getCallableReferenceAdaptation(context.session, fir, callInfo.expectedType, unboundReferenceTarget)
|
||||
context.bodyResolveComponents
|
||||
.getCallableReferenceAdaptation(context.session, fir, callInfo.expectedType, unboundReferenceTarget)
|
||||
|
||||
val parameters = mutableListOf<ConeKotlinType>()
|
||||
|
||||
@@ -153,7 +155,7 @@ private fun CallableReferenceAdaptation?.needCompatibilityResolveForCallableRefe
|
||||
mappedArguments.values.any { it is ResolvedCallArgument.VarargArgument }
|
||||
}
|
||||
|
||||
private fun getCallableReferenceAdaptation(
|
||||
private fun BodyResolveComponents.getCallableReferenceAdaptation(
|
||||
session: FirSession,
|
||||
function: FirFunction<*>,
|
||||
expectedType: ConeKotlinType?,
|
||||
@@ -169,7 +171,8 @@ private fun getCallableReferenceAdaptation(
|
||||
if (expectedArgumentsCount < 0) return null
|
||||
|
||||
val fakeArguments = createFakeArgumentsForReference(function, expectedArgumentsCount, inputTypes, unboundReceiverCount)
|
||||
val argumentMapping = mapArguments(fakeArguments, function)
|
||||
// TODO: Use correct originScope
|
||||
val argumentMapping = mapArguments(fakeArguments, function, originScope = null)
|
||||
if (argumentMapping.diagnostics.any { !it.applicability.isSuccess }) return null
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.PostponedResolvedAtom
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
|
||||
@@ -82,7 +83,8 @@ class Candidate(
|
||||
val explicitReceiverKind: ExplicitReceiverKind,
|
||||
val constraintSystemFactory: InferenceComponents.ConstraintSystemFactory,
|
||||
private val baseSystem: ConstraintStorage,
|
||||
val callInfo: CallInfo
|
||||
val callInfo: CallInfo,
|
||||
val originScope: FirScope?,
|
||||
) {
|
||||
|
||||
var systemInitialized: Boolean = false
|
||||
|
||||
@@ -12,6 +12,7 @@ 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.returnExpressions
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirErrorFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirErrorPropertySymbol
|
||||
@@ -49,6 +50,7 @@ class CandidateFactory private constructor(
|
||||
fun createCandidate(
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
explicitReceiverKind: ExplicitReceiverKind,
|
||||
scope: FirScope?,
|
||||
dispatchReceiverValue: ReceiverValue? = null,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue<*>? = null,
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
|
||||
@@ -58,7 +60,8 @@ class CandidateFactory private constructor(
|
||||
explicitReceiverKind, context.inferenceComponents.constraintSystemFactory, baseSystem,
|
||||
builtInExtensionFunctionReceiverValue?.receiverExpression?.let {
|
||||
callInfo.withReceiverAsArgument(it)
|
||||
} ?: callInfo
|
||||
} ?: callInfo,
|
||||
scope,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -79,7 +82,8 @@ class CandidateFactory private constructor(
|
||||
explicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||
context.inferenceComponents.constraintSystemFactory,
|
||||
baseSystem,
|
||||
callInfo
|
||||
callInfo,
|
||||
originScope = null,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+14
-6
@@ -14,6 +14,9 @@ import org.jetbrains.kotlin.fir.expressions.FirLambdaArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultParameterResolver
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
@@ -45,9 +48,10 @@ data class ArgumentMapping(
|
||||
|
||||
private val EmptyArgumentMapping = ArgumentMapping(emptyMap(), emptyList())
|
||||
|
||||
fun mapArguments(
|
||||
fun BodyResolveComponents.mapArguments(
|
||||
arguments: List<FirExpression>,
|
||||
function: FirFunction<*>
|
||||
function: FirFunction<*>,
|
||||
originScope: FirScope?,
|
||||
): ArgumentMapping {
|
||||
if (arguments.isEmpty() && function.valueParameters.isEmpty()) {
|
||||
return EmptyArgumentMapping
|
||||
@@ -77,7 +81,7 @@ fun mapArguments(
|
||||
}
|
||||
}
|
||||
|
||||
val processor = FirCallArgumentsProcessor(function)
|
||||
val processor = FirCallArgumentsProcessor(function, this, originScope)
|
||||
processor.processArgumentsInParenthesis(argumentsInParenthesis)
|
||||
if (externalArgument != null) {
|
||||
processor.processExternalArgument(externalArgument)
|
||||
@@ -87,7 +91,11 @@ fun mapArguments(
|
||||
return ArgumentMapping(processor.result, processor.diagnostics ?: emptyList())
|
||||
}
|
||||
|
||||
private class FirCallArgumentsProcessor(private val function: FirFunction<*>) {
|
||||
private class FirCallArgumentsProcessor(
|
||||
private val function: FirFunction<*>,
|
||||
private val bodyResolveComponents: BodyResolveComponents,
|
||||
private val originScope: FirScope?,
|
||||
) {
|
||||
private var state = State.POSITION_ARGUMENTS
|
||||
private var currentPositionedParameterIndex = 0
|
||||
private var varargArguments: MutableList<FirExpression>? = null
|
||||
@@ -207,9 +215,9 @@ private class FirCallArgumentsProcessor(private val function: FirFunction<*>) {
|
||||
}
|
||||
}
|
||||
|
||||
for (parameter in parameters) {
|
||||
for ((index, parameter) in parameters.withIndex()) {
|
||||
if (!result.containsKey(parameter)) {
|
||||
if (parameter.defaultValue != null) {
|
||||
if (bodyResolveComponents.session.defaultParameterResolver.declaresDefaultValue(parameter, function, originScope, index)) {
|
||||
result[parameter] = ResolvedCallArgument.DefaultArgument
|
||||
} else if (parameter.isVararg) {
|
||||
result[parameter] = ResolvedCallArgument.VarargArgument(emptyList())
|
||||
|
||||
@@ -169,7 +169,7 @@ internal object MapArguments : ResolutionStage() {
|
||||
val symbol = candidate.symbol as? FirFunctionSymbol<*> ?: return sink.reportDiagnostic(HiddenCandidate)
|
||||
val function = symbol.fir
|
||||
|
||||
val mapping = mapArguments(callInfo.arguments, function)
|
||||
val mapping = context.bodyResolveComponents.mapArguments(callInfo.arguments, function, candidate.originScope)
|
||||
candidate.argumentMapping = mapping.toArgumentToParameterMapping()
|
||||
|
||||
mapping.diagnostics.forEach(sink::reportDiagnostic)
|
||||
|
||||
+1
@@ -105,6 +105,7 @@ class FirTowerResolver(
|
||||
candidateFactory.createCandidate(
|
||||
it,
|
||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||
scope,
|
||||
dispatchReceiver,
|
||||
implicitExtensionReceiverValue = null,
|
||||
builtInExtensionFunctionReceiverValue = null
|
||||
|
||||
+3
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls.tower
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
@@ -147,6 +148,7 @@ private class TowerScopeLevelProcessor(
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
dispatchReceiverValue: ReceiverValue?,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
||||
scope: FirScope,
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue?
|
||||
) {
|
||||
// Check explicit extension receiver for default package members
|
||||
@@ -179,6 +181,7 @@ private class TowerScopeLevelProcessor(
|
||||
group, candidateFactory.createCandidate(
|
||||
symbol,
|
||||
explicitReceiverKind,
|
||||
scope,
|
||||
dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue,
|
||||
builtInExtensionFunctionReceiverValue
|
||||
|
||||
+10
-5
@@ -48,6 +48,7 @@ interface TowerScopeLevel {
|
||||
symbol: T,
|
||||
dispatchReceiverValue: ReceiverValue?,
|
||||
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
||||
scope: FirScope,
|
||||
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
|
||||
)
|
||||
}
|
||||
@@ -94,18 +95,20 @@ class MemberScopeTowerLevel(
|
||||
|
||||
output.consumeCandidate(
|
||||
candidate, dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>
|
||||
implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>,
|
||||
scope
|
||||
)
|
||||
|
||||
if (implicitExtensionInvokeMode) {
|
||||
output.consumeCandidate(
|
||||
candidate, dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue = null,
|
||||
scope,
|
||||
builtInExtensionFunctionReceiverValue = this.extensionReceiver
|
||||
)
|
||||
}
|
||||
} else if (candidate is FirClassLikeSymbol<*>) {
|
||||
output.consumeCandidate(candidate, null, extensionReceiver as? ImplicitReceiverValue<*>)
|
||||
output.consumeCandidate(candidate, null, extensionReceiver as? ImplicitReceiverValue<*>, scope)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +116,7 @@ class MemberScopeTowerLevel(
|
||||
val withSynthetic = FirSyntheticPropertiesScope(session, scope)
|
||||
withSynthetic.processScopeMembers { symbol ->
|
||||
empty = false
|
||||
output.consumeCandidate(symbol, NotNullableReceiverValue(dispatchReceiver), null)
|
||||
output.consumeCandidate(symbol, NotNullableReceiverValue(dispatchReceiver), null, scope)
|
||||
}
|
||||
}
|
||||
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
|
||||
@@ -226,7 +229,8 @@ class ScopeTowerLevel(
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
processor.consumeCandidate(
|
||||
unwrappedCandidate as T, dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>
|
||||
implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>,
|
||||
scope
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -256,7 +260,8 @@ class ScopeTowerLevel(
|
||||
empty = false
|
||||
processor.consumeCandidate(
|
||||
it as T, dispatchReceiverValue = null,
|
||||
implicitExtensionReceiverValue = null
|
||||
implicitExtensionReceiverValue = null,
|
||||
scope = scope
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -175,7 +175,8 @@ class FirSyntheticCallGenerator(
|
||||
private fun generateCandidate(callInfo: CallInfo, function: FirSimpleFunction, context: ResolutionContext): Candidate =
|
||||
CandidateFactory(context, callInfo).createCandidate(
|
||||
symbol = function.symbol,
|
||||
explicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||
explicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||
scope = null
|
||||
)
|
||||
|
||||
private fun generateCallInfo(name: Name, argumentList: FirArgumentList, callKind: CallKind) = CallInfo(
|
||||
|
||||
+4
-37
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.scopes.impl
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.*
|
||||
@@ -36,11 +35,10 @@ abstract class AbstractFirUseSiteMemberScope(
|
||||
name: Name
|
||||
): Collection<FirFunctionSymbol<*>> = mutableListOf<FirFunctionSymbol<*>>().apply {
|
||||
val overrideCandidates = mutableSetOf<FirFunctionSymbol<*>>()
|
||||
declaredMemberScope.processFunctionsByName(name) {
|
||||
if (it.isStatic) return@processFunctionsByName
|
||||
val directOverridden = computeDirectOverridden(it)
|
||||
this@AbstractFirUseSiteMemberScope.directOverriddenFunctions[it] = directOverridden
|
||||
val symbol = processInheritedDefaultParameters(it, directOverridden)
|
||||
declaredMemberScope.processFunctionsByName(name) { symbol ->
|
||||
if (symbol.isStatic) return@processFunctionsByName
|
||||
val directOverridden = computeDirectOverridden(symbol)
|
||||
this@AbstractFirUseSiteMemberScope.directOverriddenFunctions[symbol] = directOverridden
|
||||
overrideCandidates += symbol
|
||||
add(symbol)
|
||||
}
|
||||
@@ -70,37 +68,6 @@ abstract class AbstractFirUseSiteMemberScope(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun processInheritedDefaultParameters(
|
||||
symbol: FirFunctionSymbol<*>,
|
||||
directOverridden: Collection<FirFunctionSymbol<*>>
|
||||
): FirFunctionSymbol<*> {
|
||||
val firSimpleFunction = symbol.fir as? FirSimpleFunction ?: return symbol
|
||||
if (firSimpleFunction.valueParameters.isEmpty() || firSimpleFunction.valueParameters.any { it.defaultValue != null }) return symbol
|
||||
|
||||
val overriddenWithDefault: FirFunction<*> =
|
||||
directOverridden.singleOrNull {
|
||||
it.fir.valueParameters.any { parameter -> parameter.defaultValue != null }
|
||||
}?.fir ?: return symbol
|
||||
|
||||
val newSymbol = FirNamedFunctionSymbol(symbol.callableId, false, null)
|
||||
|
||||
createFunctionCopy(firSimpleFunction, newSymbol).apply {
|
||||
resolvePhase = firSimpleFunction.resolvePhase
|
||||
typeParameters += firSimpleFunction.typeParameters
|
||||
valueParameters += firSimpleFunction.valueParameters.zip(overriddenWithDefault.valueParameters)
|
||||
.map { (overrideParameter, overriddenParameter) ->
|
||||
if (overriddenParameter.defaultValue != null)
|
||||
createValueParameterCopy(overrideParameter, overriddenParameter.defaultValue).apply {
|
||||
annotations += overrideParameter.annotations
|
||||
}.build()
|
||||
else
|
||||
overrideParameter
|
||||
}
|
||||
}.build()
|
||||
|
||||
return newSymbol
|
||||
}
|
||||
|
||||
override fun processDirectOverriddenFunctionsWithBaseScope(
|
||||
functionSymbol: FirFunctionSymbol<*>,
|
||||
processor: (FirFunctionSymbol<*>, FirTypeScope) -> ProcessorAction
|
||||
|
||||
+1
@@ -69,6 +69,7 @@ class SingleCandidateResolver(
|
||||
explicitReceiverKind = explicitReceiverKind,
|
||||
dispatchReceiverValue = dispatchReceiverValue,
|
||||
implicitExtensionReceiverValue = implicitExtensionReceiverValue,
|
||||
scope = null,
|
||||
)
|
||||
|
||||
val applicability = resolutionStageRunner.processCandidate(candidate, resolutionContext, stopOnFirstError = true)
|
||||
|
||||
Reference in New Issue
Block a user