Introduce "flat signature" - a generalized abstraction for a (call) signatures that can be compared for specificity.
This commit is contained in:
-92
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.results
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
|
|
||||||
class CandidateCallWithArgumentMapping<D : CallableDescriptor, K> private constructor(
|
|
||||||
val resolvedCall: MutableResolvedCall<D>,
|
|
||||||
private val argumentsToParameters: Map<K, ValueParameterDescriptor>,
|
|
||||||
val parametersWithDefaultValuesCount: Int
|
|
||||||
) {
|
|
||||||
override fun toString(): String =
|
|
||||||
"${resolvedCall.call}: $parametersWithDefaultValuesCount defaults in ${resolvedCall.candidateDescriptor}"
|
|
||||||
|
|
||||||
val candidateDescriptor: D
|
|
||||||
get() = resolvedCall.candidateDescriptor
|
|
||||||
|
|
||||||
val hasVarargs: Boolean
|
|
||||||
get() = candidateDescriptor.valueParameters.any { it.varargElementType != null }
|
|
||||||
|
|
||||||
val typeParameters: List<TypeParameterDescriptor>
|
|
||||||
get() = candidateDescriptor.original.typeParameters
|
|
||||||
|
|
||||||
val argumentsCount: Int
|
|
||||||
get() = argumentsToParameters.size
|
|
||||||
|
|
||||||
val argumentKeys: Collection<K>
|
|
||||||
get() = argumentsToParameters.keys
|
|
||||||
|
|
||||||
val isGeneric: Boolean = typeParameters.isNotEmpty()
|
|
||||||
|
|
||||||
val extensionReceiverType: KotlinType?
|
|
||||||
get() = candidateDescriptor.extensionReceiverParameter?.type
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the type of a value that can be used in place of the corresponding parameter.
|
|
||||||
*/
|
|
||||||
fun getValueParameterType(argumentKey: K): KotlinType? =
|
|
||||||
argumentsToParameters[argumentKey]?.let {
|
|
||||||
valueParameterDescriptor ->
|
|
||||||
valueParameterDescriptor.varargElementType ?: valueParameterDescriptor.type
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun <D : CallableDescriptor, K> create(
|
|
||||||
call: MutableResolvedCall<D>,
|
|
||||||
resolvedArgumentToKeys: (ResolvedValueArgument) -> Collection<K>
|
|
||||||
): CandidateCallWithArgumentMapping<D, K> {
|
|
||||||
val argumentsToParameters = hashMapOf<K, ValueParameterDescriptor>()
|
|
||||||
var parametersWithDefaultValuesCount = 0
|
|
||||||
|
|
||||||
val unsubstitutedValueParameters = call.candidateDescriptor.original.valueParameters
|
|
||||||
for ((valueParameterDescriptor, resolvedValueArgument) in call.valueArguments.entries) {
|
|
||||||
if (resolvedValueArgument is DefaultValueArgument) {
|
|
||||||
parametersWithDefaultValuesCount++
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val keys = resolvedArgumentToKeys(resolvedValueArgument)
|
|
||||||
for (argumentKey in keys) {
|
|
||||||
// TODO fix 'original' for value parameters of Java generic descriptors.
|
|
||||||
// Should be able to use just 'valueParameterDescriptor' below.
|
|
||||||
// Doesn't work for Java generic descriptors. See also KT-10939.
|
|
||||||
argumentsToParameters[argumentKey] = unsubstitutedValueParameters[valueParameterDescriptor.index]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CandidateCallWithArgumentMapping(call, argumentsToParameters, parametersWithDefaultValuesCount)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.resolve.calls.results
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.psi.ValueArgument
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class FlatSignature<out T>(
|
||||||
|
val origin: T,
|
||||||
|
val typeParameters: Collection<TypeParameterDescriptor>,
|
||||||
|
val valueParameterTypes: List<KotlinType?>,
|
||||||
|
val hasVarargs: Boolean,
|
||||||
|
val numDefaults: Int
|
||||||
|
) {
|
||||||
|
override fun toString() = "<${typeParameters.joinToString {it.name.asString()} }> ${valueParameterTypes.joinToString()}; " +
|
||||||
|
"${if (hasVarargs) "varargs;" else ""} $numDefaults"
|
||||||
|
|
||||||
|
val isGeneric = typeParameters.isNotEmpty()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun <D : CallableDescriptor, RC : ResolvedCall<D>> createFromResolvedCall(call: RC): FlatSignature<RC> {
|
||||||
|
val originalDescriptor = call.candidateDescriptor.original
|
||||||
|
val originalValueParameters = originalDescriptor.valueParameters
|
||||||
|
val originalTypeParameters = originalDescriptor.typeParameters
|
||||||
|
|
||||||
|
var numDefaults = 0
|
||||||
|
val valueArgumentToParameterType = HashMap<ValueArgument, KotlinType>()
|
||||||
|
for ((valueParameter, resolvedValueArgument) in call.valueArguments.entries) {
|
||||||
|
if (resolvedValueArgument is DefaultValueArgument) {
|
||||||
|
numDefaults++
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val originalValueParameter = originalValueParameters[valueParameter.index]
|
||||||
|
val parameterType = originalValueParameter.flatType
|
||||||
|
for (valueArgument in resolvedValueArgument.arguments) {
|
||||||
|
if (valueArgument.getArgumentExpression() == null) continue
|
||||||
|
valueArgumentToParameterType[valueArgument] = parameterType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val extensionReceiverParameterType = originalDescriptor.extensionReceiverParameter?.type
|
||||||
|
val valueArgumentParameterTypes = call.call.valueArguments.map { valueArgumentToParameterType[it] }
|
||||||
|
val valueParameterTypes = extensionReceiverParameterType.singletonOrEmptyList() + valueArgumentParameterTypes
|
||||||
|
|
||||||
|
val hasVarargs = originalDescriptor.valueParameters.any { it.varargElementType != null }
|
||||||
|
|
||||||
|
return FlatSignature(call, originalTypeParameters, valueParameterTypes, hasVarargs, numDefaults)
|
||||||
|
}
|
||||||
|
|
||||||
|
val ValueParameterDescriptor.flatType: KotlinType
|
||||||
|
get() = varargElementType ?: type
|
||||||
|
}
|
||||||
|
}
|
||||||
+42
-59
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION
|
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.toHandle
|
import org.jetbrains.kotlin.resolve.calls.inference.toHandle
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
||||||
@@ -33,7 +32,6 @@ import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionMutableResolve
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
|
||||||
|
|
||||||
class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
||||||
|
|
||||||
@@ -84,23 +82,21 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
|
|
||||||
val conflictingCandidates = filteredCandidates.map {
|
val conflictingCandidates = filteredCandidates.map {
|
||||||
candidateCall ->
|
candidateCall ->
|
||||||
CandidateCallWithArgumentMapping.create(candidateCall) { it.arguments.filter { it.getArgumentExpression() != null } }
|
FlatSignature.createFromResolvedCall(candidateCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
val bestCandidatesByParameterTypes = conflictingCandidates.mapNotNull {
|
val bestCandidatesByParameterTypes = conflictingCandidates.filter {
|
||||||
candidate ->
|
candidate ->
|
||||||
candidate.check {
|
isMostSpecific(candidate, conflictingCandidates) {
|
||||||
isMostSpecific(candidate, conflictingCandidates) {
|
call1, call2 ->
|
||||||
call1, call2 ->
|
isNotLessSpecificCallWithArgumentMapping(call1, call2, discriminateGenerics)
|
||||||
isNotLessSpecificCallWithArgumentMapping(call1, call2, discriminateGenerics)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestCandidatesByParameterTypes.exactMaxWith {
|
return bestCandidatesByParameterTypes.exactMaxWith {
|
||||||
call1, call2 ->
|
call1, call2 ->
|
||||||
isOfNotLessSpecificShape(call1, call2) && isOfNotLessSpecificVisibilityForDebugger(call1, call2, isDebuggerContext)
|
isOfNotLessSpecificShape(call1, call2) && isOfNotLessSpecificVisibilityForDebugger(call1, call2, isDebuggerContext)
|
||||||
}?.resolvedCall
|
}?.origin
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun <C : Any> Collection<C>.exactMaxWith(isNotWorse: (C, C) -> Boolean): C? {
|
private inline fun <C : Any> Collection<C>.exactMaxWith(isNotWorse: (C, C) -> Boolean): C? {
|
||||||
@@ -134,12 +130,12 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
/**
|
/**
|
||||||
* `call1` is not less specific than `call2`
|
* `call1` is not less specific than `call2`
|
||||||
*/
|
*/
|
||||||
private fun <D : CallableDescriptor, K> isNotLessSpecificCallWithArgumentMapping(
|
private fun <D : CallableDescriptor> isNotLessSpecificCallWithArgumentMapping(
|
||||||
call1: CandidateCallWithArgumentMapping<D, K>,
|
call1: FlatSignature<MutableResolvedCall<D>>,
|
||||||
call2: CandidateCallWithArgumentMapping<D, K>,
|
call2: FlatSignature<MutableResolvedCall<D>>,
|
||||||
discriminateGenerics: Boolean
|
discriminateGenerics: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return tryCompareDescriptorsFromScripts(call1.candidateDescriptor, call2.candidateDescriptor) ?:
|
return tryCompareDescriptorsFromScripts(call1.candidateDescriptor(), call2.candidateDescriptor()) ?:
|
||||||
compareCallsByUsedArguments(call1, call2, discriminateGenerics)
|
compareCallsByUsedArguments(call1, call2, discriminateGenerics)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,9 +143,9 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
* Returns `true` if `d1` is definitely not less specific than `d2`,
|
* Returns `true` if `d1` is definitely not less specific than `d2`,
|
||||||
* `false` otherwise.
|
* `false` otherwise.
|
||||||
*/
|
*/
|
||||||
private fun <D : CallableDescriptor, K> compareCallsByUsedArguments(
|
private fun <D : CallableDescriptor> compareCallsByUsedArguments(
|
||||||
call1: CandidateCallWithArgumentMapping<D, K>,
|
call1: FlatSignature<MutableResolvedCall<D>>,
|
||||||
call2: CandidateCallWithArgumentMapping<D, K>,
|
call2: FlatSignature<MutableResolvedCall<D>>,
|
||||||
discriminateGenerics: Boolean
|
discriminateGenerics: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (discriminateGenerics) {
|
if (discriminateGenerics) {
|
||||||
@@ -165,7 +161,7 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
val typeParameters = call2.typeParameters
|
val typeParameters = call2.typeParameters
|
||||||
val constraintSystemBuilder: ConstraintSystem.Builder = ConstraintSystemBuilderImpl()
|
val constraintSystemBuilder: ConstraintSystem.Builder = ConstraintSystemBuilderImpl()
|
||||||
var hasConstraints = false
|
var hasConstraints = false
|
||||||
val typeSubstitutor = constraintSystemBuilder.registerTypeVariables(call1.resolvedCall.call.toHandle(), typeParameters)
|
val typeSubstitutor = constraintSystemBuilder.registerTypeVariables(call1.callHandle(), typeParameters)
|
||||||
|
|
||||||
fun compareTypesAndUpdateConstraints(type1: KotlinType?, type2: KotlinType?, constraintPosition: ConstraintPosition): Boolean {
|
fun compareTypesAndUpdateConstraints(type1: KotlinType?, type2: KotlinType?, constraintPosition: ConstraintPosition): Boolean {
|
||||||
if (type1 == null || type2 == null) return true
|
if (type1 == null || type2 == null) return true
|
||||||
@@ -186,23 +182,11 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
val extensionReceiverType1 = call1.extensionReceiverType
|
var argumentIndex = 0
|
||||||
val extensionReceiverType2 = call2.extensionReceiverType
|
for ((type1, type2) in call1.valueParameterTypes.zip(call2.valueParameterTypes)) {
|
||||||
if (!compareTypesAndUpdateConstraints(extensionReceiverType1, extensionReceiverType2, RECEIVER_POSITION.position())) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(call1.argumentsCount == call2.argumentsCount) {
|
|
||||||
"$call1 and $call2 have different number of explicit arguments"
|
|
||||||
}
|
|
||||||
|
|
||||||
for (argumentKey in call1.argumentKeys) {
|
|
||||||
val type1 = call1.getValueParameterType(argumentKey)
|
|
||||||
val type2 = call2.getValueParameterType(argumentKey)
|
|
||||||
|
|
||||||
// We use this constraint system for subtyping relation check only,
|
// We use this constraint system for subtyping relation check only,
|
||||||
// so exact value parameter position doesn't matter.
|
// so exact value parameter position doesn't matter.
|
||||||
if (!compareTypesAndUpdateConstraints(type1, type2, VALUE_PARAMETER_POSITION.position(0))) {
|
if (!compareTypesAndUpdateConstraints(type1, type2, VALUE_PARAMETER_POSITION.position(++argumentIndex))) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,32 +202,29 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <D: CallableDescriptor, K> isOfNotLessSpecificShape(
|
private fun <D: CallableDescriptor> isOfNotLessSpecificShape(
|
||||||
call1: CandidateCallWithArgumentMapping<D, K>,
|
call1: FlatSignature<MutableResolvedCall<D>>,
|
||||||
call2: CandidateCallWithArgumentMapping<D, K>
|
call2: FlatSignature<MutableResolvedCall<D>>
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val hasVarargs1 = call1.hasVarargs
|
val hasVarargs1 = call1.hasVarargs
|
||||||
val hasVarargs2 = call2.hasVarargs
|
val hasVarargs2 = call2.hasVarargs
|
||||||
if (hasVarargs1 && !hasVarargs2) return false
|
if (hasVarargs1 && !hasVarargs2) return false
|
||||||
if (!hasVarargs1 && hasVarargs2) return true
|
if (!hasVarargs1 && hasVarargs2) return true
|
||||||
|
|
||||||
if (call1.parametersWithDefaultValuesCount > call2.parametersWithDefaultValuesCount) {
|
if (call1.numDefaults > call2.numDefaults) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <D: CallableDescriptor, K> isOfNotLessSpecificVisibilityForDebugger(
|
private fun <D: CallableDescriptor> isOfNotLessSpecificVisibilityForDebugger(
|
||||||
call1: CandidateCallWithArgumentMapping<D, K>,
|
call1: FlatSignature<MutableResolvedCall<D>>,
|
||||||
call2: CandidateCallWithArgumentMapping<D, K>,
|
call2: FlatSignature<MutableResolvedCall<D>>,
|
||||||
isDebuggerContext: Boolean
|
isDebuggerContext: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (isDebuggerContext) {
|
if (isDebuggerContext) {
|
||||||
val isMoreVisible1 = Visibilities.compare(
|
val isMoreVisible1 = Visibilities.compare(call1.descriptorVisibility(), call2.descriptorVisibility())
|
||||||
call1.resolvedCall.resultingDescriptor.visibility,
|
|
||||||
call2.resolvedCall.resultingDescriptor.visibility
|
|
||||||
)
|
|
||||||
if (isMoreVisible1 != null && isMoreVisible1 < 0) return false
|
if (isMoreVisible1 != null && isMoreVisible1 < 0) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,24 +249,20 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns `false` if `d1` is definitely less specific than `d2`,
|
|
||||||
* `null` if undecided.
|
|
||||||
*/
|
|
||||||
private fun tryCompareExtensionReceiverType(type1: KotlinType?, type2: KotlinType?): Boolean? {
|
|
||||||
if (type1 != null && type2 != null) {
|
|
||||||
if (!typeNotLessSpecific(type1, type2))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `true` if `d1` is definitely not less specific than `d2`,
|
* Returns `true` if `d1` is definitely not less specific than `d2`,
|
||||||
* `false` if `d1` is definitely less specific than `d2`,
|
* `false` if `d1` is definitely less specific than `d2`,
|
||||||
* `null` if undecided.
|
* `null` if undecided.
|
||||||
*/
|
*/
|
||||||
private fun compareFunctionParameterTypes(f: CallableDescriptor, g: CallableDescriptor): Boolean {
|
private fun compareFunctionParameterTypes(f: CallableDescriptor, g: CallableDescriptor): Boolean {
|
||||||
|
val fReceiverType = f.extensionReceiverType
|
||||||
|
val gReceiverType = g.extensionReceiverType
|
||||||
|
if (fReceiverType != null && gReceiverType != null) {
|
||||||
|
if (!typeNotLessSpecific(fReceiverType, gReceiverType)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val fParams = f.valueParameters
|
val fParams = f.valueParameters
|
||||||
val gParams = g.valueParameters
|
val gParams = g.valueParameters
|
||||||
|
|
||||||
@@ -319,8 +296,6 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
private fun isNotLessSpecificCallableReference(f: CallableDescriptor, g: CallableDescriptor): Boolean =
|
private fun isNotLessSpecificCallableReference(f: CallableDescriptor, g: CallableDescriptor): Boolean =
|
||||||
// TODO should we "discriminate generic descriptors" for callable references?
|
// TODO should we "discriminate generic descriptors" for callable references?
|
||||||
tryCompareDescriptorsFromScripts(f, g) ?:
|
tryCompareDescriptorsFromScripts(f, g) ?:
|
||||||
// TODO compare functional types for 'f' and 'g'
|
|
||||||
tryCompareExtensionReceiverType(f.extensionReceiverType, g.extensionReceiverType) ?:
|
|
||||||
compareFunctionParameterTypes(f, g)
|
compareFunctionParameterTypes(f, g)
|
||||||
|
|
||||||
private fun getVarargElementTypeOrType(parameterDescriptor: ValueParameterDescriptor): KotlinType =
|
private fun getVarargElementTypeOrType(parameterDescriptor: ValueParameterDescriptor): KotlinType =
|
||||||
@@ -398,5 +373,13 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
ResolvedCallHashingStrategy as TObjectHashingStrategy<C>
|
ResolvedCallHashingStrategy as TObjectHashingStrategy<C>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun <D : CallableDescriptor> FlatSignature<ResolvedCall<D>>.candidateDescriptor() =
|
||||||
|
origin.candidateDescriptor.original
|
||||||
|
|
||||||
|
internal fun <D : CallableDescriptor> FlatSignature<ResolvedCall<D>>.callHandle() =
|
||||||
|
origin.call.toHandle()
|
||||||
|
|
||||||
|
internal fun <D : CallableDescriptor> FlatSignature<ResolvedCall<D>>.descriptorVisibility() =
|
||||||
|
candidateDescriptor().visibility
|
||||||
|
|||||||
Reference in New Issue
Block a user