@markw65/monkeyc-optimizer 1.0.30 → 1.0.33
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/README.md +50 -0
- package/build/api.cjs +1012 -299
- package/build/optimizer.cjs +909 -386
- package/build/src/api.d.ts +5 -1
- package/build/src/ast.d.ts +21 -1
- package/build/src/build.d.ts +1 -0
- package/build/src/control-flow.d.ts +1 -0
- package/build/src/function-info.d.ts +12 -0
- package/build/src/inliner.d.ts +1 -0
- package/build/src/jungles.d.ts +1 -0
- package/build/src/mc-rewrite.d.ts +2 -1
- package/build/src/optimizer-types.d.ts +188 -0
- package/build/src/optimizer.d.ts +4 -174
- package/build/src/pragma-checker.d.ts +2 -1
- package/build/src/pre.d.ts +1 -0
- package/build/src/unused-exprs.d.ts +3 -0
- package/build/src/variable-renamer.d.ts +1 -0
- package/build/src/visitor.d.ts +1 -0
- package/package.json +6 -6
package/build/optimizer.cjs
CHANGED
|
@@ -10977,6 +10977,7 @@ function simulateProgram(prg, device, test = false, logger) {
|
|
|
10977
10977
|
}
|
|
10978
10978
|
|
|
10979
10979
|
;// CONCATENATED MODULE: ./src/ast.ts
|
|
10980
|
+
|
|
10980
10981
|
/*
|
|
10981
10982
|
* This ensures that mctreeTypeInfo has every key of MCTreeTypeInfo,
|
|
10982
10983
|
* and that the corresponding arrays contain every element of the
|
|
@@ -11163,18 +11164,185 @@ function withLoc(node, start, end) {
|
|
|
11163
11164
|
}
|
|
11164
11165
|
return node;
|
|
11165
11166
|
}
|
|
11166
|
-
function withLocDeep(node, start, end) {
|
|
11167
|
-
node = withLoc({ ...node }, start, end);
|
|
11167
|
+
function withLocDeep(node, start, end, inplace) {
|
|
11168
|
+
node = withLoc(inplace ? node : { ...node }, start, end);
|
|
11168
11169
|
for (const key of mctreeTypeInfo[node.type].keys) {
|
|
11169
11170
|
const value = node[key];
|
|
11170
11171
|
if (!value)
|
|
11171
11172
|
continue;
|
|
11172
|
-
const fix = (v) => isMCTreeNode(v) ? withLocDeep(v, start, end) : v;
|
|
11173
|
+
const fix = (v) => isMCTreeNode(v) ? withLocDeep(v, start, end, inplace) : v;
|
|
11173
11174
|
const repl = Array.isArray(value) ? value.map(fix) : fix(value);
|
|
11174
|
-
node[key] = repl;
|
|
11175
|
+
inplace || (node[key] = repl);
|
|
11175
11176
|
}
|
|
11176
11177
|
return node;
|
|
11177
11178
|
}
|
|
11179
|
+
function cloneDeep(node) {
|
|
11180
|
+
return withLocDeep(node, null);
|
|
11181
|
+
}
|
|
11182
|
+
function getNodeValue(node) {
|
|
11183
|
+
if (node.type == "BinaryExpression" &&
|
|
11184
|
+
node.operator == "as" &&
|
|
11185
|
+
node.right.type == "TypeSpecList" &&
|
|
11186
|
+
node.right.ts.length == 1 &&
|
|
11187
|
+
typeof node.right.ts[0] == "string") {
|
|
11188
|
+
// this is a cast we inserted to retain the type of an enum
|
|
11189
|
+
// any arithmetic on it will revert to "Number", or "Long",
|
|
11190
|
+
// so just ignore it.
|
|
11191
|
+
return getNodeValue(node.left);
|
|
11192
|
+
}
|
|
11193
|
+
if (node.type != "Literal") {
|
|
11194
|
+
return [null, null];
|
|
11195
|
+
}
|
|
11196
|
+
if (node.value === null) {
|
|
11197
|
+
return [node, "Null"];
|
|
11198
|
+
}
|
|
11199
|
+
const type = typeof node.value;
|
|
11200
|
+
if (type === "number") {
|
|
11201
|
+
const match = prettier_plugin_monkeyc_namespaceObject.LiteralIntegerRe.exec(node.raw);
|
|
11202
|
+
if (match) {
|
|
11203
|
+
return match[2] === "l" || match[2] === "L"
|
|
11204
|
+
? [node, "Long"]
|
|
11205
|
+
: [node, "Number"];
|
|
11206
|
+
}
|
|
11207
|
+
return [node, node.raw.endsWith("d") ? "Double" : "Float"];
|
|
11208
|
+
}
|
|
11209
|
+
if (type === "bigint") {
|
|
11210
|
+
return [node, "Long"];
|
|
11211
|
+
}
|
|
11212
|
+
if (type === "string") {
|
|
11213
|
+
return [node, "String"];
|
|
11214
|
+
}
|
|
11215
|
+
if (type === "boolean") {
|
|
11216
|
+
return [node, "Boolean"];
|
|
11217
|
+
}
|
|
11218
|
+
throw new Error(`Literal has unknown type '${type}'`);
|
|
11219
|
+
}
|
|
11220
|
+
|
|
11221
|
+
;// CONCATENATED MODULE: ./src/function-info.ts
|
|
11222
|
+
|
|
11223
|
+
function cloneSet(ae) {
|
|
11224
|
+
return new Set(ae);
|
|
11225
|
+
}
|
|
11226
|
+
function mergeSet(a, b) {
|
|
11227
|
+
b.forEach((event) => a.add(event));
|
|
11228
|
+
}
|
|
11229
|
+
function recordModifiedDecl(func, decl) {
|
|
11230
|
+
if (!func.next_info) {
|
|
11231
|
+
func.next_info = { modifiedDecls: new Set(), calledFuncs: new Set() };
|
|
11232
|
+
}
|
|
11233
|
+
func.next_info.modifiedDecls.add(decl);
|
|
11234
|
+
return null;
|
|
11235
|
+
}
|
|
11236
|
+
function recordModifiedDecls(func, lookupDefs) {
|
|
11237
|
+
lookupDefs.forEach((lookupDef) => lookupDef.results.forEach((result) => {
|
|
11238
|
+
if (result.type == "VariableDeclarator" && result.node.kind === "var") {
|
|
11239
|
+
recordModifiedDecl(func, result);
|
|
11240
|
+
}
|
|
11241
|
+
}));
|
|
11242
|
+
}
|
|
11243
|
+
function recordModifiedName(func, name) {
|
|
11244
|
+
if (!func.next_info) {
|
|
11245
|
+
func.next_info = { modifiedDecls: new Set(), calledFuncs: new Set() };
|
|
11246
|
+
}
|
|
11247
|
+
if (!func.next_info.modifiedNames) {
|
|
11248
|
+
func.next_info.modifiedNames = new Set();
|
|
11249
|
+
}
|
|
11250
|
+
func.next_info.modifiedNames.add(name);
|
|
11251
|
+
}
|
|
11252
|
+
function recordModifiedUnknown(func) {
|
|
11253
|
+
if (!func.next_info) {
|
|
11254
|
+
func.next_info = { modifiedDecls: new Set(), calledFuncs: new Set() };
|
|
11255
|
+
}
|
|
11256
|
+
func.next_info.modifiedUnknown = true;
|
|
11257
|
+
}
|
|
11258
|
+
function recordCalledFunc(func, callee) {
|
|
11259
|
+
if (!func.next_info) {
|
|
11260
|
+
func.next_info = { modifiedDecls: new Set(), calledFuncs: new Set() };
|
|
11261
|
+
}
|
|
11262
|
+
func.next_info.calledFuncs.add(callee);
|
|
11263
|
+
return null;
|
|
11264
|
+
}
|
|
11265
|
+
function recordCalledFuncs(func, callees) {
|
|
11266
|
+
callees.forEach((callee) => {
|
|
11267
|
+
recordCalledFunc(func, callee);
|
|
11268
|
+
});
|
|
11269
|
+
}
|
|
11270
|
+
function functionMayModify(state, func, decl) {
|
|
11271
|
+
const info = func.info;
|
|
11272
|
+
if (!info || info.modifiedUnknown)
|
|
11273
|
+
return true;
|
|
11274
|
+
if (info.resolvedDecls) {
|
|
11275
|
+
return info.resolvedDecls.has(decl);
|
|
11276
|
+
}
|
|
11277
|
+
if (info.modifiedNames?.has(decl.name))
|
|
11278
|
+
return true;
|
|
11279
|
+
if (info.modifiedDecls.has(decl))
|
|
11280
|
+
return true;
|
|
11281
|
+
const visited = new Set();
|
|
11282
|
+
const resolved = new Set();
|
|
11283
|
+
const resolveDecls = (f) => {
|
|
11284
|
+
if (visited.has(f))
|
|
11285
|
+
return true;
|
|
11286
|
+
if (!f.info)
|
|
11287
|
+
return false;
|
|
11288
|
+
if (f.info.modifiedUnknown) {
|
|
11289
|
+
info.modifiedUnknown = true;
|
|
11290
|
+
return false;
|
|
11291
|
+
}
|
|
11292
|
+
if (f.info.modifiedNames) {
|
|
11293
|
+
if (info.modifiedNames) {
|
|
11294
|
+
mergeSet(info.modifiedNames, f.info.modifiedNames);
|
|
11295
|
+
}
|
|
11296
|
+
else {
|
|
11297
|
+
info.modifiedNames = cloneSet(f.info.modifiedNames);
|
|
11298
|
+
}
|
|
11299
|
+
}
|
|
11300
|
+
mergeSet(resolved, f.info.modifiedDecls);
|
|
11301
|
+
visited.add(f);
|
|
11302
|
+
const q = true;
|
|
11303
|
+
if (q &&
|
|
11304
|
+
f.info.callsExposed &&
|
|
11305
|
+
state.exposed &&
|
|
11306
|
+
!Object.keys(state.exposed).every((key) => !state.allFunctions[key] ||
|
|
11307
|
+
state.allFunctions[key].every(resolveDecls))) {
|
|
11308
|
+
return false;
|
|
11309
|
+
}
|
|
11310
|
+
return Array.from(f.info.calledFuncs).every(resolveDecls);
|
|
11311
|
+
};
|
|
11312
|
+
if (resolveDecls(func)) {
|
|
11313
|
+
info.resolvedDecls = resolved;
|
|
11314
|
+
return resolved.has(decl);
|
|
11315
|
+
}
|
|
11316
|
+
return true;
|
|
11317
|
+
}
|
|
11318
|
+
function findCallees(lookupDefs) {
|
|
11319
|
+
const decls = lookupDefs.reduce((decls, r) => (decls ? decls.concat(r.results) : r.results), null);
|
|
11320
|
+
return (decls &&
|
|
11321
|
+
decls.filter((decl) => decl ? decl.type === "FunctionDeclaration" : false));
|
|
11322
|
+
}
|
|
11323
|
+
function findCalleesForNew(lookupDefs) {
|
|
11324
|
+
const initializer = (decl) => {
|
|
11325
|
+
if (hasProperty(decl.decls, "initialize")) {
|
|
11326
|
+
return decl.decls["initialize"];
|
|
11327
|
+
}
|
|
11328
|
+
if (decl.superClass && decl.superClass !== true) {
|
|
11329
|
+
return decl.superClass.reduce((cur, cls) => {
|
|
11330
|
+
const init = initializer(cls);
|
|
11331
|
+
if (init) {
|
|
11332
|
+
if (!cur)
|
|
11333
|
+
return init;
|
|
11334
|
+
return cur.concat(init);
|
|
11335
|
+
}
|
|
11336
|
+
return cur;
|
|
11337
|
+
}, null);
|
|
11338
|
+
}
|
|
11339
|
+
return null;
|
|
11340
|
+
};
|
|
11341
|
+
return lookupDefs.flatMap((r) => r.results
|
|
11342
|
+
.filter((decl) => decl.type === "ClassDeclaration")
|
|
11343
|
+
.flatMap(initializer)
|
|
11344
|
+
.filter((decl) => decl ? decl.type === "FunctionDeclaration" : false));
|
|
11345
|
+
}
|
|
11178
11346
|
|
|
11179
11347
|
;// CONCATENATED MODULE: ./src/variable-renamer.ts
|
|
11180
11348
|
|
|
@@ -11236,6 +11404,7 @@ function renameVariable(state, locals, declName) {
|
|
|
11236
11404
|
|
|
11237
11405
|
|
|
11238
11406
|
|
|
11407
|
+
|
|
11239
11408
|
function getArgSafety(state, func, args, requireAll) {
|
|
11240
11409
|
// determine whether decl might be changed by a function call
|
|
11241
11410
|
// or assignment during the evaluation of FunctionStateNode.
|
|
@@ -11268,8 +11437,9 @@ function getArgSafety(state, func, args, requireAll) {
|
|
|
11268
11437
|
}
|
|
11269
11438
|
};
|
|
11270
11439
|
const safeArgs = [];
|
|
11440
|
+
const argDecls = [];
|
|
11271
11441
|
let allSafe = true;
|
|
11272
|
-
if (!args.every((arg) => {
|
|
11442
|
+
if (!args.every((arg, i) => {
|
|
11273
11443
|
switch (arg.type) {
|
|
11274
11444
|
case "Literal":
|
|
11275
11445
|
safeArgs.push(true);
|
|
@@ -11283,13 +11453,17 @@ function getArgSafety(state, func, args, requireAll) {
|
|
|
11283
11453
|
safeArgs.push(null);
|
|
11284
11454
|
return !requireAll;
|
|
11285
11455
|
}
|
|
11286
|
-
const
|
|
11456
|
+
const decl = results[0].results[0];
|
|
11457
|
+
const safety = getSafety(decl);
|
|
11287
11458
|
safeArgs.push(safety);
|
|
11288
11459
|
if (!safety) {
|
|
11289
11460
|
allSafe = false;
|
|
11290
11461
|
if (safety === null) {
|
|
11291
11462
|
return !requireAll;
|
|
11292
11463
|
}
|
|
11464
|
+
else if (decl.type === "VariableDeclarator") {
|
|
11465
|
+
argDecls[i] = decl;
|
|
11466
|
+
}
|
|
11293
11467
|
}
|
|
11294
11468
|
return true;
|
|
11295
11469
|
}
|
|
@@ -11302,34 +11476,91 @@ function getArgSafety(state, func, args, requireAll) {
|
|
|
11302
11476
|
}
|
|
11303
11477
|
if (allSafe && requireAll)
|
|
11304
11478
|
return true;
|
|
11305
|
-
|
|
11479
|
+
const callsSeen = new Set();
|
|
11480
|
+
const modifiedDecls = new Set();
|
|
11481
|
+
let modifiedUnknown = false;
|
|
11306
11482
|
const params = Object.fromEntries(func.node.params.map((param, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(param), i]));
|
|
11307
11483
|
// look for uses of "unsafe" args that occur after a call.
|
|
11308
11484
|
// use post to do the checking, because arguments are evaluated
|
|
11309
11485
|
// prior to the call, so eg "return f(x.y);" is fine, but
|
|
11310
11486
|
// "return f()+x.y" is not.
|
|
11311
|
-
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11487
|
+
const { pre, post, stack } = state;
|
|
11488
|
+
try {
|
|
11489
|
+
delete state.pre;
|
|
11490
|
+
state.post = (node) => {
|
|
11491
|
+
switch (node.type) {
|
|
11492
|
+
case "AssignmentExpression":
|
|
11493
|
+
case "UpdateExpression": {
|
|
11494
|
+
const v = node.type == "UpdateExpression" ? node.argument : node.left;
|
|
11495
|
+
if (v.type === "Identifier" && (0,external_api_cjs_namespaceObject.hasProperty)(params, v.name)) {
|
|
11496
|
+
// If a parameter is modified, we can't just substitute the
|
|
11497
|
+
// argument wherever the parameter is used.
|
|
11498
|
+
safeArgs[params[v.name]] = null;
|
|
11499
|
+
break;
|
|
11500
|
+
}
|
|
11501
|
+
if (modifiedUnknown)
|
|
11502
|
+
break;
|
|
11503
|
+
const [, results] = state.lookup(v);
|
|
11504
|
+
if (results) {
|
|
11505
|
+
results.forEach((r) => r.results.forEach((decl) => decl.type === "VariableDeclarator" && modifiedDecls.add(decl)));
|
|
11506
|
+
}
|
|
11507
|
+
else {
|
|
11508
|
+
modifiedUnknown = true;
|
|
11509
|
+
}
|
|
11510
|
+
break;
|
|
11318
11511
|
}
|
|
11512
|
+
case "CallExpression":
|
|
11513
|
+
case "NewExpression":
|
|
11514
|
+
if (!modifiedUnknown) {
|
|
11515
|
+
const [, results] = state.lookup(node.callee, null,
|
|
11516
|
+
// calls are looked up as non-locals, but new is not
|
|
11517
|
+
node.type === "CallExpression" ? func.stack : state.stack);
|
|
11518
|
+
if (!results) {
|
|
11519
|
+
const callee_name = node.callee.type === "Identifier"
|
|
11520
|
+
? node.callee
|
|
11521
|
+
: node.callee.type === "MemberExpression"
|
|
11522
|
+
? (0,external_api_cjs_namespaceObject.isLookupCandidate)(node.callee)
|
|
11523
|
+
: null;
|
|
11524
|
+
if (callee_name) {
|
|
11525
|
+
const callees = state.allFunctions[callee_name.name];
|
|
11526
|
+
if (callees) {
|
|
11527
|
+
callees.forEach((callee) => callsSeen.add(callee));
|
|
11528
|
+
}
|
|
11529
|
+
}
|
|
11530
|
+
else {
|
|
11531
|
+
modifiedUnknown = true;
|
|
11532
|
+
}
|
|
11533
|
+
}
|
|
11534
|
+
else {
|
|
11535
|
+
const callees = node.type === "CallExpression"
|
|
11536
|
+
? findCallees(results)
|
|
11537
|
+
: findCalleesForNew(results);
|
|
11538
|
+
if (callees) {
|
|
11539
|
+
callees.forEach((callee) => callsSeen.add(callee));
|
|
11540
|
+
}
|
|
11541
|
+
}
|
|
11542
|
+
}
|
|
11543
|
+
break;
|
|
11544
|
+
case "Identifier":
|
|
11545
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(params, node.name) &&
|
|
11546
|
+
!safeArgs[params[node.name]] &&
|
|
11547
|
+
(modifiedUnknown ||
|
|
11548
|
+
!argDecls[params[node.name]] ||
|
|
11549
|
+
modifiedDecls.has(argDecls[params[node.name]]) ||
|
|
11550
|
+
Array.from(callsSeen).some((callee) => functionMayModify(state, callee, argDecls[params[node.name]])))) {
|
|
11551
|
+
safeArgs[params[node.name]] = null;
|
|
11552
|
+
}
|
|
11319
11553
|
}
|
|
11320
|
-
|
|
11321
|
-
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
|
|
11326
|
-
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
}
|
|
11331
|
-
}
|
|
11332
|
-
});
|
|
11554
|
+
return null;
|
|
11555
|
+
};
|
|
11556
|
+
state.stack = func.stack;
|
|
11557
|
+
state.traverse(func.node.body);
|
|
11558
|
+
}
|
|
11559
|
+
finally {
|
|
11560
|
+
state.pre = pre;
|
|
11561
|
+
state.post = post;
|
|
11562
|
+
state.stack = stack;
|
|
11563
|
+
}
|
|
11333
11564
|
return safeArgs;
|
|
11334
11565
|
}
|
|
11335
11566
|
function canInline(state, func, args) {
|
|
@@ -11434,9 +11665,6 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
11434
11665
|
state.pre = (node) => {
|
|
11435
11666
|
if (failed)
|
|
11436
11667
|
return [];
|
|
11437
|
-
node.start = call.start;
|
|
11438
|
-
node.end = call.end;
|
|
11439
|
-
node.loc = call.loc;
|
|
11440
11668
|
if (replacements.has(node))
|
|
11441
11669
|
return false;
|
|
11442
11670
|
const result = pre(node, state);
|
|
@@ -11451,6 +11679,7 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
11451
11679
|
if (params[paramName] >= 0)
|
|
11452
11680
|
return null;
|
|
11453
11681
|
const name = renameVariable(state, locals, paramName) || paramName;
|
|
11682
|
+
locals.map[name] = true;
|
|
11454
11683
|
return {
|
|
11455
11684
|
type: "VariableDeclarator",
|
|
11456
11685
|
id: { type: "Identifier", name },
|
|
@@ -11469,31 +11698,49 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
11469
11698
|
}
|
|
11470
11699
|
return result;
|
|
11471
11700
|
};
|
|
11701
|
+
const fixId = (node) => {
|
|
11702
|
+
if (state.inType)
|
|
11703
|
+
return null;
|
|
11704
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(params, node.name)) {
|
|
11705
|
+
const ix = params[node.name];
|
|
11706
|
+
if (ix >= 0) {
|
|
11707
|
+
const replacement = { ...call.arguments[ix] };
|
|
11708
|
+
replacements.add(replacement);
|
|
11709
|
+
return replacement;
|
|
11710
|
+
}
|
|
11711
|
+
return null;
|
|
11712
|
+
}
|
|
11713
|
+
const replacement = fixNodeScope(state, node, func.stack);
|
|
11714
|
+
if (!replacement) {
|
|
11715
|
+
failed = true;
|
|
11716
|
+
inlineDiagnostic(state, func, call, `Failed to resolve '${node.name}'`);
|
|
11717
|
+
}
|
|
11718
|
+
return replacement;
|
|
11719
|
+
};
|
|
11472
11720
|
state.post = (node) => {
|
|
11473
11721
|
if (failed)
|
|
11474
11722
|
return post(node, state);
|
|
11475
11723
|
let replacement = null;
|
|
11476
11724
|
switch (node.type) {
|
|
11477
|
-
case "
|
|
11478
|
-
if (
|
|
11479
|
-
|
|
11480
|
-
|
|
11481
|
-
|
|
11482
|
-
if (ix >= 0) {
|
|
11483
|
-
replacement = { ...call.arguments[ix] };
|
|
11484
|
-
replacements.add(replacement);
|
|
11485
|
-
return replacement;
|
|
11725
|
+
case "AssignmentExpression":
|
|
11726
|
+
if (node.left.type === "Identifier") {
|
|
11727
|
+
const rep = fixId(node.left);
|
|
11728
|
+
if (rep) {
|
|
11729
|
+
node.left = rep;
|
|
11486
11730
|
}
|
|
11487
|
-
break;
|
|
11488
11731
|
}
|
|
11489
|
-
|
|
11490
|
-
|
|
11491
|
-
|
|
11492
|
-
|
|
11493
|
-
|
|
11732
|
+
break;
|
|
11733
|
+
case "UpdateExpression":
|
|
11734
|
+
if (node.argument.type === "Identifier") {
|
|
11735
|
+
const rep = fixId(node.argument);
|
|
11736
|
+
if (rep) {
|
|
11737
|
+
node.argument = rep;
|
|
11738
|
+
}
|
|
11494
11739
|
}
|
|
11495
11740
|
break;
|
|
11496
|
-
|
|
11741
|
+
case "Identifier":
|
|
11742
|
+
replacement = fixId(node);
|
|
11743
|
+
break;
|
|
11497
11744
|
}
|
|
11498
11745
|
const ret = post(replacement || node, state);
|
|
11499
11746
|
return ret === false || ret ? ret : replacement;
|
|
@@ -11662,7 +11909,7 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
11662
11909
|
}
|
|
11663
11910
|
}
|
|
11664
11911
|
}
|
|
11665
|
-
const body =
|
|
11912
|
+
const body = cloneDeep(func.node.body);
|
|
11666
11913
|
const safeArgs = getArgSafety(state, func, call.arguments, false);
|
|
11667
11914
|
const params = Object.fromEntries(func.node.params.map((param, i) => {
|
|
11668
11915
|
const argnum = safeArgs === true || (safeArgs !== false && safeArgs[i] !== null)
|
|
@@ -11711,18 +11958,19 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
11711
11958
|
--block.body.length;
|
|
11712
11959
|
}
|
|
11713
11960
|
}
|
|
11961
|
+
withLocDeep(body, context, context, true);
|
|
11714
11962
|
return body;
|
|
11715
11963
|
}
|
|
11716
11964
|
function inlineFunction(state, func, call, context) {
|
|
11717
11965
|
if (context) {
|
|
11718
11966
|
return inlineWithArgs(state, func, call, context);
|
|
11719
11967
|
}
|
|
11720
|
-
const retArg =
|
|
11968
|
+
const retArg = cloneDeep(func.node.body.body[0].argument);
|
|
11721
11969
|
const params = Object.fromEntries(func.node.params.map((param, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(param), i]));
|
|
11722
11970
|
const map = fixupLocalsMap(state);
|
|
11723
11971
|
const ret = processInlineBody(state, func, call, retArg, params);
|
|
11724
11972
|
state.localsStack[state.localsStack.length - 1].map = map;
|
|
11725
|
-
return ret;
|
|
11973
|
+
return ret && withLocDeep(ret, call, call, true);
|
|
11726
11974
|
}
|
|
11727
11975
|
function applyTypeIfNeeded(node) {
|
|
11728
11976
|
if ("enumType" in node && node.enumType) {
|
|
@@ -11827,6 +12075,121 @@ function fixNodeScope(state, lookupNode, nodeStack) {
|
|
|
11827
12075
|
return null;
|
|
11828
12076
|
}
|
|
11829
12077
|
|
|
12078
|
+
;// CONCATENATED MODULE: ./src/pragma-checker.ts
|
|
12079
|
+
|
|
12080
|
+
|
|
12081
|
+
|
|
12082
|
+
function pragmaChecker(state, ast, diagnostics) {
|
|
12083
|
+
const comments = ast.comments;
|
|
12084
|
+
if (!comments)
|
|
12085
|
+
return;
|
|
12086
|
+
diagnostics = diagnostics
|
|
12087
|
+
?.slice()
|
|
12088
|
+
.sort((d1, d2) => d1.loc.start < d2.loc.start ? -1 : d1.loc.start == d2.loc.start ? 0 : 1);
|
|
12089
|
+
let diagIndex = 0;
|
|
12090
|
+
let index = -1;
|
|
12091
|
+
let comment;
|
|
12092
|
+
let matchers;
|
|
12093
|
+
const next = () => {
|
|
12094
|
+
while (++index < comments.length) {
|
|
12095
|
+
comment = comments[index];
|
|
12096
|
+
let match = comment.value.match(/^\s*@(match|expect)\s+(.+)/);
|
|
12097
|
+
if (!match)
|
|
12098
|
+
continue;
|
|
12099
|
+
const kind = match[1];
|
|
12100
|
+
let str = match[2];
|
|
12101
|
+
matchers = [];
|
|
12102
|
+
while ((match = str.match(/^([/%&#@"])(.+?(?<!\\)(?:\\{2})*)\1(\s+|$)/))) {
|
|
12103
|
+
matchers.push({ kind, quote: match[1], needle: match[2] });
|
|
12104
|
+
str = str.substring(match[0].length);
|
|
12105
|
+
if (!str.length)
|
|
12106
|
+
break;
|
|
12107
|
+
}
|
|
12108
|
+
if (!str.length)
|
|
12109
|
+
break;
|
|
12110
|
+
if (!matchers.length) {
|
|
12111
|
+
match = str.match(/^(\S+)\s+$/);
|
|
12112
|
+
if (match) {
|
|
12113
|
+
matchers.push({ kind, quote: '"', needle: match[1] });
|
|
12114
|
+
break;
|
|
12115
|
+
}
|
|
12116
|
+
}
|
|
12117
|
+
diagnostic(state, comment.loc, `Build pragma '${comment.value}' is invalid`, "ERROR");
|
|
12118
|
+
}
|
|
12119
|
+
};
|
|
12120
|
+
const matcher = (quote, needle, haystack) => {
|
|
12121
|
+
if (quote == '"') {
|
|
12122
|
+
return haystack.includes(needle);
|
|
12123
|
+
}
|
|
12124
|
+
const re = new RegExp(needle.replace(/@(\d+)/g, "(pre_)?$1(_\\d+)?"));
|
|
12125
|
+
return re.test(haystack);
|
|
12126
|
+
};
|
|
12127
|
+
next();
|
|
12128
|
+
traverseAst(ast, (node) => {
|
|
12129
|
+
if (index >= comments.length)
|
|
12130
|
+
return false;
|
|
12131
|
+
if (node.start && node.start >= (comment.end || Infinity)) {
|
|
12132
|
+
const { kind, quote, needle } = matchers.shift();
|
|
12133
|
+
if (kind === "match") {
|
|
12134
|
+
const haystack = (0,external_api_cjs_namespaceObject.formatAst)(node).replace(/([\r\n]|\s)+/g, " ");
|
|
12135
|
+
if (!matcher(quote, needle, haystack)) {
|
|
12136
|
+
matcher(quote, needle, haystack);
|
|
12137
|
+
diagnostic(state, comment.loc, `Didn't find '${needle}' in '${haystack}'`, "ERROR");
|
|
12138
|
+
}
|
|
12139
|
+
}
|
|
12140
|
+
else if (kind === "expect") {
|
|
12141
|
+
const locCmp = (a, b) => {
|
|
12142
|
+
if (!b)
|
|
12143
|
+
return -1;
|
|
12144
|
+
if (a.start.line < b.start.line)
|
|
12145
|
+
return -1;
|
|
12146
|
+
if (a.start.line === b.start.line &&
|
|
12147
|
+
a.start.column < b.start.column) {
|
|
12148
|
+
return -1;
|
|
12149
|
+
}
|
|
12150
|
+
if (a.end.line > b.end.line)
|
|
12151
|
+
return 1;
|
|
12152
|
+
if (a.end.line === b.end.line && a.end.column >= b.end.column) {
|
|
12153
|
+
return 1;
|
|
12154
|
+
}
|
|
12155
|
+
return 0;
|
|
12156
|
+
};
|
|
12157
|
+
let found = false;
|
|
12158
|
+
if (diagnostics) {
|
|
12159
|
+
while (true) {
|
|
12160
|
+
if (diagIndex >= diagnostics.length) {
|
|
12161
|
+
diagnostics = null;
|
|
12162
|
+
break;
|
|
12163
|
+
}
|
|
12164
|
+
const diag = diagnostics[diagIndex];
|
|
12165
|
+
const cmp = locCmp(diag.loc, node.loc);
|
|
12166
|
+
if (cmp > 0) {
|
|
12167
|
+
break;
|
|
12168
|
+
}
|
|
12169
|
+
diagIndex++;
|
|
12170
|
+
if (cmp < 0)
|
|
12171
|
+
continue;
|
|
12172
|
+
if (matcher(quote, needle, diag.message)) {
|
|
12173
|
+
found = true;
|
|
12174
|
+
diag.type = "INFO";
|
|
12175
|
+
}
|
|
12176
|
+
}
|
|
12177
|
+
}
|
|
12178
|
+
if (!found) {
|
|
12179
|
+
diagnostic(state, comment.loc, `Missing error message '${needle}`, "ERROR");
|
|
12180
|
+
}
|
|
12181
|
+
}
|
|
12182
|
+
if (matchers.length) {
|
|
12183
|
+
// if we're checking a series of nodes, we need
|
|
12184
|
+
// to skip over this one.
|
|
12185
|
+
return false;
|
|
12186
|
+
}
|
|
12187
|
+
next();
|
|
12188
|
+
}
|
|
12189
|
+
return null;
|
|
12190
|
+
});
|
|
12191
|
+
}
|
|
12192
|
+
|
|
11830
12193
|
;// CONCATENATED MODULE: ./src/control-flow.ts
|
|
11831
12194
|
|
|
11832
12195
|
|
|
@@ -12347,6 +12710,7 @@ var priorityqueuejs = __webpack_require__(2789);
|
|
|
12347
12710
|
|
|
12348
12711
|
|
|
12349
12712
|
|
|
12713
|
+
|
|
12350
12714
|
/**
|
|
12351
12715
|
* This implements a pseudo Partial Redundancy Elimination
|
|
12352
12716
|
* pass. It isn't quite like traditional PRE because we're
|
|
@@ -12416,7 +12780,7 @@ function sizeBasedPRE(state, func) {
|
|
|
12416
12780
|
return;
|
|
12417
12781
|
}
|
|
12418
12782
|
const { graph: head, identifiers } = buildPREGraph(state, func);
|
|
12419
|
-
const candidates = computeAttributes(head);
|
|
12783
|
+
const candidates = computeAttributes(state, head);
|
|
12420
12784
|
if (candidates) {
|
|
12421
12785
|
if (logging) {
|
|
12422
12786
|
console.log(`Found ${candidates.size} candidates in ${func.fullName}`);
|
|
@@ -12436,8 +12800,10 @@ function sizeBasedPRE(state, func) {
|
|
|
12436
12800
|
let i = 0;
|
|
12437
12801
|
do {
|
|
12438
12802
|
name = `pre_${declName(decl)}${i ? "_" + i : ""}`;
|
|
12439
|
-
if (!identifiers.has(name))
|
|
12803
|
+
if (!identifiers.has(name)) {
|
|
12804
|
+
identifiers.add(name);
|
|
12440
12805
|
break;
|
|
12806
|
+
}
|
|
12441
12807
|
i++;
|
|
12442
12808
|
} while (true);
|
|
12443
12809
|
declMap.set(decl, name);
|
|
@@ -12528,11 +12894,16 @@ function buildPREGraph(state, func) {
|
|
|
12528
12894
|
case "ParenthesizedExpression":
|
|
12529
12895
|
break;
|
|
12530
12896
|
case "Literal":
|
|
12531
|
-
if (
|
|
12532
|
-
|
|
12897
|
+
if (refCost(node) > LocalRefCost) {
|
|
12898
|
+
const result = getNodeValue(node);
|
|
12899
|
+
const key = result[1] +
|
|
12900
|
+
(result[0].value === null
|
|
12901
|
+
? ""
|
|
12902
|
+
: "-" + result[0].value.toString());
|
|
12903
|
+
let decl = literals.get(key);
|
|
12533
12904
|
if (!decl) {
|
|
12534
12905
|
decl = node;
|
|
12535
|
-
literals.set(
|
|
12906
|
+
literals.set(key, decl);
|
|
12536
12907
|
}
|
|
12537
12908
|
return {
|
|
12538
12909
|
type: "ref",
|
|
@@ -12612,10 +12983,18 @@ function buildPREGraph(state, func) {
|
|
|
12612
12983
|
}
|
|
12613
12984
|
break;
|
|
12614
12985
|
}
|
|
12615
|
-
case "NewExpression":
|
|
12616
|
-
|
|
12986
|
+
case "NewExpression": {
|
|
12987
|
+
const [, results] = state.lookup(node.callee);
|
|
12988
|
+
const callees = results ? findCalleesForNew(results) : null;
|
|
12989
|
+
liveDef(null, stmt);
|
|
12990
|
+
return { type: "mod", node, mayThrow, callees };
|
|
12991
|
+
}
|
|
12992
|
+
case "CallExpression": {
|
|
12617
12993
|
liveDef(null, stmt);
|
|
12618
|
-
|
|
12994
|
+
const [, results] = state.lookup(node.callee);
|
|
12995
|
+
const callees = results ? findCallees(results) : null;
|
|
12996
|
+
return { type: "mod", node, mayThrow, callees };
|
|
12997
|
+
}
|
|
12619
12998
|
default:
|
|
12620
12999
|
if (!isExpression(node))
|
|
12621
13000
|
break;
|
|
@@ -12631,12 +13010,6 @@ function buildPREGraph(state, func) {
|
|
|
12631
13010
|
function anticipatedDecls() {
|
|
12632
13011
|
return new Map();
|
|
12633
13012
|
}
|
|
12634
|
-
function cloneSet(ae) {
|
|
12635
|
-
return new Set(ae);
|
|
12636
|
-
}
|
|
12637
|
-
function mergeSet(a, b) {
|
|
12638
|
-
b.forEach((event) => a.add(event));
|
|
12639
|
-
}
|
|
12640
13013
|
function equalSet(a, b) {
|
|
12641
13014
|
if (a.size != b.size)
|
|
12642
13015
|
return false;
|
|
@@ -12715,6 +13088,7 @@ function refCost(node) {
|
|
|
12715
13088
|
switch (typeof node.value) {
|
|
12716
13089
|
case "string":
|
|
12717
13090
|
return 5;
|
|
13091
|
+
case "bigint":
|
|
12718
13092
|
case "number":
|
|
12719
13093
|
return 5;
|
|
12720
13094
|
case "boolean":
|
|
@@ -12776,7 +13150,7 @@ function candidateCost(candState) {
|
|
|
12776
13150
|
cost += defCost(candState.node) * boundarySize;
|
|
12777
13151
|
return cost;
|
|
12778
13152
|
}
|
|
12779
|
-
function computeAttributes(head) {
|
|
13153
|
+
function computeAttributes(state, head) {
|
|
12780
13154
|
const order = getPostOrder(head);
|
|
12781
13155
|
order.forEach((block, i) => {
|
|
12782
13156
|
block.order = i;
|
|
@@ -12885,7 +13259,9 @@ function computeAttributes(head) {
|
|
|
12885
13259
|
curState.forEach((candidates, decl) => {
|
|
12886
13260
|
if (decl.type === "VariableDeclarator" &&
|
|
12887
13261
|
decl.node.kind === "var" &&
|
|
12888
|
-
candidates.live
|
|
13262
|
+
candidates.live &&
|
|
13263
|
+
(!event.callees ||
|
|
13264
|
+
event.callees.some((callee) => functionMayModify(state, callee, decl)))) {
|
|
12889
13265
|
candidates.ant.add(getMod(event, decl, candidates.node));
|
|
12890
13266
|
candidates.live = false;
|
|
12891
13267
|
}
|
|
@@ -13074,20 +13450,26 @@ function applyReplacements(func, nodeMap, declMap) {
|
|
|
13074
13450
|
stmtStack.pop();
|
|
13075
13451
|
const events = nodeMap.get(node);
|
|
13076
13452
|
if (events) {
|
|
13077
|
-
|
|
13078
|
-
if (
|
|
13453
|
+
const ret = events.reduce((ret, event) => {
|
|
13454
|
+
if (event.type === "ref") {
|
|
13455
|
+
if (ret) {
|
|
13456
|
+
throw new Error(`ref found when there was already a replacement for this node`);
|
|
13457
|
+
}
|
|
13079
13458
|
if (node.type !== "Identifier" &&
|
|
13080
13459
|
node.type !== "MemberExpression" &&
|
|
13081
13460
|
node.type !== "Literal") {
|
|
13082
13461
|
throw new Error(`Ref found, but wrong type of node: ${node.type}`);
|
|
13083
13462
|
}
|
|
13084
|
-
const name = declMap.get(
|
|
13463
|
+
const name = declMap.get(event.decl);
|
|
13085
13464
|
if (!name) {
|
|
13086
13465
|
throw new Error(`No replacement found for "${(0,external_api_cjs_namespaceObject.formatAst)(node)}"`);
|
|
13087
13466
|
}
|
|
13088
13467
|
return ident(name, node);
|
|
13089
13468
|
}
|
|
13090
|
-
|
|
13469
|
+
if (event.type === "def") {
|
|
13470
|
+
if (ret) {
|
|
13471
|
+
throw new Error(`def found when there was already a replacement for this node`);
|
|
13472
|
+
}
|
|
13091
13473
|
if (node.type !== "AssignmentExpression" &&
|
|
13092
13474
|
node.type !== "UpdateExpression") {
|
|
13093
13475
|
throw new Error(`Def found, but wrong type of node: ${node.type}`);
|
|
@@ -13095,7 +13477,7 @@ function applyReplacements(func, nodeMap, declMap) {
|
|
|
13095
13477
|
const target = node.type === "AssignmentExpression"
|
|
13096
13478
|
? node.left
|
|
13097
13479
|
: node.argument;
|
|
13098
|
-
const name = declMap.get(
|
|
13480
|
+
const name = declMap.get(event.decl);
|
|
13099
13481
|
if (!name) {
|
|
13100
13482
|
throw new Error(`No replacement found for "${(0,external_api_cjs_namespaceObject.formatAst)(target)}"`);
|
|
13101
13483
|
}
|
|
@@ -13114,20 +13496,24 @@ function applyReplacements(func, nodeMap, declMap) {
|
|
|
13114
13496
|
}
|
|
13115
13497
|
return withLoc({ type: "SequenceExpression", expressions: [node, assign] }, node);
|
|
13116
13498
|
}
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13121
|
-
|
|
13122
|
-
|
|
13123
|
-
|
|
13499
|
+
if (event.type === "mod") {
|
|
13500
|
+
if (!event.decl) {
|
|
13501
|
+
throw new Error(`Unexpected null decl on mod event`);
|
|
13502
|
+
}
|
|
13503
|
+
let pending = pendingMap.get(stmt);
|
|
13504
|
+
if (!pending) {
|
|
13505
|
+
pendingMap.set(stmt, (pending = new Set()));
|
|
13506
|
+
}
|
|
13507
|
+
pending.add(event);
|
|
13124
13508
|
}
|
|
13125
|
-
|
|
13126
|
-
|
|
13127
|
-
pendingMap.set(stmt, (pending = new Set()));
|
|
13509
|
+
else {
|
|
13510
|
+
throw new Error(`Unexpected ${event.type} found`);
|
|
13128
13511
|
}
|
|
13129
|
-
|
|
13130
|
-
});
|
|
13512
|
+
return ret;
|
|
13513
|
+
}, null);
|
|
13514
|
+
if (ret) {
|
|
13515
|
+
return ret;
|
|
13516
|
+
}
|
|
13131
13517
|
}
|
|
13132
13518
|
const pending = pendingMap.get(node);
|
|
13133
13519
|
if (node.type === "SequenceExpression") {
|
|
@@ -13201,6 +13587,148 @@ function applyReplacements(func, nodeMap, declMap) {
|
|
|
13201
13587
|
});
|
|
13202
13588
|
}
|
|
13203
13589
|
|
|
13590
|
+
;// CONCATENATED MODULE: ./src/unused-exprs.ts
|
|
13591
|
+
|
|
13592
|
+
|
|
13593
|
+
|
|
13594
|
+
function cleanupUnusedVars(state, node) {
|
|
13595
|
+
const [parent] = state.stack.slice(-1);
|
|
13596
|
+
if (parent.node !== node) {
|
|
13597
|
+
return;
|
|
13598
|
+
}
|
|
13599
|
+
if (parent.type != "BlockStatement") {
|
|
13600
|
+
throw new Error(`Unexpected parent type '${parent.type}' for local declaration`);
|
|
13601
|
+
}
|
|
13602
|
+
if (parent.decls) {
|
|
13603
|
+
let toRemove = null;
|
|
13604
|
+
Object.values(parent.decls).forEach((decls) => {
|
|
13605
|
+
if (decls.length === 1 &&
|
|
13606
|
+
decls[0].type === "VariableDeclarator" &&
|
|
13607
|
+
!decls[0].used) {
|
|
13608
|
+
if (!toRemove)
|
|
13609
|
+
toRemove = {};
|
|
13610
|
+
toRemove[decls[0].name] = decls[0];
|
|
13611
|
+
}
|
|
13612
|
+
});
|
|
13613
|
+
if (toRemove) {
|
|
13614
|
+
const varDeclarations = new Map();
|
|
13615
|
+
traverseAst(node, null, (node) => {
|
|
13616
|
+
switch (node.type) {
|
|
13617
|
+
case "VariableDeclaration": {
|
|
13618
|
+
node.declarations.forEach((decl, i) => {
|
|
13619
|
+
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(decl.id);
|
|
13620
|
+
if (hasProperty(toRemove, name)) {
|
|
13621
|
+
const indices = varDeclarations.get(node);
|
|
13622
|
+
if (indices) {
|
|
13623
|
+
indices.push(i);
|
|
13624
|
+
}
|
|
13625
|
+
else {
|
|
13626
|
+
varDeclarations.set(node, [i]);
|
|
13627
|
+
}
|
|
13628
|
+
}
|
|
13629
|
+
});
|
|
13630
|
+
break;
|
|
13631
|
+
}
|
|
13632
|
+
case "ExpressionStatement":
|
|
13633
|
+
if (node.expression.type === "AssignmentExpression") {
|
|
13634
|
+
if (node.expression.left.type === "Identifier" &&
|
|
13635
|
+
hasProperty(toRemove, node.expression.left.name)) {
|
|
13636
|
+
return unused(node.expression.right);
|
|
13637
|
+
}
|
|
13638
|
+
}
|
|
13639
|
+
else if (node.expression.type === "UpdateExpression" &&
|
|
13640
|
+
node.expression.argument.type === "Identifier" &&
|
|
13641
|
+
hasProperty(toRemove, node.expression.argument.name)) {
|
|
13642
|
+
return false;
|
|
13643
|
+
}
|
|
13644
|
+
break;
|
|
13645
|
+
case "SequenceExpression": {
|
|
13646
|
+
for (let i = node.expressions.length; i--;) {
|
|
13647
|
+
const expr = node.expressions[i];
|
|
13648
|
+
if (expr.type === "AssignmentExpression") {
|
|
13649
|
+
if (expr.left.type === "Identifier" &&
|
|
13650
|
+
hasProperty(toRemove, expr.left.name)) {
|
|
13651
|
+
const rep = unused(expr.right);
|
|
13652
|
+
if (!rep.length) {
|
|
13653
|
+
node.expressions.splice(i, 1);
|
|
13654
|
+
}
|
|
13655
|
+
else {
|
|
13656
|
+
// Sequence expressions can only be assignments
|
|
13657
|
+
// or update expressions. Even calls aren't allowed
|
|
13658
|
+
toRemove[expr.left.name] = null;
|
|
13659
|
+
expr.operator = "=";
|
|
13660
|
+
}
|
|
13661
|
+
}
|
|
13662
|
+
}
|
|
13663
|
+
else if (expr.type === "UpdateExpression" &&
|
|
13664
|
+
expr.argument.type === "Identifier" &&
|
|
13665
|
+
hasProperty(toRemove, expr.argument.name)) {
|
|
13666
|
+
node.expressions.splice(i, 1);
|
|
13667
|
+
}
|
|
13668
|
+
}
|
|
13669
|
+
break;
|
|
13670
|
+
}
|
|
13671
|
+
}
|
|
13672
|
+
return null;
|
|
13673
|
+
});
|
|
13674
|
+
varDeclarations.forEach((indices, decl) => {
|
|
13675
|
+
let index = -1;
|
|
13676
|
+
for (let ii = indices.length, j = decl.declarations.length; ii--;) {
|
|
13677
|
+
const i = indices[ii];
|
|
13678
|
+
const vdecl = decl.declarations[i];
|
|
13679
|
+
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(vdecl.id);
|
|
13680
|
+
if (hasProperty(toRemove, name)) {
|
|
13681
|
+
const rep = vdecl.init ? unused(vdecl.init) : [];
|
|
13682
|
+
if (rep.length) {
|
|
13683
|
+
if (parent.node.type === "ForStatement") {
|
|
13684
|
+
// declarations whose inits have side effects
|
|
13685
|
+
// can't be deleted from for statements.
|
|
13686
|
+
continue;
|
|
13687
|
+
}
|
|
13688
|
+
if (index < 0) {
|
|
13689
|
+
index = parent.node.body.findIndex((s) => s === decl);
|
|
13690
|
+
if (index < 0) {
|
|
13691
|
+
throw new Error(`Failed to find variable declaration for ${(0,external_api_cjs_namespaceObject.variableDeclarationName)(vdecl.id)}`);
|
|
13692
|
+
}
|
|
13693
|
+
}
|
|
13694
|
+
if (j > i + 1) {
|
|
13695
|
+
const tail = {
|
|
13696
|
+
...decl,
|
|
13697
|
+
declarations: decl.declarations.slice(i + 1, j),
|
|
13698
|
+
};
|
|
13699
|
+
if (decl.loc && vdecl.loc) {
|
|
13700
|
+
tail.loc = { ...decl.loc, start: vdecl.loc.end };
|
|
13701
|
+
tail.start = vdecl.end;
|
|
13702
|
+
}
|
|
13703
|
+
rep.push(tail);
|
|
13704
|
+
}
|
|
13705
|
+
if (decl.loc && vdecl.loc) {
|
|
13706
|
+
decl.loc = { ...decl.loc, end: vdecl.loc.start };
|
|
13707
|
+
decl.end = vdecl.start;
|
|
13708
|
+
}
|
|
13709
|
+
decl.declarations.splice(i);
|
|
13710
|
+
parent.node.body.splice(index + 1, 0, ...rep);
|
|
13711
|
+
j = i;
|
|
13712
|
+
continue;
|
|
13713
|
+
}
|
|
13714
|
+
if (toRemove[name]) {
|
|
13715
|
+
j--;
|
|
13716
|
+
decl.declarations.splice(i, 1);
|
|
13717
|
+
if (i === j && decl.loc && vdecl.loc) {
|
|
13718
|
+
decl.loc = { ...decl.loc, end: vdecl.loc.start };
|
|
13719
|
+
decl.end = vdecl.start;
|
|
13720
|
+
}
|
|
13721
|
+
}
|
|
13722
|
+
else {
|
|
13723
|
+
delete vdecl.init;
|
|
13724
|
+
}
|
|
13725
|
+
}
|
|
13726
|
+
}
|
|
13727
|
+
});
|
|
13728
|
+
}
|
|
13729
|
+
}
|
|
13730
|
+
}
|
|
13731
|
+
|
|
13204
13732
|
;// CONCATENATED MODULE: ./src/visitor.ts
|
|
13205
13733
|
|
|
13206
13734
|
function visitReferences(state, ast, name, defn, callback) {
|
|
@@ -13265,14 +13793,16 @@ function visitReferences(state, ast, name, defn, callback) {
|
|
|
13265
13793
|
return checkResults(state.lookup(node), node);
|
|
13266
13794
|
}
|
|
13267
13795
|
break;
|
|
13268
|
-
case "MemberExpression":
|
|
13269
|
-
|
|
13270
|
-
|
|
13796
|
+
case "MemberExpression": {
|
|
13797
|
+
const property = (0,external_api_cjs_namespaceObject.isLookupCandidate)(node);
|
|
13798
|
+
if (property) {
|
|
13799
|
+
if (!name || property.name === name) {
|
|
13271
13800
|
return checkResults(state.lookup(node), node) || ["object"];
|
|
13272
13801
|
}
|
|
13273
13802
|
return ["object"];
|
|
13274
13803
|
}
|
|
13275
13804
|
break;
|
|
13805
|
+
}
|
|
13276
13806
|
case "MethodDefinition": {
|
|
13277
13807
|
if (!state.inType) {
|
|
13278
13808
|
throw new Error("Method definition outside of type!");
|
|
@@ -13281,7 +13811,6 @@ function visitReferences(state, ast, name, defn, callback) {
|
|
|
13281
13811
|
node.params.forEach((param) => {
|
|
13282
13812
|
if (param.type == "BinaryExpression") {
|
|
13283
13813
|
state.traverse(param.right);
|
|
13284
|
-
state.inType = true;
|
|
13285
13814
|
}
|
|
13286
13815
|
});
|
|
13287
13816
|
}
|
|
@@ -13304,6 +13833,9 @@ function visitReferences(state, ast, name, defn, callback) {
|
|
|
13304
13833
|
|
|
13305
13834
|
|
|
13306
13835
|
|
|
13836
|
+
|
|
13837
|
+
|
|
13838
|
+
|
|
13307
13839
|
function collectClassInfo(state) {
|
|
13308
13840
|
const toybox = state.stack[0].decls["Toybox"][0];
|
|
13309
13841
|
const lang = toybox.decls["Lang"][0];
|
|
@@ -13363,8 +13895,7 @@ function collectClassInfo(state) {
|
|
|
13363
13895
|
c.decls &&
|
|
13364
13896
|
Object.values(c.decls).forEach((funcs) => {
|
|
13365
13897
|
funcs.forEach((f) => {
|
|
13366
|
-
if (
|
|
13367
|
-
f.type === "FunctionDeclaration" &&
|
|
13898
|
+
if (f.type === "FunctionDeclaration" &&
|
|
13368
13899
|
(0,external_api_cjs_namespaceObject.hasProperty)(cls.decls, f.name)) {
|
|
13369
13900
|
f.node.hasOverride = true;
|
|
13370
13901
|
}
|
|
@@ -13377,6 +13908,15 @@ function collectClassInfo(state) {
|
|
|
13377
13908
|
state.allClasses.forEach((elm) => {
|
|
13378
13909
|
if (elm.superClass)
|
|
13379
13910
|
markOverrides(elm, elm.superClass);
|
|
13911
|
+
if (elm.hasInvoke && elm.decls) {
|
|
13912
|
+
Object.values(elm.decls).forEach((funcs) => {
|
|
13913
|
+
funcs.forEach((f) => {
|
|
13914
|
+
if (f.type === "FunctionDeclaration" && !f.isStatic) {
|
|
13915
|
+
(0,external_api_cjs_namespaceObject.markInvokeClassMethod)(f);
|
|
13916
|
+
}
|
|
13917
|
+
});
|
|
13918
|
+
});
|
|
13919
|
+
}
|
|
13380
13920
|
});
|
|
13381
13921
|
}
|
|
13382
13922
|
function getFileSources(fnMap) {
|
|
@@ -13415,7 +13955,7 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
13415
13955
|
const preState = {
|
|
13416
13956
|
fnMap,
|
|
13417
13957
|
config,
|
|
13418
|
-
allFunctions:
|
|
13958
|
+
allFunctions: {},
|
|
13419
13959
|
allClasses: [],
|
|
13420
13960
|
shouldExclude(node) {
|
|
13421
13961
|
if ("attrs" in node &&
|
|
@@ -13445,11 +13985,6 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
13445
13985
|
pre(node, state) {
|
|
13446
13986
|
switch (node.type) {
|
|
13447
13987
|
case "FunctionDeclaration":
|
|
13448
|
-
if (markApi) {
|
|
13449
|
-
node.body = null;
|
|
13450
|
-
break;
|
|
13451
|
-
}
|
|
13452
|
-
// falls through
|
|
13453
13988
|
case "ModuleDeclaration":
|
|
13454
13989
|
case "ClassDeclaration": {
|
|
13455
13990
|
const [scope] = state.stack.slice(-1);
|
|
@@ -13460,7 +13995,18 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
13460
13995
|
(scope.node.attrs &&
|
|
13461
13996
|
scope.node.attrs.access &&
|
|
13462
13997
|
scope.node.attrs.access.includes("static"));
|
|
13463
|
-
|
|
13998
|
+
if (markApi) {
|
|
13999
|
+
node.body = null;
|
|
14000
|
+
scope.info = (0,external_api_cjs_namespaceObject.getApiFunctionInfo)(scope);
|
|
14001
|
+
delete scope.stack;
|
|
14002
|
+
}
|
|
14003
|
+
const allFuncs = state.allFunctions;
|
|
14004
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(allFuncs, scope.name)) {
|
|
14005
|
+
allFuncs[scope.name] = [scope];
|
|
14006
|
+
}
|
|
14007
|
+
else {
|
|
14008
|
+
allFuncs[scope.name].push(scope);
|
|
14009
|
+
}
|
|
13464
14010
|
}
|
|
13465
14011
|
else if (scope.type === "ClassDeclaration") {
|
|
13466
14012
|
state.allClasses.push(scope);
|
|
@@ -13485,7 +14031,7 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
13485
14031
|
value.hasTests = hasTests;
|
|
13486
14032
|
});
|
|
13487
14033
|
delete state.shouldExclude;
|
|
13488
|
-
delete state.
|
|
14034
|
+
delete state.pre;
|
|
13489
14035
|
collectClassInfo(state);
|
|
13490
14036
|
const diagnosticType = config?.checkInvalidSymbols !== "OFF"
|
|
13491
14037
|
? config?.checkInvalidSymbols || "WARNING"
|
|
@@ -13508,6 +14054,8 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
13508
14054
|
});
|
|
13509
14055
|
});
|
|
13510
14056
|
}
|
|
14057
|
+
state.exposed = state.nextExposed;
|
|
14058
|
+
state.nextExposed = {};
|
|
13511
14059
|
return state;
|
|
13512
14060
|
}
|
|
13513
14061
|
function compareLiteralLike(a, b) {
|
|
@@ -13553,57 +14101,16 @@ function getLiteralNode(node) {
|
|
|
13553
14101
|
if (node.argument.type != "Literal")
|
|
13554
14102
|
return null;
|
|
13555
14103
|
switch (node.operator) {
|
|
13556
|
-
case "-":
|
|
13557
|
-
|
|
13558
|
-
|
|
13559
|
-
|
|
13560
|
-
value: -node.argument.value,
|
|
13561
|
-
raw: "-" + node.argument.value,
|
|
13562
|
-
enumType: node.enumType,
|
|
13563
|
-
};
|
|
14104
|
+
case "-": {
|
|
14105
|
+
const [arg, type] = getNodeValue(node.argument);
|
|
14106
|
+
if (type === "Number" || type === "Long") {
|
|
14107
|
+
return replacementLiteral(arg, -arg.value, type);
|
|
13564
14108
|
}
|
|
14109
|
+
}
|
|
13565
14110
|
}
|
|
13566
14111
|
}
|
|
13567
14112
|
return null;
|
|
13568
14113
|
}
|
|
13569
|
-
function getNodeValue(node) {
|
|
13570
|
-
if (node.type == "BinaryExpression" &&
|
|
13571
|
-
node.operator == "as" &&
|
|
13572
|
-
node.right.type == "TypeSpecList" &&
|
|
13573
|
-
node.right.ts.length == 1 &&
|
|
13574
|
-
typeof node.right.ts[0] == "string") {
|
|
13575
|
-
// this is a cast we inserted to retain the type of an enum
|
|
13576
|
-
// any arithmetic on it will revert to "Number", or "Long",
|
|
13577
|
-
// so just ignore it.
|
|
13578
|
-
return getNodeValue(node.left);
|
|
13579
|
-
}
|
|
13580
|
-
if (node.type != "Literal") {
|
|
13581
|
-
return [null, null];
|
|
13582
|
-
}
|
|
13583
|
-
let type = node.value === null ? "Null" : typeof node.value;
|
|
13584
|
-
if (type === "number") {
|
|
13585
|
-
const match = node.raw && prettier_plugin_monkeyc_namespaceObject.LiteralIntegerRe.exec(node.raw);
|
|
13586
|
-
if (match) {
|
|
13587
|
-
type = match[2] == "l" ? "Long" : "Number";
|
|
13588
|
-
}
|
|
13589
|
-
else if (node.raw && node.raw.endsWith("d")) {
|
|
13590
|
-
type = "Double";
|
|
13591
|
-
}
|
|
13592
|
-
else {
|
|
13593
|
-
type = "Float";
|
|
13594
|
-
}
|
|
13595
|
-
}
|
|
13596
|
-
else if (type === "string") {
|
|
13597
|
-
type = "String";
|
|
13598
|
-
}
|
|
13599
|
-
else if (type === "boolean") {
|
|
13600
|
-
type = "Boolean";
|
|
13601
|
-
}
|
|
13602
|
-
else {
|
|
13603
|
-
type = "Unknown";
|
|
13604
|
-
}
|
|
13605
|
-
return [node, type];
|
|
13606
|
-
}
|
|
13607
14114
|
function fullTypeName(state, tsp) {
|
|
13608
14115
|
if (typeof tsp.name === "string") {
|
|
13609
14116
|
return tsp.name;
|
|
@@ -13647,6 +14154,46 @@ function isBooleanExpression(state, node) {
|
|
|
13647
14154
|
}
|
|
13648
14155
|
return false;
|
|
13649
14156
|
}
|
|
14157
|
+
function replacementLiteral(arg, value, type) {
|
|
14158
|
+
if (typeof value === "boolean") {
|
|
14159
|
+
type = "Boolean";
|
|
14160
|
+
}
|
|
14161
|
+
else if (type === "Number") {
|
|
14162
|
+
value = Number(BigInt.asIntN(32, BigInt(value)));
|
|
14163
|
+
}
|
|
14164
|
+
else if (type === "Long") {
|
|
14165
|
+
value = BigInt.asIntN(64, BigInt(value));
|
|
14166
|
+
}
|
|
14167
|
+
return {
|
|
14168
|
+
...arg,
|
|
14169
|
+
value,
|
|
14170
|
+
raw: value.toString() + (type === "Long" ? "l" : ""),
|
|
14171
|
+
};
|
|
14172
|
+
}
|
|
14173
|
+
const operators = {
|
|
14174
|
+
"+": (left, right) => left + right,
|
|
14175
|
+
"-": (left, right) => left - right,
|
|
14176
|
+
"*": (left, right) => left * right,
|
|
14177
|
+
"/": (left, right) => left / right,
|
|
14178
|
+
"%": (left, right) => left % right,
|
|
14179
|
+
"&": (left, right) => left & right,
|
|
14180
|
+
"|": (left, right) => left | right,
|
|
14181
|
+
"^": (left, right) => left ^ right,
|
|
14182
|
+
"<<": (left, right) => left << (right & 127n),
|
|
14183
|
+
">>": (left, right) => left >> (right & 127n),
|
|
14184
|
+
"==": (left, right) =>
|
|
14185
|
+
// two string literals will compare unequal, becuase string
|
|
14186
|
+
// equality is object equality.
|
|
14187
|
+
typeof left === "string" ? false : left === right,
|
|
14188
|
+
"!=": (left, right) => typeof left === "string" ? true : left !== right,
|
|
14189
|
+
"<=": (left, right) => left <= right,
|
|
14190
|
+
">=": (left, right) => left >= right,
|
|
14191
|
+
"<": (left, right) => left < right,
|
|
14192
|
+
">": (left, right) => left > right,
|
|
14193
|
+
as: null,
|
|
14194
|
+
instanceof: null,
|
|
14195
|
+
has: null,
|
|
14196
|
+
};
|
|
13650
14197
|
function optimizeNode(state, node) {
|
|
13651
14198
|
switch (node.type) {
|
|
13652
14199
|
case "UnaryExpression": {
|
|
@@ -13661,29 +14208,17 @@ function optimizeNode(state, node) {
|
|
|
13661
14208
|
break;
|
|
13662
14209
|
case "-":
|
|
13663
14210
|
if (type === "Number" || type === "Long") {
|
|
13664
|
-
return
|
|
13665
|
-
...arg,
|
|
13666
|
-
value: -arg.value,
|
|
13667
|
-
raw: (-arg.value).toString() + (type === "Long" ? "l" : ""),
|
|
13668
|
-
};
|
|
14211
|
+
return replacementLiteral(arg, -arg.value, type);
|
|
13669
14212
|
}
|
|
13670
14213
|
break;
|
|
13671
14214
|
case "!":
|
|
13672
14215
|
case "~":
|
|
13673
14216
|
{
|
|
13674
|
-
let value;
|
|
13675
14217
|
if (type === "Number" || type === "Long") {
|
|
13676
|
-
|
|
14218
|
+
return replacementLiteral(arg, ~BigInt(arg.value), type);
|
|
13677
14219
|
}
|
|
13678
|
-
|
|
13679
|
-
|
|
13680
|
-
}
|
|
13681
|
-
if (value !== undefined) {
|
|
13682
|
-
return {
|
|
13683
|
-
...arg,
|
|
13684
|
-
value,
|
|
13685
|
-
raw: value.toString() + (type === "Long" ? "l" : ""),
|
|
13686
|
-
};
|
|
14220
|
+
if (type === "Boolean" && node.operator == "!") {
|
|
14221
|
+
return replacementLiteral(arg, !arg.value, type);
|
|
13687
14222
|
}
|
|
13688
14223
|
}
|
|
13689
14224
|
break;
|
|
@@ -13691,27 +14226,6 @@ function optimizeNode(state, node) {
|
|
|
13691
14226
|
break;
|
|
13692
14227
|
}
|
|
13693
14228
|
case "BinaryExpression": {
|
|
13694
|
-
const operators = {
|
|
13695
|
-
"+": (left, right) => left + right,
|
|
13696
|
-
"-": (left, right) => left - right,
|
|
13697
|
-
"*": (left, right) => left * right,
|
|
13698
|
-
"/": (left, right) => Math.trunc(left / right),
|
|
13699
|
-
"%": (left, right) => left % right,
|
|
13700
|
-
"&": (left, right, type) => type === "Number" ? left & right : null,
|
|
13701
|
-
"|": (left, right, type) => type === "Number" ? left | right : null,
|
|
13702
|
-
"^": (left, right, type) => type === "Number" ? left ^ right : null,
|
|
13703
|
-
"<<": (left, right, type) => type === "Number" ? left << right : null,
|
|
13704
|
-
">>": (left, right, type) => type === "Number" ? left >> right : null,
|
|
13705
|
-
"==": (left, right) => left == right,
|
|
13706
|
-
"!=": (left, right) => left != right,
|
|
13707
|
-
"<=": (left, right) => left <= right,
|
|
13708
|
-
">=": (left, right) => left >= right,
|
|
13709
|
-
"<": (left, right) => left < right,
|
|
13710
|
-
">": (left, right) => left > right,
|
|
13711
|
-
as: null,
|
|
13712
|
-
instanceof: null,
|
|
13713
|
-
has: null,
|
|
13714
|
-
};
|
|
13715
14229
|
const op = operators[node.operator];
|
|
13716
14230
|
if (op) {
|
|
13717
14231
|
const [left, left_type] = getNodeValue(node.left);
|
|
@@ -13719,23 +14233,22 @@ function optimizeNode(state, node) {
|
|
|
13719
14233
|
if (!left || !right)
|
|
13720
14234
|
break;
|
|
13721
14235
|
let value = null;
|
|
13722
|
-
|
|
13723
|
-
|
|
14236
|
+
let type;
|
|
14237
|
+
if ((left_type != "Number" && left_type != "Long") ||
|
|
14238
|
+
left_type != right_type) {
|
|
13724
14239
|
if (node.operator !== "==" && node.operator !== "!=") {
|
|
13725
14240
|
break;
|
|
13726
14241
|
}
|
|
13727
14242
|
value = operators[node.operator](left.value, right.value);
|
|
14243
|
+
type = "Boolean";
|
|
13728
14244
|
}
|
|
13729
14245
|
else {
|
|
13730
|
-
|
|
14246
|
+
type = left_type;
|
|
14247
|
+
value = op(BigInt(left.value), BigInt(right.value));
|
|
13731
14248
|
}
|
|
13732
14249
|
if (value === null)
|
|
13733
14250
|
break;
|
|
13734
|
-
return
|
|
13735
|
-
...left,
|
|
13736
|
-
value,
|
|
13737
|
-
raw: value.toString() + (left_type === "Long" ? "l" : ""),
|
|
13738
|
-
};
|
|
14251
|
+
return replacementLiteral(left, value, type);
|
|
13739
14252
|
}
|
|
13740
14253
|
break;
|
|
13741
14254
|
}
|
|
@@ -13745,7 +14258,8 @@ function optimizeNode(state, node) {
|
|
|
13745
14258
|
break;
|
|
13746
14259
|
const falsy = left.value === false ||
|
|
13747
14260
|
left.value === null ||
|
|
13748
|
-
(
|
|
14261
|
+
((left_type === "Number" || left_type === "Long") &&
|
|
14262
|
+
(left.value === 0 || left.value === 0n));
|
|
13749
14263
|
if (falsy === (node.operator === "&&")) {
|
|
13750
14264
|
return left;
|
|
13751
14265
|
}
|
|
@@ -13786,9 +14300,7 @@ function evaluateFunction(state, func, args) {
|
|
|
13786
14300
|
const paramValues = args &&
|
|
13787
14301
|
Object.fromEntries(func.params.map((p, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(p), args[i]]));
|
|
13788
14302
|
let ret = null;
|
|
13789
|
-
const body = args
|
|
13790
|
-
? JSON.parse(JSON.stringify(func.body))
|
|
13791
|
-
: func.body;
|
|
14303
|
+
const body = args ? cloneDeep(func.body) : func.body;
|
|
13792
14304
|
try {
|
|
13793
14305
|
traverseAst(body, (node) => {
|
|
13794
14306
|
switch (node.type) {
|
|
@@ -13839,12 +14351,10 @@ function markFunctionCalled(state, func) {
|
|
|
13839
14351
|
(0,external_util_cjs_namespaceObject.pushUnique)(state.calledFunctions[func.id.name], func);
|
|
13840
14352
|
}
|
|
13841
14353
|
async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
13842
|
-
const state =
|
|
13843
|
-
|
|
13844
|
-
|
|
13845
|
-
|
|
13846
|
-
calledFunctions: {},
|
|
13847
|
-
};
|
|
14354
|
+
const state = (await analyze(fnMap, barrelList, config));
|
|
14355
|
+
state.localsStack = [{}];
|
|
14356
|
+
state.calledFunctions = {};
|
|
14357
|
+
state.usedByName = {};
|
|
13848
14358
|
const replace = (node, old) => {
|
|
13849
14359
|
if (node === false || node === null)
|
|
13850
14360
|
return node;
|
|
@@ -13933,6 +14443,58 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
13933
14443
|
f.type == "FunctionDeclaration" &&
|
|
13934
14444
|
maybeCalled(f.node))) ||
|
|
13935
14445
|
(sc.superClass && checkInherited(sc, name))));
|
|
14446
|
+
const renamer = (idnode) => {
|
|
14447
|
+
const ident = idnode.type === "Identifier" ? idnode : idnode.left;
|
|
14448
|
+
const locals = topLocals();
|
|
14449
|
+
const { map } = locals;
|
|
14450
|
+
if (map) {
|
|
14451
|
+
const declName = ident.name;
|
|
14452
|
+
const name = renameVariable(state, locals, declName);
|
|
14453
|
+
if (name) {
|
|
14454
|
+
const [, results] = state.lookupValue(ident);
|
|
14455
|
+
if (!results) {
|
|
14456
|
+
throw new Error(`Didn't find local ${declName} which needed renaming`);
|
|
14457
|
+
}
|
|
14458
|
+
if (results.length !== 1) {
|
|
14459
|
+
throw new Error(`Lookup of local ${declName} found more than one result`);
|
|
14460
|
+
}
|
|
14461
|
+
const parent = results[0].parent;
|
|
14462
|
+
if (!parent) {
|
|
14463
|
+
throw new Error(`No parent in lookup of local ${declName}`);
|
|
14464
|
+
}
|
|
14465
|
+
const decls = parent.decls;
|
|
14466
|
+
if (!decls || !(0,external_api_cjs_namespaceObject.hasProperty)(decls, declName)) {
|
|
14467
|
+
throw new Error(`Missing decls in lookup of local ${declName}`);
|
|
14468
|
+
}
|
|
14469
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(decls, name)) {
|
|
14470
|
+
throw new Error(`While renaming ${declName} to ${name}, there was already a variable ${name}`);
|
|
14471
|
+
}
|
|
14472
|
+
if (decls[declName].length === 1) {
|
|
14473
|
+
decls[name] = decls[declName];
|
|
14474
|
+
delete decls[declName];
|
|
14475
|
+
}
|
|
14476
|
+
else {
|
|
14477
|
+
let i = decls[declName].length;
|
|
14478
|
+
while (i--) {
|
|
14479
|
+
const decl = decls[declName][i];
|
|
14480
|
+
if (decl === idnode ||
|
|
14481
|
+
(decl.type === "VariableDeclarator" && decl.node.id === idnode)) {
|
|
14482
|
+
decls[declName].splice(i, 1);
|
|
14483
|
+
decls[name] = [decl];
|
|
14484
|
+
break;
|
|
14485
|
+
}
|
|
14486
|
+
}
|
|
14487
|
+
if (i < 0) {
|
|
14488
|
+
throw new Error(`While renaming ${declName} to ${name}: Didn't find original declaration`);
|
|
14489
|
+
}
|
|
14490
|
+
}
|
|
14491
|
+
ident.name = name;
|
|
14492
|
+
}
|
|
14493
|
+
else {
|
|
14494
|
+
map[declName] = true;
|
|
14495
|
+
}
|
|
14496
|
+
}
|
|
14497
|
+
};
|
|
13936
14498
|
state.pre = (node) => {
|
|
13937
14499
|
switch (node.type) {
|
|
13938
14500
|
case "ConditionalExpression":
|
|
@@ -13953,7 +14515,11 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
13953
14515
|
result = !!value.value;
|
|
13954
14516
|
}
|
|
13955
14517
|
if (result !== null) {
|
|
13956
|
-
node.test = {
|
|
14518
|
+
node.test = {
|
|
14519
|
+
type: "Literal",
|
|
14520
|
+
value: result,
|
|
14521
|
+
raw: result.toString(),
|
|
14522
|
+
};
|
|
13957
14523
|
if (node.type === "IfStatement" ||
|
|
13958
14524
|
node.type === "ConditionalExpression") {
|
|
13959
14525
|
return [result ? "consequent" : "alternate"];
|
|
@@ -13972,7 +14538,7 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
13972
14538
|
return null;
|
|
13973
14539
|
}
|
|
13974
14540
|
case "EnumDeclaration":
|
|
13975
|
-
return
|
|
14541
|
+
return [];
|
|
13976
14542
|
case "ForStatement": {
|
|
13977
14543
|
const map = topLocals().map;
|
|
13978
14544
|
if (map) {
|
|
@@ -13981,43 +14547,13 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
13981
14547
|
break;
|
|
13982
14548
|
}
|
|
13983
14549
|
case "VariableDeclarator": {
|
|
13984
|
-
|
|
13985
|
-
const { map } = locals;
|
|
13986
|
-
if (map) {
|
|
13987
|
-
const declName = (0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id);
|
|
13988
|
-
const name = renameVariable(state, locals, declName);
|
|
13989
|
-
if (name) {
|
|
13990
|
-
if (node.id.type === "Identifier") {
|
|
13991
|
-
node.id.name = name;
|
|
13992
|
-
}
|
|
13993
|
-
else {
|
|
13994
|
-
node.id.left.name = name;
|
|
13995
|
-
}
|
|
13996
|
-
}
|
|
13997
|
-
else {
|
|
13998
|
-
map[declName] = true;
|
|
13999
|
-
}
|
|
14000
|
-
}
|
|
14550
|
+
renamer(node.id);
|
|
14001
14551
|
return ["init"];
|
|
14002
14552
|
}
|
|
14003
14553
|
case "CatchClause":
|
|
14004
14554
|
if (node.param) {
|
|
14005
14555
|
state.localsStack.push({ node, map: { ...(topLocals().map || {}) } });
|
|
14006
|
-
|
|
14007
|
-
const map = locals.map;
|
|
14008
|
-
const declName = (0,external_api_cjs_namespaceObject.variableDeclarationName)(node.param);
|
|
14009
|
-
const name = renameVariable(state, locals, declName);
|
|
14010
|
-
if (name) {
|
|
14011
|
-
if (node.param.type === "Identifier") {
|
|
14012
|
-
node.param.name = name;
|
|
14013
|
-
}
|
|
14014
|
-
else {
|
|
14015
|
-
node.param.left.name = name;
|
|
14016
|
-
}
|
|
14017
|
-
}
|
|
14018
|
-
else {
|
|
14019
|
-
map[declName] = true;
|
|
14020
|
-
}
|
|
14556
|
+
renamer(node.param);
|
|
14021
14557
|
return ["body"];
|
|
14022
14558
|
}
|
|
14023
14559
|
break;
|
|
@@ -14033,14 +14569,8 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14033
14569
|
break;
|
|
14034
14570
|
case "UnaryExpression":
|
|
14035
14571
|
if (node.operator == ":") {
|
|
14036
|
-
//
|
|
14037
|
-
//
|
|
14038
|
-
// indirectly, so we can't remove any enums or
|
|
14039
|
-
// constants with that name (we can still replace
|
|
14040
|
-
// uses of those constants though).
|
|
14041
|
-
state.exposed[node.argument.name] = true;
|
|
14042
|
-
// In any case, we can't replace *this* use of the
|
|
14043
|
-
// symbol with its value...
|
|
14572
|
+
// node.argument is not a normal identifier.
|
|
14573
|
+
// don't visit it.
|
|
14044
14574
|
return [];
|
|
14045
14575
|
}
|
|
14046
14576
|
break;
|
|
@@ -14052,29 +14582,73 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14052
14582
|
if (typeof name === "string") {
|
|
14053
14583
|
node.name = name;
|
|
14054
14584
|
}
|
|
14585
|
+
const [, results] = state.lookupValue(node);
|
|
14586
|
+
if (results) {
|
|
14587
|
+
if (results.length !== 1 || results[0].results.length !== 1) {
|
|
14588
|
+
throw new Error(`Local ${node.name} had multiple lookup results`);
|
|
14589
|
+
}
|
|
14590
|
+
const parent = results[0].parent;
|
|
14591
|
+
if (!parent) {
|
|
14592
|
+
throw new Error(`Local ${node.name} had no parent`);
|
|
14593
|
+
}
|
|
14594
|
+
const decl = results[0].results[0];
|
|
14595
|
+
if (parent.type === "FunctionDeclaration" ||
|
|
14596
|
+
decl.type !== "VariableDeclarator") {
|
|
14597
|
+
// we can't optimize away function or catch parameters
|
|
14598
|
+
return [];
|
|
14599
|
+
}
|
|
14600
|
+
if (parent.type !== "BlockStatement") {
|
|
14601
|
+
throw new Error(`Local ${node.name} was not declared at block scope(??)`);
|
|
14602
|
+
}
|
|
14603
|
+
decl.used = true;
|
|
14604
|
+
}
|
|
14055
14605
|
}
|
|
14056
14606
|
}
|
|
14057
14607
|
if ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, node.name)) {
|
|
14058
14608
|
if (!lookupAndReplace(node)) {
|
|
14059
|
-
state.
|
|
14609
|
+
state.usedByName[node.name] = true;
|
|
14060
14610
|
}
|
|
14061
14611
|
}
|
|
14062
14612
|
return [];
|
|
14063
14613
|
}
|
|
14064
|
-
case "MemberExpression":
|
|
14065
|
-
|
|
14066
|
-
|
|
14614
|
+
case "MemberExpression": {
|
|
14615
|
+
const property = (0,external_api_cjs_namespaceObject.isLookupCandidate)(node);
|
|
14616
|
+
if (property) {
|
|
14617
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, property.name)) {
|
|
14067
14618
|
if (lookupAndReplace(node)) {
|
|
14068
14619
|
return false;
|
|
14069
14620
|
}
|
|
14070
14621
|
else {
|
|
14071
|
-
state.
|
|
14622
|
+
state.usedByName[property.name] = true;
|
|
14072
14623
|
}
|
|
14073
14624
|
}
|
|
14074
14625
|
// Don't optimize the property.
|
|
14075
14626
|
return ["object"];
|
|
14076
14627
|
}
|
|
14077
14628
|
break;
|
|
14629
|
+
}
|
|
14630
|
+
case "AssignmentExpression":
|
|
14631
|
+
case "UpdateExpression": {
|
|
14632
|
+
const lhs = node.type === "AssignmentExpression" ? node.left : node.argument;
|
|
14633
|
+
if (lhs.type === "Identifier") {
|
|
14634
|
+
const map = topLocals().map;
|
|
14635
|
+
if (map) {
|
|
14636
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(map, lhs.name)) {
|
|
14637
|
+
const name = map[lhs.name];
|
|
14638
|
+
if (typeof name === "string") {
|
|
14639
|
+
lhs.name = name;
|
|
14640
|
+
}
|
|
14641
|
+
}
|
|
14642
|
+
}
|
|
14643
|
+
}
|
|
14644
|
+
else if (lhs.type === "MemberExpression") {
|
|
14645
|
+
state.traverse(lhs.object);
|
|
14646
|
+
if (lhs.computed) {
|
|
14647
|
+
state.traverse(lhs.property);
|
|
14648
|
+
}
|
|
14649
|
+
}
|
|
14650
|
+
return node.type === "AssignmentExpression" ? ["right"] : [];
|
|
14651
|
+
}
|
|
14078
14652
|
case "BlockStatement": {
|
|
14079
14653
|
const map = topLocals().map;
|
|
14080
14654
|
if (map) {
|
|
@@ -14090,7 +14664,11 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14090
14664
|
node.params &&
|
|
14091
14665
|
node.params.forEach((p) => (map[(0,external_api_cjs_namespaceObject.variableDeclarationName)(p)] = true));
|
|
14092
14666
|
state.localsStack.push({ node, map });
|
|
14093
|
-
const [parent] = state.stack.slice(-2);
|
|
14667
|
+
const [parent, self] = state.stack.slice(-2);
|
|
14668
|
+
if (state.currentFunction) {
|
|
14669
|
+
throw new Error(`Nested functions: ${self.fullName} was activated during processing of ${state.currentFunction.fullName}`);
|
|
14670
|
+
}
|
|
14671
|
+
state.currentFunction = self;
|
|
14094
14672
|
if (parent.type == "ClassDeclaration" && !maybeCalled(node)) {
|
|
14095
14673
|
let used = false;
|
|
14096
14674
|
if (node.id.name == "initialize") {
|
|
@@ -14117,10 +14695,23 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14117
14695
|
return replace(opt, node);
|
|
14118
14696
|
}
|
|
14119
14697
|
switch (node.type) {
|
|
14698
|
+
case "FunctionDeclaration":
|
|
14699
|
+
if (!state.currentFunction) {
|
|
14700
|
+
throw new Error(`Finished function ${state.stack.slice(-1)[0].fullName}, but it was not marked current`);
|
|
14701
|
+
}
|
|
14702
|
+
state.currentFunction.info = state.currentFunction.next_info;
|
|
14703
|
+
delete state.currentFunction.next_info;
|
|
14704
|
+
delete state.currentFunction;
|
|
14705
|
+
break;
|
|
14120
14706
|
case "BlockStatement":
|
|
14121
14707
|
if (node.body.length === 1 && node.body[0].type === "BlockStatement") {
|
|
14122
14708
|
node.body.splice(0, 1, ...node.body[0].body);
|
|
14123
14709
|
}
|
|
14710
|
+
// fall through
|
|
14711
|
+
case "ForStatement":
|
|
14712
|
+
if (locals.map) {
|
|
14713
|
+
cleanupUnusedVars(state, node);
|
|
14714
|
+
}
|
|
14124
14715
|
break;
|
|
14125
14716
|
case "ConditionalExpression":
|
|
14126
14717
|
case "IfStatement":
|
|
@@ -14153,17 +14744,20 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14153
14744
|
return replace(optimizeCall(state, node.argument, node), node.argument);
|
|
14154
14745
|
}
|
|
14155
14746
|
break;
|
|
14747
|
+
case "NewExpression":
|
|
14748
|
+
if (state.currentFunction) {
|
|
14749
|
+
const [, results] = state.lookup(node.callee);
|
|
14750
|
+
if (results) {
|
|
14751
|
+
recordCalledFuncs(state.currentFunction, findCalleesForNew(results));
|
|
14752
|
+
}
|
|
14753
|
+
else {
|
|
14754
|
+
recordModifiedUnknown(state.currentFunction);
|
|
14755
|
+
}
|
|
14756
|
+
}
|
|
14757
|
+
break;
|
|
14156
14758
|
case "CallExpression": {
|
|
14157
14759
|
return replace(optimizeCall(state, node, null), node);
|
|
14158
14760
|
}
|
|
14159
|
-
case "AssignmentExpression":
|
|
14160
|
-
if (node.operator === "=" &&
|
|
14161
|
-
node.left.type === "Identifier" &&
|
|
14162
|
-
node.right.type === "Identifier" &&
|
|
14163
|
-
node.left.name === node.right.name) {
|
|
14164
|
-
return { type: "Literal", value: null, raw: "null" };
|
|
14165
|
-
}
|
|
14166
|
-
break;
|
|
14167
14761
|
case "VariableDeclaration": {
|
|
14168
14762
|
const locals = topLocals();
|
|
14169
14763
|
if (locals.map &&
|
|
@@ -14237,6 +14831,32 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14237
14831
|
}
|
|
14238
14832
|
}
|
|
14239
14833
|
break;
|
|
14834
|
+
case "AssignmentExpression":
|
|
14835
|
+
if (node.operator === "=" &&
|
|
14836
|
+
node.left.type === "Identifier" &&
|
|
14837
|
+
node.right.type === "Identifier" &&
|
|
14838
|
+
node.left.name === node.right.name) {
|
|
14839
|
+
return { type: "Literal", value: null, raw: "null" };
|
|
14840
|
+
}
|
|
14841
|
+
// fall through;
|
|
14842
|
+
case "UpdateExpression":
|
|
14843
|
+
if (state.currentFunction) {
|
|
14844
|
+
const lhs = node.type === "AssignmentExpression" ? node.left : node.argument;
|
|
14845
|
+
const [, results] = state.lookup(lhs);
|
|
14846
|
+
if (results) {
|
|
14847
|
+
recordModifiedDecls(state.currentFunction, results);
|
|
14848
|
+
}
|
|
14849
|
+
else {
|
|
14850
|
+
const id = lhs.type === "Identifier" ? lhs : (0,external_api_cjs_namespaceObject.isLookupCandidate)(lhs);
|
|
14851
|
+
if (id) {
|
|
14852
|
+
recordModifiedName(state.currentFunction, id.name);
|
|
14853
|
+
}
|
|
14854
|
+
else {
|
|
14855
|
+
recordModifiedUnknown(state.currentFunction);
|
|
14856
|
+
}
|
|
14857
|
+
}
|
|
14858
|
+
}
|
|
14859
|
+
break;
|
|
14240
14860
|
}
|
|
14241
14861
|
return null;
|
|
14242
14862
|
};
|
|
@@ -14244,13 +14864,16 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14244
14864
|
(0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
|
|
14245
14865
|
});
|
|
14246
14866
|
state.calledFunctions = {};
|
|
14247
|
-
state.exposed =
|
|
14867
|
+
state.exposed = state.nextExposed;
|
|
14868
|
+
state.nextExposed = {};
|
|
14248
14869
|
Object.values(fnMap).forEach((f) => {
|
|
14249
14870
|
(0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
|
|
14250
14871
|
});
|
|
14872
|
+
state.exposed = state.nextExposed;
|
|
14873
|
+
state.nextExposed = {};
|
|
14251
14874
|
delete state.pre;
|
|
14252
14875
|
delete state.post;
|
|
14253
|
-
state.allFunctions.forEach((fn) => sizeBasedPRE(state, fn));
|
|
14876
|
+
Object.values(state.allFunctions).forEach((fns) => fns.forEach((fn) => sizeBasedPRE(state, fn)));
|
|
14254
14877
|
const cleanup = (node) => {
|
|
14255
14878
|
switch (node.type) {
|
|
14256
14879
|
case "ThisExpression":
|
|
@@ -14260,7 +14883,8 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14260
14883
|
if (node.members.every((m) => {
|
|
14261
14884
|
const name = "name" in m ? m.name : m.id.name;
|
|
14262
14885
|
return ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) &&
|
|
14263
|
-
!(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name)
|
|
14886
|
+
!(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name) &&
|
|
14887
|
+
!(0,external_api_cjs_namespaceObject.hasProperty)(state.usedByName, name));
|
|
14264
14888
|
})) {
|
|
14265
14889
|
node.enumType = [
|
|
14266
14890
|
...new Set(node.members.map((m) => {
|
|
@@ -14303,7 +14927,9 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14303
14927
|
case "VariableDeclaration": {
|
|
14304
14928
|
node.declarations = node.declarations.filter((d) => {
|
|
14305
14929
|
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(d.id);
|
|
14306
|
-
return (!(0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) ||
|
|
14930
|
+
return (!(0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) ||
|
|
14931
|
+
(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name) ||
|
|
14932
|
+
(0,external_api_cjs_namespaceObject.hasProperty)(state.usedByName, name));
|
|
14307
14933
|
});
|
|
14308
14934
|
if (!node.declarations.length) {
|
|
14309
14935
|
return false;
|
|
@@ -14317,6 +14943,11 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14317
14943
|
break;
|
|
14318
14944
|
case "FunctionDeclaration":
|
|
14319
14945
|
if (!maybeCalled(node)) {
|
|
14946
|
+
if (node.attrs &&
|
|
14947
|
+
node.attrs.attributes &&
|
|
14948
|
+
node.attrs.attributes.elements.some((attr) => attr.type === "UnaryExpression" && attr.argument.name === "keep")) {
|
|
14949
|
+
break;
|
|
14950
|
+
}
|
|
14320
14951
|
return false;
|
|
14321
14952
|
}
|
|
14322
14953
|
break;
|
|
@@ -14336,7 +14967,7 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14336
14967
|
}
|
|
14337
14968
|
return null;
|
|
14338
14969
|
};
|
|
14339
|
-
Object.
|
|
14970
|
+
Object.entries(fnMap).forEach(([name, f]) => {
|
|
14340
14971
|
traverseAst(f.ast, undefined, (node) => {
|
|
14341
14972
|
const ret = cleanup(node);
|
|
14342
14973
|
if (ret === false) {
|
|
@@ -14344,16 +14975,15 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14344
14975
|
}
|
|
14345
14976
|
return ret;
|
|
14346
14977
|
});
|
|
14978
|
+
if (state.config && state.config.checkBuildPragmas) {
|
|
14979
|
+
pragmaChecker(state, f.ast, state.diagnostics?.[name]);
|
|
14980
|
+
}
|
|
14347
14981
|
});
|
|
14348
14982
|
return state.diagnostics;
|
|
14349
14983
|
}
|
|
14350
14984
|
function optimizeCall(state, node, context) {
|
|
14351
14985
|
const [name, results] = state.lookupNonlocal(node.callee);
|
|
14352
|
-
const callees = results
|
|
14353
|
-
results
|
|
14354
|
-
.map((r) => r.results)
|
|
14355
|
-
.flat()
|
|
14356
|
-
.filter((c) => c.type === "FunctionDeclaration");
|
|
14986
|
+
const callees = results ? findCallees(results) : null;
|
|
14357
14987
|
if (!callees || !callees.length) {
|
|
14358
14988
|
const n = name ||
|
|
14359
14989
|
("name" in node.callee && node.callee.name) ||
|
|
@@ -14362,14 +14992,24 @@ function optimizeCall(state, node, context) {
|
|
|
14362
14992
|
"name" in node.callee.property &&
|
|
14363
14993
|
node.callee.property.name);
|
|
14364
14994
|
if (n) {
|
|
14365
|
-
state.
|
|
14995
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(state.allFunctions, n)) {
|
|
14996
|
+
if (state.currentFunction) {
|
|
14997
|
+
recordCalledFuncs(state.currentFunction, state.allFunctions[n]);
|
|
14998
|
+
}
|
|
14999
|
+
state.allFunctions[n].forEach((fn) => markFunctionCalled(state, fn.node));
|
|
15000
|
+
}
|
|
14366
15001
|
}
|
|
14367
|
-
else {
|
|
14368
|
-
//
|
|
14369
|
-
//
|
|
15002
|
+
else if (state.currentFunction) {
|
|
15003
|
+
// I don't think this can happen: foo[x](args)
|
|
15004
|
+
// doesn't parse, so you can't even do things like
|
|
15005
|
+
// $.Toybox.Lang[:format]("fmt", [])
|
|
15006
|
+
recordModifiedUnknown(state.currentFunction);
|
|
14370
15007
|
}
|
|
14371
15008
|
return null;
|
|
14372
15009
|
}
|
|
15010
|
+
if (state.currentFunction) {
|
|
15011
|
+
recordCalledFuncs(state.currentFunction, callees);
|
|
15012
|
+
}
|
|
14373
15013
|
if (callees.length == 1 && callees[0].type === "FunctionDeclaration") {
|
|
14374
15014
|
const callee = callees[0].node;
|
|
14375
15015
|
if (!context &&
|
|
@@ -14392,120 +15032,6 @@ function optimizeCall(state, node, context) {
|
|
|
14392
15032
|
return null;
|
|
14393
15033
|
}
|
|
14394
15034
|
|
|
14395
|
-
;// CONCATENATED MODULE: ./src/pragma-checker.ts
|
|
14396
|
-
|
|
14397
|
-
|
|
14398
|
-
function pragmaChecker(ast, diagnostics) {
|
|
14399
|
-
const comments = ast.comments;
|
|
14400
|
-
if (!comments)
|
|
14401
|
-
return;
|
|
14402
|
-
diagnostics = diagnostics
|
|
14403
|
-
?.slice()
|
|
14404
|
-
.sort((d1, d2) => d1.loc.start < d2.loc.start ? -1 : d1.loc.start == d2.loc.start ? 0 : 1);
|
|
14405
|
-
let diagIndex = 0;
|
|
14406
|
-
let index = -1;
|
|
14407
|
-
let comment;
|
|
14408
|
-
let matchers;
|
|
14409
|
-
const next = () => {
|
|
14410
|
-
while (++index < comments.length) {
|
|
14411
|
-
comment = comments[index];
|
|
14412
|
-
let match = comment.value.match(/^\s*@(match|expect)\s+(.+)/);
|
|
14413
|
-
if (!match)
|
|
14414
|
-
continue;
|
|
14415
|
-
const kind = match[1];
|
|
14416
|
-
let str = match[2];
|
|
14417
|
-
matchers = [];
|
|
14418
|
-
while ((match = str.match(/^([/%&#@"])(.+?(?<!\\)(?:\\{2})*)\1(\s+|$)/))) {
|
|
14419
|
-
matchers.push({ kind, quote: match[1], needle: match[2] });
|
|
14420
|
-
str = str.substring(match[0].length);
|
|
14421
|
-
if (!str.length)
|
|
14422
|
-
break;
|
|
14423
|
-
}
|
|
14424
|
-
if (!str.length)
|
|
14425
|
-
break;
|
|
14426
|
-
if (!matchers.length) {
|
|
14427
|
-
match = str.match(/^(\S+)\s+$/);
|
|
14428
|
-
if (match) {
|
|
14429
|
-
matchers.push({ kind, quote: '"', needle: match[1] });
|
|
14430
|
-
break;
|
|
14431
|
-
}
|
|
14432
|
-
}
|
|
14433
|
-
throw new Error(`Build pragma '${comment.value}' is invalid. In ${comment.loc.source}:${comment.loc.start.line}`);
|
|
14434
|
-
}
|
|
14435
|
-
};
|
|
14436
|
-
const matcher = (quote, needle, haystack) => {
|
|
14437
|
-
if (quote == '"') {
|
|
14438
|
-
return haystack.includes(needle);
|
|
14439
|
-
}
|
|
14440
|
-
const re = new RegExp(needle.replace(/@(\d+)/g, "(pre_)?$1(_\\d+)?"));
|
|
14441
|
-
return re.test(haystack);
|
|
14442
|
-
};
|
|
14443
|
-
next();
|
|
14444
|
-
traverseAst(ast, (node) => {
|
|
14445
|
-
if (index >= comments.length)
|
|
14446
|
-
return false;
|
|
14447
|
-
if (node.start && node.start >= (comment.end || Infinity)) {
|
|
14448
|
-
const { kind, quote, needle } = matchers.shift();
|
|
14449
|
-
if (kind === "match") {
|
|
14450
|
-
const haystack = (0,external_api_cjs_namespaceObject.formatAst)(node).replace(/([\r\n]|\s)+/g, " ");
|
|
14451
|
-
if (!matcher(quote, needle, haystack)) {
|
|
14452
|
-
matcher(quote, needle, haystack);
|
|
14453
|
-
throw new Error(`Didn't find '${needle}' in '${haystack}' at ${comment.loc.source}:${comment.loc.start.line}`);
|
|
14454
|
-
}
|
|
14455
|
-
}
|
|
14456
|
-
else if (kind === "expect") {
|
|
14457
|
-
const locCmp = (a, b) => {
|
|
14458
|
-
if (!b)
|
|
14459
|
-
return -1;
|
|
14460
|
-
if (a.start.line < b.start.line)
|
|
14461
|
-
return -1;
|
|
14462
|
-
if (a.start.line === b.start.line &&
|
|
14463
|
-
a.start.column < b.start.column) {
|
|
14464
|
-
return -1;
|
|
14465
|
-
}
|
|
14466
|
-
if (a.end.line > b.end.line)
|
|
14467
|
-
return 1;
|
|
14468
|
-
if (a.end.line === b.end.line && a.end.column >= b.end.column) {
|
|
14469
|
-
return 1;
|
|
14470
|
-
}
|
|
14471
|
-
return 0;
|
|
14472
|
-
};
|
|
14473
|
-
let found = false;
|
|
14474
|
-
if (diagnostics) {
|
|
14475
|
-
while (true) {
|
|
14476
|
-
if (diagIndex >= diagnostics.length) {
|
|
14477
|
-
diagnostics = null;
|
|
14478
|
-
break;
|
|
14479
|
-
}
|
|
14480
|
-
const diag = diagnostics[diagIndex];
|
|
14481
|
-
const cmp = locCmp(diag.loc, node.loc);
|
|
14482
|
-
if (cmp > 0) {
|
|
14483
|
-
break;
|
|
14484
|
-
}
|
|
14485
|
-
diagIndex++;
|
|
14486
|
-
if (cmp < 0)
|
|
14487
|
-
continue;
|
|
14488
|
-
if (matcher(quote, needle, diag.message)) {
|
|
14489
|
-
found = true;
|
|
14490
|
-
diag.type = "INFO";
|
|
14491
|
-
}
|
|
14492
|
-
}
|
|
14493
|
-
}
|
|
14494
|
-
if (!found) {
|
|
14495
|
-
throw new Error(`Missing error message '${needle} at ${comment.loc.source}:${comment.loc.start.line}`);
|
|
14496
|
-
}
|
|
14497
|
-
}
|
|
14498
|
-
if (matchers.length) {
|
|
14499
|
-
// if we're checking a series of nodes, we need
|
|
14500
|
-
// to skip over this one.
|
|
14501
|
-
return false;
|
|
14502
|
-
}
|
|
14503
|
-
next();
|
|
14504
|
-
}
|
|
14505
|
-
return null;
|
|
14506
|
-
});
|
|
14507
|
-
}
|
|
14508
|
-
|
|
14509
15035
|
;// CONCATENATED MODULE: ./src/optimizer.ts
|
|
14510
15036
|
|
|
14511
15037
|
|
|
@@ -14943,22 +15469,19 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
14943
15469
|
// the oldest optimized file, we don't need to regenerate
|
|
14944
15470
|
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
14945
15471
|
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
14946
|
-
if (source_time < opt_time &&
|
|
15472
|
+
if (source_time < opt_time && 1658088370253 < opt_time) {
|
|
14947
15473
|
return { hasTests, diagnostics: prevDiagnostics };
|
|
14948
15474
|
}
|
|
14949
15475
|
}
|
|
14950
15476
|
await promises_namespaceObject.rm(output, { recursive: true, force: true });
|
|
14951
15477
|
await promises_namespaceObject.mkdir(output, { recursive: true });
|
|
14952
15478
|
const diagnostics = await optimizeMonkeyC(fnMap, Object.keys(buildConfig.barrelMap || {}), config);
|
|
14953
|
-
return Promise.all(Object.
|
|
15479
|
+
return Promise.all(Object.values(fnMap).map(async (info) => {
|
|
14954
15480
|
const name = info.output;
|
|
14955
15481
|
const dir = external_path_.dirname(name);
|
|
14956
15482
|
await promises_namespaceObject.mkdir(dir, { recursive: true });
|
|
14957
15483
|
const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(info.ast, info.monkeyCSource);
|
|
14958
15484
|
await promises_namespaceObject.writeFile(name, opt_source);
|
|
14959
|
-
if (config.checkBuildPragmas) {
|
|
14960
|
-
pragmaChecker(info.ast, diagnostics?.[inFile]);
|
|
14961
|
-
}
|
|
14962
15485
|
return info.hasTests;
|
|
14963
15486
|
})).then((results) => {
|
|
14964
15487
|
const hasTests = results.some((v) => v);
|