Implement REPL support in IR scripting
This commit is contained in:
+1
-1
@@ -48,7 +48,7 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
|
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
|
||||||
|
|
||||||
class JvmGeneratorExtensionsImpl(private val generateFacades: Boolean = true) : GeneratorExtensions(), JvmGeneratorExtensions {
|
open class JvmGeneratorExtensionsImpl(private val generateFacades: Boolean = true) : GeneratorExtensions(), JvmGeneratorExtensions {
|
||||||
override val classNameOverride: MutableMap<IrClass, JvmClassName> = mutableMapOf()
|
override val classNameOverride: MutableMap<IrClass, JvmClassName> = mutableMapOf()
|
||||||
|
|
||||||
override val samConversion: SamConversion
|
override val samConversion: SamConversion
|
||||||
|
|||||||
+18
-8
@@ -37,17 +37,23 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
||||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl
|
import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl
|
||||||
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.generateTypicalIrProviderList
|
import org.jetbrains.kotlin.psi2ir.generators.generateTypicalIrProviderList
|
||||||
import org.jetbrains.kotlin.resolve.CleanableBindingContext
|
import org.jetbrains.kotlin.resolve.CleanableBindingContext
|
||||||
|
|
||||||
class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory {
|
open class JvmIrCodegenFactory(
|
||||||
|
private val phaseConfig: PhaseConfig,
|
||||||
|
private val externalMangler: JvmManglerDesc? = null,
|
||||||
|
private val externalSymbolTable: SymbolTable? = null,
|
||||||
|
private val jvmGeneratorExtensions: JvmGeneratorExtensionsImpl = JvmGeneratorExtensionsImpl()
|
||||||
|
) : CodegenFactory {
|
||||||
data class JvmIrBackendInput(
|
data class JvmIrBackendInput(
|
||||||
val state: GenerationState,
|
val state: GenerationState,
|
||||||
val irModuleFragment: IrModuleFragment,
|
val irModuleFragment: IrModuleFragment,
|
||||||
val symbolTable: SymbolTable,
|
val symbolTable: SymbolTable,
|
||||||
val phaseConfig: PhaseConfig,
|
val phaseConfig: PhaseConfig,
|
||||||
val irProviders: List<IrProvider>,
|
val irProviders: List<IrProvider>,
|
||||||
val extensions: JvmGeneratorExtensions,
|
val extensions: JvmGeneratorExtensionsImpl,
|
||||||
val backendExtension: JvmBackendExtension,
|
val backendExtension: JvmBackendExtension,
|
||||||
val notifyCodegenStart: () -> Unit,
|
val notifyCodegenStart: () -> Unit,
|
||||||
)
|
)
|
||||||
@@ -59,18 +65,22 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
|
|||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun convertToIr(state: GenerationState, files: Collection<KtFile>, ignoreErrors: Boolean = false): JvmIrBackendInput {
|
fun convertToIr(state: GenerationState, files: Collection<KtFile>, ignoreErrors: Boolean = false): JvmIrBackendInput {
|
||||||
val extensions = JvmGeneratorExtensionsImpl()
|
val (mangler, symbolTable) =
|
||||||
val mangler = JvmManglerDesc(MainFunctionDetector(state.bindingContext, state.languageVersionSettings))
|
if (externalSymbolTable != null) externalMangler!! to externalSymbolTable
|
||||||
|
else {
|
||||||
|
val mangler = JvmManglerDesc(MainFunctionDetector(state.bindingContext, state.languageVersionSettings))
|
||||||
|
val symbolTable = SymbolTable(JvmIdSignatureDescriptor(mangler), IrFactoryImpl, JvmNameProvider)
|
||||||
|
mangler to symbolTable
|
||||||
|
}
|
||||||
val psi2ir = Psi2IrTranslator(state.languageVersionSettings, Psi2IrConfiguration(ignoreErrors))
|
val psi2ir = Psi2IrTranslator(state.languageVersionSettings, Psi2IrConfiguration(ignoreErrors))
|
||||||
val symbolTable = SymbolTable(JvmIdSignatureDescriptor(mangler), IrFactoryImpl, JvmNameProvider)
|
|
||||||
val messageLogger = state.configuration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None
|
val messageLogger = state.configuration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None
|
||||||
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, symbolTable, extensions)
|
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, symbolTable, jvmGeneratorExtensions)
|
||||||
val pluginExtensions = IrGenerationExtension.getInstances(state.project)
|
val pluginExtensions = IrGenerationExtension.getInstances(state.project)
|
||||||
val functionFactory = IrFunctionFactory(psi2irContext.irBuiltIns, symbolTable)
|
val functionFactory = IrFunctionFactory(psi2irContext.irBuiltIns, symbolTable)
|
||||||
psi2irContext.irBuiltIns.functionFactory = functionFactory
|
psi2irContext.irBuiltIns.functionFactory = functionFactory
|
||||||
|
|
||||||
val stubGenerator =
|
val stubGenerator =
|
||||||
DeclarationStubGeneratorImpl(psi2irContext.moduleDescriptor, symbolTable, state.languageVersionSettings, extensions)
|
DeclarationStubGeneratorImpl(psi2irContext.moduleDescriptor, symbolTable, state.languageVersionSettings, jvmGeneratorExtensions)
|
||||||
val frontEndContext = object : TranslationPluginContext {
|
val frontEndContext = object : TranslationPluginContext {
|
||||||
override val moduleDescriptor: ModuleDescriptor
|
override val moduleDescriptor: ModuleDescriptor
|
||||||
get() = psi2irContext.moduleDescriptor
|
get() = psi2irContext.moduleDescriptor
|
||||||
@@ -153,7 +163,7 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
|
|||||||
symbolTable,
|
symbolTable,
|
||||||
phaseConfig,
|
phaseConfig,
|
||||||
irProviders,
|
irProviders,
|
||||||
extensions,
|
jvmGeneratorExtensions,
|
||||||
JvmBackendExtension.Default,
|
JvmBackendExtension.Default,
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|||||||
+77
-2
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.declarations.impl.*
|
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.toIrConst
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
@@ -29,6 +30,7 @@ import org.jetbrains.kotlin.ir.util.*
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
internal val scriptsToClassesPhase = makeCustomPhase<JvmBackendContext, IrModuleFragment>(
|
internal val scriptsToClassesPhase = makeCustomPhase<JvmBackendContext, IrModuleFragment>(
|
||||||
name = "ScriptsToClasses",
|
name = "ScriptsToClasses",
|
||||||
@@ -77,12 +79,13 @@ private class ScriptsToClassesLowering(val context: JvmBackendContext) {
|
|||||||
irScriptClass.superTypes += irScript.baseClass
|
irScriptClass.superTypes += irScript.baseClass
|
||||||
irScriptClass.parent = irFile
|
irScriptClass.parent = irFile
|
||||||
irScriptClass.metadata = irScript.metadata
|
irScriptClass.metadata = irScript.metadata
|
||||||
|
irScript.targetClass = irScriptClass.symbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun finalizeScriptClass(irScriptClass: IrClass, irScript: IrScript, symbolRemapper: ScriptsToClassesSymbolRemapper) {
|
private fun finalizeScriptClass(irScriptClass: IrClass, irScript: IrScript, symbolRemapper: ScriptsToClassesSymbolRemapper) {
|
||||||
val typeRemapper = SimpleTypeRemapper(symbolRemapper)
|
val typeRemapper = SimpleTypeRemapper(symbolRemapper)
|
||||||
val scriptTransformer = ScriptToClassTransformer(irScript, irScriptClass, symbolRemapper, typeRemapper)
|
val scriptTransformer = ScriptToClassTransformer(irScript, irScriptClass, symbolRemapper, typeRemapper, context)
|
||||||
irScriptClass.thisReceiver = irScript.thisReceiver.run {
|
irScriptClass.thisReceiver = irScript.thisReceiver.run {
|
||||||
transform(scriptTransformer, null)
|
transform(scriptTransformer, null)
|
||||||
}
|
}
|
||||||
@@ -112,6 +115,9 @@ private class ScriptsToClassesLowering(val context: JvmBackendContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
irScript.earlierScriptsParameter?.let { earlierScriptdParameter ->
|
||||||
|
addConstructorParameter(earlierScriptdParameter, false)
|
||||||
|
}
|
||||||
irScript.explicitCallParameters.forEach { addConstructorParameter(it, false) }
|
irScript.explicitCallParameters.forEach { addConstructorParameter(it, false) }
|
||||||
irScript.implicitReceiversParameters.forEach { addConstructorParameter(it, false) }
|
irScript.implicitReceiversParameters.forEach { addConstructorParameter(it, false) }
|
||||||
irScript.providedProperties.forEach { addConstructorParameter(it.first, false) }
|
irScript.providedProperties.forEach { addConstructorParameter(it.first, false) }
|
||||||
@@ -300,7 +306,8 @@ private class ScriptToClassTransformer(
|
|||||||
val irScript: IrScript,
|
val irScript: IrScript,
|
||||||
val irScriptClass: IrClass,
|
val irScriptClass: IrClass,
|
||||||
val symbolRemapper: SymbolRemapper,
|
val symbolRemapper: SymbolRemapper,
|
||||||
val typeRemapper: TypeRemapper
|
val typeRemapper: TypeRemapper,
|
||||||
|
val context: JvmBackendContext
|
||||||
) : IrElementTransformerVoid() {
|
) : IrElementTransformerVoid() {
|
||||||
|
|
||||||
private fun IrType.remapType() = typeRemapper.remapType(this)
|
private fun IrType.remapType() = typeRemapper.remapType(this)
|
||||||
@@ -425,6 +432,74 @@ private class ScriptToClassTransformer(
|
|||||||
}
|
}
|
||||||
visitExpression(expression)
|
visitExpression(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getAccessCallForEarlierScript(expression: IrDeclarationReference, maybeScriptType: IrType): IrExpression? {
|
||||||
|
if (irScript.earlierScripts?.isEmpty() != false) return null
|
||||||
|
val scriptSymbol = maybeScriptType.classifierOrNull ?: return null
|
||||||
|
val scriptSymbolOwner = scriptSymbol.owner
|
||||||
|
val earlierScriptIndex = when {
|
||||||
|
scriptSymbolOwner is IrScript ->
|
||||||
|
irScript.earlierScripts!!.indexOfFirst { it == scriptSymbol }
|
||||||
|
(scriptSymbolOwner as? IrClass)?.origin == IrDeclarationOrigin.SCRIPT_CLASS -> {
|
||||||
|
irScript.earlierScripts!!.indexOfFirst { it.owner.targetClass == scriptSymbol }
|
||||||
|
}
|
||||||
|
else -> return null
|
||||||
|
}
|
||||||
|
if (earlierScriptIndex >= 0) {
|
||||||
|
val objArray = context.irBuiltIns.arrayClass
|
||||||
|
val objArrayGet = objArray.functions.single { it.owner.name == OperatorNameConventions.GET }
|
||||||
|
val builder = context.createIrBuilder(expression.symbol)
|
||||||
|
val getPrevScriptObjectExpression = builder.irCall(objArrayGet).apply {
|
||||||
|
dispatchReceiver = builder.irGet(objArray.defaultType, irScript.earlierScriptsParameter!!.symbol)
|
||||||
|
putValueArgument(0, earlierScriptIndex.toIrConst(objArrayGet.owner.valueParameters.first().type))
|
||||||
|
}
|
||||||
|
val prevScriptClassType =
|
||||||
|
when {
|
||||||
|
scriptSymbolOwner is IrScript -> scriptSymbolOwner.targetClass?.owner
|
||||||
|
(scriptSymbolOwner as? IrClass)?.origin == IrDeclarationOrigin.SCRIPT_CLASS -> scriptSymbolOwner
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
return if (prevScriptClassType == null) getPrevScriptObjectExpression
|
||||||
|
else builder.irImplicitCast(getPrevScriptObjectExpression, prevScriptClassType.defaultType)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitGetField(expression: IrGetField): IrExpression {
|
||||||
|
if (irScript.earlierScripts != null) {
|
||||||
|
val receiver = expression.receiver
|
||||||
|
if (receiver is IrGetValue && receiver.symbol.owner.name == Name.special("<this>")) {
|
||||||
|
val newReceiver = getAccessCallForEarlierScript(expression, receiver.type)
|
||||||
|
if (newReceiver != null) {
|
||||||
|
val newGetField =
|
||||||
|
IrGetFieldImpl(expression.startOffset, expression.endOffset, expression.symbol, expression.type, newReceiver)
|
||||||
|
return super.visitGetField(newGetField)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.visitGetField(expression)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
if (irScript.earlierScripts != null) {
|
||||||
|
val target = expression.symbol.owner
|
||||||
|
val receiver: IrValueParameter? = target.dispatchReceiverParameter
|
||||||
|
if (target.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR && receiver?.name == Name.special("<this>")) {
|
||||||
|
val newReceiver = getAccessCallForEarlierScript(expression, receiver.type)
|
||||||
|
if (newReceiver != null) {
|
||||||
|
val builder = context.createIrBuilder(expression.symbol)
|
||||||
|
val newCall = builder.irCall(expression.symbol, target.returnType, origin = expression.origin).also {
|
||||||
|
it.copyTypeAndValueArgumentsFrom(expression)
|
||||||
|
it.dispatchReceiver = newReceiver
|
||||||
|
}
|
||||||
|
return super.visitCall(newCall)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.visitCall(expression)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ScriptsToClassesSymbolRemapper(
|
private class ScriptsToClassesSymbolRemapper(
|
||||||
|
|||||||
+1
-1
@@ -41,5 +41,5 @@ open class GeneratorExtensions : StubGeneratorExtensions() {
|
|||||||
open val shouldPreventDeprecatedIntegerValueTypeLiteralConversion: Boolean
|
open val shouldPreventDeprecatedIntegerValueTypeLiteralConversion: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
|
|
||||||
open fun getPreviousScripts(): List<IrScriptSymbol> = emptyList()
|
open fun getPreviousScripts(): List<IrScriptSymbol>? = null
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-19
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.psi2ir.generators
|
|||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.assertCast
|
import org.jetbrains.kotlin.ir.assertCast
|
||||||
import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource
|
import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
@@ -18,10 +19,13 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.toArrayOrPrimitiveArrayType
|
||||||
import org.jetbrains.kotlin.ir.util.indexOrMinusOne
|
import org.jetbrains.kotlin.ir.util.indexOrMinusOne
|
||||||
import org.jetbrains.kotlin.ir.util.isCrossinline
|
import org.jetbrains.kotlin.ir.util.isCrossinline
|
||||||
import org.jetbrains.kotlin.ir.util.isNoinline
|
import org.jetbrains.kotlin.ir.util.isNoinline
|
||||||
import org.jetbrains.kotlin.ir.util.varargElementType
|
import org.jetbrains.kotlin.ir.util.varargElementType
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtScript
|
import org.jetbrains.kotlin.psi.KtScript
|
||||||
import org.jetbrains.kotlin.psi.KtScriptInitializer
|
import org.jetbrains.kotlin.psi.KtScriptInitializer
|
||||||
@@ -39,27 +43,12 @@ class ScriptGenerator(declarationGenerator: DeclarationGenerator) : DeclarationG
|
|||||||
fun generateScriptDeclaration(ktScript: KtScript): IrDeclaration? {
|
fun generateScriptDeclaration(ktScript: KtScript): IrDeclaration? {
|
||||||
val descriptor = getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktScript) as ScriptDescriptor
|
val descriptor = getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktScript) as ScriptDescriptor
|
||||||
|
|
||||||
val previousScripts = context.extensions.getPreviousScripts()
|
|
||||||
|
|
||||||
return context.symbolTable.declareScript(descriptor).buildWithScope { irScript ->
|
return context.symbolTable.declareScript(descriptor).buildWithScope { irScript ->
|
||||||
|
|
||||||
irScript.metadata = DescriptorMetadataSource.Class(descriptor)
|
irScript.metadata = DescriptorMetadataSource.Class(descriptor)
|
||||||
|
|
||||||
// A workaround for the JS/REPL backend:
|
|
||||||
// JS backend doesn't save previously executed snippets anywhere, they should be taken for now from the context.symbolTable.listExistedScripts()
|
|
||||||
// on the other hand imported scripts are also stored there so to avoid clashes the imported scripts should be filtered out
|
|
||||||
// NOTE: that JVM IR is not properly tested with REPL, so it might have the same problem
|
|
||||||
// TODO: design and implement other schema for handling previous snippets
|
|
||||||
val importedScripts = descriptor.implicitReceivers.filterIsInstanceTo(HashSet<ScriptDescriptor>())
|
val importedScripts = descriptor.implicitReceivers.filterIsInstanceTo(HashSet<ScriptDescriptor>())
|
||||||
|
|
||||||
// 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
|
|
||||||
previousScripts.forEach {
|
|
||||||
if (it.owner != irScript && it.descriptor !in importedScripts) {
|
|
||||||
context.symbolTable.introduceValueParameter(it.owner.thisReceiver)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val startOffset = ktScript.pureStartOffset
|
val startOffset = ktScript.pureStartOffset
|
||||||
val endOffset = ktScript.pureEndOffset
|
val endOffset = ktScript.pureEndOffset
|
||||||
|
|
||||||
@@ -93,6 +82,24 @@ class ScriptGenerator(declarationGenerator: DeclarationGenerator) : DeclarationG
|
|||||||
// TODO: implement implicit receiver parameters handlin properly
|
// TODO: implement implicit receiver parameters handlin properly
|
||||||
var parametersIndex = 0
|
var parametersIndex = 0
|
||||||
|
|
||||||
|
irScript.earlierScripts = context.extensions.getPreviousScripts()?.filter {
|
||||||
|
// TODO: probably unnecessary filtering
|
||||||
|
it.owner != irScript && it.descriptor !in importedScripts
|
||||||
|
}
|
||||||
|
irScript.earlierScripts?.forEach {
|
||||||
|
context.symbolTable.introduceValueParameter(it.owner.thisReceiver)
|
||||||
|
}
|
||||||
|
irScript.earlierScriptsParameter = irScript.earlierScripts?.takeIf { it.isNotEmpty() }?.let {
|
||||||
|
val baseType = context.irBuiltIns.anyType
|
||||||
|
val arrayType = baseType.toArrayOrPrimitiveArrayType(context.irBuiltIns)
|
||||||
|
context.irFactory.createValueParameter(
|
||||||
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.SCRIPT_EARLIER_SCRIPTS, IrValueParameterSymbolImpl(),
|
||||||
|
Name.special("<earlierScripts>"), parametersIndex++,
|
||||||
|
arrayType, null,
|
||||||
|
false, false, false, false
|
||||||
|
).also { it.parent = irScript }
|
||||||
|
}
|
||||||
|
|
||||||
irScript.explicitCallParameters = descriptor.explicitConstructorParameters.map { valueParameterDescriptor ->
|
irScript.explicitCallParameters = descriptor.explicitConstructorParameters.map { valueParameterDescriptor ->
|
||||||
parametersIndex++
|
parametersIndex++
|
||||||
valueParameterDescriptor.toIrValueParameter(startOffset, endOffset, IrDeclarationOrigin.SCRIPT_CALL_PARAMETER).also { it.parent = irScript }
|
valueParameterDescriptor.toIrValueParameter(startOffset, endOffset, IrDeclarationOrigin.SCRIPT_CALL_PARAMETER).also { it.parent = irScript }
|
||||||
@@ -111,14 +118,17 @@ class ScriptGenerator(declarationGenerator: DeclarationGenerator) : DeclarationG
|
|||||||
startOffset, endOffset, IrDeclarationOrigin.SCRIPT_PROVIDED_PROPERTY, parameter, type
|
startOffset, endOffset, IrDeclarationOrigin.SCRIPT_PROVIDED_PROPERTY, parameter, type
|
||||||
)
|
)
|
||||||
val irProperty =
|
val irProperty =
|
||||||
PropertyGenerator(declarationGenerator).generateSyntheticProperty(ktScript, providedProperty, valueParameter, generateSyntheticAccessors = true)
|
PropertyGenerator(declarationGenerator).generateSyntheticProperty(
|
||||||
|
ktScript,
|
||||||
|
providedProperty,
|
||||||
|
valueParameter,
|
||||||
|
generateSyntheticAccessors = true
|
||||||
|
)
|
||||||
irProperty.origin = IrDeclarationOrigin.SCRIPT_PROVIDED_PROPERTY
|
irProperty.origin = IrDeclarationOrigin.SCRIPT_PROVIDED_PROPERTY
|
||||||
irScript.statements += irProperty
|
irScript.statements += irProperty
|
||||||
valueParameter to irProperty.symbol
|
valueParameter to irProperty.symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
irScript.earlierScripts = previousScripts
|
|
||||||
|
|
||||||
for (d in ktScript.declarations) {
|
for (d in ktScript.declarations) {
|
||||||
when (d) {
|
when (d) {
|
||||||
is KtScriptInitializer -> {
|
is KtScriptInitializer -> {
|
||||||
@@ -129,7 +139,11 @@ class ScriptGenerator(declarationGenerator: DeclarationGenerator) : DeclarationG
|
|||||||
if (d == ktScript.declarations.last() && descriptor.resultValue != null) {
|
if (d == ktScript.declarations.last() && descriptor.resultValue != null) {
|
||||||
descriptor.resultValue!!.let { resultDescriptor ->
|
descriptor.resultValue!!.let { resultDescriptor ->
|
||||||
PropertyGenerator(declarationGenerator)
|
PropertyGenerator(declarationGenerator)
|
||||||
.generateSyntheticPropertyWithInitializer(ktScript, resultDescriptor, generateSyntheticAccessors = true) {
|
.generateSyntheticPropertyWithInitializer(
|
||||||
|
ktScript,
|
||||||
|
resultDescriptor,
|
||||||
|
generateSyntheticAccessors = true
|
||||||
|
) {
|
||||||
// TODO: check if this is a correct place to do it
|
// TODO: check if this is a correct place to do it
|
||||||
it.visibility = DescriptorVisibilities.PUBLIC
|
it.visibility = DescriptorVisibilities.PUBLIC
|
||||||
irExpressionBody
|
irExpressionBody
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ interface IrDeclarationOrigin {
|
|||||||
|
|
||||||
object SCRIPT_CLASS : IrDeclarationOriginImpl("SCRIPT_CLASS")
|
object SCRIPT_CLASS : IrDeclarationOriginImpl("SCRIPT_CLASS")
|
||||||
object SCRIPT_STATEMENT : IrDeclarationOriginImpl("SCRIPT_STATEMENT")
|
object SCRIPT_STATEMENT : IrDeclarationOriginImpl("SCRIPT_STATEMENT")
|
||||||
|
object SCRIPT_EARLIER_SCRIPTS : IrDeclarationOriginImpl("SCRIPT_EARLIER_SCRIPTS")
|
||||||
object SCRIPT_CALL_PARAMETER : IrDeclarationOriginImpl("SCRIPT_CALL_PARAMETER")
|
object SCRIPT_CALL_PARAMETER : IrDeclarationOriginImpl("SCRIPT_CALL_PARAMETER")
|
||||||
object SCRIPT_IMPLICIT_RECEIVER : IrDeclarationOriginImpl("SCRIPT_IMPLICIT_RECEIVER")
|
object SCRIPT_IMPLICIT_RECEIVER : IrDeclarationOriginImpl("SCRIPT_IMPLICIT_RECEIVER")
|
||||||
object SCRIPT_PROVIDED_PROPERTY : IrDeclarationOriginImpl("SCRIPT_PROVIDED_PROPERTY")
|
object SCRIPT_PROVIDED_PROPERTY : IrDeclarationOriginImpl("SCRIPT_PROVIDED_PROPERTY")
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.declarations
|
package org.jetbrains.kotlin.ir.declarations
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStatementContainer
|
import org.jetbrains.kotlin.ir.expressions.IrStatementContainer
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
@@ -32,5 +33,9 @@ abstract class IrScript :
|
|||||||
|
|
||||||
abstract var resultProperty: IrPropertySymbol?
|
abstract var resultProperty: IrPropertySymbol?
|
||||||
|
|
||||||
|
abstract var earlierScriptsParameter: IrValueParameter?
|
||||||
|
|
||||||
abstract var earlierScripts: List<IrScriptSymbol>?
|
abstract var earlierScripts: List<IrScriptSymbol>?
|
||||||
|
|
||||||
|
abstract var targetClass: IrClassSymbol?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
|||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
@@ -52,7 +53,9 @@ class IrScriptImpl(
|
|||||||
override lateinit var implicitReceiversParameters: List<IrValueParameter>
|
override lateinit var implicitReceiversParameters: List<IrValueParameter>
|
||||||
override lateinit var providedProperties: List<Pair<IrValueParameter, IrPropertySymbol>>
|
override lateinit var providedProperties: List<Pair<IrValueParameter, IrPropertySymbol>>
|
||||||
override var resultProperty: IrPropertySymbol? = null
|
override var resultProperty: IrPropertySymbol? = null
|
||||||
|
override var earlierScriptsParameter: IrValueParameter? = null
|
||||||
override var earlierScripts: List<IrScriptSymbol>? = null
|
override var earlierScripts: List<IrScriptSymbol>? = null
|
||||||
|
override var targetClass: IrClassSymbol? = null
|
||||||
|
|
||||||
@ObsoleteDescriptorBasedAPI
|
@ObsoleteDescriptorBasedAPI
|
||||||
override val descriptor: ScriptDescriptor
|
override val descriptor: ScriptDescriptor
|
||||||
|
|||||||
@@ -118,6 +118,8 @@ open class DeepCopyIrTreeWithSymbols(
|
|||||||
).also { scriptCopy ->
|
).also { scriptCopy ->
|
||||||
scriptCopy.thisReceiver = declaration.thisReceiver.transform()
|
scriptCopy.thisReceiver = declaration.thisReceiver.transform()
|
||||||
declaration.statements.mapTo(scriptCopy.statements) { it.transform() }
|
declaration.statements.mapTo(scriptCopy.statements) { it.transform() }
|
||||||
|
scriptCopy.earlierScripts = declaration.earlierScripts
|
||||||
|
scriptCopy.earlierScriptsParameter = declaration.earlierScriptsParameter
|
||||||
scriptCopy.explicitCallParameters = declaration.explicitCallParameters.map { it.transform() }
|
scriptCopy.explicitCallParameters = declaration.explicitCallParameters.map { it.transform() }
|
||||||
scriptCopy.implicitReceiversParameters = declaration.implicitReceiversParameters.map { it.transform() }
|
scriptCopy.implicitReceiversParameters = declaration.implicitReceiversParameters.map { it.transform() }
|
||||||
scriptCopy.providedProperties = declaration.providedProperties.map { it.first.transform() to it.second }
|
scriptCopy.providedProperties = declaration.providedProperties.map { it.first.transform() to it.second }
|
||||||
|
|||||||
+1
-2
@@ -8,7 +8,6 @@ package kotlin.script.experimental.jvmhost.repl
|
|||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.jetbrains.kotlin.backend.common.push
|
import org.jetbrains.kotlin.backend.common.push
|
||||||
import org.jetbrains.kotlin.cli.common.repl.*
|
import org.jetbrains.kotlin.cli.common.repl.*
|
||||||
import org.jetbrains.kotlin.cli.common.repl.ReplCompilerWithoutCheck
|
|
||||||
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmReplCompilerBase
|
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmReplCompilerBase
|
||||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerStageHistory
|
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerStageHistory
|
||||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerState
|
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerState
|
||||||
@@ -78,7 +77,7 @@ class JvmReplCompiler(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val message = res.reports.joinToString("\n") { it.message }
|
val message = res.reports.joinToString("\n")
|
||||||
if (res.isIncomplete()) {
|
if (res.isIncomplete()) {
|
||||||
ReplCompileResult.Incomplete(message)
|
ReplCompileResult.Incomplete(message)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+4
-2
@@ -75,7 +75,7 @@ class LazyScriptDescriptor(
|
|||||||
resolveSession.trace.record(BindingContext.SCRIPT, scriptInfo.script, this)
|
resolveSession.trace.record(BindingContext.SCRIPT, scriptInfo.script, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getResultValue(): ReplResultPropertyDescriptor? {
|
private val _resultValue: () -> ReplResultPropertyDescriptor? = resolveSession.storageManager.createNullableLazyValue {
|
||||||
val expression = scriptInfo.script
|
val expression = scriptInfo.script
|
||||||
.getChildOfType<KtBlockExpression>()
|
.getChildOfType<KtBlockExpression>()
|
||||||
?.getChildrenOfType<KtScriptInitializer>()?.lastOrNull()
|
?.getChildrenOfType<KtScriptInitializer>()?.lastOrNull()
|
||||||
@@ -85,7 +85,7 @@ class LazyScriptDescriptor(
|
|||||||
resolveSession.trace.bindingContext.getType(it)
|
resolveSession.trace.bindingContext.getType(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (type != null && !type.isUnit() && !type.isNothing()) {
|
if (type != null && !type.isUnit() && !type.isNothing()) {
|
||||||
resultFieldName()?.let {
|
resultFieldName()?.let {
|
||||||
ReplResultPropertyDescriptor(
|
ReplResultPropertyDescriptor(
|
||||||
it,
|
it,
|
||||||
@@ -98,6 +98,8 @@ class LazyScriptDescriptor(
|
|||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getResultValue(): ReplResultPropertyDescriptor? = _resultValue()
|
||||||
|
|
||||||
fun resultFieldName(): Name? {
|
fun resultFieldName(): Name? {
|
||||||
// TODO: implement robust REPL/script selection
|
// TODO: implement robust REPL/script selection
|
||||||
val replSnippetId =
|
val replSnippetId =
|
||||||
|
|||||||
+89
-32
@@ -7,6 +7,10 @@ package org.jetbrains.kotlin.scripting.compiler.plugin.impl
|
|||||||
|
|
||||||
|
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.*
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
||||||
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||||
import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
|
import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
|
||||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
@@ -16,13 +20,16 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|||||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||||
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||||
|
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmManglerDesc
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitsExtensionsResolutionFilter
|
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitsExtensionsResolutionFilter
|
||||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerStageHistory
|
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.*
|
||||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerState
|
|
||||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzerBase
|
|
||||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplImplicitsExtensionsResolutionFilter
|
|
||||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider
|
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider
|
||||||
import org.jetbrains.kotlin.scripting.resolve.skipExtensionsResolutionForImplicits
|
import org.jetbrains.kotlin.scripting.resolve.skipExtensionsResolutionForImplicits
|
||||||
import org.jetbrains.kotlin.scripting.resolve.skipExtensionsResolutionForImplicitsExceptInnermost
|
import org.jetbrains.kotlin.scripting.resolve.skipExtensionsResolutionForImplicitsExceptInnermost
|
||||||
@@ -112,45 +119,35 @@ open class KJvmReplCompilerBase<AnalyzerT : ReplCodeAnalyzerBase> protected cons
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val no = scriptPriority.getAndIncrement()
|
val snippetNo = scriptPriority.getAndIncrement()
|
||||||
|
|
||||||
val analysisResult =
|
val analysisResult =
|
||||||
compilationState.analyzerEngine.analyzeReplLineWithImportedScripts(snippetKtFile, sourceFiles.drop(1), snippet, no)
|
compilationState.analyzerEngine.analyzeReplLineWithImportedScripts(
|
||||||
|
snippetKtFile,
|
||||||
|
sourceFiles.drop(1),
|
||||||
|
snippet,
|
||||||
|
snippetNo
|
||||||
|
)
|
||||||
AnalyzerWithCompilerReport.reportDiagnostics(analysisResult.diagnostics, errorHolder)
|
AnalyzerWithCompilerReport.reportDiagnostics(analysisResult.diagnostics, errorHolder)
|
||||||
|
|
||||||
val scriptDescriptor = when (analysisResult) {
|
val scriptDescriptor = when (analysisResult) {
|
||||||
is ReplCodeAnalyzerBase.ReplLineAnalysisResult.WithErrors -> return failure(
|
is ReplCodeAnalyzerBase.ReplLineAnalysisResult.WithErrors -> return failure(messageCollector)
|
||||||
messageCollector
|
|
||||||
)
|
|
||||||
is ReplCodeAnalyzerBase.ReplLineAnalysisResult.Successful -> {
|
is ReplCodeAnalyzerBase.ReplLineAnalysisResult.Successful -> {
|
||||||
(analysisResult.scriptDescriptor as? ScriptDescriptor)
|
(analysisResult.scriptDescriptor as? ScriptDescriptor)
|
||||||
?: return failure(
|
?: throw AssertionError("Unexpected script descriptor type ${analysisResult.scriptDescriptor::class}")
|
||||||
snippet,
|
|
||||||
messageCollector,
|
|
||||||
"Unexpected script descriptor type ${analysisResult.scriptDescriptor::class}"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
else -> return failure(
|
else -> throw AssertionError("Unexpected result ${analysisResult::class.java}")
|
||||||
snippet,
|
|
||||||
messageCollector,
|
|
||||||
"Unexpected result ${analysisResult::class.java}"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val generationState = GenerationState.Builder(
|
val isIr = context.environment.configuration.getBoolean(JVMConfigurationKeys.IR)
|
||||||
snippetKtFile.project,
|
|
||||||
ClassBuilderFactories.BINARIES,
|
|
||||||
compilationState.analyzerEngine.module,
|
|
||||||
compilationState.analyzerEngine.trace.bindingContext,
|
|
||||||
sourceFiles,
|
|
||||||
compilationState.environment.configuration
|
|
||||||
).build().apply {
|
|
||||||
scriptSpecific.earlierScriptsForReplInterpreter = history.map { it.item }
|
|
||||||
beforeCompile()
|
|
||||||
}
|
|
||||||
KotlinCodegenFacade.generatePackage(generationState, snippetKtFile.script!!.containingKtFile.packageFqName, sourceFiles)
|
|
||||||
|
|
||||||
history.push(LineId(no, 0, snippet.hashCode()), scriptDescriptor)
|
val generationState = if (isIr) {
|
||||||
|
generateWithBackendIr(compilationState, snippetKtFile, sourceFiles)
|
||||||
|
} else {
|
||||||
|
generateWithOldBackend(compilationState, snippetKtFile, sourceFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
history.push(LineId(snippetNo, 0, snippet.hashCode()), scriptDescriptor)
|
||||||
|
|
||||||
val dependenciesProvider = ScriptDependenciesProvider.getInstance(context.environment.project)
|
val dependenciesProvider = ScriptDependenciesProvider.getInstance(context.environment.project)
|
||||||
val compiledScript =
|
val compiledScript =
|
||||||
@@ -175,6 +172,55 @@ open class KJvmReplCompilerBase<AnalyzerT : ReplCodeAnalyzerBase> protected cons
|
|||||||
}
|
}
|
||||||
}.last()
|
}.last()
|
||||||
|
|
||||||
|
private fun generateWithOldBackend(
|
||||||
|
compilationState: ReplCompilationState<AnalyzerT>,
|
||||||
|
snippetKtFile: KtFile,
|
||||||
|
sourceFiles: List<KtFile>
|
||||||
|
): GenerationState {
|
||||||
|
val generationState = GenerationState.Builder(
|
||||||
|
snippetKtFile.project,
|
||||||
|
ClassBuilderFactories.BINARIES,
|
||||||
|
compilationState.analyzerEngine.module,
|
||||||
|
compilationState.analyzerEngine.trace.bindingContext,
|
||||||
|
sourceFiles,
|
||||||
|
compilationState.environment.configuration
|
||||||
|
).build().also { generationState ->
|
||||||
|
generationState.scriptSpecific.earlierScriptsForReplInterpreter = history.map { it.item }
|
||||||
|
generationState.beforeCompile()
|
||||||
|
}
|
||||||
|
KotlinCodegenFacade.generatePackage(generationState, snippetKtFile.script!!.containingKtFile.packageFqName, sourceFiles)
|
||||||
|
|
||||||
|
return generationState
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateWithBackendIr(
|
||||||
|
compilationState: ReplCompilationState<AnalyzerT>,
|
||||||
|
snippetKtFile: KtFile,
|
||||||
|
sourceFiles: List<KtFile>
|
||||||
|
): GenerationState {
|
||||||
|
val generatorExtensions = object : JvmGeneratorExtensionsImpl() {
|
||||||
|
override fun getPreviousScripts() = history.map { compilationState.symbolTable.referenceScript(it.item) }
|
||||||
|
}
|
||||||
|
val codegenFactory = JvmIrCodegenFactory(
|
||||||
|
compilationState.environment.configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases),
|
||||||
|
compilationState.mangler, compilationState.symbolTable, generatorExtensions
|
||||||
|
)
|
||||||
|
val generationState = GenerationState.Builder(
|
||||||
|
snippetKtFile.project,
|
||||||
|
ClassBuilderFactories.BINARIES,
|
||||||
|
compilationState.analyzerEngine.module,
|
||||||
|
compilationState.analyzerEngine.trace.bindingContext,
|
||||||
|
sourceFiles,
|
||||||
|
compilationState.environment.configuration
|
||||||
|
)
|
||||||
|
.codegenFactory(codegenFactory)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
generationState.codegenFactory.generateModule(generationState, generationState.files)
|
||||||
|
|
||||||
|
return generationState
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun invoke(
|
override suspend fun invoke(
|
||||||
script: SourceCode,
|
script: SourceCode,
|
||||||
scriptCompilationConfiguration: ScriptCompilationConfiguration
|
scriptCompilationConfiguration: ScriptCompilationConfiguration
|
||||||
@@ -294,4 +340,15 @@ class ReplCompilationState<AnalyzerT : ReplCodeAnalyzerBase>(
|
|||||||
// ReplCodeAnalyzer1(context.environment)
|
// ReplCodeAnalyzer1(context.environment)
|
||||||
analyzerInit(context, implicitsResolutionFilter)
|
analyzerInit(context, implicitsResolutionFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val manglerAndSymbolTable by lazy {
|
||||||
|
val mangler = JvmManglerDesc(
|
||||||
|
MainFunctionDetector(analyzerEngine.trace.bindingContext, environment.configuration.languageVersionSettings)
|
||||||
|
)
|
||||||
|
val symbolTable = SymbolTable(JvmIdSignatureDescriptor(mangler), IrFactoryImpl, JvmNameProvider)
|
||||||
|
mangler to symbolTable
|
||||||
|
}
|
||||||
|
|
||||||
|
override val mangler: JvmManglerDesc get() = manglerAndSymbolTable.first
|
||||||
|
override val symbolTable: SymbolTable get() = manglerAndSymbolTable.second
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -7,13 +7,16 @@ package org.jetbrains.kotlin.scripting.compiler.plugin.repl
|
|||||||
|
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.openapi.util.Disposer
|
import com.intellij.openapi.util.Disposer
|
||||||
import org.jetbrains.kotlin.cli.common.repl.*
|
import org.jetbrains.kotlin.cli.common.repl.BasicReplStageHistory
|
||||||
|
import org.jetbrains.kotlin.cli.common.repl.IReplStageState
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmManglerDesc
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitsExtensionsResolutionFilter
|
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitsExtensionsResolutionFilter
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||||
import kotlin.concurrent.write
|
import kotlin.concurrent.write
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.ScriptCompilationConfiguration
|
||||||
|
|
||||||
class JvmReplCompilerStageHistory<CompilationT : JvmReplCompilerState.Compilation>(private val state: JvmReplCompilerState<CompilationT>) :
|
class JvmReplCompilerStageHistory<CompilationT : JvmReplCompilerState.Compilation>(private val state: JvmReplCompilerState<CompilationT>) :
|
||||||
BasicReplStageHistory<ScriptDescriptor>(state.lock)
|
BasicReplStageHistory<ScriptDescriptor>(state.lock)
|
||||||
@@ -62,5 +65,7 @@ class JvmReplCompilerState<CompilationT : JvmReplCompilerState.Compilation>(
|
|||||||
val environment: KotlinCoreEnvironment
|
val environment: KotlinCoreEnvironment
|
||||||
val analyzerEngine: ReplCodeAnalyzerBase
|
val analyzerEngine: ReplCodeAnalyzerBase
|
||||||
val implicitsResolutionFilter: ImplicitsExtensionsResolutionFilter
|
val implicitsResolutionFilter: ImplicitsExtensionsResolutionFilter
|
||||||
|
val mangler: JvmManglerDesc
|
||||||
|
val symbolTable: SymbolTable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user