diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt index 1589b4502cc..e4d8808cfbb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt @@ -459,7 +459,12 @@ class ControlFlowInformationProvider private constructor( if (!hasReassignMethodReturningUnit) { if (!isThisOrNoDispatchReceiver || !varWithValReassignErrorGenerated.contains(variableDescriptor)) { if (captured && !mayBeInitializedNotHere && hasBackingField && isThisOrNoDispatchReceiver) { - report(Errors.CAPTURED_VAL_INITIALIZATION.on(expression, variableDescriptor), ctxt) + if (variableDescriptor.containingDeclaration is ClassDescriptor) { + report(Errors.CAPTURED_MEMBER_VAL_INITIALIZATION.on(expression, variableDescriptor), ctxt) + } + else { + report(Errors.CAPTURED_VAL_INITIALIZATION.on(expression, variableDescriptor), ctxt) + } } else { report(Errors.VAL_REASSIGNMENT.on(expression, variableDescriptor), ctxt) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index bac4ec139b9..5118884436a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -762,6 +762,7 @@ public interface Errors { DiagnosticFactory1 VAL_REASSIGNMENT = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 CAPTURED_VAL_INITIALIZATION = DiagnosticFactory1.create(ERROR); + DiagnosticFactory1 CAPTURED_MEMBER_VAL_INITIALIZATION = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 SETTER_PROJECTED_OUT = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 INITIALIZATION_BEFORE_DECLARATION = DiagnosticFactory1.create(ERROR); 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 77e3dfd8e8a..feae4e1170a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -300,6 +300,7 @@ public class DefaultErrorMessages { MAP.put(VAL_REASSIGNMENT, "Val cannot be reassigned", 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); MAP.put(INVISIBLE_SETTER, "Cannot assign to ''{0}'': the setter is {1} in {2}", NAME, VISIBILITY, NAME_OF_PARENT_OR_FILE); MAP.put(INITIALIZATION_BEFORE_DECLARATION, "Variable cannot be initialized before declaration", NAME); diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/assignmentInLocalsInConstructor.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/assignmentInLocalsInConstructor.kt index 79d545aa3b8..572fa3a5893 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/assignmentInLocalsInConstructor.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/assignmentInLocalsInConstructor.kt @@ -7,7 +7,7 @@ class Test { val t = object { fun some() { // See KT-13597 - a = "12" + a = "12" } } @@ -41,7 +41,7 @@ class Test4 { init { exec { // See KT-14381 - a = "12" + a = "12" } a = "34" } diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt index fdbf1833664..10f2dee59e5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt +++ b/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt @@ -106,7 +106,7 @@ object J2KPostProcessingRegistrar { } registerDiagnosticBasedProcessingFactory( - Errors.VAL_REASSIGNMENT, Errors.CAPTURED_VAL_INITIALIZATION + Errors.VAL_REASSIGNMENT, Errors.CAPTURED_VAL_INITIALIZATION, Errors.CAPTURED_MEMBER_VAL_INITIALIZATION ) { element: KtSimpleNameExpression, _: Diagnostic -> val property = element.mainReference.resolve() as? KtProperty diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt index 47bcd5669c7..a2c9d4a6223 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt @@ -68,6 +68,8 @@ class ChangeVariableMutabilityFix(element: KtValVarKeywordOwner, private val mak val CAPTURED_VAL_INITIALIZATION_FACTORY = ReassignmentActionFactory(Errors.CAPTURED_VAL_INITIALIZATION) + val CAPTURED_MEMBER_VAL_INITIALIZATION_FACTORY = ReassignmentActionFactory(Errors.CAPTURED_MEMBER_VAL_INITIALIZATION) + val VAR_OVERRIDDEN_BY_VAL_FACTORY: KotlinSingleIntentionActionFactory = object: KotlinSingleIntentionActionFactory() { override fun createAction(diagnostic: Diagnostic): IntentionAction? { val element = diagnostic.psiElement diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index b2f2bc13efa..b86ddcb1432 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -194,6 +194,7 @@ class QuickFixRegistrar : QuickFixContributor { VAL_REASSIGNMENT.registerFactory(ChangeVariableMutabilityFix.VAL_REASSIGNMENT_FACTORY) VAL_REASSIGNMENT.registerFactory(LiftAssignmentOutOfTryFix) CAPTURED_VAL_INITIALIZATION.registerFactory(ChangeVariableMutabilityFix.CAPTURED_VAL_INITIALIZATION_FACTORY) + CAPTURED_MEMBER_VAL_INITIALIZATION.registerFactory(ChangeVariableMutabilityFix.CAPTURED_MEMBER_VAL_INITIALIZATION_FACTORY) VAR_OVERRIDDEN_BY_VAL.registerFactory(ChangeVariableMutabilityFix.VAR_OVERRIDDEN_BY_VAL_FACTORY) VAR_ANNOTATION_PARAMETER.registerFactory(ChangeVariableMutabilityFix.VAR_ANNOTATION_PARAMETER_FACTORY) diff --git a/idea/testData/quickfix/variables/changeMutability/capturedMemberValInitialization.kt b/idea/testData/quickfix/variables/changeMutability/capturedMemberValInitialization.kt new file mode 100644 index 00000000000..77a192d8031 --- /dev/null +++ b/idea/testData/quickfix/variables/changeMutability/capturedMemberValInitialization.kt @@ -0,0 +1,16 @@ +// "Make variable mutable" "true" + +class Test { + val a: String + + init { + val t = object { + fun some() { + a = "12" + } + } + + a = "2" + t.some() + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/variables/changeMutability/capturedMemberValInitialization.kt.after b/idea/testData/quickfix/variables/changeMutability/capturedMemberValInitialization.kt.after new file mode 100644 index 00000000000..55a1aab8f72 --- /dev/null +++ b/idea/testData/quickfix/variables/changeMutability/capturedMemberValInitialization.kt.after @@ -0,0 +1,16 @@ +// "Make variable mutable" "true" + +class Test { + var a: String + + init { + val t = object { + fun some() { + a = "12" + } + } + + a = "2" + t.some() + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index f255743b71a..cd45a3fb58c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -10600,6 +10600,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/variables/changeMutability"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("capturedMemberValInitialization.kt") + public void testCapturedMemberValInitialization() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/variables/changeMutability/capturedMemberValInitialization.kt"); + doTest(fileName); + } + @TestMetadata("capturedValInitialization.kt") public void testCapturedValInitialization() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/variables/changeMutability/capturedValInitialization.kt");