Report error about val reassignment via backing field since Kotlin 1.3

Also improve message for current warning

 #KT-16681 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2017-09-06 17:20:07 +03:00
parent 03440210ee
commit 088800d82f
8 changed files with 37 additions and 2 deletions
@@ -458,7 +458,7 @@ class ControlFlowInformationProvider private constructor(
}
else {
if (KtPsiUtil.isBackingFieldReference(variableDescriptor)) {
report(Errors.VAL_REASSIGNMENT_VIA_BACKING_FIELD.on(expression, variableDescriptor), ctxt)
reportValReassigned(expression, variableDescriptor, ctxt)
}
else {
report(Errors.VAL_REASSIGNMENT.on(expression, variableDescriptor), ctxt)
@@ -476,6 +476,15 @@ class ControlFlowInformationProvider private constructor(
return false
}
private fun reportValReassigned(expression: KtExpression, variableDescriptor: VariableDescriptor, ctxt: VariableInitContext) {
val diagnosticFactory = if (languageVersionSettings.supportsFeature(LanguageFeature.RestrictionOfValReassignmentViaBackingField))
Errors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR
else
Errors.VAL_REASSIGNMENT_VIA_BACKING_FIELD
report(diagnosticFactory.on(expression, variableDescriptor), ctxt)
}
private fun checkAssignmentBeforeDeclaration(ctxt: VariableInitContext, expression: KtExpression) =
if (ctxt.enterInitState?.isDeclared == true
|| ctxt.exitInitState?.isDeclared == true
@@ -784,6 +784,7 @@ public interface Errors {
DiagnosticFactory1<KtExpression, DeclarationDescriptor> VAL_REASSIGNMENT = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<KtExpression, DeclarationDescriptor> VAL_REASSIGNMENT_VIA_BACKING_FIELD = DiagnosticFactory1.create(WARNING);
DiagnosticFactory1<KtExpression, DeclarationDescriptor> VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<KtExpression, DeclarationDescriptor> CAPTURED_VAL_INITIALIZATION = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<KtExpression, DeclarationDescriptor> CAPTURED_MEMBER_VAL_INITIALIZATION = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<KtExpression, DeclarationDescriptor> SETTER_PROJECTED_OUT = DiagnosticFactory1.create(ERROR);
@@ -308,7 +308,8 @@ public class DefaultErrorMessages {
MAP.put(UNUSED_LAMBDA_EXPRESSION, "The lambda expression is unused. If you mean a block, you can use 'run { ... }'");
MAP.put(VAL_REASSIGNMENT, "Val cannot be reassigned", NAME);
MAP.put(VAL_REASSIGNMENT_VIA_BACKING_FIELD, "Val cannot be reassigned via backing field", NAME);
MAP.put(VAL_REASSIGNMENT_VIA_BACKING_FIELD, "Reassignment of read-only property via backing field is deprecated", NAME);
MAP.put(VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR, "Reassignment of read-only property via backing field", NAME);
MAP.put(CAPTURED_VAL_INITIALIZATION, "Captured values initialization is forbidden due to possible reassignment", NAME);
MAP.put(CAPTURED_MEMBER_VAL_INITIALIZATION, "Captured member values initialization is forbidden due to possible reassignment", NAME);
MAP.put(SETTER_PROJECTED_OUT, "Setter for ''{0}'' is removed by type projection", NAME);
@@ -0,0 +1,7 @@
// !LANGUAGE: +RestrictionOfValReassignmentViaBackingField
val my: Int = 1
get() {
<!VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR!>field<!>++
return field
}
@@ -0,0 +1,3 @@
package
public val my: kotlin.Int = 1
@@ -1777,6 +1777,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("FieldReassignmentError.kt")
public void testFieldReassignmentError() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/backingField/FieldReassignmentError.kt");
doTest(fileName);
}
@TestMetadata("FieldShadow.kt")
public void testFieldShadow() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/backingField/FieldShadow.kt");
@@ -1777,6 +1777,12 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
doTest(fileName);
}
@TestMetadata("FieldReassignmentError.kt")
public void testFieldReassignmentError() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/backingField/FieldReassignmentError.kt");
doTest(fileName);
}
@TestMetadata("FieldShadow.kt")
public void testFieldShadow() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/backingField/FieldShadow.kt");
@@ -60,6 +60,8 @@ enum class LanguageFeature(
LateinitTopLevelProperties(KOTLIN_1_2),
LateinitLocalVariables(KOTLIN_1_2),
RestrictionOfValReassignmentViaBackingField(KOTLIN_1_3),
// Experimental features
Coroutines(KOTLIN_1_1, ApiVersion.KOTLIN_1_1, "https://kotlinlang.org/docs/diagnostics/experimental-coroutines", State.ENABLED_WITH_WARNING),