@markw65/monkeyc-optimizer 1.0.10 → 1.0.13
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 +41 -0
- package/build/api.cjs +1333 -1066
- package/build/optimizer.cjs +2020 -2080
- package/build/sdk-util.cjs +33 -34
- package/build/src/api.d.ts +9 -0
- package/build/src/build.d.ts +6 -0
- package/build/src/estree-types.d.ts +324 -0
- package/build/src/jungles.d.ts +51 -0
- package/build/src/launch.d.ts +2 -0
- package/build/src/manifest.d.ts +71 -0
- package/build/src/mc-rewrite.d.ts +7 -0
- package/build/src/negative-fixups.d.ts +1 -0
- package/build/src/optimizer.d.ts +185 -0
- package/build/src/sdk-util.d.ts +15 -0
- package/build/src/util.d.ts +13 -0
- package/build/util.cjs +108 -108
- package/package.json +10 -3
package/build/optimizer.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
0 && (module.exports = {copyRecursiveAsNeeded,launchSimulator,defaultConfig,buildOptimizedProject,generateOptimizedProject,generateApiMirTests});
|
|
1
|
+
0 && (module.exports = {copyRecursiveAsNeeded,get_jungle,launchSimulator,manifestProducts,mctree,simulateProgram,defaultConfig,isErrorWithLocation,buildOptimizedProject,generateOptimizedProject,getProjectAnalysis,generateApiMirTests});
|
|
2
2
|
/******/ (() => { // webpackBootstrap
|
|
3
3
|
/******/ var __webpack_modules__ = ({
|
|
4
4
|
|
|
@@ -9772,6 +9772,18 @@ module.exports = require("zlib");
|
|
|
9772
9772
|
/******/ }
|
|
9773
9773
|
/******/
|
|
9774
9774
|
/************************************************************************/
|
|
9775
|
+
/******/ /* webpack/runtime/compat get default export */
|
|
9776
|
+
/******/ (() => {
|
|
9777
|
+
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
9778
|
+
/******/ __webpack_require__.n = (module) => {
|
|
9779
|
+
/******/ var getter = module && module.__esModule ?
|
|
9780
|
+
/******/ () => (module['default']) :
|
|
9781
|
+
/******/ () => (module);
|
|
9782
|
+
/******/ __webpack_require__.d(getter, { a: getter });
|
|
9783
|
+
/******/ return getter;
|
|
9784
|
+
/******/ };
|
|
9785
|
+
/******/ })();
|
|
9786
|
+
/******/
|
|
9775
9787
|
/******/ /* webpack/runtime/define property getters */
|
|
9776
9788
|
/******/ (() => {
|
|
9777
9789
|
/******/ // define getter functions for harmony exports
|
|
@@ -9815,9 +9827,18 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
9815
9827
|
"defaultConfig": () => (/* binding */ defaultConfig),
|
|
9816
9828
|
"generateApiMirTests": () => (/* binding */ generateApiMirTests),
|
|
9817
9829
|
"generateOptimizedProject": () => (/* binding */ generateOptimizedProject),
|
|
9818
|
-
"
|
|
9830
|
+
"getProjectAnalysis": () => (/* binding */ getProjectAnalysis),
|
|
9831
|
+
"get_jungle": () => (/* reexport */ get_jungle),
|
|
9832
|
+
"isErrorWithLocation": () => (/* binding */ isErrorWithLocation),
|
|
9833
|
+
"launchSimulator": () => (/* reexport */ launchSimulator),
|
|
9834
|
+
"manifestProducts": () => (/* reexport */ manifestProducts),
|
|
9835
|
+
"mctree": () => (/* reexport */ prettier_plugin_monkeyc_namespaceObject.mctree),
|
|
9836
|
+
"simulateProgram": () => (/* reexport */ simulateProgram)
|
|
9819
9837
|
});
|
|
9820
9838
|
|
|
9839
|
+
;// CONCATENATED MODULE: external "@markw65/prettier-plugin-monkeyc"
|
|
9840
|
+
const prettier_plugin_monkeyc_namespaceObject = require("@markw65/prettier-plugin-monkeyc");
|
|
9841
|
+
var prettier_plugin_monkeyc_default = /*#__PURE__*/__webpack_require__.n(prettier_plugin_monkeyc_namespaceObject);
|
|
9821
9842
|
;// CONCATENATED MODULE: external "crypto"
|
|
9822
9843
|
const external_crypto_namespaceObject = require("crypto");
|
|
9823
9844
|
;// CONCATENATED MODULE: external "fs/promises"
|
|
@@ -9830,72 +9851,66 @@ const external_api_cjs_namespaceObject = require("./api.cjs");
|
|
|
9830
9851
|
const external_sdk_util_cjs_namespaceObject = require("./sdk-util.cjs");
|
|
9831
9852
|
;// CONCATENATED MODULE: external "./util.cjs"
|
|
9832
9853
|
const external_util_cjs_namespaceObject = require("./util.cjs");
|
|
9833
|
-
;// CONCATENATED MODULE: ./src/build.
|
|
9834
|
-
|
|
9854
|
+
;// CONCATENATED MODULE: ./src/build.ts
|
|
9835
9855
|
|
|
9836
9856
|
|
|
9837
9857
|
|
|
9838
9858
|
async function build_project(product, options, lineCallback) {
|
|
9839
|
-
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
|
|
9843
|
-
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
|
|
9854
|
-
|
|
9855
|
-
|
|
9856
|
-
|
|
9857
|
-
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
|
|
9865
|
-
|
|
9866
|
-
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
|
|
9875
|
-
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9884
|
-
|
|
9885
|
-
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
return returnCommand
|
|
9895
|
-
? { exe, args, program: external_path_.resolve(workspace, program), product }
|
|
9896
|
-
: (0,external_util_cjs_namespaceObject.spawnByLine)(exe, args, handlers, {
|
|
9897
|
-
cwd: workspace,
|
|
9898
|
-
});
|
|
9859
|
+
const { workspace, program, jungleFiles, developerKeyPath, simulatorBuild, releaseBuild, testBuild, compilerOptions, compilerWarnings, typeCheckLevel, returnCommand, } = options;
|
|
9860
|
+
const sdk = await (0,external_sdk_util_cjs_namespaceObject.getSdkPath)();
|
|
9861
|
+
let extraArgs = [];
|
|
9862
|
+
if (compilerOptions) {
|
|
9863
|
+
extraArgs.push(...compilerOptions.split(/\s+/));
|
|
9864
|
+
}
|
|
9865
|
+
if (compilerWarnings) {
|
|
9866
|
+
extraArgs.push("-w");
|
|
9867
|
+
}
|
|
9868
|
+
if (testBuild) {
|
|
9869
|
+
extraArgs.push("-t");
|
|
9870
|
+
}
|
|
9871
|
+
else if (releaseBuild) {
|
|
9872
|
+
extraArgs.push("-r");
|
|
9873
|
+
}
|
|
9874
|
+
if (!product) {
|
|
9875
|
+
extraArgs.push("-e");
|
|
9876
|
+
}
|
|
9877
|
+
switch (typeCheckLevel) {
|
|
9878
|
+
case "Off":
|
|
9879
|
+
extraArgs.push("-l", "0");
|
|
9880
|
+
break;
|
|
9881
|
+
case "Gradual":
|
|
9882
|
+
extraArgs.push("-l", "1");
|
|
9883
|
+
break;
|
|
9884
|
+
case "Informative":
|
|
9885
|
+
extraArgs.push("-l", "2");
|
|
9886
|
+
break;
|
|
9887
|
+
case "Strict":
|
|
9888
|
+
extraArgs.push("-l", "3");
|
|
9889
|
+
break;
|
|
9890
|
+
}
|
|
9891
|
+
if (product) {
|
|
9892
|
+
extraArgs.push("-d", testBuild || simulatorBuild !== false ? `${product}_sim` : product);
|
|
9893
|
+
}
|
|
9894
|
+
else if (testBuild) {
|
|
9895
|
+
throw new Error("Building for tests requires a device to build for!");
|
|
9896
|
+
}
|
|
9897
|
+
const exe = external_path_.resolve(sdk, "bin", external_sdk_util_cjs_namespaceObject.isWin ? "monkeyc.bat" : "monkeyc");
|
|
9898
|
+
const args = [
|
|
9899
|
+
["-o", program],
|
|
9900
|
+
["-f", jungleFiles],
|
|
9901
|
+
["-y", developerKeyPath],
|
|
9902
|
+
extraArgs,
|
|
9903
|
+
].flat();
|
|
9904
|
+
if (!returnCommand) {
|
|
9905
|
+
const handlers = [
|
|
9906
|
+
lineCallback || ((line) => console.log(line)),
|
|
9907
|
+
(line) => console.error(line),
|
|
9908
|
+
];
|
|
9909
|
+
await (0,external_util_cjs_namespaceObject.spawnByLine)(exe, args, handlers, {
|
|
9910
|
+
cwd: workspace,
|
|
9911
|
+
});
|
|
9912
|
+
}
|
|
9913
|
+
return { exe, args, program: external_path_.resolve(workspace, program), product };
|
|
9899
9914
|
}
|
|
9900
9915
|
|
|
9901
9916
|
// EXTERNAL MODULE: ./node_modules/extract-zip/index.js
|
|
@@ -9904,123 +9919,112 @@ var extract_zip = __webpack_require__(2106);
|
|
|
9904
9919
|
var xml2js = __webpack_require__(5055);
|
|
9905
9920
|
;// CONCATENATED MODULE: ./build/jungle.js
|
|
9906
9921
|
function peg$subclass(u,A){function E(){this.constructor=u}E.prototype=A.prototype,u.prototype=new E}function peg$SyntaxError(u,A,E,C){var F=Error.call(this,u);return Object.setPrototypeOf&&Object.setPrototypeOf(F,peg$SyntaxError.prototype),F.expected=A,F.found=E,F.location=C,F.name="SyntaxError",F}function peg$padEnd(u,A,E){return E=E||" ",u.length>A?u:(A-=u.length,u+(E+=E.repeat(A)).slice(0,A))}function peg$parse(u,A){var E,C,F,t,B={},r=(A=void 0!==A?A:{}).grammarSource,e={Jungle:Su},D=Su,n=/^[\n\r\u2028\u2029]/,o=/^[a-z\xB5\xDF-\xF6\xF8-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137-\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148-\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C-\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA-\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9-\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC-\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF-\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F-\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0-\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB-\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE-\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0560-\u0588\u10D0-\u10FA\u10FD-\u10FF\u13F8-\u13FD\u1C80-\u1C88\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6-\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FC7\u1FD0-\u1FD3\u1FD6-\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6-\u1FF7\u210A\u210E-\u210F\u2113\u212F\u2134\u2139\u213C-\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65-\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73-\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3-\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7AF\uA7B5\uA7B7\uA7B9\uA7FA\uAB30-\uAB5A\uAB60-\uAB65\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A]/,s=/^[\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5-\u06E6\u07F4-\u07F5\u07FA\u081A\u0824\u0828\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1AA7\u1C78-\u1C7D\u1D2C-\u1D6A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\u2D6F\u2E2F\u3005\u3031-\u3035\u303B\u309D-\u309E\u30FC-\u30FE\uA015\uA4F8-\uA4FD\uA60C\uA67F\uA69C-\uA69D\uA717-\uA71F\uA770\uA788\uA7F8-\uA7F9\uA9CF\uA9E6\uAA70\uAADD\uAAF3-\uAAF4\uAB5C-\uAB5F\uFF70\uFF9E-\uFF9F]/,a=/^[\xAA\xBA\u01BB\u01C0-\u01C3\u0294\u05D0-\u05EA\u05EF-\u05F2\u0620-\u063F\u0641-\u064A\u066E-\u066F\u0671-\u06D3\u06D5\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u0800-\u0815\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0972-\u0980\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u09FC\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0-\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60-\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0-\u0CE1\u0CF1-\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065-\u1066\u106E-\u1070\u1075-\u1081\u108E\u1100-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17DC\u1820-\u1842\u1844-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE-\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C77\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5-\u1CF6\u2135-\u2138\u2D30-\u2D67\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3006\u303C\u3041-\u3096\u309F\u30A1-\u30FA\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEF\uA000-\uA014\uA016-\uA48C\uA4D0-\uA4F7\uA500-\uA60B\uA610-\uA61F\uA62A-\uA62B\uA66E\uA6A0-\uA6E5\uA78F\uA7F7\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD-\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9E0-\uA9E4\uA9E7-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA6F\uAA71-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADC\uAAE0-\uAAEA\uAAF2\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF66-\uFF6F\uFF71-\uFF9D\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/,c=/^[\u01C5\u01C8\u01CB\u01F2\u1F88-\u1F8F\u1F98-\u1F9F\u1FA8-\u1FAF\u1FBC\u1FCC\u1FFC]/,l=/^[A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178-\u0179\u017B\u017D\u0181-\u0182\u0184\u0186-\u0187\u0189-\u018B\u018E-\u0191\u0193-\u0194\u0196-\u0198\u019C-\u019D\u019F-\u01A0\u01A2\u01A4\u01A6-\u01A7\u01A9\u01AC\u01AE-\u01AF\u01B1-\u01B3\u01B5\u01B7-\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A-\u023B\u023D-\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E-\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9-\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0-\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1C90-\u1CBA\u1CBD-\u1CBF\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E-\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D-\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AE\uA7B0-\uA7B4\uA7B6\uA7B8\uFF21-\uFF3A]/,i=/^[\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E-\u094F\u0982-\u0983\u09BE-\u09C0\u09C7-\u09C8\u09CB-\u09CC\u09D7\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB-\u0ACC\u0B02-\u0B03\u0B3E\u0B40\u0B47-\u0B48\u0B4B-\u0B4C\u0B57\u0BBE-\u0BBF\u0BC1-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD7\u0C01-\u0C03\u0C41-\u0C44\u0C82-\u0C83\u0CBE\u0CC0-\u0CC4\u0CC7-\u0CC8\u0CCA-\u0CCB\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D57\u0D82-\u0D83\u0DCF-\u0DD1\u0DD8-\u0DDF\u0DF2-\u0DF3\u0F3E-\u0F3F\u0F7F\u102B-\u102C\u1031\u1038\u103B-\u103C\u1056-\u1057\u1062-\u1064\u1067-\u106D\u1083-\u1084\u1087-\u108C\u108F\u109A-\u109C\u17B6\u17BE-\u17C5\u17C7-\u17C8\u1923-\u1926\u1929-\u192B\u1930-\u1931\u1933-\u1938\u1A19-\u1A1A\u1A55\u1A57\u1A61\u1A63-\u1A64\u1A6D-\u1A72\u1B04\u1B35\u1B3B\u1B3D-\u1B41\u1B43-\u1B44\u1B82\u1BA1\u1BA6-\u1BA7\u1BAA\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2-\u1BF3\u1C24-\u1C2B\u1C34-\u1C35\u1CE1\u1CF2-\u1CF3\u1CF7\u302E-\u302F\uA823-\uA824\uA827\uA880-\uA881\uA8B4-\uA8C3\uA952-\uA953\uA983\uA9B4-\uA9B5\uA9BA-\uA9BB\uA9BD-\uA9C0\uAA2F-\uAA30\uAA33-\uAA34\uAA4D\uAA7B\uAA7D\uAAEB\uAAEE-\uAAEF\uAAF5\uABE3-\uABE4\uABE6-\uABE7\uABE9-\uABEA\uABEC]/,f=/^[\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962-\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2-\u09E3\u09FE\u0A01-\u0A02\u0A3C\u0A41-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A51\u0A70-\u0A71\u0A75\u0A81-\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7-\u0AC8\u0ACD\u0AE2-\u0AE3\u0AFA-\u0AFF\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B62-\u0B63\u0B82\u0BC0\u0BCD\u0C00\u0C04\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C62-\u0C63\u0C81\u0CBC\u0CBF\u0CC6\u0CCC-\u0CCD\u0CE2-\u0CE3\u0D00-\u0D01\u0D3B-\u0D3C\u0D41-\u0D44\u0D4D\u0D62-\u0D63\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86-\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039-\u103A\u103D-\u103E\u1058-\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085-\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17B4-\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u1885-\u1886\u18A9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193B\u1A17-\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1ABD\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80-\u1B81\u1BA2-\u1BA5\u1BA8-\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8-\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302D\u3099-\u309A\uA66F\uA674-\uA67D\uA69E-\uA69F\uA6F0-\uA6F1\uA802\uA806\uA80B\uA825-\uA826\uA8C4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9E5\uAA29-\uAA2E\uAA31-\uAA32\uAA35-\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7-\uAAB8\uAABE-\uAABF\uAAC1\uAAEC-\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]/,h=/^[0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]/,x=/^[\u16EE-\u16F0\u2160-\u2182\u2185-\u2188\u3007\u3021-\u3029\u3038-\u303A\uA6E6-\uA6EF]/,p=/^[_\u203F-\u2040\u2054\uFE33-\uFE34\uFE4D-\uFE4F\uFF3F]/,d=/^[ \xA0\u1680\u2000-\u200A\u202F\u205F\u3000]/,P={type:"any"},g=Pu("=",!1),v=Pu(".",!1),y=Pu(";",!1),m=Pu("$(",!1),$=Pu(")",!1),S=vu("raw string"),b=vu("quoted string"),w=Pu('"',!1),j=Pu("[",!1),O=Pu("]",!1),R=Pu(" ",!1),_=Pu("\t",!1),L=Pu("\\",!1),z=vu("identifier"),M=Pu("_",!1),Z=Pu("$",!1),k=Pu("-",!1),q=Pu("",!1),J=Pu("",!1),N=Pu("/",!1),Q=Pu("*",!1),U=vu("whitespace"),G=Pu("\v",!1),H=Pu("\f",!1),I=Pu(" ",!1),K=Pu("\ufeff",!1),T=gu(["\n","\r","\u2028","\u2029"],!1,!1),V=vu("end of line"),W=Pu("\n",!1),X=Pu("\r\n",!1),Y=Pu("\r",!1),uu=Pu("\u2028",!1),Au=Pu("\u2029",!1),Eu=vu("comment"),Cu=Pu("#",!1),Fu=gu([["a","z"],"µ",["ß","ö"],["ø","ÿ"],"ā","ă","ą","ć","ĉ","ċ","č","ď","đ","ē","ĕ","ė","ę","ě","ĝ","ğ","ġ","ģ","ĥ","ħ","ĩ","ī","ĭ","į","ı","ij","ĵ",["ķ","ĸ"],"ĺ","ļ","ľ","ŀ","ł","ń","ņ",["ň","ʼn"],"ŋ","ō","ŏ","ő","œ","ŕ","ŗ","ř","ś","ŝ","ş","š","ţ","ť","ŧ","ũ","ū","ŭ","ů","ű","ų","ŵ","ŷ","ź","ż",["ž","ƀ"],"ƃ","ƅ","ƈ",["ƌ","ƍ"],"ƒ","ƕ",["ƙ","ƛ"],"ƞ","ơ","ƣ","ƥ","ƨ",["ƪ","ƫ"],"ƭ","ư","ƴ","ƶ",["ƹ","ƺ"],["ƽ","ƿ"],"dž","lj","nj","ǎ","ǐ","ǒ","ǔ","ǖ","ǘ","ǚ",["ǜ","ǝ"],"ǟ","ǡ","ǣ","ǥ","ǧ","ǩ","ǫ","ǭ",["ǯ","ǰ"],"dz","ǵ","ǹ","ǻ","ǽ","ǿ","ȁ","ȃ","ȅ","ȇ","ȉ","ȋ","ȍ","ȏ","ȑ","ȓ","ȕ","ȗ","ș","ț","ȝ","ȟ","ȡ","ȣ","ȥ","ȧ","ȩ","ȫ","ȭ","ȯ","ȱ",["ȳ","ȹ"],"ȼ",["ȿ","ɀ"],"ɂ","ɇ","ɉ","ɋ","ɍ",["ɏ","ʓ"],["ʕ","ʯ"],"ͱ","ͳ","ͷ",["ͻ","ͽ"],"ΐ",["ά","ώ"],["ϐ","ϑ"],["ϕ","ϗ"],"ϙ","ϛ","ϝ","ϟ","ϡ","ϣ","ϥ","ϧ","ϩ","ϫ","ϭ",["ϯ","ϳ"],"ϵ","ϸ",["ϻ","ϼ"],["а","џ"],"ѡ","ѣ","ѥ","ѧ","ѩ","ѫ","ѭ","ѯ","ѱ","ѳ","ѵ","ѷ","ѹ","ѻ","ѽ","ѿ","ҁ","ҋ","ҍ","ҏ","ґ","ғ","ҕ","җ","ҙ","қ","ҝ","ҟ","ҡ","ң","ҥ","ҧ","ҩ","ҫ","ҭ","ү","ұ","ҳ","ҵ","ҷ","ҹ","һ","ҽ","ҿ","ӂ","ӄ","ӆ","ӈ","ӊ","ӌ",["ӎ","ӏ"],"ӑ","ӓ","ӕ","ӗ","ә","ӛ","ӝ","ӟ","ӡ","ӣ","ӥ","ӧ","ө","ӫ","ӭ","ӯ","ӱ","ӳ","ӵ","ӷ","ӹ","ӻ","ӽ","ӿ","ԁ","ԃ","ԅ","ԇ","ԉ","ԋ","ԍ","ԏ","ԑ","ԓ","ԕ","ԗ","ԙ","ԛ","ԝ","ԟ","ԡ","ԣ","ԥ","ԧ","ԩ","ԫ","ԭ","ԯ",["ՠ","ֈ"],["ა","ჺ"],["ჽ","ჿ"],["ᏸ","ᏽ"],["ᲀ","ᲈ"],["ᴀ","ᴫ"],["ᵫ","ᵷ"],["ᵹ","ᶚ"],"ḁ","ḃ","ḅ","ḇ","ḉ","ḋ","ḍ","ḏ","ḑ","ḓ","ḕ","ḗ","ḙ","ḛ","ḝ","ḟ","ḡ","ḣ","ḥ","ḧ","ḩ","ḫ","ḭ","ḯ","ḱ","ḳ","ḵ","ḷ","ḹ","ḻ","ḽ","ḿ","ṁ","ṃ","ṅ","ṇ","ṉ","ṋ","ṍ","ṏ","ṑ","ṓ","ṕ","ṗ","ṙ","ṛ","ṝ","ṟ","ṡ","ṣ","ṥ","ṧ","ṩ","ṫ","ṭ","ṯ","ṱ","ṳ","ṵ","ṷ","ṹ","ṻ","ṽ","ṿ","ẁ","ẃ","ẅ","ẇ","ẉ","ẋ","ẍ","ẏ","ẑ","ẓ",["ẕ","ẝ"],"ẟ","ạ","ả","ấ","ầ","ẩ","ẫ","ậ","ắ","ằ","ẳ","ẵ","ặ","ẹ","ẻ","ẽ","ế","ề","ể","ễ","ệ","ỉ","ị","ọ","ỏ","ố","ồ","ổ","ỗ","ộ","ớ","ờ","ở","ỡ","ợ","ụ","ủ","ứ","ừ","ử","ữ","ự","ỳ","ỵ","ỷ","ỹ","ỻ","ỽ",["ỿ","ἇ"],["ἐ","ἕ"],["ἠ","ἧ"],["ἰ","ἷ"],["ὀ","ὅ"],["ὐ","ὗ"],["ὠ","ὧ"],["ὰ","ώ"],["ᾀ","ᾇ"],["ᾐ","ᾗ"],["ᾠ","ᾧ"],["ᾰ","ᾴ"],["ᾶ","ᾷ"],"ι",["ῂ","ῄ"],["ῆ","ῇ"],["ῐ","ΐ"],["ῖ","ῗ"],["ῠ","ῧ"],["ῲ","ῴ"],["ῶ","ῷ"],"ℊ",["ℎ","ℏ"],"ℓ","ℯ","ℴ","ℹ",["ℼ","ℽ"],["ⅆ","ⅉ"],"ⅎ","ↄ",["ⰰ","ⱞ"],"ⱡ",["ⱥ","ⱦ"],"ⱨ","ⱪ","ⱬ","ⱱ",["ⱳ","ⱴ"],["ⱶ","ⱻ"],"ⲁ","ⲃ","ⲅ","ⲇ","ⲉ","ⲋ","ⲍ","ⲏ","ⲑ","ⲓ","ⲕ","ⲗ","ⲙ","ⲛ","ⲝ","ⲟ","ⲡ","ⲣ","ⲥ","ⲧ","ⲩ","ⲫ","ⲭ","ⲯ","ⲱ","ⲳ","ⲵ","ⲷ","ⲹ","ⲻ","ⲽ","ⲿ","ⳁ","ⳃ","ⳅ","ⳇ","ⳉ","ⳋ","ⳍ","ⳏ","ⳑ","ⳓ","ⳕ","ⳗ","ⳙ","ⳛ","ⳝ","ⳟ","ⳡ",["ⳣ","ⳤ"],"ⳬ","ⳮ","ⳳ",["ⴀ","ⴥ"],"ⴧ","ⴭ","ꙁ","ꙃ","ꙅ","ꙇ","ꙉ","ꙋ","ꙍ","ꙏ","ꙑ","ꙓ","ꙕ","ꙗ","ꙙ","ꙛ","ꙝ","ꙟ","ꙡ","ꙣ","ꙥ","ꙧ","ꙩ","ꙫ","ꙭ","ꚁ","ꚃ","ꚅ","ꚇ","ꚉ","ꚋ","ꚍ","ꚏ","ꚑ","ꚓ","ꚕ","ꚗ","ꚙ","ꚛ","ꜣ","ꜥ","ꜧ","ꜩ","ꜫ","ꜭ",["ꜯ","ꜱ"],"ꜳ","ꜵ","ꜷ","ꜹ","ꜻ","ꜽ","ꜿ","ꝁ","ꝃ","ꝅ","ꝇ","ꝉ","ꝋ","ꝍ","ꝏ","ꝑ","ꝓ","ꝕ","ꝗ","ꝙ","ꝛ","ꝝ","ꝟ","ꝡ","ꝣ","ꝥ","ꝧ","ꝩ","ꝫ","ꝭ","ꝯ",["ꝱ","ꝸ"],"ꝺ","ꝼ","ꝿ","ꞁ","ꞃ","ꞅ","ꞇ","ꞌ","ꞎ","ꞑ",["ꞓ","ꞕ"],"ꞗ","ꞙ","ꞛ","ꞝ","ꞟ","ꞡ","ꞣ","ꞥ","ꞧ","ꞩ","ꞯ","ꞵ","ꞷ","ꞹ","ꟺ",["ꬰ","ꭚ"],["ꭠ","ꭥ"],["ꭰ","ꮿ"],["ff","st"],["ﬓ","ﬗ"],["a","z"]],!1,!1),tu=gu([["ʰ","ˁ"],["ˆ","ˑ"],["ˠ","ˤ"],"ˬ","ˮ","ʹ","ͺ","ՙ","ـ",["ۥ","ۦ"],["ߴ","ߵ"],"ߺ","ࠚ","ࠤ","ࠨ","ॱ","ๆ","ໆ","ჼ","ៗ","ᡃ","ᪧ",["ᱸ","ᱽ"],["ᴬ","ᵪ"],"ᵸ",["ᶛ","ᶿ"],"ⁱ","ⁿ",["ₐ","ₜ"],["ⱼ","ⱽ"],"ⵯ","ⸯ","々",["〱","〵"],"〻",["ゝ","ゞ"],["ー","ヾ"],"ꀕ",["ꓸ","ꓽ"],"ꘌ","ꙿ",["ꚜ","ꚝ"],["ꜗ","ꜟ"],"ꝰ","ꞈ",["ꟸ","ꟹ"],"ꧏ","ꧦ","ꩰ","ꫝ",["ꫳ","ꫴ"],["ꭜ","ꭟ"],"ー",["゙","゚"]],!1,!1),Bu=gu(["ª","º","ƻ",["ǀ","ǃ"],"ʔ",["א","ת"],["ׯ","ײ"],["ؠ","ؿ"],["ف","ي"],["ٮ","ٯ"],["ٱ","ۓ"],"ە",["ۮ","ۯ"],["ۺ","ۼ"],"ۿ","ܐ",["ܒ","ܯ"],["ݍ","ޥ"],"ޱ",["ߊ","ߪ"],["ࠀ","ࠕ"],["ࡀ","ࡘ"],["ࡠ","ࡪ"],["ࢠ","ࢴ"],["ࢶ","ࢽ"],["ऄ","ह"],"ऽ","ॐ",["क़","ॡ"],["ॲ","ঀ"],["অ","ঌ"],["এ","ঐ"],["ও","ন"],["প","র"],"ল",["শ","হ"],"ঽ","ৎ",["ড়","ঢ়"],["য়","ৡ"],["ৰ","ৱ"],"ৼ",["ਅ","ਊ"],["ਏ","ਐ"],["ਓ","ਨ"],["ਪ","ਰ"],["ਲ","ਲ਼"],["ਵ","ਸ਼"],["ਸ","ਹ"],["ਖ਼","ੜ"],"ਫ਼",["ੲ","ੴ"],["અ","ઍ"],["એ","ઑ"],["ઓ","ન"],["પ","ર"],["લ","ળ"],["વ","હ"],"ઽ","ૐ",["ૠ","ૡ"],"ૹ",["ଅ","ଌ"],["ଏ","ଐ"],["ଓ","ନ"],["ପ","ର"],["ଲ","ଳ"],["ଵ","ହ"],"ଽ",["ଡ଼","ଢ଼"],["ୟ","ୡ"],"ୱ","ஃ",["அ","ஊ"],["எ","ஐ"],["ஒ","க"],["ங","ச"],"ஜ",["ஞ","ட"],["ண","த"],["ந","ப"],["ம","ஹ"],"ௐ",["అ","ఌ"],["ఎ","ఐ"],["ఒ","న"],["ప","హ"],"ఽ",["ౘ","ౚ"],["ౠ","ౡ"],"ಀ",["ಅ","ಌ"],["ಎ","ಐ"],["ಒ","ನ"],["ಪ","ಳ"],["ವ","ಹ"],"ಽ","ೞ",["ೠ","ೡ"],["ೱ","ೲ"],["അ","ഌ"],["എ","ഐ"],["ഒ","ഺ"],"ഽ","ൎ",["ൔ","ൖ"],["ൟ","ൡ"],["ൺ","ൿ"],["අ","ඖ"],["ක","න"],["ඳ","ර"],"ල",["ව","ෆ"],["ก","ะ"],["า","ำ"],["เ","ๅ"],["ກ","ຂ"],"ຄ",["ງ","ຈ"],"ຊ","ຍ",["ດ","ທ"],["ນ","ຟ"],["ມ","ຣ"],"ລ","ວ",["ສ","ຫ"],["ອ","ະ"],["າ","ຳ"],"ຽ",["ເ","ໄ"],["ໜ","ໟ"],"ༀ",["ཀ","ཇ"],["ཉ","ཬ"],["ྈ","ྌ"],["က","ဪ"],"ဿ",["ၐ","ၕ"],["ၚ","ၝ"],"ၡ",["ၥ","ၦ"],["ၮ","ၰ"],["ၵ","ႁ"],"ႎ",["ᄀ","ቈ"],["ቊ","ቍ"],["ቐ","ቖ"],"ቘ",["ቚ","ቝ"],["በ","ኈ"],["ኊ","ኍ"],["ነ","ኰ"],["ኲ","ኵ"],["ኸ","ኾ"],"ዀ",["ዂ","ዅ"],["ወ","ዖ"],["ዘ","ጐ"],["ጒ","ጕ"],["ጘ","ፚ"],["ᎀ","ᎏ"],["ᐁ","ᙬ"],["ᙯ","ᙿ"],["ᚁ","ᚚ"],["ᚠ","ᛪ"],["ᛱ","ᛸ"],["ᜀ","ᜌ"],["ᜎ","ᜑ"],["ᜠ","ᜱ"],["ᝀ","ᝑ"],["ᝠ","ᝬ"],["ᝮ","ᝰ"],["ក","ឳ"],"ៜ",["ᠠ","ᡂ"],["ᡄ","ᡸ"],["ᢀ","ᢄ"],["ᢇ","ᢨ"],"ᢪ",["ᢰ","ᣵ"],["ᤀ","ᤞ"],["ᥐ","ᥭ"],["ᥰ","ᥴ"],["ᦀ","ᦫ"],["ᦰ","ᧉ"],["ᨀ","ᨖ"],["ᨠ","ᩔ"],["ᬅ","ᬳ"],["ᭅ","ᭋ"],["ᮃ","ᮠ"],["ᮮ","ᮯ"],["ᮺ","ᯥ"],["ᰀ","ᰣ"],["ᱍ","ᱏ"],["ᱚ","ᱷ"],["ᳩ","ᳬ"],["ᳮ","ᳱ"],["ᳵ","ᳶ"],["ℵ","ℸ"],["ⴰ","ⵧ"],["ⶀ","ⶖ"],["ⶠ","ⶦ"],["ⶨ","ⶮ"],["ⶰ","ⶶ"],["ⶸ","ⶾ"],["ⷀ","ⷆ"],["ⷈ","ⷎ"],["ⷐ","ⷖ"],["ⷘ","ⷞ"],"〆","〼",["ぁ","ゖ"],"ゟ",["ァ","ヺ"],"ヿ",["ㄅ","ㄯ"],["ㄱ","ㆎ"],["ㆠ","ㆺ"],["ㇰ","ㇿ"],["㐀","䶵"],["一","鿯"],["ꀀ","ꀔ"],["ꀖ","ꒌ"],["ꓐ","ꓷ"],["ꔀ","ꘋ"],["ꘐ","ꘟ"],["ꘪ","ꘫ"],"ꙮ",["ꚠ","ꛥ"],"ꞏ","ꟷ",["ꟻ","ꠁ"],["ꠃ","ꠅ"],["ꠇ","ꠊ"],["ꠌ","ꠢ"],["ꡀ","ꡳ"],["ꢂ","ꢳ"],["ꣲ","ꣷ"],"ꣻ",["ꣽ","ꣾ"],["ꤊ","ꤥ"],["ꤰ","ꥆ"],["ꥠ","ꥼ"],["ꦄ","ꦲ"],["ꧠ","ꧤ"],["ꧧ","ꧯ"],["ꧺ","ꧾ"],["ꨀ","ꨨ"],["ꩀ","ꩂ"],["ꩄ","ꩋ"],["ꩠ","ꩯ"],["ꩱ","ꩶ"],"ꩺ",["ꩾ","ꪯ"],"ꪱ",["ꪵ","ꪶ"],["ꪹ","ꪽ"],"ꫀ","ꫂ",["ꫛ","ꫜ"],["ꫠ","ꫪ"],"ꫲ",["ꬁ","ꬆ"],["ꬉ","ꬎ"],["ꬑ","ꬖ"],["ꬠ","ꬦ"],["ꬨ","ꬮ"],["ꯀ","ꯢ"],["가","힣"],["ힰ","ퟆ"],["ퟋ","ퟻ"],["豈","舘"],["並","龎"],"יִ",["ײַ","ﬨ"],["שׁ","זּ"],["טּ","לּ"],"מּ",["נּ","סּ"],["ףּ","פּ"],["צּ","ﮱ"],["ﯓ","ﴽ"],["ﵐ","ﶏ"],["ﶒ","ﷇ"],["ﷰ","ﷻ"],["ﹰ","ﹴ"],["ﹶ","ﻼ"],["ヲ","ッ"],["ア","ン"],["ᅠ","ᄒ"],["ᅡ","ᅦ"],["ᅧ","ᅬ"],["ᅭ","ᅲ"],["ᅳ","ᅵ"]],!1,!1),ru=gu(["Dž","Lj","Nj","Dz",["ᾈ","ᾏ"],["ᾘ","ᾟ"],["ᾨ","ᾯ"],"ᾼ","ῌ","ῼ"],!1,!1),eu=gu([["A","Z"],["À","Ö"],["Ø","Þ"],"Ā","Ă","Ą","Ć","Ĉ","Ċ","Č","Ď","Đ","Ē","Ĕ","Ė","Ę","Ě","Ĝ","Ğ","Ġ","Ģ","Ĥ","Ħ","Ĩ","Ī","Ĭ","Į","İ","IJ","Ĵ","Ķ","Ĺ","Ļ","Ľ","Ŀ","Ł","Ń","Ņ","Ň","Ŋ","Ō","Ŏ","Ő","Œ","Ŕ","Ŗ","Ř","Ś","Ŝ","Ş","Š","Ţ","Ť","Ŧ","Ũ","Ū","Ŭ","Ů","Ű","Ų","Ŵ","Ŷ",["Ÿ","Ź"],"Ż","Ž",["Ɓ","Ƃ"],"Ƅ",["Ɔ","Ƈ"],["Ɖ","Ƌ"],["Ǝ","Ƒ"],["Ɠ","Ɣ"],["Ɩ","Ƙ"],["Ɯ","Ɲ"],["Ɵ","Ơ"],"Ƣ","Ƥ",["Ʀ","Ƨ"],"Ʃ","Ƭ",["Ʈ","Ư"],["Ʊ","Ƴ"],"Ƶ",["Ʒ","Ƹ"],"Ƽ","DŽ","LJ","NJ","Ǎ","Ǐ","Ǒ","Ǔ","Ǖ","Ǘ","Ǚ","Ǜ","Ǟ","Ǡ","Ǣ","Ǥ","Ǧ","Ǩ","Ǫ","Ǭ","Ǯ","DZ","Ǵ",["Ƕ","Ǹ"],"Ǻ","Ǽ","Ǿ","Ȁ","Ȃ","Ȅ","Ȇ","Ȉ","Ȋ","Ȍ","Ȏ","Ȑ","Ȓ","Ȕ","Ȗ","Ș","Ț","Ȝ","Ȟ","Ƞ","Ȣ","Ȥ","Ȧ","Ȩ","Ȫ","Ȭ","Ȯ","Ȱ","Ȳ",["Ⱥ","Ȼ"],["Ƚ","Ⱦ"],"Ɂ",["Ƀ","Ɇ"],"Ɉ","Ɋ","Ɍ","Ɏ","Ͱ","Ͳ","Ͷ","Ϳ","Ά",["Έ","Ί"],"Ό",["Ύ","Ώ"],["Α","Ρ"],["Σ","Ϋ"],"Ϗ",["ϒ","ϔ"],"Ϙ","Ϛ","Ϝ","Ϟ","Ϡ","Ϣ","Ϥ","Ϧ","Ϩ","Ϫ","Ϭ","Ϯ","ϴ","Ϸ",["Ϲ","Ϻ"],["Ͻ","Я"],"Ѡ","Ѣ","Ѥ","Ѧ","Ѩ","Ѫ","Ѭ","Ѯ","Ѱ","Ѳ","Ѵ","Ѷ","Ѹ","Ѻ","Ѽ","Ѿ","Ҁ","Ҋ","Ҍ","Ҏ","Ґ","Ғ","Ҕ","Җ","Ҙ","Қ","Ҝ","Ҟ","Ҡ","Ң","Ҥ","Ҧ","Ҩ","Ҫ","Ҭ","Ү","Ұ","Ҳ","Ҵ","Ҷ","Ҹ","Һ","Ҽ","Ҿ",["Ӏ","Ӂ"],"Ӄ","Ӆ","Ӈ","Ӊ","Ӌ","Ӎ","Ӑ","Ӓ","Ӕ","Ӗ","Ә","Ӛ","Ӝ","Ӟ","Ӡ","Ӣ","Ӥ","Ӧ","Ө","Ӫ","Ӭ","Ӯ","Ӱ","Ӳ","Ӵ","Ӷ","Ӹ","Ӻ","Ӽ","Ӿ","Ԁ","Ԃ","Ԅ","Ԇ","Ԉ","Ԋ","Ԍ","Ԏ","Ԑ","Ԓ","Ԕ","Ԗ","Ԙ","Ԛ","Ԝ","Ԟ","Ԡ","Ԣ","Ԥ","Ԧ","Ԩ","Ԫ","Ԭ","Ԯ",["Ա","Ֆ"],["Ⴀ","Ⴥ"],"Ⴧ","Ⴭ",["Ꭰ","Ᏽ"],["Ა","Ჺ"],["Ჽ","Ჿ"],"Ḁ","Ḃ","Ḅ","Ḇ","Ḉ","Ḋ","Ḍ","Ḏ","Ḑ","Ḓ","Ḕ","Ḗ","Ḙ","Ḛ","Ḝ","Ḟ","Ḡ","Ḣ","Ḥ","Ḧ","Ḩ","Ḫ","Ḭ","Ḯ","Ḱ","Ḳ","Ḵ","Ḷ","Ḹ","Ḻ","Ḽ","Ḿ","Ṁ","Ṃ","Ṅ","Ṇ","Ṉ","Ṋ","Ṍ","Ṏ","Ṑ","Ṓ","Ṕ","Ṗ","Ṙ","Ṛ","Ṝ","Ṟ","Ṡ","Ṣ","Ṥ","Ṧ","Ṩ","Ṫ","Ṭ","Ṯ","Ṱ","Ṳ","Ṵ","Ṷ","Ṹ","Ṻ","Ṽ","Ṿ","Ẁ","Ẃ","Ẅ","Ẇ","Ẉ","Ẋ","Ẍ","Ẏ","Ẑ","Ẓ","Ẕ","ẞ","Ạ","Ả","Ấ","Ầ","Ẩ","Ẫ","Ậ","Ắ","Ằ","Ẳ","Ẵ","Ặ","Ẹ","Ẻ","Ẽ","Ế","Ề","Ể","Ễ","Ệ","Ỉ","Ị","Ọ","Ỏ","Ố","Ồ","Ổ","Ỗ","Ộ","Ớ","Ờ","Ở","Ỡ","Ợ","Ụ","Ủ","Ứ","Ừ","Ử","Ữ","Ự","Ỳ","Ỵ","Ỷ","Ỹ","Ỻ","Ỽ","Ỿ",["Ἀ","Ἇ"],["Ἐ","Ἕ"],["Ἠ","Ἧ"],["Ἰ","Ἷ"],["Ὀ","Ὅ"],"Ὑ","Ὓ","Ὕ","Ὗ",["Ὠ","Ὧ"],["Ᾰ","Ά"],["Ὲ","Ή"],["Ῐ","Ί"],["Ῠ","Ῥ"],["Ὸ","Ώ"],"ℂ","ℇ",["ℋ","ℍ"],["ℐ","ℒ"],"ℕ",["ℙ","ℝ"],"ℤ","Ω","ℨ",["K","ℭ"],["ℰ","ℳ"],["ℾ","ℿ"],"ⅅ","Ↄ",["Ⰰ","Ⱞ"],"Ⱡ",["Ɫ","Ɽ"],"Ⱨ","Ⱪ","Ⱬ",["Ɑ","Ɒ"],"Ⱳ","Ⱶ",["Ȿ","Ⲁ"],"Ⲃ","Ⲅ","Ⲇ","Ⲉ","Ⲋ","Ⲍ","Ⲏ","Ⲑ","Ⲓ","Ⲕ","Ⲗ","Ⲙ","Ⲛ","Ⲝ","Ⲟ","Ⲡ","Ⲣ","Ⲥ","Ⲧ","Ⲩ","Ⲫ","Ⲭ","Ⲯ","Ⲱ","Ⲳ","Ⲵ","Ⲷ","Ⲹ","Ⲻ","Ⲽ","Ⲿ","Ⳁ","Ⳃ","Ⳅ","Ⳇ","Ⳉ","Ⳋ","Ⳍ","Ⳏ","Ⳑ","Ⳓ","Ⳕ","Ⳗ","Ⳙ","Ⳛ","Ⳝ","Ⳟ","Ⳡ","Ⳣ","Ⳬ","Ⳮ","Ⳳ","Ꙁ","Ꙃ","Ꙅ","Ꙇ","Ꙉ","Ꙋ","Ꙍ","Ꙏ","Ꙑ","Ꙓ","Ꙕ","Ꙗ","Ꙙ","Ꙛ","Ꙝ","Ꙟ","Ꙡ","Ꙣ","Ꙥ","Ꙧ","Ꙩ","Ꙫ","Ꙭ","Ꚁ","Ꚃ","Ꚅ","Ꚇ","Ꚉ","Ꚋ","Ꚍ","Ꚏ","Ꚑ","Ꚓ","Ꚕ","Ꚗ","Ꚙ","Ꚛ","Ꜣ","Ꜥ","Ꜧ","Ꜩ","Ꜫ","Ꜭ","Ꜯ","Ꜳ","Ꜵ","Ꜷ","Ꜹ","Ꜻ","Ꜽ","Ꜿ","Ꝁ","Ꝃ","Ꝅ","Ꝇ","Ꝉ","Ꝋ","Ꝍ","Ꝏ","Ꝑ","Ꝓ","Ꝕ","Ꝗ","Ꝙ","Ꝛ","Ꝝ","Ꝟ","Ꝡ","Ꝣ","Ꝥ","Ꝧ","Ꝩ","Ꝫ","Ꝭ","Ꝯ","Ꝺ","Ꝼ",["Ᵹ","Ꝿ"],"Ꞁ","Ꞃ","Ꞅ","Ꞇ","Ꞌ","Ɥ","Ꞑ","Ꞓ","Ꞗ","Ꞙ","Ꞛ","Ꞝ","Ꞟ","Ꞡ","Ꞣ","Ꞥ","Ꞧ","Ꞩ",["Ɦ","Ɪ"],["Ʞ","Ꞵ"],"Ꞷ","Ꞹ",["A","Z"]],!1,!1),Du=gu(["ः","ऻ",["ा","ी"],["ॉ","ौ"],["ॎ","ॏ"],["ং","ঃ"],["া","ী"],["ে","ৈ"],["ো","ৌ"],"ৗ","ਃ",["ਾ","ੀ"],"ઃ",["ા","ી"],"ૉ",["ો","ૌ"],["ଂ","ଃ"],"ା","ୀ",["େ","ୈ"],["ୋ","ୌ"],"ୗ",["ா","ி"],["ு","ூ"],["ெ","ை"],["ொ","ௌ"],"ௗ",["ఁ","ః"],["ు","ౄ"],["ಂ","ಃ"],"ಾ",["ೀ","ೄ"],["ೇ","ೈ"],["ೊ","ೋ"],["ೕ","ೖ"],["ം","ഃ"],["ാ","ീ"],["െ","ൈ"],["ൊ","ൌ"],"ൗ",["ං","ඃ"],["ා","ෑ"],["ෘ","ෟ"],["ෲ","ෳ"],["༾","༿"],"ཿ",["ါ","ာ"],"ေ","း",["ျ","ြ"],["ၖ","ၗ"],["ၢ","ၤ"],["ၧ","ၭ"],["ႃ","ႄ"],["ႇ","ႌ"],"ႏ",["ႚ","ႜ"],"ា",["ើ","ៅ"],["ះ","ៈ"],["ᤣ","ᤦ"],["ᤩ","ᤫ"],["ᤰ","ᤱ"],["ᤳ","ᤸ"],["ᨙ","ᨚ"],"ᩕ","ᩗ","ᩡ",["ᩣ","ᩤ"],["ᩭ","ᩲ"],"ᬄ","ᬵ","ᬻ",["ᬽ","ᭁ"],["ᭃ","᭄"],"ᮂ","ᮡ",["ᮦ","ᮧ"],"᮪","ᯧ",["ᯪ","ᯬ"],"ᯮ",["᯲","᯳"],["ᰤ","ᰫ"],["ᰴ","ᰵ"],"᳡",["ᳲ","ᳳ"],"᳷",["〮","〯"],["ꠣ","ꠤ"],"ꠧ",["ꢀ","ꢁ"],["ꢴ","ꣃ"],["ꥒ","꥓"],"ꦃ",["ꦴ","ꦵ"],["ꦺ","ꦻ"],["ꦽ","꧀"],["ꨯ","ꨰ"],["ꨳ","ꨴ"],"ꩍ","ꩻ","ꩽ","ꫫ",["ꫮ","ꫯ"],"ꫵ",["ꯣ","ꯤ"],["ꯦ","ꯧ"],["ꯩ","ꯪ"],"꯬"],!1,!1),nu=gu([["̀","ͯ"],["҃","҇"],["֑","ֽ"],"ֿ",["ׁ","ׂ"],["ׄ","ׅ"],"ׇ",["ؐ","ؚ"],["ً","ٟ"],"ٰ",["ۖ","ۜ"],["۟","ۤ"],["ۧ","ۨ"],["۪","ۭ"],"ܑ",["ܰ","݊"],["ަ","ް"],["߫","߳"],"߽",["ࠖ","࠙"],["ࠛ","ࠣ"],["ࠥ","ࠧ"],["ࠩ","࠭"],["࡙","࡛"],["࣓","࣡"],["ࣣ","ं"],"ऺ","़",["ु","ै"],"्",["॑","ॗ"],["ॢ","ॣ"],"ঁ","়",["ু","ৄ"],"্",["ৢ","ৣ"],"৾",["ਁ","ਂ"],"਼",["ੁ","ੂ"],["ੇ","ੈ"],["ੋ","੍"],"ੑ",["ੰ","ੱ"],"ੵ",["ઁ","ં"],"઼",["ુ","ૅ"],["ે","ૈ"],"્",["ૢ","ૣ"],["ૺ","૿"],"ଁ","଼","ି",["ୁ","ୄ"],"୍","ୖ",["ୢ","ୣ"],"ஂ","ீ","்","ఀ","ఄ",["ా","ీ"],["ె","ై"],["ొ","్"],["ౕ","ౖ"],["ౢ","ౣ"],"ಁ","಼","ಿ","ೆ",["ೌ","್"],["ೢ","ೣ"],["ഀ","ഁ"],["഻","഼"],["ു","ൄ"],"്",["ൢ","ൣ"],"්",["ි","ු"],"ූ","ั",["ิ","ฺ"],["็","๎"],"ັ",["ິ","ູ"],["ົ","ຼ"],["່","ໍ"],["༘","༙"],"༵","༷","༹",["ཱ","ཾ"],["ྀ","྄"],["྆","྇"],["ྍ","ྗ"],["ྙ","ྼ"],"࿆",["ိ","ူ"],["ဲ","့"],["္","်"],["ွ","ှ"],["ၘ","ၙ"],["ၞ","ၠ"],["ၱ","ၴ"],"ႂ",["ႅ","ႆ"],"ႍ","ႝ",["፝","፟"],["ᜒ","᜔"],["ᜲ","᜴"],["ᝒ","ᝓ"],["ᝲ","ᝳ"],["឴","឵"],["ិ","ួ"],"ំ",["៉","៓"],"៝",["᠋","᠍"],["ᢅ","ᢆ"],"ᢩ",["ᤠ","ᤢ"],["ᤧ","ᤨ"],"ᤲ",["᤹","᤻"],["ᨗ","ᨘ"],"ᨛ","ᩖ",["ᩘ","ᩞ"],"᩠","ᩢ",["ᩥ","ᩬ"],["ᩳ","᩼"],"᩿",["᪰","᪽"],["ᬀ","ᬃ"],"᬴",["ᬶ","ᬺ"],"ᬼ","ᭂ",["᭫","᭳"],["ᮀ","ᮁ"],["ᮢ","ᮥ"],["ᮨ","ᮩ"],["᮫","ᮭ"],"᯦",["ᯨ","ᯩ"],"ᯭ",["ᯯ","ᯱ"],["ᰬ","ᰳ"],["ᰶ","᰷"],["᳐","᳒"],["᳔","᳠"],["᳢","᳨"],"᳭","᳴",["᳸","᳹"],["᷀","᷹"],["᷻","᷿"],["⃐","⃜"],"⃡",["⃥","⃰"],["⳯","⳱"],"⵿",["ⷠ","ⷿ"],["〪","〭"],["゙","゚"],"꙯",["ꙴ","꙽"],["ꚞ","ꚟ"],["꛰","꛱"],"ꠂ","꠆","ꠋ",["ꠥ","ꠦ"],["꣄","ꣅ"],["꣠","꣱"],"ꣿ",["ꤦ","꤭"],["ꥇ","ꥑ"],["ꦀ","ꦂ"],"꦳",["ꦶ","ꦹ"],"ꦼ","ꧥ",["ꨩ","ꨮ"],["ꨱ","ꨲ"],["ꨵ","ꨶ"],"ꩃ","ꩌ","ꩼ","ꪰ",["ꪲ","ꪴ"],["ꪷ","ꪸ"],["ꪾ","꪿"],"꫁",["ꫬ","ꫭ"],"꫶","ꯥ","ꯨ","꯭","ﬞ",["︀","️"],["︠","︯"]],!1,!1),ou=gu([["0","9"],["٠","٩"],["۰","۹"],["߀","߉"],["०","९"],["০","৯"],["੦","੯"],["૦","૯"],["୦","୯"],["௦","௯"],["౦","౯"],["೦","೯"],["൦","൯"],["෦","෯"],["๐","๙"],["໐","໙"],["༠","༩"],["၀","၉"],["႐","႙"],["០","៩"],["᠐","᠙"],["᥆","᥏"],["᧐","᧙"],["᪀","᪉"],["᪐","᪙"],["᭐","᭙"],["᮰","᮹"],["᱀","᱉"],["᱐","᱙"],["꘠","꘩"],["꣐","꣙"],["꤀","꤉"],["꧐","꧙"],["꧰","꧹"],["꩐","꩙"],["꯰","꯹"],["0","9"]],!1,!1),su=gu([["ᛮ","ᛰ"],["Ⅰ","ↂ"],["ↅ","ↈ"],"〇",["〡","〩"],["〸","〺"],["ꛦ","ꛯ"]],!1,!1),au=gu(["_",["‿","⁀"],"⁔",["︳","︴"],["﹍","﹏"],"_"],!1,!1),cu=gu([" "," "," ",[" "," "]," "," "," "],!1,!1),lu=0,iu=0,fu=[{line:1,column:1}],hu=0,xu=[],pu=0,du={};if("startRule"in A){if(!(A.startRule in e))throw new Error("Can't start parsing from rule \""+A.startRule+'".');D=e[A.startRule]}function Pu(u,A){return{type:"literal",text:u,ignoreCase:A}}function gu(u,A,E){return{type:"class",parts:u,inverted:A,ignoreCase:E}}function vu(u){return{type:"other",description:u}}function yu(A){var E,C=fu[A];if(C)return C;for(E=A-1;!fu[E];)E--;for(C={line:(C=fu[E]).line,column:C.column};E<A;)10===u.charCodeAt(E)?(C.line++,C.column=1):C.column++,E++;return fu[A]=C,C}function mu(u,A){var E=yu(u),C=yu(A);return{source:r,start:{offset:u,line:E.line,column:E.column},end:{offset:A,line:C.line,column:C.column}}}function $u(u){lu<hu||(lu>hu&&(hu=lu,xu=[]),xu.push(u))}function Su(){var A,E,C,F,t,r=32*lu+0,e=du[r];if(e)return lu=e.nextPos,e.result;for(A=lu,E=[],C=lu,F=Ru(),(t=bu())!==B?C=t:(lu=C,C=B);C!==B;)E.push(C),C=lu,F=Ru(),(t=bu())!==B?C=t:(lu=C,C=B);return C=Ru(),F=lu,pu++,u.length>lu?(t=u.charAt(lu),lu++):(t=B,0===pu&&$u(P)),pu--,t===B?F=void 0:(lu=F,F=B),F!==B?A=E:(lu=A,A=B),du[r]={nextPos:lu,result:A},A}function bu(){var A,E,C,F,t,r=32*lu+1,e=du[r];return e?(lu=e.nextPos,e.result):(A=lu,(E=wu())!==B?(Ru(),61===u.charCodeAt(lu)?(C="=",lu++):(C=B,0===pu&&$u(g)),C!==B?(Ru(),(F=ju())!==B?(Ru(),iu=A,t=F,A=Uu({names:E.names,values:t})):(lu=A,A=B)):(lu=A,A=B)):(lu=A,A=B),du[r]={nextPos:lu,result:A},A)}function wu(){var A,E,C,F,t,r,e,D=32*lu+2,n=du[D];if(n)return lu=n.nextPos,n.result;if(A=lu,(E=Lu())!==B){for(C=[],F=lu,_u(),46===u.charCodeAt(lu)?(t=".",lu++):(t=B,0===pu&&$u(v)),t!==B?(_u(),(r=Lu())!==B?F=r:(lu=F,F=B)):(lu=F,F=B);F!==B;)C.push(F),F=lu,_u(),46===u.charCodeAt(lu)?(t=".",lu++):(t=B,0===pu&&$u(v)),t!==B?(_u(),(r=Lu())!==B?F=r:(lu=F,F=B)):(lu=F,F=B);iu=A,e=C,A=Uu({type:"QualifiedName",names:[E,...e]})}else lu=A,A=B;return du[D]={nextPos:lu,result:A},A}function ju(){var A,E,C,F,t,r,e,D=32*lu+3,n=du[D];if(n)return lu=n.nextPos,n.result;if(A=lu,(E=Ou())!==B){for(C=[],F=lu,_u(),59===u.charCodeAt(lu)?(t=";",lu++):(t=B,0===pu&&$u(y)),t!==B?(_u(),(r=Ou())!==B?F=r:(lu=F,F=B)):(lu=F,F=B);F!==B;)C.push(F),F=lu,_u(),59===u.charCodeAt(lu)?(t=";",lu++):(t=B,0===pu&&$u(y)),t!==B?(_u(),(r=Ou())!==B?F=r:(lu=F,F=B)):(lu=F,F=B);iu=A,e=C,A=[E,...e]}else lu=A,A=B;return du[D]={nextPos:lu,result:A},A}function Ou(){var A,E,C,F,t=32*lu+4,r=du[t];return r?(lu=r.nextPos,r.result):(A=lu,"$("===u.substr(lu,2)?(E="$(",lu+=2):(E=B,0===pu&&$u(m)),E!==B&&(C=wu())!==B?(41===u.charCodeAt(lu)?(F=")",lu++):(F=B,0===pu&&$u($)),F!==B?A=C:(lu=A,A=B)):(lu=A,A=B),A===B&&(A=function(){var u,A,E,C,F,t=32*lu+5,r=du[t];if(r)return lu=r.nextPos,r.result;if(pu++,u=lu,(A=Zu())!==B){for(E=[],C=lu,_u(),(F=Zu())!==B?C=F:(lu=C,C=B);C!==B;)E.push(C),C=lu,_u(),(F=Zu())!==B?C=F:(lu=C,C=B);iu=u,u=Uu({type:"Literal",value:A+E.join("")})}else lu=u,u=B;return pu--,u===B&&(A=B,0===pu&&$u(S)),du[t]={nextPos:lu,result:u},u}(),A===B&&(A=function(){var A,E,C,F,t,r,e,D,n,o,s=32*lu+6,a=du[s];if(a)return lu=a.nextPos,a.result;if(pu++,A=lu,34===u.charCodeAt(lu)?(E='"',lu++):(E=B,0===pu&&$u(w)),E!==B){if(C=lu,F=lu,t=[],(r=Zu())!==B)for(;r!==B;)t.push(r),r=Zu();else t=B;if(t!==B){if(r=[],e=lu,D=[],(n=qu())!==B)for(;n!==B;)D.push(n),n=qu();else D=B;if(D!==B){if(n=[],(o=Zu())!==B)for(;o!==B;)n.push(o),o=Zu();else n=B;n!==B?e=D=[D,n]:(lu=e,e=B)}else lu=e,e=B;for(;e!==B;){if(r.push(e),e=lu,D=[],(n=qu())!==B)for(;n!==B;)D.push(n),n=qu();else D=B;if(D!==B){if(n=[],(o=Zu())!==B)for(;o!==B;)n.push(o),o=Zu();else n=B;n!==B?e=D=[D,n]:(lu=e,e=B)}else lu=e,e=B}for(e=[],D=qu();D!==B;)e.push(D),D=qu();F=t=[t,r,e]}else lu=F,F=B;(C=F!==B?u.substring(C,lu):F)!==B?(34===u.charCodeAt(lu)?(F='"',lu++):(F=B,0===pu&&$u(w)),F!==B?(iu=A,A=Uu({type:"Literal",value:C})):(lu=A,A=B)):(lu=A,A=B)}else lu=A,A=B;return pu--,A===B&&(E=B,0===pu&&$u(b)),du[s]={nextPos:lu,result:A},A}(),A===B&&(A=function(){var A,E,C,F,t=32*lu+7,r=du[t];return r?(lu=r.nextPos,r.result):(A=lu,91===u.charCodeAt(lu)?(E="[",lu++):(E=B,0===pu&&$u(j)),E!==B&&(C=ju())!==B?(93===u.charCodeAt(lu)?(F="]",lu++):(F=B,0===pu&&$u(O)),F!==B?(iu=A,A=Uu({type:"SubList",values:C})):(lu=A,A=B)):(lu=A,A=B),du[t]={nextPos:lu,result:A},A)}()))),du[t]={nextPos:lu,result:A},A)}function Ru(){var u,A,E=32*lu+8,C=du[E];if(C)return lu=C.nextPos,C.result;for(u=[],(A=qu())===B&&(A=Nu())===B&&(A=Qu());A!==B;)u.push(A),(A=qu())===B&&(A=Nu())===B&&(A=Qu());return du[E]={nextPos:lu,result:u},u}function _u(){var A,E,C,F,t=32*lu+9,r=du[t];if(r)return lu=r.nextPos,r.result;for(A=[],32===u.charCodeAt(lu)?(E=" ",lu++):(E=B,0===pu&&$u(R)),E===B&&(9===u.charCodeAt(lu)?(E="\t",lu++):(E=B,0===pu&&$u(_)),E===B&&(E=lu,92===u.charCodeAt(lu)?(C="\\",lu++):(C=B,0===pu&&$u(L)),C!==B&&(F=Nu())!==B?E=C=[C,F]:(lu=E,E=B),E===B&&(E=Qu())));E!==B;)A.push(E),32===u.charCodeAt(lu)?(E=" ",lu++):(E=B,0===pu&&$u(R)),E===B&&(9===u.charCodeAt(lu)?(E="\t",lu++):(E=B,0===pu&&$u(_)),E===B&&(E=lu,92===u.charCodeAt(lu)?(C="\\",lu++):(C=B,0===pu&&$u(L)),C!==B&&(F=Nu())!==B?E=C=[C,F]:(lu=E,E=B),E===B&&(E=Qu())));return du[t]={nextPos:lu,result:A},A}function Lu(){var u,A,E,C,F=32*lu+10,t=du[F];if(t)return lu=t.nextPos,t.result;if(pu++,u=lu,(A=zu())!==B){for(E=[],C=Mu();C!==B;)E.push(C),C=Mu();iu=u,u=A+E.join("")}else lu=u,u=B;return pu--,u===B&&(A=B,0===pu&&$u(z)),du[F]={nextPos:lu,result:u},u}function zu(){var A,E=32*lu+11,C=du[E];return C?(lu=C.nextPos,C.result):(A=function(){var A,E=32*lu+14,C=du[E];return C?(lu=C.nextPos,C.result):(A=function(){var A,E=32*lu+25,C=du[E];return C?(lu=C.nextPos,C.result):(l.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(eu)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+21,C=du[E];return C?(lu=C.nextPos,C.result):(o.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(Fu)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+24,C=du[E];return C?(lu=C.nextPos,C.result):(c.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(ru)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+22,C=du[E];return C?(lu=C.nextPos,C.result):(s.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(tu)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+23,C=du[E];return C?(lu=C.nextPos,C.result):(a.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(Bu)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+29,C=du[E];return C?(lu=C.nextPos,C.result):(x.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(su)),du[E]={nextPos:lu,result:A},A)}()))))),du[E]={nextPos:lu,result:A},A)}(),A===B&&(95===u.charCodeAt(lu)?(A="_",lu++):(A=B,0===pu&&$u(M))),du[E]={nextPos:lu,result:A},A)}function Mu(){var A,E=32*lu+12,C=du[E];return C?(lu=C.nextPos,C.result):((A=zu())===B&&(A=function(){var A,E=32*lu+15,C=du[E];return C?(lu=C.nextPos,C.result):(A=function(){var A,E=32*lu+27,C=du[E];return C?(lu=C.nextPos,C.result):(f.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(nu)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+26,C=du[E];return C?(lu=C.nextPos,C.result):(i.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(Du)),du[E]={nextPos:lu,result:A},A)}()),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+28,C=du[E];return C?(lu=C.nextPos,C.result):(h.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(ou)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+30,C=du[E];return C?(lu=C.nextPos,C.result):(p.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(au)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(36===u.charCodeAt(lu)?(A="$",lu++):(A=B,0===pu&&$u(Z)),A===B&&(45===u.charCodeAt(lu)?(A="-",lu++):(A=B,0===pu&&$u(k)),A===B&&(8204===u.charCodeAt(lu)?(A="",lu++):(A=B,0===pu&&$u(q)),A===B&&(8205===u.charCodeAt(lu)?(A="",lu++):(A=B,0===pu&&$u(J))))))))),du[E]={nextPos:lu,result:A},A)}function Zu(){var A,E,C=32*lu+13,F=du[C];return F?(lu=F.nextPos,F.result):((A=Mu())===B&&(46===u.charCodeAt(lu)?(A=".",lu++):(A=B,0===pu&&$u(v)),A===B&&(47===u.charCodeAt(lu)?(A="/",lu++):(A=B,0===pu&&$u(N)),A===B&&(42===u.charCodeAt(lu)?(A="*",lu++):(A=B,0===pu&&$u(Q)),A===B&&(A=lu,92===u.charCodeAt(lu)?(E="\\",lu++):(E=B,0===pu&&$u(L)),E!==B&&(iu=A,E="/"),A=E)))),du[C]={nextPos:lu,result:A},A)}function ku(){var A,E=32*lu+16,C=du[E];return C?(lu=C.nextPos,C.result):(u.length>lu?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(P)),du[E]={nextPos:lu,result:A},A)}function qu(){var A,E=32*lu+17,C=du[E];return C?(lu=C.nextPos,C.result):(pu++,9===u.charCodeAt(lu)?(A="\t",lu++):(A=B,0===pu&&$u(_)),A===B&&(11===u.charCodeAt(lu)?(A="\v",lu++):(A=B,0===pu&&$u(G)),A===B&&(12===u.charCodeAt(lu)?(A="\f",lu++):(A=B,0===pu&&$u(H)),A===B&&(32===u.charCodeAt(lu)?(A=" ",lu++):(A=B,0===pu&&$u(R)),A===B&&(160===u.charCodeAt(lu)?(A=" ",lu++):(A=B,0===pu&&$u(I)),A===B&&(65279===u.charCodeAt(lu)?(A="\ufeff",lu++):(A=B,0===pu&&$u(K)),A===B&&(A=function(){var A,E=32*lu+31,C=du[E];return C?(lu=C.nextPos,C.result):(d.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(cu)),du[E]={nextPos:lu,result:A},A)}())))))),pu--,A===B&&0===pu&&$u(U),du[E]={nextPos:lu,result:A},A)}function Ju(){var A,E=32*lu+18,C=du[E];return C?(lu=C.nextPos,C.result):(n.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(T)),du[E]={nextPos:lu,result:A},A)}function Nu(){var A,E=32*lu+19,C=du[E];return C?(lu=C.nextPos,C.result):(pu++,10===u.charCodeAt(lu)?(A="\n",lu++):(A=B,0===pu&&$u(W)),A===B&&("\r\n"===u.substr(lu,2)?(A="\r\n",lu+=2):(A=B,0===pu&&$u(X)),A===B&&(13===u.charCodeAt(lu)?(A="\r",lu++):(A=B,0===pu&&$u(Y)),A===B&&(8232===u.charCodeAt(lu)?(A="\u2028",lu++):(A=B,0===pu&&$u(uu)),A===B&&(8233===u.charCodeAt(lu)?(A="\u2029",lu++):(A=B,0===pu&&$u(Au)))))),pu--,A===B&&0===pu&&$u(V),du[E]={nextPos:lu,result:A},A)}function Qu(){var A,E,C,F,t,r,e=32*lu+20,D=du[e];if(D)return lu=D.nextPos,D.result;if(pu++,A=lu,35===u.charCodeAt(lu)?(E="#",lu++):(E=B,0===pu&&$u(Cu)),E!==B){for(C=[],F=lu,t=lu,pu++,r=Ju(),pu--,r===B?t=void 0:(lu=t,t=B),t!==B&&(r=ku())!==B?F=t=[t,r]:(lu=F,F=B);F!==B;)C.push(F),F=lu,t=lu,pu++,r=Ju(),pu--,r===B?t=void 0:(lu=t,t=B),t!==B&&(r=ku())!==B?F=t=[t,r]:(lu=F,F=B);A=E=[E,C]}else lu=A,A=B;return pu--,A===B&&(E=B,0===pu&&$u(Eu)),du[e]={nextPos:lu,result:A},A}function Uu(u){return{...u,source:mu(iu,lu).source}}if((E=D())!==B&&lu===u.length)return E;throw E!==B&&lu<u.length&&$u({type:"end"}),C=xu,F=hu<u.length?u.charAt(hu):null,t=hu<u.length?mu(hu,hu+1):mu(hu,hu),new peg$SyntaxError(peg$SyntaxError.buildMessage(C,F),C,F,t)}peg$subclass(peg$SyntaxError,Error),peg$SyntaxError.prototype.format=function(u){var A="Error: "+this.message;if(this.location){var E,C=null;for(E=0;E<u.length;E++)if(u[E].source===this.location.source){C=u[E].text.split(/\r\n|\n|\r/g);break}var F=this.location.start,t=this.location.source+":"+F.line+":"+F.column;if(C){var B=this.location.end,r=peg$padEnd("",F.line.toString().length),e=C[F.line-1],D=F.line===B.line?B.column:e.length+1;A+="\n --\x3e "+t+"\n"+r+" |\n"+F.line+" | "+e+"\n"+r+" | "+peg$padEnd("",F.column-1)+peg$padEnd("",D-F.column,"^")}else A+="\n at "+t}return A},peg$SyntaxError.buildMessage=function(u,A){var E={literal:function(u){return'"'+F(u.text)+'"'},class:function(u){var A=u.parts.map((function(u){return Array.isArray(u)?t(u[0])+"-"+t(u[1]):t(u)}));return"["+(u.inverted?"^":"")+A+"]"},any:function(){return"any character"},end:function(){return"end of input"},other:function(u){return u.description}};function C(u){return u.charCodeAt(0).toString(16).toUpperCase()}function F(u){return u.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,(function(u){return"\\x0"+C(u)})).replace(/[\x10-\x1F\x7F-\x9F]/g,(function(u){return"\\x"+C(u)}))}function t(u){return u.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,(function(u){return"\\x0"+C(u)})).replace(/[\x10-\x1F\x7F-\x9F]/g,(function(u){return"\\x"+C(u)}))}function B(u){return E[u.type](u)}return"Expected "+function(u){var A,E,C=u.map(B);if(C.sort(),C.length>0){for(A=1,E=1;A<C.length;A++)C[A-1]!==C[A]&&(C[E]=C[A],E++);C.length=E}switch(C.length){case 1:return C[0];case 2:return C[0]+" or "+C[1];default:return C.slice(0,-1).join(", ")+", or "+C[C.length-1]}}(u)+" but "+function(u){return u?'"'+F(u)+'"':"end of input"}(A)+" found."};
|
|
9907
|
-
;// CONCATENATED MODULE: ./src/manifest.
|
|
9908
|
-
|
|
9922
|
+
;// CONCATENATED MODULE: ./src/manifest.ts
|
|
9909
9923
|
|
|
9910
9924
|
|
|
9911
9925
|
|
|
9912
9926
|
async function readManifest(manifest) {
|
|
9913
|
-
|
|
9914
|
-
|
|
9927
|
+
const data = await promises_namespaceObject.readFile(manifest);
|
|
9928
|
+
return (0,xml2js.parseStringPromise)(data.toString(), { trim: true });
|
|
9915
9929
|
}
|
|
9916
|
-
|
|
9917
9930
|
async function writeManifest(filename, xml) {
|
|
9918
|
-
|
|
9919
|
-
|
|
9920
|
-
|
|
9931
|
+
let builder = new xml2js.Builder();
|
|
9932
|
+
let text = builder.buildObject(xml);
|
|
9933
|
+
return promises_namespaceObject.writeFile(filename, text);
|
|
9921
9934
|
}
|
|
9922
|
-
|
|
9923
9935
|
function manifestProducts(manifest) {
|
|
9924
|
-
|
|
9925
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
|
|
9929
|
-
|
|
9930
|
-
.filter((p, i, a) => !i || p !== a[i - 1]);
|
|
9936
|
+
const app = manifest["iq:manifest"]["iq:application"] ||
|
|
9937
|
+
manifest["iq:manifest"]["iq:barrel"];
|
|
9938
|
+
return (app?.[0]["iq:products"]?.[0]["iq:product"] || [])
|
|
9939
|
+
.map((p) => p.$.id)
|
|
9940
|
+
.sort()
|
|
9941
|
+
.filter((p, i, a) => !i || p !== a[i - 1]);
|
|
9931
9942
|
}
|
|
9932
|
-
|
|
9933
9943
|
function manifestBarrels(manifest) {
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
9937
|
-
|
|
9938
|
-
|
|
9939
|
-
|
|
9940
|
-
|
|
9941
|
-
|
|
9942
|
-
|
|
9943
|
-
|
|
9944
|
-
|
|
9945
|
-
|
|
9946
|
-
|
|
9947
|
-
}
|
|
9948
|
-
return [];
|
|
9944
|
+
const app = manifest["iq:manifest"]["iq:application"];
|
|
9945
|
+
if (Array.isArray(app) &&
|
|
9946
|
+
app.length &&
|
|
9947
|
+
app[0] &&
|
|
9948
|
+
Array.isArray(app[0]["iq:barrels"]) &&
|
|
9949
|
+
app[0]["iq:barrels"].length &&
|
|
9950
|
+
Array.isArray(app[0]["iq:barrels"][0]["iq:depends"])) {
|
|
9951
|
+
return app[0]["iq:barrels"][0]["iq:depends"]
|
|
9952
|
+
.map((p) => p.$.name)
|
|
9953
|
+
.sort()
|
|
9954
|
+
.filter((p, i, a) => !i || p !== a[i - 1]);
|
|
9955
|
+
}
|
|
9956
|
+
return [];
|
|
9949
9957
|
}
|
|
9950
|
-
|
|
9951
9958
|
function manifestDropBarrels(manifest) {
|
|
9952
|
-
|
|
9959
|
+
const app = manifest["iq:manifest"]["iq:application"];
|
|
9960
|
+
if (!app)
|
|
9961
|
+
return;
|
|
9962
|
+
delete app[0]["iq:barrels"];
|
|
9953
9963
|
}
|
|
9954
|
-
|
|
9955
9964
|
function manifestBarrelName(manifestName, manifest) {
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9965
|
+
const barrel = manifest["iq:manifest"]["iq:barrel"];
|
|
9966
|
+
if (!barrel)
|
|
9967
|
+
throw new Error(`Not a barrel manifest: ${manifestName}`);
|
|
9968
|
+
return barrel[0].$.module;
|
|
9959
9969
|
}
|
|
9960
|
-
|
|
9961
9970
|
function manifestAnnotations(manifest) {
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9971
|
+
const barrel = manifest["iq:manifest"]["iq:barrel"];
|
|
9972
|
+
if (!barrel)
|
|
9973
|
+
return undefined;
|
|
9974
|
+
const annotations = barrel[0]["iq:annotations"];
|
|
9975
|
+
return annotations && annotations[0]["iq:annotation"];
|
|
9966
9976
|
}
|
|
9967
|
-
|
|
9968
9977
|
async function checkManifest(manifest, products) {
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
|
|
9973
|
-
|
|
9974
|
-
|
|
9975
|
-
|
|
9976
|
-
|
|
9977
|
-
|
|
9978
|
-
|
|
9979
|
-
|
|
9980
|
-
|
|
9981
|
-
|
|
9982
|
-
|
|
9983
|
-
|
|
9984
|
-
|
|
9985
|
-
|
|
9986
|
-
|
|
9987
|
-
|
|
9988
|
-
|
|
9989
|
-
|
|
9990
|
-
|
|
9991
|
-
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
|
|
9999
|
-
|
|
10000
|
-
|
|
9978
|
+
let ok = true;
|
|
9979
|
+
if (!manifest["iq:manifest"]["$"]["xmlns:iq"]) {
|
|
9980
|
+
manifest["iq:manifest"]["$"]["xmlns:iq"] =
|
|
9981
|
+
"http://www.garmin.com/xml/connectiq";
|
|
9982
|
+
ok = false;
|
|
9983
|
+
}
|
|
9984
|
+
const app = manifest["iq:manifest"]["iq:application"];
|
|
9985
|
+
if (!app)
|
|
9986
|
+
return ok;
|
|
9987
|
+
const elm = app[0];
|
|
9988
|
+
const id = elm.$.id;
|
|
9989
|
+
if (id.length < 32 || !/^[-_0-9a-f.]+$/.test(id)) {
|
|
9990
|
+
ok = false;
|
|
9991
|
+
elm.$.id = "08070f9d-8b4e-40a4-9c49-fe67a2a55dec";
|
|
9992
|
+
}
|
|
9993
|
+
const type = elm.$.type.replace(/-/g, "").toLowerCase();
|
|
9994
|
+
const deviceInfo = await (0,external_sdk_util_cjs_namespaceObject.getDeviceInfo)();
|
|
9995
|
+
const allowedProducts = products.sort().filter((p) => deviceInfo[p] &&
|
|
9996
|
+
deviceInfo[p].appTypes.find((at) => {
|
|
9997
|
+
const t = at.type.toLowerCase();
|
|
9998
|
+
return t === type || `${t}app` === type;
|
|
9999
|
+
}));
|
|
10000
|
+
if (JSON.stringify(allowedProducts) !=
|
|
10001
|
+
JSON.stringify(manifestProducts(manifest))) {
|
|
10002
|
+
ok = false;
|
|
10003
|
+
elm["iq:products"] = [
|
|
10004
|
+
{
|
|
10005
|
+
"iq:product": allowedProducts.map((id) => {
|
|
10006
|
+
return { $: { id } };
|
|
10007
|
+
}),
|
|
10008
|
+
},
|
|
10009
|
+
];
|
|
10010
|
+
}
|
|
10011
|
+
Object.keys(elm).forEach((key) => {
|
|
10012
|
+
if (![
|
|
10013
|
+
"$",
|
|
10014
|
+
"iq:permissions",
|
|
10015
|
+
"iq:languages",
|
|
10016
|
+
"iq:products",
|
|
10017
|
+
"iq:barrels",
|
|
10018
|
+
"iq:trialMode",
|
|
10019
|
+
].includes(key)) {
|
|
10020
|
+
ok = false;
|
|
10021
|
+
delete elm[key];
|
|
10022
|
+
}
|
|
10001
10023
|
});
|
|
10002
|
-
|
|
10003
|
-
Object.keys(elm).forEach((key) => {
|
|
10004
|
-
if (
|
|
10005
|
-
![
|
|
10006
|
-
"$",
|
|
10007
|
-
"iq:permissions",
|
|
10008
|
-
"iq:languages",
|
|
10009
|
-
"iq:products",
|
|
10010
|
-
"iq:barrels",
|
|
10011
|
-
"iq:trialMode",
|
|
10012
|
-
].includes(key)
|
|
10013
|
-
) {
|
|
10014
|
-
ok = false;
|
|
10015
|
-
delete elm[key];
|
|
10016
|
-
}
|
|
10017
|
-
});
|
|
10018
|
-
|
|
10019
|
-
return ok;
|
|
10024
|
+
return ok;
|
|
10020
10025
|
}
|
|
10021
10026
|
|
|
10022
|
-
;// CONCATENATED MODULE: ./src/jungles.
|
|
10023
|
-
|
|
10027
|
+
;// CONCATENATED MODULE: ./src/jungles.ts
|
|
10024
10028
|
|
|
10025
10029
|
|
|
10026
10030
|
|
|
@@ -10031,510 +10035,509 @@ async function checkManifest(manifest, products) {
|
|
|
10031
10035
|
|
|
10032
10036
|
|
|
10033
10037
|
|
|
10038
|
+
function isJNode(obj) {
|
|
10039
|
+
return (0,external_api_cjs_namespaceObject.hasProperty)(obj, "type");
|
|
10040
|
+
}
|
|
10034
10041
|
async function default_jungle() {
|
|
10035
|
-
|
|
10036
|
-
|
|
10037
|
-
|
|
10038
|
-
|
|
10039
|
-
|
|
10040
|
-
|
|
10041
|
-
|
|
10042
|
-
|
|
10043
|
-
assign(name,
|
|
10044
|
-
|
|
10045
|
-
|
|
10046
|
-
|
|
10047
|
-
|
|
10048
|
-
|
|
10049
|
-
|
|
10050
|
-
|
|
10051
|
-
|
|
10052
|
-
|
|
10053
|
-
|
|
10054
|
-
|
|
10055
|
-
|
|
10056
|
-
|
|
10057
|
-
|
|
10058
|
-
|
|
10059
|
-
|
|
10060
|
-
|
|
10061
|
-
|
|
10062
|
-
|
|
10063
|
-
|
|
10064
|
-
|
|
10065
|
-
|
|
10066
|
-
|
|
10067
|
-
|
|
10068
|
-
|
|
10069
|
-
|
|
10070
|
-
|
|
10071
|
-
|
|
10072
|
-
|
|
10073
|
-
|
|
10074
|
-
}
|
|
10075
|
-
rezAndLang(deviceId, `resources-${deviceId}`, deviceFamily);
|
|
10076
|
-
});
|
|
10077
|
-
return process_assignments(assignments, {});
|
|
10042
|
+
const assignments = [];
|
|
10043
|
+
const devices = await (0,external_sdk_util_cjs_namespaceObject.getDeviceInfo)();
|
|
10044
|
+
const languages = await (0,external_sdk_util_cjs_namespaceObject.getLanguages)();
|
|
10045
|
+
const literal = (value) => ({ type: "Literal", value });
|
|
10046
|
+
const qname = (name) => ({
|
|
10047
|
+
type: "QualifiedName",
|
|
10048
|
+
names: name.split("."),
|
|
10049
|
+
});
|
|
10050
|
+
const assign = (name, values) => assignments.push({ names: name.split("."), values });
|
|
10051
|
+
const rassign = (name, values, base) => {
|
|
10052
|
+
assign(name, base ? [qname(name)].concat(values) : values);
|
|
10053
|
+
};
|
|
10054
|
+
const rezAndLang = (id, rez, base = null) => {
|
|
10055
|
+
if (base) {
|
|
10056
|
+
assign(id, [qname(base)]);
|
|
10057
|
+
}
|
|
10058
|
+
rassign(`${id}.resourcePath`, [literal(rez)], base);
|
|
10059
|
+
languages.forEach((l) => rassign(`${id}.lang.${l.id}`, [literal(`${rez}-${l.id}`)], base));
|
|
10060
|
+
};
|
|
10061
|
+
const done = {};
|
|
10062
|
+
assign("base.sourcePath", [literal("./**.mc")]);
|
|
10063
|
+
rezAndLang("base", "resources");
|
|
10064
|
+
Object.entries(devices).forEach(([deviceId, { deviceFamily }]) => {
|
|
10065
|
+
const match = deviceFamily.match(/^(\w+)-\d+x\d+/);
|
|
10066
|
+
if (!match) {
|
|
10067
|
+
throw new Error(`Strange deviceFamily (${deviceFamily}) for device ${deviceId}`);
|
|
10068
|
+
}
|
|
10069
|
+
const shape = match[1];
|
|
10070
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(done, shape)) {
|
|
10071
|
+
rezAndLang(shape, `resources-${shape}`, "base");
|
|
10072
|
+
done[shape] = true;
|
|
10073
|
+
}
|
|
10074
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(done, deviceFamily)) {
|
|
10075
|
+
rezAndLang(deviceFamily, `resources-${deviceFamily}`, shape);
|
|
10076
|
+
done[deviceFamily] = true;
|
|
10077
|
+
}
|
|
10078
|
+
rezAndLang(deviceId, `resources-${deviceId}`, deviceFamily);
|
|
10079
|
+
});
|
|
10080
|
+
return process_assignments(assignments, {});
|
|
10078
10081
|
}
|
|
10079
|
-
|
|
10080
10082
|
function process_assignments(assignments, current) {
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10093
|
-
|
|
10094
|
-
|
|
10095
|
-
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
|
|
10099
|
-
|
|
10100
|
-
|
|
10101
|
-
|
|
10102
|
-
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
|
|
10106
|
-
|
|
10107
|
-
|
|
10108
|
-
|
|
10109
|
-
|
|
10110
|
-
|
|
10111
|
-
|
|
10112
|
-
|
|
10113
|
-
|
|
10114
|
-
|
|
10115
|
-
|
|
10116
|
-
|
|
10117
|
-
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
|
|
10129
|
-
|
|
10130
|
-
|
|
10131
|
-
|
|
10132
|
-
|
|
10133
|
-
|
|
10134
|
-
const match = a.values[0].names[0].match(/^(\w+)-(\w+)$/);
|
|
10135
|
-
if (match) {
|
|
10136
|
-
const key = `${match[1]}_watch`;
|
|
10137
|
-
if (!state[key]) state[key] = { products: [] };
|
|
10138
|
-
state[key].products.push(a.names[0]);
|
|
10139
|
-
}
|
|
10140
|
-
}
|
|
10141
|
-
node["."] = a.values;
|
|
10142
|
-
return state;
|
|
10143
|
-
}, current);
|
|
10083
|
+
return assignments.reduce((state, a) => {
|
|
10084
|
+
const { node, dot, dotnames } = a.names.reduce((r, name) => {
|
|
10085
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(r.node, name))
|
|
10086
|
+
r.node[name] = {};
|
|
10087
|
+
r.dotnames.push(name);
|
|
10088
|
+
r.node = r.node[name];
|
|
10089
|
+
if (r.node["."]) {
|
|
10090
|
+
r.dot = r.node["."];
|
|
10091
|
+
r.dotnames = [];
|
|
10092
|
+
}
|
|
10093
|
+
return r;
|
|
10094
|
+
}, { node: state, dot: undefined, dotnames: [] });
|
|
10095
|
+
// an assignment to a node overwrites its old value
|
|
10096
|
+
Object.keys(node).forEach((k) => delete node[k]);
|
|
10097
|
+
const process_list = (values) => {
|
|
10098
|
+
for (let i = values.length; i--;) {
|
|
10099
|
+
const v = values[i];
|
|
10100
|
+
if (v.type == "QualifiedName" &&
|
|
10101
|
+
v.names.every((n, i) => n === a.names[i])) {
|
|
10102
|
+
values.splice(i, 1, ...(dot
|
|
10103
|
+
? dot.map((v) => v.type == "QualifiedName"
|
|
10104
|
+
? { ...v, names: v.names.concat(dotnames) }
|
|
10105
|
+
: v)
|
|
10106
|
+
: []));
|
|
10107
|
+
}
|
|
10108
|
+
else if (v.type == "SubList") {
|
|
10109
|
+
process_list(v.values);
|
|
10110
|
+
}
|
|
10111
|
+
}
|
|
10112
|
+
};
|
|
10113
|
+
process_list(a.values);
|
|
10114
|
+
if (a.names.length === 1 &&
|
|
10115
|
+
a.values.length === 1 &&
|
|
10116
|
+
a.values[0].type === "QualifiedName" &&
|
|
10117
|
+
a.values[0].names.length === 1) {
|
|
10118
|
+
// some older manifests have things like "round_watch"
|
|
10119
|
+
// as a product. You can't put that in a jungle file
|
|
10120
|
+
// so instead, we identify every round device, and
|
|
10121
|
+
// replace round_watch with all the corresponding
|
|
10122
|
+
// devices. So we look for assignments of the form
|
|
10123
|
+
// device = $(shape-size)
|
|
10124
|
+
// and put all such devices on a `shape`_watch entry
|
|
10125
|
+
const match = a.values[0].names[0].match(/^(\w+)-(\w+)$/);
|
|
10126
|
+
if (match) {
|
|
10127
|
+
const key = `${match[1]}_watch`;
|
|
10128
|
+
if (!current[key])
|
|
10129
|
+
current[key] = { products: [] };
|
|
10130
|
+
current[key].products.push(a.names[0]);
|
|
10131
|
+
}
|
|
10132
|
+
}
|
|
10133
|
+
node["."] = a.values;
|
|
10134
|
+
return state;
|
|
10135
|
+
}, current);
|
|
10144
10136
|
}
|
|
10145
|
-
|
|
10146
10137
|
function evaluate_locals(assignments) {
|
|
10147
|
-
|
|
10148
|
-
|
|
10149
|
-
|
|
10150
|
-
|
|
10151
|
-
|
|
10152
|
-
|
|
10153
|
-
|
|
10154
|
-
|
|
10155
|
-
|
|
10156
|
-
|
|
10157
|
-
|
|
10158
|
-
|
|
10159
|
-
|
|
10160
|
-
|
|
10161
|
-
|
|
10162
|
-
|
|
10163
|
-
|
|
10164
|
-
|
|
10165
|
-
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
|
|
10169
|
-
|
|
10170
|
-
|
|
10171
|
-
|
|
10172
|
-
|
|
10173
|
-
|
|
10138
|
+
const locals = {};
|
|
10139
|
+
while (true) {
|
|
10140
|
+
assignments = assignments.filter((a) => {
|
|
10141
|
+
if (a.names.length == 1 && a.values.every((v) => typeof v === "string")) {
|
|
10142
|
+
locals[a.names[0]] = a.values;
|
|
10143
|
+
return false;
|
|
10144
|
+
}
|
|
10145
|
+
return true;
|
|
10146
|
+
});
|
|
10147
|
+
if (!Object.keys(locals).length)
|
|
10148
|
+
break;
|
|
10149
|
+
const process_list = (values) => {
|
|
10150
|
+
for (let i = values.length; i--;) {
|
|
10151
|
+
const v = values[i];
|
|
10152
|
+
if (v.type == "QualifiedName" &&
|
|
10153
|
+
v.names.length == 1 &&
|
|
10154
|
+
(0,external_api_cjs_namespaceObject.hasProperty)(locals, v.names[0])) {
|
|
10155
|
+
values.splice(i, 1, ...locals[v.names[0]]);
|
|
10156
|
+
}
|
|
10157
|
+
else if (v.type == "SubList") {
|
|
10158
|
+
process_list(v.values);
|
|
10159
|
+
}
|
|
10160
|
+
}
|
|
10161
|
+
};
|
|
10162
|
+
assignments.forEach((a) => process_list(a.values));
|
|
10163
|
+
}
|
|
10164
|
+
return assignments;
|
|
10174
10165
|
}
|
|
10175
|
-
|
|
10176
10166
|
async function parse_one(file) {
|
|
10177
|
-
|
|
10178
|
-
|
|
10179
|
-
|
|
10180
|
-
|
|
10167
|
+
const [fileName, grammarSource] = Array.isArray(file) ? file : [file, file];
|
|
10168
|
+
const source = await promises_namespaceObject.readFile(fileName).catch(() => {
|
|
10169
|
+
throw new Error(`Couldn't read jungle file '${fileName}`);
|
|
10170
|
+
});
|
|
10171
|
+
const assignments = peg$parse(source.toString(), { grammarSource });
|
|
10172
|
+
return evaluate_locals(assignments);
|
|
10181
10173
|
}
|
|
10182
|
-
|
|
10183
10174
|
// Read default.jungle, and all jungles in sources, and
|
|
10184
10175
|
// return a jungle object with all local variables resolved,
|
|
10185
10176
|
// but all qualifier references left unresolved.
|
|
10186
10177
|
async function process_jungles(sources) {
|
|
10187
|
-
|
|
10188
|
-
|
|
10189
|
-
|
|
10190
|
-
|
|
10191
|
-
|
|
10192
|
-
|
|
10193
|
-
|
|
10178
|
+
if (!Array.isArray(sources)) {
|
|
10179
|
+
sources = [sources];
|
|
10180
|
+
}
|
|
10181
|
+
const results = await Promise.all(sources.map(parse_one));
|
|
10182
|
+
const state = await default_jungle();
|
|
10183
|
+
results.forEach((r) => process_assignments(r, state));
|
|
10184
|
+
return state;
|
|
10194
10185
|
}
|
|
10195
|
-
|
|
10196
10186
|
function resolve_node_list(state, list) {
|
|
10197
|
-
|
|
10198
|
-
|
|
10199
|
-
|
|
10200
|
-
|
|
10201
|
-
|
|
10202
|
-
if (
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
|
|
10210
|
-
|
|
10211
|
-
|
|
10212
|
-
|
|
10187
|
+
if (!Array.isArray(list)) {
|
|
10188
|
+
throw new Error("Expected an array");
|
|
10189
|
+
}
|
|
10190
|
+
for (let i = list.length; i--;) {
|
|
10191
|
+
const v = list[i];
|
|
10192
|
+
if (typeof v === "string" || Array.isArray(v))
|
|
10193
|
+
continue;
|
|
10194
|
+
if (v.type === "QualifiedName") {
|
|
10195
|
+
const rep = resolve_node(state, resolve_node_by_path(state, v.names));
|
|
10196
|
+
if (Array.isArray(rep)) {
|
|
10197
|
+
if (rep.length !== 1 || (isJNode(rep[0]) && rep[0].type)) {
|
|
10198
|
+
resolve_node_list(state, rep);
|
|
10199
|
+
}
|
|
10200
|
+
list.splice(i, 1, ...rep);
|
|
10201
|
+
}
|
|
10202
|
+
else if (rep != null) {
|
|
10203
|
+
list[i] = rep;
|
|
10204
|
+
}
|
|
10205
|
+
else {
|
|
10206
|
+
list.splice(i, 1);
|
|
10207
|
+
}
|
|
10208
|
+
}
|
|
10209
|
+
else if (v.type === "SubList") {
|
|
10210
|
+
resolve_node_list(state, v.values);
|
|
10211
|
+
}
|
|
10213
10212
|
}
|
|
10214
|
-
|
|
10215
|
-
return list;
|
|
10213
|
+
return list;
|
|
10216
10214
|
}
|
|
10217
|
-
|
|
10218
|
-
|
|
10219
|
-
|
|
10220
|
-
|
|
10221
|
-
|
|
10222
|
-
|
|
10223
|
-
.join(".")} should have length 1: ${JSON.stringify(dot)}`
|
|
10224
|
-
);
|
|
10225
|
-
}
|
|
10215
|
+
function check_non_leaf_dot(dot, path = null, i = 0) {
|
|
10216
|
+
if (dot.length !== 1 || dot[0].type) {
|
|
10217
|
+
throw new Error(`'.' node at ${(path || [])
|
|
10218
|
+
.slice(0, i + 1)
|
|
10219
|
+
.join(".")} should have length 1: ${JSON.stringify(dot)}`);
|
|
10220
|
+
}
|
|
10226
10221
|
}
|
|
10227
10222
|
// return the resolved node at path
|
|
10228
10223
|
function resolve_node_by_path(state, path) {
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10232
|
-
|
|
10233
|
-
|
|
10234
|
-
|
|
10235
|
-
|
|
10236
|
-
|
|
10237
|
-
|
|
10238
|
-
|
|
10239
|
-
|
|
10240
|
-
|
|
10241
|
-
|
|
10242
|
-
|
|
10224
|
+
return path.reduce((s, n, i) => {
|
|
10225
|
+
if (!s || Array.isArray(s)) {
|
|
10226
|
+
return s;
|
|
10227
|
+
}
|
|
10228
|
+
if (!s[n] && s["."]) {
|
|
10229
|
+
const sdot = s["."];
|
|
10230
|
+
let resolved = resolve_node_list(state, sdot);
|
|
10231
|
+
if (!resolved.length)
|
|
10232
|
+
return undefined;
|
|
10233
|
+
const r = resolved[0][n];
|
|
10234
|
+
if (!r && sdot.every((e) => e.type == "Literal")) {
|
|
10235
|
+
/*
|
|
10236
|
+
* We had something like:
|
|
10237
|
+
*
|
|
10238
|
+
* foo = whatever
|
|
10239
|
+
* bar = $(foo.resourcePath)
|
|
10240
|
+
*
|
|
10241
|
+
* and its supposed to work as if you'd left out the (obviously
|
|
10242
|
+
* incorrect) ".resourcePath"
|
|
10243
|
+
*/
|
|
10244
|
+
return s;
|
|
10245
|
+
}
|
|
10246
|
+
/*
|
|
10247
|
+
* This is a pretty unusual edge case.
|
|
10248
|
+
*
|
|
10249
|
+
* If we do something like:
|
|
10250
|
+
*
|
|
10251
|
+
* fenix6 = $(base)
|
|
10252
|
+
* fenix5.sourcePath = $(fenix6.sourcePath)
|
|
10253
|
+
*
|
|
10254
|
+
* and fenix5 gets resolved before fenix6 (which it will,
|
|
10255
|
+
* currently, because products are resolved in lexicographical
|
|
10256
|
+
* order), we'll end up here when we try to resolve
|
|
10257
|
+
* fenix6.sourcePath.
|
|
10258
|
+
*/
|
|
10259
|
+
check_non_leaf_dot(sdot, path, i);
|
|
10260
|
+
return r;
|
|
10261
|
+
}
|
|
10262
|
+
return s[n];
|
|
10263
|
+
}, state);
|
|
10243
10264
|
}
|
|
10244
|
-
|
|
10245
10265
|
// fully resolve the given node, and all its children
|
|
10246
10266
|
function resolve_node(state, node) {
|
|
10247
|
-
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
|
|
10251
|
-
|
|
10252
|
-
|
|
10253
|
-
|
|
10254
|
-
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
|
|
10261
|
-
|
|
10262
|
-
|
|
10263
|
-
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
|
|
10267
|
+
if (node === undefined || Array.isArray(node)) {
|
|
10268
|
+
// an already optimized leaf node
|
|
10269
|
+
return node;
|
|
10270
|
+
}
|
|
10271
|
+
const { ".": dot, ...rest } = node;
|
|
10272
|
+
if (dot) {
|
|
10273
|
+
const entries = Object.entries(rest);
|
|
10274
|
+
resolve_node_list(state, dot);
|
|
10275
|
+
if (entries.length) {
|
|
10276
|
+
// not a leaf, so dot must have a single element
|
|
10277
|
+
check_non_leaf_dot(dot);
|
|
10278
|
+
Object.entries(dot[0]).forEach(([k, v]) => {
|
|
10279
|
+
node[k] = v;
|
|
10280
|
+
});
|
|
10281
|
+
entries.forEach(([k, v]) => {
|
|
10282
|
+
node[k] = v;
|
|
10283
|
+
});
|
|
10284
|
+
}
|
|
10285
|
+
else if (dot.length === 1 && !dot[0].type) {
|
|
10286
|
+
Object.entries(dot[0]).forEach(([k, v]) => {
|
|
10287
|
+
node[k] = v;
|
|
10288
|
+
});
|
|
10289
|
+
}
|
|
10290
|
+
else {
|
|
10291
|
+
return dot;
|
|
10292
|
+
}
|
|
10293
|
+
delete node["."];
|
|
10270
10294
|
}
|
|
10271
|
-
|
|
10272
|
-
|
|
10273
|
-
|
|
10274
|
-
node
|
|
10275
|
-
});
|
|
10276
|
-
return node;
|
|
10295
|
+
Object.entries(node).forEach(([key, value]) => {
|
|
10296
|
+
node[key] = resolve_node(state, value);
|
|
10297
|
+
});
|
|
10298
|
+
return node;
|
|
10277
10299
|
}
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10300
|
+
function resolve_filename(literal, default_source = null) {
|
|
10301
|
+
if (typeof literal === "string")
|
|
10302
|
+
return literal;
|
|
10303
|
+
const root = external_path_.dirname(literal.source || default_source);
|
|
10304
|
+
return external_path_.resolve(root, literal.value);
|
|
10283
10305
|
}
|
|
10284
|
-
|
|
10285
10306
|
async function resolve_literals(qualifier, default_source) {
|
|
10286
|
-
|
|
10287
|
-
|
|
10288
|
-
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
|
|
10299
|
-
|
|
10300
|
-
|
|
10301
|
-
|
|
10302
|
-
|
|
10303
|
-
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
10307
|
+
const resolve_file_list = async (literals) => literals &&
|
|
10308
|
+
(await Promise.all(literals.map(async (v) => {
|
|
10309
|
+
if (!isJNode(v)) {
|
|
10310
|
+
return v;
|
|
10311
|
+
}
|
|
10312
|
+
if (v.type == "QualifiedName") {
|
|
10313
|
+
throw new Error("Unexpected QualifiedName found!");
|
|
10314
|
+
}
|
|
10315
|
+
if (v.type == "SubList") {
|
|
10316
|
+
return resolve_file_list(v.values);
|
|
10317
|
+
}
|
|
10318
|
+
let resolved = resolve_filename(v, default_source);
|
|
10319
|
+
if (/[*?\[\]\{\}]/.test(resolved)) {
|
|
10320
|
+
// Jungle files can contain "./**.mc" which is supposed to match
|
|
10321
|
+
// any mc file under "./". The standard way to express that
|
|
10322
|
+
// is "./**/*.mc", which is what glob expects, so translate.
|
|
10323
|
+
resolved = resolved.replace(/[\\\/]\*\*([^\\\/])/g, "/**/*$1");
|
|
10324
|
+
const match = await (0,external_util_cjs_namespaceObject.globa)(resolved);
|
|
10325
|
+
return match.length ? resolved : null;
|
|
10326
|
+
}
|
|
10327
|
+
else {
|
|
10328
|
+
const stat = await promises_namespaceObject.stat(resolved).catch(() => null);
|
|
10329
|
+
return stat ? resolved : null;
|
|
10330
|
+
}
|
|
10331
|
+
}))).filter((name) => name != null);
|
|
10332
|
+
const resolve_one_file_list = async (base, name) => {
|
|
10333
|
+
const bname = base[name];
|
|
10334
|
+
if (!bname)
|
|
10335
|
+
return;
|
|
10336
|
+
const result = await resolve_file_list(bname);
|
|
10337
|
+
if (!result || !result.length) {
|
|
10338
|
+
delete base[name];
|
|
10339
|
+
}
|
|
10340
|
+
else {
|
|
10341
|
+
base[name] = result;
|
|
10342
|
+
}
|
|
10343
|
+
};
|
|
10344
|
+
await resolve_one_file_list(qualifier, "sourcePath");
|
|
10345
|
+
await resolve_one_file_list(qualifier, "resourcePath");
|
|
10346
|
+
await resolve_one_file_list(qualifier, "barrelPath");
|
|
10347
|
+
const lang = qualifier["lang"];
|
|
10348
|
+
if (lang) {
|
|
10349
|
+
await Promise.all(Object.keys(lang).map((key) => resolve_one_file_list(lang, key)));
|
|
10350
|
+
if (Object.keys(lang).length === 0)
|
|
10351
|
+
delete qualifier["lang"];
|
|
10317
10352
|
}
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
await resolve_one_file_list(qualifier, "sourcePath");
|
|
10321
|
-
await resolve_one_file_list(qualifier, "resourcePath");
|
|
10322
|
-
await resolve_one_file_list(qualifier, "barrelPath");
|
|
10323
|
-
const lang = qualifier["lang"];
|
|
10324
|
-
if (lang) {
|
|
10325
|
-
await Promise.all(
|
|
10326
|
-
Object.keys(lang).map((key) => resolve_one_file_list(lang, key))
|
|
10327
|
-
);
|
|
10328
|
-
if (Object.keys(lang).length === 0) delete qualifier["lang"];
|
|
10329
|
-
} else {
|
|
10330
|
-
delete qualifier["lang"];
|
|
10331
|
-
}
|
|
10332
|
-
|
|
10333
|
-
const resolve_literal_list = (base, name) => {
|
|
10334
|
-
const literals = base[name];
|
|
10335
|
-
if (!literals || !literals.length) return;
|
|
10336
|
-
base[name] = literals.map((v) => v.value);
|
|
10337
|
-
};
|
|
10338
|
-
resolve_literal_list(qualifier, "excludeAnnotations");
|
|
10339
|
-
// turn the annotations inside out.
|
|
10340
|
-
// in the jungle we have
|
|
10341
|
-
// qualifier.BarrelName.annotations = Foo;Bar
|
|
10342
|
-
// but its more convenient as
|
|
10343
|
-
// qualifier.annotations.BarrelName = Foo;Bar
|
|
10344
|
-
const annotations = {};
|
|
10345
|
-
Object.entries(qualifier).forEach(([k, v]) => {
|
|
10346
|
-
if ((0,external_api_cjs_namespaceObject.hasProperty)(v, "annotations")) {
|
|
10347
|
-
annotations[k] = v.annotations;
|
|
10348
|
-
resolve_literal_list(annotations, k);
|
|
10349
|
-
delete qualifier[k];
|
|
10353
|
+
else {
|
|
10354
|
+
delete qualifier["lang"];
|
|
10350
10355
|
}
|
|
10351
|
-
|
|
10352
|
-
|
|
10356
|
+
const resolve_literal_list = (base, name) => {
|
|
10357
|
+
const literals = base[name];
|
|
10358
|
+
if (!literals || !literals.length)
|
|
10359
|
+
return;
|
|
10360
|
+
base[name] = literals.map((v) => v.value);
|
|
10361
|
+
};
|
|
10362
|
+
resolve_literal_list(qualifier, "excludeAnnotations");
|
|
10363
|
+
// turn the annotations inside out.
|
|
10364
|
+
// in the jungle we have
|
|
10365
|
+
// qualifier.BarrelName.annotations = Foo;Bar
|
|
10366
|
+
// but its more convenient as
|
|
10367
|
+
// qualifier.annotations.BarrelName = Foo;Bar
|
|
10368
|
+
const annotations = {};
|
|
10369
|
+
Object.entries(qualifier).forEach(([k, v]) => {
|
|
10370
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(v, "annotations")) {
|
|
10371
|
+
annotations[k] = v["annotations"];
|
|
10372
|
+
resolve_literal_list(annotations, k);
|
|
10373
|
+
delete qualifier[k];
|
|
10374
|
+
}
|
|
10375
|
+
});
|
|
10376
|
+
qualifier.annotations = annotations;
|
|
10377
|
+
return qualifier;
|
|
10353
10378
|
}
|
|
10354
|
-
|
|
10355
10379
|
async function find_build_instructions_in_resource(file) {
|
|
10356
|
-
|
|
10357
|
-
|
|
10358
|
-
|
|
10380
|
+
const data = await promises_namespaceObject.readFile(file);
|
|
10381
|
+
const rez = await (0,xml2js.parseStringPromise)(data).catch(() => ({}));
|
|
10382
|
+
if (!rez.build || !rez.build.exclude)
|
|
10383
|
+
return null;
|
|
10359
10384
|
const dir = external_path_.dirname(file);
|
|
10360
10385
|
const sourceExcludes = rez.build.exclude
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
|
|
10364
|
-
|
|
10386
|
+
.map((e) => e.$.file)
|
|
10387
|
+
.filter((f) => f != null)
|
|
10388
|
+
.map((f) => external_path_.resolve(dir, f).replace(/\\/g, "/"));
|
|
10365
10389
|
const filePatterns = rez.build.exclude
|
|
10366
|
-
|
|
10367
|
-
|
|
10368
|
-
|
|
10390
|
+
.map((e) => e.$.dir)
|
|
10391
|
+
.filter((f) => f != null)
|
|
10392
|
+
.map((f) => external_path_.join(dir, f, "**", "*.mc").replace(/\\/g, "/"));
|
|
10369
10393
|
if (filePatterns.length) {
|
|
10370
|
-
|
|
10371
|
-
|
|
10372
|
-
).flat();
|
|
10373
|
-
sourceExcludes.push(...files);
|
|
10394
|
+
const files = (await Promise.all(filePatterns.map((p) => (0,external_util_cjs_namespaceObject.globa)(p)))).flat();
|
|
10395
|
+
sourceExcludes.push(...files);
|
|
10374
10396
|
}
|
|
10375
10397
|
const excludeAnnotations = rez.build.exclude
|
|
10376
|
-
|
|
10377
|
-
|
|
10398
|
+
.map((e) => e.$.annotation)
|
|
10399
|
+
.filter((f) => f != null);
|
|
10378
10400
|
return { sourceExcludes, excludeAnnotations };
|
|
10379
|
-
}
|
|
10380
10401
|
}
|
|
10381
10402
|
async function find_build_instructions(targets) {
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10398
|
-
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
|
|
10402
|
-
|
|
10403
|
-
|
|
10404
|
-
|
|
10405
|
-
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10409
|
-
|
|
10410
|
-
|
|
10411
|
-
.
|
|
10412
|
-
|
|
10413
|
-
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
|
|
10417
|
-
|
|
10418
|
-
|
|
10419
|
-
});
|
|
10420
|
-
if (sourceExcludes.length) {
|
|
10421
|
-
p.qualifier.sourceExcludes = sourceExcludes;
|
|
10422
|
-
}
|
|
10423
|
-
if (excludeAnnotations.length) {
|
|
10424
|
-
if (p.qualifier.excludeAnnotations) {
|
|
10425
|
-
p.qualifier.excludeAnnotations.push(excludeAnnotations);
|
|
10426
|
-
} else {
|
|
10427
|
-
p.qualifier.excludeAnnotations = excludeAnnotations;
|
|
10428
|
-
}
|
|
10403
|
+
const resourceGroups = {};
|
|
10404
|
+
await Promise.all(targets.map(async (p) => {
|
|
10405
|
+
if (!p.qualifier.resourcePath)
|
|
10406
|
+
return;
|
|
10407
|
+
const key = p.qualifier.resourcePath.join(";");
|
|
10408
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(resourceGroups, key)) {
|
|
10409
|
+
resourceGroups[key] = {
|
|
10410
|
+
resourcePath: p.qualifier.resourcePath,
|
|
10411
|
+
products: [],
|
|
10412
|
+
};
|
|
10413
|
+
const paths = (await Promise.all(p.qualifier.resourcePath.map((pattern) => (0,external_util_cjs_namespaceObject.globa)(pattern, { mark: true })))).flat();
|
|
10414
|
+
const sourceExcludes = [];
|
|
10415
|
+
const excludeAnnotations = [];
|
|
10416
|
+
const resourceFiles = await Promise.all(paths.map((path) => path.endsWith("/") ? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.xml`, { mark: true }) : path));
|
|
10417
|
+
const buildInstructions = await Promise.all(resourceFiles
|
|
10418
|
+
.flat()
|
|
10419
|
+
.filter((file) => !file.endsWith("/"))
|
|
10420
|
+
.map((file) => find_build_instructions_in_resource(file)));
|
|
10421
|
+
buildInstructions
|
|
10422
|
+
.filter((i) => i != null)
|
|
10423
|
+
.map((i) => {
|
|
10424
|
+
if (i.sourceExcludes)
|
|
10425
|
+
sourceExcludes.push(...i.sourceExcludes);
|
|
10426
|
+
if (i.excludeAnnotations)
|
|
10427
|
+
excludeAnnotations.push(...i.excludeAnnotations);
|
|
10428
|
+
});
|
|
10429
|
+
if (sourceExcludes.length) {
|
|
10430
|
+
p.qualifier.sourceExcludes = sourceExcludes;
|
|
10431
|
+
}
|
|
10432
|
+
if (excludeAnnotations.length) {
|
|
10433
|
+
if (p.qualifier.excludeAnnotations) {
|
|
10434
|
+
p.qualifier.excludeAnnotations.push(...excludeAnnotations);
|
|
10435
|
+
}
|
|
10436
|
+
else {
|
|
10437
|
+
p.qualifier.excludeAnnotations = excludeAnnotations;
|
|
10438
|
+
}
|
|
10439
|
+
}
|
|
10429
10440
|
}
|
|
10430
|
-
|
|
10431
|
-
|
|
10432
|
-
})
|
|
10433
|
-
);
|
|
10441
|
+
resourceGroups[key].products.push(p.product);
|
|
10442
|
+
}));
|
|
10434
10443
|
}
|
|
10435
|
-
|
|
10436
10444
|
function identify_optimizer_groups(targets, options) {
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
|
|
10441
|
-
|
|
10442
|
-
|
|
10443
|
-
|
|
10444
|
-
|
|
10445
|
-
|
|
10446
|
-
|
|
10447
|
-
|
|
10448
|
-
|
|
10449
|
-
|
|
10450
|
-
|
|
10451
|
-
|
|
10452
|
-
|
|
10453
|
-
|
|
10454
|
-
|
|
10455
|
-
|
|
10456
|
-
|
|
10457
|
-
|
|
10458
|
-
|
|
10459
|
-
|
|
10460
|
-
|
|
10461
|
-
|
|
10462
|
-
options.ignoredExcludeAnnotations
|
|
10463
|
-
|
|
10464
|
-
|
|
10465
|
-
|
|
10466
|
-
|
|
10467
|
-
|
|
10468
|
-
|
|
10469
|
-
|
|
10470
|
-
|
|
10471
|
-
|
|
10472
|
-
|
|
10473
|
-
|
|
10474
|
-
|
|
10475
|
-
|
|
10476
|
-
|
|
10477
|
-
|
|
10478
|
-
|
|
10445
|
+
const groups = {};
|
|
10446
|
+
let key = 0;
|
|
10447
|
+
const ignoreStrOption = (str) => str == null
|
|
10448
|
+
? null
|
|
10449
|
+
: str === "*"
|
|
10450
|
+
? "*"
|
|
10451
|
+
: Object.fromEntries(str.split(";").map((e) => [e, true]));
|
|
10452
|
+
const getStrsWithIgnore = (strs, option) => {
|
|
10453
|
+
if (option === "*") {
|
|
10454
|
+
return [];
|
|
10455
|
+
}
|
|
10456
|
+
else {
|
|
10457
|
+
return strs.filter((a) => !(0,external_api_cjs_namespaceObject.hasProperty)(option, a));
|
|
10458
|
+
}
|
|
10459
|
+
};
|
|
10460
|
+
const ignoreRegExpOption = (str) => {
|
|
10461
|
+
try {
|
|
10462
|
+
if (!str)
|
|
10463
|
+
return null;
|
|
10464
|
+
return new RegExp(str);
|
|
10465
|
+
}
|
|
10466
|
+
catch {
|
|
10467
|
+
return null;
|
|
10468
|
+
}
|
|
10469
|
+
};
|
|
10470
|
+
const ignoredExcludeAnnotations = ignoreStrOption(options.ignoredExcludeAnnotations);
|
|
10471
|
+
const ignoredAnnotations = ignoreStrOption(options.ignoredAnnotations);
|
|
10472
|
+
const ignoredSourcePathsRe = ignoreRegExpOption(options.ignoredSourcePaths);
|
|
10473
|
+
const ignoredSourcePaths = ignoredSourcePathsRe
|
|
10474
|
+
? targets.reduce((state, target) => {
|
|
10475
|
+
if (target.qualifier.sourcePath) {
|
|
10476
|
+
target.qualifier.sourcePath.forEach((path) => {
|
|
10477
|
+
const m = path.match(ignoredSourcePathsRe);
|
|
10478
|
+
const key = m ? "key-" + m.slice(1).join("") : path;
|
|
10479
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.keys, key)) {
|
|
10480
|
+
state.keys[key] = {};
|
|
10481
|
+
}
|
|
10482
|
+
state.keys[key][path] = true;
|
|
10483
|
+
state.paths[path] = state.keys[key];
|
|
10484
|
+
});
|
|
10485
|
+
}
|
|
10486
|
+
return state;
|
|
10487
|
+
}, { keys: {}, paths: {} }).paths
|
|
10488
|
+
: null;
|
|
10489
|
+
targets.forEach((target) => {
|
|
10490
|
+
let { sourcePath, sourceExcludes, barrelPath, barrelMap, excludeAnnotations, annotations, } = target.qualifier;
|
|
10491
|
+
if (excludeAnnotations && ignoredExcludeAnnotations) {
|
|
10492
|
+
excludeAnnotations = getStrsWithIgnore(excludeAnnotations, ignoredExcludeAnnotations);
|
|
10493
|
+
}
|
|
10494
|
+
annotations &&
|
|
10495
|
+
Object.entries(annotations).forEach(([key, value]) => {
|
|
10496
|
+
if (ignoredAnnotations) {
|
|
10497
|
+
annotations[key] = getStrsWithIgnore(value, ignoredAnnotations);
|
|
10498
|
+
}
|
|
10479
10499
|
});
|
|
10480
|
-
|
|
10481
|
-
|
|
10482
|
-
|
|
10483
|
-
|
|
10484
|
-
|
|
10485
|
-
|
|
10486
|
-
|
|
10487
|
-
|
|
10488
|
-
|
|
10489
|
-
|
|
10490
|
-
|
|
10491
|
-
|
|
10492
|
-
|
|
10493
|
-
|
|
10494
|
-
|
|
10495
|
-
|
|
10496
|
-
|
|
10497
|
-
|
|
10498
|
-
|
|
10499
|
-
|
|
10500
|
-
|
|
10501
|
-
|
|
10502
|
-
|
|
10503
|
-
|
|
10504
|
-
|
|
10505
|
-
|
|
10500
|
+
if (ignoredSourcePaths) {
|
|
10501
|
+
sourcePath = sourcePath
|
|
10502
|
+
?.map((path) => Object.keys(ignoredSourcePaths[path]))
|
|
10503
|
+
.flat()
|
|
10504
|
+
.sort()
|
|
10505
|
+
.filter((v, i, a) => i === 0 || v !== a[i - 1]);
|
|
10506
|
+
}
|
|
10507
|
+
const optimizerConfig = {
|
|
10508
|
+
sourcePath,
|
|
10509
|
+
sourceExcludes,
|
|
10510
|
+
barrelPath,
|
|
10511
|
+
barrelMap,
|
|
10512
|
+
excludeAnnotations,
|
|
10513
|
+
annotations,
|
|
10514
|
+
};
|
|
10515
|
+
const toSortedEntries = (value) => Object.entries(value)
|
|
10516
|
+
.filter(([, v]) => v != null)
|
|
10517
|
+
.sort((a, b) => (a[0] < b[0] ? -1 : a[0] === b[0] ? 0 : 1));
|
|
10518
|
+
const serialized = JSON.stringify(optimizerConfig, function (key, value) {
|
|
10519
|
+
if (!value || Array.isArray(value) || typeof value !== "object") {
|
|
10520
|
+
return value;
|
|
10521
|
+
}
|
|
10522
|
+
if (key === "" && barrelMap) {
|
|
10523
|
+
const bm = toSortedEntries(barrelMap).map(([k, v]) => {
|
|
10524
|
+
const { jungles, qualifier } = v;
|
|
10525
|
+
return [k, [jungles, qualifier]];
|
|
10526
|
+
});
|
|
10527
|
+
value = { ...value, barrelMap: bm };
|
|
10528
|
+
}
|
|
10529
|
+
return toSortedEntries(value);
|
|
10530
|
+
});
|
|
10531
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(groups, serialized)) {
|
|
10532
|
+
groups[serialized] = {
|
|
10533
|
+
key: "group" + key.toString().padStart(3, "0"),
|
|
10534
|
+
optimizerConfig,
|
|
10535
|
+
};
|
|
10536
|
+
key++;
|
|
10537
|
+
}
|
|
10538
|
+
target.group = groups[serialized];
|
|
10506
10539
|
});
|
|
10507
|
-
if (ignoredSourcePaths) {
|
|
10508
|
-
sourcePath = sourcePath
|
|
10509
|
-
.map((path) => Object.keys(ignoredSourcePaths[path]))
|
|
10510
|
-
.flat()
|
|
10511
|
-
.sort()
|
|
10512
|
-
.filter((v, i, a) => i === 0 || v !== a[i - 1]);
|
|
10513
|
-
}
|
|
10514
|
-
const optimizerConfig = {
|
|
10515
|
-
sourcePath,
|
|
10516
|
-
sourceExcludes,
|
|
10517
|
-
barrelPath,
|
|
10518
|
-
barrelMap,
|
|
10519
|
-
excludeAnnotations,
|
|
10520
|
-
annotations,
|
|
10521
|
-
};
|
|
10522
|
-
|
|
10523
|
-
const serialized = JSON.stringify(
|
|
10524
|
-
optimizerConfig,
|
|
10525
|
-
Object.keys(optimizerConfig).sort()
|
|
10526
|
-
);
|
|
10527
|
-
if (!(0,external_api_cjs_namespaceObject.hasProperty)(groups, serialized)) {
|
|
10528
|
-
groups[serialized] = {
|
|
10529
|
-
key: "group" + key.toString().padStart(3, "0"),
|
|
10530
|
-
optimizerConfig,
|
|
10531
|
-
};
|
|
10532
|
-
key++;
|
|
10533
|
-
}
|
|
10534
|
-
target.group = groups[serialized];
|
|
10535
|
-
});
|
|
10536
10540
|
}
|
|
10537
|
-
|
|
10538
10541
|
/**
|
|
10539
10542
|
* Find the barrels referred to by barrelPath.
|
|
10540
10543
|
*
|
|
@@ -10547,65 +10550,21 @@ function identify_optimizer_groups(targets, options) {
|
|
|
10547
10550
|
* @returns {Promise<string[]>}
|
|
10548
10551
|
*/
|
|
10549
10552
|
function find_barrels(barrelPath) {
|
|
10550
|
-
|
|
10551
|
-
|
|
10552
|
-
|
|
10553
|
-
|
|
10554
|
-
|
|
10555
|
-
|
|
10556
|
-
|
|
10557
|
-
|
|
10558
|
-
|
|
10559
|
-
|
|
10560
|
-
|
|
10561
|
-
|
|
10562
|
-
.then((paths) =>
|
|
10563
|
-
Promise.all(
|
|
10564
|
-
paths.map((path) =>
|
|
10565
|
-
path.endsWith("/") ? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.barrel`) : path
|
|
10566
|
-
)
|
|
10567
|
-
)
|
|
10568
|
-
)
|
|
10569
|
-
.then((barrelPaths) =>
|
|
10570
|
-
barrelPaths
|
|
10553
|
+
if (Array.isArray(barrelPath)) {
|
|
10554
|
+
// This is a sublist. The barrel has more than one jungle file.
|
|
10555
|
+
return Promise.all(barrelPath.map((path) => (0,external_util_cjs_namespaceObject.globa)(path, { mark: true }))).then((paths) => [
|
|
10556
|
+
paths
|
|
10557
|
+
.flat()
|
|
10558
|
+
.filter((path) => path.endsWith(".jungle"))
|
|
10559
|
+
.join(";"),
|
|
10560
|
+
]);
|
|
10561
|
+
}
|
|
10562
|
+
return (0,external_util_cjs_namespaceObject.globa)(barrelPath, { mark: true })
|
|
10563
|
+
.then((paths) => Promise.all(paths.map((path) => path.endsWith("/") ? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.barrel`) : path)))
|
|
10564
|
+
.then((barrelPaths) => barrelPaths
|
|
10571
10565
|
.flat()
|
|
10572
|
-
.filter((path) => path.endsWith(".jungle") || path.endsWith(".barrel"))
|
|
10573
|
-
);
|
|
10566
|
+
.filter((path) => path.endsWith(".jungle") || path.endsWith(".barrel")));
|
|
10574
10567
|
}
|
|
10575
|
-
|
|
10576
|
-
/**
|
|
10577
|
-
*@typedef {Object} Target - Build instructions for a particular product in a jungle
|
|
10578
|
-
*
|
|
10579
|
-
* @typedef {Object} JungleInfoBase - The result of parsing a jungle file, without resolving any products
|
|
10580
|
-
* @property {string[]} jungles - Paths to the barrel's jungle files
|
|
10581
|
-
* @property {string} manifest - Path to the barrel's manifest file
|
|
10582
|
-
* @property {Object} xml - The xml content of the manifest, as returned by xml2js
|
|
10583
|
-
* @property {string[]=} annotations - Array of annotations supported by this barrel
|
|
10584
|
-
*
|
|
10585
|
-
* @typedef {Object} PartialJungle - Used to extend JungleInfoBase to ResolvedJungle
|
|
10586
|
-
* @property {Target[]} targets - All of the supported targets in the manifest
|
|
10587
|
-
*
|
|
10588
|
-
* @typedef {Object} PartialBarrel - Used to extend JungleInfoBase to ResolvedBarrel
|
|
10589
|
-
* @property {JungleQualifier} qualifier - the qualifier for this PartialBarrel's target
|
|
10590
|
-
*
|
|
10591
|
-
* @typedef {JungleInfoBase & PartialJungle} ResolvedJungle - The result of parsing an application's jungle file
|
|
10592
|
-
* @typedef {JungleInfoBase & PartialBarrel} ResolvedBarrel - The result of parsing a barrel's jungle file for a particular product
|
|
10593
|
-
*
|
|
10594
|
-
* @typedef {Object} JungleQualifier
|
|
10595
|
-
* @property {string[]=} sourcePath - locations to find source file
|
|
10596
|
-
* @property {string[]=} sourceExcludes - array of files to exclude from the build (from resource build instructions)
|
|
10597
|
-
* @property {string[]=} excludeAnnotations - array of excludeAnnotations
|
|
10598
|
-
* @property {string[]=} resourcePath - locations to find resource files
|
|
10599
|
-
* @property {LangResourcePaths} lang - locations to find resource files
|
|
10600
|
-
* @property {(string|string[])[]=} barrelPath - locations to find barrels
|
|
10601
|
-
* @property {BarrelAnnotations=} annotations - map from barrel names to arrays of annotations
|
|
10602
|
-
* @property {BarrelMap=} barrelMap
|
|
10603
|
-
*
|
|
10604
|
-
* @typedef {{[key:string]:string[]}} LangResourcePaths - Map from language codes to the corresponding resource paths
|
|
10605
|
-
* @typedef {{[key:string]:string[]}} BarrelAnnotations - Map from barrel name to imported annotations
|
|
10606
|
-
* @typedef {{[key:string]:ResolvedBarrel}} BarrelMap - Map from barrel name to the set of resolved barrel projects for that name. Note that they must all share a manifest.
|
|
10607
|
-
*/
|
|
10608
|
-
|
|
10609
10568
|
/**
|
|
10610
10569
|
* Given a .barrel file, unpack it into barrelDir, then process its .jungle file as below
|
|
10611
10570
|
* Given a .jungle file, resolve it to a ResolvedJungle
|
|
@@ -10613,53 +10572,43 @@ function find_barrels(barrelPath) {
|
|
|
10613
10572
|
* @param {string} barrel Path to a .jungle or .barrel file to resolve
|
|
10614
10573
|
* @param {string} barrelDir Directory where .barrel files should be unpacked
|
|
10615
10574
|
* @param {string[]} products The products supported by the importing project
|
|
10616
|
-
* @param {
|
|
10575
|
+
* @param {BuildConfig} options
|
|
10617
10576
|
* @returns {Promise<ResolvedJungle>}
|
|
10618
10577
|
*/
|
|
10619
10578
|
function resolve_barrel(barrel, barrelDir, products, options) {
|
|
10620
|
-
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
|
|
10624
|
-
|
|
10625
|
-
|
|
10626
|
-
|
|
10627
|
-
|
|
10628
|
-
|
|
10629
|
-
|
|
10630
|
-
|
|
10631
|
-
|
|
10632
|
-
|
|
10633
|
-
|
|
10634
|
-
|
|
10635
|
-
|
|
10636
|
-
|
|
10637
|
-
rawBarrel = external_path_.resolve(localPath, "barrel.jungle");
|
|
10638
|
-
promise = promise.then(() =>
|
|
10639
|
-
promises_namespaceObject.stat(localPath)
|
|
10640
|
-
.then(
|
|
10641
|
-
(localStat) =>
|
|
10642
|
-
!localStat.isDirectory() ||
|
|
10579
|
+
const cache = options._cache;
|
|
10580
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(cache.barrels, barrel)) {
|
|
10581
|
+
return cache.barrels[barrel];
|
|
10582
|
+
}
|
|
10583
|
+
let promise = Promise.resolve();
|
|
10584
|
+
let rawBarrel = barrel;
|
|
10585
|
+
if (barrel.endsWith(".barrel")) {
|
|
10586
|
+
// A barrel with the given name could in theory resolve to a different physical
|
|
10587
|
+
// barrel file for each product, so uniqify the local name with a sha1.
|
|
10588
|
+
const sha1 = external_crypto_namespaceObject.createHash("sha1")
|
|
10589
|
+
.update(barrel, "binary")
|
|
10590
|
+
.digest("base64")
|
|
10591
|
+
.replace(/[\/=+]/g, "");
|
|
10592
|
+
const localPath = external_path_.resolve(barrelDir, `${external_path_.basename(barrel, ".barrel")}-${sha1}`);
|
|
10593
|
+
rawBarrel = external_path_.resolve(localPath, "barrel.jungle");
|
|
10594
|
+
promise = promise.then(() => promises_namespaceObject.stat(localPath)
|
|
10595
|
+
.then((localStat) => !localStat.isDirectory() ||
|
|
10643
10596
|
promises_namespaceObject.stat(barrel)
|
|
10644
|
-
|
|
10645
|
-
|
|
10646
|
-
)
|
|
10647
|
-
.then(
|
|
10648
|
-
(needsUpdate) =>
|
|
10597
|
+
.then((barrelStat) => localStat.mtimeMs < barrelStat.mtimeMs), () => true)
|
|
10598
|
+
.then((needsUpdate) => {
|
|
10649
10599
|
needsUpdate &&
|
|
10650
|
-
|
|
10651
|
-
|
|
10652
|
-
)
|
|
10653
|
-
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10600
|
+
promises_namespaceObject.rm(localPath, { recursive: true, force: true })
|
|
10601
|
+
.then(() => extract_zip(barrel, { dir: localPath }));
|
|
10602
|
+
}));
|
|
10603
|
+
}
|
|
10604
|
+
return promise
|
|
10605
|
+
.then(() => get_jungle_and_barrels(rawBarrel, products, options))
|
|
10606
|
+
.then((result) => {
|
|
10607
|
+
if (!cache.barrels)
|
|
10608
|
+
cache.barrels = {};
|
|
10609
|
+
return (cache.barrels[barrel] = { ...result });
|
|
10660
10610
|
});
|
|
10661
10611
|
}
|
|
10662
|
-
|
|
10663
10612
|
/**
|
|
10664
10613
|
* Find and resolve the BarrelMap for product, and add it to qualifier.
|
|
10665
10614
|
*
|
|
@@ -10667,944 +10616,975 @@ function resolve_barrel(barrel, barrelDir, products, options) {
|
|
|
10667
10616
|
* @param {JungleQualifier} qualifier The qualifier for product from the main jungle
|
|
10668
10617
|
* @param {string[]} barrels The barrels imported by the project's manifest
|
|
10669
10618
|
* @param {string[]} products The products supported by the importing project (used when the barrel project has none)
|
|
10670
|
-
* @param {
|
|
10619
|
+
* @param {BuildConfig} options
|
|
10671
10620
|
* @returns {Promise<void>}
|
|
10672
10621
|
*/
|
|
10673
10622
|
function resolve_barrels(product, qualifier, barrels, products, options) {
|
|
10674
|
-
|
|
10675
|
-
|
|
10676
|
-
|
|
10677
|
-
|
|
10678
|
-
|
|
10679
|
-
|
|
10680
|
-
|
|
10681
|
-
|
|
10682
|
-
|
|
10683
|
-
|
|
10684
|
-
|
|
10685
|
-
|
|
10686
|
-
|
|
10687
|
-
|
|
10688
|
-
|
|
10689
|
-
|
|
10690
|
-
|
|
10691
|
-
|
|
10692
|
-
|
|
10693
|
-
|
|
10694
|
-
|
|
10695
|
-
|
|
10696
|
-
|
|
10697
|
-
|
|
10698
|
-
|
|
10699
|
-
|
|
10700
|
-
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
|
|
10704
|
-
|
|
10705
|
-
|
|
10706
|
-
|
|
10707
|
-
|
|
10708
|
-
|
|
10709
|
-
|
|
10710
|
-
|
|
10711
|
-
|
|
10712
|
-
|
|
10713
|
-
|
|
10714
|
-
|
|
10715
|
-
|
|
10716
|
-
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
)
|
|
10720
|
-
);
|
|
10721
|
-
})
|
|
10722
|
-
.then((resolvedBarrels) => {
|
|
10723
|
-
resolvedBarrels.forEach((resolvedBarrel) => {
|
|
10724
|
-
const name = manifestBarrelName(
|
|
10725
|
-
resolvedBarrel.manifest,
|
|
10726
|
-
resolvedBarrel.xml
|
|
10727
|
-
);
|
|
10728
|
-
if (!(0,external_api_cjs_namespaceObject.hasProperty)(barrelMap, name)) return;
|
|
10729
|
-
if (barrelMap[name]) {
|
|
10623
|
+
if (qualifier.annotations) {
|
|
10624
|
+
Object.keys(qualifier.annotations).forEach((key) => {
|
|
10625
|
+
// delete annotations for non-existent barrels such as
|
|
10626
|
+
if (!barrels.includes(key)) {
|
|
10627
|
+
delete qualifier.annotations[key];
|
|
10628
|
+
}
|
|
10629
|
+
});
|
|
10630
|
+
}
|
|
10631
|
+
if (!barrels.length) {
|
|
10632
|
+
delete qualifier.barrelPath;
|
|
10633
|
+
return null;
|
|
10634
|
+
}
|
|
10635
|
+
const cache = options._cache || (options._cache = {});
|
|
10636
|
+
const barrelMapKey = JSON.stringify([barrels, qualifier.barrelPath]);
|
|
10637
|
+
const setBarrelMap = (barrelMap) => {
|
|
10638
|
+
qualifier.barrelMap = barrels.reduce((result, barrel) => {
|
|
10639
|
+
const { targets, ...rest } = barrelMap[barrel];
|
|
10640
|
+
const target = targets.find((t) => t.product === product);
|
|
10641
|
+
if (!target) {
|
|
10642
|
+
throw new Error(`Barrel ${barrel} does not support device ${product}`);
|
|
10643
|
+
}
|
|
10644
|
+
const resolvedBarrel = { qualifier: target.qualifier, ...rest };
|
|
10645
|
+
result[barrel] = resolvedBarrel;
|
|
10646
|
+
return result;
|
|
10647
|
+
}, {});
|
|
10648
|
+
};
|
|
10649
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(cache.barrelMap, barrelMapKey)) {
|
|
10650
|
+
setBarrelMap(cache.barrelMap[barrelMapKey]);
|
|
10651
|
+
return null;
|
|
10652
|
+
}
|
|
10653
|
+
const barrelDir = external_path_.resolve(options.workspace, options.outputPath, "raw-barrels");
|
|
10654
|
+
const barrelMap = Object.fromEntries(barrels.map((b) => [b, null]));
|
|
10655
|
+
return (qualifier.barrelPath || [])
|
|
10656
|
+
.reduce((promise, barrelPath) => promise
|
|
10657
|
+
.then(() => find_barrels(barrelPath))
|
|
10658
|
+
.then((barrelPaths) => {
|
|
10659
|
+
return Promise.all(barrelPaths.map((barrel) => resolve_barrel(barrel, barrelDir, products, options)));
|
|
10660
|
+
})
|
|
10661
|
+
.then((resolvedBarrels) => {
|
|
10662
|
+
resolvedBarrels.forEach((resolvedBarrel) => {
|
|
10663
|
+
const name = manifestBarrelName(resolvedBarrel.manifest, resolvedBarrel.xml);
|
|
10664
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(barrelMap, name))
|
|
10665
|
+
return;
|
|
10666
|
+
const bmapName = barrelMap[name];
|
|
10667
|
+
if (bmapName) {
|
|
10730
10668
|
const bname = (r) => r.jungles.join(";");
|
|
10731
|
-
throw new Error(
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
|
|
10735
|
-
|
|
10736
|
-
|
|
10737
|
-
|
|
10738
|
-
|
|
10739
|
-
|
|
10740
|
-
|
|
10741
|
-
|
|
10742
|
-
|
|
10743
|
-
|
|
10744
|
-
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
|
|
10748
|
-
.join(",")}`
|
|
10749
|
-
);
|
|
10750
|
-
}
|
|
10751
|
-
if (!cache.barrelMap) cache.barrelMap = {};
|
|
10752
|
-
cache.barrelMap[barrelMapKey] = barrelMap;
|
|
10753
|
-
setBarrelMap(barrelMap);
|
|
10669
|
+
throw new Error(`Barrel ${name} already resolved to ${bname(bmapName)}; can't also resolve to ${bname(resolvedBarrel)}`);
|
|
10670
|
+
}
|
|
10671
|
+
barrelMap[name] = resolvedBarrel;
|
|
10672
|
+
});
|
|
10673
|
+
}), Promise.resolve())
|
|
10674
|
+
.then(() => {
|
|
10675
|
+
const unresolved = Object.entries(barrelMap).filter((v) => v[1] === null);
|
|
10676
|
+
if (unresolved.length) {
|
|
10677
|
+
throw new Error(`Failed to resolve some barrels: ${unresolved
|
|
10678
|
+
.map(([name]) => name)
|
|
10679
|
+
.join(",")}`);
|
|
10680
|
+
}
|
|
10681
|
+
const finalMap = barrelMap;
|
|
10682
|
+
if (!cache.barrelMap)
|
|
10683
|
+
cache.barrelMap = {};
|
|
10684
|
+
cache.barrelMap[barrelMapKey] = finalMap;
|
|
10685
|
+
setBarrelMap(finalMap);
|
|
10754
10686
|
});
|
|
10755
10687
|
}
|
|
10756
10688
|
/**
|
|
10757
10689
|
*
|
|
10758
10690
|
* @param {string} jungleFiles Semicolon separated list of jungle files
|
|
10759
10691
|
* @param {string[]} defaultProducts Default set of products. Only used by a barrel with no products of its own
|
|
10760
|
-
* @param {
|
|
10692
|
+
* @param {BuildConfig} options
|
|
10761
10693
|
* @returns {Promise<ResolvedJungle>}
|
|
10762
10694
|
*/
|
|
10763
10695
|
async function get_jungle_and_barrels(jungleFiles, defaultProducts, options) {
|
|
10764
|
-
|
|
10765
|
-
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
|
|
10777
|
-
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
|
|
10783
|
-
|
|
10784
|
-
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
|
|
10793
|
-
|
|
10794
|
-
|
|
10795
|
-
|
|
10796
|
-
|
|
10797
|
-
|
|
10798
|
-
|
|
10799
|
-
|
|
10800
|
-
|
|
10801
|
-
|
|
10802
|
-
|
|
10803
|
-
|
|
10804
|
-
|
|
10805
|
-
|
|
10806
|
-
|
|
10807
|
-
|
|
10808
|
-
|
|
10809
|
-
|
|
10810
|
-
|
|
10811
|
-
|
|
10812
|
-
|
|
10813
|
-
|
|
10814
|
-
|
|
10815
|
-
|
|
10816
|
-
|
|
10817
|
-
|
|
10818
|
-
|
|
10819
|
-
|
|
10820
|
-
|
|
10821
|
-
await find_build_instructions(targets);
|
|
10822
|
-
return { manifest, targets, xml, annotations, jungles };
|
|
10696
|
+
const jungles = jungleFiles
|
|
10697
|
+
.split(";")
|
|
10698
|
+
.map((jungle) => external_path_.resolve(options.workspace || "./", jungle));
|
|
10699
|
+
const barrels_jungle = external_path_.resolve(external_path_.dirname(jungles[0]), "barrels.jungle");
|
|
10700
|
+
if (!jungles.includes(barrels_jungle)) {
|
|
10701
|
+
if (await promises_namespaceObject.stat(barrels_jungle)
|
|
10702
|
+
.then((s) => s.isFile())
|
|
10703
|
+
.catch(() => false)) {
|
|
10704
|
+
jungles.push(barrels_jungle);
|
|
10705
|
+
}
|
|
10706
|
+
}
|
|
10707
|
+
const state = await process_jungles(jungles);
|
|
10708
|
+
// apparently square_watch is an alias for rectangle_watch
|
|
10709
|
+
state["square_watch"] = state["rectangle_watch"];
|
|
10710
|
+
const manifest_node = resolve_node(state, resolve_node_by_path(state, ["project", "manifest"]));
|
|
10711
|
+
if (!manifest_node)
|
|
10712
|
+
throw new Error("No manifest found!");
|
|
10713
|
+
const manifest = resolve_filename(manifest_node[0]);
|
|
10714
|
+
if (!options.workspace) {
|
|
10715
|
+
options.workspace = external_path_.dirname(manifest);
|
|
10716
|
+
}
|
|
10717
|
+
const xml = await readManifest(manifest);
|
|
10718
|
+
const targets = [];
|
|
10719
|
+
const barrels = manifestBarrels(xml);
|
|
10720
|
+
const annotations = manifestAnnotations(xml);
|
|
10721
|
+
const products = manifestProducts(xml);
|
|
10722
|
+
if (products.length === 0)
|
|
10723
|
+
products.push(...defaultProducts);
|
|
10724
|
+
let promise = Promise.resolve();
|
|
10725
|
+
const add_one = (product, shape = undefined) => {
|
|
10726
|
+
const rawQualifier = resolve_node(state, state[product]);
|
|
10727
|
+
if (!rawQualifier || Array.isArray(rawQualifier))
|
|
10728
|
+
return;
|
|
10729
|
+
promise = promise
|
|
10730
|
+
.then(() => resolve_literals(rawQualifier, manifest))
|
|
10731
|
+
.then((qualifier) => {
|
|
10732
|
+
targets.push({ product, qualifier, shape });
|
|
10733
|
+
return resolve_barrels(product, qualifier, barrels, products, options);
|
|
10734
|
+
})
|
|
10735
|
+
.then(() => { });
|
|
10736
|
+
};
|
|
10737
|
+
products.forEach((product) => {
|
|
10738
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(state, product)) {
|
|
10739
|
+
const sp = state[product];
|
|
10740
|
+
if (sp && !Array.isArray(sp) && sp.products) {
|
|
10741
|
+
// this was something like round_watch. Add all the corresponding
|
|
10742
|
+
// products.
|
|
10743
|
+
sp.products.forEach((p) => add_one(p, product));
|
|
10744
|
+
}
|
|
10745
|
+
else {
|
|
10746
|
+
add_one(product);
|
|
10747
|
+
}
|
|
10748
|
+
}
|
|
10749
|
+
});
|
|
10750
|
+
await promise;
|
|
10751
|
+
await find_build_instructions(targets);
|
|
10752
|
+
return { manifest, targets, xml, annotations, jungles };
|
|
10823
10753
|
}
|
|
10824
|
-
|
|
10825
10754
|
async function get_jungle(jungles, options) {
|
|
10826
|
-
|
|
10827
|
-
|
|
10828
|
-
|
|
10829
|
-
|
|
10755
|
+
options = options || {};
|
|
10756
|
+
const result = await get_jungle_and_barrels(jungles, [], options);
|
|
10757
|
+
identify_optimizer_groups(result.targets, options);
|
|
10758
|
+
return result;
|
|
10830
10759
|
}
|
|
10831
10760
|
|
|
10832
10761
|
;// CONCATENATED MODULE: external "child_process"
|
|
10833
10762
|
const external_child_process_namespaceObject = require("child_process");
|
|
10834
|
-
;// CONCATENATED MODULE: ./src/launch.
|
|
10835
|
-
|
|
10763
|
+
;// CONCATENATED MODULE: ./src/launch.ts
|
|
10836
10764
|
|
|
10837
10765
|
|
|
10838
10766
|
|
|
10839
10767
|
|
|
10840
10768
|
function launchSimulator() {
|
|
10841
|
-
|
|
10842
|
-
|
|
10843
|
-
|
|
10844
|
-
);
|
|
10845
|
-
child.unref();
|
|
10846
|
-
});
|
|
10769
|
+
return (0,external_sdk_util_cjs_namespaceObject.getSdkPath)().then((sdk) => {
|
|
10770
|
+
const child = (0,external_child_process_namespaceObject.execFile)(external_path_.resolve(sdk, "bin", external_sdk_util_cjs_namespaceObject.isWin ? "simulator" : "connectiq"));
|
|
10771
|
+
child.unref();
|
|
10772
|
+
});
|
|
10847
10773
|
}
|
|
10848
|
-
|
|
10849
|
-
|
|
10850
|
-
|
|
10851
|
-
|
|
10852
|
-
|
|
10853
|
-
)
|
|
10854
|
-
);
|
|
10774
|
+
function simulateProgram(prg, device, test) {
|
|
10775
|
+
const args = [prg, device];
|
|
10776
|
+
if (test)
|
|
10777
|
+
args.push("-t");
|
|
10778
|
+
return (0,external_sdk_util_cjs_namespaceObject.getSdkPath)().then((sdk) => (0,external_util_cjs_namespaceObject.spawnByLine)(external_path_.resolve(sdk, "bin", "monkeydo"), args, (line) => console.log(line)).then(() => { }));
|
|
10855
10779
|
}
|
|
10856
10780
|
|
|
10857
|
-
;// CONCATENATED MODULE:
|
|
10858
|
-
const prettier_plugin_monkeyc_namespaceObject = require("@markw65/prettier-plugin-monkeyc");
|
|
10859
|
-
;// CONCATENATED MODULE: ./src/mc-rewrite.js
|
|
10860
|
-
|
|
10781
|
+
;// CONCATENATED MODULE: ./src/mc-rewrite.ts
|
|
10861
10782
|
|
|
10862
10783
|
|
|
10863
10784
|
|
|
10864
10785
|
|
|
10865
10786
|
function processImports(allImports, lookup) {
|
|
10866
|
-
|
|
10867
|
-
|
|
10868
|
-
|
|
10869
|
-
|
|
10870
|
-
|
|
10871
|
-
|
|
10872
|
-
|
|
10873
|
-
|
|
10874
|
-
|
|
10787
|
+
allImports.forEach(({ node, stack }) => {
|
|
10788
|
+
const [name, module] = lookup(node.id, ("as" in node && node.as && node.as.name) || null, stack);
|
|
10789
|
+
if (name && module) {
|
|
10790
|
+
const [parent] = stack.slice(-1);
|
|
10791
|
+
if (!parent.decls)
|
|
10792
|
+
parent.decls = {};
|
|
10793
|
+
const decls = parent.decls;
|
|
10794
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(parent.decls, name))
|
|
10795
|
+
parent.decls[name] = [];
|
|
10796
|
+
module.forEach((m) => {
|
|
10797
|
+
if ((0,external_api_cjs_namespaceObject.isStateNode)(m) && m.type == "ModuleDeclaration") {
|
|
10798
|
+
(0,external_util_cjs_namespaceObject.pushUnique)(decls[name], m);
|
|
10799
|
+
}
|
|
10800
|
+
});
|
|
10875
10801
|
}
|
|
10876
|
-
|
|
10877
|
-
}
|
|
10878
|
-
});
|
|
10802
|
+
});
|
|
10879
10803
|
}
|
|
10880
|
-
|
|
10881
10804
|
function collectClassInfo(state) {
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
|
|
10887
|
-
|
|
10888
|
-
|
|
10889
|
-
|
|
10890
|
-
}
|
|
10891
|
-
|
|
10892
|
-
|
|
10893
|
-
|
|
10894
|
-
|
|
10895
|
-
|
|
10896
|
-
|
|
10897
|
-
|
|
10898
|
-
|
|
10899
|
-
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
|
|
10805
|
+
state.allClasses.forEach((elm) => {
|
|
10806
|
+
if (elm.node.superClass) {
|
|
10807
|
+
const [, classes] = state.lookup(elm.node.superClass, null, elm.stack);
|
|
10808
|
+
const superClass = classes &&
|
|
10809
|
+
classes.filter((c) => (0,external_api_cjs_namespaceObject.isStateNode)(c) && c.type === "ClassDeclaration");
|
|
10810
|
+
// set it "true" if there is a superClass, but we can't find it.
|
|
10811
|
+
elm.superClass = superClass && superClass.length ? superClass : true;
|
|
10812
|
+
}
|
|
10813
|
+
});
|
|
10814
|
+
const markOverrides = (cls, scls) => {
|
|
10815
|
+
if (scls === true)
|
|
10816
|
+
return;
|
|
10817
|
+
scls.forEach((c) => {
|
|
10818
|
+
c.decls &&
|
|
10819
|
+
Object.values(c.decls).forEach((funcs) => {
|
|
10820
|
+
funcs.forEach((f) => {
|
|
10821
|
+
if ((0,external_api_cjs_namespaceObject.isStateNode)(f) &&
|
|
10822
|
+
f.type === "FunctionDeclaration" &&
|
|
10823
|
+
(0,external_api_cjs_namespaceObject.hasProperty)(cls.decls, f.name)) {
|
|
10824
|
+
f.node.hasOverride = true;
|
|
10825
|
+
}
|
|
10826
|
+
});
|
|
10827
|
+
});
|
|
10828
|
+
if (c.superClass)
|
|
10829
|
+
markOverrides(cls, c.superClass);
|
|
10903
10830
|
});
|
|
10904
|
-
|
|
10831
|
+
};
|
|
10832
|
+
state.allClasses.forEach((elm) => {
|
|
10833
|
+
if (elm.superClass)
|
|
10834
|
+
markOverrides(elm, elm.superClass);
|
|
10905
10835
|
});
|
|
10906
|
-
};
|
|
10907
|
-
|
|
10908
|
-
state.allClasses.forEach((elm) => {
|
|
10909
|
-
if (elm.superClass) markOverrides(elm, elm.superClass);
|
|
10910
|
-
});
|
|
10911
10836
|
}
|
|
10912
|
-
|
|
10913
|
-
|
|
10914
|
-
|
|
10915
|
-
|
|
10916
|
-
|
|
10917
|
-
|
|
10918
|
-
|
|
10919
|
-
|
|
10920
|
-
|
|
10921
|
-
if (
|
|
10922
|
-
|
|
10923
|
-
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
|
|
10927
|
-
|
|
10928
|
-
|
|
10837
|
+
function getFileSources(fnMap) {
|
|
10838
|
+
return Promise.all(Object.entries(fnMap).map(([name, value]) => {
|
|
10839
|
+
return (value.monkeyCSource ||
|
|
10840
|
+
promises_namespaceObject.readFile(name)
|
|
10841
|
+
.then((data) => (value.monkeyCSource = data.toString().replace(/\r\n/g, "\n"))));
|
|
10842
|
+
})).then(() => { });
|
|
10843
|
+
}
|
|
10844
|
+
function getFileASTs(fnMap) {
|
|
10845
|
+
return getFileSources(fnMap).then(() => Object.entries(fnMap).reduce((ok, [name, value]) => {
|
|
10846
|
+
if (!value.ast) {
|
|
10847
|
+
try {
|
|
10848
|
+
value.ast = prettier_plugin_monkeyc_default().parsers.monkeyc.parse(value.monkeyCSource, null, {
|
|
10849
|
+
filepath: name,
|
|
10850
|
+
});
|
|
10851
|
+
}
|
|
10852
|
+
catch (e) {
|
|
10853
|
+
ok = false;
|
|
10854
|
+
if (e instanceof Error) {
|
|
10855
|
+
value.parserError = e;
|
|
10856
|
+
}
|
|
10857
|
+
else {
|
|
10858
|
+
value.parserError = new Error("An unknown parser error occurred");
|
|
10859
|
+
}
|
|
10860
|
+
}
|
|
10929
10861
|
}
|
|
10930
|
-
|
|
10931
|
-
},
|
|
10932
|
-
|
|
10933
|
-
|
|
10934
|
-
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
|
|
10938
|
-
|
|
10939
|
-
|
|
10940
|
-
|
|
10941
|
-
|
|
10942
|
-
|
|
10943
|
-
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
|
|
10950
|
-
|
|
10951
|
-
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
|
|
10955
|
-
|
|
10956
|
-
|
|
10957
|
-
|
|
10958
|
-
|
|
10959
|
-
|
|
10960
|
-
|
|
10961
|
-
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
|
|
10967
|
-
|
|
10968
|
-
|
|
10969
|
-
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
|
|
10862
|
+
return ok;
|
|
10863
|
+
}, true));
|
|
10864
|
+
}
|
|
10865
|
+
async function analyze(fnMap) {
|
|
10866
|
+
let excludeAnnotations;
|
|
10867
|
+
let hasTests = false;
|
|
10868
|
+
const allImports = [];
|
|
10869
|
+
const preState = {
|
|
10870
|
+
allFunctions: [],
|
|
10871
|
+
allClasses: [],
|
|
10872
|
+
shouldExclude(node) {
|
|
10873
|
+
if ("attrs" in node &&
|
|
10874
|
+
node.attrs &&
|
|
10875
|
+
"attrs" in node.attrs &&
|
|
10876
|
+
node.attrs.attrs) {
|
|
10877
|
+
return node.attrs.attrs.reduce((drop, attr) => {
|
|
10878
|
+
if (attr.type != "UnaryExpression")
|
|
10879
|
+
return drop;
|
|
10880
|
+
if (attr.argument.type != "Identifier")
|
|
10881
|
+
return drop;
|
|
10882
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(excludeAnnotations, attr.argument.name)) {
|
|
10883
|
+
return true;
|
|
10884
|
+
}
|
|
10885
|
+
if (attr.argument.name == "test") {
|
|
10886
|
+
hasTests = true;
|
|
10887
|
+
}
|
|
10888
|
+
return drop;
|
|
10889
|
+
}, false);
|
|
10890
|
+
}
|
|
10891
|
+
return null;
|
|
10892
|
+
},
|
|
10893
|
+
post(node, state) {
|
|
10894
|
+
switch (node.type) {
|
|
10895
|
+
case "FunctionDeclaration":
|
|
10896
|
+
case "ClassDeclaration": {
|
|
10897
|
+
const [scope] = state.stack.slice(-1);
|
|
10898
|
+
const stack = state.stack.slice(0, -1);
|
|
10899
|
+
scope.stack = stack;
|
|
10900
|
+
if (scope.type == "FunctionDeclaration") {
|
|
10901
|
+
state.allFunctions.push(scope);
|
|
10902
|
+
}
|
|
10903
|
+
else {
|
|
10904
|
+
state.allClasses.push(scope);
|
|
10905
|
+
}
|
|
10906
|
+
return null;
|
|
10907
|
+
}
|
|
10908
|
+
case "Using":
|
|
10909
|
+
case "ImportModule":
|
|
10910
|
+
allImports.push({ node, stack: state.stack.slice() });
|
|
10911
|
+
return null;
|
|
10912
|
+
default:
|
|
10913
|
+
return null;
|
|
10914
|
+
}
|
|
10915
|
+
},
|
|
10916
|
+
};
|
|
10917
|
+
await (0,external_api_cjs_namespaceObject.getApiMapping)(preState);
|
|
10918
|
+
const state = preState;
|
|
10919
|
+
// Mark all functions from api.mir as "special" by
|
|
10920
|
+
// setting their bodies to null. In api.mir, they're
|
|
10921
|
+
// all empty, which makes it look like they're
|
|
10922
|
+
// do-nothing functions.
|
|
10923
|
+
const markApi = (node) => {
|
|
10924
|
+
if (node.type == "FunctionDeclaration") {
|
|
10925
|
+
node.node.body = null;
|
|
10926
|
+
}
|
|
10927
|
+
if ((0,external_api_cjs_namespaceObject.isStateNode)(node) && node.decls) {
|
|
10928
|
+
Object.values(node.decls).forEach((v) => v.forEach(markApi));
|
|
10929
|
+
}
|
|
10930
|
+
};
|
|
10931
|
+
markApi(state.stack[0]);
|
|
10932
|
+
await getFileASTs(fnMap);
|
|
10933
|
+
Object.entries(fnMap).forEach(([name, value]) => {
|
|
10934
|
+
const { ast, parserError } = value;
|
|
10935
|
+
if (!ast) {
|
|
10936
|
+
throw parserError || new Error(`Failed to parse ${name}`);
|
|
10937
|
+
}
|
|
10938
|
+
excludeAnnotations = value.excludeAnnotations;
|
|
10939
|
+
hasTests = false;
|
|
10940
|
+
(0,external_api_cjs_namespaceObject.collectNamespaces)(ast, state);
|
|
10941
|
+
value.hasTests = hasTests;
|
|
10973
10942
|
});
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
(
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
const files = await Promise.all(
|
|
10980
|
-
Object.entries(fnMap).map(([name, { excludeAnnotations }]) =>
|
|
10981
|
-
promises_namespaceObject.readFile(name).then((data) => ({
|
|
10982
|
-
name,
|
|
10983
|
-
ast: getAst(
|
|
10984
|
-
name,
|
|
10985
|
-
data.toString().replace(/\r\n/g, "\n"),
|
|
10986
|
-
excludeAnnotations
|
|
10987
|
-
),
|
|
10988
|
-
}))
|
|
10989
|
-
)
|
|
10990
|
-
);
|
|
10991
|
-
|
|
10992
|
-
delete state.shouldExclude;
|
|
10993
|
-
delete state.post;
|
|
10994
|
-
|
|
10995
|
-
processImports(allImports, state.lookup);
|
|
10996
|
-
collectClassInfo(state);
|
|
10997
|
-
|
|
10998
|
-
return { files, state };
|
|
10943
|
+
delete state.shouldExclude;
|
|
10944
|
+
delete state.post;
|
|
10945
|
+
processImports(allImports, state.lookup);
|
|
10946
|
+
collectClassInfo(state);
|
|
10947
|
+
return state;
|
|
10999
10948
|
}
|
|
11000
|
-
|
|
11001
|
-
|
|
11002
|
-
|
|
11003
|
-
|
|
11004
|
-
|
|
11005
|
-
|
|
11006
|
-
|
|
11007
|
-
|
|
11008
|
-
|
|
11009
|
-
|
|
11010
|
-
|
|
11011
|
-
|
|
11012
|
-
|
|
11013
|
-
|
|
10949
|
+
function compareLiteralLike(a, b) {
|
|
10950
|
+
while (a.type === "BinaryExpression")
|
|
10951
|
+
a = a.left;
|
|
10952
|
+
while (b.type === "BinaryExpression")
|
|
10953
|
+
b = b.left;
|
|
10954
|
+
return a.type === "Literal" && b.type === "Literal" && a.value === b.value;
|
|
10955
|
+
}
|
|
10956
|
+
function getLiteralFromDecls(decls) {
|
|
10957
|
+
if (!decls.length)
|
|
10958
|
+
return null;
|
|
10959
|
+
let result = null;
|
|
10960
|
+
if (decls.every((d) => {
|
|
10961
|
+
if (d.type === "EnumStringMember" ||
|
|
10962
|
+
(d.type === "VariableDeclarator" && d.kind === "const")) {
|
|
10963
|
+
const init = getLiteralNode(d.init);
|
|
10964
|
+
if (!init)
|
|
10965
|
+
return false;
|
|
10966
|
+
if (!result) {
|
|
10967
|
+
result = init;
|
|
10968
|
+
return true;
|
|
10969
|
+
}
|
|
10970
|
+
else {
|
|
10971
|
+
return compareLiteralLike(init, result);
|
|
10972
|
+
}
|
|
11014
10973
|
}
|
|
11015
|
-
return
|
|
11016
|
-
|
|
11017
|
-
|
|
11018
|
-
return result;
|
|
10974
|
+
return false;
|
|
10975
|
+
})) {
|
|
10976
|
+
return result;
|
|
11019
10977
|
}
|
|
11020
10978
|
return null;
|
|
11021
|
-
|
|
11022
|
-
|
|
11023
|
-
|
|
11024
|
-
|
|
11025
|
-
|
|
11026
|
-
|
|
11027
|
-
if (node.
|
|
11028
|
-
|
|
11029
|
-
|
|
11030
|
-
|
|
11031
|
-
|
|
11032
|
-
|
|
11033
|
-
|
|
11034
|
-
|
|
11035
|
-
|
|
11036
|
-
|
|
10979
|
+
}
|
|
10980
|
+
function getLiteralNode(node) {
|
|
10981
|
+
if (node == null)
|
|
10982
|
+
return null;
|
|
10983
|
+
if (node.type == "Literal")
|
|
10984
|
+
return node;
|
|
10985
|
+
if (node.type == "BinaryExpression" && node.operator == "as") {
|
|
10986
|
+
return getLiteralNode(node.left) && node;
|
|
10987
|
+
}
|
|
10988
|
+
if (node.type == "UnaryExpression") {
|
|
10989
|
+
if (node.argument.type != "Literal")
|
|
10990
|
+
return null;
|
|
10991
|
+
switch (node.operator) {
|
|
10992
|
+
case "-":
|
|
10993
|
+
if (typeof node.argument.value == "number") {
|
|
10994
|
+
return {
|
|
10995
|
+
...node.argument,
|
|
10996
|
+
value: -node.argument.value,
|
|
10997
|
+
raw: "-" + node.argument.value,
|
|
10998
|
+
enumType: node.enumType,
|
|
10999
|
+
};
|
|
11000
|
+
}
|
|
11037
11001
|
}
|
|
11038
11002
|
}
|
|
11039
|
-
|
|
11003
|
+
return null;
|
|
11040
11004
|
}
|
|
11041
|
-
|
|
11042
11005
|
function getNodeValue(node) {
|
|
11043
|
-
|
|
11044
|
-
|
|
11045
|
-
|
|
11046
|
-
|
|
11047
|
-
|
|
11048
|
-
|
|
11049
|
-
|
|
11050
|
-
|
|
11051
|
-
|
|
11052
|
-
|
|
11053
|
-
|
|
11054
|
-
|
|
11055
|
-
|
|
11056
|
-
|
|
11057
|
-
|
|
11058
|
-
|
|
11059
|
-
|
|
11060
|
-
|
|
11061
|
-
|
|
11062
|
-
|
|
11063
|
-
|
|
11064
|
-
|
|
11065
|
-
|
|
11066
|
-
|
|
11006
|
+
if (node.type == "BinaryExpression" &&
|
|
11007
|
+
node.operator == "as" &&
|
|
11008
|
+
node.right.type == "TypeSpecList" &&
|
|
11009
|
+
node.right.ts.length == 1 &&
|
|
11010
|
+
typeof node.right.ts[0] == "string") {
|
|
11011
|
+
// this is a cast we inserted to retain the type of an enum
|
|
11012
|
+
// any arithmetic on it will revert to "Number", or "Long",
|
|
11013
|
+
// so just ignore it.
|
|
11014
|
+
return getNodeValue(node.left);
|
|
11015
|
+
}
|
|
11016
|
+
if (node.type != "Literal") {
|
|
11017
|
+
return [null, null];
|
|
11018
|
+
}
|
|
11019
|
+
let type = node.value === null ? "Null" : typeof node.value;
|
|
11020
|
+
if (type === "number") {
|
|
11021
|
+
const match = node.raw && prettier_plugin_monkeyc_namespaceObject.LiteralIntegerRe.exec(node.raw);
|
|
11022
|
+
if (match) {
|
|
11023
|
+
type = match[2] == "l" ? "Long" : "Number";
|
|
11024
|
+
}
|
|
11025
|
+
else if (node.raw && node.raw.endsWith("d")) {
|
|
11026
|
+
type = "Double";
|
|
11027
|
+
}
|
|
11028
|
+
else {
|
|
11029
|
+
type = "Float";
|
|
11030
|
+
}
|
|
11067
11031
|
}
|
|
11068
|
-
|
|
11069
|
-
|
|
11070
|
-
|
|
11071
|
-
type
|
|
11072
|
-
|
|
11073
|
-
|
|
11074
|
-
|
|
11075
|
-
|
|
11032
|
+
else if (type === "string") {
|
|
11033
|
+
type = "String";
|
|
11034
|
+
}
|
|
11035
|
+
else if (type === "boolean") {
|
|
11036
|
+
type = "Boolean";
|
|
11037
|
+
}
|
|
11038
|
+
else {
|
|
11039
|
+
type = "Unknown";
|
|
11040
|
+
}
|
|
11041
|
+
return [node, type];
|
|
11076
11042
|
}
|
|
11077
|
-
|
|
11078
11043
|
function optimizeNode(node) {
|
|
11079
|
-
|
|
11080
|
-
|
|
11081
|
-
|
|
11082
|
-
|
|
11083
|
-
|
|
11084
|
-
|
|
11085
|
-
|
|
11086
|
-
|
|
11087
|
-
|
|
11088
|
-
|
|
11089
|
-
|
|
11090
|
-
|
|
11091
|
-
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
|
|
11096
|
-
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
|
|
11100
|
-
|
|
11101
|
-
|
|
11102
|
-
|
|
11103
|
-
|
|
11104
|
-
|
|
11105
|
-
|
|
11044
|
+
switch (node.type) {
|
|
11045
|
+
case "UnaryExpression": {
|
|
11046
|
+
const [arg, type] = getNodeValue(node.argument);
|
|
11047
|
+
if (arg === null)
|
|
11048
|
+
break;
|
|
11049
|
+
switch (node.operator) {
|
|
11050
|
+
case "+":
|
|
11051
|
+
if (type === "Number" || type === "Long") {
|
|
11052
|
+
return arg;
|
|
11053
|
+
}
|
|
11054
|
+
break;
|
|
11055
|
+
case "-":
|
|
11056
|
+
if (type === "Number" || type === "Long") {
|
|
11057
|
+
return {
|
|
11058
|
+
...arg,
|
|
11059
|
+
value: -arg.value,
|
|
11060
|
+
raw: (-arg.value).toString() + (type === "Long" ? "l" : ""),
|
|
11061
|
+
};
|
|
11062
|
+
}
|
|
11063
|
+
break;
|
|
11064
|
+
case "!":
|
|
11065
|
+
case "~":
|
|
11066
|
+
{
|
|
11067
|
+
let value;
|
|
11068
|
+
if (type === "Number" || type === "Long") {
|
|
11069
|
+
value = -arg.value - 1;
|
|
11070
|
+
}
|
|
11071
|
+
else if (type === "Boolean" && node.operator == "!") {
|
|
11072
|
+
value = !arg.value;
|
|
11073
|
+
}
|
|
11074
|
+
if (value !== undefined) {
|
|
11075
|
+
return {
|
|
11076
|
+
...arg,
|
|
11077
|
+
value,
|
|
11078
|
+
raw: value.toString() + (type === "Long" ? "l" : ""),
|
|
11079
|
+
};
|
|
11080
|
+
}
|
|
11081
|
+
}
|
|
11082
|
+
break;
|
|
11106
11083
|
}
|
|
11107
|
-
|
|
11108
|
-
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11084
|
+
break;
|
|
11085
|
+
}
|
|
11086
|
+
case "BinaryExpression": {
|
|
11087
|
+
const operators = {
|
|
11088
|
+
"+": (left, right) => left + right,
|
|
11089
|
+
"-": (left, right) => left - right,
|
|
11090
|
+
"*": (left, right) => left * right,
|
|
11091
|
+
"/": (left, right) => Math.trunc(left / right),
|
|
11092
|
+
"%": (left, right) => left % right,
|
|
11093
|
+
"&": (left, right, type) => type === "Number" ? left & right : null,
|
|
11094
|
+
"|": (left, right, type) => type === "Number" ? left | right : null,
|
|
11095
|
+
"<<": (left, right, type) => type === "Number" ? left << right : null,
|
|
11096
|
+
">>": (left, right, type) => type === "Number" ? left >> right : null,
|
|
11097
|
+
};
|
|
11098
|
+
const op = operators[node.operator];
|
|
11099
|
+
if (op) {
|
|
11100
|
+
const [left, left_type] = getNodeValue(node.left);
|
|
11101
|
+
const [right, right_type] = getNodeValue(node.right);
|
|
11102
|
+
if (!left || !right)
|
|
11103
|
+
break;
|
|
11104
|
+
if (left_type != right_type ||
|
|
11105
|
+
(left_type != "Number" && left_type != "Long")) {
|
|
11106
|
+
break;
|
|
11107
|
+
}
|
|
11108
|
+
const value = op(left.value, right.value, left_type);
|
|
11109
|
+
if (value === null)
|
|
11110
|
+
break;
|
|
11111
|
+
return {
|
|
11112
|
+
...left,
|
|
11113
|
+
value,
|
|
11114
|
+
raw: value.toString() + (left_type === "Long" ? "l" : ""),
|
|
11115
|
+
};
|
|
11113
11116
|
}
|
|
11114
|
-
|
|
11115
|
-
break;
|
|
11116
|
-
}
|
|
11117
|
-
break;
|
|
11118
|
-
}
|
|
11119
|
-
case "BinaryExpression": {
|
|
11120
|
-
const operators = {
|
|
11121
|
-
"+": (left, right) => left + right,
|
|
11122
|
-
"-": (left, right) => left - right,
|
|
11123
|
-
"*": (left, right) => left * right,
|
|
11124
|
-
"/": (left, right) => Math.trunc(left / right),
|
|
11125
|
-
"%": (left, right) => left % right,
|
|
11126
|
-
"&": (left, right, type) => (type === "Number" ? left & right : null),
|
|
11127
|
-
"|": (left, right, type) => (type === "Number" ? left | right : null),
|
|
11128
|
-
"<<": (left, right, type) => (type === "Number" ? left << right : null),
|
|
11129
|
-
">>": (left, right, type) => (type === "Number" ? left >> right : null),
|
|
11130
|
-
};
|
|
11131
|
-
const op = operators[node.operator];
|
|
11132
|
-
if (op) {
|
|
11133
|
-
const [left, left_type] = getNodeValue(node.left);
|
|
11134
|
-
const [right, right_type] = getNodeValue(node.right);
|
|
11135
|
-
if (!left || !right) break;
|
|
11136
|
-
if (
|
|
11137
|
-
left_type != right_type ||
|
|
11138
|
-
(left_type != "Number" && left_type != "Long")
|
|
11139
|
-
) {
|
|
11140
|
-
break;
|
|
11117
|
+
break;
|
|
11141
11118
|
}
|
|
11142
|
-
|
|
11143
|
-
|
|
11144
|
-
|
|
11145
|
-
|
|
11146
|
-
|
|
11147
|
-
raw: value.toString() + (left_type === "Long" ? "l" : ""),
|
|
11148
|
-
};
|
|
11149
|
-
}
|
|
11150
|
-
break;
|
|
11119
|
+
case "FunctionDeclaration":
|
|
11120
|
+
if (node.body && evaluateFunction(node, null) !== false) {
|
|
11121
|
+
node.optimizable = true;
|
|
11122
|
+
}
|
|
11123
|
+
break;
|
|
11151
11124
|
}
|
|
11152
|
-
|
|
11153
|
-
if (node.body && evaluateFunction(node, null) !== false) {
|
|
11154
|
-
node.optimizable = true;
|
|
11155
|
-
}
|
|
11156
|
-
break;
|
|
11157
|
-
}
|
|
11125
|
+
return null;
|
|
11158
11126
|
}
|
|
11159
|
-
|
|
11160
11127
|
function evaluateFunction(func, args) {
|
|
11161
|
-
|
|
11162
|
-
|
|
11163
|
-
}
|
|
11164
|
-
const paramValues =
|
|
11165
|
-
args && Object.fromEntries(func.params.map((p, i) => [p.name, args[i]]));
|
|
11166
|
-
let ret = null;
|
|
11167
|
-
const body = args ? JSON.parse(JSON.stringify(func.body)) : func.body;
|
|
11168
|
-
try {
|
|
11169
|
-
(0,external_api_cjs_namespaceObject.traverseAst)(
|
|
11170
|
-
body,
|
|
11171
|
-
(node) => {
|
|
11172
|
-
switch (node.type) {
|
|
11173
|
-
case "BlockStatement":
|
|
11174
|
-
case "ReturnStatement":
|
|
11175
|
-
case "UnaryExpression":
|
|
11176
|
-
case "BinaryExpression":
|
|
11177
|
-
case "Literal":
|
|
11178
|
-
case "Identifier":
|
|
11179
|
-
return;
|
|
11180
|
-
default:
|
|
11181
|
-
throw new Error("Bad node type");
|
|
11182
|
-
}
|
|
11183
|
-
},
|
|
11184
|
-
args &&
|
|
11185
|
-
((node) => {
|
|
11186
|
-
switch (node.type) {
|
|
11187
|
-
case "ReturnStatement":
|
|
11188
|
-
ret = node.argument;
|
|
11189
|
-
return;
|
|
11190
|
-
case "BlockStatement":
|
|
11191
|
-
case "Literal":
|
|
11192
|
-
return;
|
|
11193
|
-
case "Identifier":
|
|
11194
|
-
if ((0,external_api_cjs_namespaceObject.hasProperty)(paramValues, node.name)) {
|
|
11195
|
-
return paramValues[node.name];
|
|
11196
|
-
}
|
|
11197
|
-
// fall through;
|
|
11198
|
-
default: {
|
|
11199
|
-
const repl = optimizeNode(node);
|
|
11200
|
-
if (repl && repl.type === "Literal") return repl;
|
|
11201
|
-
throw new Error("Didn't optimize");
|
|
11202
|
-
}
|
|
11203
|
-
}
|
|
11204
|
-
})
|
|
11205
|
-
);
|
|
11206
|
-
return ret;
|
|
11207
|
-
} catch (e) {
|
|
11208
|
-
return false;
|
|
11209
|
-
}
|
|
11210
|
-
}
|
|
11211
|
-
|
|
11212
|
-
async function optimizeMonkeyC(fnMap) {
|
|
11213
|
-
const { files, state } = await analyze(fnMap);
|
|
11214
|
-
const replace = (node, obj) => {
|
|
11215
|
-
for (const k of Object.keys(node)) {
|
|
11216
|
-
delete node[k];
|
|
11217
|
-
}
|
|
11218
|
-
if (obj.enumType) {
|
|
11219
|
-
obj = {
|
|
11220
|
-
type: "BinaryExpression",
|
|
11221
|
-
operator: "as",
|
|
11222
|
-
left: obj,
|
|
11223
|
-
right: { type: "TypeSpecList", ts: [obj.enumType] },
|
|
11224
|
-
};
|
|
11225
|
-
}
|
|
11226
|
-
for (const [k, v] of Object.entries(obj)) {
|
|
11227
|
-
node[k] = v;
|
|
11228
|
-
}
|
|
11229
|
-
};
|
|
11230
|
-
const lookupAndReplace = (node) => {
|
|
11231
|
-
const [, objects] = state.lookup(node);
|
|
11232
|
-
if (!objects) {
|
|
11233
|
-
return false;
|
|
11234
|
-
}
|
|
11235
|
-
const obj = getLiteralNode(objects);
|
|
11236
|
-
if (!obj) {
|
|
11237
|
-
return false;
|
|
11128
|
+
if (args && args.length != func.params.length) {
|
|
11129
|
+
return false;
|
|
11238
11130
|
}
|
|
11239
|
-
|
|
11240
|
-
|
|
11241
|
-
|
|
11242
|
-
|
|
11243
|
-
|
|
11244
|
-
|
|
11245
|
-
|
|
11246
|
-
|
|
11247
|
-
|
|
11248
|
-
|
|
11249
|
-
|
|
11250
|
-
|
|
11131
|
+
const paramValues = args &&
|
|
11132
|
+
Object.fromEntries(func.params.map((p, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(p), args[i]]));
|
|
11133
|
+
let ret = null;
|
|
11134
|
+
const body = args ? JSON.parse(JSON.stringify(func.body)) : func.body;
|
|
11135
|
+
try {
|
|
11136
|
+
(0,external_api_cjs_namespaceObject.traverseAst)(body, (node) => {
|
|
11137
|
+
switch (node.type) {
|
|
11138
|
+
case "BlockStatement":
|
|
11139
|
+
case "ReturnStatement":
|
|
11140
|
+
case "UnaryExpression":
|
|
11141
|
+
case "BinaryExpression":
|
|
11142
|
+
case "Literal":
|
|
11143
|
+
case "Identifier":
|
|
11144
|
+
return;
|
|
11145
|
+
default:
|
|
11146
|
+
throw new Error("Bad node type");
|
|
11147
|
+
}
|
|
11148
|
+
}, !args
|
|
11149
|
+
? undefined
|
|
11150
|
+
: (node) => {
|
|
11151
|
+
switch (node.type) {
|
|
11152
|
+
case "ReturnStatement":
|
|
11153
|
+
ret = node.argument || null;
|
|
11154
|
+
return null;
|
|
11155
|
+
case "BlockStatement":
|
|
11156
|
+
case "Literal":
|
|
11157
|
+
return null;
|
|
11158
|
+
case "Identifier":
|
|
11159
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(paramValues, node.name)) {
|
|
11160
|
+
return paramValues[node.name];
|
|
11161
|
+
}
|
|
11162
|
+
// fall through;
|
|
11163
|
+
default: {
|
|
11164
|
+
const repl = optimizeNode(node);
|
|
11165
|
+
if (repl && repl.type === "Literal")
|
|
11166
|
+
return repl;
|
|
11167
|
+
throw new Error("Didn't optimize");
|
|
11168
|
+
}
|
|
11169
|
+
}
|
|
11170
|
+
});
|
|
11171
|
+
return ret;
|
|
11251
11172
|
}
|
|
11252
|
-
|
|
11253
|
-
|
|
11254
|
-
return (
|
|
11255
|
-
state.calledFunctions[func.id.name].find((f) => f === func) !== null
|
|
11256
|
-
);
|
|
11173
|
+
catch (e) {
|
|
11174
|
+
return false;
|
|
11257
11175
|
}
|
|
11258
|
-
|
|
11259
|
-
|
|
11260
|
-
|
|
11261
|
-
|
|
11262
|
-
|
|
11263
|
-
|
|
11264
|
-
|
|
11265
|
-
|
|
11266
|
-
|
|
11267
|
-
(
|
|
11268
|
-
|
|
11269
|
-
|
|
11270
|
-
|
|
11271
|
-
|
|
11272
|
-
|
|
11273
|
-
|
|
11274
|
-
|
|
11275
|
-
|
|
11276
|
-
|
|
11277
|
-
|
|
11278
|
-
|
|
11279
|
-
|
|
11280
|
-
|
|
11281
|
-
|
|
11282
|
-
|
|
11283
|
-
state.
|
|
11284
|
-
|
|
11285
|
-
|
|
11286
|
-
|
|
11287
|
-
|
|
11288
|
-
|
|
11289
|
-
|
|
11290
|
-
|
|
11291
|
-
|
|
11292
|
-
|
|
11293
|
-
|
|
11294
|
-
|
|
11295
|
-
|
|
11296
|
-
|
|
11297
|
-
|
|
11298
|
-
|
|
11299
|
-
|
|
11300
|
-
|
|
11301
|
-
|
|
11302
|
-
|
|
11303
|
-
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11311
|
-
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11176
|
+
}
|
|
11177
|
+
async function optimizeMonkeyC(fnMap) {
|
|
11178
|
+
const state = {
|
|
11179
|
+
...(await analyze(fnMap)),
|
|
11180
|
+
localsStack: [{}],
|
|
11181
|
+
exposed: {},
|
|
11182
|
+
calledFunctions: {},
|
|
11183
|
+
};
|
|
11184
|
+
const replace = (node, obj) => {
|
|
11185
|
+
for (const k of Object.keys(node)) {
|
|
11186
|
+
delete node[k];
|
|
11187
|
+
}
|
|
11188
|
+
if (obj.enumType) {
|
|
11189
|
+
obj = {
|
|
11190
|
+
type: "BinaryExpression",
|
|
11191
|
+
operator: "as",
|
|
11192
|
+
left: obj,
|
|
11193
|
+
right: { type: "TypeSpecList", ts: [obj.enumType] },
|
|
11194
|
+
};
|
|
11195
|
+
}
|
|
11196
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
11197
|
+
node[k] = v;
|
|
11198
|
+
}
|
|
11199
|
+
};
|
|
11200
|
+
const lookupAndReplace = (node) => {
|
|
11201
|
+
const [, objects] = state.lookup(node);
|
|
11202
|
+
if (!objects) {
|
|
11203
|
+
return false;
|
|
11204
|
+
}
|
|
11205
|
+
const obj = getLiteralFromDecls(objects);
|
|
11206
|
+
if (!obj) {
|
|
11207
|
+
return false;
|
|
11208
|
+
}
|
|
11209
|
+
replace(node, obj);
|
|
11210
|
+
return true;
|
|
11211
|
+
};
|
|
11212
|
+
const topLocals = () => state.localsStack[state.localsStack.length - 1];
|
|
11213
|
+
/*
|
|
11214
|
+
* Might this function be called from somewhere, including
|
|
11215
|
+
* callbacks from the api (eg getSettingsView, etc).
|
|
11216
|
+
*/
|
|
11217
|
+
const maybeCalled = (func) => {
|
|
11218
|
+
if (!func.body) {
|
|
11219
|
+
// this is an api.mir function. It can be called
|
|
11220
|
+
return true;
|
|
11221
|
+
}
|
|
11222
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, func.id.name))
|
|
11223
|
+
return true;
|
|
11224
|
+
if (func.attrs &&
|
|
11225
|
+
func.attrs.attrs &&
|
|
11226
|
+
func.attrs.attrs.some((attr) => {
|
|
11227
|
+
if (attr.type != "UnaryExpression")
|
|
11228
|
+
return false;
|
|
11229
|
+
if (attr.argument.type != "Identifier")
|
|
11230
|
+
return false;
|
|
11231
|
+
return attr.argument.name == "test";
|
|
11232
|
+
})) {
|
|
11233
|
+
return true;
|
|
11234
|
+
}
|
|
11235
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, func.id.name)) {
|
|
11236
|
+
return (state.calledFunctions[func.id.name].find((f) => f === func) !== null);
|
|
11319
11237
|
}
|
|
11320
|
-
return;
|
|
11321
|
-
|
|
11322
|
-
case "EnumDeclaration":
|
|
11323
11238
|
return false;
|
|
11324
|
-
|
|
11325
|
-
|
|
11326
|
-
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
11333
|
-
|
|
11334
|
-
|
|
11335
|
-
|
|
11336
|
-
|
|
11337
|
-
|
|
11338
|
-
|
|
11339
|
-
|
|
11340
|
-
|
|
11341
|
-
|
|
11342
|
-
|
|
11343
|
-
|
|
11239
|
+
};
|
|
11240
|
+
/*
|
|
11241
|
+
* Does elm (a class) have a maybeCalled function called name,
|
|
11242
|
+
* anywhere in its superClass chain.
|
|
11243
|
+
*/
|
|
11244
|
+
const checkInherited = (elm, name) => elm.superClass === true ||
|
|
11245
|
+
elm.superClass.some((sc) => ((0,external_api_cjs_namespaceObject.hasProperty)(sc.decls, name) &&
|
|
11246
|
+
sc.decls[name].some((f) => (0,external_api_cjs_namespaceObject.isStateNode)(f) &&
|
|
11247
|
+
f.type == "FunctionDeclaration" &&
|
|
11248
|
+
maybeCalled(f.node))) ||
|
|
11249
|
+
(sc.superClass && checkInherited(sc, name)));
|
|
11250
|
+
state.pre = (node) => {
|
|
11251
|
+
switch (node.type) {
|
|
11252
|
+
case "ConditionalExpression":
|
|
11253
|
+
case "IfStatement":
|
|
11254
|
+
case "DoWhileStatement":
|
|
11255
|
+
case "WhileStatement":
|
|
11256
|
+
const test = (state.traverse(node.test) ||
|
|
11257
|
+
node.test);
|
|
11258
|
+
const [value, type] = getNodeValue(test);
|
|
11259
|
+
if (value) {
|
|
11260
|
+
let result = null;
|
|
11261
|
+
if (type === "Null") {
|
|
11262
|
+
result = false;
|
|
11263
|
+
}
|
|
11264
|
+
else if (type === "Boolean" ||
|
|
11265
|
+
type === "Number" ||
|
|
11266
|
+
type === "Long") {
|
|
11267
|
+
result = !!value.value;
|
|
11268
|
+
}
|
|
11269
|
+
if (result !== null) {
|
|
11270
|
+
node.test = { type: "Literal", value: result };
|
|
11271
|
+
if (node.type === "IfStatement" ||
|
|
11272
|
+
node.type === "ConditionalExpression") {
|
|
11273
|
+
return [result ? "consequent" : "alternate"];
|
|
11274
|
+
}
|
|
11275
|
+
else if (node.type === "WhileStatement") {
|
|
11276
|
+
return result === false ? [] : ["body"];
|
|
11277
|
+
}
|
|
11278
|
+
else if (node.type === "DoWhileStatement") {
|
|
11279
|
+
return ["body"];
|
|
11280
|
+
}
|
|
11281
|
+
else {
|
|
11282
|
+
throw new Error("Unexpected Node type");
|
|
11283
|
+
}
|
|
11284
|
+
}
|
|
11285
|
+
}
|
|
11286
|
+
return null;
|
|
11287
|
+
case "EnumDeclaration":
|
|
11288
|
+
return false;
|
|
11289
|
+
case "ForStatement": {
|
|
11290
|
+
const map = topLocals().map;
|
|
11291
|
+
if (map) {
|
|
11292
|
+
state.localsStack.push({ node, map: { ...map } });
|
|
11293
|
+
}
|
|
11294
|
+
break;
|
|
11344
11295
|
}
|
|
11345
|
-
|
|
11346
|
-
|
|
11347
|
-
|
|
11348
|
-
|
|
11349
|
-
|
|
11350
|
-
|
|
11351
|
-
|
|
11296
|
+
case "VariableDeclarator": {
|
|
11297
|
+
const locals = topLocals();
|
|
11298
|
+
const { map } = locals;
|
|
11299
|
+
if (map) {
|
|
11300
|
+
const declName = (0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id);
|
|
11301
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(map, declName)) {
|
|
11302
|
+
// We already have a variable with this name in scope
|
|
11303
|
+
// Recent monkeyc compilers complain, so rename it
|
|
11304
|
+
let suffix = 0;
|
|
11305
|
+
let node_name = declName;
|
|
11306
|
+
const match = node_name.match(/^pmcr_(.*)_(\d+)$/);
|
|
11307
|
+
if (match) {
|
|
11308
|
+
node_name = match[1];
|
|
11309
|
+
suffix = parseInt(match[2], 10) + 1;
|
|
11310
|
+
}
|
|
11311
|
+
if (!locals.inners) {
|
|
11312
|
+
// find all the names declared in this scope, to avoid
|
|
11313
|
+
// more conflicts
|
|
11314
|
+
locals.inners = {};
|
|
11315
|
+
const inners = locals.inners;
|
|
11316
|
+
(0,external_api_cjs_namespaceObject.traverseAst)(locals.node, (node) => {
|
|
11317
|
+
if (node.type === "VariableDeclarator") {
|
|
11318
|
+
inners[(0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id)] = true;
|
|
11319
|
+
}
|
|
11320
|
+
});
|
|
11321
|
+
}
|
|
11322
|
+
let name;
|
|
11323
|
+
while (true) {
|
|
11324
|
+
name = `pmcr_${node_name}_${suffix}`;
|
|
11325
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(map, name) &&
|
|
11326
|
+
!(0,external_api_cjs_namespaceObject.hasProperty)(locals.inners, name)) {
|
|
11327
|
+
// we also need to ensure that we don't hide the name of
|
|
11328
|
+
// an outer module, class, function, enum or variable,
|
|
11329
|
+
// since someone might want to access it from this scope.
|
|
11330
|
+
let ok = false;
|
|
11331
|
+
let i;
|
|
11332
|
+
for (i = state.stack.length; i--;) {
|
|
11333
|
+
const elm = state.stack[i];
|
|
11334
|
+
if (ok) {
|
|
11335
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(elm.decls, name)) {
|
|
11336
|
+
break;
|
|
11337
|
+
}
|
|
11338
|
+
}
|
|
11339
|
+
else if (elm.node &&
|
|
11340
|
+
elm.node.type === "FunctionDeclaration") {
|
|
11341
|
+
ok = true;
|
|
11342
|
+
}
|
|
11343
|
+
}
|
|
11344
|
+
if (i < 0) {
|
|
11345
|
+
break;
|
|
11346
|
+
}
|
|
11347
|
+
}
|
|
11348
|
+
suffix++;
|
|
11349
|
+
}
|
|
11350
|
+
map[declName] = name;
|
|
11351
|
+
map[name] = true;
|
|
11352
|
+
if (node.id.type === "Identifier") {
|
|
11353
|
+
node.id.name = name;
|
|
11354
|
+
}
|
|
11355
|
+
else {
|
|
11356
|
+
node.id.left.name = name;
|
|
11357
|
+
}
|
|
11358
|
+
}
|
|
11359
|
+
else {
|
|
11360
|
+
map[declName] = true;
|
|
11361
|
+
}
|
|
11352
11362
|
}
|
|
11353
|
-
|
|
11363
|
+
return ["init"];
|
|
11354
11364
|
}
|
|
11355
|
-
|
|
11356
|
-
|
|
11357
|
-
|
|
11358
|
-
|
|
11359
|
-
|
|
11360
|
-
|
|
11361
|
-
|
|
11362
|
-
|
|
11363
|
-
|
|
11364
|
-
|
|
11365
|
-
|
|
11366
|
-
|
|
11367
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
11370
|
-
|
|
11371
|
-
|
|
11365
|
+
case "UnaryExpression":
|
|
11366
|
+
if (node.operator == ":") {
|
|
11367
|
+
// If we produce a Symbol, for a given name,
|
|
11368
|
+
// its possible that someone uses that symbol
|
|
11369
|
+
// indirectly, so we can't remove any enums or
|
|
11370
|
+
// constants with that name (we can still replace
|
|
11371
|
+
// uses of those constants though).
|
|
11372
|
+
state.exposed[node.argument.name] = true;
|
|
11373
|
+
// In any case, we can't replace *this* use of the
|
|
11374
|
+
// symbol with its value...
|
|
11375
|
+
return false;
|
|
11376
|
+
}
|
|
11377
|
+
break;
|
|
11378
|
+
case "Identifier": {
|
|
11379
|
+
const map = topLocals().map;
|
|
11380
|
+
if (map) {
|
|
11381
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(map, node.name)) {
|
|
11382
|
+
const name = map[node.name];
|
|
11383
|
+
if (name !== true) {
|
|
11384
|
+
node.name = name;
|
|
11385
|
+
}
|
|
11372
11386
|
}
|
|
11373
|
-
} else if (elm.node.type === "FunctionDeclaration") {
|
|
11374
|
-
ok = true;
|
|
11375
|
-
}
|
|
11376
11387
|
}
|
|
11377
|
-
if (
|
|
11378
|
-
|
|
11388
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, node.name)) {
|
|
11389
|
+
if (!lookupAndReplace(node)) {
|
|
11390
|
+
state.exposed[node.name] = true;
|
|
11391
|
+
}
|
|
11379
11392
|
}
|
|
11380
|
-
|
|
11381
|
-
suffix++;
|
|
11393
|
+
return false;
|
|
11382
11394
|
}
|
|
11383
|
-
|
|
11384
|
-
|
|
11385
|
-
|
|
11386
|
-
|
|
11387
|
-
|
|
11388
|
-
|
|
11389
|
-
|
|
11390
|
-
|
|
11391
|
-
|
|
11392
|
-
|
|
11393
|
-
|
|
11394
|
-
|
|
11395
|
-
|
|
11396
|
-
|
|
11397
|
-
|
|
11398
|
-
|
|
11399
|
-
|
|
11400
|
-
|
|
11401
|
-
|
|
11402
|
-
|
|
11403
|
-
|
|
11404
|
-
|
|
11405
|
-
|
|
11406
|
-
const map = state.localsStack.slice(-1).pop().map;
|
|
11407
|
-
if (map) {
|
|
11408
|
-
if ((0,external_api_cjs_namespaceObject.hasProperty)(map, node.name)) {
|
|
11409
|
-
const name = map[node.name];
|
|
11410
|
-
if (name !== true) {
|
|
11411
|
-
node.name = name;
|
|
11395
|
+
case "MemberExpression":
|
|
11396
|
+
if (node.property.type === "Identifier" && !node.computed) {
|
|
11397
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, node.property.name)) {
|
|
11398
|
+
if (lookupAndReplace(node)) {
|
|
11399
|
+
return false;
|
|
11400
|
+
}
|
|
11401
|
+
else {
|
|
11402
|
+
state.exposed[node.property.name] = true;
|
|
11403
|
+
}
|
|
11404
|
+
}
|
|
11405
|
+
// Don't optimize the property.
|
|
11406
|
+
return ["object"];
|
|
11407
|
+
}
|
|
11408
|
+
break;
|
|
11409
|
+
case "BlockStatement": {
|
|
11410
|
+
const map = topLocals().map;
|
|
11411
|
+
if (map) {
|
|
11412
|
+
state.localsStack.push({
|
|
11413
|
+
node,
|
|
11414
|
+
map: { ...map },
|
|
11415
|
+
});
|
|
11416
|
+
}
|
|
11417
|
+
break;
|
|
11412
11418
|
}
|
|
11413
|
-
|
|
11414
|
-
|
|
11415
|
-
|
|
11416
|
-
|
|
11417
|
-
|
|
11418
|
-
|
|
11419
|
-
|
|
11420
|
-
|
|
11421
|
-
|
|
11422
|
-
|
|
11423
|
-
|
|
11424
|
-
|
|
11425
|
-
|
|
11426
|
-
|
|
11427
|
-
|
|
11428
|
-
|
|
11419
|
+
case "FunctionDeclaration": {
|
|
11420
|
+
const map = {};
|
|
11421
|
+
node.params &&
|
|
11422
|
+
node.params.forEach((p) => (map[(0,external_api_cjs_namespaceObject.variableDeclarationName)(p)] = true));
|
|
11423
|
+
state.localsStack.push({ node, map });
|
|
11424
|
+
const [parent] = state.stack.slice(-2);
|
|
11425
|
+
if (parent.type == "ClassDeclaration" && !maybeCalled(node)) {
|
|
11426
|
+
let used = false;
|
|
11427
|
+
if (node.id.name == "initialize") {
|
|
11428
|
+
used = true;
|
|
11429
|
+
}
|
|
11430
|
+
else if (parent.superClass) {
|
|
11431
|
+
used = checkInherited(parent, node.id.name);
|
|
11432
|
+
}
|
|
11433
|
+
if (used) {
|
|
11434
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, node.id.name)) {
|
|
11435
|
+
state.calledFunctions[node.id.name] = [];
|
|
11436
|
+
}
|
|
11437
|
+
state.calledFunctions[node.id.name].push(node);
|
|
11438
|
+
}
|
|
11439
|
+
}
|
|
11429
11440
|
}
|
|
11430
|
-
}
|
|
11431
|
-
// Don't optimize the property.
|
|
11432
|
-
return ["object"];
|
|
11433
|
-
}
|
|
11434
|
-
break;
|
|
11435
|
-
case "BlockStatement": {
|
|
11436
|
-
const map = state.localsStack.slice(-1).pop().map;
|
|
11437
|
-
if (map) {
|
|
11438
|
-
state.localsStack.push({
|
|
11439
|
-
node,
|
|
11440
|
-
map: { ...map },
|
|
11441
|
-
});
|
|
11442
11441
|
}
|
|
11443
|
-
|
|
11444
|
-
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
|
|
11448
|
-
state.localsStack.push({ node, map });
|
|
11449
|
-
const [parent] = state.stack.slice(-2);
|
|
11450
|
-
if (parent.type == "ClassDeclaration" && !maybeCalled(node)) {
|
|
11451
|
-
let used = false;
|
|
11452
|
-
if (node.id.name == "initialize") {
|
|
11453
|
-
used = true;
|
|
11454
|
-
} else if (parent.superClass) {
|
|
11455
|
-
used = checkInherited(parent, node.id.name);
|
|
11456
|
-
}
|
|
11457
|
-
if (used) {
|
|
11458
|
-
if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, node.id.name)) {
|
|
11459
|
-
state.calledFunctions[node.id.name] = [];
|
|
11460
|
-
}
|
|
11461
|
-
state.calledFunctions[node.id.name].push(node);
|
|
11462
|
-
}
|
|
11442
|
+
return null;
|
|
11443
|
+
};
|
|
11444
|
+
state.post = (node) => {
|
|
11445
|
+
if (topLocals().node === node) {
|
|
11446
|
+
state.localsStack.pop();
|
|
11463
11447
|
}
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
if (state.localsStack.slice(-1).pop().node === node) {
|
|
11469
|
-
state.localsStack.pop();
|
|
11470
|
-
}
|
|
11471
|
-
const opt = optimizeNode(node);
|
|
11472
|
-
if (opt) {
|
|
11473
|
-
replace(node, opt);
|
|
11474
|
-
return;
|
|
11475
|
-
}
|
|
11476
|
-
switch (node.type) {
|
|
11477
|
-
case "ConditionalExpression":
|
|
11478
|
-
case "IfStatement":
|
|
11479
|
-
if (typeof node.test === "boolean") {
|
|
11480
|
-
const rep = node.test ? node.consequent : node.alternate;
|
|
11481
|
-
if (!rep) return false;
|
|
11482
|
-
replace(node, rep);
|
|
11483
|
-
}
|
|
11484
|
-
break;
|
|
11485
|
-
case "WhileStatement":
|
|
11486
|
-
if (!node.body) return false;
|
|
11487
|
-
break;
|
|
11488
|
-
case "DoWhileStatement":
|
|
11489
|
-
if (!node.test) return node.body;
|
|
11490
|
-
break;
|
|
11491
|
-
|
|
11492
|
-
case "CallExpression": {
|
|
11493
|
-
const [name, callees] = state.lookup(node.callee);
|
|
11494
|
-
if (!callees || !callees.length) {
|
|
11495
|
-
const n =
|
|
11496
|
-
name ||
|
|
11497
|
-
node.callee.name ||
|
|
11498
|
-
(node.callee.property && node.callee.property.name);
|
|
11499
|
-
if (n) {
|
|
11500
|
-
state.exposed[n] = true;
|
|
11501
|
-
} else {
|
|
11502
|
-
// There are unnamed CallExpressions, such as new [size]
|
|
11503
|
-
// So there's nothing to do here.
|
|
11504
|
-
}
|
|
11505
|
-
return;
|
|
11448
|
+
const opt = optimizeNode(node);
|
|
11449
|
+
if (opt) {
|
|
11450
|
+
replace(node, opt);
|
|
11451
|
+
return null;
|
|
11506
11452
|
}
|
|
11507
|
-
|
|
11508
|
-
|
|
11509
|
-
|
|
11510
|
-
|
|
11511
|
-
|
|
11512
|
-
|
|
11513
|
-
|
|
11514
|
-
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
|
|
11453
|
+
switch (node.type) {
|
|
11454
|
+
case "ConditionalExpression":
|
|
11455
|
+
case "IfStatement":
|
|
11456
|
+
if (node.test.type === "Literal" &&
|
|
11457
|
+
typeof node.test.value === "boolean") {
|
|
11458
|
+
const rep = node.test.value ? node.consequent : node.alternate;
|
|
11459
|
+
if (!rep)
|
|
11460
|
+
return false;
|
|
11461
|
+
replace(node, rep);
|
|
11462
|
+
}
|
|
11463
|
+
break;
|
|
11464
|
+
case "WhileStatement":
|
|
11465
|
+
if (node.test.type === "Literal" && node.test.value === false) {
|
|
11466
|
+
return false;
|
|
11467
|
+
}
|
|
11468
|
+
break;
|
|
11469
|
+
case "DoWhileStatement":
|
|
11470
|
+
if (node.test.type === "Literal" && node.test.value === false) {
|
|
11471
|
+
return node.body;
|
|
11472
|
+
}
|
|
11473
|
+
break;
|
|
11474
|
+
case "CallExpression": {
|
|
11475
|
+
const [name, callees] = state.lookup(node.callee);
|
|
11476
|
+
if (!callees || !callees.length) {
|
|
11477
|
+
const n = name ||
|
|
11478
|
+
("name" in node.callee && node.callee.name) ||
|
|
11479
|
+
("property" in node.callee &&
|
|
11480
|
+
node.callee.property &&
|
|
11481
|
+
"name" in node.callee.property &&
|
|
11482
|
+
node.callee.property.name);
|
|
11483
|
+
if (n) {
|
|
11484
|
+
state.exposed[n] = true;
|
|
11485
|
+
}
|
|
11486
|
+
else {
|
|
11487
|
+
// There are unnamed CallExpressions, such as new [size]
|
|
11488
|
+
// So there's nothing to do here.
|
|
11489
|
+
}
|
|
11490
|
+
return null;
|
|
11491
|
+
}
|
|
11492
|
+
if (callees.length == 1) {
|
|
11493
|
+
const callee = (0,external_api_cjs_namespaceObject.isStateNode)(callees[0]) && callees[0].node;
|
|
11494
|
+
if (callee &&
|
|
11495
|
+
callee.type == "FunctionDeclaration" &&
|
|
11496
|
+
callee.optimizable &&
|
|
11497
|
+
!callee.hasOverride &&
|
|
11498
|
+
node.arguments.every((n) => getNodeValue(n)[0] !== null)) {
|
|
11499
|
+
const ret = evaluateFunction(callee, node.arguments);
|
|
11500
|
+
if (ret) {
|
|
11501
|
+
replace(node, ret);
|
|
11502
|
+
return null;
|
|
11503
|
+
}
|
|
11504
|
+
}
|
|
11505
|
+
}
|
|
11506
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, name)) {
|
|
11507
|
+
state.calledFunctions[name] = [];
|
|
11508
|
+
}
|
|
11509
|
+
callees.forEach((c) => (0,external_api_cjs_namespaceObject.isStateNode)(c) && state.calledFunctions[name].push(c.node));
|
|
11510
|
+
break;
|
|
11518
11511
|
}
|
|
11519
|
-
}
|
|
11520
|
-
}
|
|
11521
|
-
if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, name)) {
|
|
11522
|
-
state.calledFunctions[name] = [];
|
|
11523
11512
|
}
|
|
11524
|
-
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
|
|
11534
|
-
|
|
11535
|
-
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
|
|
11539
|
-
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11543
|
-
|
|
11544
|
-
|
|
11545
|
-
|
|
11546
|
-
|
|
11547
|
-
|
|
11548
|
-
|
|
11549
|
-
|
|
11550
|
-
|
|
11551
|
-
|
|
11552
|
-
|
|
11553
|
-
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
|
|
11559
|
-
|
|
11560
|
-
|
|
11561
|
-
|
|
11562
|
-
|
|
11563
|
-
|
|
11564
|
-
|
|
11513
|
+
return null;
|
|
11514
|
+
};
|
|
11515
|
+
Object.values(fnMap).forEach((f) => {
|
|
11516
|
+
(0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
|
|
11517
|
+
});
|
|
11518
|
+
Object.values(fnMap).forEach((f) => {
|
|
11519
|
+
(0,external_api_cjs_namespaceObject.traverseAst)(f.ast, undefined, (node) => {
|
|
11520
|
+
switch (node.type) {
|
|
11521
|
+
case "EnumStringBody":
|
|
11522
|
+
if (node.members.every((m) => {
|
|
11523
|
+
const name = "name" in m ? m.name : m.id.name;
|
|
11524
|
+
return ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) &&
|
|
11525
|
+
!(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name));
|
|
11526
|
+
})) {
|
|
11527
|
+
node.enumType = [
|
|
11528
|
+
...new Set(node.members.map((m) => {
|
|
11529
|
+
if (!("init" in m))
|
|
11530
|
+
return "Number";
|
|
11531
|
+
const [node, type] = getNodeValue(m.init);
|
|
11532
|
+
if (!node) {
|
|
11533
|
+
throw new Error("Failed to get type for eliminated enum");
|
|
11534
|
+
}
|
|
11535
|
+
return type;
|
|
11536
|
+
})),
|
|
11537
|
+
].join(" or ");
|
|
11538
|
+
node.members.splice(0);
|
|
11539
|
+
}
|
|
11540
|
+
break;
|
|
11541
|
+
case "EnumDeclaration":
|
|
11542
|
+
if (!node.body.members.length) {
|
|
11543
|
+
if (!node.id)
|
|
11544
|
+
return false;
|
|
11545
|
+
if (!node.body["enumType"]) {
|
|
11546
|
+
throw new Error("Missing enumType on optimized enum");
|
|
11547
|
+
}
|
|
11548
|
+
replace(node, {
|
|
11549
|
+
type: "TypedefDeclaration",
|
|
11550
|
+
id: node.id,
|
|
11551
|
+
ts: {
|
|
11552
|
+
type: "UnaryExpression",
|
|
11553
|
+
argument: { type: "TypeSpecList", ts: [node.body.enumType] },
|
|
11554
|
+
prefix: true,
|
|
11555
|
+
operator: " as",
|
|
11556
|
+
},
|
|
11557
|
+
});
|
|
11558
|
+
}
|
|
11559
|
+
break;
|
|
11560
|
+
case "VariableDeclaration": {
|
|
11561
|
+
node.declarations = node.declarations.filter((d) => {
|
|
11562
|
+
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(d.id);
|
|
11563
|
+
return (!(0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) ||
|
|
11564
|
+
(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name));
|
|
11565
|
+
});
|
|
11566
|
+
if (!node.declarations.length) {
|
|
11567
|
+
return false;
|
|
11568
|
+
}
|
|
11569
|
+
break;
|
|
11570
|
+
}
|
|
11571
|
+
case "ClassElement":
|
|
11572
|
+
if (!node.item) {
|
|
11573
|
+
return false;
|
|
11574
|
+
}
|
|
11575
|
+
break;
|
|
11576
|
+
case "FunctionDeclaration":
|
|
11577
|
+
if (!maybeCalled(node)) {
|
|
11578
|
+
return false;
|
|
11579
|
+
}
|
|
11580
|
+
break;
|
|
11565
11581
|
}
|
|
11566
|
-
|
|
11567
|
-
|
|
11568
|
-
id: node.id,
|
|
11569
|
-
ts: {
|
|
11570
|
-
type: "UnaryExpression",
|
|
11571
|
-
argument: { type: "TypeSpecList", ts: [node.body.enumType] },
|
|
11572
|
-
prefix: true,
|
|
11573
|
-
operator: " as",
|
|
11574
|
-
},
|
|
11575
|
-
});
|
|
11576
|
-
}
|
|
11577
|
-
break;
|
|
11578
|
-
case "VariableDeclaration": {
|
|
11579
|
-
node.declarations = node.declarations.filter(
|
|
11580
|
-
(d) =>
|
|
11581
|
-
!(0,external_api_cjs_namespaceObject.hasProperty)(state.index, d.id.name) ||
|
|
11582
|
-
(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, d.id.name)
|
|
11583
|
-
);
|
|
11584
|
-
if (!node.declarations.length) {
|
|
11585
|
-
return false;
|
|
11586
|
-
}
|
|
11587
|
-
break;
|
|
11588
|
-
}
|
|
11589
|
-
case "ClassElement":
|
|
11590
|
-
if (!node.item) {
|
|
11591
|
-
return false;
|
|
11592
|
-
}
|
|
11593
|
-
break;
|
|
11594
|
-
case "FunctionDeclaration":
|
|
11595
|
-
if (!maybeCalled(node)) {
|
|
11596
|
-
return false;
|
|
11597
|
-
}
|
|
11598
|
-
break;
|
|
11599
|
-
}
|
|
11582
|
+
return null;
|
|
11583
|
+
});
|
|
11600
11584
|
});
|
|
11601
|
-
});
|
|
11602
|
-
|
|
11603
|
-
return files;
|
|
11604
11585
|
}
|
|
11605
11586
|
|
|
11606
|
-
;// CONCATENATED MODULE: ./src/optimizer.
|
|
11607
|
-
|
|
11587
|
+
;// CONCATENATED MODULE: ./src/optimizer.ts
|
|
11608
11588
|
|
|
11609
11589
|
|
|
11610
11590
|
|
|
@@ -11619,81 +11599,95 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11619
11599
|
|
|
11620
11600
|
|
|
11621
11601
|
function relative_path_no_dotdot(relative) {
|
|
11622
|
-
|
|
11623
|
-
/^(\.\.[\\\/])+/,
|
|
11624
|
-
(str) => `__${"dot".repeat(str.length / 3)}__${str.slice(-1)}`
|
|
11625
|
-
);
|
|
11602
|
+
return relative.replace(/^(\.\.[\\\/])+/, (str) => `__${"dot".repeat(str.length / 3)}__${str.slice(-1)}`);
|
|
11626
11603
|
}
|
|
11627
|
-
|
|
11628
11604
|
async function getVSCodeSettings(path) {
|
|
11629
|
-
|
|
11630
|
-
|
|
11631
|
-
|
|
11632
|
-
|
|
11633
|
-
|
|
11634
|
-
|
|
11605
|
+
try {
|
|
11606
|
+
const settings = await promises_namespaceObject.readFile(path);
|
|
11607
|
+
return JSON.parse(settings.toString());
|
|
11608
|
+
}
|
|
11609
|
+
catch (e) {
|
|
11610
|
+
return {};
|
|
11611
|
+
}
|
|
11635
11612
|
}
|
|
11636
|
-
|
|
11637
11613
|
const defaultConfig = {
|
|
11638
|
-
|
|
11639
|
-
|
|
11614
|
+
outputPath: "bin/optimized",
|
|
11615
|
+
workspace: "./",
|
|
11640
11616
|
};
|
|
11641
|
-
|
|
11642
|
-
|
|
11643
|
-
const config = { ...defaultConfig, ...(options || {}) };
|
|
11644
|
-
let promise;
|
|
11645
|
-
[
|
|
11646
|
-
"jungleFiles",
|
|
11647
|
-
"developerKeyPath",
|
|
11648
|
-
"typeCheckLevel",
|
|
11649
|
-
"compilerOptions",
|
|
11650
|
-
"compilerWarnings",
|
|
11651
|
-
].forEach((key) => {
|
|
11652
|
-
if (config[key]) return;
|
|
11653
|
-
if (!promise) {
|
|
11654
|
-
promise = Promise.resolve()
|
|
11655
|
-
.then(() => getVSCodeSettings(`${external_sdk_util_cjs_namespaceObject.appSupport}/Code/User/settings.json`))
|
|
11656
|
-
.then((globals) =>
|
|
11657
|
-
getVSCodeSettings(`${config.workspace}/.vscode/settings.json`).then(
|
|
11658
|
-
(locals) => ({ ...globals, ...locals })
|
|
11659
|
-
)
|
|
11660
|
-
);
|
|
11661
|
-
}
|
|
11662
|
-
promise.then((settings) => {
|
|
11663
|
-
const value = settings[`monkeyC.${key}`];
|
|
11664
|
-
if (value) {
|
|
11665
|
-
config[key] = value;
|
|
11666
|
-
}
|
|
11667
|
-
});
|
|
11668
|
-
});
|
|
11669
|
-
promise && (await promise);
|
|
11670
|
-
return config;
|
|
11617
|
+
function isErrorWithLocation(e) {
|
|
11618
|
+
return (0,external_api_cjs_namespaceObject.hasProperty)(e, "location");
|
|
11671
11619
|
}
|
|
11672
|
-
|
|
11620
|
+
/**
|
|
11621
|
+
* @param {BuildConfig} options
|
|
11622
|
+
* @returns {Promise<BuildConfig>}
|
|
11623
|
+
*/
|
|
11624
|
+
function getConfig(options) {
|
|
11625
|
+
const config = { ...defaultConfig, ...(options || {}) };
|
|
11626
|
+
return [
|
|
11627
|
+
"jungleFiles",
|
|
11628
|
+
"developerKeyPath",
|
|
11629
|
+
"typeCheckLevel",
|
|
11630
|
+
"compilerOptions",
|
|
11631
|
+
"compilerWarnings",
|
|
11632
|
+
"ignoredExcludeAnnotations",
|
|
11633
|
+
"ignoredAnnotations",
|
|
11634
|
+
"ignoredSourcePaths",
|
|
11635
|
+
]
|
|
11636
|
+
.reduce((promise, key) => {
|
|
11637
|
+
if (key in config)
|
|
11638
|
+
return promise;
|
|
11639
|
+
return promise
|
|
11640
|
+
.then((v) => v ||
|
|
11641
|
+
getVSCodeSettings(`${external_sdk_util_cjs_namespaceObject.appSupport}/Code/User/settings.json`).then((globals) => getVSCodeSettings(`${config.workspace}/.vscode/settings.json`).then((locals) => ({ ...globals, ...locals }))))
|
|
11642
|
+
.then((settings) => {
|
|
11643
|
+
const value = settings[`monkeyC.${key}`] || settings[`prettierMonkeyC.${key}`];
|
|
11644
|
+
if (value !== undefined) {
|
|
11645
|
+
config[key] = value;
|
|
11646
|
+
}
|
|
11647
|
+
return settings;
|
|
11648
|
+
});
|
|
11649
|
+
}, Promise.resolve(null))
|
|
11650
|
+
.then(() => config);
|
|
11651
|
+
}
|
|
11652
|
+
/**
|
|
11653
|
+
*
|
|
11654
|
+
* @param {string | null} product
|
|
11655
|
+
* @param {BuildConfig} options
|
|
11656
|
+
* @returns
|
|
11657
|
+
*/
|
|
11673
11658
|
async function buildOptimizedProject(product, options) {
|
|
11674
|
-
|
|
11675
|
-
|
|
11676
|
-
|
|
11677
|
-
|
|
11678
|
-
|
|
11679
|
-
|
|
11680
|
-
|
|
11681
|
-
|
|
11682
|
-
|
|
11683
|
-
|
|
11684
|
-
|
|
11685
|
-
|
|
11686
|
-
|
|
11687
|
-
|
|
11688
|
-
|
|
11689
|
-
|
|
11690
|
-
|
|
11691
|
-
|
|
11692
|
-
|
|
11693
|
-
|
|
11694
|
-
|
|
11659
|
+
const config = await getConfig(options);
|
|
11660
|
+
if (product) {
|
|
11661
|
+
config.products = [product];
|
|
11662
|
+
}
|
|
11663
|
+
else {
|
|
11664
|
+
delete config.testBuild;
|
|
11665
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(config, "releaseBuild")) {
|
|
11666
|
+
config.releaseBuild = true;
|
|
11667
|
+
}
|
|
11668
|
+
}
|
|
11669
|
+
const { jungleFiles, program, hasTests } = await generateOptimizedProject(config);
|
|
11670
|
+
config.jungleFiles = jungleFiles;
|
|
11671
|
+
let bin = config.buildDir || "bin";
|
|
11672
|
+
let name = `optimized-${program}.prg`;
|
|
11673
|
+
if (product) {
|
|
11674
|
+
product = config.products[0];
|
|
11675
|
+
if (config.simulatorBuild === false) {
|
|
11676
|
+
bin = external_path_.join(bin, product);
|
|
11677
|
+
}
|
|
11678
|
+
}
|
|
11679
|
+
else {
|
|
11680
|
+
bin = external_path_.join(bin, "exported");
|
|
11681
|
+
name = `${program}.iq`;
|
|
11682
|
+
}
|
|
11683
|
+
config.program = external_path_.join(bin, name);
|
|
11684
|
+
if (!hasTests)
|
|
11685
|
+
delete config.testBuild;
|
|
11686
|
+
return build_project(product, config).then((result) => ({
|
|
11687
|
+
hasTests,
|
|
11688
|
+
...result,
|
|
11689
|
+
}));
|
|
11695
11690
|
}
|
|
11696
|
-
|
|
11697
11691
|
/**
|
|
11698
11692
|
* For each barrel project included in the build, we want to build
|
|
11699
11693
|
* a local barrel project inside the optimized directory.
|
|
@@ -11707,464 +11701,410 @@ async function buildOptimizedProject(product, options) {
|
|
|
11707
11701
|
* files corresponding to an input barrel), we create a copy of
|
|
11708
11702
|
* the barrel with all the sources removed (and pick up the sources
|
|
11709
11703
|
* from the input barrel)
|
|
11704
|
+
*
|
|
11705
|
+
* @param {BuildConfig} options
|
|
11706
|
+
* @param {Target[]} targets
|
|
11710
11707
|
*/
|
|
11711
11708
|
async function createLocalBarrels(targets, options) {
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
|
|
11726
|
-
|
|
11727
|
-
|
|
11728
|
-
|
|
11729
|
-
|
|
11730
|
-
|
|
11731
|
-
|
|
11732
|
-
|
|
11733
|
-
|
|
11734
|
-
|
|
11735
|
-
|
|
11736
|
-
|
|
11737
|
-
|
|
11738
|
-
|
|
11739
|
-
|
|
11740
|
-
|
|
11741
|
-
|
|
11742
|
-
|
|
11743
|
-
|
|
11744
|
-
|
|
11745
|
-
|
|
11746
|
-
|
|
11747
|
-
|
|
11748
|
-
|
|
11749
|
-
|
|
11750
|
-
|
|
11751
|
-
|
|
11752
|
-
|
|
11753
|
-
|
|
11754
|
-
|
|
11755
|
-
|
|
11756
|
-
};
|
|
11757
|
-
return promise.then(() =>
|
|
11758
|
-
(0,external_util_cjs_namespaceObject.copyRecursiveAsNeeded)(
|
|
11759
|
-
rawBarrelDir,
|
|
11760
|
-
optBarrelDir,
|
|
11761
|
-
(src) => !src.endsWith(".mc")
|
|
11762
|
-
)
|
|
11763
|
-
);
|
|
11764
|
-
}
|
|
11765
|
-
if (
|
|
11766
|
-
optBarrels[barrel].manifest !== manifest ||
|
|
11767
|
-
optBarrels[barrel].optBarrelDir !== optBarrelDir ||
|
|
11768
|
-
optBarrels[barrel].rawBarrelDir != rawBarrelDir
|
|
11769
|
-
) {
|
|
11770
|
-
throw new Error(
|
|
11771
|
-
`For device ${
|
|
11772
|
-
target.product
|
|
11773
|
-
}, barrel ${barrel} was mapped to both ${external_path_.relative(
|
|
11774
|
-
optBarrels[barrel].rawBarrelDir,
|
|
11775
|
-
optBarrels[barrel].manifest
|
|
11776
|
-
)} in ${optBarrels[barrel].rawBarrelDir} and ${external_path_.relative(
|
|
11777
|
-
rawBarrelDir,
|
|
11778
|
-
manifest
|
|
11779
|
-
)} in ${rawBarrelDir}.`
|
|
11780
|
-
);
|
|
11781
|
-
}
|
|
11782
|
-
optBarrels[barrel].jungleFiles.push(...rawJungles);
|
|
11783
|
-
return promise;
|
|
11784
|
-
},
|
|
11785
|
-
promise
|
|
11786
|
-
);
|
|
11787
|
-
}, Promise.resolve());
|
|
11709
|
+
if (targets.every((target) => !target.group?.optimizerConfig.barrelMap ||
|
|
11710
|
+
Object.values(target.group.optimizerConfig.barrelMap).every((resolvedBarrel) => !resolvedBarrel.qualifier.resourcePath))) {
|
|
11711
|
+
// there are no barrels, or every barrel has no resources.
|
|
11712
|
+
// we can drop any barrels altogether (we'll need to drop them
|
|
11713
|
+
// from the manifest file too).
|
|
11714
|
+
return null;
|
|
11715
|
+
}
|
|
11716
|
+
// where to create the local barrel projects.
|
|
11717
|
+
const barrelDir = external_path_.resolve(options.workspace, options.outputPath, "opt-barrels");
|
|
11718
|
+
return targets.reduce((promise, target) => {
|
|
11719
|
+
if (!target.group)
|
|
11720
|
+
return promise;
|
|
11721
|
+
const barrelMap = target.group.optimizerConfig.barrelMap;
|
|
11722
|
+
if (!barrelMap || target.group.optimizerConfig.optBarrels) {
|
|
11723
|
+
return promise;
|
|
11724
|
+
}
|
|
11725
|
+
const optBarrels = (target.group.optimizerConfig.optBarrels = {});
|
|
11726
|
+
return Object.entries(barrelMap).reduce((promise, [barrel, resolvedBarrel]) => {
|
|
11727
|
+
const { manifest, jungles } = resolvedBarrel;
|
|
11728
|
+
const rawBarrelDir = external_path_.dirname(jungles[0]);
|
|
11729
|
+
const rawJungles = jungles.map((jungle) => external_path_.relative(rawBarrelDir, jungle));
|
|
11730
|
+
const sha1 = external_crypto_namespaceObject.createHash("sha1")
|
|
11731
|
+
.update(rawBarrelDir, "binary")
|
|
11732
|
+
.digest("base64")
|
|
11733
|
+
.replace(/[\/=+]/g, "");
|
|
11734
|
+
const optBarrelDir = external_path_.resolve(barrelDir, `${barrel}-${sha1}`);
|
|
11735
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(optBarrels, barrel)) {
|
|
11736
|
+
optBarrels[barrel] = {
|
|
11737
|
+
rawBarrelDir,
|
|
11738
|
+
manifest,
|
|
11739
|
+
jungleFiles: [...rawJungles],
|
|
11740
|
+
optBarrelDir,
|
|
11741
|
+
};
|
|
11742
|
+
return promise.then(() => (0,external_util_cjs_namespaceObject.copyRecursiveAsNeeded)(rawBarrelDir, optBarrelDir, (src) => !src.endsWith(".mc")));
|
|
11743
|
+
}
|
|
11744
|
+
if (optBarrels[barrel].manifest !== manifest ||
|
|
11745
|
+
optBarrels[barrel].optBarrelDir !== optBarrelDir ||
|
|
11746
|
+
optBarrels[barrel].rawBarrelDir != rawBarrelDir) {
|
|
11747
|
+
throw new Error(`For device ${target.product}, barrel ${barrel} was mapped to both ${external_path_.relative(optBarrels[barrel].rawBarrelDir, optBarrels[barrel].manifest)} in ${optBarrels[barrel].rawBarrelDir} and ${external_path_.relative(rawBarrelDir, manifest)} in ${rawBarrelDir}.`);
|
|
11748
|
+
}
|
|
11749
|
+
optBarrels[barrel].jungleFiles.push(...rawJungles);
|
|
11750
|
+
return promise;
|
|
11751
|
+
}, promise);
|
|
11752
|
+
}, Promise.resolve());
|
|
11788
11753
|
}
|
|
11789
|
-
|
|
11790
11754
|
async function generateOptimizedProject(options) {
|
|
11791
|
-
|
|
11792
|
-
|
|
11793
|
-
|
|
11794
|
-
|
|
11795
|
-
|
|
11796
|
-
|
|
11797
|
-
|
|
11798
|
-
|
|
11799
|
-
|
|
11800
|
-
|
|
11801
|
-
|
|
11802
|
-
|
|
11803
|
-
|
|
11804
|
-
|
|
11805
|
-
|
|
11806
|
-
|
|
11807
|
-
|
|
11808
|
-
|
|
11809
|
-
|
|
11810
|
-
|
|
11811
|
-
|
|
11812
|
-
|
|
11813
|
-
|
|
11814
|
-
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
|
|
11818
|
-
|
|
11819
|
-
const key = configKey(p);
|
|
11820
|
-
if (!(0,external_api_cjs_namespaceObject.hasProperty)(buildConfigs, key)) {
|
|
11821
|
-
p.group.dir = key;
|
|
11822
|
-
if (
|
|
11823
|
-
p.group.optimizerConfig.barrelMap &&
|
|
11824
|
-
!p.group.optimizerConfig.optBarrels
|
|
11825
|
-
) {
|
|
11826
|
-
dropBarrels = true;
|
|
11827
|
-
}
|
|
11828
|
-
buildConfigs[key] = null;
|
|
11829
|
-
}
|
|
11830
|
-
if (
|
|
11831
|
-
pick_one >= 0 ||
|
|
11832
|
-
!options.products ||
|
|
11833
|
-
options.products.includes(p.product) ||
|
|
11834
|
-
(p.shape && options.products.includes(p.shape))
|
|
11835
|
-
) {
|
|
11836
|
-
if (pick_one >= 0) {
|
|
11837
|
-
// don't modify the original array since it may be shared
|
|
11838
|
-
// (and *is* shared when we're called from test.js)
|
|
11839
|
-
options.products = [...options.products];
|
|
11840
|
-
options.products[pick_one] = p.product;
|
|
11841
|
-
pick_one = -1;
|
|
11842
|
-
}
|
|
11843
|
-
if (!buildConfigs[key]) {
|
|
11844
|
-
buildConfigs[key] = p.group.optimizerConfig;
|
|
11845
|
-
products[key] = [];
|
|
11846
|
-
}
|
|
11847
|
-
products[key].push(p.product);
|
|
11755
|
+
const config = await getConfig(options);
|
|
11756
|
+
const workspace = config.workspace;
|
|
11757
|
+
const { manifest, targets, xml, jungles } = await get_jungle(config.jungleFiles, config);
|
|
11758
|
+
if (!xml["iq:manifest"]["iq:application"]) {
|
|
11759
|
+
const error = new Error(xml["iq:manifest"]["iq:barrel"]
|
|
11760
|
+
? "Optimize the project that uses this barrel, not the barrel itself"
|
|
11761
|
+
: "Manifest is missing an `iq:application` tag");
|
|
11762
|
+
error.location = {
|
|
11763
|
+
start: { line: 1, column: 1 },
|
|
11764
|
+
end: { line: 1, column: 1 },
|
|
11765
|
+
source: manifest,
|
|
11766
|
+
};
|
|
11767
|
+
throw error;
|
|
11768
|
+
}
|
|
11769
|
+
const dependencyFiles = [manifest, ...jungles];
|
|
11770
|
+
await createLocalBarrels(targets, options);
|
|
11771
|
+
const buildConfigs = {};
|
|
11772
|
+
const products = {};
|
|
11773
|
+
let pick_one = config.products ? config.products.indexOf("pick-one") : -1;
|
|
11774
|
+
if (config.skipOptimization) {
|
|
11775
|
+
if (pick_one >= 0) {
|
|
11776
|
+
options.products = [...options.products];
|
|
11777
|
+
options.products[pick_one] = targets[0].product;
|
|
11778
|
+
}
|
|
11779
|
+
return {
|
|
11780
|
+
jungleFiles: config.jungleFiles,
|
|
11781
|
+
program: external_path_.basename(external_path_.dirname(manifest)),
|
|
11782
|
+
};
|
|
11848
11783
|
}
|
|
11849
|
-
|
|
11850
|
-
|
|
11851
|
-
|
|
11852
|
-
|
|
11853
|
-
|
|
11854
|
-
|
|
11855
|
-
|
|
11856
|
-
|
|
11857
|
-
|
|
11858
|
-
|
|
11859
|
-
|
|
11860
|
-
|
|
11861
|
-
targets.map((t) => t.product)
|
|
11862
|
-
))) &&
|
|
11863
|
-
!dropBarrels;
|
|
11864
|
-
const promises = Object.keys(buildConfigs)
|
|
11865
|
-
.sort()
|
|
11866
|
-
.map((key) => {
|
|
11867
|
-
const buildConfig = buildConfigs[key];
|
|
11868
|
-
const outputPath = external_path_.join(config.outputPath, key);
|
|
11869
|
-
|
|
11870
|
-
return buildConfig
|
|
11871
|
-
? generateOneConfig({
|
|
11872
|
-
...config,
|
|
11873
|
-
buildConfig,
|
|
11874
|
-
outputPath,
|
|
11875
|
-
dependencyFiles,
|
|
11876
|
-
}).catch((e) => {
|
|
11877
|
-
if (!e.stack) {
|
|
11878
|
-
e = new Error(e.toString());
|
|
11784
|
+
let dropBarrels = false;
|
|
11785
|
+
const configKey = (p) => p.group.key + (config.releaseBuild ? "-release" : "-debug");
|
|
11786
|
+
targets.forEach((p) => {
|
|
11787
|
+
if (!p.group) {
|
|
11788
|
+
throw new Error(`Missing group in build target ${p.product}`);
|
|
11789
|
+
}
|
|
11790
|
+
const key = configKey(p);
|
|
11791
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(buildConfigs, key)) {
|
|
11792
|
+
p.group.dir = key;
|
|
11793
|
+
if (p.group.optimizerConfig.barrelMap &&
|
|
11794
|
+
!p.group.optimizerConfig.optBarrels) {
|
|
11795
|
+
dropBarrels = true;
|
|
11879
11796
|
}
|
|
11880
|
-
|
|
11881
|
-
|
|
11882
|
-
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
11797
|
+
buildConfigs[key] = null;
|
|
11798
|
+
}
|
|
11799
|
+
if (pick_one >= 0 ||
|
|
11800
|
+
!options.products ||
|
|
11801
|
+
options.products.includes(p.product) ||
|
|
11802
|
+
(p.shape && options.products.includes(p.shape))) {
|
|
11803
|
+
if (pick_one >= 0) {
|
|
11804
|
+
// don't modify the original array since it may be shared
|
|
11805
|
+
// (and *is* shared when we're called from test.js)
|
|
11806
|
+
options.products = [...options.products];
|
|
11807
|
+
options.products[pick_one] = p.product;
|
|
11808
|
+
pick_one = -1;
|
|
11809
|
+
}
|
|
11810
|
+
if (!buildConfigs[key]) {
|
|
11811
|
+
buildConfigs[key] = p.group.optimizerConfig;
|
|
11812
|
+
products[key] = [];
|
|
11813
|
+
}
|
|
11814
|
+
products[key].push(p.product);
|
|
11815
|
+
}
|
|
11887
11816
|
});
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
const
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
|
|
11897
|
-
|
|
11898
|
-
|
|
11899
|
-
|
|
11900
|
-
|
|
11901
|
-
|
|
11902
|
-
|
|
11903
|
-
|
|
11904
|
-
|
|
11905
|
-
|
|
11906
|
-
|
|
11907
|
-
|
|
11908
|
-
|
|
11909
|
-
|
|
11910
|
-
|
|
11911
|
-
|
|
11912
|
-
|
|
11913
|
-
|
|
11914
|
-
|
|
11915
|
-
|
|
11916
|
-
|
|
11917
|
-
|
|
11918
|
-
|
|
11919
|
-
|
|
11920
|
-
|
|
11921
|
-
|
|
11922
|
-
(
|
|
11923
|
-
|
|
11817
|
+
// console.log(JSON.stringify(targets));
|
|
11818
|
+
const jungle_dir = external_path_.resolve(workspace, config.outputPath);
|
|
11819
|
+
await promises_namespaceObject.mkdir(jungle_dir, { recursive: true });
|
|
11820
|
+
const relative_path = (s) => external_path_.relative(jungle_dir, s);
|
|
11821
|
+
let relative_manifest = relative_path(manifest);
|
|
11822
|
+
const manifestOk = (!config.checkManifest ||
|
|
11823
|
+
(await checkManifest(xml, targets.map((t) => t.product)))) &&
|
|
11824
|
+
!dropBarrels;
|
|
11825
|
+
let hasTests = false;
|
|
11826
|
+
const promises = Object.keys(buildConfigs)
|
|
11827
|
+
.sort()
|
|
11828
|
+
.map((key) => {
|
|
11829
|
+
const buildConfig = buildConfigs[key];
|
|
11830
|
+
const outputPath = external_path_.join(config.outputPath, key);
|
|
11831
|
+
return buildConfig
|
|
11832
|
+
? generateOneConfig(buildConfig, dependencyFiles, {
|
|
11833
|
+
...config,
|
|
11834
|
+
outputPath,
|
|
11835
|
+
})
|
|
11836
|
+
.catch((e) => {
|
|
11837
|
+
if (!e.stack) {
|
|
11838
|
+
e = new Error(e.toString());
|
|
11839
|
+
}
|
|
11840
|
+
e.products = products[key];
|
|
11841
|
+
throw e;
|
|
11842
|
+
})
|
|
11843
|
+
.then((t) => t && (hasTests = true))
|
|
11844
|
+
: promises_namespaceObject.rm(external_path_.resolve(workspace, outputPath), {
|
|
11845
|
+
recursive: true,
|
|
11846
|
+
force: true,
|
|
11847
|
+
});
|
|
11848
|
+
});
|
|
11849
|
+
if (!manifestOk) {
|
|
11850
|
+
if (dropBarrels) {
|
|
11851
|
+
manifestDropBarrels(xml);
|
|
11852
|
+
}
|
|
11853
|
+
const manifestFile = external_path_.join(jungle_dir, "manifest.xml");
|
|
11854
|
+
promises.push(writeManifest(manifestFile, xml));
|
|
11855
|
+
relative_manifest = "manifest.xml";
|
|
11856
|
+
}
|
|
11857
|
+
const parts = [`project.manifest=${relative_manifest}`];
|
|
11858
|
+
const process_field = (prefix, base, name, mapper = null) => {
|
|
11859
|
+
const obj = base[name];
|
|
11860
|
+
if (!obj)
|
|
11861
|
+
return;
|
|
11862
|
+
const map_one = (s) => (mapper ? mapper(s) : s);
|
|
11863
|
+
const map = (s) => Array.isArray(s) ? `[${s.map(map_one).join(";")}]` : map_one(s);
|
|
11864
|
+
parts.push(`${prefix}${name} = ${obj.map(map).join(";")}`);
|
|
11865
|
+
};
|
|
11866
|
+
targets.forEach((target) => {
|
|
11867
|
+
if (!buildConfigs[configKey(target)])
|
|
11868
|
+
return;
|
|
11869
|
+
const { product, qualifier, group } = target;
|
|
11870
|
+
if (!group) {
|
|
11871
|
+
throw new Error(`Missing group in target ${target.product}`);
|
|
11872
|
+
}
|
|
11873
|
+
const prefix = `${product}.`;
|
|
11874
|
+
process_field(prefix, qualifier, "sourcePath", (s) => external_path_.join(group.dir, "source", relative_path_no_dotdot(external_path_.relative(workspace, s)))
|
|
11875
|
+
.replace(/([\\\/]\*\*)[\\\/]\*/g, "$1"));
|
|
11876
|
+
if (group.optimizerConfig.optBarrels) {
|
|
11877
|
+
parts.push(`${prefix}barrelPath = ${Object.values(group.optimizerConfig.optBarrels)
|
|
11878
|
+
.map((value) => `[${value.jungleFiles
|
|
11924
11879
|
.map((j) => relative_path(external_path_.join(value.optBarrelDir, j)))
|
|
11925
|
-
.join(";")}]`
|
|
11926
|
-
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
|
|
11930
|
-
|
|
11931
|
-
|
|
11932
|
-
`${prefix}sourcePath = ${[`$(${prefix}sourcePath)`]
|
|
11933
|
-
.concat(
|
|
11934
|
-
Object.entries(group.optimizerConfig.barrelMap)
|
|
11935
|
-
.map(([barrel, resolvedBarrel]) => {
|
|
11880
|
+
.join(";")}]`)
|
|
11881
|
+
.join(";")}`);
|
|
11882
|
+
}
|
|
11883
|
+
if (group.optimizerConfig.barrelMap) {
|
|
11884
|
+
parts.push(`${prefix}sourcePath = ${[`$(${prefix}sourcePath)`]
|
|
11885
|
+
.concat(Object.entries(group.optimizerConfig.barrelMap)
|
|
11886
|
+
.map(([barrel, resolvedBarrel]) => {
|
|
11936
11887
|
const root = external_path_.dirname(resolvedBarrel.jungles[0]);
|
|
11937
|
-
return (resolvedBarrel.qualifier.sourcePath || []).map((s) =>
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
)
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
|
|
11949
|
-
|
|
11950
|
-
|
|
11951
|
-
|
|
11952
|
-
|
|
11953
|
-
|
|
11954
|
-
|
|
11955
|
-
|
|
11956
|
-
|
|
11957
|
-
|
|
11958
|
-
|
|
11959
|
-
|
|
11960
|
-
|
|
11961
|
-
|
|
11962
|
-
|
|
11963
|
-
|
|
11964
|
-
|
|
11965
|
-
await Promise.all(promises);
|
|
11966
|
-
return {
|
|
11967
|
-
jungleFiles,
|
|
11968
|
-
program: external_path_.basename(external_path_.dirname(manifest)),
|
|
11969
|
-
};
|
|
11888
|
+
return (resolvedBarrel.qualifier.sourcePath || []).map((s) => external_path_.join(group.dir, "barrels", barrel, external_path_.relative(root, s))
|
|
11889
|
+
.replace(/([\\\/]\*\*)[\\\/]\*/g, "$1"));
|
|
11890
|
+
})
|
|
11891
|
+
.flat()
|
|
11892
|
+
.sort()
|
|
11893
|
+
.filter((s, i, arr) => !i || s !== arr[i - 1]))
|
|
11894
|
+
.join(";")}`);
|
|
11895
|
+
}
|
|
11896
|
+
// annotations were handled via source transformations.
|
|
11897
|
+
process_field(prefix, qualifier, "resourcePath", relative_path);
|
|
11898
|
+
process_field(prefix, qualifier, "excludeAnnotations");
|
|
11899
|
+
const qlang = qualifier.lang;
|
|
11900
|
+
if (qlang) {
|
|
11901
|
+
Object.keys(qlang).forEach((key) => {
|
|
11902
|
+
process_field(`${prefix}lang.`, qlang, key, relative_path);
|
|
11903
|
+
});
|
|
11904
|
+
}
|
|
11905
|
+
});
|
|
11906
|
+
const jungleFiles = external_path_.join(jungle_dir, `${config.releaseBuild ? "release" : "debug"}.jungle`);
|
|
11907
|
+
promises.push(promises_namespaceObject.writeFile(jungleFiles, parts.join("\n")));
|
|
11908
|
+
await Promise.all(promises);
|
|
11909
|
+
return {
|
|
11910
|
+
jungleFiles,
|
|
11911
|
+
xml,
|
|
11912
|
+
program: external_path_.basename(external_path_.dirname(manifest)),
|
|
11913
|
+
hasTests,
|
|
11914
|
+
};
|
|
11970
11915
|
}
|
|
11971
|
-
|
|
11972
|
-
|
|
11973
|
-
|
|
11974
|
-
|
|
11975
|
-
|
|
11976
|
-
|
|
11977
|
-
)
|
|
11978
|
-
const paths = (
|
|
11979
|
-
await Promise.all(
|
|
11980
|
-
buildConfig.sourcePath.map((pattern) =>
|
|
11981
|
-
(0,external_util_cjs_namespaceObject.globa)(pattern, { cwd: workspace, mark: true })
|
|
11982
|
-
)
|
|
11983
|
-
)
|
|
11984
|
-
).flat();
|
|
11985
|
-
|
|
11986
|
-
const files = (
|
|
11987
|
-
await Promise.all(
|
|
11988
|
-
paths.map((path) =>
|
|
11989
|
-
path.endsWith("/")
|
|
11990
|
-
? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.mc`, { cwd: workspace, mark: true })
|
|
11991
|
-
: path
|
|
11992
|
-
)
|
|
11993
|
-
)
|
|
11994
|
-
)
|
|
11995
|
-
.flat()
|
|
11996
|
-
.filter(
|
|
11997
|
-
(file) =>
|
|
11998
|
-
file.endsWith(".mc") &&
|
|
11916
|
+
async function fileInfoFromConfig(workspace, output, buildConfig, extraExcludes) {
|
|
11917
|
+
const paths = (await Promise.all(buildConfig.sourcePath?.map((pattern) => (0,external_util_cjs_namespaceObject.globa)(pattern, { cwd: workspace, mark: true })) || [])).flat();
|
|
11918
|
+
const files = (await Promise.all(paths.map((path) => path.endsWith("/")
|
|
11919
|
+
? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.mc`, { cwd: workspace, mark: true })
|
|
11920
|
+
: path)))
|
|
11921
|
+
.flat()
|
|
11922
|
+
.filter((file) => file.endsWith(".mc") &&
|
|
11999
11923
|
!external_path_.relative(workspace, file).startsWith("bin") &&
|
|
12000
11924
|
(!buildConfig.sourceExcludes ||
|
|
12001
|
-
|
|
12002
|
-
|
|
12003
|
-
|
|
12004
|
-
|
|
12005
|
-
|
|
12006
|
-
|
|
12007
|
-
|
|
12008
|
-
|
|
12009
|
-
|
|
12010
|
-
|
|
12011
|
-
|
|
12012
|
-
|
|
12013
|
-
|
|
12014
|
-
|
|
12015
|
-
file,
|
|
12016
|
-
{
|
|
12017
|
-
output: external_path_.join(
|
|
12018
|
-
output,
|
|
12019
|
-
relative_path_no_dotdot(external_path_.relative(workspace, file))
|
|
12020
|
-
),
|
|
12021
|
-
excludeAnnotations,
|
|
12022
|
-
},
|
|
12023
|
-
])
|
|
12024
|
-
);
|
|
11925
|
+
!buildConfig.sourceExcludes.includes(file)));
|
|
11926
|
+
const excludeAnnotations = Object.assign(buildConfig.excludeAnnotations
|
|
11927
|
+
? Object.fromEntries(buildConfig.excludeAnnotations.map((ex) => [ex, true]))
|
|
11928
|
+
: {}, extraExcludes);
|
|
11929
|
+
return {
|
|
11930
|
+
fnMap: Object.fromEntries(files.map((file) => [
|
|
11931
|
+
file,
|
|
11932
|
+
{
|
|
11933
|
+
output: external_path_.join(output, relative_path_no_dotdot(external_path_.relative(workspace, file))),
|
|
11934
|
+
excludeAnnotations,
|
|
11935
|
+
},
|
|
11936
|
+
])),
|
|
11937
|
+
paths: paths.filter((path) => path.endsWith("/")),
|
|
11938
|
+
};
|
|
12025
11939
|
}
|
|
12026
|
-
|
|
12027
11940
|
function excludesFromAnnotations(barrel, annotations, resolvedBarrel) {
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
|
|
12031
|
-
|
|
12032
|
-
|
|
12033
|
-
|
|
12034
|
-
|
|
12035
|
-
|
|
12036
|
-
|
|
11941
|
+
const excludes = resolvedBarrel.annotations
|
|
11942
|
+
? Object.fromEntries(resolvedBarrel.annotations.map((a) => [a, true]))
|
|
11943
|
+
: {};
|
|
11944
|
+
if (annotations && annotations[barrel]) {
|
|
11945
|
+
annotations[barrel].forEach((a) => {
|
|
11946
|
+
delete excludes[a];
|
|
11947
|
+
});
|
|
11948
|
+
}
|
|
11949
|
+
return excludes;
|
|
12037
11950
|
}
|
|
12038
|
-
|
|
12039
|
-
|
|
12040
|
-
|
|
12041
|
-
|
|
12042
|
-
|
|
12043
|
-
|
|
12044
|
-
|
|
12045
|
-
|
|
12046
|
-
|
|
12047
|
-
|
|
12048
|
-
|
|
12049
|
-
|
|
12050
|
-
|
|
12051
|
-
|
|
12052
|
-
|
|
12053
|
-
|
|
12054
|
-
|
|
12055
|
-
|
|
12056
|
-
|
|
12057
|
-
|
|
12058
|
-
|
|
12059
|
-
|
|
12060
|
-
|
|
12061
|
-
|
|
12062
|
-
|
|
12063
|
-
|
|
12064
|
-
|
|
12065
|
-
|
|
12066
|
-
|
|
12067
|
-
|
|
12068
|
-
resolvedBarrel.qualifier,
|
|
12069
|
-
|
|
12070
|
-
|
|
12071
|
-
|
|
12072
|
-
barrel,
|
|
12073
|
-
buildConfig.annotations,
|
|
12074
|
-
resolvedBarrel
|
|
12075
|
-
),
|
|
12076
|
-
}
|
|
12077
|
-
);
|
|
11951
|
+
const configOptionsToCheck = [
|
|
11952
|
+
"workspace",
|
|
11953
|
+
"releaseBuild",
|
|
11954
|
+
"testBuild",
|
|
11955
|
+
"checkManifest",
|
|
11956
|
+
"ignoredExcludeAnnotations",
|
|
11957
|
+
"ignoredAnnotations",
|
|
11958
|
+
"ignoredSourcePaths",
|
|
11959
|
+
];
|
|
11960
|
+
/**
|
|
11961
|
+
* @param {BuildConfig} config
|
|
11962
|
+
* @param {*} buildConfig
|
|
11963
|
+
* @param {string[]} dependencyFiles
|
|
11964
|
+
* @returns
|
|
11965
|
+
*/
|
|
11966
|
+
async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
11967
|
+
const { workspace } = config;
|
|
11968
|
+
const output = external_path_.join(workspace, config.outputPath);
|
|
11969
|
+
const buildModeExcludes = {
|
|
11970
|
+
// note: exclude debug in release builds, and release in debug builds
|
|
11971
|
+
[config.releaseBuild ? "debug" : "release"]: true,
|
|
11972
|
+
};
|
|
11973
|
+
if (!config.testBuild) {
|
|
11974
|
+
buildModeExcludes.test = true;
|
|
11975
|
+
}
|
|
11976
|
+
const { fnMap } = await fileInfoFromConfig(workspace, external_path_.join(output, "source"), buildConfig, buildModeExcludes);
|
|
11977
|
+
if (buildConfig.barrelMap) {
|
|
11978
|
+
const barrelFnMaps = await Promise.all(Object.entries(buildConfig.barrelMap)
|
|
11979
|
+
.map(([barrel, resolvedBarrel]) => {
|
|
11980
|
+
dependencyFiles = dependencyFiles.concat(resolvedBarrel.jungles, resolvedBarrel.manifest);
|
|
11981
|
+
return fileInfoFromConfig(external_path_.dirname(resolvedBarrel.jungles[0]), external_path_.join(output, "barrels", barrel), resolvedBarrel.qualifier, {
|
|
11982
|
+
...buildModeExcludes,
|
|
11983
|
+
...excludesFromAnnotations(barrel, buildConfig.annotations, resolvedBarrel),
|
|
11984
|
+
}).then(({ fnMap }) => fnMap);
|
|
12078
11985
|
})
|
|
11986
|
+
.flat());
|
|
11987
|
+
barrelFnMaps.forEach((barrelFnMap) => Object.assign(fnMap, barrelFnMap));
|
|
11988
|
+
}
|
|
11989
|
+
const actualOptimizedFiles = (await (0,external_util_cjs_namespaceObject.globa)(external_path_.join(output, "**", "*.mc"), { mark: true }))
|
|
11990
|
+
.filter((file) => !file.endsWith("/"))
|
|
11991
|
+
.sort();
|
|
11992
|
+
const { hasTests, ...prevOptions } = JSON.parse(await promises_namespaceObject.readFile(external_path_.join(output, "build-info.json"), "utf-8")
|
|
11993
|
+
.catch(() => "{}"));
|
|
11994
|
+
// check that the set of files thats actually there is the same as the
|
|
11995
|
+
// set of files we're going to generate (in case eg a jungle file change
|
|
11996
|
+
// might have altered it), and that the options we care about haven't
|
|
11997
|
+
// changed
|
|
11998
|
+
if (hasTests != null &&
|
|
11999
|
+
configOptionsToCheck.every((option) => prevOptions[option] === config[option]) &&
|
|
12000
|
+
actualOptimizedFiles.length == Object.values(fnMap).length &&
|
|
12001
|
+
Object.values(fnMap)
|
|
12002
|
+
.map((v) => v.output)
|
|
12003
|
+
.sort()
|
|
12004
|
+
.every((f, i) => f == actualOptimizedFiles[i])) {
|
|
12005
|
+
// now if the newest source file is older than
|
|
12006
|
+
// the oldest optimized file, we don't need to regenerate
|
|
12007
|
+
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
12008
|
+
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
12009
|
+
if (source_time < opt_time && 1653671578547 < opt_time) {
|
|
12010
|
+
return hasTests;
|
|
12011
|
+
}
|
|
12012
|
+
}
|
|
12013
|
+
await promises_namespaceObject.rm(output, { recursive: true, force: true });
|
|
12014
|
+
await promises_namespaceObject.mkdir(output, { recursive: true });
|
|
12015
|
+
await optimizeMonkeyC(fnMap);
|
|
12016
|
+
return Promise.all(Object.values(fnMap).map(async (info) => {
|
|
12017
|
+
const name = info.output;
|
|
12018
|
+
const dir = external_path_.dirname(name);
|
|
12019
|
+
await promises_namespaceObject.mkdir(dir, { recursive: true });
|
|
12020
|
+
const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(info.ast, info.monkeyCSource);
|
|
12021
|
+
await promises_namespaceObject.writeFile(name, opt_source);
|
|
12022
|
+
return info.hasTests;
|
|
12023
|
+
})).then((results) => {
|
|
12024
|
+
const hasTests = results.some((v) => v);
|
|
12025
|
+
return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
|
|
12026
|
+
hasTests,
|
|
12027
|
+
...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
|
|
12028
|
+
}))
|
|
12029
|
+
.then(() => hasTests);
|
|
12030
|
+
});
|
|
12031
|
+
}
|
|
12032
|
+
async function getProjectAnalysis(targets, analysis, options) {
|
|
12033
|
+
const sourcePath = targets
|
|
12034
|
+
.map(({ qualifier: { sourcePath } }) => sourcePath)
|
|
12035
|
+
.filter((sp) => sp != null)
|
|
12079
12036
|
.flat()
|
|
12080
|
-
|
|
12081
|
-
|
|
12082
|
-
|
|
12083
|
-
|
|
12084
|
-
|
|
12085
|
-
|
|
12086
|
-
|
|
12087
|
-
|
|
12088
|
-
|
|
12089
|
-
|
|
12090
|
-
|
|
12091
|
-
|
|
12092
|
-
|
|
12093
|
-
|
|
12094
|
-
|
|
12095
|
-
|
|
12096
|
-
|
|
12097
|
-
|
|
12098
|
-
|
|
12099
|
-
) {
|
|
12100
|
-
// now if the newest source file is older than
|
|
12101
|
-
// the oldest optimized file, we don't need to regenerate
|
|
12102
|
-
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(
|
|
12103
|
-
Object.keys(fnMap).concat(dependencyFiles)
|
|
12104
|
-
);
|
|
12105
|
-
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(
|
|
12106
|
-
Object.values(fnMap).map((v) => v.output)
|
|
12107
|
-
);
|
|
12108
|
-
if (source_time < opt_time && 1652050734499 < opt_time) return;
|
|
12109
|
-
}
|
|
12110
|
-
|
|
12111
|
-
await promises_namespaceObject.rm(output, { recursive: true, force: true });
|
|
12112
|
-
await promises_namespaceObject.mkdir(output, { recursive: true });
|
|
12113
|
-
const optFiles = await optimizeMonkeyC(fnMap);
|
|
12114
|
-
return await Promise.all(
|
|
12115
|
-
optFiles.map(async (file) => {
|
|
12116
|
-
const name = fnMap[file.name].output;
|
|
12117
|
-
const dir = external_path_.dirname(name);
|
|
12118
|
-
await promises_namespaceObject.mkdir(dir, { recursive: true });
|
|
12119
|
-
|
|
12120
|
-
const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(file.ast);
|
|
12121
|
-
await promises_namespaceObject.writeFile(name, opt_source);
|
|
12122
|
-
return name;
|
|
12123
|
-
})
|
|
12124
|
-
);
|
|
12037
|
+
.sort()
|
|
12038
|
+
.filter((s, i, arr) => !i || s !== arr[i - 1]);
|
|
12039
|
+
const { fnMap, paths } = await fileInfoFromConfig(options.workspace, options.workspace, { sourcePath }, {});
|
|
12040
|
+
if (analysis) {
|
|
12041
|
+
Object.entries(fnMap).forEach(([k, v]) => {
|
|
12042
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(analysis.fnMap, k)) {
|
|
12043
|
+
const old = analysis.fnMap[k];
|
|
12044
|
+
if (old.monkeyCSource)
|
|
12045
|
+
v.monkeyCSource = old.monkeyCSource;
|
|
12046
|
+
if (old.ast)
|
|
12047
|
+
v.ast = old.ast;
|
|
12048
|
+
}
|
|
12049
|
+
});
|
|
12050
|
+
}
|
|
12051
|
+
if (!(await getFileASTs(fnMap))) {
|
|
12052
|
+
return { fnMap, paths };
|
|
12053
|
+
}
|
|
12054
|
+
const state = await analyze(fnMap);
|
|
12055
|
+
return { fnMap: fnMap, paths, state };
|
|
12125
12056
|
}
|
|
12126
|
-
|
|
12057
|
+
/**
|
|
12058
|
+
*
|
|
12059
|
+
* @param {BuildConfig} options
|
|
12060
|
+
* @returns
|
|
12061
|
+
*/
|
|
12127
12062
|
async function generateApiMirTests(options) {
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
|
|
12134
|
-
|
|
12135
|
-
|
|
12136
|
-
|
|
12137
|
-
|
|
12138
|
-
|
|
12139
|
-
|
|
12140
|
-
|
|
12141
|
-
|
|
12142
|
-
|
|
12143
|
-
|
|
12144
|
-
|
|
12145
|
-
|
|
12146
|
-
|
|
12147
|
-
|
|
12148
|
-
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
|
|
12152
|
-
|
|
12153
|
-
|
|
12154
|
-
|
|
12155
|
-
|
|
12156
|
-
|
|
12157
|
-
|
|
12158
|
-
|
|
12159
|
-
|
|
12160
|
-
|
|
12161
|
-
|
|
12162
|
-
|
|
12163
|
-
|
|
12164
|
-
|
|
12165
|
-
|
|
12166
|
-
|
|
12167
|
-
|
|
12063
|
+
const config = { ...defaultConfig, ...(options || {}) };
|
|
12064
|
+
const tests = [];
|
|
12065
|
+
const api = await (0,external_api_cjs_namespaceObject.getApiMapping)();
|
|
12066
|
+
if (!api) {
|
|
12067
|
+
throw new Error("Failed to read api.mir");
|
|
12068
|
+
}
|
|
12069
|
+
const findConstants = (node) => {
|
|
12070
|
+
node.decls &&
|
|
12071
|
+
Object.entries(node.decls).forEach(([key, decl]) => {
|
|
12072
|
+
if (decl.length > 1)
|
|
12073
|
+
throw `Bad decl length:${node.fullName}.${key}`;
|
|
12074
|
+
if (decl.length != 1)
|
|
12075
|
+
return;
|
|
12076
|
+
const d = decl[0];
|
|
12077
|
+
if (d.type === "EnumStringMember" ||
|
|
12078
|
+
(d.type === "VariableDeclarator" && d.kind === "const")) {
|
|
12079
|
+
if (!d.init) {
|
|
12080
|
+
throw new Error(`Missing init for ${node.fullName}.${key}`);
|
|
12081
|
+
}
|
|
12082
|
+
tests.push([`${node.fullName}.${key}`, (0,external_api_cjs_namespaceObject.formatAst)(d.init)]);
|
|
12083
|
+
}
|
|
12084
|
+
else if ((0,external_api_cjs_namespaceObject.isStateNode)(d)) {
|
|
12085
|
+
findConstants(d);
|
|
12086
|
+
}
|
|
12087
|
+
});
|
|
12088
|
+
};
|
|
12089
|
+
findConstants(api);
|
|
12090
|
+
function hasTests(name) {
|
|
12091
|
+
const names = name.split(".");
|
|
12092
|
+
return names
|
|
12093
|
+
.map((t, i, arr) => arr.slice(0, i).join(".") + " has :" + t)
|
|
12094
|
+
.slice(2)
|
|
12095
|
+
.join(" && ");
|
|
12096
|
+
}
|
|
12097
|
+
const source = [
|
|
12098
|
+
"import Toybox.Lang;",
|
|
12099
|
+
"import Toybox.Test;",
|
|
12100
|
+
"(:test,:typecheck(false))",
|
|
12101
|
+
"function apiTest(logger as Logger) as Boolean {",
|
|
12102
|
+
...tests.map((t) => ` if (${hasTests(t[0])}) { if (${t[0]} != ${t[1]}) { logger.debug("${t[0]}: "+${t[0]}.toString()+" != ${t[1]}"); } } else { logger.debug("Not tested: ${t[0]}"); }`),
|
|
12103
|
+
" return true;",
|
|
12104
|
+
"}",
|
|
12105
|
+
].join("\n");
|
|
12106
|
+
const workspace = config.workspace;
|
|
12107
|
+
return promises_namespaceObject.writeFile(`${workspace}/source/apiTest.mc`, source);
|
|
12168
12108
|
}
|
|
12169
12109
|
|
|
12170
12110
|
})();
|