diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 6557ee2..deef080 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -19,5 +19,8 @@ jobs: - name: Install Dependencies run: bun install + - name: Build Tests + run: bun run pretest + - name: Run Tests run: bun run test diff --git a/.gitignore b/.gitignore index 447ac79..6e79218 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,13 @@ -node_modules -*.lock -pnpm-lock.yaml -package-lock.json -.vscode -logs -as-tral -*.lockb -.vscode/ +# Package Manager +node_modules +*.lock +pnpm-lock.yaml +package-lock.json +*.lockb + +# IDE Files +.vscode/ + +# Build Artifacts +as-tral/ build/ \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json index ee7eae4..dfc8386 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,7 +1,4 @@ { - "pluginSearchDirs": ["node_modules"], - "plugins": ["assemblyscript-prettier"], "singleQuote": false, - "printWidth": 65536, - "tabWidth": 2 + "printWidth": 65536 } diff --git a/CHANGELOG b/CHANGELOG index a8c5e29..4530aae 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,45 +1,11 @@ -v0.8.2 - Properties starting with `static` or `private` would be ignored -v0.8.3 - Dirty fix to issue #68. Add __JSON_Stringify callable to global scope. -v0.8.4 - Fix #71. Classes with the extending class overriding a property cause the property to be serialized twice. -v0.8.5 - Fix #73. Support for nullable primatives with Box from as-container -v0.8.6 - Fix. Forgot to stash before publishing. Stash and push what should have been v0.8.5 +# Change Log -v0.9.0 - BREAKING CHANGE - API changed from JSON.parse(data, defaultValues) to JSON.parse(data). Default Values defaults to true. Large update. Refactor all the code, nullable primitives, rewrite the transform, allow extensibility with @omit keywords, and fix a plethora of bugs -v0.9.1 - Fix #71 -v0.9.2 - Fix #75 + Build sizes significantly reduced -v0.9.3 - Fix #76 -v0.9.4 - Fix #77 -v0.9.5 - Fix #46 -v0.9.6 - Fix bugs -v0.9.7 - Update testing framework and readme logo -v0.9.8 - Update dependencies -v0.9.8a - Fix #80 - Empty Maps were not serialized to {}, instead, threw memory out of bounds -v0.9.8b - Fix #81 - Revert transform -v0.9.9 - Fix #82 - Initialize maps -v0.9.9a - Remove extraneous logs from transform -v0.9.10 - Fix transform type checks. switch to nodekind checks -v0.9.11 - Remove MpZ--implement custom serializers and deserializers in the works -v0.9.12 - Add compat with aspect -v0.9.13 - Fix empty strings not indexing correctly -v0.9.14 - Ignore properties of type Function -v0.9.15 - Support JSON.Raw blocks -v0.9.16 - JSON.Raw should be completely untouched -v0.9.17 - A schema's parent's fields should be included properly -v0.9.18 - Should be able to use @alias and @omit*** or JSON.Raw -v0.9.19 - Fix arguments in @omitif declarations not working properly -v0.9.20 - Strings were being received with quotes attached via the toString functionality. Removed that. -v0.9.22 - Fix #89 and #93. Several bug fixes some severe such as ",null" being prepended when using @omit. Properly warn when a schema has fields that are not compatible with json -v0.9.23 - Comment out SIMD-related code for now -v0.9.24 - Remove transform changes from previous release -v0.9.25 - Implement JSON.parseSafe -v0.9.26 - Remove unnecessary dependencies +## UNRELEASED -[UNRELEASED] v1.0.0 - - Allow nullable primitives - - Port over JSON.Value - - Performance improvements - - Add SIMD support - - Introduce options - - Custom serializers - - Support arbitrary-length integers (@hypercubed/as-mpz) - - Remove as-container (Box) \ No newline at end of file +- fix: allow plain `null` values during serialization [#700](https://github.com/hypermodeinc/modus/pull/700) + +- fix: resolve warning in `deserializeRawMap` [#692](https://github.com/hypermodeinc/modus/pull/692) +- fix: add json serialization support for neo4j sdk types + [#699](https://github.com/hypermodeinc/modus/pull/699) + +## 2025-01-09 - CLI 0.16.6 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3927fb2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,35 @@ +v0.8.2 - Properties starting with `static` or `private` would be ignored +v0.8.3 - Dirty fix to issue #68. Add __JSON_Stringify callable to global scope. +v0.8.4 - Fix #71. Classes with the extending class overriding a property cause the property to be serialized twice. +v0.8.5 - Fix #73. Support for nullable primatives with Box from as-container +v0.8.6 - Fix. Forgot to stash before publishing. Stash and push what should have been v0.8.5 + +v0.9.0 - BREAKING CHANGE - API changed from JSON.parse(data, defaultValues) to JSON.parse(data). Default Values defaults to true. Large update. Refactor all the code, nullable primitives, rewrite the transform, allow extensibility with @omit keywords, and fix a plethora of bugs +v0.9.1 - Fix #71 +v0.9.2 - Fix #75 + Build sizes significantly reduced +v0.9.3 - Fix #76 +v0.9.4 - Fix #77 +v0.9.5 - Fix #46 +v0.9.6 - Fix bugs +v0.9.7 - Update testing framework and readme logo +v0.9.8 - Update dependencies +v0.9.8a - Fix #80 - Empty Maps were not serialized to {}, instead, threw memory out of bounds +v0.9.8b - Fix #81 - Revert transform +v0.9.9 - Fix #82 - Initialize maps +v0.9.9a - Remove extraneous logs from transform +v0.9.10 - Fix transform type checks. switch to nodekind checks +v0.9.11 - Remove MpZ--implement custom serializers and deserializers in the works +v0.9.12 - Add compat with aspect +v0.9.13 - Fix empty strings not indexing correctly +v0.9.14 - Ignore properties of type Function +v0.9.15 - Support JSON.Raw blocks +v0.9.16 - JSON.Raw should be completely untouched +v0.9.17 - A schema's parent's fields should be included properly +v0.9.18 - Should be able to use @alias and @omit*** or JSON.Raw +v0.9.19 - Fix arguments in @omitif declarations not working properly +v0.9.20 - Strings were being received with quotes attached via the toString functionality. Removed that. +v0.9.22 - Fix #89 and #93. Several bug fixes some severe such as ",null" being prepended when using @omit. Properly warn when a schema has fields that are not compatible with json +v0.9.23 - Comment out SIMD-related code for now +v0.9.24 - Remove transform changes from previous release +v0.9.25 - Implement JSON.parseSafe +v0.9.26 - Remove unnecessary dependencies \ No newline at end of file diff --git a/LICENSE b/LICENSE index 8bd0283..8b6e361 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 Jairus Tanaka +Copyright (c) 2023 Jairus Tanaka Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 218cd2a..d461ce9 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,10 @@
-
-     ██ ███████  ██████  ███    ██        █████  ███████
-     ██ ██      ██    ██ ████   ██       ██   ██ ██     
-     ██ ███████ ██    ██ ██ ██  ██ █████ ███████ ███████
-██   ██      ██ ██    ██ ██  ██ ██       ██   ██      ██
- █████  ███████  ██████  ██   ████       ██   ██ ███████
- 
-    AssemblyScript - v1.0.0
-  
+
    __  _____  _____  _____       _____  _____ 
