KT-455 Do not repeat errors in definite assignment checks

This commit is contained in:
svtk
2011-11-08 17:33:50 +04:00
parent 1cbee4b28f
commit 24d663a08f
4 changed files with 44 additions and 13 deletions
@@ -182,6 +182,8 @@ public class JetFlowInformationProvider {
initialMapForStartInstruction, initialMapForStartInstruction,
true); true);
final Collection<VariableDescriptor> varWithUninitializedErrorGenerated = Sets.newHashSet();
final Collection<VariableDescriptor> varWithValReassignErrorGenerated = Sets.newHashSet();
traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Map<VariableDescriptor, InitializationPoints>>() { traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Map<VariableDescriptor, InitializationPoints>>() {
@Override @Override
public void execute(Instruction instruction, @Nullable Map<VariableDescriptor, InitializationPoints> enterData, @Nullable Map<VariableDescriptor, InitializationPoints> exitData) { public void execute(Instruction instruction, @Nullable Map<VariableDescriptor, InitializationPoints> enterData, @Nullable Map<VariableDescriptor, InitializationPoints> exitData) {
@@ -200,7 +202,8 @@ public class JetFlowInformationProvider {
isInitialized = true; isInitialized = true;
} }
} }
if (!analyzeLocalDeclaration && !isInitialized) { if (!analyzeLocalDeclaration && !isInitialized && !varWithUninitializedErrorGenerated.contains(variableDescriptor)) {
varWithUninitializedErrorGenerated.add(variableDescriptor);
trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, variableDescriptor)); trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, variableDescriptor));
} }
} }
@@ -222,9 +225,10 @@ public class JetFlowInformationProvider {
} }
} }
JetExpression expression = (JetExpression) element; 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); PsiElement psiElement = trace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, variableDescriptor);
JetProperty property = psiElement instanceof JetProperty ? (JetProperty) psiElement : null; 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 })); trace.report(Errors.VAL_REASSIGNMENT.on(expression, variableDescriptor, property == null ? new JetProperty[0] : new JetProperty[] { property }));
} }
if (expression instanceof JetSimpleNameExpression && inAnonymousInitializers && if (expression instanceof JetSimpleNameExpression && inAnonymousInitializers &&
@@ -12,11 +12,15 @@ class C() : B() {
this.b = 123 this.b = 123
super.b = 23 super.b = 23
<!VAL_REASSIGNMENT!>this.c<!> = 34 <!VAL_REASSIGNMENT!>this.c<!> = 34
<!VAL_REASSIGNMENT!>super.c<!> = 3535 super.c = 3535 //repeat for 'c'
<!VARIABLE_EXPECTED!>getInt()<!> = 12 <!VARIABLE_EXPECTED!>getInt()<!> = 12
} }
fun foo1(c: C) {
<!VAL_REASSIGNMENT!>super.c<!> = 34
}
fun bar(c: C) { fun bar(c: C) {
<!VARIABLE_EXPECTED!>this<!> = c //should be an error <!VARIABLE_EXPECTED!>this<!> = c //should be an error
} }
@@ -47,12 +51,16 @@ fun canBe(var i: Int, val j: Int) {
(@label i) = 34 (@label i) = 34
(<!VAL_REASSIGNMENT!>j<!>: Int) = 36 (<!VAL_REASSIGNMENT!>j<!>: Int) = 36
(@label <!VAL_REASSIGNMENT!>j<!>) = 34 (@label j) = 34 //repeat for j
val a = A() val a = A()
(@ a.a) = 3894 (@ a.a) = 3894
} }
fun canBe2(val j: Int) {
(@label <!VAL_REASSIGNMENT!>j<!>) = 34
}
class A() { class A() {
var a: Int = 3 var a: Int = 3
} }
@@ -92,9 +100,6 @@ class Test() {
(a : Int) += 34 (a : Int) += 34
<!VAL_REASSIGNMENT!>b<!> += 34 <!VAL_REASSIGNMENT!>b<!> += 34
(@l <!VAL_REASSIGNMENT!>b<!>) += 34
(<!VAL_REASSIGNMENT!>b<!> : Int) += 34
(<!VAL_REASSIGNMENT!>b<!>) += 3
a++ a++
(@ a)++ (@ a)++
@@ -102,6 +107,15 @@ class Test() {
(a)++ (a)++
} }
fun testVariables1() {
val b: Int = 34
(@l <!VAL_REASSIGNMENT!>b<!>) += 34
//repeat for b
(b : Int) += 34
(b) += 3
}
fun testArrays(a: Array<Int>, ab: Ab) { fun testArrays(a: Array<Int>, ab: Ab) {
a[3] = 4 a[3] = 4
a[4]++ a[4]++
@@ -30,7 +30,7 @@ fun t1(b : Boolean) {
doSmth(<!UNINITIALIZED_VARIABLE!>t<!>) doSmth(<!UNINITIALIZED_VARIABLE!>t<!>)
else else
t = "ss" t = "ss"
doSmth(<!UNINITIALIZED_VARIABLE!>t<!>) doSmth(t) //repeat for t
val i = 3 val i = 3
doSmth(i) doSmth(i)
@@ -82,13 +82,13 @@ abstract enum class ProtocolState {
abstract fun signal() : ProtocolState abstract fun signal() : ProtocolState
} }
fun t2() { fun t3() {
val x: ProtocolState = ProtocolState.WAITING val x: ProtocolState = ProtocolState.WAITING
<!VAL_REASSIGNMENT!>x<!> = x.signal() <!VAL_REASSIGNMENT!>x<!> = x.signal()
<!VAL_REASSIGNMENT!>x<!> = x.signal() x = x.signal() //repeat for x
} }
fun t3() { fun t4() {
val x = 1 val x = 1
<!VAL_REASSIGNMENT!>x<!> += 2 <!VAL_REASSIGNMENT!>x<!> += 2
val y = 3 val y = 3
@@ -97,7 +97,7 @@ fun t3() {
z -= y z -= y
} }
fun t4() { fun t5() {
for (i in 0..2) { for (i in 0..2) {
<!VAL_REASSIGNMENT!>i<!> += 1 <!VAL_REASSIGNMENT!>i<!> += 1
fun t5() { fun t5() {
@@ -119,7 +119,7 @@ class AnonymousInitializers(var a: String, val b: String) {
a = "s" a = "s"
<!VAL_REASSIGNMENT!>$b<!> = "3" <!VAL_REASSIGNMENT!>$b<!> = "3"
<!VAL_REASSIGNMENT!>b<!> = "tt" b = "tt" //repeat for b
} }
val i: Int val i: Int
@@ -345,6 +345,9 @@ class M() {
fun test(m : M) { fun test(m : M) {
<!VAL_REASSIGNMENT!>m.x<!> = 23 <!VAL_REASSIGNMENT!>m.x<!> = 23
m.y = 23 m.y = 23
}
fun test1(m : M) {
<!VAL_REASSIGNMENT!>m.x<!>++ <!VAL_REASSIGNMENT!>m.x<!>++
m.y-- m.y--
} }
@@ -0,0 +1,10 @@
//KT-455 Do not repeat errors in definite assignment checks
namespace kt455
fun foo() {
val a: Int
doSmth(<!UNINITIALIZED_VARIABLE!>a<!>) //error
doSmth(a) //no repeat error
}
fun doSmth(i: Int) {}