From 22595acbfddd37a4ceac75718d46fc8930e5271d Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 5 Feb 2018 19:29:41 +0100 Subject: [PATCH] Fix AssertionError on overloading function with property in actual class #KT-22352 Fixed --- .../diagnostics/PositioningStrategies.kt | 4 ++++ .../multiplatform/ExpectedActualResolver.kt | 5 +++++ .../functionAndPropertyWithSameName.kt | 15 +++++++++++++ .../functionAndPropertyWithSameName.txt | 22 +++++++++++++++++++ .../functionAndPropertyWithSameName/common.kt | 5 +++++ .../functionAndPropertyWithSameName/jvm.kt | 5 +++++ .../output.txt | 22 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 +++++ .../DiagnosticsUsingJavacTestGenerated.java | 6 +++++ ...MultiPlatformIntegrationTestGenerated.java | 6 +++++ 10 files changed, 96 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/multiplatform/headerClass/functionAndPropertyWithSameName.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/headerClass/functionAndPropertyWithSameName.txt create mode 100644 compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/common.kt create mode 100644 compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/jvm.kt create mode 100644 compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/output.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index 210d9eab6cb..477e4e83c73 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -153,6 +153,10 @@ object PositioningStrategies { TypeParameterUpperBounds, TypeParameterVariance, TypeParameterReified -> { (element as? KtTypeParameterListOwner)?.typeParameterList } + CallableKind -> { + (callableDeclaration as? KtNamedFunction)?.funKeyword + ?: (callableDeclaration as? KtProperty)?.valOrVarKeyword + } ParameterShape -> { callableDeclaration?.let { it.receiverTypeReference ?: it.valueParameterList } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt index d132d92d2e6..4c6108316ef 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt @@ -161,6 +161,8 @@ object ExpectedActualResolver { sealed class Incompatible(val reason: String?, val kind: IncompatibilityKind = IncompatibilityKind.WEAK) : Compatibility() { // Callables + object CallableKind : Incompatible("callable kinds are different (function vs property)", IncompatibilityKind.STRONG) + object ParameterShape : Incompatible("parameter shapes are different (extension vs non-extension)", IncompatibilityKind.STRONG) object ParameterCount : Incompatible("number of value parameters is different", IncompatibilityKind.STRONG) @@ -227,6 +229,9 @@ object ExpectedActualResolver { "This function should be invoked only for declarations in the same kind of container (both members or both top level): $a, $b" } + if (a is FunctionDescriptor && b !is FunctionDescriptor || + a !is FunctionDescriptor && b is FunctionDescriptor) return Incompatible.CallableKind + val aExtensionReceiver = a.extensionReceiverParameter val bExtensionReceiver = b.extensionReceiverParameter if ((aExtensionReceiver != null) != (bExtensionReceiver != null)) return Incompatible.ParameterShape diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/functionAndPropertyWithSameName.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/functionAndPropertyWithSameName.kt new file mode 100644 index 00000000000..79af20b647b --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/functionAndPropertyWithSameName.kt @@ -0,0 +1,15 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt + +expect class Foo { + val bar: String +} + +// MODULE: m1-jvm(m1-common) +// FILE: jvm.kt + +actual class Foo { + actual val bar = "bar" + fun bar() = bar +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/functionAndPropertyWithSameName.txt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/functionAndPropertyWithSameName.txt new file mode 100644 index 00000000000..bbb459d5324 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/functionAndPropertyWithSameName.txt @@ -0,0 +1,22 @@ +// -- Module: -- +package + +public final expect class Foo { + public expect final val bar: kotlin.String + 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 +} + + +// -- Module: -- +package + +public final actual class Foo { + public constructor Foo() + public actual final val bar: kotlin.String = "bar" + public final fun bar(): kotlin.String + 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/testData/multiplatform/classScopes/functionAndPropertyWithSameName/common.kt b/compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/common.kt new file mode 100644 index 00000000000..440b1665bd3 --- /dev/null +++ b/compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/common.kt @@ -0,0 +1,5 @@ +package test + +expect class Foo { + val bar: String +} diff --git a/compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/jvm.kt b/compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/jvm.kt new file mode 100644 index 00000000000..ac6ebf68c02 --- /dev/null +++ b/compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/jvm.kt @@ -0,0 +1,5 @@ +package test + +actual class Foo { + actual fun bar(): String = "" +} diff --git a/compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/output.txt b/compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/output.txt new file mode 100644 index 00000000000..53b906c28d9 --- /dev/null +++ b/compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/output.txt @@ -0,0 +1,22 @@ +-- Common -- +Exit code: OK +Output: + +-- JVM -- +Exit code: COMPILATION_ERROR +Output: +compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/jvm.kt:3:14: error: actual class 'Foo' has no corresponding members for expected class members: + + public expect final val bar: String + + The following declaration is incompatible because callable kinds are different (function vs property): + public final actual fun bar(): String + +actual class Foo { + ^ +compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/jvm.kt:4:12: error: actual function 'bar' has no corresponding expected declaration +The following declaration is incompatible because callable kinds are different (function vs property): + public expect final val bar: String + + actual fun bar(): String = "" + ^ diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index ba47286318a..928b1401862 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -14470,6 +14470,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("functionAndPropertyWithSameName.kt") + public void testFunctionAndPropertyWithSameName() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/functionAndPropertyWithSameName.kt"); + doTest(fileName); + } + @TestMetadata("genericClassImplTypeAlias.kt") public void testGenericClassImplTypeAlias() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/genericClassImplTypeAlias.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 959a928d9e7..094f7514ead 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -14470,6 +14470,12 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing doTest(fileName); } + @TestMetadata("functionAndPropertyWithSameName.kt") + public void testFunctionAndPropertyWithSameName() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/functionAndPropertyWithSameName.kt"); + doTest(fileName); + } + @TestMetadata("genericClassImplTypeAlias.kt") public void testGenericClassImplTypeAlias() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/genericClassImplTypeAlias.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java index bb76a600643..e6c70f0b4f7 100644 --- a/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java @@ -153,6 +153,12 @@ public class MultiPlatformIntegrationTestGenerated extends AbstractMultiPlatform doTest(fileName); } + @TestMetadata("functionAndPropertyWithSameName") + public void testFunctionAndPropertyWithSameName() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/classScopes/functionAndPropertyWithSameName/"); + doTest(fileName); + } + @TestMetadata("functionIncorrectSignature") public void testFunctionIncorrectSignature() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/classScopes/functionIncorrectSignature/");