From c9d54d7110bb9731c71840ec73df332726d0babf Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 19 Jul 2017 15:34:49 +0300 Subject: [PATCH] Generate proper error candidates for type aliases #KT-17745 Fixed Target versions 1.1.5 --- .../calls/tower/ErrorCandidateFactory.kt | 44 +++++++++++-------- .../tests/typealias/typeAliasConstructor.kt | 2 +- .../typeAliasConstructorForInterface.kt | 6 +++ .../typeAliasConstructorForInterface.txt | 11 +++++ .../typeAliasConstructorWrongClass.kt | 4 +- .../checkers/DiagnosticsTestGenerated.java | 6 +++ 6 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForInterface.kt create mode 100644 compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForInterface.txt diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ErrorCandidateFactory.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ErrorCandidateFactory.kt index 0c33e90b052..cd6b2bc81a1 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ErrorCandidateFactory.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ErrorCandidateFactory.kt @@ -86,24 +86,32 @@ private fun ErrorCandidateContext.asClassifierCall(asFunction: Boolean) { else -> scopeTower.lexicalScope.findClassifier(name, scopeTower.location) } ?: return - val kind = - when (classifier) { - is TypeParameterDescriptor -> if (asFunction) TYPE_PARAMETER_AS_FUNCTION else TYPE_PARAMETER_AS_VALUE - is ClassDescriptor -> { - when (classifier.kind) { - ClassKind.INTERFACE -> if (asFunction) INTERFACE_AS_FUNCTION else INTERFACE_AS_VALUE - ClassKind.OBJECT -> if (asFunction) OBJECT_AS_FUNCTION else return - ClassKind.CLASS -> when { - asFunction && explicitReceiver is QualifierReceiver? && classifier.isInner -> INNER_CLASS_CONSTRUCTOR_NO_RECEIVER - !asFunction -> CLASS_AS_VALUE - else -> return - } - else -> return - } - } - else -> return - } - + val kind = getWrongResolutionToClassifier(classifier, asFunction) ?: return add(ErrorCandidate.Classifier(classifier, kind)) } + +private fun ErrorCandidateContext.getWrongResolutionToClassifier(classifier: ClassifierDescriptor, asFunction: Boolean): WrongResolutionToClassifier? = + when (classifier) { + is TypeAliasDescriptor -> classifier.classDescriptor?.let { getWrongResolutionToClassifier(it, asFunction) } + + is TypeParameterDescriptor -> if (asFunction) TYPE_PARAMETER_AS_FUNCTION else TYPE_PARAMETER_AS_VALUE + + is ClassDescriptor -> { + when (classifier.kind) { + ClassKind.INTERFACE -> if (asFunction) INTERFACE_AS_FUNCTION else INTERFACE_AS_VALUE + + ClassKind.OBJECT -> if (asFunction) OBJECT_AS_FUNCTION else null + + ClassKind.CLASS -> when { + asFunction && explicitReceiver is QualifierReceiver? && classifier.isInner -> INNER_CLASS_CONSTRUCTOR_NO_RECEIVER + !asFunction -> CLASS_AS_VALUE + else -> null + } + + else -> null + } + } + + else -> null + } diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructor.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructor.kt index 87576906b3b..53a4fa33b0c 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructor.kt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructor.kt @@ -17,7 +17,7 @@ typealias TI = Interface object AnObject typealias TO = AnObject -val test6 = TI() +val test6 = TI() val test6a = Interface() val test7 = TO() diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForInterface.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForInterface.kt new file mode 100644 index 00000000000..9fb25cbcc02 --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForInterface.kt @@ -0,0 +1,6 @@ +interface IFoo + +typealias Test = IFoo + +val testAsFunction = Test() +val testAsValue = Test \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForInterface.txt b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForInterface.txt new file mode 100644 index 00000000000..bfc96fcc1ce --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForInterface.txt @@ -0,0 +1,11 @@ +package + +public val testAsFunction: [ERROR : Type for Test()] +public val testAsValue: [ERROR : Type for Test] + +public interface IFoo { + 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 typealias Test = IFoo diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.kt index 1859412c047..cafaeda2aa2 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.kt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorWrongClass.kt @@ -26,9 +26,9 @@ class Outer { } typealias Test5 = Outer.Inner -val test5 = Test5() +val test5 = Test5() val test5a = Outer.Inner() -val test5b = Outer.TestInner() +val test5b = Outer.TestInner() val test5c = Outer().TestInner() val test5d = Outer().Inner() val test5e = Outer().Test5() diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 02d765a550c..9a86bbc654b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -22951,6 +22951,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("typeAliasConstructorForInterface.kt") + public void testTypeAliasConstructorForInterface() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForInterface.kt"); + doTest(fileName); + } + @TestMetadata("typeAliasConstructorForProjection.kt") public void testTypeAliasConstructorForProjection() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typeAliasConstructorForProjection.kt");