@markw65/monkeyc-optimizer 1.1.9 → 1.1.10

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/build/api.cjs CHANGED
@@ -1,4 +1,4 @@
1
- 0 && (module.exports = {checkCompilerVersion,collectNamespaces,createDocumentationMap,diagnostic,diagnosticHelper,findNamesInScope,findUsingForNode,formatAst,formatAstLongLines,getApiFunctionInfo,getApiMapping,getSuperClasses,hasProperty,isLocal,isLookupCandidate,isStateNode,lookupByFullName,lookupNext,lookupResultContains,lookupWithType,makeToyboxLink,mapVarDeclsByType,markInvokeClassMethod,parseSdkVersion,sameLookupResult,traverseAst,variableDeclarationName,visitReferences,visit_resources,visitorNode});
1
+ 0 && (module.exports = {checkCompilerVersion,collectNamespaces,createDocumentationMap,diagnostic,diagnosticHelper,findNamesInScope,findUsingForNode,formatAst,formatAstLongLines,getApiFunctionInfo,getApiMapping,getSuperClasses,hasProperty,isClassVariable,isLocal,isLookupCandidate,isStateNode,lookupByFullName,lookupNext,lookupResultContains,lookupWithType,makeToyboxLink,mapVarDeclsByType,markInvokeClassMethod,parseSdkVersion,sameLookupResult,traverseAst,variableDeclarationName,visitReferences,visit_resources,visitorNode});
2
2
  /******/ (() => { // webpackBootstrap
3
3
  /******/ var __webpack_modules__ = ({
4
4
 
@@ -1846,7 +1846,7 @@ function findCalleesByNode(state, callee) {
1846
1846
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
1847
1847
 
1848
1848
  "use strict";
1849
- /* unused harmony exports inlinableSubExpression, shouldInline, unused, inlineFunction, applyTypeIfNeeded */
1849
+ /* unused harmony exports inlinableSubExpression, shouldInline, unused, inlineDiagnostic, inlineFunction, applyTypeIfNeeded */
1850
1850
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6817);
1851
1851
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
1852
1852
  /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6652);
@@ -2725,10 +2725,12 @@ function fixNodeScope(state, lookupNode, nodeStack) {
2725
2725
  /* harmony import */ var _type_flow_interp__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(7161);
2726
2726
  /* harmony import */ var _type_flow_optimize__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(3687);
2727
2727
  /* harmony import */ var _type_flow_sub_type__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(9234);
2728
- /* harmony import */ var _unused_exprs__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(424);
2729
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(6906);
2730
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_15__);
2731
- /* harmony import */ var _variable_renamer__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(4405);
2728
+ /* harmony import */ var _type_flow_types__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(7255);
2729
+ /* harmony import */ var _unused_exprs__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(424);
2730
+ /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(6906);
2731
+ /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_16__);
2732
+ /* harmony import */ var _variable_renamer__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(4405);
2733
+
2732
2734
 
2733
2735
 
2734
2736
 
@@ -3180,7 +3182,12 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
3180
3182
  const result = optimizeCall(istate, call, node);
3181
3183
  if (result) {
3182
3184
  if (isExpression(result)) {
3183
- istate.stack[istate.stack.length - 1].node = result;
3185
+ const elem = istate.stack[istate.stack.length - 1];
3186
+ elem.node = result;
3187
+ if (result.type === "Literal") {
3188
+ elem.value = typeFromLiteral(result);
3189
+ elem.embeddedEffects = false;
3190
+ }
3184
3191
  }
3185
3192
  again = true;
3186
3193
  }
@@ -3270,7 +3277,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
3270
3277
  throw new Error(`While renaming ${declName} to ${name}: Didn't find original declaration`);
3271
3278
  }
3272
3279
  }
3273
- ident.name = name;
3280
+ renameIdentifier(ident, name);
3274
3281
  }
3275
3282
  else {
3276
3283
  map[declName] = true;
@@ -3330,7 +3337,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
3330
3337
  if (hasProperty(map, node.name)) {
3331
3338
  const name = map[node.name];
3332
3339
  if (typeof name === "string") {
3333
- node.name = name;
3340
+ renameIdentifier(node, name);
3334
3341
  }
3335
3342
  const [, results] = state.lookupValue(node);
3336
3343
  if (results) {
@@ -3365,7 +3372,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
3365
3372
  if (hasProperty(map, lhs.name)) {
3366
3373
  const name = map[lhs.name];
3367
3374
  if (typeof name === "string") {
3368
- lhs.name = name;
3375
+ renameIdentifier(lhs, name);
3369
3376
  }
3370
3377
  }
3371
3378
  }
@@ -3529,9 +3536,14 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
3529
3536
  }
3530
3537
  case "VariableDeclaration": {
3531
3538
  const locals = topLocals();
3532
- if (locals.map &&
3533
- locals.node &&
3534
- locals.node.type === "BlockStatement") {
3539
+ if (!locals.map) {
3540
+ if (again) {
3541
+ again = false;
3542
+ state.traverse(node);
3543
+ }
3544
+ break;
3545
+ }
3546
+ if (locals.node && locals.node.type === "BlockStatement") {
3535
3547
  let results;
3536
3548
  const declarations = node.declarations;
3537
3549
  let i = 0;
@@ -3799,6 +3811,7 @@ function optimizeCall(istate, node, context) {
3799
3811
  node.arguments.every((n) => getNodeValue(n)[0] !== null)) {
3800
3812
  const ret = evaluateFunction(istate, callee, node.arguments);
3801
3813
  if (ret) {
3814
+ inlineDiagnostic(state, callees[0], node, null);
3802
3815
  return withLoc(ret, node, node);
3803
3816
  }
3804
3817
  }
@@ -4302,11 +4315,12 @@ const LocalRefCost = 2;
4302
4315
  function refCost(node) {
4303
4316
  if (node.type === "Literal") {
4304
4317
  switch (typeof node.value) {
4318
+ case "bigint":
4319
+ return 9;
4305
4320
  case "string":
4306
4321
  return 5;
4307
- case "bigint":
4308
4322
  case "number":
4309
- return 5;
4323
+ return node.raw.match(/d/i) ? 9 : 5;
4310
4324
  case "boolean":
4311
4325
  return 2;
4312
4326
  default:
@@ -4802,26 +4816,30 @@ function applyReplacements(func, nodeMap, declMap) {
4802
4816
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4803
4817
 
4804
4818
  "use strict";
4805
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
4806
- /* harmony export */ "nK": () => (/* binding */ findObjectDeclsByProperty)
4807
- /* harmony export */ });
4808
- /* unused harmony exports missingNullWorkaround, buildTypeInfo, buildConflictGraph, resolveDottedMember */
4809
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6817);
4810
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
4811
- /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6652);
4812
- /* harmony import */ var _control_flow__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5101);
4813
- /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8180);
4814
- /* harmony import */ var _function_info__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(819);
4815
- /* harmony import */ var _type_flow_dead_store__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8486);
4816
- /* harmony import */ var _type_flow_interp__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7161);
4817
- /* harmony import */ var _type_flow_interp_call__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2222);
4818
- /* harmony import */ var _type_flow_intersection_type__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(6973);
4819
- /* harmony import */ var _type_flow_sub_type__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(9234);
4820
- /* harmony import */ var _type_flow_type_flow_util__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(1638);
4821
- /* harmony import */ var _type_flow_types__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(7255);
4822
- /* harmony import */ var _type_flow_union_type__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(757);
4823
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(6906);
4824
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_13__);
4819
+ /* unused harmony exports missingNullWorkaround, buildTypeInfo, buildConflictGraph */
4820
+ /* harmony import */ var node_assert__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4143);
4821
+ /* harmony import */ var node_assert__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(node_assert__WEBPACK_IMPORTED_MODULE_0__);
4822
+ /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6817);
4823
+ /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_1__);
4824
+ /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6652);
4825
+ /* harmony import */ var _control_flow__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5101);
4826
+ /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8180);
4827
+ /* harmony import */ var _function_info__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(819);
4828
+ /* harmony import */ var _optimizer_types__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(9697);
4829
+ /* harmony import */ var _type_flow_could_be__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(4055);
4830
+ /* harmony import */ var _type_flow_dead_store__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(8486);
4831
+ /* harmony import */ var _type_flow_interp__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(7161);
4832
+ /* harmony import */ var _type_flow_interp_call__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(2222);
4833
+ /* harmony import */ var _type_flow_intersection_type__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(6973);
4834
+ /* harmony import */ var _type_flow_sub_type__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(9234);
4835
+ /* harmony import */ var _type_flow_type_flow_util__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(1638);
4836
+ /* harmony import */ var _type_flow_types__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(7255);
4837
+ /* harmony import */ var _type_flow_union_type__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(757);
4838
+ /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(6906);
4839
+ /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_16__);
4840
+
4841
+
4842
+
4825
4843
 
