@markw65/monkeyc-optimizer 1.1.4 → 1.1.5

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
@@ -636,3 +636,9 @@ Bug Fixes
636
636
  - Code cleanup
637
637
  - refactor some of the type code for better type safety
638
638
  - turn on the eslint rule eqeqeq and fix all the issues
639
+
640
+ ### 1.1.5
641
+
642
+ - Bug fixes
643
+ - Always evaluate a constant's initializer to determine its type
644
+ - Fix a bug refining the object type based on the properties it accesses that could lose the type of the object.
package/build/api.cjs CHANGED
@@ -3022,45 +3022,115 @@ function printBlockState(block, state, indent = "") {
3022
3022
  console.log(`${indent} - ${typeStateEntry(value, key)}${value.equivSet ? " " + tsEquivs(state, key) : ""}`);
3023
3023
  });
3024
3024
  }
3025
- function filterDecls(decls, possible) {
3025
+ /*
3026
+ * We have an object, and a MemberExpression object.<name>
3027
+ * - decls are the StateNodes associated with the known type
3028
+ * of object.
3029
+ * - possible are all the StateNodes that declare <name>
3030
+ *
3031
+ * We want to find all the elements of possible which are
3032
+ * "compatible" with decls, which tells us the set of things
3033
+ * that object.<name> could correspond to, and also what that
3034
+ * tells us about object.
3035
+ *
3036
+ * The return value is two arrays of StateNode. The first
3037
+ * gives the refined type of object, and the second is the
3038
+ * array of StateNodes that could declare <name>
3039
+ */
3040
+ function filterDecls(decls, possible, name) {
3026
3041
  if (!possible)
3027
- return null;
3028
- return decls.reduce((cur, decl) => {
3042
+ return [null, null];
3043
+ const result = decls.reduce((cur, decl) => {
3029
3044
  const found = possible.reduce((flag, poss) => {
3030
3045
  if (decl === poss ||
3031
- (poss.type === "ClassDeclaration" &&
3032
- (0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(poss)?.has(decl)) ||
3033
- (decl.type === "ClassDeclaration" && (0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(decl)?.has(poss))) {
3034
- if (!cur)
3035
- cur = [poss];
3036
- else
3037
- cur.push(poss);
3046
+ (poss.type === "ClassDeclaration" && (0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(poss)?.has(decl))) {
3047
+ // poss extends decl, so decl must actually be a poss
3048
+ // eg we know obj is an Object, and we call obj.toNumber
3049
+ // so possible includes all the classes that declare toNumber
3050
+ // so we can refine obj's type to the union of those types
3051
+ if (!cur[0]) {
3052
+ cur = [new Set(), new Set()];
3053
+ }
3054
+ cur[0].add(poss);
3055
+ cur[1].add(poss);
3056
+ return true;
3057
+ }
3058
+ else if (decl.type === "ClassDeclaration" &&
3059
+ (0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(decl)?.has(poss)) {
3060
+ // decl extends poss, so decl remains unchanged
3061
+ // eg we know obj is Menu2, we call obj.toString
3062
+ // Menu2 doesn't define toString, but Object does
3063
+ // so poss is Object. But we still know that
3064
+ // obj is Menu2
3065
+ if (!cur[0]) {
3066
+ cur = [new Set(), new Set()];
3067
+ }
3068
+ cur[0].add(decl);
3069
+ cur[1].add(poss);
3038
3070
  return true;
3039
3071
  }
3040
3072
  return flag;
3041
3073
  }, false);
3042
3074
  if (!found) {
3043
- possible.some((poss) => {
3044
- if (decl.stack?.some((sn) => sn.decls === poss.decls)) {
3045
- if (!cur)
3046
- cur = [poss];
3047
- else
3048
- cur.push(poss);
3049
- return true;
3050
- }
3051
- return false;
3052
- });
3075
+ // If we didn't find the property in any of the
3076
+ // standard places, the runtime might still find
3077
+ // it by searching up the Module stack (and up
3078
+ // the module stack from any super classes)
3079
+ //
3080
+ // eg
3081
+ //
3082
+ // obj = Application.getApp();
3083
+ // obj.Properties.whatever
3084
+ //
3085
+ // Properties doesn't exist on AppBase, but AppBase
3086
+ // is declared in Application, and Application
3087
+ // does declare Properties. So Application.Properties
3088
+ // is (one of) the declarations we should find; but we
3089
+ // must not refine obj's type to include Application.
3090
+ let d = [decl];
3091
+ do {
3092
+ d.forEach((d) => {
3093
+ const stack = d.stack;
3094
+ possible.forEach((poss) => {
3095
+ for (let i = stack.length; i--;) {
3096
+ const sn = stack[i];
3097
+ if (sn.decls === poss.decls) {
3098
+ if (!cur[0]) {
3099
+ cur = [new Set(), new Set()];
3100
+ }
3101
+ cur[0].add(decl);
3102
+ cur[1].add(poss);
3103
+ break;
3104
+ }
3105
+ if ((0,_api__WEBPACK_IMPORTED_MODULE_0__.hasProperty)(sn.decls, name)) {
3106
+ break;
3107
+ }
3108
+ }
3109
+ });
3110
+ });
3111
+ d = d.flatMap((d) => {
3112
+ if (d.type !== "ClassDeclaration" ||
3113
+ !d.superClass ||
3114
+ d.superClass === true) {
3115
+ return [];
3116
+ }
3117
+ return d.superClass;
3118
+ });
3119
+ } while (d.length);
3053
3120
  }
3054
3121
  return cur;
3055
- }, null);
3122
+ }, [null, null]);
3123
+ if (!result[0])
3124
+ return [null, null];
3125
+ return [Array.from(result[0]), Array.from(result[1])];
3056
3126
  }
3057
3127
  function findObjectDeclsByProperty(state, object, next) {
3058
3128
  const decls = (0,_type_flow_types__WEBPACK_IMPORTED_MODULE_11__/* .getStateNodeDeclsFromType */ .iX)(state, object);
3059
3129
  if (!decls)
3060
- return null;
3130
+ return [null, null];
3061
3131
  const possibleDecls = (0,_api__WEBPACK_IMPORTED_MODULE_0__.hasProperty)(state.allDeclarations, next.property.name) &&
3062
3132
  state.allDeclarations[next.property.name];
3063
- return filterDecls(decls, possibleDecls);
3133
+ return filterDecls(decls, possibleDecls, next.property.name);
3064
3134
  }
3065
3135
  function refineObjectTypeByDecls(istate, object, trueDecls) {
3066
3136
  const refinedType = typeFromTypeStateNodes(istate.state, trueDecls);
@@ -3076,13 +3146,13 @@ function findNextObjectType(istate, trueDecls, next) {
3076
3146
  }, { type: 0 /* TypeTag.Never */ });
3077
3147
  }
3078
3148
  function resolveDottedMember(istate, object, next) {
3079
- const decls = findObjectDeclsByProperty(istate.state, object, next);
3080
- if (!decls)
3149
+ const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, object, next);
3150
+ if (!objDecls)
3081
3151
  return null;
3082
- const property = findNextObjectType(istate, decls, next);
3152
+ const property = findNextObjectType(istate, trueDecls, next);
3083
3153
  if (!property)
3084
3154
  return null;
3085
- const type = refineObjectTypeByDecls(istate, object, decls);
3155
+ const type = refineObjectTypeByDecls(istate, object, objDecls);
3086
3156
  const mayThrow = !subtypeOf(object, type);
3087
3157
  return { mayThrow, object: type, property };
3088
3158
  }
@@ -3119,11 +3189,11 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
3119
3189
  next = value.obj[me.property.name];
3120
3190
  }
3121
3191
  else {
3122
- const trueDecls = findObjectDeclsByProperty(istate.state, cur, me);
3123
- if (!trueDecls) {
3192
+ const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, cur, me);
3193
+ if (!objDecls) {
3124
3194
  return null;
3125
3195
  }
3126
- cur = refineObjectTypeByDecls(istate, cur, trueDecls);
3196
+ cur = refineObjectTypeByDecls(istate, cur, objDecls);
3127
3197
  next = findNextObjectType(istate, trueDecls, me);
3128
3198
  }
3129
3199
  }
@@ -5288,9 +5358,9 @@ function getLhsConstraint(istate, node) {
5288
5358
  }
5289
5359
  const object = istate.typeMap.get(node.object);
5290
5360
  if (object && !node.computed) {
5291
- const objDecls = findObjectDeclsByProperty(istate.state, object, node);
5292
- if (objDecls) {
5293
- lookupDefs = lookupNext(istate.state, [{ parent: null, results: objDecls }], "decls", node.property);
5361
+ const [, trueDecls] = findObjectDeclsByProperty(istate.state, object, node);
5362
+ if (trueDecls) {
5363
+ lookupDefs = lookupNext(istate.state, [{ parent: null, results: trueDecls }], "decls", node.property);
5294
5364
  }
5295
5365
  }
5296
5366
  }
@@ -6643,6 +6713,8 @@ function printBlockTrailer(block) {
6643
6713
  /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_4__);
6644
6714
  /* harmony import */ var _interp__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7161);
