Skip to content

Commit 0b49dc2

Browse files
committed
Fix binary compatibility for inlined local delegated properies
#KT-54650 Fixed
1 parent 90b3e21 commit 0b49dc2

File tree

7 files changed

+72
-5
lines changed

7 files changed

+72
-5
lines changed

compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt

+17-5
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ package org.jetbrains.kotlin.backend.common.lower
88
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
99
import org.jetbrains.kotlin.backend.common.CommonBackendContext
1010
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString
11-
import org.jetbrains.kotlin.backend.common.ir.*
1211
import org.jetbrains.kotlin.backend.common.lower.inline.isInlineParameter
1312
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
1413
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
1514
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
1615
import org.jetbrains.kotlin.descriptors.Modality
17-
import org.jetbrains.kotlin.ir.*
16+
import org.jetbrains.kotlin.ir.IrElement
17+
import org.jetbrains.kotlin.ir.IrStatement
18+
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
1819
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
1920
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
2021
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
@@ -25,7 +26,9 @@ import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
2526
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
2627
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
2728
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
28-
import org.jetbrains.kotlin.ir.types.*
29+
import org.jetbrains.kotlin.ir.transformStatement
30+
import org.jetbrains.kotlin.ir.types.IrType
31+
import org.jetbrains.kotlin.ir.types.defaultType
2932
import org.jetbrains.kotlin.ir.util.*
3033
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
3134
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -71,6 +74,7 @@ class LocalDeclarationsLowering(
7174
val localNameSanitizer: (String) -> String = { it },
7275
val visibilityPolicy: VisibilityPolicy = VisibilityPolicy.DEFAULT,
7376
val suggestUniqueNames: Boolean = true, // When `true` appends a `$#index` suffix to lifted declaration names
77+
val compatibilityModeForInlinedLocalDelegatedPropertyAccessors: Boolean = false, // Keep old names because of KT-49030
7478
val forceFieldsForInlineCaptures: Boolean = false, // See `LocalClassContext`
7579
private val postLocalDeclarationLoweringCallback: ((IntermediateDatastructures) -> Unit)? = null
7680
) :
@@ -589,8 +593,16 @@ class LocalDeclarationsLowering(
589593
val declarationName = localNameSanitizer(declaration.name.asString())
590594
localFunctions[declaration]?.let {
591595
val baseName = if (declaration.name.isSpecial) "lambda" else declarationName
592-
if (it.index >= 0)
593-
return if (suggestUniqueNames) "$baseName\$${it.index}" else baseName
596+
if (it.index >= 0) {
597+
if (!suggestUniqueNames) return baseName
598+
599+
val separator = if (
600+
compatibilityModeForInlinedLocalDelegatedPropertyAccessors &&
601+
declaration.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR &&
602+
container is IrFunction && container.isInline
603+
) "-" else "$"
604+
return "$baseName$separator${it.index}"
605+
}
594606
}
595607

596608
return declarationName

compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ internal val localDeclarationsPhase = makeIrFilePhase(
138138
private fun scopedVisibility(inInlineFunctionScope: Boolean): DescriptorVisibility =
139139
if (inInlineFunctionScope) DescriptorVisibilities.PUBLIC else JavaDescriptorVisibilities.PACKAGE_VISIBILITY
140140
},
141+
compatibilityModeForInlinedLocalDelegatedPropertyAccessors = true,
141142
forceFieldsForInlineCaptures = true,
142143
postLocalDeclarationLoweringCallback = context.localDeclarationsLoweringData?.let {
143144
{ data ->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// This test checks that we use the `...$lambda-0` method name, instead of `...$lambda$0`, for extracted accessors of local delegated properties.
2+
// It's important to keep these names until we fix the binary compatibility issue KT-49030.
3+
4+
operator fun String.getValue(thisRef: Any?, prop: Any?): String = this
5+
operator fun String.setValue(thisRef: Any?, prop: Any?, value: String) {}
6+
7+
inline fun foo(): String {
8+
var x by "OK"
9+
return x
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@kotlin.Metadata
2+
public final class LocalDelegatedPropertyKt$foo$x$1 {
3+
// source: 'localDelegatedProperty.kt'
4+
public final static field INSTANCE: kotlin.reflect.KMutableProperty0
5+
static method <clinit>(): void
6+
method <init>(): void
7+
public method getName(): java.lang.String
8+
public method getOwner(): kotlin.reflect.KDeclarationContainer
9+
public method getSignature(): java.lang.String
10+
}
11+
12+
@kotlin.Metadata
13+
public final class LocalDelegatedPropertyKt {
14+
// source: 'localDelegatedProperty.kt'
15+
synthetic final static field $$delegatedProperties: kotlin.reflect.KProperty[]
16+
static method <clinit>(): void
17+
public final static @org.jetbrains.annotations.NotNull method foo(): java.lang.String
18+
public final static @org.jetbrains.annotations.NotNull method getValue(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.Object, @org.jetbrains.annotations.Nullable p2: java.lang.Object): java.lang.String
19+
public final static method setValue(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.Object, @org.jetbrains.annotations.Nullable p2: java.lang.Object, @org.jetbrains.annotations.NotNull p3: java.lang.String): void
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@kotlin.Metadata
2+
public final class LocalDelegatedPropertyKt {
3+
// source: 'localDelegatedProperty.kt'
4+
synthetic final static field $$delegatedProperties: kotlin.reflect.KProperty[]
5+
static method <clinit>(): void
6+
public synthetic final static method access$foo$lambda-0(p0: java.lang.String): java.lang.String
7+
private final static method foo$lambda-0(p0: java.lang.String): java.lang.String
8+
private final static method foo$lambda-1(p0: java.lang.String, p1: java.lang.String): void
9+
public final static @org.jetbrains.annotations.NotNull method foo(): java.lang.String
10+
public final static @org.jetbrains.annotations.NotNull method getValue(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.Object, @org.jetbrains.annotations.Nullable p2: java.lang.Object): java.lang.String
11+
public final static method setValue(@org.jetbrains.annotations.NotNull p0: java.lang.String, @org.jetbrains.annotations.Nullable p1: java.lang.Object, @org.jetbrains.annotations.Nullable p2: java.lang.Object, @org.jetbrains.annotations.NotNull p3: java.lang.String): void
12+
}

compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeListingTestGenerated.java

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeListingTestGenerated.java

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)