@markw65/monkeyc-optimizer 1.1.3 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3626,7 +3626,7 @@ async function checkManifest(manifest, products) {
3626
3626
  `${t}app` === type ||
3627
3627
  (type === "widget" && t === "watchapp"));
3628
3628
  }));
3629
- if (JSON.stringify(allowedProducts) !=
3629
+ if (JSON.stringify(allowedProducts) !==
3630
3630
  JSON.stringify(manifestProducts(manifest))) {
3631
3631
  ok = false;
3632
3632
  const products = app.children("iq:products");
@@ -3730,15 +3730,15 @@ function process_assignments(assignments, current) {
3730
3730
  const process_list = (values) => {
3731
3731
  for (let i = values.length; i--;) {
3732
3732
  const v = values[i];
3733
- if (v.type == "QualifiedName" &&
3733
+ if (v.type === "QualifiedName" &&
3734
3734
  v.names.every((n, i) => n === a.names[i])) {
3735
3735
  values.splice(i, 1, ...(dot
3736
- ? dot.map((v) => v.type == "QualifiedName"
3736
+ ? dot.map((v) => v.type === "QualifiedName"
3737
3737
  ? { ...v, names: v.names.concat(dotnames) }
3738
3738
  : v)
3739
3739
  : []));
3740
3740
  }
3741
- else if (v.type == "SubList") {
3741
+ else if (v.type === "SubList") {
3742
3742
  process_list(v.values);
3743
3743
  }
3744
3744
  }
@@ -3771,7 +3771,8 @@ function evaluate_locals(assignments) {
3771
3771
  const locals = {};
3772
3772
  while (true) {
3773
3773
  assignments = assignments.filter((a) => {
3774
- if (a.names.length == 1 && a.values.every((v) => typeof v === "string")) {
3774
+ if (a.names.length === 1 &&
3775
+ a.values.every((v) => typeof v === "string")) {
3775
3776
  locals[a.names[0]] = a.values;
3776
3777
  return false;
3777
3778
  }
@@ -3782,12 +3783,12 @@ function evaluate_locals(assignments) {
3782
3783
  const process_list = (values) => {
3783
3784
  for (let i = values.length; i--;) {
3784
3785
  const v = values[i];
3785
- if (v.type == "QualifiedName" &&
3786
- v.names.length == 1 &&
3786
+ if (v.type === "QualifiedName" &&
3787
+ v.names.length === 1 &&
3787
3788
  (0,external_api_cjs_namespaceObject.hasProperty)(locals, v.names[0])) {
3788
3789
  values.splice(i, 1, ...locals[v.names[0]]);
3789
3790
  }
3790
- else if (v.type == "SubList") {
3791
+ else if (v.type === "SubList") {
3791
3792
  process_list(v.values);
3792
3793
  }
3793
3794
  }
@@ -3866,7 +3867,7 @@ function resolve_node_by_path(state, path) {
3866
3867
  if (!resolved.length)
3867
3868
  return undefined;
3868
3869
  const r = resolved[0][n];
3869
- if (!r && sdot.every((e) => e.type == "Literal")) {
3870
+ if (!r && sdot.every((e) => e.type === "Literal")) {
3870
3871
  /*
3871
3872
  * We had something like:
3872
3873
  *
@@ -3944,10 +3945,10 @@ async function resolve_literals(qualifier, default_source, deviceInfo, cache) {
3944
3945
  if (!isJNode(v)) {
3945
3946
  return v;
3946
3947
  }
3947
- if (v.type == "QualifiedName") {
3948
+ if (v.type === "QualifiedName") {
3948
3949
  throw new Error("Unexpected QualifiedName found!");
3949
3950
  }
3950
- if (v.type == "SubList") {
3951
+ if (v.type === "SubList") {
3951
3952
  return resolve_file_list(v.values);
3952
3953
  }
3953
3954
  // Jungle files can contain "./**.mc" which is supposed to match
@@ -4741,6 +4742,9 @@ function withLoc(node, start, end) {
4741
4742
  if (!node.end)
4742
4743
  node.end = start.end;
4743
4744
  node.loc = { ...(node.loc || start.loc), start: start.loc.start };
4745
+ if (end === start && start.origins) {
4746
+ node.origins = start.origins;
4747
+ }
4744
4748
  }
4745
4749
  if (end === false) {
4746
4750
  if (node.loc) {
@@ -4773,17 +4777,17 @@ function cloneDeep(node) {
4773
4777
  return withLocDeep(node, null);
4774
4778
  }
4775
4779
  function getNodeValue(node) {
4776
- if (node.type == "BinaryExpression" &&
4777
- node.operator == "as" &&
4778
- node.right.type == "TypeSpecList" &&
4779
- node.right.ts.length == 1 &&
4780
- typeof node.right.ts[0] == "string") {
4780
+ if (node.type === "BinaryExpression" &&
4781
+ node.operator === "as" &&
4782
+ node.right.type === "TypeSpecList" &&
4783
+ node.right.ts.length === 1 &&
4784
+ typeof node.right.ts[0] === "string") {
4781
4785
  // this is a cast we inserted to retain the type of an enum
4782
4786
  // any arithmetic on it will revert to "Number", or "Long",
4783
4787
  // so just ignore it.
4784
4788
  return getNodeValue(node.left);
4785
4789
  }
4786
- if (node.type != "Literal") {
4790
+ if (node.type !== "Literal") {
4787
4791
  return [null, null];
4788
4792
  }
4789
4793
  if (node.value === null) {
@@ -4873,13 +4877,13 @@ function makeScopedName(dotted, l) {
4873
4877
  function ast_getLiteralNode(node) {
4874
4878
  if (node == null)
4875
4879
  return null;
4876
- if (node.type == "Literal")
4880
+ if (node.type === "Literal")
4877
4881
  return node;
4878
- if (node.type == "BinaryExpression" && node.operator == "as") {
4882
+ if (node.type === "BinaryExpression" && node.operator === "as") {
4879
4883
  return ast_getLiteralNode(node.left) && node;
4880
4884
  }
4881
- if (node.type == "UnaryExpression") {
4882
- if (node.argument.type != "Literal")
4885
+ if (node.type === "UnaryExpression") {
4886
+ if (node.argument.type !== "Literal")
4883
4887
  return null;
4884
4888
  switch (node.operator) {
4885
4889
  case "-": {
@@ -4910,7 +4914,7 @@ function recordModifiedDecl(func, decl) {
4910
4914
  }
4911
4915
  function recordModifiedDecls(func, lookupDefs) {
4912
4916
  lookupDefs.forEach((lookupDef) => lookupDef.results.forEach((result) => {
4913
- if (result.type == "VariableDeclarator" && result.node.kind === "var") {
4917
+ if (result.type === "VariableDeclarator" && result.node.kind === "var") {
4914
4918
  recordModifiedDecl(func, result);
4915
4919
  }
4916
4920
  }));
@@ -5262,7 +5266,7 @@ function getArgSafety(state, func, args, requireAll) {
5262
5266
  switch (node.type) {
5263
5267
  case "AssignmentExpression":
5264
5268
  case "UpdateExpression": {
5265
- const v = node.type == "UpdateExpression" ? node.argument : node.left;
5269
+ const v = node.type === "UpdateExpression" ? node.argument : node.left;
5266
5270
  if (v.type === "Identifier" && (0,external_api_cjs_namespaceObject.hasProperty)(params, v.name)) {
5267
5271
  // If a parameter is modified, we can't just substitute the
5268
5272
  // argument wherever the parameter is used.
@@ -5482,6 +5486,12 @@ function processInlineBody(state, func, call, root, params) {
5482
5486
  const ix = params[node.name];
5483
5487
  if (ix >= 0) {
5484
5488
  const replacement = { ...call.arguments[ix] };
5489
+ if (node.loc) {
5490
+ if (!replacement.origins) {
5491
+ replacement.origins = [];
5492
+ }
5493
+ replacement.origins.unshift({ loc: node.loc, func: func.fullName });
5494
+ }
5485
5495
  replacements.add(replacement);
5486
5496
  return replacement;
5487
5497
  }
@@ -5568,7 +5578,7 @@ function unused(state, expression, top) {
5568
5578
  body: [estmt(expression.right)],
5569
5579
  }, expression.right);
5570
5580
  let alternate;
5571
- if (expression.operator == "||" || expression.operator == "or") {
5581
+ if (expression.operator === "||" || expression.operator === "or") {
5572
5582
  alternate = { ...consequent };
5573
5583
  consequent.body = [];
5574
5584
  }
@@ -5629,7 +5639,10 @@ function unused(state, expression, top) {
5629
5639
  }
5630
5640
  function inlineDiagnostic(state, func, call, message) {
5631
5641
  if (inlineRequested(state, func)) {
5632
- (0,external_api_cjs_namespaceObject.diagnostic)(state, call, message && `While inlining ${func.node.id.name}: ${message}`);
5642
+ if (!state.inlineDiagnostics) {
5643
+ state.inlineDiagnostics = {};
5644
+ }
5645
+ (0,external_api_cjs_namespaceObject.diagnosticHelper)(state.inlineDiagnostics, call, message && `While inlining ${func.node.id.name}: ${message}`, "INFO", undefined, true);
5633
5646
  }
5634
5647
  }
5635
5648
  function inlineWithArgs(state, func, call, context) {
@@ -5688,10 +5701,10 @@ function inlineWithArgs(state, func, call, context) {
5688
5701
  if (!processInlineBody(state, func, call, body, params)) {
5689
5702
  return null;
5690
5703
  }
5691
- (0,external_api_cjs_namespaceObject.diagnostic)(state, call, null);
5704
+ inlineDiagnostic(state, func, call, null);
5692
5705
  if (context.type !== "ReturnStatement" && retStmtCount) {
5693
5706
  const [last, block] = lastStmt(body);
5694
- if (last.type != "ReturnStatement") {
5707
+ if (last.type !== "ReturnStatement") {
5695
5708
  throw new Error("ReturnStatement got lost!");
5696
5709
  }
5697
5710
  if (last.argument) {
@@ -5988,7 +6001,7 @@ function pragmaChecker(state, ast, diagnostics) {
5988
6001
  }
5989
6002
  };
5990
6003
  const matcher = (quote, needle, haystack) => {
5991
- if (quote == '"') {
6004
+ if (quote === '"') {
5992
6005
  return haystack.includes(needle);
5993
6006
  }
5994
6007
  const re = new RegExp(needle.replace(/@([-\d.\w]+|"[^"]*")/g, (_match, pat) => `(?:${pat}|pre_${pat.replace(/\W/g, "_")}(?:_\\d+)?)`));
@@ -6785,7 +6798,7 @@ function buildDataFlowGraph(state, func, wantsLiteral, trackInsertionPoints, wan
6785
6798
  uniqueDeclMap.set(decls[0], decls);
6786
6799
  return decls;
6787
6800
  }
6788
- if (canon.length != decls.length ||
6801
+ if (canon.length !== decls.length ||
6789
6802
  !canon.every((v, i) => v === decls[i])) {
6790
6803
  throw new Error(`Canonical representation of ${declFullName(canon)} did not match`);
6791
6804
  }
@@ -7376,7 +7389,7 @@ function anticipatedDecls() {
7376
7389
  return new Map();
7377
7390
  }
7378
7391
  function equalSet(a, b) {
7379
- if (a.size != b.size)
7392
+ if (a.size !== b.size)
7380
7393
  return false;
7381
7394
  for (const item of a) {
7382
7395
  if (!b.has(item))
@@ -7385,7 +7398,7 @@ function equalSet(a, b) {
7385
7398
  return true;
7386
7399
  }
7387
7400
  function equalMap(a, b) {
7388
- if (a.size != b.size)
7401
+ if (a.size !== b.size)
7389
7402
  return false;
7390
7403
  for (const [item, value] of a) {
7391
7404
  if (b.get(item) !== value)
@@ -7438,8 +7451,8 @@ function equalStates(a, b) {
7438
7451
  for (const [k, ae] of a) {
7439
7452
  const be = b.get(k);
7440
7453
  if (!be ||
7441
- be.live != ae.live ||
7442
- be.isIsolated != ae.isIsolated ||
7454
+ be.live !== ae.live ||
7455
+ be.isIsolated !== ae.isIsolated ||
7443
7456
  !equalSet(ae.ant, be.ant) ||
7444
7457
  !equalMap(ae.members, be.members)) {
7445
7458
  return false;
@@ -7471,8 +7484,8 @@ function refCost(node) {
7471
7484
  return cost;
7472
7485
  while (true) {
7473
7486
  const next = node.object;
7474
- if (next.type != "MemberExpression") {
7475
- if (next.type != "ThisExpression") {
7487
+ if (next.type !== "MemberExpression") {
7488
+ if (next.type !== "ThisExpression") {
7476
7489
  cost += next.type === "Identifier" && next.name === "$" ? 4 : 6;
7477
7490
  }
7478
7491
  return cost;
@@ -7728,7 +7741,7 @@ function computeAttributes(state, head) {
7728
7741
  delete existing.isIsolated;
7729
7742
  mergeAnticipatedState(events, existing);
7730
7743
  }
7731
- else if (candidateCost(events) != cost) {
7744
+ else if (candidateCost(events) !== cost) {
7732
7745
  throw new Error(`cost of block ${i} changed`);
7733
7746
  }
7734
7747
  candidateDecls.set(decl, events);
@@ -8014,7 +8027,7 @@ function describeEvent(event) {
8014
8027
  }
8015
8028
  function printBlockEvents(block, extra) {
8016
8029
  console.log("Events:");
8017
- (0,external_util_cjs_namespaceObject.forEach)(block.events, (event) => console.log(` ${describeEvent(event)} ${extra?.(event)}`));
8030
+ (0,external_util_cjs_namespaceObject.forEach)(block.events, (event) => console.log(` ${describeEvent(event)} ${extra ? extra(event) : ""}`));
8018
8031
  }
8019
8032
  function printBlockTrailer(block) {
8020
8033
  console.log(`Succs: ${(block.succs || [])
@@ -8090,19 +8103,20 @@ function findDeadStores(graph, logThisRun) {
8090
8103
  }
8091
8104
  break;
8092
8105
  case "def":
8093
- if (isTypeStateKey(event.decl) &&
8094
- ((event.node.type === "AssignmentExpression" &&
8095
- event.node.operator === "=") ||
8096
- (event.node.type === "VariableDeclarator" && event.node.init))) {
8106
+ if (isTypeStateKey(event.decl)) {
8097
8107
  if (curState.has(event.decl)) {
8098
8108
  deadStores.add(event.node);
8099
8109
  }
8100
8110
  else {
8101
8111
  deadStores.delete(event.node);
8102
8112
  }
8103
- curState.add(event.decl);
8104
- if (logThisRun) {
8105
- console.log(` anticipated => ${tsKey(event.decl)}`);
8113
+ if ((event.node.type === "AssignmentExpression" &&
8114
+ event.node.operator === "=") ||
8115
+ (event.node.type === "VariableDeclarator" && event.node.init)) {
8116
+ curState.add(event.decl);
8117
+ if (logThisRun) {
8118
+ console.log(` anticipated => ${tsKey(event.decl)}`);
8119
+ }
8106
8120
  }
8107
8121
  }
8108
8122
  break;
@@ -8156,12 +8170,23 @@ function eliminateDeadStores(state, func, graph, logThisRun) {
8156
8170
  node.expression.type === "AssignmentExpression" &&
8157
8171
  deadStores.has(node.expression)) {
8158
8172
  const body = unused(state, node.expression.left).concat(unused(state, node.expression.right));
8173
+ changes = true;
8159
8174
  if (body.length) {
8160
8175
  return withLoc({ type: "BlockStatement", body }, node, node);
8161
8176
  }
8162
- changes = true;
8163
8177
  return false;
8164
8178
  }
8179
+ if (node.type === "UpdateExpression" && deadStores.has(node)) {
8180
+ changes = true;
8181
+ return { type: "Literal", value: null, raw: "null" };
8182
+ }
8183
+ if (node.type === "AssignmentExpression" &&
8184
+ deadStores.has(node) &&
8185
+ unused(state, node.right, true)?.length === 0 &&
8186
+ unused(state, node.left, true)?.length === 0) {
8187
+ changes = true;
8188
+ return { type: "Literal", value: null, raw: "null" };
8189
+ }
8165
8190
  if (node.type === "VariableDeclaration") {
8166
8191
  const result = [];
8167
8192
  for (let i = 0; i < node.declarations.length; i++) {
@@ -8305,28 +8330,32 @@ function intersection(a, b) {
8305
8330
  }
8306
8331
  let mask = 0;
8307
8332
  const result = {};
8308
- forEachUnionComponent(a, common, (bit, avalue) => {
8309
- const bvalue = getUnionComponent(b, bit);
8310
- if (avalue == null) {
8333
+ forEachUnionComponent(a, common, (ac) => {
8334
+ const bvalue = getUnionComponent(b, ac.type);
8335
+ if (ac.value == null) {
8311
8336
  if (!bvalue)
8312
8337
  return;
8313
- result[bit] = bvalue;
8314
- mask |= bit;
8338
+ result[ac.type] = bvalue;
8339
+ mask |= ac.type;
8315
8340
  return;
8316
8341
  }
8317
- if (bvalue === null || avalue === bvalue) {
8318
- result[bit] = avalue;
8319
- mask |= bit;
8342
+ if (bvalue === null || ac.value === bvalue) {
8343
+ result[ac.type] = ac.value;
8344
+ mask |= ac.type;
8320
8345
  return;
8321
8346
  }
8322
- const ivalue = intersectionValue(bit, avalue, bvalue);
8347
+ const ivalue = intersectionValue({
8348
+ type: ac.type,
8349
+ avalue: ac.value,
8350
+ bvalue,
8351
+ });
8323
8352
  if (ivalue != null) {
8324
- result[bit] = ivalue;
8325
- mask |= bit;
8353
+ result[ac.type] = ivalue;
8354
+ mask |= ac.type;
8326
8355
  return;
8327
8356
  }
8328
8357
  else {
8329
- common -= bit;
8358
+ common -= ac.type;
8330
8359
  }
8331
8360
  });
8332
8361
  if (!mask)
@@ -8339,13 +8368,13 @@ function intersection(a, b) {
8339
8368
  }
8340
8369
  return { type: common, value: result[mask] };
8341
8370
  }
8342
- function intersectionValue(bit, avalue, bvalue) {
8343
- switch (bit) {
8371
+ function intersectionValue(pair) {
8372
+ switch (pair.type) {
8344
8373
  case 1 /* TypeTag.Null */:
8345
8374
  case 2 /* TypeTag.False */:
8346
8375
  case 4 /* TypeTag.True */:
8347
8376
  case 262144 /* TypeTag.Typedef */:
8348
- throw new Error(`Unexpected TypeTag '${typeTagName(bit)}'`);
8377
+ throw new Error(`Unexpected TypeTag '${typeTagName(pair.type)}'`);
8349
8378
  case 8 /* TypeTag.Number */:
8350
8379
  case 16 /* TypeTag.Long */:
8351
8380
  case 32 /* TypeTag.Float */:
@@ -8353,31 +8382,27 @@ function intersectionValue(bit, avalue, bvalue) {
8353
8382
  case 256 /* TypeTag.String */:
8354
8383
  case 128 /* TypeTag.Char */:
8355
8384
  case 131072 /* TypeTag.Symbol */:
8356
- return avalue === bvalue ? avalue : null;
8385
+ return pair.avalue === pair.bvalue ? pair.avalue : null;
8357
8386
  case 512 /* TypeTag.Array */: {
8358
- const atype = intersection(avalue, bvalue);
8387
+ const atype = intersection(pair.avalue, pair.bvalue);
8359
8388
  return atype.type === 0 /* TypeTag.Never */ ? null : atype;
8360
8389
  }
8361
8390
  case 1024 /* TypeTag.Dictionary */: {
8362
- const adict = avalue;
8363
- const bdict = bvalue;
8364
- const dkey = intersection(adict.key, bdict.key);
8365
- const dvalue = intersection(adict.value, bdict.value);
8391
+ const dkey = intersection(pair.avalue.key, pair.bvalue.key);
8392
+ const dvalue = intersection(pair.avalue.value, pair.bvalue.value);
8366
8393
  return dkey.type !== 0 /* TypeTag.Never */ && dvalue.type !== 0 /* TypeTag.Never */
8367
8394
  ? { key: dkey, value: dvalue }
8368
8395
  : null;
8369
8396
  }
8370
8397
  case 2048 /* TypeTag.Method */: {
8371
- const ameth = avalue;
8372
- const bmeth = bvalue;
8373
- if (ameth.args.length != bmeth.args.length)
8398
+ if (pair.avalue.args.length !== pair.bvalue.args.length)
8374
8399
  return null;
8375
- const mresult = intersection(ameth.result, bmeth.result);
8400
+ const mresult = intersection(pair.avalue.result, pair.bvalue.result);
8376
8401
  if (mresult.type === 0 /* TypeTag.Never */)
8377
8402
  return null;
8378
- const margs = ameth.args.map((aarg, i) => {
8403
+ const margs = pair.avalue.args.map((aarg, i) => {
8379
8404
  aarg = cloneType(aarg);
8380
- unionInto(aarg, bmeth.args[i]);
8405
+ unionInto(aarg, pair.bvalue.args[i]);
8381
8406
  return aarg;
8382
8407
  });
8383
8408
  if (margs.some((arg) => arg.type === 0 /* TypeTag.Never */))
@@ -8386,23 +8411,19 @@ function intersectionValue(bit, avalue, bvalue) {
8386
8411
  }
8387
8412
  case 4096 /* TypeTag.Module */:
8388
8413
  case 8192 /* TypeTag.Function */: {
8389
- const asd = avalue;
8390
- const bsd = bvalue;
8391
8414
  // quadratic :-(
8392
8415
  const common = [];
8393
- (0,external_util_cjs_namespaceObject.forEach)(asd, (sna) => (0,external_util_cjs_namespaceObject.some)(bsd, (snb) => sna === snb) &&
8416
+ (0,external_util_cjs_namespaceObject.forEach)(pair.avalue, (sna) => (0,external_util_cjs_namespaceObject.some)(pair.bvalue, (snb) => sna === snb) &&
8394
8417
  common.push(sna));
8395
8418
  if (!common.length)
8396
8419
  return null;
8397
8420
  return (common.length === 1 ? common[0] : common);
8398
8421
  }
8399
8422
  case 16384 /* TypeTag.Class */: {
8400
- const asd = avalue;
8401
- const bsd = bvalue;
8402
8423
  const common = [];
8403
- (0,external_util_cjs_namespaceObject.forEach)(asd, (sna) => {
8424
+ (0,external_util_cjs_namespaceObject.forEach)(pair.avalue, (sna) => {
8404
8425
  const superA = (0,external_api_cjs_namespaceObject.getSuperClasses)(sna);
8405
- (0,external_util_cjs_namespaceObject.forEach)(bsd, (snb) => {
8426
+ (0,external_util_cjs_namespaceObject.forEach)(pair.bvalue, (snb) => {
8406
8427
  if (sna === snb || (superA && superA.has(snb))) {
8407
8428
  common.push(sna);
8408
8429
  }
@@ -8417,10 +8438,8 @@ function intersectionValue(bit, avalue, bvalue) {
8417
8438
  return common.length === 1 ? common[0] : common;
8418
8439
  }
8419
8440
  case 32768 /* TypeTag.Object */: {
8420
- const aobj = avalue;
8421
- const bobj = bvalue;
8422
- const klass = intersection(aobj.klass, bobj.klass);
8423
- const obj = intersectObj(aobj.obj, bobj.obj);
8441
+ const klass = intersection(pair.avalue.klass, pair.bvalue.klass);
8442
+ const obj = intersectObj(pair.avalue.obj, pair.bvalue.obj);
8424
8443
  return klass.type !== 16384 /* TypeTag.Class */ || klass.value == null
8425
8444
  ? null
8426
8445
  : obj
@@ -8428,24 +8447,24 @@ function intersectionValue(bit, avalue, bvalue) {
8428
8447
  : { klass: klass };
8429
8448
  }
8430
8449
  case 65536 /* TypeTag.Enum */: {
8431
- const aenum = avalue;
8432
- const benum = bvalue;
8433
- if (aenum.enum !== benum.enum && aenum.enum && benum.enum) {
8450
+ if (pair.avalue.enum !== pair.bvalue.enum &&
8451
+ pair.avalue.enum &&
8452
+ pair.bvalue.enum) {
8434
8453
  return null;
8435
8454
  }
8436
- const enumDecl = aenum.enum || benum.enum;
8437
- if (aenum.value != null) {
8438
- if (benum.value != null) {
8439
- const value = intersection(aenum.value, benum.value);
8455
+ const enumDecl = pair.avalue.enum || pair.bvalue.enum;
8456
+ if (pair.avalue.value != null) {
8457
+ if (pair.bvalue.value != null) {
8458
+ const value = intersection(pair.avalue.value, pair.bvalue.value);
8440
8459
  const e = { enum: enumDecl, value };
8441
8460
  return e;
8442
8461
  }
8443
- return aenum.value;
8462
+ return pair.avalue.value;
8444
8463
  }
8445
- return benum;
8464
+ return pair.bvalue;
8446
8465
  }
8447
8466
  default:
8448
- unhandledType(bit);
8467
+ unhandledType(pair);
8449
8468
  }
8450
8469
  }
8451
8470
  function intersectObj(to, from) {
@@ -8509,9 +8528,11 @@ function restrictExactTypesByEquality(a, b) {
8509
8528
  extra_bits |= 4 /* TypeTag.True */;
8510
8529
  }
8511
8530
  let value_bits = b.type & (120 /* TypeTag.Numeric */ | 128 /* TypeTag.Char */);
8531
+ // Some Numbers don't fit exactly in a Float
8532
+ // We can eliminate Float from b's type in those cases.
8512
8533
  if (a.value != null &&
8513
8534
  value_bits & 32 /* TypeTag.Float */ &&
8514
- roundToFloat(Number(a.value)) != a.value) {
8535
+ roundToFloat(Number(a.value)) !== a.value) {
8515
8536
  value_bits -= 32 /* TypeTag.Float */;
8516
8537
  }
8517
8538
  let v = {
@@ -8540,14 +8561,15 @@ function restrictExactTypesByEquality(a, b) {
8540
8561
  let value_bits = b.type & 120 /* TypeTag.Numeric */;
8541
8562
  if (a.value != null) {
8542
8563
  if (value_bits & 8 /* TypeTag.Number */ &&
8543
- BigInt.asIntN(32, a.value) != a.value) {
8564
+ BigInt.asIntN(32, a.value) !== a.value) {
8544
8565
  value_bits -= 8 /* TypeTag.Number */;
8545
8566
  }
8546
8567
  if (value_bits & 32 /* TypeTag.Float */ &&
8547
- BigInt(roundToFloat(Number(a.value))) != a.value) {
8568
+ BigInt(roundToFloat(Number(a.value))) !== a.value) {
8548
8569
  value_bits -= 32 /* TypeTag.Float */;
8549
8570
  }
8550
- if (value_bits & 64 /* TypeTag.Double */ && BigInt(Number(a.value)) != a.value) {
8571
+ if (value_bits & 64 /* TypeTag.Double */ &&
8572
+ BigInt(Number(a.value)) !== a.value) {
8551
8573
  value_bits -= 64 /* TypeTag.Double */;
8552
8574
  }
8553
8575
  }
@@ -8648,7 +8670,7 @@ function restrictExactTypesByEquality(a, b) {
8648
8670
  }
8649
8671
  function restrictByEqualityByComponent(a, b) {
8650
8672
  let bits = a.type;
8651
- if (a.value == null && (b.type & bits) == b.type) {
8673
+ if (a.value == null && (b.type & bits) === b.type) {
8652
8674
  // shortcut:
8653
8675
  // if b.type is contained in a.type, and a has no
8654
8676
  // specialization, the result is just b.
@@ -8690,7 +8712,7 @@ function restrictByEqualityByComponent(a, b) {
8690
8712
  * 5.0 == 5, and 5.toChar() == 5.
8691
8713
  */
8692
8714
  function restrictByEquality(a, b) {
8693
- if (a.type == 0 /* TypeTag.Never */)
8715
+ if (a.type === 0 /* TypeTag.Never */)
8694
8716
  return a;
8695
8717
  if (isExact(a)) {
8696
8718
  return restrictExactTypesByEquality(a, b);
@@ -8741,11 +8763,12 @@ function subtypeOf(a, b) {
8741
8763
  if (b.value == null)
8742
8764
  return true;
8743
8765
  let result = true;
8744
- forEachUnionComponent(b, common, (bit, bvalue) => {
8745
- const avalue = getUnionComponent(a, bit);
8746
- if (bvalue == null || avalue === bvalue)
8766
+ forEachUnionComponent(b, common, (bc) => {
8767
+ const avalue = getUnionComponent(a, bc.type);
8768
+ if (bc.value == null || avalue === bc.value)
8747
8769
  return true;
8748
- if (avalue == null || !subtypeOfValue(bit, avalue, bvalue)) {
8770
+ if (avalue == null ||
8771
+ !subtypeOfValue({ type: bc.type, avalue, bvalue: bc.value })) {
8749
8772
  result = false;
8750
8773
  return false;
8751
8774
  }
@@ -8753,13 +8776,13 @@ function subtypeOf(a, b) {
8753
8776
  });
8754
8777
  return result;
8755
8778
  }
8756
- function subtypeOfValue(bit, avalue, bvalue) {
8757
- switch (bit) {
8779
+ function subtypeOfValue(pair) {
8780
+ switch (pair.type) {
8758
8781
  case 1 /* TypeTag.Null */:
8759
8782
  case 2 /* TypeTag.False */:
8760
8783
  case 4 /* TypeTag.True */:
8761
8784
  case 262144 /* TypeTag.Typedef */:
8762
- throw new Error(`Unexpected TypeTag '${typeTagName(bit)}'`);
8785
+ throw new Error(`Unexpected TypeTag '${typeTagName(pair.type)}'`);
8763
8786
  case 8 /* TypeTag.Number */:
8764
8787
  case 16 /* TypeTag.Long */:
8765
8788
  case 32 /* TypeTag.Float */:
@@ -8767,31 +8790,29 @@ function subtypeOfValue(bit, avalue, bvalue) {
8767
8790
  case 256 /* TypeTag.String */:
8768
8791
  case 128 /* TypeTag.Char */:
8769
8792
  case 131072 /* TypeTag.Symbol */:
8770
- return avalue === bvalue;
8793
+ return pair.avalue === pair.bvalue;
8771
8794
  case 512 /* TypeTag.Array */:
8772
- return subtypeOf(avalue, bvalue);
8795
+ return subtypeOf(pair.avalue, pair.bvalue);
8773
8796
  case 1024 /* TypeTag.Dictionary */: {
8774
- const adict = avalue;
8775
- const bdict = bvalue;
8797
+ const adict = pair.avalue;
8798
+ const bdict = pair.bvalue;
8776
8799
  return (subtypeOf(adict.key, bdict.key) && subtypeOf(adict.value, bdict.value));
8777
8800
  }
8778
8801
  case 2048 /* TypeTag.Method */: {
8779
- const ameth = avalue;
8780
- const bmeth = bvalue;
8781
- return (ameth.args.length === bmeth.args.length &&
8782
- subtypeOf(ameth.result, bmeth.result) &&
8783
- ameth.args.every((arg, i) => subtypeOf(bmeth.args[i], arg)));
8802
+ return (pair.avalue.args.length === pair.bvalue.args.length &&
8803
+ subtypeOf(pair.avalue.result, pair.bvalue.result) &&
8804
+ pair.avalue.args.every((arg, i) => subtypeOf(pair.bvalue.args[i], arg)));
8784
8805
  }
8785
8806
  case 4096 /* TypeTag.Module */:
8786
8807
  case 8192 /* TypeTag.Function */: {
8787
- const asd = avalue;
8788
- const bsd = bvalue;
8808
+ const asd = pair.avalue;
8809
+ const bsd = pair.bvalue;
8789
8810
  // quadratic :-(
8790
8811
  return (0,external_util_cjs_namespaceObject.some)(asd, (sna) => (0,external_util_cjs_namespaceObject.some)(bsd, (snb) => sna === snb));
8791
8812
  }
8792
8813
  case 16384 /* TypeTag.Class */: {
8793
- const asd = avalue;
8794
- const bsd = bvalue;
8814
+ const asd = pair.avalue;
8815
+ const bsd = pair.bvalue;
8795
8816
  return (0,external_util_cjs_namespaceObject.every)(asd, (sna) => {
8796
8817
  const superA = (0,external_api_cjs_namespaceObject.getSuperClasses)(sna);
8797
8818
  return (0,external_util_cjs_namespaceObject.some)(bsd, (snb) => {
@@ -8803,18 +8824,18 @@ function subtypeOfValue(bit, avalue, bvalue) {
8803
8824
  });
8804
8825
  }
8805
8826
  case 32768 /* TypeTag.Object */: {
8806
- const aobj = avalue;
8807
- const bobj = bvalue;
8827
+ const aobj = pair.avalue;
8828
+ const bobj = pair.bvalue;
8808
8829
  return (subtypeOf(aobj.klass, bobj.klass) && subtypeOfObj(aobj.obj, bobj.obj));
8809
8830
  }
8810
8831
  case 65536 /* TypeTag.Enum */: {
8811
- const aenum = avalue;
8812
- const benum = bvalue;
8832
+ const aenum = pair.avalue;
8833
+ const benum = pair.bvalue;
8813
8834
  return (aenum.enum === benum.enum &&
8814
8835
  (!aenum.value || !benum.value || subtypeOf(aenum.value, benum.value)));
8815
8836
  }
8816
8837
  default:
8817
- unhandledType(bit);
8838
+ unhandledType(pair);
8818
8839
  }
8819
8840
  }
8820
8841
  function subtypeOfObj(a, b) {
@@ -8835,6 +8856,9 @@ function subtypeOfObj(a, b) {
8835
8856
 
8836
8857
 
8837
8858
  function unionInto(to, from) {
8859
+ if (to == null || from == null) {
8860
+ throw new Error("Null");
8861
+ }
8838
8862
  if (from.type === 0 || to === from)
8839
8863
  return false;
8840
8864
  if (to.type === 0) {
@@ -8884,23 +8908,27 @@ function mergeMultiple(to, from) {
8884
8908
  let anyChanged = newTags !== to.type;
8885
8909
  let mask = 0;
8886
8910
  const result = {};
8887
- forEachUnionComponent(to, newTags, (tag, tov) => {
8888
- const fromv = getUnionComponent(from, tag);
8889
- if (tov != null) {
8911
+ forEachUnionComponent(to, newTags, (ac) => {
8912
+ const fromv = getUnionComponent(from, ac.type);
8913
+ if (ac.value != null) {
8890
8914
  if (fromv != null) {
8891
- const [value, changed] = mergeSingle(tag, tov, fromv);
8915
+ const [value, changed] = mergeSingle({
8916
+ type: ac.type,
8917
+ avalue: ac.value,
8918
+ bvalue: fromv,
8919
+ });
8892
8920
  if (changed)
8893
8921
  anyChanged = true;
8894
8922
  if (value) {
8895
- mask |= tag;
8896
- result[tag] = value;
8923
+ mask |= ac.type;
8924
+ result[ac.type] = value;
8897
8925
  }
8898
8926
  }
8899
- else if (!(from.type & tag)) {
8927
+ else if (!(from.type & ac.type)) {
8900
8928
  // from doesn't contribute to this tag,
8901
8929
  // so just keep it. No change.
8902
- mask |= tag;
8903
- result[tag] = tov;
8930
+ mask |= ac.type;
8931
+ result[ac.type] = ac.value;
8904
8932
  }
8905
8933
  else {
8906
8934
  // We dropped the data for this tag, so
@@ -8908,13 +8936,13 @@ function mergeMultiple(to, from) {
8908
8936
  anyChanged = true;
8909
8937
  }
8910
8938
  }
8911
- else if (fromv && !(to.type & tag)) {
8939
+ else if (fromv && !(to.type & ac.type)) {
8912
8940
  // to doesn't contribute to this tag,
8913
8941
  // so just keep from's component.
8914
8942
  // this is new, so it changed.
8915
8943
  anyChanged = true;
8916
- mask |= tag;
8917
- result[tag] = fromv;
8944
+ mask |= ac.type;
8945
+ result[ac.type] = fromv;
8918
8946
  }
8919
8947
  });
8920
8948
  if (!anyChanged)
@@ -8941,8 +8969,8 @@ function tryUnion(to, from) {
8941
8969
  return to;
8942
8970
  return null;
8943
8971
  }
8944
- function mergeSingle(type, to, from) {
8945
- switch (type) {
8972
+ function mergeSingle(pair) {
8973
+ switch (pair.type) {
8946
8974
  case 1 /* TypeTag.Null */:
8947
8975
  case 2 /* TypeTag.False */:
8948
8976
  case 4 /* TypeTag.True */:
@@ -8954,48 +8982,49 @@ function mergeSingle(type, to, from) {
8954
8982
  case 128 /* TypeTag.Char */:
8955
8983
  case 256 /* TypeTag.String */:
8956
8984
  case 131072 /* TypeTag.Symbol */:
8957
- if (to === from) {
8958
- return [to, false];
8985
+ if (pair.avalue === pair.bvalue) {
8986
+ return [pair.avalue, false];
8959
8987
  }
8960
8988
  return [null, true];
8961
8989
  case 512 /* TypeTag.Array */: {
8962
- const merged = tryUnion(to, from);
8963
- return [merged || to, merged != null];
8990
+ const merged = tryUnion(pair.avalue, pair.bvalue);
8991
+ return [merged || pair.avalue, merged != null];
8964
8992
  }
8965
8993
  case 1024 /* TypeTag.Dictionary */: {
8966
- const { key, value } = to;
8967
- const keyChange = tryUnion(key, from.key);
8968
- const valueChange = tryUnion(value, from.value);
8994
+ const { key, value } = pair.avalue;
8995
+ const keyChange = tryUnion(key, pair.bvalue.key);
8996
+ const valueChange = tryUnion(value, pair.bvalue.value);
8969
8997
  if (keyChange || valueChange) {
8970
8998
  return [{ key: keyChange || key, value: valueChange || value }, true];
8971
8999
  }
8972
- return [to, false];
9000
+ return [pair.avalue, false];
8973
9001
  }
8974
9002
  case 2048 /* TypeTag.Method */: {
8975
- const ameth = to;
8976
- const bmeth = from;
8977
- if (ameth.args.length != bmeth.args.length)
9003
+ if (pair.avalue.args.length !== pair.bvalue.args.length)
8978
9004
  return [null, true];
8979
- const resultChange = tryUnion(ameth.result, bmeth.result);
8980
- const args = ameth.args.map((arg, i) => intersection(arg, bmeth.args[i]));
9005
+ const resultChange = tryUnion(pair.avalue.result, pair.bvalue.result);
9006
+ const args = pair.avalue.args.map((arg, i) => intersection(arg, pair.bvalue.args[i]));
8981
9007
  if (args.some((arg) => arg.type === 0 /* TypeTag.Never */)) {
8982
9008
  return [null, true];
8983
9009
  }
8984
- const argsChanged = args.some((arg, i) => !subtypeOf(ameth.args[i], arg));
9010
+ const argsChanged = args.some((arg, i) => !subtypeOf(pair.avalue.args[i], arg));
8985
9011
  if (resultChange || argsChanged) {
8986
- return [{ result: resultChange || ameth.result, args }, true];
9012
+ return [{ result: resultChange || pair.avalue.result, args }, true];
8987
9013
  }
8988
- return [to, false];
9014
+ return [pair.avalue, false];
8989
9015
  }
8990
9016
  case 4096 /* TypeTag.Module */:
9017
+ return mergeStateDecls(pair.avalue, pair.bvalue);
8991
9018
  case 8192 /* TypeTag.Function */:
9019
+ return mergeStateDecls(pair.avalue, pair.bvalue);
8992
9020
  case 16384 /* TypeTag.Class */:
9021
+ return mergeStateDecls(pair.avalue, pair.bvalue);
8993
9022
  case 262144 /* TypeTag.Typedef */:
8994
- return mergeStateDecls(to, from);
9023
+ return mergeStateDecls(pair.avalue, pair.bvalue);
8995
9024
  case 32768 /* TypeTag.Object */: {
8996
- let klass = to.klass;
8997
- const [obj, objChanged] = mergeObjectValues(to.obj, from.obj);
8998
- const klassChanged = tryUnion(klass, from.klass);
9025
+ let klass = pair.avalue.klass;
9026
+ const [obj, objChanged] = mergeObjectValues(pair.avalue.obj, pair.bvalue.obj);
9027
+ const klassChanged = tryUnion(klass, pair.bvalue.klass);
8999
9028
  if (klassChanged || objChanged) {
9000
9029
  klass = (klassChanged || klass);
9001
9030
  if (obj) {
@@ -9003,11 +9032,11 @@ function mergeSingle(type, to, from) {
9003
9032
  }
9004
9033
  return [{ klass }, true];
9005
9034
  }
9006
- return [to, false];
9035
+ return [pair.avalue, false];
9007
9036
  }
9008
9037
  case 65536 /* TypeTag.Enum */: {
9009
- const toE = to;
9010
- const fromE = from;
9038
+ const toE = pair.avalue;
9039
+ const fromE = pair.bvalue;
9011
9040
  if (toE.enum !== fromE.enum) {
9012
9041
  return [null, true];
9013
9042
  }
@@ -9026,9 +9055,8 @@ function mergeSingle(type, to, from) {
9026
9055
  return [toE, false];
9027
9056
  }
9028
9057
  default:
9029
- unhandledType(type);
9058
+ unhandledType(pair);
9030
9059
  }
9031
- throw new Error(`Unexpected type ${type}`);
9032
9060
  }
9033
9061
  function mergeObjectValues(to, from) {
9034
9062
  if (!to) {
@@ -9172,22 +9200,22 @@ function clearValuesUnder(v, tag, clearTag = false) {
9172
9200
  }
9173
9201
  function widenTypeHelper(t, depth) {
9174
9202
  let result = null;
9175
- forEachUnionComponent(t, t.type & (512 /* TypeTag.Array */ | 1024 /* TypeTag.Dictionary */), (tag, value) => {
9176
- if (!value)
9203
+ forEachUnionComponent(t, t.type & (512 /* TypeTag.Array */ | 1024 /* TypeTag.Dictionary */), (ac) => {
9204
+ if (ac.value == null)
9177
9205
  return;
9178
- switch (tag) {
9206
+ switch (ac.type) {
9179
9207
  case 512 /* TypeTag.Array */:
9180
9208
  if (depth > 4) {
9181
9209
  if (!result)
9182
9210
  result = cloneType(t);
9183
- clearValuesUnder(result, tag);
9211
+ clearValuesUnder(result, ac.type);
9184
9212
  }
9185
9213
  else {
9186
- const v = widenTypeHelper(value, depth + 1);
9214
+ const v = widenTypeHelper(ac.value, depth + 1);
9187
9215
  if (v) {
9188
9216
  if (!result)
9189
9217
  result = cloneType(t);
9190
- setUnionComponent(result, tag, v);
9218
+ setUnionComponent(result, ac.type, v);
9191
9219
  }
9192
9220
  }
9193
9221
  return;
@@ -9195,10 +9223,10 @@ function widenTypeHelper(t, depth) {
9195
9223
  if (depth > 4) {
9196
9224
  if (!result)
9197
9225
  result = cloneType(t);
9198
- clearValuesUnder(result, tag);
9226
+ clearValuesUnder(result, ac.type);
9199
9227
  }
9200
9228
  else {
9201
- const ddata = value;
9229
+ const ddata = ac.value;
9202
9230
  const key = widenTypeHelper(ddata.key, depth + 1);
9203
9231
  const data = widenTypeHelper(ddata.value, depth + 1);
9204
9232
  if (key || data) {
@@ -9209,7 +9237,7 @@ function widenTypeHelper(t, depth) {
9209
9237
  newDData.key = key;
9210
9238
  if (data)
9211
9239
  newDData.value = data;
9212
- setUnionComponent(result, tag, newDData);
9240
+ setUnionComponent(result, ac.type, newDData);
9213
9241
  }
9214
9242
  }
9215
9243
  return;
@@ -9229,6 +9257,7 @@ function widenType(t) {
9229
9257
 
9230
9258
 
9231
9259
 
9260
+
9232
9261
  function typeTagName(tag) {
9233
9262
  switch (tag) {
9234
9263
  case 0 /* TypeTag.Never */:
@@ -9327,7 +9356,7 @@ function hasNoData(v, t) {
9327
9356
  return true;
9328
9357
  return ((hasUnionData(v.type)
9329
9358
  ? v.value.mask & t
9330
- : v.type & t & ~SingleTonTypeTagsConst) == 0);
9359
+ : v.type & t & ~SingleTonTypeTagsConst) === 0);
9331
9360
  }
9332
9361
  function lookupByFullName(state, fullName) {
9333
9362
  return fullName.split(".").reduce((results, part) => {
@@ -9445,24 +9474,47 @@ function typeFromTypeStateNode(state, sn, classVsObj) {
9445
9474
  sn.resolvedType = result;
9446
9475
  return result;
9447
9476
  }
9448
- case "VariableDeclarator":
9477
+ case "VariableDeclarator": {
9478
+ if (sn.resolvedType)
9479
+ return sn.resolvedType;
9480
+ let declared = null;
9481
+ if (sn.node.id.type === "BinaryExpression") {
9482
+ declared = typeFromTypespec(state, sn.node.id.right, sn.stack);
9483
+ }
9449
9484
  if (sn.node.kind === "const" && sn.node.init) {
9450
- let node = sn.node.init;
9451
- if (node.type === "Literal") {
9452
- return typeFromLiteral(node);
9485
+ if (hasProperty(sn, "resolvedType")) {
9486
+ // The constant is defined recursively
9487
+ return declared ?? { type: 524287 /* TypeTag.Any */ };
9488
+ }
9489
+ // set the marker in case the constant appears in its
9490
+ // own initializer.
9491
+ sn.resolvedType = undefined;
9492
+ const stack = state.stack;
9493
+ let resolved;
9494
+ try {
9495
+ state.stack = sn.stack;
9496
+ resolved = evaluateExpr(state, sn.node.init).value;
9453
9497
  }
9454
- while (node.type === "BinaryExpression" && node.operator === "as") {
9455
- node = node.left;
9498
+ finally {
9499
+ state.stack = stack;
9456
9500
  }
9457
- if (node.type === "Literal" ||
9458
- (node.type === "UnaryExpression" && node.operator === ":")) {
9459
- return evaluateExpr(state, sn.node.init).value;
9501
+ if (resolved.type === 0 /* TypeTag.Never */) {
9502
+ resolved = declared ?? { type: 524287 /* TypeTag.Any */ };
9460
9503
  }
9504
+ else if (declared) {
9505
+ resolved = intersection(resolved, declared);
9506
+ if (resolved.type === 0 /* TypeTag.Never */) {
9507
+ resolved = declared;
9508
+ }
9509
+ }
9510
+ sn.resolvedType = resolved;
9511
+ return resolved;
9461
9512
  }
9462
9513
  if (sn.node.id.type === "BinaryExpression") {
9463
9514
  return typeFromTypespec(state, sn.node.id.right, sn.stack);
9464
9515
  }
9465
9516
  return { type: 524287 /* TypeTag.Any */ };
9517
+ }
9466
9518
  }
9467
9519
  throw new Error(`Internal error: Unexpected StateNodeDecl.type: ${sn.type}`);
9468
9520
  }
@@ -9742,7 +9794,7 @@ function castType(type, target) {
9742
9794
  // Number or Long operands to '&', '|', and '^' are coerced
9743
9795
  // to boolean if the other argument is boolean.
9744
9796
  if (type.type & (8 /* TypeTag.Number */ | 16 /* TypeTag.Long */)) {
9745
- result.type = type.value == 0 ? 2 /* TypeTag.False */ : 4 /* TypeTag.True */;
9797
+ result.type = Number(type.value) === 0 ? 2 /* TypeTag.False */ : 4 /* TypeTag.True */;
9746
9798
  return result;
9747
9799
  }
9748
9800
  }
@@ -9760,15 +9812,15 @@ const TruthyTypes = 4 /* TypeTag.True */ |
9760
9812
  function mustBeTrue(arg) {
9761
9813
  return (((arg.type === 8 /* TypeTag.Number */ || arg.type === 16 /* TypeTag.Long */) &&
9762
9814
  arg.value != null &&
9763
- arg.value != 0) ||
9764
- ((arg.type & TruthyTypes) != 0 && (arg.type & ~TruthyTypes) == 0));
9815
+ Number(arg.value) !== 0) ||
9816
+ ((arg.type & TruthyTypes) !== 0 && (arg.type & ~TruthyTypes) === 0));
9765
9817
  }
9766
9818
  function mustBeFalse(arg) {
9767
9819
  return (arg.type === 1 /* TypeTag.Null */ ||
9768
9820
  arg.type === 2 /* TypeTag.False */ ||
9769
9821
  ((arg.type === 8 /* TypeTag.Number */ || arg.type === 16 /* TypeTag.Long */) &&
9770
9822
  arg.value != null &&
9771
- arg.value == 0));
9823
+ Number(arg.value) === 0));
9772
9824
  }
9773
9825
  function display(type) {
9774
9826
  const names = (v, fn) => (0,external_util_cjs_namespaceObject.map)(v, fn)
@@ -9869,7 +9921,7 @@ function display(type) {
9869
9921
  }
9870
9922
  function hasUnionData(tag) {
9871
9923
  tag &= UnionDataTypeTagsConst;
9872
- return (tag & (tag - 1)) != 0;
9924
+ return (tag & (tag - 1)) !== 0;
9873
9925
  }
9874
9926
  function getObjectValue(t) {
9875
9927
  if (!(t.type & 32768 /* TypeTag.Object */) || t.value == null)
@@ -9903,7 +9955,7 @@ function forEachUnionComponent(v, bits, fn) {
9903
9955
  : bit & v.type
9904
9956
  ? v.value
9905
9957
  : null;
9906
- if (fn(bit, data) === false)
9958
+ if (fn({ type: bit, value: data }) === false)
9907
9959
  break;
9908
9960
  bits = next;
9909
9961
  } while (bits);
@@ -9945,27 +9997,30 @@ function getStateNodeDeclsFromType(state, object) {
9945
9997
  const decls = [];
9946
9998
  if (object.value != null &&
9947
9999
  object.type & (4096 /* TypeTag.Module */ | 16384 /* TypeTag.Class */ | 32768 /* TypeTag.Object */)) {
9948
- forEachUnionComponent(object, object.type & (4096 /* TypeTag.Module */ | 16384 /* TypeTag.Class */ | 32768 /* TypeTag.Object */), (tag, value) => {
9949
- if (!value)
10000
+ forEachUnionComponent(object, object.type & (4096 /* TypeTag.Module */ | 16384 /* TypeTag.Class */ | 32768 /* TypeTag.Object */), (type) => {
10001
+ if (type.value == null)
9950
10002
  return;
9951
- if (tag === 32768 /* TypeTag.Object */) {
9952
- const ovalue = value;
9953
- if (ovalue.klass.type === 16384 /* TypeTag.Class */ && ovalue.klass.value) {
9954
- if (Array.isArray(ovalue.klass.value)) {
9955
- decls.push(...ovalue.klass.value);
10003
+ switch (type.type) {
10004
+ case 32768 /* TypeTag.Object */:
10005
+ if (type.value.klass.type === 16384 /* TypeTag.Class */ &&
10006
+ type.value.klass.value) {
10007
+ if (Array.isArray(type.value.klass.value)) {
10008
+ decls.push(...type.value.klass.value);
10009
+ }
10010
+ else {
10011
+ decls.push(type.value.klass.value);
10012
+ }
10013
+ }
10014
+ break;
10015
+ case 4096 /* TypeTag.Module */:
10016
+ case 16384 /* TypeTag.Class */:
10017
+ if (Array.isArray(type.value)) {
10018
+ decls.push(...type.value);
9956
10019
  }
9957
10020
  else {
9958
- decls.push(ovalue.klass.value);
10021
+ decls.push(type.value);
9959
10022
  }
9960
- }
9961
- }
9962
- else {
9963
- if (Array.isArray(value)) {
9964
- decls.push(...value);
9965
- }
9966
- else {
9967
- decls.push(value);
9968
- }
10023
+ break;
9969
10024
  }
9970
10025
  });
9971
10026
  }
@@ -10014,15 +10069,15 @@ function couldBe(a, b) {
10014
10069
  return true;
10015
10070
  }
10016
10071
  let result = false;
10017
- forEachUnionComponent(a, common, (bit, avalue) => {
10018
- if (avalue == null) {
10072
+ forEachUnionComponent(a, common, (ac) => {
10073
+ if (ac.value == null) {
10019
10074
  result = true;
10020
10075
  return false;
10021
10076
  }
10022
- const bvalue = getUnionComponent(b, bit);
10077
+ const bvalue = getUnionComponent(b, ac.type);
10023
10078
  if (bvalue == null ||
10024
- avalue === bvalue ||
10025
- couldBeValue(bit, avalue, bvalue)) {
10079
+ ac.value === bvalue ||
10080
+ couldBeValue({ type: ac.type, avalue: ac.value, bvalue })) {
10026
10081
  result = true;
10027
10082
  return false;
10028
10083
  }
@@ -10077,13 +10132,13 @@ function couldBeWeak(a, b) {
10077
10132
  return true;
10078
10133
  return couldBe(a, b);
10079
10134
  }
10080
- function couldBeValue(bit, avalue, bvalue) {
10081
- switch (bit) {
10135
+ function couldBeValue(pair) {
10136
+ switch (pair.type) {
10082
10137
  case 1 /* TypeTag.Null */:
10083
10138
  case 2 /* TypeTag.False */:
10084
10139
  case 4 /* TypeTag.True */:
10085
10140
  case 262144 /* TypeTag.Typedef */:
10086
- throw new Error(`Unexpected TypeTag '${typeTagName(bit)}'`);
10141
+ throw new Error(`Unexpected TypeTag '${typeTagName(pair.type)}'`);
10087
10142
  case 8 /* TypeTag.Number */:
10088
10143
  case 16 /* TypeTag.Long */:
10089
10144
  case 32 /* TypeTag.Float */:
@@ -10091,34 +10146,27 @@ function couldBeValue(bit, avalue, bvalue) {
10091
10146
  case 256 /* TypeTag.String */:
10092
10147
  case 128 /* TypeTag.Char */:
10093
10148
  case 131072 /* TypeTag.Symbol */:
10094
- return avalue === bvalue;
10149
+ return pair.avalue === pair.bvalue;
10095
10150
  case 512 /* TypeTag.Array */:
10096
- return couldBe(avalue, bvalue);
10151
+ return couldBe(pair.avalue, pair.bvalue);
10097
10152
  case 1024 /* TypeTag.Dictionary */: {
10098
- const adict = avalue;
10099
- const bdict = bvalue;
10100
- return couldBe(adict.key, bdict.key) && couldBe(adict.value, bdict.value);
10153
+ return (couldBe(pair.avalue.key, pair.bvalue.key) &&
10154
+ couldBe(pair.avalue.value, pair.bvalue.value));
10101
10155
  }
10102
10156
  case 2048 /* TypeTag.Method */: {
10103
- const ameth = avalue;
10104
- const bmeth = bvalue;
10105
- return (ameth.args.length === bmeth.args.length &&
10106
- couldBe(ameth.result, bmeth.result) &&
10107
- ameth.args.every((arg, i) => couldBe(arg, bmeth.args[i])));
10157
+ return (pair.avalue.args.length === pair.bvalue.args.length &&
10158
+ couldBe(pair.avalue.result, pair.bvalue.result) &&
10159
+ pair.avalue.args.every((arg, i) => couldBe(arg, pair.bvalue.args[i])));
10108
10160
  }
10109
10161
  case 4096 /* TypeTag.Module */:
10110
10162
  case 8192 /* TypeTag.Function */: {
10111
- const asd = avalue;
10112
- const bsd = bvalue;
10113
10163
  // quadratic :-(
10114
- return (0,external_util_cjs_namespaceObject.some)(asd, (sna) => (0,external_util_cjs_namespaceObject.some)(bsd, (snb) => sna === snb));
10164
+ return (0,external_util_cjs_namespaceObject.some)(pair.avalue, (sna) => (0,external_util_cjs_namespaceObject.some)(pair.bvalue, (snb) => sna === snb));
10115
10165
  }
10116
10166
  case 16384 /* TypeTag.Class */: {
10117
- const asd = avalue;
10118
- const bsd = bvalue;
10119
- return (0,external_util_cjs_namespaceObject.some)(asd, (sna) => {
10167
+ return (0,external_util_cjs_namespaceObject.some)(pair.avalue, (sna) => {
10120
10168
  const superA = (0,external_api_cjs_namespaceObject.getSuperClasses)(sna);
10121
- return (0,external_util_cjs_namespaceObject.some)(bsd, (snb) => {
10169
+ return (0,external_util_cjs_namespaceObject.some)(pair.bvalue, (snb) => {
10122
10170
  if (sna === snb || (superA && superA.has(snb))) {
10123
10171
  return true;
10124
10172
  }
@@ -10128,18 +10176,17 @@ function couldBeValue(bit, avalue, bvalue) {
10128
10176
  });
10129
10177
  }
10130
10178
  case 32768 /* TypeTag.Object */: {
10131
- const aobj = avalue;
10132
- const bobj = bvalue;
10133
- return couldBe(aobj.klass, bobj.klass) && couldBeObj(aobj.obj, bobj.obj);
10179
+ return (couldBe(pair.avalue.klass, pair.bvalue.klass) &&
10180
+ couldBeObj(pair.avalue.obj, pair.bvalue.obj));
10134
10181
  }
10135
10182
  case 65536 /* TypeTag.Enum */: {
10136
- const aenum = avalue;
10137
- const benum = bvalue;
10138
- return (aenum.enum === benum.enum &&
10139
- (!aenum.value || !benum.value || couldBe(aenum.value, benum.value)));
10183
+ return (pair.avalue.enum === pair.bvalue.enum &&
10184
+ (!pair.avalue.value ||
10185
+ !pair.bvalue.value ||
10186
+ couldBe(pair.avalue.value, pair.bvalue.value)));
10140
10187
  }
10141
10188
  default:
10142
- unhandledType(bit);
10189
+ unhandledType(pair);
10143
10190
  }
10144
10191
  }
10145
10192
  function couldBeObj(a, b) {
@@ -10255,16 +10302,17 @@ function equalsCheck(left, right) {
10255
10302
  // Note that each type can only have a single bit set. This is important!
10256
10303
  const lrBits = left.type | right.type;
10257
10304
  return left.type & 120 /* TypeTag.Numeric */ && right.type & 120 /* TypeTag.Numeric */
10258
- ? left.value == right.value
10259
- : lrBits == (8 /* TypeTag.Number */ | 128 /* TypeTag.Char */)
10305
+ ? // eslint-disable-next-line eqeqeq
10306
+ left.value == right.value
10307
+ : lrBits === (8 /* TypeTag.Number */ | 128 /* TypeTag.Char */)
10260
10308
  ? // Char vs Number is true iff the number is the char-code of the char
10261
10309
  left.type === 128 /* TypeTag.Char */
10262
10310
  ? left.value.charCodeAt(0) === right.value
10263
10311
  : left.value === right.value.charCodeAt(0)
10264
- : left.type == 8 /* TypeTag.Number */ && right.type & 6 /* TypeTag.Boolean */
10265
- ? left.value == (right.value ? 1 : 0)
10266
- : right.type == 8 /* TypeTag.Number */ && left.type & 6 /* TypeTag.Boolean */
10267
- ? right.value == (left.value ? 1 : 0)
10312
+ : left.type === 8 /* TypeTag.Number */ && right.type & 6 /* TypeTag.Boolean */
10313
+ ? left.value === (right.value ? 1 : 0)
10314
+ : right.type === 8 /* TypeTag.Number */ && left.type & 6 /* TypeTag.Boolean */
10315
+ ? right.value === (left.value ? 1 : 0)
10268
10316
  : left.type !== right.type
10269
10317
  ? lrBits & 1 /* TypeTag.Null */
10270
10318
  ? lrBits & (32768 /* TypeTag.Object */ | 512 /* TypeTag.Array */ | 1024 /* TypeTag.Dictionary */)
@@ -10330,7 +10378,7 @@ function evaluateBinaryTypes(op, left, right) {
10330
10378
  "/": {
10331
10379
  allowed: 8 /* TypeTag.Number */ | 16 /* TypeTag.Long */ | 32 /* TypeTag.Float */ | 64 /* TypeTag.Double */,
10332
10380
  typeFn: common_types,
10333
- valueFn: (left, right) => right.value == 0 // "==" because it could be a bigint
10381
+ valueFn: (left, right) => Number(right.value) === 0
10334
10382
  ? { type: left.type }
10335
10383
  : left.type === 8 /* TypeTag.Number */
10336
10384
  ? {
@@ -10345,7 +10393,7 @@ function evaluateBinaryTypes(op, left, right) {
10345
10393
  "%": {
10346
10394
  allowed: 8 /* TypeTag.Number */ | 16 /* TypeTag.Long */,
10347
10395
  typeFn: common_types,
10348
- valueFn: (left, right) => right.value == 0 // "==" because it could be a bigint
10396
+ valueFn: (left, right) => Number(right.value) === 0
10349
10397
  ? { type: left.type }
10350
10398
  : {
10351
10399
  type: left.type,
@@ -11179,9 +11227,9 @@ function getLhsConstraint(istate, node) {
11179
11227
  }
11180
11228
  const object = istate.typeMap.get(node.object);
11181
11229
  if (object && !node.computed) {
11182
- const objDecls = findObjectDeclsByProperty(istate, object, node);
11183
- if (objDecls) {
11184
- lookupDefs = (0,external_api_cjs_namespaceObject.lookupNext)(istate.state, [{ parent: null, results: objDecls }], "decls", node.property);
11230
+ const [, trueDecls] = findObjectDeclsByProperty(istate.state, object, node);
11231
+ if (trueDecls) {
11232
+ lookupDefs = (0,external_api_cjs_namespaceObject.lookupNext)(istate.state, [{ parent: null, results: trueDecls }], "decls", node.property);
11185
11233
  }
11186
11234
  }
11187
11235
  }
@@ -11242,6 +11290,17 @@ function pushScopedNameType(istate, node, object) {
11242
11290
  node,
11243
11291
  });
11244
11292
  }
11293
+ function byteArrayType(state) {
11294
+ return {
11295
+ type: 32768 /* TypeTag.Object */,
11296
+ value: {
11297
+ klass: {
11298
+ type: 16384 /* TypeTag.Class */,
11299
+ value: lookupByFullName(state, "Toybox.Lang.ByteArray"),
11300
+ },
11301
+ },
11302
+ };
11303
+ }
11245
11304
  function evaluateNode(istate, node) {
11246
11305
  const { state, stack } = istate;
11247
11306
  const push = (item) => {
@@ -11268,7 +11327,9 @@ function evaluateNode(istate, node) {
11268
11327
  // garmin's type checker.
11269
11328
  if (subtypeOf(left.value, right.value) &&
11270
11329
  !subtypeOf({ type: 1 /* TypeTag.Null */ | 32768 /* TypeTag.Object */ }, right.value) &&
11271
- (!(left.value.type & 65536 /* TypeTag.Enum */) || right.value.type & 65536 /* TypeTag.Enum */)) {
11330
+ (!(left.value.type & 65536 /* TypeTag.Enum */) ||
11331
+ right.value.type & 65536 /* TypeTag.Enum */) &&
11332
+ !couldBe({ type: 512 /* TypeTag.Array */ | 1024 /* TypeTag.Dictionary */ }, left.value)) {
11272
11333
  push({
11273
11334
  value: left.value,
11274
11335
  embeddedEffects: left.embeddedEffects,
@@ -11280,7 +11341,7 @@ function evaluateNode(istate, node) {
11280
11341
  (0,external_api_cjs_namespaceObject.diagnostic)(istate.state, node, `The type ${display(left.value)} cannot be converted to ${display(right.value)} because they have nothing in common`, istate.checkTypes);
11281
11342
  }
11282
11343
  if (hasValue(right.value) && right.value.type === 65536 /* TypeTag.Enum */) {
11283
- if ((left.value.type & EnumTagsConst) == left.value.type) {
11344
+ if ((left.value.type & EnumTagsConst) === left.value.type) {
11284
11345
  const result = cloneType(right.value);
11285
11346
  result.value = { ...result.value, value: left.value };
11286
11347
  stack.push({
@@ -11299,7 +11360,7 @@ function evaluateNode(istate, node) {
11299
11360
  }
11300
11361
  else {
11301
11362
  if (istate.checkTypes &&
11302
- (node.operator === "==" || node.operator == "!=") &&
11363
+ (node.operator === "==" || node.operator === "!=") &&
11303
11364
  ((left.value.type === 1 /* TypeTag.Null */ &&
11304
11365
  !(right.value.type & 1 /* TypeTag.Null */)) ||
11305
11366
  (right.value.type === 1 /* TypeTag.Null */ &&
@@ -11339,7 +11400,10 @@ function evaluateNode(istate, node) {
11339
11400
  case "SizedArrayExpression": {
11340
11401
  const arg = popIstate(istate, node.size);
11341
11402
  let type = { type: 512 /* TypeTag.Array */ };
11342
- if (node.ts) {
11403
+ if (node.byte) {
11404
+ type = byteArrayType(state);
11405
+ }
11406
+ else if (node.ts) {
11343
11407
  type = typeFromSingleTypeSpec(istate.state, node.ts);
11344
11408
  if (type.type !== 512 /* TypeTag.Array */) {
11345
11409
  type = { type: 512 /* TypeTag.Array */, value: type };
@@ -11359,15 +11423,7 @@ function evaluateNode(istate, node) {
11359
11423
  const embeddedEffects = args.some((arg) => arg.embeddedEffects);
11360
11424
  if (node.byte) {
11361
11425
  push({
11362
- value: {
11363
- type: 32768 /* TypeTag.Object */,
11364
- value: {
11365
- klass: {
11366
- type: 16384 /* TypeTag.Class */,
11367
- value: lookupByFullName(state, "Toybox.Lang.ByteArray"),
11368
- },
11369
- },
11370
- },
11426
+ value: byteArrayType(state),
11371
11427
  embeddedEffects,
11372
11428
  node,
11373
11429
  });
@@ -11551,6 +11607,13 @@ function evaluateNode(istate, node) {
11551
11607
  node,
11552
11608
  });
11553
11609
  }
11610
+ else {
11611
+ push({
11612
+ value: { type: 1 /* TypeTag.Null */ },
11613
+ embeddedEffects: false,
11614
+ node,
11615
+ });
11616
+ }
11554
11617
  break;
11555
11618
  }
11556
11619
  case "AssignmentExpression": {
@@ -11869,7 +11932,7 @@ function getEquivSet(ts, k) {
11869
11932
  }
11870
11933
  keys.add(s);
11871
11934
  s = next.equivSet.next;
11872
- } while (s != k);
11935
+ } while (s !== k);
11873
11936
  return keys;
11874
11937
  }
11875
11938
  function intersectEquiv(ts1, ts2, k) {
@@ -11894,7 +11957,7 @@ function intersectEquiv(ts1, ts2, k) {
11894
11957
  removeEquiv(ts1, s);
11895
11958
  }
11896
11959
  s = next.equivSet.next;
11897
- } while (s != k);
11960
+ } while (s !== k);
11898
11961
  return ret;
11899
11962
  }
11900
11963
  function mergeTypeState(blockStates, blockVisits, index, from) {
@@ -11954,7 +12017,7 @@ function tsEquivs(state, key) {
11954
12017
  throw new Error(`Inconsistent equivSet for ${tsKey(key)}: missing value for ${tsKey(s)}`);
11955
12018
  }
11956
12019
  s = next.equivSet.next;
11957
- } while (s != key);
12020
+ } while (s !== key);
11958
12021
  return `[(${result.join(", ")})]`;
11959
12022
  }
11960
12023
  function typeStateEntry(value, key) {
@@ -11970,45 +12033,115 @@ function printBlockState(block, state, indent = "") {
11970
12033
  console.log(`${indent} - ${typeStateEntry(value, key)}${value.equivSet ? " " + tsEquivs(state, key) : ""}`);
11971
12034
  });
11972
12035
  }
11973
- function filterDecls(decls, possible) {
12036
+ /*
12037
+ * We have an object, and a MemberExpression object.<name>
12038
+ * - decls are the StateNodes associated with the known type
12039
+ * of object.
12040
+ * - possible are all the StateNodes that declare <name>
12041
+ *
12042
+ * We want to find all the elements of possible which are
12043
+ * "compatible" with decls, which tells us the set of things
12044
+ * that object.<name> could correspond to, and also what that
12045
+ * tells us about object.
12046
+ *
12047
+ * The return value is two arrays of StateNode. The first
12048
+ * gives the refined type of object, and the second is the
12049
+ * array of StateNodes that could declare <name>
12050
+ */
12051
+ function filterDecls(decls, possible, name) {
11974
12052
  if (!possible)
11975
- return null;
11976
- return decls.reduce((cur, decl) => {
12053
+ return [null, null];
12054
+ const result = decls.reduce((cur, decl) => {
11977
12055
  const found = possible.reduce((flag, poss) => {
11978
12056
  if (decl === poss ||
11979
- (poss.type === "ClassDeclaration" &&
11980
- (0,external_api_cjs_namespaceObject.getSuperClasses)(poss)?.has(decl)) ||
11981
- (decl.type === "ClassDeclaration" && (0,external_api_cjs_namespaceObject.getSuperClasses)(decl)?.has(poss))) {
11982
- if (!cur)
11983
- cur = [poss];
11984
- else
11985
- cur.push(poss);
12057
+ (poss.type === "ClassDeclaration" && (0,external_api_cjs_namespaceObject.getSuperClasses)(poss)?.has(decl))) {
12058
+ // poss extends decl, so decl must actually be a poss
12059
+ // eg we know obj is an Object, and we call obj.toNumber
12060
+ // so possible includes all the classes that declare toNumber
12061
+ // so we can refine obj's type to the union of those types
12062
+ if (!cur[0]) {
12063
+ cur = [new Set(), new Set()];
12064
+ }
12065
+ cur[0].add(poss);
12066
+ cur[1].add(poss);
12067
+ return true;
12068
+ }
12069
+ else if (decl.type === "ClassDeclaration" &&
12070
+ (0,external_api_cjs_namespaceObject.getSuperClasses)(decl)?.has(poss)) {
12071
+ // decl extends poss, so decl remains unchanged
12072
+ // eg we know obj is Menu2, we call obj.toString
12073
+ // Menu2 doesn't define toString, but Object does
12074
+ // so poss is Object. But we still know that
12075
+ // obj is Menu2
12076
+ if (!cur[0]) {
12077
+ cur = [new Set(), new Set()];
12078
+ }
12079
+ cur[0].add(decl);
12080
+ cur[1].add(poss);
11986
12081
  return true;
11987
12082
  }
11988
12083
  return flag;
11989
12084
  }, false);
11990
12085
  if (!found) {
11991
- possible.some((poss) => {
11992
- if (decl.stack?.some((sn) => sn.decls === poss.decls)) {
11993
- if (!cur)
11994
- cur = [poss];
11995
- else
11996
- cur.push(poss);
11997
- return true;
11998
- }
11999
- return false;
12000
- });
12086
+ // If we didn't find the property in any of the
12087
+ // standard places, the runtime might still find
12088
+ // it by searching up the Module stack (and up
12089
+ // the module stack from any super classes)
12090
+ //
12091
+ // eg
12092
+ //
12093
+ // obj = Application.getApp();
12094
+ // obj.Properties.whatever
12095
+ //
12096
+ // Properties doesn't exist on AppBase, but AppBase
12097
+ // is declared in Application, and Application
12098
+ // does declare Properties. So Application.Properties
12099
+ // is (one of) the declarations we should find; but we
12100
+ // must not refine obj's type to include Application.
12101
+ let d = [decl];
12102
+ do {
12103
+ d.forEach((d) => {
12104
+ const stack = d.stack;
12105
+ possible.forEach((poss) => {
12106
+ for (let i = stack.length; i--;) {
12107
+ const sn = stack[i];
12108
+ if (sn.decls === poss.decls) {
12109
+ if (!cur[0]) {
12110
+ cur = [new Set(), new Set()];
12111
+ }
12112
+ cur[0].add(decl);
12113
+ cur[1].add(poss);
12114
+ break;
12115
+ }
12116
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(sn.decls, name)) {
12117
+ break;
12118
+ }
12119
+ }
12120
+ });
12121
+ });
12122
+ d = d.flatMap((d) => {
12123
+ if (d.type !== "ClassDeclaration" ||
12124
+ !d.superClass ||
12125
+ d.superClass === true) {
12126
+ return [];
12127
+ }
12128
+ return d.superClass;
12129
+ });
12130
+ } while (d.length);
12001
12131
  }
12002
12132
  return cur;
12003
- }, null);
12133
+ }, [null, null]);
12134
+ if (!result[0])
12135
+ return [null, null];
12136
+ return [Array.from(result[0]), Array.from(result[1])];
12004
12137
  }
12005
- function findObjectDeclsByProperty(istate, object, next) {
12006
- const decls = getStateNodeDeclsFromType(istate.state, object);
12138
+ function findObjectDeclsByProperty(state, object, next) {
12139
+ const decls = getStateNodeDeclsFromType(state, object);
12007
12140
  if (!decls)
12008
- return null;
12009
- const possibleDecls = (0,external_api_cjs_namespaceObject.hasProperty)(istate.state.allDeclarations, next.property.name) &&
12010
- istate.state.allDeclarations[next.property.name];
12011
- return filterDecls(decls, possibleDecls);
12141
+ return [null, null];
12142
+ const possibleDecls = (0,external_api_cjs_namespaceObject.hasProperty)(state.allDeclarations, next.property.name) &&
12143
+ state.allDeclarations[next.property.name];
12144
+ return filterDecls(decls, possibleDecls, next.property.name);
12012
12145
  }
12013
12146
  function refineObjectTypeByDecls(istate, object, trueDecls) {
12014
12147
  const refinedType = typeFromTypeStateNodes(istate.state, trueDecls);
@@ -12024,13 +12157,13 @@ function findNextObjectType(istate, trueDecls, next) {
12024
12157
  }, { type: 0 /* TypeTag.Never */ });
12025
12158
  }
12026
12159
  function resolveDottedMember(istate, object, next) {
12027
- const decls = findObjectDeclsByProperty(istate, object, next);
12028
- if (!decls)
12160
+ const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, object, next);
12161
+ if (!objDecls)
12029
12162
  return null;
12030
- const property = findNextObjectType(istate, decls, next);
12163
+ const property = findNextObjectType(istate, trueDecls, next);
12031
12164
  if (!property)
12032
12165
  return null;
12033
- const type = refineObjectTypeByDecls(istate, object, decls);
12166
+ const type = refineObjectTypeByDecls(istate, object, objDecls);
12034
12167
  const mayThrow = !subtypeOf(object, type);
12035
12168
  return { mayThrow, object: type, property };
12036
12169
  }
@@ -12067,12 +12200,11 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
12067
12200
  next = value.obj[me.property.name];
12068
12201
  }
12069
12202
  else {
12070
- const trueDecls = findObjectDeclsByProperty(istate, cur, me);
12071
- if (!trueDecls ||
12072
- (0,external_util_cjs_namespaceObject.some)(trueDecls, (decl) => decl.type !== "ClassDeclaration")) {
12203
+ const [objDecls, trueDecls] = findObjectDeclsByProperty(istate.state, cur, me);
12204
+ if (!objDecls) {
12073
12205
  return null;
12074
12206
  }
12075
- cur = refineObjectTypeByDecls(istate, cur, trueDecls);
12207
+ cur = refineObjectTypeByDecls(istate, cur, objDecls);
12076
12208
  next = findNextObjectType(istate, trueDecls, me);
12077
12209
  }
12078
12210
  }
@@ -12389,10 +12521,10 @@ function propagateTypes(state, func, graph, optimizeEquivalencies, logThisRun) {
12389
12521
  type: 32768 /* TypeTag.Object */,
12390
12522
  value: leftValue,
12391
12523
  });
12392
- const leftReduced = leftDecls.filter((ldec) => !rightDecls.every((rdec) => ldec == rdec ||
12524
+ const leftReduced = leftDecls.filter((ldec) => !rightDecls.every((rdec) => ldec === rdec ||
12393
12525
  (ldec.type === "ClassDeclaration" &&
12394
12526
  (0,external_api_cjs_namespaceObject.getSuperClasses)(ldec)?.has(rdec))));
12395
- if (leftReduced.length != leftDecls.length) {
12527
+ if (leftReduced.length !== leftDecls.length) {
12396
12528
  result = cloneType(left);
12397
12529
  clearValuesUnder(result, 32768 /* TypeTag.Object */, true);
12398
12530
  if (leftReduced.length) {
@@ -13033,7 +13165,15 @@ function beforeEvaluate(istate, node) {
13033
13165
  break;
13034
13166
  }
13035
13167
  case "ForStatement": {
13036
- if (node.init?.type === "Literal") {
13168
+ if (node.update?.type === "Literal" ||
13169
+ (node.update?.type === "SequenceExpression" &&
13170
+ node.update.expressions.length === 0)) {
13171
+ popIstate(istate, node.update);
13172
+ delete node.update;
13173
+ }
13174
+ if (node.init?.type === "Literal" ||
13175
+ (node.init?.type === "SequenceExpression" &&
13176
+ node.init.expressions.length === 0)) {
13037
13177
  delete node.init;
13038
13178
  const depth = -1 - (node.update ? 1 : 0) - (node.test ? 1 : 0);
13039
13179
  istate.stack.splice(depth, 1);
@@ -13057,7 +13197,7 @@ function beforeEvaluate(istate, node) {
13057
13197
  for (let i = node.expressions.length; i--;) {
13058
13198
  const expr = node.expressions[i];
13059
13199
  if (expr.type === "Literal") {
13060
- istate.stack.splice(i - node.expressions.length);
13200
+ istate.stack.splice(i - node.expressions.length, 1);
13061
13201
  node.expressions.splice(i, 1);
13062
13202
  }
13063
13203
  }
@@ -13411,7 +13551,7 @@ function cleanupUnusedVars(state, node) {
13411
13551
  if (parent.node !== node) {
13412
13552
  return false;
13413
13553
  }
13414
- if (parent.type != "BlockStatement") {
13554
+ if (parent.type !== "BlockStatement") {
13415
13555
  throw new Error(`Unexpected parent type '${parent.type}' for local declaration`);
13416
13556
  }
13417
13557
  if (!parent.decls)
@@ -13767,14 +13907,14 @@ async function analyze(fnMap, resourcesMap, manifestXML, config) {
13767
13907
  const excludeAnnotations = fnMap[node.loc.source].excludeAnnotations;
13768
13908
  if (excludeAnnotations) {
13769
13909
  return node.attrs.attributes.elements.reduce((drop, attr) => {
13770
- if (attr.type != "UnaryExpression")
13910
+ if (attr.type !== "UnaryExpression")
13771
13911
  return drop;
13772
- if (attr.argument.type != "Identifier")
13912
+ if (attr.argument.type !== "Identifier")
13773
13913
  return drop;
13774
13914
  if ((0,external_api_cjs_namespaceObject.hasProperty)(excludeAnnotations, attr.argument.name)) {
13775
13915
  return true;
13776
13916
  }
13777
- if (attr.argument.name == "test") {
13917
+ if (attr.argument.name === "test") {
13778
13918
  hasTests = true;
13779
13919
  }
13780
13920
  return drop;
@@ -13790,7 +13930,7 @@ async function analyze(fnMap, resourcesMap, manifestXML, config) {
13790
13930
  case "ClassDeclaration": {
13791
13931
  const [scope] = state.stack.slice(-1);
13792
13932
  scope.stack = state.stackClone().slice(0, -1);
13793
- if (scope.type == "FunctionDeclaration") {
13933
+ if (scope.type === "FunctionDeclaration") {
13794
13934
  if (markApi) {
13795
13935
  node.body = null;
13796
13936
  scope.info = (0,external_api_cjs_namespaceObject.getApiFunctionInfo)(state, scope);
@@ -13956,7 +14096,7 @@ function optimizeNode(istate, node) {
13956
14096
  function evaluateFunction(istate, func, args) {
13957
14097
  if (!func.body ||
13958
14098
  istate.state.inlining ||
13959
- (args && args.length != func.params.length)) {
14099
+ (args && args.length !== func.params.length)) {
13960
14100
  return false;
13961
14101
  }
13962
14102
  const paramValues = args &&
@@ -14051,11 +14191,11 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
14051
14191
  if (func.attrs &&
14052
14192
  func.attrs.attributes &&
14053
14193
  func.attrs.attributes.elements.some((attr) => {
14054
- if (attr.type != "UnaryExpression")
14194
+ if (attr.type !== "UnaryExpression")
14055
14195
  return false;
14056
- if (attr.argument.type != "Identifier")
14196
+ if (attr.argument.type !== "Identifier")
14057
14197
  return false;
14058
- return attr.argument.name == "test";
14198
+ return attr.argument.name === "test";
14059
14199
  })) {
14060
14200
  return true;
14061
14201
  }
@@ -14072,7 +14212,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
14072
14212
  (elm.superClass != null &&
14073
14213
  elm.superClass.some((sc) => ((0,external_api_cjs_namespaceObject.hasProperty)(sc.decls, name) &&
14074
14214
  sc.decls[name].some((f) => (0,external_api_cjs_namespaceObject.isStateNode)(f) &&
14075
- f.type == "FunctionDeclaration" &&
14215
+ f.type === "FunctionDeclaration" &&
14076
14216
  maybeCalled(f.node))) ||
14077
14217
  (sc.superClass && checkInherited(sc, name))));
14078
14218
  const renamer = (idnode) => {
@@ -14255,7 +14395,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
14255
14395
  }
14256
14396
  state.currentFunction = self;
14257
14397
  const is = !state.config?.propagateTypes ||
14258
- node.attrs?.attributes?.elements.find((attr) => attr.type == "UnaryExpression" &&
14398
+ node.attrs?.attributes?.elements.find((attr) => attr.type === "UnaryExpression" &&
14259
14399
  attr.argument.name === "noConstProp")
14260
14400
  ? null
14261
14401
  : type_flow_buildTypeInfo(state, state.currentFunction, true);
@@ -14276,9 +14416,9 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
14276
14416
  }
14277
14417
  istate = is;
14278
14418
  }
14279
- if (parent.type == "ClassDeclaration" && !maybeCalled(node)) {
14419
+ if (parent.type === "ClassDeclaration" && !maybeCalled(node)) {
14280
14420
  let used = false;
14281
- if (node.id.name == "initialize") {
14421
+ if (node.id.name === "initialize") {
14282
14422
  used = true;
14283
14423
  }
14284
14424
  else if (parent.superClass) {
@@ -14395,7 +14535,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
14395
14535
  const inlined = optimizeCallHelper(istate, call, decl);
14396
14536
  if (!inlined)
14397
14537
  continue;
14398
- if (Array.isArray(inlined) || inlined.type != "BlockStatement") {
14538
+ if (Array.isArray(inlined) || inlined.type !== "BlockStatement") {
14399
14539
  throw new Error("Unexpected inlined result");
14400
14540
  }
14401
14541
  if (!results) {
@@ -14435,7 +14575,7 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
14435
14575
  ok = true;
14436
14576
  }
14437
14577
  }
14438
- if (!ok && node.expression.operator == "=") {
14578
+ if (!ok && node.expression.operator === "=") {
14439
14579
  const [, result] = state.lookup(node.expression.left);
14440
14580
  ok = !!result;
14441
14581
  }
@@ -14588,6 +14728,22 @@ async function optimizeMonkeyC(fnMap, resourcesMap, manifestXML, config) {
14588
14728
  });
14589
14729
  });
14590
14730
  reportMissingSymbols(state, config);
14731
+ if (state.inlineDiagnostics) {
14732
+ if (!state.diagnostics) {
14733
+ state.diagnostics = state.inlineDiagnostics;
14734
+ }
14735
+ else {
14736
+ Object.entries(state.inlineDiagnostics).forEach(([key, diags]) => {
14737
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.diagnostics, key)) {
14738
+ state.diagnostics[key] = diags;
14739
+ }
14740
+ else {
14741
+ state.diagnostics[key].push(...diags);
14742
+ }
14743
+ });
14744
+ }
14745
+ delete state.inlineDiagnostics;
14746
+ }
14591
14747
  Object.entries(fnMap).forEach(([name, f]) => {
14592
14748
  if (state.config && state.config.checkBuildPragmas) {
14593
14749
  pragmaChecker(state, f.ast, state.diagnostics?.[name]);
@@ -14625,7 +14781,7 @@ function optimizeCall(istate, node, context) {
14625
14781
  if (state.currentFunction) {
14626
14782
  recordCalledFuncs(state.currentFunction, callees);
14627
14783
  }
14628
- if (callees.length == 1 && callees[0].type === "FunctionDeclaration") {
14784
+ if (callees.length === 1 && callees[0].type === "FunctionDeclaration") {
14629
14785
  const callee = callees[0].node;
14630
14786
  if (!context &&
14631
14787
  callee.optimizable &&
@@ -14826,7 +14982,7 @@ async function createLocalBarrels(targets, options) {
14826
14982
  }
14827
14983
  if (optBarrels[barrel].manifest !== manifest ||
14828
14984
  optBarrels[barrel].optBarrelDir !== optBarrelDir ||
14829
- optBarrels[barrel].rawBarrelDir != rawBarrelDir) {
14985
+ optBarrels[barrel].rawBarrelDir !== rawBarrelDir) {
14830
14986
  throw new Error(`For device ${target.product}, barrel ${barrel} was mapped to both ${external_path_.relative(optBarrels[barrel].rawBarrelDir, optBarrels[barrel].manifest)} in ${optBarrels[barrel].rawBarrelDir} and ${external_path_.relative(rawBarrelDir, manifest)} in ${rawBarrelDir}.`);
14831
14987
  }
14832
14988
  optBarrels[barrel].jungleFiles.push(...rawJungles);
@@ -15160,16 +15316,16 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
15160
15316
  if (hasTests != null &&
15161
15317
  !config.checkBuildPragmas &&
15162
15318
  configOptionsToCheck.every((option) => prevOptions[option] === config[option]) &&
15163
- actualOptimizedFiles.length == Object.values(fnMap).length &&
15319
+ actualOptimizedFiles.length === Object.values(fnMap).length &&
15164
15320
  Object.values(fnMap)
15165
15321
  .map((v) => v.output)
15166
15322
  .sort()
15167
- .every((f, i) => f == actualOptimizedFiles[i])) {
15323
+ .every((f, i) => f === actualOptimizedFiles[i])) {
15168
15324
  // now if the newest source file is older than
15169
15325
  // the oldest optimized file, we don't need to regenerate
15170
15326
  const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
15171
15327
  const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
15172
- if (source_time < opt_time && 1674436813829 < opt_time) {
15328
+ if (source_time < opt_time && 1674683508654 < opt_time) {
15173
15329
  return { hasTests, diagnostics: prevDiagnostics };
15174
15330
  }
15175
15331
  }
@@ -15196,7 +15352,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
15196
15352
  return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
15197
15353
  hasTests,
15198
15354
  diagnostics,
15199
- optimizerVersion: "1.1.3",
15355
+ optimizerVersion: "1.1.5",
15200
15356
  ...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
15201
15357
  }))
15202
15358
  .then(() => ({ hasTests, diagnostics }));
@@ -15249,6 +15405,7 @@ async function getProjectAnalysis(targets, analysis, manifestXML, options) {
15249
15405
  });
15250
15406
  const state = await analyze(fnMap, resourcesMap, manifestXML, options);
15251
15407
  reportMissingSymbols(state, options);
15408
+ let typeMap = null;
15252
15409
  if (state.config?.propagateTypes &&
15253
15410
  state.config.trustDeclaredTypes &&
15254
15411
  state.config.checkTypes !== "OFF" &&
@@ -15271,6 +15428,14 @@ async function getProjectAnalysis(targets, analysis, manifestXML, options) {
15271
15428
  istate.typeChecker = gistate.typeChecker;
15272
15429
  istate.checkTypes = gistate.checkTypes;
15273
15430
  interp_evaluate(istate, node.body);
15431
+ if (istate.typeMap) {
15432
+ if (typeMap == null) {
15433
+ typeMap = istate.typeMap;
15434
+ }
15435
+ else {
15436
+ istate.typeMap.forEach((value, key) => typeMap.set(key, value));
15437
+ }
15438
+ }
15274
15439
  }
15275
15440
  return [];
15276
15441
  }
@@ -15280,8 +15445,9 @@ async function getProjectAnalysis(targets, analysis, manifestXML, options) {
15280
15445
  Object.values(state.fnMap).forEach((f) => {
15281
15446
  (0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
15282
15447
  });
15448
+ delete state.pre;
15283
15449
  }
15284
- return { fnMap: fnMap, paths, state };
15450
+ return { fnMap: fnMap, paths, state, typeMap };
15285
15451
  }
15286
15452
  /**
15287
15453
  *
@@ -15300,7 +15466,7 @@ async function generateApiMirTests(options) {
15300
15466
  Object.entries(node.decls).forEach(([key, decl]) => {
15301
15467
  if (decl.length > 1)
15302
15468
  throw `Bad decl length:${node.fullName}.${key}`;
15303
- if (decl.length != 1)
15469
+ if (decl.length !== 1)
15304
15470
  return;
15305
15471
  const d = decl[0];
15306
15472
  if (d.type === "EnumStringMember" ||