@markw65/monkeyc-optimizer 1.0.38 → 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 +53 -0
- package/build/api.cjs +645 -186
- package/build/optimizer.cjs +476 -6950
- package/build/sdk-util.cjs +212 -7146
- package/build/src/api.d.ts +13 -4
- package/build/src/inliner.d.ts +2 -2
- package/build/src/jungles.d.ts +5 -1
- package/build/src/launch.d.ts +2 -2
- package/build/src/manifest.d.ts +2 -63
- package/build/src/mc-rewrite.d.ts +4 -2
- package/build/src/optimizer-types.d.ts +16 -7
- package/build/src/optimizer.d.ts +16 -3
- package/build/src/projects.d.ts +2 -0
- 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 +140 -0
- package/build/util.cjs +1491 -1565
- package/package.json +10 -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 = {checkCompilerVersion,collectNamespaces,findUsingForNode,formatAst,getApiFunctionInfo,getApiMapping,hasProperty,isLookupCandidate,isStateNode,markInvokeClassMethod,parseSdkVersion,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
|
/**
|
|
@@ -258,6 +258,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
258
258
|
|
|
259
259
|
// EXPORTS
|
|
260
260
|
__webpack_require__.d(__webpack_exports__, {
|
|
261
|
+
"checkCompilerVersion": () => (/* binding */ api_checkCompilerVersion),
|
|
261
262
|
"collectNamespaces": () => (/* binding */ api_collectNamespaces),
|
|
262
263
|
"findUsingForNode": () => (/* binding */ findUsingForNode),
|
|
263
264
|
"formatAst": () => (/* binding */ api_formatAst),
|
|
@@ -267,10 +268,12 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
267
268
|
"isLookupCandidate": () => (/* binding */ api_isLookupCandidate),
|
|
268
269
|
"isStateNode": () => (/* binding */ api_isStateNode),
|
|
269
270
|
"markInvokeClassMethod": () => (/* binding */ api_markInvokeClassMethod),
|
|
271
|
+
"parseSdkVersion": () => (/* binding */ parseSdkVersion),
|
|
270
272
|
"sameLookupResult": () => (/* binding */ api_sameLookupResult),
|
|
271
273
|
"traverseAst": () => (/* reexport */ ast_traverseAst),
|
|
272
274
|
"variableDeclarationName": () => (/* binding */ api_variableDeclarationName),
|
|
273
|
-
"visitReferences": () => (/* reexport */ visitor_visitReferences)
|
|
275
|
+
"visitReferences": () => (/* reexport */ visitor_visitReferences),
|
|
276
|
+
"visitorNode": () => (/* reexport */ visitorNode)
|
|
274
277
|
});
|
|
275
278
|
|
|
276
279
|
;// CONCATENATED MODULE: external "@markw65/prettier-plugin-monkeyc"
|
|
@@ -650,6 +653,15 @@ function function_info_findCalleesForNew(lookupDefs) {
|
|
|
650
653
|
.filter((decl) => decl ? decl.type === "FunctionDeclaration" : false));
|
|
651
654
|
}
|
|
652
655
|
|
|
656
|
+
;// CONCATENATED MODULE: ./src/optimizer-types.ts
|
|
657
|
+
var optimizer_types_StateNodeAttributes;
|
|
658
|
+
(function (StateNodeAttributes) {
|
|
659
|
+
StateNodeAttributes[StateNodeAttributes["PUBLIC"] = 1] = "PUBLIC";
|
|
660
|
+
StateNodeAttributes[StateNodeAttributes["PROTECTED"] = 2] = "PROTECTED";
|
|
661
|
+
StateNodeAttributes[StateNodeAttributes["PRIVATE"] = 4] = "PRIVATE";
|
|
662
|
+
StateNodeAttributes[StateNodeAttributes["STATIC"] = 8] = "STATIC";
|
|
663
|
+
})(optimizer_types_StateNodeAttributes || (optimizer_types_StateNodeAttributes = {}));
|
|
664
|
+
|
|
653
665
|
;// CONCATENATED MODULE: ./src/variable-renamer.ts
|
|
654
666
|
|
|
655
667
|
|
|
@@ -716,6 +728,7 @@ function variable_renamer_renameVariable(state, locals, declName) {
|
|
|
716
728
|
|
|
717
729
|
|
|
718
730
|
|
|
731
|
+
|
|
719
732
|
// Note: Keep in sync with replaceInlinedSubExpression below
|
|
720
733
|
function inliner_inlinableSubExpression(expr) {
|
|
721
734
|
while (true) {
|
|
@@ -1035,6 +1048,12 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
1035
1048
|
state.inlining = true;
|
|
1036
1049
|
let insertedVariableDecls = null;
|
|
1037
1050
|
const replacements = new Set();
|
|
1051
|
+
// lookup determines static-ness of the lookup context based on seeing
|
|
1052
|
+
// a static FunctionDeclaration, but the FunctionDeclaration's stack
|
|
1053
|
+
// doesn't include the FunctionDeclaration itself.
|
|
1054
|
+
const stack = func.attributes & StateNodeAttributes.STATIC
|
|
1055
|
+
? func.stack.concat(func)
|
|
1056
|
+
: func.stack;
|
|
1038
1057
|
try {
|
|
1039
1058
|
state.pre = (node) => {
|
|
1040
1059
|
if (failed)
|
|
@@ -1084,7 +1103,7 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
1084
1103
|
}
|
|
1085
1104
|
return null;
|
|
1086
1105
|
}
|
|
1087
|
-
const replacement = fixNodeScope(state, node,
|
|
1106
|
+
const replacement = fixNodeScope(state, node, stack);
|
|
1088
1107
|
if (!replacement) {
|
|
1089
1108
|
failed = true;
|
|
1090
1109
|
inlineDiagnostic(state, func, call, `Failed to resolve '${node.name}'`);
|
|
@@ -1139,7 +1158,7 @@ function processInlineBody(state, func, call, root, params) {
|
|
|
1139
1158
|
delete state.inlining;
|
|
1140
1159
|
}
|
|
1141
1160
|
}
|
|
1142
|
-
function inliner_unused(expression, top) {
|
|
1161
|
+
function inliner_unused(state, expression, top) {
|
|
1143
1162
|
const estmt = (expression) => withLoc({
|
|
1144
1163
|
type: "ExpressionStatement",
|
|
1145
1164
|
expression,
|
|
@@ -1153,19 +1172,19 @@ function inliner_unused(expression, top) {
|
|
|
1153
1172
|
return [];
|
|
1154
1173
|
case "BinaryExpression":
|
|
1155
1174
|
if (expression.operator === "as") {
|
|
1156
|
-
return inliner_unused(expression.left);
|
|
1175
|
+
return inliner_unused(state, expression.left);
|
|
1157
1176
|
}
|
|
1158
|
-
return inliner_unused(expression.left).concat(inliner_unused(expression.right));
|
|
1177
|
+
return inliner_unused(state, expression.left).concat(inliner_unused(state, expression.right));
|
|
1159
1178
|
case "LogicalExpression": {
|
|
1160
|
-
const right = inliner_unused(expression.right);
|
|
1179
|
+
const right = inliner_unused(state, expression.right);
|
|
1161
1180
|
if (!right.length)
|
|
1162
|
-
return inliner_unused(expression.left);
|
|
1181
|
+
return inliner_unused(state, expression.left);
|
|
1163
1182
|
const consequent = withLoc({
|
|
1164
1183
|
type: "BlockStatement",
|
|
1165
1184
|
body: [estmt(expression.right)],
|
|
1166
1185
|
}, expression.right);
|
|
1167
1186
|
let alternate;
|
|
1168
|
-
if (expression.operator == "||") {
|
|
1187
|
+
if (expression.operator == "||" || expression.operator == "or") {
|
|
1169
1188
|
alternate = { ...consequent };
|
|
1170
1189
|
consequent.body = [];
|
|
1171
1190
|
}
|
|
@@ -1179,10 +1198,10 @@ function inliner_unused(expression, top) {
|
|
|
1179
1198
|
];
|
|
1180
1199
|
}
|
|
1181
1200
|
case "ConditionalExpression": {
|
|
1182
|
-
const consequentExprs = inliner_unused(expression.consequent);
|
|
1183
|
-
const alternateExprs = inliner_unused(expression.alternate);
|
|
1201
|
+
const consequentExprs = inliner_unused(state, expression.consequent);
|
|
1202
|
+
const alternateExprs = inliner_unused(state, expression.alternate);
|
|
1184
1203
|
if (!consequentExprs.length && !alternateExprs.length) {
|
|
1185
|
-
return inliner_unused(expression.test);
|
|
1204
|
+
return inliner_unused(state, expression.test);
|
|
1186
1205
|
}
|
|
1187
1206
|
return [
|
|
1188
1207
|
withLoc({
|
|
@@ -1200,17 +1219,24 @@ function inliner_unused(expression, top) {
|
|
|
1200
1219
|
];
|
|
1201
1220
|
}
|
|
1202
1221
|
case "UnaryExpression":
|
|
1203
|
-
return inliner_unused(expression.argument);
|
|
1222
|
+
return inliner_unused(state, expression.argument);
|
|
1204
1223
|
case "MemberExpression":
|
|
1205
1224
|
if (expression.computed) {
|
|
1206
|
-
return inliner_unused(expression.object).concat(inliner_unused(expression.property));
|
|
1225
|
+
return inliner_unused(state, expression.object).concat(inliner_unused(state, expression.property));
|
|
1226
|
+
}
|
|
1227
|
+
if ((state.sdkVersion || 0) < 4001007 &&
|
|
1228
|
+
expression.object.type === "NewExpression") {
|
|
1229
|
+
// prior to 4.1.7 top level new expressions were discarded,
|
|
1230
|
+
// but (new X()).a was not. After 4.1.7, top level new is
|
|
1231
|
+
// executed, but top level (new X()).a is an error.
|
|
1232
|
+
break;
|
|
1207
1233
|
}
|
|
1208
|
-
return inliner_unused(expression.object);
|
|
1234
|
+
return inliner_unused(state, expression.object);
|
|
1209
1235
|
case "ArrayExpression":
|
|
1210
|
-
return expression.elements.map((e) => inliner_unused(e)).flat(1);
|
|
1236
|
+
return expression.elements.map((e) => inliner_unused(state, e)).flat(1);
|
|
1211
1237
|
case "ObjectExpression":
|
|
1212
1238
|
return expression.properties
|
|
1213
|
-
.map((p) => inliner_unused(p.key).concat(inliner_unused(p.value)))
|
|
1239
|
+
.map((p) => inliner_unused(state, p.key).concat(inliner_unused(state, p.value)))
|
|
1214
1240
|
.flat(1);
|
|
1215
1241
|
}
|
|
1216
1242
|
return top ? null : [estmt(expression)];
|
|
@@ -1370,7 +1396,7 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
1370
1396
|
];
|
|
1371
1397
|
}
|
|
1372
1398
|
else {
|
|
1373
|
-
const side_exprs = inliner_unused(last.argument);
|
|
1399
|
+
const side_exprs = inliner_unused(state, last.argument);
|
|
1374
1400
|
block.body.splice(block.body.length - 1, 1, ...side_exprs);
|
|
1375
1401
|
}
|
|
1376
1402
|
}
|
|
@@ -1505,7 +1531,7 @@ function pragma_checker_pragmaChecker(state, ast, diagnostics) {
|
|
|
1505
1531
|
return;
|
|
1506
1532
|
diagnostics = diagnostics
|
|
1507
1533
|
?.slice()
|
|
1508
|
-
.sort((d1, d2) => d1.loc.start
|
|
1534
|
+
.sort((d1, d2) => d1.loc.start.offset - d2.loc.start.offset);
|
|
1509
1535
|
let diagIndex = 0;
|
|
1510
1536
|
let index = -1;
|
|
1511
1537
|
let comment;
|
|
@@ -1518,6 +1544,12 @@ function pragma_checker_pragmaChecker(state, ast, diagnostics) {
|
|
|
1518
1544
|
continue;
|
|
1519
1545
|
const kind = match[1];
|
|
1520
1546
|
let str = match[2];
|
|
1547
|
+
const verCheck = checkCompilerVersion(str.replace(/\s.*/, ""), state.sdkVersion || 0);
|
|
1548
|
+
if (verCheck === false)
|
|
1549
|
+
continue;
|
|
1550
|
+
if (verCheck === true) {
|
|
1551
|
+
str = str.replace(/^\S+\s+/, "");
|
|
1552
|
+
}
|
|
1521
1553
|
matchers = [];
|
|
1522
1554
|
while ((match = str.match(/^([/%&#@"])(.+?(?<!\\)(?:\\{2})*)\1(\s+|$)/))) {
|
|
1523
1555
|
matchers.push({ kind, quote: match[1], needle: match[2] });
|
|
@@ -2126,7 +2158,7 @@ function getPreOrder(head) {
|
|
|
2126
2158
|
}
|
|
2127
2159
|
|
|
2128
2160
|
// EXTERNAL MODULE: ./node_modules/priorityqueuejs/index.js
|
|
2129
|
-
var priorityqueuejs = __webpack_require__(
|
|
2161
|
+
var priorityqueuejs = __webpack_require__(789);
|
|
2130
2162
|
;// CONCATENATED MODULE: ./src/pre.ts
|
|
2131
2163
|
|
|
2132
2164
|
|
|
@@ -3072,7 +3104,7 @@ function unused_exprs_cleanupUnusedVars(state, node) {
|
|
|
3072
3104
|
if (node.expression.type === "AssignmentExpression") {
|
|
3073
3105
|
if (node.expression.left.type === "Identifier" &&
|
|
3074
3106
|
hasProperty(toRemove, node.expression.left.name)) {
|
|
3075
|
-
return unused(node.expression.right);
|
|
3107
|
+
return unused(state, node.expression.right);
|
|
3076
3108
|
}
|
|
3077
3109
|
}
|
|
3078
3110
|
else if (node.expression.type === "UpdateExpression" &&
|
|
@@ -3087,7 +3119,7 @@ function unused_exprs_cleanupUnusedVars(state, node) {
|
|
|
3087
3119
|
if (expr.type === "AssignmentExpression") {
|
|
3088
3120
|
if (expr.left.type === "Identifier" &&
|
|
3089
3121
|
hasProperty(toRemove, expr.left.name)) {
|
|
3090
|
-
const rep = unused(expr.right);
|
|
3122
|
+
const rep = unused(state, expr.right);
|
|
3091
3123
|
if (!rep.length) {
|
|
3092
3124
|
node.expressions.splice(i, 1);
|
|
3093
3125
|
}
|
|
@@ -3117,8 +3149,18 @@ function unused_exprs_cleanupUnusedVars(state, node) {
|
|
|
3117
3149
|
const vdecl = decl.declarations[i];
|
|
3118
3150
|
const name = variableDeclarationName(vdecl.id);
|
|
3119
3151
|
if (hasProperty(toRemove, name)) {
|
|
3120
|
-
const rep = vdecl.init ? unused(vdecl.init) : [];
|
|
3152
|
+
const rep = vdecl.init ? unused(state, vdecl.init) : [];
|
|
3121
3153
|
if (rep.length) {
|
|
3154
|
+
if ((state.sdkVersion || 0) < 4001007 &&
|
|
3155
|
+
rep.find((s) => s.type === "ExpressionStatement" &&
|
|
3156
|
+
(s.expression.type === "NewExpression" ||
|
|
3157
|
+
(s.expression.type === "MemberExpression" &&
|
|
3158
|
+
!s.expression.computed &&
|
|
3159
|
+
s.expression.object.type === "NewExpression")))) {
|
|
3160
|
+
// prior to 4.1.7 vanilla new expressions were discarded,
|
|
3161
|
+
// so don't create top level new expressions.
|
|
3162
|
+
continue;
|
|
3163
|
+
}
|
|
3122
3164
|
if (parent.node.type === "ForStatement") {
|
|
3123
3165
|
// declarations whose inits have side effects
|
|
3124
3166
|
// can't be deleted from for statements.
|
|
@@ -3168,100 +3210,6 @@ function unused_exprs_cleanupUnusedVars(state, node) {
|
|
|
3168
3210
|
}
|
|
3169
3211
|
}
|
|
3170
3212
|
|
|
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
3213
|
;// CONCATENATED MODULE: ./src/mc-rewrite.ts
|
|
3266
3214
|
|
|
3267
3215
|
|
|
@@ -3350,7 +3298,8 @@ function collectClassInfo(state) {
|
|
|
3350
3298
|
if (elm.hasInvoke && elm.decls) {
|
|
3351
3299
|
Object.values(elm.decls).forEach((funcs) => {
|
|
3352
3300
|
funcs.forEach((f) => {
|
|
3353
|
-
if (f.type === "FunctionDeclaration" &&
|
|
3301
|
+
if (f.type === "FunctionDeclaration" &&
|
|
3302
|
+
!(f.attributes & StateNodeAttributes.STATIC)) {
|
|
3354
3303
|
markInvokeClassMethod(f);
|
|
3355
3304
|
}
|
|
3356
3305
|
});
|
|
@@ -3389,7 +3338,7 @@ function getFileASTs(fnMap) {
|
|
|
3389
3338
|
return ok;
|
|
3390
3339
|
}, true));
|
|
3391
3340
|
}
|
|
3392
|
-
async function analyze(fnMap,
|
|
3341
|
+
async function analyze(fnMap, resourcesMap, config) {
|
|
3393
3342
|
let hasTests = false;
|
|
3394
3343
|
let markApi = true;
|
|
3395
3344
|
const preState = {
|
|
@@ -3430,11 +3379,6 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
3430
3379
|
const [scope] = state.stack.slice(-1);
|
|
3431
3380
|
scope.stack = state.stackClone().slice(0, -1);
|
|
3432
3381
|
if (scope.type == "FunctionDeclaration") {
|
|
3433
|
-
scope.isStatic =
|
|
3434
|
-
scope.stack.slice(-1)[0].type !== "ClassDeclaration" ||
|
|
3435
|
-
(scope.node.attrs &&
|
|
3436
|
-
scope.node.attrs.access &&
|
|
3437
|
-
scope.node.attrs.access.includes("static"));
|
|
3438
3382
|
if (markApi) {
|
|
3439
3383
|
node.body = null;
|
|
3440
3384
|
scope.info = getApiFunctionInfo(scope);
|
|
@@ -3457,7 +3401,7 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
3457
3401
|
return null;
|
|
3458
3402
|
},
|
|
3459
3403
|
};
|
|
3460
|
-
await getApiMapping(preState,
|
|
3404
|
+
await getApiMapping(preState, resourcesMap);
|
|
3461
3405
|
markApi = false;
|
|
3462
3406
|
const state = preState;
|
|
3463
3407
|
await getFileASTs(fnMap);
|
|
@@ -3473,17 +3417,53 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
3473
3417
|
delete state.shouldExclude;
|
|
3474
3418
|
delete state.pre;
|
|
3475
3419
|
collectClassInfo(state);
|
|
3420
|
+
state.exposed = state.nextExposed;
|
|
3421
|
+
state.nextExposed = {};
|
|
3422
|
+
return state;
|
|
3423
|
+
}
|
|
3424
|
+
function reportMissingSymbols(state, config) {
|
|
3476
3425
|
const diagnosticType = config?.checkInvalidSymbols !== "OFF"
|
|
3477
3426
|
? config?.checkInvalidSymbols || "WARNING"
|
|
3478
3427
|
: null;
|
|
3428
|
+
const compiler2DiagnosticType = config?.checkCompilerLookupRules !== "OFF"
|
|
3429
|
+
? config?.checkCompilerLookupRules || "WARNING"
|
|
3430
|
+
: null;
|
|
3479
3431
|
if (diagnosticType &&
|
|
3480
3432
|
!config?.compilerOptions?.includes("--Eno-invalid-symbol")) {
|
|
3481
3433
|
const checkTypes = config?.typeCheckLevel && config.typeCheckLevel !== "Off";
|
|
3482
|
-
Object.entries(fnMap).forEach(([, v]) => {
|
|
3434
|
+
Object.entries(state.fnMap).forEach(([, v]) => {
|
|
3483
3435
|
visitReferences(state, v.ast, null, false, (node, results, error) => {
|
|
3484
|
-
if (
|
|
3436
|
+
if (node.type === "BinaryExpression" && node.operator === "has") {
|
|
3437
|
+
// Its not an error to check whether a property exists...
|
|
3485
3438
|
return undefined;
|
|
3439
|
+
}
|
|
3486
3440
|
const nodeStr = formatAst(node);
|
|
3441
|
+
if (!error) {
|
|
3442
|
+
if (state.sdkVersion === 4001006 &&
|
|
3443
|
+
compiler2DiagnosticType &&
|
|
3444
|
+
node.type === "MemberExpression" &&
|
|
3445
|
+
(node.object.type === "Identifier" ||
|
|
3446
|
+
node.object.type === "MemberExpression") &&
|
|
3447
|
+
results.some((result) => {
|
|
3448
|
+
const parent = result.parent;
|
|
3449
|
+
if (!parent || parent.type !== "ClassDeclaration") {
|
|
3450
|
+
return false;
|
|
3451
|
+
}
|
|
3452
|
+
return result.results.some((sn) => {
|
|
3453
|
+
switch (sn.type) {
|
|
3454
|
+
case "VariableDeclarator":
|
|
3455
|
+
case "FunctionDeclaration":
|
|
3456
|
+
return (sn.attributes &
|
|
3457
|
+
(StateNodeAttributes.PRIVATE |
|
|
3458
|
+
StateNodeAttributes.PROTECTED));
|
|
3459
|
+
}
|
|
3460
|
+
return false;
|
|
3461
|
+
});
|
|
3462
|
+
})) {
|
|
3463
|
+
diagnostic(state, node.loc, `The expression ${nodeStr} will fail at runtime using sdk-4.1.6`, compiler2DiagnosticType);
|
|
3464
|
+
}
|
|
3465
|
+
return undefined;
|
|
3466
|
+
}
|
|
3487
3467
|
if (state.inType) {
|
|
3488
3468
|
if (!checkTypes || nodeStr.match(/^Void|Null$/)) {
|
|
3489
3469
|
return undefined;
|
|
@@ -3494,9 +3474,6 @@ async function analyze(fnMap, barrelList, config) {
|
|
|
3494
3474
|
});
|
|
3495
3475
|
});
|
|
3496
3476
|
}
|
|
3497
|
-
state.exposed = state.nextExposed;
|
|
3498
|
-
state.nextExposed = {};
|
|
3499
|
-
return state;
|
|
3500
3477
|
}
|
|
3501
3478
|
function compareLiteralLike(a, b) {
|
|
3502
3479
|
while (a.type === "BinaryExpression")
|
|
@@ -3700,7 +3677,7 @@ function optimizeNode(state, node) {
|
|
|
3700
3677
|
left.value === null ||
|
|
3701
3678
|
((left_type === "Number" || left_type === "Long") &&
|
|
3702
3679
|
(left.value === 0 || left.value === 0n));
|
|
3703
|
-
if (falsy === (node.operator === "&&")) {
|
|
3680
|
+
if (falsy === (node.operator === "&&" || node.operator === "and")) {
|
|
3704
3681
|
return left;
|
|
3705
3682
|
}
|
|
3706
3683
|
if (left_type !== "Boolean" &&
|
|
@@ -3710,10 +3687,12 @@ function optimizeNode(state, node) {
|
|
|
3710
3687
|
}
|
|
3711
3688
|
const [right, right_type] = getNodeValue(node.right);
|
|
3712
3689
|
if (right && right_type === left_type) {
|
|
3713
|
-
if (left_type === "Boolean" ||
|
|
3690
|
+
if (left_type === "Boolean" ||
|
|
3691
|
+
node.operator === "||" ||
|
|
3692
|
+
node.operator === "or") {
|
|
3714
3693
|
return right;
|
|
3715
3694
|
}
|
|
3716
|
-
if (node.operator !== "&&") {
|
|
3695
|
+
if (node.operator !== "&&" && node.operator !== "and") {
|
|
3717
3696
|
throw new Error(`Unexpected operator "${node.operator}"`);
|
|
3718
3697
|
}
|
|
3719
3698
|
return { ...node, type: "BinaryExpression", operator: "&" };
|
|
@@ -3790,8 +3769,8 @@ function markFunctionCalled(state, func) {
|
|
|
3790
3769
|
}
|
|
3791
3770
|
pushUnique(state.calledFunctions[func.id.name], func);
|
|
3792
3771
|
}
|
|
3793
|
-
async function optimizeMonkeyC(fnMap,
|
|
3794
|
-
const state = (await analyze(fnMap,
|
|
3772
|
+
async function optimizeMonkeyC(fnMap, resourcesMap, config) {
|
|
3773
|
+
const state = (await analyze(fnMap, resourcesMap, config));
|
|
3795
3774
|
state.localsStack = [{}];
|
|
3796
3775
|
state.calledFunctions = {};
|
|
3797
3776
|
state.usedByName = {};
|
|
@@ -4191,6 +4170,36 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4191
4170
|
return replace(optimizeCall(state, node.argument, node), node.argument);
|
|
4192
4171
|
}
|
|
4193
4172
|
break;
|
|
4173
|
+
case "BinaryExpression":
|
|
4174
|
+
if (node.operator === "has" &&
|
|
4175
|
+
node.right.type === "UnaryExpression" &&
|
|
4176
|
+
node.right.operator === ":") {
|
|
4177
|
+
const [, results] = state.lookup(node.left);
|
|
4178
|
+
if (results &&
|
|
4179
|
+
results.length === 1 &&
|
|
4180
|
+
results[0].results.length === 1) {
|
|
4181
|
+
const obj = results[0].results[0];
|
|
4182
|
+
if ((obj.type === "ModuleDeclaration" ||
|
|
4183
|
+
obj.type === "Program" ||
|
|
4184
|
+
obj.type === "ClassDeclaration") &&
|
|
4185
|
+
obj.stack) {
|
|
4186
|
+
const exists = hasProperty(obj.decls, node.right.argument.name) ||
|
|
4187
|
+
// This is overkill, since we've already looked up
|
|
4188
|
+
// node.left, but the actual lookup rules are complicated,
|
|
4189
|
+
// and embedded within state.lookup; so just defer to that.
|
|
4190
|
+
state.lookup({
|
|
4191
|
+
type: "MemberExpression",
|
|
4192
|
+
object: node.left,
|
|
4193
|
+
property: node.right.argument,
|
|
4194
|
+
computed: false,
|
|
4195
|
+
})[1];
|
|
4196
|
+
if (!exists) {
|
|
4197
|
+
return replace({ type: "Literal", value: false, raw: "false" }, node);
|
|
4198
|
+
}
|
|
4199
|
+
}
|
|
4200
|
+
}
|
|
4201
|
+
}
|
|
4202
|
+
break;
|
|
4194
4203
|
case "NewExpression":
|
|
4195
4204
|
if (state.currentFunction) {
|
|
4196
4205
|
const [, results] = state.lookup(node.callee);
|
|
@@ -4273,7 +4282,7 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4273
4282
|
}
|
|
4274
4283
|
}
|
|
4275
4284
|
else {
|
|
4276
|
-
const ret = unused(node.expression, true);
|
|
4285
|
+
const ret = unused(state, node.expression, true);
|
|
4277
4286
|
if (ret) {
|
|
4278
4287
|
return ret
|
|
4279
4288
|
.map((r) => replace(r, r))
|
|
@@ -4418,7 +4427,7 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4418
4427
|
}
|
|
4419
4428
|
return null;
|
|
4420
4429
|
};
|
|
4421
|
-
Object.entries(fnMap).forEach(([
|
|
4430
|
+
Object.entries(fnMap).forEach(([, f]) => {
|
|
4422
4431
|
traverseAst(f.ast, undefined, (node) => {
|
|
4423
4432
|
const ret = cleanup(node);
|
|
4424
4433
|
if (ret === false) {
|
|
@@ -4426,6 +4435,9 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
4426
4435
|
}
|
|
4427
4436
|
return ret;
|
|
4428
4437
|
});
|
|
4438
|
+
});
|
|
4439
|
+
reportMissingSymbols(state, config);
|
|
4440
|
+
Object.entries(fnMap).forEach(([name, f]) => {
|
|
4429
4441
|
if (state.config && state.config.checkBuildPragmas) {
|
|
4430
4442
|
pragmaChecker(state, f.ast, state.diagnostics?.[name]);
|
|
4431
4443
|
}
|
|
@@ -4541,6 +4553,322 @@ const negativeFixups = [
|
|
|
4541
4553
|
|
|
4542
4554
|
;// CONCATENATED MODULE: external "./sdk-util.cjs"
|
|
4543
4555
|
const external_sdk_util_cjs_namespaceObject = require("./sdk-util.cjs");
|
|
4556
|
+
;// CONCATENATED MODULE: ./src/resources.ts
|
|
4557
|
+
|
|
4558
|
+
|
|
4559
|
+
/*
|
|
4560
|
+
* This is unavoidably ad-hoc. Garmin has arbitrary rules for how
|
|
4561
|
+
* resources can be nested, which we need to mimic here.
|
|
4562
|
+
*/
|
|
4563
|
+
function visit_resources(elements, parent, visitor, error) {
|
|
4564
|
+
elements.forEach((e) => {
|
|
4565
|
+
switch (e.name) {
|
|
4566
|
+
// <resources> can contain any of the resource lists (except
|
|
4567
|
+
// another resources), and any of their contents
|
|
4568
|
+
case "resources":
|
|
4569
|
+
if (parent) {
|
|
4570
|
+
error(e, parent);
|
|
4571
|
+
return;
|
|
4572
|
+
}
|
|
4573
|
+
visit_resources(external_sdk_util_cjs_namespaceObject.xmlUtil.elementKids(e), "resources", visitor, error);
|
|
4574
|
+
return;
|
|
4575
|
+
// Each of these is a list that can contain certain kinds of resource.
|
|
4576
|
+
// They can only occur at the top level, or under a <resources> list.
|
|
4577
|
+
case "strings":
|
|
4578
|
+
case "fonts":
|
|
4579
|
+
case "animations":
|
|
4580
|
+
case "bitmaps":
|
|
4581
|
+
case "layouts":
|
|
4582
|
+
case "menus":
|
|
4583
|
+
case "drawables":
|
|
4584
|
+
case "properties":
|
|
4585
|
+
case "settings":
|
|
4586
|
+
case "fitContributions":
|
|
4587
|
+
case "jsonDataResources":
|
|
4588
|
+
case "complications":
|
|
4589
|
+
if (parent && parent !== "resources") {
|
|
4590
|
+
error(e, parent);
|
|
4591
|
+
return;
|
|
4592
|
+
}
|
|
4593
|
+
visit_resources(external_sdk_util_cjs_namespaceObject.xmlUtil.elementKids(e), e.name, visitor, error);
|
|
4594
|
+
return;
|
|
4595
|
+
// These are the resources themselves. Some can occur at top level; most
|
|
4596
|
+
// are restricted to <resources> or one or more of the specific lists above
|
|
4597
|
+
case "string":
|
|
4598
|
+
if (parent !== "strings" && parent !== "resources") {
|
|
4599
|
+
error(e, parent);
|
|
4600
|
+
return;
|
|
4601
|
+
}
|
|
4602
|
+
visitor(e, "Strings");
|
|
4603
|
+
return;
|
|
4604
|
+
case "font":
|
|
4605
|
+
if (parent !== "fonts" && parent !== "resources") {
|
|
4606
|
+
error(e, parent);
|
|
4607
|
+
return;
|
|
4608
|
+
}
|
|
4609
|
+
visitor(e, "Fonts");
|
|
4610
|
+
return;
|
|
4611
|
+
case "animation":
|
|
4612
|
+
if (parent !== "animations" && parent !== "resources") {
|
|
4613
|
+
error(e, parent);
|
|
4614
|
+
return;
|
|
4615
|
+
}
|
|
4616
|
+
visitor(e, "Drawables");
|
|
4617
|
+
return;
|
|
4618
|
+
case "menu":
|
|
4619
|
+
case "menu2":
|
|
4620
|
+
case "checkbox-menu":
|
|
4621
|
+
case "action-menu":
|
|
4622
|
+
if (parent && parent !== "menus" && parent !== "resources") {
|
|
4623
|
+
error(e, parent);
|
|
4624
|
+
return;
|
|
4625
|
+
}
|
|
4626
|
+
visitor(e, "Menus");
|
|
4627
|
+
return;
|
|
4628
|
+
case "bitmap":
|
|
4629
|
+
if (parent !== "bitmaps" &&
|
|
4630
|
+
parent !== "drawables" &&
|
|
4631
|
+
parent !== "resources") {
|
|
4632
|
+
error(e, parent);
|
|
4633
|
+
return;
|
|
4634
|
+
}
|
|
4635
|
+
visitor(e, "Drawables");
|
|
4636
|
+
return;
|
|
4637
|
+
case "layout":
|
|
4638
|
+
if (parent && parent !== "layouts" && parent !== "resources") {
|
|
4639
|
+
error(e, parent);
|
|
4640
|
+
return;
|
|
4641
|
+
}
|
|
4642
|
+
visitor(e, "Layouts");
|
|
4643
|
+
return;
|
|
4644
|
+
case "drawable-list":
|
|
4645
|
+
if (parent && parent !== "drawables" && parent !== "resources") {
|
|
4646
|
+
error(e, parent);
|
|
4647
|
+
return;
|
|
4648
|
+
}
|
|
4649
|
+
visitor(e, "Drawables");
|
|
4650
|
+
return;
|
|
4651
|
+
case "property":
|
|
4652
|
+
if (parent !== "properties" && parent !== "resources") {
|
|
4653
|
+
error(e, parent);
|
|
4654
|
+
return;
|
|
4655
|
+
}
|
|
4656
|
+
visitor(e, "Properties");
|
|
4657
|
+
return;
|
|
4658
|
+
case "setting":
|
|
4659
|
+
if (parent !== "settings" && parent !== "resources") {
|
|
4660
|
+
error(e, parent);
|
|
4661
|
+
return;
|
|
4662
|
+
}
|
|
4663
|
+
visitor(e, null);
|
|
4664
|
+
return;
|
|
4665
|
+
case "group":
|
|
4666
|
+
if (parent !== "settings" /* && parent !== "resources" */) {
|
|
4667
|
+
error(e, parent);
|
|
4668
|
+
return;
|
|
4669
|
+
}
|
|
4670
|
+
visitor(e, null);
|
|
4671
|
+
return;
|
|
4672
|
+
case "fitField":
|
|
4673
|
+
if (parent !== "fitContributions" && parent !== "resources") {
|
|
4674
|
+
error(e, parent);
|
|
4675
|
+
return;
|
|
4676
|
+
}
|
|
4677
|
+
visitor(e, null);
|
|
4678
|
+
return;
|
|
4679
|
+
case "jsonData":
|
|
4680
|
+
if (parent && parent != "jsonDataResources" && parent !== "resources") {
|
|
4681
|
+
error(e, parent);
|
|
4682
|
+
return;
|
|
4683
|
+
}
|
|
4684
|
+
visitor(e, "JsonData");
|
|
4685
|
+
return;
|
|
4686
|
+
case "build":
|
|
4687
|
+
if (parent && parent !== "resources") {
|
|
4688
|
+
error(e, parent);
|
|
4689
|
+
return;
|
|
4690
|
+
}
|
|
4691
|
+
visitor(e, null);
|
|
4692
|
+
return;
|
|
4693
|
+
}
|
|
4694
|
+
});
|
|
4695
|
+
}
|
|
4696
|
+
function add_resources_to_ast(ast, resources) {
|
|
4697
|
+
Object.entries(resources).forEach(([barrel, resourceMap]) => {
|
|
4698
|
+
const rezModules = {
|
|
4699
|
+
Drawables: [],
|
|
4700
|
+
Fonts: [],
|
|
4701
|
+
JsonData: [],
|
|
4702
|
+
Layouts: [],
|
|
4703
|
+
Menus: [],
|
|
4704
|
+
Properties: [],
|
|
4705
|
+
Strings: [],
|
|
4706
|
+
};
|
|
4707
|
+
Object.values(resourceMap).forEach((rez) => {
|
|
4708
|
+
if (!rez || !(rez instanceof external_sdk_util_cjs_namespaceObject.xmlUtil.Document))
|
|
4709
|
+
return;
|
|
4710
|
+
visit_resources(rez.body.elements, null, (e, s) => {
|
|
4711
|
+
if (!s)
|
|
4712
|
+
return;
|
|
4713
|
+
if (!ast_hasProperty(rezModules, s))
|
|
4714
|
+
return;
|
|
4715
|
+
rezModules[s].push(e);
|
|
4716
|
+
}, (_e, _s) => {
|
|
4717
|
+
return;
|
|
4718
|
+
});
|
|
4719
|
+
});
|
|
4720
|
+
const outerLoc = ast.loc && { ...ast.loc };
|
|
4721
|
+
const makeModule = (m) => ({
|
|
4722
|
+
type: "ModuleDeclaration",
|
|
4723
|
+
id: { type: "Identifier", name: m },
|
|
4724
|
+
body: { type: "BlockStatement", body: [] },
|
|
4725
|
+
loc: outerLoc,
|
|
4726
|
+
});
|
|
4727
|
+
let body = ast.body;
|
|
4728
|
+
if (barrel !== "") {
|
|
4729
|
+
const module = makeModule(barrel);
|
|
4730
|
+
body.push(module);
|
|
4731
|
+
body = module.body.body;
|
|
4732
|
+
}
|
|
4733
|
+
const rez = makeModule("Rez");
|
|
4734
|
+
body.push(rez);
|
|
4735
|
+
body = rez.body.body;
|
|
4736
|
+
Object.entries(rezModules).forEach(([m, elements]) => {
|
|
4737
|
+
const module = makeModule(m);
|
|
4738
|
+
body.push(module);
|
|
4739
|
+
elements.forEach((e) => e.attr.id &&
|
|
4740
|
+
module.body.body.push({
|
|
4741
|
+
type: "VariableDeclaration",
|
|
4742
|
+
declarations: [
|
|
4743
|
+
{
|
|
4744
|
+
type: "VariableDeclarator",
|
|
4745
|
+
kind: "var",
|
|
4746
|
+
id: { type: "Identifier", name: e.attr.id, loc: e.loc },
|
|
4747
|
+
loc: e.loc,
|
|
4748
|
+
},
|
|
4749
|
+
],
|
|
4750
|
+
kind: "var",
|
|
4751
|
+
loc: e.loc,
|
|
4752
|
+
}));
|
|
4753
|
+
});
|
|
4754
|
+
});
|
|
4755
|
+
}
|
|
4756
|
+
|
|
4757
|
+
;// CONCATENATED MODULE: ./src/visitor.ts
|
|
4758
|
+
|
|
4759
|
+
function visitorNode(node) {
|
|
4760
|
+
if (node.type === "Identifier") {
|
|
4761
|
+
return node;
|
|
4762
|
+
}
|
|
4763
|
+
if (node.type === "MemberExpression") {
|
|
4764
|
+
return node.property;
|
|
4765
|
+
}
|
|
4766
|
+
if (node.type === "BinaryExpression" &&
|
|
4767
|
+
node.operator === "has" &&
|
|
4768
|
+
node.right.type === "UnaryExpression" &&
|
|
4769
|
+
node.right.operator === ":") {
|
|
4770
|
+
return node.right.argument;
|
|
4771
|
+
}
|
|
4772
|
+
return node;
|
|
4773
|
+
}
|
|
4774
|
+
function visitor_visitReferences(state, ast, name, defn, callback) {
|
|
4775
|
+
const checkResults = ([name, results], node) => {
|
|
4776
|
+
if (name && results) {
|
|
4777
|
+
if (!defn || (0,external_api_cjs_namespaceObject.sameLookupResult)(results, defn)) {
|
|
4778
|
+
if (callback(node, results, false) === false) {
|
|
4779
|
+
return [];
|
|
4780
|
+
}
|
|
4781
|
+
}
|
|
4782
|
+
}
|
|
4783
|
+
else if (defn === false) {
|
|
4784
|
+
if (callback(node, [], results === null) === false) {
|
|
4785
|
+
return [];
|
|
4786
|
+
}
|
|
4787
|
+
}
|
|
4788
|
+
return null;
|
|
4789
|
+
};
|
|
4790
|
+
state.pre = (node) => {
|
|
4791
|
+
switch (node.type) {
|
|
4792
|
+
case "AttributeList":
|
|
4793
|
+
return [];
|
|
4794
|
+
case "UnaryExpression":
|
|
4795
|
+
// a bare symbol isn't a reference
|
|
4796
|
+
if (node.operator === ":")
|
|
4797
|
+
return [];
|
|
4798
|
+
break;
|
|
4799
|
+
case "BinaryExpression":
|
|
4800
|
+
/*
|
|
4801
|
+
* `expr has :symbol` can be treated as a reference
|
|
4802
|
+
* to expr.symbol.
|
|
4803
|
+
*/
|
|
4804
|
+
if (node.operator === "has") {
|
|
4805
|
+
if (node.right.type === "UnaryExpression" &&
|
|
4806
|
+
node.right.operator === ":") {
|
|
4807
|
+
if (!name || node.right.argument.name === name) {
|
|
4808
|
+
return checkResults(state.lookup({
|
|
4809
|
+
type: "MemberExpression",
|
|
4810
|
+
object: node.left,
|
|
4811
|
+
property: node.right.argument,
|
|
4812
|
+
computed: false,
|
|
4813
|
+
}), node);
|
|
4814
|
+
}
|
|
4815
|
+
}
|
|
4816
|
+
}
|
|
4817
|
+
break;
|
|
4818
|
+
case "CallExpression":
|
|
4819
|
+
// A call expression whose callee is an identifier is looked
|
|
4820
|
+
// up as a non-local. ie even if there's a same named local,
|
|
4821
|
+
// it will be ignored, and the lookup will start as if the
|
|
4822
|
+
// call had been written self.foo() rather than foo().
|
|
4823
|
+
if (node.callee.type === "Identifier") {
|
|
4824
|
+
if (!name || node.callee.name === name) {
|
|
4825
|
+
/* ignore return value */
|
|
4826
|
+
checkResults(state.lookupNonlocal(node.callee), node.callee);
|
|
4827
|
+
}
|
|
4828
|
+
return ["arguments"];
|
|
4829
|
+
}
|
|
4830
|
+
break;
|
|
4831
|
+
case "Identifier":
|
|
4832
|
+
if (!name || node.name === name) {
|
|
4833
|
+
return checkResults(state.lookup(node), node);
|
|
4834
|
+
}
|
|
4835
|
+
break;
|
|
4836
|
+
case "MemberExpression": {
|
|
4837
|
+
const property = (0,external_api_cjs_namespaceObject.isLookupCandidate)(node);
|
|
4838
|
+
if (property) {
|
|
4839
|
+
if (!name || property.name === name) {
|
|
4840
|
+
return checkResults(state.lookup(node), node) || ["object"];
|
|
4841
|
+
}
|
|
4842
|
+
return ["object"];
|
|
4843
|
+
}
|
|
4844
|
+
break;
|
|
4845
|
+
}
|
|
4846
|
+
case "MethodDefinition": {
|
|
4847
|
+
if (!state.inType) {
|
|
4848
|
+
throw new Error("Method definition outside of type!");
|
|
4849
|
+
}
|
|
4850
|
+
if (node.params) {
|
|
4851
|
+
node.params.forEach((param) => {
|
|
4852
|
+
if (param.type == "BinaryExpression") {
|
|
4853
|
+
state.traverse(param.right);
|
|
4854
|
+
}
|
|
4855
|
+
});
|
|
4856
|
+
}
|
|
4857
|
+
return ["returnType"];
|
|
4858
|
+
}
|
|
4859
|
+
case "ModuleDeclaration":
|
|
4860
|
+
return ["body"];
|
|
4861
|
+
case "ClassDeclaration":
|
|
4862
|
+
return ["body", "superClass"];
|
|
4863
|
+
case "FunctionDeclaration":
|
|
4864
|
+
return ["params", "returnType", "body"];
|
|
4865
|
+
}
|
|
4866
|
+
return null;
|
|
4867
|
+
};
|
|
4868
|
+
(0,external_api_cjs_namespaceObject.collectNamespaces)(ast, state);
|
|
4869
|
+
delete state.pre;
|
|
4870
|
+
}
|
|
4871
|
+
|
|
4544
4872
|
;// CONCATENATED MODULE: ./src/api.ts
|
|
4545
4873
|
|
|
4546
4874
|
|
|
@@ -4553,6 +4881,8 @@ const external_sdk_util_cjs_namespaceObject = require("./sdk-util.cjs");
|
|
|
4553
4881
|
|
|
4554
4882
|
|
|
4555
4883
|
|
|
4884
|
+
|
|
4885
|
+
|
|
4556
4886
|
/*
|
|
4557
4887
|
* This is an unfortunate hack. I want to be able to extract things
|
|
4558
4888
|
* like the types of all of a Class's variables (in particular the type
|
|
@@ -4562,35 +4892,62 @@ const external_sdk_util_cjs_namespaceObject = require("./sdk-util.cjs");
|
|
|
4562
4892
|
* undocumented. The same could be said of compiler.json and simulator.json,
|
|
4563
4893
|
* but those are at least in a standard format.
|
|
4564
4894
|
*/
|
|
4895
|
+
function parseSdkVersion(version) {
|
|
4896
|
+
if (!version)
|
|
4897
|
+
return 0;
|
|
4898
|
+
const match = version.match(/^(\d+)[._](\d+)[._](\d+)$/);
|
|
4899
|
+
if (!match)
|
|
4900
|
+
return 0;
|
|
4901
|
+
return (parseInt(match[1], 10) * 1000000 +
|
|
4902
|
+
parseInt(match[2], 10) * 1000 +
|
|
4903
|
+
parseInt(match[3], 10));
|
|
4904
|
+
}
|
|
4905
|
+
function api_checkCompilerVersion(version, sdkVer) {
|
|
4906
|
+
const match = version.match(/^(\d+[._]\d+[._]\d+)?([-_])?(\d+[._]\d+[._]\d+)?$/);
|
|
4907
|
+
if (!match ||
|
|
4908
|
+
(match[1] && match[3] && !match[2]) ||
|
|
4909
|
+
(!match[1] && !match[3])) {
|
|
4910
|
+
return undefined;
|
|
4911
|
+
}
|
|
4912
|
+
const v1 = parseSdkVersion(match[1]);
|
|
4913
|
+
const v2 = parseSdkVersion(match[3]);
|
|
4914
|
+
if (v1) {
|
|
4915
|
+
if (v2) {
|
|
4916
|
+
return v1 <= sdkVer && sdkVer <= v2;
|
|
4917
|
+
}
|
|
4918
|
+
if (match[2]) {
|
|
4919
|
+
return v1 <= sdkVer;
|
|
4920
|
+
}
|
|
4921
|
+
return v1 === sdkVer;
|
|
4922
|
+
}
|
|
4923
|
+
return sdkVer <= v2;
|
|
4924
|
+
}
|
|
4565
4925
|
// Extract all enum values from api.mir
|
|
4566
|
-
async function api_getApiMapping(state,
|
|
4926
|
+
async function api_getApiMapping(state, resourcesMap) {
|
|
4567
4927
|
// get the path to the currently active sdk
|
|
4568
4928
|
const parser = (prettier_plugin_monkeyc_default()).parsers.monkeyc;
|
|
4569
4929
|
const sdk = await (0,external_sdk_util_cjs_namespaceObject.getSdkPath)();
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
]
|
|
4578
|
-
.map((s) => ` module ${s} {}\n`)
|
|
4579
|
-
.join("")}}`;
|
|
4930
|
+
if (state) {
|
|
4931
|
+
state.sdk = sdk;
|
|
4932
|
+
const match = state.sdk?.match(/-(\d+\.\d+\.\d+)/);
|
|
4933
|
+
if (match) {
|
|
4934
|
+
state.sdkVersion = parseSdkVersion(match[1]);
|
|
4935
|
+
}
|
|
4936
|
+
}
|
|
4580
4937
|
const api = (await promises_namespaceObject.readFile(`${sdk}bin/api.mir`))
|
|
4581
4938
|
.toString()
|
|
4582
4939
|
.replace(/\r\n/g, "\n")
|
|
4583
4940
|
.replace(/^\s*\[.*?\]\s*$/gm, "")
|
|
4584
4941
|
//.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("");
|
|
4942
|
+
.replace(/^(\s*type)\s/gm, "$1def ");
|
|
4590
4943
|
try {
|
|
4591
|
-
const
|
|
4944
|
+
const ast = parser.parse(api, null, {
|
|
4592
4945
|
filepath: "api.mir",
|
|
4593
|
-
})
|
|
4946
|
+
});
|
|
4947
|
+
if (resourcesMap) {
|
|
4948
|
+
add_resources_to_ast(ast, resourcesMap);
|
|
4949
|
+
}
|
|
4950
|
+
const result = api_collectNamespaces(ast, state);
|
|
4594
4951
|
negativeFixups.forEach((fixup) => {
|
|
4595
4952
|
const vs = fixup.split(".").reduce((state, part) => {
|
|
4596
4953
|
const decls = api_isStateNode(state) && state.decls?.[part];
|
|
@@ -4633,6 +4990,26 @@ function api_isStateNode(node) {
|
|
|
4633
4990
|
function api_variableDeclarationName(node) {
|
|
4634
4991
|
return ("left" in node ? node.left : node).name;
|
|
4635
4992
|
}
|
|
4993
|
+
function stateNodeAttrs(attrs) {
|
|
4994
|
+
return attrs && attrs.access
|
|
4995
|
+
? attrs.access.reduce((cur, attr) => {
|
|
4996
|
+
switch (attr) {
|
|
4997
|
+
case "static":
|
|
4998
|
+
return cur | optimizer_types_StateNodeAttributes.STATIC;
|
|
4999
|
+
case "public":
|
|
5000
|
+
return cur | optimizer_types_StateNodeAttributes.PUBLIC;
|
|
5001
|
+
case "protected":
|
|
5002
|
+
return cur | optimizer_types_StateNodeAttributes.PROTECTED;
|
|
5003
|
+
case "hidden":
|
|
5004
|
+
return cur | optimizer_types_StateNodeAttributes.PROTECTED;
|
|
5005
|
+
case "private":
|
|
5006
|
+
return cur | optimizer_types_StateNodeAttributes.PRIVATE;
|
|
5007
|
+
default:
|
|
5008
|
+
return cur;
|
|
5009
|
+
}
|
|
5010
|
+
}, 0)
|
|
5011
|
+
: 0;
|
|
5012
|
+
}
|
|
4636
5013
|
function lookupToStateNodeDecls(results) {
|
|
4637
5014
|
return results.reduce((result, current) => current.results.length
|
|
4638
5015
|
? result
|
|
@@ -4640,7 +5017,7 @@ function lookupToStateNodeDecls(results) {
|
|
|
4640
5017
|
: current.results
|
|
4641
5018
|
: result, null);
|
|
4642
5019
|
}
|
|
4643
|
-
function checkOne(state, ns, decls, node
|
|
5020
|
+
function checkOne(state, ns, decls, node) {
|
|
4644
5021
|
// follow the superchain, looking up node in each class
|
|
4645
5022
|
const superChain = (cls) => {
|
|
4646
5023
|
if (!cls.superClass || cls.superClass === true) {
|
|
@@ -4655,7 +5032,7 @@ function checkOne(state, ns, decls, node, isStatic) {
|
|
|
4655
5032
|
}, null);
|
|
4656
5033
|
};
|
|
4657
5034
|
const lookupInContext = (ns) => {
|
|
4658
|
-
const [, lkup] = lookup(state, decls, node, null, ns.stack);
|
|
5035
|
+
const [, lkup] = lookup(state, decls, node, null, ns.stack, false, true);
|
|
4659
5036
|
return lkup && lookupToStateNodeDecls(lkup);
|
|
4660
5037
|
};
|
|
4661
5038
|
// follow the superchain, looking up node in each class's scope
|
|
@@ -4677,10 +5054,7 @@ function checkOne(state, ns, decls, node, isStatic) {
|
|
|
4677
5054
|
}
|
|
4678
5055
|
switch (ns.type) {
|
|
4679
5056
|
case "ClassDeclaration":
|
|
4680
|
-
|
|
4681
|
-
return superChain(ns) || superChainScopes(ns) || false;
|
|
4682
|
-
}
|
|
4683
|
-
// fall through
|
|
5057
|
+
return superChain(ns) || superChainScopes(ns) || false;
|
|
4684
5058
|
case "ModuleDeclaration":
|
|
4685
5059
|
return lookupInContext(ns) || false;
|
|
4686
5060
|
}
|
|
@@ -4728,7 +5102,7 @@ function api_isLookupCandidate(node) {
|
|
|
4728
5102
|
* - [false, false] - if the lookup fails, but its not an error because its not the kind of expression we can lookup
|
|
4729
5103
|
* - [null, null] - if the lookup fails unexpectedly.
|
|
4730
5104
|
*/
|
|
4731
|
-
function lookup(state, decls, node, name, maybeStack, nonlocal) {
|
|
5105
|
+
function lookup(state, decls, node, name, maybeStack, nonlocal, ignoreImports) {
|
|
4732
5106
|
const stack = maybeStack || state.stack;
|
|
4733
5107
|
switch (node.type) {
|
|
4734
5108
|
case "MemberExpression": {
|
|
@@ -4737,7 +5111,7 @@ function lookup(state, decls, node, name, maybeStack, nonlocal) {
|
|
|
4737
5111
|
break;
|
|
4738
5112
|
let result;
|
|
4739
5113
|
if (node.object.type === "ThisExpression") {
|
|
4740
|
-
[, result] = lookup(state, decls, node.property, name, stack, true);
|
|
5114
|
+
[, result] = lookup(state, decls, node.property, name, stack, true, true);
|
|
4741
5115
|
}
|
|
4742
5116
|
else {
|
|
4743
5117
|
const [, results] = lookup(state, decls, node.object, name, stack, false);
|
|
@@ -4751,7 +5125,7 @@ function lookup(state, decls, node, name, maybeStack, nonlocal) {
|
|
|
4751
5125
|
if (!api_isStateNode(module)) {
|
|
4752
5126
|
return null;
|
|
4753
5127
|
}
|
|
4754
|
-
const res = checkOne(state, module, decls, property
|
|
5128
|
+
const res = checkOne(state, module, decls, property);
|
|
4755
5129
|
return res ? { parent: module, results: res } : null;
|
|
4756
5130
|
})
|
|
4757
5131
|
.filter((r) => r != null);
|
|
@@ -4760,14 +5134,11 @@ function lookup(state, decls, node, name, maybeStack, nonlocal) {
|
|
|
4760
5134
|
return current ? current.concat(items) : items;
|
|
4761
5135
|
}, null);
|
|
4762
5136
|
if (!result &&
|
|
4763
|
-
results.some((ld) => ld.results.some((sn) =>
|
|
4764
|
-
sn.type === "VariableDeclarator" ||
|
|
5137
|
+
results.some((ld) => ld.results.some((sn) => sn.type === "VariableDeclarator" ||
|
|
4765
5138
|
sn.type === "Identifier" ||
|
|
4766
5139
|
sn.type === "BinaryExpression" ||
|
|
4767
5140
|
(sn.type === "ClassDeclaration" &&
|
|
4768
5141
|
property.name === "initialize")))) {
|
|
4769
|
-
// - The Rez module can contain lots of things from the resource
|
|
4770
|
-
// compiler which we don't track.
|
|
4771
5142
|
// - Variables, and formal parameters would require type tracking
|
|
4772
5143
|
// which we don't yet do
|
|
4773
5144
|
// - Its ok to call an undeclared initialize method.
|
|
@@ -4781,7 +5152,7 @@ function lookup(state, decls, node, name, maybeStack, nonlocal) {
|
|
|
4781
5152
|
}
|
|
4782
5153
|
case "ThisExpression": {
|
|
4783
5154
|
for (let i = stack.length;;) {
|
|
4784
|
-
const si = stack[i];
|
|
5155
|
+
const si = stack[--i];
|
|
4785
5156
|
if (si.type == "ModuleDeclaration" ||
|
|
4786
5157
|
si.type == "ClassDeclaration" ||
|
|
4787
5158
|
!i) {
|
|
@@ -4797,30 +5168,66 @@ function lookup(state, decls, node, name, maybeStack, nonlocal) {
|
|
|
4797
5168
|
return [name || node.name, [{ parent: null, results: [stack[0]] }]];
|
|
4798
5169
|
}
|
|
4799
5170
|
let inStatic = false;
|
|
4800
|
-
let checkedImports =
|
|
5171
|
+
let checkedImports = ignoreImports;
|
|
5172
|
+
let imports = null;
|
|
4801
5173
|
for (let i = stack.length; i--;) {
|
|
4802
5174
|
const si = stack[i];
|
|
4803
5175
|
switch (si.type) {
|
|
4804
5176
|
case "ClassDeclaration":
|
|
5177
|
+
if (inStatic && state.config?.enforceStatic != "NO") {
|
|
5178
|
+
inStatic = false;
|
|
5179
|
+
if (ast_hasProperty(si.decls, node.name)) {
|
|
5180
|
+
const r = si.decls[node.name].filter((s) => {
|
|
5181
|
+
switch (s.type) {
|
|
5182
|
+
case "FunctionDeclaration":
|
|
5183
|
+
case "VariableDeclarator":
|
|
5184
|
+
case "ClassDeclaration":
|
|
5185
|
+
// In theory we should include EnumStringMember here too, but
|
|
5186
|
+
// without adding an attributes field to EnumStringMember,
|
|
5187
|
+
// or turning it into a StateNodeDecl, we don't know whether
|
|
5188
|
+
// its static or not. But thats ok, because the optimizer
|
|
5189
|
+
// will replace its use with its value, so the optimized
|
|
5190
|
+
// code *will* work anyway.
|
|
5191
|
+
return s.attributes & optimizer_types_StateNodeAttributes.STATIC;
|
|
5192
|
+
default:
|
|
5193
|
+
return true;
|
|
5194
|
+
}
|
|
5195
|
+
});
|
|
5196
|
+
if (r.length) {
|
|
5197
|
+
return [name || node.name, [{ parent: si, results: r }]];
|
|
5198
|
+
}
|
|
5199
|
+
}
|
|
5200
|
+
continue;
|
|
5201
|
+
}
|
|
5202
|
+
// fall through
|
|
4805
5203
|
case "ModuleDeclaration":
|
|
4806
5204
|
case "Program":
|
|
4807
5205
|
if (!checkedImports) {
|
|
4808
5206
|
checkedImports = true;
|
|
4809
|
-
const results = findUsingForNode(state, stack, i, node
|
|
5207
|
+
const results = findUsingForNode(state, stack, i, node);
|
|
4810
5208
|
if (results) {
|
|
4811
|
-
|
|
5209
|
+
if (Array.isArray(results)) {
|
|
5210
|
+
if (!imports)
|
|
5211
|
+
imports = results;
|
|
5212
|
+
}
|
|
5213
|
+
else {
|
|
5214
|
+
return [
|
|
5215
|
+
name || node.name,
|
|
5216
|
+
[{ parent: si, results: [results] }],
|
|
5217
|
+
];
|
|
5218
|
+
}
|
|
4812
5219
|
}
|
|
4813
5220
|
}
|
|
4814
5221
|
break;
|
|
4815
5222
|
case "FunctionDeclaration":
|
|
4816
|
-
inStatic = si.
|
|
5223
|
+
inStatic = !!(si.attributes & optimizer_types_StateNodeAttributes.STATIC);
|
|
4817
5224
|
// fall through
|
|
4818
5225
|
default:
|
|
4819
5226
|
if (nonlocal)
|
|
4820
5227
|
continue;
|
|
4821
5228
|
break;
|
|
4822
5229
|
}
|
|
4823
|
-
const results = checkOne(state, si, decls, node
|
|
5230
|
+
const results = checkOne(state, si, decls, node);
|
|
4824
5231
|
if (results) {
|
|
4825
5232
|
return [name || node.name, [{ parent: si, results }]];
|
|
4826
5233
|
}
|
|
@@ -4828,6 +5235,31 @@ function lookup(state, decls, node, name, maybeStack, nonlocal) {
|
|
|
4828
5235
|
break;
|
|
4829
5236
|
}
|
|
4830
5237
|
}
|
|
5238
|
+
if (imports) {
|
|
5239
|
+
if (imports.length > 1) {
|
|
5240
|
+
if (state.config?.checkInvalidSymbols !== "OFF") {
|
|
5241
|
+
inliner_diagnostic(state, node.loc, `${api_formatAst(node)} is ambiguous and exists in multiple imported modules [${imports
|
|
5242
|
+
.map(({ name }) => name)
|
|
5243
|
+
.join(", ")}]`, state.config?.checkInvalidSymbols || "WARNING");
|
|
5244
|
+
}
|
|
5245
|
+
else if (decls !== "type_decls" &&
|
|
5246
|
+
state.lookupRules === "COMPILER1") {
|
|
5247
|
+
return [null, null];
|
|
5248
|
+
}
|
|
5249
|
+
return [name || node.name, imports.map((d) => d.decls)];
|
|
5250
|
+
}
|
|
5251
|
+
if (imports.length == 1) {
|
|
5252
|
+
if (decls !== "type_decls") {
|
|
5253
|
+
if (state.config?.checkCompilerLookupRules !== "OFF") {
|
|
5254
|
+
inliner_diagnostic(state, node.loc, `${api_formatAst(node)} will only be found when compiled with compiler2 at -O1 or above`, state.config?.checkCompilerLookupRules || "WARNING");
|
|
5255
|
+
}
|
|
5256
|
+
else if (state.lookupRules === "COMPILER1") {
|
|
5257
|
+
return [null, null];
|
|
5258
|
+
}
|
|
5259
|
+
}
|
|
5260
|
+
return [name || node.name, [imports[0].decls]];
|
|
5261
|
+
}
|
|
5262
|
+
}
|
|
4831
5263
|
return [null, null];
|
|
4832
5264
|
}
|
|
4833
5265
|
}
|
|
@@ -4841,9 +5273,27 @@ function api_collectNamespaces(ast, stateIn) {
|
|
|
4841
5273
|
state.index = {};
|
|
4842
5274
|
if (!state.stack) {
|
|
4843
5275
|
state.stack = [
|
|
4844
|
-
{
|
|
5276
|
+
{
|
|
5277
|
+
type: "Program",
|
|
5278
|
+
name: "$",
|
|
5279
|
+
fullName: "$",
|
|
5280
|
+
node: undefined,
|
|
5281
|
+
attributes: 0,
|
|
5282
|
+
},
|
|
4845
5283
|
];
|
|
4846
5284
|
}
|
|
5285
|
+
if (!state.lookupRules) {
|
|
5286
|
+
const rules = state?.config?.compilerLookupRules || "DEFAULT";
|
|
5287
|
+
if (rules !== "COMPILER1" && rules !== "COMPILER2") {
|
|
5288
|
+
const match = state.sdk?.match(/-(\d+\.\d+\.\d+).(compiler2beta)?/i);
|
|
5289
|
+
if (match && (match[2] || parseSdkVersion(match[1]) >= 4001006)) {
|
|
5290
|
+
state.lookupRules = "COMPILER2";
|
|
5291
|
+
}
|
|
5292
|
+
else {
|
|
5293
|
+
state.lookupRules = "COMPILER1";
|
|
5294
|
+
}
|
|
5295
|
+
}
|
|
5296
|
+
}
|
|
4847
5297
|
state.removeNodeComments = (node, ast) => {
|
|
4848
5298
|
if (node.start && node.end && ast.comments && ast.comments.length) {
|
|
4849
5299
|
let low = 0, high = ast.comments.length;
|
|
@@ -4938,6 +5388,7 @@ function api_collectNamespaces(ast, stateIn) {
|
|
|
4938
5388
|
name: undefined,
|
|
4939
5389
|
node: node.body,
|
|
4940
5390
|
decls: { [id.name]: [id] },
|
|
5391
|
+
attributes: 0,
|
|
4941
5392
|
});
|
|
4942
5393
|
}
|
|
4943
5394
|
break;
|
|
@@ -4948,6 +5399,7 @@ function api_collectNamespaces(ast, stateIn) {
|
|
|
4948
5399
|
fullName: undefined,
|
|
4949
5400
|
name: undefined,
|
|
4950
5401
|
node: node,
|
|
5402
|
+
attributes: 0,
|
|
4951
5403
|
});
|
|
4952
5404
|
}
|
|
4953
5405
|
break;
|
|
@@ -4975,6 +5427,9 @@ function api_collectNamespaces(ast, stateIn) {
|
|
|
4975
5427
|
name,
|
|
4976
5428
|
fullName,
|
|
4977
5429
|
node,
|
|
5430
|
+
attributes: node.type === "BlockStatement"
|
|
5431
|
+
? 0
|
|
5432
|
+
: stateNodeAttrs(node.attrs),
|
|
4978
5433
|
};
|
|
4979
5434
|
state.stack.push(elm);
|
|
4980
5435
|
if (name) {
|
|
@@ -5001,9 +5456,6 @@ function api_collectNamespaces(ast, stateIn) {
|
|
|
5001
5456
|
parent.decls[name].push(elm);
|
|
5002
5457
|
if (node.type == "ModuleDeclaration" ||
|
|
5003
5458
|
node.type == "ClassDeclaration") {
|
|
5004
|
-
// Inject the class/module name into itself,
|
|
5005
|
-
// so you can say Graphics.Graphics.Graphics.COLOR_RED
|
|
5006
|
-
elm.decls = { [name]: [elm] };
|
|
5007
5459
|
if (!parent.type_decls)
|
|
5008
5460
|
parent.type_decls = {};
|
|
5009
5461
|
if (!ast_hasProperty(parent.type_decls, name)) {
|
|
@@ -5045,6 +5497,7 @@ function api_collectNamespaces(ast, stateIn) {
|
|
|
5045
5497
|
node,
|
|
5046
5498
|
name,
|
|
5047
5499
|
fullName: parent.fullName + "." + name,
|
|
5500
|
+
attributes: stateNodeAttrs(node.attrs),
|
|
5048
5501
|
});
|
|
5049
5502
|
break;
|
|
5050
5503
|
}
|
|
@@ -5063,12 +5516,13 @@ function api_collectNamespaces(ast, stateIn) {
|
|
|
5063
5516
|
return;
|
|
5064
5517
|
}
|
|
5065
5518
|
decl.kind = node.kind;
|
|
5066
|
-
|
|
5519
|
+
decls[name].push({
|
|
5067
5520
|
type: "VariableDeclarator",
|
|
5068
5521
|
node: decl,
|
|
5069
5522
|
name,
|
|
5070
5523
|
fullName: parent.fullName + "." + name,
|
|
5071
5524
|
stack,
|
|
5525
|
+
attributes: stateNodeAttrs(node.attrs),
|
|
5072
5526
|
});
|
|
5073
5527
|
if (node.kind == "const") {
|
|
5074
5528
|
if (!ast_hasProperty(state.index, name)) {
|
|
@@ -5293,27 +5747,32 @@ function findUsing(state, stack, using) {
|
|
|
5293
5747
|
}
|
|
5294
5748
|
return null;
|
|
5295
5749
|
}
|
|
5296
|
-
function findUsingForNode(state, stack, i, node
|
|
5750
|
+
function findUsingForNode(state, stack, i, node) {
|
|
5751
|
+
let imports = null;
|
|
5297
5752
|
while (i >= 0) {
|
|
5298
5753
|
const si = stack[i--];
|
|
5299
5754
|
if (ast_hasProperty(si.usings, node.name)) {
|
|
5300
5755
|
const using = si.usings[node.name];
|
|
5301
|
-
|
|
5302
|
-
return module && [module];
|
|
5756
|
+
return findUsing(state, stack, using);
|
|
5303
5757
|
}
|
|
5304
|
-
if (si.imports
|
|
5758
|
+
if (si.imports) {
|
|
5305
5759
|
for (let j = si.imports.length; j--;) {
|
|
5306
5760
|
const using = si.imports[j];
|
|
5307
5761
|
const module = findUsing(state, stack, using);
|
|
5308
5762
|
if (module) {
|
|
5309
5763
|
if (ast_hasProperty(module.type_decls, node.name)) {
|
|
5310
|
-
|
|
5764
|
+
if (!imports)
|
|
5765
|
+
imports = [];
|
|
5766
|
+
imports.push({
|
|
5767
|
+
name: `${module.fullName}.${node.name}`,
|
|
5768
|
+
decls: { parent: si, results: module.type_decls[node.name] },
|
|
5769
|
+
});
|
|
5311
5770
|
}
|
|
5312
5771
|
}
|
|
5313
5772
|
}
|
|
5314
5773
|
}
|
|
5315
5774
|
}
|
|
5316
|
-
return
|
|
5775
|
+
return imports;
|
|
5317
5776
|
}
|
|
5318
5777
|
const invokeInfo = {};
|
|
5319
5778
|
const toyboxFnInfo = {};
|