KT-2960 Perform control flow checks for package property initializers
#KT-2960 fixed
This commit is contained in:
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user