@markw65/monkeyc-optimizer 1.0.37 → 1.0.38

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 CHANGED
@@ -420,3 +420,15 @@ Bug Fixes
420
420
  - Update to [@markw65/prettier-plugin-monkeyc@1.0.35](https://github.com/markw65/prettier-plugin-monkeyc#1035).
421
421
  - Fixes [prettier-plugin-monkeyc#1](https://github.com/markw65/prettier-plugin-monkeyc/issues/1)
422
422
  - Fixes [monkeyc-optimizer#1](https://github.com/markw65/monkeyc-optimizer/issues/1)
423
+
424
+ ### 1.0.37
425
+
426
+ - Update the testing framework to launch the simulator before each test run, rather than start it once at the beginning. This is because the latest beta crashes after successfully completing.
427
+ - Update launchSimulator to check if the simulator is already running. This avoids lots of screen switching when the simulator is running on a separate desktop.
428
+ - Add optimizerVersion and extensionVersion to build-info.json.
429
+
430
+ ### 1.0.38
431
+
432
+ - Allow inlining the argument to an if-statement, with the same constraints as inlining in assignment context
433
+ - Expand `assignment`, `declaration` and `if` contexts to include (recursively) the left operand of any binary operator, the operand of any unary operator, the `test` operand of any conditional operator or the `object` of a member-expression. So now it will inline `inlinableFunction` in:
434
+ - `var x = !((inlinableFunction() + 4) == 42 ? foo() : bar());`
package/build/api.cjs CHANGED
@@ -655,8 +655,13 @@ function function_info_findCalleesForNew(lookupDefs) {
655
655
 
656
656
  function variable_renamer_renameVariable(state, locals, declName) {
657
657
  const map = locals.map;
658
- if (!hasProperty(map, declName))
659
- return null;
658
+ if (declName) {
659
+ if (!hasProperty(map, declName))
660
+ return null;
661
+ }
662
+ else {
663
+ declName = "tmp";
664
+ }
660
665
  let suffix = 0;
661
666
  let node_name = declName;
662
667
  const match = node_name.match(/^pmcr_(.*)_(\d+)$/);
@@ -711,6 +716,69 @@ function variable_renamer_renameVariable(state, locals, declName) {
711
716
 
712
717
 
713
718
 
719
+ // Note: Keep in sync with replaceInlinedSubExpression below
720
+ function inliner_inlinableSubExpression(expr) {
721
+ while (true) {
722
+ if (expr.type === "BinaryExpression" || expr.type === "LogicalExpression") {
723
+ expr = expr.left;
724
+ }
725
+ else if (expr.type === "UnaryExpression") {
726
+ expr = expr.argument;
727
+ }
728
+ else if (expr.type === "ConditionalExpression") {
729
+ expr = expr.test;
730
+ }
731
+ else if (expr.type === "MemberExpression") {
732
+ expr = expr.object;
733
+ }
734
+ else if (expr.type === "CallExpression") {
735
+ return expr;
736
+ }
737
+ else {
738
+ return null;
739
+ }
740
+ }
741
+ }
742
+ // Note: Keep in sync with inlinableSubExpression above
743
+ function replaceInlinedSubExpression(top, call, repl) {
744
+ if (top === call)
745
+ return repl;
746
+ let expr = top;
747
+ while (true) {
748
+ if (expr.type === "LogicalExpression" || expr.type === "BinaryExpression") {
749
+ if (expr.left === call) {
750
+ expr.left = repl;
751
+ break;
752
+ }
753
+ expr = expr.left;
754
+ }
755
+ else if (expr.type === "UnaryExpression") {
756
+ if (expr.argument === call) {
757
+ expr.argument = repl;
758
+ break;
759
+ }
760
+ expr = expr.argument;
761
+ }
762
+ else if (expr.type === "ConditionalExpression") {
763
+ if (expr.test === call) {
764
+ expr.test = repl;
765
+ break;
766
+ }
767
+ expr = expr.test;
768
+ }
769
+ else if (expr.type === "MemberExpression") {
770
+ if (expr.object === call) {
771
+ expr.object = repl;
772
+ break;
773
+ }
774
+ expr = expr.object;
775
+ }
776
+ else {
777
+ throw new Error("Internal error: Didn't find CallExpression");
778
+ }
779
+ }
780
+ return top;
781
+ }
714
782
  function getArgSafety(state, func, args, requireAll) {
715
783
  // determine whether decl might be changed by a function call
716
784
  // or assignment during the evaluation of FunctionStateNode.
@@ -938,7 +1006,7 @@ function inliner_shouldInline(state, func, call, context) {
938
1006
  }
939
1007
  }
940
1008
  if (!context && requested) {
941
- inlineDiagnostic(state, func, call, "This function can only be inlined in statement, assignment, or return contexts");
1009
+ inlineDiagnostic(state, func, call, "This function can only be inlined in statement, assignment, if or return contexts");
942
1010
  }
943
1011
  return context != null;
944
1012
  }
@@ -1198,7 +1266,8 @@ function inlineWithArgs(state, func, call, context) {
1198
1266
  inlineDiagnostic(state, func, call, "Function had more than one return statement");
1199
1267
  }
1200
1268
  else if ((context.type === "AssignmentExpression" ||
1201
- context.type === "VariableDeclarator") &&
1269
+ context.type === "VariableDeclarator" ||
1270
+ context.type === "IfStatement") &&
1202
1271
  retStmtCount !== 1) {
1203
1272
  inlineDiagnostic(state, func, call, "Function did not have a return statement");
1204
1273
  return null;
@@ -1208,7 +1277,8 @@ function inlineWithArgs(state, func, call, context) {
1208
1277
  if (!last ||
1209
1278
  last.type !== "ReturnStatement" ||
1210
1279
  ((context.type === "AssignmentExpression" ||
1211
- context.type === "VariableDeclarator") &&
1280
+ context.type === "VariableDeclarator" ||
1281
+ context.type === "IfStatement") &&
1212
1282
  !last.argument)) {
1213
1283
  inlineDiagnostic(state, func, call, "There was a return statement, but not at the end of the function");
1214
1284
  return null;
@@ -1235,14 +1305,15 @@ function inlineWithArgs(state, func, call, context) {
1235
1305
  }
1236
1306
  if (last.argument) {
1237
1307
  if (context.type === "AssignmentExpression") {
1238
- context.right = last.argument;
1308
+ context.right = replaceInlinedSubExpression(context.right, call, last.argument);
1239
1309
  block.body[block.body.length - 1] = {
1240
1310
  type: "ExpressionStatement",
1241
1311
  expression: context,
1242
1312
  };
1243
1313
  }
1244
1314
  else if (context.type === "VariableDeclarator") {
1245
- const { id, init: _init, kind: _kind, ...rest } = context;
1315
+ const { id, init, kind: _kind, ...rest } = context;
1316
+ const right = replaceInlinedSubExpression(init, call, last.argument);
1246
1317
  block.body[block.body.length - 1] = {
1247
1318
  ...rest,
1248
1319
  type: "ExpressionStatement",
@@ -1251,9 +1322,52 @@ function inlineWithArgs(state, func, call, context) {
1251
1322
  type: "AssignmentExpression",
1252
1323
  operator: "=",
1253
1324
  left: id.type === "Identifier" ? id : id.left,
1325
+ right,
1326
+ },
1327
+ };
1328
+ }
1329
+ else if (context.type === "IfStatement") {
1330
+ // Generate a pmcr_tmp name that doesn't conflict with anything
1331
+ const locals = state.localsStack[state.localsStack.length - 1];
1332
+ const name = renameVariable(state, locals, null);
1333
+ locals.map[name] = true;
1334
+ // Replace the inlined function's return statement
1335
+ // with an assignment to pmcr_tmp
1336
+ block.body[block.body.length - 1] = {
1337
+ type: "ExpressionStatement",
1338
+ expression: {
1339
+ type: "AssignmentExpression",
1340
+ operator: "=",
1341
+ left: { type: "Identifier", name },
1254
1342
  right: last.argument,
1255
1343
  },
1256
1344
  };
1345
+ // The IfStatement either has the call as its test, or as
1346
+ // the leftmost argument to a series of Binary/Logical expressions
1347
+ // Either way, replace the call with pmcr_tmp
1348
+ const repl = { type: "Identifier", name };
1349
+ context.test = replaceInlinedSubExpression(context.test, call, repl);
1350
+ // Wrap the inlined body so it looks like
1351
+ // {
1352
+ // var pmcr_tmp;
1353
+ // { /* inlined body, with assignment to pmcr_tmp */ }
1354
+ // if (context) {} // original if statement
1355
+ // }
1356
+ body.body = [
1357
+ {
1358
+ type: "VariableDeclaration",
1359
+ kind: "var",
1360
+ declarations: [
1361
+ {
1362
+ type: "VariableDeclarator",
1363
+ kind: "var",
1364
+ id: { type: "Identifier", name },
1365
+ },
1366
+ ],
1367
+ },
1368
+ { type: "BlockStatement", body: body.body },
1369
+ context,
1370
+ ];
1257
1371
  }
1258
1372
  else {
1259
1373
  const side_exprs = inliner_unused(last.argument);
@@ -1427,7 +1541,7 @@ function pragma_checker_pragmaChecker(state, ast, diagnostics) {
1427
1541
  if (quote == '"') {
1428
1542
  return haystack.includes(needle);
1429
1543
  }
1430
- const re = new RegExp(needle.replace(/@(\d+)/g, "(pre_)?$1(_\\d+)?"));
1544
+ const re = new RegExp(needle.replace(/@([\d\w]+)/g, "(pre_)?$1(_\\d+)?"));
1431
1545
  return re.test(haystack);
1432
1546
  };
1433
1547
  next();
@@ -4048,11 +4162,18 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
4048
4162
  return false;
4049
4163
  return replace(rep, rep);
4050
4164
  }
4051
- else if (node.type === "IfStatement" &&
4052
- node.alternate &&
4053
- node.alternate.type === "BlockStatement" &&
4054
- !node.alternate.body.length) {
4055
- delete node.alternate;
4165
+ else if (node.type === "IfStatement") {
4166
+ if (node.alternate &&
4167
+ node.alternate.type === "BlockStatement" &&
4168
+ !node.alternate.body.length) {
4169
+ delete node.alternate;
4170
+ }
4171
+ else {
4172
+ const call = inlinableSubExpression(node.test);
4173
+ if (call) {
4174
+ return replace(optimizeCall(state, call, node), node.test);
4175
+ }
4176
+ }
4056
4177
  }
4057
4178
  break;
4058
4179
  case "WhileStatement":
@@ -4095,8 +4216,11 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
4095
4216
  let j = 0;
4096
4217
  while (i < node.declarations.length) {
4097
4218
  const decl = declarations[i++];
4098
- if (decl.init && decl.init.type === "CallExpression") {
4099
- const inlined = replace(optimizeCall(state, decl.init, decl), decl.init);
4219
+ if (!decl.init)
4220
+ continue;
4221
+ const call = inlinableSubExpression(decl.init);
4222
+ if (call) {
4223
+ const inlined = replace(optimizeCall(state, call, decl), decl.init);
4100
4224
  if (!inlined)
4101
4225
  continue;
4102
4226
  if (Array.isArray(inlined) || inlined.type != "BlockStatement") {
@@ -4131,7 +4255,8 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
4131
4255
  return replace(optimizeCall(state, node.expression, node), node.expression);
4132
4256
  }
4133
4257
  else if (node.expression.type === "AssignmentExpression") {
4134
- if (node.expression.right.type === "CallExpression") {
4258
+ const call = inlinableSubExpression(node.expression.right);
4259
+ if (call) {
4135
4260
  let ok = false;
4136
4261
  if (node.expression.left.type === "Identifier") {
4137
4262
  if (hasProperty(topLocals().map, node.expression.left.type)) {
@@ -4143,7 +4268,7 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
4143
4268
  ok = !!result;
4144
4269
  }
4145
4270
  if (ok) {
4146
- return replace(optimizeCall(state, node.expression.right, node.expression), node.expression.right);
4271
+ return replace(optimizeCall(state, call, node.expression), node.expression.right);
4147
4272
  }
4148
4273
  }
4149
4274
  }
@@ -11370,8 +11370,13 @@ function findCalleesForNew(lookupDefs) {
11370
11370
 
11371
11371
  function renameVariable(state, locals, declName) {
11372
11372
  const map = locals.map;
11373
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(map, declName))
11374
- return null;
11373
+ if (declName) {
11374
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(map, declName))
11375
+ return null;
11376
+ }
11377
+ else {
11378
+ declName = "tmp";
11379
+ }
11375
11380
  let suffix = 0;
11376
11381
  let node_name = declName;
11377
11382
  const match = node_name.match(/^pmcr_(.*)_(\d+)$/);
@@ -11426,6 +11431,69 @@ function renameVariable(state, locals, declName) {
11426
11431
 
11427
11432
 
11428
11433
 
11434
+ // Note: Keep in sync with replaceInlinedSubExpression below
11435
+ function inlinableSubExpression(expr) {
11436
+ while (true) {
11437
+ if (expr.type === "BinaryExpression" || expr.type === "LogicalExpression") {
11438
+ expr = expr.left;
11439
+ }
11440
+ else if (expr.type === "UnaryExpression") {
11441
+ expr = expr.argument;
11442
+ }
11443
+ else if (expr.type === "ConditionalExpression") {
11444
+ expr = expr.test;
11445
+ }
11446
+ else if (expr.type === "MemberExpression") {
11447
+ expr = expr.object;
11448
+ }
11449
+ else if (expr.type === "CallExpression") {
11450
+ return expr;
11451
+ }
11452
+ else {
11453
+ return null;
11454
+ }
11455
+ }
11456
+ }
11457
+ // Note: Keep in sync with inlinableSubExpression above
11458
+ function replaceInlinedSubExpression(top, call, repl) {
11459
+ if (top === call)
11460
+ return repl;
11461
+ let expr = top;
11462
+ while (true) {
11463
+ if (expr.type === "LogicalExpression" || expr.type === "BinaryExpression") {
11464
+ if (expr.left === call) {
11465
+ expr.left = repl;
11466
+ break;
11467
+ }
11468
+ expr = expr.left;
11469
+ }
11470
+ else if (expr.type === "UnaryExpression") {
11471
+ if (expr.argument === call) {
11472
+ expr.argument = repl;
11473
+ break;
11474
+ }
11475
+ expr = expr.argument;
11476
+ }
11477
+ else if (expr.type === "ConditionalExpression") {
11478
+ if (expr.test === call) {
11479
+ expr.test = repl;
11480
+ break;
11481
+ }
11482
+ expr = expr.test;
11483
+ }
11484
+ else if (expr.type === "MemberExpression") {
11485
+ if (expr.object === call) {
11486
+ expr.object = repl;
11487
+ break;
11488
+ }
11489
+ expr = expr.object;
11490
+ }
11491
+ else {
11492
+ throw new Error("Internal error: Didn't find CallExpression");
11493
+ }
11494
+ }
11495
+ return top;
11496
+ }
11429
11497
  function getArgSafety(state, func, args, requireAll) {
11430
11498
  // determine whether decl might be changed by a function call
11431
11499
  // or assignment during the evaluation of FunctionStateNode.
@@ -11653,7 +11721,7 @@ function shouldInline(state, func, call, context) {
11653
11721
  }
11654
11722
  }
11655
11723
  if (!context && requested) {
11656
- inlineDiagnostic(state, func, call, "This function can only be inlined in statement, assignment, or return contexts");
11724
+ inlineDiagnostic(state, func, call, "This function can only be inlined in statement, assignment, if or return contexts");
11657
11725
  }
11658
11726
  return context != null;
11659
11727
  }
@@ -11913,7 +11981,8 @@ function inlineWithArgs(state, func, call, context) {
11913
11981
  inlineDiagnostic(state, func, call, "Function had more than one return statement");
11914
11982
  }
11915
11983
  else if ((context.type === "AssignmentExpression" ||
11916
- context.type === "VariableDeclarator") &&
11984
+ context.type === "VariableDeclarator" ||
11985
+ context.type === "IfStatement") &&
11917
11986
  retStmtCount !== 1) {
11918
11987
  inlineDiagnostic(state, func, call, "Function did not have a return statement");
11919
11988
  return null;
@@ -11923,7 +11992,8 @@ function inlineWithArgs(state, func, call, context) {
11923
11992
  if (!last ||
11924
11993
  last.type !== "ReturnStatement" ||
11925
11994
  ((context.type === "AssignmentExpression" ||
11926
- context.type === "VariableDeclarator") &&
11995
+ context.type === "VariableDeclarator" ||
11996
+ context.type === "IfStatement") &&
11927
11997
  !last.argument)) {
11928
11998
  inlineDiagnostic(state, func, call, "There was a return statement, but not at the end of the function");
11929
11999
  return null;
@@ -11950,14 +12020,15 @@ function inlineWithArgs(state, func, call, context) {
11950
12020
  }
11951
12021
  if (last.argument) {
11952
12022
  if (context.type === "AssignmentExpression") {
11953
- context.right = last.argument;
12023
+ context.right = replaceInlinedSubExpression(context.right, call, last.argument);
11954
12024
  block.body[block.body.length - 1] = {
11955
12025
  type: "ExpressionStatement",
11956
12026
  expression: context,
11957
12027
  };
11958
12028
  }
11959
12029
  else if (context.type === "VariableDeclarator") {
11960
- const { id, init: _init, kind: _kind, ...rest } = context;
12030
+ const { id, init, kind: _kind, ...rest } = context;
12031
+ const right = replaceInlinedSubExpression(init, call, last.argument);
11961
12032
  block.body[block.body.length - 1] = {
11962
12033
  ...rest,
11963
12034
  type: "ExpressionStatement",
@@ -11966,9 +12037,52 @@ function inlineWithArgs(state, func, call, context) {
11966
12037
  type: "AssignmentExpression",
11967
12038
  operator: "=",
11968
12039
  left: id.type === "Identifier" ? id : id.left,
12040
+ right,
12041
+ },
12042
+ };
12043
+ }
12044
+ else if (context.type === "IfStatement") {
12045
+ // Generate a pmcr_tmp name that doesn't conflict with anything
12046
+ const locals = state.localsStack[state.localsStack.length - 1];
12047
+ const name = renameVariable(state, locals, null);
12048
+ locals.map[name] = true;
12049
+ // Replace the inlined function's return statement
12050
+ // with an assignment to pmcr_tmp
12051
+ block.body[block.body.length - 1] = {
12052
+ type: "ExpressionStatement",
12053
+ expression: {
12054
+ type: "AssignmentExpression",
12055
+ operator: "=",
12056
+ left: { type: "Identifier", name },
11969
12057
  right: last.argument,
11970
12058
  },
11971
12059
  };
12060
+ // The IfStatement either has the call as its test, or as
12061
+ // the leftmost argument to a series of Binary/Logical expressions
12062
+ // Either way, replace the call with pmcr_tmp
12063
+ const repl = { type: "Identifier", name };
12064
+ context.test = replaceInlinedSubExpression(context.test, call, repl);
12065
+ // Wrap the inlined body so it looks like
12066
+ // {
12067
+ // var pmcr_tmp;
12068
+ // { /* inlined body, with assignment to pmcr_tmp */ }
12069
+ // if (context) {} // original if statement
12070
+ // }
12071
+ body.body = [
12072
+ {
12073
+ type: "VariableDeclaration",
12074
+ kind: "var",
12075
+ declarations: [
12076
+ {
12077
+ type: "VariableDeclarator",
12078
+ kind: "var",
12079
+ id: { type: "Identifier", name },
12080
+ },
12081
+ ],
12082
+ },
12083
+ { type: "BlockStatement", body: body.body },
12084
+ context,
12085
+ ];
11972
12086
  }
11973
12087
  else {
11974
12088
  const side_exprs = unused(last.argument);
@@ -12142,7 +12256,7 @@ function pragmaChecker(state, ast, diagnostics) {
12142
12256
  if (quote == '"') {
12143
12257
  return haystack.includes(needle);
12144
12258
  }
12145
- const re = new RegExp(needle.replace(/@(\d+)/g, "(pre_)?$1(_\\d+)?"));
12259
+ const re = new RegExp(needle.replace(/@([\d\w]+)/g, "(pre_)?$1(_\\d+)?"));
12146
12260
  return re.test(haystack);
12147
12261
  };
12148
12262
  next();
@@ -14760,11 +14874,18 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
14760
14874
  return false;
14761
14875
  return replace(rep, rep);
14762
14876
  }
14763
- else if (node.type === "IfStatement" &&
14764
- node.alternate &&
14765
- node.alternate.type === "BlockStatement" &&
14766
- !node.alternate.body.length) {
14767
- delete node.alternate;
14877
+ else if (node.type === "IfStatement") {
14878
+ if (node.alternate &&
14879
+ node.alternate.type === "BlockStatement" &&
14880
+ !node.alternate.body.length) {
14881
+ delete node.alternate;
14882
+ }
14883
+ else {
14884
+ const call = inlinableSubExpression(node.test);
14885
+ if (call) {
14886
+ return replace(optimizeCall(state, call, node), node.test);
14887
+ }
14888
+ }
14768
14889
  }
14769
14890
  break;
14770
14891
  case "WhileStatement":
@@ -14807,8 +14928,11 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
14807
14928
  let j = 0;
14808
14929
  while (i < node.declarations.length) {
14809
14930
  const decl = declarations[i++];
14810
- if (decl.init && decl.init.type === "CallExpression") {
14811
- const inlined = replace(optimizeCall(state, decl.init, decl), decl.init);
14931
+ if (!decl.init)
14932
+ continue;
14933
+ const call = inlinableSubExpression(decl.init);
14934
+ if (call) {
14935
+ const inlined = replace(optimizeCall(state, call, decl), decl.init);
14812
14936
  if (!inlined)
14813
14937
  continue;
14814
14938
  if (Array.isArray(inlined) || inlined.type != "BlockStatement") {
@@ -14843,7 +14967,8 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
14843
14967
  return replace(optimizeCall(state, node.expression, node), node.expression);
14844
14968
  }
14845
14969
  else if (node.expression.type === "AssignmentExpression") {
14846
- if (node.expression.right.type === "CallExpression") {
14970
+ const call = inlinableSubExpression(node.expression.right);
14971
+ if (call) {
14847
14972
  let ok = false;
14848
14973
  if (node.expression.left.type === "Identifier") {
14849
14974
  if ((0,external_api_cjs_namespaceObject.hasProperty)(topLocals().map, node.expression.left.type)) {
@@ -14855,7 +14980,7 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
14855
14980
  ok = !!result;
14856
14981
  }
14857
14982
  if (ok) {
14858
- return replace(optimizeCall(state, node.expression.right, node.expression), node.expression.right);
14983
+ return replace(optimizeCall(state, call, node.expression), node.expression.right);
14859
14984
  }
14860
14985
  }
14861
14986
  }
@@ -15509,7 +15634,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
15509
15634
  // the oldest optimized file, we don't need to regenerate
15510
15635
  const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
15511
15636
  const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
15512
- if (source_time < opt_time && 1666558228929 < opt_time) {
15637
+ if (source_time < opt_time && 1666827670006 < opt_time) {
15513
15638
  return { hasTests, diagnostics: prevDiagnostics };
15514
15639
  }
15515
15640
  }
@@ -15534,7 +15659,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
15534
15659
  return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
15535
15660
  hasTests,
15536
15661
  diagnostics,
15537
- optimizerVersion: "1.0.37",
15662
+ optimizerVersion: "1.0.38",
15538
15663
  ...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
15539
15664
  }))
15540
15665
  .then(() => ({ hasTests, diagnostics }));
@@ -1,11 +1,12 @@
1
1
  import { mctree } from "@markw65/prettier-plugin-monkeyc";
2
2
  import { FunctionStateNode, ProgramStateAnalysis, ProgramStateLive } from "./optimizer-types";
3
+ export declare function inlinableSubExpression(expr: mctree.Expression): mctree.SimpleCallExpression | null;
3
4
  export declare function shouldInline(state: ProgramStateAnalysis, func: FunctionStateNode, call: mctree.CallExpression, context: InlineContext | null): boolean;
4
5
  declare type InlineBody = mctree.BlockStatement | mctree.ExpressionStatement["expression"];
5
6
  export declare function unused(expression: mctree.ExpressionStatement["expression"]): mctree.Statement[];
6
7
  export declare function unused(expression: mctree.ExpressionStatement["expression"], top: true): mctree.Statement[] | null;
7
8
  export declare function diagnostic(state: ProgramStateLive, loc: mctree.Node["loc"], message: string | null, type?: NonNullable<ProgramStateAnalysis["diagnostics"]>[string][number]["type"]): void;
8
- export declare type InlineContext = mctree.ReturnStatement | mctree.AssignmentExpression | mctree.ExpressionStatement | mctree.VariableDeclarator;
9
+ export declare type InlineContext = mctree.ReturnStatement | mctree.IfStatement | mctree.AssignmentExpression | mctree.ExpressionStatement | mctree.VariableDeclarator;
9
10
  export declare function inlineFunction(state: ProgramStateAnalysis, func: FunctionStateNode, call: mctree.CallExpression, context: InlineContext | null): InlineBody | null;
10
11
  export declare function applyTypeIfNeeded(node: mctree.Node): mctree.Node;
11
12
  export {};
@@ -1,2 +1,2 @@
1
1
  import { ProgramStateAnalysis } from "./optimizer-types";
2
- export declare function renameVariable(state: ProgramStateAnalysis, locals: NonNullable<ProgramStateAnalysis["localsStack"]>[number], declName: string): string | null;
2
+ export declare function renameVariable(state: ProgramStateAnalysis, locals: NonNullable<ProgramStateAnalysis["localsStack"]>[number], declName: string | null): string | null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@markw65/monkeyc-optimizer",
3
3
  "type": "module",
4
- "version": "1.0.37",
4
+ "version": "1.0.38",
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",