@markw65/monkeyc-optimizer 1.0.13 → 1.0.16
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 +37 -0
- package/build/api.cjs +573 -155
- package/build/optimizer.cjs +584 -235
- package/build/sdk-util.cjs +8 -2
- package/build/src/inliner.d.ts +4 -0
- package/build/src/optimizer.d.ts +52 -30
- package/build/src/sdk-util.d.ts +4 -2
- package/build/util.cjs +12 -4
- package/package.json +13 -6
package/build/optimizer.cjs
CHANGED
|
@@ -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__(
|
|
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:
|
|
@@ -10077,7 +10077,8 @@ async function default_jungle() {
|
|
|
10077
10077
|
}
|
|
10078
10078
|
rezAndLang(deviceId, `resources-${deviceId}`, deviceFamily);
|
|
10079
10079
|
});
|
|
10080
|
-
|
|
10080
|
+
const state = await process_assignments(assignments, {});
|
|
10081
|
+
return { state, devices };
|
|
10081
10082
|
}
|
|
10082
10083
|
function process_assignments(assignments, current) {
|
|
10083
10084
|
return assignments.reduce((state, a) => {
|
|
@@ -10179,9 +10180,9 @@ async function process_jungles(sources) {
|
|
|
10179
10180
|
sources = [sources];
|
|
10180
10181
|
}
|
|
10181
10182
|
const results = await Promise.all(sources.map(parse_one));
|
|
10182
|
-
const state = await default_jungle();
|
|
10183
|
+
const { state, devices } = await default_jungle();
|
|
10183
10184
|
results.forEach((r) => process_assignments(r, state));
|
|
10184
|
-
return state;
|
|
10185
|
+
return { state, devices };
|
|
10185
10186
|
}
|
|
10186
10187
|
function resolve_node_list(state, list) {
|
|
10187
10188
|
if (!Array.isArray(list)) {
|
|
@@ -10303,7 +10304,7 @@ function resolve_filename(literal, default_source = null) {
|
|
|
10303
10304
|
const root = external_path_.dirname(literal.source || default_source);
|
|
10304
10305
|
return external_path_.resolve(root, literal.value);
|
|
10305
10306
|
}
|
|
10306
|
-
async function resolve_literals(qualifier, default_source) {
|
|
10307
|
+
async function resolve_literals(qualifier, default_source, deviceInfo) {
|
|
10307
10308
|
const resolve_file_list = async (literals) => literals &&
|
|
10308
10309
|
(await Promise.all(literals.map(async (v) => {
|
|
10309
10310
|
if (!isJNode(v)) {
|
|
@@ -10346,7 +10347,13 @@ async function resolve_literals(qualifier, default_source) {
|
|
|
10346
10347
|
await resolve_one_file_list(qualifier, "barrelPath");
|
|
10347
10348
|
const lang = qualifier["lang"];
|
|
10348
10349
|
if (lang) {
|
|
10349
|
-
await Promise.all(Object.keys(lang).map((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
|
+
}));
|
|
10350
10357
|
if (Object.keys(lang).length === 0)
|
|
10351
10358
|
delete qualifier["lang"];
|
|
10352
10359
|
}
|
|
@@ -10704,7 +10711,7 @@ async function get_jungle_and_barrels(jungleFiles, defaultProducts, options) {
|
|
|
10704
10711
|
jungles.push(barrels_jungle);
|
|
10705
10712
|
}
|
|
10706
10713
|
}
|
|
10707
|
-
const state = await process_jungles(jungles);
|
|
10714
|
+
const { state, devices } = await process_jungles(jungles);
|
|
10708
10715
|
// apparently square_watch is an alias for rectangle_watch
|
|
10709
10716
|
state["square_watch"] = state["rectangle_watch"];
|
|
10710
10717
|
const manifest_node = resolve_node(state, resolve_node_by_path(state, ["project", "manifest"]));
|
|
@@ -10719,15 +10726,21 @@ async function get_jungle_and_barrels(jungleFiles, defaultProducts, options) {
|
|
|
10719
10726
|
const barrels = manifestBarrels(xml);
|
|
10720
10727
|
const annotations = manifestAnnotations(xml);
|
|
10721
10728
|
const products = manifestProducts(xml);
|
|
10722
|
-
if (products.length === 0)
|
|
10723
|
-
|
|
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
|
+
}
|
|
10724
10737
|
let promise = Promise.resolve();
|
|
10725
10738
|
const add_one = (product, shape = undefined) => {
|
|
10726
10739
|
const rawQualifier = resolve_node(state, state[product]);
|
|
10727
10740
|
if (!rawQualifier || Array.isArray(rawQualifier))
|
|
10728
10741
|
return;
|
|
10729
10742
|
promise = promise
|
|
10730
|
-
.then(() => resolve_literals(rawQualifier, manifest))
|
|
10743
|
+
.then(() => resolve_literals(rawQualifier, manifest, devices[product]))
|
|
10731
10744
|
.then((qualifier) => {
|
|
10732
10745
|
targets.push({ product, qualifier, shape });
|
|
10733
10746
|
return resolve_barrels(product, qualifier, barrels, products, options);
|
|
@@ -10753,7 +10766,7 @@ async function get_jungle_and_barrels(jungleFiles, defaultProducts, options) {
|
|
|
10753
10766
|
}
|
|
10754
10767
|
async function get_jungle(jungles, options) {
|
|
10755
10768
|
options = options || {};
|
|
10756
|
-
const result = await get_jungle_and_barrels(jungles,
|
|
10769
|
+
const result = await get_jungle_and_barrels(jungles, null, options);
|
|
10757
10770
|
identify_optimizer_groups(result.targets, options);
|
|
10758
10771
|
return result;
|
|
10759
10772
|
}
|
|
@@ -10778,11 +10791,282 @@ function simulateProgram(prg, device, test) {
|
|
|
10778
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(() => { }));
|
|
10779
10792
|
}
|
|
10780
10793
|
|
|
10794
|
+
;// CONCATENATED MODULE: ./src/inliner.ts
|
|
10795
|
+
|
|
10796
|
+
function canInline(state, func, args) {
|
|
10797
|
+
// determine whether decl might be changed by a function call
|
|
10798
|
+
// during the evaluation of FunctionStateNode.
|
|
10799
|
+
const getSafety = (decl) => {
|
|
10800
|
+
// enums are constant, they cant change
|
|
10801
|
+
if (decl.type === "EnumStringMember")
|
|
10802
|
+
return true;
|
|
10803
|
+
if (decl.type === "VariableDeclarator") {
|
|
10804
|
+
// constants also can't change
|
|
10805
|
+
if (decl.node.kind === "const")
|
|
10806
|
+
return true;
|
|
10807
|
+
// if decl is a local, it also can't be changed
|
|
10808
|
+
// by a call to another function.
|
|
10809
|
+
for (let i = 0;; i++) {
|
|
10810
|
+
if (!state.stack[i] || decl.stack[i] !== state.stack[i])
|
|
10811
|
+
return false;
|
|
10812
|
+
if (state.stack[i].type === "FunctionDeclaration")
|
|
10813
|
+
return true;
|
|
10814
|
+
}
|
|
10815
|
+
}
|
|
10816
|
+
return null;
|
|
10817
|
+
};
|
|
10818
|
+
const safeArgs = [];
|
|
10819
|
+
let allSafe = true;
|
|
10820
|
+
if (!args.every((arg) => {
|
|
10821
|
+
switch (arg.type) {
|
|
10822
|
+
case "Literal":
|
|
10823
|
+
safeArgs.push(true);
|
|
10824
|
+
return true;
|
|
10825
|
+
case "Identifier":
|
|
10826
|
+
case "MemberExpression": {
|
|
10827
|
+
const [, results] = state.lookup(arg);
|
|
10828
|
+
if (!results || results.length !== 1)
|
|
10829
|
+
return false;
|
|
10830
|
+
const safety = getSafety(results[0]);
|
|
10831
|
+
if (safety === null)
|
|
10832
|
+
return false;
|
|
10833
|
+
if (!safety)
|
|
10834
|
+
allSafe = false;
|
|
10835
|
+
safeArgs.push(safety);
|
|
10836
|
+
return true;
|
|
10837
|
+
}
|
|
10838
|
+
}
|
|
10839
|
+
return false;
|
|
10840
|
+
})) {
|
|
10841
|
+
return false;
|
|
10842
|
+
}
|
|
10843
|
+
if (allSafe)
|
|
10844
|
+
return true;
|
|
10845
|
+
let callSeen = false;
|
|
10846
|
+
let ok = true;
|
|
10847
|
+
const params = Object.fromEntries(func.node.params.map((param, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(param), i]));
|
|
10848
|
+
const getLoc = (node) => (Array.isArray(node) ? node[0].start : node.start) || 0;
|
|
10849
|
+
// look for uses of "unsafe" args that occur after a call.
|
|
10850
|
+
// use post to do the checking, because arguments are evaluated
|
|
10851
|
+
// prior to the call, so eg "return f(x.y);" is fine, but
|
|
10852
|
+
// "return f()+x.y" is not.
|
|
10853
|
+
//
|
|
10854
|
+
// We also have to use a "pre" to ensure that child nodes are
|
|
10855
|
+
// visited in source order (otherwise we could visit x.y before f()
|
|
10856
|
+
// in the above example)
|
|
10857
|
+
(0,external_api_cjs_namespaceObject.traverseAst)(func.node.body, (node) => {
|
|
10858
|
+
return Object.entries(node)
|
|
10859
|
+
.filter((kv) => Array.isArray(kv[1])
|
|
10860
|
+
? kv[1].length !== 0 && (0,external_api_cjs_namespaceObject.hasProperty)(kv[1][0], "type")
|
|
10861
|
+
: (0,external_api_cjs_namespaceObject.hasProperty)(kv[1], "type"))
|
|
10862
|
+
.sort(([, a], [, b]) => getLoc(a) - getLoc(b))
|
|
10863
|
+
.map(([key]) => key);
|
|
10864
|
+
}, (node) => {
|
|
10865
|
+
switch (node.type) {
|
|
10866
|
+
case "CallExpression":
|
|
10867
|
+
case "NewExpression":
|
|
10868
|
+
callSeen = true;
|
|
10869
|
+
break;
|
|
10870
|
+
case "Identifier":
|
|
10871
|
+
if (callSeen &&
|
|
10872
|
+
(0,external_api_cjs_namespaceObject.hasProperty)(params, node.name) &&
|
|
10873
|
+
!safeArgs[params[node.name]]) {
|
|
10874
|
+
ok = false;
|
|
10875
|
+
}
|
|
10876
|
+
}
|
|
10877
|
+
});
|
|
10878
|
+
return ok;
|
|
10879
|
+
}
|
|
10880
|
+
function inliningLooksUseful(func, node) {
|
|
10881
|
+
while (true) {
|
|
10882
|
+
if (node.type === "BinaryExpression" && node.operator === "as") {
|
|
10883
|
+
node = node.left;
|
|
10884
|
+
}
|
|
10885
|
+
else if (node.type === "UnaryExpression" && node.operator === " as") {
|
|
10886
|
+
node = node.argument;
|
|
10887
|
+
}
|
|
10888
|
+
else {
|
|
10889
|
+
break;
|
|
10890
|
+
}
|
|
10891
|
+
}
|
|
10892
|
+
if (node.type === "Literal")
|
|
10893
|
+
return true;
|
|
10894
|
+
if (node.type === "Identifier") {
|
|
10895
|
+
if (func.params.length === 1 &&
|
|
10896
|
+
(0,external_api_cjs_namespaceObject.variableDeclarationName)(func.params[0]) === node.name) {
|
|
10897
|
+
return 1;
|
|
10898
|
+
}
|
|
10899
|
+
return true;
|
|
10900
|
+
}
|
|
10901
|
+
return false;
|
|
10902
|
+
}
|
|
10903
|
+
function shouldInline(state, func, args) {
|
|
10904
|
+
if (!func.node.body ||
|
|
10905
|
+
func.node.body.body.length !== 1 ||
|
|
10906
|
+
func.node.body.body[0].type !== "ReturnStatement" ||
|
|
10907
|
+
!func.node.body.body[0].argument ||
|
|
10908
|
+
func.node.params.length !== args.length) {
|
|
10909
|
+
return false;
|
|
10910
|
+
}
|
|
10911
|
+
const autoInline = inliningLooksUseful(func.node, func.node.body.body[0].argument);
|
|
10912
|
+
const excludeAnnotations = (func.node.loc?.source &&
|
|
10913
|
+
state.fnMap[func.node.loc?.source].excludeAnnotations) ||
|
|
10914
|
+
{};
|
|
10915
|
+
return ((autoInline ||
|
|
10916
|
+
(func.node.attrs &&
|
|
10917
|
+
func.node.attrs.attrs &&
|
|
10918
|
+
func.node.attrs.attrs.some((attr) => attr.type === "UnaryExpression" &&
|
|
10919
|
+
(attr.argument.name === "inline" ||
|
|
10920
|
+
(attr.argument.name.startsWith("inline_") &&
|
|
10921
|
+
(0,external_api_cjs_namespaceObject.hasProperty)(excludeAnnotations, attr.argument.name.substring(7))))))) &&
|
|
10922
|
+
(autoInline === 1 || canInline(state, func, args)));
|
|
10923
|
+
}
|
|
10924
|
+
function inlineFunction(state, func, call) {
|
|
10925
|
+
const retArg = JSON.parse(JSON.stringify(func.node.body.body[0].argument));
|
|
10926
|
+
const params = Object.fromEntries(func.node.params.map((param, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(param), i]));
|
|
10927
|
+
try {
|
|
10928
|
+
const result = (0,external_api_cjs_namespaceObject.traverseAst)(retArg, (node) => {
|
|
10929
|
+
switch (node.type) {
|
|
10930
|
+
case "MemberExpression":
|
|
10931
|
+
if (!node.computed) {
|
|
10932
|
+
return ["object"];
|
|
10933
|
+
}
|
|
10934
|
+
break;
|
|
10935
|
+
case "BinaryExpression":
|
|
10936
|
+
if (node.operator === "as") {
|
|
10937
|
+
return ["left"];
|
|
10938
|
+
}
|
|
10939
|
+
break;
|
|
10940
|
+
case "UnaryExpression":
|
|
10941
|
+
if (node.operator === " as") {
|
|
10942
|
+
return [];
|
|
10943
|
+
}
|
|
10944
|
+
}
|
|
10945
|
+
return null;
|
|
10946
|
+
}, (node) => {
|
|
10947
|
+
switch (node.type) {
|
|
10948
|
+
case "Identifier": {
|
|
10949
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(params, node.name)) {
|
|
10950
|
+
return call.arguments[params[node.name]];
|
|
10951
|
+
}
|
|
10952
|
+
const rep = fixNodeScope(state, node, func.stack);
|
|
10953
|
+
if (!rep) {
|
|
10954
|
+
throw new Error(`Inliner: Couldn't fix the scope of '${node.name}`);
|
|
10955
|
+
}
|
|
10956
|
+
return rep;
|
|
10957
|
+
}
|
|
10958
|
+
}
|
|
10959
|
+
return null;
|
|
10960
|
+
}) || retArg;
|
|
10961
|
+
result.loc = call.loc;
|
|
10962
|
+
result.start = call.start;
|
|
10963
|
+
result.end = call.end;
|
|
10964
|
+
return result;
|
|
10965
|
+
}
|
|
10966
|
+
catch (ex) {
|
|
10967
|
+
if (ex instanceof Error) {
|
|
10968
|
+
if (ex.message.startsWith("Inliner: ")) {
|
|
10969
|
+
return null;
|
|
10970
|
+
}
|
|
10971
|
+
}
|
|
10972
|
+
throw ex;
|
|
10973
|
+
}
|
|
10974
|
+
}
|
|
10975
|
+
function applyTypeIfNeeded(node) {
|
|
10976
|
+
if ("enumType" in node && node.enumType) {
|
|
10977
|
+
node = {
|
|
10978
|
+
type: "BinaryExpression",
|
|
10979
|
+
operator: "as",
|
|
10980
|
+
left: node,
|
|
10981
|
+
right: { type: "TypeSpecList", ts: [node.enumType] },
|
|
10982
|
+
};
|
|
10983
|
+
}
|
|
10984
|
+
return node;
|
|
10985
|
+
}
|
|
10986
|
+
function fixNodeScope(state, lookupNode, nodeStack) {
|
|
10987
|
+
const [, original] = state.lookup(lookupNode, null, nodeStack);
|
|
10988
|
+
if (!original) {
|
|
10989
|
+
return null;
|
|
10990
|
+
}
|
|
10991
|
+
const [, current] = state.lookup(lookupNode);
|
|
10992
|
+
// For now, leave it alone if it already maps to the same thing.
|
|
10993
|
+
// With a bit more work, we could find the guaranteed shortest
|
|
10994
|
+
// reference, and then use this to optimize *all* symbols, not
|
|
10995
|
+
// just fix inlined ones.
|
|
10996
|
+
if (current &&
|
|
10997
|
+
current.length === original.length &&
|
|
10998
|
+
current.every((item, index) => item == original[index])) {
|
|
10999
|
+
return lookupNode;
|
|
11000
|
+
}
|
|
11001
|
+
const node = lookupNode.type === "Identifier"
|
|
11002
|
+
? lookupNode
|
|
11003
|
+
: lookupNode.property;
|
|
11004
|
+
if (original.length === 1 && original[0].type === "EnumStringMember") {
|
|
11005
|
+
return applyTypeIfNeeded(original[0].init);
|
|
11006
|
+
}
|
|
11007
|
+
const prefixes = original.map((sn) => {
|
|
11008
|
+
if ((0,external_api_cjs_namespaceObject.isStateNode)(sn) && sn.fullName) {
|
|
11009
|
+
return sn.fullName;
|
|
11010
|
+
}
|
|
11011
|
+
return "";
|
|
11012
|
+
});
|
|
11013
|
+
if (prefixes.length &&
|
|
11014
|
+
prefixes[0].startsWith("$.") &&
|
|
11015
|
+
prefixes.every((prefix, i) => !i || prefix === prefixes[i - 1])) {
|
|
11016
|
+
const prefix = prefixes[0].split(".").slice(0, -1).reverse();
|
|
11017
|
+
let found = false;
|
|
11018
|
+
return prefix.reduce((current, name) => {
|
|
11019
|
+
if (found)
|
|
11020
|
+
return current;
|
|
11021
|
+
const [, results] = state.lookup(current);
|
|
11022
|
+
if (results &&
|
|
11023
|
+
results.length === original.length &&
|
|
11024
|
+
results.every((result, i) => result === original[i])) {
|
|
11025
|
+
found = true;
|
|
11026
|
+
return current;
|
|
11027
|
+
}
|
|
11028
|
+
const object = typeof name === "string"
|
|
11029
|
+
? {
|
|
11030
|
+
type: "Identifier",
|
|
11031
|
+
name,
|
|
11032
|
+
start: node.start,
|
|
11033
|
+
end: node.end,
|
|
11034
|
+
loc: node.loc,
|
|
11035
|
+
}
|
|
11036
|
+
: name;
|
|
11037
|
+
let root = null;
|
|
11038
|
+
let property = current;
|
|
11039
|
+
while (property.type !== "Identifier") {
|
|
11040
|
+
root = property;
|
|
11041
|
+
property = property.object;
|
|
11042
|
+
}
|
|
11043
|
+
const mb = {
|
|
11044
|
+
type: "MemberExpression",
|
|
11045
|
+
object,
|
|
11046
|
+
property,
|
|
11047
|
+
computed: false,
|
|
11048
|
+
start: node.start,
|
|
11049
|
+
end: node.end,
|
|
11050
|
+
loc: node.loc,
|
|
11051
|
+
};
|
|
11052
|
+
if (root) {
|
|
11053
|
+
root.object = mb;
|
|
11054
|
+
}
|
|
11055
|
+
else {
|
|
11056
|
+
current = mb;
|
|
11057
|
+
}
|
|
11058
|
+
return current;
|
|
11059
|
+
}, node);
|
|
11060
|
+
}
|
|
11061
|
+
return null;
|
|
11062
|
+
}
|
|
11063
|
+
|
|
10781
11064
|
;// CONCATENATED MODULE: ./src/mc-rewrite.ts
|
|
10782
11065
|
|
|
10783
11066
|
|
|
10784
11067
|
|
|
10785
11068
|
|
|
11069
|
+
|
|
10786
11070
|
function processImports(allImports, lookup) {
|
|
10787
11071
|
allImports.forEach(({ node, stack }) => {
|
|
10788
11072
|
const [name, module] = lookup(node.id, ("as" in node && node.as && node.as.name) || null, stack);
|
|
@@ -10791,11 +11075,21 @@ function processImports(allImports, lookup) {
|
|
|
10791
11075
|
if (!parent.decls)
|
|
10792
11076
|
parent.decls = {};
|
|
10793
11077
|
const decls = parent.decls;
|
|
10794
|
-
if (!(0,external_api_cjs_namespaceObject.hasProperty)(
|
|
10795
|
-
|
|
11078
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(decls, name))
|
|
11079
|
+
decls[name] = [];
|
|
10796
11080
|
module.forEach((m) => {
|
|
10797
11081
|
if ((0,external_api_cjs_namespaceObject.isStateNode)(m) && m.type == "ModuleDeclaration") {
|
|
10798
11082
|
(0,external_util_cjs_namespaceObject.pushUnique)(decls[name], m);
|
|
11083
|
+
if (node.type == "ImportModule" && m.type_decls) {
|
|
11084
|
+
if (!parent.type_decls)
|
|
11085
|
+
parent.type_decls = {};
|
|
11086
|
+
const tdecls = parent.type_decls;
|
|
11087
|
+
Object.entries(m.type_decls).forEach(([name, decls]) => {
|
|
11088
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(tdecls, name))
|
|
11089
|
+
tdecls[name] = [];
|
|
11090
|
+
decls.forEach((decl) => (0,external_util_cjs_namespaceObject.pushUnique)(tdecls[name], decl));
|
|
11091
|
+
});
|
|
11092
|
+
}
|
|
10799
11093
|
}
|
|
10800
11094
|
});
|
|
10801
11095
|
}
|
|
@@ -10804,11 +11098,39 @@ function processImports(allImports, lookup) {
|
|
|
10804
11098
|
function collectClassInfo(state) {
|
|
10805
11099
|
state.allClasses.forEach((elm) => {
|
|
10806
11100
|
if (elm.node.superClass) {
|
|
10807
|
-
const [, classes] = state.lookup(elm.node.superClass, null, elm.stack);
|
|
11101
|
+
const [name, classes] = state.lookup(elm.node.superClass, null, elm.stack);
|
|
10808
11102
|
const superClass = classes &&
|
|
10809
11103
|
classes.filter((c) => (0,external_api_cjs_namespaceObject.isStateNode)(c) && c.type === "ClassDeclaration");
|
|
10810
11104
|
// set it "true" if there is a superClass, but we can't find it.
|
|
10811
11105
|
elm.superClass = superClass && superClass.length ? superClass : true;
|
|
11106
|
+
if (name && elm.superClass !== true) {
|
|
11107
|
+
/*
|
|
11108
|
+
* The runtime behavior of monkeyc is strange. Lookups
|
|
11109
|
+
* of the name of the superclass, either bare, or via self.<name>
|
|
11110
|
+
* always find the superclass, even if there's a member variable
|
|
11111
|
+
* or method of the same name. So its ok to just overwrite
|
|
11112
|
+
* elm.decls[name] here.
|
|
11113
|
+
*
|
|
11114
|
+
* ie
|
|
11115
|
+
*
|
|
11116
|
+
* class A { function foo() as Number { return 1; } }
|
|
11117
|
+
* class B { function foo() as String { return "B"; } }
|
|
11118
|
+
* class C extends A {
|
|
11119
|
+
* var A as B = new B();
|
|
11120
|
+
* function initialize() {
|
|
11121
|
+
* A.initialize(); // class A's initialize
|
|
11122
|
+
* A.foo(); // returns 1
|
|
11123
|
+
* self.A.foo(); // still returns 1
|
|
11124
|
+
* }
|
|
11125
|
+
* }
|
|
11126
|
+
*
|
|
11127
|
+
* The typechecker seems to get confused in some circumstances
|
|
11128
|
+
* though (ie it doesn't always use the same rules)
|
|
11129
|
+
*/
|
|
11130
|
+
if (!elm.decls)
|
|
11131
|
+
elm.decls = {};
|
|
11132
|
+
elm.decls[name] = elm.superClass;
|
|
11133
|
+
}
|
|
10812
11134
|
}
|
|
10813
11135
|
});
|
|
10814
11136
|
const markOverrides = (cls, scls) => {
|
|
@@ -10863,32 +11185,36 @@ function getFileASTs(fnMap) {
|
|
|
10863
11185
|
}, true));
|
|
10864
11186
|
}
|
|
10865
11187
|
async function analyze(fnMap) {
|
|
10866
|
-
let excludeAnnotations;
|
|
10867
11188
|
let hasTests = false;
|
|
10868
11189
|
const allImports = [];
|
|
10869
11190
|
const preState = {
|
|
11191
|
+
fnMap,
|
|
10870
11192
|
allFunctions: [],
|
|
10871
11193
|
allClasses: [],
|
|
10872
11194
|
shouldExclude(node) {
|
|
10873
11195
|
if ("attrs" in node &&
|
|
10874
11196
|
node.attrs &&
|
|
10875
11197
|
"attrs" in node.attrs &&
|
|
10876
|
-
node.attrs.attrs
|
|
10877
|
-
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
11198
|
+
node.attrs.attrs &&
|
|
11199
|
+
node.loc?.source) {
|
|
11200
|
+
const excludeAnnotations = fnMap[node.loc.source].excludeAnnotations;
|
|
11201
|
+
if (excludeAnnotations) {
|
|
11202
|
+
return node.attrs.attrs.reduce((drop, attr) => {
|
|
11203
|
+
if (attr.type != "UnaryExpression")
|
|
11204
|
+
return drop;
|
|
11205
|
+
if (attr.argument.type != "Identifier")
|
|
11206
|
+
return drop;
|
|
11207
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(excludeAnnotations, attr.argument.name)) {
|
|
11208
|
+
return true;
|
|
11209
|
+
}
|
|
11210
|
+
if (attr.argument.name == "test") {
|
|
11211
|
+
hasTests = true;
|
|
11212
|
+
}
|
|
10881
11213
|
return drop;
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
}
|
|
10885
|
-
if (attr.argument.name == "test") {
|
|
10886
|
-
hasTests = true;
|
|
10887
|
-
}
|
|
10888
|
-
return drop;
|
|
10889
|
-
}, false);
|
|
11214
|
+
}, false);
|
|
11215
|
+
}
|
|
10890
11216
|
}
|
|
10891
|
-
return
|
|
11217
|
+
return false;
|
|
10892
11218
|
},
|
|
10893
11219
|
post(node, state) {
|
|
10894
11220
|
switch (node.type) {
|
|
@@ -10935,7 +11261,6 @@ async function analyze(fnMap) {
|
|
|
10935
11261
|
if (!ast) {
|
|
10936
11262
|
throw parserError || new Error(`Failed to parse ${name}`);
|
|
10937
11263
|
}
|
|
10938
|
-
excludeAnnotations = value.excludeAnnotations;
|
|
10939
11264
|
hasTests = false;
|
|
10940
11265
|
(0,external_api_cjs_namespaceObject.collectNamespaces)(ast, state);
|
|
10941
11266
|
value.hasTests = hasTests;
|
|
@@ -10959,8 +11284,8 @@ function getLiteralFromDecls(decls) {
|
|
|
10959
11284
|
let result = null;
|
|
10960
11285
|
if (decls.every((d) => {
|
|
10961
11286
|
if (d.type === "EnumStringMember" ||
|
|
10962
|
-
(d.type === "VariableDeclarator" && d.kind === "const")) {
|
|
10963
|
-
const init = getLiteralNode(d.init);
|
|
11287
|
+
(d.type === "VariableDeclarator" && d.node.kind === "const")) {
|
|
11288
|
+
const init = getLiteralNode(d.type === "EnumStringMember" ? d.init : d.node.init);
|
|
10964
11289
|
if (!init)
|
|
10965
11290
|
return false;
|
|
10966
11291
|
if (!result) {
|
|
@@ -11242,11 +11567,12 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11242
11567
|
* anywhere in its superClass chain.
|
|
11243
11568
|
*/
|
|
11244
11569
|
const checkInherited = (elm, name) => elm.superClass === true ||
|
|
11245
|
-
elm.superClass
|
|
11246
|
-
|
|
11247
|
-
f
|
|
11248
|
-
|
|
11249
|
-
|
|
11570
|
+
(elm.superClass != null &&
|
|
11571
|
+
elm.superClass.some((sc) => ((0,external_api_cjs_namespaceObject.hasProperty)(sc.decls, name) &&
|
|
11572
|
+
sc.decls[name].some((f) => (0,external_api_cjs_namespaceObject.isStateNode)(f) &&
|
|
11573
|
+
f.type == "FunctionDeclaration" &&
|
|
11574
|
+
maybeCalled(f.node))) ||
|
|
11575
|
+
(sc.superClass && checkInherited(sc, name))));
|
|
11250
11576
|
state.pre = (node) => {
|
|
11251
11577
|
switch (node.type) {
|
|
11252
11578
|
case "ConditionalExpression":
|
|
@@ -11489,11 +11815,9 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11489
11815
|
}
|
|
11490
11816
|
return null;
|
|
11491
11817
|
}
|
|
11492
|
-
if (callees.length == 1) {
|
|
11493
|
-
const callee =
|
|
11494
|
-
if (callee &&
|
|
11495
|
-
callee.type == "FunctionDeclaration" &&
|
|
11496
|
-
callee.optimizable &&
|
|
11818
|
+
if (callees.length == 1 && callees[0].type === "FunctionDeclaration") {
|
|
11819
|
+
const callee = callees[0].node;
|
|
11820
|
+
if (callee.optimizable &&
|
|
11497
11821
|
!callee.hasOverride &&
|
|
11498
11822
|
node.arguments.every((n) => getNodeValue(n)[0] !== null)) {
|
|
11499
11823
|
const ret = evaluateFunction(callee, node.arguments);
|
|
@@ -11502,6 +11826,13 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11502
11826
|
return null;
|
|
11503
11827
|
}
|
|
11504
11828
|
}
|
|
11829
|
+
if (shouldInline(state, callees[0], node.arguments)) {
|
|
11830
|
+
const ret = inlineFunction(state, callees[0], node);
|
|
11831
|
+
if (ret) {
|
|
11832
|
+
replace(node, ret);
|
|
11833
|
+
return null;
|
|
11834
|
+
}
|
|
11835
|
+
}
|
|
11505
11836
|
}
|
|
11506
11837
|
if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, name)) {
|
|
11507
11838
|
state.calledFunctions[name] = [];
|
|
@@ -11515,71 +11846,79 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11515
11846
|
Object.values(fnMap).forEach((f) => {
|
|
11516
11847
|
(0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
|
|
11517
11848
|
});
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
|
|
11523
|
-
|
|
11524
|
-
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
|
|
11534
|
-
|
|
11535
|
-
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
|
|
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;
|
|
11849
|
+
delete state.pre;
|
|
11850
|
+
delete state.post;
|
|
11851
|
+
const cleanup = (node) => {
|
|
11852
|
+
switch (node.type) {
|
|
11853
|
+
case "EnumStringBody":
|
|
11854
|
+
if (node.members.every((m) => {
|
|
11855
|
+
const name = "name" in m ? m.name : m.id.name;
|
|
11856
|
+
return ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) &&
|
|
11857
|
+
!(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name));
|
|
11858
|
+
})) {
|
|
11859
|
+
node.enumType = [
|
|
11860
|
+
...new Set(node.members.map((m) => {
|
|
11861
|
+
if (!("init" in m))
|
|
11862
|
+
return "Number";
|
|
11863
|
+
const [node, type] = getNodeValue(m.init);
|
|
11864
|
+
if (!node) {
|
|
11865
|
+
throw new Error("Failed to get type for eliminated enum");
|
|
11866
|
+
}
|
|
11867
|
+
return type;
|
|
11868
|
+
})),
|
|
11869
|
+
].join(" or ");
|
|
11870
|
+
node.members.splice(0);
|
|
11570
11871
|
}
|
|
11571
|
-
|
|
11572
|
-
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
break;
|
|
11576
|
-
case "FunctionDeclaration":
|
|
11577
|
-
if (!maybeCalled(node)) {
|
|
11872
|
+
break;
|
|
11873
|
+
case "EnumDeclaration":
|
|
11874
|
+
if (!node.body.members.length) {
|
|
11875
|
+
if (!node.id)
|
|
11578
11876
|
return false;
|
|
11877
|
+
if (!node.body["enumType"]) {
|
|
11878
|
+
throw new Error("Missing enumType on optimized enum");
|
|
11579
11879
|
}
|
|
11580
|
-
|
|
11880
|
+
replace(node, {
|
|
11881
|
+
type: "TypedefDeclaration",
|
|
11882
|
+
id: node.id,
|
|
11883
|
+
ts: {
|
|
11884
|
+
type: "UnaryExpression",
|
|
11885
|
+
argument: { type: "TypeSpecList", ts: [node.body.enumType] },
|
|
11886
|
+
prefix: true,
|
|
11887
|
+
operator: " as",
|
|
11888
|
+
},
|
|
11889
|
+
});
|
|
11890
|
+
}
|
|
11891
|
+
break;
|
|
11892
|
+
case "VariableDeclaration": {
|
|
11893
|
+
node.declarations = node.declarations.filter((d) => {
|
|
11894
|
+
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(d.id);
|
|
11895
|
+
return (!(0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) || (0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name));
|
|
11896
|
+
});
|
|
11897
|
+
if (!node.declarations.length) {
|
|
11898
|
+
return false;
|
|
11899
|
+
}
|
|
11900
|
+
break;
|
|
11581
11901
|
}
|
|
11582
|
-
|
|
11902
|
+
case "ClassElement":
|
|
11903
|
+
if (!node.item) {
|
|
11904
|
+
return false;
|
|
11905
|
+
}
|
|
11906
|
+
break;
|
|
11907
|
+
case "FunctionDeclaration":
|
|
11908
|
+
if (!maybeCalled(node)) {
|
|
11909
|
+
return false;
|
|
11910
|
+
}
|
|
11911
|
+
break;
|
|
11912
|
+
}
|
|
11913
|
+
return null;
|
|
11914
|
+
};
|
|
11915
|
+
Object.values(fnMap).forEach((f) => {
|
|
11916
|
+
(0,external_api_cjs_namespaceObject.traverseAst)(f.ast, undefined, (node) => {
|
|
11917
|
+
const ret = cleanup(node);
|
|
11918
|
+
if (ret === false) {
|
|
11919
|
+
state.removeNodeComments(node, f.ast);
|
|
11920
|
+
}
|
|
11921
|
+
return ret;
|
|
11583
11922
|
});
|
|
11584
11923
|
});
|
|
11585
11924
|
}
|
|
@@ -11996,6 +12335,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
11996
12335
|
// might have altered it), and that the options we care about haven't
|
|
11997
12336
|
// changed
|
|
11998
12337
|
if (hasTests != null &&
|
|
12338
|
+
!config.checkBuildPragmas &&
|
|
11999
12339
|
configOptionsToCheck.every((option) => prevOptions[option] === config[option]) &&
|
|
12000
12340
|
actualOptimizedFiles.length == Object.values(fnMap).length &&
|
|
12001
12341
|
Object.values(fnMap)
|
|
@@ -12006,7 +12346,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
12006
12346
|
// the oldest optimized file, we don't need to regenerate
|
|
12007
12347
|
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
12008
12348
|
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
12009
|
-
if (source_time < opt_time &&
|
|
12349
|
+
if (source_time < opt_time && 1654222986123 < opt_time) {
|
|
12010
12350
|
return hasTests;
|
|
12011
12351
|
}
|
|
12012
12352
|
}
|
|
@@ -12018,6 +12358,14 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
12018
12358
|
const dir = external_path_.dirname(name);
|
|
12019
12359
|
await promises_namespaceObject.mkdir(dir, { recursive: true });
|
|
12020
12360
|
const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(info.ast, info.monkeyCSource);
|
|
12361
|
+
if (config.checkBuildPragmas) {
|
|
12362
|
+
const matches = opt_source.matchAll(/^.*\/\*\s*@match\s+(\S+)\s+\*\/(.*)$/gm);
|
|
12363
|
+
for (const [line, needle, haystack] of matches) {
|
|
12364
|
+
if (!haystack.includes(needle)) {
|
|
12365
|
+
throw new Error(`Checking build pragmas in ${name} failed at \n\n${line}\n\n - Didn't find '${needle}'`);
|
|
12366
|
+
}
|
|
12367
|
+
}
|
|
12368
|
+
}
|
|
12021
12369
|
await promises_namespaceObject.writeFile(name, opt_source);
|
|
12022
12370
|
return info.hasTests;
|
|
12023
12371
|
})).then((results) => {
|
|
@@ -12075,11 +12423,12 @@ async function generateApiMirTests(options) {
|
|
|
12075
12423
|
return;
|
|
12076
12424
|
const d = decl[0];
|
|
12077
12425
|
if (d.type === "EnumStringMember" ||
|
|
12078
|
-
(d.type === "VariableDeclarator" && d.kind === "const")) {
|
|
12079
|
-
|
|
12426
|
+
(d.type === "VariableDeclarator" && d.node.kind === "const")) {
|
|
12427
|
+
const init = (0,external_api_cjs_namespaceObject.isStateNode)(d) ? d.node.init : d.init;
|
|
12428
|
+
if (!init) {
|
|
12080
12429
|
throw new Error(`Missing init for ${node.fullName}.${key}`);
|
|
12081
12430
|
}
|
|
12082
|
-
tests.push([`${node.fullName}.${key}`, (0,external_api_cjs_namespaceObject.formatAst)(
|
|
12431
|
+
tests.push([`${node.fullName}.${key}`, (0,external_api_cjs_namespaceObject.formatAst)(init)]);
|
|
12083
12432
|
}
|
|
12084
12433
|
else if ((0,external_api_cjs_namespaceObject.isStateNode)(d)) {
|
|
12085
12434
|
findConstants(d);
|