From eab7fdf4bc5e0b0ddb99700c72aa7db69308b1a7 Mon Sep 17 00:00:00 2001 From: svtk Date: Tue, 1 Nov 2011 18:54:33 +0400 Subject: [PATCH] Added information about anonymous initializers to cfg & proper checks --- .../jet/lang/cfg/JetControlFlowProcessor.java | 15 +++++++ .../jet/lang/resolve/ControlFlowAnalyzer.java | 18 +++++--- .../cfg/AnonymousInitializers.instructions | 41 +++++++++++++++++++ .../testData/cfg/AnonymousInitializers.jet | 15 +++++++ .../testData/cfg/Assignments.instructions | 12 ++++++ .../jetbrains/jet/cfg/JetControlFlowTest.java | 17 ++++++-- 6 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 compiler/testData/cfg/AnonymousInitializers.instructions create mode 100644 compiler/testData/cfg/AnonymousInitializers.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index b2f14f97964..fa05e1cd24f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -781,6 +781,21 @@ public class JetControlFlowProcessor { // TODO : Support Type Arguments. Class object may be initialized at this point"); } + @Override + public void visitAnonymousInitializer(JetClassInitializer classInitializer) { + classInitializer.getBody().accept(this); + } + + @Override + public void visitClass(JetClass klass) { + List declarations = klass.getDeclarations(); + for (JetDeclaration declaration : declarations) { + if (declaration instanceof JetProperty || declaration instanceof JetClassInitializer) { + declaration.accept(this); + } + } + } + @Override public void visitJetElement(JetElement element) { builder.unsupported(element); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java index fbea9ad37d4..e4fad9c4fd8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java @@ -4,9 +4,7 @@ import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; -import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptorImpl; +import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetStandardClasses; @@ -14,6 +12,7 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lexer.JetTokens; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -38,6 +37,11 @@ public class ControlFlowAnalyzer { } public void process() { + for (Map.Entry entry : context.getClasses().entrySet()) { + JetClass aClass = entry.getKey(); + MutableClassDescriptor classDescriptor = entry.getValue(); + checkClass(aClass, classDescriptor); + } for (Map.Entry entry : context.getFunctions().entrySet()) { JetNamedFunction function = entry.getKey(); FunctionDescriptorImpl functionDescriptor = entry.getValue(); @@ -61,6 +65,11 @@ public class ControlFlowAnalyzer { checkProperty(property); } } + + private void checkClass(JetClass klass, MutableClassDescriptor classDescriptor) { + JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider(klass, klass, flowDataTraceFactory, context.getTrace()); + flowInformationProvider.markUninitializedVariables(klass, true); + } private void checkFunction(JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, final @NotNull JetType expectedReturnType) { assert function instanceof JetDeclaration; @@ -114,8 +123,7 @@ public class ControlFlowAnalyzer { }); } if (!declaredLocally) { - flowInformationProvider.markUninitializedVariables(function.asElement(), functionDescriptor.getValueParameters()); - + flowInformationProvider.markUninitializedVariables(function.asElement(), false); if (((JetDeclaration) function).hasModifier(JetTokens.INLINE_KEYWORD)) { //inline functions after M1 // flowInformationProvider.markNotOnlyInvokedFunctionVariables(function.asElement(), functionDescriptor.getValueParameters()); diff --git a/compiler/testData/cfg/AnonymousInitializers.instructions b/compiler/testData/cfg/AnonymousInitializers.instructions new file mode 100644 index 00000000000..218e35049b6 --- /dev/null +++ b/compiler/testData/cfg/AnonymousInitializers.instructions @@ -0,0 +1,41 @@ +== AnonymousInitializers == +class AnonymousInitializers() { + val k = 34 + + val i: Int + { + $i = 12 + } + + val j: Int + get() = 20 + + { + $i = 13 + } +} +--------------------- +l0: + NEXT:[r(34)] PREV:[] + r(34) NEXT:[w(k)] PREV:[] + w(k) NEXT:[r(12)] PREV:[r(34)] + r(12) NEXT:[w($i)] PREV:[w(k)] + w($i) NEXT:[r(13)] PREV:[r(12)] + r(13) NEXT:[w($i)] PREV:[w($i)] + w($i) NEXT:[] PREV:[r(13)] +l1: + NEXT:[] PREV:[w($i)] +error: + NEXT:[] PREV:[] +===================== +== k == +val k = 34 +--------------------- +l0: + NEXT:[r(34)] PREV:[] + r(34) NEXT:[] PREV:[] +l1: + NEXT:[] PREV:[r(34)] +error: + NEXT:[] PREV:[] +===================== diff --git a/compiler/testData/cfg/AnonymousInitializers.jet b/compiler/testData/cfg/AnonymousInitializers.jet new file mode 100644 index 00000000000..7971b9991a8 --- /dev/null +++ b/compiler/testData/cfg/AnonymousInitializers.jet @@ -0,0 +1,15 @@ +class AnonymousInitializers() { + val k = 34 + + val i: Int + { + $i = 12 + } + + val j: Int + get() = 20 + + { + $i = 13 + } +} \ No newline at end of file diff --git a/compiler/testData/cfg/Assignments.instructions b/compiler/testData/cfg/Assignments.instructions index 671c6729d14..a0adbac1a3c 100644 --- a/compiler/testData/cfg/Assignments.instructions +++ b/compiler/testData/cfg/Assignments.instructions @@ -1,3 +1,15 @@ +== Test == +class Test { + var x : Int; +} +--------------------- +l0: + NEXT:[] PREV:[] +l1: + NEXT:[] PREV:[] +error: + NEXT:[] PREV:[] +===================== == assignments == fun assignments() : Unit { var x = 1 diff --git a/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java b/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java index 77dda242a64..9f67398d6ba 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java +++ b/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java @@ -32,7 +32,12 @@ public class JetControlFlowTest extends JetLiteFixture { super(dataPath); myName = name; } - + + @Override + public String getName() { + return "test" + myName; + } + protected String getTestFilePath() { return myFullDataPath + "/" + myName; } @@ -94,15 +99,19 @@ public class JetControlFlowTest extends JetLiteFixture { int i = 0; for (Pseudocode pseudocode : pseudocodes) { JetElement correspondingElement = pseudocode.getCorrespondingElement(); - String label; - assert correspondingElement instanceof JetNamedDeclaration; + String label = ""; + assert (correspondingElement instanceof JetNamedDeclaration || correspondingElement instanceof JetConstructor) : + "Unexpected element class is pseudocode: " + correspondingElement.getClass(); if (correspondingElement instanceof JetFunctionLiteral) { label = "anonymous_" + i++; } - else { + else if (correspondingElement instanceof JetNamedDeclaration) { JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) correspondingElement; label = namedDeclaration.getName(); } + else { + label = "this"; + } instructionDump.append("== ").append(label).append(" ==\n");