@markw65/monkeyc-optimizer 1.1.8 → 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
  }
@@ -3483,7 +3490,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
3483
3490
  break;
3484
3491
  case "BlockStatement":
3485
3492
  case "ForStatement":
3486
- if (locals.map && cleanupUnusedVars(state, node)) {
3493
+ if (locals.map && cleanupUnusedVars(state, node) && !state.inlining) {
3487
3494
  again = true;
3488
3495
  }
3489
3496
  break;
@@ -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
  }
@@ -3971,7 +3984,9 @@ function pragmaChecker(state, ast, diagnostics) {
3971
3984
  if (node.start && node.start >= (comment.end || Infinity)) {
3972
3985
  const { kind, quote, needle } = matchers.shift();
3973
3986
  if (kind === "match") {
3974
- const haystack = formatAst(node).replace(/([\r\n]|\s)+/g, " ");
3987
+ const haystack = formatAst(node)
3988
+ .replace(/([\r\n]|\s)+/g, " ")
3989
+ .replace(/\b\w+\s\/\*>(\w+)<\*\//g, "$1");
3975
3990
  if (!matcher(quote, needle, haystack)) {
3976
3991
  matcher(quote, needle, haystack);
3977
3992
  diagnostic(state, comment, `Didn't find '${needle}' in '${haystack}'`, "ERROR");
@@ -3989,7 +4004,7 @@ function pragmaChecker(state, ast, diagnostics) {
3989
4004
  }
3990
4005
  if (a.end.line > b.end.line)
3991
4006
  return 1;
3992
- if (a.end.line === b.end.line && a.end.column >= b.end.column) {
4007
+ if (a.end.line === b.end.line && a.end.column > b.end.column) {
3993
4008
  return 1;
3994
4009
  }
3995
4010
  return 0;
@@ -4044,8 +4059,10 @@ function pragmaChecker(state, ast, diagnostics) {
4044
4059
  /* harmony import */ var _control_flow__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5101);
4045
4060
  /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8180);
4046
4061
  /* harmony import */ var _function_info__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(819);
4047
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(6906);
4048
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_5__);
4062
+ /* harmony import */ var _type_flow_minimize_locals__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(736);
4063
+ /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(6906);
4064
+ /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_6__);
4065
+
4049
4066
 
4050
4067
 
4051
4068
 
@@ -4150,6 +4167,7 @@ function sizeBasedPRE(state, func) {
4150
4167
  applyReplacements(func.node, nodeMap, declMap);
4151
4168
  func.node.body.body.unshift(variableDecl);
4152
4169
  }
4170
+ minimizeLocals(state, func);
4153
4171
  }
4154
4172
  function buildPREGraph(state, func) {
4155
4173
  const result = buildDataFlowGraph(state, func, (literal) => refCost(literal) > LocalRefCost, true, false);
@@ -4297,11 +4315,12 @@ const LocalRefCost = 2;
4297
4315
  function refCost(node) {
4298
4316
  if (node.type === "Literal") {
4299
4317
  switch (typeof node.value) {
4318
+ case "bigint":
4319
+ return 9;
4300
4320
  case "string":
4301
4321
  return 5;
4302
- case "bigint":
4303
4322
  case "number":
4304
- return 5;
4323
+ return node.raw.match(/d/i) ? 9 : 5;
4305
4324
  case "boolean":
4306
4325
  return 2;
4307
4326
  default:
@@ -4797,26 +4816,30 @@ function applyReplacements(func, nodeMap, declMap) {
4797
4816
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4798
4817
 
4799
4818
  "use strict";
4800
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
4801
- /* harmony export */ "nK": () => (/* binding */ findObjectDeclsByProperty)
4802
- /* harmony export */ });
4803
- /* unused harmony exports missingNullWorkaround, buildTypeInfo, resolveDottedMember */
4804
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6817);
4805
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
4806
- /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6652);
4807
- /* harmony import */ var _control_flow__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5101);
4808
- /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8180);
4809
- /* harmony import */ var _function_info__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(819);
4810
- /* harmony import */ var _type_flow_dead_store__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8486);
4811
- /* harmony import */ var _type_flow_interp__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7161);
4812
- /* harmony import */ var _type_flow_interp_call__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2222);
4813
- /* harmony import */ var _type_flow_intersection_type__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(6973);
4814
- /* harmony import */ var _type_flow_sub_type__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(9234);
4815
- /* harmony import */ var _type_flow_type_flow_util__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(1638);
4816
- /* harmony import */ var _type_flow_types__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(7255);
4817
- /* harmony import */ var _type_flow_union_type__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(757);
4818
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(6906);
4819
- /* 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
+
4820
4843
 
4821
4844
 
4822
4845
 
@@ -4836,10 +4859,20 @@ const logging = true;
4836
4859
  // To avoid over zealous optimizations, we don't optimize
4837
4860
  // away any Null checks for now.
4838
4861
  const missingNullWorkaround = true;
4862
+ function loggingEnabledFor(env, func) {
4863
+ const pattern = process.env[env];
4864
+ if (!pattern)
4865
+ return false;
4866
+ const match = pattern.match(/^\/(.*)\/(i?)$/);
4867
+ if (match) {
4868
+ return new RegExp(match[1], match[2]).test(func.fullName);
4869
+ }
4870
+ return pattern === func.fullName;
4871
+ }
4839
4872
  function buildTypeInfo(state, func, optimizeEquivalencies) {
4840
4873
  if (!func.node.body || !func.stack)
4841
4874
  return;
4842
- const logThisRun = logging && process.env["TYPEFLOW_FUNC"] === func.fullName;
4875
+ const logThisRun = logging && loggingEnabledFor("TYPEFLOW_FUNC", func);
4843
4876
  while (true) {
4844
4877
  const { graph } = buildDataFlowGraph(state, func, () => false, false, true);
4845
4878
  if (optimizeEquivalencies &&
@@ -4850,9 +4883,18 @@ function buildTypeInfo(state, func, optimizeEquivalencies) {
4850
4883
  */
4851
4884
  continue;
4852
4885
  }
4853
- return propagateTypes({ ...state, stack: func.stack }, func, graph, optimizeEquivalencies, logThisRun);
4886
+ return propagateTypes({ ...state, stack: func.stack }, func, graph, optimizeEquivalencies, logThisRun).istate;
4854
4887
  }
4855
4888
  }
4889
+ function buildConflictGraph(state, func) {
4890
+ if (!func.node.body || !func.stack)
4891
+ return;
4892
+ const logThisRun = logging && loggingEnabledFor("CONFLICT_FUNC", func);
4893
+ const { graph, identifiers } = buildDataFlowGraph(state, func, () => false, false, true);
4894
+ const { nodeEquivs } = propagateTypes({ ...state, stack: func.stack }, func, graph, false, false);
4895
+ const { locals, localConflicts } = findDeadStores(func, graph, nodeEquivs, logThisRun);
4896
+ return { graph, localConflicts, locals, identifiers, logThisRun };
4897
+ }
4856
4898
  function addEquiv(ts, key, equiv) {
4857
4899
  if (key === equiv)
4858
4900
  return true;
@@ -4956,36 +4998,101 @@ function intersectEquiv(ts1, ts2, k) {
4956
4998
  } while (s !== k);
4957
4999
  return ret;
4958
5000
  }
