diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java index cef9bbdfda4..98b49352263 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java @@ -182,6 +182,8 @@ public class JetFlowInformationProvider { initialMapForStartInstruction, true); + final Collection varWithUninitializedErrorGenerated = Sets.newHashSet(); + final Collection varWithValReassignErrorGenerated = Sets.newHashSet(); traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy>() { @Override public void execute(Instruction instruction, @Nullable Map enterData, @Nullable Map exitData) { @@ -200,7 +202,8 @@ public class JetFlowInformationProvider { isInitialized = true; } } - if (!analyzeLocalDeclaration && !isInitialized) { + if (!analyzeLocalDeclaration && !isInitialized && !varWithUninitializedErrorGenerated.contains(variableDescriptor)) { + varWithUninitializedErrorGenerated.add(variableDescriptor); trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, variableDescriptor)); } } @@ -222,9 +225,10 @@ public class JetFlowInformationProvider { } } JetExpression expression = (JetExpression) element; - if (!analyzeLocalDeclaration && hasInitializer && !variableDescriptor.isVar()) { + if (!analyzeLocalDeclaration && hasInitializer && !variableDescriptor.isVar() && !varWithValReassignErrorGenerated.contains(variableDescriptor)) { PsiElement psiElement = trace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, variableDescriptor); JetProperty property = psiElement instanceof JetProperty ? (JetProperty) psiElement : null; + varWithValReassignErrorGenerated.add(variableDescriptor); trace.report(Errors.VAL_REASSIGNMENT.on(expression, variableDescriptor, property == null ? new JetProperty[0] : new JetProperty[] { property })); } if (expression instanceof JetSimpleNameExpression && inAnonymousInitializers && diff --git a/compiler/testData/checkerWithErrorTypes/quick/LValueAssignment.jet b/compiler/testData/checkerWithErrorTypes/quick/LValueAssignment.jet index a4c22abbd91..fd3796e1ffd 100644 --- a/compiler/testData/checkerWithErrorTypes/quick/LValueAssignment.jet +++ b/compiler/testData/checkerWithErrorTypes/quick/LValueAssignment.jet @@ -12,11 +12,15 @@ class C() : B() { this.b = 123 super.b = 23 this.c = 34 - super.c = 3535 + super.c = 3535 //repeat for 'c' getInt() = 12 } + fun foo1(c: C) { + super.c = 34 + } + fun bar(c: C) { this = c //should be an error } @@ -47,12 +51,16 @@ fun canBe(var i: Int, val j: Int) { (@label i) = 34 (j: Int) = 36 - (@label j) = 34 + (@label j) = 34 //repeat for j val a = A() (@ a.a) = 3894 } +fun canBe2(val j: Int) { + (@label j) = 34 +} + class A() { var a: Int = 3 } @@ -92,9 +100,6 @@ class Test() { (a : Int) += 34 b += 34 - (@l b) += 34 - (b : Int) += 34 - (b) += 3 a++ (@ a)++ @@ -102,6 +107,15 @@ class Test() { (a)++ } + fun testVariables1() { + val b: Int = 34 + + (@l b) += 34 + //repeat for b + (b : Int) += 34 + (b) += 3 + } + fun testArrays(a: Array, ab: Ab) { a[3] = 4 a[4]++ diff --git a/compiler/testData/checkerWithErrorTypes/quick/UninitializedOrReassignedVariables.jet b/compiler/testData/checkerWithErrorTypes/quick/UninitializedOrReassignedVariables.jet index 0dac79bd8cb..548e67dece9 100644 --- a/compiler/testData/checkerWithErrorTypes/quick/UninitializedOrReassignedVariables.jet +++ b/compiler/testData/checkerWithErrorTypes/quick/UninitializedOrReassignedVariables.jet @@ -30,7 +30,7 @@ fun t1(b : Boolean) { doSmth(t) else t = "ss" - doSmth(t) + doSmth(t) //repeat for t val i = 3 doSmth(i) @@ -82,13 +82,13 @@ abstract enum class ProtocolState { abstract fun signal() : ProtocolState } -fun t2() { +fun t3() { val x: ProtocolState = ProtocolState.WAITING x = x.signal() - x = x.signal() + x = x.signal() //repeat for x } -fun t3() { +fun t4() { val x = 1 x += 2 val y = 3 @@ -97,7 +97,7 @@ fun t3() { z -= y } -fun t4() { +fun t5() { for (i in 0..2) { i += 1 fun t5() { @@ -119,7 +119,7 @@ class AnonymousInitializers(var a: String, val b: String) { a = "s" $b = "3" - b = "tt" + b = "tt" //repeat for b } val i: Int @@ -345,6 +345,9 @@ class M() { fun test(m : M) { m.x = 23 m.y = 23 +} + +fun test1(m : M) { m.x++ m.y-- } \ No newline at end of file diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt455.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt455.jet new file mode 100644 index 00000000000..d8d20b06265 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt455.jet @@ -0,0 +1,10 @@ +//KT-455 Do not repeat errors in definite assignment checks + +namespace kt455 + +fun foo() { + val a: Int + doSmth(a) //error + doSmth(a) //no repeat error +} +fun doSmth(i: Int) {}