diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt index cd45da13b82..b968ec543e2 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiSourceCompilerForInline.kt @@ -418,9 +418,20 @@ class PsiSourceCompilerForInline( fun DeclarationDescriptor.isInlineOrInsideInline(): Boolean = getInlineCallSiteVisibility() != null -fun DeclarationDescriptor.getInlineCallSiteVisibility(): DescriptorVisibility? = - if (this is FunctionDescriptor && isInline) visibility - else containingDeclaration?.getInlineCallSiteVisibility() +fun DeclarationDescriptor.getInlineCallSiteVisibility(): DescriptorVisibility? { + var declaration: DeclarationDescriptor? = this + var result: DescriptorVisibility? = null + while (declaration != null) { + if (declaration is FunctionDescriptor && declaration.isInline) { + if (!DescriptorVisibilities.isPrivate(declaration.visibility)) { + return declaration.visibility + } + result = declaration.visibility + } + declaration = declaration.containingDeclaration + } + return result +} fun getDeclarationLabels(lambdaOrFun: PsiElement?, descriptor: DeclarationDescriptor): Set { val result = HashSet() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java index 9365dd7e263..1eab134872c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/inline/InlineUtil.java @@ -76,11 +76,10 @@ public class InlineUtil { public static boolean isInPublicInlineScope(@Nullable DeclarationDescriptor descriptor) { if (descriptor == null) return false; - if (isInline(descriptor)) { - if (!(descriptor instanceof DeclarationDescriptorWithVisibility)) - return false; + if (isInline(descriptor) && descriptor instanceof DeclarationDescriptorWithVisibility) { DescriptorVisibility visibility = ((DeclarationDescriptorWithVisibility) descriptor).getVisibility(); - return !DescriptorVisibilities.isPrivate(visibility); + if (!DescriptorVisibilities.isPrivate(visibility)) + return true; } return isInPublicInlineScope(descriptor.getContainingDeclaration()); } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt index dfc53348106..fbe6a0f2177 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt @@ -13,10 +13,7 @@ import org.jetbrains.kotlin.backend.jvm.codegen.representativeUpperBound import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.config.JvmDefaultMode -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.DescriptorVisibilities -import org.jetbrains.kotlin.descriptors.DescriptorVisibility -import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrElement @@ -431,13 +428,17 @@ private val IrDeclaration.original: IrDeclaration // (determined *before* lowering), or null if the given declaration is not in the scope of an inline function. val IrDeclaration.inlineScopeVisibility: DescriptorVisibility? get() { - var owner = original - while (true) { + var owner: IrDeclaration? = original + var result: DescriptorVisibility? = null + while (owner != null) { if (owner is IrFunction && owner.isInline) { - return owner.visibility + if (!DescriptorVisibilities.isPrivate(owner.visibility)) + return owner.visibility + result = owner.visibility } - owner = owner.parent.safeAs()?.original ?: return null + owner = owner.parent.safeAs()?.original } + return result } // True for declarations which are in the scope of an externally visible inline function. diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/CompileAgainstJvmAbiTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/CompileAgainstJvmAbiTestGenerated.java index 3d86ca4c1c0..f4daccf1951 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/CompileAgainstJvmAbiTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/CompileAgainstJvmAbiTestGenerated.java @@ -55,11 +55,21 @@ public class CompileAgainstJvmAbiTestGenerated extends AbstractCompileAgainstJvm runTest("plugins/jvm-abi-gen/testData/compile/inlineCapture/"); } + @TestMetadata("inlineNoRegeneration") + public void testInlineNoRegeneration() throws Exception { + runTest("plugins/jvm-abi-gen/testData/compile/inlineNoRegeneration/"); + } + @TestMetadata("inlineReifiedFunction") public void testInlineReifiedFunction() throws Exception { runTest("plugins/jvm-abi-gen/testData/compile/inlineReifiedFunction/"); } + @TestMetadata("innerObjectRegeneration") + public void testInnerObjectRegeneration() throws Exception { + runTest("plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/"); + } + @TestMetadata("privateOnlyConstructors") public void testPrivateOnlyConstructors() throws Exception { runTest("plugins/jvm-abi-gen/testData/compile/privateOnlyConstructors/"); diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrCompileAgainstJvmAbiTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrCompileAgainstJvmAbiTestGenerated.java index b7f9ef30bde..c50a1392a8c 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrCompileAgainstJvmAbiTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrCompileAgainstJvmAbiTestGenerated.java @@ -55,11 +55,21 @@ public class IrCompileAgainstJvmAbiTestGenerated extends AbstractIrCompileAgains runTest("plugins/jvm-abi-gen/testData/compile/inlineCapture/"); } + @TestMetadata("inlineNoRegeneration") + public void testInlineNoRegeneration() throws Exception { + runTest("plugins/jvm-abi-gen/testData/compile/inlineNoRegeneration/"); + } + @TestMetadata("inlineReifiedFunction") public void testInlineReifiedFunction() throws Exception { runTest("plugins/jvm-abi-gen/testData/compile/inlineReifiedFunction/"); } + @TestMetadata("innerObjectRegeneration") + public void testInnerObjectRegeneration() throws Exception { + runTest("plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/"); + } + @TestMetadata("privateOnlyConstructors") public void testPrivateOnlyConstructors() throws Exception { runTest("plugins/jvm-abi-gen/testData/compile/privateOnlyConstructors/"); diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyCompileAgainstJvmAbiTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyCompileAgainstJvmAbiTestGenerated.java index 6907226bc04..e8ec7e0abfa 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyCompileAgainstJvmAbiTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyCompileAgainstJvmAbiTestGenerated.java @@ -55,11 +55,21 @@ public class LegacyCompileAgainstJvmAbiTestGenerated extends AbstractLegacyCompi runTest("plugins/jvm-abi-gen/testData/compile/inlineCapture/"); } + @TestMetadata("inlineNoRegeneration") + public void testInlineNoRegeneration() throws Exception { + runTest("plugins/jvm-abi-gen/testData/compile/inlineNoRegeneration/"); + } + @TestMetadata("inlineReifiedFunction") public void testInlineReifiedFunction() throws Exception { runTest("plugins/jvm-abi-gen/testData/compile/inlineReifiedFunction/"); } + @TestMetadata("innerObjectRegeneration") + public void testInnerObjectRegeneration() throws Exception { + runTest("plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/"); + } + @TestMetadata("privateOnlyConstructors") public void testPrivateOnlyConstructors() throws Exception { runTest("plugins/jvm-abi-gen/testData/compile/privateOnlyConstructors/"); diff --git a/plugins/jvm-abi-gen/testData/compile/inlineNoRegeneration/app/app.kt b/plugins/jvm-abi-gen/testData/compile/inlineNoRegeneration/app/app.kt new file mode 100644 index 00000000000..ef5e12af7bf --- /dev/null +++ b/plugins/jvm-abi-gen/testData/compile/inlineNoRegeneration/app/app.kt @@ -0,0 +1,10 @@ +package app + +import lib.* + +fun runAppAndReturnOk(): String { + foo { + "K" + } + return result +} diff --git a/plugins/jvm-abi-gen/testData/compile/inlineNoRegeneration/lib/lib.kt b/plugins/jvm-abi-gen/testData/compile/inlineNoRegeneration/lib/lib.kt new file mode 100644 index 00000000000..d1e07a76c0e --- /dev/null +++ b/plugins/jvm-abi-gen/testData/compile/inlineNoRegeneration/lib/lib.kt @@ -0,0 +1,19 @@ +package lib + +var result = "fail" + +inline fun foo(crossinline s: () -> String) { + object { + private inline fun test(crossinline z: () -> String) { + result = object { //should be marked as public abi as there is no regenerated abject on inline + fun run(): String { + return "O" + } + }.run() + z() + } + + fun foo() { + test { s() } + } + }.foo() +} diff --git a/plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/app/app.kt b/plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/app/app.kt new file mode 100644 index 00000000000..b176501b9fd --- /dev/null +++ b/plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/app/app.kt @@ -0,0 +1,10 @@ +package app + +import lib.* + +fun runAppAndReturnOk(): String { + foo { + "OK" + } + return result +} diff --git a/plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/directives.txt b/plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/directives.txt new file mode 100644 index 00000000000..3f7eb8b3500 --- /dev/null +++ b/plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/directives.txt @@ -0,0 +1 @@ +// IGNORE_BACKEND_LEGACY: JVM \ No newline at end of file diff --git a/plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/lib/lib.kt b/plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/lib/lib.kt new file mode 100644 index 00000000000..c1b04950d4c --- /dev/null +++ b/plugins/jvm-abi-gen/testData/compile/innerObjectRegeneration/lib/lib.kt @@ -0,0 +1,19 @@ +package lib + +var result = "fail" + +inline fun foo(crossinline s: () -> String) { + object { + private inline fun test(crossinline z: () -> String) { + object { + fun run() { + result = z() + } + }.run() + } + + fun foo() { + test { s() } // regenerated object should be marked as public abi + } + }.foo() +}