json-as 0.2.6 → 0.4.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/LICENSE +1 -1
- package/README.md +52 -99
- package/asconfig.json +10 -35
- package/assembly/__benches__/as-tral.d.ts +1 -0
- package/assembly/__benches__/benchmark.ts +69 -0
- package/assembly/chars.ts +16 -0
- package/assembly/index.ts +337 -778
- package/assembly/test.ts +35 -207
- package/assembly/tsconfig.json +9 -0
- package/index.ts +1 -0
- package/package.json +26 -37
- package/tests/index.js +3 -3
- package/tests/test.js +13 -6
- package/transform/lib/index.js +47 -150
- package/transform/package.json +30 -2
- package/transform/src/index.old.js +430 -0
- package/transform/src/index.ts +98 -0
- package/transform/tsconfig.json +68 -69
- package/assembly/DynamicObject.ts +0 -29
- package/assembly/bench.ts +0 -199
- package/assembly/unknown.ts +0 -175
- package/bench/bench.js +0 -102
- package/transform/index.ts +0 -224
package/transform/index.ts
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import { TypeNode, ClassDeclaration, Expression, Token, IndexSignature, ElementAccessExpression, ClassExpression, ExpressionStatement, ArrayLiteralExpression, FieldDeclaration, Statement, BinaryExpression, VariableStatement, TypeParameterNode, TypeName, TypeDeclaration, Transform, ObjectLiteralExpression, FunctionDeclaration, Parser, Source, FunctionExpression, FunctionTypeNode } from "visitor-as/as";
|
|
2
|
-
import {
|
|
3
|
-
SimpleParser,
|
|
4
|
-
BaseVisitor,
|
|
5
|
-
registerDecorator,
|
|
6
|
-
Decorator,
|
|
7
|
-
} from "visitor-as";
|
|
8
|
-
import { toString, getName } from "visitor-as/dist/utils";
|
|
9
|
-
function getTypeName(type: TypeNode): string {
|
|
10
|
-
let _type = getName(type);
|
|
11
|
-
const OR_NULL = /\|.*null/;
|
|
12
|
-
if (type.isNullable && !OR_NULL.test(_type)) {
|
|
13
|
-
_type = `${_type} | null`;
|
|
14
|
-
}
|
|
15
|
-
return _type;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Replace Next Line
|
|
19
|
-
const replaceNextLineRegex = /^\W*\/\/ <replace next line>.*$/gm;
|
|
20
|
-
|
|
21
|
-
class JSONTransformer extends BaseVisitor {
|
|
22
|
-
public currentClass?: ClassDeclaration;
|
|
23
|
-
public encodeStmts = new Map<string, string[]>()
|
|
24
|
-
public decodeCode = new Map<string, string[]>()
|
|
25
|
-
public lastType: string = ''
|
|
26
|
-
public sources: Source[] = []
|
|
27
|
-
|
|
28
|
-
private globalStatements: Statement[] = []
|
|
29
|
-
public replaceNextLines = new Set<number>()
|
|
30
|
-
|
|
31
|
-
visitObjectLiteralExpression(node: ObjectLiteralExpression): void {
|
|
32
|
-
const keys = node.names
|
|
33
|
-
const values = node.values
|
|
34
|
-
const replacer = SimpleParser.parseExpression(`new Object()`)
|
|
35
|
-
for (const key of keys) {
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
visitElementAccessExpression(node: ElementAccessExpression): void {
|
|
41
|
-
super.visitElementAccessExpression(node)
|
|
42
|
-
if (toString(node.expression) === 'o') {
|
|
43
|
-
// Should be like if (node.expression.type.text === "Object") {
|
|
44
|
-
const replacer = SimpleParser.parseExpression(`u32(changetype<usize>(${toString(node.elementExpression)}))`)
|
|
45
|
-
node.elementExpression = replacer
|
|
46
|
-
this.sources.push(replacer.range.source)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
visitArrayLiteralExpression(node: ArrayLiteralExpression): void {
|
|
50
|
-
super.visitArrayLiteralExpression(node)
|
|
51
|
-
if (isanyArray(node)) {
|
|
52
|
-
for (let i = 0; i < node.elementExpressions.length; i++) {
|
|
53
|
-
const expr = node.elementExpressions[i]
|
|
54
|
-
// @ts-ignore
|
|
55
|
-
let replacement
|
|
56
|
-
// @ts-ignore
|
|
57
|
-
if (expr.elementExpressions) {
|
|
58
|
-
// @ts-ignore
|
|
59
|
-
this.convertToAnyArray(expr.elementExpressions)
|
|
60
|
-
}
|
|
61
|
-
// @ts-ignore
|
|
62
|
-
replacement = SimpleParser.parseExpression(`unknown.wrap(${toString(expr)})`)
|
|
63
|
-
node.elementExpressions[i] = replacement
|
|
64
|
-
this.sources.push(replacement.range.source)
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
convertToAnyArray(exprs: Expression[]): void {
|
|
70
|
-
for (let i = 0; i < exprs.length; i++) {
|
|
71
|
-
const expr = exprs[i]
|
|
72
|
-
// @ts-ignore
|
|
73
|
-
let replacement
|
|
74
|
-
// @ts-ignore
|
|
75
|
-
if (expr.elementExpressions) {
|
|
76
|
-
// @ts-ignore
|
|
77
|
-
this.convertToAnyArray(expr.elementExpressions)
|
|
78
|
-
}
|
|
79
|
-
// @ts-ignore
|
|
80
|
-
replacement = SimpleParser.parseExpression(`unknown.wrap(${toString(expr)})`)
|
|
81
|
-
exprs[i] = replacement
|
|
82
|
-
this.sources.push(replacement.range.source)
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
visitFieldDeclaration(node: FieldDeclaration): void {
|
|
87
|
-
super.visitFieldDeclaration(node)
|
|
88
|
-
const name = toString(node.name);
|
|
89
|
-
if (!node.type) {
|
|
90
|
-
throw new Error(`Field ${name} is missing a type declaration`);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const type = getTypeName(node.type);
|
|
94
|
-
if (this.currentClass) {
|
|
95
|
-
const className = this.currentClass!.name.text
|
|
96
|
-
if (!this.encodeStmts.has(className)) this.encodeStmts.set(className, [])
|
|
97
|
-
if (!this.decodeCode.has(className)) this.decodeCode.set(className, [])
|
|
98
|
-
// TODO: fix later
|
|
99
|
-
// @ts-ignore
|
|
100
|
-
this.encodeStmts.get(className).push(
|
|
101
|
-
`this.__encoded += '' + '"' + '${name}' + '"' + ':' + JSON.stringify<${type}>(this.${name}) + ',';`
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
// @ts-ignore
|
|
105
|
-
this.decodeCode.get(className).push(
|
|
106
|
-
`${name}: JSON.parse<${type}>(unchecked(values.get('${name}'))),\n`
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
visitClassDeclaration(node: ClassDeclaration): void {
|
|
113
|
-
super.visitClassDeclaration(node)
|
|
114
|
-
if (!node.members) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
this.currentClass = node;
|
|
119
|
-
|
|
120
|
-
const name = getName(node);
|
|
121
|
-
|
|
122
|
-
this.encodeStmts.delete(name);
|
|
123
|
-
this.decodeCode.delete(name);
|
|
124
|
-
this.visit(node.members);
|
|
125
|
-
|
|
126
|
-
const encodedProp = `__encoded: string = ''`
|
|
127
|
-
|
|
128
|
-
let encodeMethod = ``
|
|
129
|
-
|
|
130
|
-
if (this.encodeStmts.has(name) && this.encodeStmts.get(name)) {
|
|
131
|
-
encodeMethod = `
|
|
132
|
-
__encode(): void {
|
|
133
|
-
if (!this.__encoded) {
|
|
134
|
-
${// @ts-ignore
|
|
135
|
-
this.encodeStmts.get(name).join("\n")};
|
|
136
|
-
this.__encoded = this.__encoded.slice(0, this.__encoded.length - 1)
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
`
|
|
140
|
-
} else {
|
|
141
|
-
encodeMethod = `
|
|
142
|
-
__encode(): void {}
|
|
143
|
-
`
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const decodeMethod = `
|
|
147
|
-
__decode(values: Map<string, string>): ${name} {
|
|
148
|
-
const decoded: ${name} = {
|
|
149
|
-
${// @ts-ignore
|
|
150
|
-
this.decodeCode.get(name) ? this.decodeCode.get(name).join("") : ''}
|
|
151
|
-
}
|
|
152
|
-
return decoded
|
|
153
|
-
}
|
|
154
|
-
`;
|
|
155
|
-
|
|
156
|
-
const encodedPropMember = SimpleParser.parseClassMember(encodedProp, node);
|
|
157
|
-
node.members.push(encodedPropMember);
|
|
158
|
-
|
|
159
|
-
const encodeMember = SimpleParser.parseClassMember(encodeMethod, node);
|
|
160
|
-
node.members.push(encodeMember);
|
|
161
|
-
|
|
162
|
-
const decodeMember = SimpleParser.parseClassMember(decodeMethod, node);
|
|
163
|
-
node.members.push(decodeMember);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
static visit(node: ClassDeclaration): void {
|
|
167
|
-
new JSONTransformer().visit(node);
|
|
168
|
-
}
|
|
169
|
-
visitSource(source: Source) {
|
|
170
|
-
this.globalStatements = []
|
|
171
|
-
super.visitSource(source)
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
/*
|
|
175
|
-
class Encoder extends Decorator {
|
|
176
|
-
visitClassDeclaration(node: ClassDeclaration): void {
|
|
177
|
-
JSONTransformer.visit(node);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
get name(): string {
|
|
181
|
-
return "json";
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
get sourceFilter() {
|
|
185
|
-
return (_: any) => true;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export = registerDecorator(new Encoder());*/
|
|
190
|
-
|
|
191
|
-
export = class MyTransform extends Transform {
|
|
192
|
-
// Trigger the transform after parse.
|
|
193
|
-
afterParse(parser: Parser): void {
|
|
194
|
-
// Create new transform
|
|
195
|
-
const transformer = new JSONTransformer();
|
|
196
|
-
// Loop over every source
|
|
197
|
-
for (const source of parser.sources) {
|
|
198
|
-
// Ignore all lib (std lib). Visit everything else.
|
|
199
|
-
if (!source.isLibrary && !source.internalPath.startsWith(`~lib/`)) {
|
|
200
|
-
transformer.visit(source);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
let i = 0
|
|
204
|
-
for (const source of transformer.sources) {
|
|
205
|
-
//source.internalPath += `${i++}.ts`
|
|
206
|
-
if (i === 0) {
|
|
207
|
-
parser.sources.push(source)
|
|
208
|
-
i++
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function isanyArray(node: ArrayLiteralExpression): boolean {
|
|
215
|
-
if (node.elementExpressions.length === 0) return false
|
|
216
|
-
const firstKind = node.elementExpressions[0]?.kind
|
|
217
|
-
const isBoolean = (toString(node.elementExpressions[0]!) === 'true' || toString(node.elementExpressions[0]!) === 'false')
|
|
218
|
-
for (const chunk of node.elementExpressions) {
|
|
219
|
-
if (isBoolean) {
|
|
220
|
-
if (toString(chunk) !== 'true' || toString(chunk) !== 'false') true
|
|
221
|
-
} else if (chunk.kind !== firstKind) return true
|
|
222
|
-
}
|
|
223
|
-
return false
|
|
224
|
-
}
|