@markw65/monkeyc-optimizer 1.0.20 → 1.0.21
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 +9 -0
- package/build/api.cjs +62 -58
- package/build/optimizer.cjs +63 -50
- package/build/src/optimizer.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -235,3 +235,12 @@ More fixes found via open source projects.
|
|
|
235
235
|
|
|
236
236
|
- Code cleanup
|
|
237
237
|
- Called function cleanup
|
|
238
|
+
|
|
239
|
+
### 1.0.21
|
|
240
|
+
|
|
241
|
+
- Bug fixes
|
|
242
|
+
|
|
243
|
+
- Parameters from the calling function should be treated just line locals when inlining
|
|
244
|
+
- Upgrade to @markw65/prettier-plugin-monkeyc@1.0.24
|
|
245
|
+
- fixes crash with comments following an attribute: `(:foo) /* comment */ function foo() {}`
|
|
246
|
+
- Fix issues with recursive inlining
|
package/build/api.cjs
CHANGED
|
@@ -132,23 +132,32 @@ function getArgSafety(state, func, args, requireAll) {
|
|
|
132
132
|
// determine whether decl might be changed by a function call
|
|
133
133
|
// or assignment during the evaluation of FunctionStateNode.
|
|
134
134
|
const getSafety = (decl) => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (decl.type === "VariableDeclarator") {
|
|
139
|
-
// constants also can't change
|
|
140
|
-
if (decl.node.kind === "const")
|
|
135
|
+
switch (decl.type) {
|
|
136
|
+
// enums are constant, they cant change
|
|
137
|
+
case "EnumStringMember":
|
|
141
138
|
return true;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (!state.stack[i] || decl.stack[i] !== state.stack[i])
|
|
146
|
-
return false;
|
|
147
|
-
if (state.stack[i].type === "FunctionDeclaration")
|
|
139
|
+
case "VariableDeclarator": {
|
|
140
|
+
// constants also can't change
|
|
141
|
+
if (decl.node.kind === "const")
|
|
148
142
|
return true;
|
|
143
|
+
// if decl is a local, it also can't be changed
|
|
144
|
+
// by a call to another function.
|
|
145
|
+
for (let i = 0;; i++) {
|
|
146
|
+
if (!state.stack[i] || decl.stack[i] !== state.stack[i])
|
|
147
|
+
return false;
|
|
148
|
+
if (state.stack[i].type === "FunctionDeclaration")
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
149
151
|
}
|
|
152
|
+
case "Identifier":
|
|
153
|
+
case "BinaryExpression":
|
|
154
|
+
// This is a parameter of the calling function.
|
|
155
|
+
// It also can't be changed during the execution
|
|
156
|
+
// of the inlined function
|
|
157
|
+
return true;
|
|
158
|
+
default:
|
|
159
|
+
return null;
|
|
150
160
|
}
|
|
151
|
-
return null;
|
|
152
161
|
};
|
|
153
162
|
const safeArgs = [];
|
|
154
163
|
let allSafe = true;
|
|
@@ -267,8 +276,8 @@ function inlineRequested(state, func) {
|
|
|
267
276
|
state.fnMap[func.node.loc?.source]?.excludeAnnotations) ||
|
|
268
277
|
{};
|
|
269
278
|
if (func.node.attrs &&
|
|
270
|
-
func.node.attrs.
|
|
271
|
-
func.node.attrs.
|
|
279
|
+
func.node.attrs.attributes &&
|
|
280
|
+
func.node.attrs.attributes.elements.some((attr) => attr.type === "UnaryExpression" &&
|
|
272
281
|
(attr.argument.name === "inline" ||
|
|
273
282
|
(attr.argument.name.startsWith("inline_") &&
|
|
274
283
|
hasProperty(excludeAnnotations, attr.argument.name.substring(7)))))) {
|
|
@@ -277,6 +286,8 @@ function inlineRequested(state, func) {
|
|
|
277
286
|
return false;
|
|
278
287
|
}
|
|
279
288
|
function inliner_shouldInline(state, func, call, context) {
|
|
289
|
+
if (state.inlining)
|
|
290
|
+
return false;
|
|
280
291
|
let autoInline = false;
|
|
281
292
|
let inlineAsExpression = false;
|
|
282
293
|
const args = call.arguments;
|
|
@@ -309,6 +320,7 @@ function processInlineBody(state, func, call, root, insertedVariableDecls, param
|
|
|
309
320
|
let failed = false;
|
|
310
321
|
const pre = state.pre;
|
|
311
322
|
const post = state.post;
|
|
323
|
+
state.inlining = true;
|
|
312
324
|
try {
|
|
313
325
|
state.pre = (node) => {
|
|
314
326
|
if (failed)
|
|
@@ -354,7 +366,7 @@ function processInlineBody(state, func, call, root, insertedVariableDecls, param
|
|
|
354
366
|
};
|
|
355
367
|
state.post = (node) => {
|
|
356
368
|
if (failed)
|
|
357
|
-
return
|
|
369
|
+
return post(node, state);
|
|
358
370
|
let replacement = null;
|
|
359
371
|
switch (node.type) {
|
|
360
372
|
case "Identifier": {
|
|
@@ -371,12 +383,13 @@ function processInlineBody(state, func, call, root, insertedVariableDecls, param
|
|
|
371
383
|
if (!replacement) {
|
|
372
384
|
failed = true;
|
|
373
385
|
inlineDiagnostic(state, func, call, `Failed to resolve '${node.name}'`);
|
|
374
|
-
return
|
|
386
|
+
return post(node, state);
|
|
375
387
|
}
|
|
376
388
|
break;
|
|
377
389
|
}
|
|
378
390
|
}
|
|
379
|
-
|
|
391
|
+
const ret = post(replacement || node, state);
|
|
392
|
+
return ret === false || ret ? ret : replacement;
|
|
380
393
|
};
|
|
381
394
|
let ret = state.traverse(root);
|
|
382
395
|
if (failed) {
|
|
@@ -395,6 +408,7 @@ function processInlineBody(state, func, call, root, insertedVariableDecls, param
|
|
|
395
408
|
finally {
|
|
396
409
|
state.pre = pre;
|
|
397
410
|
state.post = post;
|
|
411
|
+
delete state.inlining;
|
|
398
412
|
}
|
|
399
413
|
}
|
|
400
414
|
function inliner_unused(expression, top) {
|
|
@@ -779,12 +793,12 @@ async function analyze(fnMap) {
|
|
|
779
793
|
shouldExclude(node) {
|
|
780
794
|
if ("attrs" in node &&
|
|
781
795
|
node.attrs &&
|
|
782
|
-
"
|
|
783
|
-
node.attrs.
|
|
796
|
+
"attributes" in node.attrs &&
|
|
797
|
+
node.attrs.attributes &&
|
|
784
798
|
node.loc?.source) {
|
|
785
799
|
const excludeAnnotations = fnMap[node.loc.source].excludeAnnotations;
|
|
786
800
|
if (excludeAnnotations) {
|
|
787
|
-
return node.attrs.
|
|
801
|
+
return node.attrs.attributes.elements.reduce((drop, attr) => {
|
|
788
802
|
if (attr.type != "UnaryExpression")
|
|
789
803
|
return drop;
|
|
790
804
|
if (attr.argument.type != "Identifier")
|
|
@@ -1100,7 +1114,13 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
1100
1114
|
exposed: {},
|
|
1101
1115
|
calledFunctions: {},
|
|
1102
1116
|
};
|
|
1103
|
-
const replace = (node
|
|
1117
|
+
const replace = (node) => {
|
|
1118
|
+
if (node === false || node === null)
|
|
1119
|
+
return node;
|
|
1120
|
+
const rep = state.traverse(node);
|
|
1121
|
+
return rep === false || rep ? rep : node;
|
|
1122
|
+
};
|
|
1123
|
+
const inPlaceReplacement = (node, obj) => {
|
|
1104
1124
|
for (const k of Object.keys(node)) {
|
|
1105
1125
|
delete node[k];
|
|
1106
1126
|
}
|
|
@@ -1125,7 +1145,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
1125
1145
|
if (!obj) {
|
|
1126
1146
|
return false;
|
|
1127
1147
|
}
|
|
1128
|
-
|
|
1148
|
+
inPlaceReplacement(node, obj);
|
|
1129
1149
|
return true;
|
|
1130
1150
|
};
|
|
1131
1151
|
const topLocals = () => state.localsStack[state.localsStack.length - 1];
|
|
@@ -1141,8 +1161,8 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
1141
1161
|
if (hasProperty(state.exposed, func.id.name))
|
|
1142
1162
|
return true;
|
|
1143
1163
|
if (func.attrs &&
|
|
1144
|
-
func.attrs.
|
|
1145
|
-
func.attrs.
|
|
1164
|
+
func.attrs.attributes &&
|
|
1165
|
+
func.attrs.attributes.elements.some((attr) => {
|
|
1146
1166
|
if (attr.type != "UnaryExpression")
|
|
1147
1167
|
return false;
|
|
1148
1168
|
if (attr.argument.type != "Identifier")
|
|
@@ -1315,8 +1335,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
1315
1335
|
}
|
|
1316
1336
|
const opt = optimizeNode(node);
|
|
1317
1337
|
if (opt) {
|
|
1318
|
-
replace(
|
|
1319
|
-
return null;
|
|
1338
|
+
return replace(opt);
|
|
1320
1339
|
}
|
|
1321
1340
|
switch (node.type) {
|
|
1322
1341
|
case "ConditionalExpression":
|
|
@@ -1326,7 +1345,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
1326
1345
|
const rep = node.test.value ? node.consequent : node.alternate;
|
|
1327
1346
|
if (!rep)
|
|
1328
1347
|
return false;
|
|
1329
|
-
replace(
|
|
1348
|
+
return replace(rep);
|
|
1330
1349
|
}
|
|
1331
1350
|
break;
|
|
1332
1351
|
case "WhileStatement":
|
|
@@ -1341,15 +1360,11 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
1341
1360
|
break;
|
|
1342
1361
|
case "ReturnStatement":
|
|
1343
1362
|
if (node.argument && node.argument.type === "CallExpression") {
|
|
1344
|
-
return optimizeCall(state, node.argument, node);
|
|
1363
|
+
return replace(optimizeCall(state, node.argument, node));
|
|
1345
1364
|
}
|
|
1346
1365
|
break;
|
|
1347
1366
|
case "CallExpression": {
|
|
1348
|
-
|
|
1349
|
-
if (ret) {
|
|
1350
|
-
replace(node, ret);
|
|
1351
|
-
}
|
|
1352
|
-
break;
|
|
1367
|
+
return replace(optimizeCall(state, node, null));
|
|
1353
1368
|
}
|
|
1354
1369
|
case "AssignmentExpression":
|
|
1355
1370
|
if (node.operator === "=" &&
|
|
@@ -1361,7 +1376,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
1361
1376
|
break;
|
|
1362
1377
|
case "ExpressionStatement":
|
|
1363
1378
|
if (node.expression.type === "CallExpression") {
|
|
1364
|
-
return optimizeCall(state, node.expression, node);
|
|
1379
|
+
return replace(optimizeCall(state, node.expression, node));
|
|
1365
1380
|
}
|
|
1366
1381
|
else if (node.expression.type === "AssignmentExpression") {
|
|
1367
1382
|
if (node.expression.right.type === "CallExpression") {
|
|
@@ -1376,11 +1391,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
1376
1391
|
ok = result != null;
|
|
1377
1392
|
}
|
|
1378
1393
|
if (ok) {
|
|
1379
|
-
|
|
1380
|
-
if (ret && ret.type === "BlockStatement") {
|
|
1381
|
-
const r2 = state.traverse(ret);
|
|
1382
|
-
return r2 === false || r2 ? r2 : ret;
|
|
1383
|
-
}
|
|
1394
|
+
return replace(optimizeCall(state, node.expression.right, node.expression));
|
|
1384
1395
|
}
|
|
1385
1396
|
}
|
|
1386
1397
|
}
|
|
@@ -1388,12 +1399,9 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
1388
1399
|
const ret = unused(node.expression, true);
|
|
1389
1400
|
if (ret) {
|
|
1390
1401
|
return ret
|
|
1391
|
-
.map(
|
|
1392
|
-
const r2 = state.traverse(s);
|
|
1393
|
-
return r2 === false || r2 ? r2 : s;
|
|
1394
|
-
})
|
|
1402
|
+
.map(replace)
|
|
1395
1403
|
.flat(1)
|
|
1396
|
-
.filter((s) => s
|
|
1404
|
+
.filter((s) => !!s);
|
|
1397
1405
|
}
|
|
1398
1406
|
}
|
|
1399
1407
|
break;
|
|
@@ -1436,19 +1444,24 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
1436
1444
|
if (!node.body.members.length) {
|
|
1437
1445
|
if (!node.id)
|
|
1438
1446
|
return false;
|
|
1439
|
-
if (!node.body
|
|
1447
|
+
if (!node.body.enumType) {
|
|
1440
1448
|
throw new Error("Missing enumType on optimized enum");
|
|
1441
1449
|
}
|
|
1442
|
-
|
|
1450
|
+
return {
|
|
1443
1451
|
type: "TypedefDeclaration",
|
|
1444
1452
|
id: node.id,
|
|
1445
1453
|
ts: {
|
|
1446
1454
|
type: "UnaryExpression",
|
|
1447
|
-
argument: {
|
|
1455
|
+
argument: {
|
|
1456
|
+
type: "TypeSpecList",
|
|
1457
|
+
ts: [
|
|
1458
|
+
node.body.enumType,
|
|
1459
|
+
],
|
|
1460
|
+
},
|
|
1448
1461
|
prefix: true,
|
|
1449
1462
|
operator: " as",
|
|
1450
1463
|
},
|
|
1451
|
-
}
|
|
1464
|
+
};
|
|
1452
1465
|
}
|
|
1453
1466
|
break;
|
|
1454
1467
|
case "VariableDeclaration": {
|
|
@@ -2055,15 +2068,6 @@ function api_traverseAst(node, pre, post) {
|
|
|
2055
2068
|
return post && post(node);
|
|
2056
2069
|
}
|
|
2057
2070
|
function formatAst(node, monkeyCSource = null) {
|
|
2058
|
-
if ("comments" in node && !monkeyCSource) {
|
|
2059
|
-
// Prettier inserts comments by using the source location to
|
|
2060
|
-
// find the original comment, rather than using the contents
|
|
2061
|
-
// of the comment as reported by the comment nodes themselves.
|
|
2062
|
-
// If all we've got is the ast, rather than the actual
|
|
2063
|
-
// source code, this goes horribly wrong, so just drop all
|
|
2064
|
-
// the comments.
|
|
2065
|
-
delete node.comments;
|
|
2066
|
-
}
|
|
2067
2071
|
/*
|
|
2068
2072
|
* The estree printer sometimes looks at the parent node without
|
|
2069
2073
|
* checking that there *is* a parent node (eg it assumes all
|
package/build/optimizer.cjs
CHANGED
|
@@ -10853,23 +10853,32 @@ function getArgSafety(state, func, args, requireAll) {
|
|
|
10853
10853
|
// determine whether decl might be changed by a function call
|
|
10854
10854
|
// or assignment during the evaluation of FunctionStateNode.
|
|
10855
10855
|
const getSafety = (decl) => {
|
|
10856
|
-
|
|
10857
|
-
|
|
10858
|
-
|
|
10859
|
-
if (decl.type === "VariableDeclarator") {
|
|
10860
|
-
// constants also can't change
|
|
10861
|
-
if (decl.node.kind === "const")
|
|
10856
|
+
switch (decl.type) {
|
|
10857
|
+
// enums are constant, they cant change
|
|
10858
|
+
case "EnumStringMember":
|
|
10862
10859
|
return true;
|
|
10863
|
-
|
|
10864
|
-
|
|
10865
|
-
|
|
10866
|
-
if (!state.stack[i] || decl.stack[i] !== state.stack[i])
|
|
10867
|
-
return false;
|
|
10868
|
-
if (state.stack[i].type === "FunctionDeclaration")
|
|
10860
|
+
case "VariableDeclarator": {
|
|
10861
|
+
// constants also can't change
|
|
10862
|
+
if (decl.node.kind === "const")
|
|
10869
10863
|
return true;
|
|
10864
|
+
// if decl is a local, it also can't be changed
|
|
10865
|
+
// by a call to another function.
|
|
10866
|
+
for (let i = 0;; i++) {
|
|
10867
|
+
if (!state.stack[i] || decl.stack[i] !== state.stack[i])
|
|
10868
|
+
return false;
|
|
10869
|
+
if (state.stack[i].type === "FunctionDeclaration")
|
|
10870
|
+
return true;
|
|
10871
|
+
}
|
|
10870
10872
|
}
|
|
10873
|
+
case "Identifier":
|
|
10874
|
+
case "BinaryExpression":
|
|
10875
|
+
// This is a parameter of the calling function.
|
|
10876
|
+
// It also can't be changed during the execution
|
|
10877
|
+
// of the inlined function
|
|
10878
|
+
return true;
|
|
10879
|
+
default:
|
|
10880
|
+
return null;
|
|
10871
10881
|
}
|
|
10872
|
-
return null;
|
|
10873
10882
|
};
|
|
10874
10883
|
const safeArgs = [];
|
|
10875
10884
|
let allSafe = true;
|
|
@@ -10988,8 +10997,8 @@ function inlineRequested(state, func) {
|
|
|
10988
10997
|
state.fnMap[func.node.loc?.source]?.excludeAnnotations) ||
|
|
10989
10998
|
{};
|
|
10990
10999
|
if (func.node.attrs &&
|
|
10991
|
-
func.node.attrs.
|
|
10992
|
-
func.node.attrs.
|
|
11000
|
+
func.node.attrs.attributes &&
|
|
11001
|
+
func.node.attrs.attributes.elements.some((attr) => attr.type === "UnaryExpression" &&
|
|
10993
11002
|
(attr.argument.name === "inline" ||
|
|
10994
11003
|
(attr.argument.name.startsWith("inline_") &&
|
|
10995
11004
|
(0,external_api_cjs_namespaceObject.hasProperty)(excludeAnnotations, attr.argument.name.substring(7)))))) {
|
|
@@ -10998,6 +11007,8 @@ function inlineRequested(state, func) {
|
|
|
10998
11007
|
return false;
|
|
10999
11008
|
}
|
|
11000
11009
|
function shouldInline(state, func, call, context) {
|
|
11010
|
+
if (state.inlining)
|
|
11011
|
+
return false;
|
|
11001
11012
|
let autoInline = false;
|
|
11002
11013
|
let inlineAsExpression = false;
|
|
11003
11014
|
const args = call.arguments;
|
|
@@ -11030,6 +11041,7 @@ function processInlineBody(state, func, call, root, insertedVariableDecls, param
|
|
|
11030
11041
|
let failed = false;
|
|
11031
11042
|
const pre = state.pre;
|
|
11032
11043
|
const post = state.post;
|
|
11044
|
+
state.inlining = true;
|
|
11033
11045
|
try {
|
|
11034
11046
|
state.pre = (node) => {
|
|
11035
11047
|
if (failed)
|
|
@@ -11075,7 +11087,7 @@ function processInlineBody(state, func, call, root, insertedVariableDecls, param
|
|
|
11075
11087
|
};
|
|
11076
11088
|
state.post = (node) => {
|
|
11077
11089
|
if (failed)
|
|
11078
|
-
return
|
|
11090
|
+
return post(node, state);
|
|
11079
11091
|
let replacement = null;
|
|
11080
11092
|
switch (node.type) {
|
|
11081
11093
|
case "Identifier": {
|
|
@@ -11092,12 +11104,13 @@ function processInlineBody(state, func, call, root, insertedVariableDecls, param
|
|
|
11092
11104
|
if (!replacement) {
|
|
11093
11105
|
failed = true;
|
|
11094
11106
|
inlineDiagnostic(state, func, call, `Failed to resolve '${node.name}'`);
|
|
11095
|
-
return
|
|
11107
|
+
return post(node, state);
|
|
11096
11108
|
}
|
|
11097
11109
|
break;
|
|
11098
11110
|
}
|
|
11099
11111
|
}
|
|
11100
|
-
|
|
11112
|
+
const ret = post(replacement || node, state);
|
|
11113
|
+
return ret === false || ret ? ret : replacement;
|
|
11101
11114
|
};
|
|
11102
11115
|
let ret = state.traverse(root);
|
|
11103
11116
|
if (failed) {
|
|
@@ -11116,6 +11129,7 @@ function processInlineBody(state, func, call, root, insertedVariableDecls, param
|
|
|
11116
11129
|
finally {
|
|
11117
11130
|
state.pre = pre;
|
|
11118
11131
|
state.post = post;
|
|
11132
|
+
delete state.inlining;
|
|
11119
11133
|
}
|
|
11120
11134
|
}
|
|
11121
11135
|
function unused(expression, top) {
|
|
@@ -11497,12 +11511,12 @@ async function analyze(fnMap) {
|
|
|
11497
11511
|
shouldExclude(node) {
|
|
11498
11512
|
if ("attrs" in node &&
|
|
11499
11513
|
node.attrs &&
|
|
11500
|
-
"
|
|
11501
|
-
node.attrs.
|
|
11514
|
+
"attributes" in node.attrs &&
|
|
11515
|
+
node.attrs.attributes &&
|
|
11502
11516
|
node.loc?.source) {
|
|
11503
11517
|
const excludeAnnotations = fnMap[node.loc.source].excludeAnnotations;
|
|
11504
11518
|
if (excludeAnnotations) {
|
|
11505
|
-
return node.attrs.
|
|
11519
|
+
return node.attrs.attributes.elements.reduce((drop, attr) => {
|
|
11506
11520
|
if (attr.type != "UnaryExpression")
|
|
11507
11521
|
return drop;
|
|
11508
11522
|
if (attr.argument.type != "Identifier")
|
|
@@ -11818,7 +11832,13 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11818
11832
|
exposed: {},
|
|
11819
11833
|
calledFunctions: {},
|
|
11820
11834
|
};
|
|
11821
|
-
const replace = (node
|
|
11835
|
+
const replace = (node) => {
|
|
11836
|
+
if (node === false || node === null)
|
|
11837
|
+
return node;
|
|
11838
|
+
const rep = state.traverse(node);
|
|
11839
|
+
return rep === false || rep ? rep : node;
|
|
11840
|
+
};
|
|
11841
|
+
const inPlaceReplacement = (node, obj) => {
|
|
11822
11842
|
for (const k of Object.keys(node)) {
|
|
11823
11843
|
delete node[k];
|
|
11824
11844
|
}
|
|
@@ -11843,7 +11863,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11843
11863
|
if (!obj) {
|
|
11844
11864
|
return false;
|
|
11845
11865
|
}
|
|
11846
|
-
|
|
11866
|
+
inPlaceReplacement(node, obj);
|
|
11847
11867
|
return true;
|
|
11848
11868
|
};
|
|
11849
11869
|
const topLocals = () => state.localsStack[state.localsStack.length - 1];
|
|
@@ -11859,8 +11879,8 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11859
11879
|
if ((0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, func.id.name))
|
|
11860
11880
|
return true;
|
|
11861
11881
|
if (func.attrs &&
|
|
11862
|
-
func.attrs.
|
|
11863
|
-
func.attrs.
|
|
11882
|
+
func.attrs.attributes &&
|
|
11883
|
+
func.attrs.attributes.elements.some((attr) => {
|
|
11864
11884
|
if (attr.type != "UnaryExpression")
|
|
11865
11885
|
return false;
|
|
11866
11886
|
if (attr.argument.type != "Identifier")
|
|
@@ -12033,8 +12053,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
12033
12053
|
}
|
|
12034
12054
|
const opt = optimizeNode(node);
|
|
12035
12055
|
if (opt) {
|
|
12036
|
-
replace(
|
|
12037
|
-
return null;
|
|
12056
|
+
return replace(opt);
|
|
12038
12057
|
}
|
|
12039
12058
|
switch (node.type) {
|
|
12040
12059
|
case "ConditionalExpression":
|
|
@@ -12044,7 +12063,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
12044
12063
|
const rep = node.test.value ? node.consequent : node.alternate;
|
|
12045
12064
|
if (!rep)
|
|
12046
12065
|
return false;
|
|
12047
|
-
replace(
|
|
12066
|
+
return replace(rep);
|
|
12048
12067
|
}
|
|
12049
12068
|
break;
|
|
12050
12069
|
case "WhileStatement":
|
|
@@ -12059,15 +12078,11 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
12059
12078
|
break;
|
|
12060
12079
|
case "ReturnStatement":
|
|
12061
12080
|
if (node.argument && node.argument.type === "CallExpression") {
|
|
12062
|
-
return optimizeCall(state, node.argument, node);
|
|
12081
|
+
return replace(optimizeCall(state, node.argument, node));
|
|
12063
12082
|
}
|
|
12064
12083
|
break;
|
|
12065
12084
|
case "CallExpression": {
|
|
12066
|
-
|
|
12067
|
-
if (ret) {
|
|
12068
|
-
replace(node, ret);
|
|
12069
|
-
}
|
|
12070
|
-
break;
|
|
12085
|
+
return replace(optimizeCall(state, node, null));
|
|
12071
12086
|
}
|
|
12072
12087
|
case "AssignmentExpression":
|
|
12073
12088
|
if (node.operator === "=" &&
|
|
@@ -12079,7 +12094,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
12079
12094
|
break;
|
|
12080
12095
|
case "ExpressionStatement":
|
|
12081
12096
|
if (node.expression.type === "CallExpression") {
|
|
12082
|
-
return optimizeCall(state, node.expression, node);
|
|
12097
|
+
return replace(optimizeCall(state, node.expression, node));
|
|
12083
12098
|
}
|
|
12084
12099
|
else if (node.expression.type === "AssignmentExpression") {
|
|
12085
12100
|
if (node.expression.right.type === "CallExpression") {
|
|
@@ -12094,11 +12109,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
12094
12109
|
ok = result != null;
|
|
12095
12110
|
}
|
|
12096
12111
|
if (ok) {
|
|
12097
|
-
|
|
12098
|
-
if (ret && ret.type === "BlockStatement") {
|
|
12099
|
-
const r2 = state.traverse(ret);
|
|
12100
|
-
return r2 === false || r2 ? r2 : ret;
|
|
12101
|
-
}
|
|
12112
|
+
return replace(optimizeCall(state, node.expression.right, node.expression));
|
|
12102
12113
|
}
|
|
12103
12114
|
}
|
|
12104
12115
|
}
|
|
@@ -12106,12 +12117,9 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
12106
12117
|
const ret = unused(node.expression, true);
|
|
12107
12118
|
if (ret) {
|
|
12108
12119
|
return ret
|
|
12109
|
-
.map(
|
|
12110
|
-
const r2 = state.traverse(s);
|
|
12111
|
-
return r2 === false || r2 ? r2 : s;
|
|
12112
|
-
})
|
|
12120
|
+
.map(replace)
|
|
12113
12121
|
.flat(1)
|
|
12114
|
-
.filter((s) => s
|
|
12122
|
+
.filter((s) => !!s);
|
|
12115
12123
|
}
|
|
12116
12124
|
}
|
|
12117
12125
|
break;
|
|
@@ -12154,19 +12162,24 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
12154
12162
|
if (!node.body.members.length) {
|
|
12155
12163
|
if (!node.id)
|
|
12156
12164
|
return false;
|
|
12157
|
-
if (!node.body
|
|
12165
|
+
if (!node.body.enumType) {
|
|
12158
12166
|
throw new Error("Missing enumType on optimized enum");
|
|
12159
12167
|
}
|
|
12160
|
-
|
|
12168
|
+
return {
|
|
12161
12169
|
type: "TypedefDeclaration",
|
|
12162
12170
|
id: node.id,
|
|
12163
12171
|
ts: {
|
|
12164
12172
|
type: "UnaryExpression",
|
|
12165
|
-
argument: {
|
|
12173
|
+
argument: {
|
|
12174
|
+
type: "TypeSpecList",
|
|
12175
|
+
ts: [
|
|
12176
|
+
node.body.enumType,
|
|
12177
|
+
],
|
|
12178
|
+
},
|
|
12166
12179
|
prefix: true,
|
|
12167
12180
|
operator: " as",
|
|
12168
12181
|
},
|
|
12169
|
-
}
|
|
12182
|
+
};
|
|
12170
12183
|
}
|
|
12171
12184
|
break;
|
|
12172
12185
|
case "VariableDeclaration": {
|
|
@@ -12740,7 +12753,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
12740
12753
|
// the oldest optimized file, we don't need to regenerate
|
|
12741
12754
|
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
12742
12755
|
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
12743
|
-
if (source_time < opt_time &&
|
|
12756
|
+
if (source_time < opt_time && 1654811717108 < opt_time) {
|
|
12744
12757
|
return { hasTests, diagnostics: prevDiagnostics };
|
|
12745
12758
|
}
|
|
12746
12759
|
}
|
package/build/src/optimizer.d.ts
CHANGED
|
@@ -117,6 +117,7 @@ declare global {
|
|
|
117
117
|
lookupType?: (node: mctree.Node, name?: string | null, stack?: ProgramStateStack) => [string, StateNodeDecl[], ProgramStateStack] | [null, null, null];
|
|
118
118
|
traverse?: (node: mctree.Node) => void | null | false | mctree.Node | mctree.Node[];
|
|
119
119
|
inType?: boolean;
|
|
120
|
+
inlining?: true;
|
|
120
121
|
exposed?: {
|
|
121
122
|
[key: string]: true;
|
|
122
123
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markw65/monkeyc-optimizer",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.21",
|
|
5
5
|
"description": "Source to source optimizer for Garmin Monkey C code",
|
|
6
6
|
"main": "build/optimizer.cjs",
|
|
7
7
|
"types": "build/src/optimizer.d.ts",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"author": "markw65",
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@markw65/prettier-plugin-monkeyc": "^1.0.
|
|
37
|
+
"@markw65/prettier-plugin-monkeyc": "^1.0.24"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/glob": "^7.2.0",
|