@markw65/monkeyc-optimizer 1.0.16 → 1.0.19
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 +42 -0
- package/build/api.cjs +501 -332
- package/build/optimizer.cjs +551 -175
- package/build/sdk-util.cjs +1 -1
- package/build/src/api.d.ts +1 -1
- package/build/src/inliner.d.ts +12 -2
- package/build/src/mc-rewrite.d.ts +8 -1
- package/build/src/optimizer.d.ts +28 -3
- package/build/src/pragma-checker.d.ts +2 -0
- package/build/src/variable-renamer.d.ts +1 -0
- package/build/util.cjs +1 -1
- package/package.json +2 -2
package/build/optimizer.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
0 && (module.exports = {copyRecursiveAsNeeded,
|
|
1
|
+
0 && (module.exports = {buildOptimizedProject,copyRecursiveAsNeeded,defaultConfig,generateApiMirTests,generateOptimizedProject,getProjectAnalysis,get_jungle,isErrorWithLocation,launchSimulator,manifestProducts,mctree,simulateProgram});
|
|
2
2
|
/******/ (() => { // webpackBootstrap
|
|
3
3
|
/******/ var __webpack_modules__ = ({
|
|
4
4
|
|
|
@@ -10791,11 +10791,67 @@ function simulateProgram(prg, device, test) {
|
|
|
10791
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(() => { }));
|
|
10792
10792
|
}
|
|
10793
10793
|
|
|
10794
|
+
;// CONCATENATED MODULE: ./src/variable-renamer.ts
|
|
10795
|
+
|
|
10796
|
+
function renameVariable(state, locals, declName) {
|
|
10797
|
+
const map = locals.map;
|
|
10798
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(map, declName))
|
|
10799
|
+
return null;
|
|
10800
|
+
let suffix = 0;
|
|
10801
|
+
let node_name = declName;
|
|
10802
|
+
const match = node_name.match(/^pmcr_(.*)_(\d+)$/);
|
|
10803
|
+
if (match) {
|
|
10804
|
+
node_name = match[1];
|
|
10805
|
+
suffix = parseInt(match[2], 10) + 1;
|
|
10806
|
+
}
|
|
10807
|
+
if (!locals.inners) {
|
|
10808
|
+
// find all the names declared in this scope, to avoid
|
|
10809
|
+
// more conflicts
|
|
10810
|
+
locals.inners = {};
|
|
10811
|
+
const inners = locals.inners;
|
|
10812
|
+
(0,external_api_cjs_namespaceObject.traverseAst)(locals.node, (node) => {
|
|
10813
|
+
if (node.type === "VariableDeclarator") {
|
|
10814
|
+
inners[(0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id)] = true;
|
|
10815
|
+
}
|
|
10816
|
+
});
|
|
10817
|
+
}
|
|
10818
|
+
let name;
|
|
10819
|
+
while (true) {
|
|
10820
|
+
name = `pmcr_${node_name}_${suffix}`;
|
|
10821
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(map, name) && !(0,external_api_cjs_namespaceObject.hasProperty)(locals.inners, name)) {
|
|
10822
|
+
// we also need to ensure that we don't hide the name of
|
|
10823
|
+
// an outer module, class, function, enum or variable,
|
|
10824
|
+
// since someone might want to access it from this scope.
|
|
10825
|
+
let ok = false;
|
|
10826
|
+
let i;
|
|
10827
|
+
for (i = state.stack.length; i--;) {
|
|
10828
|
+
const elm = state.stack[i];
|
|
10829
|
+
if (ok) {
|
|
10830
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(elm.decls, name)) {
|
|
10831
|
+
break;
|
|
10832
|
+
}
|
|
10833
|
+
}
|
|
10834
|
+
else if (elm.node && elm.node.type === "FunctionDeclaration") {
|
|
10835
|
+
ok = true;
|
|
10836
|
+
}
|
|
10837
|
+
}
|
|
10838
|
+
if (i < 0) {
|
|
10839
|
+
break;
|
|
10840
|
+
}
|
|
10841
|
+
}
|
|
10842
|
+
suffix++;
|
|
10843
|
+
}
|
|
10844
|
+
map[declName] = name;
|
|
10845
|
+
map[name] = true;
|
|
10846
|
+
return name;
|
|
10847
|
+
}
|
|
10848
|
+
|
|
10794
10849
|
;// CONCATENATED MODULE: ./src/inliner.ts
|
|
10795
10850
|
|
|
10796
|
-
|
|
10851
|
+
|
|
10852
|
+
function getArgSafety(state, func, args, requireAll) {
|
|
10797
10853
|
// determine whether decl might be changed by a function call
|
|
10798
|
-
// during the evaluation of FunctionStateNode.
|
|
10854
|
+
// or assignment during the evaluation of FunctionStateNode.
|
|
10799
10855
|
const getSafety = (decl) => {
|
|
10800
10856
|
// enums are constant, they cant change
|
|
10801
10857
|
if (decl.type === "EnumStringMember")
|
|
@@ -10825,22 +10881,28 @@ function canInline(state, func, args) {
|
|
|
10825
10881
|
case "Identifier":
|
|
10826
10882
|
case "MemberExpression": {
|
|
10827
10883
|
const [, results] = state.lookup(arg);
|
|
10828
|
-
if (!results || results.length !== 1)
|
|
10829
|
-
|
|
10884
|
+
if (!results || results.length !== 1) {
|
|
10885
|
+
safeArgs.push(null);
|
|
10886
|
+
return !requireAll;
|
|
10887
|
+
}
|
|
10830
10888
|
const safety = getSafety(results[0]);
|
|
10831
|
-
if (safety === null)
|
|
10832
|
-
return false;
|
|
10833
|
-
if (!safety)
|
|
10834
|
-
allSafe = false;
|
|
10835
10889
|
safeArgs.push(safety);
|
|
10890
|
+
if (!safety) {
|
|
10891
|
+
allSafe = false;
|
|
10892
|
+
if (safety === null) {
|
|
10893
|
+
return !requireAll;
|
|
10894
|
+
}
|
|
10895
|
+
}
|
|
10836
10896
|
return true;
|
|
10837
10897
|
}
|
|
10838
10898
|
}
|
|
10839
|
-
|
|
10899
|
+
allSafe = false;
|
|
10900
|
+
safeArgs.push(null);
|
|
10901
|
+
return !requireAll;
|
|
10840
10902
|
})) {
|
|
10841
10903
|
return false;
|
|
10842
10904
|
}
|
|
10843
|
-
if (allSafe)
|
|
10905
|
+
if (allSafe && requireAll)
|
|
10844
10906
|
return true;
|
|
10845
10907
|
let callSeen = false;
|
|
10846
10908
|
let ok = true;
|
|
@@ -10863,6 +10925,14 @@ function canInline(state, func, args) {
|
|
|
10863
10925
|
.map(([key]) => key);
|
|
10864
10926
|
}, (node) => {
|
|
10865
10927
|
switch (node.type) {
|
|
10928
|
+
case "AssignmentExpression":
|
|
10929
|
+
case "UpdateExpression": {
|
|
10930
|
+
const v = node.type == "UpdateExpression" ? node.argument : node.left;
|
|
10931
|
+
if (v.type === "Identifier" && (0,external_api_cjs_namespaceObject.hasProperty)(params, v.name)) {
|
|
10932
|
+
safeArgs[params[v.name]] = null;
|
|
10933
|
+
}
|
|
10934
|
+
}
|
|
10935
|
+
// fall through
|
|
10866
10936
|
case "CallExpression":
|
|
10867
10937
|
case "NewExpression":
|
|
10868
10938
|
callSeen = true;
|
|
@@ -10871,11 +10941,18 @@ function canInline(state, func, args) {
|
|
|
10871
10941
|
if (callSeen &&
|
|
10872
10942
|
(0,external_api_cjs_namespaceObject.hasProperty)(params, node.name) &&
|
|
10873
10943
|
!safeArgs[params[node.name]]) {
|
|
10874
|
-
|
|
10944
|
+
safeArgs[params[node.name]] = null;
|
|
10875
10945
|
}
|
|
10876
10946
|
}
|
|
10877
10947
|
});
|
|
10878
|
-
return
|
|
10948
|
+
return safeArgs;
|
|
10949
|
+
}
|
|
10950
|
+
function canInline(state, func, args) {
|
|
10951
|
+
const safeArgs = getArgSafety(state, func, args, true);
|
|
10952
|
+
if (safeArgs === true || safeArgs === false) {
|
|
10953
|
+
return safeArgs;
|
|
10954
|
+
}
|
|
10955
|
+
return safeArgs.every((arg) => arg !== null);
|
|
10879
10956
|
}
|
|
10880
10957
|
function inliningLooksUseful(func, node) {
|
|
10881
10958
|
while (true) {
|
|
@@ -10900,77 +10977,288 @@ function inliningLooksUseful(func, node) {
|
|
|
10900
10977
|
}
|
|
10901
10978
|
return false;
|
|
10902
10979
|
}
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
|
|
10909
|
-
|
|
10910
|
-
}
|
|
10911
|
-
const autoInline = inliningLooksUseful(func.node, func.node.body.body[0].argument);
|
|
10980
|
+
var InlineStatus;
|
|
10981
|
+
(function (InlineStatus) {
|
|
10982
|
+
InlineStatus[InlineStatus["Never"] = 0] = "Never";
|
|
10983
|
+
InlineStatus[InlineStatus["AsExpression"] = 1] = "AsExpression";
|
|
10984
|
+
InlineStatus[InlineStatus["AsStatement"] = 2] = "AsStatement";
|
|
10985
|
+
})(InlineStatus || (InlineStatus = {}));
|
|
10986
|
+
function inlineRequested(state, func) {
|
|
10912
10987
|
const excludeAnnotations = (func.node.loc?.source &&
|
|
10913
|
-
state.fnMap[func.node.loc?.source]
|
|
10988
|
+
state.fnMap[func.node.loc?.source]?.excludeAnnotations) ||
|
|
10914
10989
|
{};
|
|
10915
|
-
|
|
10916
|
-
|
|
10917
|
-
|
|
10918
|
-
|
|
10919
|
-
(attr.argument.name
|
|
10920
|
-
(attr.argument.name.
|
|
10921
|
-
|
|
10922
|
-
|
|
10923
|
-
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
|
|
10990
|
+
if (func.node.attrs &&
|
|
10991
|
+
func.node.attrs.attrs &&
|
|
10992
|
+
func.node.attrs.attrs.some((attr) => attr.type === "UnaryExpression" &&
|
|
10993
|
+
(attr.argument.name === "inline" ||
|
|
10994
|
+
(attr.argument.name.startsWith("inline_") &&
|
|
10995
|
+
(0,external_api_cjs_namespaceObject.hasProperty)(excludeAnnotations, attr.argument.name.substring(7)))))) {
|
|
10996
|
+
return true;
|
|
10997
|
+
}
|
|
10998
|
+
return false;
|
|
10999
|
+
}
|
|
11000
|
+
function shouldInline(state, func, call, context) {
|
|
11001
|
+
let autoInline = false;
|
|
11002
|
+
let inlineAsExpression = false;
|
|
11003
|
+
const args = call.arguments;
|
|
11004
|
+
if (func.node.body &&
|
|
11005
|
+
func.node.body.body.length === 1 &&
|
|
11006
|
+
func.node.body.body[0].type === "ReturnStatement" &&
|
|
11007
|
+
func.node.body.body[0].argument &&
|
|
11008
|
+
func.node.params.length === args.length) {
|
|
11009
|
+
inlineAsExpression = true;
|
|
11010
|
+
autoInline = inliningLooksUseful(func.node, func.node.body.body[0].argument);
|
|
11011
|
+
}
|
|
11012
|
+
if (autoInline === 1) {
|
|
11013
|
+
return true;
|
|
11014
|
+
}
|
|
11015
|
+
const requested = inlineRequested(state, func);
|
|
11016
|
+
if (autoInline || requested) {
|
|
11017
|
+
if (inlineAsExpression) {
|
|
11018
|
+
if (canInline(state, func, args)) {
|
|
11019
|
+
return true;
|
|
11020
|
+
}
|
|
11021
|
+
}
|
|
11022
|
+
if (!context && requested) {
|
|
11023
|
+
inlineDiagnostic(state, func, call, "This function can only be inlined in statement, assignment, or return contexts");
|
|
11024
|
+
}
|
|
11025
|
+
return context != null;
|
|
11026
|
+
}
|
|
11027
|
+
return false;
|
|
11028
|
+
}
|
|
11029
|
+
function processInlineBody(state, func, call, root, insertedVariableDecls, params) {
|
|
11030
|
+
let failed = false;
|
|
11031
|
+
const pre = state.pre;
|
|
11032
|
+
const post = state.post;
|
|
10927
11033
|
try {
|
|
10928
|
-
|
|
10929
|
-
|
|
10930
|
-
|
|
10931
|
-
|
|
10932
|
-
|
|
10933
|
-
|
|
10934
|
-
|
|
10935
|
-
|
|
10936
|
-
|
|
10937
|
-
|
|
10938
|
-
|
|
10939
|
-
|
|
10940
|
-
|
|
10941
|
-
|
|
10942
|
-
|
|
10943
|
-
|
|
11034
|
+
state.pre = (node) => {
|
|
11035
|
+
if (failed)
|
|
11036
|
+
return [];
|
|
11037
|
+
node.start = call.start;
|
|
11038
|
+
node.end = call.end;
|
|
11039
|
+
node.loc = call.loc;
|
|
11040
|
+
if (node === insertedVariableDecls)
|
|
11041
|
+
return false;
|
|
11042
|
+
const result = pre(node, state);
|
|
11043
|
+
if (!insertedVariableDecls && node.type === "BlockStatement") {
|
|
11044
|
+
const locals = state.localsStack[state.localsStack.length - 1];
|
|
11045
|
+
const { map } = locals;
|
|
11046
|
+
if (!map)
|
|
11047
|
+
throw new Error("No local variable map!");
|
|
11048
|
+
// We still need to keep track of every local name that was
|
|
11049
|
+
// already in use, but we don't want to use any of its renames.
|
|
11050
|
+
// We also want to know whether a local is from the function being
|
|
11051
|
+
// inlined, or the calling function, so set every element to false.
|
|
11052
|
+
Object.keys(map).forEach((key) => (map[key] = false));
|
|
11053
|
+
const declarations = func.node.params
|
|
11054
|
+
.map((param, i) => {
|
|
11055
|
+
const paramName = (0,external_api_cjs_namespaceObject.variableDeclarationName)(param);
|
|
11056
|
+
if (params[paramName] >= 0)
|
|
11057
|
+
return null;
|
|
11058
|
+
const name = renameVariable(state, locals, paramName) || paramName;
|
|
11059
|
+
return {
|
|
11060
|
+
type: "VariableDeclarator",
|
|
11061
|
+
id: { type: "Identifier", name },
|
|
11062
|
+
kind: "var",
|
|
11063
|
+
init: call.arguments[i],
|
|
11064
|
+
};
|
|
11065
|
+
})
|
|
11066
|
+
.filter((n) => n != null);
|
|
11067
|
+
insertedVariableDecls = {
|
|
11068
|
+
type: "VariableDeclaration",
|
|
11069
|
+
declarations,
|
|
11070
|
+
kind: "var",
|
|
11071
|
+
};
|
|
11072
|
+
node.body.unshift(insertedVariableDecls);
|
|
10944
11073
|
}
|
|
10945
|
-
return
|
|
10946
|
-
}
|
|
11074
|
+
return result;
|
|
11075
|
+
};
|
|
11076
|
+
state.post = (node) => {
|
|
11077
|
+
if (failed)
|
|
11078
|
+
return null;
|
|
11079
|
+
let replacement = null;
|
|
10947
11080
|
switch (node.type) {
|
|
10948
11081
|
case "Identifier": {
|
|
11082
|
+
if (state.inType)
|
|
11083
|
+
break;
|
|
10949
11084
|
if ((0,external_api_cjs_namespaceObject.hasProperty)(params, node.name)) {
|
|
10950
|
-
|
|
11085
|
+
const ix = params[node.name];
|
|
11086
|
+
if (ix >= 0) {
|
|
11087
|
+
replacement = call.arguments[ix];
|
|
11088
|
+
}
|
|
11089
|
+
break;
|
|
10951
11090
|
}
|
|
10952
|
-
|
|
10953
|
-
if (!
|
|
10954
|
-
|
|
11091
|
+
replacement = fixNodeScope(state, node, func.stack);
|
|
11092
|
+
if (!replacement) {
|
|
11093
|
+
failed = true;
|
|
11094
|
+
inlineDiagnostic(state, func, call, `Failed to resolve '${node.name}'`);
|
|
11095
|
+
return null;
|
|
10955
11096
|
}
|
|
10956
|
-
|
|
11097
|
+
break;
|
|
10957
11098
|
}
|
|
10958
11099
|
}
|
|
11100
|
+
return post(replacement || node, state) || replacement;
|
|
11101
|
+
};
|
|
11102
|
+
let ret = state.traverse(root);
|
|
11103
|
+
if (failed) {
|
|
10959
11104
|
return null;
|
|
10960
|
-
}
|
|
10961
|
-
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
11105
|
+
}
|
|
11106
|
+
if (ret === null) {
|
|
11107
|
+
ret = root;
|
|
11108
|
+
}
|
|
11109
|
+
if (!ret) {
|
|
11110
|
+
inlineDiagnostic(state, func, call, `Internal error`);
|
|
11111
|
+
return null;
|
|
11112
|
+
}
|
|
11113
|
+
inlineDiagnostic(state, func, call, null);
|
|
11114
|
+
return ret;
|
|
10965
11115
|
}
|
|
10966
|
-
|
|
10967
|
-
|
|
10968
|
-
|
|
11116
|
+
finally {
|
|
11117
|
+
state.pre = pre;
|
|
11118
|
+
state.post = post;
|
|
11119
|
+
}
|
|
11120
|
+
}
|
|
11121
|
+
function unused(expression, top) {
|
|
11122
|
+
switch (expression.type) {
|
|
11123
|
+
case "Literal":
|
|
11124
|
+
return [];
|
|
11125
|
+
case "Identifier":
|
|
11126
|
+
return [];
|
|
11127
|
+
case "BinaryExpression":
|
|
11128
|
+
if (expression.operator === "as") {
|
|
11129
|
+
return unused(expression.left);
|
|
11130
|
+
}
|
|
11131
|
+
// fall through
|
|
11132
|
+
case "LogicalExpression":
|
|
11133
|
+
return unused(expression.left).concat(unused(expression.right));
|
|
11134
|
+
case "UnaryExpression":
|
|
11135
|
+
return unused(expression.argument);
|
|
11136
|
+
case "MemberExpression":
|
|
11137
|
+
if (expression.computed) {
|
|
11138
|
+
return unused(expression.object).concat(unused(expression.property));
|
|
11139
|
+
}
|
|
11140
|
+
return unused(expression.object);
|
|
11141
|
+
case "ArrayExpression":
|
|
11142
|
+
return expression.elements.map((e) => unused(e)).flat(1);
|
|
11143
|
+
case "ObjectExpression":
|
|
11144
|
+
return expression.properties
|
|
11145
|
+
.map((p) => unused(p.key).concat(unused(p.value)))
|
|
11146
|
+
.flat(1);
|
|
11147
|
+
}
|
|
11148
|
+
return top
|
|
11149
|
+
? null
|
|
11150
|
+
: [
|
|
11151
|
+
{
|
|
11152
|
+
type: "ExpressionStatement",
|
|
11153
|
+
expression,
|
|
11154
|
+
start: expression.start,
|
|
11155
|
+
end: expression.end,
|
|
11156
|
+
loc: expression.loc,
|
|
11157
|
+
},
|
|
11158
|
+
];
|
|
11159
|
+
}
|
|
11160
|
+
function diagnostic(state, loc, message) {
|
|
11161
|
+
if (!loc || !loc.source)
|
|
11162
|
+
return;
|
|
11163
|
+
const source = loc.source;
|
|
11164
|
+
if (!state.diagnostics)
|
|
11165
|
+
state.diagnostics = {};
|
|
11166
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.diagnostics, source)) {
|
|
11167
|
+
if (!message)
|
|
11168
|
+
return;
|
|
11169
|
+
state.diagnostics[source] = [];
|
|
11170
|
+
}
|
|
11171
|
+
const diags = state.diagnostics[source];
|
|
11172
|
+
let index = diags.findIndex((item) => item.loc === loc);
|
|
11173
|
+
if (message) {
|
|
11174
|
+
if (index < 0)
|
|
11175
|
+
index = diags.length;
|
|
11176
|
+
diags[index] = { type: "INFO", loc, message };
|
|
11177
|
+
}
|
|
11178
|
+
else if (index >= 0) {
|
|
11179
|
+
diags.splice(index, 1);
|
|
11180
|
+
}
|
|
11181
|
+
}
|
|
11182
|
+
function inlineDiagnostic(state, func, call, message) {
|
|
11183
|
+
if (inlineRequested(state, func)) {
|
|
11184
|
+
diagnostic(state, call.loc, message && `While inlining ${func.node.id.name}: ${message}`);
|
|
11185
|
+
}
|
|
11186
|
+
}
|
|
11187
|
+
function inlineWithArgs(state, func, call, context) {
|
|
11188
|
+
if (!func.node || !func.node.body) {
|
|
11189
|
+
return null;
|
|
11190
|
+
}
|
|
11191
|
+
let retStmtCount = 0;
|
|
11192
|
+
if (context.type === "ReturnStatement") {
|
|
11193
|
+
const last = func.node.body.body.slice(-1)[0];
|
|
11194
|
+
if (!last || last.type !== "ReturnStatement") {
|
|
11195
|
+
inlineDiagnostic(state, func, call, "Function didn't end with a return statement");
|
|
11196
|
+
return null;
|
|
11197
|
+
}
|
|
11198
|
+
}
|
|
11199
|
+
else {
|
|
11200
|
+
(0,external_api_cjs_namespaceObject.traverseAst)(func.node.body, (node) => {
|
|
11201
|
+
node.type === "ReturnStatement" && retStmtCount++;
|
|
11202
|
+
});
|
|
11203
|
+
if (retStmtCount > 1) {
|
|
11204
|
+
inlineDiagnostic(state, func, call, "Function had more than one return statement");
|
|
11205
|
+
}
|
|
11206
|
+
else if (context.type === "AssignmentExpression" && retStmtCount !== 1) {
|
|
11207
|
+
inlineDiagnostic(state, func, call, "Function did not have a return statement");
|
|
11208
|
+
return null;
|
|
11209
|
+
}
|
|
11210
|
+
if (retStmtCount === 1) {
|
|
11211
|
+
const last = func.node.body.body.slice(-1)[0];
|
|
11212
|
+
if (!last ||
|
|
11213
|
+
last.type !== "ReturnStatement" ||
|
|
11214
|
+
(context.type === "AssignmentExpression" && !last.argument)) {
|
|
11215
|
+
inlineDiagnostic(state, func, call, "There was a return statement, but not at the end of the function");
|
|
10969
11216
|
return null;
|
|
10970
11217
|
}
|
|
10971
11218
|
}
|
|
10972
|
-
throw ex;
|
|
10973
11219
|
}
|
|
11220
|
+
const body = JSON.parse(JSON.stringify(func.node.body));
|
|
11221
|
+
const safeArgs = getArgSafety(state, func, call.arguments, false);
|
|
11222
|
+
const params = Object.fromEntries(func.node.params.map((param, i) => {
|
|
11223
|
+
const argnum = safeArgs === true || (safeArgs !== false && safeArgs[i] !== null)
|
|
11224
|
+
? i
|
|
11225
|
+
: -1;
|
|
11226
|
+
const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(param);
|
|
11227
|
+
return [name, argnum];
|
|
11228
|
+
}));
|
|
11229
|
+
if (!processInlineBody(state, func, call, body, func.node.params.length ? false : true, params)) {
|
|
11230
|
+
return null;
|
|
11231
|
+
}
|
|
11232
|
+
diagnostic(state, call.loc, null);
|
|
11233
|
+
if (context.type !== "ReturnStatement" && retStmtCount) {
|
|
11234
|
+
const last = body.body[body.body.length - 1];
|
|
11235
|
+
if (last.type != "ReturnStatement") {
|
|
11236
|
+
throw new Error("ReturnStatement got lost!");
|
|
11237
|
+
}
|
|
11238
|
+
if (context.type === "AssignmentExpression") {
|
|
11239
|
+
context.right = last.argument;
|
|
11240
|
+
body.body[body.body.length - 1] = {
|
|
11241
|
+
type: "ExpressionStatement",
|
|
11242
|
+
expression: context,
|
|
11243
|
+
};
|
|
11244
|
+
}
|
|
11245
|
+
else if (last.argument) {
|
|
11246
|
+
const side_exprs = unused(last.argument);
|
|
11247
|
+
body.body.splice(body.body.length - 1, 1, ...side_exprs);
|
|
11248
|
+
}
|
|
11249
|
+
else {
|
|
11250
|
+
--body.body.length;
|
|
11251
|
+
}
|
|
11252
|
+
}
|
|
11253
|
+
return body;
|
|
11254
|
+
}
|
|
11255
|
+
function inlineFunction(state, func, call, context) {
|
|
11256
|
+
if (context) {
|
|
11257
|
+
return inlineWithArgs(state, func, call, context);
|
|
11258
|
+
}
|
|
11259
|
+
const retArg = JSON.parse(JSON.stringify(func.node.body.body[0].argument));
|
|
11260
|
+
const params = Object.fromEntries(func.node.params.map((param, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(param), i]));
|
|
11261
|
+
return processInlineBody(state, func, call, retArg, true, params);
|
|
10974
11262
|
}
|
|
10975
11263
|
function applyTypeIfNeeded(node) {
|
|
10976
11264
|
if ("enumType" in node && node.enumType) {
|
|
@@ -10984,6 +11272,17 @@ function applyTypeIfNeeded(node) {
|
|
|
10984
11272
|
return node;
|
|
10985
11273
|
}
|
|
10986
11274
|
function fixNodeScope(state, lookupNode, nodeStack) {
|
|
11275
|
+
if (lookupNode.type === "Identifier") {
|
|
11276
|
+
const locals = state.localsStack[state.localsStack.length - 1];
|
|
11277
|
+
const { map } = locals;
|
|
11278
|
+
if (!map)
|
|
11279
|
+
throw new Error("No local variable map!");
|
|
11280
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(map, lookupNode.name) && map[lookupNode.name] !== false) {
|
|
11281
|
+
// map[name] !== false means its an entry that was created during inlining
|
|
11282
|
+
// so its definitely one of our locals.
|
|
11283
|
+
return lookupNode;
|
|
11284
|
+
}
|
|
11285
|
+
}
|
|
10987
11286
|
const [, original] = state.lookup(lookupNode, null, nodeStack);
|
|
10988
11287
|
if (!original) {
|
|
10989
11288
|
return null;
|
|
@@ -11067,6 +11366,7 @@ function fixNodeScope(state, lookupNode, nodeStack) {
|
|
|
11067
11366
|
|
|
11068
11367
|
|
|
11069
11368
|
|
|
11369
|
+
|
|
11070
11370
|
function processImports(allImports, lookup) {
|
|
11071
11371
|
allImports.forEach(({ node, stack }) => {
|
|
11072
11372
|
const [name, module] = lookup(node.id, ("as" in node && node.as && node.as.name) || null, stack);
|
|
@@ -11080,10 +11380,13 @@ function processImports(allImports, lookup) {
|
|
|
11080
11380
|
module.forEach((m) => {
|
|
11081
11381
|
if ((0,external_api_cjs_namespaceObject.isStateNode)(m) && m.type == "ModuleDeclaration") {
|
|
11082
11382
|
(0,external_util_cjs_namespaceObject.pushUnique)(decls[name], m);
|
|
11383
|
+
if (!parent.type_decls)
|
|
11384
|
+
parent.type_decls = {};
|
|
11385
|
+
const tdecls = parent.type_decls;
|
|
11386
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(tdecls, name))
|
|
11387
|
+
tdecls[name] = [];
|
|
11388
|
+
(0,external_util_cjs_namespaceObject.pushUnique)(tdecls[name], m);
|
|
11083
11389
|
if (node.type == "ImportModule" && m.type_decls) {
|
|
11084
|
-
if (!parent.type_decls)
|
|
11085
|
-
parent.type_decls = {};
|
|
11086
|
-
const tdecls = parent.type_decls;
|
|
11087
11390
|
Object.entries(m.type_decls).forEach(([name, decls]) => {
|
|
11088
11391
|
if (!(0,external_api_cjs_namespaceObject.hasProperty)(tdecls, name))
|
|
11089
11392
|
tdecls[name] = [];
|
|
@@ -11450,13 +11753,15 @@ function optimizeNode(node) {
|
|
|
11450
11753
|
return null;
|
|
11451
11754
|
}
|
|
11452
11755
|
function evaluateFunction(func, args) {
|
|
11453
|
-
if (args && args.length != func.params.length) {
|
|
11756
|
+
if (!func.body || (args && args.length != func.params.length)) {
|
|
11454
11757
|
return false;
|
|
11455
11758
|
}
|
|
11456
11759
|
const paramValues = args &&
|
|
11457
11760
|
Object.fromEntries(func.params.map((p, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(p), args[i]]));
|
|
11458
11761
|
let ret = null;
|
|
11459
|
-
const body = args
|
|
11762
|
+
const body = args
|
|
11763
|
+
? JSON.parse(JSON.stringify(func.body))
|
|
11764
|
+
: func.body;
|
|
11460
11765
|
try {
|
|
11461
11766
|
(0,external_api_cjs_namespaceObject.traverseAst)(body, (node) => {
|
|
11462
11767
|
switch (node.type) {
|
|
@@ -11624,57 +11929,8 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11624
11929
|
const { map } = locals;
|
|
11625
11930
|
if (map) {
|
|
11626
11931
|
const declName = (0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id);
|
|
11627
|
-
|
|
11628
|
-
|
|
11629
|
-
// Recent monkeyc compilers complain, so rename it
|
|
11630
|
-
let suffix = 0;
|
|
11631
|
-
let node_name = declName;
|
|
11632
|
-
const match = node_name.match(/^pmcr_(.*)_(\d+)$/);
|
|
11633
|
-
if (match) {
|
|
11634
|
-
node_name = match[1];
|
|
11635
|
-
suffix = parseInt(match[2], 10) + 1;
|
|
11636
|
-
}
|
|
11637
|
-
if (!locals.inners) {
|
|
11638
|
-
// find all the names declared in this scope, to avoid
|
|
11639
|
-
// more conflicts
|
|
11640
|
-
locals.inners = {};
|
|
11641
|
-
const inners = locals.inners;
|
|
11642
|
-
(0,external_api_cjs_namespaceObject.traverseAst)(locals.node, (node) => {
|
|
11643
|
-
if (node.type === "VariableDeclarator") {
|
|
11644
|
-
inners[(0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id)] = true;
|
|
11645
|
-
}
|
|
11646
|
-
});
|
|
11647
|
-
}
|
|
11648
|
-
let name;
|
|
11649
|
-
while (true) {
|
|
11650
|
-
name = `pmcr_${node_name}_${suffix}`;
|
|
11651
|
-
if (!(0,external_api_cjs_namespaceObject.hasProperty)(map, name) &&
|
|
11652
|
-
!(0,external_api_cjs_namespaceObject.hasProperty)(locals.inners, name)) {
|
|
11653
|
-
// we also need to ensure that we don't hide the name of
|
|
11654
|
-
// an outer module, class, function, enum or variable,
|
|
11655
|
-
// since someone might want to access it from this scope.
|
|
11656
|
-
let ok = false;
|
|
11657
|
-
let i;
|
|
11658
|
-
for (i = state.stack.length; i--;) {
|
|
11659
|
-
const elm = state.stack[i];
|
|
11660
|
-
if (ok) {
|
|
11661
|
-
if ((0,external_api_cjs_namespaceObject.hasProperty)(elm.decls, name)) {
|
|
11662
|
-
break;
|
|
11663
|
-
}
|
|
11664
|
-
}
|
|
11665
|
-
else if (elm.node &&
|
|
11666
|
-
elm.node.type === "FunctionDeclaration") {
|
|
11667
|
-
ok = true;
|
|
11668
|
-
}
|
|
11669
|
-
}
|
|
11670
|
-
if (i < 0) {
|
|
11671
|
-
break;
|
|
11672
|
-
}
|
|
11673
|
-
}
|
|
11674
|
-
suffix++;
|
|
11675
|
-
}
|
|
11676
|
-
map[declName] = name;
|
|
11677
|
-
map[name] = true;
|
|
11932
|
+
const name = renameVariable(state, locals, declName);
|
|
11933
|
+
if (name) {
|
|
11678
11934
|
if (node.id.type === "Identifier") {
|
|
11679
11935
|
node.id.name = name;
|
|
11680
11936
|
}
|
|
@@ -11698,7 +11954,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11698
11954
|
state.exposed[node.argument.name] = true;
|
|
11699
11955
|
// In any case, we can't replace *this* use of the
|
|
11700
11956
|
// symbol with its value...
|
|
11701
|
-
return
|
|
11957
|
+
return [];
|
|
11702
11958
|
}
|
|
11703
11959
|
break;
|
|
11704
11960
|
case "Identifier": {
|
|
@@ -11706,7 +11962,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11706
11962
|
if (map) {
|
|
11707
11963
|
if ((0,external_api_cjs_namespaceObject.hasProperty)(map, node.name)) {
|
|
11708
11964
|
const name = map[node.name];
|
|
11709
|
-
if (name
|
|
11965
|
+
if (typeof name === "string") {
|
|
11710
11966
|
node.name = name;
|
|
11711
11967
|
}
|
|
11712
11968
|
}
|
|
@@ -11716,7 +11972,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11716
11972
|
state.exposed[node.name] = true;
|
|
11717
11973
|
}
|
|
11718
11974
|
}
|
|
11719
|
-
return
|
|
11975
|
+
return [];
|
|
11720
11976
|
}
|
|
11721
11977
|
case "MemberExpression":
|
|
11722
11978
|
if (node.property.type === "Identifier" && !node.computed) {
|
|
@@ -11797,49 +12053,58 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11797
12053
|
return node.body;
|
|
11798
12054
|
}
|
|
11799
12055
|
break;
|
|
12056
|
+
case "ReturnStatement":
|
|
12057
|
+
if (node.argument && node.argument.type === "CallExpression") {
|
|
12058
|
+
return optimizeCall(state, node.argument, node);
|
|
12059
|
+
}
|
|
12060
|
+
break;
|
|
11800
12061
|
case "CallExpression": {
|
|
11801
|
-
const
|
|
11802
|
-
if (
|
|
11803
|
-
|
|
11804
|
-
("name" in node.callee && node.callee.name) ||
|
|
11805
|
-
("property" in node.callee &&
|
|
11806
|
-
node.callee.property &&
|
|
11807
|
-
"name" in node.callee.property &&
|
|
11808
|
-
node.callee.property.name);
|
|
11809
|
-
if (n) {
|
|
11810
|
-
state.exposed[n] = true;
|
|
11811
|
-
}
|
|
11812
|
-
else {
|
|
11813
|
-
// There are unnamed CallExpressions, such as new [size]
|
|
11814
|
-
// So there's nothing to do here.
|
|
11815
|
-
}
|
|
11816
|
-
return null;
|
|
12062
|
+
const ret = optimizeCall(state, node, null);
|
|
12063
|
+
if (ret) {
|
|
12064
|
+
replace(node, ret);
|
|
11817
12065
|
}
|
|
11818
|
-
|
|
11819
|
-
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
|
|
11825
|
-
|
|
11826
|
-
|
|
12066
|
+
break;
|
|
12067
|
+
}
|
|
12068
|
+
case "AssignmentExpression":
|
|
12069
|
+
if (node.operator === "=" &&
|
|
12070
|
+
node.left.type === "Identifier" &&
|
|
12071
|
+
node.right.type === "Identifier" &&
|
|
12072
|
+
node.left.name === node.right.name) {
|
|
12073
|
+
return { type: "Literal", value: null, raw: "null" };
|
|
12074
|
+
}
|
|
12075
|
+
break;
|
|
12076
|
+
case "ExpressionStatement":
|
|
12077
|
+
if (node.expression.type === "CallExpression") {
|
|
12078
|
+
return optimizeCall(state, node.expression, node);
|
|
12079
|
+
}
|
|
12080
|
+
else if (node.expression.type === "AssignmentExpression") {
|
|
12081
|
+
if (node.expression.right.type === "CallExpression") {
|
|
12082
|
+
let ok = false;
|
|
12083
|
+
if (node.expression.left.type === "Identifier") {
|
|
12084
|
+
if ((0,external_api_cjs_namespaceObject.hasProperty)(topLocals().map, node.expression.left.type)) {
|
|
12085
|
+
ok = true;
|
|
12086
|
+
}
|
|
11827
12087
|
}
|
|
11828
|
-
|
|
11829
|
-
|
|
11830
|
-
|
|
11831
|
-
|
|
11832
|
-
|
|
11833
|
-
|
|
12088
|
+
if (!ok && node.expression.operator == "=") {
|
|
12089
|
+
const [, result] = state.lookup(node.expression.left);
|
|
12090
|
+
ok = result != null;
|
|
12091
|
+
}
|
|
12092
|
+
if (ok) {
|
|
12093
|
+
const ret = optimizeCall(state, node.expression.right, node.expression);
|
|
12094
|
+
if (ret && ret.type === "BlockStatement") {
|
|
12095
|
+
const r2 = state.traverse(ret);
|
|
12096
|
+
return r2 === false || r2 ? r2 : ret;
|
|
12097
|
+
}
|
|
11834
12098
|
}
|
|
11835
12099
|
}
|
|
11836
12100
|
}
|
|
11837
|
-
|
|
11838
|
-
|
|
12101
|
+
else {
|
|
12102
|
+
const ret = unused(node.expression, true);
|
|
12103
|
+
if (ret) {
|
|
12104
|
+
return ret;
|
|
12105
|
+
}
|
|
11839
12106
|
}
|
|
11840
|
-
callees.forEach((c) => (0,external_api_cjs_namespaceObject.isStateNode)(c) && state.calledFunctions[name].push(c.node));
|
|
11841
12107
|
break;
|
|
11842
|
-
}
|
|
11843
12108
|
}
|
|
11844
12109
|
return null;
|
|
11845
12110
|
};
|
|
@@ -11921,6 +12186,111 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11921
12186
|
return ret;
|
|
11922
12187
|
});
|
|
11923
12188
|
});
|
|
12189
|
+
return state.diagnostics;
|
|
12190
|
+
}
|
|
12191
|
+
function optimizeCall(state, node, context) {
|
|
12192
|
+
const [name, callees] = state.lookup(node.callee);
|
|
12193
|
+
if (!callees || !callees.length) {
|
|
12194
|
+
const n = name ||
|
|
12195
|
+
("name" in node.callee && node.callee.name) ||
|
|
12196
|
+
("property" in node.callee &&
|
|
12197
|
+
node.callee.property &&
|
|
12198
|
+
"name" in node.callee.property &&
|
|
12199
|
+
node.callee.property.name);
|
|
12200
|
+
if (n) {
|
|
12201
|
+
state.exposed[n] = true;
|
|
12202
|
+
}
|
|
12203
|
+
else {
|
|
12204
|
+
// There are unnamed CallExpressions, such as new [size]
|
|
12205
|
+
// So there's nothing to do here.
|
|
12206
|
+
}
|
|
12207
|
+
return null;
|
|
12208
|
+
}
|
|
12209
|
+
if (callees.length == 1 && callees[0].type === "FunctionDeclaration") {
|
|
12210
|
+
const callee = callees[0].node;
|
|
12211
|
+
if (!context &&
|
|
12212
|
+
callee.optimizable &&
|
|
12213
|
+
!callee.hasOverride &&
|
|
12214
|
+
node.arguments.every((n) => getNodeValue(n)[0] !== null)) {
|
|
12215
|
+
const ret = evaluateFunction(callee, node.arguments);
|
|
12216
|
+
if (ret) {
|
|
12217
|
+
return ret;
|
|
12218
|
+
}
|
|
12219
|
+
}
|
|
12220
|
+
if (shouldInline(state, callees[0], node, context)) {
|
|
12221
|
+
const ret = inlineFunction(state, callees[0], node, context);
|
|
12222
|
+
if (ret) {
|
|
12223
|
+
return ret;
|
|
12224
|
+
}
|
|
12225
|
+
}
|
|
12226
|
+
}
|
|
12227
|
+
if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, name)) {
|
|
12228
|
+
state.calledFunctions[name] = [];
|
|
12229
|
+
}
|
|
12230
|
+
callees.forEach((c) => (0,external_api_cjs_namespaceObject.isStateNode)(c) && (0,external_util_cjs_namespaceObject.pushUnique)(state.calledFunctions[name], c.node));
|
|
12231
|
+
return null;
|
|
12232
|
+
}
|
|
12233
|
+
|
|
12234
|
+
;// CONCATENATED MODULE: ./src/pragma-checker.ts
|
|
12235
|
+
|
|
12236
|
+
function pragmaChecker(ast) {
|
|
12237
|
+
const comments = ast.comments;
|
|
12238
|
+
if (!comments)
|
|
12239
|
+
return;
|
|
12240
|
+
let index = -1;
|
|
12241
|
+
let comment;
|
|
12242
|
+
let matchers;
|
|
12243
|
+
const next = () => {
|
|
12244
|
+
while (++index < comments.length) {
|
|
12245
|
+
comment = comments[index];
|
|
12246
|
+
let match = comment.value.match(/^\s*@match\s+(.+)/);
|
|
12247
|
+
if (!match)
|
|
12248
|
+
continue;
|
|
12249
|
+
let str = match[1];
|
|
12250
|
+
matchers = [];
|
|
12251
|
+
while ((match = str.match(/^([/%&#@"])(.+?(?<!\\)(?:\\{2})*)\1(\s+|$)/))) {
|
|
12252
|
+
matchers.push({ quote: match[1], needle: match[2] });
|
|
12253
|
+
str = str.substring(match[0].length);
|
|
12254
|
+
if (!str.length)
|
|
12255
|
+
break;
|
|
12256
|
+
}
|
|
12257
|
+
if (!str.length)
|
|
12258
|
+
break;
|
|
12259
|
+
if (!matchers.length) {
|
|
12260
|
+
match = str.match(/^(\S+)\s+$/);
|
|
12261
|
+
if (match) {
|
|
12262
|
+
matchers.push({ quote: '"', needle: match[1] });
|
|
12263
|
+
break;
|
|
12264
|
+
}
|
|
12265
|
+
}
|
|
12266
|
+
throw new Error(`Build pragma '${comment.value}' is invalid. In ${comment.loc.source}:${comment.loc.start.line}`);
|
|
12267
|
+
}
|
|
12268
|
+
};
|
|
12269
|
+
next();
|
|
12270
|
+
(0,external_api_cjs_namespaceObject.traverseAst)(ast, (node) => {
|
|
12271
|
+
if (index >= comments.length)
|
|
12272
|
+
return false;
|
|
12273
|
+
if (node.start && node.start >= (comment.end || Infinity)) {
|
|
12274
|
+
const { quote, needle } = matchers.shift();
|
|
12275
|
+
const haystack = (0,external_api_cjs_namespaceObject.formatAst)(node).replace(/[\r\n]/g, " ");
|
|
12276
|
+
let found = false;
|
|
12277
|
+
if (quote == '"') {
|
|
12278
|
+
found = haystack.includes(needle);
|
|
12279
|
+
}
|
|
12280
|
+
else {
|
|
12281
|
+
const re = new RegExp(needle);
|
|
12282
|
+
found = re.test(haystack);
|
|
12283
|
+
}
|
|
12284
|
+
if (!found) {
|
|
12285
|
+
throw new Error(`Didn't find '${needle}' at ${comment.loc.source}:${comment.loc.start.line}`);
|
|
12286
|
+
}
|
|
12287
|
+
if (!matchers.length) {
|
|
12288
|
+
next();
|
|
12289
|
+
}
|
|
12290
|
+
return false;
|
|
12291
|
+
}
|
|
12292
|
+
return null;
|
|
12293
|
+
});
|
|
11924
12294
|
}
|
|
11925
12295
|
|
|
11926
12296
|
;// CONCATENATED MODULE: ./src/optimizer.ts
|
|
@@ -11937,6 +12307,7 @@ async function optimizeMonkeyC(fnMap) {
|
|
|
11937
12307
|
|
|
11938
12308
|
|
|
11939
12309
|
|
|
12310
|
+
|
|
11940
12311
|
function relative_path_no_dotdot(relative) {
|
|
11941
12312
|
return relative.replace(/^(\.\.[\\\/])+/, (str) => `__${"dot".repeat(str.length / 3)}__${str.slice(-1)}`);
|
|
11942
12313
|
}
|
|
@@ -12005,7 +12376,7 @@ async function buildOptimizedProject(product, options) {
|
|
|
12005
12376
|
config.releaseBuild = true;
|
|
12006
12377
|
}
|
|
12007
12378
|
}
|
|
12008
|
-
const { jungleFiles, program, hasTests } = await generateOptimizedProject(config);
|
|
12379
|
+
const { jungleFiles, program, hasTests, diagnostics } = await generateOptimizedProject(config);
|
|
12009
12380
|
config.jungleFiles = jungleFiles;
|
|
12010
12381
|
let bin = config.buildDir || "bin";
|
|
12011
12382
|
let name = `optimized-${program}.prg`;
|
|
@@ -12024,6 +12395,7 @@ async function buildOptimizedProject(product, options) {
|
|
|
12024
12395
|
delete config.testBuild;
|
|
12025
12396
|
return build_project(product, config).then((result) => ({
|
|
12026
12397
|
hasTests,
|
|
12398
|
+
diagnostics,
|
|
12027
12399
|
...result,
|
|
12028
12400
|
}));
|
|
12029
12401
|
}
|
|
@@ -12162,6 +12534,7 @@ async function generateOptimizedProject(options) {
|
|
|
12162
12534
|
(await checkManifest(xml, targets.map((t) => t.product)))) &&
|
|
12163
12535
|
!dropBarrels;
|
|
12164
12536
|
let hasTests = false;
|
|
12537
|
+
let diagnostics = {};
|
|
12165
12538
|
const promises = Object.keys(buildConfigs)
|
|
12166
12539
|
.sort()
|
|
12167
12540
|
.map((key) => {
|
|
@@ -12179,7 +12552,13 @@ async function generateOptimizedProject(options) {
|
|
|
12179
12552
|
e.products = products[key];
|
|
12180
12553
|
throw e;
|
|
12181
12554
|
})
|
|
12182
|
-
.then((t) =>
|
|
12555
|
+
.then((t) => {
|
|
12556
|
+
if (t.hasTests)
|
|
12557
|
+
hasTests = true;
|
|
12558
|
+
if (t.diagnostics) {
|
|
12559
|
+
diagnostics = { ...diagnostics, ...t.diagnostics };
|
|
12560
|
+
}
|
|
12561
|
+
})
|
|
12183
12562
|
: promises_namespaceObject.rm(external_path_.resolve(workspace, outputPath), {
|
|
12184
12563
|
recursive: true,
|
|
12185
12564
|
force: true,
|
|
@@ -12250,6 +12629,7 @@ async function generateOptimizedProject(options) {
|
|
|
12250
12629
|
xml,
|
|
12251
12630
|
program: external_path_.basename(external_path_.dirname(manifest)),
|
|
12252
12631
|
hasTests,
|
|
12632
|
+
diagnostics,
|
|
12253
12633
|
};
|
|
12254
12634
|
}
|
|
12255
12635
|
async function fileInfoFromConfig(workspace, output, buildConfig, extraExcludes) {
|
|
@@ -12328,7 +12708,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
12328
12708
|
const actualOptimizedFiles = (await (0,external_util_cjs_namespaceObject.globa)(external_path_.join(output, "**", "*.mc"), { mark: true }))
|
|
12329
12709
|
.filter((file) => !file.endsWith("/"))
|
|
12330
12710
|
.sort();
|
|
12331
|
-
const { hasTests, ...prevOptions } = JSON.parse(await promises_namespaceObject.readFile(external_path_.join(output, "build-info.json"), "utf-8")
|
|
12711
|
+
const { hasTests, diagnostics: prevDiagnostics, ...prevOptions } = JSON.parse(await promises_namespaceObject.readFile(external_path_.join(output, "build-info.json"), "utf-8")
|
|
12332
12712
|
.catch(() => "{}"));
|
|
12333
12713
|
// check that the set of files thats actually there is the same as the
|
|
12334
12714
|
// set of files we're going to generate (in case eg a jungle file change
|
|
@@ -12346,35 +12726,31 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
12346
12726
|
// the oldest optimized file, we don't need to regenerate
|
|
12347
12727
|
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
12348
12728
|
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
12349
|
-
if (source_time < opt_time &&
|
|
12350
|
-
return hasTests;
|
|
12729
|
+
if (source_time < opt_time && 1654554780017 < opt_time) {
|
|
12730
|
+
return { hasTests, diagnostics: prevDiagnostics };
|
|
12351
12731
|
}
|
|
12352
12732
|
}
|
|
12353
12733
|
await promises_namespaceObject.rm(output, { recursive: true, force: true });
|
|
12354
12734
|
await promises_namespaceObject.mkdir(output, { recursive: true });
|
|
12355
|
-
await optimizeMonkeyC(fnMap);
|
|
12735
|
+
const diagnostics = await optimizeMonkeyC(fnMap);
|
|
12356
12736
|
return Promise.all(Object.values(fnMap).map(async (info) => {
|
|
12357
12737
|
const name = info.output;
|
|
12358
12738
|
const dir = external_path_.dirname(name);
|
|
12359
12739
|
await promises_namespaceObject.mkdir(dir, { recursive: true });
|
|
12360
12740
|
const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(info.ast, info.monkeyCSource);
|
|
12741
|
+
await promises_namespaceObject.writeFile(name, opt_source);
|
|
12361
12742
|
if (config.checkBuildPragmas) {
|
|
12362
|
-
|
|
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
|
-
}
|
|
12743
|
+
pragmaChecker(info.ast);
|
|
12368
12744
|
}
|
|
12369
|
-
await promises_namespaceObject.writeFile(name, opt_source);
|
|
12370
12745
|
return info.hasTests;
|
|
12371
12746
|
})).then((results) => {
|
|
12372
12747
|
const hasTests = results.some((v) => v);
|
|
12373
12748
|
return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
|
|
12374
12749
|
hasTests,
|
|
12750
|
+
diagnostics,
|
|
12375
12751
|
...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
|
|
12376
12752
|
}))
|
|
12377
|
-
.then(() => hasTests);
|
|
12753
|
+
.then(() => ({ hasTests, diagnostics }));
|
|
12378
12754
|
});
|
|
12379
12755
|
}
|
|
12380
12756
|
async function getProjectAnalysis(targets, analysis, options) {
|