From eb3b9032d67edab3dc5baafdfe4639cb0316c496 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Fri, 6 Apr 2018 20:27:09 +0300 Subject: [PATCH] Add synthetic flag to generated private suspend functions Private suspend functions need to be generated as package-local, since they are called from their continuations. However, this means that they can be called from Java, which breaks their private visibility. Adding synthetic to them fixes the issue. #KT-17584: Fixed --- .../src/org/jetbrains/kotlin/codegen/AsmUtil.java | 3 ++- .../codegen/bytecodeListing/privateSuspendFun.kt | 5 +++++ .../codegen/bytecodeListing/privateSuspendFun.txt | 10 ++++++++++ .../bytecodeListing/tailcall/tailCallIntrinsics.txt | 4 ++-- .../kotlin/codegen/BytecodeListingTestGenerated.java | 6 ++++++ 5 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeListing/privateSuspendFun.kt create mode 100644 compiler/testData/codegen/bytecodeListing/privateSuspendFun.txt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index f16e251bf65..7306dd612dc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -244,7 +244,8 @@ public class AsmUtil { int flags = getVisibilityAccessFlag(functionDescriptor); flags |= getVarargsFlag(functionDescriptor); flags |= getDeprecatedAccessFlag(functionDescriptor); - if (state.getDeprecationProvider().isDeprecatedHidden(functionDescriptor)) { + if (state.getDeprecationProvider().isDeprecatedHidden(functionDescriptor) || + (functionDescriptor.isSuspend()) && functionDescriptor.getVisibility().equals(Visibilities.PRIVATE)) { flags |= ACC_SYNTHETIC; } return flags; diff --git a/compiler/testData/codegen/bytecodeListing/privateSuspendFun.kt b/compiler/testData/codegen/bytecodeListing/privateSuspendFun.kt new file mode 100644 index 00000000000..ef751acfc87 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/privateSuspendFun.kt @@ -0,0 +1,5 @@ +private suspend fun foo() {} + +class A { + private suspend fun foo() {} +} diff --git a/compiler/testData/codegen/bytecodeListing/privateSuspendFun.txt b/compiler/testData/codegen/bytecodeListing/privateSuspendFun.txt new file mode 100644 index 00000000000..bb9e32bd9ce --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/privateSuspendFun.txt @@ -0,0 +1,10 @@ +@kotlin.Metadata +public final class A { + public method (): void + synthetic final @org.jetbrains.annotations.Nullable method foo(@org.jetbrains.annotations.Nullable p0: java.lang.Object): java.lang.Object +} + +@kotlin.Metadata +public final class PrivateSuspendFunKt { + synthetic final static @org.jetbrains.annotations.Nullable method foo(@org.jetbrains.annotations.Nullable p0: java.lang.Object): java.lang.Object +} diff --git a/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIntrinsics.txt b/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIntrinsics.txt index f9d255385e3..e15f53eae48 100644 --- a/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIntrinsics.txt +++ b/compiler/testData/codegen/bytecodeListing/tailcall/tailCallIntrinsics.txt @@ -15,6 +15,6 @@ public final class TailCallIntrinsicsKt { static method (): void public final static method getP(): int public final static method setP(p0: int): void - final static @org.jetbrains.annotations.Nullable method withInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object - final static @org.jetbrains.annotations.Nullable method withoutInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object + synthetic final static @org.jetbrains.annotations.Nullable method withInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object + synthetic final static @org.jetbrains.annotations.Nullable method withoutInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 2134d8d7dd8..34006a96ddc 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -145,6 +145,12 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { doTest(fileName); } + @TestMetadata("privateSuspendFun.kt") + public void testPrivateSuspendFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/privateSuspendFun.kt"); + doTest(fileName); + } + @TestMetadata("samAdapterAndInlinedOne.kt") public void testSamAdapterAndInlinedOne() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/samAdapterAndInlinedOne.kt");