@markw65/monkeyc-optimizer 1.0.30 → 1.0.31
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 +35 -0
- package/build/api.cjs +977 -275
- package/build/optimizer.cjs +877 -365
- package/build/src/api.d.ts +5 -1
- package/build/src/ast.d.ts +2 -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 +2 -2
package/build/optimizer.cjs
CHANGED
|
@@ -11163,18 +11163,147 @@ function withLoc(node, start, end) {
|
|
|
11163
11163
|
}
|
|
11164
11164
|
return node;
|
|
11165
11165
|
}
|
|
11166
|
-
function withLocDeep(node, start, end) {
|
|
11167
|
-
node = withLoc({ ...node }, start, end);
|
|
11166
|
+
function withLocDeep(node, start, end, inplace) {
|
|
11167
|
+
node = withLoc(inplace ? node : { ...node }, start, end);
|
|
11168
11168
|
for (const key of mctreeTypeInfo[node.type].keys) {
|
|
11169
11169
|
const value = node[key];
|
|
11170
11170
|
if (!value)
|
|
11171
11171
|
continue;
|
|
11172
|
-
const fix = (v) => isMCTreeNode(v) ? withLocDeep(v, start, end) : v;
|
|
11172
|
+
const fix = (v) => isMCTreeNode(v) ? withLocDeep(v, start, end, inplace) : v;
|
|
11173
11173
|
const repl = Array.isArray(value) ? value.map(fix) : fix(value);
|
|
11174
|
-
node[key] = repl;
|
|
11174
|
+
inplace || (node[key] = repl);
|
|
11175
11175
|
}
|
|
11176
11176
|
return node;
|
|
11177
11177
|
}
|
|
11178
|
+
function cloneDeep(node) {
|
|
11179
|
+
return withLocDeep(node, null);
|
|
11180
|
+
}
|
|
11181
|
+
|
|
11182
|
+
;// CONCATENATED MODULE: ./src/function-info.ts
|
|
11183
|
+
|
|
11184
|
+
function cloneSet(ae) {
|
|
11185
|
+
return new Set(ae);
|
|
11186
|
+
}
|
|
11187
|
+
function mergeSet(a, b) {
|
|
11188
|
+
b.forEach((event) => a.add(event));
|
|
11189
|
+
}
|
|
11190
|
+
function recordModifiedDecl(func, decl) {
|
|
11191
|
+
if (!func.next_info) {
|
|
11192
|
+
func.next_info = { modifiedDecls: new Set(), calledFuncs: new Set() };
|
|
11193
|
+
}
|
|
11194
|
+
func.next_info.modifiedDecls.add(decl);
|
|
11195
|
+
return null;
|
|
11196
|
+
}
|
|
11197
|
+
function recordModifiedDecls(func, lookupDefs) {
|
|
11198
|
+
lookupDefs.forEach((lookupDef) => lookupDef.results.forEach((result) => {
|
|
11199
|
+
if (result.type == "VariableDeclarator" && result.node.kind === "var") {
|
|
11200
|
+
recordModifiedDecl(func, result);
|
|
11201
|
+
}
|
|
11202
|
+
}));
|
|
11203
|
+
}
|
|
11204
|
+
function recordModifiedName(func, name) {
|
|
11205
|
+
if (!func.next_info) {
|
|
11206
|
+
func.next_info = { modifiedDecls: new Set(), calledFuncs: new Set() };
|
|
11207
|
+
}
|
|
11208
|
+
if (!func.next_info.modifiedNames) {
|
|
11209
|
+
func.next_info.modifiedNames = new Set();
|
|
11210
|
+
}
|
|
11211
|
+
func.next_info.modifiedNames.add(name);
|
|
11212
|
+
}
|
|
11213
|
+
function recordModifiedUnknown(func) {
|
|
11214
|
+
if (!func.next_info) {
|
|
11215
|
+
func.next_info = { modifiedDecls: new Set(), calledFuncs: new Set() };
|
|
11216
|
+
}
|
|
11217
|
+
func.next_info.modifiedUnknown = true;
|
|
11218
|
+
}
|
|
11219
|
+
function recordCalledFunc(func, callee) {
|
|
11220
|
+
if (!func.next_info) {
|
|
11221
|
+
func.next_info = { modifiedDecls: new Set(), calledFuncs: new Set() };
|
|
11222
|
+
}
|
|
11223
|
+
func.next_info.calledFuncs.add(callee);
|
|
11224
|
+
return null;
|
|
11225
|
+
}
|
|
11226
|
+
function recordCalledFuncs(func, callees) {
|
|
11227
|
+
callees.forEach((callee) => {
|
|
11228
|
+
recordCalledFunc(func, callee);
|
|
11229
|
+
});
|
|
11230
|
+
}
|
|
11231
|
+
function functionMayModify(state, func, decl) {
|
|
11232
|
+
const info = func.info;
|
|
11233
|
+
if (!info || info.modifiedUnknown)
|
|
11234
|
+
return true;
|
|
11235
|
+
if (info.resolvedDecls) {
|
|
11236
|
+
return info.resolvedDecls.has(decl);
|
|
11237
|
+
}
|
|
11238
|
+
if (info.modifiedNames?.has(decl.name))
|
|
11239
|
+
return true;
|
|
11240
|
+
if (info.modifiedDecls.has(decl))
|
|
11241
|
+
return true;
|
|
11242
|
+
const visited = new Set();
|
|
11243
|
+
const resolved = new Set();
|
|
11244
|
+
const resolveDecls = (f) => {
|
|
11245
|
+
if (visited.has(f))
|
|
11246
|
+
return true;
|
|
11247
|
+
if (!f.info)
|
|
11248
|
+
return false;
|
|
11249
|
+
if (f.info.modifiedUnknown) {
|
|
11250
|
+
info.modifiedUnknown = true;
|
|
11251
|
+
return false;
|
|
11252
|
+
}
|
|
11253
|
+
if (f.info.modifiedNames) {
|
|
11254
|
+
if (info.modifiedNames) {
|
|
11255
|
+
mergeSet(info.modifiedNames, f.info.modifiedNames);
|
|
11256
|
+
}
|
|
11257
|
+
else {
|
|
11258
|
+
info.modifiedNames = cloneSet(f.info.modifiedNames);
|
|
11259
|
+
}
|
|
11260
|
+
}
|
|
11261
|
+
mergeSet(resolved, f.info.modifiedDecls);
|
|
11262
|
+
visited.add(f);
|
|
11263
|
+
const q = true;
|
|
11264
|
+
if (q &&
|
|
11265
|
+
f.info.callsExposed &&
|
|
11266
|
+
state.exposed &&
|
|
11267
|
+
!Object.keys(state.exposed).every((key) => !state.allFunctions[key] ||
|
|
11268
|
+
state.allFunctions[key].every(resolveDecls))) {
|
|
11269
|
+
return false;
|
|
11270
|
+
}
|
|
11271
|
+
return Array.from(f.info.calledFuncs).every(resolveDecls);
|
|
11272
|
+
};
|
|
11273
|
+
if (resolveDecls(func)) {
|
|
11274
|
+
info.resolvedDecls = resolved;
|
|
11275
|
+
return resolved.has(decl);
|
|
11276
|
+
}
|
|
11277
|
+
return true;
|
|
11278
|
+
}
|
|
11279
|
+
function findCallees(lookupDefs) {
|
|
11280
|
+
const decls = lookupDefs.reduce((decls, r) => (decls ? decls.concat(r.results) : r.results), null);
|
|
11281
|
+
return (decls &&
|
|
11282
|
+
decls.filter((decl) => decl ? decl.type === "FunctionDeclaration" : false));
|
|
11283
|
+
}
|
|
11284
|
+
function findCalleesForNew(lookupDefs) {
|
|
11285
|
+
const initializer = (decl) => {
|
|
11286
|
+
if (hasProperty(decl.decls, "initialize")) {
|
|
11287
|
+
return decl.decls["initialize"];
|
|
11288
|
+
}
|
|
11289
|
+
if (decl.superClass && decl.superClass !== true) {
|
|
11290
|
+
return decl.superClass.reduce((cur, cls) => {
|
|
11291
|
+
const init = initializer(cls);
|
|
11292
|
+
if (init) {
|
|
11293
|
+
if (!cur)
|
|
11294
|
+
return init;
|
|
11295
|
+
return cur.concat(init);
|
|
11296
|
+
}
|
|
11297
|
+
return cur;
|
|
11298
|
+
}, null);
|
|
11299
|
+
}
|
|
11300
|
+
return null;
|
|
11301
|
+
};
|
|
11302
|
+
return lookupDefs.flatMap((r) => r.results
|
|
11303
|
+
.filter((decl) => decl.type === "ClassDeclaration")
|
|
11304
|
+
.flatMap(initializer)
|
|
11305
|
+
.filter((decl) => decl ? decl.type === "FunctionDeclaration" : false));
|
|
11306
|
+
}
|
|
11178
11307
|
|
|
11179
11308
|
;// CONCATENATED MODULE: ./src/variable-renamer.ts
|
|
11180
11309
|
|
|
@@ -11236,6 +11365,7 @@ function renameVariable(state, locals, declName) {
|
|
|
11236
11365
|
|
|
11237
11366
|
|
|
11238
11367
|
|
|
11368
|
+
|
|
11239
11369
|
function getArgSafety(state, func, args, requireAll) {
|
|
11240
11370
|
// determine whether decl might be changed by a function call
|
|
11241
11371
|
// or assignment during the evaluation of FunctionStateNode.
|
|
@@ -11268,8 +11398,9 @@ function getArgSafety(state, func, args, requireAll) {
|
|
|
11268
11398
|
}
|
|
11269
11399
|
};
|
|
11270
11400
|
const safeArgs = [];
|
|
11401
|
+
const argDecls = [];
|
|
11271
11402
|
let allSafe = true;
|
|
11272
|
-
if (!args.every((arg) => {
|
|
11403
|
+
if (!args.every((arg, i) => {
|
|
11273
11404
|
switch (arg.type) {
|
|
11274
11405
|
case "Literal":
|
|
11275
11406
|
safeArgs.push(true);
|
|
@@ -11283,13 +11414,17 @@ function getArgSafety(state, func, args, requireAll) {
|
|
|
11283
11414
|
safeArgs.push(null);
|
|
11284
11415
|
return !requireAll;
|
|
11285
11416
|
}
|
|
11286
|
-
const
|
|
11417
|
+
const decl = results[0].results[0];
|
|
11418
|
+
const safety = getSafety(decl);
|
|
11287
11419
|
safeArgs.push(safety);
|
|
11288
11420
|
if (!safety) {
|
|
11289
11421
|
allSafe = false;
|
|
11290
11422
|
if (safety === null) {
|
|
11291
11423
|
return !requireAll;
|
|
11292
11424
|
}
|
|
11425
|
+
else if (decl.type === "VariableDeclarator") {
|
|
11426
|
+
argDecls[i] = decl;
|
|
11427
|
+
}
|
|
11293
11428
|
}
|
|
11294
11429
|
return true;
|
|
11295
11430
|
}
|
|
@@ -11302,34 +11437,91 @@ function getArgSafety(state, func, args, requireAll) {
|
|
|
11302
11437
|
}
|
|
11303
11438
|
if (allSafe && requireAll)
|
|
11304
11439
|
return true;
|
|
11305
|
-
|
|
11440
|
+
const callsSeen = new Set();
|
|
11441
|
+
const modifiedDecls = new Set();
|
|
11442
|
+
let modifiedUnknown = false;
|
|
11306
11443
|
const params = Object.fromEntries(func.node.params.map((param, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(param), i]));
|
|
11307
11444
|
// look for uses of "unsafe" args that occur after a call.
|
|
11308
11445
|
// use post to do the checking, because arguments are evaluated
|
|
11309
11446
|
// prior to the call, so eg "return f(x.y);" is fine, but
|
|
11310
11447
|
// "return f()+x.y" is not.
|
|
11311
|
-
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11448
|
+
const { pre, post, stack } = state;
|
|
11449
|
+
try {
|
|
11450
|
+
delete state.pre;
|
|
11451
|
+
state.post = (node) => {
|
|
11452
|
+
switch (node.type) {
|
|
11453
|
+
case "AssignmentExpression":
|
|
11454
|
+
case "UpdateExpression": {
|
|
11455
|
+
const v = node.type == "UpdateExpression" ? node.argument : node.left;
|
|
11456
|
+
if (v.type === "Identifier" && (0,external_api_cjs_namespaceObject.hasProperty)(params, v.name)) {
|
|
11457
|
+
// If a parameter is modified, we can't just substitute the
|
|
11458
|
+
// argument wherever the parameter is used.
|
|
11459
|
+
safeArgs[params[v.name]] = null;
|
|
11460
|
+
break;
|
|
11461
|
+
}
|
|
11462
|
+
if (modifiedUnknown)
|
|
11463
|
+
break;
|
|
11464
|
+
const [, results] = state.lookup(v);
|
|
11465
|
+
if (results) {
|
|
11466
|
+
results.forEach((r) => r.results.forEach((decl) => decl.type === "VariableDeclarator" && modifiedDecls.add(decl)));
|
|
11467
|
+
}
|
|
11468
|
+
else {
|
|
11469
|
+
modifiedUnknown = true;
|
|
11470
|
+
}
|
|
11471
|
+
break;
|
|
11318
11472
|
}
|
|
11473
|
+
case "CallExpression":
|
|
11474
|
+
case "NewExpression":
|
|
11475
|
+
if (!modifiedUnknown) {
|
|
11476
|
+
const [, results] = state.lookup(node.callee, null,
|
|
11477
|
+
// calls are looked up as non-locals, but new is not
|
|
11478
|
+
node.type === "CallExpression" ? func.stack : state.stack);
|
|
11479
|
+
if (!results) {
|
|
11480
|
+
const callee_name = node.callee.type === "Identifier"
|
|
11481
|
+
? node.callee
|
|
11482
|
+
: node.callee.type === "MemberExpression"
|
|
11483
|
+
? (0,external_api_cjs_namespaceObject.isLookupCandidate)(node.callee)
|
|
11484
|
+
: null;
|
|
11485
|
+
if (callee_name) {
|
|
11486
|
+
const callees = state.allFunctions[callee_name.name];
|
|
11487
|
+
if (callees) {
|
|
11488
|
+
callees.forEach((callee) => callsSeen.add(callee));
|
|
11489
|
+
}
|
|
11490
|
+
}
|
|
11491
|
+
else {
|
|
11492
|
+
modifiedUnknown = true;
|
|
11493
|
+
}
|
|
11494
|
+
}
|
|
11495
|
+
else {
|
|
11496
|
+
const callees = node.type === "CallExpression"
|
|
11497
|
+
? findCallees(results)
|
|
11498
|
+
: findCalleesForNew(results);
|
|
11499
|
+
if (callees) {
|
|
11500
|
+
callees.forEach((callee) => callsSeen.add(callee));
|
|
11501
|
+
}
|
|
11502
|
+
}
|
|
11503
|
+
}
|
|
11504
|
+
break;
|
|
11505
|
+
case "Identifier":
|
|
11506
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(params, node.name) &&
|
|
11507
|
+
!safeArgs[params[node.name]] &&
|
|
11508
|
+
(modifiedUnknown ||
|
|
11509
|
+
!argDecls[params[node.name]] ||
|
|
11510
|
+
modifiedDecls.has(argDecls[params[node.name]]) ||
|
|
11511
|
+
Array.from(callsSeen).some((callee) => functionMayModify(state, callee, argDecls[params[node.name]])))) {
|
|
11512
|
+
safeArgs[params[node.name]] = null;
|
|
11513
|
+
}
|
|
11319
11514
|
}
|
|
11320
|
-
|
|
11321
|
-
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
|
|
11326
|
-
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
}
|
|
11331
|
-
}
|
|
11332
|
-
});
|
|
11515
|
+
return null;
|
|
11516
|
+
};
|
|
11517
|
+
state.stack = func.stack;
|
|
11518
|
+
state.traverse(func.node.body);
|
|
11519
|
+
}
|
|
11520
|
+
finally {
|
|
11521
|
+
state.pre = pre;
|
|
11522
|
+
state.post = post;
|
|
11523
|
+
state.stack = stack;
|
|
11524
|
+
}
|
|
11333
11525
|
return safeArgs;
|
|
11334
11526
|
}
|
|
11335
11527
|
function canInline(state, func, args) {
|
|
@@ -11434,9 +11626,6 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
11434
11626
|
state.pre = (node) => {
|
|
11435
11627
|
if (failed)
|
|
11436
11628
|
return [];
|
|
11437
|
-
node.start = call.start;
|
|
11438
|
-
node.end = call.end;
|
|
11439
|
-
node.loc = call.loc;
|
|
11440
11629
|
if (replacements.has(node))
|
|
11441
11630
|
return false;
|
|
11442
11631
|
const result = pre(node, state);
|
|
@@ -11451,6 +11640,7 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
11451
11640
|
if (params[paramName] >= 0)
|
|
11452
11641
|
return null;
|
|
11453
11642
|
const name = renameVariable(state, locals, paramName) || paramName;
|
|
11643
|
+
locals.map[name] = true;
|
|
11454
11644
|
return {
|
|
11455
11645
|
type: "VariableDeclarator",
|
|
11456
11646
|
id: { type: "Identifier", name },
|
|
@@ -11469,31 +11659,49 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
11469
11659
|
}
|
|
11470
11660
|
return result;
|
|
11471
11661
|
};
|
|
11662
|
+
const fixId = (node) => {
|
|
11663
|
+
if (state.inType)
|
|
11664
|
+
return null;
|
|
11665
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(params, node.name)) {
|
|
11666
|
+
const ix = params[node.name];
|
|
11667
|
+
if (ix >= 0) {
|
|
11668
|
+
const replacement = { ...call.arguments[ix] };
|
|
11669
|
+
replacements.add(replacement);
|
|
11670
|
+
return replacement;
|
|
11671
|
+
}
|
|
11672
|
+
return null;
|
|
11673
|
+
}
|
|
11674
|
+
const replacement = fixNodeScope(state, node, func.stack);
|
|
11675
|
+
if (!replacement) {
|
|
11676
|
+
failed = true;
|
|
11677
|
+
inlineDiagnostic(state, func, call, `Failed to resolve '${node.name}'`);
|
|
11678
|
+
}
|
|
11679
|
+
return replacement;
|
|
11680
|
+
};
|
|
11472
11681
|
state.post = (node) => {
|
|
11473
11682
|
if (failed)
|
|
11474
11683
|
return post(node, state);
|
|
11475
11684
|
let replacement = null;
|
|
11476
11685
|
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;
|
|
11686
|
+
case "AssignmentExpression":
|
|
11687
|
+
if (node.left.type === "Identifier") {
|
|
11688
|
+
const rep = fixId(node.left);
|
|
11689
|
+
if (rep) {
|
|
11690
|
+
node.left = rep;
|
|
11486
11691
|
}
|
|
11487
|
-
break;
|
|
11488
11692
|
}
|
|
11489
|
-
|
|
11490
|
-
|
|
11491
|
-
|
|
11492
|
-
|
|
11493
|
-
|
|
11693
|
+
break;
|
|
11694
|
+
case "UpdateExpression":
|
|
11695
|
+
if (node.argument.type === "Identifier") {
|
|
11696
|
+
const rep = fixId(node.argument);
|
|
11697
|
+
if (rep) {
|
|
11698
|
+
node.argument = rep;
|
|
11699
|
+
}
|
|
11494
11700
|
}
|
|
11495
11701
|
break;
|
|
11496
|
-
|
|
11702
|
+
case "Identifier":
|
|
11703
|
+
replacement = fixId(node);
|
|
11704
|
+
break;
|
|
11497
11705
|
}
|
|
11498
11706
|
const ret = post(replacement || node, state);
|
|
11499
11707
|
return ret === false || ret ? ret : replacement;
|
|
@@ -11662,7 +11870,7 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
11662
11870
|
}
|
|
11663
11871
|
}
|
|
11664
11872
|
}
|
|
11665
|
-
const body =
|
|
11873
|
+
const body = cloneDeep(func.node.body);
|
|
11666
11874
|
const safeArgs = getArgSafety(state, func, call.arguments, false);
|
|
11667
11875
|
const params = Object.fromEntries(func.node.params.map((param, i) => {
|
|
11668
11876
|
const argnum = safeArgs === true || (safeArgs !== false && safeArgs[i] !== null)
|
|
@@ -11711,18 +11919,19 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
11711
11919
|
--block.body.length;
|
|
11712
11920
|
}
|
|
11713
11921
|
}
|
|
11922
|
+
withLocDeep(body, context, context, true);
|
|
11714
11923
|
return body;
|
|
11715
11924
|
}
|
|
11716
11925
|
function inlineFunction(state, func, call, context) {
|
|
11717
11926
|
if (context) {
|
|
11718
11927
|
return inlineWithArgs(state, func, call, context);
|
|
11719
11928
|
}
|
|
11720
|
-
const retArg =
|
|
11929
|
+
const retArg = cloneDeep(func.node.body.body[0].argument);
|
|
11721
11930
|
const params = Object.fromEntries(func.node.params.map((param, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(param), i]));
|
|
11722
11931
|
const map = fixupLocalsMap(state);
|
|
11723
11932
|
const ret = processInlineBody(state, func, call, retArg, params);
|
|
11724
11933
|
state.localsStack[state.localsStack.length - 1].map = map;
|
|
11725
|
-
return ret;
|
|
11934
|
+
return ret && withLocDeep(ret, call, call, true);
|
|
11726
11935
|
}
|
|
11727
11936
|
function applyTypeIfNeeded(node) {
|
|
11728
11937
|
if ("enumType" in node && node.enumType) {
|
|
@@ -11827,6 +12036,121 @@ function fixNodeScope(state, lookupNode, nodeStack) {
|
|
|
11827
12036
|
return null;
|
|
11828
12037
|
}
|
|
11829
12038
|
|
|
12039
|
+
;// CONCATENATED MODULE: ./src/pragma-checker.ts
|
|
12040
|
+
|
|
12041
|
+
|
|
12042
|
+
|
|
12043
|
+
function pragmaChecker(state, ast, diagnostics) {
|
|
12044
|
+
const comments = ast.comments;
|
|
12045
|
+
if (!comments)
|
|
12046
|
+
return;
|
|
12047
|
+
diagnostics = diagnostics
|
|
12048
|
+
?.slice()
|
|
12049
|
+
.sort((d1, d2) => d1.loc.start < d2.loc.start ? -1 : d1.loc.start == d2.loc.start ? 0 : 1);
|
|
12050
|
+
let diagIndex = 0;
|
|
12051
|
+
let index = -1;
|
|
12052
|
+
let comment;
|
|
12053
|
+
let matchers;
|
|
12054
|
+
const next = () => {
|
|
12055
|
+
while (++index < comments.length) {
|
|
12056
|
+
comment = comments[index];
|
|
12057
|
+
let match = comment.value.match(/^\s*@(match|expect)\s+(.+)/);
|
|
12058
|
+
if (!match)
|
|
12059
|
+
continue;
|
|
12060
|
+
const kind = match[1];
|
|
12061
|
+
let str = match[2];
|
|
12062
|
+
matchers = [];
|
|
12063
|
+
while ((match = str.match(/^([/%&#@"])(.+?(?<!\\)(?:\\{2})*)\1(\s+|$)/))) {
|
|
12064
|
+
matchers.push({ kind, quote: match[1], needle: match[2] });
|
|
12065
|
+
str = str.substring(match[0].length);
|
|
12066
|
+
if (!str.length)
|
|
12067
|
+
break;
|
|
12068
|
+
}
|
|
12069
|
+
if (!str.length)
|
|
12070
|
+
break;
|
|
12071
|
+
if (!matchers.length) {
|
|
12072
|
+
match = str.match(/^(\S+)\s+$/);
|
|
12073
|
+
if (match) {
|
|
12074
|
+
matchers.push({ kind, quote: '"', needle: match[1] });
|
|
12075
|
+
break;
|
|
12076
|
+
}
|
|
12077
|
+
}
|
|
12078
|
+
diagnostic(state, comment.loc, `Build pragma '${comment.value}' is invalid`, "ERROR");
|
|
12079
|
+
}
|
|
12080
|
+
};
|
|
12081
|
+
const matcher = (quote, needle, haystack) => {
|
|
12082
|
+
if (quote == '"') {
|
|
12083
|
+
return haystack.includes(needle);
|
|
12084
|
+
}
|
|
12085
|
+
const re = new RegExp(needle.replace(/@(\d+)/g, "(pre_)?$1(_\\d+)?"));
|
|
12086
|
+
return re.test(haystack);
|
|
12087
|
+
};
|
|
12088
|
+
next();
|
|
12089
|
+
traverseAst(ast, (node) => {
|
|
12090
|
+
if (index >= comments.length)
|
|
12091
|
+
return false;
|
|
12092
|
+
if (node.start && node.start >= (comment.end || Infinity)) {
|
|
12093
|
+
const { kind, quote, needle } = matchers.shift();
|
|
12094
|
+
if (kind === "match") {
|
|
12095
|
+
const haystack = (0,external_api_cjs_namespaceObject.formatAst)(node).replace(/([\r\n]|\s)+/g, " ");
|
|
12096
|
+
if (!matcher(quote, needle, haystack)) {
|
|
12097
|
+
matcher(quote, needle, haystack);
|
|
12098
|
+
diagnostic(state, comment.loc, `Didn't find '${needle}' in '${haystack}'`, "ERROR");
|
|
12099
|
+
}
|
|
12100
|
+
}
|
|
12101
|
+
else if (kind === "expect") {
|
|
12102
|
+
const locCmp = (a, b) => {
|
|
12103
|
+
if (!b)
|
|
12104
|
+
return -1;
|
|
12105
|
+
if (a.start.line < b.start.line)
|
|
12106
|
+
return -1;
|
|
12107
|
+
if (a.start.line === b.start.line &&
|
|
12108
|
+
a.start.column < b.start.column) {
|
|
12109
|
+
return -1;
|
|
12110
|
+
}
|
|
12111
|
+
if (a.end.line > b.end.line)
|
|
12112
|
+
return 1;
|
|
12113
|
+
if (a.end.line === b.end.line && a.end.column >= b.end.column) {
|
|
12114
|
+
return 1;
|
|
12115
|
+
}
|
|
12116
|
+
return 0;
|
|
12117
|
+
};
|
|
12118
|
+
let found = false;
|
|
12119
|
+
if (diagnostics) {
|
|
12120
|
+
while (true) {
|
|
12121
|
+
if (diagIndex >= diagnostics.length) {
|
|
12122
|
+
diagnostics = null;
|
|
12123
|
+
break;
|
|
12124
|
+
}
|
|
12125
|
+
const diag = diagnostics[diagIndex];
|
|
12126
|
+
const cmp = locCmp(diag.loc, node.loc);
|
|
12127
|
+
if (cmp > 0) {
|
|
12128
|
+
break;
|
|
12129
|
+
}
|
|
12130
|
+
diagIndex++;
|
|
12131
|
+
if (cmp < 0)
|
|
12132
|
+
continue;
|
|
12133
|
+
if (matcher(quote, needle, diag.message)) {
|
|
12134
|
+
found = true;
|
|
12135
|
+
diag.type = "INFO";
|
|
12136
|
+
}
|
|
12137
|
+
}
|
|
12138
|
+
}
|
|
12139
|
+
if (!found) {
|
|
12140
|
+
diagnostic(state, comment.loc, `Missing error message '${needle}`, "ERROR");
|
|
12141
|
+
}
|
|
12142
|
+
}
|
|
12143
|
+
if (matchers.length) {
|
|
12144
|
+
// if we're checking a series of nodes, we need
|
|
12145
|
+
// to skip over this one.
|
|
12146
|
+
return false;
|
|
12147
|
+
}
|
|
12148
|
+
next();
|
|
12149
|
+
}
|
|
12150
|
+
return null;
|
|
12151
|
+
});
|
|
12152
|
+
}
|
|
12153
|
+
|
|
11830
12154
|
;// CONCATENATED MODULE: ./src/control-flow.ts
|
|
11831
12155
|
|
|
11832
12156
|
|
|
@@ -12347,6 +12671,7 @@ var priorityqueuejs = __webpack_require__(2789);
|
|
|
12347
12671
|
|
|
12348
12672
|
|
|
12349
12673
|
|
|
12674
|
+
|
|
12350
12675
|
/**
|
|
12351
12676
|
* This implements a pseudo Partial Redundancy Elimination
|
|
12352
12677
|
* pass. It isn't quite like traditional PRE because we're
|
|
@@ -12416,7 +12741,7 @@ function sizeBasedPRE(state, func) {
|
|
|
12416
12741
|
return;
|
|
12417
12742
|
}
|
|
12418
12743
|
const { graph: head, identifiers } = buildPREGraph(state, func);
|
|
12419
|
-
const candidates = computeAttributes(head);
|
|
12744
|
+
const candidates = computeAttributes(state, head);
|
|
12420
12745
|
if (candidates) {
|
|
12421
12746
|
if (logging) {
|
|
12422
12747
|
console.log(`Found ${candidates.size} candidates in ${func.fullName}`);
|
|
@@ -12436,8 +12761,10 @@ function sizeBasedPRE(state, func) {
|
|
|
12436
12761
|
let i = 0;
|
|
12437
12762
|
do {
|
|
12438
12763
|
name = `pre_${declName(decl)}${i ? "_" + i : ""}`;
|
|
12439
|
-
if (!identifiers.has(name))
|
|
12764
|
+
if (!identifiers.has(name)) {
|
|
12765
|
+
identifiers.add(name);
|
|
12440
12766
|
break;
|
|
12767
|
+
}
|
|
12441
12768
|
i++;
|
|
12442
12769
|
} while (true);
|
|
12443
12770
|
declMap.set(decl, name);
|
|
@@ -12528,7 +12855,7 @@ function buildPREGraph(state, func) {
|
|
|
12528
12855
|
case "ParenthesizedExpression":
|
|
12529
12856
|
break;
|
|
12530
12857
|
case "Literal":
|
|
12531
|
-
if (
|
|
12858
|
+
if (refCost(node) > LocalRefCost) {
|
|
12532
12859
|
let decl = literals.get(node.value);
|
|
12533
12860
|
if (!decl) {
|
|
12534
12861
|
decl = node;
|
|
@@ -12612,10 +12939,18 @@ function buildPREGraph(state, func) {
|
|
|
12612
12939
|
}
|
|
12613
12940
|
break;
|
|
12614
12941
|
}
|
|
12615
|
-
case "NewExpression":
|
|
12616
|
-
|
|
12942
|
+
case "NewExpression": {
|
|
12943
|
+
const [, results] = state.lookup(node.callee);
|
|
12944
|
+
const callees = results ? findCalleesForNew(results) : null;
|
|
12945
|
+
liveDef(null, stmt);
|
|
12946
|
+
return { type: "mod", node, mayThrow, callees };
|
|
12947
|
+
}
|
|
12948
|
+
case "CallExpression": {
|
|
12617
12949
|
liveDef(null, stmt);
|
|
12618
|
-
|
|
12950
|
+
const [, results] = state.lookup(node.callee);
|
|
12951
|
+
const callees = results ? findCallees(results) : null;
|
|
12952
|
+
return { type: "mod", node, mayThrow, callees };
|
|
12953
|
+
}
|
|
12619
12954
|
default:
|
|
12620
12955
|
if (!isExpression(node))
|
|
12621
12956
|
break;
|
|
@@ -12631,12 +12966,6 @@ function buildPREGraph(state, func) {
|
|
|
12631
12966
|
function anticipatedDecls() {
|
|
12632
12967
|
return new Map();
|
|
12633
12968
|
}
|
|
12634
|
-
function cloneSet(ae) {
|
|
12635
|
-
return new Set(ae);
|
|
12636
|
-
}
|
|
12637
|
-
function mergeSet(a, b) {
|
|
12638
|
-
b.forEach((event) => a.add(event));
|
|
12639
|
-
}
|
|
12640
12969
|
function equalSet(a, b) {
|
|
12641
12970
|
if (a.size != b.size)
|
|
12642
12971
|
return false;
|
|
@@ -12715,6 +13044,7 @@ function refCost(node) {
|
|
|
12715
13044
|
switch (typeof node.value) {
|
|
12716
13045
|
case "string":
|
|
12717
13046
|
return 5;
|
|
13047
|
+
case "bigint":
|
|
12718
13048
|
case "number":
|
|
12719
13049
|
return 5;
|
|
12720
13050
|
case "boolean":
|
|
@@ -12776,7 +13106,7 @@ function candidateCost(candState) {
|
|
|
12776
13106
|
cost += defCost(candState.node) * boundarySize;
|
|
12777
13107
|
return cost;
|
|
12778
13108
|
}
|
|
12779
|
-
function computeAttributes(head) {
|
|
13109
|
+
function computeAttributes(state, head) {
|
|
12780
13110
|
const order = getPostOrder(head);
|
|
12781
13111
|
order.forEach((block, i) => {
|
|
12782
13112
|
block.order = i;
|
|
@@ -12885,7 +13215,9 @@ function computeAttributes(head) {
|
|
|
12885
13215
|
curState.forEach((candidates, decl) => {
|
|
12886
13216
|
if (decl.type === "VariableDeclarator" &&
|
|
12887
13217
|
decl.node.kind === "var" &&
|
|
12888
|
-
candidates.live
|
|
13218
|
+
candidates.live &&
|
|
13219
|
+
(!event.callees ||
|
|
13220
|
+
event.callees.some((callee) => functionMayModify(state, callee, decl)))) {
|
|
12889
13221
|
candidates.ant.add(getMod(event, decl, candidates.node));
|
|
12890
13222
|
candidates.live = false;
|
|
12891
13223
|
}
|
|
@@ -13074,20 +13406,26 @@ function applyReplacements(func, nodeMap, declMap) {
|
|
|
13074
13406
|
stmtStack.pop();
|
|
13075
13407
|
const events = nodeMap.get(node);
|
|
13076
13408
|
if (events) {
|
|
13077
|
-
|
|
13078
|
-
if (
|
|
13409
|
+
const ret = events.reduce((ret, event) => {
|
|
13410
|
+
if (event.type === "ref") {
|
|
13411
|
+
if (ret) {
|
|
13412
|
+
throw new Error(`ref found when there was already a replacement for this node`);
|
|
13413
|
+
}
|
|
13079
13414
|
if (node.type !== "Identifier" &&
|
|
13080
13415
|
node.type !== "MemberExpression" &&
|
|
13081
13416
|
node.type !== "Literal") {
|
|
13082
13417
|
throw new Error(`Ref found, but wrong type of node: ${node.type}`);
|
|
13083
13418
|
}
|
|
13084
|
-
const name = declMap.get(
|
|
13419
|
+
const name = declMap.get(event.decl);
|
|
13085
13420
|
if (!name) {
|
|
13086
13421
|
throw new Error(`No replacement found for "${(0,external_api_cjs_namespaceObject.formatAst)(node)}"`);
|
|
13087
13422
|
}
|
|
13088
13423
|
return ident(name, node);
|
|
13089
13424
|
}
|
|
13090
|
-
|
|
13425
|
+
if (event.type === "def") {
|
|
13426
|
+
if (ret) {
|
|
13427
|
+
throw new Error(`def found when there was already a replacement for this node`);
|
|
13428
|
+
}
|
|
13091
13429
|
if (node.type !== "AssignmentExpression" &&
|
|
13092
13430
|
node.type !== "UpdateExpression") {
|
|
13093
13431
|
throw new Error(`Def found, but wrong type of node: ${node.type}`);
|
|
@@ -13095,7 +13433,7 @@ function applyReplacements(func, nodeMap, declMap) {
|
|
|
13095
13433
|
const target = node.type === "AssignmentExpression"
|
|
13096
13434
|
? node.left
|
|
13097
13435
|
: node.argument;
|
|
13098
|
-
const name = declMap.get(
|
|
13436
|
+
const name = declMap.get(event.decl);
|
|
13099
13437
|
if (!name) {
|
|
13100
13438
|
throw new Error(`No replacement found for "${(0,external_api_cjs_namespaceObject.formatAst)(target)}"`);
|
|
13101
13439
|
}
|
|
@@ -13114,20 +13452,24 @@ function applyReplacements(func, nodeMap, declMap) {
|
|
|
13114
13452
|
}
|
|
13115
13453
|
return withLoc({ type: "SequenceExpression", expressions: [node, assign] }, node);
|
|
13116
13454
|
}
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13121
|
-
|
|
13122
|
-
|
|
13123
|
-
|
|
13455
|
+
if (event.type === "mod") {
|
|
13456
|
+
if (!event.decl) {
|
|
13457
|
+
throw new Error(`Unexpected null decl on mod event`);
|
|
13458
|
+
}
|
|
13459
|
+
let pending = pendingMap.get(stmt);
|
|
13460
|
+
if (!pending) {
|
|
13461
|
+
pendingMap.set(stmt, (pending = new Set()));
|
|
13462
|
+
}
|
|
13463
|
+
pending.add(event);
|
|
13124
13464
|
}
|
|
13125
|
-
|
|
13126
|
-
|
|
13127
|
-
pendingMap.set(stmt, (pending = new Set()));
|
|
13465
|
+
else {
|
|
13466
|
+
throw new Error(`Unexpected ${event.type} found`);
|
|
13128
13467
|
}
|
|
13129
|
-
|
|
13130
|
-
});
|
|
13468
|
+
return ret;
|
|
13469
|
+
}, null);
|
|
13470
|
+
if (ret) {
|
|
13471
|
+
return ret;
|
|
13472
|
+
}
|
|
13131
13473
|
}
|
|
13132
13474
|
const pending = pendingMap.get(node);
|
|
13133
13475
|
if (node.type === "SequenceExpression") {
|
|
@@ -13201,10 +13543,152 @@ function applyReplacements(func, nodeMap, declMap) {
|
|
|
13201
13543
|
});
|
|
13202
13544
|
}
|
|
13203
13545
|
|
|
13204
|
-
;// CONCATENATED MODULE: ./src/
|
|
13546
|
+
;// CONCATENATED MODULE: ./src/unused-exprs.ts
|
|
13205
13547
|
|
|
13206
|
-
|
|
13207
|
-
|
|
13548
|
+
|
|
13549
|
+
|
|
13550
|
+
function cleanupUnusedVars(state, node) {
|
|
13551
|
+
const [parent] = state.stack.slice(-1);
|
|
13552
|
+
if (parent.node !== node) {
|
|
13553
|
+
return;
|
|
13554
|
+
}
|
|
13555
|
+
if (parent.type != "BlockStatement") {
|
|
13556
|
+
throw new Error(`Unexpected parent type '${parent.type}' for local declaration`);
|
|
13557
|
+
}
|
|
13558
|
+
if (parent.decls) {
|
|
13559
|
+
let toRemove = null;
|
|
13560
|
+
Object.values(parent.decls).forEach((decls) => {
|
|
13561
|
+
if (decls.length === 1 &&
|
|
13562
|
+
decls[0].type === "VariableDeclarator" &&
|
|
13563
|
+
!decls[0].used) {
|
|
13564
|
+
if (!toRemove)
|
|
13565
|
+
toRemove = {};
|
|
13566
|
+
toRemove[decls[0].name] = decls[0];
|
|
13567
|
+
}
|
|
13568
|
+
});
|
|
13569
|
+
if (toRemove) {
|
|
13570
|
+
const varDeclarations = new Map();
|
|
13571
|
+
traverseAst(node, null, (node) => {
|
|
13572
|
+
switch (node.type) {
|
|
13573
|
+
case "VariableDeclaration": {
|
|
13574
|
+
node.declarations.forEach((decl, i) => {
|
|
13575
|
+
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(decl.id);
|
|
13576
|
+
if (hasProperty(toRemove, name)) {
|
|
13577
|
+
const indices = varDeclarations.get(node);
|
|
13578
|
+
if (indices) {
|
|
13579
|
+
indices.push(i);
|
|
13580
|
+
}
|
|
13581
|
+
else {
|
|
13582
|
+
varDeclarations.set(node, [i]);
|
|
13583
|
+
}
|
|
13584
|
+
}
|
|
13585
|
+
});
|
|
13586
|
+
break;
|
|
13587
|
+
}
|
|
13588
|
+
case "ExpressionStatement":
|
|
13589
|
+
if (node.expression.type === "AssignmentExpression") {
|
|
13590
|
+
if (node.expression.left.type === "Identifier" &&
|
|
13591
|
+
hasProperty(toRemove, node.expression.left.name)) {
|
|
13592
|
+
return unused(node.expression.right);
|
|
13593
|
+
}
|
|
13594
|
+
}
|
|
13595
|
+
else if (node.expression.type === "UpdateExpression" &&
|
|
13596
|
+
node.expression.argument.type === "Identifier" &&
|
|
13597
|
+
hasProperty(toRemove, node.expression.argument.name)) {
|
|
13598
|
+
return false;
|
|
13599
|
+
}
|
|
13600
|
+
break;
|
|
13601
|
+
case "SequenceExpression": {
|
|
13602
|
+
for (let i = node.expressions.length; i--;) {
|
|
13603
|
+
const expr = node.expressions[i];
|
|
13604
|
+
if (expr.type === "AssignmentExpression") {
|
|
13605
|
+
if (expr.left.type === "Identifier" &&
|
|
13606
|
+
hasProperty(toRemove, expr.left.name)) {
|
|
13607
|
+
const rep = unused(expr.right);
|
|
13608
|
+
if (!rep.length) {
|
|
13609
|
+
node.expressions.splice(i, 1);
|
|
13610
|
+
}
|
|
13611
|
+
else {
|
|
13612
|
+
// Sequence expressions can only be assignments
|
|
13613
|
+
// or update expressions. Even calls aren't allowed
|
|
13614
|
+
toRemove[expr.left.name] = null;
|
|
13615
|
+
expr.operator = "=";
|
|
13616
|
+
}
|
|
13617
|
+
}
|
|
13618
|
+
}
|
|
13619
|
+
else if (expr.type === "UpdateExpression" &&
|
|
13620
|
+
expr.argument.type === "Identifier" &&
|
|
13621
|
+
hasProperty(toRemove, expr.argument.name)) {
|
|
13622
|
+
node.expressions.splice(i, 1);
|
|
13623
|
+
}
|
|
13624
|
+
}
|
|
13625
|
+
break;
|
|
13626
|
+
}
|
|
13627
|
+
}
|
|
13628
|
+
return null;
|
|
13629
|
+
});
|
|
13630
|
+
varDeclarations.forEach((indices, decl) => {
|
|
13631
|
+
let index = -1;
|
|
13632
|
+
for (let ii = indices.length, j = decl.declarations.length; ii--;) {
|
|
13633
|
+
const i = indices[ii];
|
|
13634
|
+
const vdecl = decl.declarations[i];
|
|
13635
|
+
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(vdecl.id);
|
|
13636
|
+
if (hasProperty(toRemove, name)) {
|
|
13637
|
+
const rep = vdecl.init ? unused(vdecl.init) : [];
|
|
13638
|
+
if (rep.length) {
|
|
13639
|
+
if (parent.node.type === "ForStatement") {
|
|
13640
|
+
// declarations whose inits have side effects
|
|
13641
|
+
// can't be deleted from for statements.
|
|
13642
|
+
continue;
|
|
13643
|
+
}
|
|
13644
|
+
if (index < 0) {
|
|
13645
|
+
index = parent.node.body.findIndex((s) => s === decl);
|
|
13646
|
+
if (index < 0) {
|
|
13647
|
+
throw new Error(`Failed to find variable declaration for ${(0,external_api_cjs_namespaceObject.variableDeclarationName)(vdecl.id)}`);
|
|
13648
|
+
}
|
|
13649
|
+
}
|
|
13650
|
+
if (j > i + 1) {
|
|
13651
|
+
const tail = {
|
|
13652
|
+
...decl,
|
|
13653
|
+
declarations: decl.declarations.slice(i + 1, j),
|
|
13654
|
+
};
|
|
13655
|
+
if (decl.loc && vdecl.loc) {
|
|
13656
|
+
tail.loc = { ...decl.loc, start: vdecl.loc.end };
|
|
13657
|
+
tail.start = vdecl.end;
|
|
13658
|
+
}
|
|
13659
|
+
rep.push(tail);
|
|
13660
|
+
}
|
|
13661
|
+
if (decl.loc && vdecl.loc) {
|
|
13662
|
+
decl.loc = { ...decl.loc, end: vdecl.loc.start };
|
|
13663
|
+
decl.end = vdecl.start;
|
|
13664
|
+
}
|
|
13665
|
+
decl.declarations.splice(i);
|
|
13666
|
+
parent.node.body.splice(index + 1, 0, ...rep);
|
|
13667
|
+
j = i;
|
|
13668
|
+
continue;
|
|
13669
|
+
}
|
|
13670
|
+
if (toRemove[name]) {
|
|
13671
|
+
j--;
|
|
13672
|
+
decl.declarations.splice(i, 1);
|
|
13673
|
+
if (i === j && decl.loc && vdecl.loc) {
|
|
13674
|
+
decl.loc = { ...decl.loc, end: vdecl.loc.start };
|
|
13675
|
+
decl.end = vdecl.start;
|
|
13676
|
+
}
|
|
13677
|
+
}
|
|
13678
|
+
else {
|
|
13679
|
+
delete vdecl.init;
|
|
13680
|
+
}
|
|
13681
|
+
}
|
|
13682
|
+
}
|
|
13683
|
+
});
|
|
13684
|
+
}
|
|
13685
|
+
}
|
|
13686
|
+
}
|
|
13687
|
+
|
|
13688
|
+
;// CONCATENATED MODULE: ./src/visitor.ts
|
|
13689
|
+
|
|
13690
|
+
function visitReferences(state, ast, name, defn, callback) {
|
|
13691
|
+
const checkResults = ([name, results], node) => {
|
|
13208
13692
|
if (name && results) {
|
|
13209
13693
|
if (!defn || (0,external_api_cjs_namespaceObject.sameLookupResult)(results, defn)) {
|
|
13210
13694
|
if (callback(node, results, false) === false) {
|
|
@@ -13265,14 +13749,16 @@ function visitReferences(state, ast, name, defn, callback) {
|
|
|
13265
13749
|
return checkResults(state.lookup(node), node);
|
|
13266
13750
|
}
|
|
13267
13751
|
break;
|
|
13268
|
-
case "MemberExpression":
|
|
13269
|
-
|
|
13270
|
-
|
|
13752
|
+
case "MemberExpression": {
|
|
13753
|
+
const property = (0,external_api_cjs_namespaceObject.isLookupCandidate)(node);
|
|
13754
|
+
if (property) {
|
|
13755
|
+
if (!name || property.name === name) {
|
|
13271
13756
|
return checkResults(state.lookup(node), node) || ["object"];
|
|
13272
13757
|
}
|
|
13273
13758
|
return ["object"];
|
|
13274
13759
|
}
|
|
13275
13760
|
break;
|
|
13761
|
+
}
|
|
13276
13762
|
case "MethodDefinition": {
|
|
13277
13763
|
if (!state.inType) {
|
|
13278
13764
|
throw new Error("Method definition outside of type!");
|
|
@@ -13281,7 +13767,6 @@ function visitReferences(state, ast, name, defn, callback) {
|
|
|
13281
13767
|
node.params.forEach((param) => {
|
|
13282
13768
|
if (param.type == "BinaryExpression") {
|
|
13283
13769
|
state.traverse(param.right);
|
|
13284
|
-
state.inType = true;
|
|
13285
13770
|
}
|
|
13286
13771
|
});
|
|
13287
13772
|
}
|
|
@@ -13304,6 +13789,9 @@ function visitReferences(state, ast, name, defn, callback) {
|
|
|
13304
13789
|
|
|
13305
13790
|
|
|
13306
13791
|
|
|
13792
|
+
|
|
13793
|
+
|
|
13794
|
+
|
|
13307
13795
|
function collectClassInfo(state) {
|
|
13308
13796
|
const toybox = state.stack[0].decls["Toybox"][0];
|
|
13309
13797
|
const lang = toybox.decls["Lang"][0];
|
|
@@ -13363,8 +13851,7 @@ function collectClassInfo(state) {
|
|
|
13363
13851
|
c.decls &&
|
|
13364
13852
|
Object.values(c.decls).forEach((funcs) => {
|
|
13365
13853
|
funcs.forEach((f) => {
|
|
13366
|
-
if (
|
|
13367
|
-
f.type === "FunctionDeclaration" &&
|
|
13854
|
+
if (f.type === "FunctionDeclaration" &&
|
|
13368
13855
|
(0,external_api_cjs_namespaceObject.hasProperty)(cls.decls, f.name)) {
|
|
13369
13856
|
f.node.hasOverride = true;
|
|
13370
13857
|
}
|
|
@@ -13377,6 +13864,15 @@ function collectClassInfo(state) {
|
|
|
13377
13864
|
state.allClasses.forEach((elm) => {
|
|
13378
13865
|
if (elm.superClass)
|
|
13379
13866
|
markOverrides(elm, elm.superClass);
|
|
13867
|
+
if (elm.hasInvoke && elm.decls) {
|
|
13868
|
+
Object.values(elm.decls).forEach((funcs) => {
|
|
13869
|
+
funcs.forEach((f) => {
|
|
13870
|
+
if (f.type === "FunctionDeclaration" && !f.isStatic) {
|
|
13871
|
+
(0,external_api_cjs_namespaceObject.markInvokeClassMethod)(f);
|
|
13872
|
+
}
|
|
13873
|
+
});
|
|
13874
|
+
});
|
|
13875
|
+
}
|
|
13380
13876
|
});
|
|
13381
13877
|
}
|
|
13382
13878
|
function getFileSources(fnMap) {
|
|
@@ -13415,7 +13911,7 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
13415
13911
|
const preState = {
|
|
13416
13912
|
fnMap,
|
|
13417
13913
|
config,
|
|
13418
|
-
allFunctions:
|
|
13914
|
+
allFunctions: {},
|
|
13419
13915
|
allClasses: [],
|
|
13420
13916
|
shouldExclude(node) {
|
|
13421
13917
|
if ("attrs" in node &&
|
|
@@ -13445,11 +13941,6 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
13445
13941
|
pre(node, state) {
|
|
13446
13942
|
switch (node.type) {
|
|
13447
13943
|
case "FunctionDeclaration":
|
|
13448
|
-
if (markApi) {
|
|
13449
|
-
node.body = null;
|
|
13450
|
-
break;
|
|
13451
|
-
}
|
|
13452
|
-
// falls through
|
|
13453
13944
|
case "ModuleDeclaration":
|
|
13454
13945
|
case "ClassDeclaration": {
|
|
13455
13946
|
const [scope] = state.stack.slice(-1);
|
|
@@ -13460,7 +13951,18 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
13460
13951
|
(scope.node.attrs &&
|
|
13461
13952
|
scope.node.attrs.access &&
|
|
13462
13953
|
scope.node.attrs.access.includes("static"));
|
|
13463
|
-
|
|
13954
|
+
if (markApi) {
|
|
13955
|
+
node.body = null;
|
|
13956
|
+
scope.info = (0,external_api_cjs_namespaceObject.getApiFunctionInfo)(scope);
|
|
13957
|
+
delete scope.stack;
|
|
13958
|
+
}
|
|
13959
|
+
const allFuncs = state.allFunctions;
|
|
13960
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(allFuncs, scope.name)) {
|
|
13961
|
+
allFuncs[scope.name] = [scope];
|
|
13962
|
+
}
|
|
13963
|
+
else {
|
|
13964
|
+
allFuncs[scope.name].push(scope);
|
|
13965
|
+
}
|
|
13464
13966
|
}
|
|
13465
13967
|
else if (scope.type === "ClassDeclaration") {
|
|
13466
13968
|
state.allClasses.push(scope);
|
|
@@ -13485,7 +13987,7 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
13485
13987
|
value.hasTests = hasTests;
|
|
13486
13988
|
});
|
|
13487
13989
|
delete state.shouldExclude;
|
|
13488
|
-
delete state.
|
|
13990
|
+
delete state.pre;
|
|
13489
13991
|
collectClassInfo(state);
|
|
13490
13992
|
const diagnosticType = config?.checkInvalidSymbols !== "OFF"
|
|
13491
13993
|
? config?.checkInvalidSymbols || "WARNING"
|
|
@@ -13508,6 +14010,8 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
13508
14010
|
});
|
|
13509
14011
|
});
|
|
13510
14012
|
}
|
|
14013
|
+
state.exposed = state.nextExposed;
|
|
14014
|
+
state.nextExposed = {};
|
|
13511
14015
|
return state;
|
|
13512
14016
|
}
|
|
13513
14017
|
function compareLiteralLike(a, b) {
|
|
@@ -13553,15 +14057,12 @@ function getLiteralNode(node) {
|
|
|
13553
14057
|
if (node.argument.type != "Literal")
|
|
13554
14058
|
return null;
|
|
13555
14059
|
switch (node.operator) {
|
|
13556
|
-
case "-":
|
|
13557
|
-
|
|
13558
|
-
|
|
13559
|
-
|
|
13560
|
-
value: -node.argument.value,
|
|
13561
|
-
raw: "-" + node.argument.value,
|
|
13562
|
-
enumType: node.enumType,
|
|
13563
|
-
};
|
|
14060
|
+
case "-": {
|
|
14061
|
+
const [arg, type] = getNodeValue(node.argument);
|
|
14062
|
+
if (type === "Number" || type === "Long") {
|
|
14063
|
+
return replacementLiteral(arg, -arg.value, type);
|
|
13564
14064
|
}
|
|
14065
|
+
}
|
|
13565
14066
|
}
|
|
13566
14067
|
}
|
|
13567
14068
|
return null;
|
|
@@ -13580,29 +14081,29 @@ function getNodeValue(node) {
|
|
|
13580
14081
|
if (node.type != "Literal") {
|
|
13581
14082
|
return [null, null];
|
|
13582
14083
|
}
|
|
13583
|
-
|
|
14084
|
+
if (node.value === null) {
|
|
14085
|
+
return [node, "Null"];
|
|
14086
|
+
}
|
|
14087
|
+
const type = typeof node.value;
|
|
13584
14088
|
if (type === "number") {
|
|
13585
|
-
const match =
|
|
14089
|
+
const match = prettier_plugin_monkeyc_namespaceObject.LiteralIntegerRe.exec(node.raw);
|
|
13586
14090
|
if (match) {
|
|
13587
|
-
|
|
13588
|
-
|
|
13589
|
-
|
|
13590
|
-
type = "Double";
|
|
13591
|
-
}
|
|
13592
|
-
else {
|
|
13593
|
-
type = "Float";
|
|
14091
|
+
return match[2] === "l" || match[2] === "L"
|
|
14092
|
+
? [node, "Long"]
|
|
14093
|
+
: [node, "Number"];
|
|
13594
14094
|
}
|
|
14095
|
+
return [node, node.raw.endsWith("d") ? "Double" : "Float"];
|
|
13595
14096
|
}
|
|
13596
|
-
|
|
13597
|
-
|
|
14097
|
+
if (type === "bigint") {
|
|
14098
|
+
return [node, "Long"];
|
|
13598
14099
|
}
|
|
13599
|
-
|
|
13600
|
-
|
|
14100
|
+
if (type === "string") {
|
|
14101
|
+
return [node, "String"];
|
|
13601
14102
|
}
|
|
13602
|
-
|
|
13603
|
-
|
|
14103
|
+
if (type === "boolean") {
|
|
14104
|
+
return [node, "Boolean"];
|
|
13604
14105
|
}
|
|
13605
|
-
|
|
14106
|
+
throw new Error(`Literal has unknown type '${type}'`);
|
|
13606
14107
|
}
|
|
13607
14108
|
function fullTypeName(state, tsp) {
|
|
13608
14109
|
if (typeof tsp.name === "string") {
|
|
@@ -13647,6 +14148,46 @@ function isBooleanExpression(state, node) {
|
|
|
13647
14148
|
}
|
|
13648
14149
|
return false;
|
|
13649
14150
|
}
|
|
14151
|
+
function replacementLiteral(arg, value, type) {
|
|
14152
|
+
if (typeof value === "boolean") {
|
|
14153
|
+
type = "Boolean";
|
|
14154
|
+
}
|
|
14155
|
+
else if (type === "Number") {
|
|
14156
|
+
value = Number(BigInt.asIntN(32, BigInt(value)));
|
|
14157
|
+
}
|
|
14158
|
+
else if (type === "Long") {
|
|
14159
|
+
value = BigInt.asIntN(64, BigInt(value));
|
|
14160
|
+
}
|
|
14161
|
+
return {
|
|
14162
|
+
...arg,
|
|
14163
|
+
value,
|
|
14164
|
+
raw: value.toString() + (type === "Long" ? "l" : ""),
|
|
14165
|
+
};
|
|
14166
|
+
}
|
|
14167
|
+
const operators = {
|
|
14168
|
+
"+": (left, right) => left + right,
|
|
14169
|
+
"-": (left, right) => left - right,
|
|
14170
|
+
"*": (left, right) => left * right,
|
|
14171
|
+
"/": (left, right) => left / right,
|
|
14172
|
+
"%": (left, right) => left % right,
|
|
14173
|
+
"&": (left, right) => left & right,
|
|
14174
|
+
"|": (left, right) => left | right,
|
|
14175
|
+
"^": (left, right) => left ^ right,
|
|
14176
|
+
"<<": (left, right) => left << (right & 127n),
|
|
14177
|
+
">>": (left, right) => left >> (right & 127n),
|
|
14178
|
+
"==": (left, right) =>
|
|
14179
|
+
// two string literals will compare unequal, becuase string
|
|
14180
|
+
// equality is object equality.
|
|
14181
|
+
typeof left === "string" ? false : left === right,
|
|
14182
|
+
"!=": (left, right) => typeof left === "string" ? true : left !== right,
|
|
14183
|
+
"<=": (left, right) => left <= right,
|
|
14184
|
+
">=": (left, right) => left >= right,
|
|
14185
|
+
"<": (left, right) => left < right,
|
|
14186
|
+
">": (left, right) => left > right,
|
|
14187
|
+
as: null,
|
|
14188
|
+
instanceof: null,
|
|
14189
|
+
has: null,
|
|
14190
|
+
};
|
|
13650
14191
|
function optimizeNode(state, node) {
|
|
13651
14192
|
switch (node.type) {
|
|
13652
14193
|
case "UnaryExpression": {
|
|
@@ -13661,29 +14202,17 @@ function optimizeNode(state, node) {
|
|
|
13661
14202
|
break;
|
|
13662
14203
|
case "-":
|
|
13663
14204
|
if (type === "Number" || type === "Long") {
|
|
13664
|
-
return
|
|
13665
|
-
...arg,
|
|
13666
|
-
value: -arg.value,
|
|
13667
|
-
raw: (-arg.value).toString() + (type === "Long" ? "l" : ""),
|
|
13668
|
-
};
|
|
14205
|
+
return replacementLiteral(arg, -arg.value, type);
|
|
13669
14206
|
}
|
|
13670
14207
|
break;
|
|
13671
14208
|
case "!":
|
|
13672
14209
|
case "~":
|
|
13673
14210
|
{
|
|
13674
|
-
let value;
|
|
13675
14211
|
if (type === "Number" || type === "Long") {
|
|
13676
|
-
|
|
14212
|
+
return replacementLiteral(arg, ~BigInt(arg.value), type);
|
|
13677
14213
|
}
|
|
13678
|
-
|
|
13679
|
-
|
|
13680
|
-
}
|
|
13681
|
-
if (value !== undefined) {
|
|
13682
|
-
return {
|
|
13683
|
-
...arg,
|
|
13684
|
-
value,
|
|
13685
|
-
raw: value.toString() + (type === "Long" ? "l" : ""),
|
|
13686
|
-
};
|
|
14214
|
+
if (type === "Boolean" && node.operator == "!") {
|
|
14215
|
+
return replacementLiteral(arg, !arg.value, type);
|
|
13687
14216
|
}
|
|
13688
14217
|
}
|
|
13689
14218
|
break;
|
|
@@ -13691,27 +14220,6 @@ function optimizeNode(state, node) {
|
|
|
13691
14220
|
break;
|
|
13692
14221
|
}
|
|
13693
14222
|
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
14223
|
const op = operators[node.operator];
|
|
13716
14224
|
if (op) {
|
|
13717
14225
|
const [left, left_type] = getNodeValue(node.left);
|
|
@@ -13719,23 +14227,22 @@ function optimizeNode(state, node) {
|
|
|
13719
14227
|
if (!left || !right)
|
|
13720
14228
|
break;
|
|
13721
14229
|
let value = null;
|
|
13722
|
-
|
|
13723
|
-
|
|
14230
|
+
let type;
|
|
14231
|
+
if ((left_type != "Number" && left_type != "Long") ||
|
|
14232
|
+
left_type != right_type) {
|
|
13724
14233
|
if (node.operator !== "==" && node.operator !== "!=") {
|
|
13725
14234
|
break;
|
|
13726
14235
|
}
|
|
13727
14236
|
value = operators[node.operator](left.value, right.value);
|
|
14237
|
+
type = "Boolean";
|
|
13728
14238
|
}
|
|
13729
14239
|
else {
|
|
13730
|
-
|
|
14240
|
+
type = left_type;
|
|
14241
|
+
value = op(BigInt(left.value), BigInt(right.value));
|
|
13731
14242
|
}
|
|
13732
14243
|
if (value === null)
|
|
13733
14244
|
break;
|
|
13734
|
-
return
|
|
13735
|
-
...left,
|
|
13736
|
-
value,
|
|
13737
|
-
raw: value.toString() + (left_type === "Long" ? "l" : ""),
|
|
13738
|
-
};
|
|
14245
|
+
return replacementLiteral(left, value, type);
|
|
13739
14246
|
}
|
|
13740
14247
|
break;
|
|
13741
14248
|
}
|
|
@@ -13745,7 +14252,8 @@ function optimizeNode(state, node) {
|
|
|
13745
14252
|
break;
|
|
13746
14253
|
const falsy = left.value === false ||
|
|
13747
14254
|
left.value === null ||
|
|
13748
|
-
(
|
|
14255
|
+
((left_type === "Number" || left_type === "Long") &&
|
|
14256
|
+
(left.value === 0 || left.value === 0n));
|
|
13749
14257
|
if (falsy === (node.operator === "&&")) {
|
|
13750
14258
|
return left;
|
|
13751
14259
|
}
|
|
@@ -13786,9 +14294,7 @@ function evaluateFunction(state, func, args) {
|
|
|
13786
14294
|
const paramValues = args &&
|
|
13787
14295
|
Object.fromEntries(func.params.map((p, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(p), args[i]]));
|
|
13788
14296
|
let ret = null;
|
|
13789
|
-
const body = args
|
|
13790
|
-
? JSON.parse(JSON.stringify(func.body))
|
|
13791
|
-
: func.body;
|
|
14297
|
+
const body = args ? cloneDeep(func.body) : func.body;
|
|
13792
14298
|
try {
|
|
13793
14299
|
traverseAst(body, (node) => {
|
|
13794
14300
|
switch (node.type) {
|
|
@@ -13839,12 +14345,10 @@ function markFunctionCalled(state, func) {
|
|
|
13839
14345
|
(0,external_util_cjs_namespaceObject.pushUnique)(state.calledFunctions[func.id.name], func);
|
|
13840
14346
|
}
|
|
13841
14347
|
async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
13842
|
-
const state =
|
|
13843
|
-
|
|
13844
|
-
|
|
13845
|
-
|
|
13846
|
-
calledFunctions: {},
|
|
13847
|
-
};
|
|
14348
|
+
const state = (await analyze(fnMap, barrelList, config));
|
|
14349
|
+
state.localsStack = [{}];
|
|
14350
|
+
state.calledFunctions = {};
|
|
14351
|
+
state.usedByName = {};
|
|
13848
14352
|
const replace = (node, old) => {
|
|
13849
14353
|
if (node === false || node === null)
|
|
13850
14354
|
return node;
|
|
@@ -13933,6 +14437,58 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
13933
14437
|
f.type == "FunctionDeclaration" &&
|
|
13934
14438
|
maybeCalled(f.node))) ||
|
|
13935
14439
|
(sc.superClass && checkInherited(sc, name))));
|
|
14440
|
+
const renamer = (idnode) => {
|
|
14441
|
+
const ident = idnode.type === "Identifier" ? idnode : idnode.left;
|
|
14442
|
+
const locals = topLocals();
|
|
14443
|
+
const { map } = locals;
|
|
14444
|
+
if (map) {
|
|
14445
|
+
const declName = ident.name;
|
|
14446
|
+
const name = renameVariable(state, locals, declName);
|
|
14447
|
+
if (name) {
|
|
14448
|
+
const [, results] = state.lookupValue(ident);
|
|
14449
|
+
if (!results) {
|
|
14450
|
+
throw new Error(`Didn't find local ${declName} which needed renaming`);
|
|
14451
|
+
}
|
|
14452
|
+
if (results.length !== 1) {
|
|
14453
|
+
throw new Error(`Lookup of local ${declName} found more than one result`);
|
|
14454
|
+
}
|
|
14455
|
+
const parent = results[0].parent;
|
|
14456
|
+
if (!parent) {
|
|
14457
|
+
throw new Error(`No parent in lookup of local ${declName}`);
|
|
14458
|
+
}
|
|
14459
|
+
const decls = parent.decls;
|
|
14460
|
+
if (!decls || !(0,external_api_cjs_namespaceObject.hasProperty)(decls, declName)) {
|
|
14461
|
+
throw new Error(`Missing decls in lookup of local ${declName}`);
|
|
14462
|
+
}
|
|
14463
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(decls, name)) {
|
|
14464
|
+
throw new Error(`While renaming ${declName} to ${name}, there was already a variable ${name}`);
|
|
14465
|
+
}
|
|
14466
|
+
if (decls[declName].length === 1) {
|
|
14467
|
+
decls[name] = decls[declName];
|
|
14468
|
+
delete decls[declName];
|
|
14469
|
+
}
|
|
14470
|
+
else {
|
|
14471
|
+
let i = decls[declName].length;
|
|
14472
|
+
while (i--) {
|
|
14473
|
+
const decl = decls[declName][i];
|
|
14474
|
+
if (decl === idnode ||
|
|
14475
|
+
(decl.type === "VariableDeclarator" && decl.node.id === idnode)) {
|
|
14476
|
+
decls[declName].splice(i, 1);
|
|
14477
|
+
decls[name] = [decl];
|
|
14478
|
+
break;
|
|
14479
|
+
}
|
|
14480
|
+
}
|
|
14481
|
+
if (i < 0) {
|
|
14482
|
+
throw new Error(`While renaming ${declName} to ${name}: Didn't find original declaration`);
|
|
14483
|
+
}
|
|
14484
|
+
}
|
|
14485
|
+
ident.name = name;
|
|
14486
|
+
}
|
|
14487
|
+
else {
|
|
14488
|
+
map[declName] = true;
|
|
14489
|
+
}
|
|
14490
|
+
}
|
|
14491
|
+
};
|
|
13936
14492
|
state.pre = (node) => {
|
|
13937
14493
|
switch (node.type) {
|
|
13938
14494
|
case "ConditionalExpression":
|
|
@@ -13953,7 +14509,11 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
13953
14509
|
result = !!value.value;
|
|
13954
14510
|
}
|
|
13955
14511
|
if (result !== null) {
|
|
13956
|
-
node.test = {
|
|
14512
|
+
node.test = {
|
|
14513
|
+
type: "Literal",
|
|
14514
|
+
value: result,
|
|
14515
|
+
raw: result.toString(),
|
|
14516
|
+
};
|
|
13957
14517
|
if (node.type === "IfStatement" ||
|
|
13958
14518
|
node.type === "ConditionalExpression") {
|
|
13959
14519
|
return [result ? "consequent" : "alternate"];
|
|
@@ -13972,7 +14532,7 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
13972
14532
|
return null;
|
|
13973
14533
|
}
|
|
13974
14534
|
case "EnumDeclaration":
|
|
13975
|
-
return
|
|
14535
|
+
return [];
|
|
13976
14536
|
case "ForStatement": {
|
|
13977
14537
|
const map = topLocals().map;
|
|
13978
14538
|
if (map) {
|
|
@@ -13981,43 +14541,13 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
13981
14541
|
break;
|
|
13982
14542
|
}
|
|
13983
14543
|
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
|
-
}
|
|
14544
|
+
renamer(node.id);
|
|
14001
14545
|
return ["init"];
|
|
14002
14546
|
}
|
|
14003
14547
|
case "CatchClause":
|
|
14004
14548
|
if (node.param) {
|
|
14005
14549
|
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
|
-
}
|
|
14550
|
+
renamer(node.param);
|
|
14021
14551
|
return ["body"];
|
|
14022
14552
|
}
|
|
14023
14553
|
break;
|
|
@@ -14033,14 +14563,8 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14033
14563
|
break;
|
|
14034
14564
|
case "UnaryExpression":
|
|
14035
14565
|
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...
|
|
14566
|
+
// node.argument is not a normal identifier.
|
|
14567
|
+
// don't visit it.
|
|
14044
14568
|
return [];
|
|
14045
14569
|
}
|
|
14046
14570
|
break;
|
|
@@ -14052,29 +14576,73 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14052
14576
|
if (typeof name === "string") {
|
|
14053
14577
|
node.name = name;
|
|
14054
14578
|
}
|
|
14579
|
+
const [, results] = state.lookupValue(node);
|
|
14580
|
+
if (results) {
|
|
14581
|
+
if (results.length !== 1 || results[0].results.length !== 1) {
|
|
14582
|
+
throw new Error(`Local ${node.name} had multiple lookup results`);
|
|
14583
|
+
}
|
|
14584
|
+
const parent = results[0].parent;
|
|
14585
|
+
if (!parent) {
|
|
14586
|
+
throw new Error(`Local ${node.name} had no parent`);
|
|
14587
|
+
}
|
|
14588
|
+
const decl = results[0].results[0];
|
|
14589
|
+
if (parent.type === "FunctionDeclaration" ||
|
|
14590
|
+
decl.type !== "VariableDeclarator") {
|
|
14591
|
+
// we can't optimize away function or catch parameters
|
|
14592
|
+
return [];
|
|
14593
|
+
}
|
|
14594
|
+
if (parent.type !== "BlockStatement") {
|
|
14595
|
+
throw new Error(`Local ${node.name} was not declared at block scope(??)`);
|
|
14596
|
+
}
|
|
14597
|
+
decl.used = true;
|
|
14598
|
+
}
|
|
14055
14599
|
}
|
|
14056
14600
|
}
|
|
14057
14601
|
if ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, node.name)) {
|
|
14058
14602
|
if (!lookupAndReplace(node)) {
|
|
14059
|
-
state.
|
|
14603
|
+
state.usedByName[node.name] = true;
|
|
14060
14604
|
}
|
|
14061
14605
|
}
|
|
14062
14606
|
return [];
|
|
14063
14607
|
}
|
|
14064
|
-
case "MemberExpression":
|
|
14065
|
-
|
|
14066
|
-
|
|
14608
|
+
case "MemberExpression": {
|
|
14609
|
+
const property = (0,external_api_cjs_namespaceObject.isLookupCandidate)(node);
|
|
14610
|
+
if (property) {
|
|
14611
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, property.name)) {
|
|
14067
14612
|
if (lookupAndReplace(node)) {
|
|
14068
14613
|
return false;
|
|
14069
14614
|
}
|
|
14070
14615
|
else {
|
|
14071
|
-
state.
|
|
14616
|
+
state.usedByName[property.name] = true;
|
|
14072
14617
|
}
|
|
14073
14618
|
}
|
|
14074
14619
|
// Don't optimize the property.
|
|
14075
14620
|
return ["object"];
|
|
14076
14621
|
}
|
|
14077
14622
|
break;
|
|
14623
|
+
}
|
|
14624
|
+
case "AssignmentExpression":
|
|
14625
|
+
case "UpdateExpression": {
|
|
14626
|
+
const lhs = node.type === "AssignmentExpression" ? node.left : node.argument;
|
|
14627
|
+
if (lhs.type === "Identifier") {
|
|
14628
|
+
const map = topLocals().map;
|
|
14629
|
+
if (map) {
|
|
14630
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(map, lhs.name)) {
|
|
14631
|
+
const name = map[lhs.name];
|
|
14632
|
+
if (typeof name === "string") {
|
|
14633
|
+
lhs.name = name;
|
|
14634
|
+
}
|
|
14635
|
+
}
|
|
14636
|
+
}
|
|
14637
|
+
}
|
|
14638
|
+
else if (lhs.type === "MemberExpression") {
|
|
14639
|
+
state.traverse(lhs.object);
|
|
14640
|
+
if (lhs.computed) {
|
|
14641
|
+
state.traverse(lhs.property);
|
|
14642
|
+
}
|
|
14643
|
+
}
|
|
14644
|
+
return node.type === "AssignmentExpression" ? ["right"] : [];
|
|
14645
|
+
}
|
|
14078
14646
|
case "BlockStatement": {
|
|
14079
14647
|
const map = topLocals().map;
|
|
14080
14648
|
if (map) {
|
|
@@ -14090,7 +14658,11 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14090
14658
|
node.params &&
|
|
14091
14659
|
node.params.forEach((p) => (map[(0,external_api_cjs_namespaceObject.variableDeclarationName)(p)] = true));
|
|
14092
14660
|
state.localsStack.push({ node, map });
|
|
14093
|
-
const [parent] = state.stack.slice(-2);
|
|
14661
|
+
const [parent, self] = state.stack.slice(-2);
|
|
14662
|
+
if (state.currentFunction) {
|
|
14663
|
+
throw new Error(`Nested functions: ${self.fullName} was activated during processing of ${state.currentFunction.fullName}`);
|
|
14664
|
+
}
|
|
14665
|
+
state.currentFunction = self;
|
|
14094
14666
|
if (parent.type == "ClassDeclaration" && !maybeCalled(node)) {
|
|
14095
14667
|
let used = false;
|
|
14096
14668
|
if (node.id.name == "initialize") {
|
|
@@ -14117,10 +14689,23 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14117
14689
|
return replace(opt, node);
|
|
14118
14690
|
}
|
|
14119
14691
|
switch (node.type) {
|
|
14692
|
+
case "FunctionDeclaration":
|
|
14693
|
+
if (!state.currentFunction) {
|
|
14694
|
+
throw new Error(`Finished function ${state.stack.slice(-1)[0].fullName}, but it was not marked current`);
|
|
14695
|
+
}
|
|
14696
|
+
state.currentFunction.info = state.currentFunction.next_info;
|
|
14697
|
+
delete state.currentFunction.next_info;
|
|
14698
|
+
delete state.currentFunction;
|
|
14699
|
+
break;
|
|
14120
14700
|
case "BlockStatement":
|
|
14121
14701
|
if (node.body.length === 1 && node.body[0].type === "BlockStatement") {
|
|
14122
14702
|
node.body.splice(0, 1, ...node.body[0].body);
|
|
14123
14703
|
}
|
|
14704
|
+
// fall through
|
|
14705
|
+
case "ForStatement":
|
|
14706
|
+
if (locals.map) {
|
|
14707
|
+
cleanupUnusedVars(state, node);
|
|
14708
|
+
}
|
|
14124
14709
|
break;
|
|
14125
14710
|
case "ConditionalExpression":
|
|
14126
14711
|
case "IfStatement":
|
|
@@ -14153,17 +14738,20 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14153
14738
|
return replace(optimizeCall(state, node.argument, node), node.argument);
|
|
14154
14739
|
}
|
|
14155
14740
|
break;
|
|
14741
|
+
case "NewExpression":
|
|
14742
|
+
if (state.currentFunction) {
|
|
14743
|
+
const [, results] = state.lookup(node.callee);
|
|
14744
|
+
if (results) {
|
|
14745
|
+
recordCalledFuncs(state.currentFunction, findCalleesForNew(results));
|
|
14746
|
+
}
|
|
14747
|
+
else {
|
|
14748
|
+
recordModifiedUnknown(state.currentFunction);
|
|
14749
|
+
}
|
|
14750
|
+
}
|
|
14751
|
+
break;
|
|
14156
14752
|
case "CallExpression": {
|
|
14157
14753
|
return replace(optimizeCall(state, node, null), node);
|
|
14158
14754
|
}
|
|
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
14755
|
case "VariableDeclaration": {
|
|
14168
14756
|
const locals = topLocals();
|
|
14169
14757
|
if (locals.map &&
|
|
@@ -14237,6 +14825,32 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14237
14825
|
}
|
|
14238
14826
|
}
|
|
14239
14827
|
break;
|
|
14828
|
+
case "AssignmentExpression":
|
|
14829
|
+
if (node.operator === "=" &&
|
|
14830
|
+
node.left.type === "Identifier" &&
|
|
14831
|
+
node.right.type === "Identifier" &&
|
|
14832
|
+
node.left.name === node.right.name) {
|
|
14833
|
+
return { type: "Literal", value: null, raw: "null" };
|
|
14834
|
+
}
|
|
14835
|
+
// fall through;
|
|
14836
|
+
case "UpdateExpression":
|
|
14837
|
+
if (state.currentFunction) {
|
|
14838
|
+
const lhs = node.type === "AssignmentExpression" ? node.left : node.argument;
|
|
14839
|
+
const [, results] = state.lookup(lhs);
|
|
14840
|
+
if (results) {
|
|
14841
|
+
recordModifiedDecls(state.currentFunction, results);
|
|
14842
|
+
}
|
|
14843
|
+
else {
|
|
14844
|
+
const id = lhs.type === "Identifier" ? lhs : (0,external_api_cjs_namespaceObject.isLookupCandidate)(lhs);
|
|
14845
|
+
if (id) {
|
|
14846
|
+
recordModifiedName(state.currentFunction, id.name);
|
|
14847
|
+
}
|
|
14848
|
+
else {
|
|
14849
|
+
recordModifiedUnknown(state.currentFunction);
|
|
14850
|
+
}
|
|
14851
|
+
}
|
|
14852
|
+
}
|
|
14853
|
+
break;
|
|
14240
14854
|
}
|
|
14241
14855
|
return null;
|
|
14242
14856
|
};
|
|
@@ -14244,13 +14858,16 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14244
14858
|
(0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
|
|
14245
14859
|
});
|
|
14246
14860
|
state.calledFunctions = {};
|
|
14247
|
-
state.exposed =
|
|
14861
|
+
state.exposed = state.nextExposed;
|
|
14862
|
+
state.nextExposed = {};
|
|
14248
14863
|
Object.values(fnMap).forEach((f) => {
|
|
14249
14864
|
(0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
|
|
14250
14865
|
});
|
|
14866
|
+
state.exposed = state.nextExposed;
|
|
14867
|
+
state.nextExposed = {};
|
|
14251
14868
|
delete state.pre;
|
|
14252
14869
|
delete state.post;
|
|
14253
|
-
state.allFunctions.forEach((fn) => sizeBasedPRE(state, fn));
|
|
14870
|
+
Object.values(state.allFunctions).forEach((fns) => fns.forEach((fn) => sizeBasedPRE(state, fn)));
|
|
14254
14871
|
const cleanup = (node) => {
|
|
14255
14872
|
switch (node.type) {
|
|
14256
14873
|
case "ThisExpression":
|
|
@@ -14260,7 +14877,8 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14260
14877
|
if (node.members.every((m) => {
|
|
14261
14878
|
const name = "name" in m ? m.name : m.id.name;
|
|
14262
14879
|
return ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) &&
|
|
14263
|
-
!(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name)
|
|
14880
|
+
!(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name) &&
|
|
14881
|
+
!(0,external_api_cjs_namespaceObject.hasProperty)(state.usedByName, name));
|
|
14264
14882
|
})) {
|
|
14265
14883
|
node.enumType = [
|
|
14266
14884
|
...new Set(node.members.map((m) => {
|
|
@@ -14303,7 +14921,9 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14303
14921
|
case "VariableDeclaration": {
|
|
14304
14922
|
node.declarations = node.declarations.filter((d) => {
|
|
14305
14923
|
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(d.id);
|
|
14306
|
-
return (!(0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) ||
|
|
14924
|
+
return (!(0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) ||
|
|
14925
|
+
(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name) ||
|
|
14926
|
+
(0,external_api_cjs_namespaceObject.hasProperty)(state.usedByName, name));
|
|
14307
14927
|
});
|
|
14308
14928
|
if (!node.declarations.length) {
|
|
14309
14929
|
return false;
|
|
@@ -14336,7 +14956,7 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14336
14956
|
}
|
|
14337
14957
|
return null;
|
|
14338
14958
|
};
|
|
14339
|
-
Object.
|
|
14959
|
+
Object.entries(fnMap).forEach(([name, f]) => {
|
|
14340
14960
|
traverseAst(f.ast, undefined, (node) => {
|
|
14341
14961
|
const ret = cleanup(node);
|
|
14342
14962
|
if (ret === false) {
|
|
@@ -14344,16 +14964,15 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14344
14964
|
}
|
|
14345
14965
|
return ret;
|
|
14346
14966
|
});
|
|
14967
|
+
if (state.config && state.config.checkBuildPragmas) {
|
|
14968
|
+
pragmaChecker(state, f.ast, state.diagnostics?.[name]);
|
|
14969
|
+
}
|
|
14347
14970
|
});
|
|
14348
14971
|
return state.diagnostics;
|
|
14349
14972
|
}
|
|
14350
14973
|
function optimizeCall(state, node, context) {
|
|
14351
14974
|
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");
|
|
14975
|
+
const callees = results ? findCallees(results) : null;
|
|
14357
14976
|
if (!callees || !callees.length) {
|
|
14358
14977
|
const n = name ||
|
|
14359
14978
|
("name" in node.callee && node.callee.name) ||
|
|
@@ -14362,14 +14981,24 @@ function optimizeCall(state, node, context) {
|
|
|
14362
14981
|
"name" in node.callee.property &&
|
|
14363
14982
|
node.callee.property.name);
|
|
14364
14983
|
if (n) {
|
|
14365
|
-
state.
|
|
14984
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(state.allFunctions, n)) {
|
|
14985
|
+
if (state.currentFunction) {
|
|
14986
|
+
recordCalledFuncs(state.currentFunction, state.allFunctions[n]);
|
|
14987
|
+
}
|
|
14988
|
+
state.allFunctions[n].forEach((fn) => markFunctionCalled(state, fn.node));
|
|
14989
|
+
}
|
|
14366
14990
|
}
|
|
14367
|
-
else {
|
|
14368
|
-
//
|
|
14369
|
-
//
|
|
14991
|
+
else if (state.currentFunction) {
|
|
14992
|
+
// I don't think this can happen: foo[x](args)
|
|
14993
|
+
// doesn't parse, so you can't even do things like
|
|
14994
|
+
// $.Toybox.Lang[:format]("fmt", [])
|
|
14995
|
+
recordModifiedUnknown(state.currentFunction);
|
|
14370
14996
|
}
|
|
14371
14997
|
return null;
|
|
14372
14998
|
}
|
|
14999
|
+
if (state.currentFunction) {
|
|
15000
|
+
recordCalledFuncs(state.currentFunction, callees);
|
|
15001
|
+
}
|
|
14373
15002
|
if (callees.length == 1 && callees[0].type === "FunctionDeclaration") {
|
|
14374
15003
|
const callee = callees[0].node;
|
|
14375
15004
|
if (!context &&
|
|
@@ -14392,120 +15021,6 @@ function optimizeCall(state, node, context) {
|
|
|
14392
15021
|
return null;
|
|
14393
15022
|
}
|
|
14394
15023
|
|
|
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
15024
|
;// CONCATENATED MODULE: ./src/optimizer.ts
|
|
14510
15025
|
|
|
14511
15026
|
|
|
@@ -14943,22 +15458,19 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
14943
15458
|
// the oldest optimized file, we don't need to regenerate
|
|
14944
15459
|
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
14945
15460
|
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
14946
|
-
if (source_time < opt_time &&
|
|
15461
|
+
if (source_time < opt_time && 1657670997056 < opt_time) {
|
|
14947
15462
|
return { hasTests, diagnostics: prevDiagnostics };
|
|
14948
15463
|
}
|
|
14949
15464
|
}
|
|
14950
15465
|
await promises_namespaceObject.rm(output, { recursive: true, force: true });
|
|
14951
15466
|
await promises_namespaceObject.mkdir(output, { recursive: true });
|
|
14952
15467
|
const diagnostics = await optimizeMonkeyC(fnMap, Object.keys(buildConfig.barrelMap || {}), config);
|
|
14953
|
-
return Promise.all(Object.
|
|
15468
|
+
return Promise.all(Object.values(fnMap).map(async (info) => {
|
|
14954
15469
|
const name = info.output;
|
|
14955
15470
|
const dir = external_path_.dirname(name);
|
|
14956
15471
|
await promises_namespaceObject.mkdir(dir, { recursive: true });
|
|
14957
15472
|
const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(info.ast, info.monkeyCSource);
|
|
14958
15473
|
await promises_namespaceObject.writeFile(name, opt_source);
|
|
14959
|
-
if (config.checkBuildPragmas) {
|
|
14960
|
-
pragmaChecker(info.ast, diagnostics?.[inFile]);
|
|
14961
|
-
}
|
|
14962
15474
|
return info.hasTests;
|
|
14963
15475
|
})).then((results) => {
|
|
14964
15476
|
const hasTests = results.some((v) => v);
|