JS: add AST deserializer
This commit is contained in:
@@ -17,6 +17,11 @@ public class JsCatch extends SourceInfoAwareJsNode implements HasCondition {
|
||||
private JsExpression condition;
|
||||
private JsParameter param;
|
||||
|
||||
public JsCatch(@NotNull JsName name) {
|
||||
param = new JsParameter(name);
|
||||
scope = null;
|
||||
}
|
||||
|
||||
public JsCatch(JsScope parent, @NotNull String ident) {
|
||||
super();
|
||||
assert (parent != null);
|
||||
|
||||
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* 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.Expression.ExpressionCase
|
||||
import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf.Statement.StatementCase
|
||||
import java.io.InputStream
|
||||
|
||||
class JsAstDeserializer(private val program: JsProgram) {
|
||||
private val scope = JsRootScope(program)
|
||||
private val stringTable = mutableListOf<String>()
|
||||
private val nameTable = mutableListOf<Name>()
|
||||
private val nameCache = mutableListOf<JsName?>()
|
||||
|
||||
fun deserialize(input: InputStream): JsProgramFragment {
|
||||
return deserialize(Chunk.parseFrom(input))
|
||||
}
|
||||
|
||||
fun deserialize(proto: Chunk): JsProgramFragment {
|
||||
stringTable += proto.stringTable.entryList
|
||||
nameTable += proto.nameTable.entryList
|
||||
nameCache += nameTable.map { null }
|
||||
try {
|
||||
return deserialize(proto.fragment)
|
||||
}
|
||||
finally {
|
||||
stringTable.clear()
|
||||
nameTable.clear()
|
||||
nameCache.clear()
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserialize(proto: Fragment): JsProgramFragment {
|
||||
val fragment = JsProgramFragment(scope)
|
||||
|
||||
fragment.importedModules += proto.importedModuleList.map { importedModuleProto ->
|
||||
JsImportedModule(
|
||||
deserializeString(importedModuleProto.externalNameId),
|
||||
deserializeName(importedModuleProto.internalNameId),
|
||||
if (importedModuleProto.hasPlainReference()) deserialize(importedModuleProto.plainReference) else null
|
||||
)
|
||||
}
|
||||
|
||||
fragment.imports += proto.importEntryList.associate { importProto ->
|
||||
deserializeString(importProto.signatureId) to deserialize(importProto.expression)
|
||||
}
|
||||
|
||||
if (proto.hasDeclarationBlock()) {
|
||||
fragment.declarationBlock.statements += deserializeGlobalBlock(proto.declarationBlock).statements
|
||||
}
|
||||
if (proto.hasInitializerBlock()) {
|
||||
fragment.initializerBlock.statements += deserializeGlobalBlock(proto.initializerBlock).statements
|
||||
}
|
||||
if (proto.hasExportBlock()) {
|
||||
fragment.exportBlock.statements += deserializeGlobalBlock(proto.exportBlock).statements
|
||||
}
|
||||
|
||||
fragment.nameBindings += proto.nameBindingList.map { nameBindingProto ->
|
||||
JsNameBinding(deserializeString(nameBindingProto.signatureId), deserializeName(nameBindingProto.nameId))
|
||||
}
|
||||
|
||||
fragment.classes += proto.classModelList.associate { clsProto -> deserialize(clsProto).let { it.name to it } }
|
||||
|
||||
val moduleExpressions = proto.moduleExpressionList.map { deserialize(it) }
|
||||
fragment.inlineModuleMap += proto.inlineModuleList.associate { inlineModuleProto ->
|
||||
deserializeString(inlineModuleProto.signatureId) to moduleExpressions[inlineModuleProto.expressionId]
|
||||
}
|
||||
|
||||
return fragment
|
||||
}
|
||||
|
||||
private fun deserialize(proto: ClassModel): JsClassModel {
|
||||
val superName = if (proto.hasSuperNameId()) deserializeName(proto.superNameId) else null
|
||||
return JsClassModel(deserializeName(proto.nameId), superName).apply {
|
||||
if (proto.hasPostDeclarationBlock()) {
|
||||
postDeclarationBlock.statements += deserializeGlobalBlock(proto.postDeclarationBlock).statements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserialize(proto: Statement): JsStatement = when (proto.statementCase) {
|
||||
StatementCase.RETURN_STATEMENT -> {
|
||||
val returnProto = proto.returnStatement
|
||||
JsReturn(if (returnProto.hasValue()) deserialize(returnProto.value) else null)
|
||||
}
|
||||
|
||||
StatementCase.THROW_STATEMENT -> {
|
||||
val throwProto = proto.throwStatement
|
||||
JsThrow(deserialize(throwProto.exception))
|
||||
}
|
||||
|
||||
StatementCase.BREAK_STATEMENT -> {
|
||||
val breakProto = proto.breakStatement
|
||||
JsBreak(if (breakProto.hasLabelId()) JsNameRef(deserializeName(breakProto.labelId)) else null)
|
||||
}
|
||||
|
||||
StatementCase.CONTINUE_STATEMENT -> {
|
||||
val continueProto = proto.continueStatement
|
||||
JsContinue(if (continueProto.hasLabelId()) JsNameRef(deserializeName(continueProto.labelId)) else null)
|
||||
}
|
||||
|
||||
StatementCase.DEBUGGER -> {
|
||||
JsDebugger()
|
||||
}
|
||||
|
||||
StatementCase.EXPRESSION -> {
|
||||
val expressionProto = proto.expression
|
||||
JsExpressionStatement(deserialize(expressionProto.expression))
|
||||
}
|
||||
|
||||
StatementCase.VARS -> {
|
||||
deserializeVars(proto.vars)
|
||||
}
|
||||
|
||||
StatementCase.BLOCK -> {
|
||||
val blockProto = proto.block
|
||||
val block = JsBlock()
|
||||
block.statements += blockProto.statementList.map { deserialize(it) }
|
||||
block
|
||||
}
|
||||
|
||||
StatementCase.GLOBAL_BLOCK -> {
|
||||
deserializeGlobalBlock(proto.globalBlock)
|
||||
}
|
||||
|
||||
StatementCase.LABEL -> {
|
||||
val labelProto = proto.label
|
||||
JsLabel(deserializeName(labelProto.nameId), deserialize(labelProto.innerStatement))
|
||||
}
|
||||
|
||||
StatementCase.IF_STATEMENT -> {
|
||||
val ifProto = proto.ifStatement
|
||||
JsIf(
|
||||
deserialize(ifProto.condition),
|
||||
deserialize(ifProto.thenStatement),
|
||||
if (ifProto.hasElseStatement()) deserialize(ifProto.elseStatement) else null
|
||||
)
|
||||
}
|
||||
|
||||
StatementCase.SWITCH_STATEMENT -> {
|
||||
val switchProto = proto.switchStatement
|
||||
JsSwitch(
|
||||
deserialize(switchProto.expression),
|
||||
switchProto.entryList.map { entryProto ->
|
||||
val member = if (entryProto.hasLabel()) {
|
||||
JsCase().apply { caseExpression = deserialize(entryProto.label) }
|
||||
}
|
||||
else {
|
||||
JsDefault()
|
||||
}
|
||||
member.statements += entryProto.statementList.map { deserialize(it) }
|
||||
member
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
StatementCase.WHILE_STATEMENT -> {
|
||||
val whileProto = proto.whileStatement
|
||||
JsWhile(deserialize(whileProto.condition), deserialize(whileProto.body))
|
||||
}
|
||||
|
||||
StatementCase.DO_WHILE_STATEMENT -> {
|
||||
val doWhileProto = proto.doWhileStatement
|
||||
JsDoWhile(deserialize(doWhileProto.condition), deserialize(doWhileProto.body))
|
||||
}
|
||||
|
||||
StatementCase.FOR_STATEMENT -> {
|
||||
val forProto = proto.forStatement
|
||||
val initVars = if (forProto.hasVariables()) deserializeVars(forProto.variables) else null
|
||||
val initExpr = if (forProto.hasExpression()) deserialize(forProto.expression) else null
|
||||
val condition = if (forProto.hasCondition()) deserialize(forProto.condition) else null
|
||||
val increment = if (forProto.hasIncrement()) deserialize(forProto.increment) else null
|
||||
val body = deserialize(forProto.body)
|
||||
if (initVars != null) {
|
||||
JsFor(initVars, condition, increment, body)
|
||||
}
|
||||
else {
|
||||
JsFor(initExpr!!, condition, increment, body)
|
||||
}
|
||||
}
|
||||
|
||||
StatementCase.FOR_IN_STATEMENT -> {
|
||||
val forInProto = proto.forInStatement
|
||||
val iterName = if (forInProto.hasNameId()) deserializeName(forInProto.nameId) else null
|
||||
val iterExpr = if (forInProto.hasExpression()) deserialize(forInProto.expression) else null
|
||||
val iterable = deserialize(forInProto.iterable)
|
||||
val body = deserialize(forInProto.body)
|
||||
JsForIn(iterName, iterExpr, iterable, body)
|
||||
}
|
||||
|
||||
StatementCase.TRY_STATEMENT -> {
|
||||
val tryProto = proto.tryStatement
|
||||
val tryBlock = deserialize(tryProto.tryBlock) as JsBlock
|
||||
val catchBlock = if (tryProto.hasCatchBlock()) {
|
||||
val catchProto = tryProto.catchBlock
|
||||
JsCatch(deserializeName(catchProto.parameter.nameId)).apply {
|
||||
body = deserialize(catchProto.body) as JsBlock
|
||||
}
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
val finallyBlock = if (tryProto.hasFinallyBlock()) deserialize(tryProto.finallyBlock) as JsBlock else null
|
||||
JsTry(tryBlock, catchBlock, finallyBlock)
|
||||
}
|
||||
|
||||
StatementCase.EMPTY -> JsEmpty
|
||||
|
||||
StatementCase.STATEMENT_NOT_SET,
|
||||
null -> error("Statement not set")
|
||||
}
|
||||
|
||||
private fun deserialize(proto: Expression): JsExpression = when(proto.expressionCase) {
|
||||
ExpressionCase.THIS_LITERAL -> JsLiteral.THIS
|
||||
ExpressionCase.NULL_LITERAL -> JsLiteral.NULL
|
||||
ExpressionCase.TRUE_LITERAL -> JsLiteral.TRUE
|
||||
ExpressionCase.FALSE_LITERAL -> JsLiteral.FALSE
|
||||
ExpressionCase.STRING_LITERAL -> program.getStringLiteral(deserializeString(proto.stringLiteral.stringId))
|
||||
ExpressionCase.INT_LITERAL -> program.getNumberLiteral(proto.intLiteral.value)
|
||||
ExpressionCase.DOUBLE_LITERAL -> program.getNumberLiteral(proto.doubleLiteral.value)
|
||||
ExpressionCase.SIMPLE_NAME_REFERENCE -> JsNameRef(deserializeName(proto.simpleNameReference))
|
||||
|
||||
ExpressionCase.REG_EXP_LITERAL -> {
|
||||
val regExpProto = proto.regExpLiteral
|
||||
JsRegExp().apply {
|
||||
pattern = deserializeString(regExpProto.patternStringId)
|
||||
if (regExpProto.hasFlagsStringId()) {
|
||||
flags = deserializeString(regExpProto.flagsStringId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExpressionCase.ARRAY_LITERAL -> {
|
||||
val arrayProto = proto.arrayLiteral
|
||||
JsArrayLiteral(arrayProto.elementList.map { deserialize(it) })
|
||||
}
|
||||
|
||||
ExpressionCase.OBJECT_LITERAL -> {
|
||||
val objectProto = proto.objectLiteral
|
||||
JsObjectLiteral(
|
||||
objectProto.entryList.map { entryProto ->
|
||||
JsPropertyInitializer(deserialize(entryProto.key), deserialize(entryProto.value))
|
||||
},
|
||||
objectProto.multiline
|
||||
)
|
||||
}
|
||||
|
||||
ExpressionCase.FUNCTION -> {
|
||||
val functionProto = proto.function
|
||||
JsFunction(scope, deserialize(functionProto.body) as JsBlock, "").apply {
|
||||
parameters += functionProto.parameterList.map { deserializeParameter(it) }
|
||||
if (functionProto.hasNameId()) {
|
||||
name = deserializeName(functionProto.nameId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExpressionCase.DOC_COMMENT -> {
|
||||
val docCommentProto = proto.docComment
|
||||
JsDocComment(docCommentProto.tagList.associate { tagProto ->
|
||||
val name = deserializeString(tagProto.nameId)
|
||||
val value: Any = if (tagProto.hasExpression()) {
|
||||
deserialize(tagProto.expression)
|
||||
}
|
||||
else {
|
||||
deserializeString(tagProto.valueStringId)
|
||||
}
|
||||
name to value
|
||||
})
|
||||
}
|
||||
|
||||
ExpressionCase.BINARY -> {
|
||||
val binaryProto = proto.binary
|
||||
JsBinaryOperation(map(binaryProto.type), deserialize(binaryProto.left), deserialize(binaryProto.right))
|
||||
}
|
||||
|
||||
ExpressionCase.UNARY -> {
|
||||
val unaryProto = proto.unary
|
||||
val type = map(unaryProto.type)
|
||||
val operand = deserialize(unaryProto.operand)
|
||||
if (unaryProto.postfix) JsPostfixOperation(type, operand) else JsPrefixOperation(type, operand)
|
||||
}
|
||||
|
||||
ExpressionCase.CONDITIONAL -> {
|
||||
val conditionalProto = proto.conditional
|
||||
JsConditional(
|
||||
deserialize(conditionalProto.testExpression),
|
||||
deserialize(conditionalProto.thenExpression),
|
||||
deserialize(conditionalProto.elseExpression)
|
||||
)
|
||||
}
|
||||
|
||||
ExpressionCase.ARRAY_ACCESS -> {
|
||||
val arrayAccessProto = proto.arrayAccess
|
||||
JsArrayAccess(deserialize(arrayAccessProto.array), deserialize(arrayAccessProto.index))
|
||||
}
|
||||
|
||||
ExpressionCase.NAME_REFERENCE -> {
|
||||
val nameRefProto = proto.nameReference
|
||||
JsNameRef(deserializeName(nameRefProto.nameId), if (nameRefProto.hasQualifier()) deserialize(nameRefProto.qualifier) else null)
|
||||
}
|
||||
|
||||
ExpressionCase.PROPERTY_REFERENCE -> {
|
||||
val propertyRefProto = proto.propertyReference
|
||||
val qualifier = if (propertyRefProto.hasQualifier()) deserialize(propertyRefProto.qualifier) else null
|
||||
JsNameRef(deserializeString(propertyRefProto.stringId), qualifier)
|
||||
}
|
||||
|
||||
ExpressionCase.INVOCATION -> {
|
||||
val invocationProto = proto.invocation
|
||||
JsInvocation(
|
||||
deserialize(invocationProto.qualifier),
|
||||
invocationProto.argumentList.map { deserialize(it) }
|
||||
)
|
||||
}
|
||||
|
||||
ExpressionCase.INSTANTIATION -> {
|
||||
val instantiationProto = proto.instantiation
|
||||
JsNew(
|
||||
deserialize(instantiationProto.qualifier),
|
||||
instantiationProto.argumentList.map { deserialize(it) }
|
||||
)
|
||||
}
|
||||
|
||||
null,
|
||||
ExpressionCase.EXPRESSION_NOT_SET -> error("Unknown expression")
|
||||
}
|
||||
|
||||
private fun deserializeVars(proto: Vars): JsVars {
|
||||
val vars = JsVars(proto.multiline)
|
||||
for (declProto in proto.declarationList) {
|
||||
val initialValue = if (declProto.hasInitialValue()) deserialize(declProto.initialValue) else null
|
||||
vars.vars += JsVars.JsVar(deserializeName(declProto.nameId), initialValue)
|
||||
}
|
||||
return vars
|
||||
}
|
||||
|
||||
private fun deserializeGlobalBlock(proto: GlobalBlock): JsGlobalBlock {
|
||||
return JsGlobalBlock().apply { statements += proto.statementList.map { deserialize(it) } }
|
||||
}
|
||||
|
||||
private fun deserializeParameter(proto: Parameter): JsParameter {
|
||||
return JsParameter(deserializeName(proto.nameId))
|
||||
}
|
||||
|
||||
private fun deserializeName(id: Int): JsName {
|
||||
return nameCache[id] ?: let {
|
||||
val nameProto = nameTable[id]
|
||||
val identifier = deserializeString(nameProto.identifier)
|
||||
val name = if (nameProto.temporary) {
|
||||
JsScope.declareTemporaryName(identifier)
|
||||
}
|
||||
else {
|
||||
JsDynamicScope.declareName(identifier)
|
||||
}
|
||||
nameCache[id] = name
|
||||
name
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserializeString(id: Int): String = stringTable[id]
|
||||
|
||||
private fun map(op: BinaryOperation.Type) = when (op) {
|
||||
BinaryOperation.Type.MUL -> JsBinaryOperator.MUL
|
||||
BinaryOperation.Type.DIV -> JsBinaryOperator.DIV
|
||||
BinaryOperation.Type.MOD -> JsBinaryOperator.MOD
|
||||
BinaryOperation.Type.ADD -> JsBinaryOperator.ADD
|
||||
BinaryOperation.Type.SUB -> JsBinaryOperator.SUB
|
||||
BinaryOperation.Type.SHL -> JsBinaryOperator.SHL
|
||||
BinaryOperation.Type.SHR -> JsBinaryOperator.SHR
|
||||
BinaryOperation.Type.SHRU -> JsBinaryOperator.SHRU
|
||||
BinaryOperation.Type.LT -> JsBinaryOperator.LT
|
||||
BinaryOperation.Type.LTE -> JsBinaryOperator.LTE
|
||||
BinaryOperation.Type.GT -> JsBinaryOperator.GT
|
||||
BinaryOperation.Type.GTE -> JsBinaryOperator.GTE
|
||||
BinaryOperation.Type.INSTANCEOF -> JsBinaryOperator.INSTANCEOF
|
||||
BinaryOperation.Type.IN -> JsBinaryOperator.INOP
|
||||
BinaryOperation.Type.EQ -> JsBinaryOperator.EQ
|
||||
BinaryOperation.Type.NEQ -> JsBinaryOperator.NEQ
|
||||
BinaryOperation.Type.REF_EQ -> JsBinaryOperator.REF_EQ
|
||||
BinaryOperation.Type.REF_NEQ -> JsBinaryOperator.REF_NEQ
|
||||
BinaryOperation.Type.BIT_AND -> JsBinaryOperator.BIT_AND
|
||||
BinaryOperation.Type.BIT_XOR -> JsBinaryOperator.BIT_XOR
|
||||
BinaryOperation.Type.BIT_OR -> JsBinaryOperator.BIT_OR
|
||||
BinaryOperation.Type.AND -> JsBinaryOperator.AND
|
||||
BinaryOperation.Type.OR -> JsBinaryOperator.OR
|
||||
BinaryOperation.Type.ASG -> JsBinaryOperator.ASG
|
||||
BinaryOperation.Type.ASG_ADD -> JsBinaryOperator.ASG_ADD
|
||||
BinaryOperation.Type.ASG_SUB -> JsBinaryOperator.ASG_SUB
|
||||
BinaryOperation.Type.ASG_MUL -> JsBinaryOperator.ASG_MUL
|
||||
BinaryOperation.Type.ASG_DIV -> JsBinaryOperator.ASG_DIV
|
||||
BinaryOperation.Type.ASG_MOD -> JsBinaryOperator.ASG_MOD
|
||||
BinaryOperation.Type.ASG_SHL -> JsBinaryOperator.ASG_SHL
|
||||
BinaryOperation.Type.ASG_SHR -> JsBinaryOperator.ASG_SHR
|
||||
BinaryOperation.Type.ASG_SHRU -> JsBinaryOperator.ASG_SHRU
|
||||
BinaryOperation.Type.ASG_BIT_AND -> JsBinaryOperator.ASG_BIT_AND
|
||||
BinaryOperation.Type.ASG_BIT_OR -> JsBinaryOperator.ASG_BIT_OR
|
||||
BinaryOperation.Type.ASG_BIT_XOR -> JsBinaryOperator.ASG_BIT_XOR
|
||||
BinaryOperation.Type.COMMA -> JsBinaryOperator.COMMA
|
||||
}
|
||||
|
||||
private fun map(op: UnaryOperation.Type) = when (op) {
|
||||
UnaryOperation.Type.BIT_NOT -> JsUnaryOperator.BIT_NOT
|
||||
UnaryOperation.Type.DEC -> JsUnaryOperator.DEC
|
||||
UnaryOperation.Type.DELETE -> JsUnaryOperator.DELETE
|
||||
UnaryOperation.Type.INC -> JsUnaryOperator.INC
|
||||
UnaryOperation.Type.NEG -> JsUnaryOperator.NEG
|
||||
UnaryOperation.Type.POS -> JsUnaryOperator.POS
|
||||
UnaryOperation.Type.NOT -> JsUnaryOperator.NOT
|
||||
UnaryOperation.Type.TYPEOF -> JsUnaryOperator.TYPEOF
|
||||
UnaryOperation.Type.VOID -> JsUnaryOperator.VOID
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
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;
|
||||
@@ -38,8 +37,10 @@ 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.JsAstDeserializer;
|
||||
import org.jetbrains.kotlin.serialization.js.ast.JsAstSerializer;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -91,14 +92,20 @@ public final class K2JSTranslator {
|
||||
|
||||
// TODO: temporary code for testing purposes, remove later
|
||||
JsAstSerializer serializer = new JsAstSerializer();
|
||||
JsAstDeserializer deserializer = new JsAstDeserializer(new JsProgram());
|
||||
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());
|
||||
|
||||
ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
|
||||
JsProgramFragment deserializedFragment = deserializer.deserialize(input);
|
||||
|
||||
String expected = fragmentToString(fragment);
|
||||
String actual = fragmentToString(deserializedFragment);
|
||||
assert expected.equals(actual) : "Deserialization: " + expected + "\n\nvs.\n\n" + actual;
|
||||
}
|
||||
|
||||
program.getGlobalBlock().getStatements().add(program.getNumberLiteral(bytesTotal).makeStmt());
|
||||
@@ -123,4 +130,9 @@ public final class K2JSTranslator {
|
||||
return new TranslationResult.Success(config, files, translationResult.getProgram(), diagnostics, importedModules,
|
||||
moduleDescriptor, bindingTrace.getBindingContext());
|
||||
}
|
||||
|
||||
private static String fragmentToString(JsProgramFragment fragment) {
|
||||
return fragment.getDeclarationBlock().toString() + fragment.getInitializerBlock().toString() +
|
||||
fragment.getExportBlock().toString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user