@markw65/monkeyc-optimizer 1.0.39 → 1.0.40
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 +23 -0
- package/build/api.cjs +270 -65
- package/build/optimizer.cjs +118 -54
- package/build/sdk-util.cjs +3 -2
- package/build/src/api.d.ts +10 -2
- package/build/src/inliner.d.ts +2 -2
- package/build/src/jungles.d.ts +1 -1
- package/build/src/launch.d.ts +1 -1
- package/build/src/optimizer-types.d.ts +16 -2
- package/build/src/projects.d.ts +2 -0
- package/build/src/xml-util.d.ts +2 -1
- package/package.json +3 -2
package/build/optimizer.cjs
CHANGED
|
@@ -3977,7 +3977,7 @@ async function resolve_literals(qualifier, default_source, deviceInfo) {
|
|
|
3977
3977
|
qualifier.annotations = annotations;
|
|
3978
3978
|
return qualifier;
|
|
3979
3979
|
}
|
|
3980
|
-
async function read_resource_files(targets) {
|
|
3980
|
+
async function read_resource_files(targets, cache) {
|
|
3981
3981
|
const resourceGroups = {};
|
|
3982
3982
|
const resources = {};
|
|
3983
3983
|
await Promise.all(targets.map(async (p) => {
|
|
@@ -3993,8 +3993,16 @@ async function read_resource_files(targets) {
|
|
|
3993
3993
|
.flat()
|
|
3994
3994
|
.filter((file) => file.endsWith(".xml"))
|
|
3995
3995
|
.map((file) => {
|
|
3996
|
-
if (
|
|
3997
|
-
|
|
3996
|
+
if (!cache.resources) {
|
|
3997
|
+
cache.resources = {};
|
|
3998
|
+
}
|
|
3999
|
+
else if ((0,external_api_cjs_namespaceObject.hasProperty)(cache.resources, file)) {
|
|
4000
|
+
const rez = cache.resources[file];
|
|
4001
|
+
resources[file] = rez;
|
|
4002
|
+
return {
|
|
4003
|
+
path: file,
|
|
4004
|
+
resources: rez,
|
|
4005
|
+
};
|
|
3998
4006
|
}
|
|
3999
4007
|
return promises_namespaceObject.readFile(file)
|
|
4000
4008
|
.then((data) => external_sdk_util_cjs_namespaceObject.xmlUtil.parseXml(data.toString(), file))
|
|
@@ -4002,7 +4010,7 @@ async function read_resource_files(targets) {
|
|
|
4002
4010
|
? e
|
|
4003
4011
|
: new Error("An unknown error occurred"))
|
|
4004
4012
|
.then((rez) => {
|
|
4005
|
-
resources[file] = rez;
|
|
4013
|
+
cache.resources[file] = resources[file] = rez;
|
|
4006
4014
|
return {
|
|
4007
4015
|
path: file,
|
|
4008
4016
|
resources: rez,
|
|
@@ -4408,13 +4416,13 @@ async function get_jungle_and_barrels(jungleFiles, defaultProducts, options, cac
|
|
|
4408
4416
|
}
|
|
4409
4417
|
});
|
|
4410
4418
|
await promise;
|
|
4411
|
-
const { resourceGroups, resources } = await read_resource_files(targets);
|
|
4419
|
+
const { resourceGroups, resources } = await read_resource_files(targets, cache);
|
|
4412
4420
|
await find_build_instructions(targets, resourceGroups);
|
|
4413
4421
|
return { manifest, targets, xml, annotations, jungles, resources };
|
|
4414
4422
|
}
|
|
4415
|
-
async function get_jungle(jungles, options) {
|
|
4423
|
+
async function get_jungle(jungles, options, resources) {
|
|
4416
4424
|
options = options || {};
|
|
4417
|
-
const cache = {};
|
|
4425
|
+
const cache = resources ? { resources: { ...resources } } : {};
|
|
4418
4426
|
const result = await get_jungle_and_barrels(jungles, null, options, cache);
|
|
4419
4427
|
identify_optimizer_groups(result.targets, options);
|
|
4420
4428
|
return result;
|
|
@@ -4460,8 +4468,12 @@ function checkIfSimulatorRunningOn(port) {
|
|
|
4460
4468
|
}
|
|
4461
4469
|
function simulateProgram(prg, device, test = false, logger) {
|
|
4462
4470
|
const args = [prg, device];
|
|
4463
|
-
if (test)
|
|
4471
|
+
if (test) {
|
|
4464
4472
|
args.push(external_sdk_util_cjs_namespaceObject.isWin ? "/t" : "-t");
|
|
4473
|
+
if (typeof test === "string") {
|
|
4474
|
+
args.push(test);
|
|
4475
|
+
}
|
|
4476
|
+
}
|
|
4465
4477
|
return (0,external_sdk_util_cjs_namespaceObject.getSdkPath)().then((sdk) => (0,external_util_cjs_namespaceObject.spawnByLine)(external_path_.resolve(sdk, "bin", external_sdk_util_cjs_namespaceObject.isWin ? "monkeydo.bat" : "monkeydo"), args, logger || ((line) => console.log(line))).then(() => {
|
|
4466
4478
|
return;
|
|
4467
4479
|
}));
|
|
@@ -4835,6 +4847,15 @@ function findCalleesForNew(lookupDefs) {
|
|
|
4835
4847
|
.filter((decl) => decl ? decl.type === "FunctionDeclaration" : false));
|
|
4836
4848
|
}
|
|
4837
4849
|
|
|
4850
|
+
;// CONCATENATED MODULE: ./src/optimizer-types.ts
|
|
4851
|
+
var StateNodeAttributes;
|
|
4852
|
+
(function (StateNodeAttributes) {
|
|
4853
|
+
StateNodeAttributes[StateNodeAttributes["PUBLIC"] = 1] = "PUBLIC";
|
|
4854
|
+
StateNodeAttributes[StateNodeAttributes["PROTECTED"] = 2] = "PROTECTED";
|
|
4855
|
+
StateNodeAttributes[StateNodeAttributes["PRIVATE"] = 4] = "PRIVATE";
|
|
4856
|
+
StateNodeAttributes[StateNodeAttributes["STATIC"] = 8] = "STATIC";
|
|
4857
|
+
})(StateNodeAttributes || (StateNodeAttributes = {}));
|
|
4858
|
+
|
|
4838
4859
|
;// CONCATENATED MODULE: ./src/variable-renamer.ts
|
|
4839
4860
|
|
|
4840
4861
|
|
|
@@ -4901,6 +4922,7 @@ function renameVariable(state, locals, declName) {
|
|
|
4901
4922
|
|
|
4902
4923
|
|
|
4903
4924
|
|
|
4925
|
+
|
|
4904
4926
|
// Note: Keep in sync with replaceInlinedSubExpression below
|
|
4905
4927
|
function inlinableSubExpression(expr) {
|
|
4906
4928
|
while (true) {
|
|
@@ -5220,6 +5242,12 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
5220
5242
|
state.inlining = true;
|
|
5221
5243
|
let insertedVariableDecls = null;
|
|
5222
5244
|
const replacements = new Set();
|
|
5245
|
+
// lookup determines static-ness of the lookup context based on seeing
|
|
5246
|
+
// a static FunctionDeclaration, but the FunctionDeclaration's stack
|
|
5247
|
+
// doesn't include the FunctionDeclaration itself.
|
|
5248
|
+
const stack = func.attributes & StateNodeAttributes.STATIC
|
|
5249
|
+
? func.stack.concat(func)
|
|
5250
|
+
: func.stack;
|
|
5223
5251
|
try {
|
|
5224
5252
|
state.pre = (node) => {
|
|
5225
5253
|
if (failed)
|
|
@@ -5269,7 +5297,7 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
5269
5297
|
}
|
|
5270
5298
|
return null;
|
|
5271
5299
|
}
|
|
5272
|
-
const replacement = fixNodeScope(state, node,
|
|
5300
|
+
const replacement = fixNodeScope(state, node, stack);
|
|
5273
5301
|
if (!replacement) {
|
|
5274
5302
|
failed = true;
|
|
5275
5303
|
inlineDiagnostic(state, func, call, `Failed to resolve '${node.name}'`);
|
|
@@ -5324,7 +5352,7 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
5324
5352
|
delete state.inlining;
|
|
5325
5353
|
}
|
|
5326
5354
|
}
|
|
5327
|
-
function unused(expression, top) {
|
|
5355
|
+
function unused(state, expression, top) {
|
|
5328
5356
|
const estmt = (expression) => withLoc({
|
|
5329
5357
|
type: "ExpressionStatement",
|
|
5330
5358
|
expression,
|
|
@@ -5338,19 +5366,19 @@ function unused(expression, top) {
|
|
|
5338
5366
|
return [];
|
|
5339
5367
|
case "BinaryExpression":
|
|
5340
5368
|
if (expression.operator === "as") {
|
|
5341
|
-
return unused(expression.left);
|
|
5369
|
+
return unused(state, expression.left);
|
|
5342
5370
|
}
|
|
5343
|
-
return unused(expression.left).concat(unused(expression.right));
|
|
5371
|
+
return unused(state, expression.left).concat(unused(state, expression.right));
|
|
5344
5372
|
case "LogicalExpression": {
|
|
5345
|
-
const right = unused(expression.right);
|
|
5373
|
+
const right = unused(state, expression.right);
|
|
5346
5374
|
if (!right.length)
|
|
5347
|
-
return unused(expression.left);
|
|
5375
|
+
return unused(state, expression.left);
|
|
5348
5376
|
const consequent = withLoc({
|
|
5349
5377
|
type: "BlockStatement",
|
|
5350
5378
|
body: [estmt(expression.right)],
|
|
5351
5379
|
}, expression.right);
|
|
5352
5380
|
let alternate;
|
|
5353
|
-
if (expression.operator == "||") {
|
|
5381
|
+
if (expression.operator == "||" || expression.operator == "or") {
|
|
5354
5382
|
alternate = { ...consequent };
|
|
5355
5383
|
consequent.body = [];
|
|
5356
5384
|
}
|
|
@@ -5364,10 +5392,10 @@ function unused(expression, top) {
|
|
|
5364
5392
|
];
|
|
5365
5393
|
}
|
|
5366
5394
|
case "ConditionalExpression": {
|
|
5367
|
-
const consequentExprs = unused(expression.consequent);
|
|
5368
|
-
const alternateExprs = unused(expression.alternate);
|
|
5395
|
+
const consequentExprs = unused(state, expression.consequent);
|
|
5396
|
+
const alternateExprs = unused(state, expression.alternate);
|
|
5369
5397
|
if (!consequentExprs.length && !alternateExprs.length) {
|
|
5370
|
-
return unused(expression.test);
|
|
5398
|
+
return unused(state, expression.test);
|
|
5371
5399
|
}
|
|
5372
5400
|
return [
|
|
5373
5401
|
withLoc({
|
|
@@ -5385,20 +5413,24 @@ function unused(expression, top) {
|
|
|
5385
5413
|
];
|
|
5386
5414
|
}
|
|
5387
5415
|
case "UnaryExpression":
|
|
5388
|
-
return unused(expression.argument);
|
|
5416
|
+
return unused(state, expression.argument);
|
|
5389
5417
|
case "MemberExpression":
|
|
5390
5418
|
if (expression.computed) {
|
|
5391
|
-
return unused(expression.object).concat(unused(expression.property));
|
|
5419
|
+
return unused(state, expression.object).concat(unused(state, expression.property));
|
|
5392
5420
|
}
|
|
5393
|
-
if (
|
|
5421
|
+
if ((state.sdkVersion || 0) < 4001007 &&
|
|
5422
|
+
expression.object.type === "NewExpression") {
|
|
5423
|
+
// prior to 4.1.7 top level new expressions were discarded,
|
|
5424
|
+
// but (new X()).a was not. After 4.1.7, top level new is
|
|
5425
|
+
// executed, but top level (new X()).a is an error.
|
|
5394
5426
|
break;
|
|
5395
5427
|
}
|
|
5396
|
-
return unused(expression.object);
|
|
5428
|
+
return unused(state, expression.object);
|
|
5397
5429
|
case "ArrayExpression":
|
|
5398
|
-
return expression.elements.map((e) => unused(e)).flat(1);
|
|
5430
|
+
return expression.elements.map((e) => unused(state, e)).flat(1);
|
|
5399
5431
|
case "ObjectExpression":
|
|
5400
5432
|
return expression.properties
|
|
5401
|
-
.map((p) => unused(p.key).concat(unused(p.value)))
|
|
5433
|
+
.map((p) => unused(state, p.key).concat(unused(state, p.value)))
|
|
5402
5434
|
.flat(1);
|
|
5403
5435
|
}
|
|
5404
5436
|
return top ? null : [estmt(expression)];
|
|
@@ -5558,7 +5590,7 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
5558
5590
|
];
|
|
5559
5591
|
}
|
|
5560
5592
|
else {
|
|
5561
|
-
const side_exprs = unused(last.argument);
|
|
5593
|
+
const side_exprs = unused(state, last.argument);
|
|
5562
5594
|
block.body.splice(block.body.length - 1, 1, ...side_exprs);
|
|
5563
5595
|
}
|
|
5564
5596
|
}
|
|
@@ -5693,7 +5725,7 @@ function pragmaChecker(state, ast, diagnostics) {
|
|
|
5693
5725
|
return;
|
|
5694
5726
|
diagnostics = diagnostics
|
|
5695
5727
|
?.slice()
|
|
5696
|
-
.sort((d1, d2) => d1.loc.start
|
|
5728
|
+
.sort((d1, d2) => d1.loc.start.offset - d2.loc.start.offset);
|
|
5697
5729
|
let diagIndex = 0;
|
|
5698
5730
|
let index = -1;
|
|
5699
5731
|
let comment;
|
|
@@ -5706,6 +5738,12 @@ function pragmaChecker(state, ast, diagnostics) {
|
|
|
5706
5738
|
continue;
|
|
5707
5739
|
const kind = match[1];
|
|
5708
5740
|
let str = match[2];
|
|
5741
|
+
const verCheck = (0,external_api_cjs_namespaceObject.checkCompilerVersion)(str.replace(/\s.*/, ""), state.sdkVersion || 0);
|
|
5742
|
+
if (verCheck === false)
|
|
5743
|
+
continue;
|
|
5744
|
+
if (verCheck === true) {
|
|
5745
|
+
str = str.replace(/^\S+\s+/, "");
|
|
5746
|
+
}
|
|
5709
5747
|
matchers = [];
|
|
5710
5748
|
while ((match = str.match(/^([/%&#@"])(.+?(?<!\\)(?:\\{2})*)\1(\s+|$)/))) {
|
|
5711
5749
|
matchers.push({ kind, quote: match[1], needle: match[2] });
|
|
@@ -7258,7 +7296,7 @@ function cleanupUnusedVars(state, node) {
|
|
|
7258
7296
|
if (node.expression.type === "AssignmentExpression") {
|
|
7259
7297
|
if (node.expression.left.type === "Identifier" &&
|
|
7260
7298
|
hasProperty(toRemove, node.expression.left.name)) {
|
|
7261
|
-
return unused(node.expression.right);
|
|
7299
|
+
return unused(state, node.expression.right);
|
|
7262
7300
|
}
|
|
7263
7301
|
}
|
|
7264
7302
|
else if (node.expression.type === "UpdateExpression" &&
|
|
@@ -7273,7 +7311,7 @@ function cleanupUnusedVars(state, node) {
|
|
|
7273
7311
|
if (expr.type === "AssignmentExpression") {
|
|
7274
7312
|
if (expr.left.type === "Identifier" &&
|
|
7275
7313
|
hasProperty(toRemove, expr.left.name)) {
|
|
7276
|
-
const rep = unused(expr.right);
|
|
7314
|
+
const rep = unused(state, expr.right);
|
|
7277
7315
|
if (!rep.length) {
|
|
7278
7316
|
node.expressions.splice(i, 1);
|
|
7279
7317
|
}
|
|
@@ -7303,13 +7341,16 @@ function cleanupUnusedVars(state, node) {
|
|
|
7303
7341
|
const vdecl = decl.declarations[i];
|
|
7304
7342
|
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(vdecl.id);
|
|
7305
7343
|
if (hasProperty(toRemove, name)) {
|
|
7306
|
-
const rep = vdecl.init ? unused(vdecl.init) : [];
|
|
7344
|
+
const rep = vdecl.init ? unused(state, vdecl.init) : [];
|
|
7307
7345
|
if (rep.length) {
|
|
7308
|
-
if (
|
|
7309
|
-
(s.
|
|
7310
|
-
(s.expression.type === "
|
|
7311
|
-
|
|
7312
|
-
|
|
7346
|
+
if ((state.sdkVersion || 0) < 4001007 &&
|
|
7347
|
+
rep.find((s) => s.type === "ExpressionStatement" &&
|
|
7348
|
+
(s.expression.type === "NewExpression" ||
|
|
7349
|
+
(s.expression.type === "MemberExpression" &&
|
|
7350
|
+
!s.expression.computed &&
|
|
7351
|
+
s.expression.object.type === "NewExpression")))) {
|
|
7352
|
+
// prior to 4.1.7 vanilla new expressions were discarded,
|
|
7353
|
+
// so don't create top level new expressions.
|
|
7313
7354
|
continue;
|
|
7314
7355
|
}
|
|
7315
7356
|
if (parent.node.type === "ForStatement") {
|
|
@@ -7373,6 +7414,7 @@ function cleanupUnusedVars(state, node) {
|
|
|
7373
7414
|
|
|
7374
7415
|
|
|
7375
7416
|
|
|
7417
|
+
|
|
7376
7418
|
function collectClassInfo(state) {
|
|
7377
7419
|
const toybox = state.stack[0].decls["Toybox"][0];
|
|
7378
7420
|
const lang = toybox.decls["Lang"][0];
|
|
@@ -7448,7 +7490,8 @@ function collectClassInfo(state) {
|
|
|
7448
7490
|
if (elm.hasInvoke && elm.decls) {
|
|
7449
7491
|
Object.values(elm.decls).forEach((funcs) => {
|
|
7450
7492
|
funcs.forEach((f) => {
|
|
7451
|
-
if (f.type === "FunctionDeclaration" &&
|
|
7493
|
+
if (f.type === "FunctionDeclaration" &&
|
|
7494
|
+
!(f.attributes & StateNodeAttributes.STATIC)) {
|
|
7452
7495
|
(0,external_api_cjs_namespaceObject.markInvokeClassMethod)(f);
|
|
7453
7496
|
}
|
|
7454
7497
|
});
|
|
@@ -7527,11 +7570,6 @@ async function analyze(fnMap, resourcesMap, config) {
|
|
|
7527
7570
|
const [scope] = state.stack.slice(-1);
|
|
7528
7571
|
scope.stack = state.stackClone().slice(0, -1);
|
|
7529
7572
|
if (scope.type == "FunctionDeclaration") {
|
|
7530
|
-
scope.isStatic =
|
|
7531
|
-
scope.stack.slice(-1)[0].type !== "ClassDeclaration" ||
|
|
7532
|
-
(scope.node.attrs &&
|
|
7533
|
-
scope.node.attrs.access &&
|
|
7534
|
-
scope.node.attrs.access.includes("static"));
|
|
7535
7573
|
if (markApi) {
|
|
7536
7574
|
node.body = null;
|
|
7537
7575
|
scope.info = (0,external_api_cjs_namespaceObject.getApiFunctionInfo)(scope);
|
|
@@ -7578,18 +7616,45 @@ function reportMissingSymbols(state, config) {
|
|
|
7578
7616
|
const diagnosticType = config?.checkInvalidSymbols !== "OFF"
|
|
7579
7617
|
? config?.checkInvalidSymbols || "WARNING"
|
|
7580
7618
|
: null;
|
|
7619
|
+
const compiler2DiagnosticType = config?.checkCompilerLookupRules !== "OFF"
|
|
7620
|
+
? config?.checkCompilerLookupRules || "WARNING"
|
|
7621
|
+
: null;
|
|
7581
7622
|
if (diagnosticType &&
|
|
7582
7623
|
!config?.compilerOptions?.includes("--Eno-invalid-symbol")) {
|
|
7583
7624
|
const checkTypes = config?.typeCheckLevel && config.typeCheckLevel !== "Off";
|
|
7584
7625
|
Object.entries(state.fnMap).forEach(([, v]) => {
|
|
7585
7626
|
(0,external_api_cjs_namespaceObject.visitReferences)(state, v.ast, null, false, (node, results, error) => {
|
|
7586
|
-
if (!error)
|
|
7587
|
-
return undefined;
|
|
7588
7627
|
if (node.type === "BinaryExpression" && node.operator === "has") {
|
|
7589
7628
|
// Its not an error to check whether a property exists...
|
|
7590
7629
|
return undefined;
|
|
7591
7630
|
}
|
|
7592
7631
|
const nodeStr = (0,external_api_cjs_namespaceObject.formatAst)(node);
|
|
7632
|
+
if (!error) {
|
|
7633
|
+
if (state.sdkVersion === 4001006 &&
|
|
7634
|
+
compiler2DiagnosticType &&
|
|
7635
|
+
node.type === "MemberExpression" &&
|
|
7636
|
+
(node.object.type === "Identifier" ||
|
|
7637
|
+
node.object.type === "MemberExpression") &&
|
|
7638
|
+
results.some((result) => {
|
|
7639
|
+
const parent = result.parent;
|
|
7640
|
+
if (!parent || parent.type !== "ClassDeclaration") {
|
|
7641
|
+
return false;
|
|
7642
|
+
}
|
|
7643
|
+
return result.results.some((sn) => {
|
|
7644
|
+
switch (sn.type) {
|
|
7645
|
+
case "VariableDeclarator":
|
|
7646
|
+
case "FunctionDeclaration":
|
|
7647
|
+
return (sn.attributes &
|
|
7648
|
+
(StateNodeAttributes.PRIVATE |
|
|
7649
|
+
StateNodeAttributes.PROTECTED));
|
|
7650
|
+
}
|
|
7651
|
+
return false;
|
|
7652
|
+
});
|
|
7653
|
+
})) {
|
|
7654
|
+
diagnostic(state, node.loc, `The expression ${nodeStr} will fail at runtime using sdk-4.1.6`, compiler2DiagnosticType);
|
|
7655
|
+
}
|
|
7656
|
+
return undefined;
|
|
7657
|
+
}
|
|
7593
7658
|
if (state.inType) {
|
|
7594
7659
|
if (!checkTypes || nodeStr.match(/^Void|Null$/)) {
|
|
7595
7660
|
return undefined;
|
|
@@ -7803,7 +7868,7 @@ function optimizeNode(state, node) {
|
|
|
7803
7868
|
left.value === null ||
|
|
7804
7869
|
((left_type === "Number" || left_type === "Long") &&
|
|
7805
7870
|
(left.value === 0 || left.value === 0n));
|
|
7806
|
-
if (falsy === (node.operator === "&&")) {
|
|
7871
|
+
if (falsy === (node.operator === "&&" || node.operator === "and")) {
|
|
7807
7872
|
return left;
|
|
7808
7873
|
}
|
|
7809
7874
|
if (left_type !== "Boolean" &&
|
|
@@ -7813,10 +7878,12 @@ function optimizeNode(state, node) {
|
|
|
7813
7878
|
}
|
|
7814
7879
|
const [right, right_type] = getNodeValue(node.right);
|
|
7815
7880
|
if (right && right_type === left_type) {
|
|
7816
|
-
if (left_type === "Boolean" ||
|
|
7881
|
+
if (left_type === "Boolean" ||
|
|
7882
|
+
node.operator === "||" ||
|
|
7883
|
+
node.operator === "or") {
|
|
7817
7884
|
return right;
|
|
7818
7885
|
}
|
|
7819
|
-
if (node.operator !== "&&") {
|
|
7886
|
+
if (node.operator !== "&&" && node.operator !== "and") {
|
|
7820
7887
|
throw new Error(`Unexpected operator "${node.operator}"`);
|
|
7821
7888
|
}
|
|
7822
7889
|
return { ...node, type: "BinaryExpression", operator: "&" };
|
|
@@ -8306,7 +8373,6 @@ async function optimizeMonkeyC(fnMap, resourcesMap, config) {
|
|
|
8306
8373
|
if ((obj.type === "ModuleDeclaration" ||
|
|
8307
8374
|
obj.type === "Program" ||
|
|
8308
8375
|
obj.type === "ClassDeclaration") &&
|
|
8309
|
-
obj.decls &&
|
|
8310
8376
|
obj.stack) {
|
|
8311
8377
|
const exists = (0,external_api_cjs_namespaceObject.hasProperty)(obj.decls, node.right.argument.name) ||
|
|
8312
8378
|
// This is overkill, since we've already looked up
|
|
@@ -8407,7 +8473,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, config) {
|
|
|
8407
8473
|
}
|
|
8408
8474
|
}
|
|
8409
8475
|
else {
|
|
8410
|
-
const ret = unused(node.expression, true);
|
|
8476
|
+
const ret = unused(state, node.expression, true);
|
|
8411
8477
|
if (ret) {
|
|
8412
8478
|
return ret
|
|
8413
8479
|
.map((r) => replace(r, r))
|
|
@@ -8811,11 +8877,8 @@ async function generateOptimizedProject(options) {
|
|
|
8811
8877
|
const error = new Error(xml.body.children("iq:barrel").length()
|
|
8812
8878
|
? "Optimize the project that uses this barrel, not the barrel itself"
|
|
8813
8879
|
: "Manifest is missing an `iq:application` tag");
|
|
8814
|
-
error.location =
|
|
8815
|
-
|
|
8816
|
-
end: { line: 1, column: 1 },
|
|
8817
|
-
source: manifest,
|
|
8818
|
-
};
|
|
8880
|
+
error.location =
|
|
8881
|
+
xml.body.elements[0].loc || undefined;
|
|
8819
8882
|
throw error;
|
|
8820
8883
|
}
|
|
8821
8884
|
const dependencyFiles = [manifest, ...jungles];
|
|
@@ -9019,6 +9082,7 @@ const configOptionsToCheck = [
|
|
|
9019
9082
|
"ignoredAnnotations",
|
|
9020
9083
|
"ignoredSourcePaths",
|
|
9021
9084
|
"checkInvalidSymbols",
|
|
9085
|
+
"checkCompilerLookupRules",
|
|
9022
9086
|
"sizeBasedPRE",
|
|
9023
9087
|
"extensionVersion",
|
|
9024
9088
|
];
|
|
@@ -9079,7 +9143,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
9079
9143
|
// the oldest optimized file, we don't need to regenerate
|
|
9080
9144
|
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
9081
9145
|
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
9082
|
-
if (source_time < opt_time &&
|
|
9146
|
+
if (source_time < opt_time && 1669424079462 < opt_time) {
|
|
9083
9147
|
return { hasTests, diagnostics: prevDiagnostics };
|
|
9084
9148
|
}
|
|
9085
9149
|
}
|
|
@@ -9104,7 +9168,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
9104
9168
|
return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
|
|
9105
9169
|
hasTests,
|
|
9106
9170
|
diagnostics,
|
|
9107
|
-
optimizerVersion: "1.0.
|
|
9171
|
+
optimizerVersion: "1.0.40",
|
|
9108
9172
|
...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
|
|
9109
9173
|
}))
|
|
9110
9174
|
.then(() => ({ hasTests, diagnostics }));
|
package/build/sdk-util.cjs
CHANGED
|
@@ -73,10 +73,11 @@ function peg$subclass(t,u){function r(){this.constructor=t}r.prototype=u.prototy
|
|
|
73
73
|
;// CONCATENATED MODULE: ./src/xml-util.ts
|
|
74
74
|
|
|
75
75
|
class Document {
|
|
76
|
-
constructor(prolog, body, misc) {
|
|
76
|
+
constructor(prolog, body, misc, source) {
|
|
77
77
|
this.prolog = prolog;
|
|
78
78
|
this.body = body;
|
|
79
79
|
this.misc = misc;
|
|
80
|
+
this.source = source;
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
function elementKids(e) {
|
|
@@ -155,7 +156,7 @@ function parseXml(content, fileName = null) {
|
|
|
155
156
|
const [prolog, body, misc] = peg$parse(content, {
|
|
156
157
|
grammarSource: fileName || "unknown",
|
|
157
158
|
});
|
|
158
|
-
return new Document(prolog, new Nodes(body), misc);
|
|
159
|
+
return new Document(prolog, new Nodes(body), misc, content);
|
|
159
160
|
}
|
|
160
161
|
function reference(s) {
|
|
161
162
|
if (typeof s === "string")
|
package/build/src/api.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
2
2
|
import { hasProperty, traverseAst } from "./ast";
|
|
3
3
|
import { JungleResourceMap } from "./jungles";
|
|
4
|
-
import { FunctionInfo, FunctionStateNode, LookupDefinition, ProgramState, ProgramStateLive, ProgramStateNode, ProgramStateStack, StateNode, StateNodeDecl } from "./optimizer-types";
|
|
4
|
+
import { FunctionInfo, FunctionStateNode, LookupDefinition, ModuleStateNode, ProgramState, ProgramStateLive, ProgramStateNode, ProgramStateStack, StateNode, StateNodeDecl } from "./optimizer-types";
|
|
5
5
|
export { visitorNode, visitReferences } from "./visitor";
|
|
6
6
|
export { traverseAst, hasProperty };
|
|
7
|
+
export declare function parseSdkVersion(version: string | undefined): number;
|
|
8
|
+
export declare function checkCompilerVersion(version: string, sdkVer: number): boolean | undefined;
|
|
7
9
|
export declare function getApiMapping(state?: ProgramState, resourcesMap?: Record<string, JungleResourceMap>): Promise<ProgramStateNode | null>;
|
|
8
10
|
export declare function isStateNode(node: StateNodeDecl): node is StateNode;
|
|
9
11
|
export declare function variableDeclarationName(node: mctree.TypedIdentifier | mctree.InstanceofIdentifier): string;
|
|
@@ -11,6 +13,12 @@ export declare function sameLookupResult(a: LookupDefinition[], b: LookupDefinit
|
|
|
11
13
|
export declare function isLookupCandidate(node: mctree.MemberExpression): false | mctree.Identifier;
|
|
12
14
|
export declare function collectNamespaces(ast: mctree.Program, stateIn?: ProgramState): ProgramStateNode;
|
|
13
15
|
export declare function formatAst(node: mctree.Node, monkeyCSource?: string | null, options?: Record<string, unknown> | null): string;
|
|
14
|
-
export declare function findUsingForNode(state: ProgramStateLive, stack: ProgramStateStack, i: number, node: mctree.Identifier
|
|
16
|
+
export declare function findUsingForNode(state: ProgramStateLive, stack: ProgramStateStack, i: number, node: mctree.Identifier): ModuleStateNode | {
|
|
17
|
+
name: string;
|
|
18
|
+
decls: {
|
|
19
|
+
parent: StateNode;
|
|
20
|
+
results: StateNodeDecl[];
|
|
21
|
+
};
|
|
22
|
+
}[] | null;
|
|
15
23
|
export declare function getApiFunctionInfo(func: FunctionStateNode): FunctionInfo;
|
|
16
24
|
export declare function markInvokeClassMethod(func: FunctionStateNode): void;
|
package/build/src/inliner.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { FunctionStateNode, ProgramStateAnalysis, ProgramStateLive } from "./opt
|
|
|
3
3
|
export declare function inlinableSubExpression(expr: mctree.Expression): mctree.SimpleCallExpression | null;
|
|
4
4
|
export declare function shouldInline(state: ProgramStateAnalysis, func: FunctionStateNode, call: mctree.CallExpression, context: InlineContext | null): boolean;
|
|
5
5
|
declare type InlineBody = mctree.BlockStatement | mctree.ExpressionStatement["expression"];
|
|
6
|
-
export declare function unused(expression: mctree.ExpressionStatement["expression"]): mctree.Statement[];
|
|
7
|
-
export declare function unused(expression: mctree.ExpressionStatement["expression"], top: true): mctree.Statement[] | null;
|
|
6
|
+
export declare function unused(state: ProgramStateAnalysis, expression: mctree.ExpressionStatement["expression"]): mctree.Statement[];
|
|
7
|
+
export declare function unused(state: ProgramStateAnalysis, expression: mctree.ExpressionStatement["expression"], top: true): mctree.Statement[] | null;
|
|
8
8
|
export declare function diagnostic(state: ProgramStateLive, loc: mctree.Node["loc"], message: string | null, type?: NonNullable<ProgramStateAnalysis["diagnostics"]>[string][number]["type"]): void;
|
|
9
9
|
export declare type InlineContext = mctree.ReturnStatement | mctree.IfStatement | mctree.AssignmentExpression | mctree.ExpressionStatement | mctree.VariableDeclarator;
|
|
10
10
|
export declare function inlineFunction(state: ProgramStateAnalysis, func: FunctionStateNode, call: mctree.CallExpression, context: InlineContext | null): InlineBody | null;
|
package/build/src/jungles.d.ts
CHANGED
|
@@ -52,5 +52,5 @@ export declare type ResolvedJungle = JungleInfoBase & {
|
|
|
52
52
|
export declare type ResolvedBarrel = JungleInfoBase & {
|
|
53
53
|
qualifier: JungleQualifier;
|
|
54
54
|
};
|
|
55
|
-
export declare function get_jungle(jungles: string, options: BuildConfig): Promise<ResolvedJungle>;
|
|
55
|
+
export declare function get_jungle(jungles: string, options: BuildConfig, resources?: JungleResourceMap | undefined): Promise<ResolvedJungle>;
|
|
56
56
|
export {};
|
package/build/src/launch.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import { LineHandler } from "./util";
|
|
|
2
2
|
export declare function launchSimulator(force?: boolean): Promise<void>;
|
|
3
3
|
export declare function checkIfSimulatorRunning(): Promise<boolean>;
|
|
4
4
|
export declare function checkIfSimulatorRunningOn(port: number): Promise<boolean>;
|
|
5
|
-
export declare function simulateProgram(prg: string, device: string, test?: boolean, logger?: LineHandler | LineHandler[]): Promise<void>;
|
|
5
|
+
export declare function simulateProgram(prg: string, device: string, test?: boolean | string, logger?: LineHandler | LineHandler[]): Promise<void>;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { mctree } from "@markw65/prettier-plugin-monkeyc";
|
|
2
2
|
export declare type DiagnosticType = "ERROR" | "WARNING" | "INFO";
|
|
3
|
+
export declare type LookupRules = "COMPILER1" | "COMPILER2" | "DEFAULT";
|
|
4
|
+
export declare type EnforceStatic = "YES" | "NO";
|
|
3
5
|
export declare type BuildConfig = {
|
|
4
6
|
workspace?: string;
|
|
5
7
|
jungleFiles?: string;
|
|
@@ -23,6 +25,9 @@ export declare type BuildConfig = {
|
|
|
23
25
|
returnCommand?: boolean;
|
|
24
26
|
checkBuildPragmas?: boolean;
|
|
25
27
|
checkInvalidSymbols?: DiagnosticType | "OFF";
|
|
28
|
+
checkCompilerLookupRules?: DiagnosticType | "OFF";
|
|
29
|
+
compilerLookupRules?: LookupRules;
|
|
30
|
+
enforceStatic?: EnforceStatic;
|
|
26
31
|
sizeBasedPRE?: boolean | string;
|
|
27
32
|
prettier?: Record<string, unknown>;
|
|
28
33
|
extensionVersion?: string;
|
|
@@ -35,6 +40,12 @@ export declare type ImportUsing = {
|
|
|
35
40
|
node: mctree.Using | mctree.ImportModule;
|
|
36
41
|
module?: ModuleStateNode | null | undefined;
|
|
37
42
|
};
|
|
43
|
+
export declare enum StateNodeAttributes {
|
|
44
|
+
PUBLIC = 1,
|
|
45
|
+
PROTECTED = 2,
|
|
46
|
+
PRIVATE = 4,
|
|
47
|
+
STATIC = 8
|
|
48
|
+
}
|
|
38
49
|
interface BaseStateNode {
|
|
39
50
|
type: string;
|
|
40
51
|
node: mctree.Node | null | undefined;
|
|
@@ -45,6 +56,7 @@ interface BaseStateNode {
|
|
|
45
56
|
stack?: ProgramStateStack | undefined;
|
|
46
57
|
usings?: Record<string, ImportUsing>;
|
|
47
58
|
imports?: ImportUsing[];
|
|
59
|
+
attributes: StateNodeAttributes;
|
|
48
60
|
}
|
|
49
61
|
export interface ProgramStateNode extends BaseStateNode {
|
|
50
62
|
type: "Program";
|
|
@@ -82,7 +94,6 @@ export interface FunctionStateNode extends BaseStateNode {
|
|
|
82
94
|
fullName: string;
|
|
83
95
|
stack?: ProgramStateStack;
|
|
84
96
|
decls?: undefined;
|
|
85
|
-
isStatic?: boolean;
|
|
86
97
|
info?: FunctionInfo;
|
|
87
98
|
next_info?: FunctionInfo;
|
|
88
99
|
}
|
|
@@ -133,6 +144,9 @@ export declare type ProgramState = {
|
|
|
133
144
|
inType?: number;
|
|
134
145
|
inlining?: true;
|
|
135
146
|
config?: BuildConfig;
|
|
147
|
+
sdk?: string;
|
|
148
|
+
sdkVersion?: number;
|
|
149
|
+
lookupRules?: LookupRules;
|
|
136
150
|
nextExposed?: Record<string, true>;
|
|
137
151
|
exposed?: Record<string, true>;
|
|
138
152
|
usedByName?: Record<string, true>;
|
|
@@ -166,7 +180,7 @@ export declare type ProgramState = {
|
|
|
166
180
|
declare type Finalized<T, Keys extends keyof T> = T & {
|
|
167
181
|
[key in Keys]-?: NonNullable<T[key]>;
|
|
168
182
|
};
|
|
169
|
-
export declare type ProgramStateLive = Finalized<ProgramState, "stack" | "lookup" | "lookupValue" | "lookupType" | "lookupNonlocal" | "stackClone" | "traverse" | "index" | "constants" | "removeNodeComments" | "inType" | "nextExposed">;
|
|
183
|
+
export declare type ProgramStateLive = Finalized<ProgramState, "stack" | "lookup" | "lookupValue" | "lookupType" | "lookupNonlocal" | "stackClone" | "traverse" | "index" | "constants" | "removeNodeComments" | "inType" | "nextExposed" | "lookupRules">;
|
|
170
184
|
export declare type ProgramStateAnalysis = Finalized<ProgramStateLive, "allClasses" | "allFunctions" | "fnMap">;
|
|
171
185
|
export declare type ProgramStateOptimizer = Finalized<ProgramStateAnalysis, "localsStack" | "exposed" | "calledFunctions" | "usedByName">;
|
|
172
186
|
export declare type ExcludeAnnotationsMap = {
|
package/build/src/projects.d.ts
CHANGED
|
@@ -12,10 +12,12 @@ export declare type RemoteProject = string | {
|
|
|
12
12
|
include?: string;
|
|
13
13
|
sourcePath?: string;
|
|
14
14
|
jungleContent?: string[];
|
|
15
|
+
garminOptLevel?: number;
|
|
15
16
|
};
|
|
16
17
|
export declare const githubProjects: RemoteProject[];
|
|
17
18
|
export declare function fetchGitProjects(projects: RemoteProject[]): Promise<(string | {
|
|
18
19
|
jungle: string;
|
|
19
20
|
build: boolean | null;
|
|
20
21
|
options: BuildConfig | null;
|
|
22
|
+
garminOptLevel: number | null;
|
|
21
23
|
})[]>;
|
package/build/src/xml-util.d.ts
CHANGED
|
@@ -118,7 +118,8 @@ export declare class Document {
|
|
|
118
118
|
prolog: Prolog;
|
|
119
119
|
body: Nodes;
|
|
120
120
|
misc: Array<Misc>;
|
|
121
|
-
|
|
121
|
+
source?: string | undefined;
|
|
122
|
+
constructor(prolog: Prolog, body: Nodes, misc: Array<Misc>, source?: string | undefined);
|
|
122
123
|
}
|
|
123
124
|
export declare function elementKids(e: Element): Element[];
|
|
124
125
|
declare type ElementMatcher = string | ((c: Element) => boolean);
|
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.40",
|
|
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",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
19
|
"watch": "webpack --mode development --watch",
|
|
20
|
+
"prettier-live": "test -z \"$(git status --untracked-files=no --porcelain || echo dirty)\" && npm install ../prettier-plugin-monkeyc && git commit -am 'prettier-plugin-monkeyc-live'",
|
|
20
21
|
"build-debug": "webpack --mode development",
|
|
21
22
|
"build-release": "webpack --mode production",
|
|
22
23
|
"prepack": "webpack --mode production",
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
"author": "markw65",
|
|
38
39
|
"license": "MIT",
|
|
39
40
|
"dependencies": {
|
|
40
|
-
"@markw65/prettier-plugin-monkeyc": "^1.0.
|
|
41
|
+
"@markw65/prettier-plugin-monkeyc": "^1.0.37"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"@types/glob": "^8.0.0",
|