From 1f992ed84580ae7f69ace237076e3296cce67a6a Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 18 Sep 2017 20:20:12 +0300 Subject: [PATCH] Improve error on 'expect' delegated property #KT-15054 Fixed #KT-15055 Fixed --- .../jetbrains/kotlin/diagnostics/Errors.java | 1 + .../rendering/DefaultErrorMessages.java | 1 + .../kotlin/resolve/DeclarationsChecker.kt | 3 ++ .../kotlin/resolve/ModifiersChecker.kt | 4 +-- .../headerClass/memberPropertyKinds.kt | 29 +++++++++++++++++++ .../headerClass/memberPropertyKinds.txt | 27 +++++++++++++++++ .../differentKindsOfProperties.kt | 2 +- .../checkers/DiagnosticsTestGenerated.java | 6 ++++ .../DiagnosticsUsingJavacTestGenerated.java | 6 ++++ 9 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/multiplatform/headerClass/memberPropertyKinds.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/headerClass/memberPropertyKinds.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index a00a3080871..67361207b18 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -562,6 +562,7 @@ public interface Errors { DiagnosticFactory0> EXPECTED_ENUM_CONSTRUCTOR = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 EXPECTED_ENUM_ENTRY_WITH_BODY = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 EXPECTED_PROPERTY_INITIALIZER = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 EXPECTED_DELEGATED_PROPERTY = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 ACTUAL_TYPE_ALIAS_NOT_TO_CLASS = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); DiagnosticFactory0 diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 03f022b932d..4afd0ab6bf6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -270,6 +270,7 @@ public class DefaultErrorMessages { MAP.put(EXPECTED_ENUM_CONSTRUCTOR, "Expected enum class cannot have a constructor"); MAP.put(EXPECTED_ENUM_ENTRY_WITH_BODY, "Expected enum entry cannot have a body"); MAP.put(EXPECTED_PROPERTY_INITIALIZER, "Expected property cannot have an initializer"); + MAP.put(EXPECTED_DELEGATED_PROPERTY, "Expected property cannot be delegated"); MAP.put(ACTUAL_TYPE_ALIAS_NOT_TO_CLASS, "Right-hand side of actual type alias should be a class, not another type alias"); MAP.put(ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE, "Aliased class should not have type parameters with declaration-site variance"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index afd2ee357c1..5161b8d0eb9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -646,6 +646,9 @@ class DeclarationsChecker( if (inInterface) { trace.report(DELEGATED_PROPERTY_IN_INTERFACE.on(delegate)) } + else if (isExpect) { + trace.report(EXPECTED_DELEGATED_PROPERTY.on(delegate)) + } } else { val isUninitialized = trace.bindingContext.get(BindingContext.IS_UNINITIALIZED, propertyDescriptor) ?: false diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt index 639d0f03018..f5c0e0e1d90 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.kt @@ -86,9 +86,9 @@ object ModifierCheckerCore { CONST_KEYWORD to EnumSet.of(MEMBER_PROPERTY, TOP_LEVEL_PROPERTY), OPERATOR_KEYWORD to EnumSet.of(FUNCTION), INFIX_KEYWORD to EnumSet.of(FUNCTION), - HEADER_KEYWORD to EnumSet.of(TOP_LEVEL_FUNCTION, TOP_LEVEL_PROPERTY_WITHOUT_FIELD_OR_DELEGATE, CLASS_ONLY, OBJECT, INTERFACE, ENUM_CLASS, ANNOTATION_CLASS), + HEADER_KEYWORD to EnumSet.of(TOP_LEVEL_FUNCTION, TOP_LEVEL_PROPERTY, CLASS_ONLY, OBJECT, INTERFACE, ENUM_CLASS, ANNOTATION_CLASS), IMPL_KEYWORD to EnumSet.of(TOP_LEVEL_FUNCTION, MEMBER_FUNCTION, TOP_LEVEL_PROPERTY, MEMBER_PROPERTY, CONSTRUCTOR, CLASS_ONLY, OBJECT, INTERFACE, ENUM_CLASS, ANNOTATION_CLASS, TYPEALIAS), - EXPECT_KEYWORD to EnumSet.of(TOP_LEVEL_FUNCTION, TOP_LEVEL_PROPERTY_WITHOUT_FIELD_OR_DELEGATE, CLASS_ONLY, OBJECT, INTERFACE, ENUM_CLASS, ANNOTATION_CLASS), + EXPECT_KEYWORD to EnumSet.of(TOP_LEVEL_FUNCTION, TOP_LEVEL_PROPERTY, CLASS_ONLY, OBJECT, INTERFACE, ENUM_CLASS, ANNOTATION_CLASS), ACTUAL_KEYWORD to EnumSet.of(TOP_LEVEL_FUNCTION, MEMBER_FUNCTION, TOP_LEVEL_PROPERTY, MEMBER_PROPERTY, CONSTRUCTOR, CLASS_ONLY, OBJECT, INTERFACE, ENUM_CLASS, ANNOTATION_CLASS, TYPEALIAS) ) diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/memberPropertyKinds.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/memberPropertyKinds.kt new file mode 100644 index 00000000000..9bfba462621 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/memberPropertyKinds.kt @@ -0,0 +1,29 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt + +expect class Foo { + val justVal: String + var justVar: String + + val String.extensionVal: Unit + var T.genericExtensionVar: T + + val valWithGet: String + get + var varWithGetSet: String + get set + + val backingFieldVal: String = "no" + var backingFieldVar: String = "no" + + val customAccessorVal: String + get() = "no" + var customAccessorVar: String + get() = "no" + set(value) {} + + val delegated: String by Delegate +} + +object Delegate { operator fun getValue(x: Any?, y: Any?): String = "" } diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/memberPropertyKinds.txt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/memberPropertyKinds.txt new file mode 100644 index 00000000000..2f8b94e29a1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/memberPropertyKinds.txt @@ -0,0 +1,27 @@ +package + +public object Delegate { + private constructor Delegate() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final operator fun getValue(/*0*/ x: kotlin.Any?, /*1*/ y: kotlin.Any?): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final expect class Foo { + public constructor Foo() + public expect final val backingFieldVal: kotlin.String = "no" + public expect final var backingFieldVar: kotlin.String + public expect final val customAccessorVal: kotlin.String + public expect final var customAccessorVar: kotlin.String + public expect final val delegated: kotlin.String + public expect final val justVal: kotlin.String + public expect final var justVar: kotlin.String + public expect final val valWithGet: kotlin.String + public expect final var varWithGetSet: kotlin.String + public expect final val kotlin.String.extensionVal: kotlin.Unit + public expect final var T.genericExtensionVar: T + 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/diagnostics/tests/multiplatform/topLevelProperty/differentKindsOfProperties.kt b/compiler/testData/diagnostics/tests/multiplatform/topLevelProperty/differentKindsOfProperties.kt index 2183b91383f..cf201cc8da5 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/topLevelProperty/differentKindsOfProperties.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/topLevelProperty/differentKindsOfProperties.kt @@ -30,7 +30,7 @@ expect const val constVal: Int expect lateinit var lateinitVar: String -expect val delegated: String by Delegate +expect val delegated: String by Delegate object Delegate { operator fun getValue(x: Any?, y: Any?): String = "" } fun test(): String { diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 283319ea36e..ec416188110 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -13986,6 +13986,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("memberPropertyKinds.kt") + public void testMemberPropertyKinds() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/memberPropertyKinds.kt"); + doTest(fileName); + } + @TestMetadata("nestedClasses.kt") public void testNestedClasses() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/nestedClasses.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 5897434f96a..fac137c8608 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -13986,6 +13986,12 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing doTest(fileName); } + @TestMetadata("memberPropertyKinds.kt") + public void testMemberPropertyKinds() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/memberPropertyKinds.kt"); + doTest(fileName); + } + @TestMetadata("nestedClasses.kt") public void testNestedClasses() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/nestedClasses.kt");