json-as 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assembly/__tests__/as-json.spec.ts +298 -2
- package/assembly/src/chars.ts +12 -1
- package/assembly/src/json.ts +133 -156
- package/assembly/src/util.ts +11 -3
- package/assembly/test.ts +18 -85
- package/package.json +1 -1
- package/transform/lib/index.js +94 -76
- package/transform/package.json +1 -1
- package/transform/src/index.ts +115 -85
package/transform/lib/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Parser, Source, Tokenizer, } from "assemblyscript/dist/assemblyscript.js";
|
|
1
2
|
import { toString, isStdlib } from "visitor-as/dist/utils.js";
|
|
2
3
|
import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
|
|
3
4
|
import { Transform } from "assemblyscript/dist/transform.js";
|
|
@@ -17,7 +18,7 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
17
18
|
constructor() {
|
|
18
19
|
super(...arguments);
|
|
19
20
|
this.schemasList = [];
|
|
20
|
-
this.sources =
|
|
21
|
+
this.sources = new Set();
|
|
21
22
|
}
|
|
22
23
|
visitMethodDeclaration() { }
|
|
23
24
|
visitClassDeclaration(node) {
|
|
@@ -68,71 +69,69 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
68
69
|
// @ts-ignore
|
|
69
70
|
if (mem.type && mem.type.name && mem.type.name.identifier.text) {
|
|
70
71
|
const member = mem;
|
|
71
|
-
if (toString(member).startsWith("static"))
|
|
72
|
-
return;
|
|
73
72
|
const lineText = toString(member);
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// @ts-ignore
|
|
77
|
-
let type = toString(member.type);
|
|
78
|
-
const name = member.name.text;
|
|
79
|
-
let aliasName = name;
|
|
80
|
-
if (member.decorators && ((_d = member.decorators[0]) === null || _d === void 0 ? void 0 : _d.name.text) === "alias") {
|
|
81
|
-
if (member.decorators[0] && member.decorators[0].args[0]) {
|
|
82
|
-
aliasName = member.decorators[0].args[0].value;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
this.currentClass.keys.push(name);
|
|
86
|
-
// @ts-ignore
|
|
87
|
-
this.currentClass.types.push(type);
|
|
88
|
-
// @ts-ignore
|
|
89
|
-
if ([
|
|
90
|
-
"u8",
|
|
91
|
-
"i8",
|
|
92
|
-
"u16",
|
|
93
|
-
"i16",
|
|
94
|
-
"u32",
|
|
95
|
-
"i32",
|
|
96
|
-
"u64",
|
|
97
|
-
"i64",
|
|
98
|
-
].includes(type.toLowerCase())) {
|
|
99
|
-
this.currentClass.encodeStmts.push(`"${aliasName}":\${this.${name}.toString()},`);
|
|
73
|
+
console.log("Member: " + lineText);
|
|
74
|
+
if (!lineText.startsWith("private") && !lineText.startsWith("static")) {
|
|
100
75
|
// @ts-ignore
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
`);
|
|
106
|
-
if (member.initializer) {
|
|
107
|
-
this.currentClass.initializeStmts.push(`this.${name} = ${toString(member.initializer)}`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
else // @ts-ignore
|
|
111
|
-
if ([
|
|
112
|
-
"f32",
|
|
113
|
-
"f64",
|
|
114
|
-
].includes(type.toLowerCase())) {
|
|
115
|
-
this.currentClass.encodeStmts.push(`"${aliasName}":\${this.${name}.toString()},`);
|
|
76
|
+
let type = toString(member.type);
|
|
77
|
+
const name = member.name.text;
|
|
78
|
+
let aliasName = name;
|
|
116
79
|
// @ts-ignore
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (member.initializer) {
|
|
123
|
-
this.currentClass.initializeStmts.push(`this.${name} = ${toString(member.initializer)}`);
|
|
80
|
+
if (member.decorators && ((_d = member.decorators[0]) === null || _d === void 0 ? void 0 : _d.name.text) === "alias") {
|
|
81
|
+
if (member.decorators[0] && member.decorators[0].args[0]) {
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
aliasName = member.decorators[0].args[0].value;
|
|
84
|
+
}
|
|
124
85
|
}
|
|
125
|
-
|
|
126
|
-
else {
|
|
127
|
-
this.currentClass.encodeStmts.push(`"${aliasName}":\${JSON.stringify<${type}>(this.${name})},`);
|
|
86
|
+
this.currentClass.keys.push(name);
|
|
128
87
|
// @ts-ignore
|
|
129
|
-
this.currentClass.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
88
|
+
this.currentClass.types.push(type);
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
if ([
|
|
91
|
+
"u8",
|
|
92
|
+
"i8",
|
|
93
|
+
"u16",
|
|
94
|
+
"i16",
|
|
95
|
+
"u32",
|
|
96
|
+
"i32",
|
|
97
|
+
"u64",
|
|
98
|
+
"i64",
|
|
99
|
+
].includes(type.toLowerCase())) {
|
|
100
|
+
this.currentClass.encodeStmts.push(`${encodeKey(aliasName)}:\${this.${name}},`);
|
|
101
|
+
// @ts-ignore
|
|
102
|
+
this.currentClass.setDataStmts.push(`if (key.equals(${JSON.stringify(aliasName)})) {
|
|
103
|
+
this.${name} = __atoi_fast<${type}>(data, val_start << 1, val_end << 1);
|
|
104
|
+
return;
|
|
105
|
+
}`);
|
|
106
|
+
if (member.initializer) {
|
|
107
|
+
this.currentClass.initializeStmts.push(`this.${name} = ${toString(member.initializer)}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else // @ts-ignore
|
|
111
|
+
if ([
|
|
112
|
+
"f32",
|
|
113
|
+
"f64",
|
|
114
|
+
].includes(type.toLowerCase())) {
|
|
115
|
+
this.currentClass.encodeStmts.push(`${encodeKey(aliasName)}:\${this.${name}},`);
|
|
116
|
+
// @ts-ignore
|
|
117
|
+
this.currentClass.setDataStmts.push(`if (key.equals(${JSON.stringify(aliasName)})) {
|
|
118
|
+
this.${name} = __parseObjectValue<${type}>(data.slice(val_start, val_end), initializeDefaultValues);
|
|
119
|
+
return;
|
|
120
|
+
}`);
|
|
121
|
+
if (member.initializer) {
|
|
122
|
+
this.currentClass.initializeStmts.push(`this.${name} = ${toString(member.initializer)}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.currentClass.encodeStmts.push(`${encodeKey(aliasName)}:\${JSON.stringify<${type}>(this.${name})},`);
|
|
127
|
+
// @ts-ignore
|
|
128
|
+
this.currentClass.setDataStmts.push(`if (key.equals(${JSON.stringify(aliasName)})) {
|
|
129
|
+
this.${name} = __parseObjectValue<${type}>(val_start ? data.slice(val_start, val_end) : data, initializeDefaultValues);
|
|
130
|
+
return;
|
|
131
|
+
}`);
|
|
132
|
+
if (member.initializer) {
|
|
133
|
+
this.currentClass.initializeStmts.push(`this.${name} = ${toString(member.initializer)}`);
|
|
134
|
+
}
|
|
136
135
|
}
|
|
137
136
|
}
|
|
138
137
|
}
|
|
@@ -143,38 +142,32 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
143
142
|
this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1] =
|
|
144
143
|
stmt.slice(0, stmt.length - 1);
|
|
145
144
|
serializeFunc = `
|
|
146
|
-
|
|
145
|
+
__JSON_Serialize(): string {
|
|
147
146
|
return \`{${this.currentClass.encodeStmts.join("")}}\`;
|
|
148
|
-
}
|
|
149
|
-
`;
|
|
147
|
+
}`;
|
|
150
148
|
}
|
|
151
149
|
else {
|
|
152
150
|
serializeFunc = `
|
|
153
|
-
|
|
151
|
+
__JSON_Serialize(): string {
|
|
154
152
|
return "{}";
|
|
155
|
-
}
|
|
156
|
-
`;
|
|
153
|
+
}`;
|
|
157
154
|
}
|
|
158
|
-
// Odd behavior here... When pairing this transform with asyncify, having @inline on __JSON_Set_Key<T> with a generic will cause it to freeze.
|
|
159
|
-
// Binaryen cannot predict and add/mangle code when it is genericed.
|
|
160
155
|
const setKeyFunc = `
|
|
161
|
-
__JSON_Set_Key
|
|
162
|
-
${
|
|
163
|
-
// @ts-ignore
|
|
164
|
-
this.currentClass.setDataStmts.join("")}
|
|
156
|
+
__JSON_Set_Key(key: __Virtual<string>, data: string, val_start: i32, val_end: i32, initializeDefaultValues: boolean): void {
|
|
157
|
+
${this.currentClass.setDataStmts.join("\n ")}
|
|
165
158
|
}
|
|
166
159
|
`;
|
|
167
160
|
let initializeFunc = "";
|
|
168
161
|
if (this.currentClass.initializeStmts.length > 0) {
|
|
169
162
|
initializeFunc = `
|
|
170
|
-
|
|
163
|
+
__JSON_Initialize(): void {
|
|
171
164
|
${this.currentClass.initializeStmts.join(";\n")};
|
|
172
165
|
}
|
|
173
166
|
`;
|
|
174
167
|
}
|
|
175
168
|
else {
|
|
176
169
|
initializeFunc = `
|
|
177
|
-
|
|
170
|
+
__JSON_Initialize(): void {}
|
|
178
171
|
`;
|
|
179
172
|
}
|
|
180
173
|
const serializeMethod = SimpleParser.parseClassMember(serializeFunc, node);
|
|
@@ -184,12 +177,37 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
184
177
|
const initializeMethod = SimpleParser.parseClassMember(initializeFunc, node);
|
|
185
178
|
node.members.push(initializeMethod);
|
|
186
179
|
this.schemasList.push(this.currentClass);
|
|
187
|
-
|
|
180
|
+
this.sources.add(node.name.range.source);
|
|
181
|
+
// Uncomment to see the generated code for debugging.
|
|
182
|
+
//console.log(serializeFunc);
|
|
183
|
+
//console.log(setKeyFunc);
|
|
184
|
+
//console.log(initializeFunc);
|
|
188
185
|
}
|
|
189
186
|
visitSource(node) {
|
|
190
187
|
super.visitSource(node);
|
|
188
|
+
// Only add the import statement to sources that have JSON decorated classes.
|
|
189
|
+
if (!this.sources.has(node)) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
// Note, the following one liner would be easier, but it fails with an assertion error
|
|
193
|
+
// because as-virtual's SimpleParser doesn't set the parser.currentSource correctly.
|
|
194
|
+
//
|
|
195
|
+
// const stmt = SimpleParser.parseTopLevelStatement('import { Virtual as __Virtual } from "as-virtual/assembly";');
|
|
196
|
+
// ... So we have to do it the long way:
|
|
197
|
+
const s = 'import { Virtual as __Virtual } from "as-virtual/assembly";';
|
|
198
|
+
const t = new Tokenizer(new Source(0 /* SourceKind.User */, "index.ts", s));
|
|
199
|
+
const p = new Parser();
|
|
200
|
+
p.currentSource = t.source;
|
|
201
|
+
const stmt = p.parseTopLevelStatement(t);
|
|
202
|
+
// Add the import statement to the top of the source.
|
|
203
|
+
node.statements.unshift(stmt);
|
|
191
204
|
}
|
|
192
205
|
}
|
|
206
|
+
function encodeKey(aliasName) {
|
|
207
|
+
return JSON.stringify(aliasName)
|
|
208
|
+
.replace(/\\/g, "\\\\")
|
|
209
|
+
.replace(/\`/g, '\\`');
|
|
210
|
+
}
|
|
193
211
|
export default class Transformer extends Transform {
|
|
194
212
|
// Trigger the transform after parse.
|
|
195
213
|
afterParse(parser) {
|
package/transform/package.json
CHANGED
package/transform/src/index.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ClassDeclaration,
|
|
3
3
|
FieldDeclaration,
|
|
4
|
-
Source,
|
|
5
4
|
Parser,
|
|
6
|
-
|
|
5
|
+
Source,
|
|
6
|
+
SourceKind,
|
|
7
|
+
Tokenizer,
|
|
8
|
+
} from "assemblyscript/dist/assemblyscript.js";
|
|
9
|
+
|
|
7
10
|
import { toString, isStdlib } from "visitor-as/dist/utils.js";
|
|
8
11
|
import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
|
|
9
12
|
import { Transform } from "assemblyscript/dist/transform.js";
|
|
@@ -23,7 +26,7 @@ class SchemaData {
|
|
|
23
26
|
class AsJSONTransform extends BaseVisitor {
|
|
24
27
|
public schemasList: SchemaData[] = [];
|
|
25
28
|
public currentClass!: SchemaData;
|
|
26
|
-
public sources
|
|
29
|
+
public sources = new Set<Source>();
|
|
27
30
|
|
|
28
31
|
visitMethodDeclaration(): void { }
|
|
29
32
|
visitClassDeclaration(node: ClassDeclaration): void {
|
|
@@ -80,93 +83,95 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
80
83
|
// @ts-ignore
|
|
81
84
|
if (mem.type && mem.type.name && mem.type.name.identifier.text) {
|
|
82
85
|
const member = mem as FieldDeclaration;
|
|
83
|
-
if (toString(member).startsWith("static")) return;
|
|
84
86
|
const lineText = toString(member);
|
|
85
|
-
|
|
87
|
+
console.log("Member: " + lineText)
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
let type = toString(member.type);
|
|
89
|
+
if (!lineText.startsWith("private") && !lineText.startsWith("static")) {
|
|
89
90
|
|
|
90
|
-
const name = member.name.text;
|
|
91
|
-
let aliasName = name;
|
|
92
|
-
if (member.decorators && member.decorators[0]?.name.text === "alias") {
|
|
93
|
-
if (member.decorators[0] && member.decorators[0].args![0]) {
|
|
94
|
-
aliasName = member.decorators[0].args![0].value;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
this.currentClass.keys.push(name);
|
|
98
|
-
// @ts-ignore
|
|
99
|
-
this.currentClass.types.push(type);
|
|
100
|
-
// @ts-ignore
|
|
101
|
-
if (
|
|
102
|
-
[
|
|
103
|
-
"u8",
|
|
104
|
-
"i8",
|
|
105
|
-
"u16",
|
|
106
|
-
"i16",
|
|
107
|
-
"u32",
|
|
108
|
-
"i32",
|
|
109
|
-
"u64",
|
|
110
|
-
"i64",
|
|
111
|
-
].includes(type.toLowerCase())
|
|
112
|
-
) {
|
|
113
|
-
this.currentClass.encodeStmts.push(
|
|
114
|
-
`"${aliasName}":\${this.${name}.toString()},`
|
|
115
|
-
);
|
|
116
91
|
// @ts-ignore
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
92
|
+
let type = toString(member.type);
|
|
93
|
+
|
|
94
|
+
const name = member.name.text;
|
|
95
|
+
let aliasName = name;
|
|
96
|
+
|
|
97
|
+
// @ts-ignore
|
|
98
|
+
if (member.decorators && member.decorators[0]?.name.text === "alias") {
|
|
99
|
+
if (member.decorators[0] && member.decorators[0].args![0]) {
|
|
100
|
+
// @ts-ignore
|
|
101
|
+
aliasName = member.decorators[0].args![0].value;
|
|
102
|
+
}
|
|
128
103
|
}
|
|
129
|
-
|
|
104
|
+
this.currentClass.keys.push(name);
|
|
105
|
+
// @ts-ignore
|
|
106
|
+
this.currentClass.types.push(type);
|
|
107
|
+
// @ts-ignore
|
|
130
108
|
if (
|
|
131
109
|
[
|
|
132
|
-
"
|
|
133
|
-
"
|
|
110
|
+
"u8",
|
|
111
|
+
"i8",
|
|
112
|
+
"u16",
|
|
113
|
+
"i16",
|
|
114
|
+
"u32",
|
|
115
|
+
"i32",
|
|
116
|
+
"u64",
|
|
117
|
+
"i64",
|
|
134
118
|
].includes(type.toLowerCase())
|
|
135
119
|
) {
|
|
136
120
|
this.currentClass.encodeStmts.push(
|
|
137
|
-
|
|
121
|
+
`${encodeKey(aliasName)}:\${this.${name}},`
|
|
138
122
|
);
|
|
139
123
|
// @ts-ignore
|
|
140
124
|
this.currentClass.setDataStmts.push(
|
|
141
|
-
`if (key.equals(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
`
|
|
125
|
+
`if (key.equals(${JSON.stringify(aliasName)})) {
|
|
126
|
+
this.${name} = __atoi_fast<${type}>(data, val_start << 1, val_end << 1);
|
|
127
|
+
return;
|
|
128
|
+
}`
|
|
146
129
|
);
|
|
147
130
|
if (member.initializer) {
|
|
148
131
|
this.currentClass.initializeStmts.push(
|
|
149
132
|
`this.${name} = ${toString(member.initializer)}`
|
|
150
133
|
);
|
|
151
134
|
}
|
|
152
|
-
} else
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
135
|
+
} else // @ts-ignore
|
|
136
|
+
if (
|
|
137
|
+
[
|
|
138
|
+
"f32",
|
|
139
|
+
"f64",
|
|
140
|
+
].includes(type.toLowerCase())
|
|
141
|
+
) {
|
|
142
|
+
this.currentClass.encodeStmts.push(
|
|
143
|
+
`${encodeKey(aliasName)}:\${this.${name}},`
|
|
144
|
+
);
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
this.currentClass.setDataStmts.push(
|
|
147
|
+
`if (key.equals(${JSON.stringify(aliasName)})) {
|
|
148
|
+
this.${name} = __parseObjectValue<${type}>(data.slice(val_start, val_end), initializeDefaultValues);
|
|
149
|
+
return;
|
|
150
|
+
}`
|
|
151
|
+
);
|
|
152
|
+
if (member.initializer) {
|
|
153
|
+
this.currentClass.initializeStmts.push(
|
|
154
|
+
`this.${name} = ${toString(member.initializer)}`
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
this.currentClass.encodeStmts.push(
|
|
159
|
+
`${encodeKey(aliasName)}:\${JSON.stringify<${type}>(this.${name})},`
|
|
160
|
+
);
|
|
161
|
+
// @ts-ignore
|
|
162
|
+
this.currentClass.setDataStmts.push(
|
|
163
|
+
`if (key.equals(${JSON.stringify(aliasName)})) {
|
|
164
|
+
this.${name} = __parseObjectValue<${type}>(val_start ? data.slice(val_start, val_end) : data, initializeDefaultValues);
|
|
165
|
+
return;
|
|
166
|
+
}`
|
|
167
167
|
);
|
|
168
|
+
if (member.initializer) {
|
|
169
|
+
this.currentClass.initializeStmts.push(
|
|
170
|
+
`this.${name} = ${toString(member.initializer)}`
|
|
171
|
+
);
|
|
172
|
+
}
|
|
168
173
|
}
|
|
169
|
-
|
|
174
|
+
}
|
|
170
175
|
}
|
|
171
176
|
}
|
|
172
177
|
|
|
@@ -180,26 +185,19 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
180
185
|
this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1] =
|
|
181
186
|
stmt!.slice(0, stmt.length - 1);
|
|
182
187
|
serializeFunc = `
|
|
183
|
-
|
|
188
|
+
__JSON_Serialize(): string {
|
|
184
189
|
return \`{${this.currentClass.encodeStmts.join("")}}\`;
|
|
185
|
-
}
|
|
186
|
-
`;
|
|
190
|
+
}`;
|
|
187
191
|
} else {
|
|
188
192
|
serializeFunc = `
|
|
189
|
-
|
|
193
|
+
__JSON_Serialize(): string {
|
|
190
194
|
return "{}";
|
|
191
|
-
}
|
|
192
|
-
`;
|
|
195
|
+
}`;
|
|
193
196
|
}
|
|
194
197
|
|
|
195
|
-
// Odd behavior here... When pairing this transform with asyncify, having @inline on __JSON_Set_Key<T> with a generic will cause it to freeze.
|
|
196
|
-
// Binaryen cannot predict and add/mangle code when it is genericed.
|
|
197
198
|
const setKeyFunc = `
|
|
198
|
-
__JSON_Set_Key
|
|
199
|
-
${
|
|
200
|
-
// @ts-ignore
|
|
201
|
-
this.currentClass.setDataStmts.join("")
|
|
202
|
-
}
|
|
199
|
+
__JSON_Set_Key(key: __Virtual<string>, data: string, val_start: i32, val_end: i32, initializeDefaultValues: boolean): void {
|
|
200
|
+
${this.currentClass.setDataStmts.join("\n ")}
|
|
203
201
|
}
|
|
204
202
|
`;
|
|
205
203
|
|
|
@@ -207,13 +205,13 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
207
205
|
|
|
208
206
|
if (this.currentClass.initializeStmts.length > 0) {
|
|
209
207
|
initializeFunc = `
|
|
210
|
-
|
|
208
|
+
__JSON_Initialize(): void {
|
|
211
209
|
${this.currentClass.initializeStmts.join(";\n")};
|
|
212
210
|
}
|
|
213
211
|
`;
|
|
214
212
|
} else {
|
|
215
213
|
initializeFunc = `
|
|
216
|
-
|
|
214
|
+
__JSON_Initialize(): void {}
|
|
217
215
|
`;
|
|
218
216
|
}
|
|
219
217
|
const serializeMethod = SimpleParser.parseClassMember(serializeFunc, node);
|
|
@@ -226,13 +224,45 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
226
224
|
node.members.push(initializeMethod);
|
|
227
225
|
|
|
228
226
|
this.schemasList.push(this.currentClass);
|
|
229
|
-
|
|
227
|
+
this.sources.add(node.name.range.source);
|
|
228
|
+
|
|
229
|
+
// Uncomment to see the generated code for debugging.
|
|
230
|
+
//console.log(serializeFunc);
|
|
231
|
+
//console.log(setKeyFunc);
|
|
232
|
+
//console.log(initializeFunc);
|
|
230
233
|
}
|
|
234
|
+
|
|
231
235
|
visitSource(node: Source): void {
|
|
232
236
|
super.visitSource(node);
|
|
237
|
+
|
|
238
|
+
// Only add the import statement to sources that have JSON decorated classes.
|
|
239
|
+
if (!this.sources.has(node)) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Note, the following one liner would be easier, but it fails with an assertion error
|
|
244
|
+
// because as-virtual's SimpleParser doesn't set the parser.currentSource correctly.
|
|
245
|
+
//
|
|
246
|
+
// const stmt = SimpleParser.parseTopLevelStatement('import { Virtual as __Virtual } from "as-virtual/assembly";');
|
|
247
|
+
|
|
248
|
+
// ... So we have to do it the long way:
|
|
249
|
+
const s = 'import { Virtual as __Virtual } from "as-virtual/assembly";'
|
|
250
|
+
const t = new Tokenizer(new Source(SourceKind.User, "index.ts", s));
|
|
251
|
+
const p = new Parser();
|
|
252
|
+
p.currentSource = t.source;
|
|
253
|
+
const stmt = p.parseTopLevelStatement(t)!;
|
|
254
|
+
|
|
255
|
+
// Add the import statement to the top of the source.
|
|
256
|
+
node.statements.unshift(stmt);
|
|
233
257
|
}
|
|
234
258
|
}
|
|
235
259
|
|
|
260
|
+
function encodeKey(aliasName: string): string {
|
|
261
|
+
return JSON.stringify(aliasName)
|
|
262
|
+
.replace(/\\/g, "\\\\")
|
|
263
|
+
.replace(/\`/g, '\\`');
|
|
264
|
+
}
|
|
265
|
+
|
|
236
266
|
export default class Transformer extends Transform {
|
|
237
267
|
// Trigger the transform after parse.
|
|
238
268
|
afterParse(parser: Parser): void {
|