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 bbbdcf7f2f7..0495a52ed9b 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 @@ -75,17 +75,16 @@ class NewResolutionOldInference( val invokeContext = outer.InvokeContext(scopeTower, name, context, tracing) return outer.createFunctionTowerProcessor(invokeContext, explicitReceiver) } - } + object Variable : ResolutionKind() { override fun createTowerProcessor( outer: NewResolutionOldInference, name: Name, tracing: TracingStrategy, scopeTower: ScopeTower, explicitReceiver: Receiver?, context: BasicCallResolutionContext ): ScopeTowerProcessor> { val simpleContext = outer.SimpleContext(scopeTower, name, context, tracing) - return createVariableProcessor(simpleContext, explicitReceiver) + return createVariableAndObjectProcessor(simpleContext, explicitReceiver) } - } object CallableReference : ResolutionKind() { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt index b4495940391..6773823cf49 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt @@ -90,7 +90,7 @@ class InvokeTowerProcessor, V : Candidate( invokeContext, - createVariableProcessor(invokeContext.contextForVariable(stripExplicitReceiver = false), explicitReceiver) + createVariableAndObjectProcessor(invokeContext.contextForVariable(stripExplicitReceiver = false), explicitReceiver) ) { // todo filter by operator @@ -106,7 +106,7 @@ class InvokeExtensionTowerProcessor, V : Candi private val explicitReceiver: ReceiverValue? ) : AbstractInvokeTowerProcessor( invokeContext, - createVariableProcessor(invokeContext.contextForVariable(stripExplicitReceiver = true), explicitReceiver = null) + createVariableAndObjectProcessor(invokeContext.contextForVariable(stripExplicitReceiver = true), explicitReceiver = null) ) { override fun createInvokeProcessor(variableCandidate: V): ScopeTowerProcessor { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTower.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTower.kt index 4d8f99aed38..f7dc9981913 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTower.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTower.kt @@ -58,6 +58,8 @@ interface DataFlowDecorator { interface ScopeTowerLevel { fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection> + fun getObjects(name: Name, extensionReceiver: ReceiverValue?): Collection> + fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection> } 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 7e325ea259e..90f281fe789 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 @@ -139,5 +139,11 @@ private fun > createSimpleProcessor( fun > createVariableProcessor(context: TowerContext, explicitReceiver: Receiver?) = createSimpleProcessor(context, explicitReceiver, ScopeTowerLevel::getVariables) +fun > createVariableAndObjectProcessor(context: TowerContext, explicitReceiver: Receiver?) = + CompositeScopeTowerProcessor( + createVariableProcessor(context, explicitReceiver), + createSimpleProcessor(context, explicitReceiver, ScopeTowerLevel::getObjects) + ) + fun > createFunctionProcessor(context: TowerContext, explicitReceiver: Receiver?) = createSimpleProcessor(context, explicitReceiver, ScopeTowerLevel::getFunctions) 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 50acfa3ce15..a7ebc0077d7 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 @@ -138,6 +138,10 @@ internal class ReceiverScopeTowerLevel( return collectMembers { getContributedVariables(name, location) } } + override fun getObjects(name: Name, extensionReceiver: ReceiverValue?): Collection> { + return emptyList() + } + override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection> { return collectMembers { getContributedFunctions(name, location) + it.getInnerConstructors(name, location) @@ -147,7 +151,12 @@ internal class ReceiverScopeTowerLevel( internal class QualifierScopeTowerLevel(scopeTower: ScopeTower, val qualifier: QualifierReceiver) : AbstractScopeTowerLevel(scopeTower) { override fun getVariables(name: Name, extensionReceiver: ReceiverValue?) = qualifier.staticScope - .getContributedVariablesAndObjects(name, location).map { + .getContributedVariables(name, location).map { + createCandidateDescriptor(it, dispatchReceiver = null) + } + + override fun getObjects(name: Name, extensionReceiver: ReceiverValue?) = qualifier.staticScope + .getContributedObjectVariables(name, location).map { createCandidateDescriptor(it, dispatchReceiver = null) } @@ -166,7 +175,12 @@ internal open class ScopeBasedTowerLevel protected constructor( internal constructor(scopeTower: ScopeTower, lexicalScope: LexicalScope): this(scopeTower, lexicalScope as ResolutionScope) override fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection> - = resolutionScope.getContributedVariablesAndObjects(name, location).map { + = resolutionScope.getContributedVariables(name, location).map { + createCandidateDescriptor(it, dispatchReceiver = null) + } + + override fun getObjects(name: Name, extensionReceiver: ReceiverValue?): Collection> + = resolutionScope.getContributedObjectVariables(name, location).map { createCandidateDescriptor(it, dispatchReceiver = null) } @@ -184,7 +198,6 @@ internal class SyntheticScopeBasedTowerLevel( scopeTower: ScopeTower, private val syntheticScopes: SyntheticScopes ): AbstractScopeTowerLevel(scopeTower) { - override fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection> { if (extensionReceiver == null) return emptyList() @@ -194,6 +207,9 @@ internal class SyntheticScopeBasedTowerLevel( } } + override fun getObjects(name: Name, extensionReceiver: ReceiverValue?): Collection> + = emptyList() + override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection> { if (extensionReceiver == null) return emptyList() @@ -208,6 +224,9 @@ internal class HidesMembersTowerLevel(scopeTower: ScopeTower): AbstractScopeTowe override fun getVariables(name: Name, extensionReceiver: ReceiverValue?) = getCandidates(name, extensionReceiver, LexicalScope::collectVariables) + override fun getObjects(name: Name, extensionReceiver: ReceiverValue?) + = emptyList>() + override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?) = getCandidates(name, extensionReceiver, LexicalScope::collectFunctions) @@ -247,10 +266,9 @@ private fun ResolutionScope.getContributedFunctionsAndConstructors(name: Name, l (classifier?.getTypeAliasConstructors() ?: emptyList()) } -private fun ResolutionScope.getContributedVariablesAndObjects(name: Name, location: LookupLocation): Collection { +private fun ResolutionScope.getContributedObjectVariables(name: Name, location: LookupLocation): Collection { val objectDescriptor = getFakeDescriptorForObject(getContributedClassifier(name, location)) - - return getContributedVariables(name, location) + listOfNotNull(objectDescriptor) + return listOfNotNull(objectDescriptor) } private fun getFakeDescriptorForObject(classifier: ClassifierDescriptor?): FakeCallableDescriptorForObject? = diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/noFakeDescriptorForObject.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/noFakeDescriptorForObject.kt new file mode 100644 index 00000000000..b925d9861e5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/noFakeDescriptorForObject.kt @@ -0,0 +1,11 @@ +// !CHECK_TYPE +// KT-12322 Overload resolution ambiguity with constructor references when class has a companion object + +class Foo { + companion object +} + +fun test() { + val a = ::Foo + checkSubtype<() -> Foo>(a) +} diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/noFakeDescriptorForObject.txt b/compiler/testData/diagnostics/tests/callableReference/resolve/noFakeDescriptorForObject.txt new file mode 100644 index 00000000000..84c245ae82b --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/noFakeDescriptorForObject.txt @@ -0,0 +1,17 @@ +package + +public fun test(): kotlin.Unit + +public final class Foo { + public constructor Foo() + 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 + + public companion object Companion { + private constructor Companion() + 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 + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index d6daa37b85a..ccb8906f76d 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -2291,6 +2291,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("noFakeDescriptorForObject.kt") + public void testNoFakeDescriptorForObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/noFakeDescriptorForObject.kt"); + doTest(fileName); + } + @TestMetadata("overloads.kt") public void testOverloads() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/resolve/overloads.kt"); diff --git a/jps-plugin/testData/incremental/lookupTracker/classifierMembers/usages.kt b/jps-plugin/testData/incremental/lookupTracker/classifierMembers/usages.kt index 4a4b3b6194c..3c7b5c59828 100644 --- a/jps-plugin/testData/incremental/lookupTracker/classifierMembers/usages.kt +++ b/jps-plugin/testData/incremental/lookupTracker/classifierMembers/usages.kt @@ -12,13 +12,13 @@ import bar.* /*p:foo*/A./*c:foo.A*/B./*c:foo.A.B c:foo.A.B.CO*/bar(1) /*p:foo*/A./*c:foo.A*/B./*c:foo.A.B*/CO./*c:foo.A.B.CO*/bar(1) /*p:foo c:foo.A(Companion)*/A - /*p:foo p:kotlin(Int)*/A./*c:foo.A c:foo.A.Companion*/a + /*p:foo p:kotlin(Int)*/A./*c:foo.A.Companion c:foo.A*/a /*p:foo*/A./*c:foo.A c:foo.A.Companion*/baz() - /*p:foo c:foo.A(Companion)*/A./*c:foo.A c:foo.A.Companion*/Companion + /*p:foo c:foo.A(Companion)*/A./*c:foo.A.Companion c:foo.A*/Companion /*p:foo*/A./*c:foo.A*/Companion./*c:foo.A.Companion*/baz() - /*p:foo c:foo.A(O)*/A./*c:foo.A c:foo.A.Companion*/O + /*p:foo c:foo.A(O)*/A./*c:foo.A.Companion c:foo.A*/O /*p:foo p:kotlin(String)*/A./*c:foo.A*/O./*c:foo.A.O*/v = /*p:kotlin(String)*/"OK" - /*p:foo*/A./*c:foo.A c:foo.A.Companion c:foo.A.Companion(getVala) c:foo.A.Companion(getVALA) p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.collections p:kotlin.coroutines p:kotlin.ranges p:kotlin.sequences p:kotlin.text p:kotlin.io*/vala + /*p:foo*/A./*c:foo.A.Companion c:foo.A c:foo.A.Companion(getVala) c:foo.A.Companion(getVALA) p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.collections p:kotlin.coroutines p:kotlin.ranges p:kotlin.sequences p:kotlin.text p:kotlin.io*/vala /*p:foo*/A./*c:foo.A c:foo.A.Companion c:foo.A.Companion(getVara) c:foo.A.Companion(getVARA) p:foo p:bar p:java.lang p:kotlin p:kotlin.annotation p:kotlin.jvm p:kotlin.collections p:kotlin.coroutines p:kotlin.ranges p:kotlin.sequences p:kotlin.text p:kotlin.io*/vara() /*p:foo(I) p:kotlin(Int)*/i./*c:foo.I*/a = /*p:kotlin(Int)*/2