@markw65/monkeyc-optimizer 1.1.12 → 1.1.13
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 +4 -0
- package/build/api.cjs +383 -204
- package/build/optimizer.cjs +365 -199
- package/build/src/api.d.ts +1 -1
- package/build/src/optimizer-types.d.ts +1 -0
- package/build/src/type-flow/mimimize-modules.d.ts +3 -0
- package/build/src/type-flow/minimize-locals.d.ts +2 -0
- package/build/src/type-flow/minimize-modules.d.ts +3 -0
- package/build/src/type-flow/types.d.ts +1 -1
- package/package.json +1 -1
package/build/api.cjs
CHANGED
|
@@ -2758,13 +2758,15 @@ function fixNodeScope(state, lookupNode, nodeStack) {
|
|
|
2758
2758
|
/* harmony import */ var _type_flow__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(4859);
|
|
2759
2759
|
/* harmony import */ var _type_flow_could_be__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(4055);
|
|
2760
2760
|
/* harmony import */ var _type_flow_interp__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(7161);
|
|
2761
|
-
/* harmony import */ var
|
|
2762
|
-
/* harmony import */ var
|
|
2763
|
-
/* harmony import */ var
|
|
2764
|
-
/* harmony import */ var
|
|
2765
|
-
/* harmony import */ var
|
|
2766
|
-
/* harmony import */ var
|
|
2767
|
-
/* harmony import */ var
|
|
2761
|
+
/* harmony import */ var _type_flow_minimize_modules__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(4416);
|
|
2762
|
+
/* harmony import */ var _type_flow_optimize__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(3687);
|
|
2763
|
+
/* harmony import */ var _type_flow_sub_type__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(9234);
|
|
2764
|
+
/* harmony import */ var _type_flow_types__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(7255);
|
|
2765
|
+
/* harmony import */ var _unused_exprs__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(424);
|
|
2766
|
+
/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(6906);
|
|
2767
|
+
/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_17__);
|
|
2768
|
+
/* harmony import */ var _variable_renamer__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(4405);
|
|
2769
|
+
|
|
2768
2770
|
|
|
2769
2771
|
|
|
2770
2772
|
|
|
@@ -3370,32 +3372,30 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
|
|
|
3370
3372
|
break;
|
|
3371
3373
|
case "Identifier": {
|
|
3372
3374
|
const map = topLocals().map;
|
|
3373
|
-
if (map) {
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
if (results) {
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
throw new Error(`Local ${node.name} was not declared at block scope(??)`);
|
|
3396
|
-
}
|
|
3397
|
-
decl.used = true;
|
|
3375
|
+
if (hasProperty(map, node.name)) {
|
|
3376
|
+
const name = map[node.name];
|
|
3377
|
+
if (typeof name === "string") {
|
|
3378
|
+
renameIdentifier(node, name);
|
|
3379
|
+
}
|
|
3380
|
+
const [, results] = state.lookupValue(node);
|
|
3381
|
+
if (results) {
|
|
3382
|
+
if (results.length !== 1 || results[0].results.length !== 1) {
|
|
3383
|
+
throw new Error(`Local ${node.name} had multiple lookup results`);
|
|
3384
|
+
}
|
|
3385
|
+
const parent = results[0].parent;
|
|
3386
|
+
if (!parent) {
|
|
3387
|
+
throw new Error(`Local ${node.name} had no parent`);
|
|
3388
|
+
}
|
|
3389
|
+
const decl = results[0].results[0];
|
|
3390
|
+
if (parent.type === "FunctionDeclaration" ||
|
|
3391
|
+
decl.type !== "VariableDeclarator") {
|
|
3392
|
+
// we can't optimize away function or catch parameters
|
|
3393
|
+
return [];
|
|
3394
|
+
}
|
|
3395
|
+
if (parent.type !== "BlockStatement") {
|
|
3396
|
+
throw new Error(`Local ${node.name} was not declared at block scope(??)`);
|
|
3398
3397
|
}
|
|
3398
|
+
decl.used = true;
|
|
3399
3399
|
}
|
|
3400
3400
|
}
|
|
3401
3401
|
return [];
|
|
@@ -3683,6 +3683,11 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
|
|
|
3683
3683
|
state.nextExposed = {};
|
|
3684
3684
|
delete state.pre;
|
|
3685
3685
|
delete state.post;
|
|
3686
|
+
if (state.config?.minimizeModules ?? true) {
|
|
3687
|
+
Object.values(fnMap).forEach((f) => {
|
|
3688
|
+
minimizeModules(f.ast, state);
|
|
3689
|
+
});
|
|
3690
|
+
}
|
|
3686
3691
|
Object.values(state.allFunctions).forEach((fns) => fns.forEach((fn) => sizeBasedPRE(state, fn)));
|
|
3687
3692
|
const cleanup = (node) => {
|
|
3688
3693
|
switch (node.type) {
|
|
@@ -4026,7 +4031,7 @@ function pragmaChecker(state, ast, diagnostics) {
|
|
|
4026
4031
|
if (kind === "match") {
|
|
4027
4032
|
const haystack = formatAst(node)
|
|
4028
4033
|
.replace(/([\r\n]|\s)+/g, " ")
|
|
4029
|
-
.replace(/\b\w+\s\/\*>(\w+)<\*\//g, "$1");
|
|
4034
|
+
.replace(/\b\w+\s\/\*>([\w.]+)<\*\//g, "$1");
|
|
4030
4035
|
if (!matcher(quote, needle, haystack)) {
|
|
4031
4036
|
matcher(quote, needle, haystack);
|
|
4032
4037
|
diagnostic(state, comment, `Didn't find '${needle}' in '${haystack}'`, "ERROR");
|
|
@@ -4951,8 +4956,8 @@ function buildConflictGraph(state, func) {
|
|
|
4951
4956
|
function addEquiv(ts, key, equiv) {
|
|
4952
4957
|
if (key === equiv)
|
|
4953
4958
|
return true;
|
|
4954
|
-
|
|
4955
|
-
|
|
4959
|
+
const keyVal = ts.get(key);
|
|
4960
|
+
const equivVal = ts.get(equiv);
|
|
4956
4961
|
if (!keyVal || !equivVal)
|
|
4957
4962
|
return false;
|
|
4958
4963
|
if (equivVal.equivSet) {
|
|
@@ -4964,31 +4969,25 @@ function addEquiv(ts, key, equiv) {
|
|
|
4964
4969
|
}
|
|
4965
4970
|
// equiv is not (or no longer) part of an equivSet
|
|
4966
4971
|
if (!keyVal.equivSet) {
|
|
4967
|
-
keyVal = { ...keyVal };
|
|
4968
4972
|
keyVal.equivSet = new Set([key, equiv]);
|
|
4969
|
-
ts.set(key, keyVal);
|
|
4970
4973
|
}
|
|
4971
4974
|
else {
|
|
4972
4975
|
keyVal.equivSet.add(equiv);
|
|
4973
4976
|
}
|
|
4974
|
-
equivVal =
|
|
4975
|
-
ts.set(equiv, equivVal);
|
|
4977
|
+
equivVal.equivSet = keyVal.equivSet;
|
|
4976
4978
|
return false;
|
|
4977
4979
|
}
|
|
4978
4980
|
function removeEquiv(ts, equiv) {
|
|
4979
|
-
|
|
4981
|
+
const equivVal = ts.get(equiv);
|
|
4980
4982
|
if (!equivVal?.equivSet)
|
|
4981
4983
|
return;
|
|
4982
4984
|
equivVal.equivSet.delete(equiv);
|
|
4983
4985
|
if (equivVal.equivSet.size === 1) {
|
|
4984
4986
|
const other = Array.from(equivVal.equivSet)[0];
|
|
4985
|
-
const otherVal =
|
|
4987
|
+
const otherVal = ts.get(other);
|
|
4986
4988
|
delete otherVal.equivSet;
|
|
4987
|
-
ts.set(other, otherVal);
|
|
4988
4989
|
}
|
|
4989
|
-
equivVal = { ...equivVal };
|
|
4990
4990
|
delete equivVal.equivSet;
|
|
4991
|
-
ts.set(equiv, equivVal);
|
|
4992
4991
|
}
|
|
4993
4992
|
function getEquivSet(ts, k) {
|
|
4994
4993
|
const keys = ts.get(k)?.equivSet;
|
|
@@ -5042,9 +5041,14 @@ function cloneTypeState(blockState) {
|
|
|
5042
5041
|
const { map, trackedMemberDecls, liveCopyPropEvents, ...rest } = blockState;
|
|
5043
5042
|
const clone = { map: new Map(map), ...rest };
|
|
5044
5043
|
clone.map.forEach((value, key) => {
|
|
5045
|
-
if (value.equivSet
|
|
5046
|
-
|
|
5047
|
-
|
|
5044
|
+
if (value.equivSet) {
|
|
5045
|
+
if (key === Array.from(value.equivSet)[0]) {
|
|
5046
|
+
const equivSet = new Set(value.equivSet);
|
|
5047
|
+
equivSet.forEach((k) => clone.map.set(k, { ...clone.map.get(k), equivSet }));
|
|
5048
|
+
}
|
|
5049
|
+
}
|
|
5050
|
+
else {
|
|
5051
|
+
clone.map.set(key, { ...value });
|
|
5048
5052
|
}
|
|
5049
5053
|
});
|
|
5050
5054
|
if (trackedMemberDecls) {
|
|
@@ -5081,12 +5085,9 @@ function addCopyPropEvent(blockState, item) {
|
|
|
5081
5085
|
const liveCopyPropEvents = blockState.liveCopyPropEvents;
|
|
5082
5086
|
const decl = item.event.decl;
|
|
5083
5087
|
assert(declIsLocal(decl));
|
|
5084
|
-
|
|
5088
|
+
const tov = blockState.map.get(decl);
|
|
5085
5089
|
assert(tov);
|
|
5086
|
-
|
|
5087
|
-
tov = { ...tov, copyPropItem: item };
|
|
5088
|
-
blockState.map.set(decl, tov);
|
|
5089
|
-
}
|
|
5090
|
+
tov.copyPropItem = item;
|
|
5090
5091
|
item.contained.forEach((value, key) => {
|
|
5091
5092
|
const decls = liveCopyPropEvents.get(key);
|
|
5092
5093
|
if (!decls) {
|
|
@@ -5119,15 +5120,13 @@ function clearRelatedCopyPropEvents(blockState, decl, nodeCopyProp) {
|
|
|
5119
5120
|
blockState.liveCopyPropEvents
|
|
5120
5121
|
?.get(decl)
|
|
5121
5122
|
?.forEach((cpDecl) => {
|
|
5122
|
-
|
|
5123
|
+
const value = blockState.map.get(cpDecl);
|
|
5123
5124
|
assert(value && value.copyPropItem);
|
|
5124
5125
|
assert(Array.from(value.copyPropItem.contained).some(([key]) => {
|
|
5125
5126
|
return decl === key;
|
|
5126
5127
|
}));
|
|
5127
5128
|
copyPropFailed(blockState, value.copyPropItem, nodeCopyProp);
|
|
5128
|
-
value = { ...value };
|
|
5129
5129
|
delete value.copyPropItem;
|
|
5130
|
-
blockState.map.set(cpDecl, value);
|
|
5131
5130
|
});
|
|
5132
5131
|
}
|
|
5133
5132
|
function validateTypeState(curState) {
|
|
@@ -5170,11 +5169,9 @@ function mergeTypeState(blockStates, index, from, nodeCopyProp) {
|
|
|
5170
5169
|
if (tov.equivSet) {
|
|
5171
5170
|
if (intersectEquiv(to.map, from.map, k)) {
|
|
5172
5171
|
changes = true;
|
|
5173
|
-
tov = to.map.get(k);
|
|
5174
5172
|
}
|
|
5175
5173
|
}
|
|
5176
5174
|
if (tov.assocPaths) {
|
|
5177
|
-
tov = { ...tov };
|
|
5178
5175
|
if (!fromv.assocPaths) {
|
|
5179
5176
|
changes = true;
|
|
5180
5177
|
delete tov.assocPaths;
|
|
@@ -5197,7 +5194,6 @@ function mergeTypeState(blockStates, index, from, nodeCopyProp) {
|
|
|
5197
5194
|
delete tov.assocPaths;
|
|
5198
5195
|
}
|
|
5199
5196
|
}
|
|
5200
|
-
to.map.set(k, tov);
|
|
5201
5197
|
}
|
|
5202
5198
|
// if both from and to have copyPropEvents, we can only
|
|
5203
5199
|
// keep it if they're the same event.
|
|
@@ -5215,10 +5211,8 @@ function mergeTypeState(blockStates, index, from, nodeCopyProp) {
|
|
|
5215
5211
|
}
|
|
5216
5212
|
nodeCopyProp.set(fromv.copyPropItem.event.node, false);
|
|
5217
5213
|
}
|
|
5218
|
-
tov = { ...tov };
|
|
5219
5214
|
delete tov.copyPropItem;
|
|
5220
5215
|
changes = true;
|
|
5221
|
-
to.map.set(k, tov);
|
|
5222
5216
|
}
|
|
5223
5217
|
else {
|
|
5224
5218
|
assert(k === tov.copyPropItem.event.decl);
|
|
@@ -5229,7 +5223,7 @@ function mergeTypeState(blockStates, index, from, nodeCopyProp) {
|
|
|
5229
5223
|
if (subtypeOf(fromv.curType, tov.curType))
|
|
5230
5224
|
return;
|
|
5231
5225
|
if (subtypeOf(tov.curType, fromv.curType)) {
|
|
5232
|
-
|
|
5226
|
+
tov.curType = fromv.curType;
|
|
5233
5227
|
changes = true;
|
|
5234
5228
|
return;
|
|
5235
5229
|
}
|
|
@@ -5242,7 +5236,7 @@ function mergeTypeState(blockStates, index, from, nodeCopyProp) {
|
|
|
5242
5236
|
if (wide)
|
|
5243
5237
|
result = wide;
|
|
5244
5238
|
}
|
|
5245
|
-
|
|
5239
|
+
tov.curType = result;
|
|
5246
5240
|
changes = true;
|
|
5247
5241
|
});
|
|
5248
5242
|
return changes;
|
|
@@ -5267,7 +5261,6 @@ function updateAffected(blockState, objectType, baseDecl, assignedPath, affected
|
|
|
5267
5261
|
let droppedComponents = null;
|
|
5268
5262
|
const entry = blockState.map.get(key);
|
|
5269
5263
|
assert(entry && entry.assocPaths);
|
|
5270
|
-
let newEntry = entry;
|
|
5271
5264
|
entry.assocPaths.forEach((path) => {
|
|
5272
5265
|
if (key === baseDecl && path === assignedPath) {
|
|
5273
5266
|
return;
|
|
@@ -5286,12 +5279,9 @@ function updateAffected(blockState, objectType, baseDecl, assignedPath, affected
|
|
|
5286
5279
|
});
|
|
5287
5280
|
if (pathItem === affectedName && couldBeShallow(type, objectType)) {
|
|
5288
5281
|
const newAssocKey = assocPath.map((av) => av.name ?? "*").join(".");
|
|
5289
|
-
if (newEntry === entry) {
|
|
5290
|
-
newEntry = { ...entry };
|
|
5291
|
-
}
|
|
5292
5282
|
if (newAssocKey !== path) {
|
|
5293
|
-
|
|
5294
|
-
|
|
5283
|
+
entry.assocPaths = new Set(entry.assocPaths);
|
|
5284
|
+
entry.assocPaths.delete(path);
|
|
5295
5285
|
// the "extra" path components will also have entries
|
|
5296
5286
|
// in blockState.trackedMemberDecls. Since they're gone
|
|
5297
5287
|
// from here, we (may) need to remove them from there
|
|
@@ -5303,8 +5293,7 @@ function updateAffected(blockState, objectType, baseDecl, assignedPath, affected
|
|
|
5303
5293
|
}
|
|
5304
5294
|
break;
|
|
5305
5295
|
}
|
|
5306
|
-
|
|
5307
|
-
newEntry.curType = baseType;
|
|
5296
|
+
entry.curType = updateByAssocPath(assocPath, assignedType, true);
|
|
5308
5297
|
break;
|
|
5309
5298
|
}
|
|
5310
5299
|
if (pathItem === "*") {
|
|
@@ -5334,14 +5323,11 @@ function updateAffected(blockState, objectType, baseDecl, assignedPath, affected
|
|
|
5334
5323
|
}
|
|
5335
5324
|
}
|
|
5336
5325
|
});
|
|
5337
|
-
if (
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
droppedComponents.forEach((pathComponent) => blockState.trackedMemberDecls.get(pathComponent).delete(key));
|
|
5343
|
-
}
|
|
5344
|
-
blockState.map.set(key, newEntry);
|
|
5326
|
+
if (droppedComponents) {
|
|
5327
|
+
entry.assocPaths.forEach((path) => path
|
|
5328
|
+
.split(".")
|
|
5329
|
+
.forEach((pathComponent) => droppedComponents.delete(pathComponent)));
|
|
5330
|
+
droppedComponents.forEach((pathComponent) => blockState.trackedMemberDecls.get(pathComponent).delete(key));
|
|
5345
5331
|
}
|
|
5346
5332
|
});
|
|
5347
5333
|
}
|
|
@@ -5448,10 +5434,9 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
|
|
|
5448
5434
|
const assocKey = assocValue.map((av) => av.name ?? "*").join(".");
|
|
5449
5435
|
const newType = updateByAssocPath(assocValue, next, false);
|
|
5450
5436
|
setStateEvent(blockState, decl.base, newType, newValue ? 1 /* UpdateKind.Inner */ : 0 /* UpdateKind.None */);
|
|
5451
|
-
const tsv =
|
|
5437
|
+
const tsv = blockState.map.get(decl.base);
|
|
5452
5438
|
tsv.assocPaths = new Set(tsv.assocPaths);
|
|
5453
5439
|
tsv.assocPaths.add(assocKey);
|
|
5454
|
-
blockState.map.set(decl.base, tsv);
|
|
5455
5440
|
addTrackedMemberDecl(blockState, decl.base, assocKey);
|
|
5456
5441
|
if (newValue) {
|
|
5457
5442
|
const baseElem = assocValue[decl.path.length - 1];
|
|
@@ -5529,34 +5514,39 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
|
|
|
5529
5514
|
// that foo is side-effect free, and accesses no globals.
|
|
5530
5515
|
clearRelatedCopyPropEvents(blockState, decl, nodeCopyProp);
|
|
5531
5516
|
}
|
|
5517
|
+
const v = blockState.map.get(decl);
|
|
5518
|
+
if (!v) {
|
|
5519
|
+
blockState.map.set(decl, { curType: value });
|
|
5520
|
+
return;
|
|
5521
|
+
}
|
|
5532
5522
|
if (updateKind !== 2 /* UpdateKind.Reassign */) {
|
|
5533
5523
|
/*
|
|
5534
5524
|
* If we're not re-assigning, the equivalencies don't
|
|
5535
5525
|
* change, so this update must be applied to every
|
|
5536
5526
|
* element of the set
|
|
5537
5527
|
*/
|
|
5538
|
-
|
|
5539
|
-
if (v?.equivSet) {
|
|
5528
|
+
if (v.equivSet) {
|
|
5540
5529
|
v.equivSet.forEach((s) => {
|
|
5541
5530
|
const next = blockState.map.get(s);
|
|
5542
5531
|
assert(next && next.equivSet?.has(s));
|
|
5543
|
-
|
|
5532
|
+
next.curType = value;
|
|
5544
5533
|
});
|
|
5545
5534
|
}
|
|
5546
5535
|
else {
|
|
5547
|
-
|
|
5536
|
+
v.curType = value;
|
|
5548
5537
|
}
|
|
5549
5538
|
}
|
|
5550
5539
|
else {
|
|
5551
|
-
const v = blockState.map.get(decl);
|
|
5552
5540
|
removeEquiv(blockState.map, decl);
|
|
5553
|
-
if (v
|
|
5541
|
+
if (v.assocPaths?.size) {
|
|
5554
5542
|
clearAssocPaths(blockState, decl, v);
|
|
5543
|
+
delete v.assocPaths;
|
|
5555
5544
|
}
|
|
5556
|
-
if (v
|
|
5545
|
+
if (v.copyPropItem) {
|
|
5557
5546
|
copyPropFailed(blockState, v.copyPropItem, nodeCopyProp);
|
|
5547
|
+
delete v.copyPropItem;
|
|
5558
5548
|
}
|
|
5559
|
-
|
|
5549
|
+
v.curType = value;
|
|
5560
5550
|
}
|
|
5561
5551
|
return;
|
|
5562
5552
|
}
|
|
@@ -5890,7 +5880,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
|
|
|
5890
5880
|
break;
|
|
5891
5881
|
}
|
|
5892
5882
|
case "ref": {
|
|
5893
|
-
|
|
5883
|
+
const curEntry = getStateEntry(curState, event.decl);
|
|
5894
5884
|
typeMap.set(event.node, curEntry.curType);
|
|
5895
5885
|
nodeEquivs.delete(event.node);
|
|
5896
5886
|
if (curEntry.equivSet) {
|
|
@@ -5914,9 +5904,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
|
|
|
5914
5904
|
nodeCopyProp.set(curEntry.copyPropItem.event.node, event.node);
|
|
5915
5905
|
}
|
|
5916
5906
|
clearCopyProp(curState, curEntry.copyPropItem);
|
|
5917
|
-
curEntry = { ...curEntry };
|
|
5918
5907
|
delete curEntry.copyPropItem;
|
|
5919
|
-
curState.map.set(event.decl, curEntry);
|
|
5920
5908
|
}
|
|
5921
5909
|
else if (declIsNonLocal(event.decl)) {
|
|
5922
5910
|
clearRelatedCopyPropEvents(curState, null, nodeCopyProp);
|
|
@@ -5991,10 +5979,9 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
|
|
|
5991
5979
|
setUnionComponent(type, 32768 /* TypeTag.Object */, newData);
|
|
5992
5980
|
if (tsv.assocPaths) {
|
|
5993
5981
|
clearAssocPaths(curState, decl, tsv);
|
|
5994
|
-
tsv = { ...tsv };
|
|
5995
5982
|
delete tsv.assocPaths;
|
|
5996
5983
|
}
|
|
5997
|
-
|
|
5984
|
+
tsv.curType = type;
|
|
5998
5985
|
}
|
|
5999
5986
|
}
|
|
6000
5987
|
clearRelatedCopyPropEvents(curState, decl, nodeCopyProp);
|
|
@@ -6019,10 +6006,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, copyPropStore
|
|
|
6019
6006
|
(event.node.type !== "AssignmentExpression" ||
|
|
6020
6007
|
event.node.operator !== "=")) {
|
|
6021
6008
|
copyPropFailed(curState, before.copyPropItem, nodeCopyProp);
|
|
6022
|
-
|
|
6023
|
-
delete v.copyPropItem;
|
|
6024
|
-
assert(isTypeStateKey(event.decl));
|
|
6025
|
-
curState.map.set(event.decl, v);
|
|
6009
|
+
delete before.copyPropItem;
|
|
6026
6010
|
}
|
|
6027
6011
|
}
|
|
6028
6012
|
const expr = event.node.type === "VariableDeclarator"
|
|
@@ -6717,7 +6701,9 @@ function couldBeObj(a, b) {
|
|
|
6717
6701
|
/* harmony import */ var _control_flow__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5101);
|
|
6718
6702
|
/* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8180);
|
|
6719
6703
|
/* harmony import */ var _inliner__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(333);
|
|
6720
|
-
/* harmony import */ var
|
|
6704
|
+
/* harmony import */ var _minimize_locals__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(736);
|
|
6705
|
+
/* harmony import */ var _type_flow_util__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(1638);
|
|
6706
|
+
|
|
6721
6707
|
|
|
6722
6708
|
|
|
6723
6709
|
|
|
@@ -6985,7 +6971,10 @@ function eliminateDeadStores(state, func, graph, logThisRun) {
|
|
|
6985
6971
|
console.log(`${formatAst(dead)} (${sourceLocation(dead.loc)})`));
|
|
6986
6972
|
}
|
|
6987
6973
|
let changes = false;
|
|
6988
|
-
traverseAst(func.node.body, null, (node
|
|
6974
|
+
traverseAst(func.node.body, null, (node) => {
|
|
6975
|
+
const cleaned = variableCleanup(node);
|
|
6976
|
+
if (cleaned !== null)
|
|
6977
|
+
return cleaned;
|
|
6989
6978
|
if (node.type === "ExpressionStatement" &&
|
|
6990
6979
|
node.expression.type === "AssignmentExpression" &&
|
|
6991
6980
|
deadStores.has(node.expression)) {
|
|
@@ -7007,40 +6996,17 @@ function eliminateDeadStores(state, func, graph, logThisRun) {
|
|
|
7007
6996
|
changes = true;
|
|
7008
6997
|
return { type: "Literal", value: null, raw: "null" };
|
|
7009
6998
|
}
|
|
7010
|
-
if (node.type === "
|
|
7011
|
-
const
|
|
7012
|
-
|
|
7013
|
-
const
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
(parent.type !== "BlockStatement" && parent.type !== "SwitchCase")) {
|
|
7019
|
-
// Must be the init in a for statement. Fixing
|
|
7020
|
-
// it would be complicated, so just punt for now.
|
|
7021
|
-
break;
|
|
7022
|
-
}
|
|
7023
|
-
const newDeclaration = withLoc({ ...node }, node, decl.id);
|
|
7024
|
-
if (i + 1 < node.declarations.length) {
|
|
7025
|
-
newDeclaration.declarations = node.declarations.splice(0, i + 1);
|
|
7026
|
-
result.push(newDeclaration);
|
|
7027
|
-
withLoc(node, node.declarations[0], node);
|
|
7028
|
-
i = -1;
|
|
7029
|
-
}
|
|
7030
|
-
else {
|
|
7031
|
-
result.push(node);
|
|
7032
|
-
}
|
|
7033
|
-
result.push(...body);
|
|
7034
|
-
}
|
|
7035
|
-
changes = true;
|
|
7036
|
-
delete decl.init;
|
|
7037
|
-
}
|
|
7038
|
-
}
|
|
7039
|
-
if (result.length) {
|
|
7040
|
-
if (!result.includes(node)) {
|
|
7041
|
-
result.push(node);
|
|
6999
|
+
if (node.type === "VariableDeclarator") {
|
|
7000
|
+
const decl = node;
|
|
7001
|
+
if (decl.init && deadStores.has(decl)) {
|
|
7002
|
+
const body = unused(state, decl.init);
|
|
7003
|
+
delete decl.init;
|
|
7004
|
+
changes = true;
|
|
7005
|
+
if (!body.length) {
|
|
7006
|
+
return null;
|
|
7042
7007
|
}
|
|
7043
|
-
|
|
7008
|
+
body.unshift(decl);
|
|
7009
|
+
return body;
|
|
7044
7010
|
}
|
|
7045
7011
|
}
|
|
7046
7012
|
return null;
|
|
@@ -9339,7 +9305,7 @@ function restrictByEquality(a, b) {
|
|
|
9339
9305
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
9340
9306
|
|
|
9341
9307
|
"use strict";
|
|
9342
|
-
/* unused harmony
|
|
9308
|
+
/* unused harmony exports minimizeLocals, variableCleanup */
|
|
9343
9309
|
/* harmony import */ var node_assert__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4143);
|
|
9344
9310
|
/* harmony import */ var node_assert__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(node_assert__WEBPACK_IMPORTED_MODULE_0__);
|
|
9345
9311
|
/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6817);
|
|
@@ -9513,11 +9479,6 @@ function minimizeLocals(state, func) {
|
|
|
9513
9479
|
return null;
|
|
9514
9480
|
}
|
|
9515
9481
|
break;
|
|
9516
|
-
case "ExpressionStatement":
|
|
9517
|
-
if (node.expression.type === "Literal") {
|
|
9518
|
-
return false;
|
|
9519
|
-
}
|
|
9520
|
-
break;
|
|
9521
9482
|
case "UpdateExpression":
|
|
9522
9483
|
if (info) {
|
|
9523
9484
|
assert(node.argument.type === "Identifier");
|
|
@@ -9538,7 +9499,7 @@ function minimizeLocals(state, func) {
|
|
|
9538
9499
|
}
|
|
9539
9500
|
// VariableDeclarations aren't allowed to have
|
|
9540
9501
|
// AssignmentExpressions in them, but we'll fix that
|
|
9541
|
-
//
|
|
9502
|
+
// via variableCleanup
|
|
9542
9503
|
return withLoc({
|
|
9543
9504
|
type: "AssignmentExpression",
|
|
9544
9505
|
operator: "=",
|
|
@@ -9551,79 +9512,297 @@ function minimizeLocals(state, func) {
|
|
|
9551
9512
|
}, node, node);
|
|
9552
9513
|
}
|
|
9553
9514
|
break;
|
|
9554
|
-
|
|
9555
|
-
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
|
|
9560
|
-
|
|
9561
|
-
|
|
9562
|
-
|
|
9563
|
-
|
|
9564
|
-
|
|
9565
|
-
|
|
9566
|
-
|
|
9567
|
-
|
|
9568
|
-
|
|
9569
|
-
|
|
9570
|
-
|
|
9571
|
-
|
|
9572
|
-
|
|
9573
|
-
|
|
9574
|
-
|
|
9575
|
-
|
|
9576
|
-
|
|
9577
|
-
|
|
9578
|
-
|
|
9579
|
-
|
|
9580
|
-
|
|
9581
|
-
|
|
9582
|
-
|
|
9583
|
-
|
|
9584
|
-
|
|
9585
|
-
|
|
9515
|
+
}
|
|
9516
|
+
assert(!info);
|
|
9517
|
+
return variableCleanup(node);
|
|
9518
|
+
});
|
|
9519
|
+
return;
|
|
9520
|
+
}
|
|
9521
|
+
function variableCleanup(node) {
|
|
9522
|
+
switch (node.type) {
|
|
9523
|
+
case "ExpressionStatement":
|
|
9524
|
+
if (node.expression.type === "Literal") {
|
|
9525
|
+
return false;
|
|
9526
|
+
}
|
|
9527
|
+
break;
|
|
9528
|
+
case "VariableDeclaration":
|
|
9529
|
+
if (node.declarations.some((decl) => decl.type !== "VariableDeclarator")) {
|
|
9530
|
+
const results = [];
|
|
9531
|
+
node.declarations.forEach((decl) => {
|
|
9532
|
+
if (isStatement(decl)) {
|
|
9533
|
+
results.push(decl);
|
|
9534
|
+
}
|
|
9535
|
+
else if (isExpression(decl)) {
|
|
9536
|
+
results.push(withLoc({ type: "ExpressionStatement", expression: decl }, decl, decl));
|
|
9537
|
+
}
|
|
9538
|
+
else if (decl.init) {
|
|
9539
|
+
results.push(withLoc({
|
|
9540
|
+
type: "ExpressionStatement",
|
|
9541
|
+
expression: withLoc({
|
|
9542
|
+
type: "AssignmentExpression",
|
|
9543
|
+
operator: "=",
|
|
9544
|
+
left: withLoc({
|
|
9545
|
+
type: "Identifier",
|
|
9546
|
+
name: variableDeclarationName(decl.id),
|
|
9547
|
+
}, decl.id, decl.id),
|
|
9548
|
+
right: decl.init,
|
|
9549
|
+
}, decl, decl),
|
|
9550
|
+
}, decl, decl));
|
|
9586
9551
|
}
|
|
9587
|
-
|
|
9588
|
-
|
|
9589
|
-
|
|
9590
|
-
|
|
9552
|
+
});
|
|
9553
|
+
node.declarations = node.declarations.filter((decl) => {
|
|
9554
|
+
if (decl.type === "VariableDeclarator") {
|
|
9555
|
+
delete decl.init;
|
|
9556
|
+
return true;
|
|
9557
|
+
}
|
|
9558
|
+
return false;
|
|
9559
|
+
});
|
|
9560
|
+
if (node.declarations.length) {
|
|
9561
|
+
withLocDeep(node, node, false);
|
|
9562
|
+
results.unshift(node);
|
|
9591
9563
|
}
|
|
9592
|
-
|
|
9593
|
-
|
|
9594
|
-
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
9605
|
-
|
|
9606
|
-
|
|
9607
|
-
|
|
9608
|
-
|
|
9564
|
+
// if this was the init of a ForStatement, this will
|
|
9565
|
+
// replace its init with a BlockStatement, so we have to
|
|
9566
|
+
// fix that below.
|
|
9567
|
+
return results;
|
|
9568
|
+
}
|
|
9569
|
+
break;
|
|
9570
|
+
case "ForStatement":
|
|
9571
|
+
if (node.init) {
|
|
9572
|
+
if (node.init.type === "BlockStatement") {
|
|
9573
|
+
const result = node.init;
|
|
9574
|
+
delete node.init;
|
|
9575
|
+
result.body.push(node);
|
|
9576
|
+
if (node.loc && result.loc) {
|
|
9577
|
+
// result has the range of the original VariableDeclaration
|
|
9578
|
+
// but now we're moving that ahead of the 'for', so to keep
|
|
9579
|
+
// things straight, we need to set the for's start to be
|
|
9580
|
+
// where result ended, and result's end to be where the for
|
|
9581
|
+
// ends (since that block now encloses the for)
|
|
9582
|
+
node.start = result.end;
|
|
9583
|
+
node.loc.start = result.loc.end;
|
|
9584
|
+
result.end = node.end;
|
|
9585
|
+
result.loc.end = node.loc.end;
|
|
9586
|
+
}
|
|
9587
|
+
return result;
|
|
9588
|
+
}
|
|
9589
|
+
if (node.init.type === "Literal") {
|
|
9590
|
+
delete node.init;
|
|
9591
|
+
}
|
|
9592
|
+
}
|
|
9593
|
+
break;
|
|
9594
|
+
case "SequenceExpression":
|
|
9595
|
+
if (node.expressions.some((e) => e.type === "Literal")) {
|
|
9596
|
+
node.expressions = node.expressions.filter((e) => e.type !== "Literal");
|
|
9597
|
+
}
|
|
9598
|
+
break;
|
|
9599
|
+
}
|
|
9600
|
+
return null;
|
|
9601
|
+
}
|
|
9602
|
+
|
|
9603
|
+
|
|
9604
|
+
/***/ }),
|
|
9605
|
+
|
|
9606
|
+
/***/ 4416:
|
|
9607
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
9608
|
+
|
|
9609
|
+
"use strict";
|
|
9610
|
+
/* unused harmony export minimizeModules */
|
|
9611
|
+
/* harmony import */ var node_assert__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4143);
|
|
9612
|
+
/* harmony import */ var node_assert__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(node_assert__WEBPACK_IMPORTED_MODULE_0__);
|
|
9613
|
+
/* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6652);
|
|
9614
|
+
/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6817);
|
|
9615
|
+
/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_2__);
|
|
9616
|
+
|
|
9617
|
+
|
|
9618
|
+
|
|
9619
|
+
function minimizeModules(ast, state) {
|
|
9620
|
+
const { pre, post } = state;
|
|
9621
|
+
try {
|
|
9622
|
+
const replacementMap = new Map();
|
|
9623
|
+
const conflictingNames = new Set();
|
|
9624
|
+
state.pre = (node) => {
|
|
9625
|
+
if (state.inType)
|
|
9626
|
+
return null;
|
|
9627
|
+
switch (node.type) {
|
|
9628
|
+
case "ModuleDeclaration":
|
|
9629
|
+
case "ClassDeclaration":
|
|
9630
|
+
case "FunctionDeclaration":
|
|
9631
|
+
return ["body"];
|
|
9632
|
+
case "Using":
|
|
9633
|
+
conflictingNames.add(node.as?.name ??
|
|
9634
|
+
(node.id.type === "Identifier"
|
|
9635
|
+
? node.id.name
|
|
9636
|
+
: node.id.property.name));
|
|
9637
|
+
return [];
|
|
9638
|
+
case "ImportModule":
|
|
9639
|
+
conflictingNames.add(node.id.type === "Identifier" ? node.id.name : node.id.property.name);
|
|
9640
|
+
return [];
|
|
9641
|
+
case "Identifier":
|
|
9642
|
+
case "MemberExpression": {
|
|
9643
|
+
let current = node;
|
|
9644
|
+
const parts = [];
|
|
9645
|
+
while (current.type === "MemberExpression" && !current.computed) {
|
|
9646
|
+
parts.unshift(current);
|
|
9647
|
+
current = current.object;
|
|
9648
|
+
}
|
|
9649
|
+
if (current.type !== "Identifier" &&
|
|
9650
|
+
current.type !== "ThisExpression") {
|
|
9651
|
+
break;
|
|
9652
|
+
}
|
|
9653
|
+
let toReplace = null;
|
|
9654
|
+
let module = null;
|
|
9655
|
+
let addImport = false;
|
|
9656
|
+
let [, results] = state.lookupValue(current, null);
|
|
9657
|
+
let i = 0;
|
|
9658
|
+
for (; results &&
|
|
9659
|
+
results.length === 1 &&
|
|
9660
|
+
results[0].results.length === 1 &&
|
|
9661
|
+
(results[0].results[0].type === "Program" ||
|
|
9662
|
+
results[0].results[0].type === "ClassDeclaration" ||
|
|
9663
|
+
results[0].results[0].type === "ModuleDeclaration"); i++) {
|
|
9664
|
+
if (current.type === "Identifier" &&
|
|
9665
|
+
results[0].results[0].type === "ModuleDeclaration" &&
|
|
9666
|
+
isImportCandidate(results[0].results[0])) {
|
|
9667
|
+
const directResults = i
|
|
9668
|
+
? state.lookupValue(current, null)
|
|
9669
|
+
: results;
|
|
9670
|
+
if (directResults &&
|
|
9671
|
+
directResults.length === 1 &&
|
|
9672
|
+
directResults[0].results.length === 1 &&
|
|
9673
|
+
directResults[0].results[0] === results[0].results[0]) {
|
|
9674
|
+
// we would find the same thing if we just looked up
|
|
9675
|
+
// current directly.
|
|
9676
|
+
toReplace = (i ? parts[i - 1] : current);
|
|
9677
|
+
module = results[0].results[0];
|
|
9678
|
+
if (findUsingForNode(state, state.stack, state.stack.length - 1, current) === directResults[0].results[0]) {
|
|
9679
|
+
// we already find it via an import, so we don't need
|
|
9680
|
+
// a new import.
|
|
9681
|
+
addImport = false;
|
|
9682
|
+
}
|
|
9683
|
+
else {
|
|
9684
|
+
addImport = true;
|
|
9685
|
+
}
|
|
9686
|
+
}
|
|
9687
|
+
else {
|
|
9688
|
+
toReplace = parts[i - 1];
|
|
9689
|
+
module = results[0].results[0];
|
|
9690
|
+
addImport = true;
|
|
9691
|
+
}
|
|
9609
9692
|
}
|
|
9610
|
-
|
|
9693
|
+
if (i === parts.length)
|
|
9694
|
+
break;
|
|
9695
|
+
current = parts[i].property;
|
|
9696
|
+
results = lookupNext(state, results, "decls", current);
|
|
9697
|
+
}
|
|
9698
|
+
if (toReplace) {
|
|
9699
|
+
assert(module);
|
|
9700
|
+
replacementMap.set(toReplace, { module, addImport });
|
|
9701
|
+
}
|
|
9702
|
+
else if (parts.length === 0) {
|
|
9703
|
+
assert(node.type === "Identifier");
|
|
9704
|
+
conflictingNames.add(node.name);
|
|
9611
9705
|
}
|
|
9612
|
-
if (
|
|
9613
|
-
|
|
9706
|
+
else if (parts[0].object.type === "Identifier") {
|
|
9707
|
+
conflictingNames.add(parts[0].object.name);
|
|
9614
9708
|
}
|
|
9709
|
+
return [];
|
|
9615
9710
|
}
|
|
9616
|
-
|
|
9617
|
-
|
|
9618
|
-
|
|
9619
|
-
|
|
9711
|
+
}
|
|
9712
|
+
return null;
|
|
9713
|
+
};
|
|
9714
|
+
collectNamespaces(ast, state);
|
|
9715
|
+
const mappedNames = new Map();
|
|
9716
|
+
replacementMap.forEach((value, key) => {
|
|
9717
|
+
let name;
|
|
9718
|
+
if (value.addImport) {
|
|
9719
|
+
name = mappedNames.get(value.module);
|
|
9720
|
+
if (!name) {
|
|
9721
|
+
name = value.module.name;
|
|
9722
|
+
for (let i = 0; conflictingNames.has(name); i++) {
|
|
9723
|
+
name = `${value.module.name}_${i}`;
|
|
9724
|
+
}
|
|
9725
|
+
mappedNames.set(value.module, name);
|
|
9726
|
+
conflictingNames.add(name);
|
|
9620
9727
|
}
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9728
|
+
}
|
|
9729
|
+
else {
|
|
9730
|
+
name = key.type === "Identifier" ? key.name : key.property.name;
|
|
9731
|
+
}
|
|
9732
|
+
const original = formatAstLongLines(key);
|
|
9733
|
+
const repl = key;
|
|
9734
|
+
repl.type = "Identifier";
|
|
9735
|
+
repl.name = name;
|
|
9736
|
+
if (name !== original) {
|
|
9737
|
+
repl.original = original;
|
|
9738
|
+
}
|
|
9739
|
+
delete repl.property;
|
|
9740
|
+
delete repl.object;
|
|
9741
|
+
delete repl.computed;
|
|
9742
|
+
});
|
|
9743
|
+
mappedNames.forEach((name, module) => {
|
|
9744
|
+
const id = makeScopedName(module.fullName.slice(2));
|
|
9745
|
+
const as = name !== (id.type === "Identifier" ? id : id.property).name &&
|
|
9746
|
+
makeIdentifier(name);
|
|
9747
|
+
const using = withLocDeep(as ? { type: "Using", id, as } : { type: "Using", id }, ast, false, true);
|
|
9748
|
+
ast.body.unshift(using);
|
|
9749
|
+
});
|
|
9750
|
+
}
|
|
9751
|
+
finally {
|
|
9752
|
+
state.pre = pre;
|
|
9753
|
+
state.post = post;
|
|
9754
|
+
}
|
|
9755
|
+
}
|
|
9756
|
+
/**
|
|
9757
|
+
* There's a bug in garmin's runtime (although the compiler could
|
|
9758
|
+
* work around it). See
|
|
9759
|
+
*
|
|
9760
|
+
* https://forums.garmin.com/developer/connect-iq/i/bug-reports/referencing-an-imported-module-doesn-t-run-its-parent-s-init
|
|
9761
|
+
*
|
|
9762
|
+
* What this means is that if a module's parent isn't `globals`
|
|
9763
|
+
* and it needs to be initialized, then we can't risk
|
|
9764
|
+
* importing it, because the parent module might not get initialized
|
|
9765
|
+
* in time.
|
|
9766
|
+
*/
|
|
9767
|
+
function isImportCandidate(module) {
|
|
9768
|
+
if (module.fullName.startsWith("$.Toybox."))
|
|
9769
|
+
return true;
|
|
9770
|
+
if (module.fullName.startsWith("$.Rez."))
|
|
9771
|
+
return false;
|
|
9772
|
+
assert(module.stack);
|
|
9773
|
+
if (module.stack.length === 1)
|
|
9774
|
+
return true;
|
|
9775
|
+
return module.stack.every((elem) => {
|
|
9776
|
+
if (!elem.sn.decls)
|
|
9777
|
+
return false;
|
|
9778
|
+
if (elem.sn.type === "Program")
|
|
9779
|
+
return true;
|
|
9780
|
+
if (elem.sn.type !== "ModuleDeclaration")
|
|
9781
|
+
return false;
|
|
9782
|
+
return Object.values(elem.sn.decls).every((decls) => decls.every((decl) => {
|
|
9783
|
+
if (decl.type !== "VariableDeclarator")
|
|
9784
|
+
return true;
|
|
9785
|
+
if (!decl.node.init)
|
|
9786
|
+
return true;
|
|
9787
|
+
if (decl.node.init.type === "UnaryExpression" &&
|
|
9788
|
+
decl.node.init.operator === ":") {
|
|
9789
|
+
return true;
|
|
9790
|
+
}
|
|
9791
|
+
if (decl.node.init.type !== "Literal")
|
|
9792
|
+
return false;
|
|
9793
|
+
switch (typeof decl.node.init.value) {
|
|
9794
|
+
case "boolean":
|
|
9795
|
+
return true;
|
|
9796
|
+
case "bigint":
|
|
9797
|
+
return false;
|
|
9798
|
+
case "number":
|
|
9799
|
+
return !/[dl]$/i.test(decl.node.init.raw);
|
|
9800
|
+
case "object":
|
|
9801
|
+
return decl.node.init.value === null;
|
|
9802
|
+
}
|
|
9803
|
+
return false;
|
|
9804
|
+
}));
|
|
9625
9805
|
});
|
|
9626
|
-
return;
|
|
9627
9806
|
}
|
|
9628
9807
|
|
|
9629
9808
|
|