Extract NewAbstractResolvedCall into separate file

This commit is contained in:
Victor Petukhov
2021-09-20 15:20:48 +03:00
parent fb3f3642f7
commit 65a8c9d89a
2 changed files with 134 additions and 115 deletions
@@ -549,121 +549,6 @@ class KotlinToResolvedCallTransformer(
}
}
sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D> {
abstract val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
abstract val kotlinCall: KotlinCall
protected abstract val languageVersionSettings: LanguageVersionSettings
protected var argumentToParameterMap: Map<ValueArgument, ArgumentMatchImpl>? = null
protected var _valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>? = null
private var nonTrivialUpdatedResultInfo: DataFlowInfo? = null
abstract fun containsOnlyOnlyInputTypesErrors(): Boolean
override fun getCall(): Call = kotlinCall.psiKotlinCall.psiCall
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> {
if (_valueArguments == null) {
_valueArguments = createValueArguments()
}
return _valueArguments!!
}
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument>? {
val arguments = ArrayList<ResolvedValueArgument?>(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<ResolvedValueArgument>
}
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<ValueParameterDescriptor, ResolvedValueArgument>,
): Map<ValueArgument, ArgumentMatchImpl>
private fun createValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> =
LinkedHashMap<ValueParameterDescriptor, ResolvedValueArgument>().also { result ->
val needToUseCorrectExecutionOrderForVarargArguments =
languageVersionSettings.supportsFeature(LanguageFeature.UseCorrectExecutionOrderForVarargArguments)
var varargMappings: MutableList<Pair<ValueParameterDescriptor, VarargValueArgument>>? = 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,
@@ -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<D : CallableDescriptor>() : ResolvedCall<D> {
abstract val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
abstract val kotlinCall: KotlinCall
protected abstract val languageVersionSettings: LanguageVersionSettings
protected var argumentToParameterMap: Map<ValueArgument, ArgumentMatchImpl>? = null
protected var _valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>? = null
private var nonTrivialUpdatedResultInfo: DataFlowInfo? = null
abstract fun containsOnlyOnlyInputTypesErrors(): Boolean
override fun getCall(): Call = kotlinCall.psiKotlinCall.psiCall
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> {
if (_valueArguments == null) {
_valueArguments = createValueArguments()
}
return _valueArguments!!
}
override fun getValueArgumentsByIndex(): List<ResolvedValueArgument>? {
val arguments = ArrayList<ResolvedValueArgument?>(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<ResolvedValueArgument>
}
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<ValueParameterDescriptor, ResolvedValueArgument>,
): Map<ValueArgument, ArgumentMatchImpl>
private fun createValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> =
LinkedHashMap<ValueParameterDescriptor, ResolvedValueArgument>().also { result ->
val needToUseCorrectExecutionOrderForVarargArguments =
languageVersionSettings.supportsFeature(LanguageFeature.UseCorrectExecutionOrderForVarargArguments)
var varargMappings: MutableList<Pair<ValueParameterDescriptor, VarargValueArgument>>? = 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()
}