From 478352b7e71c33dd191ed005323721742cf3f436 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 2 Feb 2017 20:16:56 +0300 Subject: [PATCH] Fix callable reference to constructor of nested class in object #KT-15951 Fixed --- .../DoubleColonExpressionResolver.kt | 13 +++++++ .../constructorOfNestedClassInObject.kt | 21 ++++++++++ .../constructorOfNestedClassInObject.txt | 38 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 +++ 4 files changed, 78 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.kt create mode 100644 compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt index 51a51d94a9a..4241579e418 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.calls.CallResolver import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode +import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.context.* import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults @@ -682,6 +683,18 @@ class DoubleColonExpressionResolver( "resolve bound callable reference", expressionReceiver, reference, c, mode ) if (result != null) return result + + if (lhs.isObject) { + val classifier = lhsType.constructor.declarationDescriptor + val calleeExpression = expression.receiverExpression?.getCalleeExpressionIfAny() + if (calleeExpression is KtSimpleNameExpression && classifier is ClassDescriptor) { + val qualifier = ClassQualifier(calleeExpression, classifier) + val possibleStatic = tryResolveRHSWithReceiver( + "resolve object callable reference in static scope", qualifier, reference, c, mode + ) + if (possibleStatic != null) return possibleStatic + } + } } } diff --git a/compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.kt b/compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.kt new file mode 100644 index 00000000000..2a69aeccb5d --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.kt @@ -0,0 +1,21 @@ +// KT-15951 Callable reference to class constructor from object is not resolved + +object A { + class Wrapper +} + +class Outer { + companion object { + class Wrapper + } +} + +fun test() { + A::Wrapper + (A)::Wrapper + + Outer.Companion::Wrapper + (Outer.Companion)::Wrapper + Outer::Wrapper + (Outer)::Wrapper +} diff --git a/compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.txt b/compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.txt new file mode 100644 index 00000000000..ef53902cf96 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.txt @@ -0,0 +1,38 @@ +package + +public fun test(): kotlin.Unit + +public object A { + private 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 + + public final class Wrapper { + public constructor Wrapper() + 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 final class Outer { + public constructor Outer() + 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 + + public final class Wrapper { + public constructor Wrapper() + 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 bf18c1cafaa..dffc01df7e2 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -1983,6 +1983,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("constructorOfNestedClassInObject.kt") + public void testConstructorOfNestedClassInObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.kt"); + doTest(fileName); + } + @TestMetadata("differentPackageClass.kt") public void testDifferentPackageClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/function/differentPackageClass.kt");