FE 1.0: introduce DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER error

#KT-24643 Fixed
This commit is contained in:
Mikhail Glukhikh
2021-04-05 15:12:55 +03:00
parent d062f54360
commit fcbab45a88
12 changed files with 136 additions and 0 deletions
@@ -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 {
@@ -603,6 +603,8 @@ public interface Errors {
DiagnosticFactory0<KtExpression> SETTER_PARAMETER_WITH_DEFAULT_VALUE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory2<KtTypeReference, KotlinType, KotlinType> WRONG_SETTER_PARAMETER_TYPE = DiagnosticFactory2.create(ERROR);
DiagnosticFactory1<KtPropertyDelegate, String> DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<KtPropertyDelegate, String> DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER_WARNING = DiagnosticFactory1.create(WARNING);
// Function-specific
@@ -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);
@@ -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
@@ -0,0 +1,16 @@
// !LANGUAGE: +ForbidUsingExtensionPropertyTypeParameterInDelegate
class Delegate<T : Any> {
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 <T : Any> List<T>.foo by Delegate<T>()
fun useString(s: String) {}
fun main(listInt: List<Int>, listStr: List<String>) {
listInt.foo = 42
useString(listStr.foo) // CCE
}
@@ -0,0 +1,16 @@
// !LANGUAGE: +ForbidUsingExtensionPropertyTypeParameterInDelegate
class Delegate<T : Any> {
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 <T : Any> List<T>.foo <!DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER!>by Delegate<T>()<!>
fun useString(s: String) {}
fun main(listInt: List<Int>, listStr: List<String>) {
listInt.foo = 42
useString(listStr.foo) // CCE
}
@@ -0,0 +1,15 @@
package
public var </*0*/ T : kotlin.Any> kotlin.collections.List<T>.foo: T
public fun main(/*0*/ listInt: kotlin.collections.List<kotlin.Int>, /*1*/ listStr: kotlin.collections.List<kotlin.String>): kotlin.Unit
public fun useString(/*0*/ s: kotlin.String): kotlin.Unit
public final class Delegate</*0*/ T : kotlin.Any> {
public constructor Delegate</*0*/ T : kotlin.Any>()
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
}
@@ -0,0 +1,16 @@
// !LANGUAGE: -ForbidUsingExtensionPropertyTypeParameterInDelegate
class Delegate<T : Any> {
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 <T : Any> List<T>.foo by Delegate<T>()
fun useString(s: String) {}
fun main(listInt: List<Int>, listStr: List<String>) {
listInt.foo = 42
useString(listStr.foo) // CCE
}
@@ -0,0 +1,16 @@
// !LANGUAGE: -ForbidUsingExtensionPropertyTypeParameterInDelegate
class Delegate<T : Any> {
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 <T : Any> List<T>.foo <!DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER_WARNING!>by Delegate<T>()<!>
fun useString(s: String) {}
fun main(listInt: List<Int>, listStr: List<String>) {
listInt.foo = 42
useString(listStr.foo) // CCE
}
@@ -0,0 +1,15 @@
package
public var </*0*/ T : kotlin.Any> kotlin.collections.List<T>.foo: T
public fun main(/*0*/ listInt: kotlin.collections.List<kotlin.Int>, /*1*/ listStr: kotlin.collections.List<kotlin.String>): kotlin.Unit
public fun useString(/*0*/ s: kotlin.String): kotlin.Unit
public final class Delegate</*0*/ T : kotlin.Any> {
public constructor Delegate</*0*/ T : kotlin.Any>()
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
}
@@ -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 {
@@ -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),