@markw65/monkeyc-optimizer 1.0.37 → 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 +42 -0
- package/build/api.cjs +527 -148
- package/build/optimizer.cjs +517 -6930
- package/build/sdk-util.cjs +211 -7146
- package/build/src/api.d.ts +4 -3
- package/build/src/inliner.d.ts +2 -1
- 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/variable-renamer.d.ts +1 -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"
|
|
@@ -655,8 +656,13 @@ function function_info_findCalleesForNew(lookupDefs) {
|
|
|
655
656
|
|
|
656
657
|
function variable_renamer_renameVariable(state, locals, declName) {
|
|
657
658
|
const map = locals.map;
|
|
658
|
-
if (
|
|
659
|
-
|
|
659
|
+
if (declName) {
|
|
660
|
+
if (!hasProperty(map, declName))
|
|
661
|
+
return null;
|
|
662
|
+
}
|
|
663
|
+
else {
|
|
664
|
+
declName = "tmp";
|
|
665
|
+
}
|
|
660
666
|
let suffix = 0;
|
|
661
667
|
let node_name = declName;
|
|
662
668
|
const match = node_name.match(/^pmcr_(.*)_(\d+)$/);
|
|
@@ -711,6 +717,69 @@ function variable_renamer_renameVariable(state, locals, declName) {
|
|
|
711
717
|
|
|
712
718
|
|
|
713
719
|
|
|
720
|
+
// Note: Keep in sync with replaceInlinedSubExpression below
|
|
721
|
+
function inliner_inlinableSubExpression(expr) {
|
|
722
|
+
while (true) {
|
|
723
|
+
if (expr.type === "BinaryExpression" || expr.type === "LogicalExpression") {
|
|
724
|
+
expr = expr.left;
|
|
725
|
+
}
|
|
726
|
+
else if (expr.type === "UnaryExpression") {
|
|
727
|
+
expr = expr.argument;
|
|
728
|
+
}
|
|
729
|
+
else if (expr.type === "ConditionalExpression") {
|
|
730
|
+
expr = expr.test;
|
|
731
|
+
}
|
|
732
|
+
else if (expr.type === "MemberExpression") {
|
|
733
|
+
expr = expr.object;
|
|
734
|
+
}
|
|
735
|
+
else if (expr.type === "CallExpression") {
|
|
736
|
+
return expr;
|
|
737
|
+
}
|
|
738
|
+
else {
|
|
739
|
+
return null;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
// Note: Keep in sync with inlinableSubExpression above
|
|
744
|
+
function replaceInlinedSubExpression(top, call, repl) {
|
|
745
|
+
if (top === call)
|
|
746
|
+
return repl;
|
|
747
|
+
let expr = top;
|
|
748
|
+
while (true) {
|
|
749
|
+
if (expr.type === "LogicalExpression" || expr.type === "BinaryExpression") {
|
|
750
|
+
if (expr.left === call) {
|
|
751
|
+
expr.left = repl;
|
|
752
|
+
break;
|
|
753
|
+
}
|
|
754
|
+
expr = expr.left;
|
|
755
|
+
}
|
|
756
|
+
else if (expr.type === "UnaryExpression") {
|
|
757
|
+
if (expr.argument === call) {
|
|
758
|
+
expr.argument = repl;
|
|
759
|
+
break;
|
|
760
|
+
}
|
|
761
|
+
expr = expr.argument;
|
|
762
|
+
}
|
|
763
|
+
else if (expr.type === "ConditionalExpression") {
|
|
764
|
+
if (expr.test === call) {
|
|
765
|
+
expr.test = repl;
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
expr = expr.test;
|
|
769
|
+
}
|
|
770
|
+
else if (expr.type === "MemberExpression") {
|
|
771
|
+
if (expr.object === call) {
|
|
772
|
+
expr.object = repl;
|
|
773
|
+
break;
|
|
774
|
+
}
|
|
775
|
+
expr = expr.object;
|
|
776
|
+
}
|
|
777
|
+
else {
|
|
778
|
+
throw new Error("Internal error: Didn't find CallExpression");
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
return top;
|
|
782
|
+
}
|
|
714
783
|
function getArgSafety(state, func, args, requireAll) {
|
|
715
784
|
// determine whether decl might be changed by a function call
|
|
716
785
|
// or assignment during the evaluation of FunctionStateNode.
|
|
@@ -938,7 +1007,7 @@ function inliner_shouldInline(state, func, call, context) {
|
|
|
938
1007
|
}
|
|
939
1008
|
}
|
|
940
1009
|
if (!context && requested) {
|
|
941
|
-
inlineDiagnostic(state, func, call, "This function can only be inlined in statement, assignment, or return contexts");
|
|
1010
|
+
inlineDiagnostic(state, func, call, "This function can only be inlined in statement, assignment, if or return contexts");
|
|
942
1011
|
}
|
|
943
1012
|
return context != null;
|
|
944
1013
|
}
|
|
@@ -1137,6 +1206,9 @@ function inliner_unused(expression, top) {
|
|
|
1137
1206
|
if (expression.computed) {
|
|
1138
1207
|
return inliner_unused(expression.object).concat(inliner_unused(expression.property));
|
|
1139
1208
|
}
|
|
1209
|
+
if (expression.object.type === "NewExpression") {
|
|
1210
|
+
break;
|
|
1211
|
+
}
|
|
1140
1212
|
return inliner_unused(expression.object);
|
|
1141
1213
|
case "ArrayExpression":
|
|
1142
1214
|
return expression.elements.map((e) => inliner_unused(e)).flat(1);
|
|
@@ -1198,7 +1270,8 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
1198
1270
|
inlineDiagnostic(state, func, call, "Function had more than one return statement");
|
|
1199
1271
|
}
|
|
1200
1272
|
else if ((context.type === "AssignmentExpression" ||
|
|
1201
|
-
context.type === "VariableDeclarator"
|
|
1273
|
+
context.type === "VariableDeclarator" ||
|
|
1274
|
+
context.type === "IfStatement") &&
|
|
1202
1275
|
retStmtCount !== 1) {
|
|
1203
1276
|
inlineDiagnostic(state, func, call, "Function did not have a return statement");
|
|
1204
1277
|
return null;
|
|
@@ -1208,7 +1281,8 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
1208
1281
|
if (!last ||
|
|
1209
1282
|
last.type !== "ReturnStatement" ||
|
|
1210
1283
|
((context.type === "AssignmentExpression" ||
|
|
1211
|
-
context.type === "VariableDeclarator"
|
|
1284
|
+
context.type === "VariableDeclarator" ||
|
|
1285
|
+
context.type === "IfStatement") &&
|
|
1212
1286
|
!last.argument)) {
|
|
1213
1287
|
inlineDiagnostic(state, func, call, "There was a return statement, but not at the end of the function");
|
|
1214
1288
|
return null;
|
|
@@ -1235,14 +1309,15 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
1235
1309
|
}
|
|
1236
1310
|
if (last.argument) {
|
|
1237
1311
|
if (context.type === "AssignmentExpression") {
|
|
1238
|
-
context.right = last.argument;
|
|
1312
|
+
context.right = replaceInlinedSubExpression(context.right, call, last.argument);
|
|
1239
1313
|
block.body[block.body.length - 1] = {
|
|
1240
1314
|
type: "ExpressionStatement",
|
|
1241
1315
|
expression: context,
|
|
1242
1316
|
};
|
|
1243
1317
|
}
|
|
1244
1318
|
else if (context.type === "VariableDeclarator") {
|
|
1245
|
-
const { id, init
|
|
1319
|
+
const { id, init, kind: _kind, ...rest } = context;
|
|
1320
|
+
const right = replaceInlinedSubExpression(init, call, last.argument);
|
|
1246
1321
|
block.body[block.body.length - 1] = {
|
|
1247
1322
|
...rest,
|
|
1248
1323
|
type: "ExpressionStatement",
|
|
@@ -1251,9 +1326,52 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
1251
1326
|
type: "AssignmentExpression",
|
|
1252
1327
|
operator: "=",
|
|
1253
1328
|
left: id.type === "Identifier" ? id : id.left,
|
|
1329
|
+
right,
|
|
1330
|
+
},
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1333
|
+
else if (context.type === "IfStatement") {
|
|
1334
|
+
// Generate a pmcr_tmp name that doesn't conflict with anything
|
|
1335
|
+
const locals = state.localsStack[state.localsStack.length - 1];
|
|
1336
|
+
const name = renameVariable(state, locals, null);
|
|
1337
|
+
locals.map[name] = true;
|
|
1338
|
+
// Replace the inlined function's return statement
|
|
1339
|
+
// with an assignment to pmcr_tmp
|
|
1340
|
+
block.body[block.body.length - 1] = {
|
|
1341
|
+
type: "ExpressionStatement",
|
|
1342
|
+
expression: {
|
|
1343
|
+
type: "AssignmentExpression",
|
|
1344
|
+
operator: "=",
|
|
1345
|
+
left: { type: "Identifier", name },
|
|
1254
1346
|
right: last.argument,
|
|
1255
1347
|
},
|
|
1256
1348
|
};
|
|
1349
|
+
// The IfStatement either has the call as its test, or as
|
|
1350
|
+
// the leftmost argument to a series of Binary/Logical expressions
|
|
1351
|
+
// Either way, replace the call with pmcr_tmp
|
|
1352
|
+
const repl = { type: "Identifier", name };
|
|
1353
|
+
context.test = replaceInlinedSubExpression(context.test, call, repl);
|
|
1354
|
+
// Wrap the inlined body so it looks like
|
|
1355
|
+
// {
|
|
1356
|
+
// var pmcr_tmp;
|
|
1357
|
+
// { /* inlined body, with assignment to pmcr_tmp */ }
|
|
1358
|
+
// if (context) {} // original if statement
|
|
1359
|
+
// }
|
|
1360
|
+
body.body = [
|
|
1361
|
+
{
|
|
1362
|
+
type: "VariableDeclaration",
|
|
1363
|
+
kind: "var",
|
|
1364
|
+
declarations: [
|
|
1365
|
+
{
|
|
1366
|
+
type: "VariableDeclarator",
|
|
1367
|
+
kind: "var",
|
|
1368
|
+
id: { type: "Identifier", name },
|
|
1369
|
+
},
|
|
1370
|
+
],
|
|
1371
|
+
},
|
|
1372
|
+
{ type: "BlockStatement", body: body.body },
|
|
1373
|
+
context,
|
|
1374
|
+
];
|
|
1257
1375
|
}
|
|
1258
1376
|
else {
|
|
1259
1377
|
const side_exprs = inliner_unused(last.argument);
|
|
@@ -1427,7 +1545,7 @@ function pragma_checker_pragmaChecker(state, ast, diagnostics) {
|
|
|
1427
1545
|
if (quote == '"') {
|
|
1428
1546
|
return haystack.includes(needle);
|
|
1429
1547
|
}
|
|
1430
|
-
const re = new RegExp(needle.replace(/@(\d+)/g, "(pre_)?$1(_\\d+)?"));
|
|
1548
|
+
const re = new RegExp(needle.replace(/@([\d\w]+)/g, "(pre_)?$1(_\\d+)?"));
|
|
1431
1549
|
return re.test(haystack);
|
|
1432
1550
|
};
|
|
1433
1551
|
next();
|
|
@@ -2012,7 +2130,7 @@ function getPreOrder(head) {
|
|
|
2012
2130
|
}
|
|
2013
2131
|
|
|
2014
2132
|
// EXTERNAL MODULE: ./node_modules/priorityqueuejs/index.js
|
|
2015
|
-
var priorityqueuejs = __webpack_require__(
|
|
2133
|
+
var priorityqueuejs = __webpack_require__(789);
|
|
2016
2134
|
;// CONCATENATED MODULE: ./src/pre.ts
|
|
2017
2135
|
|
|
2018
2136
|
|
|
@@ -3005,6 +3123,13 @@ function unused_exprs_cleanupUnusedVars(state, node) {
|
|
|
3005
3123
|
if (hasProperty(toRemove, name)) {
|
|
3006
3124
|
const rep = vdecl.init ? unused(vdecl.init) : [];
|
|
3007
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
|
+
}
|
|
3008
3133
|
if (parent.node.type === "ForStatement") {
|
|
3009
3134
|
// declarations whose inits have side effects
|
|
3010
3135
|
// can't be deleted from for statements.
|
|
@@ -3054,100 +3179,6 @@ function unused_exprs_cleanupUnusedVars(state, node) {
|
|
|
3054
3179
|
}
|
|
3055
3180
|
}
|
|
3056
3181
|
|
|
3057
|
-
;// CONCATENATED MODULE: ./src/visitor.ts
|
|
3058
|
-
|
|
3059
|
-
function visitor_visitReferences(state, ast, name, defn, callback) {
|
|
3060
|
-
const checkResults = ([name, results], node) => {
|
|
3061
|
-
if (name && results) {
|
|
3062
|
-
if (!defn || (0,external_api_cjs_namespaceObject.sameLookupResult)(results, defn)) {
|
|
3063
|
-
if (callback(node, results, false) === false) {
|
|
3064
|
-
return [];
|
|
3065
|
-
}
|
|
3066
|
-
}
|
|
3067
|
-
}
|
|
3068
|
-
else if (defn === false) {
|
|
3069
|
-
if (callback(node, [], results === null) === false) {
|
|
3070
|
-
return [];
|
|
3071
|
-
}
|
|
3072
|
-
}
|
|
3073
|
-
return null;
|
|
3074
|
-
};
|
|
3075
|
-
state.pre = (node) => {
|
|
3076
|
-
switch (node.type) {
|
|
3077
|
-
case "AttributeList":
|
|
3078
|
-
return [];
|
|
3079
|
-
case "UnaryExpression":
|
|
3080
|
-
// a bare symbol isn't a reference
|
|
3081
|
-
if (node.operator === ":")
|
|
3082
|
-
return [];
|
|
3083
|
-
break;
|
|
3084
|
-
case "BinaryExpression":
|
|
3085
|
-
/*
|
|
3086
|
-
* `expr has :symbol` can be treated as a reference
|
|
3087
|
-
* to expr.symbol.
|
|
3088
|
-
*/
|
|
3089
|
-
if (node.operator === "has") {
|
|
3090
|
-
if (node.right.type === "UnaryExpression" &&
|
|
3091
|
-
node.right.operator === ":") {
|
|
3092
|
-
if (!name || node.right.argument.name === name) {
|
|
3093
|
-
return checkResults(state.lookup({
|
|
3094
|
-
type: "MemberExpression",
|
|
3095
|
-
object: node.left,
|
|
3096
|
-
property: node.right.argument,
|
|
3097
|
-
computed: false,
|
|
3098
|
-
}), node.right.argument);
|
|
3099
|
-
}
|
|
3100
|
-
}
|
|
3101
|
-
}
|
|
3102
|
-
break;
|
|
3103
|
-
case "CallExpression":
|
|
3104
|
-
// A call expression whose callee is an identifier is looked
|
|
3105
|
-
// up as a non-local. ie even if there's a same named local,
|
|
3106
|
-
// it will be ignored, and the lookup will start as if the
|
|
3107
|
-
// call had been written self.foo() rather than foo().
|
|
3108
|
-
if (node.callee.type === "Identifier") {
|
|
3109
|
-
if (!name || node.callee.name === name) {
|
|
3110
|
-
/* ignore return value */
|
|
3111
|
-
checkResults(state.lookupNonlocal(node.callee), node.callee);
|
|
3112
|
-
}
|
|
3113
|
-
return ["arguments"];
|
|
3114
|
-
}
|
|
3115
|
-
break;
|
|
3116
|
-
case "Identifier":
|
|
3117
|
-
if (!name || node.name === name) {
|
|
3118
|
-
return checkResults(state.lookup(node), node);
|
|
3119
|
-
}
|
|
3120
|
-
break;
|
|
3121
|
-
case "MemberExpression": {
|
|
3122
|
-
const property = (0,external_api_cjs_namespaceObject.isLookupCandidate)(node);
|
|
3123
|
-
if (property) {
|
|
3124
|
-
if (!name || property.name === name) {
|
|
3125
|
-
return checkResults(state.lookup(node), node) || ["object"];
|
|
3126
|
-
}
|
|
3127
|
-
return ["object"];
|
|
3128
|
-
}
|
|
3129
|
-
break;
|
|
3130
|
-
}
|
|
3131
|
-
case "MethodDefinition": {
|
|
3132
|
-
if (!state.inType) {
|
|
3133
|
-
throw new Error("Method definition outside of type!");
|
|
3134
|
-
}
|
|
3135
|
-
if (node.params) {
|
|
3136
|
-
node.params.forEach((param) => {
|
|
3137
|
-
if (param.type == "BinaryExpression") {
|
|
3138
|
-
state.traverse(param.right);
|
|
3139
|
-
}
|
|
3140
|
-
});
|
|
3141
|
-
}
|
|
3142
|
-
return ["returnType"];
|
|
3143
|
-
}
|
|
3144
|
-
}
|
|
3145
|
-
return null;
|
|
3146
|
-
};
|
|
3147
|
-
(0,external_api_cjs_namespaceObject.collectNamespaces)(ast, state);
|
|
3148
|
-
delete state.pre;
|
|
3149
|
-
}
|
|
3150
|
-
|
|
3151
3182
|
;// CONCATENATED MODULE: ./src/mc-rewrite.ts
|
|
3152
3183
|
|
|
3153
3184
|
|
|
@@ -3160,7 +3191,6 @@ function visitor_visitReferences(state, ast, name, defn, callback) {
|
|
|
3160
3191
|
|
|
3161
3192
|
|
|
3162
3193
|
|
|
3163
|
-
|
|
3164
3194
|
function collectClassInfo(state) {
|
|
3165
3195
|
const toybox = state.stack[0].decls["Toybox"][0];
|
|
3166
3196
|
const lang = toybox.decls["Lang"][0];
|
|
@@ -3275,7 +3305,7 @@ function getFileASTs(fnMap) {
|
|
|
3275
3305
|
return ok;
|
|
3276
3306
|
}, true));
|
|
3277
3307
|
}
|
|
3278
|
-
async function analyze(fnMap,
|
|
3308
|
+
async function analyze(fnMap, resourcesMap, config) {
|
|
3279
3309
|
let hasTests = false;
|
|
3280
3310
|
let markApi = true;
|
|
3281
3311
|
const preState = {
|
|
@@ -3343,7 +3373,7 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
3343
3373
|
return null;
|
|
3344
3374
|
},
|
|
3345
3375
|
};
|
|
3346
|
-
await getApiMapping(preState,
|
|
3376
|
+
await getApiMapping(preState, resourcesMap);
|
|
3347
3377
|
markApi = false;
|
|
3348
3378
|
const state = preState;
|
|
3349
3379
|
await getFileASTs(fnMap);
|
|
@@ -3359,16 +3389,25 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
3359
3389
|
delete state.shouldExclude;
|
|
3360
3390
|
delete state.pre;
|
|
3361
3391
|
collectClassInfo(state);
|
|
3392
|
+
state.exposed = state.nextExposed;
|
|
3393
|
+
state.nextExposed = {};
|
|
3394
|
+
return state;
|
|
3395
|
+
}
|
|
3396
|
+
function reportMissingSymbols(state, config) {
|
|
3362
3397
|
const diagnosticType = config?.checkInvalidSymbols !== "OFF"
|
|
3363
3398
|
? config?.checkInvalidSymbols || "WARNING"
|
|
3364
3399
|
: null;
|
|
3365
3400
|
if (diagnosticType &&
|
|
3366
3401
|
!config?.compilerOptions?.includes("--Eno-invalid-symbol")) {
|
|
3367
3402
|
const checkTypes = config?.typeCheckLevel && config.typeCheckLevel !== "Off";
|
|
3368
|
-
Object.entries(fnMap).forEach(([, v]) => {
|
|
3403
|
+
Object.entries(state.fnMap).forEach(([, v]) => {
|
|
3369
3404
|
visitReferences(state, v.ast, null, false, (node, results, error) => {
|
|
3370
3405
|
if (!error)
|
|
3371
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
|
+
}
|
|
3372
3411
|
const nodeStr = formatAst(node);
|
|
3373
3412
|
if (state.inType) {
|
|
3374
3413
|
if (!checkTypes || nodeStr.match(/^Void|Null$/)) {
|
|
@@ -3380,9 +3419,6 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
3380
3419
|
});
|
|
3381
3420
|
});
|
|
3382
3421
|
}
|
|
3383
|
-
state.exposed = state.nextExposed;
|
|
3384
|
-
state.nextExposed = {};
|
|
3385
|
-
return state;
|
|
3386
3422
|
}
|
|
3387
3423
|
function compareLiteralLike(a, b) {
|
|
3388
3424
|
while (a.type === "BinaryExpression")
|
|
@@ -3676,8 +3712,8 @@ function markFunctionCalled(state, func) {
|
|
|
3676
3712
|
}
|
|
3677
3713
|
pushUnique(state.calledFunctions[func.id.name], func);
|
|
3678
3714
|
}
|
|
3679
|
-
async function optimizeMonkeyC(fnMap,
|
|
3680
|
-
const state = (await analyze(fnMap,
|
|
3715
|
+
async function optimizeMonkeyC(fnMap, resourcesMap, config) {
|
|
3716
|
+
const state = (await analyze(fnMap, resourcesMap, config));
|
|
3681
3717
|
state.localsStack = [{}];
|
|
3682
3718
|
state.calledFunctions = {};
|
|
3683
3719
|
state.usedByName = {};
|
|
@@ -4048,11 +4084,18 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4048
4084
|
return false;
|
|
4049
4085
|
return replace(rep, rep);
|
|
4050
4086
|
}
|
|
4051
|
-
else if (node.type === "IfStatement"
|
|
4052
|
-
node.alternate &&
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4087
|
+
else if (node.type === "IfStatement") {
|
|
4088
|
+
if (node.alternate &&
|
|
4089
|
+
node.alternate.type === "BlockStatement" &&
|
|
4090
|
+
!node.alternate.body.length) {
|
|
4091
|
+
delete node.alternate;
|
|
4092
|
+
}
|
|
4093
|
+
else {
|
|
4094
|
+
const call = inlinableSubExpression(node.test);
|
|
4095
|
+
if (call) {
|
|
4096
|
+
return replace(optimizeCall(state, call, node), node.test);
|
|
4097
|
+
}
|
|
4098
|
+
}
|
|
4056
4099
|
}
|
|
4057
4100
|
break;
|
|
4058
4101
|
case "WhileStatement":
|
|
@@ -4070,6 +4113,37 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4070
4113
|
return replace(optimizeCall(state, node.argument, node), node.argument);
|
|
4071
4114
|
}
|
|
4072
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;
|
|
4073
4147
|
case "NewExpression":
|
|
4074
4148
|
if (state.currentFunction) {
|
|
4075
4149
|
const [, results] = state.lookup(node.callee);
|
|
@@ -4095,8 +4169,11 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4095
4169
|
let j = 0;
|
|
4096
4170
|
while (i < node.declarations.length) {
|
|
4097
4171
|
const decl = declarations[i++];
|
|
4098
|
-
if (decl.init
|
|
4099
|
-
|
|
4172
|
+
if (!decl.init)
|
|
4173
|
+
continue;
|
|
4174
|
+
const call = inlinableSubExpression(decl.init);
|
|
4175
|
+
if (call) {
|
|
4176
|
+
const inlined = replace(optimizeCall(state, call, decl), decl.init);
|
|
4100
4177
|
if (!inlined)
|
|
4101
4178
|
continue;
|
|
4102
4179
|
if (Array.isArray(inlined) || inlined.type != "BlockStatement") {
|
|
@@ -4131,7 +4208,8 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4131
4208
|
return replace(optimizeCall(state, node.expression, node), node.expression);
|
|
4132
4209
|
}
|
|
4133
4210
|
else if (node.expression.type === "AssignmentExpression") {
|
|
4134
|
-
|
|
4211
|
+
const call = inlinableSubExpression(node.expression.right);
|
|
4212
|
+
if (call) {
|
|
4135
4213
|
let ok = false;
|
|
4136
4214
|
if (node.expression.left.type === "Identifier") {
|
|
4137
4215
|
if (hasProperty(topLocals().map, node.expression.left.type)) {
|
|
@@ -4143,7 +4221,7 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4143
4221
|
ok = !!result;
|
|
4144
4222
|
}
|
|
4145
4223
|
if (ok) {
|
|
4146
|
-
return replace(optimizeCall(state,
|
|
4224
|
+
return replace(optimizeCall(state, call, node.expression), node.expression.right);
|
|
4147
4225
|
}
|
|
4148
4226
|
}
|
|
4149
4227
|
}
|
|
@@ -4293,7 +4371,7 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4293
4371
|
}
|
|
4294
4372
|
return null;
|
|
4295
4373
|
};
|
|
4296
|
-
Object.entries(fnMap).forEach(([
|
|
4374
|
+
Object.entries(fnMap).forEach(([, f]) => {
|
|
4297
4375
|
traverseAst(f.ast, undefined, (node) => {
|
|
4298
4376
|
const ret = cleanup(node);
|
|
4299
4377
|
if (ret === false) {
|
|
@@ -4301,6 +4379,9 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4301
4379
|
}
|
|
4302
4380
|
return ret;
|
|
4303
4381
|
});
|
|
4382
|
+
});
|
|
4383
|
+
reportMissingSymbols(state, config);
|
|
4384
|
+
Object.entries(fnMap).forEach(([name, f]) => {
|
|
4304
4385
|
if (state.config && state.config.checkBuildPragmas) {
|
|
4305
4386
|
pragmaChecker(state, f.ast, state.diagnostics?.[name]);
|
|
4306
4387
|
}
|
|
@@ -4416,6 +4497,316 @@ const negativeFixups = [
|
|
|
4416
4497
|
|
|
4417
4498
|
;// CONCATENATED MODULE: external "./sdk-util.cjs"
|
|
4418
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
|
+
|
|
4419
4810
|
;// CONCATENATED MODULE: ./src/api.ts
|
|
4420
4811
|
|
|
4421
4812
|
|
|
@@ -4428,6 +4819,7 @@ const external_sdk_util_cjs_namespaceObject = require("./sdk-util.cjs");
|
|
|
4428
4819
|
|
|
4429
4820
|
|
|
4430
4821
|
|
|
4822
|
+
|
|
4431
4823
|
/*
|
|
4432
4824
|
* This is an unfortunate hack. I want to be able to extract things
|
|
4433
4825
|
* like the types of all of a Class's variables (in particular the type
|
|
@@ -4438,34 +4830,24 @@ const external_sdk_util_cjs_namespaceObject = require("./sdk-util.cjs");
|
|
|
4438
4830
|
* but those are at least in a standard format.
|
|
4439
4831
|
*/
|
|
4440
4832
|
// Extract all enum values from api.mir
|
|
4441
|
-
async function api_getApiMapping(state,
|
|
4833
|
+
async function api_getApiMapping(state, resourcesMap) {
|
|
4442
4834
|
// get the path to the currently active sdk
|
|
4443
4835
|
const parser = (prettier_plugin_monkeyc_default()).parsers.monkeyc;
|
|
4444
4836
|
const sdk = await (0,external_sdk_util_cjs_namespaceObject.getSdkPath)();
|
|
4445
|
-
const rezDecl = `module Rez { ${[
|
|
4446
|
-
"Drawables",
|
|
4447
|
-
"Fonts",
|
|
4448
|
-
"JsonData",
|
|
4449
|
-
"Layouts",
|
|
4450
|
-
"Menus",
|
|
4451
|
-
"Strings",
|
|
4452
|
-
]
|
|
4453
|
-
.map((s) => ` module ${s} {}\n`)
|
|
4454
|
-
.join("")}}`;
|
|
4455
4837
|
const api = (await promises_namespaceObject.readFile(`${sdk}bin/api.mir`))
|
|
4456
4838
|
.toString()
|
|
4457
4839
|
.replace(/\r\n/g, "\n")
|
|
4458
4840
|
.replace(/^\s*\[.*?\]\s*$/gm, "")
|
|
4459
4841
|
//.replace(/(COLOR_TRANSPARENT|LAYOUT_[HV]ALIGN_\w+) = (\d+)/gm, "$1 = -$2")
|
|
4460
|
-
.replace(/^(\s*type)\s/gm, "$1def ")
|
|
4461
|
-
(barrelList || [])
|
|
4462
|
-
.map((name) => `module ${name} { ${rezDecl} }`)
|
|
4463
|
-
.concat(rezDecl)
|
|
4464
|
-
.join("");
|
|
4842
|
+
.replace(/^(\s*type)\s/gm, "$1def ");
|
|
4465
4843
|
try {
|
|
4466
|
-
const
|
|
4844
|
+
const ast = parser.parse(api, null, {
|
|
4467
4845
|
filepath: "api.mir",
|
|
4468
|
-
})
|
|
4846
|
+
});
|
|
4847
|
+
if (resourcesMap) {
|
|
4848
|
+
add_resources_to_ast(ast, resourcesMap);
|
|
4849
|
+
}
|
|
4850
|
+
const result = api_collectNamespaces(ast, state);
|
|
4469
4851
|
negativeFixups.forEach((fixup) => {
|
|
4470
4852
|
const vs = fixup.split(".").reduce((state, part) => {
|
|
4471
4853
|
const decls = api_isStateNode(state) && state.decls?.[part];
|
|
@@ -4635,14 +5017,11 @@ function lookup(state, decls, node, name, maybeStack, nonlocal) {
|
|
|
4635
5017
|
return current ? current.concat(items) : items;
|
|
4636
5018
|
}, null);
|
|
4637
5019
|
if (!result &&
|
|
4638
|
-
results.some((ld) => ld.results.some((sn) =>
|
|
4639
|
-
sn.type === "VariableDeclarator" ||
|
|
5020
|
+
results.some((ld) => ld.results.some((sn) => sn.type === "VariableDeclarator" ||
|
|
4640
5021
|
sn.type === "Identifier" ||
|
|
4641
5022
|
sn.type === "BinaryExpression" ||
|
|
4642
5023
|
(sn.type === "ClassDeclaration" &&
|
|
4643
5024
|
property.name === "initialize")))) {
|
|
4644
|
-
// - The Rez module can contain lots of things from the resource
|
|
4645
|
-
// compiler which we don't track.
|
|
4646
5025
|
// - Variables, and formal parameters would require type tracking
|
|
4647
5026
|
// which we don't yet do
|
|
4648
5027
|
// - Its ok to call an undeclared initialize method.
|
|
@@ -4656,7 +5035,7 @@ function lookup(state, decls, node, name, maybeStack, nonlocal) {
|
|
|
4656
5035
|
}
|
|
4657
5036
|
case "ThisExpression": {
|
|
4658
5037
|
for (let i = stack.length;;) {
|
|
4659
|
-
const si = stack[i];
|
|
5038
|
+
const si = stack[--i];
|
|
4660
5039
|
if (si.type == "ModuleDeclaration" ||
|
|
4661
5040
|
si.type == "ClassDeclaration" ||
|
|
4662
5041
|
!i) {
|