diff --git a/js/js.serializer/js.serializer.iml b/js/js.serializer/js.serializer.iml
index e388cce830b..568eb6175e4 100644
--- a/js/js.serializer/js.serializer.iml
+++ b/js/js.serializer/js.serializer.iml
@@ -4,7 +4,7 @@
-
+
@@ -12,5 +12,6 @@
+
\ No newline at end of file
diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstSerializer.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstSerializer.kt
new file mode 100644
index 00000000000..27cb240236f
--- /dev/null
+++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstSerializer.kt
@@ -0,0 +1,510 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.serialization.js.ast
+
+import org.jetbrains.kotlin.js.backend.ast.*
+import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.*
+import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.BinaryOperation.Type.*
+import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.UnaryOperation.Type.*
+import java.io.OutputStream
+
+class JsAstSerializer {
+ private val nameTableBuilder = NameTable.newBuilder()
+ private val stringTableBuilder = StringTable.newBuilder()
+ private val nameMap = mutableMapOf()
+ private val stringMap = mutableMapOf()
+
+ fun serialize(fragment: JsProgramFragment, output: OutputStream) {
+ serialize(fragment).writeTo(output)
+ }
+
+ fun serialize(fragment: JsProgramFragment): Chunk {
+ try {
+ val chunkBuilder = Chunk.newBuilder()
+ chunkBuilder.fragment = serializeFragment(fragment)
+ chunkBuilder.nameTable = nameTableBuilder.build()
+ chunkBuilder.stringTable = stringTableBuilder.build()
+ return chunkBuilder.build()
+ }
+ finally {
+ nameTableBuilder.clear()
+ stringTableBuilder.clear()
+ nameMap.clear()
+ stringMap.clear()
+ }
+ }
+
+ private fun serializeFragment(fragment: JsProgramFragment): Fragment {
+ val fragmentBuilder = Fragment.newBuilder()
+
+ for (importedModule in fragment.importedModules) {
+ val importedModuleBuilder = ImportedModule.newBuilder()
+ importedModuleBuilder.externalNameId = serialize(importedModule.externalName)
+ importedModuleBuilder.internalNameId = serialize(importedModule.internalName)
+ importedModule.plainReference?.let { importedModuleBuilder.plainReference = serialize(it) }
+ fragmentBuilder.addImportedModule(importedModuleBuilder)
+ }
+
+ for ((signature, expression) in fragment.imports) {
+ val importBuilder = Import.newBuilder()
+ importBuilder.signatureId = serialize(signature)
+ importBuilder.expression = serialize(expression)
+ fragmentBuilder.addImportEntry(importBuilder)
+ }
+
+ fragmentBuilder.declarationBlock = serializeBlock(fragment.declarationBlock)
+ fragmentBuilder.initializerBlock = serializeBlock(fragment.initializerBlock)
+ fragmentBuilder.exportBlock = serializeBlock(fragment.exportBlock)
+
+ for (nameBinding in fragment.nameBindings) {
+ val nameBindingBuilder = NameBinding.newBuilder()
+ nameBindingBuilder.signatureId = serialize(nameBinding.key)
+ nameBindingBuilder.nameId = serialize(nameBinding.name)
+ fragmentBuilder.addNameBinding(nameBindingBuilder)
+ }
+
+ fragment.classes.values.forEach { fragmentBuilder.addClassModel(serialize(it)) }
+
+ val inlineModuleExprMap = mutableMapOf()
+ for ((signature, expression) in fragment.inlineModuleMap) {
+ val inlineModuleBuilder = InlineModule.newBuilder()
+ inlineModuleBuilder.signatureId = serialize(signature)
+ inlineModuleBuilder.expressionId = inlineModuleExprMap.getOrPut(expression) {
+ val result = fragmentBuilder.moduleExpressionCount
+ fragmentBuilder.addModuleExpression(serialize(expression))
+ result
+ }
+ fragmentBuilder.addInlineModule(inlineModuleBuilder)
+ }
+
+ return fragmentBuilder.build()
+ }
+
+ private fun serialize(classModel: JsClassModel): ClassModel {
+ val builder = ClassModel.newBuilder()
+ builder.nameId = serialize(classModel.name)
+ classModel.superName?.let { builder.superNameId = serialize(it) }
+ if (classModel.postDeclarationBlock.statements.isNotEmpty()) {
+ builder.postDeclarationBlock = serializeBlock(classModel.postDeclarationBlock)
+ }
+ return builder.build()
+ }
+
+ private fun serialize(statement: JsStatement): Statement {
+ val visitor = object : JsVisitor() {
+ val builder = Statement.newBuilder()
+
+ override fun visitReturn(x: JsReturn) {
+ val returnBuilder = Return.newBuilder()
+ x.expression?.let { returnBuilder.value = serialize(it) }
+ builder.returnStatement = returnBuilder.build()
+ }
+
+ override fun visitThrow(x: JsThrow) {
+ val throwBuilder = Throw.newBuilder()
+ throwBuilder.exception = serialize(x.expression)
+ builder.throwStatement = throwBuilder.build()
+ }
+
+ override fun visitBreak(x: JsBreak) {
+ val breakBuilder = Break.newBuilder()
+ x.label?.let { breakBuilder.labelId = serialize(it.name!!) }
+ builder.breakStatement = breakBuilder.build()
+ }
+
+ override fun visitContinue(x: JsContinue) {
+ val continueBuilder = Continue.newBuilder()
+ x.label?.let { continueBuilder.labelId = serialize(it.name!!) }
+ builder.continueStatement = continueBuilder.build()
+ }
+
+ override fun visitDebugger(x: JsDebugger) {
+ builder.debugger = Debugger.newBuilder().build()
+ }
+
+ override fun visitExpressionStatement(x: JsExpressionStatement) {
+ val statementBuilder = ExpressionStatement.newBuilder()
+ statementBuilder.expression = serialize(x.expression)
+ builder.expression = statementBuilder.build()
+ }
+
+ override fun visitVars(x: JsVars) {
+ builder.vars = serializeVars(x)
+ }
+
+ override fun visitBlock(x: JsBlock) {
+ if (x is JsGlobalBlock) {
+ builder.globalBlock = serializeBlock(x)
+ }
+ else {
+ val blockBuilder = Block.newBuilder()
+ for (part in x.statements) {
+ blockBuilder.addStatement(serialize(part))
+ }
+ builder.block = blockBuilder.build()
+ }
+ }
+
+ override fun visitLabel(x: JsLabel) {
+ val labelBuilder = Label.newBuilder()
+ labelBuilder.nameId = serialize(x.name)
+ labelBuilder.innerStatement = serialize(x.statement)
+ builder.label = labelBuilder.build()
+ }
+
+ override fun visitIf(x: JsIf) {
+ val ifBuilder = If.newBuilder()
+ ifBuilder.condition = serialize(x.ifExpression)
+ ifBuilder.thenStatement = serialize(x.thenStatement)
+ x.elseStatement?.let { ifBuilder.elseStatement = serialize(it) }
+ builder.ifStatement = ifBuilder.build()
+ }
+
+ override fun visit(x: JsSwitch) {
+ val switchBuilder = Switch.newBuilder()
+ switchBuilder.expression = serialize(x.expression)
+ for (case in x.cases) {
+ val entryBuilder = SwitchEntry.newBuilder()
+ if (case is JsCase) {
+ entryBuilder.label = serialize(case.caseExpression)
+ }
+ for (part in case.statements) {
+ entryBuilder.addStatement(serialize(part))
+ }
+ switchBuilder.addEntry(entryBuilder)
+ }
+ builder.switchStatement = switchBuilder.build()
+ }
+
+ override fun visitWhile(x: JsWhile) {
+ val whileBuilder = While.newBuilder()
+ whileBuilder.condition = serialize(x.condition)
+ whileBuilder.body = serialize(x.body)
+ builder.whileStatement = whileBuilder.build()
+ }
+
+ override fun visitDoWhile(x: JsDoWhile) {
+ val doWhileBuilder = DoWhile.newBuilder()
+ doWhileBuilder.condition = serialize(x.condition)
+ doWhileBuilder.body = serialize(x.body)
+ builder.doWhileStatement = doWhileBuilder.build()
+ }
+
+ override fun visitFor(x: JsFor) {
+ val forBuilder = For.newBuilder()
+ when {
+ x.initVars != null -> forBuilder.variables = serializeVars(x.initVars)
+ x.initExpression != null -> forBuilder.expression = serialize(x.initExpression)
+ else -> forBuilder.empty = EmptyInit.newBuilder().build()
+ }
+ x.condition?.let { forBuilder.condition = serialize(it) }
+ x.incrementExpression?.let { forBuilder.increment = serialize(it) }
+ forBuilder.body = serialize(x.body ?: JsEmpty)
+ builder.forStatement = forBuilder.build()
+ }
+
+ override fun visitForIn(x: JsForIn) {
+ val forInBuilder = ForIn.newBuilder()
+ when {
+ x.iterVarName != null -> forInBuilder.nameId = serialize(x.iterVarName)
+ x.iterExpression != null -> forInBuilder.expression = serialize(x.iterExpression)
+ }
+ forInBuilder.iterable = serialize(x.objectExpression)
+ forInBuilder.body = serialize(x.body)
+ builder.forInStatement = forInBuilder.build()
+ }
+
+ override fun visitTry(x: JsTry) {
+ val tryBuilder = Try.newBuilder()
+ tryBuilder.tryBlock = serialize(x.tryBlock)
+ x.catches.firstOrNull()?.let { c ->
+ val catchBuilder = Catch.newBuilder()
+ catchBuilder.parameter = serializeParameter(c.parameter)
+ catchBuilder.body = serialize(c.body)
+ tryBuilder.catchBlock = catchBuilder.build()
+ }
+ x.finallyBlock?.let { tryBuilder.finallyBlock = serialize(it) }
+ builder.tryStatement = tryBuilder.build()
+ }
+
+ override fun visitEmpty(x: JsEmpty) {
+ builder.empty = Empty.newBuilder().build()
+ }
+ }
+
+ statement.accept(visitor)
+ return visitor.builder.build()
+ }
+
+ private fun serialize(expression: JsExpression): Expression {
+ val visitor = object : JsVisitor() {
+ val builder = Expression.newBuilder()
+
+ override fun visitThis(x: JsLiteral.JsThisRef) {
+ builder.thisLiteral = ThisLiteral.newBuilder().build()
+ }
+
+ override fun visitNull(x: JsNullLiteral) {
+ builder.nullLiteral = NullLiteral.newBuilder().build()
+ }
+
+ override fun visitBoolean(x: JsLiteral.JsBooleanLiteral) {
+ if (x.value) {
+ builder.trueLiteral = TrueLiteral.newBuilder().build()
+ }
+ else {
+ builder.falseLiteral = FalseLiteral.newBuilder().build()
+ }
+ }
+
+ override fun visitString(x: JsStringLiteral) {
+ val stringBuilder = StringLiteral.newBuilder()
+ stringBuilder.stringId = serialize(x.value)
+ builder.stringLiteral = stringBuilder.build()
+ }
+
+ override fun visitRegExp(x: JsRegExp) {
+ val regExpBuilder = RegExpLiteral.newBuilder()
+ regExpBuilder.patternStringId = serialize(x.pattern)
+ x.flags?.let { regExpBuilder.flagsStringId = serialize(it) }
+ builder.regExpLiteral = regExpBuilder.build()
+ }
+
+ override fun visitInt(x: JsNumberLiteral.JsIntLiteral) {
+ val intBuilder = IntLiteral.newBuilder()
+ intBuilder.value = x.value
+ builder.intLiteral = intBuilder.build()
+ }
+
+ override fun visitDouble(x: JsNumberLiteral.JsDoubleLiteral) {
+ val doubleBuilder = DoubleLiteral.newBuilder()
+ doubleBuilder.value = x.value
+ builder.doubleLiteral = doubleBuilder.build()
+ }
+
+ override fun visitArray(x: JsArrayLiteral) {
+ val arrayBuilder = ArrayLiteral.newBuilder()
+ x.expressions.forEach { arrayBuilder.addElement(serialize(it)) }
+ builder.arrayLiteral = arrayBuilder.build()
+ }
+
+ override fun visitObjectLiteral(x: JsObjectLiteral) {
+ val objectBuilder = ObjectLiteral.newBuilder()
+ for (initializer in x.propertyInitializers) {
+ val entryBuilder = ObjectLiteralEntry.newBuilder()
+ entryBuilder.key = serialize(initializer.labelExpr)
+ entryBuilder.value = serialize(initializer.valueExpr)
+ objectBuilder.addEntry(entryBuilder)
+ }
+ objectBuilder.multiline = x.isMultiline
+ builder.objectLiteral = objectBuilder.build()
+ }
+
+ override fun visitFunction(x: JsFunction) {
+ val functionBuilder = JsAstProtoBuf.Function.newBuilder()
+ x.parameters.forEach { functionBuilder.addParameter(serializeParameter(it)) }
+ x.name?.let { functionBuilder.nameId = serialize(it) }
+ functionBuilder.body = serialize(x.body)
+ builder.function = functionBuilder.build()
+ }
+
+ override fun visitDocComment(comment: JsDocComment) {
+ val commentBuilder = DocComment.newBuilder()
+ for ((name, value) in comment.tags) {
+ val tagBuilder = DocCommentTag.newBuilder()
+ tagBuilder.nameId = serialize(name)
+ when (value) {
+ is JsNameRef -> tagBuilder.expression = serialize(value)
+ is String -> tagBuilder.valueStringId = serialize(value)
+ }
+ commentBuilder.addTag(tagBuilder)
+ }
+ builder.docComment = commentBuilder.build()
+ }
+
+ override fun visitBinaryExpression(x: JsBinaryOperation) {
+ val binaryBuilder = BinaryOperation.newBuilder()
+ binaryBuilder.left = serialize(x.arg1)
+ binaryBuilder.right = serialize(x.arg2)
+ binaryBuilder.type = map(x.operator)
+ builder.binary = binaryBuilder.build()
+ }
+
+ override fun visitPrefixOperation(x: JsPrefixOperation) {
+ builder.unary = serializeUnary(x, postfix = false)
+ }
+
+ override fun visitPostfixOperation(x: JsPostfixOperation) {
+ builder.unary = serializeUnary(x, postfix = true)
+ }
+
+ override fun visitConditional(x: JsConditional) {
+ val conditionalBuilder = Conditional.newBuilder()
+ conditionalBuilder.testExpression = serialize(x.testExpression)
+ conditionalBuilder.thenExpression = serialize(x.thenExpression)
+ conditionalBuilder.elseExpression = serialize(x.elseExpression)
+ builder.conditional = conditionalBuilder.build()
+ }
+
+ override fun visitArrayAccess(x: JsArrayAccess) {
+ val arrayAccessBuilder = ArrayAccess.newBuilder()
+ arrayAccessBuilder.array = serialize(x.arrayExpression)
+ arrayAccessBuilder.index = serialize(x.indexExpression)
+ builder.arrayAccess = arrayAccessBuilder.build()
+ }
+
+ override fun visitNameRef(nameRef: JsNameRef) {
+ val name = nameRef.name
+ val qualifier = nameRef.qualifier
+ if (name != null) {
+ if (qualifier != null) {
+ val nameRefBuilder = NameReference.newBuilder()
+ nameRefBuilder.nameId = serialize(name)
+ nameRefBuilder.qualifier = serialize(qualifier)
+ builder.nameReference = nameRefBuilder.build()
+ }
+ else {
+ builder.simpleNameReference = serialize(name)
+ }
+ }
+ else {
+ val propertyRefBuilder = PropertyReference.newBuilder()
+ propertyRefBuilder.stringId = serialize(nameRef.ident)
+ qualifier?.let { propertyRefBuilder.qualifier = serialize(it) }
+ builder.propertyReference = propertyRefBuilder.build()
+ }
+ }
+
+ override fun visitInvocation(invocation: JsInvocation) {
+ val invocationBuilder = Invocation.newBuilder()
+ invocationBuilder.qualifier = serialize(invocation.qualifier)
+ invocation.arguments.forEach { invocationBuilder.addArgument(serialize(it)) }
+ builder.invocation = invocationBuilder.build()
+ }
+
+ override fun visitNew(x: JsNew) {
+ val instantiationBuilder = Instantiation.newBuilder()
+ instantiationBuilder.qualifier = serialize(x.constructorExpression)
+ x.arguments.forEach { instantiationBuilder.addArgument(serialize(it)) }
+ builder.instantiation = instantiationBuilder.build()
+ }
+ }
+
+ expression.accept(visitor)
+ return visitor.builder.build()
+ }
+
+ private fun serializeParameter(parameter: JsParameter): Parameter {
+ val parameterBuilder = Parameter.newBuilder()
+ parameterBuilder.nameId = serialize(parameter.name)
+ return parameterBuilder.build()
+ }
+
+ private fun serializeBlock(block: JsGlobalBlock): GlobalBlock {
+ val blockBuilder = GlobalBlock.newBuilder()
+ for (part in block.statements) {
+ blockBuilder.addStatement(serialize(part))
+ }
+ return blockBuilder.build()
+ }
+
+ private fun serializeVars(vars: JsVars): Vars {
+ val varsBuilder = Vars.newBuilder()
+ for (varDecl in vars.vars) {
+ val declBuilder = VarDeclaration.newBuilder()
+ declBuilder.nameId = serialize(varDecl.name)
+ varDecl.initExpression?.let { declBuilder.initialValue = serialize(it) }
+ varsBuilder.addDeclaration(declBuilder)
+ }
+ varsBuilder.multiline = vars.isMultiline
+ return varsBuilder.build()
+ }
+
+ private fun serializeUnary(x: JsUnaryOperation, postfix: Boolean): UnaryOperation {
+ val unaryBuilder = UnaryOperation.newBuilder()
+ unaryBuilder.operand = serialize(x.arg)
+ unaryBuilder.type = map(x.operator)
+ unaryBuilder.postfix = postfix
+ return unaryBuilder.build()
+ }
+
+ private fun map(op: JsBinaryOperator) = when (op) {
+ JsBinaryOperator.MUL -> MUL
+ JsBinaryOperator.DIV -> DIV
+ JsBinaryOperator.MOD -> MOD
+ JsBinaryOperator.ADD -> ADD
+ JsBinaryOperator.SUB -> SUB
+ JsBinaryOperator.SHL -> SHL
+ JsBinaryOperator.SHR -> SHR
+ JsBinaryOperator.SHRU -> SHRU
+ JsBinaryOperator.LT -> LT
+ JsBinaryOperator.LTE -> LTE
+ JsBinaryOperator.GT -> GT
+ JsBinaryOperator.GTE -> GTE
+ JsBinaryOperator.INSTANCEOF -> INSTANCEOF
+ JsBinaryOperator.INOP -> IN
+ JsBinaryOperator.EQ -> EQ
+ JsBinaryOperator.NEQ -> NEQ
+ JsBinaryOperator.REF_EQ -> REF_EQ
+ JsBinaryOperator.REF_NEQ -> REF_NEQ
+ JsBinaryOperator.BIT_AND -> BIT_AND
+ JsBinaryOperator.BIT_XOR -> BIT_XOR
+ JsBinaryOperator.BIT_OR -> BIT_OR
+ JsBinaryOperator.AND -> AND
+ JsBinaryOperator.OR -> OR
+ JsBinaryOperator.ASG -> ASG
+ JsBinaryOperator.ASG_ADD -> ASG_ADD
+ JsBinaryOperator.ASG_SUB -> ASG_SUB
+ JsBinaryOperator.ASG_MUL -> ASG_MUL
+ JsBinaryOperator.ASG_DIV -> ASG_DIV
+ JsBinaryOperator.ASG_MOD -> ASG_MOD
+ JsBinaryOperator.ASG_SHL -> ASG_SHL
+ JsBinaryOperator.ASG_SHR -> ASG_SHR
+ JsBinaryOperator.ASG_SHRU -> ASG_SHRU
+ JsBinaryOperator.ASG_BIT_AND -> ASG_BIT_AND
+ JsBinaryOperator.ASG_BIT_OR -> ASG_BIT_OR
+ JsBinaryOperator.ASG_BIT_XOR -> ASG_BIT_XOR
+ JsBinaryOperator.COMMA -> COMMA
+ }
+
+ private fun map(op: JsUnaryOperator) = when (op) {
+ JsUnaryOperator.BIT_NOT -> BIT_NOT
+ JsUnaryOperator.DEC -> DEC
+ JsUnaryOperator.DELETE -> DELETE
+ JsUnaryOperator.INC -> INC
+ JsUnaryOperator.NEG -> NEG
+ JsUnaryOperator.POS -> POS
+ JsUnaryOperator.NOT -> NOT
+ JsUnaryOperator.TYPEOF -> TYPEOF
+ JsUnaryOperator.VOID -> VOID
+ }
+
+ private fun serialize(name: JsName) = nameMap.getOrPut(name) {
+ val result = nameTableBuilder.entryCount
+ val builder = Name.newBuilder()
+ builder.identifier = serialize(name.ident)
+ builder.temporary = name.isTemporary
+ nameTableBuilder.addEntry(builder)
+ result
+ }
+
+ private fun serialize(string: String) = stringMap.getOrPut(string) {
+ val result = stringTableBuilder.entryCount
+ stringTableBuilder.addEntry(string)
+ result
+ }
+}
\ No newline at end of file
diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java
index bc750f3c9e2..2903644625f 100644
--- a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java
+++ b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java
@@ -16,12 +16,15 @@
package org.jetbrains.kotlin.js.facade;
+import com.intellij.util.Base64;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS;
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult;
import org.jetbrains.kotlin.js.backend.ast.JsImportedModule;
+import org.jetbrains.kotlin.js.backend.ast.JsProgram;
+import org.jetbrains.kotlin.js.backend.ast.JsProgramFragment;
import org.jetbrains.kotlin.js.config.JsConfig;
import org.jetbrains.kotlin.js.coroutine.CoroutineTransformer;
import org.jetbrains.kotlin.js.facade.exceptions.TranslationException;
@@ -35,7 +38,9 @@ import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStat
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics;
+import org.jetbrains.kotlin.serialization.js.ast.JsAstSerializer;
+import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
@@ -84,6 +89,20 @@ public final class K2JSTranslator {
JsInliner.process(config, analysisResult.getBindingTrace(), translationResult.getInnerModuleName(),
translationResult.getFragments(), translationResult.getFragments());
+ // TODO: temporary code for testing purposes, remove later
+ JsAstSerializer serializer = new JsAstSerializer();
+ JsProgram program = translationResult.getProgram();
+ int bytesTotal = 0;
+ for (JsProgramFragment fragment : translationResult.getFragments()) {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ serializer.serialize(fragment, output);
+ bytesTotal += output.size();
+ String base64 = Base64.encode(output.toByteArray());
+ program.getGlobalBlock().getStatements().add(program.getStringLiteral(base64).makeStmt());
+ }
+
+ program.getGlobalBlock().getStatements().add(program.getNumberLiteral(bytesTotal).makeStmt());
+
ResolveTemporaryNamesKt.resolveTemporaryNames(translationResult.getProgram());
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics);