diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplCodeAnalyzer.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplCodeAnalyzer.kt index 5484c14a8e3..3d4ad6d5ea3 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplCodeAnalyzer.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/repl/ReplCodeAnalyzer.kt @@ -73,7 +73,7 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) { this.scriptDeclarationFactory = container.get() this.resolveSession = container.get() this.topDownAnalysisContext = TopDownAnalysisContext( - TopDownAnalysisMode.LocalDeclarations, DataFlowInfoFactory.EMPTY, resolveSession.declarationScopeProvider + TopDownAnalysisMode.TopLevelDeclarations, DataFlowInfoFactory.EMPTY, resolveSession.declarationScopeProvider ) this.topDownAnalyzer = container.get() } diff --git a/compiler/testData/repl/controlFlow/functionWithoutReturn.repl b/compiler/testData/repl/controlFlow/functionWithoutReturn.repl new file mode 100644 index 00000000000..166f203c3e6 --- /dev/null +++ b/compiler/testData/repl/controlFlow/functionWithoutReturn.repl @@ -0,0 +1,4 @@ +>>> fun fn(): Int {} +error: a 'return' expression required in a function with a block body ('{...}') +fun fn(): Int {} + ^ diff --git a/compiler/testData/repl/controlFlow/incompleteIf.repl b/compiler/testData/repl/controlFlow/incompleteIf.repl new file mode 100644 index 00000000000..aa8d137934d --- /dev/null +++ b/compiler/testData/repl/controlFlow/incompleteIf.repl @@ -0,0 +1,6 @@ +>>> if (false) 42 +>>> if (true) 42 +>>> "" + (if (true) 42) +error: 'if' must have both main and 'else' branches if used as an expression +"" + (if (true) 42) + ^ diff --git a/compiler/testData/repl/controlFlow/incompleteWhen.repl b/compiler/testData/repl/controlFlow/incompleteWhen.repl new file mode 100644 index 00000000000..6a40f55fcda --- /dev/null +++ b/compiler/testData/repl/controlFlow/incompleteWhen.repl @@ -0,0 +1,11 @@ +>>> val a = when(null) { } +error: 'when' expression must be exhaustive, add necessary 'else' branch +val a = when(null) { } + ^ +warning: the expression is unused +val a = when(null) { } + ^ +>>> "" + when (true) { true -> 42 } +error: 'when' expression must be exhaustive, add necessary 'false' branch or 'else' branch instead +"" + when (true) { true -> 42 } + ^ diff --git a/compiler/testData/repl/controlFlow/loopWithWrongLabel.repl b/compiler/testData/repl/controlFlow/loopWithWrongLabel.repl new file mode 100644 index 00000000000..f9adb6558a5 --- /dev/null +++ b/compiler/testData/repl/controlFlow/loopWithWrongLabel.repl @@ -0,0 +1,4 @@ +>>> for (n in 1..10) foo@ { break@foo } +error: the label '@foo' does not denote a loop +for (n in 1..10) foo@ { break@foo } + ^ diff --git a/compiler/testData/repl/controlFlow/mutateVal.repl b/compiler/testData/repl/controlFlow/mutateVal.repl new file mode 100644 index 00000000000..d3c50413738 --- /dev/null +++ b/compiler/testData/repl/controlFlow/mutateVal.repl @@ -0,0 +1,11 @@ +>>> val x = 1 +>>> x = 2 +error: val cannot be reassigned +x = 2 +^ +>>> x++ +error: val cannot be reassigned +x++ +^ +>>> x +1 diff --git a/compiler/testData/repl/controlFlow/useUninitializedVal.repl b/compiler/testData/repl/controlFlow/useUninitializedVal.repl new file mode 100644 index 00000000000..d644dedfa21 --- /dev/null +++ b/compiler/testData/repl/controlFlow/useUninitializedVal.repl @@ -0,0 +1,12 @@ +>>> val a: String +error: property must be initialized or be abstract +val a: String +^ +>>> a +error: unresolved reference: a +a +^ +>>> val s: String = s +error: variable 's' must be initialized +val s: String = s + ^ diff --git a/compiler/tests/org/jetbrains/kotlin/repl/ReplInterpreterTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/repl/ReplInterpreterTestGenerated.java index adccff222b1..07606bf6522 100644 --- a/compiler/tests/org/jetbrains/kotlin/repl/ReplInterpreterTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/repl/ReplInterpreterTestGenerated.java @@ -213,6 +213,51 @@ public class ReplInterpreterTestGenerated extends AbstractReplInterpreterTest { } } + @TestMetadata("compiler/testData/repl/controlFlow") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ControlFlow extends AbstractReplInterpreterTest { + public void testAllFilesPresentInControlFlow() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/repl/controlFlow"), Pattern.compile("^(.+)\\.repl$"), TargetBackend.ANY, true); + } + + @TestMetadata("functionWithoutReturn.repl") + public void testFunctionWithoutReturn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/repl/controlFlow/functionWithoutReturn.repl"); + doTest(fileName); + } + + @TestMetadata("incompleteIf.repl") + public void testIncompleteIf() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/repl/controlFlow/incompleteIf.repl"); + doTest(fileName); + } + + @TestMetadata("incompleteWhen.repl") + public void testIncompleteWhen() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/repl/controlFlow/incompleteWhen.repl"); + doTest(fileName); + } + + @TestMetadata("loopWithWrongLabel.repl") + public void testLoopWithWrongLabel() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/repl/controlFlow/loopWithWrongLabel.repl"); + doTest(fileName); + } + + @TestMetadata("mutateVal.repl") + public void testMutateVal() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/repl/controlFlow/mutateVal.repl"); + doTest(fileName); + } + + @TestMetadata("useUninitializedVal.repl") + public void testUseUninitializedVal() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/repl/controlFlow/useUninitializedVal.repl"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/repl/modules") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)