diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java index 5e898189e78..4aa5f3d200a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java @@ -311,6 +311,12 @@ public class PseudocodeVariablesData { private static VariableInitState create(boolean isDeclaredHere, @Nullable VariableInitState mergedEdgesData) { return create(true, isDeclaredHere || (mergedEdgesData != null && mergedEdgesData.isDeclared)); } + + @Override + public String toString() { + if (!isInitialized && !isDeclared) return "-"; + return (isInitialized ? "I" : "") + (isDeclared ? "D" : ""); + } } public static enum VariableUseState { diff --git a/compiler/testData/cfg-variables/basic/IfWithUninitialized.instructions b/compiler/testData/cfg-variables/basic/IfWithUninitialized.instructions new file mode 100644 index 00000000000..409fa783f68 --- /dev/null +++ b/compiler/testData/cfg-variables/basic/IfWithUninitialized.instructions @@ -0,0 +1,53 @@ +== foo == +fun foo() { + val b: Boolean + if (1 < 2) { + use(b) + } + else { + b = true + } +} +--------------------- +L0: + INIT: in: {} out: {} + mark({ val b: Boolean if (1 < 2) { use(b) } else { b = true } }) + v(val b: Boolean) INIT: in: {} out: {b=D} + mark(if (1 < 2) { use(b) } else { b = true }) INIT: in: {b=D} out: {b=D} + mark(1 < 2) + r(1) + r(2) + call(<, compareTo) + jf(L2) + mark({ use(b) }) + mark(use(b)) USE: in: {b=READ} out: {b=READ} + r(b) USE: in: {} out: {b=READ} + call(use, use) + jmp(L3) USE: in: {} out: {} +L2: + mark({ b = true }) + r(true) USE: in: {b=ONLY_WRITTEN_NEVER_READ} out: {b=ONLY_WRITTEN_NEVER_READ} + w(b) INIT: in: {b=D} out: {b=ID} USE: in: {} out: {b=ONLY_WRITTEN_NEVER_READ} +L1: +L3: + INIT: in: {b=D} out: {b=D} +error: + INIT: in: {} out: {} +sink: + INIT: in: {b=D} out: {b=D} USE: in: {} out: {} +===================== +== use == +fun use(vararg a: Any?) = a +--------------------- +L0: + INIT: in: {} out: {} + v(vararg a: Any?) INIT: in: {} out: {a=D} + w(a) INIT: in: {a=D} out: {a=ID} USE: in: {a=READ} out: {a=READ} + r(a) INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {a=READ} +L1: + +error: + INIT: in: {} out: {} +sink: + INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {} +===================== diff --git a/compiler/testData/cfg-variables/basic/IfWithUninitialized.kt b/compiler/testData/cfg-variables/basic/IfWithUninitialized.kt new file mode 100644 index 00000000000..1d749efb75b --- /dev/null +++ b/compiler/testData/cfg-variables/basic/IfWithUninitialized.kt @@ -0,0 +1,11 @@ +fun foo() { + val b: Boolean + if (1 < 2) { + use(b) + } + else { + b = true + } +} + +fun use(vararg a: Any?) = a diff --git a/compiler/testData/cfg-variables/basic/InitializedNotDeclared.instructions b/compiler/testData/cfg-variables/basic/InitializedNotDeclared.instructions new file mode 100644 index 00000000000..bf2cfbe26d7 --- /dev/null +++ b/compiler/testData/cfg-variables/basic/InitializedNotDeclared.instructions @@ -0,0 +1,21 @@ +== A == +class A { + { + x = 1 + } + val x: Int +} +--------------------- +L0: + INIT: in: {} out: {} + mark({ x = 1 }) + r(1) USE: in: {x=ONLY_WRITTEN_NEVER_READ} out: {x=ONLY_WRITTEN_NEVER_READ} + w(x) INIT: in: {} out: {x=I} USE: in: {} out: {x=ONLY_WRITTEN_NEVER_READ} + v(val x: Int) INIT: in: {x=I} out: {x=ID} +L1: + INIT: in: {x=ID} out: {x=ID} +error: + INIT: in: {} out: {} +sink: + INIT: in: {x=ID} out: {x=ID} USE: in: {} out: {} +===================== diff --git a/compiler/testData/cfg-variables/basic/InitializedNotDeclared.kt b/compiler/testData/cfg-variables/basic/InitializedNotDeclared.kt new file mode 100644 index 00000000000..84574bdd4a6 --- /dev/null +++ b/compiler/testData/cfg-variables/basic/InitializedNotDeclared.kt @@ -0,0 +1,6 @@ +class A { + { + x = 1 + } + val x: Int +} \ No newline at end of file diff --git a/compiler/testData/cfg-variables/basic/UsageInFunctionLiteral.instructions b/compiler/testData/cfg-variables/basic/UsageInFunctionLiteral.instructions new file mode 100644 index 00000000000..17e4152581e --- /dev/null +++ b/compiler/testData/cfg-variables/basic/UsageInFunctionLiteral.instructions @@ -0,0 +1,71 @@ +== foo == +fun foo() { + val a = 1 + val f = { (x: Int) -> + val y = x + a + use(a) + } +} +--------------------- +L0: + INIT: in: {} out: {} + mark({ val a = 1 val f = { (x: Int) -> val y = x + a use(a) } }) + v(val a = 1) INIT: in: {} out: {a=D} + r(1) INIT: in: {a=D} out: {a=D} + w(a) INIT: in: {a=D} out: {a=ID} + v(val f = { (x: Int) -> val y = x + a use(a) }) INIT: in: {a=ID} out: {a=ID, f=D} + mark({ (x: Int) -> val y = x + a use(a) }) INIT: in: {a=ID, f=D} out: {a=ID, f=D} + jmp?(L2) + d({ (x: Int) -> val y = x + a use(a) }) INIT: in: {a=ID, f=D, x=ID, y=ID} out: {a=ID, f=D, x=ID, y=ID} USE: in: {a=READ, x=READ} out: {a=READ, x=READ} +L2: + r({ (x: Int) -> val y = x + a use(a) }) INIT: in: {a=ID, f=D} out: {a=ID, f=D} + w(f) INIT: in: {a=ID, f=D} out: {a=ID, f=ID} +L1: + INIT: in: {a=ID, f=ID} out: {a=ID, f=ID} +error: + INIT: in: {} out: {} +sink: + INIT: in: {a=ID, f=D, x=ID, y=ID} out: {a=ID, f=D, x=ID, y=ID} USE: in: {} out: {} +===================== +== anonymous_0 == +{ (x: Int) -> + val y = x + a + use(a) + } +--------------------- +L3: + INIT: in: {} out: {} + v(x: Int) INIT: in: {} out: {x=D} + w(x) INIT: in: {x=D} out: {x=ID} + mark(val y = x + a use(a)) INIT: in: {x=ID} out: {x=ID} + v(val y = x + a) INIT: in: {x=ID} out: {x=ID, y=D} + mark(x + a) INIT: in: {x=ID, y=D} out: {x=ID, y=D} USE: in: {a=READ, x=READ} out: {a=READ, x=READ} + r(x) USE: in: {a=READ} out: {a=READ, x=READ} + r(a) + call(+, plus) + w(y) INIT: in: {x=ID, y=D} out: {x=ID, y=ID} + mark(use(a)) INIT: in: {x=ID, y=ID} out: {x=ID, y=ID} USE: in: {a=READ} out: {a=READ} + r(a) USE: in: {} out: {a=READ} + call(use, use) +L4: + +error: + INIT: in: {} out: {} +sink: + INIT: in: {x=ID, y=ID} out: {x=ID, y=ID} USE: in: {} out: {} +===================== +== use == +fun use(vararg a: Any?) = a +--------------------- +L0: + INIT: in: {} out: {} + v(vararg a: Any?) INIT: in: {} out: {a=D} + w(a) INIT: in: {a=D} out: {a=ID} USE: in: {a=READ} out: {a=READ} + r(a) INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {a=READ} +L1: + +error: + INIT: in: {} out: {} +sink: + INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {} +===================== diff --git a/compiler/testData/cfg-variables/basic/UsageInFunctionLiteral.kt b/compiler/testData/cfg-variables/basic/UsageInFunctionLiteral.kt new file mode 100644 index 00000000000..893b0287bb9 --- /dev/null +++ b/compiler/testData/cfg-variables/basic/UsageInFunctionLiteral.kt @@ -0,0 +1,9 @@ +fun foo() { + val a = 1 + val f = { (x: Int) -> + val y = x + a + use(a) + } +} + +fun use(vararg a: Any?) = a \ No newline at end of file diff --git a/compiler/testData/cfg-variables/basic/VariablesInitialization.instructions b/compiler/testData/cfg-variables/basic/VariablesInitialization.instructions new file mode 100644 index 00000000000..088e88a134a --- /dev/null +++ b/compiler/testData/cfg-variables/basic/VariablesInitialization.instructions @@ -0,0 +1,66 @@ +== foo == +fun foo() { + val a = 1 + val b: Int + b = 2 + 42 +} +--------------------- +L0: + INIT: in: {} out: {} + mark({ val a = 1 val b: Int b = 2 42 }) + v(val a = 1) INIT: in: {} out: {a=D} + r(1) INIT: in: {a=D} out: {a=D} + w(a) INIT: in: {a=D} out: {a=ID} + v(val b: Int) INIT: in: {a=ID} out: {a=ID, b=D} + r(2) INIT: in: {a=ID, b=D} out: {a=ID, b=D} USE: in: {b=ONLY_WRITTEN_NEVER_READ} out: {b=ONLY_WRITTEN_NEVER_READ} + w(b) INIT: in: {a=ID, b=D} out: {a=ID, b=ID} USE: in: {} out: {b=ONLY_WRITTEN_NEVER_READ} + r(42) INIT: in: {a=ID, b=ID} out: {a=ID, b=ID} +L1: + +error: + INIT: in: {} out: {} +sink: + INIT: in: {a=ID, b=ID} out: {a=ID, b=ID} USE: in: {} out: {} +===================== +== bar == +fun bar(foo: Foo) { + foo.c + foo.c = 2 + 42 +} +--------------------- +L0: + INIT: in: {} out: {} + v(foo: Foo) INIT: in: {} out: {foo=D} + w(foo) INIT: in: {foo=D} out: {foo=ID} + mark({ foo.c foo.c = 2 42 }) INIT: in: {foo=ID} out: {foo=ID} + mark(foo.c) + r(foo) USE: in: {c=READ, foo=READ} out: {c=READ, foo=READ} + r(c) USE: in: {c=ONLY_WRITTEN_NEVER_READ, foo=READ} out: {c=READ, foo=READ} + r(2) USE: in: {c=ONLY_WRITTEN_NEVER_READ, foo=READ} out: {c=ONLY_WRITTEN_NEVER_READ, foo=READ} + r(foo) USE: in: {c=ONLY_WRITTEN_NEVER_READ} out: {c=ONLY_WRITTEN_NEVER_READ, foo=READ} + w(foo.c) INIT: in: {foo=ID} out: {c=I, foo=ID} USE: in: {} out: {c=ONLY_WRITTEN_NEVER_READ} + r(42) INIT: in: {c=I, foo=ID} out: {c=I, foo=ID} +L1: + +error: + INIT: in: {} out: {} +sink: + INIT: in: {c=I, foo=ID} out: {c=I, foo=ID} USE: in: {} out: {} +===================== +== Foo == +trait Foo { + var c: Int +} +--------------------- +L0: + INIT: in: {} out: {} + v(var c: Int) INIT: in: {} out: {c=D} +L1: + INIT: in: {c=D} out: {c=D} +error: + INIT: in: {} out: {} +sink: + INIT: in: {c=D} out: {c=D} USE: in: {} out: {} +===================== diff --git a/compiler/testData/cfg-variables/basic/VariablesInitialization.kt b/compiler/testData/cfg-variables/basic/VariablesInitialization.kt new file mode 100644 index 00000000000..ae78a8a15e1 --- /dev/null +++ b/compiler/testData/cfg-variables/basic/VariablesInitialization.kt @@ -0,0 +1,16 @@ +fun foo() { + val a = 1 + val b: Int + b = 2 + 42 +} + +fun bar(foo: Foo) { + foo.c + foo.c = 2 + 42 +} + +trait Foo { + var c: Int +} \ No newline at end of file diff --git a/compiler/testData/cfg-variables/basic/VariablesUsage.instructions b/compiler/testData/cfg-variables/basic/VariablesUsage.instructions new file mode 100644 index 00000000000..d4c3fb9c635 --- /dev/null +++ b/compiler/testData/cfg-variables/basic/VariablesUsage.instructions @@ -0,0 +1,63 @@ +== foo == +fun foo() { + var a = 1 + use(a) + a = 2 + use(a) +} +--------------------- +L0: + INIT: in: {} out: {} + mark({ var a = 1 use(a) a = 2 use(a) }) + v(var a = 1) INIT: in: {} out: {a=D} + r(1) INIT: in: {a=D} out: {a=D} + w(a) INIT: in: {a=D} out: {a=ID} + mark(use(a)) INIT: in: {a=ID} out: {a=ID} USE: in: {a=READ} out: {a=READ} + r(a) USE: in: {a=WRITTEN_AFTER_READ} out: {a=READ} + call(use, use) + r(2) USE: in: {a=WRITTEN_AFTER_READ} out: {a=WRITTEN_AFTER_READ} + w(a) USE: in: {a=READ} out: {a=WRITTEN_AFTER_READ} + mark(use(a)) USE: in: {a=READ} out: {a=READ} + r(a) USE: in: {} out: {a=READ} + call(use, use) +L1: + +error: + INIT: in: {} out: {} +sink: + INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {} +===================== +== bar == +fun bar() { + val b: Int + b = 3 +} +--------------------- +L0: + INIT: in: {} out: {} + mark({ val b: Int b = 3 }) + v(val b: Int) INIT: in: {} out: {b=D} + r(3) INIT: in: {b=D} out: {b=D} USE: in: {b=ONLY_WRITTEN_NEVER_READ} out: {b=ONLY_WRITTEN_NEVER_READ} + w(b) INIT: in: {b=D} out: {b=ID} USE: in: {} out: {b=ONLY_WRITTEN_NEVER_READ} +L1: + INIT: in: {b=ID} out: {b=ID} +error: + INIT: in: {} out: {} +sink: + INIT: in: {b=ID} out: {b=ID} USE: in: {} out: {} +===================== +== use == +fun use(a: Int) = a +--------------------- +L0: + INIT: in: {} out: {} + v(a: Int) INIT: in: {} out: {a=D} + w(a) INIT: in: {a=D} out: {a=ID} USE: in: {a=READ} out: {a=READ} + r(a) INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {a=READ} +L1: + +error: + INIT: in: {} out: {} +sink: + INIT: in: {a=ID} out: {a=ID} USE: in: {} out: {} +===================== diff --git a/compiler/testData/cfg-variables/basic/VariablesUsage.kt b/compiler/testData/cfg-variables/basic/VariablesUsage.kt new file mode 100644 index 00000000000..149f7039beb --- /dev/null +++ b/compiler/testData/cfg-variables/basic/VariablesUsage.kt @@ -0,0 +1,13 @@ +fun foo() { + var a = 1 + use(a) + a = 2 + use(a) +} + +fun bar() { + val b: Int + b = 3 +} + +fun use(a: Int) = a \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/cfg/AbstractControlFlowTest.java b/compiler/tests/org/jetbrains/jet/cfg/AbstractControlFlowTest.java index 2169111c5ae..4a9fcfd5904 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/AbstractControlFlowTest.java +++ b/compiler/tests/org/jetbrains/jet/cfg/AbstractControlFlowTest.java @@ -16,21 +16,24 @@ package org.jetbrains.jet.cfg; -import com.google.common.collect.Sets; -import kotlin.Function1; import kotlin.Function3; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.cfg.pseudocode.Instruction; import org.jetbrains.jet.lang.cfg.pseudocode.InstructionImpl; import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeImpl; +import org.jetbrains.jet.lang.resolve.BindingContext; import java.util.*; public abstract class AbstractControlFlowTest extends AbstractPseudocodeTest { @Override - protected void dumpInstructions(PseudocodeImpl pseudocode, @NotNull StringBuilder out) { + protected void dumpInstructions( + @NotNull PseudocodeImpl pseudocode, + @NotNull StringBuilder out, + @NotNull BindingContext bindingContext + ) { final int nextInstructionsColumnWidth = countNextInstructionsColumnWidth(pseudocode.getAllInstructions()); dumpInstructions(pseudocode, out, new Function3() { diff --git a/compiler/tests/org/jetbrains/jet/cfg/AbstractDataFlowTest.java b/compiler/tests/org/jetbrains/jet/cfg/AbstractDataFlowTest.java new file mode 100644 index 00000000000..ccbf36af0fe --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/cfg/AbstractDataFlowTest.java @@ -0,0 +1,110 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.cfg; + +import com.google.common.collect.Lists; +import com.intellij.openapi.util.text.StringUtil; +import kotlin.Function3; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData; +import org.jetbrains.jet.lang.cfg.pseudocode.Instruction; +import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeImpl; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.resolve.BindingContext; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static org.jetbrains.jet.lang.cfg.PseudocodeTraverser.Edges; +import static org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableInitState; +import static org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState; + +public abstract class AbstractDataFlowTest extends AbstractPseudocodeTest { + + @Override + public void dumpInstructions( + @NotNull PseudocodeImpl pseudocode, + @NotNull StringBuilder out, + @NotNull BindingContext bindingContext + ) { + PseudocodeVariablesData pseudocodeVariablesData = new PseudocodeVariablesData(pseudocode, bindingContext); + final Map>> variableInitializers = + pseudocodeVariablesData.getVariableInitializers(); + final Map>> useStatusData = + pseudocodeVariablesData.getVariableUseStatusData(); + final String initPrefix = " INIT:"; + final String usePrefix = " USE:"; + final int initializersColumnWidth = countDataColumnWidth(initPrefix, pseudocode.getAllInstructions(), variableInitializers); + + dumpInstructions(pseudocode, out, new Function3() { + @Override + public String invoke(Instruction instruction, Instruction next, Instruction prev) { + StringBuilder result = new StringBuilder(); + Edges> initializersEdges = variableInitializers.get(instruction); + Edges> previousInitializersEdges = variableInitializers.get(prev); + String initializersData = ""; + if (initializersEdges != null && !initializersEdges.equals(previousInitializersEdges)) { + initializersData = dumpEdgesData(initPrefix, initializersEdges); + } + result.append(String.format("%1$-" + initializersColumnWidth + "s", initializersData)); + + Edges> useStatusEdges = useStatusData.get(instruction); + Edges> nextUseStatusEdges = useStatusData.get(next); + if (useStatusEdges != null && !useStatusEdges.equals(nextUseStatusEdges)) { + result.append(dumpEdgesData(usePrefix, useStatusEdges)); + } + return result.toString(); + } + }); + } + + private int countDataColumnWidth( + @NotNull String prefix, + @NotNull List instructions, + @NotNull Map>> data + ) { + int maxWidth = 0; + for (Instruction instruction : instructions) { + Edges> edges = data.get(instruction); + if (edges == null) continue; + int length = dumpEdgesData(prefix, edges).length(); + if (maxWidth < length) { + maxWidth = length; + } + } + return maxWidth; + } + + @NotNull + private String dumpEdgesData(String prefix, @NotNull Edges> edges) { + return prefix + + " in: " + renderVariableMap(edges.in) + + " out: " + renderVariableMap(edges.out); + } + + private String renderVariableMap(Map map) { + List result = Lists.newArrayList(); + for (Map.Entry entry : map.entrySet()) { + VariableDescriptor variable = entry.getKey(); + D data = entry.getValue(); + result.add(variable.getName() + "=" + data); + } + Collections.sort(result); + return "{" + StringUtil.join(result, ", ") + "}"; + } +} diff --git a/compiler/tests/org/jetbrains/jet/cfg/AbstractPseudocodeTest.java b/compiler/tests/org/jetbrains/jet/cfg/AbstractPseudocodeTest.java index 9905d3a05e5..922f69c3c51 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/AbstractPseudocodeTest.java +++ b/compiler/tests/org/jetbrains/jet/cfg/AbstractPseudocodeTest.java @@ -65,7 +65,7 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironment { } try { - processCFData(file, data); + processCFData(file, data, bindingContext); } catch (IOException e) { throw new RuntimeException(e); @@ -86,7 +86,7 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironment { } } - private void processCFData(File file, Map data) throws IOException { + private void processCFData(File file, Map data, BindingContext bindingContext) throws IOException { Collection pseudocodes = data.values(); StringBuilder instructionDump = new StringBuilder(); @@ -113,7 +113,7 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironment { instructionDump.append(correspondingElement.getText()); instructionDump.append("\n---------------------\n"); - dumpInstructions((PseudocodeImpl) pseudocode, instructionDump); + dumpInstructions((PseudocodeImpl) pseudocode, instructionDump, bindingContext); instructionDump.append("=====================\n"); checkPseudocode((PseudocodeImpl) pseudocode); } @@ -142,7 +142,11 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironment { return sb.toString(); } - protected abstract void dumpInstructions(PseudocodeImpl pseudocode, @NotNull StringBuilder out); + protected abstract void dumpInstructions( + @NotNull PseudocodeImpl pseudocode, + @NotNull StringBuilder out, + @NotNull BindingContext bindingContext + ); protected void dumpInstructions( @NotNull PseudocodeImpl pseudocode, diff --git a/compiler/tests/org/jetbrains/jet/cfg/DataFlowTestGenerated.java b/compiler/tests/org/jetbrains/jet/cfg/DataFlowTestGenerated.java new file mode 100644 index 00000000000..ce71735dc1b --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/cfg/DataFlowTestGenerated.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.cfg; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.cfg.AbstractDataFlowTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/cfg-variables") +@InnerTestClasses({DataFlowTestGenerated.Basic.class}) +public class DataFlowTestGenerated extends AbstractDataFlowTest { + public void testAllFilesPresentInCfg_variables() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/cfg-variables"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("compiler/testData/cfg-variables/basic") + public static class Basic extends AbstractDataFlowTest { + public void testAllFilesPresentInBasic() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/cfg-variables/basic"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("IfWithUninitialized.kt") + public void testIfWithUninitialized() throws Exception { + doTest("compiler/testData/cfg-variables/basic/IfWithUninitialized.kt"); + } + + @TestMetadata("InitializedNotDeclared.kt") + public void testInitializedNotDeclared() throws Exception { + doTest("compiler/testData/cfg-variables/basic/InitializedNotDeclared.kt"); + } + + @TestMetadata("UsageInFunctionLiteral.kt") + public void testUsageInFunctionLiteral() throws Exception { + doTest("compiler/testData/cfg-variables/basic/UsageInFunctionLiteral.kt"); + } + + @TestMetadata("VariablesInitialization.kt") + public void testVariablesInitialization() throws Exception { + doTest("compiler/testData/cfg-variables/basic/VariablesInitialization.kt"); + } + + @TestMetadata("VariablesUsage.kt") + public void testVariablesUsage() throws Exception { + doTest("compiler/testData/cfg-variables/basic/VariablesUsage.kt"); + } + + } + + public static Test suite() { + TestSuite suite = new TestSuite("DataFlowTestGenerated"); + suite.addTestSuite(DataFlowTestGenerated.class); + suite.addTestSuite(Basic.class); + return suite; + } +} diff --git a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt index 78fe3adbae0..60d0e3b475a 100644 --- a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt @@ -97,6 +97,7 @@ import org.jetbrains.jet.resolve.AbstractReferenceToJavaWithWrongFileStructureTe import org.jetbrains.jet.plugin.navigation.AbstractKotlinGotoTest import org.jetbrains.jet.plugin.AbstractExpressionSelectionTest import org.jetbrains.jet.plugin.refactoring.move.AbstractJetMoveTest +import org.jetbrains.jet.cfg.AbstractDataFlowTest import org.jetbrains.jet.plugin.libraries.AbstractDecompiledTextTest import org.jetbrains.jet.plugin.imports.AbstractOptimizeImportsTest @@ -237,6 +238,10 @@ fun main(args: Array) { model("cfg") } + testClass(javaClass()) { + model("cfg-variables") + } + testClass(javaClass()) { model("resolveAnnotations/parameters") }