4959
- 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) {
4960
5044
  const to = blockStates[index];
4961
5045
  if (!to) {
4962
- blockStates[index] = new Map(from);
4963
- blockVisits[index] = 1;
5046
+ blockStates[index] = cloneTypeState(from);
5047
+ blockStates[index].visits = 1;
4964
5048
  return true;
4965
5049
  }
4966
- 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;
4967
5054
  let changes = false;
4968
- to.forEach((tov, k) => {
4969
- const fromv = from.get(k);
5055
+ to.map.forEach((tov, k) => {
5056
+ const fromv = from.map.get(k);
4970
5057
  if (!fromv) {
4971
5058
  changes = true;
4972
5059
  if (tov.equivSet) {
4973
- removeEquiv(to, k);
5060
+ removeEquiv(to.map, k);
4974
5061
  }
4975
- to.delete(k);
5062
+ to.map.delete(k);
4976
5063
  return;
4977
5064
  }
4978
5065
  if (tov.equivSet) {
4979
- if (intersectEquiv(to, from, k)) {
5066
+ if (intersectEquiv(to.map, from.map, k)) {
4980
5067
  changes = true;
4981
- tov = to.get(k);
5068
+ tov = to.map.get(k);
4982
5069
  }
4983
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
+ }
4984
5091
  if (widen) {
4985
5092
  if (subtypeOf(fromv.curType, tov.curType))
4986
5093
  return;
4987
5094
  if (subtypeOf(tov.curType, fromv.curType)) {
4988
- to.set(k, { ...tov, curType: fromv.curType });
5095
+ to.map.set(k, { ...tov, curType: fromv.curType });
4989
5096
  changes = true;
4990
5097
  return;
4991
5098
  }
@@ -4998,7 +5105,7 @@ function mergeTypeState(blockStates, blockVisits, index, from) {
4998
5105
  if (wide)
4999
5106
  result = wide;
5000
5107
  }
5001
- to.set(k, { ...tov, curType: result });
5108
+ to.map.set(k, { ...tov, curType: result });
5002
5109
  changes = true;
5003
5110
  });
5004
5111
  return changes;
@@ -5025,149 +5132,91 @@ function printBlockState(block, state, indent = "") {
5025
5132
  console.log(indent + "Not visited!");
5026
5133
  return;
5027
5134
  }
5028
- state.forEach((value, key) => {
5029
- 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) : ""}`);
5030
5137
  });
5031
5138
  }
5032
- /*
5033
- * We have an object, and a MemberExpression object.<name>
5034
- * - decls are the StateNodes associated with the known type
5035
- * of object.
5036
- * - possible are all the StateNodes that declare <name>
5037
- *
5038
- * We want to find all the elements of possible which are
5039
- * "compatible" with decls, which tells us the set of things
5040
- * that object.<name> could correspond to, and also what that
5041
- * tells us about object.
5042
- *
5043
- * The return value is two arrays of StateNode. The first
5044
- * gives the refined type of object, and the second is the
5045
- * array of StateNodes that could declare <name>
5046
- */
5047
- function filterDecls(decls, possible, name) {
5048
- if (!possible)
5049
- return [null, null];
5050
- const result = decls.reduce((cur, decl) => {
5051
- const found = possible.reduce((flag, poss) => {
5052
- if (decl === poss ||
5053
- (poss.type === "ClassDeclaration" && (0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(poss)?.has(decl))) {
5054
- // poss extends decl, so decl must actually be a poss
5055
- // eg we know obj is an Object, and we call obj.toNumber
5056
- // so possible includes all the classes that declare toNumber
5057
- // so we can refine obj's type to the union of those types
5058
- if (!cur[0]) {
5059
- cur = [new Set(), new Set()];
5060
- }
5061
- cur[0].add(poss);
5062
- cur[1].add(poss);
5063
- 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;
5064
5147
  }
5065
- else if (decl.type === "ClassDeclaration" &&
5066
- (0,_api__WEBPACK_IMPORTED_MODULE_0__.getSuperClasses)(decl)?.has(poss)) {
5067
- // decl extends poss, so decl remains unchanged
5068
- // eg we know obj is Menu2, we call obj.toString
5069
- // Menu2 doesn't define toString, but Object does
5070
- // so poss is Object. But we still know that
5071
- // obj is Menu2
5072
- if (!cur[0]) {
5073
- 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;
5074
5175
  }
5075
- cur[0].add(decl);
5076
- cur[1].add(poss);
5077
- return true;
5078
- }
5079
- return flag;
5080
- }, false);
5081
- if (!found) {
5082
- // If we didn't find the property in any of the
5083
- // standard places, the runtime might still find
5084
- // it by searching up the Module stack (and up
5085
- // the module stack from any super classes)
5086
- //
5087
- // eg
5088
- //
5089
- // obj = Application.getApp();
5090
- // obj.Properties.whatever
5091
- //
5092
- // Properties doesn't exist on AppBase, but AppBase
5093
- // is declared in Application, and Application
5094
- // does declare Properties. So Application.Properties
5095
- // is (one of) the declarations we should find; but we
5096
- // must not refine obj's type to include Application.
5097
- let d = [decl];
5098
- do {
5099
- d.forEach((d) => {
5100
- const stack = d.stack;
5101
- possible.forEach((poss) => {
5102
- for (let i = stack.length; i--;) {
5103
- const sn = stack[i].sn;
5104
- if (sn.decls === poss.decls) {
5105
- if (!cur[0]) {
5106
- cur = [new Set(), new Set()];
5107
- }
5108
- cur[0].add(decl);
5109
- cur[1].add(poss);
5110
- break;
5111
- }
5112
- if ((0,_api__WEBPACK_IMPORTED_MODULE_0__.hasProperty)(sn.decls, name)) {
5113
- break;
5114
- }
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);
5115
5182
  }
5116
- });
5117
- });
5118
- d = d.flatMap((d) => {
5119
- if (d.type !== "ClassDeclaration" ||
5120
- !d.superClass ||
5121
- d.superClass === true) {
5122
- return [];
5123
5183
  }
5124
- return d.superClass;
5125
- });
5126
- } 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);
5127
5205
  }
5128
- return cur;
5129
- }, [null, null]);
5130
- if (!result[0])
5131
- return [null, null];
5132
- return [Array.from(result[0]), Array.from(result[1])];
5133
- }
5134
- function findObjectDeclsByProperty(state, object, next) {
5135
- const decls = (0,_type_flow_types__WEBPACK_IMPORTED_MODULE_11__/* .getStateNodeDeclsFromType */ .iX)(state, object);
5136
- if (!decls)
5137
- return [null, null];
5138
- const possibleDecls = (0,_api__WEBPACK_IMPORTED_MODULE_0__.hasProperty)(state.allDeclarations, next.property.name) &&
5139
- state.allDeclarations[next.property.name];
5140
- return filterDecls(decls, possibleDecls, next.property.name);
5141
- }
5142
- function refineObjectTypeByDecls(istate, object, trueDecls) {
5143
- const refinedType = typeFromTypeStateNodes(istate.state, trueDecls);
5144
- return intersection(object, refinedType);
5145
- }
5146
- function findNextObjectType(istate, trueDecls, next) {
5147
- const results = lookupNext(istate.state, [{ parent: null, results: trueDecls }], "decls", next.property);
5148
- if (!results)
5149
- return null;
5150
- return results.reduce((cur, lookupDefn) => {
5151
- unionInto(cur, typeFromTypeStateNodes(istate.state, lookupDefn.results));
5152
- return cur;
5153
- }, { type: 0 /* TypeTag.Never */ });
5154
- }
5155
- function resolveDottedMember(istate, object, next) {
5156
- const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, object, next);
5157
- if (!objDecls)
5158
- return null;
5159
- const property = findNextObjectType(istate, trueDecls, next);
5160
- if (!property)
5161
- return null;
5162
- const type = refineObjectTypeByDecls(istate, object, objDecls);
5163
- const mayThrow = !subtypeOf(object, type);
5164
- return { mayThrow, object: type, property };
5206
+ });
5165
5207
  }
5166
5208
  function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5167
5209
  // We want to traverse the blocks in reverse post order, in
5168
5210
  // order to propagate the "availability" of the types.
5169
5211
  const order = getPostOrder(graph).reverse();
5170
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
+ }
5171
5220
  order.forEach((block, i) => {
5172
5221
  block.order = i;
5173
5222
  });
@@ -5181,7 +5230,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5181
5230
  function memberDeclInfo(blockState, decl, clearEquiv, newValue) {
5182
5231
  const baseType = getStateType(blockState, decl.base);
5183
5232
  const typePath = [baseType];
5184
- let next;
5233
+ let next = null;
5185
5234
  let updateAny = false;
5186
5235
  for (let i = 0, l = decl.path.length - 1; i <= l; i++) {
5187
5236
  let cur = typePath.pop();
@@ -5252,55 +5301,64 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5252
5301
  typePath.push(cur);
5253
5302
  typePath.push(next);
5254
5303
  }
5255
- for (let i = decl.path.length; i--;) {
5256
- const me = decl.path[i];
5257
- const property = typePath.pop();
5258
- let object = typePath.pop();
5259
- if (!me.computed) {
5260
- const value = getObjectValue(object);
5261
- if (value) {
5262
- if (value.obj && hasProperty(value.obj, me.property.name)) {
5263
- const prevProp = value.obj[me.property.name];
5264
- if (!subtypeOf(prevProp, property)) {
5265
- object = cloneType(object);
5266
- const newValue = { klass: value.klass, obj: { ...value.obj } };
5267
- newValue.obj[me.property.name] = intersection(prevProp, property);
5268
- 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
+ }
5269
5357
  }
5270
5358
  }
5271
- else {
5272
- const obj = value.obj ? { ...value.obj } : {};
5273
- obj[me.property.name] = property;
5274
- object = cloneType(object);
5275
- setUnionComponent(object, 32768 /* TypeTag.Object */, {
5276
- klass: value.klass,
5277
- obj,
5278
- });
5279
- }
5280
5359
  }
5281
5360
  }
5282
- else {
5283
- if (object.type & 512 /* TypeTag.Array */) {
5284
- const avalue = getUnionComponent(object, 512 /* TypeTag.Array */);
5285
- if (!avalue || !subtypeOf(property, avalue)) {
5286
- object = cloneType(object);
5287
- setUnionComponent(object, 512 /* TypeTag.Array */, property);
5288
- }
5289
- }
5290
- if (object.type & 1024 /* TypeTag.Dictionary */) {
5291
- const dvalue = getUnionComponent(object, 1024 /* TypeTag.Dictionary */);
5292
- if (!dvalue || !subtypeOf(property, dvalue.value)) {
5293
- object = cloneType(object);
5294
- setUnionComponent(object, 1024 /* TypeTag.Dictionary */, {
5295
- key: dvalue?.key || { type: 524287 /* TypeTag.Any */ },
5296
- value: property,
5297
- });
5298
- }
5299
- }
5300
- }
5301
- typePath.push(object);
5302
5361
  }
5303
- setStateEvent(blockState, decl.base, typePath[0], false);
5304
5362
  return [next, updateAny];
5305
5363
  }
5306
5364
  function typeConstraint(decls) {
@@ -5320,29 +5378,35 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5320
5378
  function setStateEvent(blockState, decl, value, clearEquiv) {
5321
5379
  if (Array.isArray(decl) ||
5322
5380
  (decl.type !== "MemberDecl" && decl.type !== "Unknown")) {
5381
+ const v = { ...blockState.map.get(decl) };
5323
5382
  if (!clearEquiv) {
5324
5383
  /*
5325
5384
  * If we're not clearing the equivalencies then this update
5326
5385
  * must be applied to every element of the set
5327
5386
  */
5328
- const v = blockState.get(decl);
5329
- if (v?.equivSet) {
5387
+ if (v.equivSet) {
5330
5388
  let s = decl;
5331
5389
  do {
5332
- const next = blockState.get(s);
5390
+ const next = blockState.map.get(s);
5333
5391
  if (!next || !next.equivSet) {
5334
5392
  throw new Error(`Inconsistent equivSet for ${tsKey(decl)}: missing value for ${tsKey(s)}`);
5335
5393
  }
5336
- blockState.set(s, { ...next, curType: value });
5394
+ blockState.map.set(s, { ...next, curType: value });
5337
5395
  s = next.equivSet.next;
5338
5396
  } while (s !== decl);
5339
5397
  return;
5340
5398
  }
5341
5399
  }
5342
5400
  else {
5343
- 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
+ }
5344
5407
  }
5345
- blockState.set(decl, { curType: value });
5408
+ v.curType = value;
5409
+ blockState.map.set(decl, v);
5346
5410
  return;
5347
5411
  }
5348
5412
  if (decl.type === "Unknown") {
@@ -5356,10 +5420,10 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5356
5420
  function getStateEntry(blockState, decl) {
5357
5421
  if (Array.isArray(decl) ||
5358
5422
  (decl.type !== "MemberDecl" && decl.type !== "Unknown")) {
5359
- let tsVal = blockState.get(decl);
5423
+ let tsVal = blockState.map.get(decl);
5360
5424
  if (!tsVal) {
5361
5425
  tsVal = { curType: typeConstraint(decl) };
5362
- blockState.set(decl, tsVal);
5426
+ blockState.map.set(decl, tsVal);
5363
5427
  }
5364
5428
  return tsVal;
5365
5429
  }
@@ -5370,7 +5434,6 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5370
5434
  return { curType: info ? info[0] : { type: 524287 /* TypeTag.Any */ } };
5371
5435
  }
5372
5436
  const blockStates = [];
5373
- const blockVisits = [];
5374
5437
  const typeMap = new Map();
5375
5438
  const istate = {
5376
5439
  state,
@@ -5388,7 +5451,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5388
5451
  if (succ.order == null) {
5389
5452
  throw new Error("Unreachable block was visited");
5390
5453
  }
5391
- if (mergeTypeState(blockStates, blockVisits, succ.order, curState)) {
5454
+ if (mergeTypeState(blockStates, succ.order, curState)) {
5392
5455
  queue.enqueue(succ);
5393
5456
  }
5394
5457
  });
@@ -5423,7 +5486,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5423
5486
  return false;
5424
5487
  }
5425
5488
  }
5426
- const tmpState = new Map(curState);
5489
+ const tmpState = cloneTypeState(curState);
5427
5490
  setStateEvent(tmpState, leftDecl, leftr, false);
5428
5491
  if (rightDecl) {
5429
5492
  let rightr = restrictByEquality(left, right);
@@ -5449,7 +5512,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5449
5512
  singletonRemoved.type -= right.type;
5450
5513
  if (singletonRemoved.type === 0 /* TypeTag.Never */)
5451
5514
  return false;
5452
- const tmpState = new Map(curState);
5515
+ const tmpState = cloneTypeState(curState);
5453
5516
  setStateEvent(tmpState, leftDecl, singletonRemoved, false);
5454
5517
  return tmpState;
5455
5518
  }
@@ -5481,7 +5544,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5481
5544
  singletonRemoved.type &= ~(1 /* TypeTag.Null */ | 2 /* TypeTag.False */);
5482
5545
  if (singletonRemoved.type === 0 /* TypeTag.Never */)
5483
5546
  return false;
5484
- const tmpState = new Map(curState);
5547
+ const tmpState = cloneTypeState(curState);
5485
5548
  setStateEvent(tmpState, event.left, singletonRemoved, false);
5486
5549
  return tmpState;
5487
5550
  }
@@ -5496,7 +5559,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5496
5559
  });
5497
5560
  if (nonNullRemoved.type === 0 /* TypeTag.Never */)
5498
5561
  return false;
5499
- const tmpState = new Map(curState);
5562
+ const tmpState = cloneTypeState(curState);
5500
5563
  setStateEvent(tmpState, event.left, nonNullRemoved, false);
5501
5564
  return tmpState;
5502
5565
  }
@@ -5554,7 +5617,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5554
5617
  }
5555
5618
  }
5556
5619
  if (result) {
5557
- const tmpState = new Map(curState);
5620
+ const tmpState = cloneTypeState(curState);
5558
5621
  setStateEvent(tmpState, event.left, result, false);
5559
5622
  return tmpState;
5560
5623
  }
@@ -5582,7 +5645,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5582
5645
  console.log(` Flow (true): merge to ${trueSucc.order || -1}`);
5583
5646
  printBlockState(top, sTrue || curState, " >true ");
5584
5647
  }
5585
- if (mergeTypeState(blockStates, blockVisits, trueSucc.order, sTrue || curState)) {
5648
+ if (mergeTypeState(blockStates, trueSucc.order, sTrue || curState)) {
5586
5649
  queue.enqueue(trueSucc);
5587
5650
  }
5588
5651
  }
@@ -5594,7 +5657,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5594
5657
  console.log(` Flow (false): merge to: ${falseSucc.order || -1}`);
5595
5658
  printBlockState(top, sFalse || curState, " >false ");
5596
5659
  }
5597
- if (mergeTypeState(blockStates, blockVisits, falseSucc.order, sFalse || curState)) {
5660
+ if (mergeTypeState(blockStates, falseSucc.order, sFalse || curState)) {
5598
5661
  queue.enqueue(falseSucc);
5599
5662
  }
5600
5663
  }
@@ -5606,7 +5669,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5606
5669
  const selfAssignments = new Set();
5607
5670
  const processEvent = (top, curState, event, skipMerge) => {
5608
5671
  if (!skipMerge && event.mayThrow && top.exsucc) {
5609
- if (mergeTypeState(blockStates, blockVisits, top.exsucc.order, curState)) {
5672
+ if (mergeTypeState(blockStates, top.exsucc.order, curState)) {
5610
5673
  queue.enqueue(top.exsucc);
5611
5674
  }
5612
5675
  }
@@ -5614,9 +5677,12 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5614
5677
  case "kil": {
5615
5678
  const curEntry = getStateEntry(curState, event.decl);
5616
5679
  if (curEntry.equivSet) {
5617
- removeEquiv(curState, event.decl);
5680
+ removeEquiv(curState.map, event.decl);
5681
+ }
5682
+ if (curEntry.assocPaths) {
5683
+ clearAssocPaths(curState, event.decl, curEntry);
5618
5684
  }
5619
- curState.delete(event.decl);
5685
+ curState.map.delete(event.decl);
5620
5686
  break;
5621
5687
  }
5622
5688
  case "ref": {
@@ -5624,7 +5690,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5624
5690
  typeMap.set(event.node, curEntry.curType);
5625
5691
  nodeEquivs.delete(event.node);
5626
5692
  if (curEntry.equivSet) {
5627
- 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));
5628
5694
  if (equiv.length) {
5629
5695
  nodeEquivs.set(event.node, {
5630
5696
  decl: event.decl,
@@ -5659,23 +5725,32 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5659
5725
  break;
5660
5726
  }
5661
5727
  }
5662
- curState.forEach((tsv, decl) => {
5728
+ curState.map.forEach((tsv, decl) => {
5663
5729
  let type = tsv.curType;
5664
- 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)) {
5665
5737
  if (tsv.equivSet) {
5666
- removeEquiv(curState, decl);
5738
+ removeEquiv(curState.map, decl);
5739
+ }
5740
+ if (tsv.assocPaths) {
5741
+ clearAssocPaths(curState, decl, tsv);
5667
5742
  }
5668
- curState.set(decl, { curType: typeConstraint(decl) });
5743
+ curState.map.set(decl, { curType: typeConstraint(decl) });
5669
5744
  }
5670
5745
  else if (type.value != null &&
5671
- !every(callees, (callee) => callee.info === false)) {
5746
+ (!callees || !every(callees, (callee) => callee.info === false))) {
5672
5747
  if (type.type & 32768 /* TypeTag.Object */) {
5673
5748
  const odata = getObjectValue(tsv.curType);
5674
5749
  if (odata?.obj) {
5675
5750
  type = cloneType(type);
5676
5751
  const newData = { klass: odata.klass };
5677
5752
  setUnionComponent(type, 32768 /* TypeTag.Object */, newData);
5678
- curState.set(decl, { ...tsv, curType: type });
5753
+ curState.map.set(decl, { ...tsv, curType: type });
5679
5754
  }
5680
5755
  }
5681
5756
  }
@@ -5700,23 +5775,43 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5700
5775
  const type = expr
5701
5776
  ? evaluate(istate, expr).value
5702
5777
  : { type: 524287 /* TypeTag.Any */ };
5703
- if (setStateEvent(curState, event.decl, type, true)) {
5704
- // we wrote through a computed member expression
5705
- // which might have been a Class, Module or Object.
5706
- // That could have affected anything...
5707
- 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...
5708
5800
  if (some(decls, (decl) => decl.type === "VariableDeclarator" &&
5709
5801
  decl.node.kind === "var" &&
5710
5802
  !isLocal(decl))) {
5711
5803
  if (value.equivSet) {
5712
- removeEquiv(curState, decls);
5804
+ removeEquiv(curState.map, decls);
5805
+ }
5806
+ if (value.assocPaths) {
5807
+ clearAssocPaths(curState, decls, value);
5713
5808
  }
5714
- curState.set(decls, { curType: typeConstraint(decls) });
5809
+ curState.map.set(decls, { curType: typeConstraint(decls) });
5715
5810
  }
5716
5811
  });
5717
5812
  }
5718
5813
  if (event.rhs) {
5719
- const selfAssign = addEquiv(curState, event.rhs, event.decl);
5814
+ const selfAssign = addEquiv(curState.map, event.rhs, event.decl);
5720
5815
  if (event.node.type === "AssignmentExpression") {
5721
5816
  if (selfAssign) {
5722
5817
  // rhs and lhs are identical
@@ -5735,7 +5830,8 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5735
5830
  }
5736
5831
  else {
5737
5832
  locals.forEach((local) => {
5738
- if (local !== event.decl && curState.has(local)) {
5833
+ if (local !== event.decl &&
5834
+ curState.map.has(local)) {
5739
5835
  localConflicts.add(local);
5740
5836
  }
5741
5837
  });
@@ -5756,7 +5852,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5756
5852
  }
5757
5853
  if (logThisRun) {
5758
5854
  console.log(` ${describeEvent(event)} : ${!Array.isArray(event.left) && event.left.type === "MemberDecl"
5759
- ? `${display(curState.get(event.left.base)?.curType || {
5855
+ ? `${display(curState.map.get(event.left.base)?.curType || {
5760
5856
  type: 524287 /* TypeTag.Any */,
5761
5857
  })} :: `
5762
5858
  : ""}${display(getStateType(curState, event.left))}`);
@@ -5768,7 +5864,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5768
5864
  }
5769
5865
  return false;
5770
5866
  };
5771
- blockStates[0] = new Map();
5867
+ blockStates[0] = { map: new Map(), visits: 0 };
5772
5868
  const head = blockStates[0];
5773
5869
  // set the parameters to their initial types
5774
5870
  func.node.params.forEach((param) => {
@@ -5784,7 +5880,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5784
5880
  }
5785
5881
  if (!blockStates[top.order])
5786
5882
  continue;
5787
- const curState = new Map(blockStates[top.order]);
5883
+ const curState = cloneTypeState(blockStates[top.order]);
5788
5884
  if (logThisRun) {
5789
5885
  printBlockHeader(top);
5790
5886
  printBlockState(top, curState);
@@ -5828,7 +5924,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5828
5924
  }
5829
5925
  if (optimizeEquivalencies) {
5830
5926
  if (!nodeEquivs.size && !selfAssignments.size) {
5831
- return istate;
5927
+ return { istate, nodeEquivs };
5832
5928
  }
5833
5929
  if (logThisRun) {
5834
5930
  if (selfAssignments.size) {
@@ -5928,7 +6024,58 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5928
6024
  return replacement;
5929
6025
  });
5930
6026
  }
5931
- return istate;
6027
+ return { istate, nodeEquivs };
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;
5932
6079
  }
5933
6080
 
5934
6081
 
@@ -5938,7 +6085,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5938
6085
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
5939
6086
 
5940
6087
  "use strict";
5941
- /* unused harmony exports couldBe, couldBeWeak */
6088
+ /* unused harmony exports couldBeHelper, couldBe, couldBeWeak, couldBeShallow */
5942
6089
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6817);
5943
6090
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
5944
6091
  /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8180);
@@ -5956,7 +6103,7 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
5956
6103
  * This is symmetric, and a subtypeOf b, or b subtypeOf a implies
5957
6104
  * a couldBe b.
5958
6105
  */
5959
- function couldBe(a, b) {
6106
+ function couldBeHelper(a, b, shallow) {
5960
6107
  const common = a.type & b.type & ~262144 /* TypeTag.Typedef */;
5961
6108
  if (common) {
5962
6109
  if (a.value == null || b.value == null || a.value === b.value) {
@@ -5976,7 +6123,7 @@ function couldBe(a, b) {
5976
6123
  const bvalue = getUnionComponent(b, ac.type);
5977
6124
  if (bvalue == null ||
5978
6125
  ac.value === bvalue ||
5979
- couldBeValue({ type: ac.type, avalue: ac.value, bvalue })) {
6126
+ couldBeValue({ type: ac.type, avalue: ac.value, bvalue }, shallow)) {
5980
6127
  result = true;
5981
6128
  return false;
5982
6129
  }
@@ -6026,12 +6173,19 @@ function couldBe(a, b) {
6026
6173
  }
6027
6174
  return false;
6028
6175
  }
6176
+ function couldBe(a, b) {
6177
+ return couldBeHelper(a, b, false);
6178
+ }
6029
6179
  function couldBeWeak(a, b) {
6030
6180
  if (a.type === 0 /* TypeTag.Never */ || b.type === 0 /* TypeTag.Never */)
6031
6181
  return true;
6032
6182
  return couldBe(a, b);
6033
6183
  }
6034
- function couldBeValue(pair) {
6184
+ //
6185
+ function couldBeShallow(a, b) {
6186
+ return couldBeHelper(a, b, true);
6187
+ }
6188
+ function couldBeValue(pair, shallow) {
6035
6189
  switch (pair.type) {
6036
6190
  case 1 /* TypeTag.Null */:
6037
6191
  case 2 /* TypeTag.False */:
@@ -6047,10 +6201,11 @@ function couldBeValue(pair) {
6047
6201
  case 131072 /* TypeTag.Symbol */:
6048
6202
  return pair.avalue === pair.bvalue;
6049
6203
  case 512 /* TypeTag.Array */:
6050
- return couldBe(pair.avalue, pair.bvalue);
6204
+ return shallow || couldBe(pair.avalue, pair.bvalue);
6051
6205
  case 1024 /* TypeTag.Dictionary */: {
6052
- return (couldBe(pair.avalue.key, pair.bvalue.key) &&
6053
- 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)));
6054
6209
  }
6055
6210
  case 2048 /* TypeTag.Method */: {
6056
6211
  return (pair.avalue.args.length === pair.bvalue.args.length &&
@@ -6076,7 +6231,7 @@ function couldBeValue(pair) {
6076
6231
  }
6077
6232
  case 32768 /* TypeTag.Object */: {
6078
6233
  return (couldBe(pair.avalue.klass, pair.bvalue.klass) &&
6079
- couldBeObj(pair.avalue.obj, pair.bvalue.obj));
6234
+ (shallow || couldBeObj(pair.avalue.obj, pair.bvalue.obj)));
6080
6235
  }
6081
6236
  case 65536 /* TypeTag.Enum */: {
6082
6237
  return (pair.avalue.enum === pair.bvalue.enum &&
@@ -6106,12 +6261,12 @@ function couldBeObj(a, b) {
6106
6261
 
6107
6262
  "use strict";
6108
6263
  /* unused harmony exports findDeadStores, eliminateDeadStores */
6109
- /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6652);
6110
- /* harmony import */ var _inliner__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(333);
6111
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6817);
6112
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_2__);
6113
- /* harmony import */ var _control_flow__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5101);
6114
- /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8180);
6264
+ /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6817);
6265
+ /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
6266
+ /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6652);
6267
+ /* harmony import */ var _control_flow__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5101);
6268
+ /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8180);
6269
+ /* harmony import */ var _inliner__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(333);
6115
6270
  /* harmony import */ var _type_flow_util__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1638);
6116
6271
 
6117
6272
 
@@ -6119,12 +6274,13 @@ function couldBeObj(a, b) {
6119
6274
 
6120
6275
 
6121
6276
 
6122
- function findDeadStores(graph, logThisRun) {
6277
+ function findDeadStores(func, graph, nodeEquivs, logThisRun) {
6123
6278
  const order = getPostOrder(graph);
6124
6279
  order.forEach((block, i) => {
6125
6280
  block.order = i;
6126
6281
  });
6127
6282
  const blockStates = [];
6283
+ const nodeConflicts = nodeEquivs && new Map();
6128
6284
  const mergeStates = (to, from) => {
6129
6285
  return Array.from(to).reduce((changed, decl) => {
6130
6286
  if (!from.has(decl)) {
@@ -6135,11 +6291,13 @@ function findDeadStores(graph, logThisRun) {
6135
6291
  }, false);
6136
6292
  };
6137
6293
  const queue = new DataflowQueue();
6138
- const locals = new Set(order.flatMap((block) => block.events
6294
+ const locals = new Set(order
6295
+ .flatMap((block) => block.events
6139
6296
  ? block.events
6140
6297
  .filter((event) => event.type === "def" && declIsLocal(event.decl))
6141
6298
  .map((def) => def.decl)
6142
- : []));
6299
+ : [])
6300
+ .concat(func.node.params));
6143
6301
  const deadStores = new Set();
6144
6302
  order.forEach((block) => {
6145
6303
  if (!block.succs) {
@@ -6180,13 +6338,34 @@ function findDeadStores(graph, logThisRun) {
6180
6338
  }
6181
6339
  break;
6182
6340
  case "def":
6183
- if (isTypeStateKey(event.decl)) {
6341
+ if (isTypeStateKey(event.decl) &&
6342
+ (event.node.type !== "VariableDeclarator" || event.node.init)) {
6184
6343
  if (curState.has(event.decl)) {
6185
6344
  deadStores.add(event.node);
6186
6345
  }
6187
6346
  else {
6188
6347
  deadStores.delete(event.node);
6189
6348
  }
6349
+ if (nodeConflicts) {
6350
+ const conflicts = new Set(locals);
6351
+ curState.forEach((dead) => conflicts.delete(dead));
6352
+ if (event.rhs) {
6353
+ conflicts.delete(event.rhs);
6354
+ const equiv = event.node.type === "AssignmentExpression" &&
6355
+ event.node.operator === "="
6356
+ ? nodeEquivs.get(event.node.right)
6357
+ : event.node.type === "VariableDeclarator" &&
6358
+ event.node.init
6359
+ ? nodeEquivs.get(event.node.init)
6360
+ : null;
6361
+ if (equiv) {
6362
+ equiv.equiv.forEach((e) => isTypeStateKey(e) && conflicts.delete(e));
6363
+ isTypeStateKey(equiv.decl) && conflicts.delete(equiv.decl);
6364
+ }
6365
+ }
6366
+ conflicts.add(event.decl);
6367
+ nodeConflicts.set(event.node, conflicts);
6368
+ }
6190
6369
  if ((event.node.type === "AssignmentExpression" &&
6191
6370
  event.node.operator === "=") ||
6192
6371
  (event.node.type === "VariableDeclarator" && event.node.init)) {
@@ -6231,10 +6410,27 @@ function findDeadStores(graph, logThisRun) {
6231
6410
  doMerge(top.bogopred);
6232
6411
  }
6233
6412
  }
6234
- return deadStores;
6413
+ let localConflicts = null;
6414
+ if (nodeConflicts) {
6415
+ localConflicts = new Map();
6416
+ const addConflicts = (conflict, conflicts) => {
6417
+ let set = localConflicts.get(conflict);
6418
+ if (set) {
6419
+ conflicts.forEach((c) => c !== conflict && set.add(c));
6420
+ }
6421
+ else {
6422
+ set = new Set(conflicts);
6423
+ set.delete(conflict);
6424
+ localConflicts.set(conflict, set);
6425
+ }
6426
+ };
6427
+ nodeConflicts.forEach((conflicts) => conflicts.forEach((conflict) => addConflicts(conflict, conflicts)));
6428
+ func.node.params.forEach((param, index, arr) => addConflicts(param, arr));
6429
+ }
6430
+ return { deadStores, locals, localConflicts };
6235
6431
  }
6236
6432
  function eliminateDeadStores(state, func, graph, logThisRun) {
6237
- const deadStores = findDeadStores(graph, logThisRun);
6433
+ const { deadStores } = findDeadStores(func, graph, null, logThisRun);
6238
6434
  if (!deadStores.size)
6239
6435
  return false;
6240
6436
  if (logThisRun) {
@@ -6722,15 +6918,15 @@ function evaluateLogicalTypes(op, left, right) {
6722
6918
  "use strict";
6723
6919
  /* unused harmony exports evaluateCall, checkCallArgs, sysCallInfo */
6724
6920
  /* harmony import */ var _optimizer_types__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9697);
6725
- /* harmony import */ var _type_flow__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4859);
6726
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6817);
6727
- /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_2__);
6728
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6906);
6729
- /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_3__);
6730
- /* harmony import */ var _interp__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7161);
6731
- /* harmony import */ var _sub_type__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9234);
6732
- /* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7255);
6733
- /* 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);
6734
6930
 
6735
6931
 
6736
6932
 
@@ -7205,11 +7401,11 @@ function getSystemCallTable() {
7205
7401
  /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6652);
7206
7402
  /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8180);
7207
7403
  /* harmony import */ var _optimizer_types__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9697);
7208
- /* harmony import */ var _type_flow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4859);
7209
- /* harmony import */ var _could_be__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(4055);
7210
- /* harmony import */ var _interp_binary__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(4706);
7211
- /* harmony import */ var _interp_call__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(2222);
7212
- /* 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);
7213
7409
  /* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(7255);
7214
7410
  /* harmony import */ var _union_type__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(757);
7215
7411
 
@@ -8504,35 +8700,329 @@ function restrictByEqualityByComponent(a, b) {
8504
8700
  br = cloneType(brt);
8505
8701
  }
8506
8702
  else {
8507
- unionInto(br, brt);
8703
+ unionInto(br, brt);
8704
+ }
8705
+ }
8706
+ bits = next;
8707
+ } while (bits);
8708
+ if (!br) {
8709
+ return { type: 0 /* TypeTag.Never */ };
8710
+ }
8711
+ return br;
8712
+ }
8713
+ /*
8714
+ * Given that a == b, reutnr what we can deduce about b's
8715
+ * type.
8716
+ *
8717
+ * Note that this is similar to intersection. In many cases, it
8718
+ * is intersection. eg if a is the type (Null or "Hello" or Menu)
8719
+ * then we know b's type must be a subtype of intersection(a, b).
8720
+ *
8721
+ * But eg if it was a == 5, and a is known to be Char, String,
8722
+ * Number or Float, we can only eliminate String, because
8723
+ * 5.0 == 5, and 5.toChar() == 5.
8724
+ */
8725
+ function restrictByEquality(a, b) {
8726
+ if (a.type === 0 /* TypeTag.Never */)
8727
+ return a;
8728
+ if (isExact(a)) {
8729
+ return restrictExactTypesByEquality(a, b);
8730
+ }
8731
+ return restrictByEqualityByComponent(a, b);
8732
+ }
8733
+
8734
+
8735
+ /***/ }),
8736
+
8737
+ /***/ 736:
8738
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8739
+
8740
+ "use strict";
8741
+ /* unused harmony export minimizeLocals */
8742
+ /* harmony import */ var node_assert__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4143);
8743
+ /* harmony import */ var node_assert__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(node_assert__WEBPACK_IMPORTED_MODULE_0__);
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);
8748
+ /* harmony import */ var _type_flow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4859);
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
+
8752
+
8753
+
8754
+
8755
+
8756
+
8757
+
8758
+ function minimizeLocals(state, func) {
8759
+ const result = buildConflictGraph(state, func);
8760
+ if (!result)
8761
+ return;
8762
+ const { graph, localConflicts, locals: localSet, identifiers, logThisRun, } = result;
8763
+ if (!localConflicts)
8764
+ return;
8765
+ const colors = new Map();
8766
+ const locals = Array.from(localSet)
8767
+ .sort((a, b) => (localConflicts.get(a)?.size ?? 0) - (localConflicts.get(b)?.size ?? 0))
8768
+ .filter((key) => key.type === "VariableDeclarator" ||
8769
+ key.type === "Identifier" ||
8770
+ key.type === "BinaryExpression");
8771
+ const merge = [];
8772
+ locals.forEach((local) => {
8773
+ let inUse = 0n;
8774
+ localConflicts.get(local)?.forEach((conflict) => {
8775
+ const color = colors.get(conflict);
8776
+ if (color != null) {
8777
+ inUse |= 1n << BigInt(color);
8778
+ }
8779
+ });
8780
+ let lowest = 0;
8781
+ while (inUse & 1n) {
8782
+ lowest++;
8783
+ inUse >>= 1n;
8784
+ }
8785
+ colors.set(local, lowest);
8786
+ if (!merge[lowest]) {
8787
+ merge[lowest] = [local];
8788
+ }
8789
+ else {
8790
+ merge[lowest].push(local);
8791
+ }
8792
+ });
8793
+ const didMerge = merge.some((merged) => merged.length > 1);
8794
+ if (didMerge !== (merge.length !== locals.length)) {
8795
+ throw new Error("WTF?");
8796
+ }
8797
+ if (!didMerge)
8798
+ return;
8799
+ if (logThisRun) {
8800
+ console.log(`>>> Merging locals in ${func.fullName}`);
8801
+ merge.forEach((merged) => merged.length > 1 &&
8802
+ console.log(` - merging ${merged.map((k) => tsKey(k)).join(" | ")}`));
8803
+ }
8804
+ const remap = new Map();
8805
+ merge.forEach((merged) => {
8806
+ if (merged.length === 1)
8807
+ return;
8808
+ const info = merged.reduce((cur, decl) => {
8809
+ if (decl.type === "Identifier" || decl.type === "BinaryExpression") {
8810
+ return {
8811
+ decl,
8812
+ stack: func.stack,
8813
+ depth: func.stack.length,
8814
+ name: variableDeclarationName(decl),
8815
+ };
8816
+ }
8817
+ if (cur === null) {
8818
+ return {
8819
+ decl,
8820
+ stack: decl.stack,
8821
+ depth: decl.stack.length,
8822
+ name: decl.name,
8823
+ };
8824
+ }
8825
+ let depth = cur.depth < decl.stack.length ? cur.depth : decl.stack.length;
8826
+ while (true) {
8827
+ if (cur.stack[depth - 1].sn === decl.stack[depth - 1].sn) {
8828
+ break;
8829
+ }
8830
+ depth--;
8831
+ }
8832
+ if (cur.stack.length > decl.stack.length) {
8833
+ return { decl, stack: decl.stack, depth, name: decl.name };
8834
+ }
8835
+ cur.depth = depth;
8836
+ return cur;
8837
+ }, null);
8838
+ assert(info);
8839
+ merged.forEach((decl) => remap.set(decl, info));
8840
+ if (info.decl.type === "VariableDeclarator") {
8841
+ let name = info.name;
8842
+ if (locals.some((local) => local !== info.decl &&
8843
+ local.type === "VariableDeclarator" &&
8844
+ local.name === name)) {
8845
+ // There's a variable in another scope with the same name, so
8846
+ // produce a new one.
8847
+ let i = 0;
8848
+ do {
8849
+ name = `${info.decl.name}_${i++}`;
8850
+ } while (identifiers.has(name));
8851
+ identifiers.add(name);
8852
+ info.name = name;
8853
+ }
8854
+ let depth = info.depth - 1;
8855
+ let sn = info.stack[depth].sn;
8856
+ while (true) {
8857
+ assert(sn.type === "BlockStatement");
8858
+ if (sn.node.type !== "ForStatement") {
8859
+ break;
8860
+ }
8861
+ sn = info.stack[--depth].sn;
8862
+ }
8863
+ const varDecl = {
8864
+ type: "VariableDeclarator",
8865
+ kind: "var",
8866
+ id: { type: "Identifier", name },
8867
+ };
8868
+ if (sn.node.body.length &&
8869
+ sn.node.body[0].type === "VariableDeclaration") {
8870
+ sn.node.body[0].declarations.unshift(withLocDeep(varDecl, sn.node.body[0], false, true));
8871
+ }
8872
+ else {
8873
+ sn.node.body.unshift(withLocDeep({
8874
+ type: "VariableDeclaration",
8875
+ declarations: [varDecl],
8876
+ kind: "var",
8877
+ }, sn.node, false, true));
8508
8878
  }
8509
8879
  }
8510
- bits = next;
8511
- } while (bits);
8512
- if (!br) {
8513
- return { type: 0 /* TypeTag.Never */ };
8514
- }
8515
- return br;
8516
- }
8517
- /*
8518
- * Given that a == b, reutnr what we can deduce about b's
8519
- * type.
8520
- *
8521
- * Note that this is similar to intersection. In many cases, it
8522
- * is intersection. eg if a is the type (Null or "Hello" or Menu)
8523
- * then we know b's type must be a subtype of intersection(a, b).
8524
- *
8525
- * But eg if it was a == 5, and a is known to be Char, String,
8526
- * Number or Float, we can only eliminate String, because
8527
- * 5.0 == 5, and 5.toChar() == 5.
8528
- */
8529
- function restrictByEquality(a, b) {
8530
- if (a.type === 0 /* TypeTag.Never */)
8531
- return a;
8532
- if (isExact(a)) {
8533
- return restrictExactTypesByEquality(a, b);
8534
- }
8535
- return restrictByEqualityByComponent(a, b);
8880
+ });
8881
+ const order = getPostOrder(graph);
8882
+ const nodeMap = new Map();
8883
+ order.forEach((block) => block.events?.forEach((event) => {
8884
+ if ((event.type !== "ref" && event.type !== "def") ||
8885
+ !isTypeStateKey(event.decl) ||
8886
+ !localSet.has(event.decl)) {
8887
+ return;
8888
+ }
8889
+ const rep = remap.get(event.decl);
8890
+ if (!rep)
8891
+ return;
8892
+ nodeMap.set(event.node, rep);
8893
+ }));
8894
+ traverseAst(func.node.body, null, (node) => {
8895
+ const info = nodeMap.get(node);
8896
+ switch (node.type) {
8897
+ case "Identifier":
8898
+ if (info && info.name !== node.name) {
8899
+ renameIdentifier(node, info.name);
8900
+ }
8901
+ return null;
8902
+ case "AssignmentExpression":
8903
+ if (info) {
8904
+ assert(node.left.type === "Identifier");
8905
+ if (node.right.type === "Identifier" &&
8906
+ node.right.name === info.name) {
8907
+ return withLoc({ type: "Literal", value: null, raw: "null" }, node, node);
8908
+ }
8909
+ if (node.left.name !== info.name) {
8910
+ renameIdentifier(node.left, info.name);
8911
+ }
8912
+ return null;
8913
+ }
8914
+ break;
8915
+ case "ExpressionStatement":
8916
+ if (node.expression.type === "Literal") {
8917
+ return false;
8918
+ }
8919
+ break;
8920
+ case "UpdateExpression":
8921
+ if (info) {
8922
+ assert(node.argument.type === "Identifier");
8923
+ if (node.argument.name !== info.name) {
8924
+ renameIdentifier(node.argument, info.name);
8925
+ }
8926
+ return null;
8927
+ }
8928
+ break;
8929
+ case "VariableDeclarator":
8930
+ if (info) {
8931
+ if (!node.init) {
8932
+ return false; // delete this entry
8933
+ }
8934
+ if (node.init.type === "Identifier" && node.init.name === info.name) {
8935
+ // this would create a self assignment, so just drop it
8936
+ return false;
8937
+ }
8938
+ // VariableDeclarations aren't allowed to have
8939
+ // AssignmentExpressions in them, but we'll fix that
8940
+ // below
8941
+ return withLoc({
8942
+ type: "AssignmentExpression",
8943
+ operator: "=",
8944
+ left: withLoc({
8945
+ type: "Identifier",
8946
+ name: info.name,
8947
+ original: variableDeclarationName(node.id),
8948
+ }, node.id, node.id),
8949
+ right: node.init,
8950
+ }, node, node);
8951
+ }
8952
+ break;
8953
+ case "VariableDeclaration":
8954
+ if (node.declarations.some((decl) => decl.type !== "VariableDeclarator")) {
8955
+ const results = [];
8956
+ node.declarations.forEach((decl) => {
8957
+ if (isExpression(decl)) {
8958
+ results.push(withLoc({ type: "ExpressionStatement", expression: decl }, decl, decl));
8959
+ }
8960
+ else if (decl.init) {
8961
+ results.push(withLoc({
8962
+ type: "ExpressionStatement",
8963
+ expression: withLoc({
8964
+ type: "AssignmentExpression",
8965
+ operator: "=",
8966
+ left: withLoc({
8967
+ type: "Identifier",
8968
+ name: variableDeclarationName(decl.id),
8969
+ }, decl.id, decl.id),
8970
+ right: decl.init,
8971
+ }, decl, decl),
8972
+ }, decl, decl));
8973
+ }
8974
+ });
8975
+ node.declarations = node.declarations.filter((decl) => {
8976
+ if (decl.type === "VariableDeclarator") {
8977
+ delete decl.init;
8978
+ return true;
8979
+ }
8980
+ return false;
8981
+ });
8982
+ if (node.declarations.length) {
8983
+ withLocDeep(node, node, false);
8984
+ results.unshift(node);
8985
+ }
8986
+ // if this was the init of a ForStatement, this will
8987
+ // replace its init with a BlockStatement, so we have to
8988
+ // fix that below.
8989
+ return results;
8990
+ }
8991
+ break;
8992
+ case "ForStatement":
8993
+ if (node.init) {
8994
+ if (node.init.type === "BlockStatement") {
8995
+ const result = node.init;
8996
+ delete node.init;
8997
+ result.body.push(node);
8998
+ if (node.loc && result.loc) {
8999
+ // result has the range of the original VariableDeclaration
9000
+ // but now we're moving that ahead of the 'for', so to keep
9001
+ // things straight, we need to set the for's start to be
9002
+ // where result ended, and result's end to be where the for
9003
+ // ends (since that block now encloses the for)
9004
+ node.start = result.end;
9005
+ node.loc.start = result.loc.end;
9006
+ result.end = node.end;
9007
+ result.loc.end = node.loc.end;
9008
+ }
9009
+ return result;
9010
+ }
9011
+ if (node.init.type === "Literal") {
9012
+ delete node.init;
9013
+ }
9014
+ }
9015
+ break;
9016
+ case "SequenceExpression":
9017
+ if (node.expressions.some((e) => e.type === "Literal")) {
9018
+ node.expressions = node.expressions.filter((e) => e.type !== "Literal");
9019
+ }
9020
+ break;
9021
+ }
9022
+ assert(!info);
9023
+ return null;
9024
+ });
9025
+ return;
8536
9026
  }
