Rewrite IR plugin infrastructure (and serialization plugin) so it won't emit LazyIR.
LazyIR was emitted because plugin was not able to declare symbols, only to reference them. Moreover, declarations added by frontend plugin were also unbound symbols produced by psi2ir, and declaration stub generator was stubbing them with LazyIR – therefore access to global symbol table is not enough for plugins. IrProvider won't help here, because some functions produced by plugin have circular dependencies. By moving compiler plugins step between psi2ir and declaration stub generator, both problems are resolved – unbound symbols produced by psi2ir and compiler plugins are declared where they would be declared if this was a user code, and only unbound symbols left are external dependencies, which is a correct input for lazy ir.
This commit is contained in:
+18
-5
@@ -5,18 +5,31 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.extensions
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class IrPluginContext(
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
val bindingContext: BindingContext,
|
||||
val languageVersionSettings: LanguageVersionSettings,
|
||||
val symbolTable: SymbolTable,
|
||||
val typeTranslator: TypeTranslator,
|
||||
override val irBuiltIns: IrBuiltIns
|
||||
): IrGeneratorContext()
|
||||
|
||||
interface IrGenerationExtension {
|
||||
companion object :
|
||||
ProjectExtensionDescriptor<IrGenerationExtension>("org.jetbrains.kotlin.irGenerationExtension", IrGenerationExtension::class.java)
|
||||
|
||||
fun generate(
|
||||
file: IrFile,
|
||||
backendContext: BackendContext,
|
||||
bindingContext: BindingContext
|
||||
moduleFragment: IrModuleFragment,
|
||||
pluginContext: IrPluginContext
|
||||
)
|
||||
}
|
||||
+3
-3
@@ -39,11 +39,11 @@ import org.jetbrains.kotlin.name.Name
|
||||
class IrLoweringContext(backendContext: BackendContext) : IrGeneratorContextBase(backendContext.irBuiltIns)
|
||||
|
||||
class DeclarationIrBuilder(
|
||||
backendContext: BackendContext,
|
||||
generatorContext: IrGeneratorContext,
|
||||
symbol: IrSymbol,
|
||||
startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET
|
||||
) : IrBuilderWithScope(
|
||||
IrLoweringContext(backendContext),
|
||||
generatorContext,
|
||||
Scope(symbol),
|
||||
startOffset,
|
||||
endOffset
|
||||
@@ -73,7 +73,7 @@ fun BackendContext.createIrBuilder(
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET
|
||||
) =
|
||||
DeclarationIrBuilder(this, symbol, startOffset, endOffset)
|
||||
DeclarationIrBuilder(IrLoweringContext(this), symbol, startOffset, endOffset)
|
||||
|
||||
|
||||
fun <T : IrBuilder> T.at(element: IrElement) = this.at(element.startOffset, element.endOffset)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
|
||||
@@ -31,6 +33,23 @@ object JvmBackendFacade {
|
||||
val psi2ir = Psi2IrTranslator(state.languageVersionSettings)
|
||||
val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext, extensions = JvmGeneratorExtensions)
|
||||
val extensions = JvmStubGeneratorExtensions()
|
||||
|
||||
for (extension in IrGenerationExtension.getInstances(state.project)) {
|
||||
psi2ir.addPostprocessingStep { module ->
|
||||
extension.generate(
|
||||
module,
|
||||
IrPluginContext(
|
||||
psi2irContext.moduleDescriptor,
|
||||
psi2irContext.bindingContext,
|
||||
psi2irContext.languageVersionSettings,
|
||||
psi2irContext.symbolTable,
|
||||
psi2irContext.typeTranslator,
|
||||
psi2irContext.irBuiltIns
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, stubGeneratorExtensions = extensions)
|
||||
doGenerateFilesInternal(
|
||||
state, errorHandler, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, extensions
|
||||
@@ -65,12 +84,6 @@ object JvmBackendFacade {
|
||||
|
||||
context.classNameOverride = extensions.classNameOverride
|
||||
|
||||
for (irFile in irModuleFragment.files) {
|
||||
for (extension in IrGenerationExtension.getInstances(context.state.project)) {
|
||||
extension.generate(irFile, context, context.state.bindingContext)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
JvmLower(context).lower(irModuleFragment)
|
||||
} catch (e: Throwable) {
|
||||
|
||||
@@ -31,17 +31,15 @@ import org.jetbrains.kotlin.psi2ir.transformations.insertImplicitCasts
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
typealias Psi2IrPostprocessingStep = (IrModuleFragment) -> Unit
|
||||
|
||||
class Psi2IrTranslator(
|
||||
val languageVersionSettings: LanguageVersionSettings,
|
||||
val configuration: Psi2IrConfiguration = Psi2IrConfiguration()
|
||||
) {
|
||||
interface PostprocessingStep {
|
||||
fun postprocess(context: GeneratorContext, irElement: IrElement)
|
||||
}
|
||||
private val postprocessingSteps = SmartList<Psi2IrPostprocessingStep>()
|
||||
|
||||
private val postprocessingSteps = SmartList<PostprocessingStep>()
|
||||
|
||||
fun add(step: PostprocessingStep) {
|
||||
fun addPostprocessingStep(step: Psi2IrPostprocessingStep) {
|
||||
postprocessingSteps.add(step)
|
||||
}
|
||||
|
||||
@@ -74,20 +72,17 @@ class Psi2IrTranslator(
|
||||
val moduleGenerator = ModuleGenerator(context)
|
||||
val irModule = moduleGenerator.generateModuleFragment(ktFiles)
|
||||
|
||||
// This is required for implicit casts insertion on IrTypes (work-in-progress).
|
||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, irProviders, stubGeneratorExtensions)
|
||||
irModule.patchDeclarationParents()
|
||||
|
||||
postprocess(context, irModule)
|
||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, irProviders, stubGeneratorExtensions)
|
||||
return irModule
|
||||
}
|
||||
|
||||
private fun postprocess(context: GeneratorContext, irElement: IrElement) {
|
||||
private fun postprocess(context: GeneratorContext, irElement: IrModuleFragment) {
|
||||
insertImplicitCasts(irElement, context)
|
||||
generateAnnotationsForDeclarations(context, irElement)
|
||||
|
||||
postprocessingSteps.forEach { it.postprocess(context, irElement) }
|
||||
postprocessingSteps.forEach { it(irElement) }
|
||||
|
||||
irElement.patchDeclarationParents()
|
||||
}
|
||||
|
||||
@@ -177,6 +177,7 @@ fun loadIr(
|
||||
}
|
||||
|
||||
val moduleFragment = psi2IrContext.generateModuleFragment(files, deserializer)
|
||||
// todo: add postprocessing step
|
||||
|
||||
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, deserializer)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user