From fcbab45a889b3bf9a6ad3b2887aeee0dc2b58d73 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 5 Apr 2021 15:12:55 +0300 Subject: [PATCH] FE 1.0: introduce DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER error #KT-24643 Fixed --- .../FirOldFrontendDiagnosticsTestGenerated.java | 12 ++++++++++++ .../org/jetbrains/kotlin/diagnostics/Errors.java | 2 ++ .../rendering/DefaultErrorMessages.java | 2 ++ .../kotlin/resolve/DeclarationsChecker.kt | 13 +++++++++++++ .../useTypeParameterOfExtensionProperty.fir.kt | 16 ++++++++++++++++ .../useTypeParameterOfExtensionProperty.kt | 16 ++++++++++++++++ .../useTypeParameterOfExtensionProperty.txt | 15 +++++++++++++++ ...eParameterOfExtensionProperty_Disabled.fir.kt | 16 ++++++++++++++++ ...eTypeParameterOfExtensionProperty_Disabled.kt | 16 ++++++++++++++++ ...TypeParameterOfExtensionProperty_Disabled.txt | 15 +++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 12 ++++++++++++ .../kotlin/config/LanguageVersionSettings.kt | 1 + 12 files changed, 136 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.fir.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.txt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.fir.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.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 47812c2b541..99f91a15195 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 @@ -7119,6 +7119,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/delegatedProperty/typeMismatchForThisGetParameter.kt"); } + @Test + @TestMetadata("useTypeParameterOfExtensionProperty.kt") + public void testUseTypeParameterOfExtensionProperty() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.kt"); + } + + @Test + @TestMetadata("useTypeParameterOfExtensionProperty_Disabled.kt") + public void testUseTypeParameterOfExtensionProperty_Disabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.kt"); + } + @Test @TestMetadata("wrongCountOfParametersInGet.kt") public void testWrongCountOfParametersInGet() 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 3fa64263b9b..ee2d9634df0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -603,6 +603,8 @@ public interface Errors { DiagnosticFactory0 SETTER_PARAMETER_WITH_DEFAULT_VALUE = DiagnosticFactory0.create(ERROR); DiagnosticFactory2 WRONG_SETTER_PARAMETER_TYPE = DiagnosticFactory2.create(ERROR); + DiagnosticFactory1 DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER = DiagnosticFactory1.create(ERROR); + DiagnosticFactory1 DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER_WARNING = DiagnosticFactory1.create(WARNING); // Function-specific 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 228e1629b59..347f6ef241b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -477,6 +477,8 @@ public class DefaultErrorMessages { MAP.put(USELESS_NULLABLE_CHECK, "Non-null type is checked for instance of nullable type"); MAP.put(USELESS_IS_CHECK, "Check for instance is always ''{0}''", TO_STRING); MAP.put(WRONG_SETTER_PARAMETER_TYPE, "Setter parameter type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE); + MAP.put(DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER, "It's forbidden using extension property type parameter ''{0}'' in delegate", TO_STRING); + MAP.put(DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER_WARNING, "Deprecation: delegate shouldn't use extension property type parameter ''{0}''", TO_STRING); MAP.put(WRONG_GETTER_RETURN_TYPE, "Getter return type must be equal to the type of the property, i.e. ''{0}''", RENDER_TYPE, RENDER_TYPE); MAP.put(WRONG_SETTER_RETURN_TYPE, "Setter return type must be Unit"); MAP.put(NO_COMPANION_OBJECT, "Classifier ''{0}'' does not have a companion object, and thus must be initialized here", NAME); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index 659b692e829..45a7ae1f6c1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -712,6 +712,19 @@ class DeclarationsChecker( trace.report(DELEGATED_PROPERTY_IN_INTERFACE.on(delegate)) } else if (isExpect) { trace.report(EXPECTED_DELEGATED_PROPERTY.on(delegate)) + } else if (property.receiverTypeReference != null) { + val delegatedPropertyResolvedCall = trace.get(DELEGATED_PROPERTY_RESOLVED_CALL, propertyDescriptor.getter) + val dispatchReceiverType = delegatedPropertyResolvedCall?.dispatchReceiver?.type + val usedParameter = propertyDescriptor.typeParameters.find { typeParameter -> + dispatchReceiverType?.contains { it.constructor == typeParameter.typeConstructor } == true + } + if (usedParameter != null) { + if (languageVersionSettings.supportsFeature(LanguageFeature.ForbidUsingExtensionPropertyTypeParameterInDelegate)) { + trace.report(DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER.on(delegate, usedParameter.name.asString())) + } else { + trace.report(DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER_WARNING.on(delegate, usedParameter.name.asString())) + } + } } } else { val isUninitialized = trace.bindingContext.get(BindingContext.IS_UNINITIALIZED, propertyDescriptor) ?: false diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.fir.kt b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.fir.kt new file mode 100644 index 00000000000..4b296090b0a --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.fir.kt @@ -0,0 +1,16 @@ +// !LANGUAGE: +ForbidUsingExtensionPropertyTypeParameterInDelegate + +class Delegate { + private var v: T? = null + operator fun getValue(thisRef: Any?, kp: Any?): T = v!! + operator fun setValue(thisRef: Any?, kp: Any?, newValue: T) { v = newValue } +} + +var List.foo by Delegate() + +fun useString(s: String) {} + +fun main(listInt: List, listStr: List) { + listInt.foo = 42 + useString(listStr.foo) // CCE +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.kt b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.kt new file mode 100644 index 00000000000..cfd2c6d418c --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.kt @@ -0,0 +1,16 @@ +// !LANGUAGE: +ForbidUsingExtensionPropertyTypeParameterInDelegate + +class Delegate { + private var v: T? = null + operator fun getValue(thisRef: Any?, kp: Any?): T = v!! + operator fun setValue(thisRef: Any?, kp: Any?, newValue: T) { v = newValue } +} + +var List.foo by Delegate() + +fun useString(s: String) {} + +fun main(listInt: List, listStr: List) { + listInt.foo = 42 + useString(listStr.foo) // CCE +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.txt b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.txt new file mode 100644 index 00000000000..4823e379b3b --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.txt @@ -0,0 +1,15 @@ +package + +public var kotlin.collections.List.foo: T +public fun main(/*0*/ listInt: kotlin.collections.List, /*1*/ listStr: kotlin.collections.List): kotlin.Unit +public fun useString(/*0*/ s: kotlin.String): kotlin.Unit + +public final class Delegate { + public constructor Delegate() + private final var v: T? + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ kp: kotlin.Any?): T + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ kp: kotlin.Any?, /*2*/ newValue: T): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.fir.kt b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.fir.kt new file mode 100644 index 00000000000..bd4b67e76cc --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.fir.kt @@ -0,0 +1,16 @@ +// !LANGUAGE: -ForbidUsingExtensionPropertyTypeParameterInDelegate + +class Delegate { + private var v: T? = null + operator fun getValue(thisRef: Any?, kp: Any?): T = v!! + operator fun setValue(thisRef: Any?, kp: Any?, newValue: T) { v = newValue } +} + +var List.foo by Delegate() + +fun useString(s: String) {} + +fun main(listInt: List, listStr: List) { + listInt.foo = 42 + useString(listStr.foo) // CCE +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.kt b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.kt new file mode 100644 index 00000000000..6fe5cfbf79f --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.kt @@ -0,0 +1,16 @@ +// !LANGUAGE: -ForbidUsingExtensionPropertyTypeParameterInDelegate + +class Delegate { + private var v: T? = null + operator fun getValue(thisRef: Any?, kp: Any?): T = v!! + operator fun setValue(thisRef: Any?, kp: Any?, newValue: T) { v = newValue } +} + +var List.foo by Delegate() + +fun useString(s: String) {} + +fun main(listInt: List, listStr: List) { + listInt.foo = 42 + useString(listStr.foo) // CCE +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.txt b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.txt new file mode 100644 index 00000000000..4823e379b3b --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.txt @@ -0,0 +1,15 @@ +package + +public var kotlin.collections.List.foo: T +public fun main(/*0*/ listInt: kotlin.collections.List, /*1*/ listStr: kotlin.collections.List): kotlin.Unit +public fun useString(/*0*/ s: kotlin.String): kotlin.Unit + +public final class Delegate { + public constructor Delegate() + private final var v: T? + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ kp: kotlin.Any?): T + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ kp: kotlin.Any?, /*2*/ newValue: T): kotlin.Unit + 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 e976c0232c8..70838edc17b 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 @@ -7125,6 +7125,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/delegatedProperty/typeMismatchForThisGetParameter.kt"); } + @Test + @TestMetadata("useTypeParameterOfExtensionProperty.kt") + public void testUseTypeParameterOfExtensionProperty() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty.kt"); + } + + @Test + @TestMetadata("useTypeParameterOfExtensionProperty_Disabled.kt") + public void testUseTypeParameterOfExtensionProperty_Disabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/delegatedProperty/useTypeParameterOfExtensionProperty_Disabled.kt"); + } + @Test @TestMetadata("wrongCountOfParametersInGet.kt") public void testWrongCountOfParametersInGet() throws Exception { diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 8acffafb403..d00f06ba442 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -165,6 +165,7 @@ enum class LanguageFeature( TypeEnhancementImprovementsInStrictMode(KOTLIN_1_6), ProhibitJvmFieldOnOverrideFromInterfaceInPrimaryConstructor(KOTLIN_1_6, kind = BUG_FIX), PrivateInFileEffectiveVisibility(KOTLIN_1_6, kind = BUG_FIX), + ForbidUsingExtensionPropertyTypeParameterInDelegate(KOTLIN_1_6, kind = BUG_FIX), // Temporarily disabled, see KT-27084/KT-22379 SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),