diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt index db664015249..787495e8e55 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt @@ -19,18 +19,19 @@ package org.jetbrains.kotlin.psi2ir import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.linkage.IrProvider import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid -import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.ir.util.ConstantValueGenerator +import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.util.TypeTranslator +import org.jetbrains.kotlin.ir.util.noUnboundLeft import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi2ir.generators.* -import org.jetbrains.kotlin.psi2ir.transformations.insertImplicitCasts +import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext +import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions +import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.utils.SmartList @@ -76,12 +77,8 @@ class Psi2IrTranslator( linkerExtensions: Collection, expectDescriptorToSymbol: MutableMap? = null ): IrModuleFragment { - val moduleGenerator = ModuleGenerator(context) - val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles) - - irModule.patchDeclarationParents() - expectDescriptorToSymbol?.let { referenceExpectsForUsedActuals(it, context.symbolTable, irModule) } - postprocess(context, irModule) + val moduleGenerator = ModuleGenerator(context, expectDescriptorToSymbol) + val irModule = moduleGenerator.generateModuleFragment(ktFiles) val deserializers = irProviders.filterIsInstance() deserializers.forEach { it.init(irModule, linkerExtensions) } @@ -100,22 +97,4 @@ class Psi2IrTranslator( 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) - } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ExpectDependencyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ExpectDependencyGenerator.kt index b4141e775c4..336b73df6a3 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ExpectDependencyGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ExpectDependencyGenerator.kt @@ -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 import org.jetbrains.kotlin.descriptors.* @@ -11,80 +16,84 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.resolve.multiplatform.findExpects // 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. -fun referenceExpectsForUsedActuals( +internal fun referenceExpectsForUsedActuals( expectDescriptorToSymbol: MutableMap, symbolTable: SymbolTable, - irModule: IrModuleFragment + element: IrElement, ) { - irModule.acceptVoid(object : IrElementVisitorVoid { - - private fun T.forEachExpect(body: (DeclarationDescriptor) -> Unit) where T : IrDeclaration { - this.descriptor.findExpects().forEach { - body(it) - } - } - - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - - override fun visitClass(declaration: IrClass) { - declaration.forEachExpect { expectDescriptor -> - val symbol = symbolTable.referenceClass(expectDescriptor as ClassDescriptor) - expectDescriptorToSymbol[expectDescriptor] = symbol - expectDescriptor.constructors.forEach { - expectDescriptorToSymbol[it] = symbolTable.referenceConstructor(it as ClassConstructorDescriptor) - } - } - super.visitDeclaration(declaration) - } - - override fun visitSimpleFunction(declaration: IrSimpleFunction) { - declaration.forEachExpect { - val symbol = symbolTable.referenceSimpleFunction(it as FunctionDescriptor) - expectDescriptorToSymbol[it] = symbol - } - super.visitDeclaration(declaration) - } - - override fun visitConstructor(declaration: IrConstructor) { - declaration.forEachExpect { - val symbol = symbolTable.referenceConstructor(it as ClassConstructorDescriptor) - expectDescriptorToSymbol[it] = symbol - - } - super.visitDeclaration(declaration) - } - - override fun visitProperty(declaration: IrProperty) { - declaration.forEachExpect { - val symbol = symbolTable.referenceProperty(it as PropertyDescriptor) - expectDescriptorToSymbol[it] = symbol - } - super.visitDeclaration(declaration) - } - - override fun visitEnumEntry(declaration: IrEnumEntry) { - declaration.forEachExpect { - val symbol = symbolTable.referenceEnumEntry(it as ClassDescriptor) - expectDescriptorToSymbol[it] = symbol - - } - super.visitDeclaration(declaration) - } - - override fun visitTypeAlias(declaration: IrTypeAlias) { - declaration.forEachExpect { - val symbol = when (it) { - is ClassDescriptor -> symbolTable.referenceClass(it) - else -> error("Unexpected expect for actual type alias: $it") - } - expectDescriptorToSymbol[it] = symbol - - } - super.visitDeclaration(declaration) - } - }) + element.acceptVoid(ExpectDependencyGenerator(expectDescriptorToSymbol, symbolTable)) +} + +private class ExpectDependencyGenerator( + private val expectDescriptorToSymbol: MutableMap, + private val symbolTable: SymbolTable, +) : IrElementVisitorVoid { + private fun T.forEachExpect(body: (DeclarationDescriptor) -> Unit) where T : IrDeclaration { + this.descriptor.findExpects().forEach { + body(it) + } + } + + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitClass(declaration: IrClass) { + declaration.forEachExpect { expectDescriptor -> + val symbol = symbolTable.referenceClass(expectDescriptor as ClassDescriptor) + expectDescriptorToSymbol[expectDescriptor] = symbol + expectDescriptor.constructors.forEach { + expectDescriptorToSymbol[it] = symbolTable.referenceConstructor(it as ClassConstructorDescriptor) + } + } + super.visitDeclaration(declaration) + } + + override fun visitSimpleFunction(declaration: IrSimpleFunction) { + declaration.forEachExpect { + val symbol = symbolTable.referenceSimpleFunction(it as FunctionDescriptor) + expectDescriptorToSymbol[it] = symbol + } + super.visitDeclaration(declaration) + } + + override fun visitConstructor(declaration: IrConstructor) { + declaration.forEachExpect { + val symbol = symbolTable.referenceConstructor(it as ClassConstructorDescriptor) + expectDescriptorToSymbol[it] = symbol + + } + super.visitDeclaration(declaration) + } + + override fun visitProperty(declaration: IrProperty) { + declaration.forEachExpect { + val symbol = symbolTable.referenceProperty(it as PropertyDescriptor) + expectDescriptorToSymbol[it] = symbol + } + super.visitDeclaration(declaration) + } + + override fun visitEnumEntry(declaration: IrEnumEntry) { + declaration.forEachExpect { + val symbol = symbolTable.referenceEnumEntry(it as ClassDescriptor) + expectDescriptorToSymbol[it] = symbol + + } + super.visitDeclaration(declaration) + } + + override fun visitTypeAlias(declaration: IrTypeAlias) { + declaration.forEachExpect { + val symbol = when (it) { + is ClassDescriptor -> symbolTable.referenceClass(it) + else -> error("Unexpected expect for actual type alias: $it") + } + expectDescriptorToSymbol[it] = symbol + + } + super.visitDeclaration(declaration) + } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt index 1c56b718327..45879220811 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt @@ -17,31 +17,38 @@ package org.jetbrains.kotlin.psi2ir.generators 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.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl import org.jetbrains.kotlin.ir.linkage.IrDeserializer 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.psi2ir.transformations.insertImplicitCasts import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile import org.jetbrains.kotlin.utils.addIfNotNull -class ModuleGenerator(override val context: GeneratorContext) : Generator { - +class ModuleGenerator( + override val context: GeneratorContext, + private val expectDescriptorToSymbol: MutableMap? = null +) : Generator { private val constantValueGenerator = context.constantValueGenerator - fun generateModuleFragment(ktFiles: Collection, deserializer: IrDeserializer, extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY): IrModuleFragment = - generateModuleFragmentWithoutDependencies(ktFiles).also { irModule -> - generateUnboundSymbolsAsDependencies(irModule, deserializer, extensions) - } - - fun generateModuleFragmentWithoutDependencies(ktFiles: Collection): IrModuleFragment = + fun generateModuleFragment(ktFiles: Collection): IrModuleFragment = 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( @@ -62,14 +69,6 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator { .generateUnboundSymbolsAsDependencies() } - private fun generateFiles(ktFiles: Collection): List { - val irDeclarationGenerator = DeclarationGenerator(context) - - return ktFiles.map { ktFile -> - generateSingleFile(irDeclarationGenerator, ktFile) - } - } - private fun generateSingleFile(irDeclarationGenerator: DeclarationGenerator, ktFile: KtFile): IrFileImpl { val irFile = createEmptyIrFile(ktFile) @@ -84,6 +83,18 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator { 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 }