@markw65/monkeyc-optimizer 1.0.11 → 1.0.14

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.
@@ -1,4 +1,4 @@
1
- 0 && (module.exports = {copyRecursiveAsNeeded,launchSimulator,simulateProgram,get_jungle,mctree,defaultConfig,buildOptimizedProject,generateOptimizedProject,getProjectAnalysis,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
 
@@ -1289,7 +1289,7 @@ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
1289
1289
  const debug = __webpack_require__(1227)('extract-zip')
1290
1290
  // eslint-disable-next-line node/no-unsupported-features/node-builtins
1291
1291
  const { createWriteStream, promises: fs } = __webpack_require__(6231)
1292
- const getStream = __webpack_require__(7491)
1292
+ const getStream = __webpack_require__(31)
1293
1293
  const path = __webpack_require__(1423)
1294
1294
  const { promisify } = __webpack_require__(6464)
1295
1295
  const stream = __webpack_require__(8311)
@@ -1461,134 +1461,6 @@ module.exports = async function (zipPath, opts) {
1461
1461
  }
1462
1462
 
1463
1463
 
1464
- /***/ }),
1465
-
1466
- /***/ 2297:
1467
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
1468
-
1469
- "use strict";
1470
-
1471
- const {PassThrough: PassThroughStream} = __webpack_require__(8311);
1472
-
1473
- module.exports = options => {
1474
- options = {...options};
1475
-
1476
- const {array} = options;
1477
- let {encoding} = options;
1478
- const isBuffer = encoding === 'buffer';
1479
- let objectMode = false;
1480
-
1481
- if (array) {
1482
- objectMode = !(encoding || isBuffer);
1483
- } else {
1484
- encoding = encoding || 'utf8';
1485
- }
1486
-
1487
- if (isBuffer) {
1488
- encoding = null;
1489
- }
1490
-
1491
- const stream = new PassThroughStream({objectMode});
1492
-
1493
- if (encoding) {
1494
- stream.setEncoding(encoding);
1495
- }
1496
-
1497
- let length = 0;
1498
- const chunks = [];
1499
-
1500
- stream.on('data', chunk => {
1501
- chunks.push(chunk);
1502
-
1503
- if (objectMode) {
1504
- length = chunks.length;
1505
- } else {
1506
- length += chunk.length;
1507
- }
1508
- });
1509
-
1510
- stream.getBufferedValue = () => {
1511
- if (array) {
1512
- return chunks;
1513
- }
1514
-
1515
- return isBuffer ? Buffer.concat(chunks, length) : chunks.join('');
1516
- };
1517
-
1518
- stream.getBufferedLength = () => length;
1519
-
1520
- return stream;
1521
- };
1522
-
1523
-
1524
- /***/ }),
1525
-
1526
- /***/ 7491:
1527
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
1528
-
1529
- "use strict";
1530
-
1531
- const {constants: BufferConstants} = __webpack_require__(871);
1532
- const pump = __webpack_require__(4286);
1533
- const bufferStream = __webpack_require__(2297);
1534
-
1535
- class MaxBufferError extends Error {
1536
- constructor() {
1537
- super('maxBuffer exceeded');
1538
- this.name = 'MaxBufferError';
1539
- }
1540
- }
1541
-
1542
- async function getStream(inputStream, options) {
1543
- if (!inputStream) {
1544
- return Promise.reject(new Error('Expected a stream'));
1545
- }
1546
-
1547
- options = {
1548
- maxBuffer: Infinity,
1549
- ...options
1550
- };
1551
-
1552
- const {maxBuffer} = options;
1553
-
1554
- let stream;
1555
- await new Promise((resolve, reject) => {
1556
- const rejectPromise = error => {
1557
- // Don't retrieve an oversized buffer.
1558
- if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
1559
- error.bufferedData = stream.getBufferedValue();
1560
- }
1561
-
1562
- reject(error);
1563
- };
1564
-
1565
- stream = pump(inputStream, bufferStream(options), error => {
1566
- if (error) {
1567
- rejectPromise(error);
1568
- return;
1569
- }
1570
-
1571
- resolve();
1572
- });
1573
-
1574
- stream.on('data', () => {
1575
- if (stream.getBufferedLength() > maxBuffer) {
1576
- rejectPromise(new MaxBufferError());
1577
- }
1578
- });
1579
- });
1580
-
1581
- return stream.getBufferedValue();
1582
- }
1583
-
1584
- module.exports = getStream;
1585
- // TODO: Remove this for the next major release
1586
- module.exports["default"] = getStream;
1587
- module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'});
1588
- module.exports.array = (stream, options) => getStream(stream, {...options, array: true});
1589
- module.exports.MaxBufferError = MaxBufferError;
1590
-
1591
-
1592
1464
  /***/ }),
1593
1465
 
1594
1466
  /***/ 8913:
@@ -1892,6 +1764,134 @@ function createFromFd(fd, options) {
1892
1764
  }
1893
1765
 
1894
1766
 
1767
+ /***/ }),
1768
+
1769
+ /***/ 5105:
1770
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
1771
+
1772
+ "use strict";
1773
+
1774
+ const {PassThrough: PassThroughStream} = __webpack_require__(8311);
1775
+
1776
+ module.exports = options => {
1777
+ options = {...options};
1778
+
1779
+ const {array} = options;
1780
+ let {encoding} = options;
1781
+ const isBuffer = encoding === 'buffer';
1782
+ let objectMode = false;
1783
+
1784
+ if (array) {
1785
+ objectMode = !(encoding || isBuffer);
1786
+ } else {
1787
+ encoding = encoding || 'utf8';
1788
+ }
1789
+
1790
+ if (isBuffer) {
1791
+ encoding = null;
1792
+ }
1793
+
1794
+ const stream = new PassThroughStream({objectMode});
1795
+
1796
+ if (encoding) {
1797
+ stream.setEncoding(encoding);
1798
+ }
1799
+
1800
+ let length = 0;
1801
+ const chunks = [];
1802
+
1803
+ stream.on('data', chunk => {
1804
+ chunks.push(chunk);
1805
+
1806
+ if (objectMode) {
1807
+ length = chunks.length;
1808
+ } else {
1809
+ length += chunk.length;
1810
+ }
1811
+ });
1812
+
1813
+ stream.getBufferedValue = () => {
1814
+ if (array) {
1815
+ return chunks;
1816
+ }
1817
+
1818
+ return isBuffer ? Buffer.concat(chunks, length) : chunks.join('');
1819
+ };
1820
+
1821
+ stream.getBufferedLength = () => length;
1822
+
1823
+ return stream;
1824
+ };
1825
+
1826
+
1827
+ /***/ }),
1828
+
1829
+ /***/ 31:
1830
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
1831
+
1832
+ "use strict";
1833
+
1834
+ const {constants: BufferConstants} = __webpack_require__(871);
1835
+ const pump = __webpack_require__(4286);
1836
+ const bufferStream = __webpack_require__(5105);
1837
+
1838
+ class MaxBufferError extends Error {
1839
+ constructor() {
1840
+ super('maxBuffer exceeded');
1841
+ this.name = 'MaxBufferError';
1842
+ }
1843
+ }
1844
+
1845
+ async function getStream(inputStream, options) {
1846
+ if (!inputStream) {
1847
+ return Promise.reject(new Error('Expected a stream'));
1848
+ }
1849
+
1850
+ options = {
1851
+ maxBuffer: Infinity,
1852
+ ...options
1853
+ };
1854
+
1855
+ const {maxBuffer} = options;
1856
+
1857
+ let stream;
1858
+ await new Promise((resolve, reject) => {
1859
+ const rejectPromise = error => {
1860
+ // Don't retrieve an oversized buffer.
1861
+ if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
1862
+ error.bufferedData = stream.getBufferedValue();
1863
+ }
1864
+
1865
+ reject(error);
1866
+ };
1867
+
1868
+ stream = pump(inputStream, bufferStream(options), error => {
1869
+ if (error) {
1870
+ rejectPromise(error);
1871
+ return;
1872
+ }
1873
+
1874
+ resolve();
1875
+ });
1876
+
1877
+ stream.on('data', () => {
1878
+ if (stream.getBufferedLength() > maxBuffer) {
1879
+ rejectPromise(new MaxBufferError());
1880
+ }
1881
+ });
1882
+ });
1883
+
1884
+ return stream.getBufferedValue();
1885
+ }
1886
+
1887
+ module.exports = getStream;
1888
+ // TODO: Remove this for the next major release
1889
+ module.exports["default"] = getStream;
1890
+ module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'});
1891
+ module.exports.array = (stream, options) => getStream(stream, {...options, array: true});
1892
+ module.exports.MaxBufferError = MaxBufferError;
1893
+
1894
+
1895
1895
  /***/ }),
