hackmud-script-manager 0.13.0-c461329 → 0.13.0-f373e9c
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/assert-1b7dada8.js +1 -0
- package/bin/hsm.d.ts +2 -0
- package/bin/hsm.js +2 -0
- package/generateTypings.d.ts +2 -0
- package/generateTypings.js +1 -0
- package/index.d.ts +15 -0
- package/index.js +1 -0
- package/package.json +35 -11
- package/processScript/index.d.ts +33 -0
- package/processScript/index.js +1 -0
- package/processScript/minify.d.ts +14 -0
- package/processScript/minify.js +1 -0
- package/processScript/postprocess.d.ts +2 -0
- package/processScript/postprocess.js +1 -0
- package/processScript/preprocess.d.ts +13 -0
- package/processScript/preprocess.js +1 -0
- package/processScript/shared.d.ts +3 -0
- package/processScript/shared.js +1 -0
- package/processScript/transform.d.ts +22 -0
- package/processScript/transform.js +1 -0
- package/pull.d.ts +9 -0
- package/pull.js +1 -0
- package/push.d.ts +28 -0
- package/push.js +1 -0
- package/spliceString-2c6f214f.js +1 -0
- package/syncMacros.d.ts +5 -0
- package/syncMacros.js +1 -0
- package/test.d.ts +6 -0
- package/test.js +1 -0
- package/watch.d.ts +14 -0
- package/watch.js +1 -0
- package/.gitattributes +0 -1
- package/.github/workflows/codeql-analysis.yml +0 -39
- package/.github/workflows/publish.yml +0 -42
- package/.vscode/settings.json +0 -6
- package/babel.config.json +0 -6
- package/rollup.config.js +0 -110
- package/scripts/build-package-json.js +0 -36
- package/scripts/jsconfig.json +0 -5
- package/scripts/version-dev.js +0 -25
- package/src/bin/hsm.ts +0 -505
- package/src/constants.json +0 -3
- package/src/generateTypings.ts +0 -116
- package/src/index.ts +0 -19
- package/src/modules.d.ts +0 -5
- package/src/processScript/index.ts +0 -198
- package/src/processScript/minify.ts +0 -529
- package/src/processScript/postprocess.ts +0 -38
- package/src/processScript/preprocess.ts +0 -146
- package/src/processScript/transform.ts +0 -760
- package/src/pull.ts +0 -16
- package/src/push.ts +0 -314
- package/src/syncMacros.ts +0 -52
- package/src/test.ts +0 -59
- package/src/tsconfig.json +0 -20
- package/src/watch.ts +0 -156
- package/tsconfig.json +0 -12
@@ -1,760 +0,0 @@
|
|
1
|
-
import babelTraverse, { NodePath } from "@babel/traverse"
|
2
|
-
import t, { BlockStatement, CallExpression, File, FunctionDeclaration, Identifier, Program } from "@babel/types"
|
3
|
-
import { clearObject } from "@samual/lib"
|
4
|
-
import { assert, ensure } from "@samual/lib/assert"
|
5
|
-
|
6
|
-
const { default: traverse } = babelTraverse as any as typeof import("@babel/traverse")
|
7
|
-
|
8
|
-
export type TransformOptions = {
|
9
|
-
/** 11 a-z 0-9 characters */
|
10
|
-
uniqueID: string
|
11
|
-
|
12
|
-
/** the user the script will be uploaded to (or set to `true` if it is not yet known) */
|
13
|
-
scriptUser: string | true
|
14
|
-
|
15
|
-
/** the name of this script (or set to `true` if it is not yet known) */
|
16
|
-
scriptName: string | true
|
17
|
-
|
18
|
-
seclevel: number
|
19
|
-
}
|
20
|
-
|
21
|
-
/**
|
22
|
-
* transform a given babel `File` to be hackmud compatible
|
23
|
-
*
|
24
|
-
* (returned File will need `postprocess()`ing)
|
25
|
-
*
|
26
|
-
* @param options {@link TransformOptions details}
|
27
|
-
*/
|
28
|
-
export async function transform(file: File, sourceCode: string, {
|
29
|
-
uniqueID = "00000000000",
|
30
|
-
scriptUser = "UNKNOWN",
|
31
|
-
scriptName = "UNKNOWN",
|
32
|
-
seclevel = -1
|
33
|
-
}: Partial<TransformOptions> = {}) {
|
34
|
-
const topFunctionName = `_SCRIPT_${uniqueID}_`
|
35
|
-
const exports = new Map<string, string>()
|
36
|
-
const liveExports = new Map<string, string>()
|
37
|
-
|
38
|
-
let program!: NodePath<t.Program>
|
39
|
-
|
40
|
-
traverse(file, {
|
41
|
-
Program(path) {
|
42
|
-
program = path
|
43
|
-
path.skip()
|
44
|
-
}
|
45
|
-
})
|
46
|
-
|
47
|
-
if (program.scope.hasGlobal("_START")) {
|
48
|
-
for (const referencePath of getReferencePathsToGlobal("_START", program))
|
49
|
-
referencePath.replaceWith(t.identifier("_ST"))
|
50
|
-
}
|
51
|
-
|
52
|
-
if (program.scope.hasGlobal("_TIMEOUT")) {
|
53
|
-
for (const referencePath of getReferencePathsToGlobal("_START", program))
|
54
|
-
referencePath.replaceWith(t.identifier("_TO"))
|
55
|
-
}
|
56
|
-
|
57
|
-
if (program.scope.hasGlobal("_SOURCE")) {
|
58
|
-
for (const referencePath of getReferencePathsToGlobal("_SOURCE", program))
|
59
|
-
referencePath.replaceWith(t.stringLiteral(sourceCode))
|
60
|
-
}
|
61
|
-
|
62
|
-
if (program.scope.hasGlobal("_BUILD_DATE")) {
|
63
|
-
for (const referencePath of getReferencePathsToGlobal("_BUILD_DATE", program))
|
64
|
-
referencePath.replaceWith(t.numericLiteral(Date.now()))
|
65
|
-
}
|
66
|
-
|
67
|
-
if (program.scope.hasGlobal("_SCRIPT_USER")) {
|
68
|
-
for (const referencePath of getReferencePathsToGlobal("_SCRIPT_USER", program)) {
|
69
|
-
if (scriptUser == true)
|
70
|
-
referencePath.replaceWith(t.stringLiteral(`$${uniqueID}$SCRIPT_USER`))
|
71
|
-
else
|
72
|
-
referencePath.replaceWith(t.stringLiteral(scriptUser))
|
73
|
-
}
|
74
|
-
}
|
75
|
-
|
76
|
-
if (program.scope.hasGlobal("_SCRIPT_NAME")) {
|
77
|
-
for (const referencePath of getReferencePathsToGlobal("_SCRIPT_NAME", program)) {
|
78
|
-
if (scriptName == true)
|
79
|
-
referencePath.replaceWith(t.stringLiteral(`$${uniqueID}$SCRIPT_NAME`))
|
80
|
-
else
|
81
|
-
referencePath.replaceWith(t.stringLiteral(scriptName))
|
82
|
-
}
|
83
|
-
}
|
84
|
-
|
85
|
-
if (program.scope.hasGlobal("_FULL_SCRIPT_NAME")) {
|
86
|
-
for (const referencePath of getReferencePathsToGlobal("_FULL_SCRIPT_NAME", program)) {
|
87
|
-
if (scriptUser == true || scriptName == true)
|
88
|
-
referencePath.replaceWith(t.stringLiteral(`$${uniqueID}$FULL_SCRIPT_NAME`))
|
89
|
-
else
|
90
|
-
referencePath.replaceWith(t.stringLiteral(`${scriptUser}.${scriptName}`))
|
91
|
-
}
|
92
|
-
}
|
93
|
-
|
94
|
-
// TODO warn when script name is invalid
|
95
|
-
// TODO warn when not calling
|
96
|
-
for (const fakeSubscriptObjectName of [ "$fs", "$hs", "$ms", "$ls", "$ns", "$4s", "$3s", "$2s", "$1s", "$0s" ]) {
|
97
|
-
if (program.scope.hasGlobal(fakeSubscriptObjectName)) {
|
98
|
-
for (const referencePath of getReferencePathsToGlobal(fakeSubscriptObjectName, program)) {
|
99
|
-
assert(referencePath.parent.type == "MemberExpression")
|
100
|
-
assert(referencePath.parent.property.type == "Identifier")
|
101
|
-
assert(referencePath.parentPath.parentPath?.node.type == "MemberExpression")
|
102
|
-
assert(referencePath.parentPath.parentPath?.node.property.type == "Identifier")
|
103
|
-
|
104
|
-
// BUG this is causing typescript to be slow
|
105
|
-
referencePath.parentPath.parentPath.replaceWith(
|
106
|
-
t.identifier(`$${uniqueID}$SUBSCRIPT$${referencePath.parent.property.name}$${referencePath.parentPath.parentPath.node.property.name}`)
|
107
|
-
)
|
108
|
-
}
|
109
|
-
}
|
110
|
-
}
|
111
|
-
|
112
|
-
// TODO warn when db method is invalid
|
113
|
-
// TODO warn when not calling
|
114
|
-
if (program.scope.hasGlobal("$db")) {
|
115
|
-
for (const referencePath of getReferencePathsToGlobal("$db", program)) {
|
116
|
-
assert(referencePath.parentPath.node.type == "MemberExpression")
|
117
|
-
assert(referencePath.parentPath.node.property.type == "Identifier")
|
118
|
-
|
119
|
-
referencePath.parentPath.replaceWith(
|
120
|
-
t.identifier(`$${uniqueID}$DB$${referencePath.parentPath.node.property.name}`)
|
121
|
-
)
|
122
|
-
}
|
123
|
-
}
|
124
|
-
|
125
|
-
// TODO detect not being called and warn
|
126
|
-
if (program.scope.hasGlobal("$D")) {
|
127
|
-
for (const referencePath of getReferencePathsToGlobal("$D", program))
|
128
|
-
referencePath.replaceWith(t.identifier(`$${uniqueID}$DEBUG`))
|
129
|
-
}
|
130
|
-
|
131
|
-
if (program.scope.hasGlobal("$FMCL")) {
|
132
|
-
for (const referencePath of getReferencePathsToGlobal("$FMCL", program))
|
133
|
-
referencePath.replaceWith(t.identifier(`$${uniqueID}$FMCL`))
|
134
|
-
}
|
135
|
-
|
136
|
-
if (program.scope.hasGlobal("$G")) {
|
137
|
-
for (const referencePath of getReferencePathsToGlobal("$G", program))
|
138
|
-
referencePath.replaceWith(t.identifier(`$${uniqueID}$GLOBAL`))
|
139
|
-
}
|
140
|
-
|
141
|
-
if (program.scope.hasGlobal("_SECLEVEL")) {
|
142
|
-
for (const referencePath of getReferencePathsToGlobal("_SECLEVEL", program)) {
|
143
|
-
referencePath.replaceWith(
|
144
|
-
seclevel < 0
|
145
|
-
? t.unaryExpression(
|
146
|
-
"-",
|
147
|
-
t.numericLiteral(-seclevel)
|
148
|
-
)
|
149
|
-
: t.numericLiteral(seclevel)
|
150
|
-
)
|
151
|
-
}
|
152
|
-
}
|
153
|
-
|
154
|
-
const globalBlock: BlockStatement = t.blockStatement([])
|
155
|
-
let mainFunction: FunctionDeclaration | undefined
|
156
|
-
const liveGlobalVariables: string[] = []
|
157
|
-
|
158
|
-
for (const statement of program.node.body) {
|
159
|
-
if (statement.type == "ExportDefaultDeclaration") {
|
160
|
-
if (statement.declaration.type == "FunctionDeclaration" || statement.declaration.type == "FunctionExpression" || statement.declaration.type == "ArrowFunctionExpression") {
|
161
|
-
mainFunction = t.functionDeclaration(
|
162
|
-
t.identifier(topFunctionName),
|
163
|
-
statement.declaration.params,
|
164
|
-
statement.declaration.body.type == "BlockStatement"
|
165
|
-
? statement.declaration.body
|
166
|
-
: t.blockStatement([ t.returnStatement(statement.declaration.body) ])
|
167
|
-
)
|
168
|
-
} else {
|
169
|
-
assert(t.isExpression(statement.declaration))
|
170
|
-
|
171
|
-
mainFunction = t.functionDeclaration(
|
172
|
-
t.identifier(topFunctionName),
|
173
|
-
[
|
174
|
-
t.identifier("context"),
|
175
|
-
t.identifier("args")
|
176
|
-
],
|
177
|
-
t.blockStatement([
|
178
|
-
t.returnStatement(
|
179
|
-
t.callExpression(statement.declaration, [])
|
180
|
-
)
|
181
|
-
])
|
182
|
-
)
|
183
|
-
}
|
184
|
-
} else if (statement.type == "ExportNamedDeclaration") {
|
185
|
-
if (statement.declaration) {
|
186
|
-
if (statement.declaration.type == "VariableDeclaration") {
|
187
|
-
for (const declarator of statement.declaration.declarations) {
|
188
|
-
for (const identifierName in t.getBindingIdentifiers(declarator.id)) {
|
189
|
-
if (statement.declaration.kind == "const")
|
190
|
-
exports.set(identifierName, identifierName)
|
191
|
-
else
|
192
|
-
liveExports.set(identifierName, identifierName)
|
193
|
-
|
194
|
-
globalBlock.body.push(
|
195
|
-
t.variableDeclaration(
|
196
|
-
"let",
|
197
|
-
[ t.variableDeclarator(t.identifier(identifierName)) ]
|
198
|
-
)
|
199
|
-
)
|
200
|
-
}
|
201
|
-
|
202
|
-
if (declarator.init) {
|
203
|
-
globalBlock.body.push(
|
204
|
-
t.expressionStatement(
|
205
|
-
t.assignmentExpression(
|
206
|
-
"=",
|
207
|
-
declarator.id,
|
208
|
-
declarator.init
|
209
|
-
)
|
210
|
-
)
|
211
|
-
)
|
212
|
-
}
|
213
|
-
}
|
214
|
-
} else {
|
215
|
-
assert("id" in statement.declaration && statement.declaration.id, `unsupported export type "${statement.declaration.type}"`)
|
216
|
-
|
217
|
-
const name = statement.declaration.id.type == "Identifier"
|
218
|
-
? statement.declaration.id.name
|
219
|
-
: statement.declaration.id.value
|
220
|
-
|
221
|
-
exports.set(name, name)
|
222
|
-
globalBlock.body.push(statement.declaration)
|
223
|
-
}
|
224
|
-
} else if (statement.specifiers) {
|
225
|
-
for (const specifier of statement.specifiers) {
|
226
|
-
assert(specifier.type == "ExportSpecifier", `${specifier.type} is currently unsupported`)
|
227
|
-
|
228
|
-
const exportedName = specifier.exported.type == "Identifier"
|
229
|
-
? specifier.exported.name
|
230
|
-
: specifier.exported.value
|
231
|
-
|
232
|
-
if (exportedName == "default") {
|
233
|
-
mainFunction = t.functionDeclaration(
|
234
|
-
t.identifier(topFunctionName),
|
235
|
-
[
|
236
|
-
t.identifier("context"),
|
237
|
-
t.identifier("args")
|
238
|
-
],
|
239
|
-
t.blockStatement([
|
240
|
-
t.returnStatement(
|
241
|
-
t.callExpression(specifier.local, [])
|
242
|
-
)
|
243
|
-
])
|
244
|
-
)
|
245
|
-
} else if (liveGlobalVariables.includes(specifier.local.name)) {
|
246
|
-
liveExports.set(
|
247
|
-
specifier.local.name,
|
248
|
-
exportedName
|
249
|
-
)
|
250
|
-
} else {
|
251
|
-
exports.set(
|
252
|
-
specifier.local.name,
|
253
|
-
exportedName
|
254
|
-
)
|
255
|
-
}
|
256
|
-
}
|
257
|
-
}
|
258
|
-
} else if (statement.type == "VariableDeclaration") {
|
259
|
-
for (const declarator of statement.declarations) {
|
260
|
-
for (const identifierName in t.getBindingIdentifiers(declarator.id)) {
|
261
|
-
if (statement.kind != "const") {
|
262
|
-
if (exports.has(identifierName)) {
|
263
|
-
liveExports.set(identifierName, exports.get(identifierName)!)
|
264
|
-
exports.delete(identifierName)
|
265
|
-
} else
|
266
|
-
liveGlobalVariables.push(identifierName)
|
267
|
-
}
|
268
|
-
|
269
|
-
globalBlock.body.push(
|
270
|
-
t.variableDeclaration(
|
271
|
-
"let",
|
272
|
-
[ t.variableDeclarator(t.identifier(identifierName)) ]
|
273
|
-
)
|
274
|
-
)
|
275
|
-
}
|
276
|
-
|
277
|
-
if (declarator.init) {
|
278
|
-
globalBlock.body.push(
|
279
|
-
t.expressionStatement(
|
280
|
-
t.assignmentExpression(
|
281
|
-
"=",
|
282
|
-
declarator.id,
|
283
|
-
declarator.init
|
284
|
-
)
|
285
|
-
)
|
286
|
-
)
|
287
|
-
}
|
288
|
-
}
|
289
|
-
} else if (statement.type == "FunctionDeclaration") {
|
290
|
-
globalBlock.body.push(
|
291
|
-
t.variableDeclaration(
|
292
|
-
"let",
|
293
|
-
[
|
294
|
-
t.variableDeclarator(
|
295
|
-
statement.id!,
|
296
|
-
t.functionExpression(
|
297
|
-
null,
|
298
|
-
statement.params,
|
299
|
-
statement.body,
|
300
|
-
statement.generator,
|
301
|
-
statement.async
|
302
|
-
)
|
303
|
-
)
|
304
|
-
]
|
305
|
-
)
|
306
|
-
)
|
307
|
-
} else
|
308
|
-
globalBlock.body.push(statement)
|
309
|
-
}
|
310
|
-
|
311
|
-
mainFunction ||= t.functionDeclaration(
|
312
|
-
t.identifier(topFunctionName),
|
313
|
-
[
|
314
|
-
t.identifier("context"),
|
315
|
-
t.identifier("args")
|
316
|
-
],
|
317
|
-
t.blockStatement([])
|
318
|
-
)
|
319
|
-
|
320
|
-
program.node.body = [ mainFunction ]
|
321
|
-
|
322
|
-
if (globalBlock.body.length) {
|
323
|
-
if (exports.size || liveExports.size) {
|
324
|
-
mainFunction.body.body.push(
|
325
|
-
t.returnStatement(
|
326
|
-
t.objectExpression([
|
327
|
-
...[ ...exports ].map(
|
328
|
-
([ local, exported ]) =>
|
329
|
-
t.objectProperty(t.identifier(exported), t.identifier(local))
|
330
|
-
),
|
331
|
-
...[ ...liveExports ].map(
|
332
|
-
([ local, exported ]) => t.objectMethod(
|
333
|
-
"get",
|
334
|
-
t.identifier(exported),
|
335
|
-
[],
|
336
|
-
t.blockStatement([
|
337
|
-
t.returnStatement(
|
338
|
-
t.identifier(local)
|
339
|
-
)
|
340
|
-
])
|
341
|
-
)
|
342
|
-
)
|
343
|
-
])
|
344
|
-
)
|
345
|
-
)
|
346
|
-
}
|
347
|
-
|
348
|
-
program.scope.crawl()
|
349
|
-
|
350
|
-
const globalBlockVariables = new Set<string>()
|
351
|
-
let hoistedGlobalBlockFunctions = 0
|
352
|
-
|
353
|
-
for (const [ globalBlockIndex, globalBlockStatement ] of [ ...globalBlock.body.entries() ].reverse()) {
|
354
|
-
if (globalBlockStatement.type == "VariableDeclaration") {
|
355
|
-
assert(globalBlockStatement.declarations.length == 1)
|
356
|
-
|
357
|
-
const declarator = globalBlockStatement.declarations[0]
|
358
|
-
|
359
|
-
assert(declarator.id.type == "Identifier", `declarator.id.type was "${declarator.id.type}"`)
|
360
|
-
|
361
|
-
program.scope.crawl()
|
362
|
-
|
363
|
-
if (program.scope.hasGlobal(declarator.id.name)) {
|
364
|
-
globalBlock.body.splice(globalBlockIndex, 1)
|
365
|
-
|
366
|
-
const [ globalBlockPath ] = program.unshiftContainer(
|
367
|
-
"body",
|
368
|
-
globalBlock
|
369
|
-
)
|
370
|
-
|
371
|
-
const [ globalBlockStatementPath ] = program.unshiftContainer(
|
372
|
-
"body",
|
373
|
-
globalBlockStatement
|
374
|
-
)
|
375
|
-
|
376
|
-
program.scope.crawl()
|
377
|
-
|
378
|
-
if (!declarator.init || (declarator.init.type != "FunctionExpression" && declarator.init.type != "ArrowFunctionExpression") || Object.keys((program.scope as any).globals).find(global => globalBlockVariables.has(global))) {
|
379
|
-
const binding = program.scope.getBinding(declarator.id.name)
|
380
|
-
|
381
|
-
assert(binding)
|
382
|
-
|
383
|
-
for (const referencePath of binding.referencePaths) {
|
384
|
-
assert(referencePath.node.type == "Identifier")
|
385
|
-
|
386
|
-
referencePath.replaceWith(
|
387
|
-
t.memberExpression(
|
388
|
-
t.identifier(`$${uniqueID}$GLOBAL`),
|
389
|
-
t.identifier(referencePath.node.name)
|
390
|
-
)
|
391
|
-
)
|
392
|
-
}
|
393
|
-
|
394
|
-
for (const referencePath of binding.constantViolations) {
|
395
|
-
assert(referencePath.node.type == "AssignmentExpression")
|
396
|
-
|
397
|
-
for (const [ name, node ] of Object.entries(t.getBindingIdentifiers(referencePath.node))) {
|
398
|
-
if (name == declarator.id.name) {
|
399
|
-
Object.assign(
|
400
|
-
clearObject(node),
|
401
|
-
t.memberExpression(
|
402
|
-
t.identifier(`$${uniqueID}$GLOBAL`),
|
403
|
-
t.identifier(name)
|
404
|
-
)
|
405
|
-
)
|
406
|
-
}
|
407
|
-
}
|
408
|
-
}
|
409
|
-
|
410
|
-
globalBlockPath.remove()
|
411
|
-
globalBlockStatementPath.remove()
|
412
|
-
|
413
|
-
if (declarator.init) {
|
414
|
-
globalBlock.body.splice(
|
415
|
-
globalBlockIndex,
|
416
|
-
0,
|
417
|
-
t.expressionStatement(
|
418
|
-
t.assignmentExpression(
|
419
|
-
"=",
|
420
|
-
t.memberExpression(
|
421
|
-
t.identifier(`$${uniqueID}$GLOBAL`),
|
422
|
-
t.identifier(declarator.id.name)
|
423
|
-
),
|
424
|
-
declarator.init
|
425
|
-
)
|
426
|
-
)
|
427
|
-
)
|
428
|
-
}
|
429
|
-
} else {
|
430
|
-
globalBlockPath.remove()
|
431
|
-
globalBlockStatementPath.remove()
|
432
|
-
|
433
|
-
mainFunction.body.body.unshift(
|
434
|
-
globalBlockStatement
|
435
|
-
)
|
436
|
-
|
437
|
-
hoistedGlobalBlockFunctions++
|
438
|
-
}
|
439
|
-
} else
|
440
|
-
globalBlockVariables.add(declarator.id.name)
|
441
|
-
} else if (globalBlockStatement.type == "ClassDeclaration") {
|
442
|
-
program.scope.crawl()
|
443
|
-
|
444
|
-
if (program.scope.hasGlobal(globalBlockStatement.id.name)) {
|
445
|
-
globalBlock.body.splice(globalBlockIndex, 1)
|
446
|
-
|
447
|
-
const [ globalBlockPath ] = program.unshiftContainer(
|
448
|
-
"body",
|
449
|
-
globalBlock
|
450
|
-
)
|
451
|
-
|
452
|
-
const [ globalBlockStatementPath ] = program.unshiftContainer(
|
453
|
-
"body",
|
454
|
-
globalBlockStatement
|
455
|
-
)
|
456
|
-
|
457
|
-
program.scope.crawl()
|
458
|
-
|
459
|
-
const binding = program.scope.getBinding(globalBlockStatement.id.name)
|
460
|
-
|
461
|
-
assert(binding)
|
462
|
-
|
463
|
-
for (const referencePath of binding.referencePaths) {
|
464
|
-
assert(referencePath.node.type == "Identifier")
|
465
|
-
|
466
|
-
referencePath.replaceWith(
|
467
|
-
t.memberExpression(
|
468
|
-
t.identifier(`$${uniqueID}$GLOBAL`),
|
469
|
-
t.identifier(referencePath.node.name)
|
470
|
-
)
|
471
|
-
)
|
472
|
-
}
|
473
|
-
|
474
|
-
globalBlockPath.remove()
|
475
|
-
globalBlockStatementPath.remove()
|
476
|
-
|
477
|
-
globalBlock.body.splice(
|
478
|
-
globalBlockIndex,
|
479
|
-
0,
|
480
|
-
t.expressionStatement(
|
481
|
-
t.assignmentExpression(
|
482
|
-
"=",
|
483
|
-
t.memberExpression(
|
484
|
-
t.identifier(`$${uniqueID}$GLOBAL`),
|
485
|
-
t.identifier(globalBlockStatement.id.name)
|
486
|
-
),
|
487
|
-
t.classExpression(
|
488
|
-
null,
|
489
|
-
globalBlockStatement.superClass,
|
490
|
-
globalBlockStatement.body,
|
491
|
-
globalBlockStatement.decorators
|
492
|
-
)
|
493
|
-
)
|
494
|
-
)
|
495
|
-
)
|
496
|
-
}
|
497
|
-
}
|
498
|
-
}
|
499
|
-
|
500
|
-
if (program.scope.hasGlobal("_EXPORTS")) {
|
501
|
-
for (const referencePath of getReferencePathsToGlobal("_EXPORTS", program)) {
|
502
|
-
referencePath.replaceWith(
|
503
|
-
t.arrayExpression(
|
504
|
-
[ ...exports.keys(), ...liveExports.keys() ]
|
505
|
-
.map(name => t.stringLiteral(name))
|
506
|
-
)
|
507
|
-
)
|
508
|
-
}
|
509
|
-
}
|
510
|
-
|
511
|
-
if (globalBlock.body.length) {
|
512
|
-
mainFunction.body.body.splice(
|
513
|
-
hoistedGlobalBlockFunctions,
|
514
|
-
0,
|
515
|
-
t.ifStatement(
|
516
|
-
t.unaryExpression(
|
517
|
-
"!",
|
518
|
-
t.identifier(`$${uniqueID}$FMCL`)
|
519
|
-
),
|
520
|
-
globalBlock
|
521
|
-
)
|
522
|
-
)
|
523
|
-
}
|
524
|
-
}
|
525
|
-
|
526
|
-
traverse(file, {
|
527
|
-
BlockStatement({ node: blockStatement }) {
|
528
|
-
for (const [ i, functionDeclaration ] of blockStatement.body.entries()) {
|
529
|
-
if (functionDeclaration.type != "FunctionDeclaration" || functionDeclaration.generator)
|
530
|
-
continue
|
531
|
-
|
532
|
-
blockStatement.body.splice(i, 1)
|
533
|
-
|
534
|
-
blockStatement.body.unshift(
|
535
|
-
t.variableDeclaration(
|
536
|
-
"let",
|
537
|
-
[
|
538
|
-
t.variableDeclarator(
|
539
|
-
functionDeclaration.id!,
|
540
|
-
t.arrowFunctionExpression(
|
541
|
-
functionDeclaration.params,
|
542
|
-
functionDeclaration.body,
|
543
|
-
functionDeclaration.async
|
544
|
-
)
|
545
|
-
)
|
546
|
-
]
|
547
|
-
)
|
548
|
-
)
|
549
|
-
}
|
550
|
-
},
|
551
|
-
|
552
|
-
ClassBody({ node: classBody, scope, parent }) {
|
553
|
-
assert(t.isClass(parent))
|
554
|
-
|
555
|
-
let thisIsReferenced = false
|
556
|
-
|
557
|
-
for (const classMethod of classBody.body) {
|
558
|
-
if (classMethod.type != "ClassMethod")
|
559
|
-
continue
|
560
|
-
|
561
|
-
let methodReferencesThis = false
|
562
|
-
|
563
|
-
traverse(classMethod.body, {
|
564
|
-
ThisExpression(path) {
|
565
|
-
methodReferencesThis = true
|
566
|
-
thisIsReferenced = true
|
567
|
-
path.replaceWith(
|
568
|
-
t.identifier(`_THIS_${uniqueID}_`)
|
569
|
-
)
|
570
|
-
},
|
571
|
-
|
572
|
-
Function(path) {
|
573
|
-
path.skip()
|
574
|
-
}
|
575
|
-
}, scope)
|
576
|
-
|
577
|
-
if (!methodReferencesThis)
|
578
|
-
continue
|
579
|
-
|
580
|
-
if (classMethod.kind == "constructor") {
|
581
|
-
const superCalls: NodePath<CallExpression>[] = []
|
582
|
-
|
583
|
-
traverse(classMethod.body, {
|
584
|
-
CallExpression(path) {
|
585
|
-
if (path.node.callee.type == "Super")
|
586
|
-
superCalls.push(path)
|
587
|
-
}
|
588
|
-
}, scope)
|
589
|
-
|
590
|
-
if (!superCalls.length) {
|
591
|
-
classMethod.body.body.unshift(
|
592
|
-
t.variableDeclaration(
|
593
|
-
"let",
|
594
|
-
[
|
595
|
-
t.variableDeclarator(
|
596
|
-
t.identifier(`_THIS_${uniqueID}_`),
|
597
|
-
t.callExpression(t.super(), [])
|
598
|
-
)
|
599
|
-
]
|
600
|
-
)
|
601
|
-
)
|
602
|
-
} else if (superCalls.length == 1 && superCalls[0].parent.type == "ExpressionStatement" && superCalls[0].parentPath.parentPath!.parent == classMethod) {
|
603
|
-
superCalls[0].parentPath.replaceWith(
|
604
|
-
t.variableDeclaration(
|
605
|
-
"let",
|
606
|
-
[
|
607
|
-
t.variableDeclarator(
|
608
|
-
t.identifier(`_THIS_${uniqueID}_`),
|
609
|
-
superCalls[0].node
|
610
|
-
)
|
611
|
-
]
|
612
|
-
)
|
613
|
-
)
|
614
|
-
} else {
|
615
|
-
for (const path of superCalls) {
|
616
|
-
path.replaceWith(
|
617
|
-
t.assignmentExpression(
|
618
|
-
"=",
|
619
|
-
t.identifier(`_THIS_${uniqueID}_`),
|
620
|
-
path.node
|
621
|
-
)
|
622
|
-
)
|
623
|
-
}
|
624
|
-
|
625
|
-
classMethod.body.body.unshift(
|
626
|
-
t.variableDeclaration(
|
627
|
-
"let",
|
628
|
-
[
|
629
|
-
t.variableDeclarator(
|
630
|
-
t.identifier(`_THIS_${uniqueID}_`)
|
631
|
-
)
|
632
|
-
]
|
633
|
-
)
|
634
|
-
)
|
635
|
-
}
|
636
|
-
|
637
|
-
continue
|
638
|
-
}
|
639
|
-
|
640
|
-
// BUG if the class or a super class overwrites `valueOf()` (or `Object.prototype` isn't even in the chain), this breaks
|
641
|
-
// TODO track whether the class is extending a class that at some point extends from `Object` (if unsure, assume no)
|
642
|
-
// TODO track whether any class in the chain overwrites `valueOf()` (if unsure, assume yes)
|
643
|
-
// TODO for classes that need it, create a super class for this one to extend from with `valueOf()` assigned to an unused name
|
644
|
-
|
645
|
-
classMethod.body.body.unshift(t.variableDeclaration(
|
646
|
-
"let",
|
647
|
-
[
|
648
|
-
t.variableDeclarator(
|
649
|
-
t.identifier(`_THIS_${uniqueID}_`),
|
650
|
-
t.callExpression(
|
651
|
-
t.memberExpression(
|
652
|
-
t.super(),
|
653
|
-
t.identifier("valueOf")
|
654
|
-
),
|
655
|
-
[]
|
656
|
-
)
|
657
|
-
)
|
658
|
-
]
|
659
|
-
))
|
660
|
-
}
|
661
|
-
|
662
|
-
if (!parent.superClass && thisIsReferenced)
|
663
|
-
parent.superClass = t.identifier("Object")
|
664
|
-
},
|
665
|
-
|
666
|
-
VariableDeclaration({ node: variableDeclaration }) {
|
667
|
-
if (variableDeclaration.kind == "const")
|
668
|
-
variableDeclaration.kind = "let"
|
669
|
-
},
|
670
|
-
|
671
|
-
ThisExpression(path) {
|
672
|
-
path.replaceWith(t.identifier(`_UNDEFINED_${uniqueID}_`))
|
673
|
-
},
|
674
|
-
|
675
|
-
BigIntLiteral(path) {
|
676
|
-
const bigIntAsNumber = Number(path.node.value)
|
677
|
-
|
678
|
-
if (BigInt(bigIntAsNumber) == BigInt(path.node.value)) {
|
679
|
-
path.replaceWith(
|
680
|
-
t.callExpression(
|
681
|
-
t.identifier("BigInt"),
|
682
|
-
[ t.numericLiteral(bigIntAsNumber) ]
|
683
|
-
)
|
684
|
-
)
|
685
|
-
} else {
|
686
|
-
path.replaceWith(
|
687
|
-
t.callExpression(
|
688
|
-
t.identifier("BigInt"),
|
689
|
-
[ t.stringLiteral(path.node.value) ]
|
690
|
-
)
|
691
|
-
)
|
692
|
-
}
|
693
|
-
}
|
694
|
-
})
|
695
|
-
|
696
|
-
// TODO this should probably be done in the minify step
|
697
|
-
// typescript does not like NodePath#get() and becomes very slow so I have to dance around it
|
698
|
-
const mainFunctionScope = (program.get("body.0" as string) as NodePath<FunctionDeclaration>).scope
|
699
|
-
|
700
|
-
for (const parameter of [ ...mainFunction.params ].reverse()) {
|
701
|
-
if (parameter.type == "Identifier") {
|
702
|
-
const binding = mainFunctionScope.getBinding(parameter.name)!
|
703
|
-
|
704
|
-
if (!binding.referenced) {
|
705
|
-
mainFunction.params.pop()
|
706
|
-
continue
|
707
|
-
}
|
708
|
-
}
|
709
|
-
|
710
|
-
break
|
711
|
-
}
|
712
|
-
|
713
|
-
// TODO this should be done in the minify step
|
714
|
-
for (const global in (program.scope as any).globals as Record<string, any>) {
|
715
|
-
if (global == "arguments" || global.startsWith(`$${uniqueID}`))
|
716
|
-
continue
|
717
|
-
|
718
|
-
const referencePaths = getReferencePathsToGlobal(global, program)
|
719
|
-
|
720
|
-
if (5 + global.length + referencePaths.length >= global.length * referencePaths.length)
|
721
|
-
continue
|
722
|
-
|
723
|
-
for (const path of referencePaths)
|
724
|
-
path.replaceWith(t.identifier(`_GLOBAL_${global}_${uniqueID}_`))
|
725
|
-
|
726
|
-
mainFunction.body.body.unshift(
|
727
|
-
t.variableDeclaration(
|
728
|
-
"let",
|
729
|
-
[
|
730
|
-
t.variableDeclarator(
|
731
|
-
t.identifier(`_GLOBAL_${global}_${uniqueID}_`),
|
732
|
-
t.identifier(global)
|
733
|
-
)
|
734
|
-
]
|
735
|
-
)
|
736
|
-
)
|
737
|
-
}
|
738
|
-
|
739
|
-
return file
|
740
|
-
}
|
741
|
-
|
742
|
-
export default transform
|
743
|
-
|
744
|
-
function getReferencePathsToGlobal(name: string, program: NodePath<Program>) {
|
745
|
-
const [ variableDeclaration ] = program.unshiftContainer(
|
746
|
-
"body",
|
747
|
-
t.variableDeclaration(
|
748
|
-
"let",
|
749
|
-
[ t.variableDeclarator(t.identifier(name)) ]
|
750
|
-
)
|
751
|
-
)
|
752
|
-
|
753
|
-
program.scope.crawl()
|
754
|
-
|
755
|
-
const binding = ensure(program.scope.getBinding(name))
|
756
|
-
|
757
|
-
variableDeclaration.remove()
|
758
|
-
|
759
|
-
return binding.referencePaths as NodePath<Identifier>[]
|
760
|
-
}
|