KT-2960 Perform control flow checks for package property initializers

#KT-2960 fixed
This commit is contained in:
Svetlana Isakova
2012-12-14 18:27:33 +04:00
parent 51c38d4cd3
commit f697098fb4
4 changed files with 49 additions and 4 deletions
@@ -69,9 +69,9 @@ public class JetControlFlowProcessor {
private Pseudocode generate(@NotNull JetDeclaration subroutine) {
builder.enterSubroutine(subroutine);
CFPVisitor cfpVisitor = new CFPVisitor(false);
if (subroutine instanceof JetDeclarationWithBody) {
JetDeclarationWithBody declarationWithBody = (JetDeclarationWithBody) subroutine;
CFPVisitor cfpVisitor = new CFPVisitor(false);
List<JetParameter> valueParameters = declarationWithBody.getValueParameters();
for (JetParameter valueParameter : valueParameters) {
valueParameter.accept(cfpVisitor);
@@ -81,8 +81,13 @@ public class JetControlFlowProcessor {
bodyExpression.accept(cfpVisitor);
}
}
else {
subroutine.accept(new CFPVisitor(false));
else if (subroutine instanceof JetProperty) {
JetExpression initializer = ((JetProperty) subroutine).getInitializer();
if (initializer != null) {
initializer.accept(cfpVisitor);
}
} else {
subroutine.accept(cfpVisitor);
}
return builder.exitSubroutine(subroutine);
}
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
@@ -74,7 +75,7 @@ public class ControlFlowAnalyzer {
private void checkClassOrObject(JetClassOrObject klass) {
// A pseudocode of class initialization corresponds to a class
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) klass, trace);
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider(klass, trace);
flowInformationProvider.markUninitializedVariables(topDownAnalysisParameters.isDeclaredLocally());
}
@@ -86,6 +87,13 @@ public class ControlFlowAnalyzer {
assert accessorDescriptor != null;
checkFunction(accessor, accessorDescriptor.getReturnType());
}
if (property.getInitializer() != null && propertyDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor) {
// check initializer's pseudocode for uninitialized values
// initializers of properties inside classes/objects are checked in 'checkClassOrObject',
// because class/object may have anonymous initialization blocks that affect analysis
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider(property, trace);
flowInformationProvider.markUninitializedVariables(false);
}
}
private void checkFunction(JetDeclarationWithBody function, final @NotNull JetType expectedReturnType) {
@@ -0,0 +1,27 @@
//KT-2960 Perform control flow checks for package property initializers
package b
class P {
var x : Int = 0
private set
}
val p = P()
var f = { -> <!INVISIBLE_SETTER!>p.x<!> = 32 }
val o = object {
fun run() {
<!INVISIBLE_SETTER!>p.x<!> = 4
val z : Int
doSmth(<!UNINITIALIZED_VARIABLE, UNINITIALIZED_VARIABLE!>z<!>)
}
}
val g = { ->
val x: Int
doSmth(<!UNINITIALIZED_VARIABLE!>x<!>)
}
fun doSmth(i: Int) = i
@@ -919,6 +919,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2845.kt");
}
@TestMetadata("kt2960.kt")
public void testKt2960() throws Exception {
doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2960.kt");
}
@TestMetadata("kt2972.kt")
public void testKt2972() throws Exception {
doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2972.kt");