From d70486258243cba16c82efa19f8b2602b5a37fd4 Mon Sep 17 00:00:00 2001 From: Anastasiya Shadrina Date: Mon, 7 Dec 2020 22:10:44 +0700 Subject: [PATCH] [FE] Prohibit property initializers with context receivers --- ...irOldFrontendDiagnosticsTestGenerated.java | 6 ++++++ .../jetbrains/kotlin/diagnostics/Errors.java | 1 + .../rendering/DefaultErrorMessages.java | 1 + .../kotlin/resolve/DeclarationsChecker.kt | 1 + .../contextReceivers/noBackingField.fir.kt | 15 +++++++++++++++ .../contextReceivers/noBackingField.kt | 15 +++++++++++++++ .../contextReceivers/noBackingField.txt | 19 +++++++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++++++ 8 files changed, 64 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.fir.kt create mode 100644 compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.kt create mode 100644 compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.txt diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 41ecb4d5084..a50e908be94 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -10606,6 +10606,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/manyReceivers.kt"); } + @Test + @TestMetadata("noBackingField.kt") + public void testNoBackingField() throws Exception { + runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.kt"); + } + @Test @TestMetadata("noExplicitReceiver.kt") public void testNoExplicitReceiver() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 31639987250..035cae444ae 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -606,6 +606,7 @@ public interface Errors { DiagnosticFactory0 UNNECESSARY_LATEINIT = DiagnosticFactory0.create(WARNING, LATEINIT_MODIFIER); DiagnosticFactory0 EXTENSION_PROPERTY_WITH_BACKING_FIELD = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 CONTEXT_RECEIVERS_WITH_BACKING_FIELD = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 PROPERTY_INITIALIZER_NO_BACKING_FIELD = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 PROPERTY_INITIALIZER_IN_INTERFACE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 PRIVATE_PROPERTY_IN_INTERFACE = DiagnosticFactory0.create(ERROR, PRIVATE_MODIFIER); 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 63b3968bd0d..ecd91af674f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -265,6 +265,7 @@ public class DefaultErrorMessages { MAP.put(PROPERTY_INITIALIZER_IN_INTERFACE, "Property initializers are not allowed in interfaces"); MAP.put(PRIVATE_PROPERTY_IN_INTERFACE, "Abstract property in an interface cannot be private"); MAP.put(EXTENSION_PROPERTY_WITH_BACKING_FIELD, "Extension property cannot be initialized because it has no backing field"); + MAP.put(CONTEXT_RECEIVERS_WITH_BACKING_FIELD, "Property with context receivers cannot be initialized because it has no backing field"); MAP.put(PROPERTY_INITIALIZER_NO_BACKING_FIELD, "Initializer is not allowed here because this property has no backing field"); MAP.put(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, "Abstract property ''{0}'' in non-abstract class ''{1}''", STRING, NAME); MAP.put(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, "Abstract function ''{0}'' in non-abstract class ''{1}''", STRING, NAME); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index 142c6606c59..aa309d1fcbd 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -713,6 +713,7 @@ class DeclarationsChecker( isExpect -> trace.report(EXPECTED_PROPERTY_INITIALIZER.on(initializer)) !backingFieldRequired -> trace.report(PROPERTY_INITIALIZER_NO_BACKING_FIELD.on(initializer)) property.receiverTypeReference != null -> trace.report(EXTENSION_PROPERTY_WITH_BACKING_FIELD.on(initializer)) + property.contextReceivers.isNotEmpty() -> trace.report(CONTEXT_RECEIVERS_WITH_BACKING_FIELD.on(initializer)) } } else if (delegate != null) { if (inInterface) { diff --git a/compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.fir.kt b/compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.fir.kt new file mode 100644 index 00000000000..673069b107e --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.fir.kt @@ -0,0 +1,15 @@ +interface A { + fun a(): Int +} +interface B { + fun b(): Int +} + +context(A) +val a = 1 + +context(A, B) +var b = 2 + +context(A, B) +val c get() = a() + b() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.kt b/compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.kt new file mode 100644 index 00000000000..3957eac2560 --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.kt @@ -0,0 +1,15 @@ +interface A { + fun a(): Int +} +interface B { + fun b(): Int +} + +context(A) +val a = 1 + +context(A, B) +var b = 2 + +context(A, B) +val c get() = a() + b() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.txt b/compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.txt new file mode 100644 index 00000000000..bc22529e432 --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.txt @@ -0,0 +1,19 @@ +package + +public val a: kotlin.Int = 1 +public var b: kotlin.Int +public val c: kotlin.Int + +public interface A { + public abstract fun a(): kotlin.Int + 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 interface B { + public abstract fun b(): kotlin.Int + 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-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index d11f8e6ef73..ee743e6bf29 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -10612,6 +10612,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/manyReceivers.kt"); } + @Test + @TestMetadata("noBackingField.kt") + public void testNoBackingField() throws Exception { + runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/noBackingField.kt"); + } + @Test @TestMetadata("noExplicitReceiver.kt") public void testNoExplicitReceiver() throws Exception {