[K/JS] chore: rewrok klib generating with LazyIr.

This commit is contained in:
Artem Kobzar
2022-06-13 12:13:22 +00:00
committed by Space
parent 9c67276201
commit ef157b5b2e
3 changed files with 144 additions and 10 deletions
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.descriptors.IrDescriptorBasedFunctionFactory
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.acceptVoid
@@ -56,6 +57,8 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl
import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorForNotFoundClasses
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl
import org.jetbrains.kotlin.resolve.BindingContext
@@ -65,6 +68,7 @@ import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.util.DummyLogger
import org.jetbrains.kotlin.util.Logger
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import java.io.File
val KotlinLibrary.moduleName: String
@@ -159,18 +163,32 @@ fun generateIrForKlibSerialization(
val feContext = psi2IrContext.run {
JsIrLinker.JsFePluginContext(moduleDescriptor, symbolTable, typeTranslator, irBuiltIns)
}
val stubGenerator = DeclarationStubGeneratorImpl(
psi2IrContext.moduleDescriptor,
symbolTable,
irBuiltIns,
DescriptorByIdSignatureFinderImpl(psi2IrContext.moduleDescriptor, JsManglerDesc),
)
val irLinker = JsIrLinker(
psi2IrContext.moduleDescriptor,
messageLogger,
psi2IrContext.irBuiltIns,
psi2IrContext.symbolTable,
feContext,
ICData(serializedIrFiles, errorPolicy.allowErrors)
ICData(serializedIrFiles, errorPolicy.allowErrors),
stubGenerator = stubGenerator
)
sortedDependencies.map { irLinker.deserializeOnlyHeaderModule(getDescriptorByLibrary(it), it) }
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files, irLinker, messageLogger, expectDescriptorToSymbol)
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(
project,
files,
irLinker,
messageLogger,
expectDescriptorToSymbol,
stubGenerator
)
if (verifySignatures) {
moduleFragment.acceptVoid(ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc)))
@@ -449,7 +467,6 @@ fun getIrModuleInfoForSourceFiles(
symbolTable.noUnboundLeft("Unbound symbols left after linker")
}
// TODO: not sure whether this check should be enabled by default. Add configuration key for it.
val mangleChecker = ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc))
if (verifySignatures) {
@@ -514,7 +531,8 @@ fun GeneratorContext.generateModuleFragmentWithPlugins(
files: List<KtFile>,
irLinker: IrDeserializer,
messageLogger: IrMessageLogger,
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null,
stubGenerator: DeclarationStubGenerator? = null
): IrModuleFragment {
val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration)
@@ -535,12 +553,25 @@ fun GeneratorContext.generateModuleFragmentWithPlugins(
for (extension in extensions) {
psi2Ir.addPostprocessingStep { module ->
extension.generate(module, pluginContext)
val old = stubGenerator?.unboundSymbolGeneration
try {
stubGenerator?.unboundSymbolGeneration = true
extension.generate(module, pluginContext)
} finally {
stubGenerator?.unboundSymbolGeneration = old!!
}
}
}
}
return psi2Ir.generateModuleFragment(this, files, listOf(irLinker), extensions, expectDescriptorToSymbol)
return psi2Ir.generateModuleFragment(
this,
files,
listOf(stubGenerator ?: irLinker),
extensions,
expectDescriptorToSymbol
)
}
private fun createBuiltIns(storageManager: StorageManager) = object : KotlinBuiltIns(storageManager) {}
@@ -7,11 +7,17 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder
import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedDeclarationsSupport
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.library.IrLibrary
@@ -24,7 +30,8 @@ class JsIrLinker(
override val translationPluginContext: TranslationPluginContext?,
private val icData: ICData? = null,
friendModules: Map<String, Collection<String>> = emptyMap(),
override val unlinkedDeclarationsSupport: UnlinkedDeclarationsSupport = JsUnlinkedDeclarationsSupport(allowUnboundSymbols = false)
override val unlinkedDeclarationsSupport: UnlinkedDeclarationsSupport = JsUnlinkedDeclarationsSupport(allowUnboundSymbols = false),
private val stubGenerator: DeclarationStubGenerator? = null
) : KotlinIrLinker(
currentModule = currentModule,
messageLogger = messageLogger,
@@ -46,9 +53,17 @@ class JsIrLinker(
private val IrLibrary.libContainsErrorCode: Boolean
get() = this is KotlinLibrary && this.containsErrorCode
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategyResolver: (String) -> DeserializationStrategy): IrModuleDeserializer {
override fun createModuleDeserializer(
moduleDescriptor: ModuleDescriptor,
klib: KotlinLibrary?,
strategyResolver: (String) -> DeserializationStrategy
): IrModuleDeserializer {
require(klib != null) { "Expecting kotlin library" }
return JsModuleDeserializer(moduleDescriptor, klib, strategyResolver, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, klib.libContainsErrorCode)
val libraryAbiVersion = klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT
return when (val lazyIrGenerator = stubGenerator) {
null -> JsModuleDeserializer(moduleDescriptor, klib, strategyResolver, libraryAbiVersion, klib.libContainsErrorCode)
else -> JsLazyIrModuleDeserializer(moduleDescriptor, libraryAbiVersion, builtIns, lazyIrGenerator)
}
}
private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategyResolver: (String) -> DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) :
@@ -0,0 +1,88 @@
/*
* Copyright 2010-2022 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.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl
import org.jetbrains.kotlin.backend.common.serialization.IrModuleDeserializer
import org.jetbrains.kotlin.backend.common.serialization.IrModuleDeserializerKind
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.library.KotlinAbiVersion
class JsLazyIrModuleDeserializer(
moduleDescriptor: ModuleDescriptor,
libraryAbiVersion: KotlinAbiVersion,
private val builtIns: IrBuiltIns,
private val stubGenerator: DeclarationStubGenerator
) : IrModuleDeserializer(moduleDescriptor, libraryAbiVersion) {
private val dependencies = emptyList<IrModuleDeserializer>()
// TODO: implement proper check whether `idSig` belongs to this module
override fun contains(idSig: IdSignature): Boolean = true
private val descriptorFinder = DescriptorByIdSignatureFinderImpl(moduleDescriptor, JsManglerDesc)
private fun resolveDescriptor(idSig: IdSignature): DeclarationDescriptor {
return descriptorFinder.findDescriptorBySignature(idSig) ?: error("No descriptor found for $idSig")
}
override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
val descriptor = resolveDescriptor(idSig)
val declaration = stubGenerator.run {
when (symbolKind) {
BinarySymbolData.SymbolKind.CLASS_SYMBOL -> generateClassStub(descriptor as ClassDescriptor)
BinarySymbolData.SymbolKind.PROPERTY_SYMBOL -> generatePropertyStub(descriptor as PropertyDescriptor)
BinarySymbolData.SymbolKind.FUNCTION_SYMBOL -> generateFunctionStub(descriptor as FunctionDescriptor)
BinarySymbolData.SymbolKind.CONSTRUCTOR_SYMBOL -> generateConstructorStub(descriptor as ClassConstructorDescriptor)
BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL -> generateEnumEntryStub(descriptor as ClassDescriptor)
BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL -> generateTypeAliasStub(descriptor as TypeAliasDescriptor)
else -> error("Unexpected type $symbolKind for sig $idSig")
}
}
return declaration.symbol
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
override fun declareIrSymbol(symbol: IrSymbol) {
if (symbol is IrFieldSymbol) {
declareFieldStub(symbol)
} else {
stubGenerator.generateMemberStub(symbol.descriptor)
}
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
private fun declareFieldStub(symbol: IrFieldSymbol): IrField {
return with(stubGenerator) {
val old = stubGenerator.unboundSymbolGeneration
try {
stubGenerator.unboundSymbolGeneration = true
generateFieldStub(symbol.descriptor)
} finally {
stubGenerator.unboundSymbolGeneration = old
}
}
}
override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList())
override val moduleDependencies: Collection<IrModuleDeserializer> = dependencies
override val kind get() = IrModuleDeserializerKind.SYNTHETIC
}