JVM_IR: KT-40330 Unify field names for captured 'this' with JVM
NB some cases such as captured extension receiver for an extension lambda are not supported yet; to be discussed, to what extent should we actually follow JVM code shape here.
This commit is contained in:
+57
-9
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.common.lower
|
package org.jetbrains.kotlin.backend.common.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
import org.jetbrains.kotlin.backend.common.*
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString
|
||||||
import org.jetbrains.kotlin.backend.common.ir.*
|
import org.jetbrains.kotlin.backend.common.ir.*
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||||
@@ -31,11 +31,13 @@ import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
|||||||
import org.jetbrains.kotlin.ir.util.constructedClass
|
import org.jetbrains.kotlin.ir.util.constructedClass
|
||||||
import org.jetbrains.kotlin.ir.util.file
|
import org.jetbrains.kotlin.ir.util.file
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
interface LocalNameProvider {
|
interface LocalNameProvider {
|
||||||
fun localName(declaration: IrDeclarationWithName): String =
|
fun localName(declaration: IrDeclarationWithName): String =
|
||||||
@@ -637,7 +639,7 @@ class LocalDeclarationsLowering(
|
|||||||
oldDeclaration: IrFunction,
|
oldDeclaration: IrFunction,
|
||||||
newDeclaration: IrFunction
|
newDeclaration: IrFunction
|
||||||
) = ArrayList<IrValueParameter>(capturedValues.size + oldDeclaration.valueParameters.size).apply {
|
) = ArrayList<IrValueParameter>(capturedValues.size + oldDeclaration.valueParameters.size).apply {
|
||||||
val generatedNames = mutableSetOf<Name>()
|
val generatedNames = mutableSetOf<String>()
|
||||||
capturedValues.mapIndexedTo(this) { i, capturedValue ->
|
capturedValues.mapIndexedTo(this) { i, capturedValue ->
|
||||||
val p = capturedValue.owner
|
val p = capturedValue.owner
|
||||||
buildValueParameter(newDeclaration) {
|
buildValueParameter(newDeclaration) {
|
||||||
@@ -743,7 +745,7 @@ class LocalDeclarationsLowering(
|
|||||||
|
|
||||||
private fun createFieldsForCapturedValues(localClassContext: LocalClassContext) {
|
private fun createFieldsForCapturedValues(localClassContext: LocalClassContext) {
|
||||||
val classDeclaration = localClassContext.declaration
|
val classDeclaration = localClassContext.declaration
|
||||||
val generatedNames = mutableSetOf<Name>()
|
val generatedNames = mutableSetOf<String>()
|
||||||
localClassContext.closure.capturedValues.forEach { capturedValue ->
|
localClassContext.closure.capturedValues.forEach { capturedValue ->
|
||||||
|
|
||||||
val owner = capturedValue.owner
|
val owner = capturedValue.owner
|
||||||
@@ -772,18 +774,64 @@ class LocalDeclarationsLowering(
|
|||||||
private fun Name.stripSpecialMarkers(): String =
|
private fun Name.stripSpecialMarkers(): String =
|
||||||
if (isSpecial) asString().substring(1, asString().length - 1) else asString()
|
if (isSpecial) asString().substring(1, asString().length - 1) else asString()
|
||||||
|
|
||||||
private fun suggestNameForCapturedValue(declaration: IrValueDeclaration, existing: MutableSet<Name>): Name {
|
private fun suggestNameForCapturedValue(declaration: IrValueDeclaration, usedNames: MutableSet<String>): Name {
|
||||||
|
if (declaration is IrValueParameter && declaration.name.asString() == "<this>") {
|
||||||
|
if (declaration.isDispatchReceiver()) {
|
||||||
|
return findFirstUnusedName("this\$0", usedNames) {
|
||||||
|
"this\$$it"
|
||||||
|
}
|
||||||
|
} else if (declaration.isExtensionReceiver()) {
|
||||||
|
val parentNameSuffix = declaration.parentNameSuffixForExtensionReceiver
|
||||||
|
return findFirstUnusedName("\$this_$parentNameSuffix", usedNames) {
|
||||||
|
"\$this_$parentNameSuffix\$$it"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO captured extension receivers of extension lambdas?
|
||||||
|
}
|
||||||
val base = if (declaration.name.isSpecial)
|
val base = if (declaration.name.isSpecial)
|
||||||
declaration.name.stripSpecialMarkers()
|
declaration.name.stripSpecialMarkers()
|
||||||
else
|
else
|
||||||
declaration.name.asString()
|
declaration.name.asString()
|
||||||
var chosen = base.synthesizedName
|
return findFirstUnusedName(base.synthesizedString, usedNames) {
|
||||||
var suffix = 0
|
"$base$$it".synthesizedString
|
||||||
while (!existing.add(chosen))
|
}
|
||||||
chosen = "$base$${++suffix}".synthesizedName
|
|
||||||
return chosen
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun findFirstUnusedName(initialName: String, usedNames: MutableSet<String>, nextName: (Int) -> String): Name {
|
||||||
|
var chosen = initialName
|
||||||
|
var suffix = 0
|
||||||
|
while (!usedNames.add(chosen))
|
||||||
|
chosen = nextName(++suffix)
|
||||||
|
return Name.identifier(chosen)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrValueParameter.isDispatchReceiver(): Boolean =
|
||||||
|
when (val parent = this.parent) {
|
||||||
|
is IrFunction ->
|
||||||
|
parent.dispatchReceiverParameter == this
|
||||||
|
is IrClass ->
|
||||||
|
parent.thisReceiver == this
|
||||||
|
else ->
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrValueParameter.isExtensionReceiver(): Boolean {
|
||||||
|
val parentFun = parent as? IrFunction ?: return false
|
||||||
|
return parentFun.extensionReceiverParameter == this
|
||||||
|
}
|
||||||
|
|
||||||
|
private val IrValueParameter.parentNameSuffixForExtensionReceiver: String
|
||||||
|
get() {
|
||||||
|
val parentFun = parent as? IrSimpleFunction
|
||||||
|
?: throw AssertionError("Extension receiver parent is not a simple function: ${parent.render()}")
|
||||||
|
val correspondingProperty = parentFun.safeAs<IrSimpleFunction>()?.correspondingPropertySymbol?.owner
|
||||||
|
return when {
|
||||||
|
correspondingProperty != null ->
|
||||||
|
correspondingProperty.name.stripSpecialMarkers()
|
||||||
|
else ->
|
||||||
|
parentFun.name.stripSpecialMarkers()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun collectClosureForLocalDeclarations() {
|
private fun collectClosureForLocalDeclarations() {
|
||||||
//TODO: maybe use for granular declarations
|
//TODO: maybe use for granular declarations
|
||||||
|
|||||||
+4
-4
@@ -26,7 +26,7 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2$1 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 {
|
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 {
|
||||||
// source: 'crossinline.kt'
|
// source: 'crossinline.kt'
|
||||||
synthetic final field $this$inlined: Sink
|
synthetic final field $this_anonymous$inlined: Sink
|
||||||
inner (anonymous) class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2
|
inner (anonymous) class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2
|
||||||
inner (anonymous) class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2$1
|
inner (anonymous) class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2$1
|
||||||
public method <init>(p0: Sink): void
|
public method <init>(p0: Sink): void
|
||||||
@@ -37,7 +37,7 @@ public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$2 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 {
|
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1 {
|
||||||
// source: 'crossinline.kt'
|
// source: 'crossinline.kt'
|
||||||
synthetic final field $this$inlined: SourceCrossinline
|
synthetic final field $this_filter$inlined: SourceCrossinline
|
||||||
inner (anonymous) class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1
|
inner (anonymous) class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1
|
||||||
inner (anonymous) class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$1
|
inner (anonymous) class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$1
|
||||||
public method <init>(p0: SourceCrossinline): void
|
public method <init>(p0: SourceCrossinline): void
|
||||||
@@ -110,7 +110,7 @@ public final class CrossinlineKt$filter$$inlined$source$1$1 {
|
|||||||
public final class CrossinlineKt$filter$$inlined$source$1 {
|
public final class CrossinlineKt$filter$$inlined$source$1 {
|
||||||
// source: 'crossinline.kt'
|
// source: 'crossinline.kt'
|
||||||
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
||||||
synthetic final field $this$inlined: SourceCrossinline
|
synthetic final field $this_filter$inlined: SourceCrossinline
|
||||||
inner (anonymous) class CrossinlineKt$filter$$inlined$source$1
|
inner (anonymous) class CrossinlineKt$filter$$inlined$source$1
|
||||||
inner (anonymous) class CrossinlineKt$filter$$inlined$source$1$1
|
inner (anonymous) class CrossinlineKt$filter$$inlined$source$1$1
|
||||||
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
public method <init>(p0: SourceCrossinline, p1: kotlin.jvm.functions.Function1): void
|
||||||
@@ -134,7 +134,7 @@ public final class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1$1 {
|
|||||||
public final class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1 {
|
public final class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1 {
|
||||||
// source: 'crossinline.kt'
|
// source: 'crossinline.kt'
|
||||||
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
synthetic final field $predicate$inlined: kotlin.jvm.functions.Function1
|
||||||
synthetic final field $this$inlined: Sink
|
synthetic final field $this_anonymous$inlined: Sink
|
||||||
inner (anonymous) class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1
|
inner (anonymous) class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1
|
||||||
inner (anonymous) class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1$1
|
inner (anonymous) class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1$1
|
||||||
public method <init>(p0: kotlin.jvm.functions.Function1, p1: Sink): void
|
public method <init>(p0: kotlin.jvm.functions.Function1, p1: Sink): void
|
||||||
|
|||||||
Vendored
+2
-2
@@ -41,7 +41,7 @@ public final class flow/InnerObjectRetransformationKt$check$$inlined$flow$1 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1 {
|
public final class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1 {
|
||||||
// source: 'innerObjectRetransformation.kt'
|
// source: 'innerObjectRetransformation.kt'
|
||||||
synthetic final field $this$inlined: flow.Flow
|
synthetic final field $this_flowWith$inlined: flow.Flow
|
||||||
inner (anonymous) class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1
|
inner (anonymous) class flow/InnerObjectRetransformationKt$check$$inlined$flowWith$1
|
||||||
public method <init>(p0: flow.Flow): void
|
public method <init>(p0: flow.Flow): void
|
||||||
public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: flow.FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
@@ -119,7 +119,7 @@ public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1
|
|||||||
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1 {
|
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1 {
|
||||||
// source: 'innerObjectRetransformation.kt'
|
// source: 'innerObjectRetransformation.kt'
|
||||||
synthetic final field $builderBlock$inlined: kotlin.jvm.functions.Function2
|
synthetic final field $builderBlock$inlined: kotlin.jvm.functions.Function2
|
||||||
synthetic final field $this$inlined: flow.Flow
|
synthetic final field $this_flowWith$inlined: flow.Flow
|
||||||
inner (anonymous) class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1
|
inner (anonymous) class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1
|
||||||
inner (anonymous) class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1
|
inner (anonymous) class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1
|
||||||
public method <init>(p0: kotlin.jvm.functions.Function2, p1: flow.Flow): void
|
public method <init>(p0: kotlin.jvm.functions.Function2, p1: flow.Flow): void
|
||||||
|
|||||||
+6
-6
@@ -88,7 +88,7 @@ public final class TcoContinuationKt$foo$$inlined$map$1$2$1 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class TcoContinuationKt$foo$$inlined$map$1$2 {
|
public final class TcoContinuationKt$foo$$inlined$map$1$2 {
|
||||||
// source: 'tcoContinuation.kt'
|
// source: 'tcoContinuation.kt'
|
||||||
synthetic final field $this$inlined: FlowCollector
|
synthetic final field $this_anonymous$inlined: FlowCollector
|
||||||
inner (anonymous) class TcoContinuationKt$foo$$inlined$map$1$2
|
inner (anonymous) class TcoContinuationKt$foo$$inlined$map$1$2
|
||||||
inner (anonymous) class TcoContinuationKt$foo$$inlined$map$1$2$1
|
inner (anonymous) class TcoContinuationKt$foo$$inlined$map$1$2$1
|
||||||
public method <init>(p0: FlowCollector): void
|
public method <init>(p0: FlowCollector): void
|
||||||
@@ -98,7 +98,7 @@ public final class TcoContinuationKt$foo$$inlined$map$1$2 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class TcoContinuationKt$foo$$inlined$map$1 {
|
public final class TcoContinuationKt$foo$$inlined$map$1 {
|
||||||
// source: 'tcoContinuation.kt'
|
// source: 'tcoContinuation.kt'
|
||||||
synthetic final field $this$inlined: Flow
|
synthetic final field $this_transform$inlined: Flow
|
||||||
inner (anonymous) class TcoContinuationKt$foo$$inlined$map$1
|
inner (anonymous) class TcoContinuationKt$foo$$inlined$map$1
|
||||||
public method <init>(p0: Flow): void
|
public method <init>(p0: Flow): void
|
||||||
public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
public @org.jetbrains.annotations.Nullable method collect(@org.jetbrains.annotations.NotNull p0: FlowCollector, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||||
@@ -131,7 +131,7 @@ public final class TcoContinuationKt$map$$inlined$transform$1$2$1 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class TcoContinuationKt$map$$inlined$transform$1$2 {
|
public final class TcoContinuationKt$map$$inlined$transform$1$2 {
|
||||||
// source: 'tcoContinuation.kt'
|
// source: 'tcoContinuation.kt'
|
||||||
synthetic final field $this$inlined: FlowCollector
|
synthetic final field $this_anonymous$inlined: FlowCollector
|
||||||
synthetic final field $transformer$inlined$1: kotlin.jvm.functions.Function2
|
synthetic final field $transformer$inlined$1: kotlin.jvm.functions.Function2
|
||||||
inner (anonymous) class TcoContinuationKt$map$$inlined$transform$1$2
|
inner (anonymous) class TcoContinuationKt$map$$inlined$transform$1$2
|
||||||
inner (anonymous) class TcoContinuationKt$map$$inlined$transform$1$2$1
|
inner (anonymous) class TcoContinuationKt$map$$inlined$transform$1$2$1
|
||||||
@@ -143,7 +143,7 @@ public final class TcoContinuationKt$map$$inlined$transform$1$2 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class TcoContinuationKt$map$$inlined$transform$1 {
|
public final class TcoContinuationKt$map$$inlined$transform$1 {
|
||||||
// source: 'tcoContinuation.kt'
|
// source: 'tcoContinuation.kt'
|
||||||
synthetic final field $this$inlined: Flow
|
synthetic final field $this_transform$inlined: Flow
|
||||||
synthetic final field $transformer$inlined$1: kotlin.jvm.functions.Function2
|
synthetic final field $transformer$inlined$1: kotlin.jvm.functions.Function2
|
||||||
inner (anonymous) class TcoContinuationKt$map$$inlined$transform$1
|
inner (anonymous) class TcoContinuationKt$map$$inlined$transform$1
|
||||||
inner (anonymous) class TcoContinuationKt$map$$inlined$transform$1$1
|
inner (anonymous) class TcoContinuationKt$map$$inlined$transform$1$1
|
||||||
@@ -166,7 +166,7 @@ public final class TcoContinuationKt$transform$$inlined$flow$1$1 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class TcoContinuationKt$transform$$inlined$flow$1 {
|
public final class TcoContinuationKt$transform$$inlined$flow$1 {
|
||||||
// source: 'tcoContinuation.kt'
|
// source: 'tcoContinuation.kt'
|
||||||
synthetic final field $this$inlined: Flow
|
synthetic final field $this_transform$inlined: Flow
|
||||||
synthetic final field $transformer$inlined: kotlin.jvm.functions.Function3
|
synthetic final field $transformer$inlined: kotlin.jvm.functions.Function3
|
||||||
inner (anonymous) class TcoContinuationKt$transform$$inlined$flow$1
|
inner (anonymous) class TcoContinuationKt$transform$$inlined$flow$1
|
||||||
inner (anonymous) class TcoContinuationKt$transform$$inlined$flow$1$1
|
inner (anonymous) class TcoContinuationKt$transform$$inlined$flow$1$1
|
||||||
@@ -189,7 +189,7 @@ public final class TcoContinuationKt$transform$lambda-1$$inlined$collect$1$1 {
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class TcoContinuationKt$transform$lambda-1$$inlined$collect$1 {
|
public final class TcoContinuationKt$transform$lambda-1$$inlined$collect$1 {
|
||||||
// source: 'tcoContinuation.kt'
|
// source: 'tcoContinuation.kt'
|
||||||
synthetic final field $this$inlined: FlowCollector
|
synthetic final field $this_anonymous$inlined: FlowCollector
|
||||||
synthetic final field $transformer$inlined: kotlin.jvm.functions.Function3
|
synthetic final field $transformer$inlined: kotlin.jvm.functions.Function3
|
||||||
inner (anonymous) class TcoContinuationKt$transform$lambda-1$$inlined$collect$1
|
inner (anonymous) class TcoContinuationKt$transform$lambda-1$$inlined$collect$1
|
||||||
inner (anonymous) class TcoContinuationKt$transform$lambda-1$$inlined$collect$1$1
|
inner (anonymous) class TcoContinuationKt$transform$lambda-1$$inlined$collect$1$1
|
||||||
|
|||||||
Vendored
+22
@@ -0,0 +1,22 @@
|
|||||||
|
class Receiver {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useExtensionLambda(lambda: Receiver.() -> Unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
useExtensionLambda {
|
||||||
|
class NamedLocal {
|
||||||
|
fun run() {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JVM_TEMPLATES
|
||||||
|
// 1 final synthetic LReceiver; \$this_useExtensionLambda
|
||||||
|
|
||||||
|
// JVM_IR_TEMPLATES
|
||||||
|
// 1 private final synthetic LReceiver; \$this
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
class Receiver {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Receiver.bar() {
|
||||||
|
class NamedLocal {
|
||||||
|
fun run() {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JVM_TEMPLATES
|
||||||
|
// 1 final synthetic LReceiver; \$this_bar
|
||||||
|
|
||||||
|
// JVM_IR_TEMPLATES
|
||||||
|
// 1 private final synthetic LReceiver; \$this_bar
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
class Outer {
|
||||||
|
inner class Inner {
|
||||||
|
private fun bar() {
|
||||||
|
class NamedLocal {
|
||||||
|
fun run() {
|
||||||
|
innerFoo()
|
||||||
|
outerFoo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun innerFoo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun outerFoo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JVM_TEMPLATES
|
||||||
|
// 1 final synthetic LOuter\$Inner; this\$0
|
||||||
|
|
||||||
|
// JVM_IR_TEMPLATES
|
||||||
|
// 1 private final synthetic LOuter\$Inner; this\$0
|
||||||
|
// 1 private final synthetic LOuter; this\$1
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
class Receiver {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useExtensionLambda(lambda: Receiver.() -> Unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
useExtensionLambda label@ {
|
||||||
|
class NamedLocal {
|
||||||
|
fun run() {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JVM_TEMPLATES
|
||||||
|
// 1 final synthetic LReceiver; \$this_label
|
||||||
|
|
||||||
|
// JVM_IR_TEMPLATES
|
||||||
|
// 1 private final synthetic LReceiver; \$this
|
||||||
Vendored
+26
@@ -0,0 +1,26 @@
|
|||||||
|
class Foo {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bar {
|
||||||
|
fun bar() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test(bar: Bar) {
|
||||||
|
fun Bar.test() {
|
||||||
|
class Local {
|
||||||
|
fun run() {
|
||||||
|
foo()
|
||||||
|
bar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JVM_TEMPLATES
|
||||||
|
// 1 final synthetic LMultipleExtensionReceiversKt\$test\$1; this\$0
|
||||||
|
// 1 final synthetic LBar; \$this_test
|
||||||
|
|
||||||
|
// JVM_IR_TEMPLATES
|
||||||
|
// 1 private final synthetic LFoo; \$this_test
|
||||||
|
// 1 private final synthetic LBar; \$this_test\$1
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
class Outer {
|
||||||
|
inner class Inner {
|
||||||
|
private fun bar() {
|
||||||
|
class NamedLocal {
|
||||||
|
fun run() {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JVM_TEMPLATES
|
||||||
|
// 1 final synthetic LOuter\$Inner; this\$0
|
||||||
|
|
||||||
|
// JVM_IR_TEMPLATES
|
||||||
|
// 1 private final synthetic LOuter; this\$0
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
class Outer {
|
||||||
|
inner class Inner {
|
||||||
|
constructor() {
|
||||||
|
class NamedLocal {
|
||||||
|
fun foo() {
|
||||||
|
outer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun outer() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JVM_TEMPLATES
|
||||||
|
// 1 final synthetic LOuter\$Inner; this\$0
|
||||||
|
|
||||||
|
// JVM_IR_TEMPLATES
|
||||||
|
// 1 private final synthetic LOuter; this\$0
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
class Outer {
|
||||||
|
inner class Inner {
|
||||||
|
init {
|
||||||
|
class NamedLocal {
|
||||||
|
fun foo() {
|
||||||
|
outer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun outer() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JVM_TEMPLATES
|
||||||
|
// 1 final synthetic LOuter\$Inner; this\$0
|
||||||
|
|
||||||
|
// JVM_IR_TEMPLATES
|
||||||
|
// 1 private final synthetic LOuter; this\$0
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
class Host {
|
||||||
|
private fun bar() {
|
||||||
|
class NamedLocal {
|
||||||
|
fun run() {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JVM_TEMPLATES
|
||||||
|
// 1 final synthetic LHost; this\$0
|
||||||
|
|
||||||
|
// JVM_IR_TEMPLATES
|
||||||
|
// 1 private final synthetic LHost; this\$0
|
||||||
@@ -17,9 +17,10 @@ fun box(): String {
|
|||||||
return `(X)`().`(Y)`()
|
return `(X)`().`(Y)`()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JVM_TEMPLATES
|
||||||
// One instance of each is in kotlin.Metadata.d2
|
// One instance of each is in kotlin.Metadata.d2
|
||||||
// 1 \(X\)
|
// 1 \(X\)
|
||||||
// 1 \(Y\)
|
// 1 \(Y\)
|
||||||
|
|
||||||
// JVM_IR_TEMPLATES
|
// JVM_IR_TEMPLATES
|
||||||
// 4 \$this
|
// 4 this\$0
|
||||||
|
|||||||
@@ -1962,6 +1962,64 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class FieldsForCapturedValues extends AbstractBytecodeTextTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInFieldsForCapturedValues() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionLambdaExtensionReceiver.kt")
|
||||||
|
public void testExtensionLambdaExtensionReceiver() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/extensionLambdaExtensionReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionReceiver.kt")
|
||||||
|
public void testExtensionReceiver() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/extensionReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerAndOuterThis.kt")
|
||||||
|
public void testInnerAndOuterThis() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/innerAndOuterThis.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("labeledExtensionLambdaExtensionReceiver.kt")
|
||||||
|
public void testLabeledExtensionLambdaExtensionReceiver() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/labeledExtensionLambdaExtensionReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multipleExtensionReceivers.kt")
|
||||||
|
public void testMultipleExtensionReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/multipleExtensionReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outerThis.kt")
|
||||||
|
public void testOuterThis() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/outerThis.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outerThisInInnerConstructor.kt")
|
||||||
|
public void testOuterThisInInnerConstructor() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/outerThisInInnerConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outerThisInInnerInitBlock.kt")
|
||||||
|
public void testOuterThisInInnerInitBlock() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/outerThisInInnerInitBlock.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("this.kt")
|
||||||
|
public void testThis() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/this.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop")
|
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+58
@@ -1917,6 +1917,64 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class FieldsForCapturedValues extends AbstractIrBytecodeTextTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInFieldsForCapturedValues() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionLambdaExtensionReceiver.kt")
|
||||||
|
public void testExtensionLambdaExtensionReceiver() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/extensionLambdaExtensionReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionReceiver.kt")
|
||||||
|
public void testExtensionReceiver() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/extensionReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerAndOuterThis.kt")
|
||||||
|
public void testInnerAndOuterThis() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/innerAndOuterThis.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("labeledExtensionLambdaExtensionReceiver.kt")
|
||||||
|
public void testLabeledExtensionLambdaExtensionReceiver() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/labeledExtensionLambdaExtensionReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multipleExtensionReceivers.kt")
|
||||||
|
public void testMultipleExtensionReceivers() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/multipleExtensionReceivers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outerThis.kt")
|
||||||
|
public void testOuterThis() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/outerThis.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outerThisInInnerConstructor.kt")
|
||||||
|
public void testOuterThisInInnerConstructor() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/outerThisInInnerConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outerThisInInnerInitBlock.kt")
|
||||||
|
public void testOuterThisInInnerInitBlock() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/outerThisInInnerInitBlock.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("this.kt")
|
||||||
|
public void testThis() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/fieldsForCapturedValues/this.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop")
|
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user