+ __|  ||   __||     ||   | | ___ |  _  ||   __|
+|  |  ||__   ||  |  || | | ||___||     ||__   |
+|_____||_____||_____||_|___|     |__|__||_____|
+v0.9.26
+
## Installation @@ -16,10 +13,10 @@ npm install json-as ``` -Add the `--transform` to your `asc` command (e.g. in package.json) +Add the transform to your `asc` command (e.g. in package.json) ```bash ---transform json-as +--transform json-as/transform ``` Alternatively, add it to your `asconfig.json` @@ -28,7 +25,7 @@ Alternatively, add it to your `asconfig.json` { // ... "options": { - "transform": ["json-as"] + "transform": ["json-as/transform"] } } ``` @@ -129,9 +126,50 @@ If you want a feature, drop an issue (and again, maybe a star). I'll likely add ## Contact -- [Email](mailto:me@jairus.dev) -- [GitHub](https://github.com/JairusSW) -- [Discord](discord.com/users/600700584038760448) +Contact me at: + +Email: `me@jairus.dev` +GitHub: `JairusSW` +Discord: `jairussw` + +## Performance + +Run or view the benchmarks [here](https://github.com/JairusSW/as-json/tree/master/bench) + +Below are benchmark results comparing JavaScript's built-in JSON implementation and `JSON-AS` + +My library beats JSON (written in C++) on all counts _and_, I see many places where I can pull at least a 60% uplift in performance if I implement it. + +Note: SIMD is in-development and only available on the `v1` branch on GitHub + +Serialization Benchmarks: + +| Value | JavaScript (ops/s) | JSON-AS (ops/s) | JSON-AS (Pages) | JSON-AS (SIMD+Pages) | Max Throughput | +| -------------------------- | ------------------ | ------------------ | ------------------- | -------------------- | -------------- | +| "hello world" | 7,124,361 | 44,290,480 (6.2x) | 73,601,235 (10.3x) | NOT IMPLEMENTED | 1.91 GB/s | +| 12345 | 9,611,677 | 66,900,642 (6.9x) | 145,924,333 (15.2x) | NOT IMPLEMENTED | 0.58 GB/s | +| 1.2345 | 7,227,259 | 20,322,939 (2.8x) | NOT IMPLEMENTED | NOT IMPLEMENTED | 0.16 GB/s | +| [[],[[]],[[],[[]]]] | 5,655,429 | 34,453,102 (6.0x) | NOT IMPLEMENTED | NOT IMPLEMENTED | 1.32 GB/s | +| { x: f64, y: f64, z: f64 } | 3,878,604 | 44,557,996 (11.5x) | 113,203,242 (29.2x) | 172,023,231 (44.4x) | 8.61 GB/s | + +Deserialization Benchmarks: + +| Value | JavaScript (ops/s) | JSON-AS (ops/s) | Difference | +| -------------------------- | ------------------ | --------------- | ---------- | +| "hello world" | 12,210,131 | 24,274,496 | + 98% | +| "12345" | 21,376,873 | 254,640,930 | + 1,191% | +| 1.2345 | 23,193,902 | 221,869,840 | + 987% | +| [[],[[]],[[],[[]]]] | 4,777,227 | 74,921,123 | + 1,568% | +| { x: f64, y: f64, z: f64 } | 10,973,723 | 25,214,019 | + 230% | + +And my PC specs: + +| Component | Specification | +| -------------- | ------------------------------ | +| Wasmer Version | v4.3.0 | +| CPU | AMD Ryzen 7 7800x3D @ 6.00 GHz | +| Memory | T-Force DDR5 6000 MHz | +| OS | Ubuntu WSL2 | ## Issues diff --git a/as-test.config.json b/as-test.config.json index 3d68293..1028f84 100644 --- a/as-test.config.json +++ b/as-test.config.json @@ -6,7 +6,7 @@ "coverage": false }, "buildOptions": { - "args": ["--enable simd", "--runtime stub"], + "args": ["--transform ./transform"], "target": "wasi" }, "runOptions": { diff --git a/asconfig.json b/asconfig.json index 6a5616e..83b8baf 100644 --- a/asconfig.json +++ b/asconfig.json @@ -29,8 +29,8 @@ } }, "options": { - "transform": [], - "disableWarning": [] + "transform": ["./transform", "as-test/transform"], + "disableWarning": [226] }, "extends": "./node_modules/@assemblyscript/wasi-shim/asconfig.json" } diff --git a/assembly/__benches__/as-tral.d.ts b/assembly/__benches__/as-tral.d.ts new file mode 100644 index 0000000..e0296ed --- /dev/null +++ b/assembly/__benches__/as-tral.d.ts @@ -0,0 +1 @@ +/// diff --git a/assembly/__benches__/misc.bench.ts b/assembly/__benches__/misc.bench.ts index 4520fd4..a82c78c 100644 --- a/assembly/__benches__/misc.bench.ts +++ b/assembly/__benches__/misc.bench.ts @@ -1,19 +1,33 @@ -import { bench } from "as-bench/assembly/bench"; -import { bs } from "as-bs"; -import { deserializeString_SIMD } from "../deserialize/simd/string"; -import { deserializeString } from "../deserialize/simple/string"; -import { bytes } from "../util/bytes"; -const str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()\\\"\t\r\f\n\u0000'; -const str2 = '"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()\\\\\\"\\t\\r\\f\\n\\u0000"'; -const srcStart = changetype(str); -const srcEnd = srcStart + bytes(str); -bs.ensureSize(2048); -bench("Deserialize String (Simple)", () => { - deserializeString(str2); +import { JSON } from ".."; +import { BRACE_LEFT, BRACKET_LEFT, CHAR_F, CHAR_T, QUOTE } from "../custom/chars"; + +bench("Match Type (string)", () => { + blackbox(matchType(blackbox("\""), JSON.Types.String)); }); -// bench("Deserialize String (SIMD)", () => { -// (str2, bs.buffer); -// }); -bench("Deserialize String (SIMD)", () => { - deserializeString_SIMD(str2, srcStart, srcEnd, __new(158, idof())); + +bench("Match Type (bool)", () => { + blackbox(matchType(blackbox("t"), JSON.Types.Bool)); }); + +bench("Match Type (array)", () => { + blackbox(matchType(blackbox("["), JSON.Types.Array)); +}); + +bench("Match Type (struct)", () => { + blackbox(matchType(blackbox("{"), JSON.Types.Obj)); +}); + +bench("Match Type (raw)", () => { + blackbox(matchType(blackbox("\""), JSON.Types.Raw)); +}); + +@inline function matchType(data: string, type: JSON.Types): boolean { + const firstChar = load(changetype(data)); + if (JSON.Types.String == type && firstChar == QUOTE) return true; + else if (JSON.Types.Bool == type && (firstChar == CHAR_T || firstChar == CHAR_F)) return true; + else if (JSON.Types.Array == type && firstChar == BRACKET_LEFT) return true; + else if (JSON.Types.Obj == type && firstChar == BRACE_LEFT) return true; + else if (type < 7 && type > 0 && (firstChar < 58 && firstChar > 46)) return true; + else if (JSON.Types.Raw == type) return true; + else return false; +} \ No newline at end of file diff --git a/assembly/__tests__/bool.spec.ts b/assembly/__tests__/bool.spec.ts index 620e3a8..049f265 100644 --- a/assembly/__tests__/bool.spec.ts +++ b/assembly/__tests__/bool.spec.ts @@ -1,4 +1,4 @@ -import { JSON } from "../"; +import { JSON } from "json-as"; import { describe, expect, run } from "as-test/assembly"; describe("Should serialize booleans", () => { diff --git a/assembly/__tests__/simd/string.spec.ts b/assembly/__tests__/simd/string.spec.ts deleted file mode 100644 index ce09a0b..0000000 --- a/assembly/__tests__/simd/string.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { describe, expect, run } from "as-test/assembly"; -import { serializeString_SIMD } from "../../serialize/simd/string"; -import { deserializeString_SIMD } from "../../deserialize/simd/string"; - -const out = changetype(new ArrayBuffer(512)); - -const serialize_simd = (data: string): string => String.UTF16.decodeUnsafe(out, serializeString_SIMD(data, out)); -const deserialize_simd = (data: string): string => String.UTF16.decodeUnsafe(out, deserializeString_SIMD(data, out)); -describe("Should serialize strings", () => { - expect(serialize_simd("abcdefg")).toBe('"abcdefg"'); - - expect(serialize_simd('st"ring" w""ith quotes"')).toBe('"st\\"ring\\" w\\"\\"ith quotes\\""'); - - expect(serialize_simd('string "with random spa\nces and \nnewlines\n\n\n')).toBe('"string \\"with random spa\\nces and \\nnewlines\\n\\n\\n"'); - - expect(serialize_simd('string with colon : comma , brace [ ] bracket { } and quote " and other quote "')).toBe('"string with colon : comma , brace [ ] bracket { } and quote \\" and other quote \\""'); - - expect(serialize_simd("\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")).toBe('"\\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"'); -}); - -describe("Should deserialize strings", () => { - expect(deserialize_simd('"abcdefg"')).toBe("abcdefg"); - expect(deserialize_simd('"st\\"ring\\" w\\"\\"ith quotes\\""')).toBe('st"ring" w""ith quotes"'); - - expect(deserialize_simd('"string \\"with random spa\\nces and \\nnewlines\\n\\n\\n"')).toBe('string "with random spa\nces and \nnewlines\n\n\n'); - - expect(deserialize_simd('"string with colon : comma , brace [ ] bracket { } and quote \\" and other quote \\""')).toBe('string with colon : comma , brace [ ] bracket { } and quote " and other quote "'); - - expect(deserialize_simd('"\\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"')).toBe("\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"); -}); - -run(); diff --git a/assembly/__tests__/types.ts b/assembly/__tests__/types.ts index 7602837..2f089b1 100644 --- a/assembly/__tests__/types.ts +++ b/assembly/__tests__/types.ts @@ -1,36 +1,28 @@ - @json export class ObjWithString { s!: string; } - @json export class ObjWithStrangeKey { - @alias('a\\\t"\x02b`c') data!: T; } - - @json export class ObjectWithStringArray { sa!: string[]; } - @json export class ObjectWithFloat { f!: f64; } - @json export class ObjectWithFloatArray { fa!: f64[]; } - @json export class BaseObject { a: string; @@ -39,7 +31,6 @@ export class BaseObject { } } - @json export class DerivedObject extends BaseObject { b: string; @@ -49,7 +40,6 @@ export class DerivedObject extends BaseObject { } } - @json export class Map4 { a: string; @@ -58,7 +48,6 @@ export class Map4 { d: string; } - @json export class Vec3 { x: f64; @@ -68,7 +57,6 @@ export class Vec3 { static shouldIgnore: string = "should not be serialized"; } - @json export class Player { firstName: string; @@ -82,17 +70,12 @@ export class Player { export class Nullable {} export type Null = Nullable | null; - @json export class OmitIf { x: i32 = 1; - - @omitif("this.y == -1") y: i32 = -1; z: i32 = 1; - - @omitnull() foo: string | null = null; } diff --git a/assembly/custom/bs.ts b/assembly/custom/bs.ts new file mode 100644 index 0000000..7d52eb0 --- /dev/null +++ b/assembly/custom/bs.ts @@ -0,0 +1,211 @@ +import { dtoa_buffered, itoa_buffered } from "util/number"; +import { OBJECT, TOTAL_OVERHEAD } from "rt/common"; +// @ts-ignore +@inline const MAX_LEN: usize = 65536; +const STORE: usize[] = []; +let STORE_LEN: usize = 0; +const CACHE = memory.data(i32(MAX_LEN)); +// Configurable amount of referenceable strings +let POINTER = changetype(CACHE); +// @ts-ignore +@inline const MAX_CACHE = CACHE + MAX_LEN; + +export namespace bs { + // @ts-ignore + @inline export function write_int(num: T): void { + POINTER += itoa_buffered(POINTER, num) << 1; + if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function write_int_u(num: T): void { + POINTER += itoa_buffered(POINTER, num) << 1; + } + + // @ts-ignore + @inline export function write_fl(num: T): void { + POINTER += dtoa_buffered(POINTER, num) << 1; + if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function write_fl_u(num: T): void { + POINTER += dtoa_buffered(POINTER, num) << 1; + } + + // @ts-ignore + @inline export function write_b(buf: usize, bytes: usize = changetype(buf - TOTAL_OVERHEAD).rtSize): void { + memory.copy(POINTER, buf, bytes); + POINTER += bytes; + if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function write_b_u(buf: usize, bytes: usize = changetype(buf - TOTAL_OVERHEAD).rtSize): void { + memory.copy(POINTER, buf, bytes); + POINTER += bytes; + } + + // @ts-ignore + @inline export function write_s(str: string, bytes: usize = changetype(changetype(str) - TOTAL_OVERHEAD).rtSize): void { + memory.copy(POINTER, changetype(str), bytes); + POINTER += bytes; + if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function write_s_u(str: string, bytes: usize = changetype(changetype(str) - TOTAL_OVERHEAD).rtSize): void { + memory.copy(POINTER, changetype(str), bytes); + POINTER += bytes; + } + + // @ts-ignore + @inline export function write_s_se(str: string, start: usize, end: usize): void { + const bytes = end - start; + memory.copy(POINTER, changetype(str) + start, bytes); + POINTER += bytes; + if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function write_s_se_u(str: string, start: usize, end: usize): void { + const bytes = end - start; + memory.copy(POINTER, changetype(str) + start, bytes); + POINTER += bytes; + } + + // @ts-ignore + @inline export function write_8(char: i32): void { + store(POINTER, char); + POINTER += 2; + if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function write_8_u(char: i32): void { + store(POINTER, char); + //POINTER += 2; + } + + // @ts-ignore + @inline export function write_16(char: i32): void { + store(POINTER, char); + POINTER += 2; + if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function write_16_u(char: i32): void { + store(POINTER, char); + //POINTER += 2; + } + + // @ts-ignore + @inline export function write_32(chars: i32): void { + store(POINTER, chars); + POINTER += 4; + if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function write_32_u(chars: i32): void { + store(POINTER, chars); + //POINTER += 4; + } + + // @ts-ignore + @inline export function write_64(chars: i64): void { + store(POINTER, chars); + POINTER += 8; + if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function write_64_u(chars: i64): void { + store(POINTER, chars); + POINTER += 8; + } + + // @ts-ignore + @inline export function write_128(chars: v128): void { + store(POINTER, chars); + POINTER += 16; + if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function write_128_n(chars: v128, n: usize): void { + store(POINTER, chars); + POINTER += n; + if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function write_128_u(chars: v128): void { + store(POINTER, chars); + //POINTER += 16; + //if (MAX_CACHE <= POINTER) bs.shrink(); + } + + // @ts-ignore + @inline export function shrink(): void { + const len = POINTER - CACHE; + STORE_LEN += len; + const out = __new( + len, + idof() + ); + memory.copy(out, CACHE, len); + bs.reset(); + STORE.push(out); + } + + // @ts-ignore + @inline export function out(): T { + const len = POINTER - CACHE; + let out = __new( + len + STORE_LEN, + idof() + ); + + memory.copy(out, CACHE, len); + if (STORE_LEN) { + out += len; + for (let i = 0; i < STORE.length; i++) { + const ptr = changetype(unchecked(STORE[i])); + const storeLen = changetype(ptr - TOTAL_OVERHEAD).rtSize; + memory.copy(out, ptr, storeLen); + //__unpin(ptr); + out += storeLen; + } + STORE_LEN = 0; + } + bs.reset(); + + return changetype(out); + } + + // @ts-ignore + @inline export function out_u(): T { + const len = POINTER - CACHE; + const out = __new( + len + STORE_LEN, + idof() + ); + + memory.copy(out, CACHE, len); + bs.reset(); + + return changetype(out); + } + + // @ts-ignore + @inline export function _out(out: usize): void { + memory.copy(out, CACHE, POINTER - CACHE); + } + + // @ts-ignore + @inline export function reset(): void { + POINTER = CACHE; + } +} \ No newline at end of file diff --git a/assembly/custom/chars.ts b/assembly/custom/chars.ts index 86a321e..918d6d1 100644 --- a/assembly/custom/chars.ts +++ b/assembly/custom/chars.ts @@ -59,9 +59,9 @@ // @ts-ignore: Decorator is valid here @inline export const BRACKET_RIGHT_WORD = "]"; // @ts-ignore: Decorator is valid here -@inline export const QUOTE_WORD = '"'; +@inline export const QUOTE_WORD = "\""; // @ts-ignore: Decorator is valid here -@inline export const EMPTY_QUOTE_WORD = '""'; +@inline export const EMPTY_QUOTE_WORD = "\"\""; // Escape Codes // @ts-ignore: Decorator is valid here diff --git a/assembly/custom/memory.ts b/assembly/custom/memory.ts deleted file mode 100644 index 8092a90..0000000 --- a/assembly/custom/memory.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { BLOCK_MAXSIZE, OBJECT, TOTAL_OVERHEAD } from "rt/common"; -import { E_INVALIDLENGTH } from "util/error"; - -// @ts-ignore: Decorator valid here -@inline export function ensureCapacity(obj: T, newSize: usize): usize { - const ptr = changetype(obj); - const oldCapacity = changetype(ptr - TOTAL_OVERHEAD).rtSize; - if (newSize > oldCapacity) { - if (newSize > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH); - const newCapacity = max(min(oldCapacity << 1, BLOCK_MAXSIZE), newSize); - const newObj = __renew(ptr, newCapacity); - return newObj; - } - return ptr; -} - -// @ts-ignore: Decorator valid here -@inline export function setCapacity(obj: T, oldCapacity: usize, newCapacity: usize): usize { - const ptr = changetype(obj); - if (newCapacity > oldCapacity) { - if (newCapacity > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH); - return __renew(ptr, newCapacity); - } - return ptr; -} diff --git a/assembly/custom/types.ts b/assembly/custom/types.ts index 9d68a72..d2d0227 100644 --- a/assembly/custom/types.ts +++ b/assembly/custom/types.ts @@ -1,4 +1,3 @@ - @json export class Vec3 { x: f64 = 1.0; diff --git a/assembly/custom/util.ts b/assembly/custom/util.ts index b38333f..73b59c7 100644 --- a/assembly/custom/util.ts +++ b/assembly/custom/util.ts @@ -1,6 +1,7 @@ import { isSpace } from "util/string"; -import { BACK_SLASH, QUOTE } from "./chars"; +import { BACK_SLASH, BRACE_LEFT, BRACKET_LEFT, CHAR_F, CHAR_T, QUOTE } from "./chars"; import { Sink } from "./sink"; +import { JSON } from ".."; // @ts-ignore: Decorator export function isMap(): bool { @@ -13,6 +14,51 @@ export function isMap(): bool { return load(changetype(data) + ((pos) << 1)); } +// @ts-ignore: Decorator +@inline export function removeWhitespace(data: string): string { + const result = new Sink(); + let instr = false; + for (let i = 0; i < data.length; i++) { + const char = unsafeCharCodeAt(data, i); + if (instr === false && char === QUOTE) instr = true; + else if ( + instr === true && char === QUOTE + && unsafeCharCodeAt(data, i - 1) !== BACK_SLASH + ) instr = false; + + if (instr === false) { + if (!isSpace(char)) result.write(data.charAt(i)); + } else { + result.write(data.charAt(i)); + } + } + return result.toString(); +} + +// @ts-ignore: Decorator +@inline export function escapeChar(char: string): string { + switch (unsafeCharCodeAt(char, 0)) { + case 0x22: + return '\\"'; + case 0x5c: + return "\\\\"; + case 0x08: + return "\\b"; + case 0x0a: + return "\\n"; + case 0x0d: + return "\\r"; + case 0x09: + return "\\t"; + case 0x0c: + return "\\f"; + case 0x0b: + return "\\u000b"; + default: + return char; + } +} + /** * A terrible function which finds the depth of a certain array. * Suffers no overhead besides function calling and a if/else. @@ -36,54 +82,54 @@ export function getArrayDepth(depth: i32 = 1): i32 { * Loads 32 bits and retrieves the high/low bits. * The reason why we only load 4 bytes at a time is that numbers in the 32-bit range are 7 chars long at most. * Using SIMD or 64 bit loads would only work well when parsing large 128+ numbers. - * + * * Here are some benchmarks - * Parsing: "12345" + * Parsing: "12345" * Results are spread over 5000ms - * + * * SNIP: 270M iterations * ATOI: 285M iterations - * ParseInt: 176M iterations - * + * ParseInt: 176M iterations + * * @param str - Any number. Can include scientific notation. - */ +*/ // @ts-ignore: Decorator @inline export function snip_fast(str: string, len: u32 = 0, offset: u32 = 0): T { if (isSigned()) { const firstChar: u32 = load(changetype(str)); - if (firstChar == 48) return 0 as T; - const isNegative = firstChar == 45; // Check if the number is negative + if (firstChar === 48) return 0 as T; + const isNegative = firstChar === 45; // Check if the number is negative let val: T = 0 as T; if (len == 0) len = u32(str.length << 1); if (isNegative) { offset += 2; if (len >= 4) { // 32-bit route - for (; offset < len - 3; offset += 4) { + for (; offset < (len - 3); offset += 4) { const ch = load(changetype(str) + offset); - const low = ch & 0xffff; + const low = ch & 0xFFFF; const high = ch >> 16; // 9 is 57. The highest group of two numbers is 114, so if a e or an E is included, this will fire. if (low > 57) { // The first char (f) is E or e // We push the offset up by two and apply the notation. if (load(changetype(str) + offset + 2) == 45) { - return -(val / 10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1)) as T; + return -(val / (10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1))) as T; } else { // Inlined this operation instead of using a loop - return -(val * 10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1)) as T; + return -(val * (10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1))) as T; } } else if (high > 57) { // The first char (f) is E or e // We push the offset up by two and apply the notation. if (load(changetype(str) + offset + 4) == 45) { - return -(val / 10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1)) as T; + return -(val / (10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1))) as T; } else { // Inlined this operation instead of using a loop - return -(val * 10 ** (__atoi_fast(str, offset + 4, offset + 6) + 1)) as T; + return -(val * (10 ** (__atoi_fast(str, offset + 4, offset + 6) + 1))) as T; } } else { - val = (val * 100 + (low - 48) * 10 + (high - 48)) as T; + val = (val * 100 + ((low - 48) * 10) + (high - 48)) as T; } } } @@ -95,43 +141,43 @@ export function getArrayDepth(depth: i32 = 1): i32 { // The first char (f) is E or e // We push the offset up by two and apply the notation. if (load(changetype(str) + offset + 2) == 45) { - return -(val / 10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1)) as T; + return -(val / (10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1))) as T; } else { // Inlined this operation instead of using a loop - return -(val * 10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1)) as T; + return -(val * (10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1))) as T; } } else { - val = (val * 10 + (ch - 48)) as T; + val = (val * 10) + (ch - 48) as T; } } return -val as T; } else { if (len >= 4) { // Duplet 16 bit lane load - for (; offset < len - 3; offset += 4) { + for (; offset < (len - 3); offset += 4) { const ch = load(changetype(str) + offset); - const low = ch & 0xffff; + const low = ch & 0xFFFF; const high = ch >> 16; // 9 is 57. The highest group of two numbers is 114, so if a e or an E is included, this will fire. if (low > 57) { // The first char (f) is E or e // We push the offset up by two and apply the notation. if (load(changetype(str) + offset + 2) == 45) { - return (val / 10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1)) as T; + return (val / (10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1))) as T; } else { // Inlined this operation instead of using a loop - return (val * 10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1)) as T; + return (val * (10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1))) as T; } } else if (high > 57) { if (load(changetype(str) + offset + 4) == 45) { - return (val / 10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1)) as T; + return (val / (10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1))) as T; } else { // Inlined this operation instead of using a loop - return (val * 10 ** (__atoi_fast(str, offset + 4, offset + 6) + 1)) as T; + return (val * (10 ** (__atoi_fast(str, offset + 4, offset + 6) + 1))) as T; } } else { // Optimized with multiplications and shifts. - val = (val * 100 + (low - 48) * 10 + (high - 48)) as T; + val = (val * 100 + ((low - 48) * 10) + (high - 48)) as T; } } } @@ -142,49 +188,49 @@ export function getArrayDepth(depth: i32 = 1): i32 { // e is 101 and E is 69. if (ch > 57) { if (load(changetype(str) + offset + 2) == 45) { - val = (val / 10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1)) as T; + val = (val / (10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1))) as T; } else { // Inlined this operation instead of using a loop - val = (val * 10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1)) as T; + val = (val * (10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1))) as T; } return val as T; } else { - val = (val * 10 + (ch - 48)) as T; + val = (val * 10) + (ch - 48) as T; } } return val as T; } } else { const firstChar: u32 = load(changetype(str)); - if (firstChar == 48) return 0 as T; + if (firstChar === 48) return 0 as T; let val: T = 0 as T; if (len == 0) len = u32(str.length << 1); if (len >= 4) { // Duplet 16 bit lane load - for (; offset < len - 3; offset += 4) { + for (; offset < (len - 3); offset += 4) { const ch = load(changetype(str) + offset); - const low = ch & 0xffff; + const low = ch & 0xFFFF; const high = ch >> 16; // 9 is 57. The highest group of two numbers is 114, so if a e or an E is included, this will fire. if (low > 57) { // The first char (f) is E or e // We push the offset up by two and apply the notation. if (load(changetype(str) + offset + 2) == 45) { - return (val / 10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1)) as T; + return (val / (10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1))) as T; } else { // Inlined this operation instead of using a loop - return (val * 10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1)) as T; + return (val * (10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1))) as T; } } else if (high > 57) { if (load(changetype(str) + offset + 4) == 45) { - return (val / 10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1)) as T; + return (val / (10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1))) as T; } else { // Inlined this operation instead of using a loop - return (val * 10 ** (__atoi_fast(str, offset + 4, offset + 6) + 1)) as T; + return (val * (10 ** (__atoi_fast(str, offset + 4, offset + 6) + 1))) as T; } } else { // Optimized with multiplications and shifts. - val = (val * 100 + (low - 48) * 10 + (high - 48)) as T; + val = (val * 100 + ((low - 48) * 10) + (high - 48)) as T; } } } @@ -195,13 +241,13 @@ export function getArrayDepth(depth: i32 = 1): i32 { // e is 101 and E is 69. if (ch > 57) { if (load(changetype(str) + offset + 2) == 45) { - return (val / 10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1)) as T; + return (val / (10 ** (__atoi_fast(str, offset + 6, offset + 8) - 1))) as T; } else { // Inlined this operation instead of using a loop - return (val * 10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1)) as T; + return (val * (10 ** (__atoi_fast(str, offset + 2, offset + 4) + 1))) as T; } } else { - val = (val * 10 + (ch - 48)) as T; + val = (val * 10) + (ch - 48) as T; } } return val as T; @@ -219,21 +265,21 @@ export function getArrayDepth(depth: i32 = 1): i32 { if (!end) end = start + u32(str.length << 1); if (isSigned()) { // Negative path - if (load(changetype(str) + start) == 45) { + if (load(changetype(str) + start) === 45) { start += 2; for (; start < end; start += 2) { - val = (val * 10 + (load(changetype(str) + start) - 48)) as T; + val = (val * 10) + (load(changetype(str) + start) - 48) as T; } return -val as T; } else { for (; start < end; start += 2) { - val = (val * 10 + (load(changetype(str) + start) - 48)) as T; + val = ((val * 10) + (load(changetype(str) + start) - 48)) as T; } return val as T; } } else { for (; start < end; start += 2) { - val = (val * 10 + (load(changetype(str) + start) - 48)) as T; + val = ((val * 10) + (load(changetype(str) + start) - 48)) as T; } return val as T; } @@ -253,14 +299,14 @@ export function getArrayDepth(depth: i32 = 1): i32 { let val: T = 0; let offset = 0; let firstChar = load(changetype(str) + offset); - if (firstChar == 45) { + if (firstChar === 45) { offset = 2; } for (; offset < str.length << 1; offset += 2) { const char = load(changetype(str) + offset); - if (char == 101 || char == 69) { + if (char === 101 || char === 69) { const char = load(changetype(str) + (offset += 2)); - if (char == 45) { + if (char === 45) { // @ts-ignore val /= sciNote(__atoi_fast(str, (offset += 2))); // @ts-ignore @@ -276,7 +322,7 @@ export function getArrayDepth(depth: i32 = 1): i32 { val = (val << 1) + (val << 3) + (char - 48); // We use load because in this case, there is no need to have bounds-checking } - if (firstChar == 45) { + if (firstChar === 45) { val = -val as T; } return val; @@ -299,6 +345,17 @@ export function getArrayDepth(depth: i32 = 1): i32 { return res; } +// @ts-ignore +@inline function equalsSlice(p1_data: string, p1_start: i32, p1_end: i32, p2_data: string, p2_start: i32, p2_end: i32): boolean { + const p1_len = p1_end - p1_start; + const p2_len = p2_end - p2_start; + if (p1_len != p2_len) return false; + if (p1_len == 2) { + return load(changetype(p1_data) + p1_start) == load(changetype(p2_data) + p2_start) + } + return memory.compare(changetype(p1_data) + p1_start, changetype(p2_data) + p2_start, p1_len) === 0; +} + // @ts-ignore @inline export function containsCodePoint(str: string, code: u32, start: i32, end: i32): bool { for (let i = start; i <= end; i++) { @@ -321,23 +378,18 @@ export function getArrayDepth(depth: i32 = 1): i32 { // @ts-ignore: Decorator @inline export function intTo16(int: i32): i32 { const high = int >> 4; - const low = int & 0x0f; + const low = int & 0x0F; if (low < 10) { if (high < 10) { - return ((48 + low) << 16) | (48 + high); + return ((48 + low) << 16) | 48 + high; } else { - return ((48 + low) << 16) | (87 + high); + return ((48 + low) << 16) | 87 + high; } } else { if (high < 10) { - return ((87 + low) << 16) | (48 + high); + return ((87 + low) << 16) | 48 + high; } else { - return ((87 + low) << 16) | (87 + high); + return ((87 + low) << 16) | 87 + high; } } -} - -// @ts-ignore: Decorator valid here -@inline export function nextPowerOf2(n: u32): u32 { - return 1 << (32 - clz(n - 1)); -} +} \ No newline at end of file diff --git a/assembly/deserialize/simple/array.ts b/assembly/deserialize/array.ts similarity index 57% rename from assembly/deserialize/simple/array.ts rename to assembly/deserialize/array.ts index 07074f8..f173ed1 100644 --- a/assembly/deserialize/simple/array.ts +++ b/assembly/deserialize/array.ts @@ -1,5 +1,5 @@ -import { BRACKET_LEFT } from "../../custom/chars"; -import { isMap } from "../../custom/util"; +import { BRACKET_LEFT } from "../custom/chars"; +import { isMap } from "../custom/util"; import { deserializeArrayArray } from "./array/array"; import { deserializeBooleanArray } from "./array/bool"; import { deserializeFloatArray } from "./array/float"; @@ -9,31 +9,38 @@ import { deserializeObjectArray } from "./array/object"; import { deserializeStringArray } from "./array/string"; // @ts-ignore: Decorator valid here -export function deserializeArray(srcStart: usize, srcEnd: usize, dst: usize = 0): T { +export function deserializeArray(data: string): T { if (isString>()) { - return deserializeStringArray(srcStart, srcEnd, dst); + return deserializeStringArray(data); } else if (isBoolean>()) { // @ts-ignore - return deserializeBooleanArray(srcStart, srcEnd, dst); + return deserializeBooleanArray(data); } else if (isInteger>()) { // @ts-ignore - return deserializeIntegerArray(srcStart, srcEnd, dst); + return deserializeIntegerArray(data); } else if (isFloat>()) { // @ts-ignore - return deserializeFloatArray(srcStart, srcEnd, dst); + return deserializeFloatArray(data); } else if (isArrayLike>()) { // @ts-ignore - return deserializeArrayArray(srcStart, srcEnd, dst); + return deserializeArrayArray(data); } else if (isMap>()) { - return deserializeMapArray(srcStart, srcEnd, dst); + return deserializeMapArray(data); } else if (isManaged>() || isReference>()) { const type = changetype>>(0); // @ts-ignore if (isDefined(type.__DESERIALIZE)) { - return deserializeObjectArray(srcStart, srcEnd, dst); + return deserializeObjectArray(data); } throw new Error("Could not parse array of type " + nameof() + "! Make sure to add the @json decorator over classes!"); } else { throw new Error("Could not parse array of type " + nameof() + "!"); } } + +// @ts-ignore: Decorator valid here +export function deserializeArray_Safe(data: string): T { + const firstChar = load(changetype(data)); + if (firstChar != BRACKET_LEFT) throw new Error("Mismatched Types! Expected " + nameof() + " but got \"" + data.slice(0, 100) + "\" instead!"); + return deserializeArray(data); +} \ No newline at end of file diff --git a/assembly/deserialize/array/array.ts b/assembly/deserialize/array/array.ts new file mode 100644 index 0000000..cde71c3 --- /dev/null +++ b/assembly/deserialize/array/array.ts @@ -0,0 +1,31 @@ +import { BRACKET_LEFT, BRACKET_RIGHT } from "../../custom/chars"; +import { JSON } from "../.."; +import { unsafeCharCodeAt } from "../../custom/util"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeArrayArray(data: string): T { + const result = instantiate(); + let lastPos = 0; + let depth = 0; + let i = 1; + // Find start of bracket + //for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) {} + //i++; + for (; i < data.length - 1; i++) { + const char = unsafeCharCodeAt(data, i); + if (char === BRACKET_LEFT) { + if (depth === 0) { + lastPos = i; + } + // Shifting is 6% faster than incrementing + depth++; + } else if (char === BRACKET_RIGHT) { + depth--; + if (depth === 0) { + i++; + result.push(JSON.parse>(data.slice(lastPos, i))); + } + } + } + return result; +} \ No newline at end of file diff --git a/assembly/deserialize/array/bool.ts b/assembly/deserialize/array/bool.ts new file mode 100644 index 0000000..465e617 --- /dev/null +++ b/assembly/deserialize/array/bool.ts @@ -0,0 +1,19 @@ +import { CHAR_E, CHAR_F, CHAR_T } from "../../custom/chars"; +import { unsafeCharCodeAt } from "../../custom/util"; +import { deserializeBoolean } from "../bool"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeBooleanArray(data: string): T { + const result = instantiate(); + let lastPos = 1; + for (let i = 1; i < data.length - 1; i++) { + const char = unsafeCharCodeAt(data, i); + if (char === CHAR_T || char === CHAR_F) { + lastPos = i; + } else if (char === CHAR_E) { + i++; + result.push(deserializeBoolean(data.slice(lastPos, i))); + } + } + return result; +} \ No newline at end of file diff --git a/assembly/deserialize/array/float.ts b/assembly/deserialize/array/float.ts new file mode 100644 index 0000000..15cae91 --- /dev/null +++ b/assembly/deserialize/array/float.ts @@ -0,0 +1,24 @@ +import { isSpace } from "util/string"; +import { unsafeCharCodeAt } from "../../custom/util"; +import { COMMA, BRACKET_RIGHT } from "../../custom/chars"; +import { deserializeFloat } from "../float"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeFloatArray(data: string): T { + const result = instantiate(); + let lastPos = 0; + let i = 1; + let awaitingParse = false; + for (; i < data.length; i++) { + const char = unsafeCharCodeAt(data, i); + if (lastPos === 0 && ((char >= 48 && char <= 57) || char === 45)) { + awaitingParse = true; + lastPos = i; + } else if (awaitingParse && (isSpace(char) || char == COMMA || char == BRACKET_RIGHT) && lastPos > 0) { + awaitingParse = false; + result.push(deserializeFloat>(data.slice(lastPos, i))); + lastPos = 0; + } + } + return result; + } \ No newline at end of file diff --git a/assembly/deserialize/array/integer.ts b/assembly/deserialize/array/integer.ts new file mode 100644 index 0000000..774b933 --- /dev/null +++ b/assembly/deserialize/array/integer.ts @@ -0,0 +1,24 @@ +import { isSpace } from "util/string"; +import { unsafeCharCodeAt } from "../../custom/util"; +import { COMMA, BRACKET_RIGHT } from "../../custom/chars"; +import { deserializeInteger } from "../integer"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeIntegerArray(data: string): T { + const result = instantiate(); + let lastPos = 0; + let i = 1; + let awaitingParse = false; + for (; i < data.length; i++) { + const char = unsafeCharCodeAt(data, i); + if (lastPos === 0 && ((char >= 48 && char <= 57) || char === 45)) { + awaitingParse = true; + lastPos = i; + } else if (awaitingParse && (isSpace(char) || char == COMMA || char == BRACKET_RIGHT) && lastPos > 0) { + awaitingParse = false; + result.push(deserializeInteger>(data.slice(lastPos, i))); + lastPos = 0; + } + } + return result; +} \ No newline at end of file diff --git a/assembly/deserialize/array/map.ts b/assembly/deserialize/array/map.ts new file mode 100644 index 0000000..a0e6901 --- /dev/null +++ b/assembly/deserialize/array/map.ts @@ -0,0 +1,27 @@ +import { BRACE_LEFT, BRACE_RIGHT } from "../../custom/chars"; +import { JSON } from "../.."; +import { unsafeCharCodeAt } from "../../custom/util"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeMapArray(data: string): T { + const result = instantiate(); + let lastPos: u32 = 1; + let depth: u32 = 0; + for (let pos: u32 = 0; pos < data.length; pos++) { + const char = unsafeCharCodeAt(data, pos); + if (char === BRACE_LEFT) { + if (depth === 0) { + lastPos = pos; + } + depth++; + } else if (char === BRACE_RIGHT) { + depth--; + if (depth === 0) { + pos++; + result.push(JSON.parse>(data.slice(lastPos, pos))); + //lastPos = pos + 2; + } + } + } + return result; +} \ No newline at end of file diff --git a/assembly/deserialize/array/object.ts b/assembly/deserialize/array/object.ts new file mode 100644 index 0000000..66856f9 --- /dev/null +++ b/assembly/deserialize/array/object.ts @@ -0,0 +1,27 @@ +import { BRACE_LEFT, BRACE_RIGHT } from "../../custom/chars"; +import { JSON } from "../.."; +import { unsafeCharCodeAt } from "../../custom/util"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeObjectArray(data: string): T { + const result = instantiate(); + let lastPos: u32 = 1; + let depth: u32 = 0; + for (let pos: u32 = 0; pos < data.length; pos++) { + const char = unsafeCharCodeAt(data, pos); + if (char === BRACE_LEFT) { + if (depth === 0) { + lastPos = pos; + } + depth++; + } else if (char === BRACE_RIGHT) { + depth--; + if (depth === 0) { + pos++; + result.push(JSON.parse>(data.slice(lastPos, pos))); + //lastPos = pos + 2; + } + } + } + return result; +} \ No newline at end of file diff --git a/assembly/deserialize/array/string.ts b/assembly/deserialize/array/string.ts new file mode 100644 index 0000000..5e94933 --- /dev/null +++ b/assembly/deserialize/array/string.ts @@ -0,0 +1,29 @@ +import { BACK_SLASH, QUOTE } from "../../custom/chars"; +import { unsafeCharCodeAt } from "../../custom/util"; +import { deserializeString } from "../string"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeStringArray(data: string): string[] { + const result: string[] = []; + let lastPos = 0; + let instr = false; + let escaping = false; + for (let i = 1; i < data.length - 1; i++) { + const char = unsafeCharCodeAt(data, i); + if (char === BACK_SLASH && !escaping) { + escaping = true; + } else { + if (char === QUOTE && !escaping) { + if (instr === false) { + instr = true; + lastPos = i; + } else { + instr = false; + result.push(deserializeString(data, lastPos, i)); + } + } + escaping = false; + } + } + return result; +} \ No newline at end of file diff --git a/assembly/deserialize/bool.ts b/assembly/deserialize/bool.ts new file mode 100644 index 0000000..918fde8 --- /dev/null +++ b/assembly/deserialize/bool.ts @@ -0,0 +1,34 @@ +import { CHAR_F, CHAR_T } from "../custom/chars"; +import { unsafeCharCodeAt } from "../custom/util"; + +/** + * Deserialize a string to type boolean + * @param data data to parse + * @returns boolean + */ +// @ts-ignore: Decorator valid here +@inline export function deserializeBoolean(data: string, start: i32 = 0, end: i32 = 0): boolean { + if (!end) end = data.length; + const len = end - start; + const ptr = changetype(data) + (start << 1); + const firstChar = unsafeCharCodeAt(data, start); + if (len === 4 && firstChar === CHAR_T && load(ptr) === 28429475166421108) return true; + else if (len === 5 && firstChar === CHAR_F && load(ptr, 2) === 28429466576093281) return false; + return false//ERROR(`Expected to find boolean, but found "${data.slice(0, 100)}" instead!`); +} + +/** + * Deserialize a string to type boolean (safely) + * @param data data to parse + * @returns boolean + */ +// @ts-ignore: Decorator valid here +@inline export function deserializeBoolean_Safe(data: string, start: i32 = 0, end: i32 = 0): boolean { + if (!end) end = data.length; + const len = end - start; + const ptr = changetype(data) + (start << 1); + const firstChar = unsafeCharCodeAt(data, start); + if (len === 4 && firstChar === CHAR_T && load(ptr) === 28429475166421108) return true; + else if (len === 5 && firstChar === CHAR_F && load(ptr, 2) === 28429466576093281) return false; + throw new Error("Mismatched Types! Expected boolean but got \"" + data.slice(0, 100) + "\" instead!"); +} \ No newline at end of file diff --git a/assembly/deserialize/date.ts b/assembly/deserialize/date.ts new file mode 100644 index 0000000..223973e --- /dev/null +++ b/assembly/deserialize/date.ts @@ -0,0 +1,19 @@ +import { QUOTE } from "../custom/chars"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeDate(dateTimeString: string): Date { + // Use AssemblyScript's date parser + const d = Date.fromString(dateTimeString); + + // Return a new object instead of the one that the parser returned. + // This may seem redundant, but addreses the issue when Date + // is globally aliased to wasi_Date (or some other superclass). + return new Date(d.getTime()); +} + +// @ts-ignore: Decorator valid here +@inline export function deserializeDate_Safe(dateTimeString: string): Date { + const firstChar = load(changetype(dateTimeString)); + if (firstChar != QUOTE) throw new Error("Mismatched Types! Expected Date but got \"" + dateTimeString.slice(0, 100) + "\" instead!"); + return deserializeDate(dateTimeString); +} \ No newline at end of file diff --git a/assembly/deserialize/float.ts b/assembly/deserialize/float.ts new file mode 100644 index 0000000..8a207a3 --- /dev/null +++ b/assembly/deserialize/float.ts @@ -0,0 +1,21 @@ +// @ts-ignore: Decorator valid here +@inline export function deserializeFloat(data: string): T { + // @ts-ignore + const type: T = 0; + // @ts-ignore + if (type instanceof f64) return f64.parse(data); + // @ts-ignore + return f32.parse(data); +} + +// @ts-ignore: Decorator valid here +@inline export function deserializeFloat_Safe(data: string): T { + const firstChar = load(changetype(data)); + if ((firstChar < 48 || firstChar > 57) && firstChar != 45) throw new Error("Mismatched Types! Expected float but got \""+data.slice(0, 100)+"\" instead!"); + // @ts-ignore + const type: T = 0; + // @ts-ignore + if (type instanceof f64) return f64.parse(data); + // @ts-ignore + return f32.parse(data); +} \ No newline at end of file diff --git a/assembly/deserialize/integer.ts b/assembly/deserialize/integer.ts new file mode 100644 index 0000000..93d3bca --- /dev/null +++ b/assembly/deserialize/integer.ts @@ -0,0 +1,16 @@ +import { snip_fast } from "../custom/util"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeInteger(data: string): T { + // @ts-ignore + return snip_fast(data); +} + +// @ts-ignore: Decorator valid here +@inline export function deserializeInteger_Safe(data: string): T { + const firstChar = load(changetype(data)); + console.log(firstChar.toString()) + if ((firstChar < 48 || firstChar > 57) && firstChar != 45) throw new Error("Mismatched Types! Expected " + nameof() + " but got \""+data.slice(0, 100)+"\" instead!"); + // @ts-ignore + return snip_fast(data); +} \ No newline at end of file diff --git a/assembly/deserialize/map.ts b/assembly/deserialize/map.ts new file mode 100644 index 0000000..5c1fe82 --- /dev/null +++ b/assembly/deserialize/map.ts @@ -0,0 +1,189 @@ +import { Virtual } from "as-virtual/assembly"; +import { containsCodePoint, unsafeCharCodeAt } from "../custom/util"; +import { + CHAR_A, + BACK_SLASH, + COLON, + COMMA, + CHAR_E, + CHAR_F, + CHAR_L, + BRACE_LEFT, + BRACKET_LEFT, + CHAR_N, + QUOTE, + CHAR_R, + BRACE_RIGHT, + BRACKET_RIGHT, + CHAR_S, + CHAR_T, + CHAR_U +} from "../custom/chars"; +import { deserializeBoolean } from "./bool"; +import { JSON } from ".."; +import { deserializeString } from "./string"; +import { isSpace } from "util/string"; +import { deserializeInteger } from "./integer"; +import { deserializeFloat } from "./float"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeMap(data: string): T { + + const map: nonnull = changetype>( + __new(offsetof>(), idof>()) + ); + + const key = Virtual.createEmpty(); + let isKey = false; + let depth = 0; + let outerLoopIndex = 1; + for (; outerLoopIndex < data.length - 1; outerLoopIndex++) { + const char = unsafeCharCodeAt(data, outerLoopIndex); + if (char === BRACKET_LEFT) { + for ( + let arrayValueIndex = outerLoopIndex; + arrayValueIndex < data.length - 1; + arrayValueIndex++ + ) { + const char = unsafeCharCodeAt(data, arrayValueIndex); + if (char === BRACKET_LEFT) { + depth++; + } else if (char === BRACKET_RIGHT) { + depth--; + if (depth === 0) { + ++arrayValueIndex; + map.set(deserializeMapKey>(key), JSON.parse>(data.slice(outerLoopIndex, arrayValueIndex))); + outerLoopIndex = arrayValueIndex; + isKey = false; + break; + } + } + } + } else if (char === BRACE_LEFT) { + for ( + let objectValueIndex = outerLoopIndex; + objectValueIndex < data.length - 1; + objectValueIndex++ + ) { + const char = unsafeCharCodeAt(data, objectValueIndex); + if (char === BRACE_LEFT) { + depth++; + } else if (char === BRACE_RIGHT) { + depth--; + if (depth === 0) { + ++objectValueIndex; + map.set(deserializeMapKey>(key), JSON.parse>(data.slice(outerLoopIndex, objectValueIndex))); + outerLoopIndex = objectValueIndex; + isKey = false; + break; + } + } + } + } else if (char === QUOTE) { + let escaping = false; + for ( + let stringValueIndex = ++outerLoopIndex; + stringValueIndex < data.length - 1; + stringValueIndex++ + ) { + const char = unsafeCharCodeAt(data, stringValueIndex); + if (char === BACK_SLASH && !escaping) { + escaping = true; + } else { + if ( + char === QUOTE && !escaping + ) { + if (isKey === false) { + // perf: we can avoid creating a new string here if the key doesn't contain any escape sequences + if (containsCodePoint(data, BACK_SLASH, outerLoopIndex, stringValueIndex)) { + key.reinst(deserializeString(data, outerLoopIndex - 1, stringValueIndex)); + } else { + key.reinst(data, outerLoopIndex, stringValueIndex); + } + isKey = true; + } else { + if (isString>()) { + const value = deserializeString(data, outerLoopIndex - 1, stringValueIndex); + map.set(deserializeMapKey>(key), value); + } + isKey = false; + } + outerLoopIndex = ++stringValueIndex; + break; + } + escaping = false; + } + } + } else if ( + char == CHAR_N && + unsafeCharCodeAt(data, ++outerLoopIndex) === CHAR_U && + unsafeCharCodeAt(data, ++outerLoopIndex) === CHAR_L && + unsafeCharCodeAt(data, ++outerLoopIndex) === CHAR_L) { + if (isNullable>()) { + map.set(deserializeMapKey>(key), null); + } + isKey = false; + } else if ( + char === CHAR_T && + unsafeCharCodeAt(data, ++outerLoopIndex) === CHAR_R && + unsafeCharCodeAt(data, ++outerLoopIndex) === CHAR_U && + unsafeCharCodeAt(data, ++outerLoopIndex) === CHAR_E + ) { + if (isBoolean>()) { + map.set(deserializeMapKey>(key), true); + } + isKey = false; + } else if ( + char === CHAR_F && + unsafeCharCodeAt(data, ++outerLoopIndex) === CHAR_A && + unsafeCharCodeAt(data, ++outerLoopIndex) === CHAR_L && + unsafeCharCodeAt(data, ++outerLoopIndex) === CHAR_S && + unsafeCharCodeAt(data, ++outerLoopIndex) === CHAR_E + ) { + if (isBoolean>()) { + map.set(deserializeMapKey>(key), false); + } + isKey = false; + } else if ((char >= 48 && char <= 57) || char === 45) { + let numberValueIndex = ++outerLoopIndex; + for (; numberValueIndex < data.length; numberValueIndex++) { + const char = unsafeCharCodeAt(data, numberValueIndex); + if (char === COLON || char === COMMA || char === BRACE_RIGHT || isSpace(char)) { + if (isInteger>()) { + map.set(deserializeMapKey>(key), deserializeInteger>(data.slice(outerLoopIndex - 1, numberValueIndex))); + } else if (isFloat>()) { + map.set(deserializeMapKey>(key), deserializeFloat>(data.slice(outerLoopIndex - 1, numberValueIndex))); + } + outerLoopIndex = numberValueIndex; + isKey = false; + break; + } + } + } + } + + return map; +} + +//@ts-ignore: Decorator +function deserializeMapKey(key: Virtual): T { + const k = key.copyOut(); + if (isString()) { + return k as T; + } else if (isBoolean()) { + return deserializeBoolean(k) as T; + } else if (isInteger()) { + return deserializeInteger(k); + } else if (isFloat()) { + return deserializeFloat(k); + } + + throw new Error(`JSON: Cannot parse JSON object to a Map with a key of type ${nameof()}`); +} + +// @ts-ignore: Decorator valid here +@inline export function deserializeMap_Safe(data: string): T { + const firstChar = load(changetype(data)); + if (firstChar != BRACE_LEFT) throw new Error("Mismatched Types! Expected " + nameof() + " but got \"" + data.slice(0, 100) + "\" instead!"); + return deserializeMap(data); +} \ No newline at end of file diff --git a/assembly/deserialize/object.ts b/assembly/deserialize/object.ts new file mode 100644 index 0000000..1ff4568 --- /dev/null +++ b/assembly/deserialize/object.ts @@ -0,0 +1,271 @@ +import { unsafeCharCodeAt } from "../custom/util"; +import { CHAR_A, BACK_SLASH, COMMA, CHAR_E, CHAR_F, CHAR_L, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, CHAR_R, BRACE_RIGHT, BRACKET_RIGHT, CHAR_S, CHAR_T, CHAR_U } from "../custom/chars"; +import { isSpace } from "util/string"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeObject(data: string): T { + const schema: nonnull = changetype>( + __new(offsetof>(), idof>()) + ); + + // @ts-ignore + schema.__INITIALIZE(); + + let key_start: i32 = 0; + let key_end: i32 = 0; + let isKey = false; + let depth = 0; + let outerLoopIndex = 1; + for (; outerLoopIndex < data.length - 1; outerLoopIndex++) { + const char = unsafeCharCodeAt(data, outerLoopIndex); + if (char === BRACKET_LEFT) { + for ( + let arrayValueIndex = outerLoopIndex; + arrayValueIndex < data.length - 1; + arrayValueIndex++ + ) { + const char = unsafeCharCodeAt(data, arrayValueIndex); + if (char === BRACKET_LEFT) { + depth++; + } else if (char === BRACKET_RIGHT) { + depth--; + if (depth === 0) { + ++arrayValueIndex; + // @ts-ignore + schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex, arrayValueIndex); + outerLoopIndex = arrayValueIndex; + isKey = false; + break; + } + } + } + } else if (char === BRACE_LEFT) { + for ( + let objectValueIndex = outerLoopIndex; + objectValueIndex < data.length - 1; + objectValueIndex++ + ) { + const char = unsafeCharCodeAt(data, objectValueIndex); + if (char === BRACE_LEFT) { + depth++; + } else if (char === BRACE_RIGHT) { + depth--; + if (depth === 0) { + ++objectValueIndex; + // @ts-ignore + schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex, objectValueIndex); + outerLoopIndex = objectValueIndex; + isKey = false; + break; + } + } + } + } else if (char === QUOTE) { + let escaping = false; + for ( + let stringValueIndex = ++outerLoopIndex; + stringValueIndex < data.length - 1; + stringValueIndex++ + ) { + const char = unsafeCharCodeAt(data, stringValueIndex); + if (char === BACK_SLASH && !escaping) { + escaping = true; + } else { + if (char === QUOTE && !escaping) { + if (isKey === false) { + key_start = outerLoopIndex; + key_end = stringValueIndex; + isKey = true; + } else { + // @ts-ignore + schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex - 1, stringValueIndex + 1); + isKey = false; + } + outerLoopIndex = ++stringValueIndex; + break; + } + escaping = false; + } + } + } else if ( + char == CHAR_N && + unsafeCharCodeAt(data, outerLoopIndex + 1) === CHAR_U && + unsafeCharCodeAt(data, outerLoopIndex + 2) === CHAR_L && + unsafeCharCodeAt(data, outerLoopIndex + 3) === CHAR_L + ) { + // @ts-ignore + schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex, outerLoopIndex + 4); + outerLoopIndex += 3; + isKey = false; + } else if ( + char === CHAR_T && + unsafeCharCodeAt(data, outerLoopIndex + 1) === CHAR_R && + unsafeCharCodeAt(data, outerLoopIndex + 2) === CHAR_U && + unsafeCharCodeAt(data, outerLoopIndex + 3) === CHAR_E + ) { + // @ts-ignore + schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex, outerLoopIndex + 4); + outerLoopIndex += 3; + isKey = false; + } else if ( + char === CHAR_F && + unsafeCharCodeAt(data, outerLoopIndex + 1) === CHAR_A && + unsafeCharCodeAt(data, outerLoopIndex + 2) === CHAR_L && + unsafeCharCodeAt(data, outerLoopIndex + 3) === CHAR_S && + unsafeCharCodeAt(data, outerLoopIndex + 4) === CHAR_E + ) { + // @ts-ignore + schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex, outerLoopIndex + 5); + outerLoopIndex += 4; + isKey = false; + } else if ((char >= 48 && char <= 57) || char === 45) { + let numberValueIndex = ++outerLoopIndex; + for (; numberValueIndex < data.length; numberValueIndex++) { + const char = unsafeCharCodeAt(data, numberValueIndex); + if (char === COMMA || char === BRACE_RIGHT || isSpace(char)) { + // @ts-ignore + schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex - 1, numberValueIndex); + outerLoopIndex = numberValueIndex; + isKey = false; + break; + } + } + } + } + return schema; +} + +// @ts-ignore: Decorator valid here +@inline export function deserializeObject_Safe(data: string): T { + const firstChar = load(changetype(data)); + if (firstChar != BRACE_LEFT) throw new Error("Mismatched Types! Expected " + nameof() + " but got \"" + data.slice(0, 100) + "\" instead!"); + const schema: nonnull = changetype>( + __new(offsetof>(), idof>()) + ); + + // @ts-ignore + schema.__INITIALIZE(); + + let key_start: i32 = 0; + let key_end: i32 = 0; + let isKey = false; + let depth = 0; + let outerLoopIndex = 1; + for (; outerLoopIndex < data.length - 1; outerLoopIndex++) { + const char = unsafeCharCodeAt(data, outerLoopIndex); + if (char === BRACKET_LEFT) { + for ( + let arrayValueIndex = outerLoopIndex; + arrayValueIndex < data.length - 1; + arrayValueIndex++ + ) { + const char = unsafeCharCodeAt(data, arrayValueIndex); + if (char === BRACKET_LEFT) { + depth++; + } else if (char === BRACKET_RIGHT) { + depth--; + if (depth === 0) { + ++arrayValueIndex; + // @ts-ignore + schema.__DESERIALIZE_SAFE(data, key_start, key_end, outerLoopIndex, arrayValueIndex); + outerLoopIndex = arrayValueIndex; + isKey = false; + break; + } + } + } + } else if (char === BRACE_LEFT) { + for ( + let objectValueIndex = outerLoopIndex; + objectValueIndex < data.length - 1; + objectValueIndex++ + ) { + const char = unsafeCharCodeAt(data, objectValueIndex); + if (char === BRACE_LEFT) { + depth++; + } else if (char === BRACE_RIGHT) { + depth--; + if (depth === 0) { + ++objectValueIndex; + // @ts-ignore + schema.__DESERIALIZE_SAFE(data, key_start, key_end, outerLoopIndex, objectValueIndex); + outerLoopIndex = objectValueIndex; + isKey = false; + break; + } + } + } + } else if (char === QUOTE) { + let escaping = false; + for ( + let stringValueIndex = ++outerLoopIndex; + stringValueIndex < data.length - 1; + stringValueIndex++ + ) { + const char = unsafeCharCodeAt(data, stringValueIndex); + if (char === BACK_SLASH && !escaping) { + escaping = true; + } else { + if (char === QUOTE && !escaping) { + if (isKey === false) { + key_start = outerLoopIndex; + key_end = stringValueIndex; + isKey = true; + } else { + // @ts-ignore + schema.__DESERIALIZE_SAFE(data, key_start, key_end, outerLoopIndex - 1, stringValueIndex + 1); + isKey = false; + } + outerLoopIndex = ++stringValueIndex; + break; + } + escaping = false; + } + } + } else if ( + char == CHAR_N && + unsafeCharCodeAt(data, outerLoopIndex + 1) === CHAR_U && + unsafeCharCodeAt(data, outerLoopIndex + 2) === CHAR_L && + unsafeCharCodeAt(data, outerLoopIndex + 3) === CHAR_L + ) { + // @ts-ignore + schema.__DESERIALIZE_SAFE(data, key_start, key_end, outerLoopIndex, outerLoopIndex + 4); + outerLoopIndex += 3; + isKey = false; + } else if ( + char === CHAR_T && + unsafeCharCodeAt(data, outerLoopIndex + 1) === CHAR_R && + unsafeCharCodeAt(data, outerLoopIndex + 2) === CHAR_U && + unsafeCharCodeAt(data, outerLoopIndex + 3) === CHAR_E + ) { + // @ts-ignore + schema.__DESERIALIZE_SAFE(data, key_start, key_end, outerLoopIndex, outerLoopIndex + 4); + outerLoopIndex += 3; + isKey = false; + } else if ( + char === CHAR_F && + unsafeCharCodeAt(data, outerLoopIndex + 1) === CHAR_A && + unsafeCharCodeAt(data, outerLoopIndex + 2) === CHAR_L && + unsafeCharCodeAt(data, outerLoopIndex + 3) === CHAR_S && + unsafeCharCodeAt(data, outerLoopIndex + 4) === CHAR_E + ) { + // @ts-ignore + schema.__DESERIALIZE_SAFE(data, key_start, key_end, outerLoopIndex, outerLoopIndex + 5); + outerLoopIndex += 4; + isKey = false; + } else if ((char >= 48 && char <= 57) || char === 45) { + let numberValueIndex = ++outerLoopIndex; + for (; numberValueIndex < data.length; numberValueIndex++) { + const char = unsafeCharCodeAt(data, numberValueIndex); + if (char === COMMA || char === BRACE_RIGHT || isSpace(char)) { + // @ts-ignore + schema.__DESERIALIZE_SAFE(data, key_start, key_end, outerLoopIndex - 1, numberValueIndex); + outerLoopIndex = numberValueIndex; + isKey = false; + break; + } + } + } + } + return schema; +} \ No newline at end of file diff --git a/assembly/deserialize/simd/string.ts b/assembly/deserialize/simd/string.ts deleted file mode 100644 index f564a66..0000000 --- a/assembly/deserialize/simd/string.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { BACK_SLASH } from "../../custom/chars"; -import { DESERIALIZE_ESCAPE_TABLE, ESCAPE_HEX_TABLE } from "../../globals/tables"; - -const SPLAT_92 = i16x8.splat(92); /* \ */ - -/** - * Deserializes strings back into into their original form using SIMD operations - * @param src string to deserialize - * @param dst buffer to write to - * @returns number of bytes written - */ -// todo: optimize and stuff. it works, its not pretty. ideally, i'd like this to be (nearly) branchless -// @ts-ignore: Decorator -@inline export function deserializeString_SIMD(src: string, srcStart: usize, srcEnd: usize, dst: usize): usize { - let src_ptr = srcStart + 2; - let dst_ptr = changetype(dst); - - const src_end = srcEnd - 2; - const src_end_15 = src_end - 15; - - while (src_ptr < src_end_15) { - const block = v128.load(src_ptr); - v128.store(dst_ptr, block); - - const backslash_indices = i16x8.eq(block, SPLAT_92); - let mask = i16x8.bitmask(backslash_indices); - - while (mask != 0) { - const lane_index = ctz(mask) << 1; - const dst_offset = dst_ptr + lane_index; - const src_offset = src_ptr + lane_index; - const code = load(src_offset, 2); - - mask &= mask - 1; - if (code == 117 && load(src_offset, 4) == 3145776) { - const block = load(src_offset, 8); - const codeA = block & 0xffff; - const codeB = (block >> 16) & 0xffff; - const escapedA = load(ESCAPE_HEX_TABLE + codeA); - const escapedB = load(ESCAPE_HEX_TABLE + codeB); - const escaped = (escapedA << 4) + escapedB; - // console.log("Escaped:"); - // console.log(" a: " + escapedA.toString()) - // console.log(" b: " + escapedB.toString()); - // console.log(" c: " + escaped.toString()); - // console.log(" o: " + (dst_ptr - dst).toString()); - // console.log(" d: " + (dst_offset - dst).toString()) - // console.log(" l: " + (lane_index).toString()) - store(dst_offset, escaped); - v128.store(dst_offset, v128.load(src_offset, 4), 2); - if (lane_index >= 6) { - const bytes_left = lane_index - 4; - src_ptr += bytes_left; - dst_ptr += bytes_left; - // console.log(" e: " + (bytes_left).toString()) - } - dst_ptr -= 10; - } else { - const escaped = load(DESERIALIZE_ESCAPE_TABLE + code); - store(dst_offset, escaped); - v128.store(dst_offset, v128.load(src_offset, 4), 2); - // console.log("Escaped:"); - if (lane_index == 14) { - src_ptr += 2; - } else { - dst_ptr -= 2; - } - } - } - - src_ptr += 16; - dst_ptr += 16; - - // console.log("src: " + (src_ptr - changetype(src)).toString()); - // console.log("dst: " + (dst_ptr - dst).toString()); - } - while (src_ptr < src_end) { - let code = load(src_ptr); - if (code == BACK_SLASH) { - code = load(DESERIALIZE_ESCAPE_TABLE + load(src_ptr, 2)); - if (code == 117 && load(src_ptr, 4) == 3145776) { - const block = load(src_ptr, 8); - const codeA = block & 0xffff; - const codeB = (block >> 16) & 0xffff; - const escapedA = load(ESCAPE_HEX_TABLE + codeA); - const escapedB = load(ESCAPE_HEX_TABLE + codeB); - const escaped = (escapedA << 4) + escapedB; - store(dst_ptr, escaped); - dst_ptr += 2; - src_ptr += 12; - } else { - store(dst_ptr, code); - dst_ptr += 2; - src_ptr += 4; - } - } else { - store(dst_ptr, code); - dst_ptr += 2; - src_ptr += 2; - } - } - - return dst_ptr - dst; -} diff --git a/assembly/deserialize/simple/arbitrary.ts b/assembly/deserialize/simple/arbitrary.ts deleted file mode 100644 index c955585..0000000 --- a/assembly/deserialize/simple/arbitrary.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { JSON } from "../.."; -import { unsafeCharCodeAt } from "../../custom/util"; -import { deserializeBoolean } from "./bool"; -import { deserializeFloat } from "./float"; -import { deserializeInteger } from "./integer"; -import { deserializeObject } from "./object"; -import { deserializeString } from "./string"; - -// @ts-ignore -@inline export function deserializeArbitrary(data: string): JSON.Value { - const firstChar = unsafeCharCodeAt(data, 0); - - if (firstChar == 34) return JSON.Value.from(deserializeString(data)); - if (firstChar == 123) return JSON.Value.from(deserializeObject(data)); - if (firstChar > 47 && firstChar < 58) return JSON.Value.from(data.includes(".") ? deserializeInteger(data) : deserializeFloat(data)); - if (firstChar == 45) return JSON.Value.from(data.includes(".") ? deserializeInteger(data) : deserializeFloat(data)); - if (firstChar == 91) { - // array - } - if (firstChar == 116 || firstChar == 102) return JSON.Value.from(deserializeBoolean(data)); - return unreachable(); -} diff --git a/assembly/deserialize/simple/array/array.ts b/assembly/deserialize/simple/array/array.ts deleted file mode 100644 index ab3af9a..0000000 --- a/assembly/deserialize/simple/array/array.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { BRACKET_LEFT, BRACKET_RIGHT } from "../../../custom/chars"; -import { JSON } from "../../../"; -import { unsafeCharCodeAt } from "../../../custom/util"; - -export function deserializeArrayArray(data: string): T { - const result = instantiate(); - let lastPos = 0; - let depth = 0; - let i = 1; - // Find start of bracket - //for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) {} - //i++; - for (; i < data.length - 1; i++) { - const char = unsafeCharCodeAt(data, i); - if (char == BRACKET_LEFT) { - if (depth == 0) { - lastPos = i; - } - // Shifting is 6% faster than incrementing - depth++; - } else if (char == BRACKET_RIGHT) { - depth--; - if (depth == 0) { - i++; - result.push(JSON.parse>(data.slice(lastPos, i))); - } - } - } - return result; -} diff --git a/assembly/deserialize/simple/array/bool.ts b/assembly/deserialize/simple/array/bool.ts deleted file mode 100644 index 0a29bb8..0000000 --- a/assembly/deserialize/simple/array/bool.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { CHAR_E, CHAR_F, CHAR_T } from "../../../custom/chars"; - -// @ts-ignore: Decorator valid here -@inline export function deserializeBooleanArray(srcStart: usize, srcEnd: usize, dst: usize): T { - const out = changetype(dst); - while (srcStart < srcEnd) { - const code = load(srcStart); - if (code == CHAR_T && load(srcStart, 8) == CHAR_E) { - out.push(true); - srcStart += 10; - } else if (code == CHAR_F && load(srcStart, 10) == CHAR_E) { - out.push(false); - srcStart += 12; - } - srcStart += 2; - } - return out; -} diff --git a/assembly/deserialize/simple/array/float.ts b/assembly/deserialize/simple/array/float.ts deleted file mode 100644 index fa58c48..0000000 --- a/assembly/deserialize/simple/array/float.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { isSpace } from "../../../util"; -import { unsafeCharCodeAt } from "../../../custom/util"; -import { COMMA, BRACKET_RIGHT, BRACE_RIGHT } from "../../../custom/chars"; -import { deserializeFloat } from "../float"; -import { JSON } from "../../.."; - -// @ts-ignore: Decorator valid here -@inline export function deserializeFloatArray(srcStart: usize, srcEnd: usize, dst: usize): T { - const out = changetype(dst); - let lastIndex: usize = 0; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (code - 48 <= 9 || code == 45) { - lastIndex = srcStart; - srcStart += 2; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) { - out.push(JSON.__deserialize>(lastIndex, srcStart)); - // while (isSpace(load((srcStart += 2)))) { - // /* empty */ - // } - break; - } - srcStart += 2; - } - } - srcStart += 2; - } - return out; -} diff --git a/assembly/deserialize/simple/array/integer.ts b/assembly/deserialize/simple/array/integer.ts deleted file mode 100644 index bcbf83f..0000000 --- a/assembly/deserialize/simple/array/integer.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { isSpace } from "../../../util"; -import { COMMA, BRACE_RIGHT } from "../../../custom/chars"; -import { JSON } from "../../.."; - -// @ts-ignore: Decorator valid here -@inline export function deserializeIntegerArray(srcStart: usize, srcEnd: usize, dst: usize): T { - const out = changetype(dst); - let lastIndex: usize = 0; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (code - 48 <= 9 || code == 45) { - lastIndex = srcStart; - srcStart += 2; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) { - out.push(JSON.__deserialize>(lastIndex, srcStart)); - // while (isSpace(load((srcStart += 2)))) { - // /* empty */ - // } - break; - } - srcStart += 2; - } - } - srcStart += 2; - } - return out; -} diff --git a/assembly/deserialize/simple/array/map.ts b/assembly/deserialize/simple/array/map.ts deleted file mode 100644 index d16abca..0000000 --- a/assembly/deserialize/simple/array/map.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BRACE_LEFT, BRACE_RIGHT } from "../../../custom/chars"; -import { JSON } from "../../.."; -import { unsafeCharCodeAt } from "../../../custom/util"; - -export function deserializeMapArray[]>(srcStart: usize, srcEnd: usize, dst: usize): T { - const out = instantiate(); - let lastPos: usize = 2; - let depth: u32 = 0; - while (srcStart < srcEnd) { - - } - return out; -} diff --git a/assembly/deserialize/simple/array/object.ts b/assembly/deserialize/simple/array/object.ts deleted file mode 100644 index d8da9a8..0000000 --- a/assembly/deserialize/simple/array/object.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { BRACE_LEFT, BRACE_RIGHT } from "../../../custom/chars"; -import { JSON } from "../../.."; -import { unsafeCharCodeAt } from "../../../custom/util"; - -export function deserializeObjectArray(data: string): T { - const result = instantiate(); - let lastPos: u32 = 1; - let depth: u32 = 0; - for (let pos: u32 = 0; pos < data.length; pos++) { - const char = unsafeCharCodeAt(data, pos); - if (char == BRACE_LEFT) { - if (depth == 0) { - lastPos = pos; - } - depth++; - } else if (char == BRACE_RIGHT) { - depth--; - if (depth == 0) { - pos++; - result.push(JSON.parse>(data.slice(lastPos, pos))); - //lastPos = pos + 2; - } - } - } - return result; -} diff --git a/assembly/deserialize/simple/array/string.ts b/assembly/deserialize/simple/array/string.ts deleted file mode 100644 index a4f1b12..0000000 --- a/assembly/deserialize/simple/array/string.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { JSON } from "../../.."; -import { BACK_SLASH, QUOTE } from "../../../custom/chars"; - -// @ts-ignore: Decorator valid here -@inline export function deserializeStringArray(srcStart: usize, srcEnd: usize, dst: usize): string[] { - const out = changetype(dst); - let lastPos = 2; - let inString = false; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (code == QUOTE) { - if (!inString) { - inString = true; - lastPos = srcStart; - } else if (load(srcStart - 2) != BACK_SLASH) { - out.push(JSON.__deserialize(lastPos, srcStart)); - inString = false; - } - } - srcStart += 2; - } - return out; -} diff --git a/assembly/deserialize/simple/bool.ts b/assembly/deserialize/simple/bool.ts deleted file mode 100644 index 84938a8..0000000 --- a/assembly/deserialize/simple/bool.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { CHAR_F, CHAR_T } from "../../custom/chars"; -import { unsafeCharCodeAt } from "../../custom/util"; - -/** - * Deserialize a string to type boolean - * @param data data to parse - * @returns boolean - */ -// @ts-ignore: Decorator valid here -@inline export function deserializeBoolean(data: string, start: i32 = 0, end: i32 = 0): boolean { - if (!end) end = data.length; - const len = end - start; - const ptr = changetype(data) + (start << 1); - const firstChar = unsafeCharCodeAt(data, start); - if (len == 4 && firstChar == CHAR_T && load(ptr) == 28429475166421108) return true; - else if (len == 5 && firstChar == CHAR_F && load(ptr, 2) == 28429466576093281) return false; - return false; //ERROR(`Expected to find boolean, but found "${data.slice(0, 100)}" instead!`); -} - -// @ts-ignore: Decorator valid here -@inline export function deserializeBoolean_NEW(srcStart: usize, srcEnd: usize): boolean { - const srcSize = srcEnd - srcStart; - const firstChar = load(srcStart); - if (srcSize == 4 && firstChar == CHAR_T && load(srcStart) == 28429475166421108) return true; - else if (srcSize == 5 && firstChar == CHAR_F && load(srcSize, 2) == 28429466576093281) return false; - return false; //ERROR(`Expected to find boolean, but found "${data.slice(0, 100)}" instead!`); -} diff --git a/assembly/deserialize/simple/date.ts b/assembly/deserialize/simple/date.ts deleted file mode 100644 index 0ae071f..0000000 --- a/assembly/deserialize/simple/date.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { QUOTE } from "../../custom/chars"; - -// @ts-ignore: Decorator valid here -@inline export function deserializeDate(dateTimeString: string): Date { - // Use AssemblyScript's date parser - const d = Date.fromString(dateTimeString); - - // Return a new object instead of the one that the parser returned. - // This may seem redundant, but addreses the issue when Date - // is globally aliased to wasi_Date (or some other superclass). - return new Date(d.getTime()); -} - -// @ts-ignore: Decorator valid here -@inline export function deserializeDate_NEW(srcStart: usize, srcEnd: usize): Date { - // Use AssemblyScript's date parser - const d = Date.fromString(str(srcStart, srcEnd)); - - // Return a new object instead of the one that the parser returned. - // This may seem redundant, but addreses the issue when Date - // is globally aliased to wasi_Date (or some other superclass). - return new Date(d.getTime()); -} - -function str(start: usize, end: usize): string { - const size = end - start; - const out = __new(size, idof()); - memory.copy(out, start, size); - return changetype(out); -} \ No newline at end of file diff --git a/assembly/deserialize/simple/float.ts b/assembly/deserialize/simple/float.ts deleted file mode 100644 index ced0057..0000000 --- a/assembly/deserialize/simple/float.ts +++ /dev/null @@ -1,26 +0,0 @@ -// @ts-ignore: Decorator valid here -@inline export function deserializeFloat(data: string): T { - // @ts-ignore - const type: T = 0; - // @ts-ignore - if (type instanceof f64) return f64.parse(data); - // @ts-ignore - return f32.parse(data); -} - -// @ts-ignore: Decorator valid here -@inline export function deserializeFloat_NEW(srcStart: usize, srcEnd: usize): T { - // @ts-ignore - const type: T = 0; - // @ts-ignore - if (type instanceof f64) return f64.parse(str(srcStart, srcEnd)); - // @ts-ignore - return f32.parse(str(srcStart, srcEnd)); -} - -function str(start: usize, end: usize): string { - const size = end - start; - const out = __new(size, idof()); - memory.copy(out, start, size); - return changetype(out); -} \ No newline at end of file diff --git a/assembly/deserialize/simple/integer.ts b/assembly/deserialize/simple/integer.ts deleted file mode 100644 index aaa2bad..0000000 --- a/assembly/deserialize/simple/integer.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { snip_fast } from "../../custom/util"; -import { strToInt } from "../../util/strToInt"; - -// @ts-ignore: Decorator valid here -@inline export function deserializeInteger(data: string): T { - // @ts-ignore - return snip_fast(data); -} - -// @ts-ignore: Decorator valid here -@inline export function deserializeInteger_NEW(srcStart: usize, srcEnd: usize): T { - return strToInt(srcStart, srcEnd); -} \ No newline at end of file diff --git a/assembly/deserialize/simple/map.ts b/assembly/deserialize/simple/map.ts deleted file mode 100644 index 072b165..0000000 --- a/assembly/deserialize/simple/map.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { JSON } from "../.."; -import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T, COLON } from "../../custom/chars"; -import { isSpace } from "../../util"; - -export function deserializeMap>(srcStart: usize, srcEnd: usize, dst: T | null = null): T { - // @ts-ignore: type - if (!isString>() && !isInteger>()) ERROR("Map key must be of type string | number!"); - dst = dst || changetype>(__new(offsetof>(), idof>())); - console.log("Data: " + str(srcStart, srcEnd)); - - const srcPtr = srcStart; - let key: string | null = null; - let isKey = false; - let depth = 0; - let lastIndex = 0; - - // while (srcStart < srcEnd && isSpace(load(srcStart))) srcStart += 2; - // while (srcEnd > srcStart && isSpace(load(srcEnd))) srcEnd -= 2; - - while (srcStart < srcEnd) { - let code = load(srcStart); // while (isSpace(code)) code = load(srcStart += 2); - if (key == null) { - if (code == QUOTE && load(srcStart - 2) !== BACK_SLASH) { - if (isKey) { - key = sliceTo(lastIndex, srcStart); - console.log("Key: " + key); - while (isSpace((code = load((srcStart += 2))))) { - /* empty */ - } - if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcStart - srcPtr).toString()); - isKey = false; - } else { - isKey = true; // i don't like this - lastIndex = srcStart + 2; - } - } - // isKey = !isKey; - srcStart += 2; - } else { - if (isString>() && code == QUOTE) { - lastIndex = srcStart; - srcStart += 2; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (code == QUOTE && load(srcStart - 2) !== BACK_SLASH) { - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - console.log("Value (string): " + str(lastIndex, srcStart)); - dst.set(key, JSON.__deserialize>(lastIndex, srcStart)); - key = null; - break; - } - srcStart += 2; - } - } else if (!isBoolean>() && isInteger>() && code - 48 <= 9 || code == 45) { - lastIndex = srcStart; - srcStart += 2; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (code == COMMA || isSpace(code) || code == BRACE_RIGHT) { - dst.set(key, JSON.__deserialize>(lastIndex, srcStart)); - console.log("Value (number): " + str(lastIndex, srcStart)); - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - key = null; - break; - } - srcStart += 2; - } - } else if (isArray>() && code == BRACKET_LEFT) { - lastIndex = srcStart; - depth++; - srcStart += 2; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (((code ^ BRACE_RIGHT) | (code ^ BRACKET_RIGHT)) == 32) { - if (--depth == 0) { - dst.set(key, JSON.__deserialize>(lastIndex, srcStart)); - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - key = null; - break; - } - } else if (code == BRACKET_LEFT) depth++; - srcStart += 2; - } - } else if (isDefined(changetype>>(0).__DESERIALIZE) && code == BRACE_LEFT) { - lastIndex = srcStart; - depth++; - srcStart += 2; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (code == BRACE_RIGHT) { - if (--depth == 0) { - dst.set(key, JSON.__deserialize>(lastIndex, srcStart)); - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - key = null; - break; - } - } else if (code == BRACE_LEFT) depth++; - srcStart += 2; - } - } else if (isBoolean>() && code == CHAR_T) { - if (load(srcStart) == 28429475166421108) { - dst.set(key, JSON.__deserialize>(srcStart, srcStart += 8)); - console.log("Value (bool): " + str(srcStart - 8, srcStart)); - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - key = null; - } - } else if (isBoolean>() && code == CHAR_F) { - if (load(srcStart, 2) == 28429466576093281) { - dst.set(key, JSON.__deserialize>(srcStart, srcStart += 10)); - console.log("Value (bool): " + str(srcStart - 10, srcStart)); - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - key = null; - } - } else if ((isNullable() || nameof() == "usize") && code == CHAR_N) { - if (load(srcStart) == 30399761348886638) { - dst.set(key, JSON.__deserialize>(srcStart, srcStart += 8)); - console.log("Value (null): " + str(srcStart - 8, srcStart)); - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - } - } else { - throw new Error("Unexpected character " + String.fromCharCode(code) +" or type " + nameof>() + " does not match found type!") - } - } - } - return dst; -} - -function str(start: usize, end: usize): string { - const size = end - start; - const out = __new(size, idof()); - memory.copy(out, start, size); - return changetype(out); -} - -// @ts-ignore: Decorator valid here -@inline function sliceTo(srcStart: usize, srcEnd: usize): string { - const dstSize = srcEnd - srcStart; - const dst = __new(dstSize, idof()); - memory.copy(dst, srcStart, dstSize); - return changetype(dst); -} \ No newline at end of file diff --git a/assembly/deserialize/simple/object.ts b/assembly/deserialize/simple/object.ts deleted file mode 100644 index 0f79129..0000000 --- a/assembly/deserialize/simple/object.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T, COLON } from "../../custom/chars"; -import { isSpace } from "../../util"; - -export function deserializeObject(srcStart: usize, srcEnd: usize, dst: nonnull = changetype>(__new(offsetof>(), idof>()))): T { - console.log("Data: " + str(srcStart, srcEnd)); - - const srcPtr = srcStart; - - let keyStart: usize = 0; - let keyEnd: usize = 0; - let isKey = false; - let depth = 0; - let lastIndex = 0; - - // while (srcStart < srcEnd && isSpace(load(srcStart))) srcStart += 2; - // while (srcEnd > srcStart && isSpace(load(srcEnd))) srcEnd -= 2; - - while (srcStart < srcEnd) { - let code = load(srcStart); // while (isSpace(code)) code = load(srcStart += 2); - if (keyStart == 0) { - if (code == QUOTE && load(srcStart - 2) !== BACK_SLASH) { - if (isKey) { - keyStart = lastIndex; - keyEnd = srcStart; - console.log("Key: " + str(lastIndex, srcStart)); - while (isSpace((code = load((srcStart += 2))))) { - /* empty */ - } - if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcStart - srcPtr).toString()); - isKey = false; - } else { - isKey = true; // i don't like this - lastIndex = srcStart + 2; - } - } - // isKey = !isKey; - srcStart += 2; - } else { - if (code == QUOTE) { - lastIndex = srcStart; - srcStart += 2; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (code == QUOTE && load(srcStart - 2) !== BACK_SLASH) { - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - console.log("Value (string): " + str(lastIndex, srcStart)); - // @ts-ignore: exists - dst.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart); - keyStart = 0; - break; - } - srcStart += 2; - } - } else if (code - 48 <= 9 || code == 45) { - lastIndex = srcStart; - srcStart += 2; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) { - // @ts-ignore: exists - dst.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart); - console.log("Value (number): " + str(lastIndex, srcStart)); - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - keyStart = 0; - break; - } - srcStart += 2; - } - } else if (code == BRACE_LEFT) { - lastIndex = srcStart; - depth++; - srcStart += 2; - while (srcStart < srcEnd) { - const code = load(srcStart); - if (((code ^ BRACE_RIGHT) | (code ^ BRACKET_RIGHT)) == 32) { - if (--depth == 0) { - // @ts-ignore: exists - dst.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart); - console.log("Value (object): " + str(lastIndex, srcStart)); - keyStart = 0; - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - break; - } - } else if (((code ^ BRACE_LEFT) | (code ^ BRACKET_LEFT)) == 220) depth++; - srcStart += 2; - } - } else if (code == CHAR_T) { - if (load(srcStart) == 28429475166421108) { - // @ts-ignore: exists - dst.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8)); - console.log("Value (bool): " + str(srcStart - 8, srcStart)); - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - keyStart = 0; - } - } else if (code == CHAR_F) { - if (load(srcStart, 2) == 28429466576093281) { - // @ts-ignore: exists - dst.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 10)); - console.log("Value (bool): " + str(srcStart - 10, srcStart)); - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - keyStart = 0; - } - } else if (code == CHAR_N) { - if (load(srcStart) == 30399761348886638) { - // @ts-ignore: exists - dst.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8)); - console.log("Value (null): " + str(srcStart - 8, srcStart)); - while (isSpace(load((srcStart += 2)))) { - /* empty */ - } - } - } - } - } - return dst; -} - -function str(start: usize, end: usize): string { - const size = end - start; - const out = __new(size, idof()); - memory.copy(out, start, size); - return changetype(out); -} diff --git a/assembly/deserialize/simple/string.ts b/assembly/deserialize/simple/string.ts deleted file mode 100644 index 12c1155..0000000 --- a/assembly/deserialize/simple/string.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { BACK_SLASH } from "../../custom/chars"; -import { DESERIALIZE_ESCAPE_TABLE, ESCAPE_HEX_TABLE } from "../../globals/tables"; - -// @ts-ignore: Decorator valid here -@inline export function deserializeString(srcStart: usize, srcEnd: usize, dst: usize = __new(srcEnd - srcStart - 4, idof())): string { - let dstPtr = dst; - let lastPtr = srcStart; - while (srcStart < srcEnd) { - let code = load(srcStart); - if (code == BACK_SLASH) { - code = load(DESERIALIZE_ESCAPE_TABLE + load(srcStart, 2)); - if (code == 117 && load(srcStart, 4) == 3145776) { - const block = load(srcStart, 8); - const codeA = block & 0xffff; - const codeB = (block >> 16) & 0xffff; - const escapedA = load(ESCAPE_HEX_TABLE + codeA); - const escapedB = load(ESCAPE_HEX_TABLE + codeB); - const escaped = (escapedA << 4) + escapedB; - const remBytes = srcStart - lastPtr; - memory.copy(dstPtr, lastPtr, remBytes); - dstPtr += remBytes; - store(dst, escaped); - dstPtr += 2; - srcStart += 12; - lastPtr = srcStart; - } else { - const remBytes = srcStart - lastPtr; - memory.copy(dstPtr, lastPtr, remBytes); - dstPtr += remBytes; - store(dstPtr, code); - dstPtr += 2; - srcStart += 4; - lastPtr = srcStart; - } - } else { - srcStart += 2; - } - } - - const remBytes = srcEnd - lastPtr; - memory.copy(dstPtr, lastPtr, remBytes); - dstPtr += remBytes; - - if (lastPtr != srcStart) dst = __renew(dst, dstPtr - dst); - return changetype(dst); -} diff --git a/assembly/deserialize/string.ts b/assembly/deserialize/string.ts new file mode 100644 index 0000000..bcf05b2 --- /dev/null +++ b/assembly/deserialize/string.ts @@ -0,0 +1,164 @@ +import { + CHAR_B, + BACK_SLASH, + BACKSPACE, + CARRIAGE_RETURN, + CHAR_F, + FORM_FEED, + FWD_SLASH, + CHAR_N, + NEW_LINE, + QUOTE, + CHAR_R, + CHAR_T, + TAB, + CHAR_U +} from "../custom/chars"; +import { Sink } from "../custom/sink"; +import { unsafeCharCodeAt } from "../custom/util"; + +// @ts-ignore: Decorator valid here +@inline export function deserializeString(data: string, start: i32 = 0, end: i32 = 0): string { + end = end || data.length - 1; + let result = Sink.withCapacity(end - start - 1); + let last = start + 1; + for (let i = last; i < end; i++) { + if (unsafeCharCodeAt(data, i) !== BACK_SLASH) { + continue; + } + const char = unsafeCharCodeAt(data, ++i); + result.write(data, last, i - 1); + switch (char) { + case QUOTE: { + result.writeCodePoint(QUOTE); + last = i + 1; + break; + } + case BACK_SLASH: { + result.writeCodePoint(BACK_SLASH); + last = i + 1; + break; + } + case FWD_SLASH: { + result.writeCodePoint(FWD_SLASH); + last = i + 1; + break; + } + case CHAR_B: { + result.writeCodePoint(BACKSPACE); + last = i + 1; + break; + } + case CHAR_F: { + result.writeCodePoint(FORM_FEED); + last = i + 1; + break; + } + case CHAR_N: { + result.writeCodePoint(NEW_LINE); + last = i + 1; + break; + } + case CHAR_R: { + result.writeCodePoint(CARRIAGE_RETURN); + last = i + 1; + break; + } + case CHAR_T: { + result.writeCodePoint(TAB); + last = i + 1; + break; + } + case CHAR_U: { + const code = u16.parse(data.slice(i + 1, i + 5), 16); + result.writeCodePoint(code); + i += 4; + last = i + 1; + break; + } + default: { + throw new Error(`JSON: Cannot parse "${data}" as string. Invalid escape sequence: \\${data.charAt(i)}`); + } + } + } + if (end > last) { + result.write(data, last, end); + } + return result.toString() +} + +// @ts-ignore: Decorator valid here +// @inline export function deserializeString_BS(data: string, start: i32 = 0, end: i32 = 0): void { +// end = end || data.length - 1; +// let last = start + 1; +// for (let i = last; i < end; i++) { +// if (unsafeCharCodeAt(data, i) !== BACK_SLASH) { +// continue; +// } +// const char = unsafeCharCodeAt(data, ++i); +// bs.write_s_se_u(data, last, i - 1); +// switch (char) { +// case QUOTE: { +// bs.write_8(QUOTE); +// last = i + 1; +// break; +// } +// case BACK_SLASH: { +// bs.write_8(BACK_SLASH); +// last = i + 1; +// break; +// } +// case FWD_SLASH: { +// bs.write_8(FWD_SLASH); +// last = i + 1; +// break; +// } +// case CHAR_B: { +// bs.write_8(BACKSPACE); +// last = i + 1; +// break; +// } +// case CHAR_F: { +// bs.write_8(FORM_FEED); +// last = i + 1; +// break; +// } +// case CHAR_N: { +// bs.write_8(NEW_LINE); +// last = i + 1; +// break; +// } +// case CHAR_R: { +// bs.write_8(CARRIAGE_RETURN); +// last = i + 1; +// break; +// } +// case CHAR_T: { +// bs.write_8(TAB); +// last = i + 1; +// break; +// } +// case CHAR_U: { + +// const code = u16.parse(data.slice(i + 1, i + 5), 16); +// bs.w(code); +// i += 4; +// last = i + 1; +// break; +// } +// default: { +// throw new Error(`JSON: Cannot parse "${data}" as string. Invalid escape sequence: \\${data.charAt(i)}`); +// } +// } +// } +// if (end > last) { +// result.write(data, last, end); +// } +// } + +// @ts-ignore: Decorator valid here +@inline export function deserializeString_Safe(data: string, start: i32 = 0, end: i32 = 0): string { + const firstChar = load(changetype(data)); + if (firstChar != QUOTE) throw new Error("Mismatched Types! Expected string but got \""+data.slice(0, 100)+"\" instead!"); + return deserializeString(data, start, end); +} \ No newline at end of file diff --git a/assembly/globals/tables.ts b/assembly/globals/tables.ts deleted file mode 100644 index c2d8caa..0000000 --- a/assembly/globals/tables.ts +++ /dev/null @@ -1,413 +0,0 @@ -export const SERIALIZE_ESCAPE_TABLE = memory.data([ - 48, - 48, - 48, - 49, - 48, - 50, - 48, - 51, // Pair 0-3 - 48, - 52, - 48, - 53, - 48, - 54, - 48, - 55, // Pair 4-7 - - 92, - 98, - 92, - 116, - 92, - 110, - 48, - 98, // Pair 8-11 - 92, - 102, - 92, - 114, - 48, - 101, - 48, - 102, // Pair 12-15 - - 49, - 48, - 49, - 49, - 49, - 50, - 49, - 51, // Pair 16-19 - 49, - 52, - 49, - 53, - 49, - 54, - 49, - 55, // Pair 20-23 - - 49, - 56, - 49, - 57, - 49, - 97, - 49, - 98, // Pair 24-27 - 49, - 99, - 49, - 100, - 49, - 101, - 49, - 102, // Pair 28-31 - - 0, - 0, - 0, - 0, - 92, - 34, - 0, - 0, // Pair 32-35 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 36-39 - - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 40-43 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 44-47 - - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 48-51 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 52-55 - - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 56-59 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 60-63 - - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 64-67 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 68-71 - - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 72-75 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 76-79 - - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 80-83 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 84-87 - - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // Pair 88-91 - 92, - 92, // Pair 92-93 -]); - -export const DESERIALIZE_ESCAPE_TABLE = memory.data([ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 0-7 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 8-15 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 16-23 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 24-31 - 0, - 0, - 34, - 0, - 0, - 0, - 0, - 0, // 32-39 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 40-47 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 48-55 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 56-63 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 64-71 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 72-79 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 80-87 - 0, - 0, - 0, - 0, - 92, - 0, - 0, - 0, // 88-95 - 0, - 0, - 8, - 0, - 0, - 0, - 12, - 0, // 96-103 - 0, - 0, - 0, - 0, - 0, - 0, - 10, - 0, // 104-111 - 0, - 0, - 13, - 0, - 9, - 117, - 0, - 0, // 112-119 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 120-127 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 128-135 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 136-143 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 144-151 -]); - -export const ESCAPE_HEX_TABLE = - memory.data([ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, // 0-7 - 8, - 9, - 0, - 0, - 0, - 0, - 0, - 0, // 8-15 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 16-23 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 24-31 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 32-39 - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // 40-47 - 0, - 10, - 11, - 12, - 13, - 14, - 15, // 48-54 - ]) - 48; diff --git a/assembly/index.d.ts b/assembly/index.d.ts index 35171ba..8d23a77 100644 --- a/assembly/index.d.ts +++ b/assembly/index.d.ts @@ -1,31 +1,35 @@ /** - * Class decorator that enables the class to be recognized as JSON. + * Class decorator that enables the class to be serializable as JSON. */ -declare function json(..._): void; +declare function json(target: any): void; /** - * Class decorator that enables the class to be recognized as JSON. + * Class decorator that enables the class to be serializable as JSON. */ -declare function serializable(..._): void; +declare function serializable(target: any): void; /** * Property decorator that provides an alias name for JSON serialization. */ -declare function alias(newName: string): Function; +declare function alias(name: string): Function; /** * Property decorator that allows omits a field, making it be ignored. */ -declare function omit(..._): void; +declare function omit(): Function; /** * Property decorator that allows a field to be omitted when equal to an Expression. */ -declare function omitif(condition: string | ((value: any) => boolean)): Function; +declare function omitif(condition: string): Function; /** * Property decorator that allows a field to be omitted when a property is null. */ -declare function omitnull(..._): Function; +declare function omitnull(): Function; -declare type Raw = number; +/** + * Property decorator that allows a field to be flattened. + * @param fieldName - Points to the field to flatten. Can use dot-notation here like @omit("foo.identifier.text") + */ +declare function flatten(fieldName: string = "value"): Function; diff --git a/assembly/index.ts b/assembly/index.ts index a9c5102..27e00d5 100644 --- a/assembly/index.ts +++ b/assembly/index.ts @@ -1,29 +1,23 @@ /// -import { serializeString } from "./serialize/simple/string"; -import { serializeArray } from "./serialize/simple/array"; -import { serializeMap } from "./serialize/simple/map"; -import { deserializeBoolean, deserializeBoolean_NEW } from "./deserialize/simple/bool"; -import { deserializeArray } from "./deserialize/simple/array"; -import { deserializeFloat, deserializeFloat_NEW } from "./deserialize/simple/float"; -import { deserializeObject } from "./deserialize/simple/object"; -import { deserializeMap } from "./deserialize/simple/map"; -import { deserializeDate } from "./deserialize/simple/date"; -import { deserializeInteger, deserializeInteger_NEW } from "./deserialize/simple/integer"; -import { deserializeString, deserializeString } from "./deserialize/simple/string"; -import { serializeArbitrary } from "./serialize/simple/arbitrary"; - +import { serializeString } from "./serialize/string"; +import { serializeBool } from "./serialize/bool"; +import { serializeInteger } from "./serialize/integer"; +import { serializeFloat } from "./serialize/float"; +import { serializeObject } from "./serialize/object"; +import { serializeDate } from "./serialize/date"; +import { serializeArray } from "./serialize/array"; +import { serializeMap } from "./serialize/map"; +import { deserializeBoolean, deserializeBoolean_Safe } from "./deserialize/bool"; +import { deserializeArray, deserializeArray_Safe } from "./deserialize/array"; +import { deserializeFloat } from "./deserialize/float"; +import { deserializeObject, deserializeObject_Safe } from "./deserialize/object"; +import { deserializeMap, deserializeMap_Safe } from "./deserialize/map"; +import { deserializeDate } from "./deserialize/date"; +import { NULL_WORD } from "./custom/chars"; +import { deserializeInteger, deserializeInteger_Safe } from "./deserialize/integer"; +import { deserializeString, deserializeString_Safe } from "./deserialize/string"; import { Sink } from "./custom/sink"; -import { NULL_WORD, QUOTE } from "./custom/chars"; -import { bs } from "as-bs"; -import { dtoa_buffered, itoa_buffered } from "util/number"; -import { serializeBool } from "./serialize/simple/bool"; -import { serializeInteger } from "./serialize/simple/integer"; -import { serializeFloat } from "./serialize/simple/float"; -import { serializeObject } from "./serialize/simple/object"; - -class Nullable {} - -export type Raw = string; +import { getArrayDepth } from "./custom/util"; /** * Offset of the 'storage' property in the JSON.Value class. @@ -35,140 +29,6 @@ export type Raw = string; * JSON Encoder/Decoder for AssemblyScript */ export namespace JSON { - /** - * Serializes valid JSON data - * ```js - * JSON.stringify(data) - * ``` - * @param data T - * @returns string - */ - export function stringify(data: T, out: string | null = null): string { - if (isBoolean(data)) { - if (out) { - if (data == true) { - out = changetype(__renew(changetype(out), 8)); - store(changetype(out), 28429475166421108); - } else { - out = changetype(__renew(changetype(out), 10)); - store(changetype(out), 32370086184550502); - store(changetype(out), 101, 8); - } - return out; - } - return out ? "true" : "false"; - } else if (isInteger() && nameof() == "usize" && data == 0) { - if (out) { - out = changetype(__renew(changetype(out), 8)); - store(changetype(out), 30399761348886638); - return out; - } - return NULL_WORD; - } else if (isInteger(data)) { - if (out) { - out = changetype(__renew(changetype(out), sizeof() << 3)); - - // @ts-ignore - const bytes = itoa_buffered(changetype(out), data) << 1; - return (out = changetype(__renew(changetype(out), bytes))); - } - return data.toString(); - } else if (isFloat(data)) { - if (out) { - out = changetype(__renew(changetype(out), 64)); - - // @ts-ignore - const bytes = dtoa_buffered(changetype(out), data) << 1; - return (out = changetype(__renew(changetype(out), bytes))); - } - return data.toString(); - // @ts-ignore: Function is generated by transform - } else if (isNullable() && changetype(data) == 0) { - if (out) { - out = changetype(__renew(changetype(out), 8)); - store(changetype(out), 30399761348886638); - return out; - } - return NULL_WORD; - // @ts-ignore - } else if (isString>()) { - serializeString(changetype(data)); - return bs.shrinkTo(); - // @ts-ignore: Supplied by transform - } else if (isDefined(data.__SERIALIZE_BS) && isDefined(data.__ALLOCATE)) { - // @ts-ignore - data.__ALLOCATE(); - // @ts-ignore - data.__SERIALIZE_BS(changetype(data), false); - return bs.out(); - // @ts-ignore: Supplied by transform - } else if (isDefined(data.__SERIALIZE)) { - // @ts-ignore - return data.__SERIALIZE(changetype(data)); - } else if (data instanceof Date) { - out = out ? changetype(__renew(changetype(out), 52)) : changetype(__new(52, idof())); - - store(changetype(out), QUOTE); - memory.copy(changetype(out) + 2, changetype(data.toISOString()), 48); - store(changetype(out), 50); - return out; - } else if (data instanceof Array) { - // @ts-ignore - serializeArray(changetype>(data)); - return bs.shrinkTo(); - } else if (data instanceof Map) { - // @ts-ignore - serializeMap(changetype>(data)); - return bs.shrinkTo(); - } else if (data instanceof JSON.Value) { - serializeArbitrary(data); - return bs.shrinkTo(); - } else { - ERROR(`Could not serialize data of type ${nameof()}. Make sure to add the correct decorators to classes.`); - } - } - - /** - * Parses valid JSON strings into their original format - * ```js - * JSON.parse(data) - * ``` - * @param data string - * @returns T - */ - export function parse(data: string): T { - if (isBoolean()) { - return deserializeBoolean(data) as T; - } else if (isInteger()) { - return deserializeInteger(data); - } else if (isFloat()) { - return deserializeFloat(data); - } else if (isNullable() && data.length == 4 && data == "null") { - // @ts-ignore - return null; - } else if (isString()) { - // @ts-ignore - return deserializeString(data); - } else if (isArray()) { - // @ts-ignore - return deserializeArray>(data); - } - let type: nonnull = changetype>(0); - // @ts-ignore: Defined by transform - if (isDefined(type.__DESERIALIZE)) { - // @ts-ignore - return deserializeObject>(data.trimStart()); - } else if (type instanceof Map) { - // @ts-ignore - return deserializeMap>(data.trimStart()); - } else if (type instanceof Date) { - // @ts-ignore - return deserializeDate(data); - } else { - ERROR(`Could not deserialize data ${data} to type ${nameof()}. Make sure to add the correct decorators to classes.`); - } - } - /** * Enum representing the different types supported by JSON. */ @@ -182,23 +42,17 @@ export namespace JSON { F64 = 6, Bool = 7, String = 8, - Object = 9, - Array = 10, - Struct = 11, + Obj = 8, + Array = 9 } - export type Raw = string; - export class Value { - static METHODS: Map = new Map(); public type: i32; // @ts-ignore private storage: u64; - private constructor() { - unreachable(); - } + private constructor() { unreachable(); } /** * Creates an JSON.Value instance from a given value. @@ -247,19 +101,11 @@ export namespace JSON { if (idof() !== idof>()) { abort("Maps must be of type Map!"); } - this.type = JSON.Types.Struct; + this.type = JSON.Types.Obj; store(changetype(this), value, STORAGE); - // @ts-ignore - } else if (isDefined(value.__SERIALIZE)) { - this.type = idof() + JSON.Types.Struct; - // @ts-ignore - if (!JSON.Value.METHODS.has(idof())) JSON.Value.METHODS.set(idof(), value.__SERIALIZE.index); - // @ts-ignore - store(changetype(this), value, STORAGE); - // @ts-ignore - } else if (isArray() && idof>() == idof()) { + } else if (isArray()) { // @ts-ignore: T satisfies constraints of any[] - this.type = JSON.Types.Array; + this.type = JSON.Types.Array + getArrayDepth(0); store(changetype(this), value, STORAGE); } } @@ -274,23 +120,18 @@ export namespace JSON { /** * Converts the JSON.Value to a string representation. + * @param useString - If true, treats Buffer as a string. * @returns The string representation of the JSON.Value. */ toString(): string { switch (this.type) { - case JSON.Types.U8: - return this.get().toString(); - case JSON.Types.U16: - return this.get().toString(); - case JSON.Types.U32: - return this.get().toString(); - case JSON.Types.U64: - return this.get().toString(); - case JSON.Types.String: - return '"' + this.get() + '"'; - case JSON.Types.Bool: - return this.get() ? "true" : "false"; - case JSON.Types.Array: { + case JSON.Types.U8: return this.get().toString(); + case JSON.Types.U16: return this.get().toString(); + case JSON.Types.U32: return this.get().toString(); + case JSON.Types.U64: return this.get().toString(); + case JSON.Types.String: return "\"" + this.get() + "\""; + case JSON.Types.Bool: return this.get() ? "true" : "false"; + default: { const arr = this.get(); if (!arr.length) return "[]"; const out = Sink.fromStringLiteral("["); @@ -307,87 +148,165 @@ export namespace JSON { out.write("]"); return out.toString(); } - default: { - const fn = JSON.Value.METHODS.get(this.type - JSON.Types.Struct); - const value = this.get(); - return call_indirect(fn, 0, value); - } } } } - - /** - * Box for primitive types - */ export class Box { - constructor(public value: T) {} - /** - * Creates a reference to a primitive type - * This means that it can create a nullable primitive - * ```js - * JSON.stringify | null>(null); - * // null - * ``` - * @param from T - * @returns Box - */ + constructor(public value: T) { } @inline static from(value: T): Box { return new Box(value); } } - export function __serialize(src: T, staticSize: bool = false): void { + /** + * Stringifies valid JSON data. + * ```js + * JSON.stringify(data) + * ``` + * @param data T + * @returns string + */ + // @ts-ignore: Decorator + @inline export function stringify(data: T/*, options: SerializeOptions = DEFAULT_SERIALIZE_OPTIONS*/): string { if (isBoolean()) { - serializeBool(src as bool, staticSize); + return serializeBool(data as bool); + } else if (isInteger() && nameof() == "usize" && data == 0) { + return NULL_WORD; } else if (isInteger()) { // @ts-ignore - serializeInteger(src, staticSize); - } else if (isFloat(src)) { + return serializeInteger(data); + } else if (isFloat(data)) { // @ts-ignore - serializeFloat(src, staticSize); + return serializeFloat(data); // @ts-ignore: Function is generated by transform - } else if (changetype(src) == 0) { - if (!staticSize) bs.ensureSize(8); - store(bs.offset, 30399761348886638); - bs.offset += 8; + } else if (isNullable() && changetype(data) == 0) { + return NULL_WORD; + // @ts-ignore } else if (isString>()) { - serializeString(src as string, staticSize); + return serializeString(changetype(data)); // @ts-ignore: Supplied by transform - } else if (isDefined(src.__SERIALIZE_BS)) { + } else if (isDefined(data.__SERIALIZE)) { + /*if (options.pretty) { + // @ts-ignore + return serializeObject_Pretty(changetype>(data)); + }*/ // @ts-ignore - serializeObject(changetype>(src), staticSize); - } else if (src instanceof Date) { + return serializeObject(changetype>(data)); + } else if (data instanceof Date) { // @ts-ignore - serializeDate(changetype>(src), staticSize); - } else if (src instanceof Array) { + return serializeDate(changetype>(data)); + } else if (data instanceof Array) { // @ts-ignore - serializeArray(changetype>(src), staticSize); - } else if (src instanceof Map) { + return serializeArray(changetype>(data)); + } else if (data instanceof Map) { // @ts-ignore - serializeMap(changetype>(src), staticSize); - } else if (src instanceof JSON.Value) { - serializeArbitrary(src); + return serializeMap(changetype>(data)); } else { - ERROR(`Could not serialize src of type ${nameof()}. Make sure to add the correct decorators to classes.`); + throw new Error( + `Could not serialize data of type ${nameof()}. Make sure to add the correct decorators to classes.` + ); } } - export function __deserialize(srcStart: usize, srcEnd: usize, dst: usize = 0): T { + /** + * Parses valid JSON strings into their original format. + * ```js + * JSON.parse(data) + * ``` + * @param data string + * @returns T + */ + + // @ts-ignore: Decorator + @inline export function parse(data: string): T { if (isBoolean()) { - // @ts-ignore: type - return deserializeBoolean_NEW(srcStart, srcEnd); + return deserializeBoolean(data) as T; } else if (isInteger()) { - return deserializeInteger_NEW(srcStart, srcEnd); + return deserializeInteger(data); } else if (isFloat()) { - return deserializeFloat_NEW(srcStart, srcEnd); + return deserializeFloat(data); + } else if (isNullable() && data.length === 4 && data == "null") { + // @ts-ignore + return null; } else if (isString()) { - // @ts-ignore: type - return deserializeString(srcStart, srcEnd, dst); + // @ts-ignore + return deserializeString(data); + } else if (isArray()) { + // @ts-ignore + return deserializeArray>(data); + } + let type: nonnull = changetype>(0); + // @ts-ignore: Defined by transform + if (isDefined(type.__DESERIALIZE)) { + // @ts-ignore + return deserializeObject>(data.trimStart()); + } else if (type instanceof Map) { + // @ts-ignore + return deserializeMap>(data.trimStart()); + } else if (type instanceof Date) { + // @ts-ignore + return deserializeDate(data); } else { - let type: nonnull = changetype>(0); - if (type instanceof Map) { - // @ts-ignore: type - return deserializeMap(srcStart, srcEnd, dst) - } + throw new Error( + `Could not deserialize data ${data} to type ${nameof()}. Make sure to add the correct decorators to classes.` + ); + } + } + /** + * Parses valid JSON strings into their original format (safely). + * ```js + * JSON.parseSafe(data) + * ``` + * @param data string + * @returns T + */ + + // @ts-ignore: Decorator + @inline export function parseSafe(data: string): T { + if (isBoolean()) { + return deserializeBoolean_Safe(data) as T; + } else if (isInteger()) { + return deserializeInteger_Safe(data); + } else if (isFloat()) { + return deserializeFloat(data); + } else if (isNullable() && data.length === 4 && data == "null") { + // @ts-ignore + return null; + } else if (isString()) { + // @ts-ignore + return deserializeString_Safe(data); + } else if (isArray()) { + // @ts-ignore + return deserializeArray_Safe>(data); + } + let type: nonnull = changetype>(0); + // @ts-ignore: Defined by transform + if (isDefined(type.__DESERIALIZE)) { + // @ts-ignore + return deserializeObject_Safe>(data.trimStart()); + } else if (type instanceof Map) { + // @ts-ignore + return deserializeMap_Safe>(data.trimStart()); + } else if (type instanceof Date) { + // @ts-ignore + return deserializeDate_Safe(data); + } else { + throw new Error( + `Could not deserialize data ${data} to type ${nameof()}. Make sure to add the correct decorators to classes.` + ); } } } + +// This allows JSON.stringify and JSON.parse to be available globally through an alias +// @ts-ignore: Decorator +@global @inline function __SERIALIZE(data: T): string { + return JSON.stringify(data); +} +// @ts-ignore: Decorator +@global @inline function __DESERIALIZE(data: string): T { + return JSON.parse(data); +} +// @ts-ignore: Decorator +@global @inline function __DESERIALIZE_SAFE(data: string): T { + return JSON.parseSafe(data); +} \ No newline at end of file diff --git a/assembly/serialize/array.ts b/assembly/serialize/array.ts new file mode 100644 index 0000000..ec13dcc --- /dev/null +++ b/assembly/serialize/array.ts @@ -0,0 +1,51 @@ +import { JSON } from ".."; +import { + COMMA, + COMMA_WORD, + EMPTY_BRACKET_WORD, + BRACKET_LEFT_WORD, + BRACKET_RIGHT, + BRACKET_RIGHT_WORD +} from "../custom/chars"; +import { Sink } from "../custom/sink"; +import { serializeString } from "./string"; + +// @ts-ignore: Decorator valid here +@inline export function serializeArray(data: T): string { + if (data.length == 0) { + return EMPTY_BRACKET_WORD; + // @ts-ignore + } else if (isString>()) { + let result = BRACKET_LEFT_WORD; + // @ts-ignore + for (let i = 0; i < data.length - 1; i++) { + // @ts-ignore + result += serializeString(unchecked(data[i])); + result += COMMA_WORD; + } + // @ts-ignore + result += serializeString(unchecked(data[data.length - 1])); + result += BRACKET_RIGHT_WORD; + return result; + // @ts-ignore + } else if (isBoolean>()) { + // @ts-ignore + return BRACKET_LEFT_WORD + data.join(COMMA_WORD) + BRACKET_RIGHT_WORD; + // @ts-ignore + } else if (isFloat>() || isInteger>()) { + // @ts-ignore + return BRACKET_LEFT_WORD + data.join(COMMA_WORD) + BRACKET_RIGHT_WORD; + } else { + let result = Sink.fromString(BRACKET_LEFT_WORD); + // @ts-ignore + for (let i = 0; i < data.length - 1; i++) { + // @ts-ignore + result.write(JSON.stringify(unchecked(data[i]))); + result.writeCodePoint(COMMA); + } + // @ts-ignore + result.write(JSON.stringify(unchecked(data[data.length - 1]))); + result.writeCodePoint(BRACKET_RIGHT); + return result.toString(); + } +} \ No newline at end of file diff --git a/assembly/serialize/bool.ts b/assembly/serialize/bool.ts new file mode 100644 index 0000000..e8f3bbf --- /dev/null +++ b/assembly/serialize/bool.ts @@ -0,0 +1,10 @@ +/** + * Serialize a bool to type string + * @param data data to serialize + * @returns string + */ + +// @ts-ignore: Decorator valid here +@inline export function serializeBool(data: bool): string { + return data ? "true" : "false"; +} \ No newline at end of file diff --git a/assembly/serialize/date.ts b/assembly/serialize/date.ts new file mode 100644 index 0000000..beaed6d --- /dev/null +++ b/assembly/serialize/date.ts @@ -0,0 +1,4 @@ +// @ts-ignore: Decorator valid here +@inline export function serializeDate(data: Date): string { + return `"${data.toISOString()}"` +} \ No newline at end of file diff --git a/assembly/serialize/float.ts b/assembly/serialize/float.ts new file mode 100644 index 0000000..9ee3e05 --- /dev/null +++ b/assembly/serialize/float.ts @@ -0,0 +1,4 @@ +// @ts-ignore: Decorator valid here +@inline export function serializeFloat(data: T): string { + return data.toString(); +} \ No newline at end of file diff --git a/assembly/serialize/integer.ts b/assembly/serialize/integer.ts new file mode 100644 index 0000000..fbf2dd3 --- /dev/null +++ b/assembly/serialize/integer.ts @@ -0,0 +1,5 @@ +// @ts-ignore: Decorator valid here +@inline export function serializeInteger(data: T): string { + // I have a much faster implementation of itoa that I will port over later. Its ~4x faster + return data.toString(); +} \ No newline at end of file diff --git a/assembly/serialize/map.ts b/assembly/serialize/map.ts new file mode 100644 index 0000000..7cc843e --- /dev/null +++ b/assembly/serialize/map.ts @@ -0,0 +1,24 @@ +import { COLON, COMMA, BRACE_LEFT_WORD, BRACE_RIGHT } from "../custom/chars"; +import { JSON } from ".."; +import { Sink } from "../custom/sink"; + +// @ts-ignore: Decorator valid here +@inline export function serializeMap>(data: T): string { + let result = Sink.fromString(BRACE_LEFT_WORD); + if (!data.size) return "{}"; + let keys = data.keys(); + let values = data.values(); + const end = data.size - 1; + for (let i = 0; i < end; i++) { + result.write(JSON.stringify(unchecked(keys[i]).toString())); + result.writeCodePoint(COLON); + result.write(JSON.stringify(unchecked(values[i]))); + result.writeCodePoint(COMMA); + } + result.write(JSON.stringify(unchecked(keys[end]).toString())); + result.writeCodePoint(COLON); + result.write(JSON.stringify(unchecked(values[end]))); + + result.writeCodePoint(BRACE_RIGHT); + return result.toString(); +} \ No newline at end of file diff --git a/assembly/serialize/object.ts b/assembly/serialize/object.ts new file mode 100644 index 0000000..e46ee77 --- /dev/null +++ b/assembly/serialize/object.ts @@ -0,0 +1,13 @@ +interface GeneratedInterface { + __SERIALIZE(): string; +} + +// @ts-ignore: Decorator valid here +@inline export function serializeObject(data: T): string { + return changetype>(data).__SERIALIZE(); +} + +// @ts-ignore: Decorator valid here +@inline export function serializeObject_Pretty(data: T): string { + return changetype>(data).__SERIALIZE_PRETTY(); +} \ No newline at end of file diff --git a/assembly/serialize/simd/string.ts b/assembly/serialize/simd/string.ts deleted file mode 100644 index ec77ad0..0000000 --- a/assembly/serialize/simd/string.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { OBJECT, TOTAL_OVERHEAD } from "rt/common"; -import { BACK_SLASH } from "../../custom/chars"; -import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables"; - -const SPLAT_34 = i16x8.splat(34); /* " */ -const SPLAT_92 = i16x8.splat(92); /* \ */ - -const SPLAT_32 = i16x8.splat(32); /* [ESC] */ -const SPLAT_0 = i16x8.splat(0); /* 0 */ - -/** - * Serializes strings into their JSON counterparts using SIMD operations - * @param src string to serialize - * @param dst buffer to write to - * @returns number of bytes written - */ -export function serializeString_SIMD(src: string, dst: usize): usize { - let src_ptr = changetype(src); - let dst_ptr = changetype(dst) + 2; - - const src_end = src_ptr + changetype(changetype(src) - TOTAL_OVERHEAD).rtSize; - const src_end_15 = src_end - 15; - - store(changetype(dst), 34); /* " */ - - while (src_ptr < src_end_15) { - const block = v128.load(src_ptr); - v128.store(dst_ptr, block); - - const backslash_indices = i16x8.eq(block, SPLAT_92); - const quote_indices = i16x8.eq(block, SPLAT_34); - const escape_indices = i16x8.lt_u(block, SPLAT_32); - const sieve = v128.or(v128.or(backslash_indices, quote_indices), escape_indices); - - let mask = i16x8.bitmask(sieve); - - while (mask != 0) { - const lane_index = ctz(mask) << 1; - const dst_offset = dst_ptr + lane_index; - const src_offset = src_ptr + lane_index; - const code = load(src_offset) << 2; - const escaped = load(SERIALIZE_ESCAPE_TABLE + code); - - mask &= mask - 1; - - if ((escaped & 0xffff) != BACK_SLASH) { - store(dst_offset, 13511005048209500); - store(dst_offset, escaped, 8); - v128.store(dst_offset, v128.load(src_offset, 2), 12); - dst_ptr += 10; - } else { - store(dst_offset, escaped); - v128.store(dst_offset, v128.load(src_offset, 2), 4); - dst_ptr += 2; - } - } - - src_ptr += 16; - dst_ptr += 16; - } - - let rem = src_end - src_ptr; - - if (rem & 8) { - const block = v128.load64_zero(src_ptr); - v128.store64_lane(dst_ptr, block, 0); - - const backslash_indices = i16x8.eq(block, SPLAT_92); - const quote_indices = i16x8.eq(block, SPLAT_34); - const escape_indices = i16x8.lt_u(block, SPLAT_32); - const zero_indices = i16x8.eq(block, SPLAT_0); - const sieve = v128.and(v128.or(v128.or(backslash_indices, quote_indices), escape_indices), v128.not(zero_indices)); - - let mask = i16x8.bitmask(sieve); - while (mask != 0) { - let lane_index = ctz(mask) << 1; - const dst_offset = dst_ptr + lane_index; - const src_offset = src_ptr + lane_index; - const code = load(src_offset) << 2; - const escaped = load(SERIALIZE_ESCAPE_TABLE + code); - mask &= mask - 1; - - if ((escaped & 0xffff) != BACK_SLASH) { - store(dst_offset, 13511005048209500); - store(dst_offset, escaped, 8); - while (lane_index < 6) { - store(dst_ptr + lane_index, load(src_ptr + lane_index, 2), 12); - lane_index += 2; - } - dst_ptr += 10; - } else { - store(dst_offset, escaped); - - while (lane_index < 6) { - store(dst_ptr + lane_index, load(src_ptr + lane_index, 2), 4); - lane_index += 2; - } - dst_ptr += 2; - } - } - - dst_ptr += 8; - src_ptr += 8; - } - if (rem & 4) { - const block = load(src_ptr); - const codeA = block & 0xffff; - const codeB = (block >> 16) & 0xffff; - - if (codeA == 92 || codeA == 34 || codeA < 32) { - const escaped = load(SERIALIZE_ESCAPE_TABLE + (codeA << 2)); - - if ((escaped & 0xffff) != BACK_SLASH) { - store(dst_ptr, 13511005048209500); - store(dst_ptr, escaped, 8); - dst_ptr += 12; - } else { - store(dst_ptr, escaped); - dst_ptr += 4; - } - } else { - store(dst_ptr, codeA); - dst_ptr += 2; - } - - if (codeB == 92 || codeB == 34 || codeB < 32) { - const escaped = load(SERIALIZE_ESCAPE_TABLE + (codeB << 2)); - - if ((escaped & 0xffff) != BACK_SLASH) { - store(dst_ptr, 13511005048209500); - store(dst_ptr, escaped, 8); - dst_ptr += 12; - } else { - store(dst_ptr, escaped); - dst_ptr += 4; - } - } else { - store(dst_ptr, codeB); - dst_ptr += 2; - } - - src_ptr += 4; - } - if (rem & 2) { - const code = load(src_ptr); - if (code == 92 || code == 34 || code < 32) { - const escaped = load(SERIALIZE_ESCAPE_TABLE + (code << 2)); - - if ((escaped & 0xffff) != BACK_SLASH) { - store(dst_ptr, 13511005048209500); - store(dst_ptr, escaped, 8); - dst_ptr += 12; - } else { - store(dst_ptr, escaped); - dst_ptr += 4; - } - } else { - store(dst_ptr, code); - dst_ptr += 2; - } - } - - store(dst_ptr, 34); /* " */ - return dst_ptr - changetype(dst) + 2; -} diff --git a/assembly/serialize/simple/arbitrary.ts b/assembly/serialize/simple/arbitrary.ts deleted file mode 100644 index cb010a8..0000000 --- a/assembly/serialize/simple/arbitrary.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { JSON } from "../.."; -import { serializeArray } from "./array"; -import { serializeBool } from "./bool"; -import { serializeInteger } from "./integer"; -import { serializeString } from "./string"; - -export function serializeArbitrary(src: JSON.Value, staticSize: bool = false): void { - switch (src.type) { - case JSON.Types.U8: - serializeInteger(src.get(), staticSize); - break; - case JSON.Types.U16: - serializeInteger(src.get(), staticSize); - break; - case JSON.Types.U32: - serializeInteger(src.get(), staticSize); - break; - case JSON.Types.U64: - serializeInteger(src.get(), staticSize); - break; - case JSON.Types.String: - serializeString(src.get(), staticSize); - break; - case JSON.Types.Bool: - serializeBool(src.get(), staticSize); - case JSON.Types.Array: { - serializeArray(src.get(), staticSize); - break; - } - default: { - const fn = JSON.Value.METHODS.get(src.type - JSON.Types.Struct); - const value = src.get(); - call_indirect(fn, 0, value); - } - } -} diff --git a/assembly/serialize/simple/array.ts b/assembly/serialize/simple/array.ts deleted file mode 100644 index b2d898a..0000000 --- a/assembly/serialize/simple/array.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { bs } from "as-bs"; -import { COMMA, BRACKET_RIGHT, BRACKET_LEFT } from "../../custom/chars"; -import { JSON } from "../.."; - -export function serializeArray(src: T, staticSize: bool = false): void { - const srcSize = load(changetype(src), offsetof("byteLength")); - - if (srcSize == 0) { - if (!staticSize) bs.ensureSize(4); - store(bs.offset, 6094939); - bs.offset += 4; - return; - } - - let srcPtr = src.dataStart; - const srcEnd = srcPtr + srcSize - sizeof>(); - // if (!bs.buffer) bs.setBuffer(__new(srcSize << 3, idof())); - // else - if (!staticSize) bs.ensureSize(srcSize << 3); - - store(bs.offset, BRACKET_LEFT); - bs.offset += 2; - - while (srcPtr < srcEnd) { - const block = load>(srcPtr); - JSON.__serialize>(block); - if (!staticSize) bs.ensureSize(2); - store(bs.offset, COMMA); - bs.offset += 2; - srcPtr += sizeof(); - } - - const lastBlock = load>(srcPtr); - JSON.__serialize>(lastBlock); - if (!staticSize) bs.ensureSize(2); - store(bs.offset, BRACKET_RIGHT); - bs.offset += 2; -} diff --git a/assembly/serialize/simple/bool.ts b/assembly/serialize/simple/bool.ts deleted file mode 100644 index 1a9d466..0000000 --- a/assembly/serialize/simple/bool.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { bs } from "as-bs"; - -/** - * Serialize a bool to type string - * @param data data to serialize - * @returns void - */ -// @ts-ignore: Decorator valid here -@inline export function serializeBool(data: bool, staticSize: bool = false): void { - if (data == true) { - if (!staticSize) bs.ensureSize(8); - store(bs.offset, 28429475166421108); - bs.offset += 8; - } else { - if (!staticSize) bs.ensureSize(10); - store(bs.offset, 32370086184550502); - store(bs.offset, 101, 8); - bs.offset += 10; - } -} diff --git a/assembly/serialize/simple/date.ts b/assembly/serialize/simple/date.ts deleted file mode 100644 index e9a536e..0000000 --- a/assembly/serialize/simple/date.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { bs } from "as-bs"; -import { QUOTE } from "../../custom/chars"; -import { bytes } from "../../util/bytes"; - -// @ts-ignore: Decorator valid here -@inline export function serializeDate(src: Date, staticSize: bool = false): void { - const data = src.toISOString(); - const dataSize = bytes(data); - if (!staticSize) bs.ensureSize(dataSize + 4); - store(bs.offset, QUOTE); - memory.copy(bs.offset + 2, changetype(data), dataSize); - store(bs.offset + dataSize, QUOTE, 2); - bs.offset += dataSize + 4; -} diff --git a/assembly/serialize/simple/float.ts b/assembly/serialize/simple/float.ts deleted file mode 100644 index d183339..0000000 --- a/assembly/serialize/simple/float.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { dtoa_buffered } from "util/number"; -import { bs } from "as-bs"; - -// @ts-ignore: Decorator valid here -@inline export function serializeFloat(data: T, staticSize: bool = false): void { - if (!staticSize) bs.ensureSize(64); - bs.offset += dtoa_buffered(bs.offset, data) << 1; -} diff --git a/assembly/serialize/simple/integer.ts b/assembly/serialize/simple/integer.ts deleted file mode 100644 index a4e76ae..0000000 --- a/assembly/serialize/simple/integer.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { itoa_buffered } from "util/number"; -import { bs } from "as-bs"; - -// @ts-ignore: Decorator valid here -@inline export function serializeInteger(data: T, staticSize: bool = false): void { - if (!staticSize) bs.ensureSize(sizeof() << 3); - bs.offset += itoa_buffered(bs.offset, data) << 1; -} diff --git a/assembly/serialize/simple/map.ts b/assembly/serialize/simple/map.ts deleted file mode 100644 index b667e51..0000000 --- a/assembly/serialize/simple/map.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { BRACE_LEFT, BRACE_RIGHT, COLON, COMMA } from "../../custom/chars"; -import { bs } from "as-bs"; - -export function serializeMap>(src: T, staticSize: bool = false): void { - const srcSize = src.size; - const srcEnd = srcSize - 1; - - if (!srcSize) { - if (!staticSize) bs.ensureSize(4); - store(bs.offset, 8192123); - bs.offset += 4; - return; - } - - let keys = src.keys(); - let values = src.values(); - - if (!staticSize) bs.ensureSize(srcSize << 3); // This needs to be predicted better - - store(bs.offset, BRACE_LEFT); - bs.offset += 2; - - for (let i = 0; i < srcEnd; i++) { - __serialize(unchecked(keys[i])); - if (!staticSize) bs.ensureSize(2); - store(bs.offset, COLON); - bs.offset += 2; - __serialize(unchecked(values[i])); - if (!staticSize) bs.ensureSize(2); - store(bs.offset, COMMA); - bs.offset += 2; - } - - __serialize(unchecked(keys[srcEnd])); - if (!staticSize) bs.ensureSize(2); - store(bs.offset, COLON); - bs.offset += 2; - __serialize(unchecked(values[srcEnd])); - if (!staticSize) bs.ensureSize(2); - store(bs.offset, BRACE_RIGHT); - bs.offset += 2; -} diff --git a/assembly/serialize/simple/object.ts b/assembly/serialize/simple/object.ts deleted file mode 100644 index f8f8c84..0000000 --- a/assembly/serialize/simple/object.ts +++ /dev/null @@ -1,8 +0,0 @@ -interface GeneratedInterface { - __SERIALIZE(ptr: usize): string; - __SERIALIZE_BS(ptr: usize, staticSize: bool): void; -} - -export function serializeObject(data: T, staticSize: bool = false): void { - return changetype>(data).__SERIALIZE_BS(changetype(data), staticSize); -} diff --git a/assembly/serialize/simple/string.ts b/assembly/serialize/simple/string.ts deleted file mode 100644 index 6a3477e..0000000 --- a/assembly/serialize/simple/string.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { _intTo16 } from "../../custom/util"; -import { bytes } from "../../util/bytes"; -import { bs } from "as-bs"; -import { BACK_SLASH, QUOTE } from "../../custom/chars"; -import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables"; - -/** - * Serializes valid strings into their JSON counterpart - * @param src string - * @returns void - */ -// @ts-ignore: Decorator -@inline export function serializeString(src: string, staticSize: bool = false): void { - const srcSize = bytes(src); - if (!staticSize) bs.ensureSize(srcSize + 4); - - let srcPtr = changetype(src); - const srcEnd = srcPtr + srcSize; - - store(bs.offset, QUOTE); - - bs.offset += 2; - - let lastPtr: i32 = srcPtr; - while (srcPtr < srcEnd) { - const code = load(srcPtr); - if (code == 34 || code == 92 || code < 32) { - const remBytes = srcPtr - lastPtr; - memory.copy(bs.offset, lastPtr, remBytes); - bs.offset += remBytes; - const escaped = load(SERIALIZE_ESCAPE_TABLE + (code << 2)); - if ((escaped & 0xffff) != BACK_SLASH) { - if (!staticSize) bs.ensureSize(12); - store(bs.offset, 13511005048209500, 0); - store(bs.offset, escaped, 8); - bs.offset += 12; - } else { - if (!staticSize) bs.ensureSize(2); - store(bs.offset, escaped, 0); - bs.offset += 4; - } - lastPtr = srcPtr + 2; - } - srcPtr += 2; - } - const remBytes = srcEnd - lastPtr; - memory.copy(bs.offset, lastPtr, remBytes); - bs.offset += remBytes; - store(bs.offset, QUOTE); - bs.offset += 2; -} diff --git a/assembly/serialize/string.ts b/assembly/serialize/string.ts new file mode 100644 index 0000000..d18eaa9 --- /dev/null +++ b/assembly/serialize/string.ts @@ -0,0 +1,287 @@ +import { _intTo16, intTo16, unsafeCharCodeAt } from "../custom/util"; +import { Sink } from "../custom/sink"; + +// function needsEscaping(data: string): bool { +// let len = data.length; + +// // if (len < 16) { +// // while (len--) { +// // const char = load(changetype(data) + len); +// // if (char == 34 || char == 92 || char <= 31) { +// // return true; +// // } +// // } +// // return false; +// // } + +// let running = v128.splat(0); +// //let i = 0; + +// //while (i + 15 < len) { +// let w = v128.load(changetype(data)); +// running = v128.or(running, v128.eq(w, i16x8.splat(34))); +// running = v128.or(running, v128.eq(w, i16x8.splat(92))); + +// let subtracted = v128.sub(w, i8x16.splat(31)); +// running = v128.or(running, v128.eq(subtracted, v128.splat(0))); +// //i += 16; +// //} + +// return v128.any_true(running); +// } + +// /** +// * A prototype SIMD implementation for string serialization which can only work in 128-byte (or 16 chars with wtf-16). +// * +// * A faster version could perhaps look like the following: +// */ +// // @ts-ignore: Decorator +// @inline export function serialize_simd_v1(src: string, dst: usize): void { +// let src_ptr = changetype(src); +// let dst_ptr = changetype(dst) + 2; + +// store(changetype(dst), 34); /* " */ + +// const src_end = src_ptr + u32(src.length << 1); +// const src_end_15 = src_end - 15; + +// while (src_ptr < src_end_15) { +// const currentBlock = v128.load(src_ptr); +// const backslash_indices = i16x8.eq(currentBlock, i16x8.splat(92)); +// const quote_indices = i16x8.eq(currentBlock, i16x8.splat(34)); +// const concat_indices = v128.or(quote_indices, backslash_indices); + +// const escape_indices = i16x8.lt_u(currentBlock, i16x8.splat(32)); + +// if (v128.any_true(v128.or(escape_indices, concat_indices))) { +// const mask = i16x8.bitmask(concat_indices); + +// const anomalies = popcnt(mask); +// const start_index = (clz(mask) & ~1) + 2 // This essentially floors to the nearest even integer +// if (anomalies === 1) { +// memory.copy(dst_ptr, src_ptr, start_index >> 1); +// store(dst_ptr + start_index, 34); +// memory.copy(dst_ptr + start_index + 2, src_ptr + start_index, (32 - start_index) >> 1) +// } + +// if (v128.any_true(escape_indices)) { + +// } +// dst_ptr += 16; +// src_ptr += 16; +// } else { +// v128.store(dst_ptr, currentBlock); +// src_ptr += 16; +// dst_ptr += 16; +// } +// } +// } + + +// const back_slash_reg = i16x8.splat(92); // "\" +// const quote_reg = i16x8.splat(34); // "\"" + +// // @ts-ignore: Decorator +// @inline export function serialize_simd_v2(src: string, dst: usize): void { +// let src_ptr = changetype(src); +// let dst_ptr = changetype(dst); + +// let i = 0; +// const len = src.length; + +// while (i < len) { +// const block = v128.load16x4_u(src_ptr); +// console.log("block: " + prt(block)); +// const backslash_mask = i16x8.eq(block, back_slash_reg); +// const quote_mask = i16x8.eq(block, quote_reg); +// const is_quote_or_backslash = v128.or(quote_mask, backslash_mask); +// console.log("mask: " + prt10(is_quote_or_backslash)) + + +// // store(dst_ptr, expanded); +// src_ptr += 8; +// dst_ptr += 16; +// i += 8; +// } +// } + +// function prt(obj: v128): string { +// let out = ""; +// out += i16x8.extract_lane_u(obj, 0).toString() + " "; +// out += i16x8.extract_lane_u(obj, 1).toString() + " "; +// out += i16x8.extract_lane_u(obj, 2).toString() + " "; +// out += i16x8.extract_lane_u(obj, 3).toString() + " "; +// out += i16x8.extract_lane_u(obj, 4).toString() + " "; +// out += i16x8.extract_lane_u(obj, 5).toString() + " "; +// out += i16x8.extract_lane_u(obj, 6).toString() + " "; +// out += i16x8.extract_lane_u(obj, 7).toString(); +// return out; +// } + +// function prt10(obj: v128): string { +// let out = ""; +// out += (i16x8.extract_lane_u(obj, 0) ? "1" : "0") + " "; +// out += (i16x8.extract_lane_u(obj, 1) ? "1" : "0") + " "; +// out += (i16x8.extract_lane_u(obj, 2) ? "1" : "0") + " "; +// out += (i16x8.extract_lane_u(obj, 3) ? "1" : "0") + " "; +// out += (i16x8.extract_lane_u(obj, 4) ? "1" : "0") + " "; +// out += (i16x8.extract_lane_u(obj, 5) ? "1" : "0") + " "; +// out += (i16x8.extract_lane_u(obj, 6) ? "1" : "0") + " "; +// out += i16x8.extract_lane_u(obj, 7) ? "1" : "0"; +// return out; +// } + +// function vis(src_ptr: usize, mask: i32): void { +// let chars = ""; +// let bits = ""; +// for (let i = 0; i < 8; i++) { +// const char = load(src_ptr + (i << 1)); +// const bit = (mask >> i) & 1; +// chars += String.fromCharCode(char) + " "; +// bits += bit.toString() + " "; +// } +// console.log(chars); +// console.log(bits); +// } + +// @ts-ignore: Decorator +@inline export function serializeString(data: string): string { + // if (!needsEscaping(data)) { + // return "\"" + data + "\""; + // } + + if (data.length === 0) { + return "\"\""; + } + let result = Sink.fromString("\""); + + let last: i32 = 0; + for (let i = 0; i < data.length; i++) { + const char = unsafeCharCodeAt(data, i); + if (char === 34 || char === 92) { + result.write(data, last, i); + result.writeCodePoint(92); + last = i; + } else if (char < 16) { + result.write(data, last, i); + last = i + 1; + switch (char) { + case 8: { + result.write("\\b"); + break; + } + case 9: { + result.write("\\t"); + break; + } + case 10: { + result.write("\\n"); + break; + } + case 12: { + result.write("\\f"); + break; + } + case 13: { + result.write("\\r"); + break; + } + default: { + // all chars 0-31 must be encoded as a four digit unicode escape sequence + // \u0000 to \u000f handled here + result.write("\\u000"); + result.write(char.toString(16)); + break; + } + } + } else if (char < 32) { + result.write(data, last, i); + last = i + 1; + // all chars 0-31 must be encoded as a four digit unicode escape sequence + // \u0010 to \u001f handled here + result.write("\\u00"); + result.write(char.toString(16)); + } + } + result.write(data, last); + result.writeCodePoint(34); + return result.toString(); +} + +// // @ts-ignore: Decorator valid here +// @inline export function serializeString_BS(data: string): void { +// const len = data.length << 1; +// if (len === 0) { +// bs.write_32(2228258); /* "" */ +// return; +// } + +// bs.write_16(QUOTE); + + +// let last: i32 = 0; +// for (let i = 0; i < len; i += 2) { +// const char = load(changetype(data) + i); +// if (char < 35) { +// if (char === QUOTE) { +// bs.write_s_se(data, last, i); +// bs.write_16(BACK_SLASH); +// last = i; +// continue; +// } else if (char < 32) { +// if (char < 16) { +// bs.write_s_se(data, last, i); +// last = i + 2; +// switch (char) { +// case BACKSPACE: { +// bs.write_32(6422620); +// continue; +// } +// case TAB: { +// bs.write_32(7602268); +// continue; +// } +// case NEW_LINE: { +// bs.write_32(7209052); +// continue; +// } +// case FORM_FEED: { +// bs.write_32(6684764); +// continue; +// } +// case CARRIAGE_RETURN: { +// bs.write_32(7471196); +// continue; +// } +// default: { +// // all chars 0-31 must be encoded as a four digit unicode escape sequence +// // \u0000 to \u000f handled here +// bs.write_64(13511005048209500) /* \\u00 */ +// bs.write_32((_intTo16(char) << 16) | 48); /* 0_ */ +// continue; +// } +// } +// } else { +// bs.write_s_se(data, last, i); +// last = i + 2; +// // all chars 0-31 must be encoded as a four digit unicode escape sequence +// // \u0010 to \u001f handled here +// bs.write_64(13511005048209500) /* \\u00 */ +// bs.write_32((intTo16(char) << 16) | 48); /* 0_ */ +// } +// } +// } else if (char === BACK_SLASH) { +// bs.write_s_se(data, last, i); +// bs.write_16(BACK_SLASH); +// last = i; +// } +// } + +// if (last === 0) { +// bs.write_s(data); +// bs.write_16(QUOTE) +// } else { +// bs.write_s_se(data, last, changetype(changetype(data) - TOTAL_OVERHEAD).rtSize); +// bs.write_16(QUOTE); +// } +// } \ No newline at end of file diff --git a/assembly/test.ts b/assembly/test.ts index 25e9196..b2bb25d 100644 --- a/assembly/test.ts +++ b/assembly/test.ts @@ -1,18 +1,34 @@ -import { JSON } from "."; -import { deserializeMap } from "./deserialize/simple/map"; -import { deserializeObject } from "./deserialize/simple/object"; -import { bytes } from "./util"; +import { JSON } from "." @json class Vec3 { - a: i16 = 1 - ab: i16 = 2; - abc: i16 = 3; - abcd: i16 = 4; - abcde: i16 = 5; + public x: i32 = 0; + public y: i32 = 0; + public z: i32 = 0; } +// @json +// class Base { +// public bam: string = "harekogkeorgke" +// } + +// @json +// class Foo extends Base { +// public bar: JSON.Raw = "\"this is ok\'" +// public baz: i32 = 0; +// public pos: Vec3> = { +// x: 1, +// y: 2, +// z: { +// x: 1, +// y: 2, +// z: 3 +// } +// } +// // ^ this is not okay +// } + const serialized = JSON.stringify(new Vec3()); console.log("Serialized: " + serialized); -const deserialized = deserializeObject(changetype(serialized), changetype(serialized) + bytes(serialized)); +const deserialized = JSON.parseSafe(`{"x":1,"y":true,"z":3}`); console.log("Deserialized: " + JSON.stringify(deserialized)); \ No newline at end of file diff --git a/assembly/tsconfig.json b/assembly/tsconfig.json index 2ed0bb1..86b8816 100644 --- a/assembly/tsconfig.json +++ b/assembly/tsconfig.json @@ -2,7 +2,96 @@ "extends": "assemblyscript/std/assembly.json", "include": ["./**/*.ts"], "compilerOptions": { - "experimentalDecorators": true, - "emitDecoratorMetadata": true + /* Visit https://aka.ms/tsconfig to read more about this file */ + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + /* Language and Environment */ + "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + "experimentalDecorators": true /* Enable experimental support for TC39 stage 2 draft decorators. */, + "emitDecoratorMetadata": true /* Emit design-type metadata for decorated declarations in source files. */, + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + /* Modules */ + "module": "commonjs" /* Specify what module code is generated. */, + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + /* Type Checking */ + "strict": false /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + "strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */, + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + "noUnusedLocals": true /* Enable error reporting when local variables aren't read. */, + "noUnusedParameters": true /* Raise an error when a function parameter isn't read. */, + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ } } diff --git a/assembly/types.ts b/assembly/types.ts deleted file mode 100644 index da92092..0000000 --- a/assembly/types.ts +++ /dev/null @@ -1,14 +0,0 @@ - -@json -export class VecBase { - base: i32 = 0; - - @inline __ALLOCATE(): void { - bs.ensureSize(4); - } - - @inline __SERIALIZE_BS(ptr: usize, staticSize: bool): void { - store(bs.offset, 8192123); - bs.offset += 4; - } -} diff --git a/assembly/util/bytes.ts b/assembly/util/bytes.ts deleted file mode 100644 index b5bb9fc..0000000 --- a/assembly/util/bytes.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { OBJECT, TOTAL_OVERHEAD } from "rt/common"; - -// @ts-ignore: Decorator valid here -@inline export function bytes(o: T): i32 { - if (isInteger() || isFloat()) { - return sizeof(); - } else if (isManaged() || isReference()) { - return changetype(changetype(o) - TOTAL_OVERHEAD).rtSize; - } else { - ERROR("Cannot convert type " + nameof() + " to bytes!"); - } -} diff --git a/assembly/util/concat.ts b/assembly/util/concat.ts deleted file mode 100644 index bed569f..0000000 --- a/assembly/util/concat.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { bytes } from "./bytes"; -export function concat(left: string, right: string): string { - const leftSize: usize = bytes(left); - const rightSize: usize = bytes(right); - const jointSize: usize = leftSize + rightSize; - const jointPtr = __renew(changetype(left), jointSize); - memory.copy(changetype(left) + leftSize, changetype(right), rightSize); - return changetype(jointPtr); -} diff --git a/assembly/util/index.ts b/assembly/util/index.ts deleted file mode 100644 index 5897d04..0000000 --- a/assembly/util/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./isSpace"; -export * from "./strToInt"; -export * from "./concat"; -export * from "./bytes"; -export * from "./nextPowerOf2"; diff --git a/assembly/util/isSpace.ts b/assembly/util/isSpace.ts deleted file mode 100644 index c96a344..0000000 --- a/assembly/util/isSpace.ts +++ /dev/null @@ -1,4 +0,0 @@ -// @ts-ignore -@inline export function isSpace(code: u16): boolean { - return code == 0x20 || code - 9 <= 4; -} diff --git a/assembly/util/nextPowerOf2.ts b/assembly/util/nextPowerOf2.ts deleted file mode 100644 index 9c98c0b..0000000 --- a/assembly/util/nextPowerOf2.ts +++ /dev/null @@ -1,4 +0,0 @@ -// @ts-ignore: Decorator valid here -@inline export function nextPowerOf2(n: u32): u32 { - return 1 << (32 - clz(n - 1)); -} diff --git a/assembly/util/strToInt.ts b/assembly/util/strToInt.ts deleted file mode 100644 index 8883690..0000000 --- a/assembly/util/strToInt.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Strtol optimized for JSON integers - * @param str - * @returns - */ -// @ts-ignore: Decorator valid here -@inline export function strToInt(srcStart: usize, srcEnd: usize): T { - // @ts-ignore: type - let val: T = 0; - if (isSigned()) { - if (load(srcStart) == 45) { - srcStart += 2; - while (srcStart < srcEnd) { - // @ts-ignore: type - val = (val * 10 + (load(srcStart) - 48)) as T; - srcStart += 2; - } - return -val as T; - } else { - while (srcStart < srcEnd) { - // @ts-ignore: type - val = (val * 10 + (load(srcStart) - 48)) as T; - srcStart += 2; - } - return val as T; - } - } else { - while (srcStart < srcEnd) { - // @ts-ignore: type - val = (val * 10 + (load(srcStart) - 48)) as T; - srcStart += 2; - } - return val as T; - } -} diff --git a/bench.js b/bench.js index e67de99..d961536 100644 --- a/bench.js +++ b/bench.js @@ -34,9 +34,9 @@ const vec = { let data; const bench = new Bench({ time: 1000 }) - .add("stringify float", () => { - data = JSON.stringify('h\\ello wor"ld'); - }) /* + /*.add("stringify float", () => { + data = JSON.stringify(1.2345) + }) .add("parse float", () => { data = JSON.parse("1.2345") }) @@ -65,10 +65,10 @@ const bench = new Bench({ time: 1000 }) .add("Stringify String", () => { data = JSON.stringify('Hello "World!'); }) - +*/ .add("Parse String", () => { data = JSON.stringify('hello "world abc'); - })*/ + }) .todo("unimplemented .add"); await bench.run(); diff --git a/package.json b/package.json index 745f8bc..64972c8 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,6 @@ "version": "0.9.26", "description": "The only JSON library you'll need for AssemblyScript. SIMD enabled", "types": "assembly/index.ts", - "main": "transform/lib/index.js", "author": "Jairus Tanaka", "contributors": [ "DogWhich", @@ -17,30 +16,34 @@ ], "license": "MIT", "scripts": { - "test": "rm -rf ./build/ && ast test", - "build:bench": "rm -rf ./build/ && asc assembly/__benches__/misc.bench.ts -o ./build/bench.wasm --textFile ./build/bench.wat --transform ./transform --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime incremental --enable simd --enable bulk-memory", - "build:test": "rm -rf ./build/ && JSON_DEBUG=true asc assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0 --enable simd --runtime stub", + "test": "ast test && rm -rf ./build/", + "pretest": "rm -rf ./build/ && ast build", + "bench": "astral --enable simd --runtime stub", + "build:test": "rm -rf ./build/ && JSON_DEBUG=true asc assembly/test.ts --transform ./transform -o ./build/test.wasm", "build:transform": "tsc -p ./transform", "test:wasmtime": "wasmtime ./build/test.wasm", - "test:wasmer": "wasmer ./build/test.wasm", - "bench:wasmer": "wasmer ./build/bench.wasm --llvm", + "test:wavm": "wavm run ./build/test.wasm", + "test:lunatic": "lunatic ./build/test.wasm", + "test:wasm3": "wasm3 ./build/test.wasm", "prettier": "prettier -w ." }, "devDependencies": { "@as-tral/cli": "^3.0.2", "@assemblyscript/wasi-shim": "^0.1.0", - "@types/node": "latest", + "@types/node": "^20.14.12", "as-bench": "^0.0.0-alpha", "as-console": "^7.0.0", - "assemblyscript": "^0.27.31", + "as-test": "0.3.1", + "assemblyscript": "^0.27.29", "assemblyscript-prettier": "^3.0.1", - "minimatch": "^10.0.1", - "prettier": "^3.4.2", - "typescript": "latest" + "benchmark": "^2.1.4", + "microtime": "^3.1.1", + "prettier": "^3.3.3", + "tinybench": "^2.8.0", + "typescript": "^5.5.4", + "visitor-as": "^0.11.4" }, "dependencies": { - "as-bs": "JairusSW/as-bs#a8d6deb", - "as-container": "^0.8.0", "as-virtual": "^0.2.0" }, "overrides": { diff --git a/transform/lib/builder.js b/transform/lib/builder.js deleted file mode 100644 index 84f3c34..0000000 --- a/transform/lib/builder.js +++ /dev/null @@ -1,1353 +0,0 @@ -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; -} -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]); - } - } - visitTypeNode(node) { - switch (node.kind) { - case 1: { - this.visitNamedTypeNode(node); - break; - } - case 2: { - this.visitFunctionTypeNode(node); - break; - } - default: - assert(false); - } - } - 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; - } - } - 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"); - } - } - 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); - } - } - 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]); - } - 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; - } - 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)); - } - 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); - } - 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); - } - } - 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"); - } - } - } - 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("{}"); - } - } - visitBreakStatement(node) { - var label = node.label; - if (label) { - this.sb.push("break "); - this.visitIdentifierExpression(label); - } - else { - this.sb.push("break"); - } - } - visitContinueStatement(node) { - var label = node.label; - if (label) { - this.sb.push("continue "); - this.visitIdentifierExpression(label); - } - else { - this.sb.push("continue"); - } - } - 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(" {}"); - } - } - 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 ("); - } - 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); - } - 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(" {}"); - } - } - visitEnumValueDeclaration(node) { - this.visitIdentifierExpression(node.name); - var initializer = node.initializer; - if (initializer) { - this.sb.push(" = "); - this.visitNode(initializer); - } - } - 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); - } - } - 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(";"); - } - 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); - } - } - 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]); - } - } - 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); - } - } - 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); - } - 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]); - } - } - 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); - } - 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); - } - } - } - 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); - } - } - 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]); - } - --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]); - } - } - 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("}"); - } - 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); - } - 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(" {}"); - } - } - visitReturnStatement(node) { - var value = node.value; - if (value) { - this.sb.push("return "); - this.visitNode(value); - } - else { - this.sb.push("return"); - } - } - 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"); - } - 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; - } - } - 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("}"); - } - 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]); - } - 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("}"); - } - 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); - } - 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); - } - } - 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]); - } - } - 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); - } - } - 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); - } - 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); - } - } - 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 "); - } - } - 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; - } -} -//# sourceMappingURL=builder.js.map \ No newline at end of file diff --git a/transform/lib/builder.js.map b/transform/lib/builder.js.map deleted file mode 100644 index a7fbfd0..0000000 --- a/transform/lib/builder.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/transform/lib/index.js b/transform/lib/index.js index e990141..e5a792a 100644 --- a/transform/lib/index.js +++ b/transform/lib/index.js @@ -1,416 +1,503 @@ -import { IdentifierExpression, Source, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, Tokenizer } from "assemblyscript/dist/assemblyscript.js"; +import { FieldDeclaration, IdentifierExpression, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression, } from "assemblyscript/dist/assemblyscript.js"; +import { toString, isStdlib } from "visitor-as/dist/utils.js"; +import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js"; import { Transform } from "assemblyscript/dist/transform.js"; -import { Visitor } from "./visitor.js"; -import { SimpleParser, toString } from "./util.js"; -import * as path from "path"; -import { fileURLToPath } from "url"; -import { Property, PropertyFlags, Schema } from "./types.js"; -import { getClasses, getImportedClass } from "./linker.js"; -let indent = " "; -class JSONTransform extends Visitor { - parser; - schemas = []; - schema; +class JSONTransform extends BaseVisitor { + schemasList = []; + currentClass; sources = new Set(); - imports = []; - jsonImport = null; - bsImport = null; - newStmts = { simd: [] }; + visitMethodDeclaration() { } visitClassDeclaration(node) { if (!node.decorators?.length) return; - if (!node.decorators.some(decorator => { + let found = false; + for (const decorator of node.decorators) { const name = decorator.name.text; - return name === "json" || name === "serializable"; - })) + if (name === "json" || name === "serializable") { + found = true; + break; + } + } + if (!found) return; - this.schema = new Schema(); - this.schema.node = node; - this.schema.name = node.name.text; - this.schemas.push(this.schema); - 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"))]; + const schema = new SchemaData(); + schema.node = node; + schema.name = node.name.text; + const members = [ + ...node.members.filter((v) => v.kind === 54), + ]; 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) { - console.log("Found " + extendsName + " internally"); - this.visitClassDeclaration(internalSearch); - this.visitClassDeclaration(node); - return; - } - const externalSearch = getImportedClass(extendsName, node.range.source, this.parser); - if (externalSearch) { - 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); + schema.parent = this.schemasList.find((v) => v.name == node.extendsType?.name.identifier.text); + if (schema.parent?.members) { + for (let i = schema.parent.members.length - 1; i >= 0; i--) { + const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name); if (!replace) { - members.unshift(this.schema.parent?.members[i].node); + members.unshift(schema.parent?.members[i].node); } } } } if (!members.length) { - this.generateEmptyMethods(node); - return; + let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}'; + let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}"; + let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}"; + if (process.env["JSON_DEBUG"]) { + console.log(SERIALIZE_RAW_EMPTY); + console.log(INITIALIZE_EMPTY); + console.log(DESERIALIZE_EMPTY); + } + const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_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 == "__INITIALIZE")) + node.members.push(INITIALIZE_METHOD_EMPTY); + if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) + node.members.push(DESERIALIZE_METHOD_EMPTY); + this.schemasList.push(schema); } - 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 (!(member instanceof FieldDeclaration)) + continue; + if (!member.type) { + throw new Error("Fields must be strongly typed! Found " + + toString(member) + + " at " + + node.range.source.normalizedPath); + } + const type = toString(member.type); if (type.startsWith("(") && type.includes("=>")) continue; + const value = member.initializer ? toString(member.initializer) : null; + if (member.flags == 32) + continue; + if (member.flags === 512) + continue; + if (member.flags === 1024) + 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 (type.includes("JSON.Raw")) { + mem.flags.set(PropertyFlags.JSON_Raw, []); + } + if (member.type.isNullable) { + mem.flags.set(PropertyFlags.Null, []); + } if (member.decorators) { for (const decorator of member.decorators) { - const decoratorName = decorator.name.text.toLowerCase().trim(); + const decoratorName = decorator.name.text; + const args = getArgs(decorator.args); 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); + throw new Error("Expected 1 argument but got zero at @alias in " + + node.range.source.normalizedPath); mem.alias = args[0]; + mem.flags.set(PropertyFlags.Alias, args); + break; + } + case "omit": { + mem.flags.set(PropertyFlags.Omit, args); break; } case "omitif": { - const 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; + throw new Error("Expected 1 argument but got zero at @omitif in " + + node.range.source.normalizedPath); + mem.flags.set(PropertyFlags.OmitIf, args); 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; + mem.flags.set(PropertyFlags.OmitNull, args); break; } } } } - this.schema.members.push(mem); + mem.generate(false); + if (this.schemasList.find((v) => v.name == type)) { + mem.initialize = + "this." + + name.text + + " = changetype>(__new(offsetof>(), idof>()));\n changetype>(this." + + name.text + + ").__INITIALIZE()"; + } + else if (mem.value) { + mem.initialize = "this." + name.text + " = " + mem.value; + } + else if (type === "Map") { + mem.initialize = "this." + name.text + " = new " + mem.type + "()"; + } + else if (type === "string") { + mem.initialize = "this." + name.text + ' = ""'; + } + else if (type === "Array") { + mem.initialize = + "this." + name.text + " = instantiate<" + mem.type + ">()"; + } + else if (type === "bool" || type === "boolean") { + mem.initialize = "this." + name.text + " = false"; + } + else if (type === "JSON.Raw") { + mem.initialize = "this." + name.text + ' = ""'; + } + else if (type === "u8" || + type === "u16" || + type === "u32" || + type === "u64" || + type === "i8" || + type === "i16" || + type === "i32" || + type === "i64") { + mem.initialize = "this." + name.text + " = 0"; + } + else if (type === "f32" || type === "f64") { + mem.initialize = "this." + name.text + " = 0.0"; + } + schema.members.push(mem); + } + let SERIALIZE_RAW = "__SERIALIZE(): string {\n let out = `{"; + let SERIALIZE_PRETTY = "__SERIALIZE_PRETTY(): string {\n let out = `{"; + let INITIALIZE = "__INITIALIZE(): this {\n"; + let DESERIALIZE = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n const len = key_end - key_start;\n"; + let indent = " "; + if (!schema.members.length) + return; + found = false; + if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) || + schema.members[0]?.flags.has(PropertyFlags.OmitIf)) { + SERIALIZE_RAW += schema.members[0]?.serialize; + SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize; } - if (!this.schema.static) - this.schema.members = sortMembers(this.schema.members); - let SERIALIZE = "@inline __SERIALIZE(ptr: usize = changetype(this)): string {\n"; - let SERIALIZE_BS = "__SERIALIZE_BS(ptr: usize, staticSize: bool): void {\n"; - let INITIALIZE = "@inline __INITIALIZE(): this {\n"; - let DESERIALIZE = "__DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize): void {\n const keySize = keyEnd - keyStart;"; - let ALLOCATE = "@inline __ALLOCATE(): void {\n"; - indent = " "; - if (this.schema.static == false) { - if (this.schema.members.some(v => v.flags.has(PropertyFlags.OmitNull))) { - SERIALIZE_BS += indent + "let block: usize = 0;\n"; - } - this.schema.byteSize += 2; - SERIALIZE_BS += indent + "store(bs.offset, 123, 0); // {\n"; - SERIALIZE_BS += indent + "bs.offset += 2;\n"; + else { + SERIALIZE_RAW += schema.members[0]?.serialize + ","; + SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n"; + found = true; } - 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; - DESERIALIZE += " if (keySize == " + ((aliasName.length - 2) << 1) + " && memory.compare(keyStart, changetype(" + aliasName + "), " + ((aliasName.length - 2) << 1) + ") == 0) {\n"; - DESERIALIZE += " this." + realName + " = JSON.__deserialize<" + member.type + ">(valStart, valEnd);\n"; - DESERIALIZE += " return;\n"; - DESERIALIZE += " }\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_BS += this.getStores(keyPart).map(v => indent + v + "\n").join(""); - SERIALIZE_BS += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof("${realName}")), ${isPrimitive(member.type)});\n`; - if (isFirst) - isFirst = false; - } - else if (isRegular && !isPure) { - const keyPart = (isFirst ? "" : ",") + aliasName + ":"; - this.schema.byteSize += keyPart.length << 1; - SERIALIZE_BS += this.getStores(keyPart).map(v => indent + v + "\n").join(""); - SERIALIZE_BS += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof("${realName}")), staticSize);\n`; - if (isFirst) - isFirst = false; + if (schema.members[0]?.initialize) + INITIALIZE += " " + schema.members[0]?.initialize + ";\n"; + for (let i = 1; i < schema.members.length; i++) { + const member = schema.members[i]; + if (member.initialize) + INITIALIZE += " " + member.initialize + ";\n"; + if (member.flags.has(PropertyFlags.OmitNull) || + member.flags.has(PropertyFlags.OmitIf)) { + SERIALIZE_RAW += member.serialize; + SERIALIZE_PRETTY += member.serialize; } else { - if (member.flags.has(PropertyFlags.OmitNull)) { - SERIALIZE_BS += indent + `if ((block = load(ptr, offsetof("${realName}"))) !== 0) {\n`; - indentInc(); - const keyPart = aliasName + ":"; - this.schema.byteSize += keyPart.length << 1; - SERIALIZE_BS += this.getStores(keyPart).map(v => indent + v + "\n").join(""); - SERIALIZE_BS += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof("${realName}")), staticSize);\n`; - if (!isLast) { - this.schema.byteSize += 2; - SERIALIZE_BS += indent + `store(bs.offset, 44, 0); // ,\n`; - SERIALIZE_BS += indent + `bs.offset += 2;\n`; - } - indentDec(); - this.schema.byteSize += 2; - SERIALIZE_BS += indent + `}\n`; - } - else if (member.flags.has(PropertyFlags.OmitIf)) { - SERIALIZE_BS += indent + `if (${toString}) !== 0) {\n`; - indentInc(); - SERIALIZE_BS += this.getStores(aliasName + ":").map(v => indent + v + "\n").join(""); - SERIALIZE_BS += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof("${realName}")), staticSize);\n`; - if (!isLast) { - this.schema.byteSize += 2; - SERIALIZE_BS += indent + `store(bs.offset, 44, 0); // ,\n`; - SERIALIZE_BS += indent + `bs.offset += 2;\n`; - } - indentDec(); - SERIALIZE_BS += indent + `}\n`; - } + SERIALIZE_RAW += member.serialize + ","; + SERIALIZE_PRETTY += indent + member.serialize + ",\\n"; + found = true; } } + if (found) { + SERIALIZE_RAW += + "`;\n store(changetype(out) + ((out.length - 1) << 1), 125);\n return out;\n}"; + SERIALIZE_PRETTY += + "`;\n store(changetype(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}"; + } + else { + SERIALIZE_RAW += "}`;\n return out;\n}"; + SERIALIZE_PRETTY += "}`;\n return out;\n}"; + } + INITIALIZE += " return this;\n}"; const sortedMembers = []; + const _sorted = schema.members.sort((a, b) => (a.alias?.length || a.name.length) - (b.alias?.length || b.name.length)); 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); + let offset = -1; + for (let i = 0; i < _sorted.length; i++) { + const member = _sorted[i]; + const _name = member.alias || member.name; + if (_name.length === len) { + sortedMembers[offset]?.push(member); } else { sortedMembers.push([member]); - len = _nameLength; + len = _name.length; + offset++; } - }); - const groups = sortedMembers.length; - for (const memberGroup of sortedMembers) { } - DESERIALIZE += "}"; - indent = " "; - this.schema.byteSize += 2; - SERIALIZE_BS += indent + "store(bs.offset, 125, 0); // }\n"; - SERIALIZE_BS += indent + "bs.offset += 2;\n"; - SERIALIZE_BS += "}"; - SERIALIZE += indent + `this.__ALLOCATE();\n`; - SERIALIZE += indent + `this.__SERIALIZE_BS(ptr, true);\n`; - SERIALIZE += indent + `return bs.out();\n`; - SERIALIZE += "}"; - indentDec(); - indentInc(); - ALLOCATE += indent + "bs.ensureSize(" + this.schema.byteSize + ");\n"; - ALLOCATE += "}"; + let first = true; + for (const memberSet of sortedMembers) { + const firstMember = memberSet[0]; + const _name = encodeKey(firstMember.alias || firstMember.name); + if (_name.length === 1) { + if (first) { + DESERIALIZE += + " if (1 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; + first = false; + } + else { + DESERIALIZE += + "else if (1 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; + } + } + else if (_name.length === 2) { + if (first) { + DESERIALIZE += + " if (2 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; + first = false; + } + else { + DESERIALIZE += + "else if (2 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; + } + } + else if (_name.length === 4) { + if (first) { + DESERIALIZE += + " if (4 === len) {\n const code = load(changetype(data) + (key_start << 1));\n"; + first = false; + } + else { + DESERIALIZE += + "else if (4 === len) {\n const code = load(changetype(data) + (key_start << 1));\n"; + } + } + else { + if (first) { + DESERIALIZE += " if (" + _name.length + " === len) {\n"; + first = false; + } + else { + DESERIALIZE += "else if (" + _name.length + " === len) {\n"; + } + } + let f = true; + for (let i = 0; i < memberSet.length; i++) { + const member = memberSet[i]; + if (!member.deserialize) + continue; + const _name = encodeKey(member.alias || member.name); + if (_name.length === 1) { + DESERIALIZE += ` case ${_name.charCodeAt(0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; + } + else if (_name.length === 2) { + DESERIALIZE += ` case ${charCodeAt32(_name, 0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; + } + else if (_name.length === 4) { + if (f) { + f = false; + DESERIALIZE += ` if (${charCodeAt64(_name, 0)} === code) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; + } + else { + DESERIALIZE = + DESERIALIZE.slice(0, DESERIALIZE.length - 1) + + `else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`; + } + } + else { + if (f) { + f = false; + DESERIALIZE += ` if (0 === memory.compare(changetype("${escapeQuote(escapeSlash(_name))}"), changetype(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; + } + else { + DESERIALIZE = + DESERIALIZE.slice(0, DESERIALIZE.length - 1) + + ` else if (0 === memory.compare(changetype("${escapeQuote(escapeSlash(_name))}"), changetype(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; + } + } + } + if (_name.length < 3) { + DESERIALIZE += ` default: {\n return false;\n }\n }\n`; + } + else if (_name.length == 4) { + DESERIALIZE = + DESERIALIZE.slice(0, DESERIALIZE.length - 1) + + ` else {\n return false;\n }\n`; + } + else { + DESERIALIZE = + DESERIALIZE.slice(0, DESERIALIZE.length - 1) + + ` else {\n return false;\n }\n`; + } + DESERIALIZE += " } "; + } + DESERIALIZE += "\n return false;\n}"; if (process.env["JSON_DEBUG"]) { - console.log(SERIALIZE); - console.log(SERIALIZE_BS); + console.log(SERIALIZE_RAW); + console.log(INITIALIZE); console.log(DESERIALIZE); - console.log(ALLOCATE); } - const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE, node); - const SERIALIZE_BS_METHOD = SimpleParser.parseClassMember(SERIALIZE_BS, node); + const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(SERIALIZE_RAW, node); + const DESERIALIZE_SAFE = DESERIALIZE.replaceAll("__DESERIALIZE", "__DESERIALIZE_SAFE"); + 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 == "__SERIALIZE_BS")) - node.members.push(SERIALIZE_BS_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(this)): string {\n return "{}";\n}'; - let SERIALIZE_BS_EMPTY = "@inline __SERIALIZE_BS(ptr: usize, staticSize: bool): void {\n store(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): 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); - } - 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); + const DESERIALIZE_SAFE_METHOD = SimpleParser.parseClassMember(DESERIALIZE_SAFE, 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_BS")) - node.members.push(SERIALIZE_BS_METHOD_EMPTY); + node.members.push(SERIALIZE_RAW_METHOD); if (!node.members.find((v) => v.name.text == "__INITIALIZE")) - node.members.push(INITIALIZE_METHOD_EMPTY); + node.members.push(INITIALIZE_METHOD); 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); + node.members.push(DESERIALIZE_METHOD); + if (!node.members.find((v) => v.name.text == "__DESERIALIZE_SAFE")) + node.members.push(DESERIALIZE_SAFE_METHOD); + this.schemasList.push(schema); } visitSource(node) { - this.imports = []; super.visitSource(node); - } - addRequiredImports(node) { - if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "bs"))) { - if (!this.bsImport) { - this.bsImport = "import { bs } from \"as-bs\""; - if (process.env["JSON_DEBUG"]) - console.log("Added as-bs import: " + this.bsImport + "\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 = true) { - 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.push(`const ${name} = ${num};`); - out.push("store(bs.offset, " + name + ", " + offset + "); // " + data.slice((offset >> 1), (offset >> 1) + 8)); - offset += 16; - } - if (size == "u64") { - out.push("store(bs.offset, " + num + ", " + offset + "); // " + data.slice((offset >> 1), (offset >> 1) + 4)); - offset += 8; - } - else if (size == "u32") { - out.push("store(bs.offset, " + num + ", " + offset + "); // " + data.slice((offset >> 1), (offset >> 1) + 2)); - offset += 4; - } - else if (size == "u16") { - out.push("store(bs.offset, " + num + ", " + offset + "); // " + data.slice((offset >> 1), (offset >> 1) + 1)); - offset += 2; - } + if (!this.sources.has(node)) { + return; } - 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 sources = parser.sources + .filter((source) => !isStdlib(source)) + .sort((_a, _b) => { const a = _a.internalPath; const b = _b.internalPath; - if (a[0] == "~" && b[0] !== "~") { + if (a[0] === "~" && b[0] !== "~") { return -1; } - else if (a[0] !== "~" && b[0] == "~") { + 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; + if (!isStdlib(source)) { + transformer.visit(source); } } - const schemas = transformer.schemas; + const schemas = transformer.schemasList; for (const schema of schemas) { if (schema.parent) { - const parent = schemas.find((v) => v.name == schema.parent?.name); + 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); + throw new Error(`Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator! Add the decorator and rebuild.`); } } } } -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; +var PropertyFlags; +(function (PropertyFlags) { + PropertyFlags[PropertyFlags["Null"] = 0] = "Null"; + PropertyFlags[PropertyFlags["Omit"] = 1] = "Omit"; + PropertyFlags[PropertyFlags["OmitNull"] = 2] = "OmitNull"; + PropertyFlags[PropertyFlags["OmitIf"] = 3] = "OmitIf"; + PropertyFlags[PropertyFlags["Alias"] = 4] = "Alias"; + PropertyFlags[PropertyFlags["JSON_Raw"] = 5] = "JSON_Raw"; +})(PropertyFlags || (PropertyFlags = {})); +class Property { + name = ""; + alias = null; + type = ""; + value = null; + flags = new Map(); + serialize = null; + deserialize = null; + initialize = null; + node; + right_s = ""; + right_d = ""; + generate(safe) { + const name = this.name; + const escapedName = escapeString(JSON.stringify(this.alias || this.name)); + const type = this.type; + if (this.flags.has(PropertyFlags.Omit)) + return; + if (this.flags.has(PropertyFlags.JSON_Raw)) { + if (this.flags.has(PropertyFlags.Null)) { + this.right_s = "(this." + name + " || \"null\")"; + this.right_d = "value_start === value_end - 4 && 30399761348886638 === load(changetype(data) + (value_start << 1)) ? null : data.substring(value_start, value_end)"; + } + else { + this.right_s = "this." + name; + this.right_d = "data.substring(value_start, value_end);"; + } + } + else { + this.right_s = "__SERIALIZE<" + type + ">(this." + name + ")"; + this.right_d = + (safe ? "__DESERIALIZE_SAFE" : "__DESERIALIZE") + "<" + type + ">(data.substring(value_start, value_end))"; + } + if (this.flags.has(PropertyFlags.OmitIf)) { + const condition = this.flags.get(PropertyFlags.OmitIf)[0]; + if (!condition) + throw new Error("Could not find condition when using decorator @omitif! Provide at least one condition"); + this.serialize = + "${" + + condition + + ' ? "" : \'' + + escapedName + + ":' + " + + this.right_s + + ' + ","}'; + this.deserialize = "this." + name + " = " + this.right_d + ";"; } - else if (!aMove && bMove) { - return 1; + else if (this.flags.has(PropertyFlags.OmitNull)) { + this.serialize = + "${changetype(this." + + name + + ") == 0" + + ' ? "" : \'' + + escapedName + + ":' + " + + this.right_s + + ' + ","}'; + this.deserialize = "this." + name + " = " + this.right_d + ";"; } else { - return 0; + this.serialize = escapedName + ":${" + this.right_s + "}"; + this.deserialize = "this." + name + " = " + this.right_d + ";"; } - }); + } +} +class SchemaData { + name = ""; + members = []; + parent = null; + node; +} +function charCodeAt32(data, offset) { + return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset); +} +function charCodeAt64(data, offset) { + if (offset + 3 >= data.length) { + throw new Error("The string must have at least 4 characters from the specified offset."); + } + const firstCharCode = BigInt(data.charCodeAt(offset)); + const secondCharCode = BigInt(data.charCodeAt(offset + 1)); + const thirdCharCode = BigInt(data.charCodeAt(offset + 2)); + const fourthCharCode = BigInt(data.charCodeAt(offset + 3)); + const u64Value = (fourthCharCode << 48n) | + (thirdCharCode << 32n) | + (secondCharCode << 16n) | + firstCharCode; + return u64Value; +} +function encodeKey(key) { + const data = JSON.stringify(key); + return data.slice(1, data.length - 1); +} +function escapeString(data) { + return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`"); +} +function escapeSlash(data) { + return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`"); +} +function escapeQuote(data) { + return data.replace(/\"/g, '\\"'); } function getArgs(args) { if (!args) @@ -441,88 +528,4 @@ function getArgs(args) { } return out; } -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; -} -function isPrimitive(type) { - 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; -} -function indentInc() { - indent += " "; -} -function indentDec() { - 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; -} -function allPrimitive(schema) { - return !schema.members.some(p => p.byteSize == 0); -} //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/transform/lib/index.js.map b/transform/lib/index.js.map index 17c4500..481fca4 100644 --- a/transform/lib/index.js.map +++ b/transform/lib/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/transform/lib/index.old.js b/transform/lib/index.old.js deleted file mode 100644 index 2ea265e..0000000 --- a/transform/lib/index.old.js +++ /dev/null @@ -1,466 +0,0 @@ -import { FieldDeclaration, IdentifierExpression, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression } from "assemblyscript/dist/assemblyscript.js"; -import { toString, isStdlib } from "visitor-as/dist/utils.js"; -import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js"; -import { Transform } from "assemblyscript/dist/transform.js"; -class JSONTransform extends BaseVisitor { - schemasList = []; - currentClass; - sources = new Set(); - visitMethodDeclaration() { } - visitClassDeclaration(node) { - if (!node.decorators?.length) - return; - let found = false; - for (const decorator of node.decorators) { - const name = decorator.name.text; - if (name === "json" || name === "serializable") { - found = true; - break; - } - } - if (!found) - return; - const schema = new SchemaData(); - schema.node = node; - schema.name = node.name.text; - const members = [...node.members.filter((v) => v.kind === 54)]; - if (node.extendsType) { - schema.parent = this.schemasList.find((v) => v.name == node.extendsType?.name.identifier.text); - if (schema.parent?.members) { - for (let i = schema.parent.members.length - 1; i >= 0; i--) { - const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name); - if (!replace) { - members.unshift(schema.parent?.members[i].node); - } - } - } - } - if (!members.length) { - let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}'; - let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}"; - let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}"; - if (process.env["JSON_DEBUG"]) { - console.log(SERIALIZE_RAW_EMPTY); - console.log(INITIALIZE_EMPTY); - console.log(DESERIALIZE_EMPTY); - } - const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_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 == "__INITIALIZE")) - node.members.push(INITIALIZE_METHOD_EMPTY); - if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) - node.members.push(DESERIALIZE_METHOD_EMPTY); - this.schemasList.push(schema); - } - for (const member of members) { - const name = member.name; - if (!(member instanceof FieldDeclaration)) - continue; - if (!member.type) { - throw new Error("Fields must be strongly typed! Found " + toString(member) + " at " + node.range.source.normalizedPath); - } - const type = toString(member.type); - if (type.startsWith("(") && type.includes("=>")) - continue; - const value = member.initializer ? toString(member.initializer) : null; - if (member.flags == 32) - continue; - if (member.flags === 512) - continue; - if (member.flags === 1024) - continue; - const mem = new Property(); - mem.name = name.text; - mem.type = type; - mem.value = value; - mem.node = member; - if (type.includes("JSON.Raw")) { - mem.flags.set(PropertyFlags.JSON_Raw, []); - } - if (member.type.isNullable) { - mem.flags.set(PropertyFlags.Null, []); - } - if (member.decorators) { - for (const decorator of member.decorators) { - const decoratorName = decorator.name.text; - const args = getArgs(decorator.args); - switch (decoratorName) { - case "alias": { - if (!args.length) - throw new Error("Expected 1 argument but got zero at @alias in " + node.range.source.normalizedPath); - mem.alias = args[0]; - mem.flags.set(PropertyFlags.Alias, args); - break; - } - case "omit": { - mem.flags.set(PropertyFlags.Omit, args); - break; - } - case "omitif": { - if (!decorator.args?.length) - throw new Error("Expected 1 argument but got zero at @omitif in " + node.range.source.normalizedPath); - mem.flags.set(PropertyFlags.OmitIf, args); - break; - } - case "omitnull": { - mem.flags.set(PropertyFlags.OmitNull, args); - break; - } - } - } - } - mem.generate(false); - if (this.schemasList.find((v) => v.name == type)) { - mem.initialize = "this." + name.text + " = changetype>(__new(offsetof>(), idof>()));\n changetype>(this." + name.text + ").__INITIALIZE()"; - } - else if (mem.value) { - mem.initialize = "this." + name.text + " = " + mem.value; - } - else if (type === "Map") { - mem.initialize = "this." + name.text + " = new " + mem.type + "()"; - } - else if (type === "string") { - mem.initialize = "this." + name.text + ' = ""'; - } - else if (type === "Array") { - mem.initialize = "this." + name.text + " = instantiate<" + mem.type + ">()"; - } - else if (type === "bool" || type === "boolean") { - mem.initialize = "this." + name.text + " = false"; - } - else if (type === "JSON.Raw") { - mem.initialize = "this." + name.text + ' = ""'; - } - else if (type === "u8" || type === "u16" || type === "u32" || type === "u64" || type === "i8" || type === "i16" || type === "i32" || type === "i64") { - mem.initialize = "this." + name.text + " = 0"; - } - else if (type === "f32" || type === "f64") { - mem.initialize = "this." + name.text + " = 0.0"; - } - schema.members.push(mem); - } - let SERIALIZE_RAW = "__SERIALIZE(): string {\n let out = `{"; - let SERIALIZE_PRETTY = "__SERIALIZE_PRETTY(): string {\n let out = `{"; - let INITIALIZE = "__INITIALIZE(): this {\n"; - let DESERIALIZE = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n const len = key_end - key_start;\n"; - let indent = " "; - if (!schema.members.length) - return; - found = false; - if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) || schema.members[0]?.flags.has(PropertyFlags.OmitIf)) { - SERIALIZE_RAW += schema.members[0]?.serialize; - SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize; - } - else { - SERIALIZE_RAW += schema.members[0]?.serialize + ","; - SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n"; - found = true; - } - if (schema.members[0]?.initialize) - INITIALIZE += " " + schema.members[0]?.initialize + ";\n"; - for (let i = 1; i < schema.members.length; i++) { - const member = schema.members[i]; - if (member.initialize) - INITIALIZE += " " + member.initialize + ";\n"; - if (member.flags.has(PropertyFlags.OmitNull) || member.flags.has(PropertyFlags.OmitIf)) { - SERIALIZE_RAW += member.serialize; - SERIALIZE_PRETTY += member.serialize; - } - else { - SERIALIZE_RAW += member.serialize + ","; - SERIALIZE_PRETTY += indent + member.serialize + ",\\n"; - found = true; - } - } - if (found) { - SERIALIZE_RAW += "`;\n store(changetype(out) + ((out.length - 1) << 1), 125);\n return out;\n}"; - SERIALIZE_PRETTY += "`;\n store(changetype(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}"; - } - else { - SERIALIZE_RAW += "}`;\n return out;\n}"; - SERIALIZE_PRETTY += "}`;\n return out;\n}"; - } - INITIALIZE += " return this;\n}"; - const sortedMembers = []; - const _sorted = schema.members.sort((a, b) => (a.alias?.length || a.name.length) - (b.alias?.length || b.name.length)); - let len = -1; - let offset = -1; - for (let i = 0; i < _sorted.length; i++) { - const member = _sorted[i]; - const _name = member.alias || member.name; - if (_name.length === len) { - sortedMembers[offset]?.push(member); - } - else { - sortedMembers.push([member]); - len = _name.length; - offset++; - } - } - let first = true; - for (const memberSet of sortedMembers) { - const firstMember = memberSet[0]; - const _name = encodeKey(firstMember.alias || firstMember.name); - if (_name.length === 1) { - if (first) { - DESERIALIZE += " if (1 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; - first = false; - } - else { - DESERIALIZE += "else if (1 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; - } - } - else if (_name.length === 2) { - if (first) { - DESERIALIZE += " if (2 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; - first = false; - } - else { - DESERIALIZE += "else if (2 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; - } - } - else if (_name.length === 4) { - if (first) { - DESERIALIZE += " if (4 === len) {\n const code = load(changetype(data) + (key_start << 1));\n"; - first = false; - } - else { - DESERIALIZE += "else if (4 === len) {\n const code = load(changetype(data) + (key_start << 1));\n"; - } - } - else { - if (first) { - DESERIALIZE += " if (" + _name.length + " === len) {\n"; - first = false; - } - else { - DESERIALIZE += "else if (" + _name.length + " === len) {\n"; - } - } - let f = true; - for (let i = 0; i < memberSet.length; i++) { - const member = memberSet[i]; - if (!member.deserialize) - continue; - const _name = encodeKey(member.alias || member.name); - if (_name.length === 1) { - DESERIALIZE += ` case ${_name.charCodeAt(0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; - } - else if (_name.length === 2) { - DESERIALIZE += ` case ${charCodeAt32(_name, 0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; - } - else if (_name.length === 4) { - if (f) { - f = false; - DESERIALIZE += ` if (${charCodeAt64(_name, 0)} === code) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; - } - else { - DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + `else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`; - } - } - else { - if (f) { - f = false; - DESERIALIZE += ` if (0 === memory.compare(changetype("${escapeQuote(escapeSlash(_name))}"), changetype(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; - } - else { - DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else if (0 === memory.compare(changetype("${escapeQuote(escapeSlash(_name))}"), changetype(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; - } - } - } - if (_name.length < 3) { - DESERIALIZE += ` default: {\n return false;\n }\n }\n`; - } - else if (_name.length == 4) { - DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`; - } - else { - DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`; - } - DESERIALIZE += " } "; - } - DESERIALIZE += "\n return false;\n}"; - if (process.env["JSON_DEBUG"]) { - console.log(SERIALIZE_RAW); - console.log(INITIALIZE); - console.log(DESERIALIZE); - } - const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(SERIALIZE_RAW, node); - const DESERIALIZE_SAFE = DESERIALIZE.replaceAll("__DESERIALIZE", "__DESERIALIZE_SAFE"); - const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node); - const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node); - const DESERIALIZE_SAFE_METHOD = SimpleParser.parseClassMember(DESERIALIZE_SAFE, node); - if (!node.members.find((v) => v.name.text == "__SERIALIZE")) - node.members.push(SERIALIZE_RAW_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 == "__DESERIALIZE_SAFE")) - node.members.push(DESERIALIZE_SAFE_METHOD); - this.schemasList.push(schema); - } - visitSource(node) { - super.visitSource(node); - if (!this.sources.has(node)) { - return; - } - } -} -export default class Transformer extends Transform { - afterParse(parser) { - const transformer = new JSONTransform(); - const sources = parser.sources - .filter((source) => !isStdlib(source)) - .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; - } - }); - for (const source of sources) { - if (!isStdlib(source)) { - transformer.visit(source); - } - } - const schemas = transformer.schemasList; - for (const schema of schemas) { - if (schema.parent) { - const parent = schemas.find((v) => v.name === schema.parent?.name); - if (!parent) - throw new Error(`Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator! Add the decorator and rebuild.`); - } - } - } -} -var PropertyFlags; -(function (PropertyFlags) { - PropertyFlags[PropertyFlags["Null"] = 0] = "Null"; - PropertyFlags[PropertyFlags["Omit"] = 1] = "Omit"; - PropertyFlags[PropertyFlags["OmitNull"] = 2] = "OmitNull"; - PropertyFlags[PropertyFlags["OmitIf"] = 3] = "OmitIf"; - PropertyFlags[PropertyFlags["Alias"] = 4] = "Alias"; - PropertyFlags[PropertyFlags["JSON_Raw"] = 5] = "JSON_Raw"; -})(PropertyFlags || (PropertyFlags = {})); -class Property { - name = ""; - alias = null; - type = ""; - value = null; - flags = new Map(); - serialize = null; - deserialize = null; - initialize = null; - node; - right_s = ""; - right_d = ""; - generate(safe) { - const name = this.name; - const escapedName = escapeString(JSON.stringify(this.alias || this.name)); - const type = this.type; - if (this.flags.has(PropertyFlags.Omit)) - return; - if (this.flags.has(PropertyFlags.JSON_Raw)) { - if (this.flags.has(PropertyFlags.Null)) { - this.right_s = "(this." + name + ' || "null")'; - this.right_d = "value_start === value_end - 4 && 30399761348886638 === load(changetype(data) + (value_start << 1)) ? null : data.substring(value_start, value_end)"; - } - else { - this.right_s = "this." + name; - this.right_d = "data.substring(value_start, value_end);"; - } - } - else { - this.right_s = "__SERIALIZE<" + type + ">(this." + name + ")"; - this.right_d = (safe ? "__DESERIALIZE_SAFE" : "__DESERIALIZE") + "<" + type + ">(data.substring(value_start, value_end))"; - } - if (this.flags.has(PropertyFlags.OmitIf)) { - const condition = this.flags.get(PropertyFlags.OmitIf)[0]; - if (!condition) - throw new Error("Could not find condition when using decorator @omitif! Provide at least one condition"); - this.serialize = "${" + condition + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}'; - this.deserialize = "this." + name + " = " + this.right_d + ";"; - } - else if (this.flags.has(PropertyFlags.OmitNull)) { - this.serialize = "${changetype(this." + name + ") == 0" + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}'; - this.deserialize = "this." + name + " = " + this.right_d + ";"; - } - else { - this.serialize = escapedName + ":${" + this.right_s + "}"; - this.deserialize = "this." + name + " = " + this.right_d + ";"; - } - } -} -class SchemaData { - name = ""; - members = []; - parent = null; - node; -} -function charCodeAt32(data, offset) { - return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset); -} -function charCodeAt64(data, offset) { - if (offset + 3 >= data.length) { - throw new Error("The string must have at least 4 characters from the specified offset."); - } - const firstCharCode = BigInt(data.charCodeAt(offset)); - const secondCharCode = BigInt(data.charCodeAt(offset + 1)); - const thirdCharCode = BigInt(data.charCodeAt(offset + 2)); - const fourthCharCode = BigInt(data.charCodeAt(offset + 3)); - const u64Value = (fourthCharCode << 48n) | (thirdCharCode << 32n) | (secondCharCode << 16n) | firstCharCode; - return u64Value; -} -function encodeKey(key) { - const data = JSON.stringify(key); - return data.slice(1, data.length - 1); -} -function escapeString(data) { - return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`"); -} -function escapeSlash(data) { - return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`"); -} -function escapeQuote(data) { - return data.replace(/\"/g, '\\"'); -} -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); - } - } - return out; -} -//# sourceMappingURL=index.old.js.map \ No newline at end of file diff --git a/transform/lib/index.old.js.map b/transform/lib/index.old.js.map deleted file mode 100644 index 57956b0..0000000 --- a/transform/lib/index.old.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.old.js","sourceRoot":"","sources":["../src/index.old.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/transform/lib/linker.js b/transform/lib/linker.js deleted file mode 100644 index bd4067b..0000000 --- a/transform/lib/linker.js +++ /dev/null @@ -1,18 +0,0 @@ -export function getImports(source) { - 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; -} -export function getClasses(source) { - return source.statements.filter((v) => v.kind === 51); -} -//# sourceMappingURL=linker.js.map \ No newline at end of file diff --git a/transform/lib/linker.js.map b/transform/lib/linker.js.map deleted file mode 100644 index 22908c9..0000000 --- a/transform/lib/linker.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"linker.js","sourceRoot":"","sources":["../src/linker.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,OAAoB,CAAsB,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,MAAc,EAAE,MAAc;IAC3E,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5F,IAAI,CAAC,cAAc;YAAE,SAAS;QAE9B,MAAM,gBAAgB,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,OAA8B,IAAuB,CAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAA4B,CAAC;QAE5K,IAAI,gBAAgB;YAAE,OAAO,gBAAgB,CAAC;IAChD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,OAA8B,CAAuB,CAAC;AACrG,CAAC"} \ No newline at end of file diff --git a/transform/lib/types.js b/transform/lib/types.js deleted file mode 100644 index a577c46..0000000 --- a/transform/lib/types.js +++ /dev/null @@ -1,25 +0,0 @@ -export var PropertyFlags; -(function (PropertyFlags) { - 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; -} -export class Schema { - static = true; - name = ""; - members = []; - parent = null; - node; - needsLink = null; - byteSize = 0; -} -//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/transform/lib/types.js.map b/transform/lib/types.js.map deleted file mode 100644 index ef48c8a..0000000 --- a/transform/lib/types.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,yDAAQ,CAAA;IACR,qDAAM,CAAA;IACN,+CAAG,CAAA;AACL,CAAC,EAJW,aAAa,KAAb,aAAa,QAIxB;AAED,MAAM,OAAO,QAAQ;IACZ,IAAI,GAAW,EAAE,CAAC;IAClB,KAAK,GAAkB,IAAI,CAAC;IAC5B,IAAI,GAAW,EAAE,CAAC;IAClB,KAAK,GAAkB,IAAI,CAAC;IAC5B,KAAK,GAA0C,IAAI,GAAG,EAAoC,CAAC;IAC3F,IAAI,CAAoB;IACxB,QAAQ,GAAW,CAAC,CAAC;CAC7B;AAED,MAAM,OAAO,MAAM;IACV,MAAM,GAAY,IAAI,CAAC;IACvB,IAAI,GAAW,EAAE,CAAC;IAClB,OAAO,GAAe,EAAE,CAAC;IACzB,MAAM,GAAkB,IAAI,CAAC;IAC7B,IAAI,CAAoB;IACxB,SAAS,GAAkB,IAAI,CAAC;IAChC,QAAQ,GAAW,CAAC,CAAC;CAC7B"} \ No newline at end of file diff --git a/transform/lib/util.js b/transform/lib/util.js deleted file mode 100644 index b8f8129..0000000 --- a/transform/lib/util.js +++ /dev/null @@ -1,47 +0,0 @@ -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 + "'"); - } - 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 + "'"); - } - 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); -} -export function toString(node) { - return ASTBuilder.build(node); -} -//# sourceMappingURL=util.js.map \ No newline at end of file diff --git a/transform/lib/util.js.map b/transform/lib/util.js.map deleted file mode 100644 index df39bed..0000000 --- a/transform/lib/util.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAgH,MAAM,uCAAuC,CAAC;AAChM,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,OAAO,YAAY;IACf,MAAM,KAAK,MAAM;QACvB,OAAO,IAAI,MAAM,EAAE,CAAC;IACtB,CAAC;IAEO,MAAM,CAAC,YAAY,CAAC,CAAS,EAAE,OAAe,UAAU;QAC9D,OAAO,IAAI,SAAS,CAAC,IAAI,MAAM,IAAkB,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,CAAS;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,CAAS,EAAE,QAAQ,GAAG,KAAK;QAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACvE,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,CAAC,sBAAsB,CAAC,CAAS,EAAE,SAAuC;QAC9E,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAChF,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,4CAA4C,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,CAAC,gBAAgB,CAAC,CAAS,EAAE,MAAwB;QACzD,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC;QACzG,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;QACnE,CAAC;QACD,OAA6B,GAAG,CAAC;IACnC,CAAC;CACF;AAED,IAAI,aAAa,GAAG,2RAA2R,CAAC;AAEhT,MAAM,UAAU,QAAQ,CAAC,CAA4B;IACnD,IAAI,MAAM,GAAG,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IACtD,OAAO,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAU;IACjC,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC"} \ No newline at end of file diff --git a/transform/lib/visitor.js b/transform/lib/visitor.js index 6c8dc4c..15a1624 100644 --- a/transform/lib/visitor.js +++ b/transform/lib/visitor.js @@ -1,531 +1,448 @@ +import { ArrayLiteralExpression, AssertionExpression, BinaryExpression, CallExpression, ElementAccessExpression, FloatLiteralExpression, FunctionTypeNode, IdentifierExpression, NamedTypeNode, Node, ObjectLiteralExpression, Source, TypeParameterNode, BlockStatement, BreakStatement, ClassDeclaration, ClassExpression, CommaExpression, ContinueStatement, DecoratorNode, DoStatement, EmptyStatement, EnumDeclaration, EnumValueDeclaration, ExportDefaultStatement, ExportImportStatement, ExportMember, ExportStatement, ExpressionStatement, FieldDeclaration, ForStatement, FunctionDeclaration, FunctionExpression, IfStatement, ImportDeclaration, ImportStatement, IndexSignatureNode, InstanceOfExpression, IntegerLiteralExpression, InterfaceDeclaration, LiteralExpression, MethodDeclaration, NamespaceDeclaration, NewExpression, ParameterNode, ParenthesizedExpression, PropertyAccessExpression, RegexpLiteralExpression, ReturnStatement, StringLiteralExpression, SwitchCase, SwitchStatement, TemplateLiteralExpression, TernaryExpression, ThrowStatement, TryStatement, TypeDeclaration, TypeName, UnaryPostfixExpression, UnaryPrefixExpression, VariableDeclaration, VariableStatement, WhileStatement } from "assemblyscript/dist/assemblyscript.js"; 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); - } - } - _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); - } - } - 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) { } + constructor() { + this.currentSource = null; + this.depth = 0; + } + visit(node) { + if (node == null) { + return; + } else if (node instanceof Array) { + for (const element of node) { + this.visit(element); + } + } else if (node instanceof Map) { + for (const element of node.values()) { + this.visit(element); + } + // @ts-ignore + } else if (typeof node[Symbol.iterator] === "function") { + // @ts-ignore + for (const element of node) { + this.visit(element); + } + } else if (node instanceof Node) { + this._visit(node); + } else { + throw new Error("Could not visit invalid type!"); + } + } + _visit(node) { + if (node instanceof Source) { + this.visitSource(node); + } else if (node instanceof NamedTypeNode) { + this.visitNamedTypeNode(node); + } else if (node instanceof FunctionTypeNode) { + this.visitFunctionTypeNode(node); + } else if (node instanceof TypeName) { + this.visitTypeName(node); + } else if (node instanceof TypeParameterNode) { + this.visitTypeParameter(node); + } else if (node instanceof IdentifierExpression) { + this.visitIdentifierExpression(node); + } else if (node instanceof AssertionExpression) { + this.visitAssertionExpression(node); + } else if (node instanceof BinaryExpression) { + this.visitBinaryExpression(node); + } else if (node instanceof CallExpression) { + this.visitCallExpression(node); + } else if (node instanceof ClassExpression) { + this.visitClassExpression(node); + } else if (node instanceof CommaExpression) { + this.visitCommaExpression(node); + } else if (node instanceof ElementAccessExpression) { + this.visitElementAccessExpression(node); + } else if (node instanceof FunctionExpression) { + this.visitFunctionExpression(node); + } else if (node instanceof InstanceOfExpression) { + this.visitInstanceOfExpression(node); + } else if (node instanceof LiteralExpression) { + this.visitLiteralExpression(node); + } else if (node instanceof NewExpression) { + this.visitNewExpression(node); + } else if (node instanceof ParenthesizedExpression) { + this.visitParenthesizedExpression(node); + } else if (node instanceof PropertyAccessExpression) { + this.visitPropertyAccessExpression(node); + } else if (node instanceof TernaryExpression) { + this.visitTernaryExpression(node); + } else if (node instanceof UnaryPostfixExpression) { + this.visitUnaryPostfixExpression(node); + } else if (node instanceof UnaryPrefixExpression) { + this.visitUnaryPrefixExpression(node); + } else if (node instanceof BlockStatement) { + this.visitBlockStatement(node); + } else if (node instanceof BreakStatement) { + this.visitBreakStatement(node); + } else if (node instanceof ContinueStatement) { + this.visitContinueStatement(node); + } else if (node instanceof DoStatement) { + this.visitDoStatement(node); + } else if (node instanceof EmptyStatement) { + this.visitEmptyStatement(node); + } else if (node instanceof ExportStatement) { + this.visitExportStatement(node); + } else if (node instanceof ExportDefaultStatement) { + this.visitExportDefaultStatement(node); + } else if (node instanceof ExportImportStatement) { + this.visitExportImportStatement(node); + } else if (node instanceof ExpressionStatement) { + this.visitExpressionStatement(node); + } else if (node instanceof ForStatement) { + this.visitForStatement(node); + } else if (node instanceof IfStatement) { + this.visitIfStatement(node); + } else if (node instanceof ImportStatement) { + this.visitImportStatement(node); + } else if (node instanceof ReturnStatement) { + this.visitReturnStatement(node); + } else if (node instanceof SwitchStatement) { + this.visitSwitchStatement(node); + } else if (node instanceof ThrowStatement) { + this.visitThrowStatement(node); + } else if (node instanceof TryStatement) { + this.visitTryStatement(node); + } else if (node instanceof VariableStatement) { + this.visitVariableStatement(node); + } else if (node instanceof WhileStatement) { + this.visitWhileStatement(node); + } else if (node instanceof ClassDeclaration) { + this.visitClassDeclaration(node); + } else if (node instanceof EnumDeclaration) { + this.visitEnumDeclaration(node); + } else if (node instanceof EnumValueDeclaration) { + this.visitEnumValueDeclaration(node); + } else if (node instanceof FieldDeclaration) { + this.visitFieldDeclaration(node); + } else if (node instanceof FunctionDeclaration) { + this.visitFunctionDeclaration(node); + } else if (node instanceof ImportDeclaration) { + this.visitImportDeclaration(node); + } else if (node instanceof InterfaceDeclaration) { + this.visitInterfaceDeclaration(node); + } else if (node instanceof MethodDeclaration) { + this.visitMethodDeclaration(node); + } else if (node instanceof NamespaceDeclaration) { + this.visitNamespaceDeclaration(node); + } else if (node instanceof TypeDeclaration) { + this.visitTypeDeclaration(node); + } else if (node instanceof VariableDeclaration) { + this.visitVariableDeclaration(node); + } else if (node instanceof DecoratorNode) { + this.visitDecoratorNode(node); + } else if (node instanceof ExportMember) { + this.visitExportMember(node); + } else if (node instanceof ParameterNode) { + this.visitParameter(node); + } else if (node instanceof SwitchCase) { + this.visitSwitchCase(node); + } else if (node instanceof IndexSignatureNode) { + this.visitIndexSignature(node); + } else { + throw new Error("Could not visit invalid type!"); + } + } + visitSource(node) { + this.currentSource = node; + for (const stmt of node.statements) { + this.depth++; + this._visit(stmt); + this.depth--; + } + this.currentSource = null; + } + visitTypeNode(node) {} + visitTypeName(node) { + this.visit(node.identifier); + this.visit(node.next); + } + visitNamedTypeNode(node) { + this.visit(node.name); + this.visit(node.typeArguments); + } + visitFunctionTypeNode(node) { + this.visit(node.parameters); + this.visit(node.returnType); + this.visit(node.explicitThisType); + } + visitTypeParameter(node) { + this.visit(node.name); + this.visit(node.extendsType); + this.visit(node.defaultType); + } + visitIdentifierExpression(node) {} + visitArrayLiteralExpression(node) { + this.visit(node.elementExpressions); + } + visitObjectLiteralExpression(node) { + this.visit(node.names); + this.visit(node.values); + } + visitAssertionExpression(node) { + this.visit(node.toType); + this.visit(node.expression); + } + visitBinaryExpression(node) { + this.visit(node.left); + this.visit(node.right); + } + visitCallExpression(node) { + this.visit(node.expression); + this.visitArguments(node.typeArguments, node.args); + } + visitArguments(typeArguments, args) { + this.visit(typeArguments); + this.visit(args); + } + visitClassExpression(node) { + this.visit(node.declaration); + } + visitCommaExpression(node) { + this.visit(node.expressions); + } + visitElementAccessExpression(node) { + this.visit(node.elementExpression); + this.visit(node.expression); + } + visitFunctionExpression(node) { + this.visit(node.declaration); + } + visitLiteralExpression(node) { + if (node instanceof FloatLiteralExpression) { + this.visitFloatLiteralExpression(node); + } else if (node instanceof IntegerLiteralExpression) { + this.visitIntegerLiteralExpression(node); + } else if (node instanceof StringLiteralExpression) { + this.visitStringLiteralExpression(node); + } else if (node instanceof TemplateLiteralExpression) { + this.visitTemplateLiteralExpression(node); + } else if (node instanceof RegexpLiteralExpression) { + this.visitRegexpLiteralExpression(node); + } else if (node instanceof ArrayLiteralExpression) { + this.visitArrayLiteralExpression(node); + } else if (node instanceof ObjectLiteralExpression) { + this.visitObjectLiteralExpression(node); + } else { + throw new Error("Invalid LiteralKind at visitLiteralExpression(): " + node.literalKind); + } + } + visitFloatLiteralExpression(node) {} + visitInstanceOfExpression(node) { + this.visit(node.expression); + this.visit(node.isType); + } + visitIntegerLiteralExpression(node) {} + visitStringLiteral(str, singleQuoted = false) {} + visitStringLiteralExpression(node) { + this.visitStringLiteral(node.value); + } + visitTemplateLiteralExpression(node) {} + visitRegexpLiteralExpression(node) {} + visitNewExpression(node) { + this.visit(node.typeArguments); + this.visitArguments(node.typeArguments, node.args); + this.visit(node.args); + } + visitParenthesizedExpression(node) { + this.visit(node.expression); + } + visitPropertyAccessExpression(node) { + this.visit(node.property); + this.visit(node.expression); + } + visitTernaryExpression(node) { + this.visit(node.condition); + this.visit(node.ifThen); + this.visit(node.ifElse); + } + visitUnaryExpression(node) { + this.visit(node.operand); + } + visitUnaryPostfixExpression(node) { + this.visit(node.operand); + } + visitUnaryPrefixExpression(node) { + this.visit(node.operand); + } + visitSuperExpression(node) {} + visitFalseExpression(node) {} + visitTrueExpression(node) {} + visitThisExpression(node) {} + visitNullExperssion(node) {} + visitConstructorExpression(node) {} + visitNodeAndTerminate(statement) {} + visitBlockStatement(node) { + this.depth++; + this.visit(node.statements); + this.depth--; + } + visitBreakStatement(node) { + this.visit(node.label); + } + visitContinueStatement(node) { + this.visit(node.label); + } + visitClassDeclaration(node, isDefault = false) { + this.visit(node.name); + this.depth++; + this.visit(node.decorators); + if (node.isGeneric ? node.typeParameters != null : node.typeParameters == null) { + this.visit(node.typeParameters); + this.visit(node.extendsType); + this.visit(node.implementsTypes); + this.visit(node.members); + this.depth--; + } else { + throw new Error("Expected to type parameters to match class declaration, but found type mismatch instead!"); + } + } + visitDoStatement(node) { + this.visit(node.condition); + this.visit(node.body); + } + visitEmptyStatement(node) {} + visitEnumDeclaration(node, isDefault = false) { + this.visit(node.name); + this.visit(node.decorators); + this.visit(node.values); + } + visitEnumValueDeclaration(node) { + this.visit(node.name); + this.visit(node.initializer); + } + visitExportImportStatement(node) { + this.visit(node.name); + this.visit(node.externalName); + } + visitExportMember(node) { + this.visit(node.localName); + this.visit(node.exportedName); + } + visitExportStatement(node) { + this.visit(node.path); + this.visit(node.members); + } + visitExportDefaultStatement(node) { + this.visit(node.declaration); + } + visitExpressionStatement(node) { + this.visit(node.expression); + } + visitFieldDeclaration(node) { + this.visit(node.name); + this.visit(node.type); + this.visit(node.initializer); + this.visit(node.decorators); + } + visitForStatement(node) { + this.visit(node.initializer); + this.visit(node.condition); + this.visit(node.incrementor); + this.visit(node.body); + } + visitFunctionDeclaration(node, isDefault = false) { + this.visit(node.name); + this.visit(node.decorators); + this.visit(node.typeParameters); + this.visit(node.signature); + this.depth++; + this.visit(node.body); + this.depth--; + } + visitIfStatement(node) { + this.visit(node.condition); + this.visit(node.ifTrue); + this.visit(node.ifFalse); + } + visitImportDeclaration(node) { + this.visit(node.foreignName); + this.visit(node.name); + this.visit(node.decorators); + } + visitImportStatement(node) { + this.visit(node.namespaceName); + this.visit(node.declarations); + } + visitIndexSignature(node) { + this.visit(node.keyType); + this.visit(node.valueType); + } + visitInterfaceDeclaration(node, isDefault = false) { + this.visit(node.name); + this.visit(node.typeParameters); + this.visit(node.implementsTypes); + this.visit(node.extendsType); + this.depth++; + this.visit(node.members); + this.depth--; + } + visitMethodDeclaration(node) { + this.visit(node.name); + this.visit(node.typeParameters); + this.visit(node.signature); + this.visit(node.decorators); + this.depth++; + this.visit(node.body); + this.depth--; + } + visitNamespaceDeclaration(node, isDefault = false) { + this.visit(node.name); + this.visit(node.decorators); + this.visit(node.members); + } + visitReturnStatement(node) { + this.visit(node.value); + } + visitSwitchCase(node) { + this.visit(node.label); + this.visit(node.statements); + } + visitSwitchStatement(node) { + this.visit(node.condition); + this.depth++; + this.visit(node.cases); + this.depth--; + } + visitThrowStatement(node) { + this.visit(node.value); + } + visitTryStatement(node) { + this.visit(node.bodyStatements); + this.visit(node.catchVariable); + this.visit(node.catchStatements); + this.visit(node.finallyStatements); + } + visitTypeDeclaration(node) { + this.visit(node.name); + this.visit(node.decorators); + this.visit(node.type); + this.visit(node.typeParameters); + } + visitVariableDeclaration(node) { + this.visit(node.name); + this.visit(node.type); + this.visit(node.initializer); + } + visitVariableStatement(node) { + this.visit(node.decorators); + this.visit(node.declarations); + } + visitWhileStatement(node) { + this.visit(node.condition); + this.depth++; + this.visit(node.body); + this.depth--; + } + visitVoidStatement(node) {} + visitComment(node) {} + visitDecoratorNode(node) { + this.visit(node.name); + this.visit(node.args); + } + visitParameter(node) { + this.visit(node.name); + this.visit(node.implicitFieldDeclaration); + this.visit(node.initializer); + this.visit(node.type); + } } -//# sourceMappingURL=visitor.js.map \ No newline at end of file diff --git a/transform/lib/visitor.js.map b/transform/lib/visitor.js.map deleted file mode 100644 index 3207307..0000000 --- a/transform/lib/visitor.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"visitor.js","sourceRoot":"","sources":["../src/visitor.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/transform/src/builder.ts b/transform/src/builder.ts deleted file mode 100644 index ab58e8f..0000000 --- a/transform/src/builder.ts +++ /dev/null @@ -1,1371 +0,0 @@ -// Taken from https://github.com/as-pect/visitor-as/blob/master/src/astBuilder.ts -// tslint:disable: as-internal-case - -import { CommonFlags, TypeNode, Node, NodeKind, Source, NamedTypeNode, FunctionTypeNode, TypeParameterNode, IdentifierExpression, CallExpression, ClassExpression, ElementAccessExpression, FunctionExpression, InstanceOfExpression, LiteralExpression, NewExpression, ParenthesizedExpression, PropertyAccessExpression, TernaryExpression, UnaryPostfixExpression, UnaryPrefixExpression, BlockStatement, BreakStatement, ContinueStatement, DoStatement, EmptyStatement, ExportStatement, ExportDefaultStatement, ExportImportStatement, ExpressionStatement, ForStatement, IfStatement, ImportStatement, ReturnStatement, SwitchStatement, ThrowStatement, TryStatement, VariableStatement, WhileStatement, ClassDeclaration, EnumDeclaration, EnumValueDeclaration, FieldDeclaration, FunctionDeclaration, ImportDeclaration, InterfaceDeclaration, MethodDeclaration, NamespaceDeclaration, TypeDeclaration, VariableDeclaration, DecoratorNode, ExportMember, ParameterNode, SwitchCase, TypeName, ArrayLiteralExpression, Expression, ObjectLiteralExpression, AssertionKind, LiteralKind, FloatLiteralExpression, StringLiteralExpression, RegexpLiteralExpression, UnaryExpression, ArrowKind, ParameterKind, DeclarationStatement, AssertionExpression, BinaryExpression, CommaExpression, IntegerLiteralExpression, isTypeOmitted, operatorTokenToString, ForOfStatement, IndexSignatureNode, TemplateLiteralExpression, util, FalseExpression, NullExpression, TrueExpression } from "assemblyscript/dist/assemblyscript.js"; -import { Visitor } from "./visitor.js"; - -function assert(isTruish: T, message: string = "assertion error"): T { - if (!isTruish) throw new Error(message); - return isTruish; -} - -/** An AST builder. */ -export class ASTBuilder extends Visitor { - /** Rebuilds the textual source from the specified AST, as far as possible. */ - static build(node: Node): string { - var builder = new ASTBuilder(); - builder.visitNode(node); - return builder.finish(); - } - - private sb: string[] = []; - private indentLevel: number = 0; - visitNode(node: Node) { - return this.visit(node); - } - - visitSource(source: Source): void { - var statements = source.statements; - for (let i = 0, k = statements.length; i < k; ++i) { - this.visitNodeAndTerminate(statements[i]); - } - } - - // types - - visitTypeNode(node: TypeNode): void { - switch (node.kind) { - case NodeKind.NamedType: { - this.visitNamedTypeNode(node); - break; - } - case NodeKind.FunctionType: { - this.visitFunctionTypeNode(node); - break; - } - default: - assert(false); - } - } - - visitTypeName(node: TypeName): void { - this.visitIdentifierExpression(node.identifier); - var sb = this.sb; - var current = node.next; - while (current) { - sb.push("."); - this.visitIdentifierExpression(current.identifier); - current = current.next; - } - } - - visitNamedTypeNode(node: NamedTypeNode): void { - 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"); - } - } - - visitFunctionTypeNode(node: FunctionTypeNode): void { - 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: TypeParameterNode): void { - 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); - } - } - - // expressions - - visitIdentifierExpression(node: IdentifierExpression): void { - if (node.isQuoted) this.visitStringLiteral(node.text); - else this.sb.push(node.text); - } - - visitArrayLiteralExpression(node: ArrayLiteralExpression): void { - 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: ObjectLiteralExpression): void { - 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("}"); - } else { - sb.push("{}"); - } - } - - visitAssertionExpression(node: AssertionExpression): void { - var sb = this.sb; - switch (node.assertionKind) { - case AssertionKind.Prefix: { - sb.push("<"); - if (node.toType) this.visitTypeNode(node.toType); - sb.push(">"); - this.visitNode(node.expression); - break; - } - case AssertionKind.As: { - this.visitNode(node.expression); - sb.push(" as "); - if (node.toType) this.visitTypeNode(node.toType); - break; - } - case AssertionKind.NonNull: { - this.visitNode(node.expression); - sb.push("!"); - break; - } - case AssertionKind.Const: { - this.visitNode(node.expression); - sb.push(" as const"); - break; - } - default: - assert(false); - } - } - - visitBinaryExpression(node: BinaryExpression): void { - var sb = this.sb; - this.visitNode(node.left); - sb.push(" "); - sb.push(operatorTokenToString(node.operator)); - sb.push(" "); - this.visitNode(node.right); - } - - visitCallExpression(node: CallExpression): void { - this.visitNode(node.expression); - this.visitArguments(node.typeArguments, node.args); - } - - visitArguments(typeArguments: TypeNode[] | null, args: Expression[]): void { - 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(")"); - } - - visitClassExpression(node: ClassExpression): void { - var declaration = node.declaration; - this.visitClassDeclaration(declaration); - } - - visitCommaExpression(node: CommaExpression): void { - 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: ElementAccessExpression): void { - var sb = this.sb; - this.visitNode(node.expression); - sb.push("["); - this.visitNode(node.elementExpression); - sb.push("]"); - } - - visitFunctionExpression(node: FunctionExpression): void { - 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: LiteralExpression): void { - switch (node.literalKind) { - case LiteralKind.Float: { - this.visitFloatLiteralExpression(node); - break; - } - case LiteralKind.Integer: { - this.visitIntegerLiteralExpression(node); - break; - } - case LiteralKind.String: { - this.visitStringLiteralExpression(node); - break; - } - case LiteralKind.Template: { - this.visitTemplateLiteralExpression(node); - break; - } - case LiteralKind.RegExp: { - this.visitRegexpLiteralExpression(node); - break; - } - case LiteralKind.Array: { - this.visitArrayLiteralExpression(node); - break; - } - case LiteralKind.Object: { - this.visitObjectLiteralExpression(node); - break; - } - default: { - assert(false); - break; - } - } - } - - visitFloatLiteralExpression(node: FloatLiteralExpression): void { - this.sb.push(node.value.toString()); - } - - visitInstanceOfExpression(node: InstanceOfExpression): void { - this.visitNode(node.expression); - this.sb.push(" instanceof "); - this.visitTypeNode(node.isType); - } - - visitIntegerLiteralExpression(node: IntegerLiteralExpression): void { - this.sb.push(i64_to_string(node.value)); - } - - visitStringLiteral(str: string): void { - var sb = this.sb; - sb.push('"'); - this.visitRawString(str, util.CharCode.DoubleQuote); - sb.push('"'); - } - - private visitRawString(str: string, quote: util.CharCode): void { - var sb = this.sb; - var off = 0; - var i = 0; - for (let k = str.length; i < k; ) { - switch (str.charCodeAt(i)) { - case util.CharCode.Null: { - if (i > off) sb.push(str.substring(off, (off = i + 1))); - sb.push("\\0"); - off = ++i; - break; - } - case util.CharCode.Backslash: { - if (i > off) sb.push(str.substring(off, i)); - off = ++i; - sb.push("\\b"); - break; - } - case util.CharCode.Tab: { - if (i > off) sb.push(str.substring(off, i)); - off = ++i; - sb.push("\\t"); - break; - } - case util.CharCode.LineFeed: { - if (i > off) sb.push(str.substring(off, i)); - off = ++i; - sb.push("\\n"); - break; - } - case util.CharCode.VerticalTab: { - if (i > off) sb.push(str.substring(off, i)); - off = ++i; - sb.push("\\v"); - break; - } - case util.CharCode.FormFeed: { - if (i > off) sb.push(str.substring(off, i)); - off = ++i; - sb.push("\\f"); - break; - } - case util.CharCode.CarriageReturn: { - if (i > off) sb.push(str.substring(off, i)); - sb.push("\\r"); - off = ++i; - break; - } - case util.CharCode.DoubleQuote: { - if (quote == util.CharCode.DoubleQuote) { - if (i > off) sb.push(str.substring(off, i)); - sb.push('\\"'); - off = ++i; - } else { - ++i; - } - break; - } - case util.CharCode.SingleQuote: { - if (quote == util.CharCode.SingleQuote) { - if (i > off) sb.push(str.substring(off, i)); - sb.push("\\'"); - off = ++i; - } else { - ++i; - } - break; - } - case util.CharCode.Backslash: { - if (i > off) sb.push(str.substring(off, i)); - sb.push("\\\\"); - off = ++i; - break; - } - case util.CharCode.Backtick: { - if (quote == util.CharCode.Backtick) { - 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: StringLiteralExpression): void { - this.visitStringLiteral(node.value); - } - - visitTemplateLiteralExpression(node: TemplateLiteralExpression): void { - 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], util.CharCode.Backtick); - 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], util.CharCode.Backtick); - } - sb.push("`"); - } - - visitRegexpLiteralExpression(node: RegexpLiteralExpression): void { - var sb = this.sb; - sb.push("/"); - sb.push(node.pattern); - sb.push("/"); - sb.push(node.patternFlags); - } - - visitNewExpression(node: NewExpression): void { - this.sb.push("new "); - this.visitTypeName(node.typeName); - this.visitArguments(node.typeArguments, node.args); - } - - visitParenthesizedExpression(node: ParenthesizedExpression): void { - var sb = this.sb; - sb.push("("); - this.visitNode(node.expression); - sb.push(")"); - } - - visitPropertyAccessExpression(node: PropertyAccessExpression): void { - this.visitNode(node.expression); - this.sb.push("."); - this.visitIdentifierExpression(node.property); - } - - visitTernaryExpression(node: TernaryExpression): void { - var sb = this.sb; - this.visitNode(node.condition); - sb.push(" ? "); - this.visitNode(node.ifThen); - sb.push(" : "); - this.visitNode(node.ifElse); - } - - visitUnaryExpression(node: UnaryExpression): void { - switch (node.kind) { - case NodeKind.UnaryPostfix: { - this.visitUnaryPostfixExpression(node); - break; - } - case NodeKind.UnaryPrefix: { - this.visitUnaryPrefixExpression(node); - break; - } - default: - assert(false); - } - } - - visitUnaryPostfixExpression(node: UnaryPostfixExpression): void { - this.visitNode(node.operand); - this.sb.push(operatorTokenToString(node.operator)); - } - - visitUnaryPrefixExpression(node: UnaryPrefixExpression): void { - this.sb.push(operatorTokenToString(node.operator)); - this.visitNode(node.operand); - } - - // statements - - visitNodeAndTerminate(node: Node): void { - this.visitNode(node); - var sb = this.sb; - if ( - !sb.length || // leading EmptyStatement - node.kind == NodeKind.Variable || // potentially assigns a FunctionExpression - node.kind == NodeKind.Expression // potentially assigns a FunctionExpression - ) { - sb.push(";\n"); - } else { - let last = sb[sb.length - 1]; - let lastCharPos = last.length - 1; - if (lastCharPos >= 0 && (last.charCodeAt(lastCharPos) == util.CharCode.CloseBrace || last.charCodeAt(lastCharPos) == util.CharCode.Semicolon)) { - sb.push("\n"); - } else { - sb.push(";\n"); - } - } - } - - visitBlockStatement(node: BlockStatement): void { - 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("{}"); - } - } - - visitBreakStatement(node: BreakStatement): void { - var label = node.label; - if (label) { - this.sb.push("break "); - this.visitIdentifierExpression(label); - } else { - this.sb.push("break"); - } - } - - visitContinueStatement(node: ContinueStatement): void { - var label = node.label; - if (label) { - this.sb.push("continue "); - this.visitIdentifierExpression(label); - } else { - this.sb.push("continue"); - } - } - - visitClassDeclaration(node: ClassDeclaration, isDefault = false): void { - 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(CommonFlags.Abstract)) 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 != NodeKind.FieldDeclaration || (member).parameterIndex < 0) { - util.indent(sb, indentLevel); - this.visitNodeAndTerminate(member); - } - } - util.indent(sb, --this.indentLevel); - sb.push("}"); - } else { - sb.push(" {}"); - } - } - - visitDoStatement(node: DoStatement): void { - var sb = this.sb; - sb.push("do "); - this.visitNode(node.body); - if (node.body.kind == NodeKind.Block) { - sb.push(" while ("); - } else { - util.indent(sb, this.indentLevel); - sb.push("while ("); - } - this.visitNode(node.condition); - sb.push(")"); - } - - visitEmptyStatement(node: EmptyStatement): void { - /* nop */ - } - - visitEnumDeclaration(node: EnumDeclaration, isDefault = false): void { - var sb = this.sb; - if (isDefault) { - sb.push("export default "); - } else { - this.serializeExternalModifiers(node); - } - if (node.is(CommonFlags.Const)) 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(" {}"); - } - } - - visitEnumValueDeclaration(node: EnumValueDeclaration): void { - this.visitIdentifierExpression(node.name); - var initializer = node.initializer; - if (initializer) { - this.sb.push(" = "); - this.visitNode(initializer); - } - } - - visitExportImportStatement(node: ExportImportStatement): void { - var sb = this.sb; - sb.push("export import "); - this.visitIdentifierExpression(node.externalName); - sb.push(" = "); - this.visitIdentifierExpression(node.name); - } - - visitExportMember(node: ExportMember): void { - this.visitIdentifierExpression(node.localName); - if (node.exportedName.text != node.localName.text) { - this.sb.push(" as "); - this.visitIdentifierExpression(node.exportedName); - } - } - - visitExportStatement(node: ExportStatement): void { - 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(";"); - } - - visitExportDefaultStatement(node: ExportDefaultStatement): void { - var declaration = node.declaration; - switch (declaration.kind) { - case NodeKind.EnumDeclaration: { - this.visitEnumDeclaration(declaration, true); - break; - } - case NodeKind.FunctionDeclaration: { - this.visitFunctionDeclaration(declaration, true); - break; - } - case NodeKind.ClassDeclaration: { - this.visitClassDeclaration(declaration, true); - break; - } - case NodeKind.InterfaceDeclaration: { - this.visitInterfaceDeclaration(declaration, true); - break; - } - case NodeKind.NamespaceDeclaration: { - this.visitNamespaceDeclaration(declaration, true); - break; - } - default: - assert(false); - } - } - - visitExpressionStatement(node: ExpressionStatement): void { - this.visitNode(node.expression); - } - - visitFieldDeclaration(node: FieldDeclaration): void { - 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 & CommonFlags.DefinitelyAssigned) { - sb.push("!"); - } - var type = node.type; - if (type) { - sb.push(": "); - this.visitTypeNode(type); - } - var initializer = node.initializer; - if (initializer) { - sb.push(" = "); - this.visitNode(initializer); - } - } - - visitForStatement(node: ForStatement): void { - 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); - } - - visitForOfStatement(node: ForOfStatement): void { - 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: FunctionDeclaration, isDefault = false): void { - 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); - } - - visitFunctionCommon(node: FunctionDeclaration): void { - 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 == ArrowKind.Single) { - 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 == ArrowKind.Single) { - 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(CommonFlags.Constructor | CommonFlags.Set)) { - sb.push("): "); - this.visitTypeNode(returnType); - } else { - sb.push(")"); - } - if (body) { - sb.push(" "); - this.visitNode(body); - } - } - } - - visitIfStatement(node: IfStatement): void { - var sb = this.sb; - sb.push("if ("); - this.visitNode(node.condition); - sb.push(") "); - var ifTrue = node.ifTrue; - this.visitNode(ifTrue); - if (ifTrue.kind != NodeKind.Block) { - sb.push(";\n"); - } - var ifFalse = node.ifFalse; - if (ifFalse) { - if (ifTrue.kind == NodeKind.Block) { - sb.push(" else "); - } else { - sb.push("else "); - } - this.visitNode(ifFalse); - } - } - - visitImportDeclaration(node: ImportDeclaration): void { - 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: ImportStatement): void { - 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); - } - - visitIndexSignature(node: IndexSignatureNode): void { - var sb = this.sb; - sb.push("[key: "); - this.visitTypeNode(node.keyType); - sb.push("]: "); - this.visitTypeNode(node.valueType); - } - - visitInterfaceDeclaration(node: InterfaceDeclaration, isDefault = false): void { - 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); - } - // must not have implementsTypes - 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("}"); - } - - visitMethodDeclaration(node: MethodDeclaration): void { - 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(CommonFlags.Get)) { - this.sb.push("get "); - } else if (node.is(CommonFlags.Set)) { - this.sb.push("set "); - } - this.visitFunctionCommon(node); - } - - visitNamespaceDeclaration(node: NamespaceDeclaration, isDefault = false): void { - 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(" {}"); - } - } - - visitReturnStatement(node: ReturnStatement): void { - var value = node.value; - if (value) { - this.sb.push("return "); - this.visitNode(value); - } else { - this.sb.push("return"); - } - } - - visitTrueExpression(node: TrueExpression): void { - this.sb.push("true"); - } - - visitFalseExpression(node: FalseExpression): void { - this.sb.push("false"); - } - visitNullExpression(node: NullExpression): void { - this.sb.push("null"); - } - visitSwitchCase(node: SwitchCase): void { - 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; - } - } - - visitSwitchStatement(node: SwitchStatement): void { - 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("}"); - } - - visitThrowStatement(node: ThrowStatement): void { - this.sb.push("throw "); - this.visitNode(node.value); - } - - visitTryStatement(node: TryStatement): void { - 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]); - } - 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("}"); - } - - visitTypeDeclaration(node: TypeDeclaration): void { - 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); - } - - visitVariableDeclaration(node: VariableDeclaration): void { - this.visitIdentifierExpression(node.name); - var type = node.type; - var sb = this.sb; - if (node.flags & CommonFlags.DefinitelyAssigned) { - sb.push("!"); - } - if (type) { - sb.push(": "); - this.visitTypeNode(type); - } - var initializer = node.initializer; - if (initializer) { - sb.push(" = "); - this.visitNode(initializer); - } - } - - visitVariableStatement(node: VariableStatement): void { - 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(CommonFlags.Const) ? "const " : firstDeclaration.is(CommonFlags.Let) ? "let " : "var "); - this.visitVariableDeclaration(node.declarations[0]); - for (let i = 1; i < numDeclarations; ++i) { - sb.push(", "); - this.visitVariableDeclaration(node.declarations[i]); - } - } - - visitWhileStatement(node: WhileStatement): void { - var sb = this.sb; - sb.push("while ("); - this.visitNode(node.condition); - var statement = node.body; - if (statement.kind == NodeKind.Empty) { - sb.push(")"); - } else { - sb.push(") "); - this.visitNode(node.body); - } - } - - // other - - serializeDecorator(node: DecoratorNode): void { - 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); - } - - serializeParameter(node: ParameterNode): void { - var sb = this.sb; - var kind = node.parameterKind; - var implicitFieldDeclaration = node.implicitFieldDeclaration; - if (implicitFieldDeclaration) { - this.serializeAccessModifiers(implicitFieldDeclaration); - } - if (kind == ParameterKind.Rest) { - sb.push("..."); - } - this.visitIdentifierExpression(node.name); - var type = node.type; - var initializer = node.initializer; - if (type) { - if (kind == ParameterKind.Optional && !initializer) sb.push("?"); - if (!isTypeOmitted(type)) { - sb.push(": "); - this.visitTypeNode(type); - } - } - if (initializer) { - sb.push(" = "); - this.visitNode(initializer); - } - } - - serializeExternalModifiers(node: DeclarationStatement): void { - var sb = this.sb; - if (node.is(CommonFlags.Export)) { - sb.push("export "); - } else if (node.is(CommonFlags.Import)) { - sb.push("import "); - } else if (node.is(CommonFlags.Declare)) { - sb.push("declare "); - } - } - - serializeAccessModifiers(node: DeclarationStatement): void { - var sb = this.sb; - if (node.is(CommonFlags.Public)) { - sb.push("public "); - } else if (node.is(CommonFlags.Private)) { - sb.push("private "); - } else if (node.is(CommonFlags.Protected)) { - sb.push("protected "); - } - if (node.is(CommonFlags.Static)) { - sb.push("static "); - } else if (node.is(CommonFlags.Abstract)) { - sb.push("abstract "); - } - if (node.is(CommonFlags.Readonly)) { - sb.push("readonly "); - } - } - - finish(): string { - var ret = this.sb.join(""); - this.sb = []; - return ret; - } -} diff --git a/transform/src/index.old.ts b/transform/src/index.old.ts deleted file mode 100644 index f81666a..0000000 --- a/transform/src/index.old.ts +++ /dev/null @@ -1,483 +0,0 @@ -import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, Expression, CommonFlags, StringLiteralExpression, IntegerLiteralExpression, FloatLiteralExpression, NullExpression, TrueExpression, FalseExpression } from "assemblyscript/dist/assemblyscript.js"; - -import { toString, isStdlib } from "visitor-as/dist/utils.js"; -import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js"; -import { Transform } from "assemblyscript/dist/transform.js"; - -class JSONTransform extends BaseVisitor { - public schemasList: SchemaData[] = []; - public currentClass!: SchemaData; - public sources = new Set(); - - visitMethodDeclaration(): void {} - visitClassDeclaration(node: ClassDeclaration): void { - if (!node.decorators?.length) return; - - let found = false; - for (const decorator of node.decorators) { - const name = (decorator.name).text; - if (name === "json" || name === "serializable") { - found = true; - break; - } - } - if (!found) return; - - const schema = new SchemaData(); - schema.node = node; - schema.name = node.name.text; - - const members = [...node.members.filter((v) => v.kind === NodeKind.FieldDeclaration)]; - - if (node.extendsType) { - schema.parent = this.schemasList.find((v) => v.name == node.extendsType?.name.identifier.text) as SchemaData | null; - - if (schema.parent?.members) { - for (let i = schema.parent.members.length - 1; i >= 0; i--) { - const replace = schema.members.find((v) => v.name == schema.parent?.members[i]?.name); - if (!replace) { - members.unshift(schema.parent?.members[i]!.node); - } - } - } - } - - if (!members.length) { - let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}'; - //let SERIALIZE_PRETTY_EMPTY = "__SERIALIZE_PRETTY(): string {\n return \"{}\";\n}"; - - let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}"; - - let DESERIALIZE_EMPTY = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}"; - - if (process.env["JSON_DEBUG"]) { - console.log(SERIALIZE_RAW_EMPTY); - //console.log(SERIALIZE_PRETTY_EMPTY); - console.log(INITIALIZE_EMPTY); - console.log(DESERIALIZE_EMPTY); - } - - const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_RAW_EMPTY, node); - //const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, 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 == "__INITIALIZE")) node.members.push(INITIALIZE_METHOD_EMPTY); - if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) node.members.push(DESERIALIZE_METHOD_EMPTY); - - this.schemasList.push(schema); - } - - for (const member of members) { - const name = member.name; - if (!(member instanceof FieldDeclaration)) continue; - if (!member.type) { - throw new Error("Fields must be strongly typed! Found " + toString(member) + " at " + node.range.source.normalizedPath); - } - const type = toString(member.type!); - if (type.startsWith("(") && type.includes("=>")) continue; - const value = member.initializer ? toString(member.initializer!) : null; - - if (member.flags == CommonFlags.Static) continue; - if (member.flags === CommonFlags.Private) continue; - if (member.flags === CommonFlags.Protected) continue; - - const mem = new Property(); - mem.name = name.text; - mem.type = type; - mem.value = value; - mem.node = member; - - if (type.includes("JSON.Raw")) { - mem.flags.set(PropertyFlags.JSON_Raw, []); - } - - if (member.type.isNullable) { - mem.flags.set(PropertyFlags.Null, []); - } - - if (member.decorators) { - for (const decorator of member.decorators) { - const decoratorName = (decorator.name as IdentifierExpression).text; - - const args = getArgs(decorator.args); - - switch (decoratorName) { - case "alias": { - if (!args.length) throw new Error("Expected 1 argument but got zero at @alias in " + node.range.source.normalizedPath); - mem.alias = args[0]!; - mem.flags.set(PropertyFlags.Alias, args); - break; - } - case "omit": { - mem.flags.set(PropertyFlags.Omit, args); - break; - } - case "omitif": { - if (!decorator.args?.length) throw new Error("Expected 1 argument but got zero at @omitif in " + node.range.source.normalizedPath); - mem.flags.set(PropertyFlags.OmitIf, args); - break; - } - case "omitnull": { - mem.flags.set(PropertyFlags.OmitNull, args); - break; - } - } - } - } - - mem.generate(false); - - if (this.schemasList.find((v) => v.name == type)) { - mem.initialize = "this." + name.text + " = changetype>(__new(offsetof>(), idof>()));\n changetype>(this." + name.text + ").__INITIALIZE()"; - } else if (mem.value) { - mem.initialize = "this." + name.text + " = " + mem.value; - } else if (type === "Map") { - mem.initialize = "this." + name.text + " = new " + mem.type + "()"; - } else if (type === "string") { - mem.initialize = "this." + name.text + ' = ""'; - } else if (type === "Array") { - mem.initialize = "this." + name.text + " = instantiate<" + mem.type + ">()"; - } else if (type === "bool" || type === "boolean") { - mem.initialize = "this." + name.text + " = false"; - } else if (type === "JSON.Raw") { - mem.initialize = "this." + name.text + ' = ""'; - } else if (type === "u8" || type === "u16" || type === "u32" || type === "u64" || type === "i8" || type === "i16" || type === "i32" || type === "i64") { - mem.initialize = "this." + name.text + " = 0"; - } else if (type === "f32" || type === "f64") { - mem.initialize = "this." + name.text + " = 0.0"; - } - - schema.members.push(mem); - } - - let SERIALIZE_RAW = "__SERIALIZE(): string {\n let out = `{"; - let SERIALIZE_PRETTY = "__SERIALIZE_PRETTY(): string {\n let out = `{"; - - let INITIALIZE = "__INITIALIZE(): this {\n"; - - let DESERIALIZE = "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n const len = key_end - key_start;\n"; - let indent = " "; - - if (!schema.members.length) return; - - found = false; - - if (schema.members[0]?.flags.has(PropertyFlags.OmitNull) || schema.members[0]?.flags.has(PropertyFlags.OmitIf)) { - SERIALIZE_RAW += schema.members[0]?.serialize; - SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize; - } else { - SERIALIZE_RAW += schema.members[0]?.serialize + ","; - SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n"; - found = true; - } - - if (schema.members[0]?.initialize) INITIALIZE += " " + schema.members[0]?.initialize + ";\n"; - - for (let i = 1; i < schema.members.length; i++) { - const member = schema.members[i]!; - if (member.initialize) INITIALIZE += " " + member.initialize + ";\n"; - if (member.flags.has(PropertyFlags.OmitNull) || member.flags.has(PropertyFlags.OmitIf)) { - SERIALIZE_RAW += member.serialize; - SERIALIZE_PRETTY += member.serialize; - } else { - SERIALIZE_RAW += member.serialize + ","; - SERIALIZE_PRETTY += indent + member.serialize + ",\\n"; - found = true; - } - } - - if (found) { - SERIALIZE_RAW += "`;\n store(changetype(out) + ((out.length - 1) << 1), 125);\n return out;\n}"; - SERIALIZE_PRETTY += "`;\n store(changetype(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}"; - } else { - SERIALIZE_RAW += "}`;\n return out;\n}"; - SERIALIZE_PRETTY += "}`;\n return out;\n}"; - } - - INITIALIZE += " return this;\n}"; - - const sortedMembers: Property[][] = []; - const _sorted = schema.members.sort((a, b) => (a.alias?.length! || a.name.length) - (b.alias?.length! || b.name.length)); - let len = -1; - let offset = -1; - for (let i = 0; i < _sorted.length; i++) { - const member = _sorted[i]!; - const _name = member.alias || member.name; - if (_name.length === len) { - sortedMembers[offset]?.push(member); - } else { - sortedMembers.push([member]); - len = _name.length; - offset++; - } - } - - let first = true; - for (const memberSet of sortedMembers) { - const firstMember = memberSet[0]!; - const _name = encodeKey(firstMember.alias || firstMember.name); - if (_name.length === 1) { - if (first) { - DESERIALIZE += " if (1 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; - first = false; - } else { - DESERIALIZE += "else if (1 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; - } - } else if (_name.length === 2) { - if (first) { - DESERIALIZE += " if (2 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; - first = false; - } else { - DESERIALIZE += "else if (2 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; - } - } else if (_name.length === 4) { - if (first) { - DESERIALIZE += " if (4 === len) {\n const code = load(changetype(data) + (key_start << 1));\n"; - first = false; - } else { - DESERIALIZE += "else if (4 === len) {\n const code = load(changetype(data) + (key_start << 1));\n"; - } - } else { - if (first) { - DESERIALIZE += " if (" + _name.length + " === len) {\n"; - first = false; - } else { - DESERIALIZE += "else if (" + _name.length + " === len) {\n"; - } - } - let f = true; - for (let i = 0; i < memberSet.length; i++) { - const member = memberSet[i]!; - if (!member.deserialize) continue; - const _name = encodeKey(member.alias || member.name); - if (_name.length === 1) { - DESERIALIZE += ` case ${_name.charCodeAt(0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; - } else if (_name.length === 2) { - DESERIALIZE += ` case ${charCodeAt32(_name, 0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; - } else if (_name.length === 4) { - if (f) { - f = false; - DESERIALIZE += ` if (${charCodeAt64(_name, 0)} === code) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; - } else { - DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + `else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`; - } - } else { - if (f) { - f = false; - DESERIALIZE += ` if (0 === memory.compare(changetype("${escapeQuote(escapeSlash(_name))}"), changetype(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; - } else { - DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else if (0 === memory.compare(changetype("${escapeQuote(escapeSlash(_name))}"), changetype(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; - } - } - } - if (_name.length < 3) { - DESERIALIZE += ` default: {\n return false;\n }\n }\n`; - } else if (_name.length == 4) { - DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`; - } else { - DESERIALIZE = DESERIALIZE.slice(0, DESERIALIZE.length - 1) + ` else {\n return false;\n }\n`; - } - DESERIALIZE += " } "; - } - - DESERIALIZE += "\n return false;\n}"; - - //console.log(sortedMembers); - - if (process.env["JSON_DEBUG"]) { - console.log(SERIALIZE_RAW); - //console.log(SERIALIZE_PRETTY); - console.log(INITIALIZE); - console.log(DESERIALIZE); - } - - const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember(SERIALIZE_RAW, node); - - const DESERIALIZE_SAFE = DESERIALIZE.replaceAll("__DESERIALIZE", "__DESERIALIZE_SAFE"); - //const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node); - const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node); - const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node); - const DESERIALIZE_SAFE_METHOD = SimpleParser.parseClassMember(DESERIALIZE_SAFE, node); - - if (!node.members.find((v) => v.name.text == "__SERIALIZE")) node.members.push(SERIALIZE_RAW_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 == "__DESERIALIZE_SAFE")) node.members.push(DESERIALIZE_SAFE_METHOD); - - this.schemasList.push(schema); - } - visitSource(node: Source): void { - super.visitSource(node); - - // Only add the import statement to sources that have JSON decorated classes. - if (!this.sources.has(node)) { - return; - } - } -} - -export default class Transformer extends Transform { - // Trigger the transform after parse. - afterParse(parser: Parser): void { - // Create new transform - const transformer = new JSONTransform(); - - // Sort the sources so that user scripts are visited last - const sources = parser.sources - .filter((source) => !isStdlib(source)) - .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; - } - }); - - // Loop over every source - for (const source of sources) { - // Ignore all lib and std. Visit everything else. - if (!isStdlib(source)) { - transformer.visit(source); - } - } - // Check that every parent and child class is hooked up correctly - const schemas = transformer.schemasList; - for (const schema of schemas) { - if (schema.parent) { - const parent = schemas.find((v) => v.name === schema.parent?.name); - if (!parent) throw new Error(`Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator! Add the decorator and rebuild.`); - } - } - } -} - -enum PropertyFlags { - Null, - Omit, - OmitNull, - OmitIf, - Alias, - JSON_Raw, -} - -class Property { - public name: string = ""; - public alias: string | null = null; - public type: string = ""; - public value: string | null = null; - public flags: Map = new Map(); - - public serialize: string | null = null; - public deserialize: string | null = null; - public initialize: string | null = null; - - public node!: FieldDeclaration; - - private right_s: string = ""; - private right_d: string = ""; - - public generate(safe: boolean): void { - const name = this.name; - const escapedName = escapeString(JSON.stringify(this.alias || this.name)); - const type = this.type; - if (this.flags.has(PropertyFlags.Omit)) return; - - if (this.flags.has(PropertyFlags.JSON_Raw)) { - if (this.flags.has(PropertyFlags.Null)) { - this.right_s = "(this." + name + ' || "null")'; - this.right_d = "value_start === value_end - 4 && 30399761348886638 === load(changetype(data) + (value_start << 1)) ? null : data.substring(value_start, value_end)"; - } else { - this.right_s = "this." + name; - this.right_d = "data.substring(value_start, value_end);"; - } - } else { - this.right_s = "__SERIALIZE<" + type + ">(this." + name + ")"; - this.right_d = (safe ? "__DESERIALIZE_SAFE" : "__DESERIALIZE") + "<" + type + ">(data.substring(value_start, value_end))"; - } - - if (this.flags.has(PropertyFlags.OmitIf)) { - const condition = this.flags.get(PropertyFlags.OmitIf)![0]; - if (!condition) throw new Error("Could not find condition when using decorator @omitif! Provide at least one condition"); - this.serialize = "${" + condition + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}'; - this.deserialize = "this." + name + " = " + this.right_d + ";"; - } else if (this.flags.has(PropertyFlags.OmitNull)) { - this.serialize = "${changetype(this." + name + ") == 0" + ' ? "" : \'' + escapedName + ":' + " + this.right_s + ' + ","}'; - this.deserialize = "this." + name + " = " + this.right_d + ";"; - } else { - this.serialize = escapedName + ":${" + this.right_s + "}"; - this.deserialize = "this." + name + " = " + this.right_d + ";"; - } - } -} - -class SchemaData { - public name: string = ""; - public members: Property[] = []; - public parent: SchemaData | null = null; - public node!: ClassDeclaration; -} - -function charCodeAt32(data: string, offset: number): number { - return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset); -} - -function charCodeAt64(data: string, offset: number): bigint { - if (offset + 3 >= data.length) { - throw new Error("The string must have at least 4 characters from the specified offset."); - } - - const firstCharCode = BigInt(data.charCodeAt(offset)); - const secondCharCode = BigInt(data.charCodeAt(offset + 1)); - const thirdCharCode = BigInt(data.charCodeAt(offset + 2)); - const fourthCharCode = BigInt(data.charCodeAt(offset + 3)); - - const u64Value = (fourthCharCode << 48n) | (thirdCharCode << 32n) | (secondCharCode << 16n) | firstCharCode; - - return u64Value; -} - -function encodeKey(key: string): string { - const data = JSON.stringify(key); - return data.slice(1, data.length - 1); -} - -function escapeString(data: string): string { - return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`"); -} - -function escapeSlash(data: string): string { - return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`"); -} - -function escapeQuote(data: string): string { - return data.replace(/\"/g, '\\"'); -} - -function getArgs(args: Expression[] | null): string[] { - if (!args) return []; - let out: string[] = []; - 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; -} diff --git a/transform/src/index.ts b/transform/src/index.ts index 37fa5ad..8bc9130 100644 --- a/transform/src/index.ts +++ b/transform/src/index.ts @@ -1,497 +1,423 @@ -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"; +import { + ClassDeclaration, + FieldDeclaration, + IdentifierExpression, + Parser, + Source, + NodeKind, + Expression, + CommonFlags, + StringLiteralExpression, + IntegerLiteralExpression, + FloatLiteralExpression, + NullExpression, + TrueExpression, + FalseExpression, +} from "assemblyscript/dist/assemblyscript.js"; + +import { toString, isStdlib } from "visitor-as/dist/utils.js"; +import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js"; import { Transform } from "assemblyscript/dist/transform.js"; -import { Visitor } from "./visitor.js"; -import { SimpleParser, toString } from "./util.js"; -import * as path from "path"; -import { fileURLToPath } from "url"; -import { Property, PropertyFlags, Schema } from "./types.js"; -import { getClasses, getImportedClass } from "./linker.js"; -import { deserialize } from "v8"; - -let indent = " "; - -class JSONTransform extends Visitor { - public parser!: Parser; - public schemas: Schema[] = []; - public schema!: Schema; - public sources = new Set(); - public imports: ImportStatement[] = []; - public jsonImport: string | null = null; - public bsImport: string | null = null; - public newStmts: { - simd: string[] - } = { simd: [] }; +class JSONTransform extends BaseVisitor { + public schemasList: SchemaData[] = []; + public currentClass!: SchemaData; + public sources = new Set(); + visitMethodDeclaration(): void { } visitClassDeclaration(node: ClassDeclaration): void { if (!node.decorators?.length) return; - if (!node.decorators.some(decorator => { + let found = false; + for (const decorator of node.decorators) { 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; + if (name === "json" || name === "serializable") { + found = true; + break; + } + } + if (!found) return; - this.schemas.push(this.schema); - console.log("Created schema: " + this.schema.name); + const schema = new SchemaData(); + schema.node = node; + schema.name = node.name.text; - const members: FieldDeclaration[] = [...node.members.filter( - (v) => - v.kind === NodeKind.FieldDeclaration && - v.flags !== CommonFlags.Static && - v.flags !== CommonFlags.Private && - v.flags !== CommonFlags.Protected && - !v.decorators?.some(decorator => (decorator.name).text === "omit") - ) as FieldDeclaration[]]; + const members = [ + ...node.members.filter((v) => v.kind === NodeKind.FieldDeclaration), + ]; if (node.extendsType) { - const extendsName = node.extendsType?.name.identifier.text; - this.schema.parent = this.schemas.find((v) => v.name == extendsName) as Schema | null; - if (!this.schema.parent) { - const internalSearch = getClasses(node.range.source).find(v => v.name.text == extendsName); - if (internalSearch) { - console.log("Found " + extendsName + " internally"); - this.visitClassDeclaration(internalSearch); - this.visitClassDeclaration(node); - return; - } - - const externalSearch = getImportedClass(extendsName, node.range.source, this.parser); - if (externalSearch) { - 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); + schema.parent = this.schemasList.find( + (v) => v.name == node.extendsType?.name.identifier.text, + ) as SchemaData | null; + + if (schema.parent?.members) { + for (let i = schema.parent.members.length - 1; i >= 0; i--) { + const replace = schema.members.find( + (v) => v.name == schema.parent?.members[i]?.name, + ); if (!replace) { - members.unshift(this.schema.parent?.members[i]!.node); + members.unshift(schema.parent?.members[i]!.node); } } } } if (!members.length) { - this.generateEmptyMethods(node); - return; - } + let SERIALIZE_RAW_EMPTY = '__SERIALIZE(): string {\n return "{}";\n}'; + //let SERIALIZE_PRETTY_EMPTY = "__SERIALIZE_PRETTY(): string {\n return \"{}\";\n}"; - this.addRequiredImports(node); + let INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}"; - for (const member of members) { - if (!member.type) throwError("Fields must be strongly typed", node.range); + let DESERIALIZE_EMPTY = + "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n return false;\n}"; - const type = toString(member.type!); + if (process.env["JSON_DEBUG"]) { + console.log(SERIALIZE_RAW_EMPTY); + //console.log(SERIALIZE_PRETTY_EMPTY); + console.log(INITIALIZE_EMPTY); + console.log(DESERIALIZE_EMPTY); + } + + const SERIALIZE_RAW_METHOD_EMPTY = SimpleParser.parseClassMember( + SERIALIZE_RAW_EMPTY, + node, + ); + //const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, 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 == "__INITIALIZE")) + node.members.push(INITIALIZE_METHOD_EMPTY); + if (!node.members.find((v) => v.name.text == "__DESERIALIZE")) + node.members.push(DESERIALIZE_METHOD_EMPTY); + + this.schemasList.push(schema); + } + + for (const member of members) { const name = member.name; + if (!(member instanceof FieldDeclaration)) continue; + if (!member.type) { + throw new Error( + "Fields must be strongly typed! Found " + + toString(member) + + " at " + + node.range.source.normalizedPath, + ); + } + const type = toString(member.type!); + if (type.startsWith("(") && type.includes("=>")) continue; const value = member.initializer ? toString(member.initializer!) : null; - if (type.startsWith("(") && type.includes("=>")) continue; + if (member.flags == CommonFlags.Static) continue; + if (member.flags === CommonFlags.Private) continue; + if (member.flags === CommonFlags.Protected) 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.JSON_Raw, []); + } - if (type.includes("JSON.Raw")) mem.flags.set(PropertyFlags.Raw, null); + if (member.type.isNullable) { + mem.flags.set(PropertyFlags.Null, []); + } if (member.decorators) { for (const decorator of member.decorators) { - const decoratorName = (decorator.name as IdentifierExpression).text.toLowerCase().trim(); + const decoratorName = (decorator.name as IdentifierExpression).text; + + const args = getArgs(decorator.args); + 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); + if (!args.length) + throw new Error( + "Expected 1 argument but got zero at @alias in " + + node.range.source.normalizedPath, + ); mem.alias = args[0]!; + mem.flags.set(PropertyFlags.Alias, args); + break; + } + case "omit": { + mem.flags.set(PropertyFlags.Omit, args); break; } case "omitif": { - const 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; + if (!decorator.args?.length) + throw new Error( + "Expected 1 argument but got zero at @omitif in " + + node.range.source.normalizedPath, + ); + mem.flags.set(PropertyFlags.OmitIf, args); 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; + mem.flags.set(PropertyFlags.OmitNull, args); break; } } } } - this.schema.members.push(mem); + mem.generate(false); + + if (this.schemasList.find((v) => v.name == type)) { + mem.initialize = + "this." + + name.text + + " = changetype>(__new(offsetof>(), idof>()));\n changetype>(this." + + name.text + + ").__INITIALIZE()"; + } else if (mem.value) { + mem.initialize = "this." + name.text + " = " + mem.value; + } else if (type === "Map") { + mem.initialize = "this." + name.text + " = new " + mem.type + "()"; + } else if (type === "string") { + mem.initialize = "this." + name.text + ' = ""'; + } else if (type === "Array") { + mem.initialize = + "this." + name.text + " = instantiate<" + mem.type + ">()"; + } else if (type === "bool" || type === "boolean") { + mem.initialize = "this." + name.text + " = false"; + } else if (type === "JSON.Raw") { + mem.initialize = "this." + name.text + ' = ""'; + } else if ( + type === "u8" || + type === "u16" || + type === "u32" || + type === "u64" || + type === "i8" || + type === "i16" || + type === "i32" || + type === "i64" + ) { + mem.initialize = "this." + name.text + " = 0"; + } else if (type === "f32" || type === "f64") { + mem.initialize = "this." + name.text + " = 0.0"; + } + + schema.members.push(mem); } - if (!this.schema.static) this.schema.members = sortMembers(this.schema.members); + let SERIALIZE_RAW = "__SERIALIZE(): string {\n let out = `{"; + let SERIALIZE_PRETTY = "__SERIALIZE_PRETTY(): string {\n let out = `{"; - let SERIALIZE = "@inline __SERIALIZE(ptr: usize = changetype(this)): string {\n"; - let SERIALIZE_BS = "__SERIALIZE_BS(ptr: usize, staticSize: bool): void {\n"; - let INITIALIZE = "@inline __INITIALIZE(): this {\n"; - let DESERIALIZE = "__DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize): void {\n const keySize = keyEnd - keyStart;"; - let ALLOCATE = "@inline __ALLOCATE(): void {\n"; + let INITIALIZE = "__INITIALIZE(): this {\n"; - indent = " "; + let DESERIALIZE = + "__DESERIALIZE(data: string, key_start: i32, key_end: i32, value_start: i32, value_end: i32): boolean {\n const len = key_end - key_start;\n"; + let indent = " "; - if (this.schema.static == false) { - if (this.schema.members.some(v => v.flags.has(PropertyFlags.OmitNull))) { - SERIALIZE_BS += indent + "let block: usize = 0;\n"; - } - this.schema.byteSize += 2; - SERIALIZE_BS += indent + "store(bs.offset, 123, 0); // {\n"; - SERIALIZE_BS += indent + "bs.offset += 2;\n"; - } + if (!schema.members.length) return; - 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; - - DESERIALIZE += " if (keySize == " + ((aliasName.length - 2) << 1) + " && memory.compare(keyStart, changetype(" + aliasName + "), " + ((aliasName.length - 2) << 1) + ") == 0) {\n"; - DESERIALIZE += " this." + realName + " = JSON.__deserialize<" + member.type + ">(valStart, valEnd);\n"; - DESERIALIZE += " return;\n"; - DESERIALIZE += " }\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_BS += this.getStores(keyPart).map(v => indent + v + "\n").join(""); - SERIALIZE_BS += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof("${realName}")), ${isPrimitive(member.type)});\n`; - if (isFirst) isFirst = false; - } else if (isRegular && !isPure) { - const keyPart = (isFirst ? "" : ",") + aliasName + ":"; - this.schema.byteSize += keyPart.length << 1; - SERIALIZE_BS += this.getStores(keyPart).map(v => indent + v + "\n").join(""); - SERIALIZE_BS += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof("${realName}")), staticSize);\n`; - if (isFirst) isFirst = false; - } else { - if (member.flags.has(PropertyFlags.OmitNull)) { - SERIALIZE_BS += indent + `if ((block = load(ptr, offsetof("${realName}"))) !== 0) {\n`; - indentInc(); - const keyPart = aliasName + ":"; - this.schema.byteSize += keyPart.length << 1; - SERIALIZE_BS += this.getStores(keyPart).map(v => indent + v + "\n").join(""); - SERIALIZE_BS += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof("${realName}")), staticSize);\n`; - - if (!isLast) { - this.schema.byteSize += 2; - SERIALIZE_BS += indent + `store(bs.offset, 44, 0); // ,\n`; - SERIALIZE_BS += indent + `bs.offset += 2;\n`; - } + found = false; - indentDec(); - this.schema.byteSize += 2; - SERIALIZE_BS += indent + `}\n`; - } else if (member.flags.has(PropertyFlags.OmitIf)) { - SERIALIZE_BS += indent + `if (${toString}) !== 0) {\n`; - indentInc(); - SERIALIZE_BS += this.getStores(aliasName + ":").map(v => indent + v + "\n").join(""); - SERIALIZE_BS += indent + `JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof("${realName}")), staticSize);\n`; - - if (!isLast) { - this.schema.byteSize += 2; - SERIALIZE_BS += indent + `store(bs.offset, 44, 0); // ,\n`; - SERIALIZE_BS += indent + `bs.offset += 2;\n`; - } + if ( + schema.members[0]?.flags.has(PropertyFlags.OmitNull) || + schema.members[0]?.flags.has(PropertyFlags.OmitIf) + ) { + SERIALIZE_RAW += schema.members[0]?.serialize; + SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize; + } else { + SERIALIZE_RAW += schema.members[0]?.serialize + ","; + SERIALIZE_PRETTY += "\\n" + schema.members[0]?.serialize + ",\\n"; + found = true; + } - indentDec(); - SERIALIZE_BS += indent + `}\n`; - } + if (schema.members[0]?.initialize) + INITIALIZE += " " + schema.members[0]?.initialize + ";\n"; + + for (let i = 1; i < schema.members.length; i++) { + const member = schema.members[i]!; + if (member.initialize) INITIALIZE += " " + member.initialize + ";\n"; + if ( + member.flags.has(PropertyFlags.OmitNull) || + member.flags.has(PropertyFlags.OmitIf) + ) { + SERIALIZE_RAW += member.serialize; + SERIALIZE_PRETTY += member.serialize; + } else { + SERIALIZE_RAW += member.serialize + ","; + SERIALIZE_PRETTY += indent + member.serialize + ",\\n"; + found = true; } } - const sortedMembers: Property[][] = []; + if (found) { + SERIALIZE_RAW += + "`;\n store(changetype(out) + ((out.length - 1) << 1), 125);\n return out;\n}"; + SERIALIZE_PRETTY += + "`;\n store(changetype(out) + ((out.length - 2) << 1), 8192010);\n return out;\n}"; + } else { + SERIALIZE_RAW += "}`;\n return out;\n}"; + SERIALIZE_PRETTY += "}`;\n return out;\n}"; + } + INITIALIZE += " return this;\n}"; + + const sortedMembers: Property[][] = []; + const _sorted = schema.members.sort( + (a, b) => (a.alias?.length! || a.name.length) - (b.alias?.length! || b.name.length), + ); 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); + let offset = -1; + for (let i = 0; i < _sorted.length; i++) { + const member = _sorted[i]!; + const _name = member.alias || member.name; + if (_name.length === len) { + sortedMembers[offset]?.push(member); + } else { + sortedMembers.push([member]); + len = _name.length; + offset++; + } + } + + let first = true; + for (const memberSet of sortedMembers) { + const firstMember = memberSet[0]!; + const _name = encodeKey(firstMember.alias || firstMember.name); + if (_name.length === 1) { + if (first) { + DESERIALIZE += + " if (1 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; + first = false; } else { - sortedMembers.push([member]); - len = _nameLength; + DESERIALIZE += + "else if (1 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; } - }); - - const groups = sortedMembers.length; - // if (groups != 1) { - // DESERIALIZE += " switch (keyEnd - keyStart) {\n"; - // indent = " "; - // } else { - // indent = " "; - // } - for (const memberGroup of sortedMembers) { - - // const firstMemberLen = (memberGroup[0].alias || memberGroup[0].name).length << 1; - // if (firstMemberLen == 2) { - // if (groups != 1) { - // DESERIALIZE += indent + "case 2: {\n"; - // indentInc(); - // } - // if (memberGroup.length == 1) { - // const member = memberGroup[0]; - // const memberName = member.alias || member.name; - // DESERIALIZE += indent + `if (load(keyStart) == ${memberName.charCodeAt(0)}) this.${member.name} = JSON.__deserialize<${member.type}>(valStart, valEnd);\n`; - // if (groups != 1) DESERIALIZE += indent + "break;\n"; - // break; - // } - // DESERIALIZE += indent + "switch (load(keyStart)) {\n"; - // for (const member of memberGroup) { - // const memberName = member.alias || member.name; - // DESERIALIZE += indent + ` case ${memberName.charCodeAt(0)}: { // ${memberName}\n`; - // DESERIALIZE += indent + ` this.${member.name} = JSON.__deserialize<${member.type}>(valStart, valEnd);\n`; - // DESERIALIZE += indent + " break;\n"; - // DESERIALIZE += indent + " }\n"; - // } - // DESERIALIZE += indent + "}\n" - // if (groups != 1) { - // indentDec(); - // DESERIALIZE += indent + "}\n" - // } - // } else if (firstMemberLen == 4) { - // if (groups != 1) { - // DESERIALIZE += indent + "case 4: {\n"; - // indentInc(); - // } - // DESERIALIZE += indent + "switch (load(keyStart)) {\n"; - // for (const member of memberGroup) { - // const memberName = member.alias || member.name; - // DESERIALIZE += indent + ` case ${memberName.charCodeAt(0)}: { // ${memberName}\n`; - // DESERIALIZE += indent + ` this.${member.name} = JSON.__deserialize<${member.type}>(valStart, valEnd);\n`; - // DESERIALIZE += indent + " break;\n"; - // DESERIALIZE += indent + " }\n"; - // } - // DESERIALIZE += indent + "}\n" - // if (groups != 1) { - // indentDec(); - // DESERIALIZE += indent + "}\n" - // } - // } /*else if (firstMemberLen == 8) { - // if (groups != 1) { - // DESERIALIZE += indent + "case 8: {\n"; - // indentInc(); - // } - // DESERIALIZE += indent + "switch ((load(keyStart)) {\n"; - // for (const member of memberGroup) { - // const memberName = member.alias || member.name; - // DESERIALIZE += indent + ` case ${}: { // ${memberName}\n`; - // DESERIALIZE += indent + ` this.${member.name} = JSON.__deserialize<${member.type}>(valStart, valEnd);\n`; - // DESERIALIZE += indent + " break;\n"; - // DESERIALIZE += indent + " }\n"; - // } - // DESERIALIZE += indent + "}\n" - // if (groups != 1) { - // indentDec(); - // DESERIALIZE += indent + "}\n" - // } - // } */else if (memberGroup.length > 1) { - // if (groups != 1) { - // DESERIALIZE += indent + "case " + firstMemberLen + ": {\n"; - // indentInc(); - // } - // DESERIALIZE += indent + "switch (load(keyStart)) {\n"; - // for (const member of memberGroup) { - // const memberName = member.alias || member.name; - // DESERIALIZE += indent + ` case ${memberName.charCodeAt(0)}: { // ${memberName}\n`; - // DESERIALIZE += indent + ` this.${member.name} = JSON.__deserialize<${member.type}>(valStart, valEnd);\n`; - // DESERIALIZE += indent + " break;\n"; - // DESERIALIZE += indent + " }\n"; - // } - // DESERIALIZE += indent + "}\n" - // if (groups != 1) { - // indentDec(); - // DESERIALIZE += indent + "}\n" - // } - // } + } else if (_name.length === 2) { + if (first) { + DESERIALIZE += + " if (2 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; + first = false; + } else { + DESERIALIZE += + "else if (2 === len) {\n switch (load(changetype(data) + (key_start << 1))) {\n"; + } + } else if (_name.length === 4) { + if (first) { + DESERIALIZE += + " if (4 === len) {\n const code = load(changetype(data) + (key_start << 1));\n"; + first = false; + } else { + DESERIALIZE += + "else if (4 === len) {\n const code = load(changetype(data) + (key_start << 1));\n"; + } + } else { + if (first) { + DESERIALIZE += " if (" + _name.length + " === len) {\n"; + first = false; + } else { + DESERIALIZE += "else if (" + _name.length + " === len) {\n"; + } + } + let f = true; + for (let i = 0; i < memberSet.length; i++) { + const member = memberSet[i]!; + if (!member.deserialize) continue; + const _name = encodeKey(member.alias || member.name); + if (_name.length === 1) { + DESERIALIZE += ` case ${_name.charCodeAt(0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; + } else if (_name.length === 2) { + DESERIALIZE += ` case ${charCodeAt32(_name, 0)}: { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; + } else if (_name.length === 4) { + if (f) { + f = false; + DESERIALIZE += ` if (${charCodeAt64(_name, 0)} === code) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; + } else { + DESERIALIZE = + DESERIALIZE.slice(0, DESERIALIZE.length - 1) + + `else if (${charCodeAt64(_name, 0)} === code) {\n ${member.deserialize}\n return true;\n }\n`; + } + } else { + if (f) { + f = false; + DESERIALIZE += ` if (0 === memory.compare(changetype("${escapeQuote(escapeSlash(_name))}"), changetype(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; + } else { + DESERIALIZE = + DESERIALIZE.slice(0, DESERIALIZE.length - 1) + + ` else if (0 === memory.compare(changetype("${escapeQuote(escapeSlash(_name))}"), changetype(data) + (key_start << 1), ${_name.length << 1})) { /* ${_name} */\n ${member.deserialize}\n return true;\n }\n`; + } + } + } + if (_name.length < 3) { + DESERIALIZE += ` default: {\n return false;\n }\n }\n`; + } else if (_name.length == 4) { + DESERIALIZE = + DESERIALIZE.slice(0, DESERIALIZE.length - 1) + + ` else {\n return false;\n }\n`; + } else { + DESERIALIZE = + DESERIALIZE.slice(0, DESERIALIZE.length - 1) + + ` else {\n return false;\n }\n`; + } + DESERIALIZE += " } "; } - // if (groups != 1) { - // DESERIALIZE += " } \n"; - // DESERIALIZE += "} "; - // } else { - // DESERIALIZE += "} "; - // } - DESERIALIZE += "}" - - indent = " "; - - this.schema.byteSize += 2; - SERIALIZE_BS += indent + "store(bs.offset, 125, 0); // }\n"; - SERIALIZE_BS += indent + "bs.offset += 2;\n"; - SERIALIZE_BS += "}"; - - SERIALIZE += indent + `this.__ALLOCATE();\n`; - SERIALIZE += indent + `this.__SERIALIZE_BS(ptr, true);\n`; - SERIALIZE += indent + `return bs.out();\n`; - SERIALIZE += "}"; - indentDec(); - - indentInc(); - ALLOCATE += indent + "bs.ensureSize(" + this.schema.byteSize + ");\n"; - ALLOCATE += "}"; - if (process.env["JSON_DEBUG"]) { - console.log(SERIALIZE); - console.log(SERIALIZE_BS); - // console.log(INITIALIZE); - console.log(DESERIALIZE); - console.log(ALLOCATE); - } + DESERIALIZE += "\n return false;\n}"; - const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE, node); - const SERIALIZE_BS_METHOD = SimpleParser.parseClassMember(SERIALIZE_BS, 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 == "__SERIALIZE_BS")) node.members.push(SERIALIZE_BS_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: ClassDeclaration): void { - let SERIALIZE_RAW_EMPTY = '@inline __SERIALIZE(ptr: usize = changetype(this)): string {\n return "{}";\n}'; - let SERIALIZE_BS_EMPTY = "@inline __SERIALIZE_BS(ptr: usize, staticSize: bool): void {\n store(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): void {\n return false;\n}"; - let ALLOCATE_EMPTY = "@inline __ALLOCATE(): void {\n bs.ensureSize(4);\n}"; + //console.log(sortedMembers); 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); + console.log(SERIALIZE_RAW); + //console.log(SERIALIZE_PRETTY); + console.log(INITIALIZE); + console.log(DESERIALIZE); } - 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_BS")) 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); - } - // visitCallExpression(node: CallExpression, ref: Node): void { - // super.visitCallExpression(node, ref); - // if (!(node.expression.kind == NodeKind.PropertyAccess && (node.expression as PropertyAccessExpression).property.text == "stringifyTo") && !(node.expression.kind == NodeKind.Identifier && (node.expression as IdentifierExpression).text == "stringifyTo")) return; - - // const source = node.range.source; - - // if (ref.kind == NodeKind.Call) { - // const newNode = Node.createBinaryExpression(Token.Equals, node.args[1], node, node.range); - - // (ref).args[(ref).args.indexOf(node)] = newNode; - // } else { - // const newNode = Node.createExpressionStatement(Node.createBinaryExpression(Token.Equals, node.args[1], node, node.range)); - - // const nodeIndex = source.statements.findIndex((n: Node) => { - // if (n == node) return true; - // if (n.kind == NodeKind.Expression && (n).expression == node) return true; - // return false; - // }); - - // if (nodeIndex > 0) source.statements[nodeIndex] = newNode; - // } - // } - // visitBinaryExpression(node: BinaryExpression, ref?: Node | null): void { - // // if (node.right.kind == NodeKind.Call && (node).) - // } - visitImportStatement(node: ImportStatement): void { - super.visitImportStatement(node); - const source = this.parser.sources.find((src) => src.internalPath == node.internalPath); - if (!source) return; - - if (source.statements.some(stmt => - stmt.kind === NodeKind.NamespaceDeclaration && - (stmt as NamespaceDeclaration).name.text === "JSON") - ) this.imports.push(node); + const SERIALIZE_RAW_METHOD = SimpleParser.parseClassMember( + SERIALIZE_RAW, + node, + ); + + const DESERIALIZE_SAFE = DESERIALIZE.replaceAll("__DESERIALIZE", "__DESERIALIZE_SAFE") + //const SERIALIZE_PRETTY_METHOD = SimpleParser.parseClassMember(SERIALIZE_PRETTY, node); + const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node); + const DESERIALIZE_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node); + const DESERIALIZE_SAFE_METHOD = SimpleParser.parseClassMember(DESERIALIZE_SAFE, node); + + if (!node.members.find((v) => v.name.text == "__SERIALIZE")) + node.members.push(SERIALIZE_RAW_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 == "__DESERIALIZE_SAFE")) + node.members.push(DESERIALIZE_SAFE_METHOD); + + this.schemasList.push(schema); } visitSource(node: Source): void { - this.imports = []; super.visitSource(node); - } - addRequiredImports(node: ClassDeclaration): void { - if (!this.imports.find((i) => i.declarations.find((d) => d.foreignName.text == "bs"))) { - if (!this.bsImport) { - this.bsImport = "import { bs } from \"as-bs\""; - if (process.env["JSON_DEBUG"]) console.log("Added as-bs import: " + this.bsImport + "\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; - // if (!existsSync(relativePath)) { - // throw new Error("Could not find a valid json-as library to import from! Please add import { JSON } from \"path-to-json-as\"; in " + node.range.source.normalizedPath + "!"); - // } - - 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: string, simd: boolean = true): string[] { - const out: string[] = []; - const sizes = strToNum(data, simd); - let offset = 0; - for (const [size, num] of sizes) { - if (size == "v128") { - // This could be put in its own file - 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.push(`const ${name} = ${num};`); - out.push("store(bs.offset, " + name + ", " + offset + "); // " + data.slice((offset >> 1), (offset >> 1) + 8)); - offset += 16; - } - if (size == "u64") { - out.push("store(bs.offset, " + num + ", " + offset + "); // " + data.slice((offset >> 1), (offset >> 1) + 4)); - offset += 8; - } else if (size == "u32") { - out.push("store(bs.offset, " + num + ", " + offset + "); // " + data.slice((offset >> 1), (offset >> 1) + 2)); - offset += 4; - } else if (size == "u16") { - out.push("store(bs.offset, " + num + ", " + offset + "); // " + data.slice((offset >> 1), (offset >> 1) + 1)); - offset += 2; - } + // Only add the import statement to sources that have JSON decorated classes. + if (!this.sources.has(node)) { + return; } - out.push("bs.offset += " + offset + ";"); - return out; } } @@ -502,74 +428,169 @@ export default class Transformer extends Transform { const transformer = new JSONTransform(); // Sort the sources so that user scripts are visited last - 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; - } - }); + const sources = parser.sources + .filter((source) => !isStdlib(source)) + .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; // Loop over every source for (const source of sources) { - transformer.imports = []; - transformer.currentSource = source; // Ignore all lib and std. Visit everything else. - transformer.visit(source); - - if (transformer.newStmts.simd) { - const tokenizer = new Tokenizer(new Source(SourceKind.User, 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(SourceKind.User, 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(SourceKind.User, source.normalizedPath, transformer.bsImport)); - parser.currentSource = tokenizer.source; - source.statements.unshift(parser.parseTopLevelStatement(tokenizer)!); - parser.currentSource = source; - transformer.bsImport = null; + if (!isStdlib(source)) { + transformer.visit(source); } } // Check that every parent and child class is hooked up correctly - const schemas = transformer.schemas; + const schemas = transformer.schemasList; 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 parent = schemas.find((v) => v.name === schema.parent?.name); + if (!parent) + throw new Error( + `Class ${schema.name} extends its parent class ${schema.parent}, but ${schema.parent} does not include a @json or @serializable decorator! Add the decorator and rebuild.`, + ); } } } } -function sortMembers(members: Property[]): Property[] { - 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); +enum PropertyFlags { + Null, + Omit, + OmitNull, + OmitIf, + Alias, + JSON_Raw, +} + +class Property { + public name: string = ""; + public alias: string | null = null; + public type: string = ""; + public value: string | null = null; + public flags: Map = new Map< + PropertyFlags, + string[] + >(); + + public serialize: string | null = null; + public deserialize: string | null = null; + public initialize: string | null = null; + + public node!: FieldDeclaration; + + private right_s: string = ""; + private right_d: string = ""; + + public generate(safe: boolean): void { + const name = this.name; + const escapedName = escapeString(JSON.stringify(this.alias || this.name)); + const type = this.type; + if (this.flags.has(PropertyFlags.Omit)) return; + + if (this.flags.has(PropertyFlags.JSON_Raw)) { + if (this.flags.has(PropertyFlags.Null)) { + this.right_s = "(this." + name + " || \"null\")"; + this.right_d = "value_start === value_end - 4 && 30399761348886638 === load(changetype(data) + (value_start << 1)) ? null : data.substring(value_start, value_end)"; + } else { + this.right_s = "this." + name; + this.right_d = "data.substring(value_start, value_end);"; + } + } else { + this.right_s = "__SERIALIZE<" + type + ">(this." + name + ")"; + this.right_d = + (safe ? "__DESERIALIZE_SAFE" : "__DESERIALIZE") + "<" + type + ">(data.substring(value_start, value_end))"; + } - if (aMove && !bMove) { - return -1; - } else if (!aMove && bMove) { - return 1; + if (this.flags.has(PropertyFlags.OmitIf)) { + const condition = this.flags.get(PropertyFlags.OmitIf)![0]; + if (!condition) + throw new Error( + "Could not find condition when using decorator @omitif! Provide at least one condition", + ); + this.serialize = + "${" + + condition + + ' ? "" : \'' + + escapedName + + ":' + " + + this.right_s + + ' + ","}'; + this.deserialize = "this." + name + " = " + this.right_d + ";"; + } else if (this.flags.has(PropertyFlags.OmitNull)) { + this.serialize = + "${changetype(this." + + name + + ") == 0" + + ' ? "" : \'' + + escapedName + + ":' + " + + this.right_s + + ' + ","}'; + this.deserialize = "this." + name + " = " + this.right_d + ";"; } else { - return 0; + this.serialize = escapedName + ":${" + this.right_s + "}"; + this.deserialize = "this." + name + " = " + this.right_d + ";"; } - }); + } +} + +class SchemaData { + public name: string = ""; + public members: Property[] = []; + public parent: SchemaData | null = null; + public node!: ClassDeclaration; +} + +function charCodeAt32(data: string, offset: number): number { + return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset); +} + +function charCodeAt64(data: string, offset: number): bigint { + if (offset + 3 >= data.length) { + throw new Error( + "The string must have at least 4 characters from the specified offset.", + ); + } + + const firstCharCode = BigInt(data.charCodeAt(offset)); + const secondCharCode = BigInt(data.charCodeAt(offset + 1)); + const thirdCharCode = BigInt(data.charCodeAt(offset + 2)); + const fourthCharCode = BigInt(data.charCodeAt(offset + 3)); + + const u64Value = + (fourthCharCode << 48n) | + (thirdCharCode << 32n) | + (secondCharCode << 16n) | + firstCharCode; + + return u64Value; +} + +function encodeKey(key: string): string { + const data = JSON.stringify(key); + return data.slice(1, data.length - 1); +} + +function escapeString(data: string): string { + return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`"); +} + +function escapeSlash(data: string): string { + return data.replace(/\\/g, "\\\\").replace(/\`/g, "\\`"); +} + +function escapeQuote(data: string): string { + return data.replace(/\"/g, '\\"'); } function getArgs(args: Expression[] | null): string[] { @@ -594,94 +615,3 @@ function getArgs(args: Expression[] | null): string[] { } return out; } - -function strToNum(data: string, simd: boolean = false, offset: number = 0): string[][] { - const out: string[][] = []; - 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: string): boolean { - const primitiveTypes = [ - "u8", "u16", "u32", "u64", - "i8", "i16", "i32", "i64", - "f32", "f64", - "bool", "boolean" - ]; - return primitiveTypes.some(v => type.includes(v)); -} - -function throwError(message: string, range: Range): never { - 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(): void { - indent += " "; -} - -function indentDec(): void { - indent = indent.slice(0, Math.max(0, indent.length - 2)); -} - -function sizeof(type: string): number { - if (type == "u8") return 6; // -127 - else if (type == "i8") return 8; // 255 - else if (type == "u16") return 10; // 65536 - else if (type == "i16") return 12; // -32767 - else if (type == "u32") return 20; // 4294967295 - else if (type == "i32") return 22; // -2147483647 - else if (type == "u64") return 40; // 18446744073709551615 - else if (type == "i64") return 40; // -9223372036854775807 - else if (type == "bool" || type == "boolean") return 10; - else return 0; -} - -function allPrimitive(schema: Schema): boolean { - return !schema.members.some(p => p.byteSize == 0); -} \ No newline at end of file diff --git a/transform/src/linker.ts b/transform/src/linker.ts deleted file mode 100644 index 5c4f95c..0000000 --- a/transform/src/linker.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ClassDeclaration, ImportStatement, NodeKind, Parser, Source } from "assemblyscript/dist/assemblyscript.js"; - -export function getImports(source: Source): ImportStatement[] { - return source.statements.filter((v) => v.kind === NodeKind.Import) as ImportStatement[]; -} - -export function getImportedClass(name: string, source: Source, parser: Parser): ClassDeclaration | 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 === NodeKind.ClassDeclaration && (s).name.text === name) as ClassDeclaration | null; - - if (classDeclaration) return classDeclaration; - } - return null; -} - -export function getClasses(source: Source): ClassDeclaration[] { - return source.statements.filter((v) => v.kind === NodeKind.ClassDeclaration) as ClassDeclaration[]; -} diff --git a/transform/src/types.ts b/transform/src/types.ts deleted file mode 100644 index f9e388f..0000000 --- a/transform/src/types.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ClassDeclaration, Expression, FieldDeclaration } from "assemblyscript/dist/assemblyscript.js"; - -export enum PropertyFlags { - OmitNull, - OmitIf, - Raw, -} - -export class Property { - public name: string = ""; - public alias: string | null = null; - public type: string = ""; - public value: string | null = null; - public flags: Map = new Map(); - public node!: FieldDeclaration; - public byteSize: number = 0; -} - -export class Schema { - public static: boolean = true; - public name: string = ""; - public members: Property[] = []; - public parent: Schema | null = null; - public node!: ClassDeclaration; - public needsLink: string | null = null; - public byteSize: number = 0; -} diff --git a/transform/src/util.ts b/transform/src/util.ts deleted file mode 100644 index 4a58420..0000000 --- a/transform/src/util.ts +++ /dev/null @@ -1,56 +0,0 @@ -// Taken from https://github.com/as-pect/visitor-as/blob/master/src/simpleParser.ts -import { Parser, Tokenizer, Source, SourceKind, Expression, Statement, NamespaceDeclaration, ClassDeclaration, DeclarationStatement, Range, Node } from "assemblyscript/dist/assemblyscript.js"; -import { ASTBuilder } from "./builder.js"; - -export class SimpleParser { - private static get parser(): Parser { - return new Parser(); - } - - private static getTokenizer(s: string, file: string = "index.ts"): Tokenizer { - return new Tokenizer(new Source(SourceKind.User, file, s)); - } - - static parseExpression(s: string): Expression { - const res = this.parser.parseExpression(this.getTokenizer(s)); - if (res == null) { - throw new Error("Failed to parse the expression: '" + s + "'"); - } - return res; - } - - static parseStatement(s: string, topLevel = false): Statement { - const res = this.parser.parseStatement(this.getTokenizer(s), topLevel); - if (res == null) { - throw new Error("Failed to parse the statement: '" + s + "'"); - } - return res; - } - - static parseTopLevelStatement(s: string, namespace?: NamespaceDeclaration | null): Statement { - 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: string, _class: ClassDeclaration): DeclarationStatement { - 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: Source | { range: Range }): boolean { - let source = s instanceof Source ? s : s.range.source; - return isStdlibRegex.test(source.internalPath); -} - -export function toString(node: Node): string { - return ASTBuilder.build(node); -} diff --git a/transform/src/visitor.ts b/transform/src/visitor.ts deleted file mode 100644 index 29b65a3..0000000 --- a/transform/src/visitor.ts +++ /dev/null @@ -1,531 +0,0 @@ -import { ArrayLiteralExpression, AssertionExpression, BinaryExpression, CallExpression, ElementAccessExpression, FloatLiteralExpression, FunctionTypeNode, IdentifierExpression, NamedTypeNode, Node, ObjectLiteralExpression, Source, TypeParameterNode, BlockStatement, BreakStatement, ClassDeclaration, ClassExpression, CommaExpression, ContinueStatement, DecoratorNode, DoStatement, EmptyStatement, EnumDeclaration, EnumValueDeclaration, ExportDefaultStatement, ExportImportStatement, ExportMember, ExportStatement, ExpressionStatement, FieldDeclaration, ForStatement, FunctionDeclaration, FunctionExpression, IfStatement, ImportDeclaration, ImportStatement, IndexSignatureNode, InstanceOfExpression, IntegerLiteralExpression, InterfaceDeclaration, LiteralExpression, MethodDeclaration, NamespaceDeclaration, NewExpression, ParameterNode, ParenthesizedExpression, PropertyAccessExpression, RegexpLiteralExpression, ReturnStatement, StringLiteralExpression, SwitchCase, SwitchStatement, TemplateLiteralExpression, TernaryExpression, ThrowStatement, TryStatement, TypeDeclaration, TypeName, UnaryPostfixExpression, UnaryPrefixExpression, VariableDeclaration, VariableStatement, WhileStatement, NodeKind, TypeNode, Expression, LiteralKind, UnaryExpression, SuperExpression, FalseExpression, TrueExpression, ThisExpression, NullExpression, ConstructorExpression, Statement, VoidStatement, CompiledExpression, CommentNode, Module, OmittedExpression, ForOfStatement, ModuleDeclaration } from "assemblyscript/dist/assemblyscript.js"; -import { toString } from "./util.js"; - -export class Visitor { - public currentSource: Source | null = null; - visit(node: Node | Node[], ref: Node | null = null): void { - if (node == null) return; - if (node instanceof Array) { - for (const n of node) { - this._visit(n, ref); - } - } else { - // @ts-ignore - this._visit(node, ref); - } - } - _visit(node: Node, ref: Node | null): void { - switch (node.kind) { - case NodeKind.Source: - this.visitSource(node as Source, ref); - break; - case NodeKind.NamedType: - this.visitNamedTypeNode(node as NamedTypeNode, ref); - break; - case NodeKind.FunctionType: - this.visitFunctionTypeNode(node as FunctionTypeNode, ref); - break; - case NodeKind.TypeName: - this.visitTypeName(node as TypeName, ref); - break; - case NodeKind.TypeParameter: - this.visitTypeParameter(node as TypeParameterNode, ref); - break; - case NodeKind.Identifier: - this.visitIdentifierExpression(node as IdentifierExpression, ref); - break; - case NodeKind.Assertion: - this.visitAssertionExpression(node as AssertionExpression, ref); - break; - case NodeKind.Binary: - this.visitBinaryExpression(node as BinaryExpression, ref); - break; - case NodeKind.Call: - this.visitCallExpression(node as CallExpression, ref); - break; - case NodeKind.Class: - this.visitClassExpression(node as ClassExpression, ref); - break; - case NodeKind.Comma: - this.visitCommaExpression(node as CommaExpression, ref); - break; - case NodeKind.ElementAccess: - this.visitElementAccessExpression(node as ElementAccessExpression, ref); - break; - case NodeKind.Function: - this.visitFunctionExpression(node as FunctionExpression, ref); - break; - case NodeKind.InstanceOf: - this.visitInstanceOfExpression(node as InstanceOfExpression, ref); - break; - case NodeKind.Literal: - this.visitLiteralExpression(node as LiteralExpression, ref); - break; - case NodeKind.New: - this.visitNewExpression(node as NewExpression, ref); - break; - case NodeKind.Parenthesized: - this.visitParenthesizedExpression(node as ParenthesizedExpression, ref); - break; - case NodeKind.PropertyAccess: - this.visitPropertyAccessExpression(node as PropertyAccessExpression, ref); - break; - case NodeKind.Ternary: - this.visitTernaryExpression(node as TernaryExpression, ref); - break; - case NodeKind.UnaryPostfix: - this.visitUnaryPostfixExpression(node as UnaryPostfixExpression, ref); - break; - case NodeKind.UnaryPrefix: - this.visitUnaryPrefixExpression(node as UnaryPrefixExpression, ref); - break; - case NodeKind.Block: - this.visitBlockStatement(node as BlockStatement, ref); - break; - case NodeKind.Break: - this.visitBreakStatement(node as BreakStatement, ref); - break; - case NodeKind.Continue: - this.visitContinueStatement(node as ContinueStatement, ref); - break; - case NodeKind.Do: - this.visitDoStatement(node as DoStatement, ref); - break; - case NodeKind.Empty: - this.visitEmptyStatement(node as EmptyStatement, ref); - break; - case NodeKind.Export: - this.visitExportStatement(node as ExportStatement, ref); - break; - case NodeKind.ExportDefault: - this.visitExportDefaultStatement(node as ExportDefaultStatement, ref); - break; - case NodeKind.ExportImport: - this.visitExportImportStatement(node as ExportImportStatement, ref); - break; - case NodeKind.Expression: - this.visitExpressionStatement(node as ExpressionStatement, ref); - break; - case NodeKind.For: - this.visitForStatement(node as ForStatement, ref); - break; - case NodeKind.If: - this.visitIfStatement(node as IfStatement, ref); - break; - case NodeKind.Import: - this.visitImportStatement(node as ImportStatement, ref); - break; - case NodeKind.Return: - this.visitReturnStatement(node as ReturnStatement, ref); - break; - case NodeKind.Switch: - this.visitSwitchStatement(node as SwitchStatement, ref); - break; - case NodeKind.Throw: - this.visitThrowStatement(node as ThrowStatement, ref); - break; - case NodeKind.Try: - this.visitTryStatement(node as TryStatement, ref); - break; - case NodeKind.Variable: - this.visitVariableStatement(node as VariableStatement, ref); - break; - case NodeKind.While: - this.visitWhileStatement(node as WhileStatement, ref); - break; - case NodeKind.ClassDeclaration: - this.visitClassDeclaration(node as ClassDeclaration, false, ref); - break; - case NodeKind.EnumDeclaration: - this.visitEnumDeclaration(node as EnumDeclaration, false, ref); - break; - case NodeKind.EnumValueDeclaration: - this.visitEnumValueDeclaration(node as EnumValueDeclaration, ref); - break; - case NodeKind.FieldDeclaration: - this.visitFieldDeclaration(node as FieldDeclaration, ref); - break; - case NodeKind.FunctionDeclaration: - this.visitFunctionDeclaration(node as FunctionDeclaration, false, ref); - break; - case NodeKind.ImportDeclaration: - this.visitImportDeclaration(node as ImportDeclaration, ref); - break; - case NodeKind.InterfaceDeclaration: - this.visitInterfaceDeclaration(node as InterfaceDeclaration, false, ref); - break; - case NodeKind.MethodDeclaration: - this.visitMethodDeclaration(node as MethodDeclaration, ref); - break; - case NodeKind.NamespaceDeclaration: - this.visitNamespaceDeclaration(node as NamespaceDeclaration, false, ref); - break; - case NodeKind.TypeDeclaration: - this.visitTypeDeclaration(node as TypeDeclaration, ref); - break; - case NodeKind.VariableDeclaration: - this.visitVariableDeclaration(node as VariableDeclaration, ref); - break; - case NodeKind.Decorator: - this.visitDecoratorNode(node as DecoratorNode, ref); - break; - case NodeKind.ExportMember: - this.visitExportMember(node as ExportMember, ref); - break; - case NodeKind.SwitchCase: - this.visitSwitchCase(node as SwitchCase, ref); - break; - case NodeKind.IndexSignature: - this.visitIndexSignature(node as IndexSignatureNode, ref); - break; - case NodeKind.Null: - this.visitNullExpression(node as NullExpression, ref); - break; - case NodeKind.True: { - this.visitTrueExpression(node as TrueExpression, ref); - break; - } - case NodeKind.False: { - this.visitFalseExpression(node as FalseExpression, ref); - break; - } - case NodeKind.Compiled: { - this.visitCompiledExpression(node as CompiledExpression, ref); - break; - } - case NodeKind.Constructor: { - this.visitConstructorExpression(node as ConstructorExpression, ref); - break; - } - case NodeKind.Comment: { - this.visitComment(node as CommentNode, ref); - break; - } - case NodeKind.ForOf: { - this.visitForOfStatement(node as ForOfStatement, ref); - break; - } - case NodeKind.Module: { - this.visitModuleDeclaration(node as ModuleDeclaration, ref); - break; - } - case NodeKind.Omitted: { - this.visitOmittedExpression(node as OmittedExpression, ref); - break; - } - case NodeKind.Parameter: { - this.visitParameter(node as ParameterNode, ref); - break; - } - case NodeKind.Super: { - this.visitSuperExpression(node as SuperExpression, ref); - break; - } - case NodeKind.This: { - this.visitThisExpression(node as ThisExpression, ref); - break; - } - case NodeKind.Void: { - this.visitVoidStatement(node as VoidStatement, ref); - break; - } - default: - throw new Error("Could not visit invalid type!"); - } - } - visitSource(node: Source, ref: Node | null = null): void { - this.currentSource = node; - this.visit(node.statements, node); - this.currentSource = null; - } - visitTypeNode(node: TypeNode, ref: Node | null = null): void {} - visitTypeName(node: TypeName, ref: Node | null = null): void { - this.visit(node.identifier, node); - this.visit(node.next, node); - } - visitNamedTypeNode(node: NamedTypeNode, ref: Node | null = null): void { - this.visit(node.name, node); - this.visit(node.typeArguments, node); - } - visitFunctionTypeNode(node: FunctionTypeNode, ref: Node | null = null): void { - this.visit(node.parameters, node); - this.visit(node.returnType, node); - this.visit(node.explicitThisType, node); - } - visitTypeParameter(node: TypeParameterNode, ref: Node | null = null): void { - this.visit(node.name, node); - this.visit(node.extendsType, node); - this.visit(node.defaultType, node); - } - visitIdentifierExpression(node: IdentifierExpression, ref: Node | null = null): void {} - visitArrayLiteralExpression(node: ArrayLiteralExpression, ref: Node | null = null): void { - this.visit(node.elementExpressions, node); - } - visitObjectLiteralExpression(node: ObjectLiteralExpression, ref: Node | null = null): void { - this.visit(node.names, node); - this.visit(node.values, node); - } - visitAssertionExpression(node: AssertionExpression, ref: Node | null = null): void { - this.visit(node.toType, node); - this.visit(node.expression, node); - } - visitBinaryExpression(node: BinaryExpression, ref: Node | null = null): void { - this.visit(node.left, node); - this.visit(node.right, node); - } - visitCallExpression(node: CallExpression, ref: Node | null = null): void { - this.visit(node.expression, node); - this.visit(node.typeArguments, node); - this.visit(node.args, node); - } - visitClassExpression(node: ClassExpression, ref: Node | null = null): void { - this.visit(node.declaration, node); - } - visitCommaExpression(node: CommaExpression, ref: Node | null = null): void { - this.visit(node.expressions, node); - } - visitElementAccessExpression(node: ElementAccessExpression, ref: Node | null = null): void { - this.visit(node.elementExpression, node); - this.visit(node.expression, node); - } - visitFunctionExpression(node: FunctionExpression, ref: Node | null = null): void { - this.visit(node.declaration, node); - } - visitLiteralExpression(node: LiteralExpression, ref: Node | null = null): void { - switch (node.literalKind) { - case LiteralKind.Float: - this.visitFloatLiteralExpression(node as FloatLiteralExpression); - break; - case LiteralKind.Integer: - this.visitIntegerLiteralExpression(node as IntegerLiteralExpression); - break; - case LiteralKind.String: - this.visitStringLiteralExpression(node as StringLiteralExpression); - break; - case LiteralKind.Template: - this.visitTemplateLiteralExpression(node as TemplateLiteralExpression); - break; - case LiteralKind.RegExp: - this.visitRegexpLiteralExpression(node as RegexpLiteralExpression); - break; - case LiteralKind.Array: - this.visitArrayLiteralExpression(node as ArrayLiteralExpression); - break; - case LiteralKind.Object: - this.visitObjectLiteralExpression(node as ObjectLiteralExpression); - break; - default: - throw new Error("Invalid LiteralKind at visitLiteralExpression(): " + node.literalKind); - } - } - visitFloatLiteralExpression(node: FloatLiteralExpression, ref: Node | null = null): void {} - visitInstanceOfExpression(node: InstanceOfExpression, ref: Node | null = null): void { - this.visit(node.expression, node); - this.visit(node.isType, node); - } - visitIntegerLiteralExpression(node: IntegerLiteralExpression, ref: Node | null = null): void {} - visitStringLiteralExpression(node: StringLiteralExpression, ref: Node | null = null): void {} - visitTemplateLiteralExpression(node: TemplateLiteralExpression, ref: Node | null = null): void {} - visitRegexpLiteralExpression(node: RegexpLiteralExpression, ref: Node | null = null): void {} - visitNewExpression(node: NewExpression, ref: Node | null = null): void { - this.visit(node.typeName, node); - this.visit(node.typeArguments, node); - this.visit(node.args, node); - } - visitParenthesizedExpression(node: ParenthesizedExpression, ref: Node | null = null): void { - this.visit(node.expression, node); - } - visitPropertyAccessExpression(node: PropertyAccessExpression, ref: Node | null = null): void { - this.visit(node.property, node); - this.visit(node.expression, node); - } - visitTernaryExpression(node: TernaryExpression, ref: Node | null = null): void { - this.visit(node.condition, node); - this.visit(node.ifThen, node); - this.visit(node.ifElse, node); - } - visitUnaryExpression(node: UnaryExpression, ref: Node | null = null): void { - this.visit(node.operand, node); - } - visitUnaryPostfixExpression(node: UnaryPostfixExpression, ref: Node | null = null): void { - this.visit(node.operand, node); - } - visitUnaryPrefixExpression(node: UnaryPrefixExpression, ref: Node | null = null): void { - this.visit(node.operand, node); - } - visitSuperExpression(node: SuperExpression, ref: Node | null = null): void {} - visitFalseExpression(node: FalseExpression, ref: Node | null = null): void {} - visitTrueExpression(node: TrueExpression, ref: Node | null = null): void {} - visitThisExpression(node: ThisExpression, ref: Node | null = null): void {} - visitNullExpression(node: NullExpression, ref: Node | null = null): void {} - visitConstructorExpression(node: ConstructorExpression, ref: Node | null = null): void {} - visitNodeAndTerminate(statement: Statement, ref: Node | null = null): void {} - visitBlockStatement(node: BlockStatement, ref: Node | null = null): void { - this.visit(node.statements, node); - } - visitBreakStatement(node: BreakStatement, ref: Node | null = null): void { - this.visit(node.label, node); - } - visitContinueStatement(node: ContinueStatement, ref: Node | null = null): void { - this.visit(node.label, node); - } - visitClassDeclaration(node: ClassDeclaration, isDefault: boolean = false, ref: Node | null = null): void { - 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: DoStatement, ref: Node | null = null): void { - this.visit(node.condition, node); - this.visit(node.body, node); - } - visitEmptyStatement(node: EmptyStatement, ref: Node | null = null): void {} - visitEnumDeclaration(node: EnumDeclaration, isDefault: boolean = false, ref: Node | null = null): void { - this.visit(node.name, node); - this.visit(node.decorators, node); - this.visit(node.values, node); - } - visitEnumValueDeclaration(node: EnumValueDeclaration, ref: Node | null = null): void { - this.visit(node.name, node); - this.visit(node.initializer, node); - } - visitExportImportStatement(node: ExportImportStatement, ref: Node | null = null): void { - this.visit(node.name, node); - this.visit(node.externalName, node); - } - visitExportMember(node: ExportMember, ref: Node | null = null): void { - this.visit(node.localName, node); - this.visit(node.exportedName, node); - } - visitExportStatement(node: ExportStatement, ref: Node | null = null): void { - this.visit(node.path, node); - this.visit(node.members, node); - } - visitExportDefaultStatement(node: ExportDefaultStatement, ref: Node | null = null): void { - this.visit(node.declaration, node); - } - visitExpressionStatement(node: ExpressionStatement, ref: Node | null = null): void { - this.visit(node.expression, ref); - } - visitFieldDeclaration(node: FieldDeclaration, ref: Node | null = null): void { - this.visit(node.name, node); - this.visit(node.type, node); - this.visit(node.initializer, node); - this.visit(node.decorators, node); - } - visitForStatement(node: ForStatement, ref: Node | null = null): void { - this.visit(node.initializer, node); - this.visit(node.condition, node); - this.visit(node.incrementor, node); - this.visit(node.body, node); - } - visitFunctionDeclaration(node: FunctionDeclaration, isDefault: boolean = false, ref: Node | null = null): void { - 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: IfStatement, ref: Node | null = null): void { - this.visit(node.condition, node); - this.visit(node.ifTrue, node); - this.visit(node.ifFalse, node); - } - visitImportDeclaration(node: ImportDeclaration, ref: Node | null = null): void { - this.visit(node.foreignName, node); - this.visit(node.name, node); - this.visit(node.decorators, node); - } - visitImportStatement(node: ImportStatement, ref: Node | null = null): void { - this.visit(node.namespaceName, node); - this.visit(node.declarations, node); - } - visitIndexSignature(node: IndexSignatureNode, ref: Node | null = null): void { - this.visit(node.keyType, node); - this.visit(node.valueType, node); - } - visitInterfaceDeclaration(node: InterfaceDeclaration, isDefault: boolean = false, ref: Node | null = null): void { - 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: MethodDeclaration, ref: Node | null = null): void { - 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: NamespaceDeclaration, isDefault: boolean = false, ref: Node | null = null): void { - this.visit(node.name, node); - this.visit(node.decorators, node); - this.visit(node.members, node); - } - visitReturnStatement(node: ReturnStatement, ref: Node | null = null): void { - this.visit(node.value, node); - } - visitSwitchCase(node: SwitchCase, ref: Node | null = null): void { - this.visit(node.label, node); - this.visit(node.statements, node); - } - visitSwitchStatement(node: SwitchStatement, ref: Node | null = null): void { - this.visit(node.condition, node); - this.visit(node.cases, node); - } - visitThrowStatement(node: ThrowStatement, ref: Node | null = null): void { - this.visit(node.value, node); - } - visitTryStatement(node: TryStatement, ref: Node | null = null): void { - this.visit(node.bodyStatements, node); - this.visit(node.catchVariable, node); - this.visit(node.catchStatements, node); - this.visit(node.finallyStatements, node); - } - visitTypeDeclaration(node: TypeDeclaration, ref: Node | null = null): void { - this.visit(node.name, node); - this.visit(node.decorators, node); - this.visit(node.type, node); - this.visit(node.typeParameters, node); - } - visitVariableDeclaration(node: VariableDeclaration, ref: Node | null = null): void { - this.visit(node.name, node); - this.visit(node.type, node); - this.visit(node.initializer, node); - } - visitVariableStatement(node: VariableStatement, ref: Node | null = null): void { - this.visit(node.decorators, node); - this.visit(node.declarations, node); - } - visitWhileStatement(node: WhileStatement, ref: Node | null = null): void { - this.visit(node.condition, node); - this.visit(node.body, node); - } - visitVoidStatement(node: VoidStatement, ref: Node | null = null): void {} - visitComment(node: CommentNode, ref: Node | null = null): void {} - visitDecoratorNode(node: DecoratorNode, ref: Node | null = null): void { - this.visit(node.name, node); - this.visit(node.args, node); - } - visitParameter(node: ParameterNode, ref: Node | null = null): void { - this.visit(node.name, node); - this.visit(node.implicitFieldDeclaration, node); - this.visit(node.initializer, node); - this.visit(node.type, node); - } - visitCompiledExpression(node: CompiledExpression, ref: Node | null = null): void {} - visitForOfStatement(node: ForOfStatement, ref: Node | null = null): void { - this.visit(node.body, node); - this.visit(node.variable, node); - this.visit(node.iterable, node); - } - visitModuleDeclaration(node: ModuleDeclaration, ref: Node | null = null): void {} - visitOmittedExpression(node: OmittedExpression, ref: Node | null = null): void {} -} diff --git a/transform/tsconfig.json b/transform/tsconfig.json index f6ab121..50c6bdf 100644 --- a/transform/tsconfig.json +++ b/transform/tsconfig.json @@ -4,9 +4,7 @@ "module": "ES2020", "moduleResolution": "Node", "removeComments": true, - "types": ["node"], "outDir": "./lib", "sourceMap": true - }, - "include": ["./src/*.ts"] + } }