@markw65/monkeyc-optimizer 1.1.5 → 1.1.6

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
@@ -642,3 +642,10 @@ Bug Fixes
642
642
  - Bug fixes
643
643
  - Always evaluate a constant's initializer to determine its type
644
644
  - Fix a bug refining the object type based on the properties it accesses that could lose the type of the object.
645
+
646
+ ### 1.1.6
647
+
648
+ - Bug fixes
649
+ - Fix an issue in restrictByEquality when restricting a union including an Enum, to a specific value of the enum.
650
+ - Fix the display of Method types to match the syntax used in MonkeyC.
651
+ - Infer the type of method(:symbol) by looking up symbol.
package/build/api.cjs CHANGED
@@ -3380,7 +3380,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
3380
3380
  const info = sysCallInfo(callee);
3381
3381
  if (!info)
3382
3382
  return false;
3383
- const result = info(callee, calleeObj, () => node.arguments.map((arg) => evaluateExpr(state, arg, typeMap).value));
3383
+ const result = info(istate.state, callee, calleeObj, () => node.arguments.map((arg) => evaluateExpr(state, arg, typeMap).value));
3384
3384
  if (result.calleeObj) {
3385
3385
  setStateEvent(curState, calleeObjDecl, result.calleeObj, false);
3386
3386
  }
@@ -4702,14 +4702,18 @@ function evaluateLogicalTypes(op, left, right) {
4702
4702
 
4703
4703
  "use strict";
4704
4704
  /* unused harmony exports evaluateCall, checkCallArgs, sysCallInfo */
4705
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6817);
4706
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
4707
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6906);
4708
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_1__);
4709
- /* harmony import */ var _interp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7161);
4710
- /* harmony import */ var _sub_type__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9234);
4711
- /* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7255);
4712
- /* harmony import */ var _union_type__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(757);
4705
+ /* harmony import */ var _optimizer_types__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9697);
4706
+ /* harmony import */ var _type_flow__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4859);
4707
+ /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6817);
4708
+ /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_2__);
4709
+ /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6906);
4710
+ /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_3__);
4711
+ /* harmony import */ var _interp__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7161);
4712
+ /* harmony import */ var _sub_type__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9234);
4713
+ /* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7255);
4714
+ /* harmony import */ var _union_type__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(757);
4715
+
4716
+
4713
4717
 
4714
4718
 
4715
4719
 
@@ -4738,6 +4742,20 @@ function evaluateCall(istate, node, callee, args) {
4738
4742
  }
4739
4743
  return checkCallArgs(istate, node, callee.value, args);
4740
4744
  }