6645
6715
  /* harmony import */ var _union_type__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(757);
6716
+ /* harmony import */ var _intersection_type__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(6973);
6717
+
6646
6718
 
6647
6719
 
6648
6720
 
@@ -6866,24 +6938,47 @@ function typeFromTypeStateNode(state, sn, classVsObj) {
6866
6938
  sn.resolvedType = result;
6867
6939
  return result;
6868
6940
  }
6869
- case "VariableDeclarator":
6941
+ case "VariableDeclarator": {
6942
+ if (sn.resolvedType)
6943
+ return sn.resolvedType;
6944
+ let declared = null;
6945
+ if (sn.node.id.type === "BinaryExpression") {
6946
+ declared = typeFromTypespec(state, sn.node.id.right, sn.stack);
6947
+ }
6870
6948
  if (sn.node.kind === "const" && sn.node.init) {
6871
- let node = sn.node.init;
6872
- if (node.type === "Literal") {
6873
- return typeFromLiteral(node);
6949
+ if (hasProperty(sn, "resolvedType")) {
6950
+ // The constant is defined recursively
6951
+ return declared ?? { type: 524287 /* TypeTag.Any */ };
6952
+ }
6953
+ // set the marker in case the constant appears in its
6954
+ // own initializer.
6955
+ sn.resolvedType = undefined;
6956
+ const stack = state.stack;
6957
+ let resolved;
6958
+ try {
6959
+ state.stack = sn.stack;
6960
+ resolved = evaluateExpr(state, sn.node.init).value;
6961
+ }
6962
+ finally {
6963
+ state.stack = stack;
6874
6964
  }
6875
- while (node.type === "BinaryExpression" && node.operator === "as") {
6876
- node = node.left;
6965
+ if (resolved.type === 0 /* TypeTag.Never */) {
6966
+ resolved = declared ?? { type: 524287 /* TypeTag.Any */ };
6877
6967
  }
6878
- if (node.type === "Literal" ||
6879
- (node.type === "UnaryExpression" && node.operator === ":")) {
6880
- return evaluateExpr(state, sn.node.init).value;
6968
+ else if (declared) {
6969
+ resolved = intersection(resolved, declared);
6970
+ if (resolved.type === 0 /* TypeTag.Never */) {
6971
+ resolved = declared;
6972
+ }
6881
6973
  }
6974
+ sn.resolvedType = resolved;
6975
+ return resolved;
6882
6976
  }
6883
6977
  if (sn.node.id.type === "BinaryExpression") {
6884
6978
  return typeFromTypespec(state, sn.node.id.right, sn.stack);
6885
6979
  }
6886
6980
  return { type: 524287 /* TypeTag.Any */ };
6981
+ }
6887
6982
  }
6888
6983
  throw new Error(`Internal error: Unexpected StateNodeDecl.type: ${sn.type}`);
6889
6984
  }
@@ -8602,7 +8697,7 @@ function visitReferences(state, ast, name, defn, callback, includeDefs = false,
8602
8697
  const objectType = typeMap.get(node.object);
8603
8698
  if (!objectType)
8604
8699
  return results;
8605
- const decls = (0,type_flow/* findObjectDeclsByProperty */.nK)(state, objectType, node);
8700
+ const [, decls] = (0,type_flow/* findObjectDeclsByProperty */.nK)(state, objectType, node);
8606
8701
  if (decls) {
8607
8702
  const next = (0,external_api_cjs_.lookupNext)(state, [{ parent: null, results: decls }], "decls", node.property);
8608
8703
  if (next) {
@@ -9257,6 +9257,7 @@ function widenType(t) {
9257
9257
 
9258
9258
 
9259
9259
 
9260
+
9260
9261
  function typeTagName(tag) {
9261
9262
  switch (tag) {
9262
9263
  case 0 /* TypeTag.Never */:
@@ -9473,24 +9474,47 @@ function typeFromTypeStateNode(state, sn, classVsObj) {
9473
9474
  sn.resolvedType = result;
9474
9475
  return result;
9475
9476
  }
9476
- case "VariableDeclarator":
9477
+ case "VariableDeclarator": {
9478
+ if (sn.resolvedType)
9479
+ return sn.resolvedType;
9480
+ let declared = null;
9481
+ if (sn.node.id.type === "BinaryExpression") {
9482
+ declared = typeFromTypespec(state, sn.node.id.right, sn.stack);
9483
+ }
9477
9484
  if (sn.node.kind === "const" && sn.node.init) {
9478
- let node = sn.node.init;
9479
- if (node.type === "Literal") {
9480
- return typeFromLiteral(node);
9485
+ if (hasProperty(sn, "resolvedType")) {
9486
+ // The constant is defined recursively
9487
+ return declared ?? { type: 524287 /* TypeTag.Any */ };
9481
9488
  }
9482
- while (node.type === "BinaryExpression" && node.operator === "as") {
9483
- node = node.left;
9489
+ // set the marker in case the constant appears in its
9490
+ // own initializer.
9491
+ sn.resolvedType = undefined;
9492
+ const stack = state.stack;
9493
+ let resolved;
9494
+ try {
9495
+ state.stack = sn.stack;
9496
+ resolved = evaluateExpr(state, sn.node.init).value;
9484
9497
  }
9485
- if (node.type === "Literal" ||
9486
- (node.type === "UnaryExpression" && node.operator === ":")) {
9487
- return evaluateExpr(state, sn.node.init).value;
9498
+ finally {
9499
+ state.stack = stack;
9488
9500
  }
9501
+ if (resolved.type === 0 /* TypeTag.Never */) {
9502
+ resolved = declared ?? { type: 524287 /* TypeTag.Any */ };
9503
+ }
9504
+ else if (declared) {
9505
+ resolved = intersection(resolved, declared);
9506
+ if (resolved.type === 0 /* TypeTag.Never */) {
9507
+ resolved = declared;
9508
+ }
9509
+ }
9510
+ sn.resolvedType = resolved;
9511
+ return resolved;
9489
9512
  }
9490
9513
  if (sn.node.id.type === "BinaryExpression") {
9491
9514
  return typeFromTypespec(state, sn.node.id.right, sn.stack);
9492
9515
  }
9493
9516
  return { type: 524287 /* TypeTag.Any */ };
9517
+ }
9494
9518
  }
9495
9519
  throw new Error(`Internal error: Unexpected StateNodeDecl.type: ${sn.type}`);
9496
9520
  }
@@ -11203,9 +11227,9 @@ function getLhsConstraint(istate, node) {
11203
11227
  }
11204
11228
  const object = istate.typeMap.get(node.object);
11205
11229
  if (object && !node.computed) {
11206
- const objDecls = findObjectDeclsByProperty(istate.state, object, node);
11207
- if (objDecls) {
11208
- lookupDefs = (0,external_api_cjs_namespaceObject.lookupNext)(istate.state, [{ parent: null, results: objDecls }], "decls", node.property);
11230
+ const [, trueDecls] = findObjectDeclsByProperty(istate.state, object, node);
11231
+ if (trueDecls) {
11232
+ lookupDefs = (0,external_api_cjs_namespaceObject.lookupNext)(istate.state, [{ parent: null, results: trueDecls }], "decls", node.property);
11209
11233
  }
11210
11234
  }
11211
11235
  }
@@ -12009,45 +12033,115 @@ function printBlockState(block, state, indent = "") {
12009
12033
  console.log(`${indent} - ${typeStateEntry(value, key)}${value.equivSet ? " " + tsEquivs(state, key) : ""}`);
12010
12034
  });
12011
12035
  }
12012
- function filterDecls(decls, possible) {
12036
+ /*
12037
+ * We have an object, and a MemberExpression object.<name>
12038
+ * - decls are the StateNodes associated with the known type
12039
+ * of object.
12040
+ * - possible are all the StateNodes that declare <name>
12041
+ *
12042
+ * We want to find all the elements of possible which are
12043
+ * "compatible" with decls, which tells us the set of things
12044
+ * that object.<name> could correspond to, and also what that
12045
+ * tells us about object.
12046
+ *
12047
+ * The return value is two arrays of StateNode. The first
12048
+ * gives the refined type of object, and the second is the
12049
+ * array of StateNodes that could declare <name>
12050
+ */
12051
+ function filterDecls(decls, possible, name) {
12013
12052
  if (!possible)
12014
- return null;
12015
- return decls.reduce((cur, decl) => {
12053
+ return [null, null];
12054
+ const result = decls.reduce((cur, decl) => {
12016
12055
  const found = possible.reduce((flag, poss) => {
12017
12056
  if (decl === poss ||
12018
- (poss.type === "ClassDeclaration" &&
12019
- (0,external_api_cjs_namespaceObject.getSuperClasses)(poss)?.has(decl)) ||
12020
- (decl.type === "ClassDeclaration" && (0,external_api_cjs_namespaceObject.getSuperClasses)(decl)?.has(poss))) {
12021
- if (!cur)
12022
- cur = [poss];
12023
- else
12024
- cur.push(poss);
12057
+ (poss.type === "ClassDeclaration" && (0,external_api_cjs_namespaceObject.getSuperClasses)(poss)?.has(decl))) {
12058
+ // poss extends decl, so decl must actually be a poss
12059
+ // eg we know obj is an Object, and we call obj.toNumber
12060
+ // so possible includes all the classes that declare toNumber
12061
+ // so we can refine obj's type to the union of those types
12062
+ if (!cur[0]) {
12063
+ cur = [new Set(), new Set()];
12064
+ }
12065
+ cur[0].add(poss);
12066
+ cur[1].add(poss);
12067
+ return true;
12068
+ }
12069
+ else if (decl.type === "ClassDeclaration" &&
12070
+ (0,external_api_cjs_namespaceObject.getSuperClasses)(decl)?.has(poss)) {
12071
+ // decl extends poss, so decl remains unchanged
12072
+ // eg we know obj is Menu2, we call obj.toString
12073
+ // Menu2 doesn't define toString, but Object does
12074
+ // so poss is Object. But we still know that
12075
+ // obj is Menu2
12076
+ if (!cur[0]) {
12077
+ cur = [new Set(), new Set()];
12078
+ }
12079
+ cur[0].add(decl);
12080
+ cur[1].add(poss);
12025
12081
  return true;
12026
12082
  }
12027
12083
  return flag;
12028
12084
  }, false);
12029
12085
  if (!found) {
12030
- possible.some((poss) => {
12031
- if (decl.stack?.some((sn) => sn.decls === poss.decls)) {
12032
- if (!cur)
12033
- cur = [poss];
12034
- else
12035
- cur.push(poss);
12036
- return true;
12037
- }
12038
- return false;
12039
- });
12086
+ // If we didn't find the property in any of the
12087
+ // standard places, the runtime might still find
12088
+ // it by searching up the Module stack (and up
12089
+ // the module stack from any super classes)
12090
+ //
12091
+ // eg
12092
+ //
12093
+ // obj = Application.getApp();
12094
+ // obj.Properties.whatever
12095
+ //
12096
+ // Properties doesn't exist on AppBase, but AppBase
12097
+ // is declared in Application, and Application
12098
+ // does declare Properties. So Application.Properties
12099
+ // is (one of) the declarations we should find; but we
12100
+ // must not refine obj's type to include Application.
12101
+ let d = [decl];
12102
+ do {
12103
+ d.forEach((d) => {
12104
+ const stack = d.stack;
12105
+ possible.forEach((poss) => {
12106
+ for (let i = stack.length; i--;) {
12107
+ const sn = stack[i];
12108
+ if (sn.decls === poss.decls) {
12109
+ if (!cur[0]) {
12110
+ cur = [new Set(), new Set()];
12111
+ }
12112
+ cur[0].add(decl);
12113
+ cur[1].add(poss);
12114
+ break;
12115
+ }
12116
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(sn.decls, name)) {
12117
+ break;
12118
+ }
12119
+ }
12120
+ });
12121
+ });
12122
+ d = d.flatMap((d) => {
12123
+ if (d.type !== "ClassDeclaration" ||
12124
+ !d.superClass ||
12125
+ d.superClass === true) {
12126
+ return [];
12127
+ }
12128
+ return d.superClass;
12129
+ });
12130
+ } while (d.length);
12040
12131
  }
12041
12132
  return cur;
12042
- }, null);
12133
+ }, [null, null]);
12134
+ if (!result[0])
12135
+ return [null, null];
12136
+ return [Array.from(result[0]), Array.from(result[1])];
12043
12137
  }
12044
12138
  function findObjectDeclsByProperty(state, object, next) {
12045
12139
  const decls = getStateNodeDeclsFromType(state, object);
12046
12140
  if (!decls)
12047
- return null;
12141
+ return [null, null];
12048
12142
  const possibleDecls = (0,external_api_cjs_namespaceObject.hasProperty)(state.allDeclarations, next.property.name) &&
12049
12143
  state.allDeclarations[next.property.name];
12050
- return filterDecls(decls, possibleDecls);
12144
+ return filterDecls(decls, possibleDecls, next.property.name);
12051
12145
  }
12052
12146
  function refineObjectTypeByDecls(istate, object, trueDecls) {
12053
12147
  const refinedType = typeFromTypeStateNodes(istate.state, trueDecls);
@@ -12063,13 +12157,13 @@ function findNextObjectType(istate, trueDecls, next) {
12063
12157
  }, { type: 0 /* TypeTag.Never */ });
12064
12158
  }
12065
12159
  function resolveDottedMember(istate, object, next) {
12066
- const decls = findObjectDeclsByProperty(istate.state, object, next);
12067
- if (!decls)
12160
+ const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, object, next);
12161
+ if (!objDecls)
12068
12162
  return null;
12069
- const property = findNextObjectType(istate, decls, next);
12163
+ const property = findNextObjectType(istate, trueDecls, next);
12070
12164
  if (!property)
12071
12165
  return null;
12072
- const type = refineObjectTypeByDecls(istate, object, decls);
12166
+ const type = refineObjectTypeByDecls(istate, object, objDecls);
12073
12167
  const mayThrow = !subtypeOf(object, type);
12074
12168
  return { mayThrow, object: type, property };
12075
12169
  }
@@ -12106,11 +12200,11 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
12106
12200
  next = value.obj[me.property.name];
12107
12201
  }
12108
12202
  else {
12109
- const trueDecls = findObjectDeclsByProperty(istate.state, cur, me);
12110
- if (!trueDecls) {
12203
+ const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, cur, me);
12204
+ if (!objDecls) {
12111
12205
  return null;
12112
12206
  }
12113
- cur = refineObjectTypeByDecls(istate, cur, trueDecls);
12207
+ cur = refineObjectTypeByDecls(istate, cur, objDecls);
12114
12208
  next = findNextObjectType(istate, trueDecls, me);
12115
12209
  }
12116
12210
  }
@@ -15231,7 +15325,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
15231
15325
  // the oldest optimized file, we don't need to regenerate
15232
15326
  const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
15233
15327
  const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
15234
- if (source_time < opt_time && 1674613939459 < opt_time) {
15328
+ if (source_time < opt_time && 1674683508654 < opt_time) {
15235
15329
  return { hasTests, diagnostics: prevDiagnostics };
15236
15330
  }
15237
15331
  }
@@ -15258,7 +15352,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
15258
15352
  return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
15259
15353
  hasTests,
15260
15354
  diagnostics,
15261
- optimizerVersion: "1.1.4",
15355
+ optimizerVersion: "1.1.5",
15262
15356
  ...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
15263
15357
  }))
