Implement JVM IR support for scripts

This commit is contained in:
Ilya Chernikov
2020-08-31 12:09:43 +02:00
parent 01d73ba0fc
commit d7112a4500
27 changed files with 924 additions and 65 deletions
@@ -242,6 +242,7 @@ class GenerationState private constructor(
var earlierScriptsForReplInterpreter: List<ScriptDescriptor>? = null
// and the rest is an output from the codegen
var resultFieldName: String? = null
var resultTypeString: String? = null
var resultType: KotlinType? = null
}
@@ -37,7 +37,8 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.OUTPUT
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
import org.jetbrains.kotlin.cli.common.output.writeAll
@@ -616,17 +617,8 @@ object KotlinToJVMBytecodeCompiler {
sourceFiles: List<KtFile>,
module: Module?
): GenerationState {
// The IR backend does not handle .kts files yet.
var isIR = (configuration.getBoolean(JVMConfigurationKeys.IR) ||
val isIR = (configuration.getBoolean(JVMConfigurationKeys.IR) ||
configuration.getBoolean(CommonConfigurationKeys.USE_FIR))
val anyKts = sourceFiles.any { it.isScript() }
if (isIR && anyKts) {
environment.messageCollector.report(
STRONG_WARNING,
"IR backend does not support .kts scripts, switching to old JVM backend"
)
isIR = false
}
val generationState = GenerationState.Builder(
environment.project,
ClassBuilderFactories.BINARIES,
@@ -48,7 +48,10 @@ class CreateScriptFunctionsPhase(val context: CommonBackendContext) : FileLoweri
it.body = it.factory.createBlockBody(
startOffset,
endOffset,
initializeStatements.map { (field, expression) -> createIrSetField(field, expression) }
initializeStatements.let {
if (irScript.resultProperty == null || initializeStatements.lastOrNull()?.first?.correspondingPropertySymbol != irScript.resultProperty) it
else it.dropLast(1)
}.map { (field, expression) -> createIrSetField(field, expression) }
)
}
@@ -56,7 +59,16 @@ class CreateScriptFunctionsPhase(val context: CommonBackendContext) : FileLoweri
it.body = it.factory.createBlockBody(
startOffset,
endOffset,
irScript.statements.filter { it !is IrDeclaration }.prepareForEvaluateScriptFunction(it)
irScript.statements.filter { it !is IrDeclaration }
.let {
val lastInitializer = initializeStatements.lastOrNull()
if (lastInitializer == null || irScript.resultProperty == null
|| lastInitializer.first.correspondingPropertySymbol != irScript.resultProperty) {
it
} else {
it + lastInitializer.second
}
}.prepareForEvaluateScriptFunction(it)
)
}
@@ -389,6 +389,7 @@ val jvmPhases = NamedCompilerPhase(
lower = validateIrBeforeLowering then
processOptionalAnnotationsPhase then
expectDeclarationsRemovingPhase then
scriptToClassPhase then
fileClassPhase then
performByIrFile(lower = jvmFilePhases) then
generateMultifileFacadesPhase then
@@ -50,7 +50,7 @@ internal val fileClassPhase = makeIrModulePhase(
stickyPostconditions = setOf(::checkAllFileLevelDeclarationsAreClasses)
)
private fun checkAllFileLevelDeclarationsAreClasses(irModuleFragment: IrModuleFragment) {
internal fun checkAllFileLevelDeclarationsAreClasses(irModuleFragment: IrModuleFragment) {
assert(irModuleFragment.files.all { irFile ->
irFile.declarations.all { it is IrClass }
})
@@ -62,10 +62,11 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa
val fileClassMembers = ArrayList<IrDeclaration>()
irFile.declarations.forEach {
if (it is IrClass)
classes.add(it)
else
fileClassMembers.add(it)
when (it) {
is IrScript -> {}
is IrClass -> classes.add(it)
else -> fileClassMembers.add(it)
}
}
// TODO FirMetadataSource.File
@@ -0,0 +1,386 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.*
import org.jetbrains.kotlin.ir.builders.irBlockBody
import org.jetbrains.kotlin.ir.builders.irDelegatingConstructorCall
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.transformStatement
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrTypeAbbreviationImpl
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
internal val scriptToClassPhase = makeIrModulePhase(
::ScriptToClassLowering,
name = "ScriptToClass",
description = "Put script declarations into a class",
stickyPostconditions = setOf(::checkAllFileLevelDeclarationsAreClasses)
)
private class ScriptToClassLowering(val context: JvmBackendContext) : FileLoweringPass {
override fun lower(irFile: IrFile) {
irFile.declarations.replaceAll { declaration ->
if (declaration is IrScript) makeScriptClass(irFile, declaration)
else declaration
}
}
private fun makeScriptClass(irFile: IrFile, irScript: IrScript): IrClass {
val fileEntry = irFile.fileEntry
return context.irFactory.buildClass {
startOffset = 0
endOffset = fileEntry.maxOffset
origin = IrDeclarationOrigin.SCRIPT_CLASS
name = irScript.name
kind = ClassKind.CLASS
visibility = DescriptorVisibilities.PUBLIC
modality = Modality.FINAL
}.also { irScriptClass ->
irScriptClass.superTypes += context.irBuiltIns.anyType
irScriptClass.parent = irFile
irScriptClass.createImplicitParameterDeclarationWithWrappedDescriptor()
val symbolRemapper = ScriptToClassSymbolRemapper(irScript.symbol, irScriptClass.symbol)
val typeRemapper = ScriptTypeRemapper(symbolRemapper)
val scriptTransformer = ScriptToClassTransformer(irScript, irScriptClass, symbolRemapper, typeRemapper)
irScriptClass.thisReceiver = irScript.thisReceiver.run {
transform(scriptTransformer, null)
}
irScriptClass.addConstructor {
isPrimary = true
}.also { irConstructor ->
irScript.explicitCallParameters.forEach { scriptCallParameter ->
val callParameter = irConstructor.addValueParameter {
updateFrom(scriptCallParameter)
name = scriptCallParameter.name
}
irScriptClass.addSimplePropertyFrom(
callParameter,
IrExpressionBodyImpl(
IrGetValueImpl(
callParameter.startOffset, callParameter.endOffset,
callParameter.type,
callParameter.symbol,
IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
)
)
)
}
irConstructor.body = context.createIrBuilder(irConstructor.symbol).irBlockBody {
+irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
+IrInstanceInitializerCallImpl(
irScript.startOffset, irScript.endOffset,
irScriptClass.symbol,
context.irBuiltIns.unitType
)
}
}
irScript.statements.forEach { scriptStatement ->
when (scriptStatement) {
is IrVariable -> irScriptClass.addSimplePropertyFrom(scriptStatement)
is IrDeclaration -> {
val copy = scriptStatement.transform(scriptTransformer, null) as IrDeclaration
irScriptClass.declarations.add(copy)
}
else -> {
val transformedStatement = scriptStatement.transformStatement(scriptTransformer)
irScriptClass.addAnonymousInitializer().also { irInitializer ->
irInitializer.body =
context.createIrBuilder(irInitializer.symbol).irBlockBody {
if (transformedStatement is IrComposite) {
for (statement in transformedStatement.statements)
+statement
} else {
+transformedStatement
}
}
}
}
}
}
irScriptClass.annotations += irFile.annotations
irScriptClass.metadata = irFile.metadata
irScript.resultProperty?.owner?.let { irResultProperty ->
context.state.scriptSpecific.resultFieldName = irResultProperty.name.identifier
context.state.scriptSpecific.resultTypeString = irResultProperty.backingField?.type?.render()
}
}
}
private fun IrClass.addSimplePropertyFrom(
from: IrValueDeclaration,
initializer: IrExpressionBodyImpl? = null
) {
addProperty {
updateFrom(from)
name = from.name
}.also { property ->
property.backingField = context.irFactory.buildField {
name = from.name
type = from.type
visibility = DescriptorVisibilities.PROTECTED
}.also { field ->
field.parent = this
if (initializer != null) {
field.initializer = initializer
}
property.addSimpleFieldGetter(from.type, this, field)
}
}
}
private fun IrProperty.addSimpleFieldGetter(type: IrType, irScriptClass: IrClass, field: IrField) =
addGetter {
returnType = type
}.apply {
dispatchReceiverParameter = irScriptClass.thisReceiver!!.copyTo(this)
body = IrBlockBodyImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf(
IrReturnImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
context.irBuiltIns.nothingType,
symbol,
IrGetFieldImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
field.symbol,
type,
IrGetValueImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
dispatchReceiverParameter!!.type,
dispatchReceiverParameter!!.symbol
)
)
)
)
)
}
}
private class ScriptToClassTransformer(
val irScript: IrScript,
val irScriptClass: IrClass,
val symbolRemapper: SymbolRemapper = ScriptToClassSymbolRemapper(irScript.symbol, irScriptClass.symbol),
val typeRemapper: TypeRemapper = ScriptTypeRemapper(symbolRemapper)
) : IrElementTransformerVoid() {
private fun IrType.remapType() = typeRemapper.remapType(this)
private fun IrDeclaration.transformParent() {
if (parent == irScript) {
parent = irScriptClass
}
}
private fun IrMutableAnnotationContainer.transformAnnotations() {
annotations = annotations.transform()
}
private inline fun <reified T : IrElement> T.transform() =
transform(this@ScriptToClassTransformer, null) as T
private inline fun <reified T : IrElement> List<T>.transform() =
map { it.transform() }
private fun <T : IrFunction> T.transformFunctionChildren(): T =
apply {
transformAnnotations()
typeRemapper.withinScope(this) {
dispatchReceiverParameter = dispatchReceiverParameter?.transform()
extensionReceiverParameter = extensionReceiverParameter?.transform()
returnType = returnType.remapType()
valueParameters = valueParameters.transform()
body = body?.transform()
}
}
private fun IrTypeParameter.remapSuperTypes(): IrTypeParameter = apply {
superTypes = superTypes.map { it.remapType() }
}
private fun unexpectedElement(element: IrElement): Nothing =
throw IllegalArgumentException("Unsupported element type: $element")
override fun visitElement(element: IrElement): 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 visitDeclaration(declaration: IrDeclarationBase): IrStatement = declaration.apply {
transformParent()
transformAnnotations()
transformChildren(this@ScriptToClassTransformer, null)
}
override fun visitClass(declaration: IrClass): IrClass = declaration.apply {
superTypes = superTypes.map {
it.remapType()
}
visitDeclaration(declaration)
}
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrSimpleFunction = declaration.apply {
transformParent()
transformFunctionChildren()
// transformChildren(this@ScriptToClassTransformer, null)
}
override fun visitConstructor(declaration: IrConstructor): IrConstructor = declaration.apply {
transformParent()
transformFunctionChildren()
}
override fun visitVariable(declaration: IrVariable): IrVariable = declaration.apply {
type = type.remapType()
visitDeclaration(declaration)
}
override fun visitTypeParameter(declaration: IrTypeParameter): IrTypeParameter = declaration.apply {
remapSuperTypes()
visitDeclaration(declaration)
}
override fun visitValueParameter(declaration: IrValueParameter): IrValueParameter = declaration.apply {
type = type.remapType()
varargElementType = varargElementType?.remapType()
visitDeclaration(declaration)
}
override fun visitTypeAlias(declaration: IrTypeAlias): IrTypeAlias = declaration.apply {
expandedType = expandedType.remapType()
visitDeclaration(declaration)
}
override fun visitVararg(expression: IrVararg): IrVararg = expression.apply {
type = type.remapType()
varargElementType = varargElementType.remapType()
transformChildren(this@ScriptToClassTransformer, null)
}
override fun visitSpreadElement(spread: IrSpreadElement): IrSpreadElement = spread.apply {
transformChildren(this@ScriptToClassTransformer, null)
}
override fun visitExpression(expression: IrExpression): IrExpression = expression.apply {
type = type.remapType()
transformChildren(this@ScriptToClassTransformer, null)
}
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())
}
visitExpression(expression)
}
}
private class ScriptToClassSymbolRemapper(
val irScriptSymbol: IrScriptSymbol,
val irScriptClassSymbol: IrClassSymbol
) : SymbolRemapper.Empty() {
override fun getReferencedClassifier(symbol: IrClassifierSymbol): IrClassifierSymbol =
if (symbol != irScriptSymbol) symbol
else irScriptClassSymbol
}
class ScriptTypeRemapper(
private val symbolRemapper: SymbolRemapper
) : TypeRemapper {
override fun enterScope(irTypeParametersContainer: IrTypeParametersContainer) {
// TODO
}
override fun leaveScope() {
// TODO
}
override fun remapType(type: IrType): IrType =
if (type !is IrSimpleType)
type
else {
val symbol = symbolRemapper.getReferencedClassifier(type.classifier)
val arguments = type.arguments.map { remapTypeArgument(it) }
if (symbol == type.classifier && arguments == type.arguments)
type
else {
IrSimpleTypeImpl(
null,
symbol,
type.hasQuestionMark,
arguments,
type.annotations,
type.abbreviation?.remapTypeAbbreviation()
)
}
}
private fun remapTypeArgument(typeArgument: IrTypeArgument): IrTypeArgument =
if (typeArgument is IrTypeProjection)
makeTypeProjection(this.remapType(typeArgument.type), typeArgument.variance)
else
typeArgument
private fun IrTypeAbbreviation.remapTypeAbbreviation() =
IrTypeAbbreviationImpl(
symbolRemapper.getReferencedTypeAlias(typeAlias),
hasQuestionMark,
arguments.map { remapTypeArgument(it) },
annotations
)
}
private inline fun IrClass.addAnonymousInitializer(builder: IrFunctionBuilder.() -> Unit = {}): IrAnonymousInitializer =
IrFunctionBuilder().run {
builder()
returnType = defaultType
IrAnonymousInitializerImpl(
startOffset, endOffset, origin,
IrAnonymousInitializerSymbolImpl(WrappedClassDescriptor())
)
}.also { anonymousInitializer ->
declarations.add(anonymousInitializer)
anonymousInitializer.parent = this@addAnonymousInitializer
}
@@ -69,26 +69,32 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
irValueParameter: IrValueParameter?, generateSyntheticAccessors: Boolean = false
): IrProperty {
val irPropertyType = propertyDescriptor.type.toIrType()
return generateSyntheticPropertyWithInitializer(ktDeclarationContainer, propertyDescriptor, generateSyntheticAccessors) {
if (irValueParameter == null) null
else {
context.irFactory.createExpressionBody(
IrGetValueImpl(
ktDeclarationContainer.startOffsetSkippingComments, ktDeclarationContainer.endOffset,
irPropertyType,
irValueParameter.symbol,
IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
)
)
}
}
}
fun generateSyntheticPropertyWithInitializer(
ktDeclarationContainer: KtElement, propertyDescriptor: PropertyDescriptor,
generateSyntheticAccessors: Boolean, generateInitializer: (IrField) -> IrExpressionBody?
): IrProperty {
return context.symbolTable.declareProperty(
ktDeclarationContainer.startOffsetSkippingComments, ktDeclarationContainer.endOffset,
IrDeclarationOrigin.DEFINED,
propertyDescriptor,
isDelegated = false
).also { irProperty ->
irProperty.backingField =
generatePropertyBackingField(ktDeclarationContainer, propertyDescriptor) {
if (irValueParameter == null) null
else {
context.irFactory.createExpressionBody(
IrGetValueImpl(
ktDeclarationContainer.startOffsetSkippingComments, ktDeclarationContainer.endOffset,
irPropertyType,
irValueParameter.symbol,
IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
)
)
}
}
irProperty.backingField = generatePropertyBackingField(ktDeclarationContainer, propertyDescriptor, generateInitializer)
val getter = propertyDescriptor.getter
?: if (generateSyntheticAccessors)
@@ -5,24 +5,17 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.assertCast
import org.jetbrains.kotlin.ir.builders.declarations.IrFunctionBuilder
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyFunction
import org.jetbrains.kotlin.ir.descriptors.WrappedFunctionDescriptorWithContainerSource
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.util.varargElementType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtScript
import org.jetbrains.kotlin.psi.KtScriptInitializer
@@ -46,7 +39,11 @@ class ScriptGenerator(declarationGenerator: DeclarationGenerator) : DeclarationG
// TODO: since script could reference instances of previous one their receivers have to be enlisted in its scope
// Remove this code once script is no longer represented by Class
existedScripts.forEach { context.symbolTable.introduceValueParameter(it.owner.thisReceiver) }
existedScripts.forEach {
if (it.owner != irScript) {
context.symbolTable.introduceValueParameter(it.owner.thisReceiver)
}
}
val startOffset = ktScript.pureStartOffset
val endOffset = ktScript.pureEndOffset
@@ -63,13 +60,33 @@ class ScriptGenerator(declarationGenerator: DeclarationGenerator) : DeclarationG
irScript.thisReceiver = makeReceiver(descriptor)
irScript.baseClass = descriptor.typeConstructor.supertypes.single().toIrType()
irScript.implicitReceivers = descriptor.implicitReceivers.map(::makeReceiver)
for (d in ktScript.declarations) {
when (d) {
is KtScriptInitializer -> {
irScript.statements += BodyGenerator(
val irExpressionBody = BodyGenerator(
irScript.symbol,
context
).generateExpressionBody(d.body!!).expression
).generateExpressionBody(d.body!!)
if (d == ktScript.declarations.last() && descriptor.resultValue != null) {
descriptor.resultValue!!.let { resultDescriptor ->
PropertyGenerator(declarationGenerator)
.generateSyntheticPropertyWithInitializer(ktScript, resultDescriptor, generateSyntheticAccessors = true) {
// TODO: check if this is a correct place to do it
it.visibility = DescriptorVisibilities.PUBLIC
irExpressionBody
}.also {
it.origin = IrDeclarationOrigin.SCRIPT_RESULT_PROPERTY
irScript.statements += it
irScript.resultProperty = it.symbol
}
}
} else {
irScript.statements += irExpressionBody.expression
}
}
is KtDestructuringDeclaration -> {
// copied with modifications from StatementGenerator.visitDestructuringDeclaration
@@ -130,14 +147,17 @@ class ScriptGenerator(declarationGenerator: DeclarationGenerator) : DeclarationG
}
}
descriptor.resultValue?.let { resultDescriptor ->
irScript.explicitCallParameters = descriptor.unsubstitutedPrimaryConstructor.valueParameters.map { valueParameterDescriptor ->
valueParameterDescriptor.toIrValueParameter(startOffset, endOffset, IrDeclarationOrigin.SCRIPT_CALL_PARAMETER)
}
irScript.providedProperties = descriptor.scriptProvidedProperties.map { providedProperty ->
// TODO: initializer
// TODO: do not keet direct link
val resultProperty =
PropertyGenerator(declarationGenerator)
.generateSyntheticProperty(ktScript, resultDescriptor, null, generateSyntheticAccessors = true)
resultProperty.origin = IrDeclarationOrigin.SCRIPT_RESULT_PROPERTY
irScript.statements += resultProperty
// TODO: do not keep direct links
val irProperty = PropertyGenerator(declarationGenerator).generateSyntheticProperty(ktScript, providedProperty, null)
irProperty.origin = IrDeclarationOrigin.SCRIPT_PROVIDED_PROPERTY
irScript.statements += irProperty
irProperty.symbol
}
}
}
@@ -38,6 +38,12 @@ interface IrDeclarationOrigin {
object FILE_CLASS : IrDeclarationOriginImpl("FILE_CLASS")
object SYNTHETIC_FILE_CLASS : IrDeclarationOriginImpl("SYNTHETIC_FILE_CLASS", isSynthetic = true)
object SCRIPT_CLASS : IrDeclarationOriginImpl("SCRIPT_CLASS")
object SCRIPT_STATEMENT : IrDeclarationOriginImpl("SCRIPT_STATEMENT")
object SCRIPT_CALL_PARAMETER : IrDeclarationOriginImpl("SCRIPT_CALL_PARAMETER")
object SCRIPT_IMPLICIT_RECEIVER : IrDeclarationOriginImpl("SCRIPT_IMPLICIT_RECEIVER")
object SCRIPT_PROVIDED_PROPERTY : IrDeclarationOriginImpl("SCRIPT_PROVIDED_PROPERTY")
object SCRIPT_RESULT_PROPERTY : IrDeclarationOriginImpl("SCRIPT_RESULT_PROPERTY")
object GENERATED_DATA_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_DATA_CLASS_MEMBER")
object GENERATED_INLINE_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_INLINE_CLASS_MEMBER")
object LOCAL_FUNCTION_FOR_LAMBDA : IrDeclarationOriginImpl("LOCAL_FUNCTION_FOR_LAMBDA")
@@ -6,7 +6,9 @@
package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.ir.expressions.IrStatementContainer
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
import org.jetbrains.kotlin.ir.types.IrType
//TODO: make IrScript as IrPackageFragment, because script is used as a file, not as a class
//NOTE: declarations and statements stored separately
@@ -15,5 +17,16 @@ abstract class IrScript :
IrDeclarationParent, IrStatementContainer {
// NOTE: is the result of the FE conversion, because there script interpreted as a class and has receiver
// TODO: consider removing from here and handle appropriately in the lowering
abstract var thisReceiver: IrValueParameter
abstract var baseClass: IrType
abstract var explicitCallParameters: List<IrValueParameter>
abstract var implicitReceivers: List<IrValueParameter>
abstract var providedProperties: List<IrPropertySymbol>
abstract var resultProperty: IrPropertySymbol?
}
@@ -11,7 +11,9 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.transformInPlace
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -42,6 +44,12 @@ class IrScriptImpl(
override lateinit var thisReceiver: IrValueParameter
override lateinit var baseClass: IrType
override lateinit var explicitCallParameters: List<IrValueParameter>
override lateinit var implicitReceivers: List<IrValueParameter>
override lateinit var providedProperties: List<IrPropertySymbol>
override var resultProperty: IrPropertySymbol? = null
@ObsoleteDescriptorBasedAPI
override val descriptor: ScriptDescriptor
get() = symbol.descriptor
@@ -10,8 +10,8 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.classifierOrFail
@@ -644,6 +644,110 @@ open class WrappedClassDescriptor : ClassDescriptor, WrappedDeclarationDescripto
}
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
open class WrappedScriptDescriptor : ScriptDescriptor, WrappedDeclarationDescriptor<IrScript>() {
override fun getName() = owner.name
override fun getMemberScope(typeArguments: MutableList<out TypeProjection>) = MemberScope.Empty
override fun getMemberScope(typeSubstitution: TypeSubstitution) = MemberScope.Empty
override fun getUnsubstitutedMemberScope() = MemberScope.Empty
override fun getUnsubstitutedInnerClassesScope() = MemberScope.Empty
override fun getStaticScope() = MemberScope.Empty
override fun getSource(): SourceElement = SourceElement.NO_SOURCE
override fun getConstructors() =
owner.statements.filterIsInstance<IrConstructor>().filter { !it.origin.isSynthetic }.map { it.descriptor }.toList()
override fun getContainingDeclaration() = (owner.parent as IrSymbolOwner).symbol.descriptor
private val _defaultType: SimpleType by lazy {
TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope, KotlinTypeFactory.EMPTY_REFINED_TYPE_FACTORY)
}
override fun getDefaultType(): SimpleType = _defaultType
override fun getKind() = TODO()
override fun getModality() = TODO()
override fun getCompanionObjectDescriptor() = owner.statements.filterIsInstance<IrClass>().firstOrNull { it.isCompanion }?.descriptor
override fun getVisibility() = TODO()
override fun isCompanionObject() = false
override fun isData() = false
override fun isInline() = false
override fun isFun() = false
override fun getThisAsReceiverParameter() = owner.thisReceiver.descriptor as ReceiverParameterDescriptor
override fun getUnsubstitutedPrimaryConstructor() = TODO()
override fun getDeclaredTypeParameters() = TODO()
override fun getSealedSubclasses(): Collection<ClassDescriptor> {
TODO("not implemented")
}
override fun getOriginal() = this
override fun isExpect() = false
override fun substitute(substitutor: TypeSubstitutor): ClassifierDescriptorWithTypeParameters =
throw UnsupportedOperationException("Wrapped descriptors SHOULD NOT be substituted")
override fun isInner(): Boolean {
TODO("Not yet implemented")
}
override fun isActual() = false
override fun isExternal(): Boolean {
TODO("Not yet implemented")
}
override fun getTypeConstructor(): TypeConstructor = TODO()
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R =
visitor!!.visitClassDescriptor(this, data)
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
visitor!!.visitClassDescriptor(this, null)
}
override fun getDefaultFunctionTypeForSamInterface(): SimpleType? {
TODO("not implemented")
}
override fun isDefinitelyNotSamInterface(): Boolean {
TODO("Not yet implemented")
}
override fun getPriority(): Int {
TODO("Not yet implemented")
}
override fun getImplicitReceivers(): MutableList<ClassDescriptor> {
TODO("Not yet implemented")
}
override fun getScriptProvidedProperties(): MutableList<PropertyDescriptor> {
TODO("Not yet implemented")
}
override fun getResultValue(): PropertyDescriptor? {
TODO("Not yet implemented")
}
}
class LazyTypeConstructor(
val classDescriptor: ClassDescriptor,
val parametersBuilder: () -> List<TypeParameterDescriptor>,
@@ -69,7 +69,7 @@ interface IrClassifierSymbol : IrSymbol, TypeConstructorMarker {
interface IrClassSymbol : IrClassifierSymbol, IrBindableSymbol<ClassDescriptor, IrClass>
interface IrScriptSymbol : IrSymbol, IrBindableSymbol<ScriptDescriptor, IrScript>
interface IrScriptSymbol : IrClassifierSymbol, IrBindableSymbol<ScriptDescriptor, IrScript>
interface IrTypeParameterSymbol : IrClassifierSymbol, IrBindableSymbol<TypeParameterDescriptor, IrTypeParameter>, TypeParameterMarker
@@ -114,8 +114,7 @@ open class DeepCopyIrTreeWithSymbols(
override fun visitScript(declaration: IrScript): IrStatement {
return IrScriptImpl(
//TODO: something may go wrong, because expected using symbolRemapper
IrScriptSymbolImpl(declaration.descriptor as ScriptDescriptor),
symbolRemapper.getDeclaredScript(declaration.symbol),
declaration.name
).also { scriptCopy ->
scriptCopy.thisReceiver = declaration.thisReceiver.transform()
@@ -33,6 +33,7 @@ open class DeepCopySymbolRemapper(
) : IrElementVisitorVoid, SymbolRemapper {
private val classes = hashMapOf<IrClassSymbol, IrClassSymbol>()
private val scripts = hashMapOf<IrScriptSymbol, IrScriptSymbol>()
private val constructors = hashMapOf<IrConstructorSymbol, IrConstructorSymbol>()
private val enumEntries = hashMapOf<IrEnumEntrySymbol, IrEnumEntrySymbol>()
private val externalPackageFragments = hashMapOf<IrExternalPackageFragmentSymbol, IrExternalPackageFragmentSymbol>()
@@ -64,6 +65,13 @@ open class DeepCopySymbolRemapper(
declaration.acceptChildrenVoid(this)
}
override fun visitScript(declaration: IrScript) {
remapSymbol(scripts, declaration) {
IrScriptSymbolImpl(descriptorsRemapper.remapDeclaredScript(it.descriptor))
}
declaration.acceptChildrenVoid(this)
}
override fun visitConstructor(declaration: IrConstructor) {
remapSymbol(constructors, declaration) {
IrConstructorSymbolImpl(descriptorsRemapper.remapDeclaredConstructor(it.descriptor))
@@ -166,6 +174,7 @@ open class DeepCopySymbolRemapper(
getOrElse(symbol) { symbol }
override fun getDeclaredClass(symbol: IrClassSymbol): IrClassSymbol = classes.getDeclared(symbol)
override fun getDeclaredScript(symbol: IrScriptSymbol): IrScriptSymbol = scripts.getDeclared(symbol)
override fun getDeclaredFunction(symbol: IrSimpleFunctionSymbol): IrSimpleFunctionSymbol = functions.getDeclared(symbol)
override fun getDeclaredProperty(symbol: IrPropertySymbol): IrPropertySymbol = properties.getDeclared(symbol)
override fun getDeclaredField(symbol: IrFieldSymbol): IrFieldSymbol = fields.getDeclared(symbol)
@@ -184,6 +193,7 @@ open class DeepCopySymbolRemapper(
override fun getDeclaredTypeAlias(symbol: IrTypeAliasSymbol): IrTypeAliasSymbol = typeAliases.getDeclared(symbol)
override fun getReferencedClass(symbol: IrClassSymbol): IrClassSymbol = classes.getReferenced(symbol)
override fun getReferencedScript(symbol: IrScriptSymbol): IrScriptSymbol = scripts.getReferenced(symbol)
override fun getReferencedClassOrNull(symbol: IrClassSymbol?): IrClassSymbol? = symbol?.let { classes.getReferenced(it) }
override fun getReferencedEnumEntry(symbol: IrEnumEntrySymbol): IrEnumEntrySymbol = enumEntries.getReferenced(symbol)
override fun getReferencedVariable(symbol: IrVariableSymbol): IrVariableSymbol = variables.getReferenced(symbol)
@@ -214,6 +224,7 @@ open class DeepCopySymbolRemapper(
override fun getReferencedClassifier(symbol: IrClassifierSymbol): IrClassifierSymbol =
when (symbol) {
is IrClassSymbol -> classes.getReferenced(symbol)
is IrScriptSymbol -> scripts.getReferenced(symbol)
is IrTypeParameterSymbol -> typeParameters.getReferenced(symbol)
else -> throw IllegalArgumentException("Unexpected symbol $symbol")
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.*
interface DescriptorsRemapper {
fun remapDeclaredClass(descriptor: ClassDescriptor): ClassDescriptor = descriptor
fun remapDeclaredScript(descriptor: ScriptDescriptor): ScriptDescriptor = descriptor
fun remapDeclaredConstructor(descriptor: ClassConstructorDescriptor): ClassConstructorDescriptor = descriptor
fun remapDeclaredEnumEntry(descriptor: ClassDescriptor): ClassDescriptor = descriptor
fun remapDeclaredExternalPackageFragment(descriptor: PackageFragmentDescriptor): PackageFragmentDescriptor = descriptor
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
@@ -743,6 +743,7 @@ internal fun IrClassifierSymbol.renderClassifierFqn(): String =
if (isBound)
when (val owner = owner) {
is IrClass -> owner.renderClassFqn()
is IrScript -> owner.renderScriptFqn()
is IrTypeParameter -> owner.renderTypeParameterFqn()
else -> "`unexpected classifier: ${owner.render()}`"
}
@@ -758,6 +759,9 @@ internal fun IrTypeAliasSymbol.renderTypeAliasFqn(): String =
internal fun IrClass.renderClassFqn(): String =
StringBuilder().also { renderDeclarationFqn(it) }.toString()
internal fun IrScript.renderScriptFqn(): String =
StringBuilder().also { renderDeclarationFqn(it) }.toString()
internal fun IrTypeParameter.renderTypeParameterFqn(): String =
StringBuilder().also { sb ->
sb.append(name.asString())
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.symbols.*
interface SymbolRemapper {
fun getDeclaredClass(symbol: IrClassSymbol): IrClassSymbol
fun getDeclaredScript(symbol: IrScriptSymbol): IrScriptSymbol
fun getDeclaredFunction(symbol: IrSimpleFunctionSymbol): IrSimpleFunctionSymbol
fun getDeclaredProperty(symbol: IrPropertySymbol): IrPropertySymbol
fun getDeclaredField(symbol: IrFieldSymbol): IrFieldSymbol
@@ -34,6 +35,7 @@ interface SymbolRemapper {
fun getDeclaredTypeAlias(symbol: IrTypeAliasSymbol): IrTypeAliasSymbol
fun getReferencedClass(symbol: IrClassSymbol): IrClassSymbol
fun getReferencedScript(symbol: IrScriptSymbol): IrScriptSymbol
fun getReferencedClassOrNull(symbol: IrClassSymbol?): IrClassSymbol?
fun getReferencedEnumEntry(symbol: IrEnumEntrySymbol): IrEnumEntrySymbol
fun getReferencedVariable(symbol: IrVariableSymbol): IrVariableSymbol
@@ -47,4 +49,65 @@ interface SymbolRemapper {
fun getReferencedReturnableBlock(symbol: IrReturnableBlockSymbol): IrReturnableBlockSymbol
fun getReferencedClassifier(symbol: IrClassifierSymbol): IrClassifierSymbol
fun getReferencedTypeAlias(symbol: IrTypeAliasSymbol): IrTypeAliasSymbol
open class Empty : SymbolRemapper {
override fun getDeclaredClass(symbol: IrClassSymbol): IrClassSymbol = symbol
override fun getDeclaredScript(symbol: IrScriptSymbol): IrScriptSymbol = symbol
override fun getDeclaredFunction(symbol: IrSimpleFunctionSymbol): IrSimpleFunctionSymbol = symbol
override fun getDeclaredProperty(symbol: IrPropertySymbol): IrPropertySymbol = symbol
override fun getDeclaredField(symbol: IrFieldSymbol): IrFieldSymbol = symbol
override fun getDeclaredFile(symbol: IrFileSymbol): IrFileSymbol = symbol
override fun getDeclaredConstructor(symbol: IrConstructorSymbol): IrConstructorSymbol = symbol
override fun getDeclaredEnumEntry(symbol: IrEnumEntrySymbol): IrEnumEntrySymbol = symbol
override fun getDeclaredExternalPackageFragment(symbol: IrExternalPackageFragmentSymbol): IrExternalPackageFragmentSymbol = symbol
override fun getDeclaredVariable(symbol: IrVariableSymbol): IrVariableSymbol = symbol
override fun getDeclaredLocalDelegatedProperty(symbol: IrLocalDelegatedPropertySymbol): IrLocalDelegatedPropertySymbol = symbol
override fun getDeclaredTypeParameter(symbol: IrTypeParameterSymbol): IrTypeParameterSymbol = symbol
override fun getDeclaredValueParameter(symbol: IrValueParameterSymbol): IrValueParameterSymbol = symbol
override fun getDeclaredTypeAlias(symbol: IrTypeAliasSymbol): IrTypeAliasSymbol = symbol
override fun getReferencedClass(symbol: IrClassSymbol): IrClassSymbol = symbol
override fun getReferencedScript(symbol: IrScriptSymbol): IrScriptSymbol = symbol
override fun getReferencedClassOrNull(symbol: IrClassSymbol?): IrClassSymbol? = symbol
override fun getReferencedEnumEntry(symbol: IrEnumEntrySymbol): IrEnumEntrySymbol = symbol
override fun getReferencedVariable(symbol: IrVariableSymbol): IrVariableSymbol = symbol
override fun getReferencedLocalDelegatedProperty(symbol: IrLocalDelegatedPropertySymbol): IrLocalDelegatedPropertySymbol = symbol
override fun getReferencedField(symbol: IrFieldSymbol): IrFieldSymbol = symbol
override fun getReferencedConstructor(symbol: IrConstructorSymbol): IrConstructorSymbol = symbol
override fun getReferencedValue(symbol: IrValueSymbol): IrValueSymbol = symbol
override fun getReferencedFunction(symbol: IrFunctionSymbol): IrFunctionSymbol = symbol
override fun getReferencedProperty(symbol: IrPropertySymbol): IrPropertySymbol = symbol
override fun getReferencedSimpleFunction(symbol: IrSimpleFunctionSymbol): IrSimpleFunctionSymbol = symbol
override fun getReferencedReturnableBlock(symbol: IrReturnableBlockSymbol): IrReturnableBlockSymbol = symbol
override fun getReferencedClassifier(symbol: IrClassifierSymbol): IrClassifierSymbol = symbol
override fun getReferencedTypeAlias(symbol: IrTypeAliasSymbol): IrTypeAliasSymbol = symbol
}
}
@@ -37,6 +37,8 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Descriptor
interface ReferenceSymbolTable {
fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol
fun referenceScript(descriptor: ScriptDescriptor): IrScriptSymbol
fun referenceConstructor(descriptor: ClassConstructorDescriptor): IrConstructorSymbol
fun referenceEnumEntry(descriptor: ClassDescriptor): IrEnumEntrySymbol
@@ -397,7 +399,19 @@ class SymbolTable(
)
}
fun referenceScript(descriptor: ScriptDescriptor): IrScriptSymbol {
fun declareScript(
sig: IdSignature,
symbolFactory: () -> IrScriptSymbol,
classFactory: (IrScriptSymbol) -> IrScript
): IrScript {
return scriptSymbolTable.declare(
sig,
symbolFactory,
classFactory
)
}
override fun referenceScript(descriptor: ScriptDescriptor): IrScriptSymbol {
return scriptSymbolTable.referenced(descriptor) { IrScriptSymbolImpl(descriptor) }
}
@@ -8,10 +8,8 @@ package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrConstructor
@@ -119,6 +117,9 @@ class TypeTranslator(
annotations = translateTypeAnnotations(upperType, approximatedType)
}
is ScriptDescriptor -> {
classifier = symbolTable.referenceScript(upperTypeDescriptor)
}
is ClassDescriptor -> {
// Types such as 'java.util.Collection<? extends CharSequence>' are treated as
// '( kotlin.collections.MutableCollection<out kotlin.CharSequence!>
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen.ir
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
abstract class AbstractFirScriptCodegenTest : AbstractIrScriptCodegenTest() {
override fun updateConfiguration(configuration: CompilerConfiguration) {
super.updateConfiguration(configuration)
configuration.put(CommonConfigurationKeys.USE_FIR, true)
configuration.put(JVMConfigurationKeys.IR, true)
}
}
@@ -0,0 +1,13 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen.ir
import org.jetbrains.kotlin.codegen.AbstractScriptCodegenTest
import org.jetbrains.kotlin.test.TargetBackend
abstract class AbstractIrScriptCodegenTest : AbstractScriptCodegenTest() {
override val backend = TargetBackend.JVM_IR
}
@@ -0,0 +1,176 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen.ir;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class IrScriptCodegenTestGenerated extends AbstractIrScriptCodegenTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
}
@TestMetadata("adder.kts")
public void testAdder() throws Exception {
runTest("compiler/testData/codegen/script/adder.kts");
}
public void testAllFilesPresentInScript() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script"), Pattern.compile("^(.+)\\.kts$"), null, TargetBackend.JVM_IR, true);
}
@TestMetadata("classLiteralInsideFunction.kts")
public void testClassLiteralInsideFunction() throws Exception {
runTest("compiler/testData/codegen/script/classLiteralInsideFunction.kts");
}
@TestMetadata("destructuringDeclaration.kts")
public void testDestructuringDeclaration() throws Exception {
runTest("compiler/testData/codegen/script/destructuringDeclaration.kts");
}
@TestMetadata("destructuringDeclarationUnderscore.kts")
public void testDestructuringDeclarationUnderscore() throws Exception {
runTest("compiler/testData/codegen/script/destructuringDeclarationUnderscore.kts");
}
@TestMetadata("empty.kts")
public void testEmpty() throws Exception {
runTest("compiler/testData/codegen/script/empty.kts");
}
@TestMetadata("helloWorld.kts")
public void testHelloWorld() throws Exception {
runTest("compiler/testData/codegen/script/helloWorld.kts");
}
@TestMetadata("inline.kts")
public void testInline() throws Exception {
runTest("compiler/testData/codegen/script/inline.kts");
}
@TestMetadata("kt20707.kts")
public void testKt20707() throws Exception {
runTest("compiler/testData/codegen/script/kt20707.kts");
}
@TestMetadata("kt22029.kts")
public void testKt22029() throws Exception {
runTest("compiler/testData/codegen/script/kt22029.kts");
}
@TestMetadata("localDelegatedProperty.kts")
public void testLocalDelegatedProperty() throws Exception {
runTest("compiler/testData/codegen/script/localDelegatedProperty.kts");
}
@TestMetadata("localDelegatedPropertyNoExplicitType.kts")
public void testLocalDelegatedPropertyNoExplicitType() throws Exception {
runTest("compiler/testData/codegen/script/localDelegatedPropertyNoExplicitType.kts");
}
@TestMetadata("localFunction.kts")
public void testLocalFunction() throws Exception {
runTest("compiler/testData/codegen/script/localFunction.kts");
}
@TestMetadata("outerCapture.kts")
public void testOuterCapture() throws Exception {
runTest("compiler/testData/codegen/script/outerCapture.kts");
}
@TestMetadata("parameter.kts")
public void testParameter() throws Exception {
runTest("compiler/testData/codegen/script/parameter.kts");
}
@TestMetadata("parameterArray.kts")
public void testParameterArray() throws Exception {
runTest("compiler/testData/codegen/script/parameterArray.kts");
}
@TestMetadata("parameterClosure.kts")
public void testParameterClosure() throws Exception {
runTest("compiler/testData/codegen/script/parameterClosure.kts");
}
@TestMetadata("parameterLong.kts")
public void testParameterLong() throws Exception {
runTest("compiler/testData/codegen/script/parameterLong.kts");
}
@TestMetadata("secondLevelFunction.kts")
public void testSecondLevelFunction() throws Exception {
runTest("compiler/testData/codegen/script/secondLevelFunction.kts");
}
@TestMetadata("secondLevelFunctionClosure.kts")
public void testSecondLevelFunctionClosure() throws Exception {
runTest("compiler/testData/codegen/script/secondLevelFunctionClosure.kts");
}
@TestMetadata("secondLevelVal.kts")
public void testSecondLevelVal() throws Exception {
runTest("compiler/testData/codegen/script/secondLevelVal.kts");
}
@TestMetadata("simpleClass.kts")
public void testSimpleClass() throws Exception {
runTest("compiler/testData/codegen/script/simpleClass.kts");
}
@TestMetadata("string.kts")
public void testString() throws Exception {
runTest("compiler/testData/codegen/script/string.kts");
}
@TestMetadata("topLevelFunction.kts")
public void testTopLevelFunction() throws Exception {
runTest("compiler/testData/codegen/script/topLevelFunction.kts");
}
@TestMetadata("topLevelFunctionClosure.kts")
public void testTopLevelFunctionClosure() throws Exception {
runTest("compiler/testData/codegen/script/topLevelFunctionClosure.kts");
}
@TestMetadata("topLevelLocalDelegatedProperty.kts")
public void testTopLevelLocalDelegatedProperty() throws Exception {
runTest("compiler/testData/codegen/script/topLevelLocalDelegatedProperty.kts");
}
@TestMetadata("topLevelPropertiesWithGetSet.kts")
public void testTopLevelPropertiesWithGetSet() throws Exception {
runTest("compiler/testData/codegen/script/topLevelPropertiesWithGetSet.kts");
}
@TestMetadata("topLevelProperty.kts")
public void testTopLevelProperty() throws Exception {
runTest("compiler/testData/codegen/script/topLevelProperty.kts");
}
@TestMetadata("topLevelPropertyWithProvideDelegate.kts")
public void testTopLevelPropertyWithProvideDelegate() throws Exception {
runTest("compiler/testData/codegen/script/topLevelPropertyWithProvideDelegate.kts");
}
@TestMetadata("topLevelTypealias.kts")
public void testTopLevelTypealias() throws Exception {
runTest("compiler/testData/codegen/script/topLevelTypealias.kts");
}
}
@@ -526,6 +526,10 @@ fun main(args: Array<String>) {
testClass<AbstractIrAsmLikeInstructionListingTest> {
model("codegen/asmLike", targetBackend = TargetBackend.JVM_IR)
}
testClass<AbstractIrScriptCodegenTest> {
model("codegen/script", extension = "kts", targetBackend = TargetBackend.JVM_IR)
}
}
testGroup(
@@ -537,6 +541,10 @@ fun main(args: Array<String>) {
model("codegen/box", targetBackend = TargetBackend.JVM_IR, excludeDirs = listOf("oldLanguageVersions"))
}
testClass<AbstractFirScriptCodegenTest> {
model("codegen/script", extension = "kts", targetBackend = TargetBackend.JVM_IR, excludeDirs = listOf("oldLanguageVersions"))
}
testClass<AbstractFirBlackBoxInlineCodegenTest> {
model("codegen/boxInline", targetBackend = TargetBackend.JVM_IR, excludeDirs = listOf("oldLanguageVersions"))
}
@@ -150,8 +150,8 @@ internal fun makeCompiledScript(
val module = makeCompiledModule(generationState)
val resultField = with(generationState.scriptSpecific) {
if (resultType == null || resultFieldName == null) null
else resultFieldName!! to KotlinType(DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(resultType!!))
if (resultFieldName == null) null
else resultFieldName!! to KotlinType(resultTypeString ?: DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(resultType!!))
}
return KJvmCompiledScript(
@@ -119,7 +119,7 @@ open class GenericReplCompiler(
classes,
generationState.scriptSpecific.resultFieldName != null,
classpathAddendum ?: emptyList(),
generationState.scriptSpecific.resultType?.let {
generationState.scriptSpecific.resultTypeString ?: generationState.scriptSpecific.resultType?.let {
DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(it)
},
null