4745
+ function calleeObjectType(istate, callee) {
4746
+ if (callee.type === "MemberExpression") {
4747
+ return (istate.typeMap?.get(callee.object) || {
4748
+ type: 524287 /* TypeTag.Any */,
4749
+ });
4750
+ }
4751
+ if (callee.type === "Identifier" && istate.func) {
4752
+ const func = istate.func;
4753
+ const [self] = func.stack.slice(-1);
4754
+ return typeFromTypeStateNode(istate.state, self, (func.attributes & StateNodeAttributes.STATIC) !== 0 ||
4755
+ self.type !== "ClassDeclaration");
4756
+ }
4757
+ return null;
4758
+ }
4741
4759
  function checkCallArgs(istate, node, callees, args) {
4742
4760
  const allDiags = [];
4743
4761
  const resultType = reduce(callees, (result, cur) => {
@@ -4747,13 +4765,11 @@ function checkCallArgs(istate, node, callees, args) {
4747
4765
  let returnType = null;
4748
4766
  let effects = true;
4749
4767
  let argEffects = true;
4750
- if (node.callee.type === "MemberExpression") {
4751
- const object = istate.typeMap?.get(node.callee.object) || {
4752
- type: 524287 /* TypeTag.Any */,
4753
- };
4768
+ const object = calleeObjectType(istate, node.callee);
4769
+ if (object) {
4754
4770
  const info = sysCallInfo(cur);
4755
4771
  if (info) {
4756
- const result = info(cur, object, () => args);
4772
+ const result = info(istate.state, cur, object, () => args);
4757
4773
  if (result.argTypes)
4758
4774
  argTypes = result.argTypes;
4759
4775
  if (result.returnType)
@@ -4892,7 +4908,7 @@ function sysCallInfo(func) {
4892
4908
  function getSystemCallTable() {
4893
4909
  if (systemCallInfo)
4894
4910
  return systemCallInfo;
4895
- const arrayAdd = (callee, calleeObj, getArgs) => {
4911
+ const arrayAdd = (state, callee, calleeObj, getArgs) => {
4896
4912
  const ret = {};
4897
4913
  if (calleeObj.type & 512 /* TypeTag.Array */) {
4898
4914
  const adata = getUnionComponent(calleeObj, 512 /* TypeTag.Array */);
@@ -4924,7 +4940,7 @@ function getSystemCallTable() {
4924
4940
  }
4925
4941
  return ret;
4926
4942
  };
4927
- const arrayRet = (callee, calleeObj, _getArgs) => {
4943
+ const arrayRet = (state, callee, calleeObj, _getArgs) => {
4928
4944
  const ret = { effectFree: true };
4929
4945
  if (calleeObj.type & 512 /* TypeTag.Array */) {
4930
4946
  const adata = getUnionComponent(calleeObj, 512 /* TypeTag.Array */);
@@ -4934,7 +4950,7 @@ function getSystemCallTable() {
4934
4950
  }
4935
4951
  return ret;
4936
4952
  };
4937
- const dictionaryGet = (callee, calleeObj, getArgs) => {
4953
+ const dictionaryGet = (state, callee, calleeObj, getArgs) => {
4938
4954
  const ret = { effectFree: true };
4939
4955
  if (calleeObj.type & 1024 /* TypeTag.Dictionary */) {
4940
4956
  const ddata = getUnionComponent(calleeObj, 1024 /* TypeTag.Dictionary */);
@@ -4948,7 +4964,7 @@ function getSystemCallTable() {
4948
4964
  }
4949
4965
  return ret;
4950
4966
  };
4951
- const dictionaryValues = (callee, calleeObj) => {
4967
+ const dictionaryValues = (state, callee, calleeObj) => {
4952
4968
  const ret = { effectFree: true };
4953
4969
  if (calleeObj.type & 1024 /* TypeTag.Dictionary */) {
4954
4970
  const ddata = getUnionComponent(calleeObj, 1024 /* TypeTag.Dictionary */);
@@ -4958,7 +4974,7 @@ function getSystemCallTable() {
4958
4974
  }
4959
4975
  return ret;
4960
4976
  };
4961
- const dictionaryKeys = (callee, calleeObj) => {
4977
+ const dictionaryKeys = (state, callee, calleeObj) => {
4962
4978
  const ret = { effectFree: true };
4963
4979
  if (calleeObj.type & 1024 /* TypeTag.Dictionary */) {
4964
4980
  const ddata = getUnionComponent(calleeObj, 1024 /* TypeTag.Dictionary */);
@@ -4968,7 +4984,7 @@ function getSystemCallTable() {
4968
4984
  }
4969
4985
  return ret;
4970
4986
  };
4971
- const dictionaryPut = (callee, calleeObj, getArgs) => {
4987
+ const dictionaryPut = (state, callee, calleeObj, getArgs) => {
4972
4988
  const ret = {};
4973
4989
  if (calleeObj.type & 1024 /* TypeTag.Dictionary */) {
4974
4990
  const ddata = getUnionComponent(calleeObj, 1024 /* TypeTag.Dictionary */);
@@ -4999,7 +5015,7 @@ function getSystemCallTable() {
4999
5015
  }
5000
5016
  return ret;
5001
5017
  };
5002
- const methodInvoke = (callee, calleeObj, getArgs) => {
5018
+ const methodInvoke = (state, callee, calleeObj, getArgs) => {
5003
5019
  const ret = { argEffects: true };
5004
5020
  if (calleeObj.type & 2048 /* TypeTag.Method */) {
5005
5021
  const data = getUnionComponent(calleeObj, 2048 /* TypeTag.Method */);
@@ -5012,9 +5028,49 @@ function getSystemCallTable() {
5012
5028
  ret.argTypes = getArgs();
5013
5029
  return ret;
5014
5030
  };
5031
+ const method = (state, callee, calleeObj, getArgs) => {
5032
+ const ret = {};
5033
+ const args = getArgs();
5034
+ if (args.length === 1 &&
5035
+ hasValue(args[0]) &&
5036
+ args[0].type === 131072 /* TypeTag.Symbol */) {
5037
+ const symbol = {
5038
+ type: "Identifier",
5039
+ name: args[0].value,
5040
+ };
5041
+ const next = {
5042
+ type: "MemberExpression",
5043
+ object: symbol,
5044
+ property: symbol,
5045
+ computed: false,
5046
+ };
5047
+ const [, trueDecls] = findObjectDeclsByProperty(state, calleeObj, next);
5048
+ if (!trueDecls)
5049
+ return ret;
5050
+ const callees = trueDecls
5051
+ .flatMap((decl) => decl.decls?.[symbol.name])
5052
+ .filter((decl) => decl?.type === "FunctionDeclaration");
5053
+ if (!callees.length)
5054
+ return ret;
5055
+ ret.returnType = callees.reduce((type, callee) => {
5056
+ const result = callee.node.returnType
5057
+ ? typeFromTypespec(state, callee.node.returnType.argument, callee.stack)
5058
+ : { type: 524287 /* TypeTag.Any */ };
5059
+ const args = callee.node.params.map((param) => param.type === "BinaryExpression"
5060
+ ? typeFromTypespec(state, param.right, callee.stack)
5061
+ : { type: 524287 /* TypeTag.Any */ });
5062
+ unionInto(type, {
5063
+ type: 2048 /* TypeTag.Method */,
5064
+ value: { result, args },
5065
+ });
5066
+ return type;
5067
+ }, { type: 0 /* TypeTag.Never */ });
5068
+ }
5069
+ return ret;
5070
+ };
5015
5071
  const nop = () => ({ effectFree: true });
5016
5072
  const mod = () => ({});
5017
- const rounder = (callee, calleeObj, getArgs) => {
5073
+ const rounder = (state, callee, calleeObj, getArgs) => {
5018
5074
  const results = {};
5019
5075
  const fn = Math[callee.name];
5020
5076
  results.effectFree = true;
@@ -5032,7 +5088,7 @@ function getSystemCallTable() {
5032
5088
  : { type: 120 /* TypeTag.Numeric */ };
5033
5089
  return results;
5034
5090
  };
5035
- const mathHelper = (callee, calleeObj, getArgs, helper) => {
5091
+ const mathHelper = (state, callee, calleeObj, getArgs, helper) => {
5036
5092
  const results = {};
5037
5093
  const fn = helper && typeof helper === "function"
5038
5094
  ? helper
@@ -5091,6 +5147,7 @@ function getSystemCallTable() {
5091
5147
  "$.Toybox.Lang.Dictionary.toString": nop,
5092
5148
  "$.Toybox.Lang.Dictionary.values": dictionaryValues,
5093
5149
  "$.Toybox.Lang.Method.invoke": methodInvoke,
5150
+ "$.Toybox.Lang.Object.method": method,
5094
5151
  "$.Toybox.Math.acos": mathHelper,
5095
5152
  "$.Toybox.Math.asin": mathHelper,
5096
5153
  "$.Toybox.Math.atan": mathHelper,
@@ -5098,15 +5155,15 @@ function getSystemCallTable() {
5098
5155
  "$.Toybox.Math.ceil": rounder,
5099
5156
  "$.Toybox.Math.cos": mathHelper,
5100
5157
  "$.Toybox.Math.floor": rounder,
5101
- "$.Toybox.Math.ln": (callee, calleeObj, getArgs) => mathHelper(callee, calleeObj, getArgs, "log"),
5102
- "$.Toybox.Math.log": (callee, calleeObj, getArgs) => mathHelper(callee, calleeObj, getArgs, (x, base) => Math.log(x) / Math.log(base)),
5158
+ "$.Toybox.Math.ln": (state, callee, calleeObj, getArgs) => mathHelper(state, callee, calleeObj, getArgs, "log"),
5159
+ "$.Toybox.Math.log": (state, callee, calleeObj, getArgs) => mathHelper(state, callee, calleeObj, getArgs, (x, base) => Math.log(x) / Math.log(base)),
5103
5160
  "$.Toybox.Math.pow": mathHelper,
5104
5161
  "$.Toybox.Math.round": rounder,
5105
5162
  "$.Toybox.Math.sin": mathHelper,
5106
5163
  "$.Toybox.Math.sqrt": mathHelper,
5107
5164
  "$.Toybox.Math.tan": mathHelper,
5108
- "$.Toybox.Math.toDegrees": (callee, calleeObj, getArgs) => mathHelper(callee, calleeObj, getArgs, (arg) => (arg * 180) / Math.PI),
5109
- "$.Toybox.Math.toRadians": (callee, calleeObj, getArgs) => mathHelper(callee, calleeObj, getArgs, (arg) => (arg * Math.PI) / 180),
5165
+ "$.Toybox.Math.toDegrees": (state, callee, calleeObj, getArgs) => mathHelper(state, callee, calleeObj, getArgs, (arg) => (arg * 180) / Math.PI),
5166
+ "$.Toybox.Math.toRadians": (state, callee, calleeObj, getArgs) => mathHelper(state, callee, calleeObj, getArgs, (arg) => (arg * Math.PI) / 180),
5110
5167
  "$.Toybox.Math.mean": nop,
5111
5168
  "$.Toybox.Math.mode": nop,
5112
5169
  "$.Toybox.Math.stdev": nop,
@@ -7312,8 +7369,8 @@ function display(type) {
7312
7369
  case 1024 /* TypeTag.Dictionary */:
7313
7370
  return `${display(tv.value.key)}, ${display(tv.value.value)}`;
7314
7371
  case 2048 /* TypeTag.Method */:
7315
- return `(${tv.value.args
7316
- .map((arg) => display(arg))
7372
+ return `Method(${tv.value.args
7373
+ .map((arg, i) => `a${i + 1} as ${display(arg)}`)
7317
7374
  .join(", ")}) as ${display(tv.value.result)}`;
7318
7375
  case 4096 /* TypeTag.Module */:
7319
7376
  case 8192 /* TypeTag.Function */:
@@ -7373,6 +7430,7 @@ function display(type) {
7373
7430
  65536 /* TypeTag.Enum */ |
7374
7431
  262144 /* TypeTag.Typedef */ |
7375
7432
  131072 /* TypeTag.Symbol */ |
7433
+ 2048 /* TypeTag.Method */ |
7376
7434
  256 /* TypeTag.String */)) {
7377
7435
  parts.push(valueStr);
7378
7436
  }
@@ -7400,7 +7458,7 @@ function forEachUnionComponent(v, bits, fn) {
7400
7458
  bits &= ~SingleTonTypeTagsConst;
7401
7459
  if (!bits)
7402
7460
  return;
7403
- if (v.type & UnionDataTypeTagsConst) {
7461
+ if ((v.type | bits) & UnionDataTypeTagsConst) {
7404
7462
  // Don't iterate the value type bits if any union bit is set
7405
7463
  bits &= ~ValueTypeTagsConst;
7406
7464
  }
@@ -9848,8 +9848,8 @@ function display(type) {
9848
9848
  case 1024 /* TypeTag.Dictionary */:
9849
9849
  return `${display(tv.value.key)}, ${display(tv.value.value)}`;
9850
9850
  case 2048 /* TypeTag.Method */:
9851
- return `(${tv.value.args
9852
- .map((arg) => display(arg))
9851
+ return `Method(${tv.value.args
9852
+ .map((arg, i) => `a${i + 1} as ${display(arg)}`)
9853
9853
  .join(", ")}) as ${display(tv.value.result)}`;
9854
9854
  case 4096 /* TypeTag.Module */:
9855
9855
  case 8192 /* TypeTag.Function */:
@@ -9909,6 +9909,7 @@ function display(type) {
9909
9909
  65536 /* TypeTag.Enum */ |
9910
9910
  262144 /* TypeTag.Typedef */ |
9911
9911
  131072 /* TypeTag.Symbol */ |
9912
+ 2048 /* TypeTag.Method */ |
9912
9913
  256 /* TypeTag.String */)) {
9913
9914
  parts.push(valueStr);
9914
9915
  }
@@ -9936,7 +9937,7 @@ function forEachUnionComponent(v, bits, fn) {
9936
9937
  bits &= ~SingleTonTypeTagsConst;
9937
9938
  if (!bits)
9938
9939
  return;
9939
- if (v.type & UnionDataTypeTagsConst) {
9940
+ if ((v.type | bits) & UnionDataTypeTagsConst) {
9940
9941
  // Don't iterate the value type bits if any union bit is set
9941
9942
  bits &= ~ValueTypeTagsConst;
9942
9943
  }
@@ -10604,6 +10605,8 @@ function evaluateLogicalTypes(op, left, right) {
10604
10605
 
10605
10606
 
10606
10607
 
10608
+
10609
+
10607
10610
  function evaluateCall(istate, node, callee, args) {
10608
10611
  while (!hasValue(callee) || callee.type !== 8192 /* TypeTag.Function */) {
10609
10612
  const name = node.callee.type === "Identifier"
@@ -10626,6 +10629,20 @@ function evaluateCall(istate, node, callee, args) {
10626
10629
  }
10627
10630
  return checkCallArgs(istate, node, callee.value, args);
10628
10631
  }
10632
+ function calleeObjectType(istate, callee) {
10633
+ if (callee.type === "MemberExpression") {
10634
+ return (istate.typeMap?.get(callee.object) || {
10635
+ type: 524287 /* TypeTag.Any */,
10636
+ });
10637
+ }
10638
+ if (callee.type === "Identifier" && istate.func) {
10639
+ const func = istate.func;
10640
+ const [self] = func.stack.slice(-1);
10641
+ return typeFromTypeStateNode(istate.state, self, (func.attributes & StateNodeAttributes.STATIC) !== 0 ||
10642
+ self.type !== "ClassDeclaration");
10643
+ }
10644
+ return null;
10645
+ }
10629
10646
  function checkCallArgs(istate, node, callees, args) {
10630
10647
  const allDiags = [];
10631
10648
  const resultType = (0,external_util_cjs_namespaceObject.reduce)(callees, (result, cur) => {
@@ -10635,13 +10652,11 @@ function checkCallArgs(istate, node, callees, args) {
10635
10652
  let returnType = null;
10636
10653
  let effects = true;
10637
10654
  let argEffects = true;
10638
- if (node.callee.type === "MemberExpression") {
10639
- const object = istate.typeMap?.get(node.callee.object) || {
10640
- type: 524287 /* TypeTag.Any */,
10641
- };
10655
+ const object = calleeObjectType(istate, node.callee);
10656
+ if (object) {
10642
10657
  const info = sysCallInfo(cur);
10643
10658
  if (info) {
10644
- const result = info(cur, object, () => args);
10659
+ const result = info(istate.state, cur, object, () => args);
10645
10660
  if (result.argTypes)
10646
10661
  argTypes = result.argTypes;
10647
10662
  if (result.returnType)
@@ -10780,7 +10795,7 @@ function sysCallInfo(func) {
10780
10795
  function getSystemCallTable() {
10781
10796
  if (systemCallInfo)
10782
10797
  return systemCallInfo;
10783
- const arrayAdd = (callee, calleeObj, getArgs) => {
10798
+ const arrayAdd = (state, callee, calleeObj, getArgs) => {
10784
10799
  const ret = {};
10785
10800
  if (calleeObj.type & 512 /* TypeTag.Array */) {
10786
10801
  const adata = getUnionComponent(calleeObj, 512 /* TypeTag.Array */);
@@ -10812,7 +10827,7 @@ function getSystemCallTable() {
10812
10827
  }
10813
10828
  return ret;
10814
10829
  };
10815
- const arrayRet = (callee, calleeObj, _getArgs) => {
10830
+ const arrayRet = (state, callee, calleeObj, _getArgs) => {
10816
10831
  const ret = { effectFree: true };
10817
10832
  if (calleeObj.type & 512 /* TypeTag.Array */) {
10818
10833
  const adata = getUnionComponent(calleeObj, 512 /* TypeTag.Array */);
@@ -10822,7 +10837,7 @@ function getSystemCallTable() {
10822
10837
  }
10823
10838
  return ret;
10824
10839
  };
10825
- const dictionaryGet = (callee, calleeObj, getArgs) => {
10840
+ const dictionaryGet = (state, callee, calleeObj, getArgs) => {
10826
10841
  const ret = { effectFree: true };
10827
10842
  if (calleeObj.type & 1024 /* TypeTag.Dictionary */) {
10828
10843
  const ddata = getUnionComponent(calleeObj, 1024 /* TypeTag.Dictionary */);
@@ -10836,7 +10851,7 @@ function getSystemCallTable() {
10836
10851
  }
10837
10852
  return ret;
10838
10853
  };
10839
- const dictionaryValues = (callee, calleeObj) => {
10854
+ const dictionaryValues = (state, callee, calleeObj) => {
10840
10855
  const ret = { effectFree: true };
10841
10856
  if (calleeObj.type & 1024 /* TypeTag.Dictionary */) {
10842
10857
  const ddata = getUnionComponent(calleeObj, 1024 /* TypeTag.Dictionary */);
@@ -10846,7 +10861,7 @@ function getSystemCallTable() {
10846
10861
  }
10847
10862
  return ret;
10848
10863
  };
10849
- const dictionaryKeys = (callee, calleeObj) => {
10864
+ const dictionaryKeys = (state, callee, calleeObj) => {
10850
10865
  const ret = { effectFree: true };
10851
10866
  if (calleeObj.type & 1024 /* TypeTag.Dictionary */) {
10852
10867
  const ddata = getUnionComponent(calleeObj, 1024 /* TypeTag.Dictionary */);
@@ -10856,7 +10871,7 @@ function getSystemCallTable() {
10856
10871
  }
10857
10872
  return ret;
10858
10873
  };
10859
- const dictionaryPut = (callee, calleeObj, getArgs) => {
10874
+ const dictionaryPut = (state, callee, calleeObj, getArgs) => {
10860
10875
  const ret = {};
10861
10876
  if (calleeObj.type & 1024 /* TypeTag.Dictionary */) {
10862
10877
  const ddata = getUnionComponent(calleeObj, 1024 /* TypeTag.Dictionary */);
@@ -10887,7 +10902,7 @@ function getSystemCallTable() {
10887
10902
  }
10888
10903
  return ret;
10889
10904
  };
10890
- const methodInvoke = (callee, calleeObj, getArgs) => {
10905
+ const methodInvoke = (state, callee, calleeObj, getArgs) => {
10891
10906
  const ret = { argEffects: true };
10892
10907
  if (calleeObj.type & 2048 /* TypeTag.Method */) {
10893
10908
  const data = getUnionComponent(calleeObj, 2048 /* TypeTag.Method */);
@@ -10900,9 +10915,49 @@ function getSystemCallTable() {
10900
10915
  ret.argTypes = getArgs();
10901
10916
  return ret;
10902
10917
  };
10918
+ const method = (state, callee, calleeObj, getArgs) => {
10919
+ const ret = {};
10920
+ const args = getArgs();
10921
+ if (args.length === 1 &&
10922
+ hasValue(args[0]) &&
10923
+ args[0].type === 131072 /* TypeTag.Symbol */) {
10924
+ const symbol = {
10925
+ type: "Identifier",
10926
+ name: args[0].value,
10927
+ };
10928
+ const next = {
10929
+ type: "MemberExpression",
10930
+ object: symbol,
10931
+ property: symbol,
10932
+ computed: false,
10933
+ };
10934
+ const [, trueDecls] = findObjectDeclsByProperty(state, calleeObj, next);
10935
+ if (!trueDecls)
10936
+ return ret;
10937
+ const callees = trueDecls
10938
+ .flatMap((decl) => decl.decls?.[symbol.name])
10939
+ .filter((decl) => decl?.type === "FunctionDeclaration");
10940
+ if (!callees.length)
10941
+ return ret;
10942
+ ret.returnType = callees.reduce((type, callee) => {
10943
+ const result = callee.node.returnType
10944
+ ? typeFromTypespec(state, callee.node.returnType.argument, callee.stack)
10945
+ : { type: 524287 /* TypeTag.Any */ };
10946
+ const args = callee.node.params.map((param) => param.type === "BinaryExpression"
10947
+ ? typeFromTypespec(state, param.right, callee.stack)
10948
+ : { type: 524287 /* TypeTag.Any */ });
10949
+ unionInto(type, {
10950
+ type: 2048 /* TypeTag.Method */,
10951
+ value: { result, args },
10952
+ });
10953
+ return type;
10954
+ }, { type: 0 /* TypeTag.Never */ });
10955
+ }
10956
+ return ret;
10957
+ };
10903
10958
  const nop = () => ({ effectFree: true });
10904
10959
  const mod = () => ({});
10905
- const rounder = (callee, calleeObj, getArgs) => {
10960
+ const rounder = (state, callee, calleeObj, getArgs) => {
10906
10961
  const results = {};
10907
10962
  const fn = Math[callee.name];
10908
10963
  results.effectFree = true;
@@ -10920,7 +10975,7 @@ function getSystemCallTable() {
10920
10975
  : { type: 120 /* TypeTag.Numeric */ };
10921
10976
  return results;
10922
10977
  };
10923
- const mathHelper = (callee, calleeObj, getArgs, helper) => {
10978
+ const mathHelper = (state, callee, calleeObj, getArgs, helper) => {
10924
10979
  const results = {};
10925
10980
  const fn = helper && typeof helper === "function"
10926
10981
  ? helper
@@ -10979,6 +11034,7 @@ function getSystemCallTable() {
10979
11034
  "$.Toybox.Lang.Dictionary.toString": nop,
10980
11035
  "$.Toybox.Lang.Dictionary.values": dictionaryValues,
10981
11036
  "$.Toybox.Lang.Method.invoke": methodInvoke,
11037
+ "$.Toybox.Lang.Object.method": method,
10982
11038
  "$.Toybox.Math.acos": mathHelper,
10983
11039
  "$.Toybox.Math.asin": mathHelper,
10984
11040
  "$.Toybox.Math.atan": mathHelper,
@@ -10986,15 +11042,15 @@ function getSystemCallTable() {
10986
11042
  "$.Toybox.Math.ceil": rounder,
10987
11043
  "$.Toybox.Math.cos": mathHelper,
10988
11044
  "$.Toybox.Math.floor": rounder,
10989
- "$.Toybox.Math.ln": (callee, calleeObj, getArgs) => mathHelper(callee, calleeObj, getArgs, "log"),
10990
- "$.Toybox.Math.log": (callee, calleeObj, getArgs) => mathHelper(callee, calleeObj, getArgs, (x, base) => Math.log(x) / Math.log(base)),
11045
+ "$.Toybox.Math.ln": (state, callee, calleeObj, getArgs) => mathHelper(state, callee, calleeObj, getArgs, "log"),
11046
+ "$.Toybox.Math.log": (state, callee, calleeObj, getArgs) => mathHelper(state, callee, calleeObj, getArgs, (x, base) => Math.log(x) / Math.log(base)),
10991
11047
  "$.Toybox.Math.pow": mathHelper,
10992
11048
  "$.Toybox.Math.round": rounder,
10993
11049
  "$.Toybox.Math.sin": mathHelper,
10994
11050
  "$.Toybox.Math.sqrt": mathHelper,
10995
11051
  "$.Toybox.Math.tan": mathHelper,
10996
- "$.Toybox.Math.toDegrees": (callee, calleeObj, getArgs) => mathHelper(callee, calleeObj, getArgs, (arg) => (arg * 180) / Math.PI),
10997
- "$.Toybox.Math.toRadians": (callee, calleeObj, getArgs) => mathHelper(callee, calleeObj, getArgs, (arg) => (arg * Math.PI) / 180),
11052
+ "$.Toybox.Math.toDegrees": (state, callee, calleeObj, getArgs) => mathHelper(state, callee, calleeObj, getArgs, (arg) => (arg * 180) / Math.PI),
11053
+ "$.Toybox.Math.toRadians": (state, callee, calleeObj, getArgs) => mathHelper(state, callee, calleeObj, getArgs, (arg) => (arg * Math.PI) / 180),
10998
11054
  "$.Toybox.Math.mean": nop,
10999
11055
  "$.Toybox.Math.mode": nop,
11000
11056
  "$.Toybox.Math.stdev": nop,
@@ -12391,7 +12447,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
12391
12447
  const info = sysCallInfo(callee);
12392
12448
  if (!info)
12393
12449
  return false;
12394
- const result = info(callee, calleeObj, () => node.arguments.map((arg) => evaluateExpr(state, arg, typeMap).value));
12450
+ const result = info(istate.state, callee, calleeObj, () => node.arguments.map((arg) => evaluateExpr(state, arg, typeMap).value));
12395
12451
  if (result.calleeObj) {
12396
12452
  setStateEvent(curState, calleeObjDecl, result.calleeObj, false);
12397
12453
  }
@@ -15325,7 +15381,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
15325
15381
  // the oldest optimized file, we don't need to regenerate
15326
15382
  const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
15327
15383
  const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
15328
- if (source_time < opt_time && 1674683508654 < opt_time) {
15384
+ if (source_time < opt_time && 1674707539512 < opt_time) {
15329
15385
  return { hasTests, diagnostics: prevDiagnostics };
15330
15386
  }
15331
15387
  }
@@ -15352,7 +15408,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
15352
15408
  return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
15353
15409
  hasTests,
15354
15410
  diagnostics,
15355
- optimizerVersion: "1.1.5",
15411
+ optimizerVersion: "1.1.6",
15356
15412
  ...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
15357
15413
  }))
15358
15414
  .then(() => ({ hasTests, diagnostics }));
@@ -1,5 +1,5 @@
1
1
  import { mctree } from "@markw65/prettier-plugin-monkeyc";
2
- import { FunctionStateNode } from "src/optimizer-types";
2
+ import { FunctionStateNode, ProgramStateAnalysis } from "../optimizer-types";
3
3
  import { InterpStackElem, InterpState } from "./interp";
4
4
  import { ExactOrUnion } from "./types";
5
5
  export declare function evaluateCall(istate: InterpState, node: mctree.CallExpression, callee: ExactOrUnion, args: ExactOrUnion[]): InterpStackElem;
@@ -11,6 +11,6 @@ declare type SysCallHelperResult = {
11
11
  effectFree?: true;
12
12
  argEffects?: true;
13
13
  };
14
- declare type SysCallHelper = (func: FunctionStateNode, calleeObj: ExactOrUnion, getArgs: () => Array<ExactOrUnion>) => SysCallHelperResult;
14
+ declare type SysCallHelper = (state: ProgramStateAnalysis, func: FunctionStateNode, calleeObj: ExactOrUnion, getArgs: () => Array<ExactOrUnion>) => SysCallHelperResult;
15
15
  export declare function sysCallInfo(func: FunctionStateNode): SysCallHelper | null;
16
16
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@markw65/monkeyc-optimizer",
3
3
  "type": "module",
4
- "version": "1.1.5",
4
+ "version": "1.1.6",
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",