Implement JVM IR support for scripts
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+3
-11
@@ -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,
|
||||
|
||||
+14
-2
@@ -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
|
||||
|
||||
+6
-5
@@ -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
|
||||
}
|
||||
|
||||
+20
-14
@@ -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)
|
||||
|
||||
+41
-21
@@ -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!>
|
||||
|
||||
+18
@@ -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)
|
||||
}
|
||||
}
|
||||
+13
@@ -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
|
||||
}
|
||||
+176
@@ -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"))
|
||||
}
|
||||
|
||||
+2
-2
@@ -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(
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user