8537
9027
 
8538
9028
 
@@ -9319,12 +9809,23 @@ function subtypeOfObj(a, b) {
9319
9809
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
9320
9810
 
9321
9811
  "use strict";
9322
- /* 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 */
9323
9816
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6817);
9324
9817
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
9325
9818
  /* harmony import */ var _data_flow__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8180);
9326
9819
  /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6906);
9327
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
+
9328
9829
 
9329
9830
 
9330
9831
 
@@ -9401,6 +9902,140 @@ function printBlockTrailer(block) {
9401
9902
  .map((block) => block.order)
9402
9903
  .join(", ")} ExSucc: ${block.exsucc ? block.exsucc.order : ""}`);
9403
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
+ }
9404
10039
 
9405
10040
 
9406
10041
  /***/ }),
@@ -10820,12 +11455,18 @@ function cleanupUnusedVars(state, node) {
10820
11455
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
10821
11456
 
10822
11457
  "use strict";
10823
- /* unused harmony export renameVariable */
11458
+ /* unused harmony exports renameIdentifier, renameVariable */
10824
11459
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6817);
10825
11460
  /* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
10826
11461
  /* harmony import */ var _ast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6652);
10827
11462
 
10828
11463
 
11464
+ function renameIdentifier(ident, newName) {
11465
+ if (!ident.original) {
11466
+ ident.original = ident.name;
11467
+ }
11468
+ ident.name = newName;
11469
+ }
10829
11470
  function renameVariable(state, locals, declName) {
10830
11471
  const map = locals.map;
10831
11472
  if (declName) {
@@ -10917,6 +11558,14 @@ module.exports = require("@markw65/prettier-plugin-monkeyc");
10917
11558
  "use strict";
10918
11559
  module.exports = require("fs/promises");
10919
11560
 
11561
+ /***/ }),
11562
+
11563
+ /***/ 4143:
11564
+ /***/ ((module) => {
11565
+
11566
+ "use strict";
11567
+ module.exports = require("node:assert");
11568
+
10920
11569
  /***/ })
10921
11570
 
10922
11571
  /******/ });
@@ -11009,6 +11658,7 @@ __webpack_require__.d(__webpack_exports__, {
11009
11658
  "getApiMapping": () => (/* binding */ getApiMapping),
11010
11659
  "getSuperClasses": () => (/* binding */ getSuperClasses),
11011
11660
  "hasProperty": () => (/* reexport */ src_ast/* hasProperty */.l$),
11661
+ "isClassVariable": () => (/* binding */ isClassVariable),
11012
11662
  "isLocal": () => (/* binding */ isLocal),
11013
11663
  "isLookupCandidate": () => (/* binding */ isLookupCandidate),
11014
11664
  "isStateNode": () => (/* binding */ isStateNode),
@@ -11410,7 +12060,7 @@ function visit_resource_refs(state, doc, e) {
11410
12060
  function add_one_resource(state, doc, module, e) {
11411
12061
  let id;
11412
12062
  let func;
11413
- const varDecl = () => {
12063
+ const makeVarDecl = (id, outer) => {
11414
12064
  const loc = id && (0,src_ast/* adjustLoc */.b5)(id.value.loc);
11415
12065
  return (0,src_ast/* wrap */.re)({
11416
12066
  type: "VariableDeclaration",
@@ -11433,17 +12083,24 @@ function add_one_resource(state, doc, module, e) {
11433
12083
  },
11434
12084
  },
11435
12085
  init,
11436
- }, e.loc),
12086
+ }, outer),
11437
12087
  ],
11438
12088
  kind: "var",
11439
- }, e.loc);
12089
+ }, outer);
11440
12090
  };
12091
+ const varDecl = () => makeVarDecl(id, e.loc);
11441
12092
  const classDecl = (parent) => {
11442
12093
  if (!id)
11443
12094
  return null;
11444
12095
  const loc = id.value.loc;
11445
12096
  const items = init
11446
- ? [{ type: "ClassElement", item: varDecl(), loc: e.loc }]
12097
+ ? [
12098
+ {
12099
+ type: "ClassElement",
12100
+ item: makeVarDecl(undefined, init.loc),
12101
+ loc: e.loc,
12102
+ },
12103
+ ]
11447
12104
  : [];
11448
12105
  return {
11449
12106
  type: "ClassDeclaration",
@@ -11457,7 +12114,9 @@ function add_one_resource(state, doc, module, e) {
11457
12114
  if (!id)
11458
12115
  return null;
11459
12116
  const loc = id.value.loc;
11460
- const items = init ? [varDecl()] : [];
12117
+ const items = init
12118
+ ? [makeVarDecl(undefined, init.loc)]
12119
+ : [];
11461
12120
  return {
11462
12121
  type: "FunctionDeclaration",
11463
12122
  body: { type: "BlockStatement", body: items, loc: e.loc },
@@ -11549,8 +12208,10 @@ function add_one_resource(state, doc, module, e) {
11549
12208
  if (!func)
11550
12209
  return;
11551
12210
  const elements = visit_resource_refs(state, doc, e);
12211
+ const startLoc = elements[0]?.loc;
12212
+ const endLoc = elements[elements.length - 1]?.loc;
11552
12213
  const init = elements.length
11553
- ? { type: "ArrayExpression", elements }
12214
+ ? (0,src_ast/* wrap */.re)({ type: "ArrayExpression", elements }, startLoc && endLoc && (0,src_ast/* locRange */.ht)(startLoc, endLoc))
11554
12215
  : undefined;
11555
12216
  if (!id) {
11556
12217
  if (!init)
@@ -11562,8 +12223,8 @@ function add_one_resource(state, doc, module, e) {
11562
12223
  }
11563
12224
  }
11564
12225
 
11565
- // EXTERNAL MODULE: ./src/type-flow.ts
11566
- var type_flow = __webpack_require__(4859);
12226
+ // EXTERNAL MODULE: ./src/type-flow/type-flow-util.ts
12227
+ var type_flow_util = __webpack_require__(1638);
11567
12228
  // EXTERNAL MODULE: ./src/type-flow/types.ts
11568
12229
  var types = __webpack_require__(7255);
11569
12230
  // EXTERNAL MODULE: external "./util.cjs"
@@ -12196,7 +12857,7 @@ function lookupWithType(state, node, typeMap, nonLocal = false, stack = null) {
12196
12857
  const objectType = typeMap.get(node.object);
12197
12858
  if (!objectType)
12198
12859
  return results;
12199
- const [, decls] = (0,type_flow/* findObjectDeclsByProperty */.nK)(state, objectType, node);
12860
+ const [, decls] = (0,type_flow_util/* findObjectDeclsByProperty */.nK)(state, objectType, node);
12200
12861
  if (decls) {
12201
12862
  const next = lookupNext(state, [{ parent: null, results: decls }], "decls", node.property);
12202
12863
  if (next) {
@@ -12936,6 +13597,9 @@ function markInvokeClassMethod(state, func) {
12936
13597
  function isLocal(v) {
12937
13598
  return v.stack[v.stack.length - 1]?.sn.type === "BlockStatement";
12938
13599
  }
13600
+ function isClassVariable(v) {
13601
+ return v.stack[v.stack.length - 1]?.sn.type === "ClassDeclaration";
13602
+ }
12939
13603
  function diagnostic(state, node, message, type = "INFO", extra) {
12940
13604
  if (!state.diagnostics)
12941
13605
  state.diagnostics = {};