diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index 90581b05937..41d99bedd04 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -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(); } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/ProtectedSyntheticExtensionCallChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/ProtectedSyntheticExtensionCallChecker.kt index 1cb0f990a09..9dabfce44b6 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/ProtectedSyntheticExtensionCallChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/ProtectedSyntheticExtensionCallChecker.kt @@ -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 } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt index c252140f3ff..c967b5eeb22 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt @@ -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, diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt index 8ff0a9775d0..372a6d81500 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt @@ -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, name: Name, location: LookupLocation): Collection { var result: SmartList? = 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): Collection { return receiverTypes.flatMapTo(LinkedHashSet()) { type -> type.memberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS) .filterIsInstance() - .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 + private val fromSourceFunctionTypeParameters: Map 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(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 diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/syntheticExtensionsUtils.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/syntheticExtensionsUtils.kt index 5a0fd9672e4..f02f4b14019 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/syntheticExtensionsUtils.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/syntheticExtensionsUtils.kt @@ -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 } } -} \ No newline at end of file +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt index 03fcda8f903..664d9b70e0e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt @@ -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) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt index ee50dba839d..f59845424ac 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt @@ -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 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 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<*> ) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt index 09406030cde..20075a8eb8b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt @@ -133,6 +133,10 @@ class OverloadingConflictResolver( 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( } /** - * 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( diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt index 9115f5543c8..36fea4def76 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt @@ -67,7 +67,6 @@ data class ResolutionCandidateStatus(val diagnostics: List 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) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt index e2c32005108..4b533e46df0 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt @@ -67,8 +67,9 @@ internal class ExplicitReceiverScopeTowerProcessor { - 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 emptyList() } + +} +private fun > processCommonAndSyntheticMembers( + receiverForMember: ReceiverValueWithSmartCastInfo, + scopeTowerLevel: ScopeTowerLevel, + collectCandidates: CandidatesCollector, + candidateFactory: CandidateFactory, + isExplicitReceiver: Boolean +): List { + 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 > createSimpleProcessor( diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt index f8e5f8ac58a..3d0adb2b3bf 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt @@ -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 collectMembers( getMembers: ResolutionScope.(KotlinType?) -> Collection ): Collection> { @@ -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> { 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> - = emptyList() + override fun getObjects( + name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo? + ): Collection> = + emptyList() - override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection> { - if (extensionReceiver == null) return emptyList() + override fun getFunctions( + name: Name, + extensionReceiver: ReceiverValueWithSmartCastInfo? + ): Collection> = + emptyList() - return syntheticScopes.collectSyntheticExtensionFunctions(extensionReceiver.allTypes, name, location).map { - createCandidateDescriptor(it, dispatchReceiver = null) - } - } } internal class HidesMembersTowerLevel(scopeTower: ImplicitScopeTower): AbstractScopeTowerLevel(scopeTower) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt index f45d4482f33..ef4923119c7 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt @@ -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 = emptyList() private var currentLevel: ResolutionCandidateApplicability? = null - override fun getSuccessfulCandidates(): Collection? = getResolved() ?: getResolvedSynthetic() + override fun getSuccessfulCandidates(): Collection? = 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) { val minimalLevel = candidates.map { getStatus(it).resultingApplicability }.min()!! diff --git a/compiler/testData/diagnostics/tests/j+k/samByProjectedType/genericInReturnType.kt b/compiler/testData/diagnostics/tests/j+k/samByProjectedType/genericInReturnType.kt index 96c6f57c812..8912bdade0e 100644 --- a/compiler/testData/diagnostics/tests/j+k/samByProjectedType/genericInReturnType.kt +++ b/compiler/testData/diagnostics/tests/j+k/samByProjectedType/genericInReturnType.kt @@ -47,6 +47,6 @@ fun main() { x -> x.toString() } - A.baz(block) + A.baz(block) A.baz(block2) } diff --git a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticSAMExtensions.kt b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticSAMExtensions.kt index dafd94ed2c9..f78f0593017 100644 --- a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticSAMExtensions.kt +++ b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/syntheticSAMExtensions.kt @@ -11,7 +11,7 @@ class Data(var x: A) class B : A() { fun baz(a: A, b: B, d: Data) { - a.foo { } + a.foo { } b.foo { } @@ -20,7 +20,7 @@ class B : A() { } if (d.x is B) { - d.x.foo {} + d.x.foo {} } } } diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/InnerClassInGeneric.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/InnerClassInGeneric.kt index f99a6cd28f9..9a58bd55427 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/InnerClassInGeneric.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/InnerClassInGeneric.kt @@ -1,7 +1,7 @@ // FILE: KotlinFile.kt fun foo(javaClass: JavaClass): Int { val inner = javaClass.createInner() - return inner.doSomething(1, "") { } + return inner.doSomething(1, "") { } } // FILE: JavaClass.java diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Protected.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Protected.kt index e5c45e0be05..0c42aaf1f66 100644 --- a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Protected.kt +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Protected.kt @@ -12,7 +12,7 @@ fun foo(javaClass: JavaClass) { class X : JavaClass() { fun foo(other: JavaClass) { doSomething { bar() } - other.doSomething { bar() } + other.doSomething { bar() } } } @@ -21,4 +21,4 @@ fun bar(){} // FILE: JavaClass.java public class JavaClass { protected void doSomething(Runnable runnable) { runnable.run(); } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolution.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolution.kt new file mode 100644 index 00000000000..ef369301d6e --- /dev/null +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolution.kt @@ -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 { _() } + a.foo {} checkType { _() } + + a.foo(null) checkType { _() } + a.foo(Runnable { }) checkType { _() } + a.foo(r) checkType { _() } + + a.foo(123) checkType { _() } + a.foo("") checkType { _() } + + a.bar(::fn) checkType { _() } + a.bar {} checkType { _() } + + a.bar(r) checkType { _() } + + a.bar(null) + + a.bar(null as Runnable?) checkType { _() } + a.bar(null as CharSequence?) checkType { _() } + + a.bar("") checkType { _() } + a.bar(123) +} diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolution.txt b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolution.txt new file mode 100644 index 00000000000..c6b3ca874bd --- /dev/null +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolution.txt @@ -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 +} diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolutionStatic.kt b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolutionStatic.kt new file mode 100644 index 00000000000..eb2b0ffc892 --- /dev/null +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolutionStatic.kt @@ -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 { _() } + A.foo {} checkType { _() } + + A.foo(null) checkType { _() } + A.foo(Runnable { }) checkType { _() } + A.foo(r) checkType { _() } + + A.foo(123) checkType { _() } + A.foo("") checkType { _() } + + A.bar(::fn) checkType { _() } + A.bar {} checkType { _() } + + A.bar(r) checkType { _() } + + A.bar(null) + + A.bar(null as Runnable?) checkType { _() } + A.bar(null as CharSequence?) checkType { _() } + + A.bar("") checkType { _() } + A.bar(123) +} diff --git a/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolutionStatic.txt b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolutionStatic.txt new file mode 100644 index 00000000000..91eb6e2de87 --- /dev/null +++ b/compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/overloadResolutionStatic.txt @@ -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! +} diff --git a/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/forEachRemainingNullability.kt b/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/forEachRemainingNullability.kt index 02a97209289..faf6de77ee2 100644 --- a/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/forEachRemainingNullability.kt +++ b/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/forEachRemainingNullability.kt @@ -30,7 +30,7 @@ abstract class MyIt7 : Iterator { fun foo(x: Iterator, y: Iterator) { - x.forEachRemaining(null) + x.forEachRemaining(null) x.forEachRemaining { it -> it.length } x.forEachRemaining { it -> it?.length } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 56ae965e6b1..6c47d02f717 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -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");