15264
15358
  .then(() => ({ hasTests, diagnostics }));
@@ -129,6 +129,7 @@ export interface VariableStateNode extends BaseStateNode {
129
129
  fullName: string;
130
130
  stack: ProgramStateStack;
131
131
  used?: true;
132
+ resolvedType?: ExactOrUnion | undefined;
132
133
  }
133
134
  export interface EnumStateNode extends BaseStateNode {
134
135
  type: "EnumDeclaration";
@@ -4,7 +4,7 @@ import { InterpState } from "./type-flow/interp";
4
4
  import { ExactOrUnion } from "./type-flow/types";
5
5
  export declare const missingNullWorkaround = true;
6
6
  export declare function buildTypeInfo(state: ProgramStateAnalysis, func: FunctionStateNode, optimizeEquivalencies: boolean): InterpState | undefined;
7
- export declare function findObjectDeclsByProperty(state: ProgramStateAnalysis, object: ExactOrUnion, next: mctree.DottedMemberExpression): StateNode[] | null;
7
+ export declare function findObjectDeclsByProperty(state: ProgramStateAnalysis, object: ExactOrUnion, next: mctree.DottedMemberExpression): [StateNode[], StateNode[]] | readonly [null, null];
8
8
  export declare function resolveDottedMember(istate: InterpState, object: ExactOrUnion, next: mctree.DottedMemberExpression): {
9
9
  mayThrow: boolean;
10
10
  object: ExactOrUnion;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@markw65/monkeyc-optimizer",
3
3
  "type": "module",
4
- "version": "1.1.4",
4
+ "version": "1.1.5",
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",