From 25d7c9f20af45f108ca40a38a3816e4e746b9561 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Wed, 22 Oct 2014 12:41:45 +0400 Subject: [PATCH] Enabled disabled non-local returns in stdlib --- .../nonLocalReturns/synchronized.kt | 178 +++++++++++++++++ .../boxWithStdlib/nonLocalReturns/use.kt | 176 ++++++++++++++++ .../nonLocalReturns/useWithException.kt | 189 ++++++++++++++++++ ...hibitNonLocalReturnOutOfTryCatchFinally.kt | 42 ---- ...ibitNonLocalReturnOutOfTryCatchFinally.txt | 7 - ...JetDiagnosticsTestWithStdLibGenerated.java | 17 +- ...lackBoxWithStdlibCodegenTestGenerated.java | 29 ++- libraries/stdlib/src/kotlin/JLangJVM.kt | 3 +- .../stdlib/src/kotlin/concurrent/Locks.kt | 7 +- libraries/stdlib/src/kotlin/io/Closable.kt | 3 +- libraries/stdlib/src/kotlin/io/JIO.kt | 3 +- 11 files changed, 578 insertions(+), 76 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/nonLocalReturns/synchronized.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/nonLocalReturns/use.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/nonLocalReturns/useWithException.kt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/nonLocalReturns/prohibitNonLocalReturnOutOfTryCatchFinally.kt delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/nonLocalReturns/prohibitNonLocalReturnOutOfTryCatchFinally.txt diff --git a/compiler/testData/codegen/boxWithStdlib/nonLocalReturns/synchronized.kt b/compiler/testData/codegen/boxWithStdlib/nonLocalReturns/synchronized.kt new file mode 100644 index 00000000000..3c2cd1bbe2f --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/nonLocalReturns/synchronized.kt @@ -0,0 +1,178 @@ +import java.util.concurrent.CountDownLatch +import java.util.concurrent.TimeUnit +import java.util.concurrent.Executors +import java.util.concurrent.Callable +import java.util.concurrent.Future + +val count: Int = 10; +var index: Int = 0; +val doneSignal = CountDownLatch(count) +val startSignal = CountDownLatch(1); +val mutex: Any = Object() +val results = arrayListOf() +val executorService = Executors.newFixedThreadPool(count) + +class MyException(message: String): Exception(message) + +enum class ExecutionType { + LOCAL + NON_LOCAL_SIMPLE + NON_LOCAL_EXCEPTION + NON_LOCAL_FINALLY + NON_LOCAL_EXCEPTION_AND_FINALLY + NON_LOCAL_EXCEPTION_AND_FINALLY_WITH_RETURN + NON_LOCAL_NESTED +} + +class TestLocal(val name: String, val executionType: ExecutionType) : Callable { + + override fun call(): String { + startSignal.await() + return when (executionType) { + is ExecutionType.LOCAL -> local() + is ExecutionType.NON_LOCAL_SIMPLE -> nonLocalSimple() + is ExecutionType.NON_LOCAL_EXCEPTION -> nonLocalWithException() + is ExecutionType.NON_LOCAL_FINALLY -> nonLocalWithFinally() + is ExecutionType.NON_LOCAL_EXCEPTION_AND_FINALLY -> nonLocalWithExceptionAndFinally() + is ExecutionType.NON_LOCAL_EXCEPTION_AND_FINALLY_WITH_RETURN -> nonLocalWithExceptionAndFinallyWithReturn() + is ExecutionType.NON_LOCAL_NESTED -> nonLocalNested() + else -> "fail" + } + } + + private fun underMutexFun() { + results.add(++index); + doneSignal.countDown() + } + + fun local(): String { + synchronized(mutex) { + underMutexFun() + } + return executionType.toString() + } + + + fun nonLocalSimple(): String { + synchronized(mutex) { + underMutexFun() + return executionType.name() + } + return "fail" + } + + fun nonLocalWithException(): String { + synchronized(mutex) { + try { + underMutexFun() + throw MyException(executionType.name()) + } catch (e: MyException) { + return e.getMessage()!! + } + } + return "fail" + } + + fun nonLocalWithFinally(): String { + synchronized(mutex) { + try { + underMutexFun() + return "fail" + } finally { + return executionType.name() + } + } + return "fail" + } + + fun nonLocalWithExceptionAndFinally(): String { + synchronized(mutex) { + try { + underMutexFun() + throw MyException(executionType.name()) + } catch (e: MyException) { + return e.getMessage()!! + } finally { + "123" + } + } + return "fail" + } + + fun nonLocalWithExceptionAndFinallyWithReturn(): String { + synchronized(mutex) { + try { + underMutexFun() + throw MyException(executionType.name()) + } catch (e: MyException) { + return "fail1" + } finally { + return executionType.name() + } + } + return "fail" + } + + fun nonLocalNested(): String { + synchronized(mutex) { + try { + try { + underMutexFun() + throw MyException(executionType.name()) + } catch (e: MyException) { + return "fail1" + } finally { + return executionType.name() + } + } finally { + val p = 1 + 1 + } + } + return "fail" + } +} + +fun testTemplate(type: ExecutionType, producer: (Int) -> Callable): String { + + try { + val futures = arrayListOf>() + for (i in 1..count) { + futures.add(executorService.submit (producer(i))) + } + + startSignal.countDown() + val b = doneSignal.await(10, TimeUnit.SECONDS) + if (!b) return "fail: processes not finished" + + for (i in 1..count) { + if (results[i - 1] != i) + return "fail $i != ${results[i]}: synchronization not works : " + results.joinToString() + } + + for (f in futures) { + if (f.get() != type.name()) return "failed result ${f.get()} != ${type.name()}" + } + } finally { + + } + + return "OK" +} + +fun runTest(type: ExecutionType): String { + return testTemplate (type) { TestLocal(it.toString(), type) } +} + +fun box(): String { + try { + for (type in ExecutionType.values()) { + val result = runTest(type) + if (result != "OK") return "fail on $type execution: $result" + } + } finally { + executorService.shutdown() + } + return "OK" +} + + diff --git a/compiler/testData/codegen/boxWithStdlib/nonLocalReturns/use.kt b/compiler/testData/codegen/boxWithStdlib/nonLocalReturns/use.kt new file mode 100644 index 00000000000..b7d59ad992e --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/nonLocalReturns/use.kt @@ -0,0 +1,176 @@ +import java.io.Closeable + +import java.io.Closeable + +import java.io.Closeable + +class MyException(message: String) : Exception(message) + +class Holder(var value: String) { + public fun plusAssign(s: String?) { + value += s + if (s != "closed") { + value += "->" + } + } +} + +class TestLocal() : Closeable { + + var status = Holder("") + + private fun underMutexFun() { + status += "called" + } + + fun local(): Holder { + use { + underMutexFun() + } + return status + } + + + fun nonLocalSimple(): Holder { + use { + underMutexFun() + return status + } + return Holder("fail") + } + + fun nonLocalWithException(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.getMessage()!! + return status + } + } + return Holder("fail") + } + + fun nonLocalWithFinally(): Holder { + use { + try { + underMutexFun() + return Holder("fail") + } finally { + status += "finally" + return status + } + } + return Holder("fail") + } + + fun nonLocalWithExceptionAndFinally(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.getMessage() + return status + } finally { + status += "finally" + } + } + return Holder("fail") + } + + fun nonLocalWithExceptionAndFinallyWithReturn(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.getMessage() + return Holder("fail") + } finally { + status += "finally" + return status + } + } + return Holder("fail") + } + + fun nonLocalNestedWithException(): Holder { + use { + try { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += "exception" + return Holder("fail") + } finally { + status += "finally1" + return status + } + } finally { + status += "finally2" + } + } + return Holder("fail") + } + + fun nonLocalNestedFinally(): Holder { + use { + try { + try { + underMutexFun() + return status + } finally { + status += "finally1" + status + } + } finally { + status += "finally2" + } + } + return Holder("fail") + } + + override fun close() { + status += "closed" + } +} + +fun box(): String { + var callable = TestLocal() + var result = callable.local() + if (result.value != "called->closed") return "fail local: " + result.value + + callable = TestLocal() + result = callable.nonLocalSimple() + if (result.value != "called->closed") return "fail nonLocalSimple: " + result.value + + callable = TestLocal() + result = callable.nonLocalWithException() + if (result.value != "called->exception->closed") return "fail nonLocalWithException: " + result.value + + callable = TestLocal() + result = callable.nonLocalWithFinally() + if (result.value != "called->finally->closed") return "fail nonLocalWithFinally: " + result.value + + callable = TestLocal() + result = callable.nonLocalWithExceptionAndFinally() + if (result.value != "called->exception->finally->closed") return "fail nonLocalWithExceptionAndFinally: " + result.value + + callable = TestLocal() + result = callable.nonLocalWithExceptionAndFinallyWithReturn() + if (result.value != "called->exception->finally->closed") return "fail nonLocalWithExceptionAndFinallyWithReturn: " + result.value + + callable = TestLocal() + result = callable.nonLocalNestedWithException() + if (result.value != "called->exception->finally1->finally2->closed") return "fail nonLocalNestedWithException: " + result.value + + callable = TestLocal() + result = callable.nonLocalNestedFinally() + if (result.value != "called->finally1->finally2->closed") return "fail nonLocalNestedFinally: " + result.value + + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/nonLocalReturns/useWithException.kt b/compiler/testData/codegen/boxWithStdlib/nonLocalReturns/useWithException.kt new file mode 100644 index 00000000000..c206b3afb93 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/nonLocalReturns/useWithException.kt @@ -0,0 +1,189 @@ +import java.io.Closeable + +import java.io.Closeable + +import java.io.Closeable +import kotlin.test.assertTrue +import kotlin.test.fail +import kotlin.test.assertEquals + +class MyException(message: String) : Exception(message) + +class Holder(var value: String) { + public fun plusAssign(s: String?) { + value += s + if (s != "closed") { + value += "->" + } + } +} + +class TestLocal() : Closeable { + + var status = Holder("") + + private fun underMutexFun() { + status += "called" + } + + fun local(): Holder { + use { + underMutexFun() + } + return status + } + + + fun nonLocalSimple(): Holder { + use { + underMutexFun() + return status + } + return Holder("fail") + } + + fun nonLocalWithException(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.getMessage()!! + return status + } + } + return Holder("fail") + } + + fun nonLocalWithFinally(): Holder { + use { + try { + underMutexFun() + return Holder("fail") + } finally { + status += "finally" + return status + } + } + return Holder("fail") + } + + fun nonLocalWithExceptionAndFinally(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.getMessage() + return status + } finally { + status += "finally" + } + } + return Holder("fail") + } + + fun nonLocalWithExceptionAndFinallyWithReturn(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.getMessage() + return Holder("fail") + } finally { + status += "finally" + return status + } + } + return Holder("fail") + } + + fun nonLocalNestedWithException(): Holder { + use { + try { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += "exception" + return Holder("fail") + } finally { + status += "finally1" + return status + } + } finally { + status += "finally2" + } + } + return Holder("fail") + } + + fun nonLocalNestedFinally(): Holder { + use { + try { + try { + underMutexFun() + return status + } finally { + status += "finally1" + status + } + } finally { + status += "finally2" + } + } + return Holder("fail") + } + + override fun close() { + status += "closed" + throw MyException("error") + } +} + +fun box(): String { + assertError(1,"called->closed") { + local() + } + + assertError(2, "called->closed") { + nonLocalSimple() + } + + assertError(3, "called->exception->closed") { + nonLocalWithException() + } + + assertError(4, "called->finally->closed") { + nonLocalWithFinally() + } + + assertError(5, "called->exception->finally->closed") { + nonLocalWithExceptionAndFinally() + } + + assertError(6, "called->exception->finally->closed") { + nonLocalWithExceptionAndFinallyWithReturn() + } + + assertError(7, "called->exception->finally1->finally2->closed") { + nonLocalNestedWithException() + } + + assertError(8, "called->finally1->finally2->closed") { + nonLocalNestedFinally() + } + + return "OK" +} + +public fun assertError(index: Int, expected: String, l: TestLocal.()->Unit) { + val testLocal = TestLocal() + try { + testLocal.l() + fail("fail $index: no error") + } catch (e: Exception) { + assertEquals(expected, testLocal.status.value, "failed on $index") + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/nonLocalReturns/prohibitNonLocalReturnOutOfTryCatchFinally.kt b/compiler/testData/diagnostics/testsWithStdLib/nonLocalReturns/prohibitNonLocalReturnOutOfTryCatchFinally.kt deleted file mode 100644 index 852927a7878..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/nonLocalReturns/prohibitNonLocalReturnOutOfTryCatchFinally.kt +++ /dev/null @@ -1,42 +0,0 @@ -import java.io.Closeable -import java.util.concurrent.locks.Lock -import java.util.concurrent.locks.ReentrantReadWriteLock -import kotlin.concurrent.* - -// Non-local returns for these functions are temporarily disabled because they contain try-finally blocks and -// the compiler doesn't correctly include the "finally" section into the inlined result. -// Once the compiler is fixed (KT-5506), non-local returns can be re-allowed for these functions - -fun testSynchronized(): Int { - synchronized("") { - return 1 - } -} - - -fun testUse(f: Closeable): Int { - f.use { - return 2 - } -} - - -fun testWithLock(l: Lock): Int { - l.withLock { - return 3 - } -} - - -fun testRead(l: ReentrantReadWriteLock): Int { - l.read { - return 4 - } -} - - -fun testWrite(l: ReentrantReadWriteLock): Int { - l.write { - return 5 - } -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/nonLocalReturns/prohibitNonLocalReturnOutOfTryCatchFinally.txt b/compiler/testData/diagnostics/testsWithStdLib/nonLocalReturns/prohibitNonLocalReturnOutOfTryCatchFinally.txt deleted file mode 100644 index cfcb82080f2..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/nonLocalReturns/prohibitNonLocalReturnOutOfTryCatchFinally.txt +++ /dev/null @@ -1,7 +0,0 @@ -package - -internal fun testRead(/*0*/ l: java.util.concurrent.locks.ReentrantReadWriteLock): kotlin.Int -internal fun testSynchronized(): kotlin.Int -internal fun testUse(/*0*/ f: java.io.Closeable): kotlin.Int -internal fun testWithLock(/*0*/ l: java.util.concurrent.locks.Lock): kotlin.Int -internal fun testWrite(/*0*/ l: java.util.concurrent.locks.ReentrantReadWriteLock): kotlin.Int diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java index d8eaa15772b..fc0e8a042c3 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -30,7 +30,7 @@ import java.util.regex.Pattern; @SuppressWarnings("all") @TestMetadata("compiler/testData/diagnostics/testsWithStdLib") @TestDataPath("$PROJECT_ROOT") -@InnerTestClasses({JetDiagnosticsTestWithStdLibGenerated.Annotations.class, JetDiagnosticsTestWithStdLibGenerated.CallableReference.class, JetDiagnosticsTestWithStdLibGenerated.DuplicateJvmSignature.class, JetDiagnosticsTestWithStdLibGenerated.FunctionLiterals.class, JetDiagnosticsTestWithStdLibGenerated.KotlinSignature.class, JetDiagnosticsTestWithStdLibGenerated.NonLocalReturns.class}) +@InnerTestClasses({JetDiagnosticsTestWithStdLibGenerated.Annotations.class, JetDiagnosticsTestWithStdLibGenerated.CallableReference.class, JetDiagnosticsTestWithStdLibGenerated.DuplicateJvmSignature.class, JetDiagnosticsTestWithStdLibGenerated.FunctionLiterals.class, JetDiagnosticsTestWithStdLibGenerated.KotlinSignature.class}) @RunWith(JUnit3RunnerWithInners.class) public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnosticsTestWithStdLib { public void testAllFilesPresentInTestsWithStdLib() throws Exception { @@ -620,19 +620,4 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic doTest(fileName); } } - - @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/nonLocalReturns") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class NonLocalReturns extends AbstractJetDiagnosticsTestWithStdLib { - public void testAllFilesPresentInNonLocalReturns() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/nonLocalReturns"), Pattern.compile("^(.+)\\.kt$"), true); - } - - @TestMetadata("prohibitNonLocalReturnOutOfTryCatchFinally.kt") - public void testProhibitNonLocalReturnOutOfTryCatchFinally() throws Exception { - String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/nonLocalReturns/prohibitNonLocalReturnOutOfTryCatchFinally.kt"); - doTest(fileName); - } - } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index fcbef27cde4..a746aa75acf 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -30,7 +30,7 @@ import java.util.regex.Pattern; @SuppressWarnings("all") @TestMetadata("compiler/testData/codegen/boxWithStdlib") @TestDataPath("$PROJECT_ROOT") -@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.DefaultArguments.class, BlackBoxWithStdlibCodegenTestGenerated.Enum.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.Intrinsics.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformStatic.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformTypes.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.StoreStackBeforeInline.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class, BlackBoxWithStdlibCodegenTestGenerated.WhenEnumOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.WhenStringOptimization.class}) +@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.DefaultArguments.class, BlackBoxWithStdlibCodegenTestGenerated.Enum.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.Intrinsics.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.NonLocalReturns.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformStatic.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformTypes.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.StoreStackBeforeInline.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class, BlackBoxWithStdlibCodegenTestGenerated.WhenEnumOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.WhenStringOptimization.class}) @RunWith(JUnit3RunnerWithInners.class) public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBoxWithStdlib() throws Exception { @@ -1452,6 +1452,33 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode } } + @TestMetadata("compiler/testData/codegen/boxWithStdlib/nonLocalReturns") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NonLocalReturns extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInNonLocalReturns() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/nonLocalReturns"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("synchronized.kt") + public void testSynchronized() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/nonLocalReturns/synchronized.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("use.kt") + public void testUse() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/nonLocalReturns/use.kt"); + doTestWithStdlib(fileName); + } + + @TestMetadata("useWithException.kt") + public void testUseWithException() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/nonLocalReturns/useWithException.kt"); + doTestWithStdlib(fileName); + } + } + @TestMetadata("compiler/testData/codegen/boxWithStdlib/platformNames") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/libraries/stdlib/src/kotlin/JLangJVM.kt b/libraries/stdlib/src/kotlin/JLangJVM.kt index 85b50ab3b35..d8476831a69 100644 --- a/libraries/stdlib/src/kotlin/JLangJVM.kt +++ b/libraries/stdlib/src/kotlin/JLangJVM.kt @@ -4,7 +4,6 @@ import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy import kotlin.jvm.internal.unsafe.* import kotlin.jvm.internal.Intrinsic -import kotlin.InlineOption.ONLY_LOCAL_RETURN /** * This annotation indicates what exceptions should be declared by a function when compiled to a JVM method @@ -26,7 +25,7 @@ public annotation class throws(public vararg val exceptionClasses: Class javaClass(): Class = null as Class -public inline fun synchronized(lock: Any, [inlineOptions(ONLY_LOCAL_RETURN)] block: () -> R): R { +public inline fun synchronized(lock: Any, block: () -> R): R { monitorEnter(lock) try { return block() diff --git a/libraries/stdlib/src/kotlin/concurrent/Locks.kt b/libraries/stdlib/src/kotlin/concurrent/Locks.kt index 22a254316da..9a4fada5248 100644 --- a/libraries/stdlib/src/kotlin/concurrent/Locks.kt +++ b/libraries/stdlib/src/kotlin/concurrent/Locks.kt @@ -3,13 +3,12 @@ package kotlin.concurrent import java.util.concurrent.locks.Lock import java.util.concurrent.locks.ReentrantReadWriteLock import java.util.concurrent.CountDownLatch -import kotlin.InlineOption.ONLY_LOCAL_RETURN /** * Executes given calculation under lock * Returns result of the calculation */ -public inline fun Lock.withLock([inlineOptions(ONLY_LOCAL_RETURN)] action: () -> T): T { +public inline fun Lock.withLock(action: () -> T): T { lock() try { return action() @@ -22,7 +21,7 @@ public inline fun Lock.withLock([inlineOptions(ONLY_LOCAL_RETURN)] action: ( * Executes given calculation under read lock * Returns result of the calculation */ -public inline fun ReentrantReadWriteLock.read([inlineOptions(ONLY_LOCAL_RETURN)] action: () -> T): T { +public inline fun ReentrantReadWriteLock.read(action: () -> T): T { val rl = readLock() rl.lock() try { @@ -38,7 +37,7 @@ public inline fun ReentrantReadWriteLock.read([inlineOptions(ONLY_LOCAL_RETU * If such write has been initiated by checking some condition, the condition must be rechecked inside the action to avoid possible races * Returns result of the calculation */ -public inline fun ReentrantReadWriteLock.write([inlineOptions(ONLY_LOCAL_RETURN)] action: () -> T): T { +public inline fun ReentrantReadWriteLock.write(action: () -> T): T { val rl = readLock() val readCount = if (getWriteHoldCount() == 0) getReadHoldCount() else 0 diff --git a/libraries/stdlib/src/kotlin/io/Closable.kt b/libraries/stdlib/src/kotlin/io/Closable.kt index 20cdffb9d65..eab1f333822 100644 --- a/libraries/stdlib/src/kotlin/io/Closable.kt +++ b/libraries/stdlib/src/kotlin/io/Closable.kt @@ -1,10 +1,9 @@ package kotlin import java.io.Closeable -import kotlin.InlineOption.ONLY_LOCAL_RETURN /** Uses the given resource then closes it down correctly whether an exception is thrown or not */ -public inline fun T.use([inlineOptions(ONLY_LOCAL_RETURN)] block: (T) -> R): R { +public inline fun T.use(block: (T) -> R): R { var closed = false try { return block(this) diff --git a/libraries/stdlib/src/kotlin/io/JIO.kt b/libraries/stdlib/src/kotlin/io/JIO.kt index 40b37f52d5a..178a61ad9f8 100644 --- a/libraries/stdlib/src/kotlin/io/JIO.kt +++ b/libraries/stdlib/src/kotlin/io/JIO.kt @@ -4,7 +4,6 @@ import java.io.* import java.nio.charset.* import java.util.NoSuchElementException import java.net.URL -import kotlin.InlineOption.ONLY_LOCAL_RETURN /** * Returns the default buffer size when working with buffered streams @@ -193,7 +192,7 @@ public fun Writer.buffered(bufferSize: Int = defaultBufferSize): BufferedWriter */ public fun Reader.forEachLine(block: (String) -> Unit): Unit = useLines { lines -> lines.forEach(block) } -public inline fun Reader.useLines([inlineOptions(ONLY_LOCAL_RETURN)] block: (Stream) -> T): T = +public inline fun Reader.useLines(block: (Stream) -> T): T = this.buffered().use { block(it.lines()) } /**