diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index 3069962ffe2..636837cf17f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -549,121 +549,6 @@ class KotlinToResolvedCallTransformer( } } -sealed class NewAbstractResolvedCall() : ResolvedCall { - abstract val argumentMappingByOriginal: Map - abstract val kotlinCall: KotlinCall - protected abstract val languageVersionSettings: LanguageVersionSettings - - protected var argumentToParameterMap: Map? = null - protected var _valueArguments: Map? = null - - private var nonTrivialUpdatedResultInfo: DataFlowInfo? = null - - abstract fun containsOnlyOnlyInputTypesErrors(): Boolean - - override fun getCall(): Call = kotlinCall.psiKotlinCall.psiCall - - override fun getValueArguments(): Map { - if (_valueArguments == null) { - _valueArguments = createValueArguments() - } - return _valueArguments!! - } - - override fun getValueArgumentsByIndex(): List? { - val arguments = ArrayList(candidateDescriptor.valueParameters.size) - for (i in 0..candidateDescriptor.valueParameters.size - 1) { - arguments.add(null) - } - - for ((parameterDescriptor, value) in valueArguments) { - val oldValue = arguments.set(parameterDescriptor.index, value) - if (oldValue != null) { - return null - } - } - - if (arguments.any { it == null }) return null - - @Suppress("UNCHECKED_CAST") - return arguments as List - } - - override fun getArgumentMapping(valueArgument: ValueArgument): ArgumentMapping { - if (argumentToParameterMap == null) { - argumentToParameterMap = argumentToParameterMap(resultingDescriptor, valueArguments) - } - return argumentToParameterMap!![valueArgument] ?: ArgumentUnmapped - } - - override fun getDataFlowInfoForArguments() = object : DataFlowInfoForArguments { - override fun getResultInfo(): DataFlowInfo = nonTrivialUpdatedResultInfo ?: kotlinCall.psiKotlinCall.resultDataFlowInfo - - override fun getInfo(valueArgument: ValueArgument): DataFlowInfo { - val externalPsiCallArgument = kotlinCall.externalArgument?.psiCallArgument - if (externalPsiCallArgument?.valueArgument == valueArgument) { - return externalPsiCallArgument.dataFlowInfoAfterThisArgument - } - return kotlinCall.psiKotlinCall.dataFlowInfoForArguments.getInfo(valueArgument) - } - } - - // Currently, updated only with info from effect system - internal fun updateResultingDataFlowInfo(dataFlowInfo: DataFlowInfo) { - if (dataFlowInfo == DataFlowInfo.EMPTY) return - assert(nonTrivialUpdatedResultInfo == null) { - "Attempt to rewrite resulting dataFlowInfo enhancement for call: $kotlinCall" - } - nonTrivialUpdatedResultInfo = dataFlowInfo.and(kotlinCall.psiKotlinCall.resultDataFlowInfo) - } - - protected abstract fun argumentToParameterMap( - resultingDescriptor: CallableDescriptor, - valueArguments: Map, - ): Map - - private fun createValueArguments(): Map = - LinkedHashMap().also { result -> - val needToUseCorrectExecutionOrderForVarargArguments = - languageVersionSettings.supportsFeature(LanguageFeature.UseCorrectExecutionOrderForVarargArguments) - var varargMappings: MutableList>? = null - for ((originalParameter, resolvedCallArgument) in argumentMappingByOriginal) { - val resultingParameter = resultingDescriptor.valueParameters[originalParameter.index] - - result[resultingParameter] = when (resolvedCallArgument) { - ResolvedCallArgument.DefaultArgument -> - DefaultValueArgument.DEFAULT - is ResolvedCallArgument.SimpleArgument -> { - val valueArgument = resolvedCallArgument.callArgument.psiCallArgument.valueArgument - if (resultingParameter.isVararg) { - if (needToUseCorrectExecutionOrderForVarargArguments) { - VarargValueArgument().apply { addArgument(valueArgument) } - } else { - val vararg = VarargValueArgument().apply { addArgument(valueArgument) } - if (varargMappings == null) varargMappings = SmartList() - varargMappings.add(resultingParameter to vararg) - continue - } - } else { - ExpressionValueArgument(valueArgument) - } - } - is ResolvedCallArgument.VarargArgument -> - VarargValueArgument().apply { - resolvedCallArgument.arguments.map { it.psiCallArgument.valueArgument }.forEach { addArgument(it) } - } - } - } - - if (varargMappings != null && !needToUseCorrectExecutionOrderForVarargArguments) { - for ((parameter, argument) in varargMappings) { - result[parameter] = argument - } - } - }.compactIfPossible() - -} - fun CandidateApplicability.toResolutionStatus(): ResolutionStatus = when (this) { CandidateApplicability.RESOLVED, CandidateApplicability.RESOLVED_LOW_PRIORITY, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewAbstractResolvedCall.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewAbstractResolvedCall.kt new file mode 100644 index 00000000000..d1f92686734 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewAbstractResolvedCall.kt @@ -0,0 +1,134 @@ +/* + * Copyright 2010-2021 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.tower + +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.psi.Call +import org.jetbrains.kotlin.psi.ValueArgument +import org.jetbrains.kotlin.resolve.calls.components.isVararg +import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor +import org.jetbrains.kotlin.resolve.calls.model.* +import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo +import org.jetbrains.kotlin.utils.SmartList +import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible + +sealed class NewAbstractResolvedCall() : ResolvedCall { + abstract val argumentMappingByOriginal: Map + abstract val kotlinCall: KotlinCall + protected abstract val languageVersionSettings: LanguageVersionSettings + + protected var argumentToParameterMap: Map? = null + protected var _valueArguments: Map? = null + + private var nonTrivialUpdatedResultInfo: DataFlowInfo? = null + + abstract fun containsOnlyOnlyInputTypesErrors(): Boolean + + override fun getCall(): Call = kotlinCall.psiKotlinCall.psiCall + + override fun getValueArguments(): Map { + if (_valueArguments == null) { + _valueArguments = createValueArguments() + } + return _valueArguments!! + } + + override fun getValueArgumentsByIndex(): List? { + val arguments = ArrayList(candidateDescriptor.valueParameters.size) + for (i in 0..candidateDescriptor.valueParameters.size - 1) { + arguments.add(null) + } + + for ((parameterDescriptor, value) in valueArguments) { + val oldValue = arguments.set(parameterDescriptor.index, value) + if (oldValue != null) { + return null + } + } + + if (arguments.any { it == null }) return null + + @Suppress("UNCHECKED_CAST") + return arguments as List + } + + override fun getArgumentMapping(valueArgument: ValueArgument): ArgumentMapping { + if (argumentToParameterMap == null) { + argumentToParameterMap = argumentToParameterMap(resultingDescriptor, valueArguments) + } + return argumentToParameterMap!![valueArgument] ?: ArgumentUnmapped + } + + override fun getDataFlowInfoForArguments() = object : DataFlowInfoForArguments { + override fun getResultInfo(): DataFlowInfo = nonTrivialUpdatedResultInfo ?: kotlinCall.psiKotlinCall.resultDataFlowInfo + + override fun getInfo(valueArgument: ValueArgument): DataFlowInfo { + val externalPsiCallArgument = kotlinCall.externalArgument?.psiCallArgument + if (externalPsiCallArgument?.valueArgument == valueArgument) { + return externalPsiCallArgument.dataFlowInfoAfterThisArgument + } + return kotlinCall.psiKotlinCall.dataFlowInfoForArguments.getInfo(valueArgument) + } + } + + // Currently, updated only with info from effect system + internal fun updateResultingDataFlowInfo(dataFlowInfo: DataFlowInfo) { + if (dataFlowInfo == DataFlowInfo.EMPTY) return + assert(nonTrivialUpdatedResultInfo == null) { + "Attempt to rewrite resulting dataFlowInfo enhancement for call: $kotlinCall" + } + nonTrivialUpdatedResultInfo = dataFlowInfo.and(kotlinCall.psiKotlinCall.resultDataFlowInfo) + } + + protected abstract fun argumentToParameterMap( + resultingDescriptor: CallableDescriptor, + valueArguments: Map, + ): Map + + private fun createValueArguments(): Map = + LinkedHashMap().also { result -> + val needToUseCorrectExecutionOrderForVarargArguments = + languageVersionSettings.supportsFeature(LanguageFeature.UseCorrectExecutionOrderForVarargArguments) + var varargMappings: MutableList>? = null + for ((originalParameter, resolvedCallArgument) in argumentMappingByOriginal) { + val resultingParameter = resultingDescriptor.valueParameters[originalParameter.index] + + result[resultingParameter] = when (resolvedCallArgument) { + ResolvedCallArgument.DefaultArgument -> + DefaultValueArgument.DEFAULT + is ResolvedCallArgument.SimpleArgument -> { + val valueArgument = resolvedCallArgument.callArgument.psiCallArgument.valueArgument + if (resultingParameter.isVararg) { + if (needToUseCorrectExecutionOrderForVarargArguments) { + VarargValueArgument().apply { addArgument(valueArgument) } + } else { + val vararg = VarargValueArgument().apply { addArgument(valueArgument) } + if (varargMappings == null) varargMappings = SmartList() + varargMappings.add(resultingParameter to vararg) + continue + } + } else { + ExpressionValueArgument(valueArgument) + } + } + is ResolvedCallArgument.VarargArgument -> + VarargValueArgument().apply { + resolvedCallArgument.arguments.map { it.psiCallArgument.valueArgument }.forEach { addArgument(it) } + } + } + } + + if (varargMappings != null && !needToUseCorrectExecutionOrderForVarargArguments) { + for ((parameter, argument) in varargMappings) { + result[parameter] = argument + } + } + }.compactIfPossible() + +} \ No newline at end of file