json-as 0.2.4 → 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.
@@ -1,223 +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
- // @ts-ignore
99
- this.encodeStmts.get(className).push(
100
- `this.__encoded += '' + '"' + '${name}' + '"' + ':' + JSON.stringify<${type}>(this.${name}) + ',';`
101
- );
102
-
103
- // @ts-ignore
104
- this.decodeCode.get(className).push(
105
- `${name}: JSON.parse<${type}>(unchecked(values.get('${name}'))),\n`
106
- );
107
- }
108
-
109
- }
110
-
111
- visitClassDeclaration(node: ClassDeclaration): void {
112
- super.visitClassDeclaration(node)
113
- if (!node.members) {
114
- return;
115
- }
116
-
117
- this.currentClass = node;
118
-
119
- const name = getName(node);
120
-
121
- this.encodeStmts.delete(name);
122
- this.decodeCode.delete(name);
123
- this.visit(node.members);
124
-
125
- const encodedProp = `__encoded: string = ''`
126
-
127
- let encodeMethod = ``
128
-
129
- if (this.encodeStmts.has(name) && this.encodeStmts.get(name)) {
130
- encodeMethod = `
131
- __encode(): void {
132
- if (!this.__encoded) {
133
- ${// @ts-ignore
134
- this.encodeStmts.get(name).join("\n")};
135
- this.__encoded = this.__encoded.slice(0, this.__encoded.length - 1)
136
- }
137
- }
138
- `
139
- } else {
140
- encodeMethod = `
141
- __encode(): void {}
142
- `
143
- }
144
-
145
- const decodeMethod = `
146
- __decode(values: Map<string, string>): ${name} {
147
- const decoded: ${name} = {
148
- ${// @ts-ignore
149
- this.decodeCode.get(name) ? this.decodeCode.get(name).join("") : ''}
150
- }
151
- return decoded
152
- }
153
- `;
154
-
155
- const encodedPropMember = SimpleParser.parseClassMember(encodedProp, node);
156
- node.members.push(encodedPropMember);
157
-
158
- const encodeMember = SimpleParser.parseClassMember(encodeMethod, node);
159
- node.members.push(encodeMember);
160
-
161
- const decodeMember = SimpleParser.parseClassMember(decodeMethod, node);
162
- node.members.push(decodeMember);
163
- }
164
-
165
- static visit(node: ClassDeclaration): void {
166
- new JSONTransformer().visit(node);
167
- }
168
- visitSource(source: Source) {
169
- this.globalStatements = []
170
- super.visitSource(source)
171
- }
172
- }
173
- /*
174
- class Encoder extends Decorator {
175
- visitClassDeclaration(node: ClassDeclaration): void {
176
- JSONTransformer.visit(node);
177
- }
178
-
179
- get name(): string {
180
- return "json";
181
- }
182
-
183
- get sourceFilter() {
184
- return (_: any) => true;
185
- }
186
- }
187
-
188
- export = registerDecorator(new Encoder());*/
189
-
190
- export = class MyTransform extends Transform {
191
- // Trigger the transform after parse.
192
- afterParse(parser: Parser): void {
193
- // Create new transform
194
- const transformer = new JSONTransformer();
195
- // Loop over every source
196
- for (const source of parser.sources) {
197
- // Ignore all lib (std lib). Visit everything else.
198
- if (!source.isLibrary && !source.internalPath.startsWith(`~lib/`)) {
199
- transformer.visit(source);
200
- }
201
- }
202
- let i = 0
203
- for (const source of transformer.sources) {
204
- //source.internalPath += `${i++}.ts`
205
- if (i === 0) {
206
- parser.sources.push(source)
207
- i++
208
- }
209
- }
210
- }
211
- }
212
-
213
- function isanyArray(node: ArrayLiteralExpression): boolean {
214
- if (node.elementExpressions.length === 0) return false
215
- const firstKind = node.elementExpressions[0]?.kind
216
- const isBoolean = (toString(node.elementExpressions[0]!) === 'true' || toString(node.elementExpressions[0]!) === 'false')
217
- for (const chunk of node.elementExpressions) {
218
- if (isBoolean) {
219
- if (toString(chunk) !== 'true' || toString(chunk) !== 'false') true
220
- } else if (chunk.kind !== firstKind) return true
221
- }
222
- return false
223
- }