feat: add polyfills insertion for ES Next used features

This commit is contained in:
Artem Kobzar
2022-02-16 10:49:11 +00:00
committed by Space
parent 76ff717091
commit 804eb61bf0
80 changed files with 8769 additions and 6552 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.backend.js.lower.JsInnerClassesSupport
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsPolyfills
import org.jetbrains.kotlin.ir.backend.js.utils.JsInlineClassesUtils
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
@@ -65,7 +66,7 @@ class JsIrBackendContext(
val granularity: JsGenerationGranularity = JsGenerationGranularity.WHOLE_PROGRAM,
val icCompatibleIr2Js: Boolean = false,
) : JsCommonBackendContext {
val polyfills = JsPolyfills()
val fieldToInitializer: MutableMap<IrField, IrExpression> = mutableMapOf()
val localClassNames: MutableMap<IrClass, String> = mutableMapOf()
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
import org.jetbrains.kotlin.ir.backend.js.lower.collectNativeImplementations
import org.jetbrains.kotlin.ir.backend.js.lower.generateJsTests
import org.jetbrains.kotlin.ir.backend.js.lower.moveBodilessDeclarationsToSeparatePlace
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
@@ -140,6 +141,7 @@ fun compileIr(
}
allModules.forEach { module ->
collectNativeImplementations(context, module)
moveBodilessDeclarationsToSeparatePlace(context, module)
}
@@ -158,6 +160,7 @@ fun generateJsCode(
moduleFragment: IrModuleFragment,
nameTables: NameTables
): String {
collectNativeImplementations(context, moduleFragment)
moveBodilessDeclarationsToSeparatePlace(context, moduleFragment)
jsPhases.invokeToplevel(PhaseConfig(jsPhases), context, listOf(moduleFragment))
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.backend.js.ic.ModuleCache
import org.jetbrains.kotlin.ir.backend.js.ic.PersistentCacheConsumer
import org.jetbrains.kotlin.ir.backend.js.lower.collectNativeImplementations
import org.jetbrains.kotlin.ir.backend.js.lower.generateJsTests
import org.jetbrains.kotlin.ir.backend.js.lower.moveBodilessDeclarationsToSeparatePlace
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
@@ -80,6 +81,7 @@ fun compileWithIC(
symbolTable.noUnboundLeft("Unbound symbols at the end of linker")
allModules.forEach {
collectNativeImplementations(context, module)
moveBodilessDeclarationsToSeparatePlace(context, it)
}
@@ -34,9 +34,11 @@ fun eliminateDeadDeclarations(
val uselessDeclarationsProcessor =
UselessDeclarationsRemover(removeUnusedAssociatedObjects, usefulDeclarations, context, context.dceRuntimeDiagnostic)
modules.forEach { module ->
module.files.forEach {
it.acceptVoid(uselessDeclarationsProcessor)
context.polyfills.saveOnlyIntersectionOfNextDeclarationsFor(it, usefulDeclarations)
}
}
}
@@ -55,7 +57,15 @@ private fun IrDeclaration.addRootsTo(
setter?.addRootsTo(nestedVisitor, context)
}
isEffectivelyExternal() -> {
acceptVoid(nestedVisitor)
val correspondingProperty = when (this) {
is IrField -> correspondingPropertySymbol?.owner
is IrSimpleFunction -> correspondingPropertySymbol?.owner
else -> null
}
if (!hasJsPolyfill() && correspondingProperty?.hasJsPolyfill() != true) {
acceptVoid(nestedVisitor)
}
}
isExported(context) -> {
acceptVoid(nestedVisitor)
@@ -55,9 +55,24 @@ abstract class UsefulDeclarationProcessor(
expression.symbol.owner.enqueue(data, "raw function access")
}
override fun visitBlock(expression: IrBlock, data: IrDeclaration) {
super.visitBlock(expression, data)
if (expression !is IrReturnableBlock) return
expression.inlineFunctionSymbol?.owner?.enqueue(data, "inline function usage")
}
override fun visitFieldAccess(expression: IrFieldAccessExpression, data: IrDeclaration) {
super.visitFieldAccess(expression, data)
expression.symbol.owner.enqueue(data, "field access")
val field = expression.symbol.owner.apply { enqueue(data, "field access") }
val correspondingProperty = field.correspondingPropertySymbol?.owner ?: return
if (
field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD &&
correspondingProperty.hasJsPolyfill()
) {
correspondingProperty.enqueue(field, "property backing field")
}
}
override fun visitStringConcatenation(expression: IrStringConcatenation, data: IrDeclaration) {
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2021 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
import org.jetbrains.kotlin.backend.common.DeclarationTransformer
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
fun collectNativeImplementations(context: JsIrBackendContext, moduleFragment: IrModuleFragment) =
CollectNativeImplementationsVisitor(context).let { collector ->
moduleFragment.files.forEach { it.accept(collector, null) }
}
class CollectNativeImplementationsVisitor(private val context: JsIrBackendContext) : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {}
override fun visitFile(declaration: IrFile) {
declaration.declarations.forEach {
context.polyfills.registerDeclarationNativeImplementation(declaration, it)
}
super.visitFile(declaration)
}
}
@@ -114,7 +114,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
expression
)
return JsNameRef(field.getJsNameOrKotlinName().identifier, receiver).withSource(expression, context)
.also { context.staticContext.polyfills.visitDeclaration(field) }
}
if (fieldParent is IrClass && context.isClassInlineLike(fieldParent)) {
@@ -129,7 +128,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
if (owner.isThisReceiver()) return JsThisRef().withSource(expression, context)
return context.getNameForValueDeclaration(owner).makeRef().withSource(expression, context)
.also { context.staticContext.polyfills.visitDeclaration(owner) }
}
override fun visitGetObjectValue(expression: IrGetObjectValue, context: JsGenerationContext): JsExpression {
@@ -146,7 +144,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
val dest = jsElementAccess(fieldName.ident, expression.receiver?.accept(this, context))
val source = expression.value.accept(this, context)
return jsAssignment(dest, source).withSource(expression, context)
.also { context.staticContext.polyfills.visitDeclaration(field) }
}
override fun visitSetValue(expression: IrSetValue, context: JsGenerationContext): JsExpression {
@@ -154,7 +151,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
val ref = JsNameRef(context.getNameForValueDeclaration(field))
val value = expression.value.accept(this, context)
return JsBinaryOperation(JsBinaryOperator.ASG, ref, value).withSource(expression, context)
.also { context.staticContext.polyfills.visitDeclaration(field) }
}
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, context: JsGenerationContext): JsExpression {
@@ -225,10 +221,6 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
return JsCallTransformer(expression, context).generateExpression()
}
return translateCall(expression, context, this).withSource(expression, context)
.also {
val function = expression.symbol.owner
context.staticContext.polyfills.visitDeclaration(function.correspondingPropertySymbol?.owner ?: function)
}
}
override fun visitWhen(expression: IrWhen, context: JsGenerationContext): JsExpression {
@@ -86,9 +86,7 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
override fun visitSetValue(expression: IrSetValue, context: JsGenerationContext): JsStatement {
val owner = expression.symbol.owner
val ref = JsNameRef(context.getNameForValueDeclaration(owner))
return expression.value
.maybeOptimizeIntoSwitch(context) { jsAssignment(ref, it).withSource(expression, context).makeStmt() }
.also { context.staticContext.polyfills.visitDeclaration(owner) }
return expression.value.maybeOptimizeIntoSwitch(context) { jsAssignment(ref, it).withSource(expression, context).makeStmt() }
}
override fun visitReturn(expression: IrReturn, context: JsGenerationContext): JsStatement {
@@ -139,7 +137,6 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
return JsCallTransformer(expression, data).generateStatement()
}
return translateCall(expression, data, IrElementToJsExpressionTransformer()).withSource(expression, data).makeStmt()
.also { data.staticContext.polyfills.visitDeclaration(expression.symbol.owner) }
}
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, context: JsGenerationContext): JsStatement {
@@ -98,7 +98,7 @@ class IrModuleToJsTransformer(
exportedModule,
namer,
refInfo,
generateMainCall = true
generateMainCall = true,
)
val dependencies = others.mapIndexed { index, module ->
@@ -112,7 +112,7 @@ class IrModuleToJsTransformer(
ExportedModule(moduleName, exportedModule.moduleKind, exportedDeclarations),
namer,
refInfo,
generateMainCall = false
generateMainCall = false,
)
}.reversed()
@@ -123,7 +123,8 @@ class IrModuleToJsTransformer(
emptyList(),
exportedModule,
namer,
EmptyCrossModuleReferenceInfo
EmptyCrossModuleReferenceInfo,
generateMainCall = true,
)
}
}
@@ -134,7 +135,7 @@ class IrModuleToJsTransformer(
exportedModule: ExportedModule,
namer: NameTables,
refInfo: CrossModuleReferenceInfo,
generateMainCall: Boolean = true
generateMainCall: Boolean = true,
): CompilationOutputs {
val nameGenerator = refInfo.withReferenceTracking(
@@ -147,6 +148,7 @@ class IrModuleToJsTransformer(
globalNameScope = namer.globalNames
)
val polyfillStatements = generatePolyfillStatements(modules)
val (importStatements, importedJsModules) =
generateImportStatements(
getNameForExternalDeclaration = { staticContext.getNameForStaticDeclaration(it) },
@@ -163,8 +165,10 @@ class IrModuleToJsTransformer(
val crossModuleExports = generateCrossModuleExports(modules, refInfo, internalModuleName)
val program = JsProgram()
if (generateScriptModule) {
with(program.globalBlock) {
statements.addWithComment("block: polyfills", polyfillStatements)
statements.addWithComment("block: imports", importStatements + crossModuleImports)
statements += moduleBody
statements.addWithComment("block: exports", exportStatements + crossModuleExports)
@@ -185,6 +189,7 @@ class IrModuleToJsTransformer(
}
}
program.globalBlock.statements.addWithComment("block: polyfills", polyfillStatements)
program.globalBlock.statements += ModuleWrapperTranslation.wrap(
exportedModule.name,
rootFunction,
@@ -223,7 +228,6 @@ class IrModuleToJsTransformer(
null
}
staticContext.polyfills.addAllNeededPolyfillsTo(jsCode)
program.accept(JsToStringGenerationVisitor(jsCode, sourceMapBuilderConsumer ?: NoOpSourceLocationConsumer))
return CompilationOutputs(
@@ -290,7 +294,6 @@ class IrModuleToJsTransformer(
val statements = mutableListOf<JsStatement>()
val preDeclarationBlock = JsGlobalBlock()
val postDeclarationBlock = JsGlobalBlock()
statements.addWithComment("block: pre-declaration", preDeclarationBlock)
@@ -394,6 +397,13 @@ class IrModuleToJsTransformer(
} ?: emptyList()
}
private fun generatePolyfillStatements(modules: Iterable<IrModuleFragment>): List<JsStatement> {
return modules.asSequence()
.flatMap { it.files }
.flatMap { backendContext.polyfills.getAllPolyfillsFor(it) }
.toList()
}
private fun generateImportStatements(
getNameForExternalDeclaration: (IrDeclarationWithName) -> JsName,
declareFreshGlobal: (String) -> JsName
@@ -147,13 +147,16 @@ class IrModuleToJsTransformerTmp(
modules: Iterable<IrModuleFragment>,
exportData: Map<IrModuleFragment, Map<IrFile, List<ExportedDeclaration>>>,
): JsIrProgram {
return JsIrProgram(
modules.map { m ->
JsIrModule(m.safeName, m.externalModuleName(), m.files.map { f ->
val exports = exportData[m]!![f]!!
generateProgramFragment(f, exports)
})
JsIrModule(
m.safeName,
m.externalModuleName(),
m.files.map {
val exports = exportData[m]!![it]!!
generateProgramFragment(it, exports)
},
)
}
)
}
@@ -172,7 +175,9 @@ class IrModuleToJsTransformerTmp(
globalNameScope = globalNameScope
)
val result = JsIrProgramFragment(file.fqName.asString())
val result = JsIrProgramFragment(file.fqName.asString()).apply {
polyfills.statements += backendContext.polyfills.getAllPolyfillsFor(file)
}
val internalModuleName = ReservedJsNames.makeInternalModuleName()
val globalNames = NameTable<String>(globalNameScope)
@@ -364,7 +369,7 @@ private fun generateSingleWrappedModuleBody(
sourceMapsInfo: SourceMapsInfo?,
generateScriptModule: Boolean,
generateCallToMain: Boolean,
crossModuleReferences: CrossModuleReferences = CrossModuleReferences.Empty
crossModuleReferences: CrossModuleReferences = CrossModuleReferences.Empty,
): CompilationOutputs {
val program = Merger(
moduleName,
@@ -21,9 +21,14 @@ class JsIrProgramFragment(val packageFqn: String) {
var testFunInvocation: JsStatement? = null
var suiteFn: JsName? = null
val definitions = mutableSetOf<String>()
val polyfills = JsGlobalBlock()
}
class JsIrModule(val moduleName: String, val externalModuleName: String, val fragments: List<JsIrProgramFragment>)
class JsIrModule(
val moduleName: String,
val externalModuleName: String,
val fragments: List<JsIrProgramFragment>,
)
class JsIrProgram(val modules: List<JsIrModule>) {
val mainModule = modules.last()
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2021 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.transformers.irToJs
import org.jetbrains.kotlin.ir.backend.js.utils.getJsPolyfill
import org.jetbrains.kotlin.ir.backend.js.utils.hasJsPolyfill
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.js.backend.ast.JsStatement
class JsPolyfills {
private val polyfillsPerFile = hashMapOf<IrFile, HashSet<IrDeclaration>>()
fun registerDeclarationNativeImplementation(file: IrFile, declaration: IrDeclaration) {
if (!declaration.hasJsPolyfill()) return
val declarations = polyfillsPerFile[file] ?: hashSetOf()
declarations.add(declaration)
polyfillsPerFile[file] = declarations
}
fun saveOnlyIntersectionOfNextDeclarationsFor(file: IrFile, declarations: Set<IrDeclaration>) {
val polyfills = polyfillsPerFile[file] ?: return
polyfillsPerFile[file] = polyfills.intersect(declarations).toHashSet()
}
fun getAllPolyfillsFor(file: IrFile): List<JsStatement> =
polyfillsPerFile[file].orEmpty().asImplementationList()
private fun Iterable<IrDeclaration>.asImplementationList() =
asSequence().asImplementationList()
private fun Sequence<IrDeclaration>.asImplementationList(): List<JsStatement> =
map { it.getJsPolyfill()!! }
.distinct()
.flatMap { parseJsCode(it).orEmpty() }
.toList()
}
@@ -1,28 +0,0 @@
/*
* Copyright 2010-2021 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.transformers.irToJs
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.backend.js.utils.getJsNativeImplementation
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
import org.jetbrains.kotlin.js.util.TextOutput
class JsPolyfillsVisitor {
private val polyfills = mutableSetOf<String>()
fun visitDeclaration(declaration: IrDeclaration) {
if (!declaration.isEffectivelyExternal()) return
val implementation = declaration.getJsNativeImplementation() ?: return
polyfills.add(implementation)
}
fun addAllNeededPolyfillsTo(output: TextOutput) {
if (polyfills.isEmpty()) return
output.print("// region block: polyfills")
output.print(polyfills.joinToString("\n"))
output.print("// endregion\n")
}
}
@@ -159,21 +159,22 @@ class Merger(
linkJsNames()
val moduleBody = mutableListOf<JsStatement>().also {
if (!generateScriptModule) it += JsStringLiteral("use strict").makeStmt()
}
val moduleBody = mutableListOf<JsStatement>()
val preDeclarationBlock = JsGlobalBlock()
val postDeclarationBlock = JsGlobalBlock()
val polyfillDeclarationBlock = JsGlobalBlock()
moduleBody.addWithComment("block: pre-declaration", preDeclarationBlock)
val classModels = mutableMapOf<JsName, JsIrIcClassModel>()
val initializerBlock = JsGlobalBlock()
fragments.forEach {
moduleBody += it.declarations.statements
classModels += it.classes
initializerBlock.statements += it.initializers.statements
polyfillDeclarationBlock.statements += it.polyfills.statements
}
// sort member forwarding code
@@ -213,9 +214,13 @@ class Merger(
if (generateScriptModule) {
with(program.globalBlock) {
this.statements.addWithComment("block: imports", importStatements)
this.statements += moduleBody
this.statements.addWithComment("block: exports", exportStatements)
if (!generateScriptModule) {
statements += JsStringLiteral("use strict").makeStmt()
}
statements.addWithComment("block: polyfills", polyfillDeclarationBlock.statements)
statements.addWithComment("block: imports", importStatements)
statements += moduleBody
statements.addWithComment("block: exports", exportStatements)
}
} else {
val internalModuleName = ReservedJsNames.makeInternalModuleName()
@@ -223,9 +228,12 @@ class Merger(
parameters += JsParameter(internalModuleName)
parameters += (importedJsModules).map { JsParameter(it.internalName) }
with(body) {
this.statements.addWithComment("block: imports", importStatements)
this.statements += moduleBody
this.statements.addWithComment("block: exports", exportStatements)
if (!generateScriptModule) {
statements += JsStringLiteral("use strict").makeStmt()
}
statements.addWithComment("block: imports", importStatements)
statements += moduleBody
statements.addWithComment("block: exports", exportStatements)
if (generateCallToMain) {
callToMain?.let { this.statements += it }
}
@@ -233,6 +241,7 @@ class Merger(
}
}
program.globalBlock.statements.addWithComment("block: polyfills", polyfillDeclarationBlock.statements)
program.globalBlock.statements += ModuleWrapperTranslation.wrap(
moduleName,
rootFunction,
@@ -27,7 +27,7 @@ object JsAnnotations {
val jsNativeSetter = FqName("kotlin.js.nativeSetter")
val jsNativeInvoke = FqName("kotlin.js.nativeInvoke")
val jsFunFqn = FqName("kotlin.js.JsFun")
val jsNativeImplementationFqn = FqName("kotlin.js.JsNativeImplementation")
val JsPolyfillFqn = FqName("kotlin.js.JsPolyfill")
}
@Suppress("UNCHECKED_CAST")
@@ -46,8 +46,11 @@ fun IrAnnotationContainer.getJsQualifier(): String? =
fun IrAnnotationContainer.getJsName(): String? =
getAnnotation(JsAnnotations.jsNameFqn)?.getSingleConstStringArgument()
fun IrAnnotationContainer.getJsNativeImplementation(): String? =
getAnnotation(JsAnnotations.jsNativeImplementationFqn)?.getSingleConstStringArgument()
fun IrAnnotationContainer.getJsPolyfill(): String? =
getAnnotation(JsAnnotations.JsPolyfillFqn)?.getSingleConstStringArgument()
fun IrAnnotationContainer.hasJsPolyfill(): Boolean =
hasAnnotation(JsAnnotations.JsPolyfillFqn)
fun IrAnnotationContainer.getJsFunAnnotation(): String? =
getAnnotation(JsAnnotations.jsFunFqn)?.getSingleConstStringArgument()
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.backend.js.utils
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIntrinsicTransformers
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrClassModel
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsPolyfillsVisitor
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
@@ -20,7 +19,6 @@ class JsStaticContext(
private val irNamer: IrNamer,
val globalNameScope: NameTable<IrDeclaration>,
) : IrNamer by irNamer {
val polyfills = JsPolyfillsVisitor()
val intrinsics = JsIntrinsicTransformers(backendContext)
val classModels = mutableMapOf<IrClassSymbol, JsIrClassModel>()
val coroutineImplDeclaration = backendContext.ir.symbols.coroutineImpl.owner
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.ir.backend.js.utils.serialization
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrClassModel
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrIcClassModel
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrProgramFragment
import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope
@@ -60,6 +59,9 @@ class JsIrAstDeserializer : JsAstDeserializerBase() {
if (proto.hasExportBlock()) {
fragment.exports.statements += deserializeGlobalBlock(proto.exportBlock).statements
}
if (proto.hasPolyfills()) {
fragment.polyfills.statements += deserializeGlobalBlock(proto.polyfills).statements
}
proto.nameBindingList.associateTo(fragment.nameBindings) { nameBindingProto ->
deserializeString(nameBindingProto.signatureId) to deserializeName(nameBindingProto.nameId)
@@ -80,7 +82,6 @@ class JsIrAstDeserializer : JsAstDeserializerBase() {
}
fragment.dts = proto.dts
fragment.definitions += proto.definitionsList.map { deserializeString(it) }
return fragment
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrProgramFragmen
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.*
import org.jetbrains.kotlin.serialization.js.ast.JsAstSerializerBase
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.io.OutputStream
@@ -60,6 +61,7 @@ class JsIrAstSerializer: JsAstSerializerBase() {
fragmentBuilder.declarationBlock = serializeBlock(fragment.declarations)
fragmentBuilder.initializerBlock = serializeBlock(fragment.initializers)
fragmentBuilder.exportBlock = serializeBlock(fragment.exports)
fragmentBuilder.polyfills = serializeBlock(fragment.polyfills)
for ((key, name) in fragment.nameBindings.entries) {
val nameBindingBuilder = NameBinding.newBuilder()