1896
1896
 
1897
1897
  /***/ 7824:
@@ -9829,18 +9829,22 @@ __webpack_require__.d(__webpack_exports__, {
9829
9829
  "generateOptimizedProject": () => (/* binding */ generateOptimizedProject),
9830
9830
  "getProjectAnalysis": () => (/* binding */ getProjectAnalysis),
9831
9831
  "get_jungle": () => (/* reexport */ get_jungle),
9832
+ "isErrorWithLocation": () => (/* binding */ isErrorWithLocation),
9832
9833
  "launchSimulator": () => (/* reexport */ launchSimulator),
9834
+ "manifestProducts": () => (/* reexport */ manifestProducts),
9833
9835
  "mctree": () => (/* reexport */ prettier_plugin_monkeyc_namespaceObject.mctree),
9834
9836
  "simulateProgram": () => (/* reexport */ simulateProgram)
9835
9837
  });
9836
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);
9837
9842
  ;// CONCATENATED MODULE: external "crypto"
9838
9843
  const external_crypto_namespaceObject = require("crypto");
9839
9844
  ;// CONCATENATED MODULE: external "fs/promises"
9840
9845
  const promises_namespaceObject = require("fs/promises");
9841
9846
  // EXTERNAL MODULE: external "path"
9842
9847
  var external_path_ = __webpack_require__(1423);
9843
- var external_path_default = /*#__PURE__*/__webpack_require__.n(external_path_);
9844
9848
  ;// CONCATENATED MODULE: external "./api.cjs"
9845
9849
  const external_api_cjs_namespaceObject = require("./api.cjs");
9846
9850
  ;// CONCATENATED MODULE: external "./sdk-util.cjs"
