jvm-abi-gen: Mark all anonymous objects in inline function scope as public
Anonymous objects inside of a private inline function nested in a public inline function can still escape.
This commit is contained in:
committed by
Alexander Udalov
parent
d94817cfb6
commit
3ffe495346
+14
-3
@@ -418,9 +418,20 @@ class PsiSourceCompilerForInline(
|
|||||||
fun DeclarationDescriptor.isInlineOrInsideInline(): Boolean =
|
fun DeclarationDescriptor.isInlineOrInsideInline(): Boolean =
|
||||||
getInlineCallSiteVisibility() != null
|
getInlineCallSiteVisibility() != null
|
||||||
|
|
||||||
fun DeclarationDescriptor.getInlineCallSiteVisibility(): DescriptorVisibility? =
|
fun DeclarationDescriptor.getInlineCallSiteVisibility(): DescriptorVisibility? {
|
||||||
if (this is FunctionDescriptor && isInline) visibility
|
var declaration: DeclarationDescriptor? = this
|
||||||
else containingDeclaration?.getInlineCallSiteVisibility()
|
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<String> {
|
fun getDeclarationLabels(lambdaOrFun: PsiElement?, descriptor: DeclarationDescriptor): Set<String> {
|
||||||
val result = HashSet<String>()
|
val result = HashSet<String>()
|
||||||
|
|||||||
@@ -76,11 +76,10 @@ public class InlineUtil {
|
|||||||
|
|
||||||
public static boolean isInPublicInlineScope(@Nullable DeclarationDescriptor descriptor) {
|
public static boolean isInPublicInlineScope(@Nullable DeclarationDescriptor descriptor) {
|
||||||
if (descriptor == null) return false;
|
if (descriptor == null) return false;
|
||||||
if (isInline(descriptor)) {
|
if (isInline(descriptor) && descriptor instanceof DeclarationDescriptorWithVisibility) {
|
||||||
if (!(descriptor instanceof DeclarationDescriptorWithVisibility))
|
|
||||||
return false;
|
|
||||||
DescriptorVisibility visibility = ((DeclarationDescriptorWithVisibility) descriptor).getVisibility();
|
DescriptorVisibility visibility = ((DeclarationDescriptorWithVisibility) descriptor).getVisibility();
|
||||||
return !DescriptorVisibilities.isPrivate(visibility);
|
if (!DescriptorVisibilities.isPrivate(visibility))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return isInPublicInlineScope(descriptor.getContainingDeclaration());
|
return isInPublicInlineScope(descriptor.getContainingDeclaration());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.backend.jvm.lower.inlineclasses.unboxInlineClass
|
||||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||||
import org.jetbrains.kotlin.config.JvmDefaultMode
|
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
|
||||||
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
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.
|
// (determined *before* lowering), or null if the given declaration is not in the scope of an inline function.
|
||||||
val IrDeclaration.inlineScopeVisibility: DescriptorVisibility?
|
val IrDeclaration.inlineScopeVisibility: DescriptorVisibility?
|
||||||
get() {
|
get() {
|
||||||
var owner = original
|
var owner: IrDeclaration? = original
|
||||||
while (true) {
|
var result: DescriptorVisibility? = null
|
||||||
|
while (owner != null) {
|
||||||
if (owner is IrFunction && owner.isInline) {
|
if (owner is IrFunction && owner.isInline) {
|
||||||
return owner.visibility
|
if (!DescriptorVisibilities.isPrivate(owner.visibility))
|
||||||
|
return owner.visibility
|
||||||
|
result = owner.visibility
|
||||||
}
|
}
|
||||||
owner = owner.parent.safeAs<IrDeclaration>()?.original ?: return null
|
owner = owner.parent.safeAs<IrDeclaration>()?.original
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// True for declarations which are in the scope of an externally visible inline function.
|
// True for declarations which are in the scope of an externally visible inline function.
|
||||||
|
|||||||
Generated
+10
@@ -55,11 +55,21 @@ public class CompileAgainstJvmAbiTestGenerated extends AbstractCompileAgainstJvm
|
|||||||
runTest("plugins/jvm-abi-gen/testData/compile/inlineCapture/");
|
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")
|
@TestMetadata("inlineReifiedFunction")
|
||||||
public void testInlineReifiedFunction() throws Exception {
|
public void testInlineReifiedFunction() throws Exception {
|
||||||
runTest("plugins/jvm-abi-gen/testData/compile/inlineReifiedFunction/");
|
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")
|
@TestMetadata("privateOnlyConstructors")
|
||||||
public void testPrivateOnlyConstructors() throws Exception {
|
public void testPrivateOnlyConstructors() throws Exception {
|
||||||
runTest("plugins/jvm-abi-gen/testData/compile/privateOnlyConstructors/");
|
runTest("plugins/jvm-abi-gen/testData/compile/privateOnlyConstructors/");
|
||||||
|
|||||||
Generated
+10
@@ -55,11 +55,21 @@ public class IrCompileAgainstJvmAbiTestGenerated extends AbstractIrCompileAgains
|
|||||||
runTest("plugins/jvm-abi-gen/testData/compile/inlineCapture/");
|
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")
|
@TestMetadata("inlineReifiedFunction")
|
||||||
public void testInlineReifiedFunction() throws Exception {
|
public void testInlineReifiedFunction() throws Exception {
|
||||||
runTest("plugins/jvm-abi-gen/testData/compile/inlineReifiedFunction/");
|
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")
|
@TestMetadata("privateOnlyConstructors")
|
||||||
public void testPrivateOnlyConstructors() throws Exception {
|
public void testPrivateOnlyConstructors() throws Exception {
|
||||||
runTest("plugins/jvm-abi-gen/testData/compile/privateOnlyConstructors/");
|
runTest("plugins/jvm-abi-gen/testData/compile/privateOnlyConstructors/");
|
||||||
|
|||||||
Generated
+10
@@ -55,11 +55,21 @@ public class LegacyCompileAgainstJvmAbiTestGenerated extends AbstractLegacyCompi
|
|||||||
runTest("plugins/jvm-abi-gen/testData/compile/inlineCapture/");
|
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")
|
@TestMetadata("inlineReifiedFunction")
|
||||||
public void testInlineReifiedFunction() throws Exception {
|
public void testInlineReifiedFunction() throws Exception {
|
||||||
runTest("plugins/jvm-abi-gen/testData/compile/inlineReifiedFunction/");
|
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")
|
@TestMetadata("privateOnlyConstructors")
|
||||||
public void testPrivateOnlyConstructors() throws Exception {
|
public void testPrivateOnlyConstructors() throws Exception {
|
||||||
runTest("plugins/jvm-abi-gen/testData/compile/privateOnlyConstructors/");
|
runTest("plugins/jvm-abi-gen/testData/compile/privateOnlyConstructors/");
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
foo {
|
||||||
|
"K"
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import lib.*
|
||||||
|
|
||||||
|
fun runAppAndReturnOk(): String {
|
||||||
|
foo {
|
||||||
|
"OK"
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
// IGNORE_BACKEND_LEGACY: JVM
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user