Implement script instance capturing in script lowering
for regular classes only. Reimplementing the main behavior of the old BE and implementing few cases on top of it. #KT-19423 fixed
This commit is contained in:
committed by
TeamCityServer
parent
87952d63a3
commit
cb5e451e05
+6
-1
@@ -177,7 +177,12 @@ class ClosureAnnotator(irElement: IrElement, declaration: IrDeclaration) {
|
||||
|
||||
closureBuilder.declareVariable(this.thisReceiver)
|
||||
if (this.isInner) {
|
||||
closureBuilder.declareVariable((this.parent as IrClass).thisReceiver)
|
||||
val receiver = when (val parent = this.parent) {
|
||||
is IrClass -> parent.thisReceiver
|
||||
is IrScript -> parent.thisReceiver
|
||||
else -> error("unexpected parent $parent")
|
||||
}
|
||||
closureBuilder.declareVariable(receiver)
|
||||
includeInParent(closureBuilder)
|
||||
}
|
||||
|
||||
|
||||
+210
-89
@@ -6,9 +6,11 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.ClosureAnnotator
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeCustomPhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmInnerClassesSupport
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -19,18 +21,17 @@ import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.interpreter.toIrConst
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
@@ -42,12 +43,12 @@ internal val scriptsToClassesPhase = makeCustomPhase<JvmBackendContext, IrModule
|
||||
name = "ScriptsToClasses",
|
||||
description = "Put script declarations into classes",
|
||||
op = { context, input ->
|
||||
ScriptsToClassesLowering(context).lower(input)
|
||||
ScriptsToClassesLowering(context, context.innerClassesSupport).lower(input)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
private class ScriptsToClassesLowering(val context: JvmBackendContext) {
|
||||
private class ScriptsToClassesLowering(val context: JvmBackendContext, val innerClassesSupport: JvmInnerClassesSupport) {
|
||||
|
||||
fun lower(module: IrModuleFragment) {
|
||||
val scriptsToClasses = mutableMapOf<IrScript, IrClass>()
|
||||
@@ -89,15 +90,35 @@ private class ScriptsToClassesLowering(val context: JvmBackendContext) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun collectCapturingClasses(irScript: IrScript): Set<IrClassImpl> {
|
||||
val annotator = ClosureAnnotator(irScript, irScript)
|
||||
val capturingClasses = mutableSetOf<IrClassImpl>()
|
||||
for (clazz in irScript.statements) {
|
||||
if (clazz is IrClassImpl && !clazz.isInner ) {
|
||||
val closure = annotator.getClassClosure(clazz)
|
||||
if (closure.capturedValues.singleOrNull()?.owner?.type == irScript.thisReceiver.type) {
|
||||
if (clazz.isClass) {
|
||||
capturingClasses.add(clazz)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return capturingClasses
|
||||
}
|
||||
|
||||
private fun finalizeScriptClass(irScriptClass: IrClass, irScript: IrScript, symbolRemapper: ScriptsToClassesSymbolRemapper) {
|
||||
val typeRemapper = SimpleTypeRemapper(symbolRemapper)
|
||||
val scriptTransformer = ScriptToClassTransformer(irScript, irScriptClass, symbolRemapper, typeRemapper, context)
|
||||
val capturingClasses = collectCapturingClasses(irScript)
|
||||
val scriptTransformer = ScriptToClassTransformer(irScript, irScriptClass, symbolRemapper, typeRemapper, context, capturingClasses, innerClassesSupport)
|
||||
val lambdaPatcher = ScriptFixLambdasTransformer(irScript, irScriptClass, context)
|
||||
|
||||
fun <E: IrElement> E.patchForClass(): IrElement =
|
||||
transform(scriptTransformer, null).transform(lambdaPatcher, ScriptToClassTransformerContext())
|
||||
irScriptClass.thisReceiver = scriptTransformer.scriptClassReceiver
|
||||
|
||||
irScriptClass.thisReceiver = irScript.thisReceiver.transform(scriptTransformer, null)
|
||||
val defaultContext = ScriptToClassTransformerContext(irScriptClass.thisReceiver?.symbol, null, null)
|
||||
fun <E: IrElement> E.patchForClass(): IrElement {
|
||||
return transform(scriptTransformer, defaultContext)
|
||||
.transform(lambdaPatcher, ScriptFixLambdasTransformerContext())
|
||||
}
|
||||
|
||||
irScript.constructor?.patchForClass()?.safeAs<IrConstructor>()!!.also { constructor ->
|
||||
val explicitParamsStartIndex = if (irScript.earlierScriptsParameter == null) 0 else 1
|
||||
@@ -266,6 +287,12 @@ private class ScriptsToClassesLowering(val context: JvmBackendContext) {
|
||||
}
|
||||
|
||||
data class ScriptToClassTransformerContext(
|
||||
val valueParameterForScriptThis: IrValueParameterSymbol?,
|
||||
val fieldForScriptThis: IrFieldSymbol?,
|
||||
val valueParameterForFieldReceiver: IrValueParameterSymbol?
|
||||
)
|
||||
|
||||
data class ScriptFixLambdasTransformerContext(
|
||||
val insideTopLevelDestructuringDeclaration: Boolean = false,
|
||||
val valueParameterToReplaceWithScript: IrValueParameter? = null
|
||||
)
|
||||
@@ -275,36 +302,54 @@ private class ScriptToClassTransformer(
|
||||
val irScriptClass: IrClass,
|
||||
val symbolRemapper: SymbolRemapper,
|
||||
val typeRemapper: TypeRemapper,
|
||||
val context: JvmBackendContext
|
||||
) : IrElementTransformerVoid() {
|
||||
val context: JvmBackendContext,
|
||||
val capturingClasses: Set<IrClassImpl>,
|
||||
val innerClassesSupport: JvmInnerClassesSupport
|
||||
) : IrElementTransformer<ScriptToClassTransformerContext> {
|
||||
|
||||
private fun IrType.remapType() = typeRemapper.remapType(this)
|
||||
|
||||
val capturingClassesConstructors = mutableMapOf<IrConstructor, IrClassImpl>().apply {
|
||||
capturingClasses.forEach { c ->
|
||||
c.declarations.forEach { d ->
|
||||
if (d is IrConstructor) {
|
||||
put(d, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val scriptClassReceiver =
|
||||
irScript.thisReceiver.transform(this, ScriptToClassTransformerContext(null, null, null))
|
||||
|
||||
private fun IrDeclaration.transformParent() {
|
||||
if (parent == irScript) {
|
||||
parent = irScriptClass
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrMutableAnnotationContainer.transformAnnotations() {
|
||||
annotations = annotations.transform()
|
||||
private fun IrMutableAnnotationContainer.transformAnnotations(data: ScriptToClassTransformerContext) {
|
||||
annotations = annotations.transform(data)
|
||||
}
|
||||
|
||||
private inline fun <reified T : IrElement> T.transform() =
|
||||
transform(this@ScriptToClassTransformer, null) as T
|
||||
private inline fun <reified T : IrElement> T.transform(data: ScriptToClassTransformerContext) =
|
||||
transform(this@ScriptToClassTransformer, data) as T
|
||||
|
||||
private inline fun <reified T : IrElement> List<T>.transform() =
|
||||
map { it.transform() }
|
||||
private inline fun <reified T : IrElement> List<T>.transform(data: ScriptToClassTransformerContext) =
|
||||
map { it.transform(data) }
|
||||
|
||||
private fun <T : IrFunction> T.transformFunctionChildren(): T =
|
||||
private fun <T : IrFunction> T.transformFunctionChildren(data: ScriptToClassTransformerContext): T =
|
||||
apply {
|
||||
transformAnnotations()
|
||||
transformAnnotations(data)
|
||||
typeRemapper.withinScope(this) {
|
||||
dispatchReceiverParameter = dispatchReceiverParameter?.transform()
|
||||
extensionReceiverParameter = extensionReceiverParameter?.transform()
|
||||
dispatchReceiverParameter = dispatchReceiverParameter?.transform(data)
|
||||
val dataForChildren =
|
||||
if (dispatchReceiverParameter?.type != scriptClassReceiver.type) data
|
||||
else ScriptToClassTransformerContext(dispatchReceiverParameter!!.symbol, null, null)
|
||||
extensionReceiverParameter = extensionReceiverParameter?.transform(dataForChildren)
|
||||
returnType = returnType.remapType()
|
||||
valueParameters = valueParameters.transform()
|
||||
body = body?.transform()
|
||||
valueParameters = valueParameters.transform(dataForChildren)
|
||||
body = body?.transform(dataForChildren)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,89 +360,163 @@ private class ScriptToClassTransformer(
|
||||
private fun unexpectedElement(element: IrElement): Nothing =
|
||||
throw IllegalArgumentException("Unsupported element type: $element")
|
||||
|
||||
override fun visitElement(element: IrElement): IrElement = unexpectedElement(element)
|
||||
override fun visitElement(element: IrElement, data: ScriptToClassTransformerContext): IrElement = unexpectedElement(element)
|
||||
|
||||
override fun visitModuleFragment(declaration: IrModuleFragment): IrModuleFragment = unexpectedElement(declaration)
|
||||
override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment) = unexpectedElement(declaration)
|
||||
override fun visitFile(declaration: IrFile): IrFile = unexpectedElement(declaration)
|
||||
override fun visitScript(declaration: IrScript): IrStatement = unexpectedElement(declaration)
|
||||
override fun visitModuleFragment(declaration: IrModuleFragment, data: ScriptToClassTransformerContext): IrModuleFragment = unexpectedElement(declaration)
|
||||
override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: ScriptToClassTransformerContext) = unexpectedElement(declaration)
|
||||
override fun visitFile(declaration: IrFile, data: ScriptToClassTransformerContext): IrFile = unexpectedElement(declaration)
|
||||
override fun visitScript(declaration: IrScript, data: ScriptToClassTransformerContext): IrStatement = unexpectedElement(declaration)
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclarationBase): IrStatement = declaration.apply {
|
||||
override fun visitDeclaration(declaration: IrDeclarationBase, data: ScriptToClassTransformerContext): IrStatement = declaration.apply {
|
||||
transformParent()
|
||||
transformAnnotations()
|
||||
transformChildren(this@ScriptToClassTransformer, null)
|
||||
transformAnnotations(data)
|
||||
transformChildren(this@ScriptToClassTransformer, data)
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass): IrClass = declaration.apply {
|
||||
override fun visitClass(declaration: IrClass, data: ScriptToClassTransformerContext): IrClass = declaration.apply {
|
||||
superTypes = superTypes.map {
|
||||
it.remapType()
|
||||
}
|
||||
visitDeclaration(declaration)
|
||||
}
|
||||
|
||||
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrSimpleFunction = declaration.apply {
|
||||
transformParent()
|
||||
transformFunctionChildren()
|
||||
var dataForChildren = data
|
||||
(declaration as? IrClassImpl)?.let {
|
||||
if (it in capturingClasses) {
|
||||
it.isInner = true
|
||||
dataForChildren =
|
||||
ScriptToClassTransformerContext(
|
||||
null, innerClassesSupport.getOuterThisField(it).symbol, it.thisReceiver?.symbol
|
||||
)
|
||||
}
|
||||
}
|
||||
transformAnnotations(dataForChildren)
|
||||
transformChildren(this@ScriptToClassTransformer, dataForChildren)
|
||||
}
|
||||
|
||||
override fun visitConstructor(declaration: IrConstructor): IrConstructor = declaration.apply {
|
||||
override fun visitSimpleFunction(declaration: IrSimpleFunction, data: ScriptToClassTransformerContext): IrSimpleFunction =
|
||||
declaration.apply {
|
||||
transformParent()
|
||||
val dataForChildren =
|
||||
if (data.valueParameterForFieldReceiver?.owner?.type.let { it != null && it == this.dispatchReceiverParameter?.type })
|
||||
ScriptToClassTransformerContext(
|
||||
data.valueParameterForScriptThis, data.fieldForScriptThis, this.dispatchReceiverParameter?.symbol
|
||||
)
|
||||
else data
|
||||
transformFunctionChildren(dataForChildren)
|
||||
}
|
||||
|
||||
override fun visitConstructor(declaration: IrConstructor, data: ScriptToClassTransformerContext): IrConstructor = declaration.apply {
|
||||
if (declaration in capturingClassesConstructors) {
|
||||
declaration.dispatchReceiverParameter =
|
||||
IrValueParameterBuilder().run<IrValueParameterBuilder, IrValueParameter> {
|
||||
name = SpecialNames.THIS
|
||||
type = scriptClassReceiver.type
|
||||
declaration.factory.createValueParameter(
|
||||
startOffset, endOffset, IrDeclarationOrigin.INSTANCE_RECEIVER,
|
||||
IrValueParameterSymbolImpl(),
|
||||
name, index, type, varargElementType, isCrossInline, isNoinline, isHidden, isAssignable
|
||||
).also {
|
||||
it.parent = declaration
|
||||
}
|
||||
}
|
||||
}
|
||||
transformParent()
|
||||
transformFunctionChildren()
|
||||
transformFunctionChildren(data)
|
||||
}
|
||||
|
||||
override fun visitVariable(declaration: IrVariable): IrVariable = declaration.apply {
|
||||
override fun visitVariable(declaration: IrVariable, data: ScriptToClassTransformerContext): IrVariable = declaration.apply {
|
||||
type = type.remapType()
|
||||
visitDeclaration(declaration)
|
||||
visitDeclaration(declaration, data)
|
||||
}
|
||||
|
||||
override fun visitTypeParameter(declaration: IrTypeParameter): IrTypeParameter = declaration.apply {
|
||||
remapSuperTypes()
|
||||
visitDeclaration(declaration)
|
||||
}
|
||||
override fun visitTypeParameter(declaration: IrTypeParameter, data: ScriptToClassTransformerContext): IrTypeParameter =
|
||||
declaration.apply {
|
||||
remapSuperTypes()
|
||||
visitDeclaration(declaration, data)
|
||||
}
|
||||
|
||||
override fun visitValueParameter(declaration: IrValueParameter): IrValueParameter = declaration.apply {
|
||||
type = type.remapType()
|
||||
varargElementType = varargElementType?.remapType()
|
||||
visitDeclaration(declaration)
|
||||
}
|
||||
override fun visitValueParameter(declaration: IrValueParameter, data: ScriptToClassTransformerContext): IrValueParameter =
|
||||
declaration.apply {
|
||||
type = type.remapType()
|
||||
varargElementType = varargElementType?.remapType()
|
||||
visitDeclaration(declaration, data)
|
||||
}
|
||||
|
||||
override fun visitTypeAlias(declaration: IrTypeAlias): IrTypeAlias = declaration.apply {
|
||||
override fun visitTypeAlias(declaration: IrTypeAlias, data: ScriptToClassTransformerContext): IrTypeAlias = declaration.apply {
|
||||
expandedType = expandedType.remapType()
|
||||
visitDeclaration(declaration)
|
||||
visitDeclaration(declaration, data)
|
||||
}
|
||||
|
||||
override fun visitVararg(expression: IrVararg): IrVararg = expression.apply {
|
||||
override fun visitVararg(expression: IrVararg, data: ScriptToClassTransformerContext): IrVararg = expression.apply {
|
||||
type = type.remapType()
|
||||
varargElementType = varargElementType.remapType()
|
||||
transformChildren(this@ScriptToClassTransformer, null)
|
||||
transformChildren(this@ScriptToClassTransformer, data)
|
||||
}
|
||||
|
||||
override fun visitSpreadElement(spread: IrSpreadElement): IrSpreadElement = spread.apply {
|
||||
transformChildren(this@ScriptToClassTransformer, null)
|
||||
override fun visitSpreadElement(spread: IrSpreadElement, data: ScriptToClassTransformerContext): IrSpreadElement = spread.apply {
|
||||
transformChildren(this@ScriptToClassTransformer, data)
|
||||
}
|
||||
|
||||
override fun visitExpression(expression: IrExpression): IrExpression = expression.apply {
|
||||
override fun visitExpression(expression: IrExpression, data: ScriptToClassTransformerContext): IrExpression = expression.apply {
|
||||
type = type.remapType()
|
||||
transformChildren(this@ScriptToClassTransformer, null)
|
||||
transformChildren(this@ScriptToClassTransformer, data)
|
||||
}
|
||||
|
||||
override fun visitClassReference(expression: IrClassReference): IrClassReference = expression.apply {
|
||||
type = type.remapType()
|
||||
classType = classType.remapType()
|
||||
transformChildren(this@ScriptToClassTransformer, null)
|
||||
}
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrTypeOperatorCall = expression.apply {
|
||||
type = type.remapType()
|
||||
typeOperand = typeOperand.remapType()
|
||||
transformChildren(this@ScriptToClassTransformer, null)
|
||||
}
|
||||
|
||||
override fun visitMemberAccess(expression: IrMemberAccessExpression<*>): IrExpression = expression.apply {
|
||||
for (i in 0 until typeArgumentsCount) {
|
||||
putTypeArgument(i, getTypeArgument(i)?.remapType())
|
||||
override fun visitClassReference(expression: IrClassReference, data: ScriptToClassTransformerContext): IrClassReference =
|
||||
expression.apply {
|
||||
type = type.remapType()
|
||||
classType = classType.remapType()
|
||||
transformChildren(this@ScriptToClassTransformer, data)
|
||||
}
|
||||
visitExpression(expression)
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: ScriptToClassTransformerContext): IrTypeOperatorCall =
|
||||
expression.apply {
|
||||
type = type.remapType()
|
||||
typeOperand = typeOperand.remapType()
|
||||
transformChildren(this@ScriptToClassTransformer, data)
|
||||
}
|
||||
|
||||
override fun visitMemberAccess(expression: IrMemberAccessExpression<*>, data: ScriptToClassTransformerContext): IrExpression =
|
||||
expression.apply {
|
||||
for (i in 0 until typeArgumentsCount) {
|
||||
putTypeArgument(i, getTypeArgument(i)?.remapType())
|
||||
}
|
||||
visitExpression(expression, data)
|
||||
}
|
||||
|
||||
override fun visitConstructorCall(expression: IrConstructorCall, data: ScriptToClassTransformerContext): IrExpression {
|
||||
capturingClassesConstructors.keys.find { it.symbol == expression.symbol }?.let {
|
||||
expression.dispatchReceiver =
|
||||
getAccessCallForScriptInstance(data, expression.startOffset, expression.endOffset, expression.origin)
|
||||
}
|
||||
return super.visitConstructorCall(expression, data) as IrExpression
|
||||
}
|
||||
|
||||
private fun getAccessCallForScriptInstance(
|
||||
data: ScriptToClassTransformerContext, startOffset: Int, endOffset: Int, origin: IrStatementOrigin?
|
||||
) = when {
|
||||
data.fieldForScriptThis != null ->
|
||||
IrGetFieldImpl(
|
||||
startOffset, endOffset,
|
||||
data.fieldForScriptThis,
|
||||
scriptClassReceiver.type,
|
||||
origin
|
||||
).apply {
|
||||
receiver =
|
||||
IrGetValueImpl(
|
||||
startOffset, endOffset,
|
||||
data.valueParameterForFieldReceiver!!.owner.type,
|
||||
data.valueParameterForFieldReceiver,
|
||||
origin
|
||||
)
|
||||
}
|
||||
data.valueParameterForScriptThis != null ->
|
||||
IrGetValueImpl(
|
||||
startOffset, endOffset,
|
||||
scriptClassReceiver.type,
|
||||
data.valueParameterForScriptThis,
|
||||
origin
|
||||
)
|
||||
else -> error("Unexpected script transformation state: $data")
|
||||
}
|
||||
|
||||
private fun getAccessCallForEarlierScript(expression: IrDeclarationReference, maybeScriptType: IrType): IrExpression? {
|
||||
@@ -432,7 +551,7 @@ private class ScriptToClassTransformer(
|
||||
return null
|
||||
}
|
||||
|
||||
override fun visitGetField(expression: IrGetField): IrExpression {
|
||||
override fun visitGetField(expression: IrGetField, data: ScriptToClassTransformerContext): IrExpression {
|
||||
if (irScript.earlierScripts != null) {
|
||||
val receiver = expression.receiver
|
||||
if (receiver is IrGetValue && receiver.symbol.owner.name == SpecialNames.THIS) {
|
||||
@@ -440,14 +559,14 @@ private class ScriptToClassTransformer(
|
||||
if (newReceiver != null) {
|
||||
val newGetField =
|
||||
IrGetFieldImpl(expression.startOffset, expression.endOffset, expression.symbol, expression.type, newReceiver)
|
||||
return super.visitGetField(newGetField)
|
||||
return super.visitGetField(newGetField, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.visitGetField(expression)
|
||||
return super.visitGetField(expression, data)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
override fun visitCall(expression: IrCall, data: ScriptToClassTransformerContext): IrExpression {
|
||||
if (irScript.earlierScripts != null) {
|
||||
val target = expression.symbol.owner
|
||||
val receiver: IrValueParameter? = target.dispatchReceiverParameter
|
||||
@@ -458,34 +577,36 @@ private class ScriptToClassTransformer(
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.visitCall(expression)
|
||||
return super.visitCall(expression, data) as IrExpression
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private class ScriptFixLambdasTransformer(
|
||||
val irScript: IrScript,
|
||||
val irScriptClass: IrClass,
|
||||
val context: JvmBackendContext
|
||||
) : IrElementTransformer<ScriptToClassTransformerContext> {
|
||||
) : IrElementTransformer<ScriptFixLambdasTransformerContext> {
|
||||
|
||||
private fun unexpectedElement(element: IrElement): Nothing =
|
||||
throw IllegalArgumentException("Unsupported element type: $element")
|
||||
|
||||
override fun visitElement(element: IrElement, data: ScriptToClassTransformerContext): IrElement = unexpectedElement(element)
|
||||
override fun visitElement(element: IrElement, data: ScriptFixLambdasTransformerContext): IrElement = unexpectedElement(element)
|
||||
|
||||
override fun visitModuleFragment(declaration: IrModuleFragment, data: ScriptToClassTransformerContext): IrModuleFragment =
|
||||
override fun visitModuleFragment(declaration: IrModuleFragment, data: ScriptFixLambdasTransformerContext): IrModuleFragment =
|
||||
unexpectedElement(declaration)
|
||||
|
||||
override fun visitExternalPackageFragment(
|
||||
declaration: IrExternalPackageFragment,
|
||||
data: ScriptToClassTransformerContext
|
||||
data: ScriptFixLambdasTransformerContext
|
||||
): IrExternalPackageFragment =
|
||||
unexpectedElement(declaration)
|
||||
|
||||
override fun visitFile(declaration: IrFile, data: ScriptToClassTransformerContext): IrFile = unexpectedElement(declaration)
|
||||
override fun visitScript(declaration: IrScript, data: ScriptToClassTransformerContext): IrScript = unexpectedElement(declaration)
|
||||
override fun visitFile(declaration: IrFile, data: ScriptFixLambdasTransformerContext): IrFile = unexpectedElement(declaration)
|
||||
override fun visitScript(declaration: IrScript, data: ScriptFixLambdasTransformerContext): IrScript = unexpectedElement(declaration)
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue, data: ScriptToClassTransformerContext): IrExpression {
|
||||
override fun visitGetValue(expression: IrGetValue, data: ScriptFixLambdasTransformerContext): IrExpression {
|
||||
if (data.valueParameterToReplaceWithScript == expression.symbol.owner) {
|
||||
val newGetValue = IrGetValueImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
@@ -497,7 +618,7 @@ private class ScriptFixLambdasTransformer(
|
||||
} else return super.visitGetValue(expression, data)
|
||||
}
|
||||
|
||||
override fun visitSimpleFunction(declaration: IrSimpleFunction, data: ScriptToClassTransformerContext): IrSimpleFunction =
|
||||
override fun visitSimpleFunction(declaration: IrSimpleFunction, data: ScriptFixLambdasTransformerContext): IrSimpleFunction =
|
||||
with(declaration) {
|
||||
if (data.insideTopLevelDestructuringDeclaration && origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA) {
|
||||
visibility = DescriptorVisibilities.LOCAL
|
||||
@@ -513,7 +634,7 @@ private class ScriptFixLambdasTransformer(
|
||||
}
|
||||
} as IrSimpleFunction
|
||||
|
||||
override fun visitComposite(expression: IrComposite, data: ScriptToClassTransformerContext): IrComposite {
|
||||
override fun visitComposite(expression: IrComposite, data: ScriptFixLambdasTransformerContext): IrComposite {
|
||||
val dataForChildren =
|
||||
if (expression.origin == IrStatementOrigin.DESTRUCTURING_DECLARATION &&
|
||||
expression.statements.firstIsInstanceOrNull<IrDeclaration>()?.parent == irScriptClass
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ open class IrClassImpl(
|
||||
override var visibility: DescriptorVisibility,
|
||||
override var modality: Modality,
|
||||
override val isCompanion: Boolean = false,
|
||||
override val isInner: Boolean = false,
|
||||
override var isInner: Boolean = false,
|
||||
override val isData: Boolean = false,
|
||||
override val isExternal: Boolean = false,
|
||||
override val isInline: Boolean = false,
|
||||
|
||||
@@ -147,6 +147,7 @@ val IrDeclaration.isLocal: Boolean
|
||||
}
|
||||
|
||||
if (current.isAnonymousObject) return true
|
||||
if (current is IrScript || (current is IrClass && current.origin == IrDeclarationOrigin.SCRIPT_CLASS)) return true
|
||||
|
||||
current = current.parent
|
||||
}
|
||||
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
fun foo() = B.bar()
|
||||
|
||||
val life = 42
|
||||
|
||||
interface A {
|
||||
fun bar(): Int
|
||||
}
|
||||
|
||||
val B = object : A {
|
||||
override fun bar() = life
|
||||
}
|
||||
|
||||
val rv = foo()
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
|
||||
// expected: rv: kotlin.Unit
|
||||
|
||||
fun foo() {
|
||||
B()
|
||||
}
|
||||
val b = B()
|
||||
|
||||
class A
|
||||
fun A.ext() = Unit
|
||||
|
||||
class B {
|
||||
fun bar() {
|
||||
A().ext()
|
||||
}
|
||||
}
|
||||
|
||||
val rv = foo()
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
|
||||
// expected: rv: kotlin.Unit
|
||||
|
||||
class C {
|
||||
fun foo() {
|
||||
B()
|
||||
}
|
||||
}
|
||||
|
||||
class A
|
||||
fun A.ext() = Unit
|
||||
|
||||
class B {
|
||||
fun bar() {
|
||||
A().ext()
|
||||
}
|
||||
}
|
||||
|
||||
val rv = C().foo()
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
val x = 6
|
||||
val y = 7
|
||||
|
||||
fun foo() = x
|
||||
|
||||
class A {
|
||||
fun bar() = foo() * y
|
||||
}
|
||||
|
||||
val rv = A().bar()
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
|
||||
// expected: rv: abc
|
||||
|
||||
// KT-19423
|
||||
val used = "abc"
|
||||
class User {
|
||||
val property = used // error: Expression is inaccessible from a nested class
|
||||
}
|
||||
|
||||
val rv = User().property
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
fun foo() = B().bar()
|
||||
|
||||
val life = 42
|
||||
|
||||
class A {
|
||||
val x = "$life"
|
||||
}
|
||||
|
||||
class B {
|
||||
fun bar() = A().x
|
||||
}
|
||||
|
||||
val rv = foo()
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
fun foo() = B().bar()
|
||||
|
||||
val life = 42
|
||||
|
||||
class A {
|
||||
val x = life
|
||||
}
|
||||
|
||||
class B {
|
||||
fun bar() = A().x
|
||||
}
|
||||
|
||||
val rv = foo()
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
class C {
|
||||
fun foo() = B().bar()
|
||||
}
|
||||
|
||||
val life = 42
|
||||
|
||||
class A {
|
||||
val x = life
|
||||
}
|
||||
|
||||
class B {
|
||||
fun bar() = A().x
|
||||
}
|
||||
|
||||
val rv = C().foo()
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM, JVM_IR
|
||||
|
||||
// expected: rv: <nofield>
|
||||
|
||||
// KT-30616
|
||||
val foo = "hello"
|
||||
|
||||
class Bar(val s: String) {
|
||||
companion object {
|
||||
fun t() {
|
||||
Bar(foo)
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM, JVM_IR
|
||||
|
||||
// expected: rv: <nofield>
|
||||
|
||||
// KT-30616
|
||||
val foo = "hello"
|
||||
|
||||
enum class Bar(val s: String = foo) {
|
||||
|
||||
Eleven("0")
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM, JVM_IR
|
||||
|
||||
// expected: rv: <nofield>
|
||||
|
||||
// KT-30616
|
||||
val foo = "hello"
|
||||
|
||||
enum class Bar(val s: String) {
|
||||
Eleven(s = foo)
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM, JVM_IR
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
fun foo() = B().bar()
|
||||
|
||||
val life = 42
|
||||
|
||||
interface A {
|
||||
val x get() = life
|
||||
}
|
||||
|
||||
class B : A {
|
||||
fun bar() = x
|
||||
}
|
||||
|
||||
val rv = foo()
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM, JVM_IR
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
fun foo() = B.bar()
|
||||
|
||||
val life = 42
|
||||
|
||||
object B {
|
||||
fun bar() = life
|
||||
}
|
||||
|
||||
val rv = foo()
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM, JVM_IR
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
fun foo() = B.bar()
|
||||
|
||||
val life = 42
|
||||
|
||||
class A {
|
||||
val x = life
|
||||
}
|
||||
|
||||
object B {
|
||||
fun bar() = A().x
|
||||
}
|
||||
|
||||
val rv = foo()
|
||||
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
// expected: rv: <nofield>
|
||||
|
||||
// This example shows a bug in the old BE
|
||||
// original issue - KT-49443, this is the reduced example of it.
|
||||
// Here the old BE manages to compile the script, because it assumes incorrect constructor of the DefaultEachEntryConfiguration class
|
||||
// on generating code for buildZip.
|
||||
// The original example from the issue works supposedly because the constructor is not called on the runtime.
|
||||
// In this example, uncommenting call to buildZip leads to the runtime exception, while uncommenting the call to copy or
|
||||
// moving DefaultEachEntryConfiguration class definition before ZipHelper breaks codegeneration (somewhat expectedly).
|
||||
// The JVM IR BE now generates correct error about invalid script instance capturing.
|
||||
|
||||
interface I {
|
||||
fun rename()
|
||||
}
|
||||
|
||||
object ZipHelper {
|
||||
fun buildZip() {
|
||||
DefaultEachEntryConfiguration(0).rename()
|
||||
// 0.copy()
|
||||
}
|
||||
}
|
||||
|
||||
class DefaultEachEntryConfiguration(val entry: Int) : I {
|
||||
override fun rename() {
|
||||
entry.copy()
|
||||
}
|
||||
}
|
||||
|
||||
fun Int.copy() = Unit
|
||||
|
||||
//ZipHelper.buildZip()
|
||||
+1
-1
@@ -107,7 +107,7 @@ fun generateJUnit3CompilerTests(args: Array<String>) {
|
||||
}
|
||||
|
||||
testClass<AbstractScriptCodegenTest> {
|
||||
model("codegen/script", extension = "kts")
|
||||
model("codegen/script", extension = "kts", targetBackend = TargetBackend.JVM)
|
||||
}
|
||||
|
||||
testClass<AbstractCustomScriptCodegenTest> {
|
||||
|
||||
+91
-2
@@ -9,6 +9,7 @@ import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -22,7 +23,7 @@ import java.util.regex.Pattern;
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class ScriptCodegenTestGenerated extends AbstractScriptCodegenTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("adder.kts")
|
||||
@@ -31,7 +32,7 @@ public class ScriptCodegenTestGenerated extends AbstractScriptCodegenTest {
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInScript() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script"), Pattern.compile("^(.+)\\.kts$"), null, true);
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script"), Pattern.compile("^(.+)\\.kts$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classLiteralInsideFunction.kts")
|
||||
@@ -183,4 +184,92 @@ public class ScriptCodegenTestGenerated extends AbstractScriptCodegenTest {
|
||||
public void testTopLevelTypealias() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/topLevelTypealias.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/script/scriptInstanceCapturing")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ScriptInstanceCapturing extends AbstractScriptCodegenTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInScriptInstanceCapturing() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script/scriptInstanceCapturing"), Pattern.compile("^(.+)\\.kts$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousObjectCapturesProperty.kts")
|
||||
public void testAnonymousObjectCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/anonymousObjectCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesExtensionIndirect.kts")
|
||||
public void testClassCapturesExtensionIndirect() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesExtensionIndirect.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesExtensionIndirect2x.kts")
|
||||
public void testClassCapturesExtensionIndirect2x() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesExtensionIndirect2x.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesFunction.kts")
|
||||
public void testClassCapturesFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesFunction.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesProperty.kts")
|
||||
public void testClassCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesPropertyInStringTemplate.kts")
|
||||
public void testClassCapturesPropertyInStringTemplate() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesPropertyInStringTemplate.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesPropertyIndirect.kts")
|
||||
public void testClassCapturesPropertyIndirect() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesPropertyIndirect.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesPropertyIndirect2x.kts")
|
||||
public void testClassCapturesPropertyIndirect2x() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesPropertyIndirect2x.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("companionCapturesProperty.kts")
|
||||
public void testCompanionCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/companionCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("enumCapturesProperty.kts")
|
||||
public void testEnumCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/enumCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("enumEntryCapturesProperty.kts")
|
||||
public void testEnumEntryCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/enumEntryCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("interfaceCapturesProperty.kts")
|
||||
public void testInterfaceCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/interfaceCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("objectCapturesProperty.kts")
|
||||
public void testObjectCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/objectCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("objectCapturesPropertyIndirect.kts")
|
||||
public void testObjectCapturesPropertyIndirect() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/objectCapturesPropertyIndirect.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("objectCapturesPropertyViaExtension.kts")
|
||||
public void testObjectCapturesPropertyViaExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/objectCapturesPropertyViaExtension.kts");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+88
@@ -184,4 +184,92 @@ public class IrScriptCodegenTestGenerated extends AbstractIrScriptCodegenTest {
|
||||
public void testTopLevelTypealias() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/topLevelTypealias.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/script/scriptInstanceCapturing")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ScriptInstanceCapturing extends AbstractIrScriptCodegenTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInScriptInstanceCapturing() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script/scriptInstanceCapturing"), Pattern.compile("^(.+)\\.kts$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousObjectCapturesProperty.kts")
|
||||
public void testAnonymousObjectCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/anonymousObjectCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesExtensionIndirect.kts")
|
||||
public void testClassCapturesExtensionIndirect() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesExtensionIndirect.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesExtensionIndirect2x.kts")
|
||||
public void testClassCapturesExtensionIndirect2x() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesExtensionIndirect2x.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesFunction.kts")
|
||||
public void testClassCapturesFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesFunction.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesProperty.kts")
|
||||
public void testClassCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesPropertyInStringTemplate.kts")
|
||||
public void testClassCapturesPropertyInStringTemplate() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesPropertyInStringTemplate.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesPropertyIndirect.kts")
|
||||
public void testClassCapturesPropertyIndirect() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesPropertyIndirect.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("classCapturesPropertyIndirect2x.kts")
|
||||
public void testClassCapturesPropertyIndirect2x() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesPropertyIndirect2x.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("companionCapturesProperty.kts")
|
||||
public void testCompanionCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/companionCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("enumCapturesProperty.kts")
|
||||
public void testEnumCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/enumCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("enumEntryCapturesProperty.kts")
|
||||
public void testEnumEntryCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/enumEntryCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("interfaceCapturesProperty.kts")
|
||||
public void testInterfaceCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/interfaceCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("objectCapturesProperty.kts")
|
||||
public void testObjectCapturesProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/objectCapturesProperty.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("objectCapturesPropertyIndirect.kts")
|
||||
public void testObjectCapturesPropertyIndirect() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/objectCapturesPropertyIndirect.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("objectCapturesPropertyViaExtension.kts")
|
||||
public void testObjectCapturesPropertyViaExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/objectCapturesPropertyViaExtension.kts");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user