@markw65/monkeyc-optimizer 1.0.38 → 1.0.39
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 +30 -0
- package/build/api.cjs +385 -131
- package/build/optimizer.cjs +375 -6913
- package/build/sdk-util.cjs +211 -7146
- package/build/src/api.d.ts +4 -3
- package/build/src/jungles.d.ts +4 -0
- package/build/src/launch.d.ts +1 -1
- package/build/src/manifest.d.ts +2 -63
- package/build/src/mc-rewrite.d.ts +4 -2
- package/build/src/optimizer-types.d.ts +0 -5
- package/build/src/optimizer.d.ts +16 -3
- package/build/src/resources.d.ts +5 -0
- package/build/src/sdk-util.d.ts +5 -1
- package/build/src/visitor.d.ts +1 -0
- package/build/src/xml-util.d.ts +139 -0
- package/build/util.cjs +1491 -1565
- package/package.json +9 -11
package/build/api.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
0 && (module.exports = {collectNamespaces,findUsingForNode,formatAst,getApiFunctionInfo,getApiMapping,hasProperty,isLookupCandidate,isStateNode,markInvokeClassMethod,sameLookupResult,traverseAst,variableDeclarationName,visitReferences});
|
|
1
|
+
0 && (module.exports = {collectNamespaces,findUsingForNode,formatAst,getApiFunctionInfo,getApiMapping,hasProperty,isLookupCandidate,isStateNode,markInvokeClassMethod,sameLookupResult,traverseAst,variableDeclarationName,visitReferences,visitorNode});
|
|
2
2
|
/******/ (() => { // webpackBootstrap
|
|
3
3
|
/******/ var __webpack_modules__ = ({
|
|
4
4
|
|
|
5
|
-
/***/
|
|
5
|
+
/***/ 789:
|
|
6
6
|
/***/ ((module) => {
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -270,7 +270,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
270
270
|
"sameLookupResult": () => (/* binding */ api_sameLookupResult),
|
|
271
271
|
"traverseAst": () => (/* reexport */ ast_traverseAst),
|
|
272
272
|
"variableDeclarationName": () => (/* binding */ api_variableDeclarationName),
|
|
273
|
-
"visitReferences": () => (/* reexport */ visitor_visitReferences)
|
|
273
|
+
"visitReferences": () => (/* reexport */ visitor_visitReferences),
|
|
274
|
+
"visitorNode": () => (/* reexport */ visitorNode)
|
|
274
275
|
});
|
|
275
276
|
|
|
276
277
|
;// CONCATENATED MODULE: external "@markw65/prettier-plugin-monkeyc"
|
|
@@ -1205,6 +1206,9 @@ function inliner_unused(expression, top) {
|
|
|
1205
1206
|
if (expression.computed) {
|
|
1206
1207
|
return inliner_unused(expression.object).concat(inliner_unused(expression.property));
|
|
1207
1208
|
}
|
|
1209
|
+
if (expression.object.type === "NewExpression") {
|
|
1210
|
+
break;
|
|
1211
|
+
}
|
|
1208
1212
|
return inliner_unused(expression.object);
|
|
1209
1213
|
case "ArrayExpression":
|
|
1210
1214
|
return expression.elements.map((e) => inliner_unused(e)).flat(1);
|
|
@@ -2126,7 +2130,7 @@ function getPreOrder(head) {
|
|
|
2126
2130
|
}
|
|
2127
2131
|
|
|
2128
2132
|
// EXTERNAL MODULE: ./node_modules/priorityqueuejs/index.js
|
|
2129
|
-
var priorityqueuejs = __webpack_require__(
|
|
2133
|
+
var priorityqueuejs = __webpack_require__(789);
|
|
2130
2134
|
;// CONCATENATED MODULE: ./src/pre.ts
|
|
2131
2135
|
|
|
2132
2136
|
|
|
@@ -3119,6 +3123,13 @@ function unused_exprs_cleanupUnusedVars(state, node) {
|
|
|
3119
3123
|
if (hasProperty(toRemove, name)) {
|
|
3120
3124
|
const rep = vdecl.init ? unused(vdecl.init) : [];
|
|
3121
3125
|
if (rep.length) {
|
|
3126
|
+
if (rep.find((s) => s.type === "ExpressionStatement" &&
|
|
3127
|
+
(s.expression.type === "NewExpression" ||
|
|
3128
|
+
(s.expression.type === "MemberExpression" &&
|
|
3129
|
+
!s.expression.computed &&
|
|
3130
|
+
s.expression.object.type === "NewExpression")))) {
|
|
3131
|
+
continue;
|
|
3132
|
+
}
|
|
3122
3133
|
if (parent.node.type === "ForStatement") {
|
|
3123
3134
|
// declarations whose inits have side effects
|
|
3124
3135
|
// can't be deleted from for statements.
|
|
@@ -3168,100 +3179,6 @@ function unused_exprs_cleanupUnusedVars(state, node) {
|
|
|
3168
3179
|
}
|
|
3169
3180
|
}
|
|
3170
3181
|
|
|
3171
|
-
;// CONCATENATED MODULE: ./src/visitor.ts
|
|
3172
|
-
|
|
3173
|
-
function visitor_visitReferences(state, ast, name, defn, callback) {
|
|
3174
|
-
const checkResults = ([name, results], node) => {
|
|
3175
|
-
if (name && results) {
|
|
3176
|
-
if (!defn || (0,external_api_cjs_namespaceObject.sameLookupResult)(results, defn)) {
|
|
3177
|
-
if (callback(node, results, false) === false) {
|
|
3178
|
-
return [];
|
|
3179
|
-
}
|
|
3180
|
-
}
|
|
3181
|
-
}
|
|
3182
|
-
else if (defn === false) {
|
|
3183
|
-
if (callback(node, [], results === null) === false) {
|
|
3184
|
-
return [];
|
|
3185
|
-
}
|
|
3186
|
-
}
|
|
3187
|
-
return null;
|
|
3188
|
-
};
|
|
3189
|
-
state.pre = (node) => {
|
|
3190
|
-
switch (node.type) {
|
|
3191
|
-
case "AttributeList":
|
|
3192
|
-
return [];
|
|
3193
|
-
case "UnaryExpression":
|
|
3194
|
-
// a bare symbol isn't a reference
|
|
3195
|
-
if (node.operator === ":")
|
|
3196
|
-
return [];
|
|
3197
|
-
break;
|
|
3198
|
-
case "BinaryExpression":
|
|
3199
|
-
/*
|
|
3200
|
-
* `expr has :symbol` can be treated as a reference
|
|
3201
|
-
* to expr.symbol.
|
|
3202
|
-
*/
|
|
3203
|
-
if (node.operator === "has") {
|
|
3204
|
-
if (node.right.type === "UnaryExpression" &&
|
|
3205
|
-
node.right.operator === ":") {
|
|
3206
|
-
if (!name || node.right.argument.name === name) {
|
|
3207
|
-
return checkResults(state.lookup({
|
|
3208
|
-
type: "MemberExpression",
|
|
3209
|
-
object: node.left,
|
|
3210
|
-
property: node.right.argument,
|
|
3211
|
-
computed: false,
|
|
3212
|
-
}), node.right.argument);
|
|
3213
|
-
}
|
|
3214
|
-
}
|
|
3215
|
-
}
|
|
3216
|
-
break;
|
|
3217
|
-
case "CallExpression":
|
|
3218
|
-
// A call expression whose callee is an identifier is looked
|
|
3219
|
-
// up as a non-local. ie even if there's a same named local,
|
|
3220
|
-
// it will be ignored, and the lookup will start as if the
|
|
3221
|
-
// call had been written self.foo() rather than foo().
|
|
3222
|
-
if (node.callee.type === "Identifier") {
|
|
3223
|
-
if (!name || node.callee.name === name) {
|
|
3224
|
-
/* ignore return value */
|
|
3225
|
-
checkResults(state.lookupNonlocal(node.callee), node.callee);
|
|
3226
|
-
}
|
|
3227
|
-
return ["arguments"];
|
|
3228
|
-
}
|
|
3229
|
-
break;
|
|
3230
|
-
case "Identifier":
|
|
3231
|
-
if (!name || node.name === name) {
|
|
3232
|
-
return checkResults(state.lookup(node), node);
|
|
3233
|
-
}
|
|
3234
|
-
break;
|
|
3235
|
-
case "MemberExpression": {
|
|
3236
|
-
const property = (0,external_api_cjs_namespaceObject.isLookupCandidate)(node);
|
|
3237
|
-
if (property) {
|
|
3238
|
-
if (!name || property.name === name) {
|
|
3239
|
-
return checkResults(state.lookup(node), node) || ["object"];
|
|
3240
|
-
}
|
|
3241
|
-
return ["object"];
|
|
3242
|
-
}
|
|
3243
|
-
break;
|
|
3244
|
-
}
|
|
3245
|
-
case "MethodDefinition": {
|
|
3246
|
-
if (!state.inType) {
|
|
3247
|
-
throw new Error("Method definition outside of type!");
|
|
3248
|
-
}
|
|
3249
|
-
if (node.params) {
|
|
3250
|
-
node.params.forEach((param) => {
|
|
3251
|
-
if (param.type == "BinaryExpression") {
|
|
3252
|
-
state.traverse(param.right);
|
|
3253
|
-
}
|
|
3254
|
-
});
|
|
3255
|
-
}
|
|
3256
|
-
return ["returnType"];
|
|
3257
|
-
}
|
|
3258
|
-
}
|
|
3259
|
-
return null;
|
|
3260
|
-
};
|
|
3261
|
-
(0,external_api_cjs_namespaceObject.collectNamespaces)(ast, state);
|
|
3262
|
-
delete state.pre;
|
|
3263
|
-
}
|
|
3264
|
-
|
|
3265
3182
|
;// CONCATENATED MODULE: ./src/mc-rewrite.ts
|
|
3266
3183
|
|
|
3267
3184
|
|
|
@@ -3274,7 +3191,6 @@ function visitor_visitReferences(state, ast, name, defn, callback) {
|
|
|
3274
3191
|
|
|
3275
3192
|
|
|
3276
3193
|
|
|
3277
|
-
|
|
3278
3194
|
function collectClassInfo(state) {
|
|
3279
3195
|
const toybox = state.stack[0].decls["Toybox"][0];
|
|
3280
3196
|
const lang = toybox.decls["Lang"][0];
|
|
@@ -3389,7 +3305,7 @@ function getFileASTs(fnMap) {
|
|
|
3389
3305
|
return ok;
|
|
3390
3306
|
}, true));
|
|
3391
3307
|
}
|
|
3392
|
-
async function analyze(fnMap,
|
|
3308
|
+
async function analyze(fnMap, resourcesMap, config) {
|
|
3393
3309
|
let hasTests = false;
|
|
3394
3310
|
let markApi = true;
|
|
3395
3311
|
const preState = {
|
|
@@ -3457,7 +3373,7 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
3457
3373
|
return null;
|
|
3458
3374
|
},
|
|
3459
3375
|
};
|
|
3460
|
-
await getApiMapping(preState,
|
|
3376
|
+
await getApiMapping(preState, resourcesMap);
|
|
3461
3377
|
markApi = false;
|
|
3462
3378
|
const state = preState;
|
|
3463
3379
|
await getFileASTs(fnMap);
|
|
@@ -3473,16 +3389,25 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
3473
3389
|
delete state.shouldExclude;
|
|
3474
3390
|
delete state.pre;
|
|
3475
3391
|
collectClassInfo(state);
|
|
3392
|
+
state.exposed = state.nextExposed;
|
|
3393
|
+
state.nextExposed = {};
|
|
3394
|
+
return state;
|
|
3395
|
+
}
|
|
3396
|
+
function reportMissingSymbols(state, config) {
|
|
3476
3397
|
const diagnosticType = config?.checkInvalidSymbols !== "OFF"
|
|
3477
3398
|
? config?.checkInvalidSymbols || "WARNING"
|
|
3478
3399
|
: null;
|
|
3479
3400
|
if (diagnosticType &&
|
|
3480
3401
|
!config?.compilerOptions?.includes("--Eno-invalid-symbol")) {
|
|
3481
3402
|
const checkTypes = config?.typeCheckLevel && config.typeCheckLevel !== "Off";
|
|
3482
|
-
Object.entries(fnMap).forEach(([, v]) => {
|
|
3403
|
+
Object.entries(state.fnMap).forEach(([, v]) => {
|
|
3483
3404
|
visitReferences(state, v.ast, null, false, (node, results, error) => {
|
|
3484
3405
|
if (!error)
|
|
3485
3406
|
return undefined;
|
|
3407
|
+
if (node.type === "BinaryExpression" && node.operator === "has") {
|
|
3408
|
+
// Its not an error to check whether a property exists...
|
|
3409
|
+
return undefined;
|
|
3410
|
+
}
|
|
3486
3411
|
const nodeStr = formatAst(node);
|
|
3487
3412
|
if (state.inType) {
|
|
3488
3413
|
if (!checkTypes || nodeStr.match(/^Void|Null$/)) {
|
|
@@ -3494,9 +3419,6 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
3494
3419
|
});
|
|
3495
3420
|
});
|
|
3496
3421
|
}
|
|
3497
|
-
state.exposed = state.nextExposed;
|
|
3498
|
-
state.nextExposed = {};
|
|
3499
|
-
return state;
|
|
3500
3422
|
}
|
|
3501
3423
|
function compareLiteralLike(a, b) {
|
|
3502
3424
|
while (a.type === "BinaryExpression")
|
|
@@ -3790,8 +3712,8 @@ function markFunctionCalled(state, func) {
|
|
|
3790
3712
|
}
|
|
3791
3713
|
pushUnique(state.calledFunctions[func.id.name], func);
|
|
3792
3714
|
}
|
|
3793
|
-
async function optimizeMonkeyC(fnMap,
|
|
3794
|
-
const state = (await analyze(fnMap,
|
|
3715
|
+
async function optimizeMonkeyC(fnMap, resourcesMap, config) {
|
|
3716
|
+
const state = (await analyze(fnMap, resourcesMap, config));
|
|
3795
3717
|
state.localsStack = [{}];
|
|
3796
3718
|
state.calledFunctions = {};
|
|
3797
3719
|
state.usedByName = {};
|
|
@@ -4191,6 +4113,37 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4191
4113
|
return replace(optimizeCall(state, node.argument, node), node.argument);
|
|
4192
4114
|
}
|
|
4193
4115
|
break;
|
|
4116
|
+
case "BinaryExpression":
|
|
4117
|
+
if (node.operator === "has" &&
|
|
4118
|
+
node.right.type === "UnaryExpression" &&
|
|
4119
|
+
node.right.operator === ":") {
|
|
4120
|
+
const [, results] = state.lookup(node.left);
|
|
4121
|
+
if (results &&
|
|
4122
|
+
results.length === 1 &&
|
|
4123
|
+
results[0].results.length === 1) {
|
|
4124
|
+
const obj = results[0].results[0];
|
|
4125
|
+
if ((obj.type === "ModuleDeclaration" ||
|
|
4126
|
+
obj.type === "Program" ||
|
|
4127
|
+
obj.type === "ClassDeclaration") &&
|
|
4128
|
+
obj.decls &&
|
|
4129
|
+
obj.stack) {
|
|
4130
|
+
const exists = hasProperty(obj.decls, node.right.argument.name) ||
|
|
4131
|
+
// This is overkill, since we've already looked up
|
|
4132
|
+
// node.left, but the actual lookup rules are complicated,
|
|
4133
|
+
// and embedded within state.lookup; so just defer to that.
|
|
4134
|
+
state.lookup({
|
|
4135
|
+
type: "MemberExpression",
|
|
4136
|
+
object: node.left,
|
|
4137
|
+
property: node.right.argument,
|
|
4138
|
+
computed: false,
|
|
4139
|
+
})[1];
|
|
4140
|
+
if (!exists) {
|
|
4141
|
+
return replace({ type: "Literal", value: false, raw: "false" }, node);
|
|
4142
|
+
}
|
|
4143
|
+
}
|
|
4144
|
+
}
|
|
4145
|
+
}
|
|
4146
|
+
break;
|
|
4194
4147
|
case "NewExpression":
|
|
4195
4148
|
if (state.currentFunction) {
|
|
4196
4149
|
const [, results] = state.lookup(node.callee);
|
|
@@ -4418,7 +4371,7 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4418
4371
|
}
|
|
4419
4372
|
return null;
|
|
4420
4373
|
};
|
|
4421
|
-
Object.entries(fnMap).forEach(([
|
|
4374
|
+
Object.entries(fnMap).forEach(([, f]) => {
|
|
4422
4375
|
traverseAst(f.ast, undefined, (node) => {
|
|
4423
4376
|
const ret = cleanup(node);
|
|
4424
4377
|
if (ret === false) {
|
|
@@ -4426,6 +4379,9 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4426
4379
|
}
|
|
4427
4380
|
return ret;
|
|
4428
4381
|
});
|
|
4382
|
+
});
|
|
4383
|
+
reportMissingSymbols(state, config);
|
|
4384
|
+
Object.entries(fnMap).forEach(([name, f]) => {
|
|
4429
4385
|
if (state.config && state.config.checkBuildPragmas) {
|
|
4430
4386
|
pragmaChecker(state, f.ast, state.diagnostics?.[name]);
|
|
4431
4387
|
}
|
|
@@ -4541,6 +4497,316 @@ const negativeFixups = [
|
|
|
4541
4497
|
|
|
4542
4498
|
;// CONCATENATED MODULE: external "./sdk-util.cjs"
|
|
4543
4499
|
const external_sdk_util_cjs_namespaceObject = require("./sdk-util.cjs");
|
|
4500
|
+
;// CONCATENATED MODULE: ./src/resources.ts
|
|
4501
|
+
|
|
4502
|
+
|
|
4503
|
+
/*
|
|
4504
|
+
* This is unavoidably ad-hoc. Garmin has arbitrary rules for how
|
|
4505
|
+
* resources can be nested, which we need to mimic here.
|
|
4506
|
+
*/
|
|
4507
|
+
function visit_resources(elements, parent, visitor, error) {
|
|
4508
|
+
elements.forEach((e) => {
|
|
4509
|
+
switch (e.name) {
|
|
4510
|
+
// <resources> can contain any of the resource lists (except
|
|
4511
|
+
// another resources), and any of their contents
|
|
4512
|
+
case "resources":
|
|
4513
|
+
if (parent) {
|
|
4514
|
+
error(e, parent);
|
|
4515
|
+
return;
|
|
4516
|
+
}
|
|
4517
|
+
visit_resources(external_sdk_util_cjs_namespaceObject.xmlUtil.elementKids(e), "resources", visitor, error);
|
|
4518
|
+
return;
|
|
4519
|
+
// Each of these is a list that can contain certain kinds of resource.
|
|
4520
|
+
// They can only occur at the top level, or under a <resources> list.
|
|
4521
|
+
case "strings":
|
|
4522
|
+
case "fonts":
|
|
4523
|
+
case "animations":
|
|
4524
|
+
case "bitmaps":
|
|
4525
|
+
case "layouts":
|
|
4526
|
+
case "menus":
|
|
4527
|
+
case "drawables":
|
|
4528
|
+
case "properties":
|
|
4529
|
+
case "settings":
|
|
4530
|
+
case "fitContributions":
|
|
4531
|
+
case "jsonDataResources":
|
|
4532
|
+
case "complications":
|
|
4533
|
+
if (parent && parent !== "resources") {
|
|
4534
|
+
error(e, parent);
|
|
4535
|
+
return;
|
|
4536
|
+
}
|
|
4537
|
+
visit_resources(external_sdk_util_cjs_namespaceObject.xmlUtil.elementKids(e), e.name, visitor, error);
|
|
4538
|
+
return;
|
|
4539
|
+
// These are the resources themselves. Some can occur at top level; most
|
|
4540
|
+
// are restricted to <resources> or one or more of the specific lists above
|
|
4541
|
+
case "string":
|
|
4542
|
+
if (parent !== "strings" && parent !== "resources") {
|
|
4543
|
+
error(e, parent);
|
|
4544
|
+
return;
|
|
4545
|
+
}
|
|
4546
|
+
visitor(e, "Strings");
|
|
4547
|
+
return;
|
|
4548
|
+
case "font":
|
|
4549
|
+
if (parent !== "fonts" && parent !== "resources") {
|
|
4550
|
+
error(e, parent);
|
|
4551
|
+
return;
|
|
4552
|
+
}
|
|
4553
|
+
visitor(e, "Fonts");
|
|
4554
|
+
return;
|
|
4555
|
+
case "animation":
|
|
4556
|
+
if (parent !== "animations" && parent !== "resources") {
|
|
4557
|
+
error(e, parent);
|
|
4558
|
+
return;
|
|
4559
|
+
}
|
|
4560
|
+
visitor(e, "Drawables");
|
|
4561
|
+
return;
|
|
4562
|
+
case "menu":
|
|
4563
|
+
case "menu2":
|
|
4564
|
+
case "checkbox-menu":
|
|
4565
|
+
case "action-menu":
|
|
4566
|
+
if (parent && parent !== "menus" && parent !== "resources") {
|
|
4567
|
+
error(e, parent);
|
|
4568
|
+
return;
|
|
4569
|
+
}
|
|
4570
|
+
visitor(e, "Menus");
|
|
4571
|
+
return;
|
|
4572
|
+
case "bitmap":
|
|
4573
|
+
if (parent !== "bitmaps" &&
|
|
4574
|
+
parent !== "drawables" &&
|
|
4575
|
+
parent !== "resources") {
|
|
4576
|
+
error(e, parent);
|
|
4577
|
+
return;
|
|
4578
|
+
}
|
|
4579
|
+
visitor(e, "Drawables");
|
|
4580
|
+
return;
|
|
4581
|
+
case "layout":
|
|
4582
|
+
if (parent && parent !== "layouts" && parent !== "resources") {
|
|
4583
|
+
error(e, parent);
|
|
4584
|
+
return;
|
|
4585
|
+
}
|
|
4586
|
+
visitor(e, "Layouts");
|
|
4587
|
+
return;
|
|
4588
|
+
case "drawable-list":
|
|
4589
|
+
if (parent && parent !== "drawables" && parent !== "resources") {
|
|
4590
|
+
error(e, parent);
|
|
4591
|
+
return;
|
|
4592
|
+
}
|
|
4593
|
+
visitor(e, "Drawables");
|
|
4594
|
+
return;
|
|
4595
|
+
case "property":
|
|
4596
|
+
if (parent !== "properties" && parent !== "resources") {
|
|
4597
|
+
error(e, parent);
|
|
4598
|
+
return;
|
|
4599
|
+
}
|
|
4600
|
+
visitor(e, "Properties");
|
|
4601
|
+
return;
|
|
4602
|
+
case "setting":
|
|
4603
|
+
if (parent !== "settings" && parent !== "resources") {
|
|
4604
|
+
error(e, parent);
|
|
4605
|
+
return;
|
|
4606
|
+
}
|
|
4607
|
+
visitor(e, null);
|
|
4608
|
+
return;
|
|
4609
|
+
case "group":
|
|
4610
|
+
if (parent !== "settings" /* && parent !== "resources" */) {
|
|
4611
|
+
error(e, parent);
|
|
4612
|
+
return;
|
|
4613
|
+
}
|
|
4614
|
+
visitor(e, null);
|
|
4615
|
+
return;
|
|
4616
|
+
case "fitField":
|
|
4617
|
+
if (parent !== "fitContributions" && parent !== "resources") {
|
|
4618
|
+
error(e, parent);
|
|
4619
|
+
return;
|
|
4620
|
+
}
|
|
4621
|
+
visitor(e, null);
|
|
4622
|
+
return;
|
|
4623
|
+
case "jsonData":
|
|
4624
|
+
if (parent && parent != "jsonDataResources" && parent !== "resources") {
|
|
4625
|
+
error(e, parent);
|
|
4626
|
+
return;
|
|
4627
|
+
}
|
|
4628
|
+
visitor(e, "JsonData");
|
|
4629
|
+
return;
|
|
4630
|
+
case "build":
|
|
4631
|
+
if (parent && parent !== "resources") {
|
|
4632
|
+
error(e, parent);
|
|
4633
|
+
return;
|
|
4634
|
+
}
|
|
4635
|
+
visitor(e, null);
|
|
4636
|
+
return;
|
|
4637
|
+
}
|
|
4638
|
+
});
|
|
4639
|
+
}
|
|
4640
|
+
function add_resources_to_ast(ast, resources) {
|
|
4641
|
+
Object.entries(resources).forEach(([barrel, resourceMap]) => {
|
|
4642
|
+
const rezModules = {
|
|
4643
|
+
Drawables: [],
|
|
4644
|
+
Fonts: [],
|
|
4645
|
+
JsonData: [],
|
|
4646
|
+
Layouts: [],
|
|
4647
|
+
Menus: [],
|
|
4648
|
+
Properties: [],
|
|
4649
|
+
Strings: [],
|
|
4650
|
+
};
|
|
4651
|
+
Object.values(resourceMap).forEach((rez) => {
|
|
4652
|
+
if (!rez || !(rez instanceof external_sdk_util_cjs_namespaceObject.xmlUtil.Document))
|
|
4653
|
+
return;
|
|
4654
|
+
visit_resources(rez.body.elements, null, (e, s) => {
|
|
4655
|
+
if (!s)
|
|
4656
|
+
return;
|
|
4657
|
+
if (!ast_hasProperty(rezModules, s))
|
|
4658
|
+
return;
|
|
4659
|
+
rezModules[s].push(e);
|
|
4660
|
+
}, (_e, _s) => {
|
|
4661
|
+
return;
|
|
4662
|
+
});
|
|
4663
|
+
});
|
|
4664
|
+
const outerLoc = ast.loc && { ...ast.loc };
|
|
4665
|
+
const makeModule = (m) => ({
|
|
4666
|
+
type: "ModuleDeclaration",
|
|
4667
|
+
id: { type: "Identifier", name: m },
|
|
4668
|
+
body: { type: "BlockStatement", body: [] },
|
|
4669
|
+
loc: outerLoc,
|
|
4670
|
+
});
|
|
4671
|
+
let body = ast.body;
|
|
4672
|
+
if (barrel !== "") {
|
|
4673
|
+
const module = makeModule(barrel);
|
|
4674
|
+
body.push(module);
|
|
4675
|
+
body = module.body.body;
|
|
4676
|
+
}
|
|
4677
|
+
const rez = makeModule("Rez");
|
|
4678
|
+
body.push(rez);
|
|
4679
|
+
body = rez.body.body;
|
|
4680
|
+
Object.entries(rezModules).forEach(([m, elements]) => {
|
|
4681
|
+
const module = makeModule(m);
|
|
4682
|
+
body.push(module);
|
|
4683
|
+
elements.forEach((e) => e.attr.id &&
|
|
4684
|
+
module.body.body.push({
|
|
4685
|
+
type: "VariableDeclaration",
|
|
4686
|
+
declarations: [
|
|
4687
|
+
{
|
|
4688
|
+
type: "VariableDeclarator",
|
|
4689
|
+
kind: "var",
|
|
4690
|
+
id: { type: "Identifier", name: e.attr.id, loc: e.loc },
|
|
4691
|
+
loc: e.loc,
|
|
4692
|
+
},
|
|
4693
|
+
],
|
|
4694
|
+
kind: "var",
|
|
4695
|
+
loc: e.loc,
|
|
4696
|
+
}));
|
|
4697
|
+
});
|
|
4698
|
+
});
|
|
4699
|
+
}
|
|
4700
|
+
|
|
4701
|
+
;// CONCATENATED MODULE: ./src/visitor.ts
|
|
4702
|
+
|
|
4703
|
+
function visitorNode(node) {
|
|
4704
|
+
if (node.type === "Identifier") {
|
|
4705
|
+
return node;
|
|
4706
|
+
}
|
|
4707
|
+
if (node.type === "MemberExpression") {
|
|
4708
|
+
return node.property;
|
|
4709
|
+
}
|
|
4710
|
+
if (node.type === "BinaryExpression" &&
|
|
4711
|
+
node.operator === "has" &&
|
|
4712
|
+
node.right.type === "UnaryExpression" &&
|
|
4713
|
+
node.right.operator === ":") {
|
|
4714
|
+
return node.right.argument;
|
|
4715
|
+
}
|
|
4716
|
+
return node;
|
|
4717
|
+
}
|
|
4718
|
+
function visitor_visitReferences(state, ast, name, defn, callback) {
|
|
4719
|
+
const checkResults = ([name, results], node) => {
|
|
4720
|
+
if (name && results) {
|
|
4721
|
+
if (!defn || (0,external_api_cjs_namespaceObject.sameLookupResult)(results, defn)) {
|
|
4722
|
+
if (callback(node, results, false) === false) {
|
|
4723
|
+
return [];
|
|
4724
|
+
}
|
|
4725
|
+
}
|
|
4726
|
+
}
|
|
4727
|
+
else if (defn === false) {
|
|
4728
|
+
if (callback(node, [], results === null) === false) {
|
|
4729
|
+
return [];
|
|
4730
|
+
}
|
|
4731
|
+
}
|
|
4732
|
+
return null;
|
|
4733
|
+
};
|
|
4734
|
+
state.pre = (node) => {
|
|
4735
|
+
switch (node.type) {
|
|
4736
|
+
case "AttributeList":
|
|
4737
|
+
return [];
|
|
4738
|
+
case "UnaryExpression":
|
|
4739
|
+
// a bare symbol isn't a reference
|
|
4740
|
+
if (node.operator === ":")
|
|
4741
|
+
return [];
|
|
4742
|
+
break;
|
|
4743
|
+
case "BinaryExpression":
|
|
4744
|
+
/*
|
|
4745
|
+
* `expr has :symbol` can be treated as a reference
|
|
4746
|
+
* to expr.symbol.
|
|
4747
|
+
*/
|
|
4748
|
+
if (node.operator === "has") {
|
|
4749
|
+
if (node.right.type === "UnaryExpression" &&
|
|
4750
|
+
node.right.operator === ":") {
|
|
4751
|
+
if (!name || node.right.argument.name === name) {
|
|
4752
|
+
return checkResults(state.lookup({
|
|
4753
|
+
type: "MemberExpression",
|
|
4754
|
+
object: node.left,
|
|
4755
|
+
property: node.right.argument,
|
|
4756
|
+
computed: false,
|
|
4757
|
+
}), node);
|
|
4758
|
+
}
|
|
4759
|
+
}
|
|
4760
|
+
}
|
|
4761
|
+
break;
|
|
4762
|
+
case "CallExpression":
|
|
4763
|
+
// A call expression whose callee is an identifier is looked
|
|
4764
|
+
// up as a non-local. ie even if there's a same named local,
|
|
4765
|
+
// it will be ignored, and the lookup will start as if the
|
|
4766
|
+
// call had been written self.foo() rather than foo().
|
|
4767
|
+
if (node.callee.type === "Identifier") {
|
|
4768
|
+
if (!name || node.callee.name === name) {
|
|
4769
|
+
/* ignore return value */
|
|
4770
|
+
checkResults(state.lookupNonlocal(node.callee), node.callee);
|
|
4771
|
+
}
|
|
4772
|
+
return ["arguments"];
|
|
4773
|
+
}
|
|
4774
|
+
break;
|
|
4775
|
+
case "Identifier":
|
|
4776
|
+
if (!name || node.name === name) {
|
|
4777
|
+
return checkResults(state.lookup(node), node);
|
|
4778
|
+
}
|
|
4779
|
+
break;
|
|
4780
|
+
case "MemberExpression": {
|
|
4781
|
+
const property = (0,external_api_cjs_namespaceObject.isLookupCandidate)(node);
|
|
4782
|
+
if (property) {
|
|
4783
|
+
if (!name || property.name === name) {
|
|
4784
|
+
return checkResults(state.lookup(node), node) || ["object"];
|
|
4785
|
+
}
|
|
4786
|
+
return ["object"];
|
|
4787
|
+
}
|
|
4788
|
+
break;
|
|
4789
|
+
}
|
|
4790
|
+
case "MethodDefinition": {
|
|
4791
|
+
if (!state.inType) {
|
|
4792
|
+
throw new Error("Method definition outside of type!");
|
|
4793
|
+
}
|
|
4794
|
+
if (node.params) {
|
|
4795
|
+
node.params.forEach((param) => {
|
|
4796
|
+
if (param.type == "BinaryExpression") {
|
|
4797
|
+
state.traverse(param.right);
|
|
4798
|
+
}
|
|
4799
|
+
});
|
|
4800
|
+
}
|
|
4801
|
+
return ["returnType"];
|
|
4802
|
+
}
|
|
4803
|
+
}
|
|
4804
|
+
return null;
|
|
4805
|
+
};
|
|
4806
|
+
(0,external_api_cjs_namespaceObject.collectNamespaces)(ast, state);
|
|
4807
|
+
delete state.pre;
|
|
4808
|
+
}
|
|
4809
|
+
|
|
4544
4810
|
;// CONCATENATED MODULE: ./src/api.ts
|
|
4545
4811
|
|
|
4546
4812
|
|
|
@@ -4553,6 +4819,7 @@ const external_sdk_util_cjs_namespaceObject = require("./sdk-util.cjs");
|
|
|
4553
4819
|
|
|
4554
4820
|
|
|
4555
4821
|
|
|
4822
|
+
|
|
4556
4823
|
/*
|
|
4557
4824
|
* This is an unfortunate hack. I want to be able to extract things
|
|
4558
4825
|
* like the types of all of a Class's variables (in particular the type
|
|
@@ -4563,34 +4830,24 @@ const external_sdk_util_cjs_namespaceObject = require("./sdk-util.cjs");
|
|
|
4563
4830
|
* but those are at least in a standard format.
|
|
4564
4831
|
*/
|
|
4565
4832
|
// Extract all enum values from api.mir
|
|
4566
|
-
async function api_getApiMapping(state,
|
|
4833
|
+
async function api_getApiMapping(state, resourcesMap) {
|
|
4567
4834
|
// get the path to the currently active sdk
|
|
4568
4835
|
const parser = (prettier_plugin_monkeyc_default()).parsers.monkeyc;
|
|
4569
4836
|
const sdk = await (0,external_sdk_util_cjs_namespaceObject.getSdkPath)();
|
|
4570
|
-
const rezDecl = `module Rez { ${[
|
|
4571
|
-
"Drawables",
|
|
4572
|
-
"Fonts",
|
|
4573
|
-
"JsonData",
|
|
4574
|
-
"Layouts",
|
|
4575
|
-
"Menus",
|
|
4576
|
-
"Strings",
|
|
4577
|
-
]
|
|
4578
|
-
.map((s) => ` module ${s} {}\n`)
|
|
4579
|
-
.join("")}}`;
|
|
4580
4837
|
const api = (await promises_namespaceObject.readFile(`${sdk}bin/api.mir`))
|
|
4581
4838
|
.toString()
|
|
4582
4839
|
.replace(/\r\n/g, "\n")
|
|
4583
4840
|
.replace(/^\s*\[.*?\]\s*$/gm, "")
|
|
4584
4841
|
//.replace(/(COLOR_TRANSPARENT|LAYOUT_[HV]ALIGN_\w+) = (\d+)/gm, "$1 = -$2")
|
|
4585
|
-
.replace(/^(\s*type)\s/gm, "$1def ")
|
|
4586
|
-
(barrelList || [])
|
|
4587
|
-
.map((name) => `module ${name} { ${rezDecl} }`)
|
|
4588
|
-
.concat(rezDecl)
|
|
4589
|
-
.join("");
|
|
4842
|
+
.replace(/^(\s*type)\s/gm, "$1def ");
|
|
4590
4843
|
try {
|
|
4591
|
-
const
|
|
4844
|
+
const ast = parser.parse(api, null, {
|
|
4592
4845
|
filepath: "api.mir",
|
|
4593
|
-
})
|
|
4846
|
+
});
|
|
4847
|
+
if (resourcesMap) {
|
|
4848
|
+
add_resources_to_ast(ast, resourcesMap);
|
|
4849
|
+
}
|
|
4850
|
+
const result = api_collectNamespaces(ast, state);
|
|
4594
4851
|
negativeFixups.forEach((fixup) => {
|
|
4595
4852
|
const vs = fixup.split(".").reduce((state, part) => {
|
|
4596
4853
|
const decls = api_isStateNode(state) && state.decls?.[part];
|
|
@@ -4760,14 +5017,11 @@ function lookup(state, decls, node, name, maybeStack, nonlocal) {
|
|
|
4760
5017
|
return current ? current.concat(items) : items;
|
|
4761
5018
|
}, null);
|
|
4762
5019
|
if (!result &&
|
|
4763
|
-
results.some((ld) => ld.results.some((sn) =>
|
|
4764
|
-
sn.type === "VariableDeclarator" ||
|
|
5020
|
+
results.some((ld) => ld.results.some((sn) => sn.type === "VariableDeclarator" ||
|
|
4765
5021
|
sn.type === "Identifier" ||
|
|
4766
5022
|
sn.type === "BinaryExpression" ||
|
|
4767
5023
|
(sn.type === "ClassDeclaration" &&
|
|
4768
5024
|
property.name === "initialize")))) {
|
|
4769
|
-
// - The Rez module can contain lots of things from the resource
|
|
4770
|
-
// compiler which we don't track.
|
|
4771
5025
|
// - Variables, and formal parameters would require type tracking
|
|
4772
5026
|
// which we don't yet do
|
|
4773
5027
|
// - Its ok to call an undeclared initialize method.
|
|
@@ -4781,7 +5035,7 @@ function lookup(state, decls, node, name, maybeStack, nonlocal) {
|
|
|
4781
5035
|
}
|
|
4782
5036
|
case "ThisExpression": {
|
|
4783
5037
|
for (let i = stack.length;;) {
|
|
4784
|
-
const si = stack[i];
|
|
5038
|
+
const si = stack[--i];
|
|
4785
5039
|
if (si.type == "ModuleDeclaration" ||
|
|
4786
5040
|
si.type == "ClassDeclaration" ||
|
|
4787
5041
|
!i) {
|