Psi2ir: refactor ModuleGenerator.generateModuleFragment
Move `postprocess` into `generateSingleFile` and do those steps on each file instead. This will allow to create `GeneratorContext.callToSubstitutedDescriptorMap` for each file and clear it after its only call site (InsertImplicitCasts) has used it. Also simplify code a bit.
This commit is contained in:
@@ -19,18 +19,19 @@ package org.jetbrains.kotlin.psi2ir
|
|||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
||||||
import org.jetbrains.kotlin.ir.linkage.IrProvider
|
import org.jetbrains.kotlin.ir.linkage.IrProvider
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.ConstantValueGenerator
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||||
|
import org.jetbrains.kotlin.ir.util.noUnboundLeft
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.*
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||||
import org.jetbrains.kotlin.psi2ir.transformations.insertImplicitCasts
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions
|
||||||
|
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
@@ -76,12 +77,8 @@ class Psi2IrTranslator(
|
|||||||
linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>,
|
linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>,
|
||||||
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
|
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
|
||||||
): IrModuleFragment {
|
): IrModuleFragment {
|
||||||
val moduleGenerator = ModuleGenerator(context)
|
val moduleGenerator = ModuleGenerator(context, expectDescriptorToSymbol)
|
||||||
val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles)
|
val irModule = moduleGenerator.generateModuleFragment(ktFiles)
|
||||||
|
|
||||||
irModule.patchDeclarationParents()
|
|
||||||
expectDescriptorToSymbol?.let { referenceExpectsForUsedActuals(it, context.symbolTable, irModule) }
|
|
||||||
postprocess(context, irModule)
|
|
||||||
|
|
||||||
val deserializers = irProviders.filterIsInstance<IrDeserializer>()
|
val deserializers = irProviders.filterIsInstance<IrDeserializer>()
|
||||||
deserializers.forEach { it.init(irModule, linkerExtensions) }
|
deserializers.forEach { it.init(irModule, linkerExtensions) }
|
||||||
@@ -100,22 +97,4 @@ class Psi2IrTranslator(
|
|||||||
|
|
||||||
return irModule
|
return irModule
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun postprocess(context: GeneratorContext, irElement: IrModuleFragment) {
|
|
||||||
generateSyntheticDeclarations(irElement, context)
|
|
||||||
insertImplicitCasts(irElement, context)
|
|
||||||
generateAnnotationsForDeclarations(context, irElement)
|
|
||||||
|
|
||||||
irElement.patchDeclarationParents()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateAnnotationsForDeclarations(context: GeneratorContext, irElement: IrElement) {
|
|
||||||
val annotationGenerator = AnnotationGenerator(context)
|
|
||||||
irElement.acceptVoid(annotationGenerator)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateSyntheticDeclarations(moduleFragment: IrModuleFragment, context: GeneratorContext) {
|
|
||||||
val generator = IrSyntheticDeclarationGenerator(context)
|
|
||||||
moduleFragment.acceptChildrenVoid(generator)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+81
-72
@@ -1,3 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* 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.psi2ir.generators
|
package org.jetbrains.kotlin.psi2ir.generators
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -11,80 +16,84 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
|||||||
import org.jetbrains.kotlin.resolve.multiplatform.findExpects
|
import org.jetbrains.kotlin.resolve.multiplatform.findExpects
|
||||||
|
|
||||||
// Need to create unbound symbols for expects corresponding to actuals of the currently compiled module.
|
// Need to create unbound symbols for expects corresponding to actuals of the currently compiled module.
|
||||||
// This is neccessary because there is no explicit links between expects and actuals
|
// This is necessary because there are no explicit links between expects and actuals
|
||||||
// neither in descriptors nor in IR.
|
// neither in descriptors nor in IR.
|
||||||
fun referenceExpectsForUsedActuals(
|
internal fun referenceExpectsForUsedActuals(
|
||||||
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>,
|
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>,
|
||||||
symbolTable: SymbolTable,
|
symbolTable: SymbolTable,
|
||||||
irModule: IrModuleFragment
|
element: IrElement,
|
||||||
) {
|
) {
|
||||||
irModule.acceptVoid(object : IrElementVisitorVoid {
|
element.acceptVoid(ExpectDependencyGenerator(expectDescriptorToSymbol, symbolTable))
|
||||||
|
}
|
||||||
private fun <T> T.forEachExpect(body: (DeclarationDescriptor) -> Unit) where T : IrDeclaration {
|
|
||||||
this.descriptor.findExpects().forEach {
|
private class ExpectDependencyGenerator(
|
||||||
body(it)
|
private val expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>,
|
||||||
}
|
private val symbolTable: SymbolTable,
|
||||||
}
|
) : IrElementVisitorVoid {
|
||||||
|
private fun <T> T.forEachExpect(body: (DeclarationDescriptor) -> Unit) where T : IrDeclaration {
|
||||||
override fun visitElement(element: IrElement) {
|
this.descriptor.findExpects().forEach {
|
||||||
element.acceptChildrenVoid(this)
|
body(it)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
override fun visitClass(declaration: IrClass) {
|
|
||||||
declaration.forEachExpect { expectDescriptor ->
|
override fun visitElement(element: IrElement) {
|
||||||
val symbol = symbolTable.referenceClass(expectDescriptor as ClassDescriptor)
|
element.acceptChildrenVoid(this)
|
||||||
expectDescriptorToSymbol[expectDescriptor] = symbol
|
}
|
||||||
expectDescriptor.constructors.forEach {
|
|
||||||
expectDescriptorToSymbol[it] = symbolTable.referenceConstructor(it as ClassConstructorDescriptor)
|
override fun visitClass(declaration: IrClass) {
|
||||||
}
|
declaration.forEachExpect { expectDescriptor ->
|
||||||
}
|
val symbol = symbolTable.referenceClass(expectDescriptor as ClassDescriptor)
|
||||||
super.visitDeclaration(declaration)
|
expectDescriptorToSymbol[expectDescriptor] = symbol
|
||||||
}
|
expectDescriptor.constructors.forEach {
|
||||||
|
expectDescriptorToSymbol[it] = symbolTable.referenceConstructor(it as ClassConstructorDescriptor)
|
||||||
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
|
}
|
||||||
declaration.forEachExpect {
|
}
|
||||||
val symbol = symbolTable.referenceSimpleFunction(it as FunctionDescriptor)
|
super.visitDeclaration(declaration)
|
||||||
expectDescriptorToSymbol[it] = symbol
|
}
|
||||||
}
|
|
||||||
super.visitDeclaration(declaration)
|
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
|
||||||
}
|
declaration.forEachExpect {
|
||||||
|
val symbol = symbolTable.referenceSimpleFunction(it as FunctionDescriptor)
|
||||||
override fun visitConstructor(declaration: IrConstructor) {
|
expectDescriptorToSymbol[it] = symbol
|
||||||
declaration.forEachExpect {
|
}
|
||||||
val symbol = symbolTable.referenceConstructor(it as ClassConstructorDescriptor)
|
super.visitDeclaration(declaration)
|
||||||
expectDescriptorToSymbol[it] = symbol
|
}
|
||||||
|
|
||||||
}
|
override fun visitConstructor(declaration: IrConstructor) {
|
||||||
super.visitDeclaration(declaration)
|
declaration.forEachExpect {
|
||||||
}
|
val symbol = symbolTable.referenceConstructor(it as ClassConstructorDescriptor)
|
||||||
|
expectDescriptorToSymbol[it] = symbol
|
||||||
override fun visitProperty(declaration: IrProperty) {
|
|
||||||
declaration.forEachExpect {
|
}
|
||||||
val symbol = symbolTable.referenceProperty(it as PropertyDescriptor)
|
super.visitDeclaration(declaration)
|
||||||
expectDescriptorToSymbol[it] = symbol
|
}
|
||||||
}
|
|
||||||
super.visitDeclaration(declaration)
|
override fun visitProperty(declaration: IrProperty) {
|
||||||
}
|
declaration.forEachExpect {
|
||||||
|
val symbol = symbolTable.referenceProperty(it as PropertyDescriptor)
|
||||||
override fun visitEnumEntry(declaration: IrEnumEntry) {
|
expectDescriptorToSymbol[it] = symbol
|
||||||
declaration.forEachExpect {
|
}
|
||||||
val symbol = symbolTable.referenceEnumEntry(it as ClassDescriptor)
|
super.visitDeclaration(declaration)
|
||||||
expectDescriptorToSymbol[it] = symbol
|
}
|
||||||
|
|
||||||
}
|
override fun visitEnumEntry(declaration: IrEnumEntry) {
|
||||||
super.visitDeclaration(declaration)
|
declaration.forEachExpect {
|
||||||
}
|
val symbol = symbolTable.referenceEnumEntry(it as ClassDescriptor)
|
||||||
|
expectDescriptorToSymbol[it] = symbol
|
||||||
override fun visitTypeAlias(declaration: IrTypeAlias) {
|
|
||||||
declaration.forEachExpect {
|
}
|
||||||
val symbol = when (it) {
|
super.visitDeclaration(declaration)
|
||||||
is ClassDescriptor -> symbolTable.referenceClass(it)
|
}
|
||||||
else -> error("Unexpected expect for actual type alias: $it")
|
|
||||||
}
|
override fun visitTypeAlias(declaration: IrTypeAlias) {
|
||||||
expectDescriptorToSymbol[it] = symbol
|
declaration.forEachExpect {
|
||||||
|
val symbol = when (it) {
|
||||||
}
|
is ClassDescriptor -> symbolTable.referenceClass(it)
|
||||||
super.visitDeclaration(declaration)
|
else -> error("Unexpected expect for actual type alias: $it")
|
||||||
}
|
}
|
||||||
})
|
expectDescriptorToSymbol[it] = symbol
|
||||||
|
|
||||||
|
}
|
||||||
|
super.visitDeclaration(declaration)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-19
@@ -17,31 +17,38 @@
|
|||||||
package org.jetbrains.kotlin.psi2ir.generators
|
package org.jetbrains.kotlin.psi2ir.generators
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource
|
import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||||
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
||||||
import org.jetbrains.kotlin.ir.linkage.IrProvider
|
import org.jetbrains.kotlin.ir.linkage.IrProvider
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||||
|
import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions
|
||||||
|
import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList
|
||||||
|
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi2ir.transformations.insertImplicitCasts
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
|
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
class ModuleGenerator(
|
||||||
|
override val context: GeneratorContext,
|
||||||
|
private val expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
|
||||||
|
) : Generator {
|
||||||
private val constantValueGenerator = context.constantValueGenerator
|
private val constantValueGenerator = context.constantValueGenerator
|
||||||
|
|
||||||
fun generateModuleFragment(ktFiles: Collection<KtFile>, deserializer: IrDeserializer, extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY): IrModuleFragment =
|
fun generateModuleFragment(ktFiles: Collection<KtFile>): IrModuleFragment =
|
||||||
generateModuleFragmentWithoutDependencies(ktFiles).also { irModule ->
|
|
||||||
generateUnboundSymbolsAsDependencies(irModule, deserializer, extensions)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun generateModuleFragmentWithoutDependencies(ktFiles: Collection<KtFile>): IrModuleFragment =
|
|
||||||
IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule ->
|
IrModuleFragmentImpl(context.moduleDescriptor, context.irBuiltIns).also { irModule ->
|
||||||
irModule.files.addAll(generateFiles(ktFiles))
|
val irDeclarationGenerator = DeclarationGenerator(context)
|
||||||
|
ktFiles.mapTo(irModule.files) { ktFile ->
|
||||||
|
generateSingleFile(irDeclarationGenerator, ktFile)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateUnboundSymbolsAsDependencies(
|
fun generateUnboundSymbolsAsDependencies(
|
||||||
@@ -62,14 +69,6 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
.generateUnboundSymbolsAsDependencies()
|
.generateUnboundSymbolsAsDependencies()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateFiles(ktFiles: Collection<KtFile>): List<IrFile> {
|
|
||||||
val irDeclarationGenerator = DeclarationGenerator(context)
|
|
||||||
|
|
||||||
return ktFiles.map { ktFile ->
|
|
||||||
generateSingleFile(irDeclarationGenerator, ktFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateSingleFile(irDeclarationGenerator: DeclarationGenerator, ktFile: KtFile): IrFileImpl {
|
private fun generateSingleFile(irDeclarationGenerator: DeclarationGenerator, ktFile: KtFile): IrFileImpl {
|
||||||
val irFile = createEmptyIrFile(ktFile)
|
val irFile = createEmptyIrFile(ktFile)
|
||||||
|
|
||||||
@@ -84,6 +83,18 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
|
|||||||
irFile.declarations.addIfNotNull(irDeclarationGenerator.generateMemberDeclaration(ktDeclaration))
|
irFile.declarations.addIfNotNull(irDeclarationGenerator.generateMemberDeclaration(ktDeclaration))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
irFile.patchDeclarationParents()
|
||||||
|
|
||||||
|
if (expectDescriptorToSymbol != null) {
|
||||||
|
referenceExpectsForUsedActuals(expectDescriptorToSymbol, context.symbolTable, irFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
irFile.acceptChildrenVoid(IrSyntheticDeclarationGenerator(context))
|
||||||
|
insertImplicitCasts(irFile, context)
|
||||||
|
irFile.acceptVoid(AnnotationGenerator(context))
|
||||||
|
|
||||||
|
irFile.patchDeclarationParents()
|
||||||
|
|
||||||
return irFile
|
return irFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user