@@ -9911,7 +9915,6 @@ async function build_project(product, options, lineCallback) {
9911
9915
 
9912
9916
  // EXTERNAL MODULE: ./node_modules/extract-zip/index.js
9913
9917
  var extract_zip = __webpack_require__(2106);
9914
- var extract_zip_default = /*#__PURE__*/__webpack_require__.n(extract_zip);
9915
9918
  // EXTERNAL MODULE: ./node_modules/xml2js/lib/xml2js.js
9916
9919
  var xml2js = __webpack_require__(5055);
9917
9920
  ;// CONCATENATED MODULE: ./build/jungle.js
@@ -9932,7 +9935,7 @@ async function writeManifest(filename, xml) {
9932
9935
  function manifestProducts(manifest) {
9933
9936
  const app = manifest["iq:manifest"]["iq:application"] ||
9934
9937
  manifest["iq:manifest"]["iq:barrel"];
9935
- return ((app[0]["iq:products"] || [{}])[0]["iq:product"] || [])
9938
+ return (app?.[0]["iq:products"]?.[0]["iq:product"] || [])
9936
9939
  .map((p) => p.$.id)
9937
9940
  .sort()
9938
9941
  .filter((p, i, a) => !i || p !== a[i - 1]);
@@ -9953,7 +9956,10 @@ function manifestBarrels(manifest) {
9953
9956
  return [];
9954
9957
  }
9955
9958
  function manifestDropBarrels(manifest) {
9956
- delete manifest["iq:manifest"]["iq:application"][0]["iq:barrels"];
9959
+ const app = manifest["iq:manifest"]["iq:application"];
9960
+ if (!app)
9961
+ return;
9962
+ delete app[0]["iq:barrels"];
9957
9963
  }
9958
9964
  function manifestBarrelName(manifestName, manifest) {
9959
9965
  const barrel = manifest["iq:manifest"]["iq:barrel"];
@@ -9964,7 +9970,7 @@ function manifestBarrelName(manifestName, manifest) {
9964
9970
  function manifestAnnotations(manifest) {
9965
9971
  const barrel = manifest["iq:manifest"]["iq:barrel"];
9966
9972
  if (!barrel)
9967
- return null;
9973
+ return undefined;
9968
9974
  const annotations = barrel[0]["iq:annotations"];
9969
9975
  return annotations && annotations[0]["iq:annotation"];
9970
9976
  }
@@ -9994,9 +10000,13 @@ async function checkManifest(manifest, products) {
9994
10000
  if (JSON.stringify(allowedProducts) !=
9995
10001
  JSON.stringify(manifestProducts(manifest))) {
9996
10002
  ok = false;
9997
- elm["iq:products"][0]["iq:product"] = allowedProducts.map((id) => {
9998
- return { $: { id } };
9999
- });
10003
+ elm["iq:products"] = [
10004
+ {
10005
+ "iq:product": allowedProducts.map((id) => {
10006
+ return { $: { id } };
10007
+ }),
10008
+ },
10009
+ ];
10000
10010
  }
10001
10011
  Object.keys(elm).forEach((key) => {
10002
10012
  if (![
@@ -10067,7 +10077,8 @@ async function default_jungle() {
10067
10077
  }
10068
10078
  rezAndLang(deviceId, `resources-${deviceId}`, deviceFamily);
10069
10079
  });
10070
- return process_assignments(assignments, {});
10080
+ const state = await process_assignments(assignments, {});
10081
+ return { state, devices };
10071
10082
  }
10072
10083
  function process_assignments(assignments, current) {
10073
10084
  return assignments.reduce((state, a) => {
@@ -10081,7 +10092,7 @@ function process_assignments(assignments, current) {
10081
10092
  r.dotnames = [];
10082
10093
  }
10083
10094
  return r;
10084
- }, { node: state, dot: null, dotnames: [] });
10095
+ }, { node: state, dot: undefined, dotnames: [] });
10085
10096
  // an assignment to a node overwrites its old value
10086
10097
  Object.keys(node).forEach((k) => delete node[k]);
10087
10098
  const process_list = (values) => {
@@ -10155,7 +10166,9 @@ function evaluate_locals(assignments) {
10155
10166
  }
10156
10167
  async function parse_one(file) {
10157
10168
  const [fileName, grammarSource] = Array.isArray(file) ? file : [file, file];
10158
- const source = await promises_namespaceObject.readFile(fileName);
10169
+ const source = await promises_namespaceObject.readFile(fileName).catch(() => {
10170
+ throw new Error(`Couldn't read jungle file '${fileName}`);
10171
+ });
10159
10172
  const assignments = peg$parse(source.toString(), { grammarSource });
10160
10173
  return evaluate_locals(assignments);
10161
10174
  }
@@ -10167,9 +10180,9 @@ async function process_jungles(sources) {
10167
10180
  sources = [sources];
10168
10181
  }
10169
10182
  const results = await Promise.all(sources.map(parse_one));
10170
- const state = await default_jungle();
10183
+ const { state, devices } = await default_jungle();
10171
10184
  results.forEach((r) => process_assignments(r, state));
10172
- return state;
10185
+ return { state, devices };
10173
10186
  }
10174
10187
  function resolve_node_list(state, list) {
10175
10188
  if (!Array.isArray(list)) {
@@ -10210,24 +10223,49 @@ function check_non_leaf_dot(dot, path = null, i = 0) {
10210
10223
  // return the resolved node at path
10211
10224
  function resolve_node_by_path(state, path) {
10212
10225
  return path.reduce((s, n, i) => {
10226
+ if (!s || Array.isArray(s)) {
10227
+ return s;
10228
+ }
10213
10229
  if (!s[n] && s["."]) {
10214
10230
  const sdot = s["."];
10215
- let resolved = resolve_node_list(state, sdot)[0][n];
10216
- if (resolved == null && sdot.every((e) => e.type == "Literal")) {
10217
- // foo = string
10218
- // bar = $(foo.resourcePath)
10219
- // is supposed to work as if you'd left out the (obviously
10220
- // incorrect) ".resourcePath"
10231
+ let resolved = resolve_node_list(state, sdot);
10232
+ if (!resolved.length)
10233
+ return undefined;
10234
+ const r = resolved[0][n];
10235
+ if (!r && sdot.every((e) => e.type == "Literal")) {
10236
+ /*
10237
+ * We had something like:
10238
+ *
10239
+ * foo = whatever
10240
+ * bar = $(foo.resourcePath)
10241
+ *
10242
+ * and its supposed to work as if you'd left out the (obviously
10243
+ * incorrect) ".resourcePath"
10244
+ */
10221
10245
  return s;
10222
10246
  }
10247
+ /*
10248
+ * This is a pretty unusual edge case.
10249
+ *
10250
+ * If we do something like:
10251
+ *
10252
+ * fenix6 = $(base)
10253
+ * fenix5.sourcePath = $(fenix6.sourcePath)
10254
+ *
10255
+ * and fenix5 gets resolved before fenix6 (which it will,
10256
+ * currently, because products are resolved in lexicographical
10257
+ * order), we'll end up here when we try to resolve
10258
+ * fenix6.sourcePath.
10259
+ */
10223
10260
  check_non_leaf_dot(sdot, path, i);
10261
+ return r;
10224
10262
  }
10225
10263
  return s[n];
10226
10264
  }, state);
10227
10265
  }
10228
10266
  // fully resolve the given node, and all its children
10229
10267
  function resolve_node(state, node) {
10230
- if (node == null || Array.isArray(node)) {
10268
+ if (node === undefined || Array.isArray(node)) {
10231
10269
  // an already optimized leaf node
10232
10270
  return node;
10233
10271
  }
@@ -10266,7 +10304,7 @@ function resolve_filename(literal, default_source = null) {
10266
10304
  const root = external_path_.dirname(literal.source || default_source);
10267
10305
  return external_path_.resolve(root, literal.value);
10268
10306
  }
10269
- async function resolve_literals(qualifier, default_source) {
10307
+ async function resolve_literals(qualifier, default_source, deviceInfo) {
10270
10308
  const resolve_file_list = async (literals) => literals &&
10271
10309
  (await Promise.all(literals.map(async (v) => {
10272
10310
  if (!isJNode(v)) {
@@ -10293,9 +10331,10 @@ async function resolve_literals(qualifier, default_source) {
10293
10331
  }
10294
10332
  }))).filter((name) => name != null);
10295
10333
  const resolve_one_file_list = async (base, name) => {
10296
- if (!base[name])
10334
+ const bname = base[name];
10335
+ if (!bname)
10297
10336
  return;
10298
- const result = await resolve_file_list(base[name]);
10337
+ const result = await resolve_file_list(bname);
10299
10338
  if (!result || !result.length) {
10300
10339
  delete base[name];
10301
10340
  }
@@ -10308,7 +10347,13 @@ async function resolve_literals(qualifier, default_source) {
10308
10347
  await resolve_one_file_list(qualifier, "barrelPath");
10309
10348
  const lang = qualifier["lang"];
10310
10349
  if (lang) {
10311
- await Promise.all(Object.keys(lang).map((key) => resolve_one_file_list(lang, key)));
10350
+ await Promise.all(Object.keys(lang).map((key) => {
10351
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(deviceInfo.languages, key)) {
10352
+ delete lang[key];
10353
+ return null;
10354
+ }
10355
+ return resolve_one_file_list(lang, key);
10356
+ }));
10312
10357
  if (Object.keys(lang).length === 0)
10313
10358
  delete qualifier["lang"];
10314
10359
  }
@@ -10453,14 +10498,15 @@ function identify_optimizer_groups(targets, options) {
10453
10498
  if (excludeAnnotations && ignoredExcludeAnnotations) {
10454
10499
  excludeAnnotations = getStrsWithIgnore(excludeAnnotations, ignoredExcludeAnnotations);
10455
10500
  }
10456
- Object.entries(annotations).forEach(([key, value]) => {
10457
- if (ignoredAnnotations) {
10458
- annotations[key] = getStrsWithIgnore(value, ignoredAnnotations);
10459
- }
10460
- });
10501
+ annotations &&
10502
+ Object.entries(annotations).forEach(([key, value]) => {
10503
+ if (ignoredAnnotations) {
10504
+ annotations[key] = getStrsWithIgnore(value, ignoredAnnotations);
10505
+ }
10506
+ });
10461
10507
  if (ignoredSourcePaths) {
10462
10508
  sourcePath = sourcePath
10463
- .map((path) => Object.keys(ignoredSourcePaths[path]))
10509
+ ?.map((path) => Object.keys(ignoredSourcePaths[path]))
10464
10510
  .flat()
10465
10511
  .sort()
10466
10512
  .filter((v, i, a) => i === 0 || v !== a[i - 1]);
@@ -10556,9 +10602,11 @@ function resolve_barrel(barrel, barrelDir, products, options) {
10556
10602
  .then((localStat) => !localStat.isDirectory() ||
10557
10603
  promises_namespaceObject.stat(barrel)
10558
10604
  .then((barrelStat) => localStat.mtimeMs < barrelStat.mtimeMs), () => true)
10559
- .then((needsUpdate) => needsUpdate &&
10560
- promises_namespaceObject.rm(localPath, { recursive: true, force: true })
10561
- .then(() => extract_zip_default()(barrel, { dir: localPath }))));
10605
+ .then((needsUpdate) => {
10606
+ needsUpdate &&
10607
+ promises_namespaceObject.rm(localPath, { recursive: true, force: true })
10608
+ .then(() => extract_zip(barrel, { dir: localPath }));
10609
+ }));
10562
10610
  }
10563
10611
  return promise
10564
10612
  .then(() => get_jungle_and_barrels(rawBarrel, products, options))
@@ -10622,9 +10670,10 @@ function resolve_barrels(product, qualifier, barrels, products, options) {
10622
10670
  const name = manifestBarrelName(resolvedBarrel.manifest, resolvedBarrel.xml);
10623
10671
  if (!(0,external_api_cjs_namespaceObject.hasProperty)(barrelMap, name))
10624
10672
  return;
10625
- if (barrelMap[name]) {
10673
+ const bmapName = barrelMap[name];
10674
+ if (bmapName) {
10626
10675
  const bname = (r) => r.jungles.join(";");
10627
- throw new Error(`Barrel ${name} already resolved to ${bname(barrelMap[name])}; can't also resolve to ${bname(resolvedBarrel)}`);
10676
+ throw new Error(`Barrel ${name} already resolved to ${bname(bmapName)}; can't also resolve to ${bname(resolvedBarrel)}`);
10628
10677
  }
10629
10678
  barrelMap[name] = resolvedBarrel;
10630
10679
  });
@@ -10636,10 +10685,11 @@ function resolve_barrels(product, qualifier, barrels, products, options) {
10636
10685
  .map(([name]) => name)
10637
10686
  .join(",")}`);
10638
10687
  }
10688
+ const finalMap = barrelMap;
10639
10689
  if (!cache.barrelMap)
10640
10690
  cache.barrelMap = {};
10641
- cache.barrelMap[barrelMapKey] = barrelMap;
10642
- setBarrelMap(barrelMap);
10691
+ cache.barrelMap[barrelMapKey] = finalMap;
10692
+ setBarrelMap(finalMap);
10643
10693
  });
10644
10694
  }
10645
10695
  /**
@@ -10661,7 +10711,7 @@ async function get_jungle_and_barrels(jungleFiles, defaultProducts, options) {
10661
10711
  jungles.push(barrels_jungle);
10662
10712
  }
10663
10713
  }
10664
- const state = await process_jungles(jungles);
10714
+ const { state, devices } = await process_jungles(jungles);
10665
10715
  // apparently square_watch is an alias for rectangle_watch
10666
10716
  state["square_watch"] = state["rectangle_watch"];
10667
10717
  const manifest_node = resolve_node(state, resolve_node_by_path(state, ["project", "manifest"]));
@@ -10676,19 +10726,26 @@ async function get_jungle_and_barrels(jungleFiles, defaultProducts, options) {
10676
10726
  const barrels = manifestBarrels(xml);
10677
10727
  const annotations = manifestAnnotations(xml);
10678
10728
  const products = manifestProducts(xml);
10679
- if (products.length === 0)
10680
- products.push(...defaultProducts);
10729
+ if (products.length === 0) {
10730
+ if (defaultProducts) {
10731
+ products.push(...defaultProducts);
10732
+ }
10733
+ else if (xml["iq:manifest"]["iq:barrel"]) {
10734
+ products.push(...Object.keys(devices).sort());
10735
+ }
10736
+ }
10681
10737
  let promise = Promise.resolve();
10682
- const add_one = (product, shape = null) => {
10738
+ const add_one = (product, shape = undefined) => {
10683
10739
  const rawQualifier = resolve_node(state, state[product]);
10684
10740
  if (!rawQualifier || Array.isArray(rawQualifier))
10685
10741
  return;
10686
10742
  promise = promise
10687
- .then(() => resolve_literals(rawQualifier, manifest))
10743
+ .then(() => resolve_literals(rawQualifier, manifest, devices[product]))
10688
10744
  .then((qualifier) => {
10689
10745
  targets.push({ product, qualifier, shape });
10690
10746
  return resolve_barrels(product, qualifier, barrels, products, options);
10691
- });
10747
+ })
10748
+ .then(() => { });
10692
10749
  };
10693
10750
  products.forEach((product) => {
10694
10751
  if ((0,external_api_cjs_namespaceObject.hasProperty)(state, product)) {
@@ -10709,7 +10766,7 @@ async function get_jungle_and_barrels(jungleFiles, defaultProducts, options) {
10709
10766
  }
10710
10767
  async function get_jungle(jungles, options) {
10711
10768
  options = options || {};
10712
- const result = await get_jungle_and_barrels(jungles, [], options);
10769
+ const result = await get_jungle_and_barrels(jungles, null, options);
10713
10770
  identify_optimizer_groups(result.targets, options);
10714
10771
  return result;
10715
10772
  }
@@ -10723,7 +10780,7 @@ const external_child_process_namespaceObject = require("child_process");
10723
10780
 
10724
10781
  function launchSimulator() {
10725
10782
  return (0,external_sdk_util_cjs_namespaceObject.getSdkPath)().then((sdk) => {
10726
- const child = (0,external_child_process_namespaceObject.execFile)(external_path_default().resolve(sdk, "bin", external_sdk_util_cjs_namespaceObject.isWin ? "simulator" : "connectiq"));
10783
+ const child = (0,external_child_process_namespaceObject.execFile)(external_path_.resolve(sdk, "bin", external_sdk_util_cjs_namespaceObject.isWin ? "simulator" : "connectiq"));
10727
10784
  child.unref();
10728
10785
  });
10729
10786
  }
@@ -10731,12 +10788,9 @@ function simulateProgram(prg, device, test) {
10731
10788
  const args = [prg, device];
10732
10789
  if (test)
10733
10790
  args.push("-t");
10734
- return (0,external_sdk_util_cjs_namespaceObject.getSdkPath)().then((sdk) => (0,external_util_cjs_namespaceObject.spawnByLine)(external_path_default().resolve(sdk, "bin", "monkeydo"), args, (line) => console.log(line)).then(() => { }));
10791
+ 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(() => { }));
10735
10792
  }
10736
10793
 
10737
- ;// CONCATENATED MODULE: external "@markw65/prettier-plugin-monkeyc"
10738
- const prettier_plugin_monkeyc_namespaceObject = require("@markw65/prettier-plugin-monkeyc");
10739
- var prettier_plugin_monkeyc_default = /*#__PURE__*/__webpack_require__.n(prettier_plugin_monkeyc_namespaceObject);
10740
10794
  ;// CONCATENATED MODULE: ./src/mc-rewrite.ts
10741
10795
 
10742
10796
 
@@ -10744,16 +10798,17 @@ var prettier_plugin_monkeyc_default = /*#__PURE__*/__webpack_require__.n(prettie
10744
10798
 
10745
10799
  function processImports(allImports, lookup) {
10746
10800
  allImports.forEach(({ node, stack }) => {
10747
- const [name, module] = lookup(node.id, "as" in node && node.as && node.as.name, stack);
10801
+ const [name, module] = lookup(node.id, ("as" in node && node.as && node.as.name) || null, stack);
10748
10802
  if (name && module) {
10749
10803
  const [parent] = stack.slice(-1);
10750
10804
  if (!parent.decls)
10751
10805
  parent.decls = {};
10806
+ const decls = parent.decls;
10752
10807
  if (!(0,external_api_cjs_namespaceObject.hasProperty)(parent.decls, name))
10753
10808
  parent.decls[name] = [];
10754
10809
  module.forEach((m) => {
10755
10810
  if ((0,external_api_cjs_namespaceObject.isStateNode)(m) && m.type == "ModuleDeclaration") {
10756
- (0,external_util_cjs_namespaceObject.pushUnique)(parent.decls[name], m);
10811
+ (0,external_util_cjs_namespaceObject.pushUnique)(decls[name], m);
10757
10812
  }
10758
10813
  });
10759
10814
  }
@@ -10824,7 +10879,7 @@ async function analyze(fnMap) {
10824
10879
  let excludeAnnotations;
10825
10880
  let hasTests = false;
10826
10881
  const allImports = [];
10827
- const state = {
10882
+ const preState = {
10828
10883
  allFunctions: [],
10829
10884
  allClasses: [],
10830
10885
  shouldExclude(node) {
@@ -10846,9 +10901,9 @@ async function analyze(fnMap) {
10846
10901
  return drop;
10847
10902
  }, false);
10848
10903
  }
10849
- return null;
10904
+ return false;
10850
10905
  },
10851
- post(node) {
10906
+ post(node, state) {
10852
10907
  switch (node.type) {
10853
10908
  case "FunctionDeclaration":
10854
10909
  case "ClassDeclaration": {
@@ -10867,10 +10922,13 @@ async function analyze(fnMap) {
10867
10922
  case "ImportModule":
10868
10923
  allImports.push({ node, stack: state.stack.slice() });
10869
10924
  return null;
10925
+ default:
10926
+ return null;
10870
10927
  }
10871
10928
  },
10872
10929
  };
10873
- await (0,external_api_cjs_namespaceObject.getApiMapping)(state);
10930
+ await (0,external_api_cjs_namespaceObject.getApiMapping)(preState);
10931
+ const state = preState;
10874
10932
  // Mark all functions from api.mir as "special" by
10875
10933
  // setting their bodies to null. In api.mir, they're
10876
10934
  // all empty, which makes it look like they're
@@ -10879,7 +10937,7 @@ async function analyze(fnMap) {
10879
10937
  if (node.type == "FunctionDeclaration") {
10880
10938
  node.node.body = null;
10881
10939
  }
10882
- if ("decls" in node) {
10940
+ if ((0,external_api_cjs_namespaceObject.isStateNode)(node) && node.decls) {
10883
10941
  Object.values(node.decls).forEach((v) => v.forEach(markApi));
10884
10942
  }
10885
10943
  };
@@ -10933,6 +10991,8 @@ function getLiteralFromDecls(decls) {
10933
10991
  return null;
10934
10992
  }
10935
10993
  function getLiteralNode(node) {
10994
+ if (node == null)
10995
+ return null;
10936
10996
  if (node.type == "Literal")
10937
10997
  return node;
10938
10998
  if (node.type == "BinaryExpression" && node.operator == "as") {
@@ -10971,11 +11031,11 @@ function getNodeValue(node) {
10971
11031
  }
10972
11032
  let type = node.value === null ? "Null" : typeof node.value;
10973
11033
  if (type === "number") {
10974
- const match = prettier_plugin_monkeyc_namespaceObject.LiteralIntegerRe.exec(node.raw);
11034
+ const match = node.raw && prettier_plugin_monkeyc_namespaceObject.LiteralIntegerRe.exec(node.raw);
10975
11035
  if (match) {
10976
11036
  type = match[2] == "l" ? "Long" : "Number";
10977
11037
  }
10978
- else if (node.raw.endsWith("d")) {
11038
+ else if (node.raw && node.raw.endsWith("d")) {
10979
11039
  type = "Double";
10980
11040
  }
10981
11041
  else {
@@ -11098,11 +11158,12 @@ function evaluateFunction(func, args) {
11098
11158
  default:
11099
11159
  throw new Error("Bad node type");
11100
11160
  }
11101
- }, args &&
11102
- ((node) => {
11161
+ }, !args
11162
+ ? undefined
11163
+ : (node) => {
11103
11164
  switch (node.type) {
11104
11165
  case "ReturnStatement":
11105
- ret = node.argument;
11166
+ ret = node.argument || null;
11106
11167
  return null;
11107
11168
  case "BlockStatement":
11108
11169
  case "Literal":
@@ -11119,7 +11180,7 @@ function evaluateFunction(func, args) {
11119
11180
  throw new Error("Didn't optimize");
11120
11181
  }
11121
11182
  }
11122
- }));
11183
+ });
11123
11184
  return ret;
11124
11185
  }
11125
11186
  catch (e) {
@@ -11127,7 +11188,12 @@ function evaluateFunction(func, args) {
11127
11188
  }
11128
11189
  }
11129
11190
  async function optimizeMonkeyC(fnMap) {
11130
- const state = await analyze(fnMap);
11191
+ const state = {
11192
+ ...(await analyze(fnMap)),
11193
+ localsStack: [{}],
11194
+ exposed: {},
11195
+ calledFunctions: {},
11196
+ };
11131
11197
  const replace = (node, obj) => {
11132
11198
  for (const k of Object.keys(node)) {
11133
11199
  delete node[k];
@@ -11156,6 +11222,7 @@ async function optimizeMonkeyC(fnMap) {
11156
11222
  replace(node, obj);
11157
11223
  return true;
11158
11224
  };
11225
+ const topLocals = () => state.localsStack[state.localsStack.length - 1];
11159
11226
  /*
11160
11227
  * Might this function be called from somewhere, including
11161
11228
  * callbacks from the api (eg getSettingsView, etc).
@@ -11193,17 +11260,15 @@ async function optimizeMonkeyC(fnMap) {
11193
11260
  f.type == "FunctionDeclaration" &&
11194
11261
  maybeCalled(f.node))) ||
11195
11262
  (sc.superClass && checkInherited(sc, name)));
11196
- state.localsStack = [{}];
11197
- state.exposed = {};
11198
- state.calledFunctions = {};
11199
11263
  state.pre = (node) => {
11200
11264
  switch (node.type) {
11201
11265
  case "ConditionalExpression":
11202
11266
  case "IfStatement":
11203
11267
  case "DoWhileStatement":
11204
11268
  case "WhileStatement":
11205
- state.traverse(node.test);
11206
- const [value, type] = getNodeValue(node.test);
11269
+ const test = (state.traverse(node.test) ||
11270
+ node.test);
11271
+ const [value, type] = getNodeValue(test);
11207
11272
  if (value) {
11208
11273
  let result = null;
11209
11274
  if (type === "Null") {
@@ -11215,25 +11280,16 @@ async function optimizeMonkeyC(fnMap) {
11215
11280
  result = !!value.value;
11216
11281
  }
11217
11282
  if (result !== null) {
11283
+ node.test = { type: "Literal", value: result };
11218
11284
  if (node.type === "IfStatement" ||
11219
11285
  node.type === "ConditionalExpression") {
11220
- if (result === false) {
11221
- node.consequent = null;
11222
- }
11223
- else {
11224
- node.alternate = null;
11225
- }
11226
- node.test = null;
11286
+ return [result ? "consequent" : "alternate"];
11227
11287
  }
11228
11288
  else if (node.type === "WhileStatement") {
11229
- if (result === false) {
11230
- node.body = null;
11231
- }
11289
+ return result === false ? [] : ["body"];
11232
11290
  }
11233
11291
  else if (node.type === "DoWhileStatement") {
11234
- if (result === false) {
11235
- node.test = null;
11236
- }
11292
+ return ["body"];
11237
11293
  }
11238
11294
  else {
11239
11295
  throw new Error("Unexpected Node type");
@@ -11244,14 +11300,14 @@ async function optimizeMonkeyC(fnMap) {
11244
11300
  case "EnumDeclaration":
11245
11301
  return false;
11246
11302
  case "ForStatement": {
11247
- const map = state.localsStack.slice(-1).pop().map;
11303
+ const map = topLocals().map;
11248
11304
  if (map) {
11249
11305
  state.localsStack.push({ node, map: { ...map } });
11250
11306
  }
11251
11307
  break;
11252
11308
  }
11253
11309
  case "VariableDeclarator": {
11254
- const locals = state.localsStack.slice(-1).pop();
11310
+ const locals = topLocals();
11255
11311
  const { map } = locals;
11256
11312
  if (map) {
11257
11313
  const declName = (0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id);
@@ -11269,9 +11325,10 @@ async function optimizeMonkeyC(fnMap) {
11269
11325
  // find all the names declared in this scope, to avoid
11270
11326
  // more conflicts
11271
11327
  locals.inners = {};
11328
+ const inners = locals.inners;
11272
11329
  (0,external_api_cjs_namespaceObject.traverseAst)(locals.node, (node) => {
11273
11330
  if (node.type === "VariableDeclarator") {
11274
- locals.inners[(0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id)] = true;
11331
+ inners[(0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id)] = true;
11275
11332
  }
11276
11333
  });
11277
11334
  }
@@ -11292,7 +11349,8 @@ async function optimizeMonkeyC(fnMap) {
11292
11349
  break;
11293
11350
  }
11294
11351
  }
11295
- else if (elm.node.type === "FunctionDeclaration") {
11352
+ else if (elm.node &&
11353
+ elm.node.type === "FunctionDeclaration") {
11296
11354
  ok = true;
11297
11355
  }
11298
11356
  }
@@ -11331,7 +11389,7 @@ async function optimizeMonkeyC(fnMap) {
11331
11389
  }
11332
11390
  break;
11333
11391
  case "Identifier": {
11334
- const map = state.localsStack.slice(-1).pop().map;
11392
+ const map = topLocals().map;
11335
11393
  if (map) {
11336
11394
  if ((0,external_api_cjs_namespaceObject.hasProperty)(map, node.name)) {
11337
11395
  const name = map[node.name];
@@ -11362,7 +11420,7 @@ async function optimizeMonkeyC(fnMap) {
11362
11420
  }
11363
11421
  break;
11364
11422
  case "BlockStatement": {
11365
- const map = state.localsStack.slice(-1).pop().map;
11423
+ const map = topLocals().map;
11366
11424
  if (map) {
11367
11425
  state.localsStack.push({
11368
11426
  node,
@@ -11397,7 +11455,7 @@ async function optimizeMonkeyC(fnMap) {
11397
11455
  return null;
11398
11456
  };
11399
11457
  state.post = (node) => {
11400
- if (state.localsStack.slice(-1).pop().node === node) {
11458
+ if (topLocals().node === node) {
11401
11459
  state.localsStack.pop();
11402
11460
  }
11403
11461
  const opt = optimizeNode(node);
@@ -11408,20 +11466,23 @@ async function optimizeMonkeyC(fnMap) {
11408
11466
  switch (node.type) {
11409
11467
  case "ConditionalExpression":
11410
11468
  case "IfStatement":
11411
- if (node.test === null) {
11412
- const rep = node.consequent || node.alternate;
11469
+ if (node.test.type === "Literal" &&
11470
+ typeof node.test.value === "boolean") {
11471
+ const rep = node.test.value ? node.consequent : node.alternate;
11413
11472
  if (!rep)
11414
11473
  return false;
11415
11474
  replace(node, rep);
11416
11475
  }
11417
11476
  break;
11418
11477
  case "WhileStatement":
11419
- if (!node.body)
11478
+ if (node.test.type === "Literal" && node.test.value === false) {
11420
11479
  return false;
11480
+ }
11421
11481
  break;
11422
11482
  case "DoWhileStatement":
11423
- if (!node.test)
11483
+ if (node.test.type === "Literal" && node.test.value === false) {
11424
11484
  return node.body;
11485
+ }
11425
11486
  break;
11426
11487
  case "CallExpression": {
11427
11488
  const [name, callees] = state.lookup(node.callee);
@@ -11443,7 +11504,8 @@ async function optimizeMonkeyC(fnMap) {
11443
11504
  }
11444
11505
  if (callees.length == 1) {
11445
11506
  const callee = (0,external_api_cjs_namespaceObject.isStateNode)(callees[0]) && callees[0].node;
11446
- if (callee.type == "FunctionDeclaration" &&
11507
+ if (callee &&
11508
+ callee.type == "FunctionDeclaration" &&
11447
11509
  callee.optimizable &&
11448
11510
  !callee.hasOverride &&
11449
11511
  node.arguments.every((n) => getNodeValue(n)[0] !== null)) {
@@ -11466,71 +11528,77 @@ async function optimizeMonkeyC(fnMap) {
11466
11528
  Object.values(fnMap).forEach((f) => {
11467
11529
  (0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
11468
11530
  });
11469
- Object.values(fnMap).forEach((f) => {
11470
- (0,external_api_cjs_namespaceObject.traverseAst)(f.ast, null, (node) => {
11471
- switch (node.type) {
11472
- case "EnumStringBody":
11473
- if (node.members.every((m) => {
11474
- const name = "name" in m ? m.name : m.id.name;
11475
- return ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) &&
11476
- !(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name));
11477
- })) {
11478
- node.enumType = [
11479
- ...new Set(node.members.map((m) => {
11480
- if (!("init" in m))
11481
- return "Number";
11482
- const [node, type] = getNodeValue(m.init);
11483
- if (!node) {
11484
- throw new Error("Failed to get type for eliminated enum");
11485
- }
11486
- return type;
11487
- })),
11488
- ].join(" or ");
11489
- node.members.splice(0);
11490
- }
11491
- break;
11492
- case "EnumDeclaration":
11493
- if (!node.body.members.length) {
11494
- if (!node.id)
11495
- return false;
11496
- if (!node.body["enumType"]) {
11497
- throw new Error("Missing enumType on optimized enum");
11498
- }
11499
- replace(node, {
11500
- type: "TypedefDeclaration",
11501
- id: node.id,
11502
- ts: {
11503
- type: "UnaryExpression",
11504
- argument: { type: "TypeSpecList", ts: [node.body.enumType] },
11505
- prefix: true,
11506
- operator: " as",
11507
- },
11508
- });
11509
- }
11510
- break;
11511
- case "VariableDeclaration": {
11512
- node.declarations = node.declarations.filter((d) => {
11513
- const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(d.id);
11514
- return (!(0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) ||
11515
- (0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name));
11516
- });
11517
- if (!node.declarations.length) {
11518
- return false;
11519
- }
11520
- break;
11531
+ const cleanup = (node) => {
11532
+ switch (node.type) {
11533
+ case "EnumStringBody":
11534
+ if (node.members.every((m) => {
11535
+ const name = "name" in m ? m.name : m.id.name;
11536
+ return ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) &&
11537
+ !(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name));
11538
+ })) {
11539
+ node.enumType = [
11540
+ ...new Set(node.members.map((m) => {
11541
+ if (!("init" in m))
11542
+ return "Number";
11543
+ const [node, type] = getNodeValue(m.init);
11544
+ if (!node) {
11545
+ throw new Error("Failed to get type for eliminated enum");
11546
+ }
11547
+ return type;
11548
+ })),
11549
+ ].join(" or ");
11550
+ node.members.splice(0);
11521
11551
  }
11522
- case "ClassElement":
11523
- if (!node.item) {
11524
- return false;
11525
- }
11526
- break;
11527
- case "FunctionDeclaration":
11528
- if (!maybeCalled(node)) {
11552
+ break;
11553
+ case "EnumDeclaration":
11554
+ if (!node.body.members.length) {
11555
+ if (!node.id)
11529
11556
  return false;
11557
+ if (!node.body["enumType"]) {
11558
+ throw new Error("Missing enumType on optimized enum");
11530
11559
  }
11531
- break;
11560
+ replace(node, {
11561
+ type: "TypedefDeclaration",
11562
+ id: node.id,
11563
+ ts: {
11564
+ type: "UnaryExpression",
11565
+ argument: { type: "TypeSpecList", ts: [node.body.enumType] },
11566
+ prefix: true,
11567
+ operator: " as",
11568
+ },
11569
+ });
11570
+ }
11571
+ break;
11572
+ case "VariableDeclaration": {
11573
+ node.declarations = node.declarations.filter((d) => {
11574
+ const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(d.id);
11575
+ return (!(0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) || (0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name));
11576
+ });
11577
+ if (!node.declarations.length) {
11578
+ return false;
11579
+ }
11580
+ break;
11532
11581
  }
11533
- return null;
11582
+ case "ClassElement":
11583
+ if (!node.item) {
11584
+ return false;
11585
+ }
11586
+ break;
11587
+ case "FunctionDeclaration":
11588
+ if (!maybeCalled(node)) {
11589
+ return false;
11590
+ }
11591
+ break;
11592
+ }
11593
+ return null;
11594
+ };
11595
+ Object.values(fnMap).forEach((f) => {
11596
+ (0,external_api_cjs_namespaceObject.traverseAst)(f.ast, undefined, (node) => {
11597
+ const ret = cleanup(node);
11598
+ if (ret === false) {
11599
+ state.removeNodeComments(node, f.ast);
11600
+ }
11601
+ return ret;
11534
11602
  });
11535
11603
  });
11536
11604
  }
@@ -11565,6 +11633,9 @@ const defaultConfig = {
11565
11633
  outputPath: "bin/optimized",
11566
11634
  workspace: "./",
11567
11635
  };
11636
+ function isErrorWithLocation(e) {
11637
+ return (0,external_api_cjs_namespaceObject.hasProperty)(e, "location");
11638
+ }
11568
11639
  /**
11569
11640
  * @param {BuildConfig} options
11570
11641
  * @returns {Promise<BuildConfig>}
@@ -11621,14 +11692,14 @@ async function buildOptimizedProject(product, options) {
11621
11692
  if (product) {
11622
11693
  product = config.products[0];
11623
11694
  if (config.simulatorBuild === false) {
11624
- bin = external_path_default().join(bin, product);
11695
+ bin = external_path_.join(bin, product);
11625
11696
  }
11626
11697
  }
11627
11698
  else {
11628
- bin = external_path_default().join(bin, "exported");
11699
+ bin = external_path_.join(bin, "exported");
11629
11700
  name = `${program}.iq`;
11630
11701
  }
11631
- config.program = external_path_default().join(bin, name);
11702
+ config.program = external_path_.join(bin, name);
11632
11703
  if (!hasTests)
11633
11704
  delete config.testBuild;
11634
11705
  return build_project(product, config).then((result) => ({
@@ -11654,7 +11725,7 @@ async function buildOptimizedProject(product, options) {
11654
11725
  * @param {Target[]} targets
11655
11726
  */
11656
11727
  async function createLocalBarrels(targets, options) {
11657
- if (targets.every((target) => !target.group.optimizerConfig.barrelMap ||
11728
+ if (targets.every((target) => !target.group?.optimizerConfig.barrelMap ||
11658
11729
  Object.values(target.group.optimizerConfig.barrelMap).every((resolvedBarrel) => !resolvedBarrel.qualifier.resourcePath))) {
11659
11730
  // there are no barrels, or every barrel has no resources.
11660
11731
  // we can drop any barrels altogether (we'll need to drop them
@@ -11662,8 +11733,10 @@ async function createLocalBarrels(targets, options) {
11662
11733
  return null;
11663
11734
  }
11664
11735
  // where to create the local barrel projects.
11665
- const barrelDir = external_path_default().resolve(options.workspace, options.outputPath, "opt-barrels");
11736
+ const barrelDir = external_path_.resolve(options.workspace, options.outputPath, "opt-barrels");
11666
11737
  return targets.reduce((promise, target) => {
11738
+ if (!target.group)
11739
+ return promise;
11667
11740
  const barrelMap = target.group.optimizerConfig.barrelMap;
11668
11741
  if (!barrelMap || target.group.optimizerConfig.optBarrels) {
11669
11742
  return promise;
@@ -11671,13 +11744,13 @@ async function createLocalBarrels(targets, options) {
11671
11744
  const optBarrels = (target.group.optimizerConfig.optBarrels = {});
11672
11745
  return Object.entries(barrelMap).reduce((promise, [barrel, resolvedBarrel]) => {
11673
11746
  const { manifest, jungles } = resolvedBarrel;
11674
- const rawBarrelDir = external_path_default().dirname(jungles[0]);
11675
- const rawJungles = jungles.map((jungle) => external_path_default().relative(rawBarrelDir, jungle));
11747
+ const rawBarrelDir = external_path_.dirname(jungles[0]);
11748
+ const rawJungles = jungles.map((jungle) => external_path_.relative(rawBarrelDir, jungle));
11676
11749
  const sha1 = external_crypto_namespaceObject.createHash("sha1")
11677
11750
  .update(rawBarrelDir, "binary")
11678
11751
  .digest("base64")
11679
11752
  .replace(/[\/=+]/g, "");
11680
- const optBarrelDir = external_path_default().resolve(barrelDir, `${barrel}-${sha1}`);
11753
+ const optBarrelDir = external_path_.resolve(barrelDir, `${barrel}-${sha1}`);
11681
11754
  if (!(0,external_api_cjs_namespaceObject.hasProperty)(optBarrels, barrel)) {
11682
11755
  optBarrels[barrel] = {
11683
11756
  rawBarrelDir,
@@ -11690,22 +11763,28 @@ async function createLocalBarrels(targets, options) {
11690
11763
  if (optBarrels[barrel].manifest !== manifest ||
11691
11764
  optBarrels[barrel].optBarrelDir !== optBarrelDir ||
11692
11765
  optBarrels[barrel].rawBarrelDir != rawBarrelDir) {
11693
- throw new Error(`For device ${target.product}, barrel ${barrel} was mapped to both ${external_path_default().relative(optBarrels[barrel].rawBarrelDir, optBarrels[barrel].manifest)} in ${optBarrels[barrel].rawBarrelDir} and ${external_path_default().relative(rawBarrelDir, manifest)} in ${rawBarrelDir}.`);
11766
+ 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}.`);
11694
11767
  }
11695
11768
  optBarrels[barrel].jungleFiles.push(...rawJungles);
11696
11769
  return promise;
11697
11770
  }, promise);
11698
11771
  }, Promise.resolve());
11699
11772
  }
11700
- /**
11701
- *
11702
- * @param {BuildConfig} options
11703
- * @returns
11704
- */
11705
11773
  async function generateOptimizedProject(options) {
11706
11774
  const config = await getConfig(options);
11707
11775
  const workspace = config.workspace;
11708
11776
  const { manifest, targets, xml, jungles } = await get_jungle(config.jungleFiles, config);
11777
+ if (!xml["iq:manifest"]["iq:application"]) {
11778
+ const error = new Error(xml["iq:manifest"]["iq:barrel"]
11779
+ ? "Optimize the project that uses this barrel, not the barrel itself"
11780
+ : "Manifest is missing an `iq:application` tag");
11781
+ error.location = {
11782
+ start: { line: 1, column: 1 },
11783
+ end: { line: 1, column: 1 },
11784
+ source: manifest,
11785
+ };
11786
+ throw error;
11787
+ }
11709
11788
  const dependencyFiles = [manifest, ...jungles];
11710
11789
  await createLocalBarrels(targets, options);
11711
11790
  const buildConfigs = {};
@@ -11718,12 +11797,15 @@ async function generateOptimizedProject(options) {
11718
11797
  }
11719
11798
  return {
11720
11799
  jungleFiles: config.jungleFiles,
11721
- program: external_path_default().basename(external_path_default().dirname(manifest)),
11800
+ program: external_path_.basename(external_path_.dirname(manifest)),
11722
11801
  };
11723
11802
  }
11724
11803
  let dropBarrels = false;
11725
11804
  const configKey = (p) => p.group.key + (config.releaseBuild ? "-release" : "-debug");
11726
11805
  targets.forEach((p) => {
11806
+ if (!p.group) {
11807
+ throw new Error(`Missing group in build target ${p.product}`);
11808
+ }
11727
11809
  const key = configKey(p);
11728
11810
  if (!(0,external_api_cjs_namespaceObject.hasProperty)(buildConfigs, key)) {
11729
11811
  p.group.dir = key;
@@ -11752,9 +11834,9 @@ async function generateOptimizedProject(options) {
11752
11834
  }
11753
11835
  });
11754
11836
  // console.log(JSON.stringify(targets));
11755
- const jungle_dir = external_path_default().resolve(workspace, config.outputPath);
11837
+ const jungle_dir = external_path_.resolve(workspace, config.outputPath);
11756
11838
  await promises_namespaceObject.mkdir(jungle_dir, { recursive: true });
11757
- const relative_path = (s) => external_path_default().relative(jungle_dir, s);
11839
+ const relative_path = (s) => external_path_.relative(jungle_dir, s);
11758
11840
  let relative_manifest = relative_path(manifest);
11759
11841
  const manifestOk = (!config.checkManifest ||
11760
11842
  (await checkManifest(xml, targets.map((t) => t.product)))) &&
@@ -11764,7 +11846,7 @@ async function generateOptimizedProject(options) {
11764
11846
  .sort()
11765
11847
  .map((key) => {
11766
11848
  const buildConfig = buildConfigs[key];
11767
- const outputPath = external_path_default().join(config.outputPath, key);
11849
+ const outputPath = external_path_.join(config.outputPath, key);
11768
11850
  return buildConfig
11769
11851
  ? generateOneConfig(buildConfig, dependencyFiles, {
11770
11852
  ...config,
@@ -11778,7 +11860,7 @@ async function generateOptimizedProject(options) {
11778
11860
  throw e;
11779
11861
  })
11780
11862
  .then((t) => t && (hasTests = true))
11781
- : promises_namespaceObject.rm(external_path_default().resolve(workspace, outputPath), {
11863
+ : promises_namespaceObject.rm(external_path_.resolve(workspace, outputPath), {
11782
11864
  recursive: true,
11783
11865
  force: true,
11784
11866
  });
@@ -11787,29 +11869,33 @@ async function generateOptimizedProject(options) {
11787
11869
  if (dropBarrels) {
11788
11870
  manifestDropBarrels(xml);
11789
11871
  }
11790
- const manifestFile = external_path_default().join(jungle_dir, "manifest.xml");
11872
+ const manifestFile = external_path_.join(jungle_dir, "manifest.xml");
11791
11873
  promises.push(writeManifest(manifestFile, xml));
11792
11874
  relative_manifest = "manifest.xml";
11793
11875
  }
11794
11876
  const parts = [`project.manifest=${relative_manifest}`];
11795
11877
  const process_field = (prefix, base, name, mapper = null) => {
11796
- if (!base[name])
11878
+ const obj = base[name];
11879
+ if (!obj)
11797
11880
  return;
11798
11881
  const map_one = (s) => (mapper ? mapper(s) : s);
11799
11882
  const map = (s) => Array.isArray(s) ? `[${s.map(map_one).join(";")}]` : map_one(s);
11800
- parts.push(`${prefix}${name} = ${base[name].map(map).join(";")}`);
11883
+ parts.push(`${prefix}${name} = ${obj.map(map).join(";")}`);
11801
11884
  };
11802
- targets.forEach((jungle) => {
11803
- if (!buildConfigs[configKey(jungle)])
11885
+ targets.forEach((target) => {
11886
+ if (!buildConfigs[configKey(target)])
11804
11887
  return;
11805
- const { product, qualifier, group } = jungle;
11888
+ const { product, qualifier, group } = target;
11889
+ if (!group) {
11890
+ throw new Error(`Missing group in target ${target.product}`);
11891
+ }
11806
11892
  const prefix = `${product}.`;
11807
- process_field(prefix, qualifier, "sourcePath", (s) => external_path_default().join(group.dir, "source", relative_path_no_dotdot(external_path_default().relative(workspace, s)))
11893
+ process_field(prefix, qualifier, "sourcePath", (s) => external_path_.join(group.dir, "source", relative_path_no_dotdot(external_path_.relative(workspace, s)))
11808
11894
  .replace(/([\\\/]\*\*)[\\\/]\*/g, "$1"));
11809
11895
  if (group.optimizerConfig.optBarrels) {
11810
11896
  parts.push(`${prefix}barrelPath = ${Object.values(group.optimizerConfig.optBarrels)
11811
11897
  .map((value) => `[${value.jungleFiles
11812
- .map((j) => relative_path(external_path_default().join(value.optBarrelDir, j)))
11898
+ .map((j) => relative_path(external_path_.join(value.optBarrelDir, j)))
11813
11899
  .join(";")}]`)
11814
11900
  .join(";")}`);
11815
11901
  }
@@ -11817,8 +11903,8 @@ async function generateOptimizedProject(options) {
11817
11903
  parts.push(`${prefix}sourcePath = ${[`$(${prefix}sourcePath)`]
11818
11904
  .concat(Object.entries(group.optimizerConfig.barrelMap)
11819
11905
  .map(([barrel, resolvedBarrel]) => {
11820
- const root = external_path_default().dirname(resolvedBarrel.jungles[0]);
11821
- return (resolvedBarrel.qualifier.sourcePath || []).map((s) => external_path_default().join(group.dir, "barrels", barrel, external_path_default().relative(root, s))
11906
+ const root = external_path_.dirname(resolvedBarrel.jungles[0]);
11907
+ return (resolvedBarrel.qualifier.sourcePath || []).map((s) => external_path_.join(group.dir, "barrels", barrel, external_path_.relative(root, s))
11822
11908
  .replace(/([\\\/]\*\*)[\\\/]\*/g, "$1"));
11823
11909
  })
11824
11910
  .flat()
@@ -11829,29 +11915,31 @@ async function generateOptimizedProject(options) {
11829
11915
  // annotations were handled via source transformations.
11830
11916
  process_field(prefix, qualifier, "resourcePath", relative_path);
11831
11917
  process_field(prefix, qualifier, "excludeAnnotations");
11832
- if (qualifier.lang) {
11833
- Object.keys(qualifier.lang).forEach((key) => {
11834
- process_field(`${prefix}lang.`, qualifier.lang, key, relative_path);
11918
+ const qlang = qualifier.lang;
11919
+ if (qlang) {
11920
+ Object.keys(qlang).forEach((key) => {
11921
+ process_field(`${prefix}lang.`, qlang, key, relative_path);
11835
11922
  });
11836
11923
  }
11837
11924
  });
11838
- const jungleFiles = external_path_default().join(jungle_dir, `${config.releaseBuild ? "release" : "debug"}.jungle`);
11925
+ const jungleFiles = external_path_.join(jungle_dir, `${config.releaseBuild ? "release" : "debug"}.jungle`);
11839
11926
  promises.push(promises_namespaceObject.writeFile(jungleFiles, parts.join("\n")));
11840
11927
  await Promise.all(promises);
11841
11928
  return {
11842
11929
  jungleFiles,
11843
- program: external_path_default().basename(external_path_default().dirname(manifest)),
11930
+ xml,
11931
+ program: external_path_.basename(external_path_.dirname(manifest)),
11844
11932
  hasTests,
11845
11933
  };
11846
11934
  }
11847
11935
  async function fileInfoFromConfig(workspace, output, buildConfig, extraExcludes) {
11848
- const paths = (await Promise.all(buildConfig.sourcePath.map((pattern) => (0,external_util_cjs_namespaceObject.globa)(pattern, { cwd: workspace, mark: true })))).flat();
11936
+ const paths = (await Promise.all(buildConfig.sourcePath?.map((pattern) => (0,external_util_cjs_namespaceObject.globa)(pattern, { cwd: workspace, mark: true })) || [])).flat();
11849
11937
  const files = (await Promise.all(paths.map((path) => path.endsWith("/")
11850
11938
  ? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.mc`, { cwd: workspace, mark: true })
11851
11939
  : path)))
11852
11940
  .flat()
11853
11941
  .filter((file) => file.endsWith(".mc") &&
11854
- !external_path_default().relative(workspace, file).startsWith("bin") &&
11942
+ !external_path_.relative(workspace, file).startsWith("bin") &&
11855
11943
  (!buildConfig.sourceExcludes ||
11856
11944
  !buildConfig.sourceExcludes.includes(file)));
11857
11945
  const excludeAnnotations = Object.assign(buildConfig.excludeAnnotations
@@ -11861,7 +11949,7 @@ async function fileInfoFromConfig(workspace, output, buildConfig, extraExcludes)
11861
11949
  fnMap: Object.fromEntries(files.map((file) => [
11862
11950
  file,
11863
11951
  {
11864
- output: external_path_default().join(output, relative_path_no_dotdot(external_path_default().relative(workspace, file))),
11952
+ output: external_path_.join(output, relative_path_no_dotdot(external_path_.relative(workspace, file))),
11865
11953
  excludeAnnotations,
11866
11954
  },
11867
11955
  ])),
@@ -11896,7 +11984,7 @@ const configOptionsToCheck = [
11896
11984
  */
11897
11985
  async function generateOneConfig(buildConfig, dependencyFiles, config) {
11898
11986
  const { workspace } = config;
11899
- const output = external_path_default().join(workspace, config.outputPath);
11987
+ const output = external_path_.join(workspace, config.outputPath);
11900
11988
  const buildModeExcludes = {
11901
11989
  // note: exclude debug in release builds, and release in debug builds
11902
11990
  [config.releaseBuild ? "debug" : "release"]: true,
@@ -11904,12 +11992,12 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
11904
11992
  if (!config.testBuild) {
11905
11993
  buildModeExcludes.test = true;
11906
11994
  }
11907
- const { fnMap } = await fileInfoFromConfig(workspace, external_path_default().join(output, "source"), buildConfig, buildModeExcludes);
11995
+ const { fnMap } = await fileInfoFromConfig(workspace, external_path_.join(output, "source"), buildConfig, buildModeExcludes);
11908
11996
  if (buildConfig.barrelMap) {
11909
11997
  const barrelFnMaps = await Promise.all(Object.entries(buildConfig.barrelMap)
11910
11998
  .map(([barrel, resolvedBarrel]) => {
11911
11999
  dependencyFiles = dependencyFiles.concat(resolvedBarrel.jungles, resolvedBarrel.manifest);
11912
- return fileInfoFromConfig(external_path_default().dirname(resolvedBarrel.jungles[0]), external_path_default().join(output, "barrels", barrel), resolvedBarrel.qualifier, {
12000
+ return fileInfoFromConfig(external_path_.dirname(resolvedBarrel.jungles[0]), external_path_.join(output, "barrels", barrel), resolvedBarrel.qualifier, {
11913
12001
  ...buildModeExcludes,
11914
12002
  ...excludesFromAnnotations(barrel, buildConfig.annotations, resolvedBarrel),
11915
12003
  }).then(({ fnMap }) => fnMap);
@@ -11917,10 +12005,10 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
11917
12005
  .flat());
11918
12006
  barrelFnMaps.forEach((barrelFnMap) => Object.assign(fnMap, barrelFnMap));
11919
12007
  }
11920
- const actualOptimizedFiles = (await (0,external_util_cjs_namespaceObject.globa)(external_path_default().join(output, "**", "*.mc"), { mark: true }))
12008
+ const actualOptimizedFiles = (await (0,external_util_cjs_namespaceObject.globa)(external_path_.join(output, "**", "*.mc"), { mark: true }))
11921
12009
  .filter((file) => !file.endsWith("/"))
11922
12010
  .sort();
11923
- const { hasTests, ...prevOptions } = JSON.parse(await promises_namespaceObject.readFile(external_path_default().join(output, "build-info.json"), "utf-8")
12011
+ const { hasTests, ...prevOptions } = JSON.parse(await promises_namespaceObject.readFile(external_path_.join(output, "build-info.json"), "utf-8")
11924
12012
  .catch(() => "{}"));
11925
12013
  // check that the set of files thats actually there is the same as the
11926
12014
  // set of files we're going to generate (in case eg a jungle file change
@@ -11937,7 +12025,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
11937
12025
  // the oldest optimized file, we don't need to regenerate
11938
12026
  const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
11939
12027
  const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
11940
- if (source_time < opt_time && 1653156641658 < opt_time) {
12028
+ if (source_time < opt_time && 1653864408816 < opt_time) {
11941
12029
  return hasTests;
11942
12030
  }
11943
12031
  }
@@ -11946,14 +12034,14 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
11946
12034
  await optimizeMonkeyC(fnMap);
11947
12035
  return Promise.all(Object.values(fnMap).map(async (info) => {
11948
12036
  const name = info.output;
11949
- const dir = external_path_default().dirname(name);
12037
+ const dir = external_path_.dirname(name);
11950
12038
  await promises_namespaceObject.mkdir(dir, { recursive: true });
11951
12039
  const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(info.ast, info.monkeyCSource);
11952
12040
  await promises_namespaceObject.writeFile(name, opt_source);
11953
12041
  return info.hasTests;
11954
12042
  })).then((results) => {
11955
12043
  const hasTests = results.some((v) => v);
11956
- return promises_namespaceObject.writeFile(external_path_default().join(output, "build-info.json"), JSON.stringify({
12044
+ return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
11957
12045
  hasTests,
11958
12046
  ...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
11959
12047
  }))
@@ -11963,6 +12051,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
11963
12051
  async function getProjectAnalysis(targets, analysis, options) {
11964
12052
  const sourcePath = targets
11965
12053
  .map(({ qualifier: { sourcePath } }) => sourcePath)
12054
+ .filter((sp) => sp != null)
11966
12055
  .flat()
11967
12056
  .sort()
11968
12057
  .filter((s, i, arr) => !i || s !== arr[i - 1]);
@@ -11993,21 +12082,28 @@ async function generateApiMirTests(options) {
11993
12082
  const config = { ...defaultConfig, ...(options || {}) };
11994
12083
  const tests = [];
11995
12084
  const api = await (0,external_api_cjs_namespaceObject.getApiMapping)();
12085
+ if (!api) {
12086
+ throw new Error("Failed to read api.mir");
12087
+ }
11996
12088
  const findConstants = (node) => {
11997
- Object.entries(node.decls).forEach(([key, decl]) => {
11998
- if (decl.length > 1)
11999
- throw `Bad decl length:${node.fullName}.${key}`;
12000
- if (decl.length != 1)
12001
- return;
12002
- const d = decl[0];
12003
- if (d.type === "EnumStringMember" ||
12004
- (d.type === "VariableDeclarator" && d.kind === "const")) {
12005
- tests.push([`${node.fullName}.${key}`, (0,external_api_cjs_namespaceObject.formatAst)(d.init)]);
12006
- }
12007
- else if ((0,external_api_cjs_namespaceObject.isStateNode)(d)) {
12008
- findConstants(d);
12009
- }
12010
- });
12089
+ node.decls &&
12090
+ Object.entries(node.decls).forEach(([key, decl]) => {
12091
+ if (decl.length > 1)
12092
+ throw `Bad decl length:${node.fullName}.${key}`;
12093
+ if (decl.length != 1)
12094
+ return;
12095
+ const d = decl[0];
12096
+ if (d.type === "EnumStringMember" ||
12097
+ (d.type === "VariableDeclarator" && d.kind === "const")) {
12098
+ if (!d.init) {
12099
+ throw new Error(`Missing init for ${node.fullName}.${key}`);
12100
+ }
12101
+ tests.push([`${node.fullName}.${key}`, (0,external_api_cjs_namespaceObject.formatAst)(d.init)]);
12102
+ }
12103
+ else if ((0,external_api_cjs_namespaceObject.isStateNode)(d)) {
12104
+ findConstants(d);
12105
+ }
12106
+ });
12011
12107
  };
12012
12108
  findConstants(api);
12013
12109
  function hasTests(name) {