Extract NewAbstractResolvedCall into separate file
This commit is contained in:
-115
@@ -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,
|
||||
|
||||
+134
@@ -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()
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user