@markw65/monkeyc-optimizer 1.0.13 → 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.
- package/README.md +14 -0
- package/build/api.cjs +112 -71
- package/build/optimizer.cjs +221 -202
- package/build/sdk-util.cjs +8 -2
- package/build/src/optimizer.d.ts +3 -2
- package/build/src/sdk-util.d.ts +4 -2
- package/build/util.cjs +12 -4
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -141,3 +141,17 @@ More fixes found via open source projects.
|
|
|
141
141
|
|
|
142
142
|
- Tests
|
|
143
143
|
- Add date/time to test logging
|
|
144
|
+
|
|
145
|
+
### 1.0.14
|
|
146
|
+
|
|
147
|
+
- Bug fixes
|
|
148
|
+
|
|
149
|
+
- When reading a barrel project with no products, add all products by default
|
|
150
|
+
- Only set language specific paths for languages that are supported by the device
|
|
151
|
+
- Remove comments that are completely contained within removed nodes
|
|
152
|
+
|
|
153
|
+
- Code cleanup
|
|
154
|
+
- Upgrade to @markw65/prettier-plugin-monkeyc@1.0.21 for some typescript fixes
|
|
155
|
+
- npm upgrade to pickup ts 4.7.2
|
|
156
|
+
- Add types to package exports for ts 4.7.2
|
|
157
|
+
- Better handling of program-logic errors
|
package/build/api.cjs
CHANGED
|
@@ -346,7 +346,7 @@ async function analyze(fnMap) {
|
|
|
346
346
|
return drop;
|
|
347
347
|
}, false);
|
|
348
348
|
}
|
|
349
|
-
return
|
|
349
|
+
return false;
|
|
350
350
|
},
|
|
351
351
|
post(node, state) {
|
|
352
352
|
switch (node.type) {
|
|
@@ -973,71 +973,77 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
973
973
|
Object.values(fnMap).forEach((f) => {
|
|
974
974
|
collectNamespaces(f.ast, state);
|
|
975
975
|
});
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
node.
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
node.members.splice(0);
|
|
997
|
-
}
|
|
998
|
-
break;
|
|
999
|
-
case "EnumDeclaration":
|
|
1000
|
-
if (!node.body.members.length) {
|
|
1001
|
-
if (!node.id)
|
|
1002
|
-
return false;
|
|
1003
|
-
if (!node.body["enumType"]) {
|
|
1004
|
-
throw new Error("Missing enumType on optimized enum");
|
|
1005
|
-
}
|
|
1006
|
-
replace(node, {
|
|
1007
|
-
type: "TypedefDeclaration",
|
|
1008
|
-
id: node.id,
|
|
1009
|
-
ts: {
|
|
1010
|
-
type: "UnaryExpression",
|
|
1011
|
-
argument: { type: "TypeSpecList", ts: [node.body.enumType] },
|
|
1012
|
-
prefix: true,
|
|
1013
|
-
operator: " as",
|
|
1014
|
-
},
|
|
1015
|
-
});
|
|
1016
|
-
}
|
|
1017
|
-
break;
|
|
1018
|
-
case "VariableDeclaration": {
|
|
1019
|
-
node.declarations = node.declarations.filter((d) => {
|
|
1020
|
-
const name = variableDeclarationName(d.id);
|
|
1021
|
-
return (!hasProperty(state.index, name) ||
|
|
1022
|
-
hasProperty(state.exposed, name));
|
|
1023
|
-
});
|
|
1024
|
-
if (!node.declarations.length) {
|
|
1025
|
-
return false;
|
|
1026
|
-
}
|
|
1027
|
-
break;
|
|
976
|
+
const cleanup = (node) => {
|
|
977
|
+
switch (node.type) {
|
|
978
|
+
case "EnumStringBody":
|
|
979
|
+
if (node.members.every((m) => {
|
|
980
|
+
const name = "name" in m ? m.name : m.id.name;
|
|
981
|
+
return (hasProperty(state.index, name) &&
|
|
982
|
+
!hasProperty(state.exposed, name));
|
|
983
|
+
})) {
|
|
984
|
+
node.enumType = [
|
|
985
|
+
...new Set(node.members.map((m) => {
|
|
986
|
+
if (!("init" in m))
|
|
987
|
+
return "Number";
|
|
988
|
+
const [node, type] = getNodeValue(m.init);
|
|
989
|
+
if (!node) {
|
|
990
|
+
throw new Error("Failed to get type for eliminated enum");
|
|
991
|
+
}
|
|
992
|
+
return type;
|
|
993
|
+
})),
|
|
994
|
+
].join(" or ");
|
|
995
|
+
node.members.splice(0);
|
|
1028
996
|
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
break;
|
|
1034
|
-
case "FunctionDeclaration":
|
|
1035
|
-
if (!maybeCalled(node)) {
|
|
997
|
+
break;
|
|
998
|
+
case "EnumDeclaration":
|
|
999
|
+
if (!node.body.members.length) {
|
|
1000
|
+
if (!node.id)
|
|
1036
1001
|
return false;
|
|
1002
|
+
if (!node.body["enumType"]) {
|
|
1003
|
+
throw new Error("Missing enumType on optimized enum");
|
|
1037
1004
|
}
|
|
1038
|
-
|
|
1005
|
+
replace(node, {
|
|
1006
|
+
type: "TypedefDeclaration",
|
|
1007
|
+
id: node.id,
|
|
1008
|
+
ts: {
|
|
1009
|
+
type: "UnaryExpression",
|
|
1010
|
+
argument: { type: "TypeSpecList", ts: [node.body.enumType] },
|
|
1011
|
+
prefix: true,
|
|
1012
|
+
operator: " as",
|
|
1013
|
+
},
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
break;
|
|
1017
|
+
case "VariableDeclaration": {
|
|
1018
|
+
node.declarations = node.declarations.filter((d) => {
|
|
1019
|
+
const name = variableDeclarationName(d.id);
|
|
1020
|
+
return (!hasProperty(state.index, name) || hasProperty(state.exposed, name));
|
|
1021
|
+
});
|
|
1022
|
+
if (!node.declarations.length) {
|
|
1023
|
+
return false;
|
|
1024
|
+
}
|
|
1025
|
+
break;
|
|
1039
1026
|
}
|
|
1040
|
-
|
|
1027
|
+
case "ClassElement":
|
|
1028
|
+
if (!node.item) {
|
|
1029
|
+
return false;
|
|
1030
|
+
}
|
|
1031
|
+
break;
|
|
1032
|
+
case "FunctionDeclaration":
|
|
1033
|
+
if (!maybeCalled(node)) {
|
|
1034
|
+
return false;
|
|
1035
|
+
}
|
|
1036
|
+
break;
|
|
1037
|
+
}
|
|
1038
|
+
return null;
|
|
1039
|
+
};
|
|
1040
|
+
Object.values(fnMap).forEach((f) => {
|
|
1041
|
+
traverseAst(f.ast, undefined, (node) => {
|
|
1042
|
+
const ret = cleanup(node);
|
|
1043
|
+
if (ret === false) {
|
|
1044
|
+
state.removeNodeComments(node, f.ast);
|
|
1045
|
+
}
|
|
1046
|
+
return ret;
|
|
1041
1047
|
});
|
|
1042
1048
|
});
|
|
1043
1049
|
}
|
|
@@ -1190,6 +1196,30 @@ function api_collectNamespaces(ast, stateIn) {
|
|
|
1190
1196
|
}
|
|
1191
1197
|
return null;
|
|
1192
1198
|
};
|
|
1199
|
+
state.removeNodeComments = (node, ast) => {
|
|
1200
|
+
if (node.start && node.end && ast.comments && ast.comments.length) {
|
|
1201
|
+
let low = 0, high = ast.comments.length;
|
|
1202
|
+
while (true) {
|
|
1203
|
+
const mid = (low + high) >> 1;
|
|
1204
|
+
if (mid == low) {
|
|
1205
|
+
if (ast.comments[mid].start < node.start) {
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
break;
|
|
1209
|
+
}
|
|
1210
|
+
if (ast.comments[mid].start < node.start) {
|
|
1211
|
+
low = mid;
|
|
1212
|
+
}
|
|
1213
|
+
else {
|
|
1214
|
+
high = mid;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
for (high = low; high < ast.comments.length && ast.comments[high].end < node.end; high++) { }
|
|
1218
|
+
if (high > low) {
|
|
1219
|
+
ast.comments.splice(low, high - low);
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
};
|
|
1193
1223
|
state.lookup = (node, name, stack) => {
|
|
1194
1224
|
stack || (stack = state.stack);
|
|
1195
1225
|
switch (node.type) {
|
|
@@ -1400,12 +1430,17 @@ function api_collectNamespaces(ast, stateIn) {
|
|
|
1400
1430
|
let ret;
|
|
1401
1431
|
if (state.shouldExclude && state.shouldExclude(node)) {
|
|
1402
1432
|
// delete the node.
|
|
1403
|
-
|
|
1433
|
+
ret = false;
|
|
1434
|
+
}
|
|
1435
|
+
else {
|
|
1436
|
+
if (state.post)
|
|
1437
|
+
ret = state.post(node, state);
|
|
1438
|
+
if (state.stack.slice(-1).pop()?.node === node) {
|
|
1439
|
+
state.stack.pop();
|
|
1440
|
+
}
|
|
1404
1441
|
}
|
|
1405
|
-
if (
|
|
1406
|
-
|
|
1407
|
-
if (state.stack.slice(-1).pop()?.node === node) {
|
|
1408
|
-
state.stack.pop();
|
|
1442
|
+
if (ret === false) {
|
|
1443
|
+
state.removeNodeComments(node, ast);
|
|
1409
1444
|
}
|
|
1410
1445
|
return ret;
|
|
1411
1446
|
}
|
|
@@ -1500,7 +1535,6 @@ function formatAst(node, monkeyCSource = null) {
|
|
|
1500
1535
|
});
|
|
1501
1536
|
}
|
|
1502
1537
|
function handleException(state, node, exception) {
|
|
1503
|
-
let message;
|
|
1504
1538
|
try {
|
|
1505
1539
|
const fullName = state.stack
|
|
1506
1540
|
.map((e) => e.name)
|
|
@@ -1510,12 +1544,19 @@ function handleException(state, node, exception) {
|
|
|
1510
1544
|
const location = node.loc && node.loc.source
|
|
1511
1545
|
? `${node.loc.source}:${node.start || 0}:${node.end || 0}`
|
|
1512
1546
|
: "<unknown>";
|
|
1513
|
-
message = `Got exception \`${
|
|
1547
|
+
const message = `Got exception \`${exception instanceof Error
|
|
1548
|
+
? exception.message
|
|
1549
|
+
: Object.prototype.toString.call(exception)}' while processing node ${fullName}:${node.type} from ${location}`;
|
|
1550
|
+
if (exception instanceof Error) {
|
|
1551
|
+
exception.message = message;
|
|
1552
|
+
}
|
|
1553
|
+
else {
|
|
1554
|
+
exception = new Error(message);
|
|
1555
|
+
}
|
|
1514
1556
|
}
|
|
1515
|
-
|
|
1557
|
+
finally {
|
|
1516
1558
|
throw exception;
|
|
1517
1559
|
}
|
|
1518
|
-
throw new Error(message);
|
|
1519
1560
|
}
|
|
1520
1561
|
|
|
1521
1562
|
})();
|
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
|
}
|
|
@@ -10888,7 +10901,7 @@ async function analyze(fnMap) {
|
|
|
10888
10901
|
return drop;
|
|
10889
10902
|
}, false);
|
|
10890
10903
|
}
|
|
10891
|
-
return
|
|
10904
|
+
return false;
|
|
10892
10905
|
},
|
|
10893
10906
|
post(node, state) {
|
|
10894
10907
|
switch (node.type) {
|
|
@@ -11515,71 +11528,77 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11515
11528
|
Object.values(fnMap).forEach((f) => {
|
|
11516
11529
|
(0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
|
|
11517
11530
|
});
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
|
|
11523
|
-
|
|
11524
|
-
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
node.
|
|
11528
|
-
|
|
11529
|
-
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
|
|
11534
|
-
|
|
11535
|
-
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
node.members.splice(0);
|
|
11539
|
-
}
|
|
11540
|
-
break;
|
|
11541
|
-
case "EnumDeclaration":
|
|
11542
|
-
if (!node.body.members.length) {
|
|
11543
|
-
if (!node.id)
|
|
11544
|
-
return false;
|
|
11545
|
-
if (!node.body["enumType"]) {
|
|
11546
|
-
throw new Error("Missing enumType on optimized enum");
|
|
11547
|
-
}
|
|
11548
|
-
replace(node, {
|
|
11549
|
-
type: "TypedefDeclaration",
|
|
11550
|
-
id: node.id,
|
|
11551
|
-
ts: {
|
|
11552
|
-
type: "UnaryExpression",
|
|
11553
|
-
argument: { type: "TypeSpecList", ts: [node.body.enumType] },
|
|
11554
|
-
prefix: true,
|
|
11555
|
-
operator: " as",
|
|
11556
|
-
},
|
|
11557
|
-
});
|
|
11558
|
-
}
|
|
11559
|
-
break;
|
|
11560
|
-
case "VariableDeclaration": {
|
|
11561
|
-
node.declarations = node.declarations.filter((d) => {
|
|
11562
|
-
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(d.id);
|
|
11563
|
-
return (!(0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) ||
|
|
11564
|
-
(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name));
|
|
11565
|
-
});
|
|
11566
|
-
if (!node.declarations.length) {
|
|
11567
|
-
return false;
|
|
11568
|
-
}
|
|
11569
|
-
break;
|
|
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);
|
|
11570
11551
|
}
|
|
11571
|
-
|
|
11572
|
-
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
break;
|
|
11576
|
-
case "FunctionDeclaration":
|
|
11577
|
-
if (!maybeCalled(node)) {
|
|
11552
|
+
break;
|
|
11553
|
+
case "EnumDeclaration":
|
|
11554
|
+
if (!node.body.members.length) {
|
|
11555
|
+
if (!node.id)
|
|
11578
11556
|
return false;
|
|
11557
|
+
if (!node.body["enumType"]) {
|
|
11558
|
+
throw new Error("Missing enumType on optimized enum");
|
|
11579
11559
|
}
|
|
11580
|
-
|
|
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;
|
|
11581
11581
|
}
|
|
11582
|
-
|
|
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;
|
|
11583
11602
|
});
|
|
11584
11603
|
});
|
|
11585
11604
|
}
|
|
@@ -12006,7 +12025,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
12006
12025
|
// the oldest optimized file, we don't need to regenerate
|
|
12007
12026
|
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
12008
12027
|
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
12009
|
-
if (source_time < opt_time &&
|
|
12028
|
+
if (source_time < opt_time && 1653864408816 < opt_time) {
|
|
12010
12029
|
return hasTests;
|
|
12011
12030
|
}
|
|
12012
12031
|
}
|
package/build/sdk-util.cjs
CHANGED
|
@@ -7215,8 +7215,14 @@ async function getDeviceInfo() {
|
|
|
7215
7215
|
}
|
|
7216
7216
|
return Promise.all(files.map((file) => {
|
|
7217
7217
|
return promises_namespaceObject.readFile(file).then((data) => {
|
|
7218
|
-
const { deviceId, appTypes, deviceFamily, displayName } = JSON.parse(data.toString());
|
|
7219
|
-
|
|
7218
|
+
const { deviceId, appTypes, deviceFamily, displayName, partNumbers } = JSON.parse(data.toString());
|
|
7219
|
+
const languages = Object.fromEntries(partNumbers
|
|
7220
|
+
.map((part) => part.languages.map((lang) => [lang.code, true]))
|
|
7221
|
+
.flat(1));
|
|
7222
|
+
return [
|
|
7223
|
+
deviceId,
|
|
7224
|
+
{ appTypes, deviceFamily, displayName, languages },
|
|
7225
|
+
];
|
|
7220
7226
|
});
|
|
7221
7227
|
})).then((info) => {
|
|
7222
7228
|
return Object.fromEntries(info);
|
package/build/src/optimizer.d.ts
CHANGED
|
@@ -90,7 +90,8 @@ declare global {
|
|
|
90
90
|
allFunctions?: FunctionStateNode[];
|
|
91
91
|
allClasses?: ClassStateNode[];
|
|
92
92
|
stack?: ProgramStateStack;
|
|
93
|
-
|
|
93
|
+
removeNodeComments?: (node: mctree.Node, ast: mctree.Program) => void;
|
|
94
|
+
shouldExclude?: (node: mctree.Node) => boolean;
|
|
94
95
|
pre?: (node: mctree.Node, state: ProgramStateLive) => null | false | (keyof mctree.NodeAll)[];
|
|
95
96
|
post?: (node: mctree.Node, state: ProgramStateLive) => null | false | mctree.Node;
|
|
96
97
|
lookup?: (node: mctree.Node, name?: string | null, stack?: ProgramStateStack) => [string, StateNodeDecl[], ProgramStateStack] | [null, null, null];
|
|
@@ -120,7 +121,7 @@ declare global {
|
|
|
120
121
|
type Finalized<T, Keys extends keyof T> = T & {
|
|
121
122
|
[key in Keys]-?: NonNullable<T[key]>;
|
|
122
123
|
};
|
|
123
|
-
export type ProgramStateLive = Finalized<ProgramState, "stack" | "lookup" | "traverse" | "index" | "constants">;
|
|
124
|
+
export type ProgramStateLive = Finalized<ProgramState, "stack" | "lookup" | "traverse" | "index" | "constants" | "removeNodeComments">;
|
|
124
125
|
export type ProgramStateAnalysis = Finalized<ProgramStateLive, "allClasses" | "allFunctions">;
|
|
125
126
|
export type ProgramStateOptimizer = Finalized<ProgramStateAnalysis, "localsStack" | "exposed" | "calledFunctions">;
|
|
126
127
|
type ExcludeAnnotationsMap = {
|
package/build/src/sdk-util.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export declare const isWin: boolean;
|
|
|
2
2
|
export declare const appSupport: string;
|
|
3
3
|
export declare const connectiq: string;
|
|
4
4
|
export declare function getSdkPath(): Promise<string>;
|
|
5
|
-
export declare
|
|
5
|
+
export declare type DeviceInfo = {
|
|
6
6
|
[key: string]: {
|
|
7
7
|
appTypes: {
|
|
8
8
|
memoryLimit: number;
|
|
@@ -10,6 +10,8 @@ export declare function getDeviceInfo(): Promise<{
|
|
|
10
10
|
}[];
|
|
11
11
|
deviceFamily: string;
|
|
12
12
|
displayName: string;
|
|
13
|
+
languages: Record<string, true>;
|
|
13
14
|
};
|
|
14
|
-
}
|
|
15
|
+
};
|
|
16
|
+
export declare function getDeviceInfo(): Promise<DeviceInfo>;
|
|
15
17
|
export declare function getLanguages(): Promise<any>;
|
package/build/util.cjs
CHANGED
|
@@ -1303,6 +1303,8 @@ function setopts (self, pattern, options) {
|
|
|
1303
1303
|
// Note that they are not supported in Glob itself anyway.
|
|
1304
1304
|
options.nonegate = true
|
|
1305
1305
|
options.nocomment = true
|
|
1306
|
+
// always treat \ in patterns as escapes, not path separators
|
|
1307
|
+
options.allowWindowsEscape = false
|
|
1306
1308
|
|
|
1307
1309
|
self.minimatch = new Minimatch(pattern, options)
|
|
1308
1310
|
self.options = self.minimatch.options
|
|
@@ -1778,7 +1780,10 @@ Glob.prototype._process = function (pattern, index, inGlobStar, cb) {
|
|
|
1778
1780
|
var read
|
|
1779
1781
|
if (prefix === null)
|
|
1780
1782
|
read = '.'
|
|
1781
|
-
else if (isAbsolute(prefix) ||
|
|
1783
|
+
else if (isAbsolute(prefix) ||
|
|
1784
|
+
isAbsolute(pattern.map(function (p) {
|
|
1785
|
+
return typeof p === 'string' ? p : '[*]'
|
|
1786
|
+
}).join('/'))) {
|
|
1782
1787
|
if (!prefix || !isAbsolute(prefix))
|
|
1783
1788
|
prefix = '/' + prefix
|
|
1784
1789
|
read = prefix
|
|
@@ -2278,7 +2283,7 @@ function GlobSync (pattern, options) {
|
|
|
2278
2283
|
}
|
|
2279
2284
|
|
|
2280
2285
|
GlobSync.prototype._finish = function () {
|
|
2281
|
-
assert(this instanceof GlobSync)
|
|
2286
|
+
assert.ok(this instanceof GlobSync)
|
|
2282
2287
|
if (this.realpath) {
|
|
2283
2288
|
var self = this
|
|
2284
2289
|
this.matches.forEach(function (matchset, index) {
|
|
@@ -2302,7 +2307,7 @@ GlobSync.prototype._finish = function () {
|
|
|
2302
2307
|
|
|
2303
2308
|
|
|
2304
2309
|
GlobSync.prototype._process = function (pattern, index, inGlobStar) {
|
|
2305
|
-
assert(this instanceof GlobSync)
|
|
2310
|
+
assert.ok(this instanceof GlobSync)
|
|
2306
2311
|
|
|
2307
2312
|
// Get the first [n] parts of pattern that are all strings.
|
|
2308
2313
|
var n = 0
|
|
@@ -2339,7 +2344,10 @@ GlobSync.prototype._process = function (pattern, index, inGlobStar) {
|
|
|
2339
2344
|
var read
|
|
2340
2345
|
if (prefix === null)
|
|
2341
2346
|
read = '.'
|
|
2342
|
-
else if (isAbsolute(prefix) ||
|
|
2347
|
+
else if (isAbsolute(prefix) ||
|
|
2348
|
+
isAbsolute(pattern.map(function (p) {
|
|
2349
|
+
return typeof p === 'string' ? p : '[*]'
|
|
2350
|
+
}).join('/'))) {
|
|
2343
2351
|
if (!prefix || !isAbsolute(prefix))
|
|
2344
2352
|
prefix = '/' + prefix
|
|
2345
2353
|
read = prefix
|
package/package.json
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markw65/monkeyc-optimizer",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.14",
|
|
5
5
|
"description": "Source to source optimizer for Garmin Monkey C code",
|
|
6
6
|
"main": "build/optimizer.cjs",
|
|
7
7
|
"types": "build/src/optimizer.d.ts",
|
|
8
8
|
"exports": {
|
|
9
|
-
".":
|
|
10
|
-
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./build/src/optimizer.d.ts",
|
|
11
|
+
"default": "./build/optimizer.cjs"
|
|
12
|
+
},
|
|
13
|
+
"./*.js": {
|
|
14
|
+
"types": "./build/src/*.d.ts",
|
|
15
|
+
"default": "./build/*.cjs"
|
|
16
|
+
}
|
|
11
17
|
},
|
|
12
18
|
"scripts": {
|
|
13
19
|
"watch": "webpack --mode development --watch",
|
|
@@ -27,7 +33,7 @@
|
|
|
27
33
|
"author": "markw65",
|
|
28
34
|
"license": "MIT",
|
|
29
35
|
"dependencies": {
|
|
30
|
-
"@markw65/prettier-plugin-monkeyc": "^1.0.
|
|
36
|
+
"@markw65/prettier-plugin-monkeyc": "^1.0.21"
|
|
31
37
|
},
|
|
32
38
|
"devDependencies": {
|
|
33
39
|
"@types/glob": "^7.2.0",
|