4826
4844
 
4827
4845
 
@@ -4980,36 +4998,101 @@ function intersectEquiv(ts1, ts2, k) {
4980
4998
  } while (s !== k);
4981
4999
  return ret;
4982
5000
  }
4983
- function mergeTypeState(blockStates, blockVisits, index, from) {
5001
+ function clearAssocPaths(blockState, decl, v) {
5002
+ if (v.assocPaths?.size) {
5003
+ assert(blockState.trackedMemberDecls);
5004
+ v.assocPaths.forEach((assocPath) => {
5005
+ assocPath.split(".").forEach((pathItem) => {
5006
+ const tmd = blockState.trackedMemberDecls?.get(pathItem);
5007
+ if (tmd) {
5008
+ tmd.delete(decl);
5009
+ }
5010
+ });
5011
+ });
5012
+ }
5013
+ }
5014
+ function cloneTypeState(blockState) {
5015
+ const { map, trackedMemberDecls, ...rest } = blockState;
5016
+ const clone = { map: new Map(map), ...rest };
5017
+ if (trackedMemberDecls) {
5018
+ clone.trackedMemberDecls = new Map();
5019
+ trackedMemberDecls.forEach((value, key) => {
5020
+ clone.trackedMemberDecls.set(key, new Map(value));
5021
+ });
5022
+ }
5023
+ return clone;
5024
+ }
5025
+ function addTrackedMemberDecl(blockState, key, assocKey) {
5026
+ if (!blockState.trackedMemberDecls) {
5027
+ blockState.trackedMemberDecls = new Map();
5028
+ }
5029
+ assocKey.split(".").forEach((pathItem) => {
5030
+ const entries = blockState.trackedMemberDecls.get(pathItem);
5031
+ if (!entries) {
5032
+ blockState.trackedMemberDecls.set(pathItem, new Map([[key, new Set([assocKey])]]));
5033
+ return;
5034
+ }
5035
+ const entry = entries.get(key);
5036
+ if (!entry) {
5037
+ entries.set(key, new Set([assocKey]));
5038
+ return;
5039
+ }
5040
+ entry.add(assocKey);
5041
+ });
5042
+ }
5043
+ function mergeTypeState(blockStates, index, from) {
4984
5044
  const to = blockStates[index];
4985
5045
  if (!to) {
4986
- blockStates[index] = new Map(from);
4987
- blockVisits[index] = 1;
5046
+ blockStates[index] = cloneTypeState(from);
5047
+ blockStates[index].visits = 1;
4988
5048
  return true;
4989
5049
  }
4990
- const widen = ++blockVisits[index] > 10;
5050
+ const widen = ++to.visits > 10;
5051
+ // we'll rebuild this from scratch via
5052
+ // addTrackedMemberDecl below.
5053
+ delete to.trackedMemberDecls;
4991
5054
  let changes = false;
4992
- to.forEach((tov, k) => {
4993
- const fromv = from.get(k);
5055
+ to.map.forEach((tov, k) => {
5056
+ const fromv = from.map.get(k);
4994
5057
  if (!fromv) {
4995
5058
  changes = true;
4996
5059
  if (tov.equivSet) {
4997
- removeEquiv(to, k);
5060
+ removeEquiv(to.map, k);
4998
5061
  }
4999
- to.delete(k);
5062
+ to.map.delete(k);
5000
5063
  return;
5001
5064
  }
5002
5065
  if (tov.equivSet) {
5003
- if (intersectEquiv(to, from, k)) {
5066
+ if (intersectEquiv(to.map, from.map, k)) {
5004
5067
  changes = true;
5005
- tov = to.get(k);
5068
+ tov = to.map.get(k);
5006
5069
  }
5007
5070
  }
5071
+ if (tov.assocPaths) {
5072
+ const assocPaths = new Set(tov.assocPaths);
5073
+ tov = { ...tov };
5074
+ if (!fromv.assocPaths) {
5075
+ changes = true;
5076
+ delete tov.assocPaths;
5077
+ }
5078
+ else {
5079
+ assocPaths.forEach((key) => {
5080
+ if (!fromv.assocPaths.has(key)) {
5081
+ assocPaths.delete(key);
5082
+ }
5083
+ else {
5084
+ addTrackedMemberDecl(to, k, key);
5085
+ }
5086
+ });
5087
+ tov.assocPaths = assocPaths;
5088
+ }
5089
+ to.map.set(k, tov);
5090
+ }
5008
5091
  if (widen) {
5009
5092
  if (subtypeOf(fromv.curType, tov.curType))
5010
5093
  return;
5011
5094
  if (subtypeOf(tov.curType, fromv.curType)) {
5012
- to.set(k, { ...tov, curType: fromv.curType });
5095
+ to.map.set(k, { ...tov, curType: fromv.curType });
5013
5096
  changes = true;
5014
5097
  return;
5015
5098
  }
@@ -5022,7 +5105,7 @@ function mergeTypeState(blockStates, blockVisits, index, from) {
5022
5105
  if (wide)
5023
5106
  result = wide;
5024
5107
  }
5025
- to.set(k, { ...tov, curType: result });
5108
+ to.map.set(k, { ...tov, curType: result });
5026
5109
  changes = true;
5027
5110
  });
5028
5111
  return changes;
@@ -5049,149 +5132,91 @@ function printBlockState(block, state, indent = "") {
5049
5132
  console.log(indent + "Not visited!");
5050
5133
  return;
5051
5134
  }
5052
- state.forEach((value, key) => {
5053
- console.log(`${indent} - ${typeStateEntry(value, key)}${value.equivSet ? " " + tsEquivs(state, key) : ""}`);
5135
+ state.map.forEach((value, key) => {
5136
+ console.log(`${indent} - ${typeStateEntry(value, key)}${value.equivSet ? " " + tsEquivs(state.map, key) : ""}`);
5054
5137
  });
5055
5138
  }
5056
- /*
5057
- * We have an object, and a MemberExpression object.<name>
5058
- * - decls are the StateNodes associated with the known type
5059
- * of object.
5060
- * - possible are all the StateNodes that declare <name>
5061
- *
5062
- * We want to find all the elements of possible which are
5063
- * "compatible" with decls, which tells us the set of things
5064
- * that object.<name> could correspond to, and also what that
5065
- * tells us about object.
5066
- *
5067
- * The return value is two arrays of StateNode. The first
5068
- * gives the refined type of object, and the second is the
5069
- * array of StateNodes that could declare <name>
5070
- */
5071
- function filterDecls(decls, possible, name) {
5072
- if (!possible)
5073
- return [null, null];
5074
- const result = decls.reduce((cur, decl) => {
5075
- const found = possible.reduce((flag, poss) => {
5076
- if (decl === poss ||
5077
- (poss.type === "ClassDeclaration" && (0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(poss)?.has(decl))) {
5078
- // poss extends decl, so decl must actually be a poss
5079
- // eg we know obj is an Object, and we call obj.toNumber
5080
- // so possible includes all the classes that declare toNumber
5081
- // so we can refine obj's type to the union of those types
5082
- if (!cur[0]) {
5083
- cur = [new Set(), new Set()];
5084
- }
5085
- cur[0].add(poss);
5086
- cur[1].add(poss);
5087
- return true;
5139
+ function updateAffected(blockState, objectType, baseDecl, assignedPath, affectedName, affected, assignedType) {
5140
+ affected.forEach((paths, key) => {
5141
+ const entry = blockState.map.get(key);
5142
+ assert(entry);
5143
+ let newEntry = entry;
5144
+ paths.forEach((path) => {
5145
+ if (key === baseDecl && path === assignedPath) {
5146
+ return;
5088
5147
  }
5089
- else if (decl.type === "ClassDeclaration" &&
5090
- (0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(decl)?.has(poss)) {
5091
- // decl extends poss, so decl remains unchanged
5092
- // eg we know obj is Menu2, we call obj.toString
5093
- // Menu2 doesn't define toString, but Object does
5094
- // so poss is Object. But we still know that
5095
- // obj is Menu2
5096
- if (!cur[0]) {
5097
- cur = [new Set(), new Set()];
5148
+ assert(entry.assocPaths?.has(path));
5149
+ const assocPath = [];
5150
+ const pathSegments = path.split(".");
5151
+ let type = entry.curType;
5152
+ for (let i = 0; i < pathSegments.length; i++) {
5153
+ const pathItem = pathSegments[i];
5154
+ assocPath.push({
5155
+ name: pathItem === "*" ? null : pathItem,
5156
+ type,
5157
+ });
5158
+ if (pathItem === affectedName && couldBeShallow(type, objectType)) {
5159
+ const newAssocKey = assocPath.map((av) => av.name ?? "*").join(".");
5160
+ const baseType = updateByAssocPath(assocPath, assignedType, true);
5161
+ if (newEntry === entry) {
5162
+ newEntry = { ...entry };
5163
+ }
5164
+ newEntry.curType = baseType;
5165
+ if (path !== newAssocKey) {
5166
+ newEntry.assocPaths = new Set(entry.assocPaths);
5167
+ newEntry.assocPaths.delete(path);
5168
+ newEntry.assocPaths.add(newAssocKey);
5169
+ const newPaths = new Set(paths);
5170
+ newPaths.delete(path);
5171
+ newPaths.add(newAssocKey);
5172
+ affected.set(key, newPaths);
5173
+ }
5174
+ break;
5098
5175
  }
5099
- cur[0].add(decl);
5100
- cur[1].add(poss);
5101
- return true;
5102
- }
5103
- return flag;
5104
- }, false);
5105
- if (!found) {
5106
- // If we didn't find the property in any of the
5107
- // standard places, the runtime might still find
5108
- // it by searching up the Module stack (and up
5109
- // the module stack from any super classes)
5110
- //
5111
- // eg
5112
- //
5113
- // obj = Application.getApp();
5114
- // obj.Properties.whatever
5115
- //
5116
- // Properties doesn't exist on AppBase, but AppBase
5117
- // is declared in Application, and Application
5118
- // does declare Properties. So Application.Properties
5119
- // is (one of) the declarations we should find; but we
5120
- // must not refine obj's type to include Application.
5121
- let d = [decl];
5122
- do {
5123
- d.forEach((d) => {
5124
- const stack = d.stack;
5125
- possible.forEach((poss) => {
5126
- for (let i = stack.length; i--;) {
5127
- const sn = stack[i].sn;
5128
- if (sn.decls === poss.decls) {
5129
- if (!cur[0]) {
5130
- cur = [new Set(), new Set()];
5131
- }
5132
- cur[0].add(decl);
5133
- cur[1].add(poss);
5134
- break;
5135
- }
5136
- if ((0,_api__WEBPACK_IMPORTED_MODULE_0__.hasProperty)(sn.decls, name)) {
5137
- break;
5138
- }
5176
+ if (pathItem === "*") {
5177
+ const newType = { type: 0 /* TypeTag.Never */ };
5178
+ if (type.type & 512 /* TypeTag.Array */) {
5179
+ const atype = getUnionComponent(type, 512 /* TypeTag.Array */);
5180
+ if (atype) {
5181
+ unionInto(newType, atype);
5139
5182
  }
5140
- });
5141
- });
5142
- d = d.flatMap((d) => {
5143
- if (d.type !== "ClassDeclaration" ||
5144
- !d.superClass ||
5145
- d.superClass === true) {
5146
- return [];
5147
5183
  }
5148
- return d.superClass;
5149
- });
5150
- } while (d.length);
5184
+ if (type.type & 1024 /* TypeTag.Dictionary */) {
5185
+ const dtype = getUnionComponent(type, 1024 /* TypeTag.Dictionary */);
5186
+ if (dtype) {
5187
+ unionInto(newType, dtype.value);
5188
+ }
5189
+ }
5190
+ if (newType.type === 0 /* TypeTag.Never */)
5191
+ break;
5192
+ type = newType;
5193
+ }
5194
+ else {
5195
+ const objValue = getObjectValue(type);
5196
+ if (!objValue || !hasProperty(objValue.obj, pathItem)) {
5197
+ break;
5198
+ }
5199
+ type = objValue.obj[pathItem];
5200
+ }
5201
+ }
5202
+ });
5203
+ if (newEntry !== entry) {
5204
+ blockState.map.set(key, newEntry);
5151
5205
  }
5152
- return cur;
5153
- }, [null, null]);
5154
- if (!result[0])
5155
- return [null, null];
5156
- return [Array.from(result[0]), Array.from(result[1])];
5157
- }
5158
- function findObjectDeclsByProperty(state, object, next) {
5159
- const decls = (0,_type_flow_types__WEBPACK_IMPORTED_MODULE_11__/* .getStateNodeDeclsFromType */ .iX)(state, object);
5160
- if (!decls)
5161
- return [null, null];
5162
- const possibleDecls = (0,_api__WEBPACK_IMPORTED_MODULE_0__.hasProperty)(state.allDeclarations, next.property.name) &&
5163
- state.allDeclarations[next.property.name];
5164
- return filterDecls(decls, possibleDecls, next.property.name);
5165
- }
5166
- function refineObjectTypeByDecls(istate, object, trueDecls) {
5167
- const refinedType = typeFromTypeStateNodes(istate.state, trueDecls);
5168
- return intersection(object, refinedType);
5169
- }
5170
- function findNextObjectType(istate, trueDecls, next) {
5171
- const results = lookupNext(istate.state, [{ parent: null, results: trueDecls }], "decls", next.property);
5172
- if (!results)
5173
- return null;
5174
- return results.reduce((cur, lookupDefn) => {
5175
- unionInto(cur, typeFromTypeStateNodes(istate.state, lookupDefn.results));
5176
- return cur;
5177
- }, { type: 0 /* TypeTag.Never */ });
5178
- }
5179
- function resolveDottedMember(istate, object, next) {
5180
- const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, object, next);
5181
- if (!objDecls)
5182
- return null;
5183
- const property = findNextObjectType(istate, trueDecls, next);
5184
- if (!property)
5185
- return null;
5186
- const type = refineObjectTypeByDecls(istate, object, objDecls);
5187
- const mayThrow = !subtypeOf(object, type);
5188
- return { mayThrow, object: type, property };
5206
+ });
5189
5207
  }
5190
5208
  function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5191
5209
  // We want to traverse the blocks in reverse post order, in
5192
5210
  // order to propagate the "availability" of the types.
5193
5211
  const order = getPostOrder(graph).reverse();
5194
5212
  const queue = new DataflowQueue();
5213
+ let selfClassDecl = null;
5214
+ if (!(func.attributes & StateNodeAttributes.STATIC)) {
5215
+ const klass = func.stack?.[func.stack?.length - 1].sn;
5216
+ if (klass && klass.type === "ClassDeclaration") {
5217
+ selfClassDecl = klass;
5218
+ }
5219
+ }
5195
5220
  order.forEach((block, i) => {
5196
5221
  block.order = i;
5197
5222
  });
@@ -5205,7 +5230,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5205
5230
  function memberDeclInfo(blockState, decl, clearEquiv, newValue) {
5206
5231
  const baseType = getStateType(blockState, decl.base);
5207
5232
  const typePath = [baseType];
5208
- let next;
5233
+ let next = null;
5209
5234
  let updateAny = false;
5210
5235
  for (let i = 0, l = decl.path.length - 1; i <= l; i++) {
5211
5236
  let cur = typePath.pop();
@@ -5276,55 +5301,64 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5276
5301
  typePath.push(cur);
5277
5302
  typePath.push(next);
5278
5303
  }
5279
- for (let i = decl.path.length; i--;) {
5280
- const me = decl.path[i];
5281
- const property = typePath.pop();
5282
- let object = typePath.pop();
5283
- if (!me.computed) {
5284
- const value = getObjectValue(object);
5285
- if (value) {
5286
- if (value.obj && hasProperty(value.obj, me.property.name)) {
5287
- const prevProp = value.obj[me.property.name];
5288
- if (!subtypeOf(prevProp, property)) {
5289
- object = cloneType(object);
5290
- const newValue = { klass: value.klass, obj: { ...value.obj } };
5291
- newValue.obj[me.property.name] = intersection(prevProp, property);
5292
- setUnionComponent(object, 32768 /* TypeTag.Object */, newValue);
5304
+ const assocValue = decl.path.map((me, i) => ({
5305
+ name: me.computed ? null : me.property.name,
5306
+ type: typePath[i],
5307
+ }));
5308
+ const assocKey = assocValue.map((av) => av.name ?? "*").join(".");
5309
+ const newType = updateByAssocPath(assocValue, next, false);
5310
+ setStateEvent(blockState, decl.base, newType, false);
5311
+ // setStateEvent guarantees that tsv is "unshared" at this
5312
+ // point. So we can munge it directly.
5313
+ const tsv = blockState.map.get(decl.base);
5314
+ if (!tsv.assocPaths)
5315
+ tsv.assocPaths = new Set();
5316
+ tsv.assocPaths.add(assocKey);
5317
+ addTrackedMemberDecl(blockState, decl.base, assocKey);
5318
+ if (newValue) {
5319
+ const baseElem = assocValue[decl.path.length - 1];
5320
+ if (baseElem.name) {
5321
+ const affected = blockState.trackedMemberDecls?.get(baseElem.name);
5322
+ if (affected) {
5323
+ updateAffected(blockState, baseElem.type, decl.base, assocKey, baseElem.name, affected, next);
5324
+ }
5325
+ }
5326
+ if (selfClassDecl) {
5327
+ // Handle interference between the MemberDecl store
5328
+ // and the "self" object.
5329
+ const baseObj = getObjectValue(baseElem.type);
5330
+ if (baseObj &&
5331
+ baseObj.klass.type === 16384 /* TypeTag.Class */ &&
5332
+ some(baseObj.klass.value, (cls) => cls === selfClassDecl ||
5333
+ getSuperClasses(cls)?.has(selfClassDecl) ||
5334
+ getSuperClasses(selfClassDecl)?.has(cls) ||
5335
+ false)) {
5336
+ const last = decl.path[decl.path.length - 1];
5337
+ if (!last.computed) {
5338
+ const result = lookupNext(state, [{ parent: null, results: [selfClassDecl] }], "decls", last.property);
5339
+ if (result) {
5340
+ const decls = result.flatMap((lookupDef) => lookupDef.results);
5341
+ const doUpdate = (key, cur) => {
5342
+ const update = cloneType(cur.curType);
5343
+ unionInto(update, next);
5344
+ setStateEvent(blockState, key, update, false);
5345
+ };
5346
+ if (decls.length === 1) {
5347
+ const cur = blockState.map.get(decls[0]);
5348
+ cur && doUpdate(decls[0], cur);
5349
+ }
5350
+ else {
5351
+ blockState.map.forEach((cur, key) => {
5352
+ if (Array.isArray(key) && key[0] === decls[0]) {
5353
+ doUpdate(key, cur);
5354
+ }
5355
+ });
5356
+ }
5293
5357
  }
5294
5358
  }
5295
- else {
5296
- const obj = value.obj ? { ...value.obj } : {};
5297
- obj[me.property.name] = property;
5298
- object = cloneType(object);
5299
- setUnionComponent(object, 32768 /* TypeTag.Object */, {
5300
- klass: value.klass,
5301
- obj,
5302
- });
5303
- }
5304
5359
  }
5305
5360
  }
5306
- else {
5307
- if (object.type & 512 /* TypeTag.Array */) {
5308
- const avalue = getUnionComponent(object, 512 /* TypeTag.Array */);
5309
- if (!avalue || !subtypeOf(property, avalue)) {
5310
- object = cloneType(object);
5311
- setUnionComponent(object, 512 /* TypeTag.Array */, property);
5312
- }
5313
- }
5314
- if (object.type & 1024 /* TypeTag.Dictionary */) {
5315
- const dvalue = getUnionComponent(object, 1024 /* TypeTag.Dictionary */);
5316
- if (!dvalue || !subtypeOf(property, dvalue.value)) {
5317
- object = cloneType(object);
5318
- setUnionComponent(object, 1024 /* TypeTag.Dictionary */, {
5319
- key: dvalue?.key || { type: 524287 /* TypeTag.Any */ },
5320
- value: property,
5321
- });
5322
- }
5323
- }
5324
- }
5325
- typePath.push(object);
5326
5361
  }
5327
- setStateEvent(blockState, decl.base, typePath[0], false);
5328
5362
  return [next, updateAny];
5329
5363
  }
5330
5364
  function typeConstraint(decls) {
@@ -5344,29 +5378,35 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5344
5378
  function setStateEvent(blockState, decl, value, clearEquiv) {
5345
5379
  if (Array.isArray(decl) ||
5346
5380
  (decl.type !== "MemberDecl" && decl.type !== "Unknown")) {
5381
+ const v = { ...blockState.map.get(decl) };
5347
5382
  if (!clearEquiv) {
5348
5383
  /*
5349
5384
  * If we're not clearing the equivalencies then this update
5350
5385
  * must be applied to every element of the set
5351
5386
  */
5352
- const v = blockState.get(decl);
5353
- if (v?.equivSet) {
5387
+ if (v.equivSet) {
5354
5388
  let s = decl;
5355
5389
  do {
5356
- const next = blockState.get(s);
5390
+ const next = blockState.map.get(s);
5357
5391
  if (!next || !next.equivSet) {
5358
5392
  throw new Error(`Inconsistent equivSet for ${tsKey(decl)}: missing value for ${tsKey(s)}`);
5359
5393
  }
5360
- blockState.set(s, { ...next, curType: value });
5394
+ blockState.map.set(s, { ...next, curType: value });
5361
5395
  s = next.equivSet.next;
5362
5396
  } while (s !== decl);
5363
5397
  return;
5364
5398
  }
5365
5399
  }
5366
5400
  else {
5367
- removeEquiv(blockState, decl);
5401
+ removeEquiv(blockState.map, decl);
5402
+ delete v.equivSet;
5403
+ if (v.assocPaths?.size) {
5404
+ clearAssocPaths(blockState, decl, v);
5405
+ delete v.assocPaths;
5406
+ }
5368
5407
  }
5369
- blockState.set(decl, { curType: value });
5408
+ v.curType = value;
5409
+ blockState.map.set(decl, v);
5370
5410
  return;
5371
5411
  }
5372
5412
  if (decl.type === "Unknown") {
@@ -5380,10 +5420,10 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5380
5420
  function getStateEntry(blockState, decl) {
5381
5421
  if (Array.isArray(decl) ||
5382
5422
  (decl.type !== "MemberDecl" && decl.type !== "Unknown")) {
5383
- let tsVal = blockState.get(decl);
5423
+ let tsVal = blockState.map.get(decl);
5384
5424
  if (!tsVal) {
5385
5425
  tsVal = { curType: typeConstraint(decl) };
5386
- blockState.set(decl, tsVal);
5426
+ blockState.map.set(decl, tsVal);
5387
5427
  }
5388
5428
  return tsVal;
5389
5429
  }
@@ -5394,7 +5434,6 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5394
5434
  return { curType: info ? info[0] : { type: 524287 /* TypeTag.Any */ } };
5395
5435
  }
5396
5436
  const blockStates = [];
5397
- const blockVisits = [];
5398
5437
  const typeMap = new Map();
5399
5438
  const istate = {
5400
5439
  state,
@@ -5412,7 +5451,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5412
5451
  if (succ.order == null) {
5413
5452
  throw new Error("Unreachable block was visited");
5414
5453
  }
5415
- if (mergeTypeState(blockStates, blockVisits, succ.order, curState)) {
5454
+ if (mergeTypeState(blockStates, succ.order, curState)) {
5416
5455
  queue.enqueue(succ);
5417
5456
  }
5418
5457
  });
@@ -5447,7 +5486,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5447
5486
  return false;
5448
5487
  }
5449
5488
  }
5450
- const tmpState = new Map(curState);
5489
+ const tmpState = cloneTypeState(curState);
5451
5490
  setStateEvent(tmpState, leftDecl, leftr, false);
5452
5491
  if (rightDecl) {
5453
5492
  let rightr = restrictByEquality(left, right);
@@ -5473,7 +5512,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5473
5512
  singletonRemoved.type -= right.type;
5474
5513
  if (singletonRemoved.type === 0 /* TypeTag.Never */)
5475
5514
  return false;
5476
- const tmpState = new Map(curState);
5515
+ const tmpState = cloneTypeState(curState);
5477
5516
  setStateEvent(tmpState, leftDecl, singletonRemoved, false);
5478
5517
  return tmpState;
5479
5518
  }
@@ -5505,7 +5544,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5505
5544
  singletonRemoved.type &= ~(1 /* TypeTag.Null */ | 2 /* TypeTag.False */);
5506
5545
  if (singletonRemoved.type === 0 /* TypeTag.Never */)
5507
5546
  return false;
5508
- const tmpState = new Map(curState);
5547
+ const tmpState = cloneTypeState(curState);
5509
5548
  setStateEvent(tmpState, event.left, singletonRemoved, false);
5510
5549
  return tmpState;
5511
5550
  }
@@ -5520,7 +5559,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5520
5559
  });
5521
5560
  if (nonNullRemoved.type === 0 /* TypeTag.Never */)
5522
5561
  return false;
5523
- const tmpState = new Map(curState);
5562
+ const tmpState = cloneTypeState(curState);
5524
5563
  setStateEvent(tmpState, event.left, nonNullRemoved, false);
5525
5564
  return tmpState;
5526
5565
  }
@@ -5578,7 +5617,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5578
5617
  }
5579
5618
  }
5580
5619
  if (result) {
5581
- const tmpState = new Map(curState);
5620
+ const tmpState = cloneTypeState(curState);
5582
5621
  setStateEvent(tmpState, event.left, result, false);
5583
5622
  return tmpState;
5584
5623
  }
@@ -5606,7 +5645,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5606
5645
  console.log(` Flow (true): merge to ${trueSucc.order || -1}`);
5607
5646
  printBlockState(top, sTrue || curState, " >true ");
5608
5647
  }
5609
- if (mergeTypeState(blockStates, blockVisits, trueSucc.order, sTrue || curState)) {
5648
+ if (mergeTypeState(blockStates, trueSucc.order, sTrue || curState)) {
5610
5649
  queue.enqueue(trueSucc);
5611
5650
  }
5612
5651
  }
@@ -5618,7 +5657,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5618
5657
  console.log(` Flow (false): merge to: ${falseSucc.order || -1}`);
5619
5658
  printBlockState(top, sFalse || curState, " >false ");
5620
5659
  }
5621
- if (mergeTypeState(blockStates, blockVisits, falseSucc.order, sFalse || curState)) {
5660
+ if (mergeTypeState(blockStates, falseSucc.order, sFalse || curState)) {
5622
5661
  queue.enqueue(falseSucc);
5623
5662
  }
5624
5663
  }
@@ -5630,7 +5669,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5630
5669
  const selfAssignments = new Set();
5631
5670
  const processEvent = (top, curState, event, skipMerge) => {
5632
5671
  if (!skipMerge && event.mayThrow && top.exsucc) {
5633
- if (mergeTypeState(blockStates, blockVisits, top.exsucc.order, curState)) {
5672
+ if (mergeTypeState(blockStates, top.exsucc.order, curState)) {
5634
5673
  queue.enqueue(top.exsucc);
5635
5674
  }
5636
5675
  }
@@ -5638,9 +5677,12 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5638
5677
  case "kil": {
5639
5678
  const curEntry = getStateEntry(curState, event.decl);
5640
5679
  if (curEntry.equivSet) {
5641
- removeEquiv(curState, event.decl);
5680
+ removeEquiv(curState.map, event.decl);
5681
+ }
5682
+ if (curEntry.assocPaths) {
5683
+ clearAssocPaths(curState, event.decl, curEntry);
5642
5684
  }
5643
- curState.delete(event.decl);
5685
+ curState.map.delete(event.decl);
5644
5686
  break;
5645
5687
  }
5646
5688
  case "ref": {
@@ -5648,7 +5690,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5648
5690
  typeMap.set(event.node, curEntry.curType);
5649
5691
  nodeEquivs.delete(event.node);
5650
5692
  if (curEntry.equivSet) {
5651
- const equiv = Array.from(getEquivSet(curState, event.decl)).filter((decl) => decl !== event.decl && declIsLocal(decl));
5693
+ const equiv = Array.from(getEquivSet(curState.map, event.decl)).filter((decl) => decl !== event.decl && declIsLocal(decl));
5652
5694
  if (equiv.length) {
5653
5695
  nodeEquivs.set(event.node, {
5654
5696
  decl: event.decl,
@@ -5683,23 +5725,32 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5683
5725
  break;
5684
5726
  }
5685
5727
  }
5686
- curState.forEach((tsv, decl) => {
5728
+ curState.map.forEach((tsv, decl) => {
5687
5729
  let type = tsv.curType;
5688
- if (callees === undefined || modifiableDecl(decl, callees)) {
5730
+ if (!some(decl, (d) => d.type === "VariableDeclarator" &&
5731
+ (d.node.kind === "var" ||
5732
+ // even a "const" could have its "inner" type altered
5733
+ (type.value != null && (type.type & 32768 /* TypeTag.Object */) !== 0)))) {
5734
+ return;
5735
+ }
5736
+ if (modifiableDecl(decl, callees)) {
5689
5737
  if (tsv.equivSet) {
5690
- removeEquiv(curState, decl);
5738
+ removeEquiv(curState.map, decl);
5739
+ }
5740
+ if (tsv.assocPaths) {
5741
+ clearAssocPaths(curState, decl, tsv);
5691
5742
  }
5692
- curState.set(decl, { curType: typeConstraint(decl) });
5743
+ curState.map.set(decl, { curType: typeConstraint(decl) });
5693
5744
  }
5694
5745
  else if (type.value != null &&
5695
- !every(callees, (callee) => callee.info === false)) {
5746
+ (!callees || !every(callees, (callee) => callee.info === false))) {
5696
5747
  if (type.type & 32768 /* TypeTag.Object */) {
5697
5748
  const odata = getObjectValue(tsv.curType);
5698
5749
  if (odata?.obj) {
5699
5750
  type = cloneType(type);
5700
5751
  const newData = { klass: odata.klass };
5701
5752
  setUnionComponent(type, 32768 /* TypeTag.Object */, newData);
5702
- curState.set(decl, { ...tsv, curType: type });
5753
+ curState.map.set(decl, { ...tsv, curType: type });
5703
5754
  }
5704
5755
  }
5705
5756
  }
@@ -5724,23 +5775,43 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5724
5775
  const type = expr
5725
5776
  ? evaluate(istate, expr).value
5726
5777
  : { type: 524287 /* TypeTag.Any */ };
5727
- if (setStateEvent(curState, event.decl, type, true)) {
5728
- // we wrote through a computed member expression
5729
- // which might have been a Class, Module or Object.
5730
- // That could have affected anything...
5731
- curState.forEach((value, decls) => {
5778
+ const wasComputedDecl = setStateEvent(curState, event.decl, type, true);
5779
+ some(event.decl, (decl) => {
5780
+ if (decl.type !== "VariableDeclarator" ||
5781
+ decl.node.kind !== "var" ||
5782
+ !isClassVariable(decl)) {
5783
+ return false;
5784
+ }
5785
+ // A write to a class variable could interfere with
5786
+ // a MemberDecl
5787
+ const affected = curState.trackedMemberDecls?.get(decl.name);
5788
+ if (affected) {
5789
+ const objType = typeFromTypeStateNodes(istate.state, map(event.decl, (decl) => decl.type === "VariableDeclarator" &&
5790
+ decl.stack[decl.stack.length - 1].sn).filter((decl) => decl && decl.type === "ClassDeclaration"));
5791
+ updateAffected(curState, objType, event.decl, decl.name, decl.name, affected, type);
5792
+ }
5793
+ return true;
5794
+ });
5795
+ if (wasComputedDecl) {
5796
+ curState.map.forEach((value, decls) => {
5797
+ // we wrote through a computed member expression
5798
+ // which might have been a Class, Module or Object.
5799
+ // That could have affected any non-local...
5732
5800
  if (some(decls, (decl) => decl.type === "VariableDeclarator" &&
5733
5801
  decl.node.kind === "var" &&
5734
5802
  !isLocal(decl))) {
5735
5803
  if (value.equivSet) {
5736
- removeEquiv(curState, decls);
5804
+ removeEquiv(curState.map, decls);
5805
+ }
5806
+ if (value.assocPaths) {
5807
+ clearAssocPaths(curState, decls, value);
5737
5808
  }
5738
- curState.set(decls, { curType: typeConstraint(decls) });
5809
+ curState.map.set(decls, { curType: typeConstraint(decls) });
5739
5810
  }
5740
5811
  });
5741
5812
  }
5742
5813
  if (event.rhs) {
5743
- const selfAssign = addEquiv(curState, event.rhs, event.decl);
5814
+ const selfAssign = addEquiv(curState.map, event.rhs, event.decl);
5744
5815
  if (event.node.type === "AssignmentExpression") {
5745
5816
  if (selfAssign) {
5746
5817
  // rhs and lhs are identical
@@ -5759,7 +5830,8 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5759
5830
  }
5760
5831
  else {
5761
5832
  locals.forEach((local) => {
5762
- if (local !== event.decl && curState.has(local)) {
5833
+ if (local !== event.decl &&
5834
+ curState.map.has(local)) {
5763
5835
  localConflicts.add(local);
5764
5836
  }
5765
5837
  });
@@ -5780,7 +5852,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5780
5852
  }
5781
5853
  if (logThisRun) {
5782
5854
  console.log(` ${describeEvent(event)} : ${!Array.isArray(event.left) && event.left.type === "MemberDecl"
5783
- ? `${display(curState.get(event.left.base)?.curType || {
5855
+ ? `${display(curState.map.get(event.left.base)?.curType || {
5784
5856
  type: 524287 /* TypeTag.Any */,
5785
5857
  })} :: `
5786
5858
  : ""}${display(getStateType(curState, event.left))}`);
@@ -5792,7 +5864,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5792
5864
  }
5793
5865
  return false;
5794
5866
  };
5795
- blockStates[0] = new Map();
5867
+ blockStates[0] = { map: new Map(), visits: 0 };
5796
5868
  const head = blockStates[0];
5797
5869
  // set the parameters to their initial types
5798
5870
  func.node.params.forEach((param) => {
@@ -5808,7 +5880,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5808
5880
  }
5809
5881
  if (!blockStates[top.order])
5810
5882
  continue;
5811
- const curState = new Map(blockStates[top.order]);
5883
+ const curState = cloneTypeState(blockStates[top.order]);
5812
5884
  if (logThisRun) {
5813
5885
  printBlockHeader(top);
5814
5886
  printBlockState(top, curState);
@@ -5954,6 +6026,57 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5954
6026
  }
5955
6027
  return { istate, nodeEquivs };
5956
6028
  }
6029
+ function updateByAssocPath(path, property, union) {
6030
+ const valueToStore = (base) => {
6031
+ const clone = cloneType(base);
6032
+ unionInto(clone, property);
6033
+ return clone;
6034
+ };
6035
+ for (let i = path.length; i--;) {
6036
+ const pathElem = path[i];
6037
+ let object = pathElem.type;
6038
+ if (pathElem.name) {
6039
+ const value = getObjectValue(object);
6040
+ if (value) {
6041
+ const obj = value.obj ? { ...value.obj } : {};
6042
+ obj[pathElem.name] = union
6043
+ ? valueToStore(obj[pathElem.name] || { type: 524287 /* TypeTag.Any */ })
6044
+ : property;
6045
+ object = cloneType(object);
6046
+ setUnionComponent(object, 32768 /* TypeTag.Object */, {
6047
+ klass: value.klass,
6048
+ obj,
6049
+ });
6050
+ }
6051
+ }
6052
+ else {
6053
+ if (object.type & 512 /* TypeTag.Array */) {
6054
+ object = cloneType(object);
6055
+ setUnionComponent(object, 512 /* TypeTag.Array */, union
6056
+ ? valueToStore(getUnionComponent(object, 512 /* TypeTag.Array */) || {
6057
+ type: 524287 /* TypeTag.Any */,
6058
+ })
6059
+ : property);
6060
+ }
6061
+ if (object.type & 1024 /* TypeTag.Dictionary */) {
6062
+ const dvalue = getUnionComponent(object, 1024 /* TypeTag.Dictionary */);
6063
+ object = cloneType(object);
6064
+ setUnionComponent(object, 1024 /* TypeTag.Dictionary */, {
6065
+ key: dvalue?.key || { type: 524287 /* TypeTag.Any */ },
6066
+ value: union
6067
+ ? valueToStore(getUnionComponent(object, 1024 /* TypeTag.Dictionary */)?.value || {
6068
+ type: 524287 /* TypeTag.Any */,
6069
+ })
6070
+ : property,
6071
+ });
6072
+ }
6073
+ }
6074
+ path[i].type = object;
6075
+ property = object;
6076
+ union = false;
6077
+ }
6078
+ return property;
6079
+ }
5957
6080
 
5958
6081
 
5959
6082
  /***/ }),
@@ -5962,7 +6085,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5962
6085
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
5963
6086
 
5964
6087
  "use strict";
5965
- /* unused harmony exports couldBe, couldBeWeak */
6088
+ /* unused harmony exports couldBeHelper, couldBe, couldBeWeak, couldBeShallow */
5966
6089
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6817);
5967
6090
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
5968
6091
  /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8180);
@@ -5980,7 +6103,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5980
6103
  * This is symmetric, and a subtypeOf b, or b subtypeOf a implies
5981
6104
  * a couldBe b.
5982
6105
  */
5983
- function couldBe(a, b) {
6106
+ function couldBeHelper(a, b, shallow) {
5984
6107
  const common = a.type & b.type & ~262144 /* TypeTag.Typedef */;
5985
6108
  if (common) {
5986
6109
  if (a.value == null || b.value == null || a.value === b.value) {
@@ -6000,7 +6123,7 @@ function couldBe(a, b) {
6000
6123
  const bvalue = getUnionComponent(b, ac.type);
6001
6124
  if (bvalue == null ||
6002
6125
  ac.value === bvalue ||
6003
- couldBeValue({ type: ac.type, avalue: ac.value, bvalue })) {
6126
+ couldBeValue({ type: ac.type, avalue: ac.value, bvalue }, shallow)) {
6004
6127
  result = true;
6005
6128
  return false;
6006
6129
  }
@@ -6050,12 +6173,19 @@ function couldBe(a, b) {
6050
6173
  }
6051
6174
  return false;
6052
6175
  }
6176
+ function couldBe(a, b) {
6177
+ return couldBeHelper(a, b, false);
6178
+ }
6053
6179
  function couldBeWeak(a, b) {
6054
6180
  if (a.type === 0 /* TypeTag.Never */ || b.type === 0 /* TypeTag.Never */)
6055
6181
  return true;
6056
6182
  return couldBe(a, b);
6057
6183
  }
6058
- function couldBeValue(pair) {
6184
+ //
6185
+ function couldBeShallow(a, b) {
6186
+ return couldBeHelper(a, b, true);
6187
+ }
6188
+ function couldBeValue(pair, shallow) {
6059
6189
  switch (pair.type) {
6060
6190
  case 1 /* TypeTag.Null */:
6061
6191
  case 2 /* TypeTag.False */:
@@ -6071,10 +6201,11 @@ function couldBeValue(pair) {
6071
6201
  case 131072 /* TypeTag.Symbol */:
6072
6202
  return pair.avalue === pair.bvalue;
6073
6203
  case 512 /* TypeTag.Array */:
6074
- return couldBe(pair.avalue, pair.bvalue);
6204
+ return shallow || couldBe(pair.avalue, pair.bvalue);
6075
6205
  case 1024 /* TypeTag.Dictionary */: {
6076
- return (couldBe(pair.avalue.key, pair.bvalue.key) &&
6077
- couldBe(pair.avalue.value, pair.bvalue.value));
6206
+ return (shallow ||
6207
+ (couldBe(pair.avalue.key, pair.bvalue.key) &&
6208
+ couldBe(pair.avalue.value, pair.bvalue.value)));
6078
6209
  }
6079
6210
  case 2048 /* TypeTag.Method */: {
6080
6211
  return (pair.avalue.args.length === pair.bvalue.args.length &&
@@ -6100,7 +6231,7 @@ function couldBeValue(pair) {
6100
6231
  }
6101
6232
  case 32768 /* TypeTag.Object */: {
6102
6233
  return (couldBe(pair.avalue.klass, pair.bvalue.klass) &&
6103
- couldBeObj(pair.avalue.obj, pair.bvalue.obj));
6234
+ (shallow || couldBeObj(pair.avalue.obj, pair.bvalue.obj)));
6104
6235
  }
6105
6236
  case 65536 /* TypeTag.Enum */: {
6106
6237
  return (pair.avalue.enum === pair.bvalue.enum &&
@@ -6787,15 +6918,15 @@ function evaluateLogicalTypes(op, left, right) {
6787
6918
  "use strict";
6788
6919
  /* unused harmony exports evaluateCall, checkCallArgs, sysCallInfo */
6789
6920
  /* harmony import */ var _optimizer_types__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9697);
6790
- /* harmony import */ var _type_flow__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4859);
6791
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6817);
6792
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_2__);
6793
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6906);
6794
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_3__);
6795
- /* harmony import */ var _interp__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7161);
6796
- /* harmony import */ var _sub_type__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9234);
6797
- /* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7255);
6798
- /* harmony import */ var _union_type__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(757);
6921
+ /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6817);
6922
+ /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_1__);
6923
+ /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6906);
6924
+ /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_2__);
6925
+ /* harmony import */ var _interp__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7161);
6926
+ /* harmony import */ var _sub_type__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9234);
6927
+ /* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7255);
6928
+ /* harmony import */ var _union_type__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(757);
6929
+ /* harmony import */ var _type_flow_util__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(1638);
6799
6930
 
6800
6931
 
6801
6932
 
@@ -7270,11 +7401,11 @@ function getSystemCallTable() {
7270
7401
  /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6652);
7271
7402
  /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8180);
7272
7403
  /* harmony import */ var _optimizer_types__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9697);
7273
- /* harmony import */ var _type_flow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4859);
7274
- /* harmony import */ var _could_be__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(4055);
7275
- /* harmony import */ var _interp_binary__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(4706);
7276
- /* harmony import */ var _interp_call__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2222);
7277
- /* harmony import */ var _sub_type__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(9234);
7404
+ /* harmony import */ var _could_be__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4055);
7405
+ /* harmony import */ var _interp_binary__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(4706);
7406
+ /* harmony import */ var _interp_call__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(2222);
7407
+ /* harmony import */ var _sub_type__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(9234);
7408
+ /* harmony import */ var _type_flow_util__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(1638);
7278
7409
  /* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(7255);
7279
7410
  /* harmony import */ var _union_type__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(757);
7280
7411
 
@@ -8610,12 +8741,14 @@ function restrictByEquality(a, b) {
8610
8741
  /* unused harmony export minimizeLocals */
8611
8742
  /* harmony import */ var node_assert__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4143);
8612
8743
  /* harmony import */ var node_assert__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(node_assert__WEBPACK_IMPORTED_MODULE_0__);
8613
- /* harmony import */ var _control_flow__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5101);
8614
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6817);
8615
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_2__);
8616
- /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6652);
8744
+ /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6817);
8745
+ /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_1__);
8746
+ /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6652);
8747
+ /* harmony import */ var _control_flow__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5101);
8617
8748
  /* harmony import */ var _type_flow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4859);
8618
- /* harmony import */ var _type_flow_util__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1638);
8749
+ /* harmony import */ var _variable_renamer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(4405);
8750
+ /* harmony import */ var _type_flow_util__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1638);
8751
+
8619
8752
 
8620
8753
 
8621
8754
 
@@ -8763,8 +8896,7 @@ function minimizeLocals(state, func) {
8763
8896
  switch (node.type) {
8764
8897
  case "Identifier":
8765
8898
  if (info && info.name !== node.name) {
8766
- node.original = node.name;
8767
- node.name = info.name;
8899
+ renameIdentifier(node, info.name);
8768
8900
  }
8769
8901
  return null;
8770
8902
  case "AssignmentExpression":
@@ -8775,8 +8907,7 @@ function minimizeLocals(state, func) {
8775
8907
  return withLoc({ type: "Literal", value: null, raw: "null" }, node, node);
8776
8908
  }
8777
8909
  if (node.left.name !== info.name) {
8778
- node.left.original = node.left.name;
8779
- node.left.name = info.name;
8910
+ renameIdentifier(node.left, info.name);
8780
8911
  }
8781
8912
  return null;
8782
8913
  }
@@ -8790,8 +8921,7 @@ function minimizeLocals(state, func) {
8790
8921
  if (info) {
8791
8922
  assert(node.argument.type === "Identifier");
8792
8923
  if (node.argument.name !== info.name) {
8793
- node.argument.original = node.argument.name;
8794
- node.argument.name = info.name;
8924
+ renameIdentifier(node.argument, info.name);
8795
8925
  }
8796
8926
  return null;
8797
8927
  }
@@ -9679,12 +9809,23 @@ function subtypeOfObj(a, b) {
9679
9809
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
9680
9810
 
9681
9811
  "use strict";
9682
- /* unused harmony exports isTypeStateKey, declIsLocal, localDeclName, tsKey, sourceLocation, printBlockHeader, describeEvent, printBlockEvents, printBlockTrailer */
9812
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
9813
+ /* harmony export */ "nK": () => (/* binding */ findObjectDeclsByProperty)
9814
+ /* harmony export */ });
9815
+ /* unused harmony exports isTypeStateKey, declIsLocal, localDeclName, tsKey, sourceLocation, printBlockHeader, describeEvent, printBlockEvents, printBlockTrailer, refineObjectTypeByDecls, findNextObjectType, resolveDottedMember */
9683
9816
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6817);
9684
9817
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
9685
9818
  /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8180);
9686
9819
  /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6906);
9687
9820
  /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_2__);
9821
+ /* harmony import */ var _intersection_type__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6973);
9822
+ /* harmony import */ var _sub_type__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9234);
9823
+ /* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7255);
9824
+ /* harmony import */ var _union_type__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(757);
9825
+
9826
+
9827
+
9828
+
9688
9829
 
9689
9830
 
9690
9831
 
@@ -9761,6 +9902,140 @@ function printBlockTrailer(block) {
9761
9902
  .map((block) => block.order)
9762
9903
  .join(", ")} ExSucc: ${block.exsucc ? block.exsucc.order : ""}`);
9763
9904
  }
9905
+ /*
9906
+ * We have an object, and a MemberExpression object.<name>
9907
+ * - decls are the StateNodes associated with the known type
9908
+ * of object.
9909
+ * - possible are all the StateNodes that declare <name>
9910
+ *
9911
+ * We want to find all the elements of possible which are
9912
+ * "compatible" with decls, which tells us the set of things
9913
+ * that object.<name> could correspond to, and also what that
9914
+ * tells us about object.
9915
+ *
9916
+ * The return value is two arrays of StateNode. The first
9917
+ * gives the refined type of object, and the second is the
9918
+ * array of StateNodes that could declare <name>
9919
+ */
9920
+ function filterDecls(decls, possible, name) {
9921
+ if (!possible)
9922
+ return [null, null];
9923
+ const result = decls.reduce((cur, decl) => {
9924
+ const found = possible.reduce((flag, poss) => {
9925
+ if (decl === poss ||
9926
+ (poss.type === "ClassDeclaration" && (0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(poss)?.has(decl))) {
9927
+ // poss extends decl, so decl must actually be a poss
9928
+ // eg we know obj is an Object, and we call obj.toNumber
9929
+ // so possible includes all the classes that declare toNumber
9930
+ // so we can refine obj's type to the union of those types
9931
+ if (!cur[0]) {
9932
+ cur = [new Set(), new Set()];
9933
+ }
9934
+ cur[0].add(poss);
9935
+ cur[1].add(poss);
9936
+ return true;
9937
+ }
9938
+ else if (decl.type === "ClassDeclaration" &&
9939
+ (0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(decl)?.has(poss)) {
9940
+ // decl extends poss, so decl remains unchanged
9941
+ // eg we know obj is Menu2, we call obj.toString
9942
+ // Menu2 doesn't define toString, but Object does
9943
+ // so poss is Object. But we still know that
9944
+ // obj is Menu2
9945
+ if (!cur[0]) {
9946
+ cur = [new Set(), new Set()];
9947
+ }
9948
+ cur[0].add(decl);
9949
+ cur[1].add(poss);
9950
+ return true;
9951
+ }
9952
+ return flag;
9953
+ }, false);
9954
+ if (!found) {
9955
+ // If we didn't find the property in any of the
9956
+ // standard places, the runtime might still find
9957
+ // it by searching up the Module stack (and up
9958
+ // the module stack from any super classes)
9959
+ //
9960
+ // eg
9961
+ //
9962
+ // obj = Application.getApp();
9963
+ // obj.Properties.whatever
9964
+ //
9965
+ // Properties doesn't exist on AppBase, but AppBase
9966
+ // is declared in Application, and Application
9967
+ // does declare Properties. So Application.Properties
9968
+ // is (one of) the declarations we should find; but we
9969
+ // must not refine obj's type to include Application.
9970
+ let d = [decl];
9971
+ do {
9972
+ d.forEach((d) => {
9973
+ const stack = d.stack;
9974
+ possible.forEach((poss) => {
9975
+ for (let i = stack.length; i--;) {
9976
+ const sn = stack[i].sn;
9977
+ if (sn.decls === poss.decls) {
9978
+ if (!cur[0]) {
9979
+ cur = [new Set(), new Set()];
9980
+ }
9981
+ cur[0].add(decl);
9982
+ cur[1].add(poss);
9983
+ break;
9984
+ }
9985
+ if ((0,_api__WEBPACK_IMPORTED_MODULE_0__.hasProperty)(sn.decls, name)) {
9986
+ break;
9987
+ }
9988
+ }
9989
+ });
9990
+ });
9991
+ d = d.flatMap((d) => {
9992
+ if (d.type !== "ClassDeclaration" ||
9993
+ !d.superClass ||
9994
+ d.superClass === true) {
9995
+ return [];
9996
+ }
9997
+ return d.superClass;
9998
+ });
9999
+ } while (d.length);
10000
+ }
10001
+ return cur;
10002
+ }, [null, null]);
10003
+ if (!result[0])
10004
+ return [null, null];
10005
+ return [Array.from(result[0]), Array.from(result[1])];
10006
+ }
10007
+ function findObjectDeclsByProperty(state, object, next) {
10008
+ const decls = (0,_types__WEBPACK_IMPORTED_MODULE_5__/* .getStateNodeDeclsFromType */ .iX)(state, object);
10009
+ if (!decls)
10010
+ return [null, null];
10011
+ const possibleDecls = (0,_api__WEBPACK_IMPORTED_MODULE_0__.hasProperty)(state.allDeclarations, next.property.name) &&
10012
+ state.allDeclarations[next.property.name];
10013
+ return filterDecls(decls, possibleDecls, next.property.name);
10014
+ }
10015
+ function refineObjectTypeByDecls(istate, object, trueDecls) {
10016
+ const refinedType = typeFromTypeStateNodes(istate.state, trueDecls);
10017
+ return intersection(object, refinedType);
10018
+ }
10019
+ function findNextObjectType(istate, trueDecls, next) {
10020
+ const results = lookupNext(istate.state, [{ parent: null, results: trueDecls }], "decls", next.property);
10021
+ if (!results)
10022
+ return null;
10023
+ return results.reduce((cur, lookupDefn) => {
10024
+ unionInto(cur, typeFromTypeStateNodes(istate.state, lookupDefn.results));
10025
+ return cur;
10026
+ }, { type: 0 /* TypeTag.Never */ });
10027
+ }
10028
+ function resolveDottedMember(istate, object, next) {
10029
+ const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, object, next);
10030
+ if (!objDecls)
10031
+ return null;
10032
+ const property = findNextObjectType(istate, trueDecls, next);
10033
+ if (!property)
10034
+ return null;
10035
+ const type = refineObjectTypeByDecls(istate, object, objDecls);
10036
+ const mayThrow = !subtypeOf(object, type);
10037
+ return { mayThrow, object: type, property };
10038
+ }
9764
10039
 
9765
10040
 
9766
10041
  /***/ }),
@@ -11180,12 +11455,18 @@ function cleanupUnusedVars(state, node) {
11180
11455
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
11181
11456
 
11182
11457
  "use strict";
11183
- /* unused harmony export renameVariable */
11458
+ /* unused harmony exports renameIdentifier, renameVariable */
11184
11459
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6817);
11185
11460
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
11186
11461
  /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6652);
11187
11462
 
11188
11463
 
11464
+ function renameIdentifier(ident, newName) {
11465
+ if (!ident.original) {
11466
+ ident.original = ident.name;
11467
+ }
11468
+ ident.name = newName;
11469
+ }
11189
11470
  function renameVariable(state, locals, declName) {
11190
11471
  const map = locals.map;
11191
11472
  if (declName) {
@@ -11377,6 +11658,7 @@ __webpack_require__.d(__webpack_exports__, {
11377
11658
  "getApiMapping": () => (/* binding */ getApiMapping),
11378
11659
  "getSuperClasses": () => (/* binding */ getSuperClasses),
11379
11660
  "hasProperty": () => (/* reexport */ src_ast/* hasProperty */.l$),
11661
+ "isClassVariable": () => (/* binding */ isClassVariable),
11380
11662
  "isLocal": () => (/* binding */ isLocal),
11381
11663
  "isLookupCandidate": () => (/* binding */ isLookupCandidate),
11382
11664
  "isStateNode": () => (/* binding */ isStateNode),
@@ -11778,7 +12060,7 @@ function visit_resource_refs(state, doc, e) {
11778
12060
  function add_one_resource(state, doc, module, e) {
11779
12061
  let id;
11780
12062
  let func;
11781
- const varDecl = () => {
12063
+ const makeVarDecl = (id, outer) => {
11782
12064
  const loc = id && (0,src_ast/* adjustLoc */.b5)(id.value.loc);
11783
12065
  return (0,src_ast/* wrap */.re)({
11784
12066
  type: "VariableDeclaration",
@@ -11801,17 +12083,24 @@ function add_one_resource(state, doc, module, e) {
11801
12083
  },
11802
12084
  },
11803
12085
  init,
11804
- }, e.loc),
12086
+ }, outer),
11805
12087
  ],
11806
12088
  kind: "var",
11807
- }, e.loc);
12089
+ }, outer);
11808
12090
  };
12091
+ const varDecl = () => makeVarDecl(id, e.loc);
11809
12092
  const classDecl = (parent) => {
11810
12093
  if (!id)
11811
12094
  return null;
11812
12095
  const loc = id.value.loc;
11813
12096
  const items = init
11814
- ? [{ type: "ClassElement", item: varDecl(), loc: e.loc }]
12097
+ ? [
12098
+ {
12099
+ type: "ClassElement",
12100
+ item: makeVarDecl(undefined, init.loc),
12101
+ loc: e.loc,
12102
+ },
12103
+ ]
11815
12104
  : [];
11816
12105
  return {
11817
12106
  type: "ClassDeclaration",
@@ -11825,7 +12114,9 @@ function add_one_resource(state, doc, module, e) {
11825
12114
  if (!id)
11826
12115
  return null;
11827
12116
  const loc = id.value.loc;
11828
- const items = init ? [varDecl()] : [];
12117
+ const items = init
12118
+ ? [makeVarDecl(undefined, init.loc)]
12119
+ : [];
11829
12120
  return {
11830
12121
  type: "FunctionDeclaration",
11831
12122
  body: { type: "BlockStatement", body: items, loc: e.loc },
@@ -11917,8 +12208,10 @@ function add_one_resource(state, doc, module, e) {
11917
12208
  if (!func)
11918
12209
  return;
11919
12210
  const elements = visit_resource_refs(state, doc, e);
12211
+ const startLoc = elements[0]?.loc;
12212
+ const endLoc = elements[elements.length - 1]?.loc;
11920
12213
  const init = elements.length
11921
- ? { type: "ArrayExpression", elements }
12214
+ ? (0,src_ast/* wrap */.re)({ type: "ArrayExpression", elements }, startLoc && endLoc && (0,src_ast/* locRange */.ht)(startLoc, endLoc))
11922
12215
  : undefined;
11923
12216
  if (!id) {
11924
12217
  if (!init)
@@ -11930,8 +12223,8 @@ function add_one_resource(state, doc, module, e) {
11930
12223
  }
11931
12224
  }
11932
12225
 
11933
- // EXTERNAL MODULE: ./src/type-flow.ts
11934
- var type_flow = __webpack_require__(4859);
12226
+ // EXTERNAL MODULE: ./src/type-flow/type-flow-util.ts
12227
+ var type_flow_util = __webpack_require__(1638);
11935
12228
  // EXTERNAL MODULE: ./src/type-flow/types.ts
11936
12229
  var types = __webpack_require__(7255);
11937
12230
  // EXTERNAL MODULE: external "./util.cjs"
@@ -12564,7 +12857,7 @@ function lookupWithType(state, node, typeMap, nonLocal = false, stack = null) {
12564
12857
  const objectType = typeMap.get(node.object);
12565
12858
  if (!objectType)
12566
12859
  return results;
12567
- const [, decls] = (0,type_flow/* findObjectDeclsByProperty */.nK)(state, objectType, node);
12860
+ const [, decls] = (0,type_flow_util/* findObjectDeclsByProperty */.nK)(state, objectType, node);
12568
12861
  if (decls) {
12569
12862
  const next = lookupNext(state, [{ parent: null, results: decls }], "decls", node.property);
12570
12863
  if (next) {
@@ -13304,6 +13597,9 @@ function markInvokeClassMethod(state, func) {
13304
13597
  function isLocal(v) {
13305
13598
  return v.stack[v.stack.length - 1]?.sn.type === "BlockStatement";
13306
13599
  }
13600
+ function isClassVariable(v) {
13601
+ return v.stack[v.stack.length - 1]?.sn.type === "ClassDeclaration";
13602
+ }
13307
13603
  function diagnostic(state, node, message, type = "INFO", extra) {
13308
13604
  if (!state.diagnostics)
13309
13605
  state.diagnostics = {};