🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

json-as

Package Overview
Dependencies
Maintainers
0
Versions
194
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

json-as - npm Package Compare versions

Comparing version

to
1.0.0-alpha.4

assembly/__tests__/box.spec.ts

11

assembly/deserialize/simple/bool.ts

@@ -1,9 +0,6 @@

import { CHAR_F, CHAR_T } from "../../custom/chars";
export function deserializeBoolean(srcStart: usize, srcEnd: usize): boolean {
const srcSize = srcEnd - srcStart;
const firstChar = load<u16>(srcStart);
if (firstChar == CHAR_T && load<u64>(srcStart) == 28429475166421108) return true;
else if (firstChar == CHAR_F && load<u64>(srcSize, 2) == 28429466576093281) return false;
const block = load<u64>(srcStart);
if (block == 28429475166421108) return true;
else if (block == 32370086184550502 && load<u16>(srcStart, 8) == 101) return false;
return false; //throw new Error(`Expected to find boolean, but found "${data.slice(0, 100)}" instead!`);
}
}

@@ -5,8 +5,8 @@ import { ptrToStr } from "../../util/ptrToStr";

// Use AssemblyScript's date parser
const d = Date.fromString(ptrToStr(srcStart, srcEnd));
const d = Date.fromString(ptrToStr(srcStart + 2, srcEnd - 2));
// Return a new object instead of the one that the parser returned.
// This may seem redundant, but addreses the issue when Date
// This may seem redundant, but it addresses the issue when Date
// is globally aliased to wasi_Date (or some other superclass).
return new Date(d.getTime());
}

@@ -0,3 +1,5 @@

import { JSON } from "../..";
import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T } from "../../custom/chars";
import { isSpace } from "../../util";
import { ptrToStr } from "../../util/ptrToStr";

@@ -63,5 +65,5 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize): T {

if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
// console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
// @ts-ignore: exists
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart, dst);
// console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
// while (isSpace(load<u16>((srcStart += 2)))) {

@@ -68,0 +70,0 @@ // /* empty */

@@ -39,2 +39,7 @@ /// <reference path="./index.d.ts" />

