KT-455 Do not repeat errors in definite assignment checks
This commit is contained in:
@@ -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]++
|
||||||
|
|||||||
+9
-6
@@ -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) {}
|
||||||
Reference in New Issue
Block a user