Change resolution priority level for SAM adapters
After this change SAM adapters are being resolved in the same group as members, thus their overload resolution happens simultaneously. But in the case of overload resolution ambiguity try to filter out all synthetic members and run the process again. See the issue and new test for clarification #KT-11128 In Progress
This commit is contained in:
@@ -49,7 +49,6 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
@@ -517,13 +516,7 @@ public abstract class StackValue {
|
||||
ReceiverParameterDescriptor dispatchReceiverParameter = descriptor.getDispatchReceiverParameter();
|
||||
ReceiverParameterDescriptor extensionReceiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
|
||||
if (descriptor.getOriginal() instanceof SamAdapterExtensionFunctionDescriptor) {
|
||||
callDispatchReceiver = callExtensionReceiver;
|
||||
callExtensionReceiver = null;
|
||||
dispatchReceiverParameter = extensionReceiverParameter;
|
||||
extensionReceiverParameter = null;
|
||||
}
|
||||
else if (descriptor instanceof SyntheticFieldDescriptor) {
|
||||
if (descriptor instanceof SyntheticFieldDescriptor) {
|
||||
dispatchReceiverParameter = ((SyntheticFieldDescriptor) descriptor).getDispatchReceiverParameterForBackend();
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -34,6 +34,8 @@ object ProtectedSyntheticExtensionCallChecker : CallChecker {
|
||||
|
||||
val sourceFunction = when (descriptor) {
|
||||
is SyntheticJavaPropertyDescriptor -> descriptor.getMethod
|
||||
// TODO: this branch becomes unnecessary, because common checks are applied to SAM adapters being resolved as common members
|
||||
// But this part may be still useful when we enable backward compatibility mode and SAM adapters become extensions again
|
||||
is SamAdapterExtensionFunctionDescriptor -> descriptor.baseDescriptorForSynthetic
|
||||
else -> return
|
||||
}
|
||||
|
||||
+2
-2
@@ -291,7 +291,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
|
||||
companion object {
|
||||
fun create(ownerClass: ClassDescriptor, getMethod: FunctionDescriptor, setMethod: FunctionDescriptor?, name: Name, type: KotlinType): MyPropertyDescriptor {
|
||||
val visibility = syntheticExtensionVisibility(getMethod)
|
||||
val visibility = syntheticVisibility(getMethod, isUsedForExtension = true)
|
||||
val descriptor = MyPropertyDescriptor(DescriptorUtils.getContainingModule(ownerClass),
|
||||
null,
|
||||
Annotations.EMPTY,
|
||||
@@ -328,7 +328,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
PropertySetterDescriptorImpl(descriptor,
|
||||
setMethod.annotations,
|
||||
Modality.FINAL,
|
||||
syntheticExtensionVisibility(setMethod),
|
||||
syntheticVisibility(setMethod, isUsedForExtension = true),
|
||||
false,
|
||||
setMethod.isExternal,
|
||||
false,
|
||||
|
||||
+16
-18
@@ -25,8 +25,7 @@ import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitution
|
||||
import org.jetbrains.kotlin.resolve.isHiddenInResolution
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
|
||||
@@ -59,8 +58,10 @@ class SamAdapterFunctionsScope(
|
||||
override fun getSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
var result: SmartList<FunctionDescriptor>? = null
|
||||
for (type in receiverTypes) {
|
||||
val substitutorForType by lazy { buildMemberScopeSubstitutorForType(type) }
|
||||
|
||||
for (function in type.memberScope.getContributedFunctions(name, location)) {
|
||||
val extension = extensionForFunction(function.original)
|
||||
val extension = extensionForFunction(function.original)?.substitute(substitutorForType)
|
||||
if (extension != null) {
|
||||
if (result == null) {
|
||||
result = SmartList()
|
||||
@@ -76,11 +77,16 @@ class SamAdapterFunctionsScope(
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildMemberScopeSubstitutorForType(type: KotlinType) =
|
||||
TypeConstructorSubstitution.create(type).wrapWithCapturingSubstitution(needApproximation = true).buildSubstitutor()
|
||||
|
||||
override fun getSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor> {
|
||||
return receiverTypes.flatMapTo(LinkedHashSet<FunctionDescriptor>()) { type ->
|
||||
type.memberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
|
||||
.filterIsInstance<FunctionDescriptor>()
|
||||
.mapNotNull { extensionForFunction(it.original) }
|
||||
.mapNotNull {
|
||||
extensionForFunction(it.original)?.substitute(buildMemberScopeSubstitutorForType(type))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,11 +106,13 @@ class SamAdapterFunctionsScope(
|
||||
override var baseDescriptorForSynthetic: FunctionDescriptor by Delegates.notNull()
|
||||
private set
|
||||
|
||||
private lateinit var fromSourceFunctionTypeParameters: Map<TypeParameterDescriptor, TypeParameterDescriptor>
|
||||
private val fromSourceFunctionTypeParameters: Map<TypeParameterDescriptor, TypeParameterDescriptor> by lazy {
|
||||
baseDescriptorForSynthetic.typeParameters.zip(typeParameters).toMap()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(sourceFunction: FunctionDescriptor): MyFunctionDescriptor {
|
||||
val descriptor = MyFunctionDescriptor(DescriptorUtils.getContainingModule(sourceFunction),
|
||||
val descriptor = MyFunctionDescriptor(sourceFunction.containingDeclaration,
|
||||
null,
|
||||
sourceFunction.annotations,
|
||||
sourceFunction.name,
|
||||
@@ -114,26 +122,16 @@ class SamAdapterFunctionsScope(
|
||||
|
||||
val sourceTypeParams = (sourceFunction.typeParameters).toMutableList()
|
||||
val ownerClass = sourceFunction.containingDeclaration as ClassDescriptor
|
||||
//TODO: should we go up parents for getters/setters too?
|
||||
//TODO: non-inner classes
|
||||
for (parent in ownerClass.parentsWithSelf) {
|
||||
if (parent !is ClassDescriptor) break
|
||||
sourceTypeParams += parent.declaredTypeParameters
|
||||
}
|
||||
//TODO: duplicated parameter names
|
||||
|
||||
val typeParameters = ArrayList<TypeParameterDescriptor>(sourceTypeParams.size)
|
||||
val typeSubstitutor = DescriptorSubstitutor.substituteTypeParameters(sourceTypeParams, TypeSubstitution.EMPTY, descriptor, typeParameters)
|
||||
|
||||
descriptor.fromSourceFunctionTypeParameters = sourceTypeParams.zip(typeParameters).toMap()
|
||||
|
||||
val returnType = typeSubstitutor.safeSubstitute(sourceFunction.returnType!!, Variance.INVARIANT)
|
||||
val receiverType = typeSubstitutor.safeSubstitute(ownerClass.defaultType, Variance.INVARIANT)
|
||||
val valueParameters = SingleAbstractMethodUtils.createValueParametersForSamAdapter(sourceFunction, descriptor, typeSubstitutor)
|
||||
|
||||
val visibility = syntheticExtensionVisibility(sourceFunction)
|
||||
val visibility = syntheticVisibility(sourceFunction, isUsedForExtension = false)
|
||||
|
||||
descriptor.initialize(receiverType, null, typeParameters, valueParameters, returnType,
|
||||
descriptor.initialize(null, ownerClass.thisAsReceiverParameter, typeParameters, valueParameters, returnType,
|
||||
Modality.FINAL, visibility)
|
||||
|
||||
descriptor.isOperator = sourceFunction.isOperator
|
||||
|
||||
+8
-4
@@ -30,14 +30,18 @@ fun FunctionDescriptor.hasJavaOriginInHierarchy(): Boolean {
|
||||
|
||||
fun Visibility.isVisibleOutside() = this != Visibilities.PRIVATE && this != Visibilities.PRIVATE_TO_THIS && this != Visibilities.INVISIBLE_FAKE
|
||||
|
||||
fun syntheticExtensionVisibility(originalDescriptor: DeclarationDescriptorWithVisibility): Visibility {
|
||||
fun syntheticVisibility(originalDescriptor: DeclarationDescriptorWithVisibility, isUsedForExtension: Boolean): Visibility {
|
||||
val originalVisibility = originalDescriptor.visibility
|
||||
return when (originalVisibility) {
|
||||
Visibilities.PUBLIC -> Visibilities.PUBLIC
|
||||
|
||||
else -> object : Visibility(originalVisibility.name, originalVisibility.isPublicAPI) {
|
||||
override fun isVisible(receiver: ReceiverValue?, what: DeclarationDescriptorWithVisibility, from: DeclarationDescriptor)
|
||||
= originalVisibility.isVisible(Visibilities.ALWAYS_SUITABLE_RECEIVER, originalDescriptor, from)
|
||||
override fun isVisible(
|
||||
receiver: ReceiverValue?,
|
||||
what: DeclarationDescriptorWithVisibility,
|
||||
from: DeclarationDescriptor
|
||||
) = originalVisibility.isVisible(
|
||||
if (isUsedForExtension) Visibilities.ALWAYS_SUITABLE_RECEIVER else receiver, originalDescriptor, from)
|
||||
|
||||
override fun mustCheckInImports()
|
||||
= throw UnsupportedOperationException("Should never be called for this visibility")
|
||||
@@ -50,4 +54,4 @@ fun syntheticExtensionVisibility(originalDescriptor: DeclarationDescriptorWithVi
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -189,8 +189,7 @@ class NewResolutionOldInference(
|
||||
)
|
||||
candidateResolver.performResolutionForCandidateCall(callCandidateResolutionContext, basicCallContext.checkArguments) // todo
|
||||
|
||||
val diagnostics = listOfNotNull(SynthesizedDescriptorDiagnostic.check { candidate.descriptor.isSynthesized },
|
||||
createPreviousResolveError(resolvedCall.status))
|
||||
val diagnostics = listOfNotNull(createPreviousResolveError(resolvedCall.status))
|
||||
MyCandidate(ResolutionCandidateStatus(diagnostics), resolvedCall)
|
||||
}
|
||||
if (basicCallContext.collectAllCandidates) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
||||
@@ -43,7 +44,8 @@ class FlatSignature<out T> private constructor(
|
||||
val hasExtensionReceiver: Boolean,
|
||||
val hasVarargs: Boolean,
|
||||
val numDefaults: Int,
|
||||
val isPlatform: Boolean
|
||||
val isPlatform: Boolean,
|
||||
val isSyntheticMember: Boolean
|
||||
) {
|
||||
val isGeneric = typeParameters.isNotEmpty()
|
||||
|
||||
@@ -63,7 +65,8 @@ class FlatSignature<out T> private constructor(
|
||||
hasExtensionReceiver = extensionReceiverType != null,
|
||||
hasVarargs = descriptor.valueParameters.any { it.varargElementType != null },
|
||||
numDefaults = numDefaults,
|
||||
isPlatform = descriptor is MemberDescriptor && descriptor.isPlatform
|
||||
isPlatform = descriptor is MemberDescriptor && descriptor.isPlatform,
|
||||
isSyntheticMember = descriptor is SyntheticMemberDescriptor<*>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -133,6 +133,10 @@ class OverloadingConflictResolver<C : Any>(
|
||||
|
||||
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS ->
|
||||
findMaximallySpecificCall(candidates, discriminateGenerics, isDebuggerContext)
|
||||
?: findMaximallySpecificCall(
|
||||
candidates.filterNotTo(mutableSetOf()) { createFlatSignature(it).isSyntheticMember },
|
||||
discriminateGenerics, isDebuggerContext
|
||||
)
|
||||
}
|
||||
|
||||
// null means ambiguity between variables
|
||||
@@ -219,7 +223,7 @@ class OverloadingConflictResolver<C : Any>(
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if [call1] is definitely not less specific than [call2],
|
||||
* Returns `true` if [call1] is definitely more or equally specific [call2],
|
||||
* `false` otherwise.
|
||||
*/
|
||||
private fun compareCallsByUsedArguments(
|
||||
|
||||
@@ -67,7 +67,6 @@ data class ResolutionCandidateStatus(val diagnostics: List<ResolutionDiagnostic>
|
||||
|
||||
enum class ResolutionCandidateApplicability {
|
||||
RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate
|
||||
RESOLVED_SYNTHESIZED, // todo remove it (need for SAM adapters which created inside some MemberScope)
|
||||
RESOLVED_LOW_PRIORITY,
|
||||
CONVENTION_ERROR, // missing infix, operator etc
|
||||
MAY_THROW_RUNTIME_ERROR, // unsafe call or unstable smart cast
|
||||
@@ -89,7 +88,6 @@ class UsedSmartCastForDispatchReceiver(val smartCastType: KotlinType): Resolutio
|
||||
|
||||
object ErrorDescriptorDiagnostic : ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED) // todo discuss and change to INAPPLICABLE
|
||||
object LowPriorityDescriptorDiagnostic : ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY)
|
||||
object SynthesizedDescriptorDiagnostic : ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED)
|
||||
object DynamicDescriptorDiagnostic: ResolutionDiagnostic(ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY)
|
||||
object UnstableSmartCastDiagnostic: ResolutionDiagnostic(ResolutionCandidateApplicability.MAY_THROW_RUNTIME_ERROR)
|
||||
object ExtensionWithStaticTypeWithDynamicReceiver: ResolutionDiagnostic(ResolutionCandidateApplicability.HIDDEN)
|
||||
|
||||
+32
-2
@@ -67,8 +67,9 @@ internal class ExplicitReceiverScopeTowerProcessor<D : CallableDescriptor, C: Ca
|
||||
}
|
||||
|
||||
private fun resolveAsMember(): Collection<C> {
|
||||
val members = ReceiverScopeTowerLevel(scopeTower, explicitReceiver)
|
||||
.collectCandidates(null).filter { !it.requiresExtensionReceiver }
|
||||
val members =
|
||||
MemberScopeTowerLevel(scopeTower, explicitReceiver)
|
||||
.collectCandidates(null).filter { !it.requiresExtensionReceiver }
|
||||
return members.map { candidateFactory.createCandidate(it, ExplicitReceiverKind.DISPATCH_RECEIVER, extensionReceiver = null) }
|
||||
}
|
||||
|
||||
@@ -118,6 +119,35 @@ private class NoExplicitReceiverScopeTowerProcessor<D : CallableDescriptor, C: C
|
||||
}
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
}
|
||||
private fun <D : CallableDescriptor, C : Candidate<D>> processCommonAndSyntheticMembers(
|
||||
receiverForMember: ReceiverValueWithSmartCastInfo,
|
||||
scopeTowerLevel: ScopeTowerLevel,
|
||||
collectCandidates: CandidatesCollector<D>,
|
||||
candidateFactory: CandidateFactory<D, C>,
|
||||
isExplicitReceiver: Boolean
|
||||
): List<C> {
|
||||
val (members, syntheticExtension) =
|
||||
scopeTowerLevel.collectCandidates(null)
|
||||
.filter {
|
||||
it.descriptor.dispatchReceiverParameter == null || it.descriptor.extensionReceiverParameter == null
|
||||
}.partition { !it.requiresExtensionReceiver }
|
||||
|
||||
return members.map {
|
||||
candidateFactory.createCandidate(
|
||||
it,
|
||||
if (isExplicitReceiver) ExplicitReceiverKind.DISPATCH_RECEIVER else ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||
extensionReceiver = null
|
||||
)
|
||||
} +
|
||||
syntheticExtension.map {
|
||||
candidateFactory.createCandidate(
|
||||
it,
|
||||
if (isExplicitReceiver) ExplicitReceiverKind.EXTENSION_RECEIVER else ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||
extensionReceiver = receiverForMember
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor, C: Candidate<D>> createSimpleProcessor(
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.getImmediateSuperclassNotAny
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
||||
import org.jetbrains.kotlin.utils.toReadOnlyList
|
||||
import java.util.*
|
||||
|
||||
@@ -62,7 +63,6 @@ internal abstract class AbstractScopeTowerLevel(
|
||||
}
|
||||
else {
|
||||
if (descriptor.hasLowPriorityInOverloadResolution()) diagnostics.add(LowPriorityDescriptorDiagnostic)
|
||||
if (descriptor.isSynthesized) diagnostics.add(SynthesizedDescriptorDiagnostic)
|
||||
if (dispatchReceiverSmartCastType != null) diagnostics.add(UsedSmartCastForDispatchReceiver(dispatchReceiverSmartCastType))
|
||||
|
||||
val shouldSkipVisibilityCheck = scopeTower.isDebuggerContext
|
||||
@@ -81,11 +81,13 @@ internal abstract class AbstractScopeTowerLevel(
|
||||
|
||||
// todo KT-9538 Unresolved inner class via subclass reference
|
||||
// todo add static methods & fields with error
|
||||
internal class ReceiverScopeTowerLevel(
|
||||
internal class MemberScopeTowerLevel(
|
||||
scopeTower: ImplicitScopeTower,
|
||||
val dispatchReceiver: ReceiverValueWithSmartCastInfo
|
||||
): AbstractScopeTowerLevel(scopeTower) {
|
||||
|
||||
private val syntheticScopes = scopeTower.syntheticScopes
|
||||
|
||||
private fun <D : CallableDescriptor> collectMembers(
|
||||
getMembers: ResolutionScope.(KotlinType?) -> Collection<D>
|
||||
): Collection<CandidateWithBoundDispatchReceiver<D>> {
|
||||
@@ -100,7 +102,11 @@ internal class ReceiverScopeTowerLevel(
|
||||
|
||||
for (possibleType in dispatchReceiver.possibleTypes) {
|
||||
possibleType.memberScope.getMembers(possibleType).mapTo(unstableCandidates ?: result) {
|
||||
createCandidateDescriptor(it, dispatchReceiver.smartCastReceiver(possibleType), unstableError, dispatchReceiverSmartCastType = possibleType)
|
||||
createCandidateDescriptor(
|
||||
it,
|
||||
dispatchReceiver.smartCastReceiver(possibleType),
|
||||
unstableError, dispatchReceiverSmartCastType = possibleType
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +145,8 @@ internal class ReceiverScopeTowerLevel(
|
||||
|
||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
||||
return collectMembers {
|
||||
getContributedFunctions(name, location) + it.getInnerConstructors(name, location)
|
||||
getContributedFunctions(name, location) + it.getInnerConstructors(name, location) +
|
||||
syntheticScopes.collectSyntheticExtensionFunctions(it.singletonOrEmptyList(), name, location)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,16 +211,17 @@ internal class SyntheticScopeBasedTowerLevel(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
|
||||
= emptyList()
|
||||
override fun getObjects(
|
||||
name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||
): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> =
|
||||
emptyList()
|
||||
|
||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
||||
if (extensionReceiver == null) return emptyList()
|
||||
override fun getFunctions(
|
||||
name: Name,
|
||||
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||
): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> =
|
||||
emptyList()
|
||||
|
||||
return syntheticScopes.collectSyntheticExtensionFunctions(extensionReceiver.allTypes, name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class HidesMembersTowerLevel(scopeTower: ImplicitScopeTower): AbstractScopeTowerLevel(scopeTower) {
|
||||
|
||||
@@ -89,7 +89,7 @@ class TowerResolver {
|
||||
if (scope is LexicalScope) {
|
||||
if (!scope.kind.withLocalDescriptors) result.add(ScopeBasedTowerLevel(this, scope))
|
||||
|
||||
getImplicitReceiver(scope)?.let { result.add(ReceiverScopeTowerLevel(this, it)) }
|
||||
getImplicitReceiver(scope)?.let { result.add(MemberScopeTowerLevel(this, it)) }
|
||||
}
|
||||
else {
|
||||
result.add(ImportingScopeBasedTowerLevel(this, scope as ImportingScope))
|
||||
@@ -119,7 +119,7 @@ class TowerResolver {
|
||||
TowerData.TowerLevel(hidesMembersLevel).process()?.let { return it }
|
||||
// possibly there is explicit member
|
||||
TowerData.Empty.process()?.let { return it }
|
||||
// synthetic member for explicit receiver
|
||||
// synthetic property for explicit receiver
|
||||
TowerData.TowerLevel(syntheticLevel).process()?.let { return it }
|
||||
|
||||
// local non-extensions or extension for explicit receiver
|
||||
@@ -140,9 +140,9 @@ class TowerResolver {
|
||||
TowerData.BothTowerLevelAndImplicitReceiver(hidesMembersLevel, implicitReceiver).process()?.let { return it }
|
||||
|
||||
// members of implicit receiver or member extension for explicit receiver
|
||||
TowerData.TowerLevel(ReceiverScopeTowerLevel(this, implicitReceiver)).process()?.let { return it }
|
||||
TowerData.TowerLevel(MemberScopeTowerLevel(this, implicitReceiver)).process()?.let { return it }
|
||||
|
||||
// synthetic members
|
||||
// synthetic properties
|
||||
TowerData.BothTowerLevelAndImplicitReceiver(syntheticLevel, implicitReceiver).process()?.let { return it }
|
||||
|
||||
// invokeExtension on local variable
|
||||
@@ -233,19 +233,17 @@ class TowerResolver {
|
||||
private var currentCandidates: Collection<C> = emptyList()
|
||||
private var currentLevel: ResolutionCandidateApplicability? = null
|
||||
|
||||
override fun getSuccessfulCandidates(): Collection<C>? = getResolved() ?: getResolvedSynthetic()
|
||||
override fun getSuccessfulCandidates(): Collection<C>? = getResolved()
|
||||
|
||||
fun getResolved() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED }
|
||||
|
||||
fun getResolvedSynthetic() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED_SYNTHESIZED }
|
||||
|
||||
fun getResolvedLowPriority() = currentCandidates.check { currentLevel == ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY }
|
||||
|
||||
fun getErrors() = currentCandidates.check {
|
||||
currentLevel == null || currentLevel!! > ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY
|
||||
}
|
||||
|
||||
override fun getFinalCandidates() = getResolved() ?: getResolvedSynthetic() ?: getResolvedLowPriority() ?: getErrors() ?: emptyList()
|
||||
override fun getFinalCandidates() = getResolved() ?: getResolvedLowPriority() ?: getErrors() ?: emptyList()
|
||||
|
||||
override fun addCandidates(candidates: Collection<C>) {
|
||||
val minimalLevel = candidates.map { getStatus(it).resultingApplicability }.min()!!
|
||||
|
||||
+1
-1
@@ -47,6 +47,6 @@ fun main() {
|
||||
x -> x.toString()
|
||||
}
|
||||
|
||||
A.<!NONE_APPLICABLE!>baz<!>(block)
|
||||
A.baz(<!TYPE_MISMATCH!>block<!>)
|
||||
A.baz(block2)
|
||||
}
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ class Data(var x: A)
|
||||
|
||||
class B : A() {
|
||||
fun baz(a: A, b: B, d: Data) {
|
||||
a.<!INVISIBLE_MEMBER!>foo<!> { }
|
||||
a.<!INVISIBLE_MEMBER!>foo<!> <!TYPE_MISMATCH!>{ }<!>
|
||||
|
||||
b.foo { }
|
||||
|
||||
@@ -20,7 +20,7 @@ class B : A() {
|
||||
}
|
||||
|
||||
if (d.x is B) {
|
||||
d.x.<!INVISIBLE_MEMBER!>foo<!> {}
|
||||
<!SMARTCAST_IMPOSSIBLE!>d.x<!>.foo <!TYPE_MISMATCH!>{}<!>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// FILE: KotlinFile.kt
|
||||
fun foo(javaClass: JavaClass<Int>): Int {
|
||||
val inner = javaClass.createInner<String>()
|
||||
return inner.doSomething(1, "") { }
|
||||
return <!TYPE_MISMATCH!>inner.doSomething(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>, "") <!TYPE_MISMATCH!>{ }<!><!>
|
||||
}
|
||||
|
||||
// FILE: JavaClass.java
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ fun foo(javaClass: JavaClass) {
|
||||
class X : JavaClass() {
|
||||
fun foo(other: JavaClass) {
|
||||
doSomething { bar() }
|
||||
other.<!INVISIBLE_MEMBER!>doSomething<!> { bar() }
|
||||
other.<!INVISIBLE_MEMBER!>doSomething<!> <!TYPE_MISMATCH!>{ bar() }<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@ fun bar(){}
|
||||
// FILE: JavaClass.java
|
||||
public class JavaClass {
|
||||
protected void doSomething(Runnable runnable) { runnable.run(); }
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// !CHECK_TYPE
|
||||
// FILE: A.java
|
||||
public class A {
|
||||
public int foo(Runnable r) { return 0; }
|
||||
public String foo(Object r) { return null;}
|
||||
|
||||
public int bar(Runnable r) { return 1; }
|
||||
public String bar(CharSequence r) { return null; }
|
||||
}
|
||||
|
||||
// FILE: 1.kt
|
||||
fun fn() {}
|
||||
fun x(a: A, r: Runnable) {
|
||||
a.foo(::fn) checkType { _<Int>() }
|
||||
a.foo {} checkType { _<Int>() }
|
||||
|
||||
a.foo(null) checkType { _<Int>() }
|
||||
a.foo(Runnable { }) checkType { _<Int>() }
|
||||
a.foo(r) checkType { _<Int>() }
|
||||
|
||||
a.foo(123) checkType { _<String>() }
|
||||
a.foo("") checkType { _<String>() }
|
||||
|
||||
a.bar(::fn) checkType { _<Int>() }
|
||||
a.bar {} checkType { _<Int>() }
|
||||
|
||||
a.bar(r) checkType { _<Int>() }
|
||||
|
||||
a.<!OVERLOAD_RESOLUTION_AMBIGUITY!>bar<!>(null)
|
||||
|
||||
a.bar(null as Runnable?) checkType { _<Int>() }
|
||||
a.bar(null as CharSequence?) checkType { _<String>() }
|
||||
|
||||
a.bar("") checkType { _<String>() }
|
||||
a.<!NONE_APPLICABLE!>bar<!>(123)
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package
|
||||
|
||||
public fun fn(): kotlin.Unit
|
||||
public fun x(/*0*/ a: A, /*1*/ r: java.lang.Runnable): kotlin.Unit
|
||||
|
||||
public open class A {
|
||||
public constructor A()
|
||||
public open fun bar(/*0*/ r: java.lang.Runnable!): kotlin.Int
|
||||
public open fun bar(/*0*/ r: kotlin.CharSequence!): kotlin.String!
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun foo(/*0*/ r: java.lang.Runnable!): kotlin.Int
|
||||
public open fun foo(/*0*/ r: kotlin.Any!): kotlin.String!
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Vendored
+36
@@ -0,0 +1,36 @@
|
||||
// !CHECK_TYPE
|
||||
// FILE: A.java
|
||||
public class A {
|
||||
public static int foo(Runnable r) { return 0; }
|
||||
public static String foo(Object r) { return null;}
|
||||
|
||||
public static int bar(Runnable r) { return 1; }
|
||||
public static String bar(CharSequence r) { return null; }
|
||||
}
|
||||
|
||||
// FILE: 1.kt
|
||||
fun fn() {}
|
||||
fun x(r: Runnable) {
|
||||
A.foo(::fn) checkType { _<Int>() }
|
||||
A.foo {} checkType { _<Int>() }
|
||||
|
||||
A.foo(null) checkType { _<Int>() }
|
||||
A.foo(Runnable { }) checkType { _<Int>() }
|
||||
A.foo(r) checkType { _<Int>() }
|
||||
|
||||
A.foo(123) checkType { _<String>() }
|
||||
A.foo("") checkType { _<String>() }
|
||||
|
||||
A.bar(::fn) checkType { _<Int>() }
|
||||
A.bar {} checkType { _<Int>() }
|
||||
|
||||
A.bar(r) checkType { _<Int>() }
|
||||
|
||||
A.<!OVERLOAD_RESOLUTION_AMBIGUITY!>bar<!>(null)
|
||||
|
||||
A.bar(null as Runnable?) checkType { _<Int>() }
|
||||
A.bar(null as CharSequence?) checkType { _<String>() }
|
||||
|
||||
A.bar("") checkType { _<String>() }
|
||||
A.<!NONE_APPLICABLE!>bar<!>(123)
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
package
|
||||
|
||||
public fun fn(): kotlin.Unit
|
||||
public fun x(/*0*/ r: java.lang.Runnable): kotlin.Unit
|
||||
|
||||
public open class A {
|
||||
public constructor A()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun bar(/*0*/ r: (() -> kotlin.Unit)!): kotlin.Int
|
||||
public open fun bar(/*0*/ r: java.lang.Runnable!): kotlin.Int
|
||||
public open fun bar(/*0*/ r: kotlin.CharSequence!): kotlin.String!
|
||||
public final /*synthesized*/ fun foo(/*0*/ r: (() -> kotlin.Unit)!): kotlin.Int
|
||||
public open fun foo(/*0*/ r: java.lang.Runnable!): kotlin.Int
|
||||
public open fun foo(/*0*/ r: kotlin.Any!): kotlin.String!
|
||||
}
|
||||
Vendored
+1
-1
@@ -30,7 +30,7 @@ abstract class MyIt7 : Iterator<String> {
|
||||
|
||||
|
||||
fun foo(x: Iterator<String>, y: Iterator<String?>) {
|
||||
x.<!TYPE_INFERENCE_INCORPORATION_ERROR!>forEachRemaining<!>(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
x.forEachRemaining(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
|
||||
x.forEachRemaining { it -> it.length }
|
||||
x.forEachRemaining { it -> it<!UNNECESSARY_SAFE_CALL!>?.<!>length }
|
||||
|
||||
@@ -20763,6 +20763,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("overloadResolution.kt")
|
||||
public void testOverloadResolution() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolution.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("overloadResolutionStatic.kt")
|
||||
public void testOverloadResolutionStatic() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolutionStatic.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PackageLocal.kt")
|
||||
public void testPackageLocal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/PackageLocal.kt");
|
||||
|
||||
Reference in New Issue
Block a user