export namespace JSON {
export namespace Memory {
export function shrink(): void {
bs.resize(64);
}
}
/**

@@ -111,6 +116,4 @@ * Serializes valid JSON data

// @ts-ignore: Supplied by transform
} else if (isDefined(data.__SERIALIZE) && isDefined(data.__ALLOCATE)) {
} else if (isDefined(data.__SERIALIZE)) {
// @ts-ignore
// data.__ALLOCATE();
// @ts-ignore
data.__SERIALIZE(changetype<usize>(data));

@@ -124,4 +127,4 @@ return bs.out<string>();

memory.copy(changetype<usize>(out) + 2, changetype<usize>(data.toISOString()), 48);
store<u16>(changetype<usize>(out), 50);
return out;
store<u16>(changetype<usize>(out), QUOTE, 50);
return changetype<string>(out);
} else if (data instanceof Array) {

@@ -162,3 +165,3 @@ // @ts-ignore

return deserializeFloat<T>(dataPtr, dataPtr + dataSize);
} else if (isNullable<T>() && data.length == 4 && data == "null") {
} else if (isNullable<T>() && dataSize == 8 && load<u64>(dataPtr) == 30399761348886638) {
// @ts-ignore

@@ -189,3 +192,3 @@ return null;

// @ts-ignore
return new JSON.Box(JSON.parse<indexof<T>>(data));
return new JSON.Box(parseBox(data, changetype<nonnull<T>>(0).value));
} else {

@@ -347,3 +350,5 @@ throw new Error(`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);

export class Box<T> {
constructor(public value: T) {}
constructor(public value: T) {
if (!isInteger<T>() && !isFloat<T>()) ERROR("JSON.Box should only hold primitive types!");
}
/**

@@ -362,2 +367,8 @@ * Creates a reference to a primitive type

}
toString(): string {
if (isNullable<this>() && changetype<usize>(this) == null) return "null";
// @ts-ignore: type
if (isDefined(this.value.toString)) return this.value.toString();
return "null";
}
}

@@ -431,2 +442,5 @@

return deserializeDate(srcStart, srcEnd);
} else if (type instanceof JSON.Box) {
// @ts-ignore: type
return new JSON.Box(deserializeBox(srcStart, srcEnd, dst, changetype<nonnull<T>>(0).value));
}

@@ -437,1 +451,10 @@ }

}
// @ts-ignore: decorator
@inline function parseBox<T>(data: string, ty: T): T {
return JSON.parse<T>(data);
}
function deserializeBox<T>(srcStart: usize, srcEnd: usize, dst: usize, ty: T): T {
return JSON.__deserialize<T>(srcStart, srcEnd, dst);
}

@@ -21,3 +21,3 @@ import { bs } from "../../../modules/as-bs";

const srcEnd = srcStart + srcSize;
bs.ensureSize(srcSize + 4);
bs.proposeSize(srcSize + 4);
const srcEnd16 = srcEnd - 15;

@@ -49,3 +49,3 @@

if ((escaped & 0xffff) != BACK_SLASH) {
bs.addSize(10);
bs.growSize(10);
store<u64>(dst_offset, 13511005048209500);

@@ -56,3 +56,3 @@ store<u32>(dst_offset, escaped, 8);

} else {
bs.addSize(2);
bs.growSize(2);
store<u32>(dst_offset, escaped);

@@ -90,3 +90,3 @@ v128.store(dst_offset, v128.load(src_offset, 2), 4);

if ((escaped & 0xffff) != BACK_SLASH) {
bs.addSize(10);
bs.growSize(10);
store<u64>(dst_offset, 13511005048209500);

@@ -100,3 +100,3 @@ store<u32>(dst_offset, escaped, 8);

} else {
bs.addSize(2);
bs.growSize(2);
store<u32>(dst_offset, escaped);

@@ -124,3 +124,3 @@

if ((escaped & 0xffff) != BACK_SLASH) {
bs.addSize(10);
bs.growSize(10);
store<u64>(bs.offset, 13511005048209500);

@@ -130,3 +130,3 @@ store<u32>(bs.offset, escaped, 8);

} else {
bs.addSize(2);
bs.growSize(2);
store<u32>(bs.offset, escaped);

@@ -144,3 +144,3 @@ bs.offset += 4;

if ((escaped & 0xffff) != BACK_SLASH) {
bs.addSize(10);
bs.growSize(10);
store<u64>(bs.offset, 13511005048209500);

@@ -150,3 +150,3 @@ store<u32>(bs.offset, escaped, 8);

} else {
bs.addSize(2);
bs.growSize(2);
store<u32>(bs.offset, escaped);

@@ -168,3 +168,3 @@ bs.offset += 4;

if ((escaped & 0xffff) != BACK_SLASH) {
bs.addSize(10);
bs.growSize(10);
store<u64>(bs.offset, 13511005048209500);

@@ -174,3 +174,3 @@ store<u32>(bs.offset, escaped, 8);

} else {
bs.addSize(2);
bs.growSize(2);
store<u32>(bs.offset, escaped);

@@ -177,0 +177,0 @@ bs.offset += 4;

@@ -6,6 +6,6 @@ import { bs } from "../../../modules/as-bs";

export function serializeArray<T extends any[]>(src: T): void {
bs.proposeSize(4);
const end = src.length - 1;
let i = 0;
if (end == -1) {
bs.proposeSize(4);
store<u32>(bs.offset, 6094939);

@@ -15,3 +15,4 @@ bs.offset += 4;

}
bs.proposeSize(end << 3);
// {} = 4
// xi, = n << 1

@@ -31,5 +32,5 @@ store<u16>(bs.offset, BRACKET_LEFT);

JSON.__serialize<valueof<T>>(lastBlock);
bs.proposeSize(2);
bs.growSize(2);
store<u16>(bs.offset, BRACKET_RIGHT);
bs.offset += 2;
}

@@ -5,4 +5,4 @@ import { dtoa_buffered } from "util/number";

export function serializeFloat<T extends number>(data: T): void {
bs.proposeSize(64);
bs.ensureSize(64);
bs.offset += dtoa_buffered(bs.offset, data) << 1;
}

@@ -5,4 +5,9 @@ import { itoa_buffered } from "util/number";

export function serializeInteger<T extends number>(data: T): void {
bs.proposeSize(sizeof<T>() << 3);
bs.offset += itoa_buffered(bs.offset, data) << 1;
bs.ensureSize(sizeof<T>() << 3);
const bytesWritten = itoa_buffered(bs.offset, data) << 1;
bs.offset += bytesWritten;
bs.growSize(bytesWritten);
}
// 32 {"x":,"y":,"z"}
// 18 3.41.28.3

@@ -1,5 +0,59 @@

import { JSON } from "./";
import { describe, expect } from "../modules/test/assembly";
import { JSON } from ".";
import { bytes } from "./util";
console.log(JSON.stringify(JSON.parse<string>('"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u000f\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f"')));
console.log('"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u000f\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f"');
@json
class Obj {
public a: string = "hello";
public b: string = "world";
public c: string = "\"\t\f\u0000\u0001";
}
@json
class Vec3 {
x: f32 = 0.0;
y: f32 = 0.0;
z: f32 = 0.0;
}
@json
class Player {
@alias("first name")
firstName!: string;
lastName!: string;
lastActive!: i32[];
// Drop in a code block, function, or expression that evaluates to a boolean
@omitif((age) => age < 18)
@omitif('this.age <= 0')
age!: i32;
@omitnull()
pos!: Vec3 | null;
isVerified!: boolean;
}
const player: Player = {
firstName: "Jairus",
lastName: "Tanaka",
lastActive: [2, 7, 2025],
age: 18,
pos: {
x: 3.4,
y: 1.2,
z: 8.3
},
isVerified: true
};
const a1 = JSON.stringify("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f\u000f\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f");
// console.log("Bytes " + bytes(a1).toString());
console.log("a1: " + a1);
const obj = new Obj();
const a2 = JSON.stringify(obj);
// console.log("Bytes " + bytes(a2).toString());
console.log("a2: " + a2);
const a3 = JSON.stringify(player);
// console.log("Bytes " + bytes(a3).toString());
console.log("a3: " + a3);
JSON.Memory.shrink();

@@ -10,3 +10,3 @@ // e -> 101

// @ts-ignore: Decorator valid here
@inline function snp<T extends number>(srcStart: usize, srcEnd: usize): T {
@inline export function snp<T extends number>(srcStart: usize, srcEnd: usize): T {
// @ts-ignore: type

@@ -50,3 +50,3 @@ let val: T = 0;

// @ts-ignore: type
return val / pow10(atoi(srcStart + 2, srcEnd));
return val / pow10(atoi<u8>(srcStart + 2, srcEnd));
} else {

@@ -53,0 +53,0 @@ // @ts-ignore: type

@@ -8,12 +8,12 @@ import { OBJECT, TOTAL_OVERHEAD } from "rt/common";

/** Current buffer pointer. */ // @ts-ignore
export let buffer: usize = __new(32, idof<ArrayBuffer>());
export let buffer: ArrayBuffer = new ArrayBuffer(32);//__new(32, idof<ArrayBuffer>());
/** Current offset within the buffer. */
export let offset: usize = buffer;
export let offset: usize = changetype<usize>(buffer);
/** Byte length of the buffer. */
export let byteLength: usize = 32;
let bufferSize: usize = 32;
/** Proposed size of output */
export let realSize: usize = offset;
export let stackSize: usize = 0;

@@ -25,9 +25,35 @@ /**

*/
// @ts-ignore: Decorator valid here
// @ts-ignore: decorator
@inline export function ensureSize(size: u32): void {
// console.log("Ensure " + (stackSize).toString() + " -> " + (stackSize + size).toString() + " (" + size.toString() + ") " + (((stackSize + size) > bufferSize) ? "+" : ""));
if (offset + size > bufferSize + changetype<usize>(buffer)) {
const deltaBytes = nextPowerOf2(size + 64);
bufferSize += deltaBytes;
// @ts-ignore: exists
const newPtr = changetype<ArrayBuffer>(__renew(
changetype<usize>(buffer),
bufferSize
));
offset = offset + changetype<usize>(newPtr) - changetype<usize>(buffer);
buffer = newPtr;
}
}
/**
* Proposes that the buffer size is should be greater than or equal to the proposed size.
* If necessary, reallocates the buffer to the exact new size.
* @param size - The size to propose.
*/
// @ts-ignore: decorator
@inline export function proposeSize(size: u32): void {
if ((realSize = size) > byteLength) {
byteLength = nextPowerOf2(size);
// @ts-ignore
const newPtr = __renew(buffer, byteLength);
offset = offset - buffer + newPtr;
// console.log("Propose " + (stackSize).toString() + " -> " + (stackSize + size).toString() + " (" + size.toString() + ") " + (((stackSize + size) > bufferSize) ? "+" : ""));
if ((stackSize += size) > bufferSize) {
const deltaBytes = nextPowerOf2(size);
bufferSize += deltaBytes;
// @ts-ignore: exists
const newPtr = changetype<ArrayBuffer>(__renew(
changetype<usize>(buffer),
bufferSize
));
offset = offset + changetype<usize>(newPtr) - changetype<usize>(buffer);
buffer = newPtr;

@@ -38,14 +64,19 @@ }

/**
* Increases the proposed size by nextPowerOf2(n + 8) if necessary.
* Increases the proposed size by nextPowerOf2(n + 64) if necessary.
* If necessary, reallocates the buffer to the exact new size.
* @param size - The size to grow by.
*/
// @ts-ignore: Decorator valid here
// @ts-ignore: decorator
@inline export function growSize(size: u32): void {
realSize += size;
if (realSize > byteLength) {
byteLength += nextPowerOf2(size + 8);
// console.log("Grow " + (stackSize).toString() + " -> " + (stackSize + size).toString() + " (" + size.toString() + ") " + (((stackSize + size) > bufferSize) ? "+" : ""));
if ((stackSize += size) > bufferSize) {
const deltaBytes = nextPowerOf2(size + 64);
bufferSize += deltaBytes;
// @ts-ignore
const newPtr = __renew(buffer, byteLength);
offset = offset - buffer + newPtr;
const newPtr = changetype<ArrayBuffer>(__renew(
changetype<usize>(buffer),
bufferSize
));
// if (buffer != newPtr) console.log(" Old: " + changetype<usize>(buffer).toString() + "\n New: " + changetype<usize>(newPtr).toString());
offset = offset + changetype<usize>(newPtr) - changetype<usize>(buffer);
buffer = newPtr;

@@ -61,8 +92,8 @@ }

@inline export function resize(newSize: u32): void {
// @ts-ignore
// @ts-ignore: exists
const newPtr = __renew(buffer, newSize);
byteLength = newSize;
bufferSize = newSize;
buffer = newPtr;
offset = newPtr + newSize;
realSize = newPtr;
stackSize = newPtr;
}

@@ -76,9 +107,9 @@

@inline export function out<T>(): T {
const len = offset - buffer;
// @ts-ignore
const len = offset - changetype<usize>(buffer);
// @ts-ignore: exists
const _out = __new(len, idof<T>());
memory.copy(_out, buffer, len);
memory.copy(_out, changetype<usize>(buffer), len);
offset = buffer;
realSize = buffer;
offset = changetype<usize>(buffer);
stackSize = 0;
return changetype<T>(_out);

@@ -96,9 +127,9 @@ }

@inline export function outTo<T>(dst: usize): T {
const len = offset - buffer;
// @ts-ignore
const len = offset - changetype<usize>(buffer);
// @ts-ignore: exists
if (len != changetype<OBJECT>(dst - TOTAL_OVERHEAD).rtSize) __renew(len, idof<T>());
memory.copy(dst, buffer, len);
memory.copy(dst, changetype<usize>(buffer), len);
offset = buffer;
realSize = buffer;
offset = changetype<usize>(buffer);
stackSize = 0;
return changetype<T>(dst);

@@ -105,0 +136,0 @@ }

{
"name": "json-as",
"version": "1.0.0-alpha.3",
"version": "1.0.0-alpha.4",
"author": "Jairus Tanaka",

@@ -12,8 +12,8 @@ "repository": {

"@assemblyscript/wasi-shim": "^0.1.0",
"@types/node": "latest",
"@types/node": "^22.13.1",
"as-console": "^7.0.0",
"assemblyscript": "^0.27.31",
"assemblyscript": "^0.27.34",
"assemblyscript-prettier": "^3.0.1",
"prettier": "^3.4.2",
"typescript": "latest"
"prettier": "^3.5.0",
"typescript": "^5.7.3"
},

@@ -20,0 +20,0 @@ "bugs": {

@@ -9,6 +9,17 @@ <h5 align="center">

</span>
AssemblyScript - v1.0.0-alpha.3
AssemblyScript - v1.0.0-alpha.4
</pre>
</h5>
## Contents
- [About](#about)
- [Installation](#installation)
- [Usage](#usage)
- [Examples](#examples)
- [Performance](#performance)
- [License](#license)
- [Contact](#contact)
## About
## Installation

@@ -44,3 +55,2 @@

// @json or @serializable work here
@json

@@ -60,4 +70,3 @@ class Vec3 {

// Drop in a code block, function, or expression that evaluates to a boolean
@omitif((age) => age < 18)
@omitif('this.age <= 0')
@omitif((self: Player) => self.age < 18)
age!: i32;

@@ -70,6 +79,6 @@ @omitnull()

const player: Player = {
firstName: "Emmet",
lastName: "West",
lastActive: [8, 27, 2022],
age: 23,
firstName: "Jairus",
lastName: "Tanaka",
lastActive: [2, 7, 2025],
age: 18,
pos: {

@@ -83,7 +92,11 @@ x: 3.4,

const stringified = JSON.stringify<Player>(player);
const serialized = JSON.stringify<Player>(player);
const parsed = JSON.parse<Player>(serialized);
const parsed = JSON.parse<Player>(stringified);
console.log("Serialized: " + serialized);
console.log("Parsed: " + JSON.stringify(parsed));
```
## Examples
Classes can even have inheritance. Here's a nasty example

@@ -132,14 +145,13 @@

## Notes
## 📃 License
If you want a feature, drop an issue (and again, maybe a star). I'll likely add it in less than 7 days.
This project is distributed under an open source license. You can view the full license using the following link: [License](./LICENSE)
## Contact
## 📫 Contact
- [Email](mailto:me@jairus.dev)
- [GitHub](https://github.com/JairusSW)
- [Discord](discord.com/users/600700584038760448)
Please send all issues to [GitHub Issues](https://github.com/JairusSW/as-json/issues) and to converse, please send me an email at [me@jairus.dev](mailto:me@jairus.dev)
## Issues
Please submit an issue to https://github.com/JairusSW/as-json/issues if you find anything wrong with this library
- **Email:** Send me inquiries, questions, or requests at [me@jairus.dev](mailto:me@jairus.dev)
- **GitHub:** Visit the official GitHub repository [Here](https://github.com/JairusSW/as-json)
- **Website:** Visit my official website at [jairus.dev](https://jairus.dev/)
- **Discord:** Converse with me on [My Discord](discord.com/users/600700584038760448) or on the [AssemblyScript Discord Server](https://discord.gg/assemblyscript/)
import { isTypeOmitted, operatorTokenToString, util } from "assemblyscript/dist/assemblyscript.js";
import { Visitor } from "./visitor.js";
function assert(isTruish, message = "assertion error") {
if (!isTruish) throw new Error(message);
return isTruish;
if (!isTruish)
throw new Error(message);
return isTruish;
}
export class ASTBuilder extends Visitor {
static build(node) {
var builder = new ASTBuilder();
builder.visitNode(node);
return builder.finish();
}
sb = [];
indentLevel = 0;
visitNode(node) {
return this.visit(node);
}
visitSource(source) {
var statements = source.statements;
for (let i = 0, k = statements.length; i < k; ++i) {
this.visitNodeAndTerminate(statements[i]);
static build(node) {
var builder = new ASTBuilder();
builder.visitNode(node);
return builder.finish();
}
}
visitTypeNode(node) {
switch (node.kind) {
case 1: {
this.visitNamedTypeNode(node);
break;
}
case 2: {
this.visitFunctionTypeNode(node);
break;
}
default:
assert(false);
sb = [];
indentLevel = 0;
visitNode(node) {
return this.visit(node);
}
}
visitTypeName(node) {
this.visitIdentifierExpression(node.identifier);
var sb = this.sb;
var current = node.next;
while (current) {
sb.push(".");
this.visitIdentifierExpression(current.identifier);
current = current.next;
visitSource(source) {
var statements = source.statements;
for (let i = 0, k = statements.length; i < k; ++i) {
this.visitNodeAndTerminate(statements[i]);
}
}
}
visitNamedTypeNode(node) {
this.visitTypeName(node.name);
var typeArguments = node.typeArguments;
if (typeArguments) {
let numTypeArguments = typeArguments.length;
let sb = this.sb;
if (numTypeArguments) {
sb.push("<");
this.visitTypeNode(typeArguments[0]);
for (let i = 1; i < numTypeArguments; ++i) {
sb.push(", ");
this.visitTypeNode(typeArguments[i]);
visitTypeNode(node) {
switch (node.kind) {
case 1: {
this.visitNamedTypeNode(node);
break;
}
case 2: {
this.visitFunctionTypeNode(node);
break;
}
default:
assert(false);
}
sb.push(">");
}
if (node.isNullable) sb.push(" | null");
}
}
visitFunctionTypeNode(node) {
var isNullable = node.isNullable;
var sb = this.sb;
sb.push(isNullable ? "((" : "(");
var explicitThisType = node.explicitThisType;
if (explicitThisType) {
sb.push("this: ");
this.visitTypeNode(explicitThisType);
}
var parameters = node.parameters;
var numParameters = parameters.length;
if (numParameters) {
if (explicitThisType) sb.push(", ");
this.serializeParameter(parameters[0]);
for (let i = 1; i < numParameters; ++i) {
sb.push(", ");
this.serializeParameter(parameters[i]);
}
}
var returnType = node.returnType;
if (returnType) {
sb.push(") => ");
this.visitTypeNode(returnType);
} else {
sb.push(") => void");
}
if (isNullable) sb.push(") | null");
}
visitTypeParameter(node) {
this.visitIdentifierExpression(node.name);
var extendsType = node.extendsType;
if (extendsType) {
this.sb.push(" extends ");
this.visitTypeNode(extendsType);
}
var defaultType = node.defaultType;
if (defaultType) {
this.sb.push("=");
this.visitTypeNode(defaultType);
}
}
visitIdentifierExpression(node) {
if (node.isQuoted) this.visitStringLiteral(node.text);
else this.sb.push(node.text);
}
visitArrayLiteralExpression(node) {
var sb = this.sb;
sb.push("[");
var elements = node.elementExpressions;
var numElements = elements.length;
if (numElements) {
let element = elements[0];
if (element) this.visitNode(element);
for (let i = 1; i < numElements; ++i) {
element = elements[i];
sb.push(", ");
if (element) this.visitNode(element);
}
}
sb.push("]");
}
visitObjectLiteralExpression(node) {
var sb = this.sb;
var names = node.names;
var values = node.values;
var numElements = names.length;
assert(numElements == values.length);
if (numElements) {
sb.push("{\n");
util.indent(sb, ++this.indentLevel);
this.visitNode(names[0]);
sb.push(": ");
this.visitNode(values[0]);
for (let i = 1; i < numElements; ++i) {
sb.push(",\n");
util.indent(sb, this.indentLevel);
let name = names[i];
let value = values[i];
if (name == value) {
this.visitNode(name);
} else {
this.visitNode(name);
sb.push(": ");
this.visitNode(value);
visitTypeName(node) {
this.visitIdentifierExpression(node.identifier);
var sb = this.sb;
var current = node.next;
while (current) {
sb.push(".");
this.visitIdentifierExpression(current.identifier);
current = current.next;
}
}
sb.push("\n");
util.indent(sb, --this.indentLevel);
sb.push("}");
} else {
sb.push("{}");
}
}
visitAssertionExpression(node) {
var sb = this.sb;
switch (node.assertionKind) {
case 0: {
sb.push("<");
if (node.toType) this.visitTypeNode(node.toType);
sb.push(">");
this.visitNode(node.expression);
break;
}
case 1: {
this.visitNode(node.expression);
sb.push(" as ");
if (node.toType) this.visitTypeNode(node.toType);
break;
}
case 2: {
this.visitNode(node.expression);
sb.push("!");
break;
}
case 3: {
this.visitNode(node.expression);
sb.push(" as const");
break;
}
default:
assert(false);
}
}
visitBinaryExpression(node) {
var sb = this.sb;
this.visitNode(node.left);
sb.push(" ");
sb.push(operatorTokenToString(node.operator));
sb.push(" ");
this.visitNode(node.right);
}
visitCallExpression(node) {
this.visitNode(node.expression);
this.visitArguments(node.typeArguments, node.args);
}
visitArguments(typeArguments, args) {
var sb = this.sb;
if (typeArguments) {
let numTypeArguments = typeArguments.length;
if (numTypeArguments) {
sb.push("<");
this.visitTypeNode(typeArguments[0]);
for (let i = 1; i < numTypeArguments; ++i) {
sb.push(", ");
this.visitTypeNode(typeArguments[i]);
visitNamedTypeNode(node) {
this.visitTypeName(node.name);
var typeArguments = node.typeArguments;
if (typeArguments) {
let numTypeArguments = typeArguments.length;
let sb = this.sb;
if (numTypeArguments) {
sb.push("<");
this.visitTypeNode(typeArguments[0]);
for (let i = 1; i < numTypeArguments; ++i) {
sb.push(", ");
this.visitTypeNode(typeArguments[i]);
}
sb.push(">");
}
if (node.isNullable)
sb.push(" | null");
}
sb.push(">(");
}
} else {
sb.push("(");
}
var numArgs = args.length;
if (numArgs) {
this.visitNode(args[0]);
for (let i = 1; i < numArgs; ++i) {
sb.push(", ");
this.visitNode(args[i]);
}
}
sb.push(")");
}
visitClassExpression(node) {
var declaration = node.declaration;
this.visitClassDeclaration(declaration);
}
visitCommaExpression(node) {
var expressions = node.expressions;
var numExpressions = expressions.length;
this.visitNode(expressions[0]);
var sb = this.sb;
for (let i = 1; i < numExpressions; ++i) {
sb.push(",");
this.visitNode(expressions[i]);
}
}
visitElementAccessExpression(node) {
var sb = this.sb;
this.visitNode(node.expression);
sb.push("[");
this.visitNode(node.elementExpression);
sb.push("]");
}
visitFunctionExpression(node) {
var declaration = node.declaration;
if (!declaration.arrowKind) {
if (declaration.name.text.length) {
this.sb.push("function ");
} else {
this.sb.push("function");
}
} else {
assert(declaration.name.text.length == 0);
}
this.visitFunctionCommon(declaration);
}
visitLiteralExpression(node) {
switch (node.literalKind) {
case 0: {
this.visitFloatLiteralExpression(node);
break;
}
case 1: {
this.visitIntegerLiteralExpression(node);
break;
}
case 2: {
this.visitStringLiteralExpression(node);
break;
}
case 3: {
this.visitTemplateLiteralExpression(node);
break;
}
case 4: {
this.visitRegexpLiteralExpression(node);
break;
}
case 5: {
this.visitArrayLiteralExpression(node);
break;
}
case 6: {
this.visitObjectLiteralExpression(node);
break;
}
default: {
assert(false);
break;
}
}
}
visitFloatLiteralExpression(node) {
this.sb.push(node.value.toString());
}
visitInstanceOfExpression(node) {
this.visitNode(node.expression);
this.sb.push(" instanceof ");
this.visitTypeNode(node.isType);
}
visitIntegerLiteralExpression(node) {
this.sb.push(i64_to_string(node.value));
}
visitStringLiteral(str) {
var sb = this.sb;
sb.push('"');
this.visitRawString(str, 34);
sb.push('"');
}
visitRawString(str, quote) {
var sb = this.sb;
var off = 0;
var i = 0;
for (let k = str.length; i < k; ) {
switch (str.charCodeAt(i)) {
case 0: {
if (i > off) sb.push(str.substring(off, (off = i + 1)));
sb.push("\\0");
off = ++i;
break;
visitFunctionTypeNode(node) {
var isNullable = node.isNullable;
var sb = this.sb;
sb.push(isNullable ? "((" : "(");
var explicitThisType = node.explicitThisType;
if (explicitThisType) {
sb.push("this: ");
this.visitTypeNode(explicitThisType);
}
case 92: {
if (i > off) sb.push(str.substring(off, i));
off = ++i;
sb.push("\\b");
break;
var parameters = node.parameters;
var numParameters = parameters.length;
if (numParameters) {
if (explicitThisType)
sb.push(", ");
this.serializeParameter(parameters[0]);
for (let i = 1; i < numParameters; ++i) {
sb.push(", ");
this.serializeParameter(parameters[i]);
}
}
case 9: {
if (i > off) sb.push(str.substring(off, i));
off = ++i;
sb.push("\\t");
break;
var returnType = node.returnType;
if (returnType) {
sb.push(") => ");
this.visitTypeNode(returnType);
}
case 10: {
if (i > off) sb.push(str.substring(off, i));
off = ++i;
sb.push("\\n");
break;
else {
sb.push(") => void");
}
case 11: {
if (i > off) sb.push(str.substring(off, i));
off = ++i;
sb.push("\\v");
break;
if (isNullable)
sb.push(") | null");
}
visitTypeParameter(node) {
this.visitIdentifierExpression(node.name);
var extendsType = node.extendsType;
if (extendsType) {
this.sb.push(" extends ");
this.visitTypeNode(extendsType);
}
case 12: {
if (i > off) sb.push(str.substring(off, i));
off = ++i;
sb.push("\\f");
break;
var defaultType = node.defaultType;
if (defaultType) {
this.sb.push("=");
this.visitTypeNode(defaultType);
}
case 13: {
if (i > off) sb.push(str.substring(off, i));
sb.push("\\r");
off = ++i;
break;
}
visitIdentifierExpression(node) {
if (node.isQuoted)
this.visitStringLiteral(node.text);
else
this.sb.push(node.text);
}
visitArrayLiteralExpression(node) {
var sb = this.sb;
sb.push("[");
var elements = node.elementExpressions;
var numElements = elements.length;
if (numElements) {
let element = elements[0];
if (element)
this.visitNode(element);
for (let i = 1; i < numElements; ++i) {
element = elements[i];
sb.push(", ");
if (element)
this.visitNode(element);
}
}
case 34: {
if (quote == 34) {
if (i > off) sb.push(str.substring(off, i));
sb.push('\\"');
off = ++i;
} else {
++i;
}
break;
sb.push("]");
}
visitObjectLiteralExpression(node) {
var sb = this.sb;
var names = node.names;
var values = node.values;
var numElements = names.length;
assert(numElements == values.length);
if (numElements) {
sb.push("{\n");
util.indent(sb, ++this.indentLevel);
this.visitNode(names[0]);
sb.push(": ");
this.visitNode(values[0]);
for (let i = 1; i < numElements; ++i) {
sb.push(",\n");
util.indent(sb, this.indentLevel);
let name = names[i];
let value = values[i];
if (name == value) {
this.visitNode(name);
}
else {
this.visitNode(name);
sb.push(": ");
this.visitNode(value);
}
}
sb.push("\n");
util.indent(sb, --this.indentLevel);
sb.push("}");
}
case 39: {
if (quote == 39) {
if (i > off) sb.push(str.substring(off, i));
sb.push("\\'");
off = ++i;
} else {
++i;
}
break;
else {
sb.push("{}");
}
case 92: {
if (i > off) sb.push(str.substring(off, i));
sb.push("\\\\");
off = ++i;
break;
}
visitAssertionExpression(node) {
var sb = this.sb;
switch (node.assertionKind) {
case 0: {
sb.push("<");
if (node.toType)
this.visitTypeNode(node.toType);
sb.push(">");
this.visitNode(node.expression);
break;
}
case 1: {
this.visitNode(node.expression);
sb.push(" as ");
if (node.toType)
this.visitTypeNode(node.toType);
break;
}
case 2: {
this.visitNode(node.expression);
sb.push("!");
break;
}
case 3: {
this.visitNode(node.expression);
sb.push(" as const");
break;
}
default:
assert(false);
}
case 96: {
if (quote == 96) {
if (i > off) sb.push(str.substring(off, i));
sb.push("\\`");
off = ++i;
} else {
++i;
}
break;
}
default: {
++i;
break;
}
}
}
if (i > off) sb.push(str.substring(off, i));
}
visitStringLiteralExpression(node) {
this.visitStringLiteral(node.value);
}
visitTemplateLiteralExpression(node) {
var sb = this.sb;
var tag = node.tag;
var parts = node.parts;
var expressions = node.expressions;
if (tag) this.visitNode(tag);
sb.push("`");
this.visitRawString(parts[0], 96);
assert(parts.length == expressions.length + 1);
for (let i = 0, k = expressions.length; i < k; ++i) {
sb.push("${");
this.visitNode(expressions[i]);
sb.push("}");
this.visitRawString(parts[i + 1], 96);
visitBinaryExpression(node) {
var sb = this.sb;
this.visitNode(node.left);
sb.push(" ");
sb.push(operatorTokenToString(node.operator));
sb.push(" ");
this.visitNode(node.right);
}
sb.push("`");
}
visitRegexpLiteralExpression(node) {
var sb = this.sb;
sb.push("/");
sb.push(node.pattern);
sb.push("/");
sb.push(node.patternFlags);
}
visitNewExpression(node) {
this.sb.push("new ");
this.visitTypeName(node.typeName);
this.visitArguments(node.typeArguments, node.args);
}
visitParenthesizedExpression(node) {
var sb = this.sb;
sb.push("(");
this.visitNode(node.expression);
sb.push(")");
}
visitPropertyAccessExpression(node) {
this.visitNode(node.expression);
this.sb.push(".");
this.visitIdentifierExpression(node.property);
}
visitTernaryExpression(node) {
var sb = this.sb;
this.visitNode(node.condition);
sb.push(" ? ");
this.visitNode(node.ifThen);
sb.push(" : ");
this.visitNode(node.ifElse);
}
visitUnaryExpression(node) {
switch (node.kind) {
case 27: {
this.visitUnaryPostfixExpression(node);
break;
}
case 28: {
this.visitUnaryPrefixExpression(node);
break;
}
default:
assert(false);
visitCallExpression(node) {
this.visitNode(node.expression);
this.visitArguments(node.typeArguments, node.args);
}
}
visitUnaryPostfixExpression(node) {
this.visitNode(node.operand);
this.sb.push(operatorTokenToString(node.operator));
}
visitUnaryPrefixExpression(node) {
this.sb.push(operatorTokenToString(node.operator));
this.visitNode(node.operand);
}
visitNodeAndTerminate(node) {
this.visitNode(node);
var sb = this.sb;
if (!sb.length || node.kind == 47 || node.kind == 38) {
sb.push(";\n");
} else {
let last = sb[sb.length - 1];
let lastCharPos = last.length - 1;
if (lastCharPos >= 0 && (last.charCodeAt(lastCharPos) == 125 || last.charCodeAt(lastCharPos) == 59)) {
sb.push("\n");
} else {
sb.push(";\n");
}
visitArguments(typeArguments, args) {
var sb = this.sb;
if (typeArguments) {
let numTypeArguments = typeArguments.length;
if (numTypeArguments) {
sb.push("<");
this.visitTypeNode(typeArguments[0]);
for (let i = 1; i < numTypeArguments; ++i) {
sb.push(", ");
this.visitTypeNode(typeArguments[i]);
}
sb.push(">(");
}
}
else {
sb.push("(");
}
var numArgs = args.length;
if (numArgs) {
this.visitNode(args[0]);
for (let i = 1; i < numArgs; ++i) {
sb.push(", ");
this.visitNode(args[i]);
}
}
sb.push(")");
}
}
visitBlockStatement(node) {
var sb = this.sb;
var statements = node.statements;
var numStatements = statements.length;
if (numStatements) {
sb.push("{\n");
let indentLevel = ++this.indentLevel;
for (let i = 0; i < numStatements; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(statements[i]);
}
util.indent(sb, --this.indentLevel);
sb.push("}");
} else {
sb.push("{}");
visitClassExpression(node) {
var declaration = node.declaration;
this.visitClassDeclaration(declaration);
}
}
visitBreakStatement(node) {
var label = node.label;
if (label) {
this.sb.push("break ");
this.visitIdentifierExpression(label);
} else {
this.sb.push("break");
visitCommaExpression(node) {
var expressions = node.expressions;
var numExpressions = expressions.length;
this.visitNode(expressions[0]);
var sb = this.sb;
for (let i = 1; i < numExpressions; ++i) {
sb.push(",");
this.visitNode(expressions[i]);
}
}
}
visitContinueStatement(node) {
var label = node.label;
if (label) {
this.sb.push("continue ");
this.visitIdentifierExpression(label);
} else {
this.sb.push("continue");
visitElementAccessExpression(node) {
var sb = this.sb;
this.visitNode(node.expression);
sb.push("[");
this.visitNode(node.elementExpression);
sb.push("]");
}
}
visitClassDeclaration(node, isDefault = false) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
var sb = this.sb;
if (isDefault) {
sb.push("export default ");
} else {
this.serializeExternalModifiers(node);
}
if (node.is(128)) sb.push("abstract ");
if (node.name.text.length) {
sb.push("class ");
this.visitIdentifierExpression(node.name);
} else {
sb.push("class");
}
var typeParameters = node.typeParameters;
if (typeParameters != null && typeParameters.length > 0) {
sb.push("<");
this.visitTypeParameter(typeParameters[0]);
for (let i = 1, k = typeParameters.length; i < k; ++i) {
sb.push(", ");
this.visitTypeParameter(typeParameters[i]);
}
sb.push(">");
}
var extendsType = node.extendsType;
if (extendsType) {
sb.push(" extends ");
this.visitTypeNode(extendsType);
}
var implementsTypes = node.implementsTypes;
if (implementsTypes) {
let numImplementsTypes = implementsTypes.length;
if (numImplementsTypes) {
sb.push(" implements ");
this.visitTypeNode(implementsTypes[0]);
for (let i = 1; i < numImplementsTypes; ++i) {
sb.push(", ");
this.visitTypeNode(implementsTypes[i]);
visitFunctionExpression(node) {
var declaration = node.declaration;
if (!declaration.arrowKind) {
if (declaration.name.text.length) {
this.sb.push("function ");
}
else {
this.sb.push("function");
}
}
}
else {
assert(declaration.name.text.length == 0);
}
this.visitFunctionCommon(declaration);
}
var indexSignature = node.indexSignature;
var members = node.members;
var numMembers = members.length;
if (indexSignature !== null || numMembers) {
sb.push(" {\n");
let indentLevel = ++this.indentLevel;
if (indexSignature) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(indexSignature);
}
for (let i = 0, k = members.length; i < k; ++i) {
let member = members[i];
if (member.kind != 54 || member.parameterIndex < 0) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(member);
visitLiteralExpression(node) {
switch (node.literalKind) {
case 0: {
this.visitFloatLiteralExpression(node);
break;
}
case 1: {
this.visitIntegerLiteralExpression(node);
break;
}
case 2: {
this.visitStringLiteralExpression(node);
break;
}
case 3: {
this.visitTemplateLiteralExpression(node);
break;
}
case 4: {
this.visitRegexpLiteralExpression(node);
break;
}
case 5: {
this.visitArrayLiteralExpression(node);
break;
}
case 6: {
this.visitObjectLiteralExpression(node);
break;
}
default: {
assert(false);
break;
}
}
}
util.indent(sb, --this.indentLevel);
sb.push("}");
} else {
sb.push(" {}");
}
}
visitDoStatement(node) {
var sb = this.sb;
sb.push("do ");
this.visitNode(node.body);
if (node.body.kind == 30) {
sb.push(" while (");
} else {
util.indent(sb, this.indentLevel);
sb.push("while (");
visitFloatLiteralExpression(node) {
this.sb.push(node.value.toString());
}
this.visitNode(node.condition);
sb.push(")");
}
visitEmptyStatement(node) {}
visitEnumDeclaration(node, isDefault = false) {
var sb = this.sb;
if (isDefault) {
sb.push("export default ");
} else {
this.serializeExternalModifiers(node);
visitInstanceOfExpression(node) {
this.visitNode(node.expression);
this.sb.push(" instanceof ");
this.visitTypeNode(node.isType);
}
if (node.is(8)) sb.push("const ");
sb.push("enum ");
this.visitIdentifierExpression(node.name);
var values = node.values;
var numValues = values.length;
if (numValues) {
sb.push(" {\n");
let indentLevel = ++this.indentLevel;
util.indent(sb, indentLevel);
this.visitEnumValueDeclaration(node.values[0]);
for (let i = 1; i < numValues; ++i) {
sb.push(",\n");
util.indent(sb, indentLevel);
this.visitEnumValueDeclaration(node.values[i]);
}
sb.push("\n");
util.indent(sb, --this.indentLevel);
sb.push("}");
} else {
sb.push(" {}");
visitIntegerLiteralExpression(node) {
this.sb.push(i64_to_string(node.value));
}
}
visitEnumValueDeclaration(node) {
this.visitIdentifierExpression(node.name);
var initializer = node.initializer;
if (initializer) {
this.sb.push(" = ");
this.visitNode(initializer);
visitStringLiteral(str) {
var sb = this.sb;
sb.push('"');
this.visitRawString(str, 34);
sb.push('"');
}
}
visitExportImportStatement(node) {
var sb = this.sb;
sb.push("export import ");
this.visitIdentifierExpression(node.externalName);
sb.push(" = ");
this.visitIdentifierExpression(node.name);
}
visitExportMember(node) {
this.visitIdentifierExpression(node.localName);
if (node.exportedName.text != node.localName.text) {
this.sb.push(" as ");
this.visitIdentifierExpression(node.exportedName);
visitRawString(str, quote) {
var sb = this.sb;
var off = 0;
var i = 0;
for (let k = str.length; i < k;) {
switch (str.charCodeAt(i)) {
case 0: {
if (i > off)
sb.push(str.substring(off, (off = i + 1)));
sb.push("\\0");
off = ++i;
break;
}
case 92: {
if (i > off)
sb.push(str.substring(off, i));
off = ++i;
sb.push("\\b");
break;
}
case 9: {
if (i > off)
sb.push(str.substring(off, i));
off = ++i;
sb.push("\\t");
break;
}
case 10: {
if (i > off)
sb.push(str.substring(off, i));
off = ++i;
sb.push("\\n");
break;
}
case 11: {
if (i > off)
sb.push(str.substring(off, i));
off = ++i;
sb.push("\\v");
break;
}
case 12: {
if (i > off)
sb.push(str.substring(off, i));
off = ++i;
sb.push("\\f");
break;
}
case 13: {
if (i > off)
sb.push(str.substring(off, i));
sb.push("\\r");
off = ++i;
break;
}
case 34: {
if (quote == 34) {
if (i > off)
sb.push(str.substring(off, i));
sb.push('\\"');
off = ++i;
}
else {
++i;
}
break;
}
case 39: {
if (quote == 39) {
if (i > off)
sb.push(str.substring(off, i));
sb.push("\\'");
off = ++i;
}
else {
++i;
}
break;
}
case 92: {
if (i > off)
sb.push(str.substring(off, i));
sb.push("\\\\");
off = ++i;
break;
}
case 96: {
if (quote == 96) {
if (i > off)
sb.push(str.substring(off, i));
sb.push("\\`");
off = ++i;
}
else {
++i;
}
break;
}
default: {
++i;
break;
}
}
}
if (i > off)
sb.push(str.substring(off, i));
}
}
visitExportStatement(node) {
var sb = this.sb;
if (node.isDeclare) {
sb.push("declare ");
visitStringLiteralExpression(node) {
this.visitStringLiteral(node.value);
}
var members = node.members;
if (members == null) {
sb.push("export *");
} else if (members.length > 0) {
let numMembers = members.length;
sb.push("export {\n");
let indentLevel = ++this.indentLevel;
util.indent(sb, indentLevel);
this.visitExportMember(members[0]);
for (let i = 1; i < numMembers; ++i) {
sb.push(",\n");
util.indent(sb, indentLevel);
this.visitExportMember(members[i]);
}
--this.indentLevel;
sb.push("\n}");
} else {
sb.push("export {}");
visitTemplateLiteralExpression(node) {
var sb = this.sb;
var tag = node.tag;
var parts = node.parts;
var expressions = node.expressions;
if (tag)
this.visitNode(tag);
sb.push("`");
this.visitRawString(parts[0], 96);
assert(parts.length == expressions.length + 1);
for (let i = 0, k = expressions.length; i < k; ++i) {
sb.push("${");
this.visitNode(expressions[i]);
sb.push("}");
this.visitRawString(parts[i + 1], 96);
}
sb.push("`");
}
var path = node.path;
if (path) {
sb.push(" from ");
this.visitStringLiteralExpression(path);
visitRegexpLiteralExpression(node) {
var sb = this.sb;
sb.push("/");
sb.push(node.pattern);
sb.push("/");
sb.push(node.patternFlags);
}
sb.push(";");
}
visitExportDefaultStatement(node) {
var declaration = node.declaration;
switch (declaration.kind) {
case 52: {
this.visitEnumDeclaration(declaration, true);
break;
}
case 55: {
this.visitFunctionDeclaration(declaration, true);
break;
}
case 51: {
this.visitClassDeclaration(declaration, true);
break;
}
case 57: {
this.visitInterfaceDeclaration(declaration, true);
break;
}
case 59: {
this.visitNamespaceDeclaration(declaration, true);
break;
}
default:
assert(false);
visitNewExpression(node) {
this.sb.push("new ");
this.visitTypeName(node.typeName);
this.visitArguments(node.typeArguments, node.args);
}
}
visitExpressionStatement(node) {
this.visitNode(node.expression);
}
visitFieldDeclaration(node) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
visitParenthesizedExpression(node) {
var sb = this.sb;
sb.push("(");
this.visitNode(node.expression);
sb.push(")");
}
this.serializeAccessModifiers(node);
this.visitIdentifierExpression(node.name);
var sb = this.sb;
if (node.flags & 16384) {
sb.push("!");
visitPropertyAccessExpression(node) {
this.visitNode(node.expression);
this.sb.push(".");
this.visitIdentifierExpression(node.property);
}
var type = node.type;
if (type) {
sb.push(": ");
this.visitTypeNode(type);
visitTernaryExpression(node) {
var sb = this.sb;
this.visitNode(node.condition);
sb.push(" ? ");
this.visitNode(node.ifThen);
sb.push(" : ");
this.visitNode(node.ifElse);
}
var initializer = node.initializer;
if (initializer) {
sb.push(" = ");
this.visitNode(initializer);
visitUnaryExpression(node) {
switch (node.kind) {
case 27: {
this.visitUnaryPostfixExpression(node);
break;
}
case 28: {
this.visitUnaryPrefixExpression(node);
break;
}
default:
assert(false);
}
}
}
visitForStatement(node) {
var sb = this.sb;
sb.push("for (");
var initializer = node.initializer;
if (initializer) {
this.visitNode(initializer);
visitUnaryPostfixExpression(node) {
this.visitNode(node.operand);
this.sb.push(operatorTokenToString(node.operator));
}
var condition = node.condition;
if (condition) {
sb.push("; ");
this.visitNode(condition);
} else {
sb.push(";");
visitUnaryPrefixExpression(node) {
this.sb.push(operatorTokenToString(node.operator));
this.visitNode(node.operand);
}
var incrementor = node.incrementor;
if (incrementor) {
sb.push("; ");
this.visitNode(incrementor);
} else {
sb.push(";");
visitNodeAndTerminate(node) {
this.visitNode(node);
var sb = this.sb;
if (!sb.length ||
node.kind == 47 ||
node.kind == 38) {
sb.push(";\n");
}
else {
let last = sb[sb.length - 1];
let lastCharPos = last.length - 1;
if (lastCharPos >= 0 && (last.charCodeAt(lastCharPos) == 125 || last.charCodeAt(lastCharPos) == 59)) {
sb.push("\n");
}
else {
sb.push(";\n");
}
}
}
sb.push(") ");
this.visitNode(node.body);
}
visitForOfStatement(node) {
var sb = this.sb;
sb.push("for (");
this.visitNode(node.variable);
sb.push(" of ");
this.visitNode(node.iterable);
sb.push(") ");
this.visitNode(node.body);
}
visitFunctionDeclaration(node, isDefault = false) {
var sb = this.sb;
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
visitBlockStatement(node) {
var sb = this.sb;
var statements = node.statements;
var numStatements = statements.length;
if (numStatements) {
sb.push("{\n");
let indentLevel = ++this.indentLevel;
for (let i = 0; i < numStatements; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(statements[i]);
}
util.indent(sb, --this.indentLevel);
sb.push("}");
}
else {
sb.push("{}");
}
}
if (isDefault) {
sb.push("export default ");
} else {
this.serializeExternalModifiers(node);
this.serializeAccessModifiers(node);
visitBreakStatement(node) {
var label = node.label;
if (label) {
this.sb.push("break ");
this.visitIdentifierExpression(label);
}
else {
this.sb.push("break");
}
}
if (node.name.text.length) {
sb.push("function ");
} else {
sb.push("function");
}
this.visitFunctionCommon(node);
}
visitFunctionCommon(node) {
var sb = this.sb;
this.visitIdentifierExpression(node.name);
var signature = node.signature;
var typeParameters = node.typeParameters;
if (typeParameters) {
let numTypeParameters = typeParameters.length;
if (numTypeParameters) {
sb.push("<");
this.visitTypeParameter(typeParameters[0]);
for (let i = 1; i < numTypeParameters; ++i) {
sb.push(", ");
this.visitTypeParameter(typeParameters[i]);
visitContinueStatement(node) {
var label = node.label;
if (label) {
this.sb.push("continue ");
this.visitIdentifierExpression(label);
}
sb.push(">");
}
else {
this.sb.push("continue");
}
}
if (node.arrowKind == 2) {
let parameters = signature.parameters;
assert(parameters.length == 1);
assert(!signature.explicitThisType);
this.serializeParameter(parameters[0]);
} else {
sb.push("(");
let parameters = signature.parameters;
let numParameters = parameters.length;
let explicitThisType = signature.explicitThisType;
if (explicitThisType) {
sb.push("this: ");
this.visitTypeNode(explicitThisType);
}
if (numParameters) {
if (explicitThisType) sb.push(", ");
this.serializeParameter(parameters[0]);
for (let i = 1; i < numParameters; ++i) {
sb.push(", ");
this.serializeParameter(parameters[i]);
visitClassDeclaration(node, isDefault = false) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
}
var sb = this.sb;
if (isDefault) {
sb.push("export default ");
}
else {
this.serializeExternalModifiers(node);
}
if (node.is(128))
sb.push("abstract ");
if (node.name.text.length) {
sb.push("class ");
this.visitIdentifierExpression(node.name);
}
else {
sb.push("class");
}
var typeParameters = node.typeParameters;
if (typeParameters != null && typeParameters.length > 0) {
sb.push("<");
this.visitTypeParameter(typeParameters[0]);
for (let i = 1, k = typeParameters.length; i < k; ++i) {
sb.push(", ");
this.visitTypeParameter(typeParameters[i]);
}
sb.push(">");
}
var extendsType = node.extendsType;
if (extendsType) {
sb.push(" extends ");
this.visitTypeNode(extendsType);
}
var implementsTypes = node.implementsTypes;
if (implementsTypes) {
let numImplementsTypes = implementsTypes.length;
if (numImplementsTypes) {
sb.push(" implements ");
this.visitTypeNode(implementsTypes[0]);
for (let i = 1; i < numImplementsTypes; ++i) {
sb.push(", ");
this.visitTypeNode(implementsTypes[i]);
}
}
}
var indexSignature = node.indexSignature;
var members = node.members;
var numMembers = members.length;
if (indexSignature !== null || numMembers) {
sb.push(" {\n");
let indentLevel = ++this.indentLevel;
if (indexSignature) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(indexSignature);
}
for (let i = 0, k = members.length; i < k; ++i) {
let member = members[i];
if (member.kind != 54 || member.parameterIndex < 0) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(member);
}
}
util.indent(sb, --this.indentLevel);
sb.push("}");
}
else {
sb.push(" {}");
}
}
var body = node.body;
var returnType = signature.returnType;
if (node.arrowKind) {
if (body) {
if (node.arrowKind == 2) {
assert(isTypeOmitted(returnType));
} else {
if (isTypeOmitted(returnType)) {
sb.push(")");
} else {
sb.push("): ");
this.visitTypeNode(returnType);
}
visitDoStatement(node) {
var sb = this.sb;
sb.push("do ");
this.visitNode(node.body);
if (node.body.kind == 30) {
sb.push(" while (");
}
sb.push(" => ");
this.visitNode(body);
} else {
assert(!isTypeOmitted(returnType));
sb.push(" => ");
this.visitTypeNode(returnType);
}
} else {
if (!isTypeOmitted(returnType) && !node.isAny(524288 | 4096)) {
sb.push("): ");
this.visitTypeNode(returnType);
} else {
else {
util.indent(sb, this.indentLevel);
sb.push("while (");
}
this.visitNode(node.condition);
sb.push(")");
}
if (body) {
sb.push(" ");
this.visitNode(body);
}
}
}
visitIfStatement(node) {
var sb = this.sb;
sb.push("if (");
this.visitNode(node.condition);
sb.push(") ");
var ifTrue = node.ifTrue;
this.visitNode(ifTrue);
if (ifTrue.kind != 30) {
sb.push(";\n");
visitEmptyStatement(node) {
}
var ifFalse = node.ifFalse;
if (ifFalse) {
if (ifTrue.kind == 30) {
sb.push(" else ");
} else {
sb.push("else ");
}
this.visitNode(ifFalse);
visitEnumDeclaration(node, isDefault = false) {
var sb = this.sb;
if (isDefault) {
sb.push("export default ");
}
else {
this.serializeExternalModifiers(node);
}
if (node.is(8))
sb.push("const ");
sb.push("enum ");
this.visitIdentifierExpression(node.name);
var values = node.values;
var numValues = values.length;
if (numValues) {
sb.push(" {\n");
let indentLevel = ++this.indentLevel;
util.indent(sb, indentLevel);
this.visitEnumValueDeclaration(node.values[0]);
for (let i = 1; i < numValues; ++i) {
sb.push(",\n");
util.indent(sb, indentLevel);
this.visitEnumValueDeclaration(node.values[i]);
}
sb.push("\n");
util.indent(sb, --this.indentLevel);
sb.push("}");
}
else {
sb.push(" {}");
}
}
}
visitImportDeclaration(node) {
var externalName = node.foreignName;
var name = node.name;
this.visitIdentifierExpression(externalName);
if (externalName.text != name.text) {
this.sb.push(" as ");
this.visitIdentifierExpression(name);
}
}
visitImportStatement(node) {
var sb = this.sb;
sb.push("import ");
var declarations = node.declarations;
var namespaceName = node.namespaceName;
if (declarations) {
let numDeclarations = declarations.length;
if (numDeclarations) {
sb.push("{\n");
let indentLevel = ++this.indentLevel;
util.indent(sb, indentLevel);
this.visitImportDeclaration(declarations[0]);
for (let i = 1; i < numDeclarations; ++i) {
sb.push(",\n");
util.indent(sb, indentLevel);
this.visitImportDeclaration(declarations[i]);
visitEnumValueDeclaration(node) {
this.visitIdentifierExpression(node.name);
var initializer = node.initializer;
if (initializer) {
this.sb.push(" = ");
this.visitNode(initializer);
}
--this.indentLevel;
sb.push("\n} from ");
} else {
sb.push("{} from ");
}
} else if (namespaceName) {
sb.push("* as ");
this.visitIdentifierExpression(namespaceName);
sb.push(" from ");
}
this.visitStringLiteralExpression(node.path);
}
visitIndexSignature(node) {
var sb = this.sb;
sb.push("[key: ");
this.visitTypeNode(node.keyType);
sb.push("]: ");
this.visitTypeNode(node.valueType);
}
visitInterfaceDeclaration(node, isDefault = false) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
visitExportImportStatement(node) {
var sb = this.sb;
sb.push("export import ");
this.visitIdentifierExpression(node.externalName);
sb.push(" = ");
this.visitIdentifierExpression(node.name);
}
var sb = this.sb;
if (isDefault) {
sb.push("export default ");
} else {
this.serializeExternalModifiers(node);
visitExportMember(node) {
this.visitIdentifierExpression(node.localName);
if (node.exportedName.text != node.localName.text) {
this.sb.push(" as ");
this.visitIdentifierExpression(node.exportedName);
}
}
sb.push("interface ");
this.visitIdentifierExpression(node.name);
var typeParameters = node.typeParameters;
if (typeParameters != null && typeParameters.length > 0) {
sb.push("<");
this.visitTypeParameter(typeParameters[0]);
for (let i = 1, k = typeParameters.length; i < k; ++i) {
sb.push(", ");
this.visitTypeParameter(typeParameters[i]);
}
sb.push(">");
visitExportStatement(node) {
var sb = this.sb;
if (node.isDeclare) {
sb.push("declare ");
}
var members = node.members;
if (members == null) {
sb.push("export *");
}
else if (members.length > 0) {
let numMembers = members.length;
sb.push("export {\n");
let indentLevel = ++this.indentLevel;
util.indent(sb, indentLevel);
this.visitExportMember(members[0]);
for (let i = 1; i < numMembers; ++i) {
sb.push(",\n");
util.indent(sb, indentLevel);
this.visitExportMember(members[i]);
}
--this.indentLevel;
sb.push("\n}");
}
else {
sb.push("export {}");
}
var path = node.path;
if (path) {
sb.push(" from ");
this.visitStringLiteralExpression(path);
}
sb.push(";");
}
var extendsType = node.extendsType;
if (extendsType) {
sb.push(" extends ");
this.visitTypeNode(extendsType);
visitExportDefaultStatement(node) {
var declaration = node.declaration;
switch (declaration.kind) {
case 52: {
this.visitEnumDeclaration(declaration, true);
break;
}
case 55: {
this.visitFunctionDeclaration(declaration, true);
break;
}
case 51: {
this.visitClassDeclaration(declaration, true);
break;
}
case 57: {
this.visitInterfaceDeclaration(declaration, true);
break;
}
case 59: {
this.visitNamespaceDeclaration(declaration, true);
break;
}
default:
assert(false);
}
}
sb.push(" {\n");
var indentLevel = ++this.indentLevel;
var members = node.members;
for (let i = 0, k = members.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(members[i]);
visitExpressionStatement(node) {
this.visitNode(node.expression);
}
--this.indentLevel;
sb.push("}");
}
visitMethodDeclaration(node) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
visitFieldDeclaration(node) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
this.serializeAccessModifiers(node);
this.visitIdentifierExpression(node.name);
var sb = this.sb;
if (node.flags & 16384) {
sb.push("!");
}
var type = node.type;
if (type) {
sb.push(": ");
this.visitTypeNode(type);
}
var initializer = node.initializer;
if (initializer) {
sb.push(" = ");
this.visitNode(initializer);
}
}
this.serializeAccessModifiers(node);
if (node.is(2048)) {
this.sb.push("get ");
} else if (node.is(4096)) {
this.sb.push("set ");
visitForStatement(node) {
var sb = this.sb;
sb.push("for (");
var initializer = node.initializer;
if (initializer) {
this.visitNode(initializer);
}
var condition = node.condition;
if (condition) {
sb.push("; ");
this.visitNode(condition);
}
else {
sb.push(";");
}
var incrementor = node.incrementor;
if (incrementor) {
sb.push("; ");
this.visitNode(incrementor);
}
else {
sb.push(";");
}
sb.push(") ");
this.visitNode(node.body);
}
this.visitFunctionCommon(node);
}
visitNamespaceDeclaration(node, isDefault = false) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
visitForOfStatement(node) {
var sb = this.sb;
sb.push("for (");
this.visitNode(node.variable);
sb.push(" of ");
this.visitNode(node.iterable);
sb.push(") ");
this.visitNode(node.body);
}
var sb = this.sb;
if (isDefault) {
sb.push("export default ");
} else {
this.serializeExternalModifiers(node);
visitFunctionDeclaration(node, isDefault = false) {
var sb = this.sb;
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
if (isDefault) {
sb.push("export default ");
}
else {
this.serializeExternalModifiers(node);
this.serializeAccessModifiers(node);
}
if (node.name.text.length) {
sb.push("function ");
}
else {
sb.push("function");
}
this.visitFunctionCommon(node);
}
sb.push("namespace ");
this.visitIdentifierExpression(node.name);
var members = node.members;
var numMembers = members.length;
if (numMembers) {
sb.push(" {\n");
let indentLevel = ++this.indentLevel;
for (let i = 0, k = members.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(members[i]);
}
util.indent(sb, --this.indentLevel);
sb.push("}");
} else {
sb.push(" {}");
visitFunctionCommon(node) {
var sb = this.sb;
this.visitIdentifierExpression(node.name);
var signature = node.signature;
var typeParameters = node.typeParameters;
if (typeParameters) {
let numTypeParameters = typeParameters.length;
if (numTypeParameters) {
sb.push("<");
this.visitTypeParameter(typeParameters[0]);
for (let i = 1; i < numTypeParameters; ++i) {
sb.push(", ");
this.visitTypeParameter(typeParameters[i]);
}
sb.push(">");
}
}
if (node.arrowKind == 2) {
let parameters = signature.parameters;
assert(parameters.length == 1);
assert(!signature.explicitThisType);
this.serializeParameter(parameters[0]);
}
else {
sb.push("(");
let parameters = signature.parameters;
let numParameters = parameters.length;
let explicitThisType = signature.explicitThisType;
if (explicitThisType) {
sb.push("this: ");
this.visitTypeNode(explicitThisType);
}
if (numParameters) {
if (explicitThisType)
sb.push(", ");
this.serializeParameter(parameters[0]);
for (let i = 1; i < numParameters; ++i) {
sb.push(", ");
this.serializeParameter(parameters[i]);
}
}
}
var body = node.body;
var returnType = signature.returnType;
if (node.arrowKind) {
if (body) {
if (node.arrowKind == 2) {
assert(isTypeOmitted(returnType));
}
else {
if (isTypeOmitted(returnType)) {
sb.push(")");
}
else {
sb.push("): ");
this.visitTypeNode(returnType);
}
}
sb.push(" => ");
this.visitNode(body);
}
else {
assert(!isTypeOmitted(returnType));
sb.push(" => ");
this.visitTypeNode(returnType);
}
}
else {
if (!isTypeOmitted(returnType) && !node.isAny(524288 | 4096)) {
sb.push("): ");
this.visitTypeNode(returnType);
}
else {
sb.push(")");
}
if (body) {
sb.push(" ");
this.visitNode(body);
}
}
}
}
visitReturnStatement(node) {
var value = node.value;
if (value) {
this.sb.push("return ");
this.visitNode(value);
} else {
this.sb.push("return");
visitIfStatement(node) {
var sb = this.sb;
sb.push("if (");
this.visitNode(node.condition);
sb.push(") ");
var ifTrue = node.ifTrue;
this.visitNode(ifTrue);
if (ifTrue.kind != 30) {
sb.push(";\n");
}
var ifFalse = node.ifFalse;
if (ifFalse) {
if (ifTrue.kind == 30) {
sb.push(" else ");
}
else {
sb.push("else ");
}
this.visitNode(ifFalse);
}
}
}
visitTrueExpression(node) {
this.sb.push("true");
}
visitFalseExpression(node) {
this.sb.push("false");
}
visitNullExpression(node) {
this.sb.push("null");
}
visitSwitchCase(node) {
var sb = this.sb;
var label = node.label;
if (label) {
sb.push("case ");
this.visitNode(label);
sb.push(":\n");
} else {
sb.push("default:\n");
visitImportDeclaration(node) {
var externalName = node.foreignName;
var name = node.name;
this.visitIdentifierExpression(externalName);
if (externalName.text != name.text) {
this.sb.push(" as ");
this.visitIdentifierExpression(name);
}
}
var statements = node.statements;
var numStatements = statements.length;
if (numStatements) {
let indentLevel = ++this.indentLevel;
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(statements[0]);
for (let i = 1; i < numStatements; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(statements[i]);
}
--this.indentLevel;
visitImportStatement(node) {
var sb = this.sb;
sb.push("import ");
var declarations = node.declarations;
var namespaceName = node.namespaceName;
if (declarations) {
let numDeclarations = declarations.length;
if (numDeclarations) {
sb.push("{\n");
let indentLevel = ++this.indentLevel;
util.indent(sb, indentLevel);
this.visitImportDeclaration(declarations[0]);
for (let i = 1; i < numDeclarations; ++i) {
sb.push(",\n");
util.indent(sb, indentLevel);
this.visitImportDeclaration(declarations[i]);
}
--this.indentLevel;
sb.push("\n} from ");
}
else {
sb.push("{} from ");
}
}
else if (namespaceName) {
sb.push("* as ");
this.visitIdentifierExpression(namespaceName);
sb.push(" from ");
}
this.visitStringLiteralExpression(node.path);
}
}
visitSwitchStatement(node) {
var sb = this.sb;
sb.push("switch (");
this.visitNode(node.condition);
sb.push(") {\n");
var indentLevel = ++this.indentLevel;
var cases = node.cases;
for (let i = 0, k = cases.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitSwitchCase(cases[i]);
sb.push("\n");
visitIndexSignature(node) {
var sb = this.sb;
sb.push("[key: ");
this.visitTypeNode(node.keyType);
sb.push("]: ");
this.visitTypeNode(node.valueType);
}
--this.indentLevel;
sb.push("}");
}
visitThrowStatement(node) {
this.sb.push("throw ");
this.visitNode(node.value);
}
visitTryStatement(node) {
var sb = this.sb;
sb.push("try {\n");
var indentLevel = ++this.indentLevel;
var statements = node.bodyStatements;
for (let i = 0, k = statements.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(statements[i]);
visitInterfaceDeclaration(node, isDefault = false) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
var sb = this.sb;
if (isDefault) {
sb.push("export default ");
}
else {
this.serializeExternalModifiers(node);
}
sb.push("interface ");
this.visitIdentifierExpression(node.name);
var typeParameters = node.typeParameters;
if (typeParameters != null && typeParameters.length > 0) {
sb.push("<");
this.visitTypeParameter(typeParameters[0]);
for (let i = 1, k = typeParameters.length; i < k; ++i) {
sb.push(", ");
this.visitTypeParameter(typeParameters[i]);
}
sb.push(">");
}
var extendsType = node.extendsType;
if (extendsType) {
sb.push(" extends ");
this.visitTypeNode(extendsType);
}
sb.push(" {\n");
var indentLevel = ++this.indentLevel;
var members = node.members;
for (let i = 0, k = members.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(members[i]);
}
--this.indentLevel;
sb.push("}");
}
var catchVariable = node.catchVariable;
if (catchVariable) {
util.indent(sb, indentLevel - 1);
sb.push("} catch (");
this.visitIdentifierExpression(catchVariable);
sb.push(") {\n");
let catchStatements = node.catchStatements;
if (catchStatements) {
for (let i = 0, k = catchStatements.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(catchStatements[i]);
visitMethodDeclaration(node) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
}
this.serializeAccessModifiers(node);
if (node.is(2048)) {
this.sb.push("get ");
}
else if (node.is(4096)) {
this.sb.push("set ");
}
this.visitFunctionCommon(node);
}
var finallyStatements = node.finallyStatements;
if (finallyStatements) {
util.indent(sb, indentLevel - 1);
sb.push("} finally {\n");
for (let i = 0, k = finallyStatements.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(finallyStatements[i]);
}
visitNamespaceDeclaration(node, isDefault = false) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
var sb = this.sb;
if (isDefault) {
sb.push("export default ");
}
else {
this.serializeExternalModifiers(node);
}
sb.push("namespace ");
this.visitIdentifierExpression(node.name);
var members = node.members;
var numMembers = members.length;
if (numMembers) {
sb.push(" {\n");
let indentLevel = ++this.indentLevel;
for (let i = 0, k = members.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(members[i]);
}
util.indent(sb, --this.indentLevel);
sb.push("}");
}
else {
sb.push(" {}");
}
}
util.indent(sb, indentLevel - 1);
sb.push("}");
}
visitTypeDeclaration(node) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
var sb = this.sb;
this.serializeExternalModifiers(node);
sb.push("type ");
this.visitIdentifierExpression(node.name);
var typeParameters = node.typeParameters;
if (typeParameters) {
let numTypeParameters = typeParameters.length;
if (numTypeParameters) {
sb.push("<");
for (let i = 0; i < numTypeParameters; ++i) {
this.visitTypeParameter(typeParameters[i]);
visitReturnStatement(node) {
var value = node.value;
if (value) {
this.sb.push("return ");
this.visitNode(value);
}
sb.push(">");
}
else {
this.sb.push("return");
}
}
sb.push(" = ");
this.visitTypeNode(node.type);
}
visitVariableDeclaration(node) {
this.visitIdentifierExpression(node.name);
var type = node.type;
var sb = this.sb;
if (node.flags & 16384) {
sb.push("!");
visitTrueExpression(node) {
this.sb.push("true");
}
if (type) {
sb.push(": ");
this.visitTypeNode(type);
visitFalseExpression(node) {
this.sb.push("false");
}
var initializer = node.initializer;
if (initializer) {
sb.push(" = ");
this.visitNode(initializer);
visitNullExpression(node) {
this.sb.push("null");
}
}
visitVariableStatement(node) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
visitSwitchCase(node) {
var sb = this.sb;
var label = node.label;
if (label) {
sb.push("case ");
this.visitNode(label);
sb.push(":\n");
}
else {
sb.push("default:\n");
}
var statements = node.statements;
var numStatements = statements.length;
if (numStatements) {
let indentLevel = ++this.indentLevel;
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(statements[0]);
for (let i = 1; i < numStatements; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(statements[i]);
}
--this.indentLevel;
}
}
var sb = this.sb;
var declarations = node.declarations;
var numDeclarations = declarations.length;
var firstDeclaration = declarations[0];
this.serializeExternalModifiers(firstDeclaration);
sb.push(firstDeclaration.is(8) ? "const " : firstDeclaration.is(16) ? "let " : "var ");
this.visitVariableDeclaration(node.declarations[0]);
for (let i = 1; i < numDeclarations; ++i) {
sb.push(", ");
this.visitVariableDeclaration(node.declarations[i]);
visitSwitchStatement(node) {
var sb = this.sb;
sb.push("switch (");
this.visitNode(node.condition);
sb.push(") {\n");
var indentLevel = ++this.indentLevel;
var cases = node.cases;
for (let i = 0, k = cases.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitSwitchCase(cases[i]);
sb.push("\n");
}
--this.indentLevel;
sb.push("}");
}
}
visitWhileStatement(node) {
var sb = this.sb;
sb.push("while (");
this.visitNode(node.condition);
var statement = node.body;
if (statement.kind == 34) {
sb.push(")");
} else {
sb.push(") ");
this.visitNode(node.body);
visitThrowStatement(node) {
this.sb.push("throw ");
this.visitNode(node.value);
}
}
serializeDecorator(node) {
var sb = this.sb;
sb.push("@");
this.visitNode(node.name);
var args = node.args;
if (args) {
sb.push("(");
let numArgs = args.length;
if (numArgs) {
this.visitNode(args[0]);
for (let i = 1; i < numArgs; ++i) {
sb.push(", ");
this.visitNode(args[i]);
visitTryStatement(node) {
var sb = this.sb;
sb.push("try {\n");
var indentLevel = ++this.indentLevel;
var statements = node.bodyStatements;
for (let i = 0, k = statements.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(statements[i]);
}
}
sb.push(")\n");
} else {
sb.push("\n");
var catchVariable = node.catchVariable;
if (catchVariable) {
util.indent(sb, indentLevel - 1);
sb.push("} catch (");
this.visitIdentifierExpression(catchVariable);
sb.push(") {\n");
let catchStatements = node.catchStatements;
if (catchStatements) {
for (let i = 0, k = catchStatements.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(catchStatements[i]);
}
}
}
var finallyStatements = node.finallyStatements;
if (finallyStatements) {
util.indent(sb, indentLevel - 1);
sb.push("} finally {\n");
for (let i = 0, k = finallyStatements.length; i < k; ++i) {
util.indent(sb, indentLevel);
this.visitNodeAndTerminate(finallyStatements[i]);
}
}
util.indent(sb, indentLevel - 1);
sb.push("}");
}
util.indent(sb, this.indentLevel);
}
serializeParameter(node) {
var sb = this.sb;
var kind = node.parameterKind;
var implicitFieldDeclaration = node.implicitFieldDeclaration;
if (implicitFieldDeclaration) {
this.serializeAccessModifiers(implicitFieldDeclaration);
visitTypeDeclaration(node) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
var sb = this.sb;
this.serializeExternalModifiers(node);
sb.push("type ");
this.visitIdentifierExpression(node.name);
var typeParameters = node.typeParameters;
if (typeParameters) {
let numTypeParameters = typeParameters.length;
if (numTypeParameters) {
sb.push("<");
for (let i = 0; i < numTypeParameters; ++i) {
this.visitTypeParameter(typeParameters[i]);
}
sb.push(">");
}
}
sb.push(" = ");
this.visitTypeNode(node.type);
}
if (kind == 2) {
sb.push("...");
visitVariableDeclaration(node) {
this.visitIdentifierExpression(node.name);
var type = node.type;
var sb = this.sb;
if (node.flags & 16384) {
sb.push("!");
}
if (type) {
sb.push(": ");
this.visitTypeNode(type);
}
var initializer = node.initializer;
if (initializer) {
sb.push(" = ");
this.visitNode(initializer);
}
}
this.visitIdentifierExpression(node.name);
var type = node.type;
var initializer = node.initializer;
if (type) {
if (kind == 1 && !initializer) sb.push("?");
if (!isTypeOmitted(type)) {
sb.push(": ");
this.visitTypeNode(type);
}
visitVariableStatement(node) {
var decorators = node.decorators;
if (decorators) {
for (let i = 0, k = decorators.length; i < k; ++i) {
this.serializeDecorator(decorators[i]);
}
}
var sb = this.sb;
var declarations = node.declarations;
var numDeclarations = declarations.length;
var firstDeclaration = declarations[0];
this.serializeExternalModifiers(firstDeclaration);
sb.push(firstDeclaration.is(8) ? "const " : firstDeclaration.is(16) ? "let " : "var ");
this.visitVariableDeclaration(node.declarations[0]);
for (let i = 1; i < numDeclarations; ++i) {
sb.push(", ");
this.visitVariableDeclaration(node.declarations[i]);
}
}
if (initializer) {
sb.push(" = ");
this.visitNode(initializer);
visitWhileStatement(node) {
var sb = this.sb;
sb.push("while (");
this.visitNode(node.condition);
var statement = node.body;
if (statement.kind == 34) {
sb.push(")");
}
else {
sb.push(") ");
this.visitNode(node.body);
}
}
}
serializeExternalModifiers(node) {
var sb = this.sb;
if (node.is(2)) {
sb.push("export ");
} else if (node.is(1)) {
sb.push("import ");
} else if (node.is(4)) {
sb.push("declare ");
serializeDecorator(node) {
var sb = this.sb;
sb.push("@");
this.visitNode(node.name);
var args = node.args;
if (args) {
sb.push("(");
let numArgs = args.length;
if (numArgs) {
this.visitNode(args[0]);
for (let i = 1; i < numArgs; ++i) {
sb.push(", ");
this.visitNode(args[i]);
}
}
sb.push(")\n");
}
else {
sb.push("\n");
}
util.indent(sb, this.indentLevel);
}
}
serializeAccessModifiers(node) {
var sb = this.sb;
if (node.is(256)) {
sb.push("public ");
} else if (node.is(512)) {
sb.push("private ");
} else if (node.is(1024)) {
sb.push("protected ");
serializeParameter(node) {
var sb = this.sb;
var kind = node.parameterKind;
var implicitFieldDeclaration = node.implicitFieldDeclaration;
if (implicitFieldDeclaration) {
this.serializeAccessModifiers(implicitFieldDeclaration);
}
if (kind == 2) {
sb.push("...");
}
this.visitIdentifierExpression(node.name);
var type = node.type;
var initializer = node.initializer;
if (type) {
if (kind == 1 && !initializer)
sb.push("?");
if (!isTypeOmitted(type)) {
sb.push(": ");
this.visitTypeNode(type);
}
}
if (initializer) {
sb.push(" = ");
this.visitNode(initializer);
}
}
if (node.is(32)) {
sb.push("static ");
} else if (node.is(128)) {
sb.push("abstract ");
serializeExternalModifiers(node) {
var sb = this.sb;
if (node.is(2)) {
sb.push("export ");
}
else if (node.is(1)) {
sb.push("import ");
}
else if (node.is(4)) {
sb.push("declare ");
}
}
if (node.is(64)) {
sb.push("readonly ");
serializeAccessModifiers(node) {
var sb = this.sb;
if (node.is(256)) {
sb.push("public ");
}
else if (node.is(512)) {
sb.push("private ");
}
else if (node.is(1024)) {
sb.push("protected ");
}
if (node.is(32)) {
sb.push("static ");
}
else if (node.is(128)) {
sb.push("abstract ");
}
if (node.is(64)) {
sb.push("readonly ");
}
}
}
finish() {
var ret = this.sb.join("");
this.sb = [];
return ret;
}
finish() {
var ret = this.sb.join("");
this.sb = [];
return ret;
}
}
//# sourceMappingURL=builder.js.map
//# sourceMappingURL=builder.js.map

@@ -11,564 +11,634 @@ import { IdentifierExpression, Source, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, Node, Tokenizer } from "assemblyscript/dist/assemblyscript.js";

class JSONTransform extends Visitor {
parser;
schemas = [];
schema;
sources = new Set();
imports = [];
jsonImport = null;
bsImport = null;
newStmts = { simd: [] };
visitClassDeclaration(node) {
if (!node.decorators?.length) return;
if (
!node.decorators.some((decorator) => {
const name = decorator.name.text;
return name === "json" || name === "serializable";
})
)
return;
this.schema = new Schema();
this.schema.node = node;
this.schema.name = node.name.text;
this.schemas.push(this.schema);
if (process.env["JSON_DEBUG"]) console.log("Created schema: " + this.schema.name);
const members = [...node.members.filter((v) => v.kind === 54 && v.flags !== 32 && v.flags !== 512 && v.flags !== 1024 && !v.decorators?.some((decorator) => decorator.name.text === "omit"))];
if (node.extendsType) {
const extendsName = node.extendsType?.name.identifier.text;
this.schema.parent = this.schemas.find((v) => v.name == extendsName);
if (!this.schema.parent) {
const internalSearch = getClasses(node.range.source).find((v) => v.name.text == extendsName);
if (internalSearch) {
if (process.env["JSON_DEBUG"]) console.log("Found " + extendsName + " internally");
this.visitClassDeclaration(internalSearch);
this.visitClassDeclaration(node);
return;
parser;
schemas = [];
schema;
sources = new Set();
imports = [];
jsonImport = null;
bsImport = null;
newStmts = { simd: [] };
visitClassDeclaration(node) {
if (!node.decorators?.length)
return;
if (!node.decorators.some((decorator) => {
const name = decorator.name.text;
return name === "json" || name === "serializable";
}))
return;
this.schema = new Schema();
this.schema.node = node;
this.schema.name = node.name.text;
this.schemas.push(this.schema);
if (process.env["JSON_DEBUG"])
console.log("Created schema: " + this.schema.name);
const members = [...node.members.filter((v) => v.kind === 54 && v.flags !== 32 && v.flags !== 512 && v.flags !== 1024 && !v.decorators?.some((decorator) => decorator.name.text === "omit"))];
if (node.extendsType) {
const extendsName = node.extendsType?.name.identifier.text;
this.schema.parent = this.schemas.find((v) => v.name == extendsName);
if (!this.schema.parent) {
const internalSearch = getClasses(node.range.source).find((v) => v.name.text == extendsName);
if (internalSearch) {
if (process.env["JSON_DEBUG"])
console.log("Found " + extendsName + " internally");
this.visitClassDeclaration(internalSearch);
this.visitClassDeclaration(node);
return;
}
const externalSearch = getImportedClass(extendsName, node.range.source, this.parser);
if (externalSearch) {
if (process.env["JSON_DEBUG"])
console.log("Found " + extendsName + " externally");
this.visitClassDeclaration(externalSearch);
this.visitClassDeclaration(node);
return;
}
}
if (this.schema.parent?.members) {
for (let i = this.schema.parent.members.length - 1; i >= 0; i--) {
const replace = this.schema.members.find((v) => v.name == this.schema.parent?.members[i]?.name);
if (!replace) {
members.unshift(this.schema.parent?.members[i].node);
}
}
}
}
const externalSearch = getImportedClass(extendsName, node.range.source, this.parser);
if (externalSearch) {
if (process.env["JSON_DEBUG"]) console.log("Found " + extendsName + " externally");
this.visitClassDeclaration(externalSearch);
this.visitClassDeclaration(node);
return;
if (!members.length) {
this.generateEmptyMethods(node);
return;
}
}
if (this.schema.parent?.members) {
for (let i = this.schema.parent.members.length - 1; i >= 0; i--) {
const replace = this.schema.members.find((v) => v.name == this.schema.parent?.members[i]?.name);
if (!replace) {
members.unshift(this.schema.parent?.members[i].node);
}
this.addRequiredImports(node);
for (const member of members) {
if (!member.type)
throwError("Fields must be strongly typed", node.range);
const type = toString(member.type);
const name = member.name;
const value = member.initializer ? toString(member.initializer) : null;
if (type.startsWith("(") && type.includes("=>"))
continue;
const mem = new Property();
mem.name = name.text;
mem.type = type;
mem.value = value;
mem.node = member;
mem.byteSize = sizeof(mem.type);
this.schema.byteSize += mem.byteSize;
if (type.includes("JSON.Raw"))
mem.flags.set(PropertyFlags.Raw, null);
if (member.decorators) {
for (const decorator of member.decorators) {
const decoratorName = decorator.name.text.toLowerCase().trim();
switch (decoratorName) {
case "alias": {
const args = getArgs(decorator.args);
if (!args.length)
throwError("@alias must have an argument of type string or number", member.range);
mem.alias = args[0];
break;
}
case "omitif": {
let arg = decorator.args[0];
if (!decorator.args?.length)
throwError("@omitif must have an argument or callback that resolves to type bool", member.range);
mem.flags.set(PropertyFlags.OmitIf, arg);
this.schema.static = false;
break;
}
case "omitnull": {
if (isPrimitive(type)) {
throwError("@omitnull cannot be used on primitive types!", member.range);
}
else if (!member.type.isNullable) {
throwError("@omitnull cannot be used on non-nullable types!", member.range);
}
mem.flags.set(PropertyFlags.OmitNull, null);
this.schema.static = false;
break;
}
}
}
}
this.schema.members.push(mem);
}
}
}
if (!members.length) {
this.generateEmptyMethods(node);
return;
}
this.addRequiredImports(node);
for (const member of members) {
if (!member.type) throwError("Fields must be strongly typed", node.range);
const type = toString(member.type);
const name = member.name;
const value = member.initializer ? toString(member.initializer) : null;
if (type.startsWith("(") && type.includes("=>")) continue;
const mem = new Property();
mem.name = name.text;
mem.type = type;
mem.value = value;
mem.node = member;
mem.byteSize = sizeof(mem.type);
this.schema.byteSize += mem.byteSize;
if (type.includes("JSON.Raw")) mem.flags.set(PropertyFlags.Raw, null);
if (member.decorators) {
for (const decorator of member.decorators) {
const decoratorName = decorator.name.text.toLowerCase().trim();
switch (decoratorName) {
case "alias": {
const args = getArgs(decorator.args);
if (!args.length) throwError("@alias must have an argument of type string or number", member.range);
mem.alias = args[0];
break;
if (!this.schema.static)
this.schema.members = sortMembers(this.schema.members);
let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
let INITIALIZE = "@inline __INITIALIZE(): this {\n";
let DESERIALIZE = "__DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n switch (<u32>keyEnd - <u32>keyStart) {\n";
indent = " ";
if (this.schema.static == false) {
if (this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitNull))) {
SERIALIZE += indent + "let block: usize = 0;\n";
}
case "omitif": {
let arg = decorator.args[0];
if (!decorator.args?.length) throwError("@omitif must have an argument or callback that resolves to type bool", member.range);
mem.flags.set(PropertyFlags.OmitIf, arg);
this.schema.static = false;
break;
this.schema.byteSize += 2;
SERIALIZE += indent + "store<u16>(bs.offset, 123, 0); // {\n";
SERIALIZE += indent + "bs.offset += 2;\n";
}
for (const member of this.schema.members) {
const nonNullType = member.type.replace(" | null", "");
if (!isPrimitive(nonNullType)) {
const schema = this.schemas.find((v) => v.name == nonNullType);
if (schema && !this.schema.deps.includes(schema)) {
this.schema.deps.push(schema);
this.schema.byteSize += schema.byteSize;
}
}
case "omitnull": {
if (isPrimitive(type)) {
throwError("@omitnull cannot be used on primitive types!", member.range);
} else if (!member.type.isNullable) {
throwError("@omitnull cannot be used on non-nullable types!", member.range);
}
mem.flags.set(PropertyFlags.OmitNull, null);
this.schema.static = false;
break;
}
let isPure = this.schema.static;
let isRegular = isPure;
let isFirst = true;
for (let i = 0; i < this.schema.members.length; i++) {
const member = this.schema.members[i];
const aliasName = JSON.stringify(member.alias || member.name);
const realName = member.name;
const isLast = i == this.schema.members.length - 1;
const nonNullType = member.type.replace(" | null", "");
if (member.value) {
INITIALIZE += ` this.${member.name} = ${member.value};\n`;
}
}
else if (this.schemas.find((v) => nonNullType == v.name)) {
INITIALIZE += ` this.${member.name} = changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())).__INITIALIZE();\n`;
}
else if (member.type.startsWith("Array<") || member.type.startsWith("Map<")) {
INITIALIZE += ` this.${member.name} = [];\n`;
}
else if (member.type == "string" || member.type == "String" || member.type == "JSON.Raw") {
INITIALIZE += ` this.${member.name} = "";\n`;
}
if (!isRegular && !member.flags.has(PropertyFlags.OmitIf) && !member.flags.has(PropertyFlags.OmitNull))
isRegular = true;
if (isRegular && isPure) {
const keyPart = (isFirst ? "{" : ",") + aliasName + ":";
this.schema.byteSize += keyPart.length << 1;
SERIALIZE += this.getStores(keyPart)
.map((v) => indent + v + "\n")
.join("");
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
if (isFirst)
isFirst = false;
}
else if (isRegular && !isPure) {
const keyPart = (isFirst ? "" : ",") + aliasName + ":";
this.schema.byteSize += keyPart.length << 1;
SERIALIZE += this.getStores(keyPart)
.map((v) => indent + v + "\n")
.join("");
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
if (isFirst)
isFirst = false;
}
else {
if (member.flags.has(PropertyFlags.OmitNull)) {
SERIALIZE += indent + `if ((block = load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))) !== 0) {\n`;
indentInc();
const keyPart = aliasName + ":";
this.schema.byteSize += keyPart.length << 1;
SERIALIZE += this.getStores(keyPart)
.map((v) => indent + v + "\n")
.join("");
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
if (!isLast) {
this.schema.byteSize += 2;
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
SERIALIZE += indent + `bs.offset += 2;\n`;
}
indentDec();
this.schema.byteSize += 2;
SERIALIZE += indent + `}\n`;
}
else if (member.flags.has(PropertyFlags.OmitIf)) {
if (member.flags.get(PropertyFlags.OmitIf).kind == 14) {
const arg = member.flags.get(PropertyFlags.OmitIf);
arg.declaration.signature.parameters[0].type = Node.createNamedType(Node.createSimpleTypeName("this", node.range), null, false, node.range);
arg.declaration.signature.returnType.name = Node.createSimpleTypeName("boolean", arg.declaration.signature.returnType.name.range);
SERIALIZE += indent + `if (!(${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
}
else {
SERIALIZE += indent + `if (${toString(member.flags.get(PropertyFlags.OmitIf))}) {\n`;
}
indentInc();
SERIALIZE += this.getStores(aliasName + ":")
.map((v) => indent + v + "\n")
.join("");
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
if (!isLast) {
this.schema.byteSize += 2;
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
SERIALIZE += indent + `bs.offset += 2;\n`;
}
indentDec();
SERIALIZE += indent + `}\n`;
}
}
}
}
this.schema.members.push(mem);
}
if (!this.schema.static) this.schema.members = sortMembers(this.schema.members);
let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
let INITIALIZE = "@inline __INITIALIZE(): this {\n";
let DESERIALIZE = "__DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n switch (<u32>keyEnd - <u32>keyStart) {\n";
let ALLOCATE = "@inline __ALLOCATE(): void {\n";
indent = " ";
if (this.schema.static == false) {
if (this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitNull))) {
SERIALIZE += indent + "let block: usize = 0;\n";
}
this.schema.byteSize += 2;
SERIALIZE += indent + "store<u16>(bs.offset, 123, 0); // {\n";
SERIALIZE += indent + "bs.offset += 2;\n";
}
for (const member of this.schema.members) {
const nonNullType = member.type.replace(" | null", "");
if (!isPrimitive(nonNullType)) {
const schema = this.schemas.find((v) => v.name == nonNullType);
if (schema && !this.schema.deps.includes(schema)) {
this.schema.deps.push(schema);
this.schema.byteSize += schema.byteSize;
let sortedMembers = [];
let len = -1;
this.schema.members
.slice()
.sort((a, b) => (a.alias?.length || a.name.length) - (b.alias?.length || b.name.length))
.forEach((member) => {
const _nameLength = member.alias?.length || member.name.length;
if (_nameLength === len) {
sortedMembers[sortedMembers.length - 1].push(member);
}
else {
sortedMembers.push([member]);
len = _nameLength;
}
});
sortedMembers = sortedMembers.sort((a, b) => b.length - a.length);
indentInc();
for (const memberGroup of sortedMembers) {
const memberLen = (memberGroup[0].alias || memberGroup[0].name).length << 1;
DESERIALIZE += `${indent}case ${memberLen}: {\n`;
indentInc();
if (memberLen == 2)
DESERIALIZE += `${indent}switch (load<u16>(keyStart)) {\n`;
else if (memberLen == 4)
DESERIALIZE += `${indent}switch (load<u32>(keyStart)) {\n`;
else if (memberLen == 6)
DESERIALIZE += `${indent}let code = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n`;
else if (memberLen == 6)
DESERIALIZE += `${indent}let code = load<u64>(keyStart);\n`;
else
DESERIALIZE += toMemCDecl(memberLen, indent);
for (let i = 0; i < memberGroup.length; i++) {
const member = memberGroup[i];
const memberName = member.alias || member.name;
const dst = this.schemas.find(v => v.name == member.type) ? "ptr + offsetof<this>(\"" + member.name + "\") + 12" : "0";
if (memberLen == 2) {
DESERIALIZE += `${indent} case ${memberName.charCodeAt(0)}: { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent} }\n`;
}
else if (memberLen == 4) {
DESERIALIZE += `${indent} case ${toU32(memberName)}: { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent} }\n`;
}
else if (memberLen == 6) {
DESERIALIZE += i == 0 ? indent : "";
DESERIALIZE += `if (code == ${toU48(memberName)}) { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
}
else if (memberLen == 8) {
DESERIALIZE += i == 0 ? indent : "";
DESERIALIZE += `if (code == ${toU64(memberName)}) { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
}
else {
DESERIALIZE += i == 0 ? indent : "";
DESERIALIZE += `if (${toMemCCheck(memberName)}) { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
}
}
if (memberLen < 6) {
DESERIALIZE += `${indent}}\n`;
}
indentDec();
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent}}\n`;
}
}
}
let isPure = this.schema.static;
let isRegular = isPure;
let isFirst = true;
for (let i = 0; i < this.schema.members.length; i++) {
const member = this.schema.members[i];
const aliasName = JSON.stringify(member.alias || member.name);
const realName = member.name;
const isLast = i == this.schema.members.length - 1;
const nonNullType = member.type.replace(" | null", "");
if (member.value) {
INITIALIZE += ` this.${member.name} = ${member.value};\n`;
} else if (this.schemas.find((v) => nonNullType == v.name)) {
INITIALIZE += ` this.${member.name} = changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())).__INITIALIZE();\n`;
} else if (member.type.startsWith("Array<") || member.type.startsWith("Map<")) {
INITIALIZE += ` this.${member.name} = [];\n`;
} else if (member.type == "string" || member.type == "String" || member.type == "JSON.Raw") {
INITIALIZE += ` this.${member.name} = "";\n`;
}
if (!isRegular && !member.flags.has(PropertyFlags.OmitIf) && !member.flags.has(PropertyFlags.OmitNull)) isRegular = true;
if (isRegular && isPure) {
const keyPart = (isFirst ? "{" : ",") + aliasName + ":";
this.schema.byteSize += keyPart.length << 1;
SERIALIZE += this.getStores(keyPart)
.map((v) => indent + v + "\n")
.join("");
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
if (isFirst) isFirst = false;
} else if (isRegular && !isPure) {
const keyPart = (isFirst ? "" : ",") + aliasName + ":";
this.schema.byteSize += keyPart.length << 1;
SERIALIZE += this.getStores(keyPart)
.map((v) => indent + v + "\n")
.join("");
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
if (isFirst) isFirst = false;
} else {
if (member.flags.has(PropertyFlags.OmitNull)) {
SERIALIZE += indent + `if ((block = load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))) !== 0) {\n`;
indentInc();
const keyPart = aliasName + ":";
this.schema.byteSize += keyPart.length << 1;
SERIALIZE += this.getStores(keyPart)
.map((v) => indent + v + "\n")
.join("");
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
if (!isLast) {
this.schema.byteSize += 2;
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
SERIALIZE += indent + `bs.offset += 2;\n`;
}
indentDec();
this.schema.byteSize += 2;
SERIALIZE += indent + `}\n`;
} else if (member.flags.has(PropertyFlags.OmitIf)) {
if (member.flags.get(PropertyFlags.OmitIf).kind == 14) {
const arg = member.flags.get(PropertyFlags.OmitIf);
arg.declaration.signature.returnType.name = Node.createSimpleTypeName("boolean", arg.declaration.signature.returnType.name.range);
SERIALIZE += indent + `if (!(${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
} else {
SERIALIZE += indent + `if (${toString(member.flags.get(PropertyFlags.OmitIf))}) {\n`;
}
indentInc();
SERIALIZE += this.getStores(aliasName + ":")
.map((v) => indent + v + "\n")
.join("");
SERIALIZE += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
if (!isLast) {
this.schema.byteSize += 2;
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
SERIALIZE += indent + `bs.offset += 2;\n`;
}
indentDec();
SERIALIZE += indent + `}\n`;
indentDec();
DESERIALIZE += `${indent}}\n`;
indentDec();
DESERIALIZE += `${indent}}\n`;
indent = " ";
this.schema.byteSize += 2;
SERIALIZE += indent + "store<u16>(bs.offset, 125, 0); // }\n";
SERIALIZE += indent + "bs.offset += 2;\n";
SERIALIZE += "}";
SERIALIZE = SERIALIZE.slice(0, 32) + indent + "bs.proposeSize(" + this.schema.byteSize + ");\n" + SERIALIZE.slice(32);
INITIALIZE += " return this;\n";
INITIALIZE += "}";
if (process.env["JSON_DEBUG"]) {
console.log(SERIALIZE);
console.log(INITIALIZE);
console.log(DESERIALIZE);
}
}
const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE, node);
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
node.members.push(SERIALIZE_METHOD);
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
node.members.push(INITIALIZE_METHOD);
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
node.members.push(DESERIALIZE_METHOD);
super.visitClassDeclaration(node);
}
let sortedMembers = [];
let len = -1;
this.schema.members
.slice()
.sort((a, b) => (a.alias?.length || a.name.length) - (b.alias?.length || b.name.length))
.forEach((member) => {
const _nameLength = member.alias?.length || member.name.length;
if (_nameLength === len) {
sortedMembers[sortedMembers.length - 1].push(member);
} else {
sortedMembers.push([member]);
len = _nameLength;
generateEmptyMethods(node) {
let SERIALIZE_RAW_EMPTY = '@inline __SERIALIZE(ptr: usize = changetype<usize>(this)): string {\n return "{}";\n}';
let SERIALIZE_BS_EMPTY = "@inline __SERIALIZE(ptr: usize: bool): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
let INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
let DESERIALIZE_EMPTY = "@inline __DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n return false;\n}";
if (process.env["JSON_DEBUG"]) {
console.log(SERIALIZE_RAW_EMPTY);
console.log(SERIALIZE_BS_EMPTY);
console.log(INITIALIZE_EMPTY);
console.log(DESERIALIZE_EMPTY);
}
});
sortedMembers = sortedMembers.sort((a, b) => b.length - a.length);
indentInc();
for (const memberGroup of sortedMembers) {
const memberLen = (memberGroup[0].alias || memberGroup[0].name).length << 1;
DESERIALIZE += `${indent}case ${memberLen}: {\n`;
indentInc();
if (memberLen == 2) DESERIALIZE += `${indent}switch (load<u16>(keyStart)) {\n`;
else if (memberLen == 4) DESERIALIZE += `${indent}switch (load<u32>(keyStart)) {\n`;
else if (memberLen == 6) DESERIALIZE += `${indent}let code = (<u64>load<u32>(keyStart) << 16) | <u64>load<u16>(keyStart, 4);\n`;
else DESERIALIZE += toMemCDecl(memberLen, indent);
for (let i = 0; i < memberGroup.length; i++) {
const member = memberGroup[i];
const memberName = member.alias || member.name;
if (memberLen == 2) {
DESERIALIZE += `${indent} case ${memberName.charCodeAt(0)}: { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent} }\n`;
} else if (memberLen == 4) {
DESERIALIZE += `${indent} case ${toU32(memberName)}: { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent} }\n`;
} else if (memberLen == 6) {
DESERIALIZE += i == 0 ? indent : "";
DESERIALIZE += `if (code == ${toU48(memberName)}) { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
} else {
DESERIALIZE += i == 0 ? indent : "";
DESERIALIZE += `if (${toMemCCheck(memberName)}) { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
}
}
if (memberLen < 6) {
DESERIALIZE += `${indent}}\n`;
}
indentDec();
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent}}\n`;
const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
const SERIALIZE_BS_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_BS_EMPTY, node);
const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
node.members.push(SERIALIZE_BS_METHOD_EMPTY);
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
node.members.push(INITIALIZE_METHOD_EMPTY);
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
node.members.push(DESERIALIZE_METHOD_EMPTY);
}
indentDec();
DESERIALIZE += `${indent}}\n`;
indentDec();
DESERIALIZE += `${indent}}\n`;
indent = " ";
this.schema.byteSize += 2;
SERIALIZE += indent + "store<u16>(bs.offset, 125, 0); // }\n";
SERIALIZE += indent + "bs.offset += 2;\n";
SERIALIZE += "}";
ALLOCATE += indent + "bs.proposeSize(" + this.schema.byteSize + ");\n";
ALLOCATE += "}";
INITIALIZE += " return this;\n";
INITIALIZE += "}";
if (process.env["JSON_DEBUG"]) {
console.log(SERIALIZE);
console.log(INITIALIZE);
console.log(DESERIALIZE);
console.log(ALLOCATE);
visitImportStatement(node) {
super.visitImportStatement(node);
const source = this.parser.sources.find((src) => src.internalPath == node.internalPath);
if (!source)
return;
if (source.statements.some((stmt) => stmt.kind === 59 && stmt.name.text === "JSON"))
this.imports.push(node);
}
const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE, node);
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
const ALLOCATE_METHOD = SimpleParser.parseClassMember(ALLOCATE, node);
if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_METHOD);
if (!node.members.find((v) => v.name.text == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD);
if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD);
if (!node.members.find((v) => v.name.text == "__ALLOCATE")) node.members.push(ALLOCATE_METHOD);
super.visitClassDeclaration(node);
}
generateEmptyMethods(node) {
let SERIALIZE_RAW_EMPTY = '@inline __SERIALIZE(ptr: usize = changetype<usize>(this)): string {\n return "{}";\n}';
let SERIALIZE_BS_EMPTY = "@inline __SERIALIZE(ptr: usize: bool): void {\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
let INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
let DESERIALIZE_EMPTY = "@inline __DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n return false;\n}";
let ALLOCATE_EMPTY = "@inline __ALLOCATE(): void {\n bs.ensureSize(4);\n}";
if (process.env["JSON_DEBUG"]) {
console.log(SERIALIZE_RAW_EMPTY);
console.log(SERIALIZE_BS_EMPTY);
console.log(INITIALIZE_EMPTY);
console.log(DESERIALIZE_EMPTY);
console.log(ALLOCATE_EMPTY);
visitSource(node) {
this.imports = [];
super.visitSource(node);
}
const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node);
const SERIALIZE_BS_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_BS_EMPTY, node);
const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
const ALLOCATE_METHOD_EMPTY = SimpleParser.parseClassMember(ALLOCATE_EMPTY, node);
if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_RAW_METHOD_EMPTY);
if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_BS_METHOD_EMPTY);
if (!node.members.find((v) => v.name.text == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD_EMPTY);
if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD_EMPTY);
if (!node.members.find((v) => v.name.text == "__ALLOCATE")) node.members.push(ALLOCATE_METHOD_EMPTY);
}
visitImportStatement(node) {
super.visitImportStatement(node);
const source = this.parser.sources.find((src) => src.internalPath == node.internalPath);
if (!source) return;
if (source.statements.some((stmt) => stmt.kind === 59 && stmt.name.text === "JSON")) this.imports.push(node);
}
visitSource(node) {
this.imports = [];
super.visitSource(node);
}
addRequiredImports(node) {
if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "bs"))) {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../modules/as-bs/"));
if (!relativePath.startsWith(".") && !relativePath.startsWith("/")) relativePath = "./" + relativePath;
const txt = `import { bs } from "${relativePath}";`;
if (!this.bsImport) {
this.bsImport = txt;
if (process.env["JSON_DEBUG"]) console.log("Added as-bs import: " + txt + "\n");
}
addRequiredImports(node) {
if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "bs"))) {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../modules/as-bs/"));
if (!relativePath.startsWith(".") && !relativePath.startsWith("/"))
relativePath = "./" + relativePath;
const txt = `import { bs } from "${relativePath}";`;
if (!this.bsImport) {
this.bsImport = txt;
if (process.env["JSON_DEBUG"])
console.log("Added as-bs import: " + txt + "\n");
}
}
if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "JSON"))) {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../assembly/index.ts"));
if (!relativePath.startsWith(".") && !relativePath.startsWith("/"))
relativePath = "./" + relativePath;
const txt = `import { JSON } from "${relativePath}";`;
if (!this.jsonImport) {
this.jsonImport = txt;
if (process.env["JSON_DEBUG"])
console.log("Added json-as import: " + txt + "\n");
}
}
}
if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "JSON"))) {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
let relativePath = path.relative(path.dirname(node.range.source.normalizedPath), path.resolve(__dirname, "../../assembly/index.ts"));
if (!relativePath.startsWith(".") && !relativePath.startsWith("/")) relativePath = "./" + relativePath;
const txt = `import { JSON } from "${relativePath}";`;
if (!this.jsonImport) {
this.jsonImport = txt;
if (process.env["JSON_DEBUG"]) console.log("Added json-as import: " + txt + "\n");
}
getStores(data, simd = false) {
const out = [];
const sizes = strToNum(data, simd);
let offset = 0;
for (const [size, num] of sizes) {
if (size == "v128") {
let index = this.newStmts.simd.findIndex((v) => v.includes(num));
let name = "SIMD_" + (index == -1 ? this.newStmts.simd.length : index);
if (index && !this.newStmts.simd.includes(`const ${name} = ${num};`))
this.newStmts.simd.push(`const ${name} = ${num};`);
out.push("store<v128>(bs.offset, " + name + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 8));
offset += 16;
}
if (size == "u64") {
out.push("store<u64>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 4));
offset += 8;
}
else if (size == "u32") {
out.push("store<u32>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 2));
offset += 4;
}
else if (size == "u16") {
out.push("store<u16>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 1));
offset += 2;
}
}
out.push("bs.offset += " + offset + ";");
return out;
}
}
getStores(data, simd = false) {
const out = [];
const sizes = strToNum(data, simd);
let offset = 0;
for (const [size, num] of sizes) {
if (size == "v128") {
let index = this.newStmts.simd.findIndex((v) => v.includes(num));
let name = "SIMD_" + (index == -1 ? this.newStmts.simd.length : index);
if (index && !this.newStmts.simd.includes(`const ${name} = ${num};`)) this.newStmts.simd.push(`const ${name} = ${num};`);
out.push("store<v128>(bs.offset, " + name + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 8));
offset += 16;
}
if (size == "u64") {
out.push("store<u64>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 4));
offset += 8;
} else if (size == "u32") {
out.push("store<u32>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 2));
offset += 4;
} else if (size == "u16") {
out.push("store<u16>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 1));
offset += 2;
}
}
out.push("bs.offset += " + offset + ";");
return out;
}
}
export default class Transformer extends Transform {
afterParse(parser) {
const transformer = new JSONTransform();
const sources = parser.sources.sort((_a, _b) => {
const a = _a.internalPath;
const b = _b.internalPath;
if (a[0] == "~" && b[0] !== "~") {
return -1;
} else if (a[0] !== "~" && b[0] == "~") {
return 1;
} else {
return 0;
}
});
transformer.parser = parser;
for (const source of sources) {
transformer.imports = [];
transformer.currentSource = source;
transformer.visit(source);
if (transformer.newStmts.simd) {
const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.newStmts.simd.join("\n")));
parser.currentSource = tokenizer.source;
for (let i = 0; i < transformer.newStmts.simd.length; i++) source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
parser.currentSource = source;
transformer.newStmts.simd = [];
}
if (transformer.jsonImport) {
const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.jsonImport));
parser.currentSource = tokenizer.source;
source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
parser.currentSource = source;
transformer.jsonImport = null;
}
if (transformer.bsImport) {
const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.bsImport));
parser.currentSource = tokenizer.source;
source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
parser.currentSource = source;
transformer.bsImport = null;
}
afterParse(parser) {
const transformer = new JSONTransform();
const sources = parser.sources.sort((_a, _b) => {
const a = _a.internalPath;
const b = _b.internalPath;
if (a[0] == "~" && b[0] !== "~") {
return -1;
}
else if (a[0] !== "~" && b[0] == "~") {
return 1;
}
else {
return 0;
}
});
transformer.parser = parser;
for (const source of sources) {
transformer.imports = [];
transformer.currentSource = source;
transformer.visit(source);
if (transformer.newStmts.simd) {
const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.newStmts.simd.join("\n")));
parser.currentSource = tokenizer.source;
for (let i = 0; i < transformer.newStmts.simd.length; i++)
source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
parser.currentSource = source;
transformer.newStmts.simd = [];
}
if (transformer.jsonImport) {
const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.jsonImport));
parser.currentSource = tokenizer.source;
source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
parser.currentSource = source;
transformer.jsonImport = null;
}
if (transformer.bsImport) {
const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, transformer.bsImport));
parser.currentSource = tokenizer.source;
source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
parser.currentSource = source;
transformer.bsImport = null;
}
}
const schemas = transformer.schemas;
for (const schema of schemas) {
if (schema.parent) {
const parent = schemas.find((v) => v.name == schema.parent?.name);
if (!parent)
throwError(`Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator!`, schema.parent.node.range);
}
}
}
const schemas = transformer.schemas;
for (const schema of schemas) {
if (schema.parent) {
const parent = schemas.find((v) => v.name == schema.parent?.name);
if (!parent) throwError(`Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator!`, schema.parent.node.range);
}
}
}
}
function sortMembers(members) {
return members.sort((a, b) => {
const aMove = a.flags.has(PropertyFlags.OmitIf) || a.flags.has(PropertyFlags.OmitNull);
const bMove = b.flags.has(PropertyFlags.OmitIf) || b.flags.has(PropertyFlags.OmitNull);
if (aMove && !bMove) {
return -1;
} else if (!aMove && bMove) {
return 1;
} else {
return 0;
}
});
return members.sort((a, b) => {
const aMove = a.flags.has(PropertyFlags.OmitIf) || a.flags.has(PropertyFlags.OmitNull);
const bMove = b.flags.has(PropertyFlags.OmitIf) || b.flags.has(PropertyFlags.OmitNull);
if (aMove && !bMove) {
return -1;
}
else if (!aMove && bMove) {
return 1;
}
else {
return 0;
}
});
}
function getArgs(args) {
if (!args) return [];
let out = [];
for (const arg of args) {
if (arg instanceof StringLiteralExpression) {
out.push(arg.value);
} else if (arg instanceof IntegerLiteralExpression) {
out.push(i64_to_string(arg.value));
} else if (arg instanceof FloatLiteralExpression) {
out.push(arg.value.toString());
} else if (arg instanceof NullExpression) {
out.push(arg.text);
} else if (arg instanceof TrueExpression) {
out.push(arg.text);
} else if (arg instanceof FalseExpression) {
out.push(arg.text);
} else if (arg instanceof IdentifierExpression) {
out.push(arg.text);
if (!args)
return [];
let out = [];
for (const arg of args) {
if (arg instanceof StringLiteralExpression) {
out.push(arg.value);
}
else if (arg instanceof IntegerLiteralExpression) {
out.push(i64_to_string(arg.value));
}
else if (arg instanceof FloatLiteralExpression) {
out.push(arg.value.toString());
}
else if (arg instanceof NullExpression) {
out.push(arg.text);
}
else if (arg instanceof TrueExpression) {
out.push(arg.text);
}
else if (arg instanceof FalseExpression) {
out.push(arg.text);
}
else if (arg instanceof IdentifierExpression) {
out.push(arg.text);
}
}
}
return out;
return out;
}
function toU16(data, offset = 0) {
return data.charCodeAt(offset + 0).toString();
return data.charCodeAt(offset + 0).toString();
}
function toU32(data, offset = 0) {
return ((data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0)).toString();
return ((data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0)).toString();
}
function toU48(data, offset = 0) {
return ((BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0))).toString();
return ((BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0))).toString();
}
function toU64(data, offset = 0) {
return ((BigInt(data.charCodeAt(offset + 3)) << 48n) | (BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0))).toString();
return ((BigInt(data.charCodeAt(offset + 3)) << 48n) | (BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0))).toString();
}
function toMemCDecl(n, indent) {
let out = "";
let offset = 0;
let index = 0;
while (n >= 8) {
out += `${indent}const code${index++} = load<u64>(keyStart, ${offset});\n`;
offset += 8;
n -= 8;
}
while (n >= 4) {
out += `${indent}const code${index++} = load<u32>(keyStart, ${offset});\n`;
offset += 4;
n -= 4;
}
if (n == 1) out += `${indent}const code${index++} = load<u16>(keyStart, ${offset});\n`;
return out;
let out = "";
let offset = 0;
let index = 0;
while (n >= 8) {
out += `${indent}const code${index++} = load<u64>(keyStart, ${offset});\n`;
offset += 8;
n -= 8;
}
while (n >= 4) {
out += `${indent}const code${index++} = load<u32>(keyStart, ${offset});\n`;
offset += 4;
n -= 4;
}
if (n == 1)
out += `${indent}const code${index++} = load<u16>(keyStart, ${offset});\n`;
return out;
}
function toMemCCheck(data) {
let n = data.length << 1;
let out = "";
let offset = 0;
let index = 0;
while (n >= 8) {
out += ` && code${index++} == ${toU64(data, offset >> 1)}`;
offset += 8;
n -= 8;
}
while (n >= 4) {
out += ` && code${index++} == ${toU32(data, offset >> 1)}`;
offset += 4;
n -= 4;
}
if (n == 1) out += ` && code${index++} == ${toU16(data, offset >> 1)}`;
return out.slice(4);
let n = data.length << 1;
let out = "";
let offset = 0;
let index = 0;
while (n >= 8) {
out += ` && code${index++} == ${toU64(data, offset >> 1)}`;
offset += 8;
n -= 8;
}
while (n >= 4) {
out += ` && code${index++} == ${toU32(data, offset >> 1)}`;
offset += 4;
n -= 4;
}
if (n == 1)
out += ` && code${index++} == ${toU16(data, offset >> 1)}`;
return out.slice(4);
}
function strToNum(data, simd = false, offset = 0) {
const out = [];
let n = data.length;
while (n >= 8 && simd) {
out.push(["v128", "i16x8(" + data.charCodeAt(offset + 0) + ", " + data.charCodeAt(offset + 1) + ", " + data.charCodeAt(offset + 2) + ", " + data.charCodeAt(offset + 3) + ", " + data.charCodeAt(offset + 4) + ", " + data.charCodeAt(offset + 5) + ", " + data.charCodeAt(offset + 6) + ", " + data.charCodeAt(offset + 7) + ")"]);
offset += 8;
n -= 8;
}
while (n >= 4) {
const value = (BigInt(data.charCodeAt(offset + 3)) << 48n) | (BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0));
out.push(["u64", value.toString()]);
offset += 4;
n -= 4;
}
while (n >= 2) {
const value = (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0);
out.push(["u32", value.toString()]);
offset += 2;
n -= 2;
}
if (n === 1) {
const value = data.charCodeAt(offset + 0);
out.push(["u16", value.toString()]);
}
return out;
const out = [];
let n = data.length;
while (n >= 8 && simd) {
out.push(["v128", "i16x8(" + data.charCodeAt(offset + 0) + ", " + data.charCodeAt(offset + 1) + ", " + data.charCodeAt(offset + 2) + ", " + data.charCodeAt(offset + 3) + ", " + data.charCodeAt(offset + 4) + ", " + data.charCodeAt(offset + 5) + ", " + data.charCodeAt(offset + 6) + ", " + data.charCodeAt(offset + 7) + ")"]);
offset += 8;
n -= 8;
}
while (n >= 4) {
const value = (BigInt(data.charCodeAt(offset + 3)) << 48n) | (BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0));
out.push(["u64", value.toString()]);
offset += 4;
n -= 4;
}
while (n >= 2) {
const value = (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0);
out.push(["u32", value.toString()]);
offset += 2;
n -= 2;
}
if (n === 1) {
const value = data.charCodeAt(offset + 0);
out.push(["u16", value.toString()]);
}
return out;
}
function isPrimitive(type) {
const primitiveTypes = ["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "f32", "f64", "bool", "boolean"];
return primitiveTypes.some((v) => type.includes(v));
const primitiveTypes = ["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "f32", "f64", "bool", "boolean"];
return primitiveTypes.some((v) => type.includes(v));
}
function throwError(message, range) {
const err = new Error();
err.stack = `${message}\n at ${range.source.normalizedPath}:${range.source.lineAt(range.start)}:${range.source.columnAt()}\n`;
throw err;
const err = new Error();
err.stack = `${message}\n at ${range.source.normalizedPath}:${range.source.lineAt(range.start)}:${range.source.columnAt()}\n`;
throw err;
}
function indentInc() {
indent += " ";
indent += " ";
}
function indentDec() {
indent = indent.slice(0, Math.max(0, indent.length - 2));
indent = indent.slice(0, Math.max(0, indent.length - 2));
}
function sizeof(type) {
if (type == "u8") return 6;
else if (type == "i8") return 8;
else if (type == "u16") return 10;
else if (type == "i16") return 12;
else if (type == "u32") return 20;
else if (type == "i32") return 22;
else if (type == "u64") return 40;
else if (type == "i64") return 40;
else if (type == "bool" || type == "boolean") return 10;
else return 0;
if (type == "u8")
return 6;
else if (type == "i8")
return 8;
else if (type == "u16")
return 10;
else if (type == "i16")
return 12;
else if (type == "u32")
return 20;
else if (type == "i32")
return 22;
else if (type == "u64")
return 40;
else if (type == "i64")
return 40;
else if (type == "bool" || type == "boolean")
return 10;
else
return 0;
}
function allPrimitive(schema) {
return !schema.members.some((p) => p.byteSize == 0);
return !schema.members.some((p) => p.byteSize == 0);
}
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map
export function getImports(source) {
return source.statements.filter((v) => v.kind === 42);
return source.statements.filter((v) => v.kind === 42);
}
export function getImportedClass(name, source, parser) {
for (const stmt of getImports(source)) {
const externalSource = parser.sources.find((src) => src.internalPath === stmt.internalPath);
if (!externalSource) continue;
const classDeclaration = externalSource.statements.find((s) => s.kind === 51 && s.name.text === name);
if (classDeclaration) return classDeclaration;
}
return null;
for (const stmt of getImports(source)) {
const externalSource = parser.sources.find((src) => src.internalPath === stmt.internalPath);
if (!externalSource)
continue;
const classDeclaration = externalSource.statements.find((s) => s.kind === 51 && s.name.text === name);
if (classDeclaration)
return classDeclaration;
}
return null;
}
export function getClasses(source) {
return source.statements.filter((v) => v.kind === 51);
return source.statements.filter((v) => v.kind === 51);
}
//# sourceMappingURL=linker.js.map
//# sourceMappingURL=linker.js.map
export var PropertyFlags;
(function (PropertyFlags) {
PropertyFlags[(PropertyFlags["OmitNull"] = 0)] = "OmitNull";
PropertyFlags[(PropertyFlags["OmitIf"] = 1)] = "OmitIf";
PropertyFlags[(PropertyFlags["Raw"] = 2)] = "Raw";
PropertyFlags[PropertyFlags["OmitNull"] = 0] = "OmitNull";
PropertyFlags[PropertyFlags["OmitIf"] = 1] = "OmitIf";
PropertyFlags[PropertyFlags["Raw"] = 2] = "Raw";
})(PropertyFlags || (PropertyFlags = {}));
export class Property {
name = "";
alias = null;
type = "";
value = null;
flags = new Map();
node;
byteSize = 0;
name = "";
alias = null;
type = "";
value = null;
flags = new Map();
node;
byteSize = 0;
}
export class Schema {
static = true;
name = "";
members = [];
parent = null;
node;
needsLink = null;
byteSize = 0;
deps = [];
static = true;
name = "";
members = [];
parent = null;
node;
needsLink = null;
byteSize = 0;
deps = [];
}
//# sourceMappingURL=types.js.map
//# sourceMappingURL=types.js.map
import { Parser, Tokenizer, Source } from "assemblyscript/dist/assemblyscript.js";
import { ASTBuilder } from "./builder.js";
export class SimpleParser {
static get parser() {
return new Parser();
}
static getTokenizer(s, file = "index.ts") {
return new Tokenizer(new Source(0, file, s));
}
static parseExpression(s) {
const res = this.parser.parseExpression(this.getTokenizer(s));
if (res == null) {
throw new Error("Failed to parse the expression: '" + s + "'");
static get parser() {
return new Parser();
}
return res;
}
static parseStatement(s, topLevel = false) {
const res = this.parser.parseStatement(this.getTokenizer(s), topLevel);
if (res == null) {
throw new Error("Failed to parse the statement: '" + s + "'");
static getTokenizer(s, file = "index.ts") {
return new Tokenizer(new Source(0, file, s));
}
return res;
}
static parseTopLevelStatement(s, namespace) {
const res = this.parser.parseTopLevelStatement(this.getTokenizer(s), namespace);
if (res == null) {
throw new Error("Failed to parse the top level statement: '" + s + "'");
static parseExpression(s) {
const res = this.parser.parseExpression(this.getTokenizer(s));
if (res == null) {
throw new Error("Failed to parse the expression: '" + s + "'");
}
return res;
}
return res;
}
static parseClassMember(s, _class) {
let res = this.parser.parseClassMember(this.getTokenizer(s, _class.range.source.normalizedPath), _class);
if (res == null) {
throw new Error("Failed to parse the class member: '" + s + "'");
static parseStatement(s, topLevel = false) {
const res = this.parser.parseStatement(this.getTokenizer(s), topLevel);
if (res == null) {
throw new Error("Failed to parse the statement: '" + s + "'");
}
return res;
}
return res;
}
static parseTopLevelStatement(s, namespace) {
const res = this.parser.parseTopLevelStatement(this.getTokenizer(s), namespace);
if (res == null) {
throw new Error("Failed to parse the top level statement: '" + s + "'");
}
return res;
}
static parseClassMember(s, _class) {
let res = this.parser.parseClassMember(this.getTokenizer(s, _class.range.source.normalizedPath), _class);
if (res == null) {
throw new Error("Failed to parse the class member: '" + s + "'");
}
return res;
}
}
let isStdlibRegex = /\~lib\/(?:array|arraybuffer|atomics|builtins|crypto|console|compat|dataview|date|diagnostics|error|function|iterator|map|math|number|object|process|reference|regexp|set|staticarray|string|symbol|table|typedarray|vector|rt\/?|bindings\/|shared\/typeinfo)|util\/|uri|polyfills|memory/;
export function isStdlib(s) {
let source = s instanceof Source ? s : s.range.source;
return isStdlibRegex.test(source.internalPath);
let source = s instanceof Source ? s : s.range.source;
return isStdlibRegex.test(source.internalPath);
}
export function toString(node) {
return ASTBuilder.build(node);
return ASTBuilder.build(node);
}
//# sourceMappingURL=util.js.map
//# sourceMappingURL=util.js.map
export class Visitor {
currentSource = null;
visit(node, ref = null) {
if (node == null) return;
if (node instanceof Array) {
for (const n of node) {
this._visit(n, ref);
}
} else {
this._visit(node, ref);
currentSource = null;
visit(node, ref = null) {
if (node == null)
return;
if (node instanceof Array) {
for (const n of node) {
this._visit(n, ref);
}
}
else {
this._visit(node, ref);
}
}
}
_visit(node, ref) {
switch (node.kind) {
case 0:
this.visitSource(node, ref);
break;
case 1:
this.visitNamedTypeNode(node, ref);
break;
case 2:
this.visitFunctionTypeNode(node, ref);
break;
case 3:
this.visitTypeName(node, ref);
break;
case 4:
this.visitTypeParameter(node, ref);
break;
case 6:
this.visitIdentifierExpression(node, ref);
break;
case 7:
this.visitAssertionExpression(node, ref);
break;
case 8:
this.visitBinaryExpression(node, ref);
break;
case 9:
this.visitCallExpression(node, ref);
break;
case 10:
this.visitClassExpression(node, ref);
break;
case 11:
this.visitCommaExpression(node, ref);
break;
case 12:
this.visitElementAccessExpression(node, ref);
break;
case 14:
this.visitFunctionExpression(node, ref);
break;
case 15:
this.visitInstanceOfExpression(node, ref);
break;
case 16:
this.visitLiteralExpression(node, ref);
break;
case 17:
this.visitNewExpression(node, ref);
break;
case 20:
this.visitParenthesizedExpression(node, ref);
break;
case 21:
this.visitPropertyAccessExpression(node, ref);
break;
case 22:
this.visitTernaryExpression(node, ref);
break;
case 27:
this.visitUnaryPostfixExpression(node, ref);
break;
case 28:
this.visitUnaryPrefixExpression(node, ref);
break;
case 30:
this.visitBlockStatement(node, ref);
break;
case 31:
this.visitBreakStatement(node, ref);
break;
case 32:
this.visitContinueStatement(node, ref);
break;
case 33:
this.visitDoStatement(node, ref);
break;
case 34:
this.visitEmptyStatement(node, ref);
break;
case 35:
this.visitExportStatement(node, ref);
break;
case 36:
this.visitExportDefaultStatement(node, ref);
break;
case 37:
this.visitExportImportStatement(node, ref);
break;
case 38:
this.visitExpressionStatement(node, ref);
break;
case 39:
this.visitForStatement(node, ref);
break;
case 41:
this.visitIfStatement(node, ref);
break;
case 42:
this.visitImportStatement(node, ref);
break;
case 43:
this.visitReturnStatement(node, ref);
break;
case 44:
this.visitSwitchStatement(node, ref);
break;
case 45:
this.visitThrowStatement(node, ref);
break;
case 46:
this.visitTryStatement(node, ref);
break;
case 47:
this.visitVariableStatement(node, ref);
break;
case 49:
this.visitWhileStatement(node, ref);
break;
case 51:
this.visitClassDeclaration(node, false, ref);
break;
case 52:
this.visitEnumDeclaration(node, false, ref);
break;
case 53:
this.visitEnumValueDeclaration(node, ref);
break;
case 54:
this.visitFieldDeclaration(node, ref);
break;
case 55:
this.visitFunctionDeclaration(node, false, ref);
break;
case 56:
this.visitImportDeclaration(node, ref);
break;
case 57:
this.visitInterfaceDeclaration(node, false, ref);
break;
case 58:
this.visitMethodDeclaration(node, ref);
break;
case 59:
this.visitNamespaceDeclaration(node, false, ref);
break;
case 60:
this.visitTypeDeclaration(node, ref);
break;
case 61:
this.visitVariableDeclaration(node, ref);
break;
case 62:
this.visitDecoratorNode(node, ref);
break;
case 63:
this.visitExportMember(node, ref);
break;
case 64:
this.visitSwitchCase(node, ref);
break;
case 65:
this.visitIndexSignature(node, ref);
break;
case 18:
this.visitNullExpression(node, ref);
break;
case 25: {
this.visitTrueExpression(node, ref);
break;
}
case 13: {
this.visitFalseExpression(node, ref);
break;
}
case 29: {
this.visitCompiledExpression(node, ref);
break;
}
case 26: {
this.visitConstructorExpression(node, ref);
break;
}
case 66: {
this.visitComment(node, ref);
break;
}
case 40: {
this.visitForOfStatement(node, ref);
break;
}
case 50: {
this.visitModuleDeclaration(node, ref);
break;
}
case 19: {
this.visitOmittedExpression(node, ref);
break;
}
case 5: {
this.visitParameter(node, ref);
break;
}
case 23: {
this.visitSuperExpression(node, ref);
break;
}
case 24: {
this.visitThisExpression(node, ref);
break;
}
case 48: {
this.visitVoidStatement(node, ref);
break;
}
default:
throw new Error("Could not visit invalid type!");
_visit(node, ref) {
switch (node.kind) {
case 0:
this.visitSource(node, ref);
break;
case 1:
this.visitNamedTypeNode(node, ref);
break;
case 2:
this.visitFunctionTypeNode(node, ref);
break;
case 3:
this.visitTypeName(node, ref);
break;
case 4:
this.visitTypeParameter(node, ref);
break;
case 6:
this.visitIdentifierExpression(node, ref);
break;
case 7:
this.visitAssertionExpression(node, ref);
break;
case 8:
this.visitBinaryExpression(node, ref);
break;
case 9:
this.visitCallExpression(node, ref);
break;
case 10:
this.visitClassExpression(node, ref);
break;
case 11:
this.visitCommaExpression(node, ref);
break;
case 12:
this.visitElementAccessExpression(node, ref);
break;
case 14:
this.visitFunctionExpression(node, ref);
break;
case 15:
this.visitInstanceOfExpression(node, ref);
break;
case 16:
this.visitLiteralExpression(node, ref);
break;
case 17:
this.visitNewExpression(node, ref);
break;
case 20:
this.visitParenthesizedExpression(node, ref);
break;
case 21:
this.visitPropertyAccessExpression(node, ref);
break;
case 22:
this.visitTernaryExpression(node, ref);
break;
case 27:
this.visitUnaryPostfixExpression(node, ref);
break;
case 28:
this.visitUnaryPrefixExpression(node, ref);
break;
case 30:
this.visitBlockStatement(node, ref);
break;
case 31:
this.visitBreakStatement(node, ref);
break;
case 32:
this.visitContinueStatement(node, ref);
break;
case 33:
this.visitDoStatement(node, ref);
break;
case 34:
this.visitEmptyStatement(node, ref);
break;
case 35:
this.visitExportStatement(node, ref);
break;
case 36:
this.visitExportDefaultStatement(node, ref);
break;
case 37:
this.visitExportImportStatement(node, ref);
break;
case 38:
this.visitExpressionStatement(node, ref);
break;
case 39:
this.visitForStatement(node, ref);
break;
case 41:
this.visitIfStatement(node, ref);
break;
case 42:
this.visitImportStatement(node, ref);
break;
case 43:
this.visitReturnStatement(node, ref);
break;
case 44:
this.visitSwitchStatement(node, ref);
break;
case 45:
this.visitThrowStatement(node, ref);
break;
case 46:
this.visitTryStatement(node, ref);
break;
case 47:
this.visitVariableStatement(node, ref);
break;
case 49:
this.visitWhileStatement(node, ref);
break;
case 51:
this.visitClassDeclaration(node, false, ref);
break;
case 52:
this.visitEnumDeclaration(node, false, ref);
break;
case 53:
this.visitEnumValueDeclaration(node, ref);
break;
case 54:
this.visitFieldDeclaration(node, ref);
break;
case 55:
this.visitFunctionDeclaration(node, false, ref);
break;
case 56:
this.visitImportDeclaration(node, ref);
break;
case 57:
this.visitInterfaceDeclaration(node, false, ref);
break;
case 58:
this.visitMethodDeclaration(node, ref);
break;
case 59:
this.visitNamespaceDeclaration(node, false, ref);
break;
case 60:
this.visitTypeDeclaration(node, ref);
break;
case 61:
this.visitVariableDeclaration(node, ref);
break;
case 62:
this.visitDecoratorNode(node, ref);
break;
case 63:
this.visitExportMember(node, ref);
break;
case 64:
this.visitSwitchCase(node, ref);
break;
case 65:
this.visitIndexSignature(node, ref);
break;
case 18:
this.visitNullExpression(node, ref);
break;
case 25: {
this.visitTrueExpression(node, ref);
break;
}
case 13: {
this.visitFalseExpression(node, ref);
break;
}
case 29: {
this.visitCompiledExpression(node, ref);
break;
}
case 26: {
this.visitConstructorExpression(node, ref);
break;
}
case 66: {
this.visitComment(node, ref);
break;
}
case 40: {
this.visitForOfStatement(node, ref);
break;
}
case 50: {
this.visitModuleDeclaration(node, ref);
break;
}
case 19: {
this.visitOmittedExpression(node, ref);
break;
}
case 5: {
this.visitParameter(node, ref);
break;
}
case 23: {
this.visitSuperExpression(node, ref);
break;
}
case 24: {
this.visitThisExpression(node, ref);
break;
}
case 48: {
this.visitVoidStatement(node, ref);
break;
}
default:
throw new Error("Could not visit invalid type!");
}
}
}
visitSource(node, ref = null) {
this.currentSource = node;
this.visit(node.statements, node);
this.currentSource = null;
}
visitTypeNode(node, ref = null) {}
visitTypeName(node, ref = null) {
this.visit(node.identifier, node);
this.visit(node.next, node);
}
visitNamedTypeNode(node, ref = null) {
this.visit(node.name, node);
this.visit(node.typeArguments, node);
}
visitFunctionTypeNode(node, ref = null) {
this.visit(node.parameters, node);
this.visit(node.returnType, node);
this.visit(node.explicitThisType, node);
}
visitTypeParameter(node, ref = null) {
this.visit(node.name, node);
this.visit(node.extendsType, node);
this.visit(node.defaultType, node);
}
visitIdentifierExpression(node, ref = null) {}
visitArrayLiteralExpression(node, ref = null) {
this.visit(node.elementExpressions, node);
}
visitObjectLiteralExpression(node, ref = null) {
this.visit(node.names, node);
this.visit(node.values, node);
}
visitAssertionExpression(node, ref = null) {
this.visit(node.toType, node);
this.visit(node.expression, node);
}
visitBinaryExpression(node, ref = null) {
this.visit(node.left, node);
this.visit(node.right, node);
}
visitCallExpression(node, ref = null) {
this.visit(node.expression, node);
this.visit(node.typeArguments, node);
this.visit(node.args, node);
}
visitClassExpression(node, ref = null) {
this.visit(node.declaration, node);
}
visitCommaExpression(node, ref = null) {
this.visit(node.expressions, node);
}
visitElementAccessExpression(node, ref = null) {
this.visit(node.elementExpression, node);
this.visit(node.expression, node);
}
visitFunctionExpression(node, ref = null) {
this.visit(node.declaration, node);
}
visitLiteralExpression(node, ref = null) {
switch (node.literalKind) {
case 0:
this.visitFloatLiteralExpression(node);
break;
case 1:
this.visitIntegerLiteralExpression(node);
break;
case 2:
this.visitStringLiteralExpression(node);
break;
case 3:
this.visitTemplateLiteralExpression(node);
break;
case 4:
this.visitRegexpLiteralExpression(node);
break;
case 5:
this.visitArrayLiteralExpression(node);
break;
case 6:
this.visitObjectLiteralExpression(node);
break;
default:
throw new Error("Invalid LiteralKind at visitLiteralExpression(): " + node.literalKind);
visitSource(node, ref = null) {
this.currentSource = node;
this.visit(node.statements, node);
this.currentSource = null;
}
}
visitFloatLiteralExpression(node, ref = null) {}
visitInstanceOfExpression(node, ref = null) {
this.visit(node.expression, node);
this.visit(node.isType, node);
}
visitIntegerLiteralExpression(node, ref = null) {}
visitStringLiteralExpression(node, ref = null) {}
visitTemplateLiteralExpression(node, ref = null) {}
visitRegexpLiteralExpression(node, ref = null) {}
visitNewExpression(node, ref = null) {
this.visit(node.typeName, node);
this.visit(node.typeArguments, node);
this.visit(node.args, node);
}
visitParenthesizedExpression(node, ref = null) {
this.visit(node.expression, node);
}
visitPropertyAccessExpression(node, ref = null) {
this.visit(node.property, node);
this.visit(node.expression, node);
}
visitTernaryExpression(node, ref = null) {
this.visit(node.condition, node);
this.visit(node.ifThen, node);
this.visit(node.ifElse, node);
}
visitUnaryExpression(node, ref = null) {
this.visit(node.operand, node);
}
visitUnaryPostfixExpression(node, ref = null) {
this.visit(node.operand, node);
}
visitUnaryPrefixExpression(node, ref = null) {
this.visit(node.operand, node);
}
visitSuperExpression(node, ref = null) {}
visitFalseExpression(node, ref = null) {}
visitTrueExpression(node, ref = null) {}
visitThisExpression(node, ref = null) {}
visitNullExpression(node, ref = null) {}
visitConstructorExpression(node, ref = null) {}
visitNodeAndTerminate(statement, ref = null) {}
visitBlockStatement(node, ref = null) {
this.visit(node.statements, node);
}
visitBreakStatement(node, ref = null) {
this.visit(node.label, node);
}
visitContinueStatement(node, ref = null) {
this.visit(node.label, node);
}
visitClassDeclaration(node, isDefault = false, ref = null) {
this.visit(node.name, node);
this.visit(node.decorators, node);
if (node.isGeneric ? node.typeParameters != null : node.typeParameters == null) {
this.visit(node.typeParameters, node);
this.visit(node.extendsType, node);
this.visit(node.implementsTypes, node);
this.visit(node.members, node);
} else {
throw new Error("Expected to type parameters to match class declaration, but found type mismatch instead!");
visitTypeNode(node, ref = null) { }
visitTypeName(node, ref = null) {
this.visit(node.identifier, node);
this.visit(node.next, node);
}
}
visitDoStatement(node, ref = null) {
this.visit(node.condition, node);
this.visit(node.body, node);
}
visitEmptyStatement(node, ref = null) {}
visitEnumDeclaration(node, isDefault = false, ref = null) {
this.visit(node.name, node);
this.visit(node.decorators, node);
this.visit(node.values, node);
}
visitEnumValueDeclaration(node, ref = null) {
this.visit(node.name, node);
this.visit(node.initializer, node);
}
visitExportImportStatement(node, ref = null) {
this.visit(node.name, node);
this.visit(node.externalName, node);
}
visitExportMember(node, ref = null) {
this.visit(node.localName, node);
this.visit(node.exportedName, node);
}
visitExportStatement(node, ref = null) {
this.visit(node.path, node);
this.visit(node.members, node);
}
visitExportDefaultStatement(node, ref = null) {
this.visit(node.declaration, node);
}
visitExpressionStatement(node, ref = null) {
this.visit(node.expression, ref);
}
visitFieldDeclaration(node, ref = null) {
this.visit(node.name, node);
this.visit(node.type, node);
this.visit(node.initializer, node);
this.visit(node.decorators, node);
}
visitForStatement(node, ref = null) {
this.visit(node.initializer, node);
this.visit(node.condition, node);
this.visit(node.incrementor, node);
this.visit(node.body, node);
}
visitFunctionDeclaration(node, isDefault = false, ref = null) {
this.visit(node.name, node);
this.visit(node.decorators, node);
this.visit(node.typeParameters, node);
this.visit(node.signature, node);
this.visit(node.body, node);
}
visitIfStatement(node, ref = null) {
this.visit(node.condition, node);
this.visit(node.ifTrue, node);
this.visit(node.ifFalse, node);
}
visitImportDeclaration(node, ref = null) {
this.visit(node.foreignName, node);
this.visit(node.name, node);
this.visit(node.decorators, node);
}
visitImportStatement(node, ref = null) {
this.visit(node.namespaceName, node);
this.visit(node.declarations, node);
}
visitIndexSignature(node, ref = null) {
this.visit(node.keyType, node);
this.visit(node.valueType, node);
}
visitInterfaceDeclaration(node, isDefault = false, ref = null) {
this.visit(node.name, node);
this.visit(node.typeParameters, node);
this.visit(node.implementsTypes, node);
this.visit(node.extendsType, node);
this.visit(node.members, node);
}
visitMethodDeclaration(node, ref = null) {
this.visit(node.name, node);
this.visit(node.typeParameters, node);
this.visit(node.signature, node);
this.visit(node.decorators, node);
this.visit(node.body, node);
}
visitNamespaceDeclaration(node, isDefault = false, ref = null) {
this.visit(node.name, node);
this.visit(node.decorators, node);
this.visit(node.members, node);
}
visitReturnStatement(node, ref = null) {
this.visit(node.value, node);
}
visitSwitchCase(node, ref = null) {
this.visit(node.label, node);
this.visit(node.statements, node);
}
visitSwitchStatement(node, ref = null) {
this.visit(node.condition, node);
this.visit(node.cases, node);
}
visitThrowStatement(node, ref = null) {
this.visit(node.value, node);
}
visitTryStatement(node, ref = null) {
this.visit(node.bodyStatements, node);
this.visit(node.catchVariable, node);
this.visit(node.catchStatements, node);
this.visit(node.finallyStatements, node);
}
visitTypeDeclaration(node, ref = null) {
this.visit(node.name, node);
this.visit(node.decorators, node);
this.visit(node.type, node);
this.visit(node.typeParameters, node);
}
visitVariableDeclaration(node, ref = null) {
this.visit(node.name, node);
this.visit(node.type, node);
this.visit(node.initializer, node);
}
visitVariableStatement(node, ref = null) {
this.visit(node.decorators, node);
this.visit(node.declarations, node);
}
visitWhileStatement(node, ref = null) {
this.visit(node.condition, node);
this.visit(node.body, node);
}
visitVoidStatement(node, ref = null) {}
visitComment(node, ref = null) {}
visitDecoratorNode(node, ref = null) {
this.visit(node.name, node);
this.visit(node.args, node);
}
visitParameter(node, ref = null) {
this.visit(node.name, node);
this.visit(node.implicitFieldDeclaration, node);
this.visit(node.initializer, node);
this.visit(node.type, node);
}
visitCompiledExpression(node, ref = null) {}
visitForOfStatement(node, ref = null) {
this.visit(node.body, node);
this.visit(node.variable, node);
this.visit(node.iterable, node);
}
visitModuleDeclaration(node, ref = null) {}
visitOmittedExpression(node, ref = null) {}
visitNamedTypeNode(node, ref = null) {
this.visit(node.name, node);
this.visit(node.typeArguments, node);
}
visitFunctionTypeNode(node, ref = null) {
this.visit(node.parameters, node);
this.visit(node.returnType, node);
this.visit(node.explicitThisType, node);
}
visitTypeParameter(node, ref = null) {
this.visit(node.name, node);
this.visit(node.extendsType, node);
this.visit(node.defaultType, node);
}
visitIdentifierExpression(node, ref = null) { }
visitArrayLiteralExpression(node, ref = null) {
this.visit(node.elementExpressions, node);
}
visitObjectLiteralExpression(node, ref = null) {
this.visit(node.names, node);
this.visit(node.values, node);
}
visitAssertionExpression(node, ref = null) {
this.visit(node.toType, node);
this.visit(node.expression, node);
}
visitBinaryExpression(node, ref = null) {
this.visit(node.left, node);
this.visit(node.right, node);
}
visitCallExpression(node, ref = null) {
this.visit(node.expression, node);
this.visit(node.typeArguments, node);
this.visit(node.args, node);
}
visitClassExpression(node, ref = null) {
this.visit(node.declaration, node);
}
visitCommaExpression(node, ref = null) {
this.visit(node.expressions, node);
}
visitElementAccessExpression(node, ref = null) {
this.visit(node.elementExpression, node);
this.visit(node.expression, node);
}
visitFunctionExpression(node, ref = null) {
this.visit(node.declaration, node);
}
visitLiteralExpression(node, ref = null) {
switch (node.literalKind) {
case 0:
this.visitFloatLiteralExpression(node);
break;
case 1:
this.visitIntegerLiteralExpression(node);
break;
case 2:
this.visitStringLiteralExpression(node);
break;
case 3:
this.visitTemplateLiteralExpression(node);
break;
case 4:
this.visitRegexpLiteralExpression(node);
break;
case 5:
this.visitArrayLiteralExpression(node);
break;
case 6:
this.visitObjectLiteralExpression(node);
break;
default:
throw new Error("Invalid LiteralKind at visitLiteralExpression(): " + node.literalKind);
}
}
visitFloatLiteralExpression(node, ref = null) { }
visitInstanceOfExpression(node, ref = null) {
this.visit(node.expression, node);
this.visit(node.isType, node);
}
visitIntegerLiteralExpression(node, ref = null) { }
visitStringLiteralExpression(node, ref = null) { }
visitTemplateLiteralExpression(node, ref = null) { }
visitRegexpLiteralExpression(node, ref = null) { }
visitNewExpression(node, ref = null) {
this.visit(node.typeName, node);
this.visit(node.typeArguments, node);
this.visit(node.args, node);
}
visitParenthesizedExpression(node, ref = null) {
this.visit(node.expression, node);
}
visitPropertyAccessExpression(node, ref = null) {
this.visit(node.property, node);
this.visit(node.expression, node);
}
visitTernaryExpression(node, ref = null) {
this.visit(node.condition, node);
this.visit(node.ifThen, node);
this.visit(node.ifElse, node);
}
visitUnaryExpression(node, ref = null) {
this.visit(node.operand, node);
}
visitUnaryPostfixExpression(node, ref = null) {
this.visit(node.operand, node);
}
visitUnaryPrefixExpression(node, ref = null) {
this.visit(node.operand, node);
}
visitSuperExpression(node, ref = null) { }
visitFalseExpression(node, ref = null) { }
visitTrueExpression(node, ref = null) { }
visitThisExpression(node, ref = null) { }
visitNullExpression(node, ref = null) { }
visitConstructorExpression(node, ref = null) { }
visitNodeAndTerminate(statement, ref = null) { }
visitBlockStatement(node, ref = null) {
this.visit(node.statements, node);
}
visitBreakStatement(node, ref = null) {
this.visit(node.label, node);
}
visitContinueStatement(node, ref = null) {
this.visit(node.label, node);
}
visitClassDeclaration(node, isDefault = false, ref = null) {
this.visit(node.name, node);
this.visit(node.decorators, node);
if (node.isGeneric ? node.typeParameters != null : node.typeParameters == null) {
this.visit(node.typeParameters, node);
this.visit(node.extendsType, node);
this.visit(node.implementsTypes, node);
this.visit(node.members, node);
}
else {
throw new Error("Expected to type parameters to match class declaration, but found type mismatch instead!");
}
}
visitDoStatement(node, ref = null) {
this.visit(node.condition, node);
this.visit(node.body, node);
}
visitEmptyStatement(node, ref = null) { }
visitEnumDeclaration(node, isDefault = false, ref = null) {
this.visit(node.name, node);
this.visit(node.decorators, node);
this.visit(node.values, node);
}
visitEnumValueDeclaration(node, ref = null) {
this.visit(node.name, node);
this.visit(node.initializer, node);
}
visitExportImportStatement(node, ref = null) {
this.visit(node.name, node);
this.visit(node.externalName, node);
}
visitExportMember(node, ref = null) {
this.visit(node.localName, node);
this.visit(node.exportedName, node);
}
visitExportStatement(node, ref = null) {
this.visit(node.path, node);
this.visit(node.members, node);
}
visitExportDefaultStatement(node, ref = null) {
this.visit(node.declaration, node);
}
visitExpressionStatement(node, ref = null) {
this.visit(node.expression, ref);
}
visitFieldDeclaration(node, ref = null) {
this.visit(node.name, node);
this.visit(node.type, node);
this.visit(node.initializer, node);
this.visit(node.decorators, node);
}
visitForStatement(node, ref = null) {
this.visit(node.initializer, node);
this.visit(node.condition, node);
this.visit(node.incrementor, node);
this.visit(node.body, node);
}
visitFunctionDeclaration(node, isDefault = false, ref = null) {
this.visit(node.name, node);
this.visit(node.decorators, node);
this.visit(node.typeParameters, node);
this.visit(node.signature, node);
this.visit(node.body, node);
}
visitIfStatement(node, ref = null) {
this.visit(node.condition, node);
this.visit(node.ifTrue, node);
this.visit(node.ifFalse, node);
}
visitImportDeclaration(node, ref = null) {
this.visit(node.foreignName, node);
this.visit(node.name, node);
this.visit(node.decorators, node);
}
visitImportStatement(node, ref = null) {
this.visit(node.namespaceName, node);
this.visit(node.declarations, node);
}
visitIndexSignature(node, ref = null) {
this.visit(node.keyType, node);
this.visit(node.valueType, node);
}
visitInterfaceDeclaration(node, isDefault = false, ref = null) {
this.visit(node.name, node);
this.visit(node.typeParameters, node);
this.visit(node.implementsTypes, node);
this.visit(node.extendsType, node);
this.visit(node.members, node);
}
visitMethodDeclaration(node, ref = null) {
this.visit(node.name, node);
this.visit(node.typeParameters, node);
this.visit(node.signature, node);
this.visit(node.decorators, node);
this.visit(node.body, node);
}
visitNamespaceDeclaration(node, isDefault = false, ref = null) {
this.visit(node.name, node);
this.visit(node.decorators, node);
this.visit(node.members, node);
}
visitReturnStatement(node, ref = null) {
this.visit(node.value, node);
}
visitSwitchCase(node, ref = null) {
this.visit(node.label, node);
this.visit(node.statements, node);
}
visitSwitchStatement(node, ref = null) {
this.visit(node.condition, node);
this.visit(node.cases, node);
}
visitThrowStatement(node, ref = null) {
this.visit(node.value, node);
}
visitTryStatement(node, ref = null) {
this.visit(node.bodyStatements, node);
this.visit(node.catchVariable, node);
this.visit(node.catchStatements, node);
this.visit(node.finallyStatements, node);
}
visitTypeDeclaration(node, ref = null) {
this.visit(node.name, node);
this.visit(node.decorators, node);
this.visit(node.type, node);
this.visit(node.typeParameters, node);
}
visitVariableDeclaration(node, ref = null) {
this.visit(node.name, node);
this.visit(node.type, node);
this.visit(node.initializer, node);
}
visitVariableStatement(node, ref = null) {
this.visit(node.decorators, node);
this.visit(node.declarations, node);
}
visitWhileStatement(node, ref = null) {
this.visit(node.condition, node);
this.visit(node.body, node);
}
visitVoidStatement(node, ref = null) { }
visitComment(node, ref = null) { }
visitDecoratorNode(node, ref = null) {
this.visit(node.name, node);
this.visit(node.args, node);
}
visitParameter(node, ref = null) {
this.visit(node.name, node);
this.visit(node.implicitFieldDeclaration, node);
this.visit(node.initializer, node);
this.visit(node.type, node);
}
visitCompiledExpression(node, ref = null) { }
visitForOfStatement(node, ref = null) {
this.visit(node.body, node);
this.visit(node.variable, node);
this.visit(node.iterable, node);
}
visitModuleDeclaration(node, ref = null) { }
visitOmittedExpression(node, ref = null) { }
}
//# sourceMappingURL=visitor.js.map
//# sourceMappingURL=visitor.js.map

@@ -141,3 +141,2 @@ import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, Expression, CommonFlags, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, CallExpression, ImportStatement, NamespaceDeclaration, Node, Statement, Tokenizer, SourceKind, PropertyAccessExpression, Token, CommentHandler, ExpressionStatement, BinaryExpression, NamedTypeNode, Range, FEATURE_SIMD, FunctionExpression } from "assemblyscript/dist/assemblyscript.js";

let DESERIALIZE = "__DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n switch (<u32>keyEnd - <u32>keyStart) {\n";
let ALLOCATE = "@inline __ALLOCATE(): void {\n";

@@ -228,2 +227,9 @@ indent = " ";

// @ts-ignore: type
arg.declaration.signature.parameters[0].type = Node.createNamedType(
Node.createSimpleTypeName("this", node.range),
null,
false,
node.range
);
// @ts-ignore: type
arg.declaration.signature.returnType.name = Node.createSimpleTypeName("boolean", arg.declaration.signature.returnType.name.range);

@@ -277,3 +283,4 @@ SERIALIZE += indent + `if (!(${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;

else if (memberLen == 4) DESERIALIZE += `${indent}switch (load<u32>(keyStart)) {\n`;
else if (memberLen == 6) DESERIALIZE += `${indent}let code = (<u64>load<u32>(keyStart) << 16) | <u64>load<u16>(keyStart, 4);\n`;
else if (memberLen == 6) DESERIALIZE += `${indent}let code = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n`;
else if (memberLen == 6) DESERIALIZE += `${indent}let code = load<u64>(keyStart);\n`;
else DESERIALIZE += toMemCDecl(memberLen, indent);

@@ -283,5 +290,6 @@ for (let i = 0; i < memberGroup.length; i++) {

const memberName = member.alias || member.name;
const dst = this.schemas.find(v => v.name == member.type) ? "ptr + offsetof<this>(\"" + member.name + "\") + 12" : "0";
if (memberLen == 2) {
DESERIALIZE += `${indent} case ${memberName.charCodeAt(0)}: { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;

@@ -291,3 +299,3 @@ DESERIALIZE += `${indent} }\n`;

DESERIALIZE += `${indent} case ${toU32(memberName)}: { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;

@@ -298,9 +306,15 @@ DESERIALIZE += `${indent} }\n`;

DESERIALIZE += `if (code == ${toU48(memberName)}) { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
} else if (memberLen == 8) {
DESERIALIZE += i == 0 ? indent : "";
DESERIALIZE += `if (code == ${toU64(memberName)}) { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;
DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;
} else {
DESERIALIZE += i == 0 ? indent : "";
DESERIALIZE += `if (${toMemCCheck(memberName)}) { // ${memberName}\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} store<${member.type}>(ptr, JSON.__deserialize<${member.type}>(valStart, valEnd, ${dst}), offsetof<this>(${JSON.stringify(member.name)}));\n`;
DESERIALIZE += `${indent} return;\n`;

@@ -330,4 +344,3 @@ DESERIALIZE += `${indent}}${i < memberGroup.length - 1 ? " else " : "\n"}`;

ALLOCATE += indent + "bs.proposeSize(" + this.schema.byteSize + ");\n";
ALLOCATE += "}";
SERIALIZE = SERIALIZE.slice(0, 32) + indent + "bs.proposeSize(" + this.schema.byteSize + ");\n" + SERIALIZE.slice(32);

@@ -341,3 +354,2 @@ INITIALIZE += " return this;\n";

console.log(DESERIALIZE);
console.log(ALLOCATE);
}

@@ -348,3 +360,2 @@

const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
const ALLOCATE_METHOD = SimpleParser.parseClassMember(ALLOCATE, node);

@@ -354,3 +365,2 @@ if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_METHOD);

if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD);
if (!node.members.find((v) => v.name.text == "__ALLOCATE")) node.members.push(ALLOCATE_METHOD);
super.visitClassDeclaration(node);

@@ -360,6 +370,5 @@ }

let SERIALIZE_RAW_EMPTY = '@inline __SERIALIZE(ptr: usize = changetype<usize>(this)): string {\n return "{}";\n}';
let SERIALIZE_BS_EMPTY = "@inline __SERIALIZE(ptr: usize: bool): void {\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
let SERIALIZE_BS_EMPTY = "@inline __SERIALIZE(ptr: usize: bool): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
let INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
let DESERIALIZE_EMPTY = "@inline __DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {\n return false;\n}";
let ALLOCATE_EMPTY = "@inline __ALLOCATE(): void {\n bs.ensureSize(4);\n}";

@@ -371,3 +380,2 @@ if (process.env["JSON_DEBUG"]) {

console.log(DESERIALIZE_EMPTY);
console.log(ALLOCATE_EMPTY);
}

@@ -379,3 +387,2 @@

const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
const ALLOCATE_METHOD_EMPTY = SimpleParser.parseClassMember(ALLOCATE_EMPTY, node);

@@ -386,3 +393,2 @@ if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_RAW_METHOD_EMPTY);

if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD_EMPTY);
if (!node.members.find((v) => v.name.text == "__ALLOCATE")) node.members.push(ALLOCATE_METHOD_EMPTY);
}

@@ -389,0 +395,0 @@ // visitCallExpression(node: CallExpression, ref: Node): void {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet