@markw65/monkeyc-optimizer 1.1.83 → 1.1.84

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.
@@ -26,8 +26,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var chunk_UNU55JJ3_exports = {};
30
- __export(chunk_UNU55JJ3_exports, {
29
+ var chunk_ZWQB5L34_exports = {};
30
+ __export(chunk_ZWQB5L34_exports, {
31
31
  EnumTagsConst: () => EnumTagsConst,
32
32
  LastTypeTag: () => LastTypeTag,
33
33
  ObjectLikeTagsConst: () => ObjectLikeTagsConst,
@@ -40,6 +40,7 @@ __export(chunk_UNU55JJ3_exports, {
40
40
  buildConfigDescription: () => buildConfigDescription,
41
41
  buildOptimizedProject: () => buildOptimizedProject,
42
42
  checkCompilerVersion: () => checkCompilerVersion,
43
+ clearDiagnostics: () => clearDiagnostics,
43
44
  collectNamespaces: () => collectNamespaces,
44
45
  connectiq: () => connectiq,
45
46
  couldBe: () => couldBe,
@@ -139,7 +140,7 @@ __export(chunk_UNU55JJ3_exports, {
139
140
  visitorNode: () => visitorNode,
140
141
  xml_util_exports: () => xml_util_exports
141
142
  });
142
- module.exports = __toCommonJS(chunk_UNU55JJ3_exports);
143
+ module.exports = __toCommonJS(chunk_ZWQB5L34_exports);
143
144
  var import_chunk_X7QCZR3F = require("./chunk-X7QCZR3F.cjs");
144
145
  var import_chunk_JDC43A3I = require("./chunk-JDC43A3I.cjs");
145
146
  var import_chunk_ABYVSU2C = require("./chunk-ABYVSU2C.cjs");
@@ -5728,7 +5729,7 @@ var init_build_config = (0, import_chunk_ABYVSU2C.__esm)({
5728
5729
  },
5729
5730
  extraReferenceTypeChecks: {
5730
5731
  type: "boolean",
5731
- description: "Whether to warn about [unsafe operations on Arrays and Dictionaries](https://github.com/markw65/monkeyc-optimizer/wiki/Extra-Reference-Type-Checks-(prettierMonkeyC.extraReferenceTypeChecks)) that Garmin's compiler allows",
5732
+ markdownDescription: "Whether to warn about [unsafe operations on Arrays and Dictionaries](https://github.com/markw65/monkeyc-optimizer/wiki/Extra-Reference-Type-Checks-(prettierMonkeyC.extraReferenceTypeChecks)) that Garmin's compiler allows",
5732
5733
  default: true,
5733
5734
  scope: "resource"
5734
5735
  },
@@ -6923,8 +6924,8 @@ function pragmaChecker(state, ast, diagnostics) {
6923
6924
  }
6924
6925
  if (node.start && node.start >= (comment.end || Infinity)) {
6925
6926
  const { kind, quote, needle } = matchers.shift();
6927
+ const thisComment = comment;
6926
6928
  if (kind === "match") {
6927
- const thisComment = comment;
6928
6929
  promise = promise.then(
6929
6930
  () => formatAstLongLines(node).then((haystack) => {
6930
6931
  haystack = haystack.replace(/([\r\n]|\s)+/g, " ").replace(/\b\w+\s\/\*>([\w.]+)<\*\//g, "$1");
@@ -6979,7 +6980,7 @@ function pragmaChecker(state, ast, diagnostics) {
6979
6980
  if (!found) {
6980
6981
  diagnostic(
6981
6982
  state,
6982
- comment,
6983
+ thisComment,
6983
6984
  `Missing error message '${needle}`,
6984
6985
  "ERROR"
6985
6986
  );
@@ -7618,723 +7619,291 @@ var init_control_flow = (0, import_chunk_ABYVSU2C.__esm)({
7618
7619
  };
7619
7620
  }
7620
7621
  });
7621
- function unionInto(to, from) {
7622
- return unionHelper(to, from, -Infinity);
7622
+ function expandTypedef(t) {
7623
+ const decls = getUnionComponent(
7624
+ t,
7625
+ 262144
7626
+ /* Typedef */
7627
+ );
7628
+ const tExpanded = cloneType(t);
7629
+ clearValuesUnder(tExpanded, 262144, true);
7630
+ (0, import_chunk_X7QCZR3F.forEach)(decls, (decl) => unionInto(tExpanded, decl.resolvedType));
7631
+ return tExpanded;
7623
7632
  }
7624
- function unionHelper(to, from, widenDepth) {
7625
- if (to == null || from == null) {
7626
- throw new Error("Null");
7633
+ function intersectEnum(t, e) {
7634
+ const enumData = getUnionComponent(
7635
+ e,
7636
+ 65536
7637
+ /* Enum */
7638
+ );
7639
+ const e2 = cloneType(e);
7640
+ const i = intersection(t, typeFromEnumValue(enumData));
7641
+ if (e2.value != null) {
7642
+ clearValuesUnder(e2, 65536, true);
7643
+ } else {
7644
+ e2.type &= ~65536;
7627
7645
  }
7628
- if (from.type === 0 || to === from)
7629
- return false;
7630
- if (to.type === 0) {
7631
- to.type = from.type;
7632
- to.value = from.value;
7633
- return true;
7646
+ const rest = intersection(t, e2);
7647
+ if (i.type === 0) {
7648
+ return rest;
7634
7649
  }
7635
- const newTags = to.type | from.type;
7636
- if (!(from.type & ~SingletonTypeTagsConst)) {
7637
- if (newTags === to.type)
7638
- return false;
7639
- to.type = newTags;
7640
- return true;
7650
+ const result = enumData ? { type: 65536, value: { ...enumData, value: i } } : cloneType(i);
7651
+ unionInto(result, rest);
7652
+ return result;
7653
+ }
7654
+ function intersection(a, b) {
7655
+ if (a.type & 262144 && a.value != null) {
7656
+ return intersection(expandTypedef(a), b);
7641
7657
  }
7642
- if (newTags === to.type) {
7643
- if (to.value === from.value || to.value == null) {
7644
- return false;
7645
- }
7646
- if (from.value == null) {
7647
- clearValuesUnder(to, from.type);
7648
- return true;
7649
- }
7650
- return mergeMultiple(to, from, widenDepth);
7658
+ if (b.type & 262144 && b.value != null) {
7659
+ return intersection(a, expandTypedef(b));
7651
7660
  }
7652
- if (to.value != null) {
7653
- if (from.value == null) {
7654
- clearValuesUnder(to, from.type);
7655
- return true;
7661
+ let common = a.type & b.type & ~262144;
7662
+ if (a.type & 32768 && b.type & ObjectLikeTagsConst && getObjectValue(a) == null) {
7663
+ common |= b.type & ObjectLikeTagsConst;
7664
+ }
7665
+ if (b.type & 32768 && a.type & ObjectLikeTagsConst && getObjectValue(b) == null) {
7666
+ common |= a.type & ObjectLikeTagsConst;
7667
+ }
7668
+ if (a.type & 65536 && b.type & EnumTagsConst && !(b.type & 65536)) {
7669
+ return intersectEnum(b, a);
7670
+ }
7671
+ if (b.type & 65536 && a.type & EnumTagsConst && !(a.type & 65536)) {
7672
+ return intersectEnum(a, b);
7673
+ }
7674
+ if (!common) {
7675
+ return {
7676
+ type: 0
7677
+ /* Never */
7678
+ };
7679
+ }
7680
+ if (a.value == null) {
7681
+ if (b.value == null) {
7682
+ return { type: common };
7656
7683
  }
7657
- mergeMultiple(to, from, widenDepth);
7658
- return true;
7684
+ const result2 = cloneType(b);
7685
+ clearValuesUnder(result2, b.type & ~common, true);
7686
+ return result2;
7659
7687
  }
7660
- if (from.value == null) {
7661
- to.type = newTags;
7662
- return true;
7688
+ if (b.value == null) {
7689
+ const result2 = cloneType(a);
7690
+ clearValuesUnder(result2, a.type & ~common, true);
7691
+ return result2;
7663
7692
  }
7664
- const tmp = cloneType(from);
7665
- clearValuesUnder(tmp, to.type);
7666
- to.type = tmp.type;
7667
- to.value = tmp.value;
7668
- return true;
7669
- }
7670
- function mergeMultiple(to, from, widenDepth) {
7671
- const newTags = to.type | from.type;
7672
- let anyChanged = newTags !== to.type;
7673
7693
  let mask = 0;
7674
7694
  const result = {};
7675
- forEachUnionComponent(to, newTags, (ac) => {
7676
- const fromv = getUnionComponent(from, ac.type);
7677
- if (ac.value != null) {
7678
- if (fromv != null) {
7679
- const [value2, changed] = ac.value === fromv ? [fromv, false] : mergeSingle(
7680
- {
7681
- type: ac.type,
7682
- avalue: ac.value,
7683
- bvalue: fromv
7684
- },
7685
- widenDepth
7686
- );
7687
- if (changed)
7688
- anyChanged = true;
7689
- if (value2) {
7690
- mask |= ac.type;
7691
- result[ac.type] = value2;
7692
- }
7693
- } else if (!(from.type & ac.type)) {
7694
- mask |= ac.type;
7695
- result[ac.type] = ac.value;
7696
- } else {
7697
- anyChanged = true;
7698
- }
7699
- } else if (fromv && !(to.type & ac.type)) {
7700
- anyChanged = true;
7695
+ forEachUnionComponent(a, common, (ac) => {
7696
+ const bvalue = getUnionComponent(b, ac.type);
7697
+ if (ac.value == null) {
7698
+ if (!bvalue)
7699
+ return;
7700
+ result[ac.type] = bvalue;
7701
7701
  mask |= ac.type;
7702
- result[ac.type] = fromv;
7702
+ return;
7703
+ }
7704
+ if (bvalue === null || ac.value === bvalue) {
7705
+ result[ac.type] = ac.value;
7706
+ mask |= ac.type;
7707
+ return;
7708
+ }
7709
+ const ivalue = intersectionValue({
7710
+ type: ac.type,
7711
+ avalue: ac.value,
7712
+ bvalue
7713
+ });
7714
+ if (ivalue != null) {
7715
+ result[ac.type] = ivalue;
7716
+ mask |= ac.type;
7717
+ return;
7718
+ } else {
7719
+ common -= ac.type;
7703
7720
  }
7704
7721
  });
7705
- if (!anyChanged)
7706
- return false;
7707
- to.type = newTags;
7708
- if (!mask) {
7709
- delete to.value;
7710
- return true;
7711
- }
7712
- if (hasUnionData(newTags)) {
7713
- to.value = result;
7714
- to.value.mask = mask;
7715
- return true;
7722
+ if (!mask)
7723
+ return { type: common };
7724
+ if (hasUnionData(common)) {
7725
+ return { type: common, value: { ...result, mask } };
7716
7726
  }
7717
7727
  if (mask & mask - 1) {
7718
- throw new Error("Union incorrectly produced a UnionData");
7728
+ throw new Error(
7729
+ `Mask with non-union data had more than one bit set: ${mask}`
7730
+ );
7719
7731
  }
7720
- to.value = result[mask];
7721
- return true;
7732
+ return { type: common, value: result[mask] };
7722
7733
  }
7723
- function mergeSingle(pair, widenDepth) {
7724
- function tryUnion(to, from) {
7725
- to = cloneType(to);
7726
- if (unionHelper(to, from, widenDepth + 1))
7727
- return to;
7728
- return null;
7729
- }
7734
+ function intersectionValue(pair) {
7730
7735
  switch (pair.type) {
7731
7736
  case 1:
7732
7737
  case 2:
7733
7738
  case 4:
7734
- throw new Error("Unexpected TypeTag in mergeSingle");
7739
+ case 262144:
7740
+ throw new Error(`Unexpected TypeTag '${typeTagName(pair.type)}'`);
7735
7741
  case 8:
7736
7742
  case 16:
7737
7743
  case 32:
7738
7744
  case 64:
7739
- case 128:
7740
7745
  case 256:
7746
+ case 128:
7741
7747
  case 131072:
7742
- return [null, true];
7743
- case 512: {
7744
- if (widenDepth > MaxWidenDepth) {
7745
- return [null, true];
7746
- }
7747
- const tupleTypes = /* @__PURE__ */ new Map();
7748
- const arrayTypes = [];
7749
- tupleForEach(
7748
+ return pair.avalue === pair.bvalue ? pair.avalue : null;
7749
+ case 512:
7750
+ return tupleMap(
7750
7751
  pair.avalue,
7751
- (v) => {
7752
- const t = tupleTypes.get(v.length);
7753
- if (t) {
7754
- t.push(v);
7755
- } else {
7756
- tupleTypes.set(v.length, [v]);
7757
- }
7758
- },
7759
- (v) => arrayTypes.push(v)
7752
+ (av) => tupleMap(
7753
+ pair.bvalue,
7754
+ (bv) => {
7755
+ if (av.length !== bv.length)
7756
+ return null;
7757
+ const isect = av.map((t, i) => intersection(t, bv[i]));
7758
+ return isect.some(
7759
+ (t) => t.type === 0
7760
+ /* Never */
7761
+ ) ? null : isect;
7762
+ },
7763
+ (bv) => {
7764
+ const isect = av.map((t) => intersection(bv, t));
7765
+ return isect.some(
7766
+ (t) => t.type === 0
7767
+ /* Never */
7768
+ ) ? null : isect;
7769
+ },
7770
+ (bv) => bv.length === 0 ? null : bv
7771
+ ),
7772
+ (av) => tupleMap(
7773
+ pair.bvalue,
7774
+ (bv) => {
7775
+ const isect = bv.map((t) => intersection(av, t));
7776
+ return isect.some(
7777
+ (t) => t.type === 0
7778
+ /* Never */
7779
+ ) ? null : isect;
7780
+ },
7781
+ (bv) => {
7782
+ const atype = intersection(av, bv);
7783
+ return atype.type === 0 ? null : atype;
7784
+ },
7785
+ (bv) => bv.length === 0 ? null : bv
7786
+ ),
7787
+ (av) => {
7788
+ const result = av.flat(1);
7789
+ return result.length === 0 ? null : tupleReduce(result);
7790
+ }
7760
7791
  );
7761
- const extraTypes = [];
7762
- tupleForEach(
7763
- pair.bvalue,
7764
- (v) => {
7765
- const tuples = tupleTypes.get(v.length);
7766
- if (!tuples?.some(
7767
- (t) => t.every((at, i) => {
7768
- const bt = v[i];
7769
- return subtypeOf(at, bt) && subtypeOf(bt, at);
7770
- })
7771
- )) {
7772
- extraTypes.push(v);
7773
- }
7774
- },
7775
- (v) => {
7776
- if (!arrayTypes.some((at) => subtypeOf(at, v) && subtypeOf(v, at))) {
7777
- extraTypes.push(v);
7778
- }
7779
- }
7780
- );
7781
- if (extraTypes.length) {
7782
- if (widenDepth >= 0) {
7783
- return [null, true];
7784
- }
7785
- const allTypes = (pair.avalue instanceof Set ? Array.from(pair.avalue) : [pair.avalue]).concat(extraTypes);
7786
- return [tupleReduce(allTypes), true];
7787
- }
7788
- return [pair.avalue, false];
7789
- }
7790
7792
  case 1024: {
7791
- if (widenDepth > MaxWidenDepth) {
7792
- return [null, true];
7793
- }
7794
- const avalue = pair.avalue;
7795
- const bvalue = pair.bvalue;
7796
- if (!avalue.value) {
7797
- if (!bvalue.value) {
7798
- const result = new Map(avalue);
7799
- let merged = false;
7800
- result.forEach((av, key2) => {
7801
- const bv = bvalue.get(key2);
7802
- if (!bv) {
7803
- result.delete(key2);
7804
- merged = true;
7805
- return;
7793
+ if (!pair.avalue.value) {
7794
+ if (!pair.bvalue.value) {
7795
+ const result = new Map(pair.avalue);
7796
+ pair.bvalue.forEach((bv, key) => {
7797
+ const av = result.get(key);
7798
+ if (av) {
7799
+ bv = intersection(bv, av);
7806
7800
  }
7807
- av = cloneType(av);
7808
- if (unionHelper(av, bv, widenDepth + 1))
7809
- merged = true;
7810
- result.set(key2, av);
7801
+ result.set(key, bv);
7811
7802
  });
7812
- return [result, merged];
7803
+ return result;
7813
7804
  } else {
7814
- const result = new Map(avalue);
7815
- let merged = false;
7816
- result.forEach((av, key2) => {
7817
- const keyType = typeFromObjectLiteralKey(key2);
7818
- if (couldBe(keyType, bvalue.key)) {
7819
- const bv = tryUnion(av, bvalue.value);
7820
- if (bv) {
7821
- result.set(key2, bv);
7822
- merged = true;
7823
- }
7824
- }
7825
- });
7826
- return [result, merged];
7805
+ return pair.bvalue;
7827
7806
  }
7828
- } else if (!bvalue.value) {
7829
- const result = new Map(bvalue);
7830
- let merged = false;
7831
- result.forEach((bv, key2) => {
7832
- const keyType = typeFromObjectLiteralKey(key2);
7833
- if (couldBe(keyType, avalue.key)) {
7834
- const av = tryUnion(bv, avalue.value);
7835
- if (av) {
7836
- result.set(key2, av);
7837
- merged = true;
7838
- }
7839
- }
7840
- });
7841
- return [result, merged];
7842
- }
7843
- const { key, value: value2 } = avalue;
7844
- const keyChange = tryUnion(key, bvalue.key);
7845
- const valueChange = tryUnion(value2, bvalue.value);
7846
- if (keyChange || valueChange) {
7847
- return [{ key: keyChange || key, value: valueChange || value2 }, true];
7807
+ } else if (!pair.bvalue.value) {
7808
+ return pair.avalue;
7848
7809
  }
7849
- return [pair.avalue, false];
7810
+ const dkey = intersection(pair.avalue.key, pair.bvalue.key);
7811
+ const dvalue = intersection(pair.avalue.value, pair.bvalue.value);
7812
+ return dkey.type !== 0 && dvalue.type !== 0 ? { key: dkey, value: dvalue } : null;
7850
7813
  }
7851
7814
  case 2048: {
7852
7815
  if (pair.avalue.args.length !== pair.bvalue.args.length)
7853
- return [null, true];
7854
- const resultChange = tryUnion(pair.avalue.result, pair.bvalue.result);
7855
- const args = pair.avalue.args.map(
7856
- (arg, i) => intersection(arg, pair.bvalue.args[i])
7857
- );
7858
- if (args.some(
7816
+ return null;
7817
+ const mresult = intersection(pair.avalue.result, pair.bvalue.result);
7818
+ if (mresult.type === 0)
7819
+ return null;
7820
+ const margs = pair.avalue.args.map((aarg, i) => {
7821
+ aarg = cloneType(aarg);
7822
+ unionInto(aarg, pair.bvalue.args[i]);
7823
+ return aarg;
7824
+ });
7825
+ if (margs.some(
7859
7826
  (arg) => arg.type === 0
7860
7827
  /* Never */
7861
- )) {
7862
- return [null, true];
7863
- }
7864
- const argsChanged = args.some(
7865
- (arg, i) => !subtypeOf(pair.avalue.args[i], arg)
7866
- );
7867
- if (resultChange || argsChanged) {
7868
- return [{ result: resultChange || pair.avalue.result, args }, true];
7869
- }
7870
- return [pair.avalue, false];
7828
+ ))
7829
+ return null;
7830
+ return { result: mresult, args: margs };
7871
7831
  }
7872
7832
  case 4096:
7873
- return mergeStateDecls(pair.avalue, pair.bvalue);
7874
- case 8192:
7875
- return mergeStateDecls(pair.avalue, pair.bvalue);
7876
- case 16384:
7877
- return mergeStateDecls(pair.avalue, pair.bvalue);
7878
- case 262144:
7879
- return mergeStateDecls(pair.avalue, pair.bvalue);
7880
- case 32768: {
7881
- let klass = pair.avalue.klass;
7882
- const [obj, objChanged] = mergeObjectValues(
7883
- pair.avalue.obj,
7884
- pair.bvalue.obj,
7885
- widenDepth
7833
+ case 8192: {
7834
+ const common = /* @__PURE__ */ new Set();
7835
+ (0, import_chunk_X7QCZR3F.forEach)(
7836
+ pair.avalue,
7837
+ (sna) => (0, import_chunk_X7QCZR3F.some)(pair.bvalue, (snb) => sna === snb) && common.add(sna)
7886
7838
  );
7887
- const klassChanged = tryUnion(klass, pair.bvalue.klass);
7888
- if (klassChanged || objChanged) {
7889
- klass = klassChanged || klass;
7890
- if (obj) {
7891
- return [{ klass, obj }, true];
7892
- }
7893
- return [{ klass }, true];
7894
- }
7895
- return [pair.avalue, false];
7839
+ if (!common.size)
7840
+ return null;
7841
+ const arr = Array.from(common);
7842
+ return arr.length === 1 ? arr[0] : arr;
7896
7843
  }
7897
- case 65536: {
7898
- const toE = pair.avalue;
7899
- const fromE = pair.bvalue;
7900
- let changed = false;
7901
- let resultEnum = toE.enum;
7902
- const s = new Set(
7903
- Array.isArray(toE.enum) ? toE.enum : [toE.enum]
7904
- );
7905
- const size = s.size;
7906
- (0, import_chunk_X7QCZR3F.forEach)(fromE.enum, (e) => s.add(e));
7907
- if (size !== s.size) {
7908
- resultEnum = Array.from(s);
7909
- changed = true;
7910
- }
7911
- let resultValue = toE.value;
7912
- if (resultValue) {
7913
- if (fromE.value) {
7914
- resultValue = cloneType(resultValue);
7915
- if (unionHelper(resultValue, fromE.value, widenDepth + 1)) {
7916
- changed = true;
7844
+ case 16384: {
7845
+ const common = /* @__PURE__ */ new Set();
7846
+ (0, import_chunk_X7QCZR3F.forEach)(pair.avalue, (sna) => {
7847
+ const superA = getSuperClasses(sna);
7848
+ (0, import_chunk_X7QCZR3F.forEach)(pair.bvalue, (snb) => {
7849
+ if (sna === snb || superA && superA.has(snb)) {
7850
+ common.add(sna);
7917
7851
  }
7918
- } else {
7919
- resultValue = void 0;
7920
- changed = true;
7852
+ const superB = getSuperClasses(snb);
7853
+ if (superB && superB.has(sna)) {
7854
+ common.add(snb);
7855
+ }
7856
+ });
7857
+ });
7858
+ if (!common.size)
7859
+ return null;
7860
+ const arr = Array.from(common);
7861
+ return arr.length === 1 ? arr[0] : arr;
7862
+ }
7863
+ case 32768: {
7864
+ const klass = intersection(pair.avalue.klass, pair.bvalue.klass);
7865
+ const obj = intersectObj(pair.avalue.obj, pair.bvalue.obj);
7866
+ return klass.type !== 16384 || klass.value == null ? null : obj ? { klass, obj } : { klass };
7867
+ }
7868
+ case 65536: {
7869
+ let enumDecl;
7870
+ if (Array.isArray(pair.avalue.enum)) {
7871
+ const s = new Set(pair.avalue.enum);
7872
+ const enums = [];
7873
+ (0, import_chunk_X7QCZR3F.forEach)(pair.bvalue.enum, (b) => s.has(b) && enums.push(b));
7874
+ if (enums.length) {
7875
+ enumDecl = enums.length === 1 ? enums[0] : enums;
7921
7876
  }
7877
+ } else {
7878
+ (0, import_chunk_X7QCZR3F.some)(pair.bvalue.enum, (b) => b === pair.avalue.enum) && (enumDecl = pair.bvalue.enum);
7922
7879
  }
7923
- if (!changed) {
7924
- return [toE, false];
7925
- }
7926
- return resultValue ? [{ enum: resultEnum, value: resultValue }, changed] : [{ enum: resultEnum }, changed];
7880
+ if (!enumDecl)
7881
+ return null;
7882
+ const enumValue = pair.avalue.value != null ? pair.bvalue.value != null ? intersection(pair.avalue.value, pair.bvalue.value) : pair.avalue.value : pair.bvalue.value;
7883
+ return { enum: enumDecl, value: enumValue };
7927
7884
  }
7928
7885
  default:
7929
7886
  unhandledType(pair);
7930
7887
  }
7931
7888
  }
7932
- function mergeObjectValues(to, from, widenDepth) {
7933
- if (!to) {
7934
- return [to, false];
7935
- }
7936
- if (!from) {
7937
- return [from, true];
7938
- }
7939
- let empty = true;
7889
+ function intersectObj(to, from) {
7890
+ if (!to)
7891
+ return from;
7892
+ if (!from)
7893
+ return to;
7940
7894
  let result = to;
7941
- Object.entries(to).forEach(([key, value2]) => {
7942
- if (!(0, import_chunk_JDC43A3I.hasProperty)(from, key)) {
7895
+ Object.entries(from).forEach(([key, value2]) => {
7896
+ if (!(0, import_chunk_JDC43A3I.hasProperty)(to, key)) {
7943
7897
  if (result === to)
7944
7898
  result = { ...result };
7945
- delete result[key];
7899
+ result[key] = value2;
7946
7900
  return;
7947
7901
  }
7948
- const rep = cloneType(value2);
7949
- if (unionHelper(rep, from[key], widenDepth + 1)) {
7950
- if (result === to)
7951
- result = { ...result };
7952
- result[key] = rep;
7953
- }
7954
- empty = false;
7902
+ if (result === to)
7903
+ result = { ...result };
7904
+ result[key] = intersection(to[key], value2);
7955
7905
  });
7956
- if (empty) {
7957
- return [void 0, true];
7958
- }
7959
- return [result, result !== to];
7960
- }
7961
- function mergeStateDecls(to, from) {
7962
- let changed = false;
7963
- let result = to;
7964
- (0, import_chunk_X7QCZR3F.forEach)(from, (v) => {
7965
- if ((0, import_chunk_X7QCZR3F.some)(to, (t) => t === v)) {
7966
- return;
7967
- }
7968
- if (Array.isArray(result)) {
7969
- if (result === to) {
7970
- result = [...result, v];
7971
- } else {
7972
- result.push(v);
7973
- }
7974
- } else {
7975
- result = [to, v];
7976
- }
7977
- changed = true;
7978
- });
7979
- return [result, changed];
7980
- }
7981
- function nonUnionDataMask(tag) {
7982
- if (tag & tag - 1) {
7983
- return tag & UnionDataTypeTagsConst || tag & ValueTypeTagsConst;
7984
- }
7985
- return tag;
7986
- }
7987
- function clearValuesUnder(v, tag, clearTag = false) {
7988
- const newTag = clearTag ? v.type & ~tag : v.type | tag;
7989
- tag &= ~SingletonTypeTagsConst;
7990
- if (!tag || v.value == null) {
7991
- v.type = newTag;
7992
- return;
7993
- }
7994
- if (tag & ValueTypeTagsConst) {
7995
- tag |= ValueTypeTagsConst;
7996
- }
7997
- if (!hasUnionData(v.type)) {
7998
- const dataMask = nonUnionDataMask(v.type);
7999
- if (dataMask & tag) {
8000
- v.type = newTag;
8001
- delete v.value;
8002
- return;
8003
- }
8004
- if (dataMask & ValueTypeTagsConst) {
8005
- delete v.value;
8006
- v.type = newTag;
8007
- return;
8008
- }
8009
- if (hasUnionData(newTag)) {
8010
- const mask = v.type & UnionDataTypeTagsConst;
8011
- v.value = {
8012
- [mask]: v.value,
8013
- mask
8014
- };
8015
- }
8016
- v.type = newTag;
8017
- return;
8018
- }
8019
- v.type = newTag;
8020
- const unionData = v.value;
8021
- let remain = unionData.mask & ~tag;
8022
- if (!remain) {
8023
- delete v.value;
8024
- return;
8025
- }
8026
- const newData = { mask: remain };
8027
- while (remain) {
8028
- const next = remain & remain - 1;
8029
- const bit = remain - next;
8030
- newData[bit] = unionData[bit];
8031
- remain = next;
8032
- }
8033
- if (!hasUnionData(newTag)) {
8034
- v.value = newData[newTag & UnionDataTypeTagsConst];
8035
- } else {
8036
- v.value = newData;
8037
- }
8038
- }
8039
- var MaxWidenDepth;
8040
- var init_union_type = (0, import_chunk_ABYVSU2C.__esm)({
8041
- "src/type-flow/union-type.ts"() {
8042
- "use strict";
8043
- (0, import_chunk_JDC43A3I.init_ast)();
8044
- init_data_flow();
8045
- (0, import_chunk_X7QCZR3F.init_util)();
8046
- init_could_be();
8047
- init_intersection_type();
8048
- init_sub_type();
8049
- init_types();
8050
- MaxWidenDepth = 4;
8051
- }
8052
- });
8053
- function expandTypedef(t) {
8054
- const decls = getUnionComponent(
8055
- t,
8056
- 262144
8057
- /* Typedef */
8058
- );
8059
- const tExpanded = cloneType(t);
8060
- clearValuesUnder(tExpanded, 262144, true);
8061
- (0, import_chunk_X7QCZR3F.forEach)(decls, (decl) => unionInto(tExpanded, decl.resolvedType));
8062
- return tExpanded;
8063
- }
8064
- function intersectEnum(t, e) {
8065
- const enumData = getUnionComponent(
8066
- e,
8067
- 65536
8068
- /* Enum */
8069
- );
8070
- const e2 = cloneType(e);
8071
- const i = intersection(t, typeFromEnumValue(enumData));
8072
- if (e2.value != null) {
8073
- clearValuesUnder(e2, 65536, true);
8074
- } else {
8075
- e2.type &= ~65536;
8076
- }
8077
- const rest = intersection(t, e2);
8078
- if (i.type === 0) {
8079
- return rest;
8080
- }
8081
- const result = enumData ? { type: 65536, value: { ...enumData, value: i } } : cloneType(i);
8082
- unionInto(result, rest);
8083
- return result;
8084
- }
8085
- function intersection(a, b) {
8086
- if (a.type & 262144 && a.value != null) {
8087
- return intersection(expandTypedef(a), b);
8088
- }
8089
- if (b.type & 262144 && b.value != null) {
8090
- return intersection(a, expandTypedef(b));
8091
- }
8092
- let common = a.type & b.type & ~262144;
8093
- if (a.type & 32768 && b.type & ObjectLikeTagsConst && getObjectValue(a) == null) {
8094
- common |= b.type & ObjectLikeTagsConst;
8095
- }
8096
- if (b.type & 32768 && a.type & ObjectLikeTagsConst && getObjectValue(b) == null) {
8097
- common |= a.type & ObjectLikeTagsConst;
8098
- }
8099
- if (a.type & 65536 && b.type & EnumTagsConst && !(b.type & 65536)) {
8100
- return intersectEnum(b, a);
8101
- }
8102
- if (b.type & 65536 && a.type & EnumTagsConst && !(a.type & 65536)) {
8103
- return intersectEnum(a, b);
8104
- }
8105
- if (!common) {
8106
- return {
8107
- type: 0
8108
- /* Never */
8109
- };
8110
- }
8111
- if (a.value == null) {
8112
- if (b.value == null) {
8113
- return { type: common };
8114
- }
8115
- const result2 = cloneType(b);
8116
- clearValuesUnder(result2, b.type & ~common, true);
8117
- return result2;
8118
- }
8119
- if (b.value == null) {
8120
- const result2 = cloneType(a);
8121
- clearValuesUnder(result2, a.type & ~common, true);
8122
- return result2;
8123
- }
8124
- let mask = 0;
8125
- const result = {};
8126
- forEachUnionComponent(a, common, (ac) => {
8127
- const bvalue = getUnionComponent(b, ac.type);
8128
- if (ac.value == null) {
8129
- if (!bvalue)
8130
- return;
8131
- result[ac.type] = bvalue;
8132
- mask |= ac.type;
8133
- return;
8134
- }
8135
- if (bvalue === null || ac.value === bvalue) {
8136
- result[ac.type] = ac.value;
8137
- mask |= ac.type;
8138
- return;
8139
- }
8140
- const ivalue = intersectionValue({
8141
- type: ac.type,
8142
- avalue: ac.value,
8143
- bvalue
8144
- });
8145
- if (ivalue != null) {
8146
- result[ac.type] = ivalue;
8147
- mask |= ac.type;
8148
- return;
8149
- } else {
8150
- common -= ac.type;
8151
- }
8152
- });
8153
- if (!mask)
8154
- return { type: common };
8155
- if (hasUnionData(common)) {
8156
- return { type: common, value: { ...result, mask } };
8157
- }
8158
- if (mask & mask - 1) {
8159
- throw new Error(
8160
- `Mask with non-union data had more than one bit set: ${mask}`
8161
- );
8162
- }
8163
- return { type: common, value: result[mask] };
8164
- }
8165
- function intersectionValue(pair) {
8166
- switch (pair.type) {
8167
- case 1:
8168
- case 2:
8169
- case 4:
8170
- case 262144:
8171
- throw new Error(`Unexpected TypeTag '${typeTagName(pair.type)}'`);
8172
- case 8:
8173
- case 16:
8174
- case 32:
8175
- case 64:
8176
- case 256:
8177
- case 128:
8178
- case 131072:
8179
- return pair.avalue === pair.bvalue ? pair.avalue : null;
8180
- case 512:
8181
- return tupleMap(
8182
- pair.avalue,
8183
- (av) => tupleMap(
8184
- pair.bvalue,
8185
- (bv) => {
8186
- if (av.length !== bv.length)
8187
- return null;
8188
- const isect = av.map((t, i) => intersection(t, bv[i]));
8189
- return isect.some(
8190
- (t) => t.type === 0
8191
- /* Never */
8192
- ) ? null : isect;
8193
- },
8194
- (bv) => {
8195
- const isect = av.map((t) => intersection(bv, t));
8196
- return isect.some(
8197
- (t) => t.type === 0
8198
- /* Never */
8199
- ) ? null : isect;
8200
- },
8201
- (bv) => bv.length === 0 ? null : bv
8202
- ),
8203
- (av) => tupleMap(
8204
- pair.bvalue,
8205
- (bv) => {
8206
- const isect = bv.map((t) => intersection(av, t));
8207
- return isect.some(
8208
- (t) => t.type === 0
8209
- /* Never */
8210
- ) ? null : isect;
8211
- },
8212
- (bv) => {
8213
- const atype = intersection(av, bv);
8214
- return atype.type === 0 ? null : atype;
8215
- },
8216
- (bv) => bv.length === 0 ? null : bv
8217
- ),
8218
- (av) => {
8219
- const result = av.flat(1);
8220
- return result.length === 0 ? null : tupleReduce(result);
8221
- }
8222
- );
8223
- case 1024: {
8224
- if (!pair.avalue.value) {
8225
- if (!pair.bvalue.value) {
8226
- const result = new Map(pair.avalue);
8227
- pair.bvalue.forEach((bv, key) => {
8228
- const av = result.get(key);
8229
- if (av) {
8230
- bv = intersection(bv, av);
8231
- }
8232
- result.set(key, bv);
8233
- });
8234
- return result;
8235
- } else {
8236
- return pair.bvalue;
8237
- }
8238
- } else if (!pair.bvalue.value) {
8239
- return pair.avalue;
8240
- }
8241
- const dkey = intersection(pair.avalue.key, pair.bvalue.key);
8242
- const dvalue = intersection(pair.avalue.value, pair.bvalue.value);
8243
- return dkey.type !== 0 && dvalue.type !== 0 ? { key: dkey, value: dvalue } : null;
8244
- }
8245
- case 2048: {
8246
- if (pair.avalue.args.length !== pair.bvalue.args.length)
8247
- return null;
8248
- const mresult = intersection(pair.avalue.result, pair.bvalue.result);
8249
- if (mresult.type === 0)
8250
- return null;
8251
- const margs = pair.avalue.args.map((aarg, i) => {
8252
- aarg = cloneType(aarg);
8253
- unionInto(aarg, pair.bvalue.args[i]);
8254
- return aarg;
8255
- });
8256
- if (margs.some(
8257
- (arg) => arg.type === 0
8258
- /* Never */
8259
- ))
8260
- return null;
8261
- return { result: mresult, args: margs };
8262
- }
8263
- case 4096:
8264
- case 8192: {
8265
- const common = /* @__PURE__ */ new Set();
8266
- (0, import_chunk_X7QCZR3F.forEach)(
8267
- pair.avalue,
8268
- (sna) => (0, import_chunk_X7QCZR3F.some)(pair.bvalue, (snb) => sna === snb) && common.add(sna)
8269
- );
8270
- if (!common.size)
8271
- return null;
8272
- const arr = Array.from(common);
8273
- return arr.length === 1 ? arr[0] : arr;
8274
- }
8275
- case 16384: {
8276
- const common = /* @__PURE__ */ new Set();
8277
- (0, import_chunk_X7QCZR3F.forEach)(pair.avalue, (sna) => {
8278
- const superA = getSuperClasses(sna);
8279
- (0, import_chunk_X7QCZR3F.forEach)(pair.bvalue, (snb) => {
8280
- if (sna === snb || superA && superA.has(snb)) {
8281
- common.add(sna);
8282
- }
8283
- const superB = getSuperClasses(snb);
8284
- if (superB && superB.has(sna)) {
8285
- common.add(snb);
8286
- }
8287
- });
8288
- });
8289
- if (!common.size)
8290
- return null;
8291
- const arr = Array.from(common);
8292
- return arr.length === 1 ? arr[0] : arr;
8293
- }
8294
- case 32768: {
8295
- const klass = intersection(pair.avalue.klass, pair.bvalue.klass);
8296
- const obj = intersectObj(pair.avalue.obj, pair.bvalue.obj);
8297
- return klass.type !== 16384 || klass.value == null ? null : obj ? { klass, obj } : { klass };
8298
- }
8299
- case 65536: {
8300
- let enumDecl;
8301
- if (Array.isArray(pair.avalue.enum)) {
8302
- const s = new Set(pair.avalue.enum);
8303
- const enums = [];
8304
- (0, import_chunk_X7QCZR3F.forEach)(pair.bvalue.enum, (b) => s.has(b) && enums.push(b));
8305
- if (enums.length) {
8306
- enumDecl = enums.length === 1 ? enums[0] : enums;
8307
- }
8308
- } else {
8309
- (0, import_chunk_X7QCZR3F.some)(pair.bvalue.enum, (b) => b === pair.avalue.enum) && (enumDecl = pair.bvalue.enum);
8310
- }
8311
- if (!enumDecl)
8312
- return null;
8313
- const enumValue = pair.avalue.value != null ? pair.bvalue.value != null ? intersection(pair.avalue.value, pair.bvalue.value) : pair.avalue.value : pair.bvalue.value;
8314
- return { enum: enumDecl, value: enumValue };
8315
- }
8316
- default:
8317
- unhandledType(pair);
8318
- }
8319
- }
8320
- function intersectObj(to, from) {
8321
- if (!to)
8322
- return from;
8323
- if (!from)
8324
- return to;
8325
- let result = to;
8326
- Object.entries(from).forEach(([key, value2]) => {
8327
- if (!(0, import_chunk_JDC43A3I.hasProperty)(to, key)) {
8328
- if (result === to)
8329
- result = { ...result };
8330
- result[key] = value2;
8331
- return;
8332
- }
8333
- if (result === to)
8334
- result = { ...result };
8335
- result[key] = intersection(to[key], value2);
8336
- });
8337
- return result;
7906
+ return result;
8338
7907
  }
8339
7908
  function fixupEnum(a, b_restricted, b) {
8340
7909
  if (b.type & 65536) {
@@ -8583,182 +8152,449 @@ var init_intersection_type = (0, import_chunk_ABYVSU2C.__esm)({
8583
8152
  init_api();
8584
8153
  init_data_flow();
8585
8154
  (0, import_chunk_X7QCZR3F.init_util)();
8155
+ init_array_type();
8586
8156
  init_could_be();
8587
8157
  init_interp();
8588
8158
  init_types();
8589
8159
  init_union_type();
8590
8160
  }
8591
8161
  });
8592
- function subtypeOf(a, b) {
8593
- if (a.type & 262144 && a.value != null) {
8594
- return subtypeOf(expandTypedef(a), b);
8162
+ function union(to, from) {
8163
+ const result = cloneType(to);
8164
+ unionHelper(result, from, -Infinity);
8165
+ return result;
8166
+ }
8167
+ function unionInto(to, from) {
8168
+ return unionHelper(to, from, -Infinity);
8169
+ }
8170
+ function unionHelper(to, from, widenDepth) {
8171
+ if (to == null || from == null) {
8172
+ throw new Error("Null");
8595
8173
  }
8596
- if (b.type & 262144 && b.value != null) {
8597
- return subtypeOf(a, expandTypedef(b));
8174
+ if (from.type === 0 || to === from)
8175
+ return false;
8176
+ if (to.type === 0) {
8177
+ to.type = from.type;
8178
+ to.value = from.value;
8179
+ return true;
8598
8180
  }
8599
- if (a.type & 65536 && !(b.type & 65536) && b.type & EnumTagsConst) {
8600
- const value2 = getUnionComponent(
8601
- a,
8602
- 65536
8603
- /* Enum */
8604
- );
8605
- if (!subtypeOf(typeFromEnumValue(value2), b)) {
8181
+ const newTags = to.type | from.type;
8182
+ if (!(from.type & ~SingletonTypeTagsConst)) {
8183
+ if (newTags === to.type)
8184
+ return false;
8185
+ to.type = newTags;
8186
+ return true;
8187
+ }
8188
+ if (newTags === to.type) {
8189
+ if (to.value === from.value || to.value == null) {
8606
8190
  return false;
8607
8191
  }
8608
- if (a.type === 65536)
8192
+ if (from.value == null) {
8193
+ clearValuesUnder(to, from.type);
8609
8194
  return true;
8610
- const a2 = cloneType(a);
8611
- clearValuesUnder(a2, 65536, true);
8612
- return subtypeOf(a2, b);
8613
- }
8614
- let common = a.type & b.type;
8615
- if (common !== a.type) {
8616
- if (b.type & 32768 && getObjectValue(b) == null) {
8617
- common |= a.type & ObjectLikeTagsConst;
8618
8195
  }
8619
- if (common !== a.type)
8620
- return false;
8196
+ return mergeMultiple(to, from, widenDepth);
8621
8197
  }
8622
- if (b.value == null)
8623
- return true;
8624
- let result = true;
8625
- forEachUnionComponent(b, common, (bc) => {
8626
- const avalue = getUnionComponent(a, bc.type);
8627
- if (bc.value == null || avalue === bc.value)
8198
+ if (to.value != null) {
8199
+ if (from.value == null) {
8200
+ clearValuesUnder(to, from.type);
8628
8201
  return true;
8629
- if (avalue == null || !subtypeOfValue({ type: bc.type, avalue, bvalue: bc.value })) {
8630
- result = false;
8631
- return false;
8632
8202
  }
8203
+ mergeMultiple(to, from, widenDepth);
8204
+ return true;
8205
+ }
8206
+ if (from.value == null) {
8207
+ to.type = newTags;
8633
8208
  return true;
8209
+ }
8210
+ const tmp = cloneType(from);
8211
+ clearValuesUnder(tmp, to.type);
8212
+ to.type = tmp.type;
8213
+ to.value = tmp.value;
8214
+ return true;
8215
+ }
8216
+ function mergeMultiple(to, from, widenDepth) {
8217
+ const newTags = to.type | from.type;
8218
+ let anyChanged = newTags !== to.type;
8219
+ let mask = 0;
8220
+ const result = {};
8221
+ forEachUnionComponent(to, newTags, (ac) => {
8222
+ const fromv = getUnionComponent(from, ac.type);
8223
+ if (ac.value != null) {
8224
+ if (fromv != null) {
8225
+ const [value2, changed] = ac.value === fromv ? [fromv, false] : mergeSingle(
8226
+ {
8227
+ type: ac.type,
8228
+ avalue: ac.value,
8229
+ bvalue: fromv
8230
+ },
8231
+ widenDepth
8232
+ );
8233
+ if (changed)
8234
+ anyChanged = true;
8235
+ if (value2) {
8236
+ mask |= ac.type;
8237
+ result[ac.type] = value2;
8238
+ }
8239
+ } else if (!(from.type & ac.type)) {
8240
+ mask |= ac.type;
8241
+ result[ac.type] = ac.value;
8242
+ } else {
8243
+ anyChanged = true;
8244
+ }
8245
+ } else if (fromv && !(to.type & ac.type)) {
8246
+ anyChanged = true;
8247
+ mask |= ac.type;
8248
+ result[ac.type] = fromv;
8249
+ }
8634
8250
  });
8635
- return result;
8251
+ if (!anyChanged)
8252
+ return false;
8253
+ to.type = newTags;
8254
+ if (!mask) {
8255
+ delete to.value;
8256
+ return true;
8257
+ }
8258
+ if (hasUnionData(newTags)) {
8259
+ to.value = result;
8260
+ to.value.mask = mask;
8261
+ return true;
8262
+ }
8263
+ if (mask & mask - 1) {
8264
+ throw new Error("Union incorrectly produced a UnionData");
8265
+ }
8266
+ to.value = result[mask];
8267
+ return true;
8636
8268
  }
8637
- function subtypeOfValue(pair) {
8269
+ function mergeSingle(pair, widenDepth) {
8270
+ function tryUnion(to, from) {
8271
+ to = cloneType(to);
8272
+ if (unionHelper(to, from, widenDepth + 1))
8273
+ return to;
8274
+ return null;
8275
+ }
8638
8276
  switch (pair.type) {
8639
8277
  case 1:
8640
8278
  case 2:
8641
8279
  case 4:
8642
- case 262144:
8643
- throw new Error(`Unexpected TypeTag '${typeTagName(pair.type)}'`);
8280
+ throw new Error("Unexpected TypeTag in mergeSingle");
8644
8281
  case 8:
8645
8282
  case 16:
8646
8283
  case 32:
8647
8284
  case 64:
8648
- case 256:
8649
8285
  case 128:
8286
+ case 256:
8650
8287
  case 131072:
8651
- return pair.avalue === pair.bvalue;
8288
+ return [null, true];
8652
8289
  case 512: {
8653
- let result = true;
8290
+ if (widenDepth > MaxWidenDepth) {
8291
+ return [null, true];
8292
+ }
8293
+ const tupleTypes = /* @__PURE__ */ new Map();
8294
+ const arrayTypes = [];
8654
8295
  tupleForEach(
8655
8296
  pair.avalue,
8656
- (av) => {
8657
- let some2 = false;
8658
- tupleForEach(
8659
- pair.bvalue,
8660
- (bv) => {
8661
- some2 = av.length === bv.length && bv.every((b, i) => subtypeOf(av[i], b));
8662
- return some2 === false;
8663
- },
8664
- (bv) => (some2 = av.every((a) => subtypeOf(a, bv))) === false
8665
- );
8666
- return result = some2;
8297
+ (v) => {
8298
+ const t = tupleTypes.get(v.length);
8299
+ if (t) {
8300
+ t.push(v);
8301
+ } else {
8302
+ tupleTypes.set(v.length, [v]);
8303
+ }
8667
8304
  },
8668
- (av) => {
8669
- let some2 = false;
8670
- tupleForEach(
8671
- pair.bvalue,
8672
- () => {
8673
- return true;
8674
- },
8675
- (bv) => (some2 = subtypeOf(av, bv)) === false
8676
- );
8677
- return result = some2;
8305
+ (v) => arrayTypes.push(v)
8306
+ );
8307
+ const extraTypes = [];
8308
+ tupleForEach(
8309
+ pair.bvalue,
8310
+ (v) => {
8311
+ const tuples = tupleTypes.get(v.length);
8312
+ if (!tuples?.some(
8313
+ (t) => t.every((at, i) => {
8314
+ const bt = v[i];
8315
+ return subtypeOf(at, bt) && subtypeOf(bt, at);
8316
+ })
8317
+ )) {
8318
+ extraTypes.push(v);
8319
+ }
8320
+ },
8321
+ (v) => {
8322
+ if (!arrayTypes.some((at) => subtypeOf(at, v) && subtypeOf(v, at))) {
8323
+ extraTypes.push(v);
8324
+ }
8678
8325
  }
8679
8326
  );
8680
- return result;
8327
+ if (extraTypes.length) {
8328
+ if (widenDepth >= 0) {
8329
+ return [null, true];
8330
+ }
8331
+ const allTypes = (pair.avalue instanceof Set ? Array.from(pair.avalue) : [pair.avalue]).concat(extraTypes);
8332
+ return [tupleReduce(allTypes), true];
8333
+ }
8334
+ return [pair.avalue, false];
8681
8335
  }
8682
8336
  case 1024: {
8683
- const adict = pair.avalue;
8684
- const bdict = pair.bvalue;
8685
- if (!adict.value) {
8686
- if (!bdict.value) {
8687
- return Array.from(adict).every(([key, av]) => {
8688
- const bv = bdict.get(key);
8689
- return !bv || subtypeOf(av, bv);
8337
+ if (widenDepth > MaxWidenDepth) {
8338
+ return [null, true];
8339
+ }
8340
+ const avalue = pair.avalue;
8341
+ const bvalue = pair.bvalue;
8342
+ if (!avalue.value) {
8343
+ if (!bvalue.value) {
8344
+ const result = new Map(avalue);
8345
+ let merged = false;
8346
+ result.forEach((av, key2) => {
8347
+ const bv = bvalue.get(key2);
8348
+ if (!bv) {
8349
+ result.delete(key2);
8350
+ merged = true;
8351
+ return;
8352
+ }
8353
+ av = cloneType(av);
8354
+ if (unionHelper(av, bv, widenDepth + 1))
8355
+ merged = true;
8356
+ result.set(key2, av);
8357
+ });
8358
+ return [result, merged];
8359
+ } else {
8360
+ const result = new Map(avalue);
8361
+ let merged = false;
8362
+ result.forEach((av, key2) => {
8363
+ const keyType = typeFromObjectLiteralKey(key2);
8364
+ if (couldBe(keyType, bvalue.key)) {
8365
+ const bv = tryUnion(av, bvalue.value);
8366
+ if (bv) {
8367
+ result.set(key2, bv);
8368
+ merged = true;
8369
+ }
8370
+ }
8690
8371
  });
8372
+ return [result, merged];
8691
8373
  }
8692
- return false;
8693
- }
8694
- if (!bdict.value) {
8695
- return Array.from(bdict).every(([key, bv]) => {
8696
- const kt = typeFromObjectLiteralKey(key);
8697
- return !couldBe(kt, adict.key) || subtypeOf(adict.value, bv);
8374
+ } else if (!bvalue.value) {
8375
+ const result = new Map(bvalue);
8376
+ let merged = false;
8377
+ result.forEach((bv, key2) => {
8378
+ const keyType = typeFromObjectLiteralKey(key2);
8379
+ if (couldBe(keyType, avalue.key)) {
8380
+ const av = tryUnion(bv, avalue.value);
8381
+ if (av) {
8382
+ result.set(key2, av);
8383
+ merged = true;
8384
+ }
8385
+ }
8698
8386
  });
8387
+ return [result, merged];
8699
8388
  }
8700
- return subtypeOf(adict.key, bdict.key) && subtypeOf(adict.value, bdict.value);
8389
+ const { key, value: value2 } = avalue;
8390
+ const keyChange = tryUnion(key, bvalue.key);
8391
+ const valueChange = tryUnion(value2, bvalue.value);
8392
+ if (keyChange || valueChange) {
8393
+ return [{ key: keyChange || key, value: valueChange || value2 }, true];
8394
+ }
8395
+ return [pair.avalue, false];
8701
8396
  }
8702
8397
  case 2048: {
8703
- return pair.avalue.args.length === pair.bvalue.args.length && subtypeOf(pair.avalue.result, pair.bvalue.result) && pair.avalue.args.every((arg, i) => subtypeOf(pair.bvalue.args[i], arg));
8398
+ if (pair.avalue.args.length !== pair.bvalue.args.length)
8399
+ return [null, true];
8400
+ const resultChange = tryUnion(pair.avalue.result, pair.bvalue.result);
8401
+ const args = pair.avalue.args.map(
8402
+ (arg, i) => intersection(arg, pair.bvalue.args[i])
8403
+ );
8404
+ if (args.some(
8405
+ (arg) => arg.type === 0
8406
+ /* Never */
8407
+ )) {
8408
+ return [null, true];
8409
+ }
8410
+ const argsChanged = args.some(
8411
+ (arg, i) => !subtypeOf(pair.avalue.args[i], arg)
8412
+ );
8413
+ if (resultChange || argsChanged) {
8414
+ return [{ result: resultChange || pair.avalue.result, args }, true];
8415
+ }
8416
+ return [pair.avalue, false];
8704
8417
  }
8705
8418
  case 4096:
8706
- case 8192: {
8707
- const asd = pair.avalue;
8708
- const bsd = pair.bvalue;
8709
- return (0, import_chunk_X7QCZR3F.every)(asd, (sna) => (0, import_chunk_X7QCZR3F.some)(bsd, (snb) => sna === snb));
8710
- }
8711
- case 16384: {
8712
- const asd = pair.avalue;
8713
- const bsd = pair.bvalue;
8714
- return (0, import_chunk_X7QCZR3F.every)(asd, (sna) => {
8715
- const superA = getSuperClasses(sna);
8716
- return (0, import_chunk_X7QCZR3F.some)(bsd, (snb) => {
8717
- if (sna === snb || superA && superA.has(snb)) {
8718
- return true;
8719
- }
8720
- return false;
8721
- });
8722
- });
8723
- }
8419
+ return mergeStateDecls(pair.avalue, pair.bvalue);
8420
+ case 8192:
8421
+ return mergeStateDecls(pair.avalue, pair.bvalue);
8422
+ case 16384:
8423
+ return mergeStateDecls(pair.avalue, pair.bvalue);
8424
+ case 262144:
8425
+ return mergeStateDecls(pair.avalue, pair.bvalue);
8724
8426
  case 32768: {
8725
- const aobj = pair.avalue;
8726
- const bobj = pair.bvalue;
8727
- return subtypeOf(aobj.klass, bobj.klass) && subtypeOfObj(aobj.obj, bobj.obj);
8427
+ let klass = pair.avalue.klass;
8428
+ const [obj, objChanged] = mergeObjectValues(
8429
+ pair.avalue.obj,
8430
+ pair.bvalue.obj,
8431
+ widenDepth
8432
+ );
8433
+ const klassChanged = tryUnion(klass, pair.bvalue.klass);
8434
+ if (klassChanged || objChanged) {
8435
+ klass = klassChanged || klass;
8436
+ if (obj) {
8437
+ return [{ klass, obj }, true];
8438
+ }
8439
+ return [{ klass }, true];
8440
+ }
8441
+ return [pair.avalue, false];
8728
8442
  }
8729
8443
  case 65536: {
8730
- const aenum = pair.avalue;
8731
- const benum = pair.bvalue;
8732
- if (benum.value) {
8733
- if (!aenum.value || !subtypeOf(aenum.value, benum.value)) {
8734
- return false;
8444
+ const toE = pair.avalue;
8445
+ const fromE = pair.bvalue;
8446
+ let changed = false;
8447
+ let resultEnum = toE.enum;
8448
+ const s = new Set(
8449
+ Array.isArray(toE.enum) ? toE.enum : [toE.enum]
8450
+ );
8451
+ const size = s.size;
8452
+ (0, import_chunk_X7QCZR3F.forEach)(fromE.enum, (e) => s.add(e));
8453
+ if (size !== s.size) {
8454
+ resultEnum = Array.from(s);
8455
+ changed = true;
8456
+ }
8457
+ let resultValue = toE.value;
8458
+ if (resultValue) {
8459
+ if (fromE.value) {
8460
+ resultValue = cloneType(resultValue);
8461
+ if (unionHelper(resultValue, fromE.value, widenDepth + 1)) {
8462
+ changed = true;
8463
+ }
8464
+ } else {
8465
+ resultValue = void 0;
8466
+ changed = true;
8735
8467
  }
8736
8468
  }
8737
- return (0, import_chunk_X7QCZR3F.every)(aenum.enum, (ea) => (0, import_chunk_X7QCZR3F.some)(benum.enum, (eb) => ea === eb));
8469
+ if (!changed) {
8470
+ return [toE, false];
8471
+ }
8472
+ return resultValue ? [{ enum: resultEnum, value: resultValue }, changed] : [{ enum: resultEnum }, changed];
8738
8473
  }
8739
8474
  default:
8740
8475
  unhandledType(pair);
8741
8476
  }
8742
8477
  }
8743
- function subtypeOfObj(a, b) {
8744
- if (!a || !b)
8745
- return true;
8746
- return Object.entries(b).every(([key, value2]) => {
8747
- if (!(0, import_chunk_JDC43A3I.hasProperty)(a, key))
8748
- return false;
8749
- return subtypeOf(a[key], value2);
8750
- });
8751
- }
8752
- var init_sub_type = (0, import_chunk_ABYVSU2C.__esm)({
8753
- "src/type-flow/sub-type.ts"() {
8478
+ function mergeObjectValues(to, from, widenDepth) {
8479
+ if (!to) {
8480
+ return [to, false];
8481
+ }
8482
+ if (!from) {
8483
+ return [from, true];
8484
+ }
8485
+ let empty = true;
8486
+ let result = to;
8487
+ Object.entries(to).forEach(([key, value2]) => {
8488
+ if (!(0, import_chunk_JDC43A3I.hasProperty)(from, key)) {
8489
+ if (result === to)
8490
+ result = { ...result };
8491
+ delete result[key];
8492
+ return;
8493
+ }
8494
+ const rep = cloneType(value2);
8495
+ if (unionHelper(rep, from[key], widenDepth + 1)) {
8496
+ if (result === to)
8497
+ result = { ...result };
8498
+ result[key] = rep;
8499
+ }
8500
+ empty = false;
8501
+ });
8502
+ if (empty) {
8503
+ return [void 0, true];
8504
+ }
8505
+ return [result, result !== to];
8506
+ }
8507
+ function mergeStateDecls(to, from) {
8508
+ let changed = false;
8509
+ let result = to;
8510
+ (0, import_chunk_X7QCZR3F.forEach)(from, (v) => {
8511
+ if ((0, import_chunk_X7QCZR3F.some)(to, (t) => t === v)) {
8512
+ return;
8513
+ }
8514
+ if (Array.isArray(result)) {
8515
+ if (result === to) {
8516
+ result = [...result, v];
8517
+ } else {
8518
+ result.push(v);
8519
+ }
8520
+ } else {
8521
+ result = [to, v];
8522
+ }
8523
+ changed = true;
8524
+ });
8525
+ return [result, changed];
8526
+ }
8527
+ function nonUnionDataMask(tag) {
8528
+ if (tag & tag - 1) {
8529
+ return tag & UnionDataTypeTagsConst || tag & ValueTypeTagsConst;
8530
+ }
8531
+ return tag;
8532
+ }
8533
+ function clearValuesUnder(v, tag, clearTag = false) {
8534
+ const newTag = clearTag ? v.type & ~tag : v.type | tag;
8535
+ tag &= ~SingletonTypeTagsConst;
8536
+ if (!tag || v.value == null) {
8537
+ v.type = newTag;
8538
+ return;
8539
+ }
8540
+ if (tag & ValueTypeTagsConst) {
8541
+ tag |= ValueTypeTagsConst;
8542
+ }
8543
+ if (!hasUnionData(v.type)) {
8544
+ const dataMask = nonUnionDataMask(v.type);
8545
+ if (dataMask & tag) {
8546
+ v.type = newTag;
8547
+ delete v.value;
8548
+ return;
8549
+ }
8550
+ if (dataMask & ValueTypeTagsConst) {
8551
+ delete v.value;
8552
+ v.type = newTag;
8553
+ return;
8554
+ }
8555
+ if (hasUnionData(newTag)) {
8556
+ const mask = v.type & UnionDataTypeTagsConst;
8557
+ v.value = {
8558
+ [mask]: v.value,
8559
+ mask
8560
+ };
8561
+ }
8562
+ v.type = newTag;
8563
+ return;
8564
+ }
8565
+ v.type = newTag;
8566
+ const unionData = v.value;
8567
+ let remain = unionData.mask & ~tag;
8568
+ if (!remain) {
8569
+ delete v.value;
8570
+ return;
8571
+ }
8572
+ const newData = { mask: remain };
8573
+ while (remain) {
8574
+ const next = remain & remain - 1;
8575
+ const bit = remain - next;
8576
+ newData[bit] = unionData[bit];
8577
+ remain = next;
8578
+ }
8579
+ if (!hasUnionData(newTag)) {
8580
+ v.value = newData[newTag & UnionDataTypeTagsConst];
8581
+ } else {
8582
+ v.value = newData;
8583
+ }
8584
+ }
8585
+ var MaxWidenDepth;
8586
+ var init_union_type = (0, import_chunk_ABYVSU2C.__esm)({
8587
+ "src/type-flow/union-type.ts"() {
8754
8588
  "use strict";
8755
- init_api();
8589
+ (0, import_chunk_JDC43A3I.init_ast)();
8756
8590
  init_data_flow();
8757
8591
  (0, import_chunk_X7QCZR3F.init_util)();
8592
+ init_array_type();
8758
8593
  init_could_be();
8759
8594
  init_intersection_type();
8595
+ init_sub_type();
8760
8596
  init_types();
8761
- init_union_type();
8597
+ MaxWidenDepth = 4;
8762
8598
  }
8763
8599
  });
8764
8600
  function common_types(left, right, allowed) {
@@ -9389,6 +9225,75 @@ var init_type_flow_util = (0, import_chunk_ABYVSU2C.__esm)({
9389
9225
  init_union_type();
9390
9226
  }
9391
9227
  });
9228
+ function getEffectiveTrackedType(constraint, tracked) {
9229
+ if (!(constraint.type & 65536) && tracked.type & 65536) {
9230
+ tracked = deEnumerate(tracked);
9231
+ }
9232
+ if (constraint.type & 262144 && constraint.value != null) {
9233
+ return getEffectiveTrackedType(expandTypedef(constraint), tracked);
9234
+ }
9235
+ if (tracked.type & 262144 && tracked.value != null) {
9236
+ return getEffectiveTrackedType(constraint, expandTypedef(tracked));
9237
+ }
9238
+ let common = constraint.type & tracked.type & ~262144;
9239
+ if (tracked.type & 32768 && constraint.type & ObjectLikeTagsConst && getObjectValue(tracked) == null) {
9240
+ common |= constraint.type & ObjectLikeTagsConst;
9241
+ }
9242
+ if (tracked.type & 65536 && constraint.type & EnumTagsConst && !(constraint.type & 65536)) {
9243
+ common |= constraint.type & typeFromEnumValue(getUnionComponent(
9244
+ tracked,
9245
+ 65536
9246
+ /* Enum */
9247
+ )).type;
9248
+ }
9249
+ if (!common) {
9250
+ return {
9251
+ type: 0
9252
+ /* Never */
9253
+ };
9254
+ }
9255
+ if (constraint.value == null) {
9256
+ return { type: common };
9257
+ }
9258
+ if (tracked.value == null) {
9259
+ const result2 = cloneType(constraint);
9260
+ clearValuesUnder(result2, constraint.type & ~common, true);
9261
+ return result2;
9262
+ }
9263
+ const result = {
9264
+ type: 0
9265
+ /* Never */
9266
+ };
9267
+ forEachUnionComponent(constraint, common, (ac) => {
9268
+ common &= ~ac.type;
9269
+ if (couldBe(ac, tracked)) {
9270
+ if (ac.type === 512 && ac.value) {
9271
+ const trackedData = getUnionComponent(tracked, ac.type);
9272
+ if (trackedData) {
9273
+ unionInto(result, {
9274
+ type: 512,
9275
+ value: restrictArrayData(ac.value, trackedData)
9276
+ });
9277
+ return;
9278
+ }
9279
+ }
9280
+ unionInto(result, ac);
9281
+ }
9282
+ });
9283
+ unionInto(result, { type: common });
9284
+ return result;
9285
+ }
9286
+ var init_effective_type = (0, import_chunk_ABYVSU2C.__esm)({
9287
+ "src/type-flow/effective-type.ts"() {
9288
+ "use strict";
9289
+ init_array_type();
9290
+ init_could_be();
9291
+ init_interp();
9292
+ init_intersection_type();
9293
+ init_types();
9294
+ init_union_type();
9295
+ }
9296
+ });
9392
9297
  function evaluateCall(istate, node, callee, args) {
9393
9298
  while (!hasValue(callee) || callee.type !== 8192) {
9394
9299
  const name = node.callee.type === "Identifier" ? node.callee : node.callee.type === "MemberExpression" && !node.callee.computed ? node.callee.property : null;
@@ -9449,7 +9354,7 @@ function checkCallArgs(istate, node, callees, args) {
9449
9354
  if (object) {
9450
9355
  const info = sysCallInfo(istate.state, cur);
9451
9356
  if (info) {
9452
- const result2 = info(istate, cur, object, () => args);
9357
+ const result2 = info(istate, cur, object, () => args, node);
9453
9358
  if (result2.argTypes)
9454
9359
  argTypes = result2.argTypes;
9455
9360
  if (result2.returnType)
@@ -9493,59 +9398,21 @@ function checkCallArgs(istate, node, callees, args) {
9493
9398
  paramType = typeFromTypespec(istate.state, param.right, cur.stack);
9494
9399
  }
9495
9400
  if (checker(arg, paramType)) {
9496
- if (istate.state.config?.extraReferenceTypeChecks && effects && argEffects && !safeReferenceArg(node.arguments[i])) {
9497
- if (arg.type & 512) {
9498
- const atype = getUnionComponent(
9499
- arg,
9500
- 512
9501
- /* Array */
9502
- );
9503
- if (atype) {
9504
- const ptype = getUnionComponent(
9505
- paramType,
9506
- 512
9507
- /* Array */
9508
- );
9509
- if (!ptype || !checkArrayCovariance(atype, ptype)) {
9510
- curDiags.push([
9511
- node.arguments[i],
9512
- `Argument ${i + 1} to ${cur.fullName}: passing ${display(
9513
- arg
9514
- )} to parameter ${display(paramType)} is not type safe`
9515
- ]);
9516
- }
9517
- }
9518
- }
9519
- if (arg.type & 1024) {
9520
- const adata = getUnionComponent(
9521
- arg,
9522
- 1024
9523
- /* Dictionary */
9524
- );
9525
- if (adata && adata.value) {
9526
- const pdata = getUnionComponent(
9527
- paramType,
9528
- 1024
9529
- /* Dictionary */
9530
- );
9531
- if (!pdata || !pdata.value || !subtypeOf(pdata.key, adata.key) || !subtypeOf(pdata.value, adata.value)) {
9532
- curDiags.push([
9533
- node.arguments[i],
9534
- `Argument ${i + 1} to ${cur.fullName}: passing Dictionary<${display(adata.key)}, ${display(
9535
- adata.value
9536
- )}> to parameter ${display(
9537
- pdata ? {
9538
- type: 1024,
9539
- value: pdata
9540
- } : {
9541
- type: 1024
9542
- /* Dictionary */
9543
- }
9544
- )} is not type safe`
9545
- ]);
9401
+ if (istate.state.config?.extraReferenceTypeChecks !== false && effects && argEffects) {
9402
+ extraReferenceTypeChecks(
9403
+ istate,
9404
+ (sourceType, targetType) => curDiags.push([
9405
+ node.arguments[i],
9406
+ `Argument ${i + 1} to ${cur.fullName}: passing ${sourceType} to parameter ${targetType} is not type safe`,
9407
+ {
9408
+ uri: "https://github.com/markw65/monkeyc-optimizer/wiki/Extra-Reference-Type-Checks-(prettierMonkeyC.extraReferenceTypeChecks)",
9409
+ message: "more info"
9546
9410
  }
9547
- }
9548
- }
9411
+ ]),
9412
+ paramType,
9413
+ arg,
9414
+ node.arguments[i]
9415
+ );
9549
9416
  }
9550
9417
  return;
9551
9418
  }
@@ -9587,7 +9454,7 @@ function checkCallArgs(istate, node, callees, args) {
9587
9454
  if (istate.typeChecker) {
9588
9455
  if (istate.typeChecker === subtypeOf || allDiags.every((diags) => diags.length > 0)) {
9589
9456
  allDiags.flat().forEach(
9590
- (diag) => diagnostic(istate.state, diag[0], diag[1], istate.checkTypes)
9457
+ (diag) => diagnostic(istate.state, diag[0], diag[1], istate.checkTypes, diag[2])
9591
9458
  );
9592
9459
  }
9593
9460
  }
@@ -9615,6 +9482,16 @@ function sysCallInfo(state, func) {
9615
9482
  }
9616
9483
  return null;
9617
9484
  }
9485
+ function getCallObjectConstrainedType(istate, call, trackedType) {
9486
+ if (call.callee.type !== "MemberExpression")
9487
+ return null;
9488
+ const calleeObjNode = call.callee.object;
9489
+ if (calleeObjNode.type !== "Identifier" && calleeObjNode.type !== "MemberExpression") {
9490
+ return null;
9491
+ }
9492
+ const constraint = getLhsConstraint(istate, calleeObjNode);
9493
+ return constraint && getEffectiveTrackedType(constraint, trackedType);
9494
+ }
9618
9495
  function getSystemCallTable(state) {
9619
9496
  if (systemCallInfo && systemCallVersion === state.sdk) {
9620
9497
  return systemCallInfo;
@@ -9688,7 +9565,7 @@ function getSystemCallTable(state) {
9688
9565
  }
9689
9566
  return ret;
9690
9567
  };
9691
- const arrayAdd = (istate, callee, calleeObj, getArgs) => {
9568
+ const arrayAdd = (istate, callee, calleeObj, getArgs, call) => {
9692
9569
  const ret = {};
9693
9570
  if (calleeObj.type & 512) {
9694
9571
  const adata = getUnionComponent(
@@ -9697,8 +9574,19 @@ function getSystemCallTable(state) {
9697
9574
  /* Array */
9698
9575
  );
9699
9576
  if (adata) {
9577
+ const constraint = getCallObjectConstrainedType(
9578
+ istate,
9579
+ call,
9580
+ calleeObj
9581
+ );
9582
+ const cdata = (constraint && getUnionComponent(
9583
+ constraint,
9584
+ 512
9585
+ /* Array */
9586
+ )) ?? adata;
9700
9587
  ret.returnType = { type: 512, value: adata };
9701
9588
  const args = getArgs();
9589
+ const checker = istate.typeChecker;
9702
9590
  if (args.length === 1) {
9703
9591
  const arg = args[0];
9704
9592
  let hasTuple = false;
@@ -9706,33 +9594,38 @@ function getSystemCallTable(state) {
9706
9594
  const relaxed = relaxType(arg);
9707
9595
  tupleMap(
9708
9596
  adata,
9709
- (v) => {
9710
- hasTuple = true;
9711
- return [...v, relaxed];
9712
- },
9713
- (v) => {
9714
- if (subtypeOf(arg, v))
9715
- return v;
9716
- const newAData = cloneType(v);
9717
- unionInto(newAData, arg);
9718
- if (!ret.argTypes) {
9719
- ret.argTypes = [v];
9720
- } else {
9721
- ret.argTypes = [intersection(ret.argTypes[0], v)];
9722
- }
9723
- return newAData;
9724
- },
9597
+ (v) => [...v, relaxed],
9598
+ (v) => subtypeOf(arg, v) ? v : union(v, arg),
9725
9599
  (v) => {
9726
9600
  const newAData = tupleReduce(v);
9727
9601
  ret.returnType.value = newAData;
9728
9602
  const newObj = cloneType(calleeObj);
9729
9603
  setUnionComponent(newObj, 512, newAData);
9730
9604
  ret.calleeObj = newObj;
9731
- if (!ret.argTypes) {
9732
- ret.argTypes = [relaxed];
9733
- }
9734
9605
  }
9735
9606
  );
9607
+ if (checker) {
9608
+ tupleForEach(
9609
+ cdata,
9610
+ () => {
9611
+ hasTuple = true;
9612
+ },
9613
+ (v) => {
9614
+ if (checker(arg, v))
9615
+ return;
9616
+ if (!ret.argTypes) {
9617
+ ret.argTypes = [v];
9618
+ } else {
9619
+ ret.argTypes = [
9620
+ (checker === subtypeOf ? intersection : union)(
9621
+ ret.argTypes[0],
9622
+ v
9623
+ )
9624
+ ];
9625
+ }
9626
+ }
9627
+ );
9628
+ }
9736
9629
  } else {
9737
9630
  const argSubtypes = arg.type & 512 ? getUnionComponent(
9738
9631
  arg,
@@ -9747,26 +9640,13 @@ function getSystemCallTable(state) {
9747
9640
  return tupleMap(
9748
9641
  argSubtypes,
9749
9642
  (a) => [...v, ...a],
9750
- (a) => {
9751
- const at = cloneType(reducedType(v));
9752
- unionInto(at, a);
9753
- return at;
9754
- },
9643
+ (a) => union(reducedType(v), a),
9755
9644
  (a) => a
9756
9645
  );
9757
9646
  },
9758
9647
  (v) => {
9759
9648
  const addedType = reducedArrayType(argSubtypes);
9760
- if (subtypeOf(addedType, v))
9761
- return [v];
9762
- if (!ret.argTypes) {
9763
- ret.argTypes = [v];
9764
- } else {
9765
- ret.argTypes = [intersection(ret.argTypes[0], v)];
9766
- }
9767
- v = cloneType(v);
9768
- unionInto(v, addedType);
9769
- return [v];
9649
+ return [subtypeOf(addedType, v) ? v : union(v, addedType)];
9770
9650
  },
9771
9651
  (va) => {
9772
9652
  const newAData = tupleReduce(va.flat());
@@ -9774,18 +9654,36 @@ function getSystemCallTable(state) {
9774
9654
  const newObj = cloneType(calleeObj);
9775
9655
  setUnionComponent(newObj, 512, newAData);
9776
9656
  ret.calleeObj = newObj;
9777
- if (!ret.argTypes) {
9778
- ret.argTypes = [
9779
- { type: 512, value: argSubtypes }
9780
- ];
9781
- }
9782
9657
  }
9783
9658
  );
9784
- } else {
9659
+ if (checker) {
9660
+ tupleForEach(
9661
+ adata,
9662
+ () => {
9663
+ hasTuple = true;
9664
+ },
9665
+ (v) => {
9666
+ const addedType = reducedArrayType(argSubtypes);
9667
+ if (subtypeOf(addedType, v))
9668
+ return;
9669
+ if (!ret.argTypes) {
9670
+ ret.argTypes = [v];
9671
+ } else {
9672
+ ret.argTypes = [
9673
+ (checker === subtypeOf ? intersection : union)(
9674
+ ret.argTypes[0],
9675
+ v
9676
+ )
9677
+ ];
9678
+ }
9679
+ }
9680
+ );
9681
+ }
9682
+ } else if (checker) {
9785
9683
  tupleForEach(
9786
- adata,
9684
+ cdata,
9787
9685
  () => hasTuple = true,
9788
- () => false
9686
+ () => true
9789
9687
  );
9790
9688
  }
9791
9689
  }
@@ -10098,6 +9996,7 @@ function getSystemCallTable(state) {
10098
9996
  }
10099
9997
  return results;
10100
9998
  };
9999
+ const mathDefault = (istate, callee, calleeObj, getArgs) => mathHelper(istate, callee, calleeObj, getArgs);
10101
10000
  systemCallVersion = state.sdk;
10102
10001
  return systemCallInfo = expandKeys(state, {
10103
10002
  "$.Toybox.Lang.Array.add": arrayAdd,
@@ -10121,12 +10020,12 @@ function getSystemCallTable(state) {
10121
10020
  "$.Toybox.Lang.Method.invoke": methodInvoke,
10122
10021
  "$.Toybox.Lang.Object.method": method,
10123
10022
  "$.Toybox.Lang.*.toNumber": toNumber,
10124
- "$.Toybox.Math.acos": mathHelper,
10125
- "$.Toybox.Math.asin": mathHelper,
10126
- "$.Toybox.Math.atan": mathHelper,
10127
- "$.Toybox.Math.atan2": mathHelper,
10023
+ "$.Toybox.Math.acos": mathDefault,
10024
+ "$.Toybox.Math.asin": mathDefault,
10025
+ "$.Toybox.Math.atan": mathDefault,
10026
+ "$.Toybox.Math.atan2": mathDefault,
10128
10027
  "$.Toybox.Math.ceil": rounder,
10129
- "$.Toybox.Math.cos": mathHelper,
10028
+ "$.Toybox.Math.cos": mathDefault,
10130
10029
  "$.Toybox.Math.floor": rounder,
10131
10030
  "$.Toybox.Math.ln": (state2, callee, calleeObj, getArgs) => mathHelper(state2, callee, calleeObj, getArgs, "log"),
10132
10031
  "$.Toybox.Math.log": (state2, callee, calleeObj, getArgs) => mathHelper(
@@ -10136,11 +10035,11 @@ function getSystemCallTable(state) {
10136
10035
  getArgs,
10137
10036
  (x, base) => Math.log(x) / Math.log(base)
10138
10037
  ),
10139
- "$.Toybox.Math.pow": mathHelper,
10038
+ "$.Toybox.Math.pow": mathDefault,
10140
10039
  "$.Toybox.Math.round": rounder,
10141
- "$.Toybox.Math.sin": mathHelper,
10142
- "$.Toybox.Math.sqrt": mathHelper,
10143
- "$.Toybox.Math.tan": mathHelper,
10040
+ "$.Toybox.Math.sin": mathDefault,
10041
+ "$.Toybox.Math.sqrt": mathDefault,
10042
+ "$.Toybox.Math.tan": mathDefault,
10144
10043
  "$.Toybox.Math.toDegrees": (state2, callee, calleeObj, getArgs) => mathHelper(
10145
10044
  state2,
10146
10045
  callee,
@@ -10202,6 +10101,88 @@ function expandKeys(state, table) {
10202
10101
  });
10203
10102
  return result;
10204
10103
  }
10104
+ function extraReferenceTypeChecks(istate, report, targetType, sourceType, sourceNode) {
10105
+ if (safeReferenceArg(sourceNode)) {
10106
+ return;
10107
+ }
10108
+ let constrainedType = null;
10109
+ const getConstrained = () => {
10110
+ if (!constrainedType) {
10111
+ const constraint = (sourceNode.type === "Identifier" || sourceNode.type === "MemberExpression") && getLhsConstraint(istate, sourceNode);
10112
+ constrainedType = constraint ? getEffectiveTrackedType(constraint, sourceType) : {
10113
+ type: 0
10114
+ /* Never */
10115
+ };
10116
+ }
10117
+ return constrainedType;
10118
+ };
10119
+ const doCheck = (checker) => {
10120
+ const result = checker(sourceType);
10121
+ if (!result)
10122
+ return false;
10123
+ const ct = getConstrained();
10124
+ if (ct.type === 0)
10125
+ return result;
10126
+ return checker(ct);
10127
+ };
10128
+ const arrayReport = doCheck((sourceType2) => {
10129
+ if (sourceType2.type & 512) {
10130
+ const atype = getUnionComponent(
10131
+ sourceType2,
10132
+ 512
10133
+ /* Array */
10134
+ );
10135
+ if (atype) {
10136
+ const ptype = getUnionComponent(
10137
+ targetType,
10138
+ 512
10139
+ /* Array */
10140
+ );
10141
+ if (!ptype || !checkArrayCovariance(atype, ptype)) {
10142
+ return [display(sourceType2), display(targetType)];
10143
+ }
10144
+ }
10145
+ }
10146
+ return false;
10147
+ });
10148
+ if (arrayReport) {
10149
+ report(...arrayReport);
10150
+ }
10151
+ const dictReport = doCheck((sourceType2) => {
10152
+ if (sourceType2.type & 1024) {
10153
+ const adata = getUnionComponent(
10154
+ sourceType2,
10155
+ 1024
10156
+ /* Dictionary */
10157
+ );
10158
+ if (adata && adata.value) {
10159
+ const pdata = getUnionComponent(
10160
+ targetType,
10161
+ 1024
10162
+ /* Dictionary */
10163
+ );
10164
+ if (!pdata || !pdata.value || !subtypeOf(pdata.key, adata.key) || !subtypeOf(pdata.value, adata.value)) {
10165
+ return [
10166
+ `Dictionary<${display(adata.key)}, ${display(adata.value)}>`,
10167
+ display(
10168
+ pdata ? {
10169
+ type: 1024,
10170
+ value: pdata
10171
+ } : {
10172
+ type: 1024
10173
+ /* Dictionary */
10174
+ }
10175
+ )
10176
+ ];
10177
+ }
10178
+ }
10179
+ }
10180
+ return false;
10181
+ });
10182
+ if (dictReport) {
10183
+ report(...dictReport);
10184
+ }
10185
+ }
10205
10186
  var systemCallInfo, systemCallVersion;
10206
10187
  var init_interp_call = (0, import_chunk_ABYVSU2C.__esm)({
10207
10188
  "src/type-flow/interp-call.ts"() {
@@ -10209,12 +10190,14 @@ var init_interp_call = (0, import_chunk_ABYVSU2C.__esm)({
10209
10190
  init_api();
10210
10191
  init_optimizer_types();
10211
10192
  (0, import_chunk_X7QCZR3F.init_util)();
10193
+ init_array_type();
10212
10194
  init_interp();
10213
10195
  init_intersection_type();
10214
10196
  init_sub_type();
10215
10197
  init_type_flow_util();
10216
10198
  init_types();
10217
10199
  init_union_type();
10200
+ init_effective_type();
10218
10201
  systemCallInfo = null;
10219
10202
  }
10220
10203
  });
@@ -10475,6 +10458,9 @@ function deEnumerate(t) {
10475
10458
  return t;
10476
10459
  }
10477
10460
  function arrayTypeAtIndex(arr, elemType, forStrictAssign, enforceTuples) {
10461
+ if (elemType) {
10462
+ elemType = deEnumerate(elemType);
10463
+ }
10478
10464
  const reduce2 = (v) => forStrictAssign ? v.reduce(
10479
10465
  (t, c) => t ? intersection(t, c) : c,
10480
10466
  null
@@ -10496,124 +10482,140 @@ function arrayTypeAtIndex(arr, elemType, forStrictAssign, enforceTuples) {
10496
10482
  }
10497
10483
  );
10498
10484
  }
10499
- function getLhsConstraint(istate, node) {
10485
+ function getLhsConstraintHelper(istate, node) {
10500
10486
  if (istate.localLvals?.has(node)) {
10501
- return null;
10487
+ return [istate.typeMap?.get(node), false];
10502
10488
  }
10503
- let lookupDefs = null;
10504
- if (node.type === "MemberExpression") {
10505
- if (!istate.typeMap) {
10506
- throw new Error("Checking types without a typeMap");
10507
- }
10508
- const object = istate.typeMap.get(node.object);
10509
- if (object) {
10510
- if (node.computed) {
10511
- const strict = istate.typeChecker === subtypeOf;
10512
- if (strict && object.type & ~(512 | 1024 | 32768 | 262144)) {
10513
- return {
10514
- type: 0
10515
- /* Never */
10516
- };
10517
- }
10518
- if (object.value) {
10519
- let result = null;
10520
- if (object.type & 512) {
10521
- const arr = getUnionComponent(
10522
- object,
10523
- 512
10524
- /* Array */
10525
- );
10526
- if (arr) {
10527
- result = arrayTypeAtIndex(
10528
- arr,
10529
- istate.typeMap.get(node.property) ?? {
10530
- type: 8,
10531
- value: arrayLiteralKeyFromExpr(node.property) ?? void 0
10532
- },
10533
- strict,
10534
- istate.state.config?.extraReferenceTypeChecks !== false
10535
- );
10536
- }
10489
+ let lookupDefs = istate.state.lookupNonlocal(node)[1];
10490
+ if (!lookupDefs) {
10491
+ if (node.type === "MemberExpression") {
10492
+ if (!istate.typeMap) {
10493
+ throw new Error("Checking types without a typeMap");
10494
+ }
10495
+ const trackedObject = istate.typeMap?.get(node.object);
10496
+ const object = (node.object.type === "Identifier" || node.object.type === "MemberExpression") && getLhsConstraintHelper(istate, node.object)[0] || trackedObject;
10497
+ if (object) {
10498
+ const tracked = trackedObject ?? object;
10499
+ const objType = object.type & tracked.type;
10500
+ if (node.computed) {
10501
+ const strict = istate.typeChecker === subtypeOf;
10502
+ if (strict && objType & ~(512 | 1024 | 32768 | 262144)) {
10503
+ return [{
10504
+ type: 0
10505
+ /* Never */
10506
+ }, true];
10537
10507
  }
10538
- const updateResult = (value2) => {
10539
- if (result) {
10540
- if (strict) {
10541
- result = intersection(result, value2);
10542
- } else {
10543
- result = cloneType(result);
10544
- unionInto(result, value2);
10508
+ if (object.value) {
10509
+ let result = null;
10510
+ if (objType & 512) {
10511
+ let arr = getUnionComponent(
10512
+ object,
10513
+ 512
10514
+ /* Array */
10515
+ );
10516
+ if (arr) {
10517
+ if (trackedObject) {
10518
+ const current = getUnionComponent(
10519
+ trackedObject,
10520
+ 512
10521
+ /* Array */
10522
+ );
10523
+ if (current) {
10524
+ arr = restrictArrayData(arr, current);
10525
+ }
10526
+ }
10527
+ result = arrayTypeAtIndex(
10528
+ arr,
10529
+ istate.typeMap.get(node.property) ?? {
10530
+ type: 8,
10531
+ value: arrayLiteralKeyFromExpr(node.property) ?? void 0
10532
+ },
10533
+ strict,
10534
+ istate.state.config?.extraReferenceTypeChecks !== false
10535
+ );
10545
10536
  }
10546
- } else {
10547
- result = value2;
10548
10537
  }
10549
- };
10550
- if (object.type & 1024) {
10551
- const dict = getUnionComponent(
10552
- object,
10553
- 1024
10554
- /* Dictionary */
10555
- );
10556
- if (dict) {
10557
- if (dict.value) {
10558
- updateResult(dict.value);
10538
+ const updateResult = (value2) => {
10539
+ if (result) {
10540
+ if (strict) {
10541
+ result = intersection(result, value2);
10542
+ } else {
10543
+ result = cloneType(result);
10544
+ unionInto(result, value2);
10545
+ }
10559
10546
  } else {
10560
- const keyType = istate.typeMap.get(node.property);
10561
- const keyStr = keyType ? objectLiteralKeyFromType(keyType) : objectLiteralKeyFromExpr(node.property);
10562
- if (keyStr) {
10563
- const value2 = dict.get(keyStr);
10564
- if (value2 != null) {
10565
- updateResult(value2);
10547
+ result = value2;
10548
+ }
10549
+ };
10550
+ if (object.type & 1024) {
10551
+ const dict = getUnionComponent(
10552
+ object,
10553
+ 1024
10554
+ /* Dictionary */
10555
+ );
10556
+ if (dict) {
10557
+ if (dict.value) {
10558
+ updateResult(dict.value);
10559
+ } else {
10560
+ const keyType = istate.typeMap.get(node.property);
10561
+ const keyStr = keyType ? objectLiteralKeyFromType(keyType) : objectLiteralKeyFromExpr(node.property);
10562
+ if (keyStr) {
10563
+ const value2 = dict.get(keyStr);
10564
+ if (value2 != null) {
10565
+ updateResult(value2);
10566
+ }
10566
10567
  }
10567
10568
  }
10568
10569
  }
10569
10570
  }
10570
- }
10571
- if (object.type & 32768) {
10572
- const obj = getUnionComponent(
10573
- object,
10574
- 32768
10575
- /* Object */
10576
- );
10577
- if (obj && isByteArrayData(obj)) {
10578
- updateResult({
10579
- type: 8 | 128
10580
- /* Char */
10581
- });
10571
+ if (object.type & 32768) {
10572
+ const obj = getUnionComponent(
10573
+ object,
10574
+ 32768
10575
+ /* Object */
10576
+ );
10577
+ if (obj && isByteArrayData(obj)) {
10578
+ updateResult({
10579
+ type: 8 | 128
10580
+ /* Char */
10581
+ });
10582
+ }
10583
+ }
10584
+ if (result) {
10585
+ return [result, true];
10582
10586
  }
10583
10587
  }
10584
- if (result) {
10585
- return result;
10586
- }
10587
- }
10588
- } else {
10589
- const [, trueDecls2] = findObjectDeclsByProperty(
10590
- istate.state,
10591
- object,
10592
- node.property
10593
- );
10594
- if (trueDecls2) {
10595
- lookupDefs = lookupNext(
10588
+ } else {
10589
+ const [, trueDecls2] = findObjectDeclsByProperty(
10596
10590
  istate.state,
10597
- [{ parent: null, results: trueDecls2 }],
10598
- "decls",
10591
+ object,
10599
10592
  node.property
10600
10593
  );
10594
+ if (trueDecls2) {
10595
+ lookupDefs = lookupNext(
10596
+ istate.state,
10597
+ [{ parent: null, results: trueDecls2 }],
10598
+ "decls",
10599
+ node.property
10600
+ );
10601
+ }
10601
10602
  }
10602
10603
  }
10603
10604
  }
10604
10605
  }
10605
10606
  if (!lookupDefs) {
10606
- [, lookupDefs] = istate.state.lookup(node);
10607
- }
10608
- if (!lookupDefs) {
10609
- return null;
10607
+ return [null, false];
10610
10608
  }
10611
10609
  const trueDecls = lookupDefs.flatMap(
10612
10610
  (lookupDef) => lookupDef.results.filter(
10613
10611
  (decl) => decl.type === "VariableDeclarator" && decl.node.kind === "var" && !isLocal(decl)
10614
10612
  )
10615
10613
  );
10616
- return trueDecls.length === 0 ? null : typeFromTypeStateNodes(istate.state, trueDecls);
10614
+ return trueDecls.length === 0 ? [null, false] : [typeFromTypeStateNodes(istate.state, trueDecls), true];
10615
+ }
10616
+ function getLhsConstraint(istate, node) {
10617
+ const [constraintType, constrained] = getLhsConstraintHelper(istate, node);
10618
+ return constrained ? constraintType : null;
10617
10619
  }
10618
10620
  function pushScopedNameType(istate, node, object) {
10619
10621
  let embeddedEffects = object ? object.embeddedEffects : false;
@@ -11148,17 +11150,40 @@ function evaluateNode(istate, node) {
11148
11150
  if (istate.typeChecker) {
11149
11151
  const constraint = getLhsConstraint(istate, node.left);
11150
11152
  const actual = istate.stack[istate.stack.length - 1].value;
11151
- if (constraint && !istate.typeChecker(actual, constraint)) {
11152
- diagnostic(
11153
- istate.state,
11154
- node,
11155
- formatAstLongLines(node.left).then(
11156
- (nodeStr) => `Invalid assignment to ${nodeStr}. Expected ${display(
11157
- constraint
11158
- )} but got ${display(actual)}`
11159
- ),
11160
- istate.checkTypes
11161
- );
11153
+ if (constraint) {
11154
+ if (istate.typeChecker(actual, constraint)) {
11155
+ if (istate.state.config?.extraReferenceTypeChecks !== false) {
11156
+ extraReferenceTypeChecks(
11157
+ istate,
11158
+ (sourceType, targetType) => diagnostic(
11159
+ istate.state,
11160
+ node,
11161
+ formatAstLongLines(node.left).then(
11162
+ (nodeStr) => `Unsafe assignment to ${nodeStr}: assigning ${sourceType} to ${targetType} is not type safe`
11163
+ ),
11164
+ istate.checkTypes,
11165
+ {
11166
+ uri: "https://github.com/markw65/monkeyc-optimizer/wiki/Extra-Reference-Type-Checks-(prettierMonkeyC.extraReferenceTypeChecks)",
11167
+ message: "more info"
11168
+ }
11169
+ ),
11170
+ constraint,
11171
+ actual,
11172
+ node.right
11173
+ );
11174
+ }
11175
+ } else {
11176
+ diagnostic(
11177
+ istate.state,
11178
+ node,
11179
+ formatAstLongLines(node.left).then(
11180
+ (nodeStr) => `Invalid assignment to ${nodeStr}. Expected ${display(
11181
+ constraint
11182
+ )} but got ${display(actual)}`
11183
+ ),
11184
+ istate.checkTypes
11185
+ );
11186
+ }
11162
11187
  }
11163
11188
  }
11164
11189
  break;
@@ -11260,21 +11285,41 @@ function evaluateNode(istate, node) {
11260
11285
  case "ReturnStatement": {
11261
11286
  const value2 = node.argument && popIstate(istate, node.argument);
11262
11287
  if (istate.typeChecker) {
11263
- if (istate.root?.type !== "FunctionDeclaration") {
11288
+ const root = istate.root;
11289
+ if (root?.type !== "FunctionDeclaration") {
11264
11290
  throw new Error("ReturnStatement found outside of function");
11265
11291
  }
11266
- if (istate.root.node.returnType) {
11292
+ if (root.node.returnType) {
11267
11293
  const returnType = typeFromTypespec(
11268
11294
  istate.state,
11269
- istate.root.node.returnType.argument,
11270
- istate.root.stack
11295
+ root.node.returnType.argument,
11296
+ root.stack
11271
11297
  );
11272
11298
  if (value2) {
11273
- if (!istate.typeChecker(value2.value, returnType)) {
11299
+ if (istate.typeChecker(value2.value, returnType)) {
11300
+ if (istate.state.config?.extraReferenceTypeChecks !== false) {
11301
+ extraReferenceTypeChecks(
11302
+ istate,
11303
+ (sourceType, targetType) => diagnostic(
11304
+ istate.state,
11305
+ node,
11306
+ `Unsafe return from ${root.fullName}: converting ${sourceType} to ${targetType} is not type safe`,
11307
+ istate.checkTypes,
11308
+ {
11309
+ uri: "https://github.com/markw65/monkeyc-optimizer/wiki/Extra-Reference-Type-Checks-(prettierMonkeyC.extraReferenceTypeChecks)",
11310
+ message: "more info"
11311
+ }
11312
+ ),
11313
+ returnType,
11314
+ value2.value,
11315
+ node.argument
11316
+ );
11317
+ }
11318
+ } else {
11274
11319
  diagnostic(
11275
11320
  istate.state,
11276
11321
  node,
11277
- `Expected ${istate.root.fullName} to return ${display(
11322
+ `Expected ${root.fullName} to return ${display(
11278
11323
  returnType
11279
11324
  )} but got ${display(value2.value)}`,
11280
11325
  istate.checkTypes
@@ -11401,6 +11446,7 @@ var init_interp = (0, import_chunk_ABYVSU2C.__esm)({
11401
11446
  init_data_flow();
11402
11447
  init_optimizer_types();
11403
11448
  (0, import_chunk_X7QCZR3F.init_util)();
11449
+ init_array_type();
11404
11450
  init_could_be();
11405
11451
  init_interp_binary();
11406
11452
  init_interp_call();
@@ -11725,10 +11771,8 @@ function arrayLiteralKeyFromType(k) {
11725
11771
  return null;
11726
11772
  }
11727
11773
  function arrayLiteralKeyFromExpr(key) {
11728
- if (key.type === "Literal") {
11729
- return arrayLiteralKeyFromType(typeFromLiteral(key));
11730
- }
11731
- return null;
11774
+ const lit = key.type === "Literal" ? key : (0, import_chunk_JDC43A3I.getNodeValue)(key)[0];
11775
+ return lit && arrayLiteralKeyFromType(typeFromLiteral(lit));
11732
11776
  }
11733
11777
  function objectLiteralKeyFromExpr(key) {
11734
11778
  switch (key.type) {
@@ -12098,236 +12142,626 @@ function castType(type, target) {
12098
12142
  }
12099
12143
  break;
12100
12144
  }
12101
- throw new Error(`Trying to cast ${display(type)} to ${display(result)}`);
12102
- } else if (result.type === 6) {
12103
- if (type.type & (8 | 16)) {
12104
- result.type = Number(type.value) === 0 ? 2 : 4;
12105
- return result;
12145
+ throw new Error(`Trying to cast ${display(type)} to ${display(result)}`);
12146
+ } else if (result.type === 6) {
12147
+ if (type.type & (8 | 16)) {
12148
+ result.type = Number(type.value) === 0 ? 2 : 4;
12149
+ return result;
12150
+ }
12151
+ }
12152
+ }
12153
+ return result;
12154
+ }
12155
+ function reducedType(elems) {
12156
+ if (!Array.isArray(elems)) {
12157
+ return elems;
12158
+ }
12159
+ return elems.flat().reduce(
12160
+ (p, t) => {
12161
+ unionInto(p, t);
12162
+ return p;
12163
+ },
12164
+ {
12165
+ type: 0
12166
+ /* Never */
12167
+ }
12168
+ );
12169
+ }
12170
+ function mustBeTrue(arg) {
12171
+ return (arg.type === 8 || arg.type === 16) && arg.value != null && Number(arg.value) !== 0 || (arg.type & TruthyTypes) !== 0 && (arg.type & ~TruthyTypes) === 0;
12172
+ }
12173
+ function mustBeFalse(arg) {
12174
+ return arg.type === 1 || arg.type === 2 || (arg.type === 8 || arg.type === 16) && arg.value != null && Number(arg.value) === 0;
12175
+ }
12176
+ function display(type) {
12177
+ const names = (v, fn) => (0, import_chunk_X7QCZR3F.map)(v, fn).sort().filter((s, i, arr) => !i || s !== arr[i - 1]).join(" or ");
12178
+ const parts = [];
12179
+ const displayOne = (tv) => {
12180
+ switch (tv.type) {
12181
+ case 1:
12182
+ case 2:
12183
+ case 4:
12184
+ throw new Error("Unexpected value for SingletonTypeTag");
12185
+ case 8:
12186
+ case 16:
12187
+ case 32:
12188
+ case 64:
12189
+ return tv.value.toString();
12190
+ case 128:
12191
+ return `'${JSON.stringify(tv.value).slice(1, -1)}'`;
12192
+ case 256:
12193
+ return JSON.stringify(tv.value);
12194
+ case 512:
12195
+ return tupleMap(
12196
+ tv.value,
12197
+ (v) => `[${v.map((t) => display(t)).join(", ")}]`,
12198
+ (v) => `Array<${display(v)}>`,
12199
+ (v) => v.join(" or ")
12200
+ );
12201
+ case 1024:
12202
+ return tv.value.value ? `Dictionary<${display(tv.value.key)}, ${display(tv.value.value)}>` : `{ ${Array.from(tv.value).map(
12203
+ ([key, value2]) => `${display(typeFromObjectLiteralKey(key))} as ${display(
12204
+ value2
12205
+ )}`
12206
+ ).join(", ")} }`;
12207
+ case 2048:
12208
+ return `Method(${tv.value.args.map((arg, i) => `a${i + 1} as ${display(arg)}`).join(", ")}) as ${display(tv.value.result)}`;
12209
+ case 4096:
12210
+ case 8192:
12211
+ case 16384:
12212
+ case 262144:
12213
+ return names(tv.value, (v) => v.fullName.slice(2));
12214
+ case 32768: {
12215
+ const klass = tv.value.klass;
12216
+ if (!klass.value)
12217
+ return void 0;
12218
+ const obj = tv.value.obj;
12219
+ const ret = displayOne({ type: 16384, value: klass.value });
12220
+ return obj ? `${ret}<{${Object.entries(obj).map(([key, value2]) => `${key}: ${display(value2)}`).join(", ")}}>` : ret;
12221
+ }
12222
+ case 65536: {
12223
+ const v = tv.value;
12224
+ const name = v.enum ? (0, import_chunk_X7QCZR3F.map)(v.enum, (e) => e.fullName.slice(2)).join(" or ") : "";
12225
+ return v.value != null ? `${display(v.value)} as ${name}` : name;
12226
+ }
12227
+ case 131072:
12228
+ return `:${tv.value}`;
12229
+ default:
12230
+ unhandledType(tv);
12231
+ }
12232
+ };
12233
+ let bits = type.type;
12234
+ if (!bits)
12235
+ return "Never";
12236
+ if (bits === 524287 && type.value == null) {
12237
+ return "Any";
12238
+ }
12239
+ while (bits) {
12240
+ const next = bits & bits - 1;
12241
+ const bit = bits - next;
12242
+ if (bit === 2 && next & 4) {
12243
+ parts.push("Boolean");
12244
+ bits = next - 4;
12245
+ continue;
12246
+ }
12247
+ const name = typeTagName(bit);
12248
+ const value2 = getUnionComponent(type, bit);
12249
+ const valueStr = value2 != null && displayOne({ type: bit, value: value2 });
12250
+ if (!valueStr) {
12251
+ parts.push(name);
12252
+ } else if (bit & (32768 | 65536 | 262144 | 131072 | 2048 | 256 | 512 | 1024)) {
12253
+ parts.push(valueStr);
12254
+ } else {
12255
+ parts.push(`${name}<${valueStr}${valueStr.endsWith(">") ? " " : ""}>`);
12256
+ }
12257
+ bits = next;
12258
+ }
12259
+ return parts.join(" or ");
12260
+ }
12261
+ function hasUnionData(tag) {
12262
+ tag &= UnionDataTypeTagsConst;
12263
+ return (tag & tag - 1) !== 0;
12264
+ }
12265
+ function getObjectValue(t) {
12266
+ if (!(t.type & 32768) || t.value == null)
12267
+ return null;
12268
+ if (hasUnionData(t.type)) {
12269
+ return t.value[
12270
+ 32768
12271
+ /* Object */
12272
+ ];
12273
+ }
12274
+ return t.value;
12275
+ }
12276
+ function forEachUnionComponent(v, bits, fn) {
12277
+ bits &= ~SingletonTypeTagsConst;
12278
+ if (!bits)
12279
+ return;
12280
+ if ((v.type | bits) & UnionDataTypeTagsConst) {
12281
+ bits &= ~ValueTypeTagsConst;
12282
+ } else if (bits & bits - 1) {
12283
+ return;
12284
+ }
12285
+ const hasUnion = hasUnionData(v.type);
12286
+ const unionData = v.value;
12287
+ do {
12288
+ const next = bits & bits - 1;
12289
+ const bit = bits - next;
12290
+ const data = hasUnion ? unionData[bit] : bit & v.type ? v.value : null;
12291
+ if (fn({ type: bit, value: data }) === false)
12292
+ break;
12293
+ bits = next;
12294
+ } while (bits);
12295
+ }
12296
+ function getUnionComponent(v, tag) {
12297
+ if (v.value == null)
12298
+ return null;
12299
+ let bits = v.type & ~SingletonTypeTagsConst;
12300
+ if (!bits)
12301
+ return null;
12302
+ if (bits & bits - 1) {
12303
+ bits &= UnionDataTypeTagsConst;
12304
+ if (!bits) {
12305
+ throw new Error(`Non-exact type had no union bits set`);
12306
+ }
12307
+ }
12308
+ if (bits === tag) {
12309
+ return v.value;
12310
+ } else if (bits & tag) {
12311
+ const unionData = v.value;
12312
+ return unionData[tag] || null;
12313
+ }
12314
+ return null;
12315
+ }
12316
+ function setUnionComponent(v, tag, c) {
12317
+ if (hasUnionData(v.type)) {
12318
+ const value2 = v.value ? { ...v.value } : { mask: 0 };
12319
+ value2[tag] = c;
12320
+ value2.mask |= tag;
12321
+ v.value = value2;
12322
+ } else {
12323
+ v.value = c;
12324
+ }
12325
+ }
12326
+ function getStateNodeDeclsFromType(state, object) {
12327
+ return getStateNodeDeclsWithExactFromType(state, object).map(({ sn }) => sn);
12328
+ }
12329
+ function getStateNodeDeclsWithExactFromType(state, object) {
12330
+ const decls = [];
12331
+ if (object.value != null && object.type & (4096 | 16384 | 32768)) {
12332
+ forEachUnionComponent(
12333
+ object,
12334
+ object.type & (4096 | 16384 | 32768),
12335
+ (type) => {
12336
+ if (type.value == null)
12337
+ return;
12338
+ switch (type.type) {
12339
+ case 32768:
12340
+ if (type.value.klass.type === 16384 && type.value.klass.value) {
12341
+ (0, import_chunk_X7QCZR3F.forEach)(
12342
+ type.value.klass.value,
12343
+ (sn) => decls.push({ sn, exact: false })
12344
+ );
12345
+ }
12346
+ break;
12347
+ case 4096:
12348
+ case 16384:
12349
+ (0, import_chunk_X7QCZR3F.forEach)(type.value, (sn) => decls.push({ sn, exact: true }));
12350
+ break;
12351
+ }
12352
+ }
12353
+ );
12354
+ }
12355
+ let bits = object.type & (ObjectLikeTagsConst | 32768);
12356
+ if (bits & 32768 && getObjectValue(object)) {
12357
+ bits -= 32768;
12358
+ }
12359
+ if (bits) {
12360
+ do {
12361
+ let next = bits & bits - 1;
12362
+ let bit = bits - next;
12363
+ if (bit & 6) {
12364
+ bit = 6;
12365
+ next &= ~6;
12366
+ }
12367
+ const name = `Toybox.Lang.${typeTagName(bit)}`;
12368
+ const sns = lookupByFullName(state, name);
12369
+ sns.forEach((sn) => isStateNode(sn) && decls.push({ sn, exact: true }));
12370
+ bits = next;
12371
+ } while (bits);
12372
+ }
12373
+ return decls;
12374
+ }
12375
+ function typeFromEnumValue(arg) {
12376
+ return arg?.value ?? (arg && reducedType(
12377
+ (0, import_chunk_X7QCZR3F.map)(
12378
+ arg.enum,
12379
+ (e) => e.resolvedType ?? {
12380
+ type: EnumTagsConst
12381
+ }
12382
+ )
12383
+ )) ?? {
12384
+ type: EnumTagsConst
12385
+ };
12386
+ }
12387
+ var LastTypeTag, SingletonTypeTagsConst, UnionDataTypeTagsConst, ValueTypeTagsConst, ObjectLikeTagsConst, EnumTagsConst, TruthyTypes;
12388
+ var init_types = (0, import_chunk_ABYVSU2C.__esm)({
12389
+ "src/type-flow/types.ts"() {
12390
+ "use strict";
12391
+ init_api();
12392
+ (0, import_chunk_JDC43A3I.init_ast)();
12393
+ init_data_flow();
12394
+ (0, import_chunk_X7QCZR3F.init_util)();
12395
+ init_array_type();
12396
+ init_interp();
12397
+ init_intersection_type();
12398
+ init_union_type();
12399
+ LastTypeTag = 262144;
12400
+ SingletonTypeTagsConst = 1 | 2 | 4;
12401
+ UnionDataTypeTagsConst = 512 | 1024 | 2048 | 4096 | 8192 | 16384 | 32768 | 65536 | 262144;
12402
+ ValueTypeTagsConst = 8 | 16 | 32 | 64 | 128 | 256 | 131072;
12403
+ ObjectLikeTagsConst = 6 | ValueTypeTagsConst | 512 | 1024 | 2048 | 65536;
12404
+ EnumTagsConst = SingletonTypeTagsConst | ValueTypeTagsConst & ~131072;
12405
+ TruthyTypes = 4 | // TypeTag.Object | // omit because of missing null on various Toybox types
12406
+ 4096 | 16384 | 8192;
12407
+ }
12408
+ });
12409
+ function couldBeHelper(a, b, shallow) {
12410
+ const common = a.type & b.type & ~262144;
12411
+ if (common) {
12412
+ if (a.value == null || b.value == null || a.value === b.value) {
12413
+ return true;
12414
+ }
12415
+ if (common & SingletonTypeTagsConst) {
12416
+ return true;
12417
+ }
12418
+ if (common & ValueTypeTagsConst && common & UnionDataTypeTagsConst) {
12419
+ return true;
12420
+ }
12421
+ let result = false;
12422
+ forEachUnionComponent(a, common, (ac) => {
12423
+ if (ac.value == null) {
12424
+ result = true;
12425
+ return false;
12426
+ }
12427
+ const bvalue = getUnionComponent(b, ac.type);
12428
+ if (bvalue == null || ac.value === bvalue || couldBeValue(
12429
+ { type: ac.type, avalue: ac.value, bvalue },
12430
+ shallow
12431
+ )) {
12432
+ result = true;
12433
+ return false;
12106
12434
  }
12107
- }
12435
+ return true;
12436
+ });
12437
+ if (result)
12438
+ return true;
12108
12439
  }
12109
- return result;
12110
- }
12111
- function reducedType(elems) {
12112
- if (!Array.isArray(elems)) {
12113
- return elems;
12440
+ if (a.type & 65536 && b.type & (EnumTagsConst | 65536) || b.type & 65536 && a.type & (EnumTagsConst | 65536)) {
12441
+ return true;
12114
12442
  }
12115
- return elems.flat().reduce(
12116
- (p, t) => {
12117
- unionInto(p, t);
12118
- return p;
12119
- },
12120
- {
12121
- type: 0
12122
- /* Never */
12123
- }
12124
- );
12443
+ if (a.type & 32768 && b.type & ObjectLikeTagsConst && getObjectValue(a) == null) {
12444
+ return true;
12445
+ }
12446
+ if (b.type & 32768 && a.type & ObjectLikeTagsConst && getObjectValue(b) == null) {
12447
+ return true;
12448
+ }
12449
+ const checkTypedef = (t, other) => {
12450
+ const typedef = getUnionComponent(
12451
+ t,
12452
+ 262144
12453
+ /* Typedef */
12454
+ );
12455
+ return typedef && (0, import_chunk_X7QCZR3F.some)(typedef, (td) => {
12456
+ if (!td.resolvedType) {
12457
+ throw new Error(`No resolved type for ${td.fullName} in 'couldBe'`);
12458
+ }
12459
+ return couldBe(td.resolvedType, other);
12460
+ });
12461
+ };
12462
+ if (a.type & 262144 && checkTypedef(a, b)) {
12463
+ return true;
12464
+ }
12465
+ if (b.type & 262144 && checkTypedef(b, a)) {
12466
+ return true;
12467
+ }
12468
+ return false;
12125
12469
  }
12126
- function mustBeTrue(arg) {
12127
- return (arg.type === 8 || arg.type === 16) && arg.value != null && Number(arg.value) !== 0 || (arg.type & TruthyTypes) !== 0 && (arg.type & ~TruthyTypes) === 0;
12470
+ function couldBe(a, b) {
12471
+ return couldBeHelper(a, b, false);
12128
12472
  }
12129
- function mustBeFalse(arg) {
12130
- return arg.type === 1 || arg.type === 2 || (arg.type === 8 || arg.type === 16) && arg.value != null && Number(arg.value) === 0;
12473
+ function couldBeWeak(a, b) {
12474
+ if (a.type === 0 || b.type === 0)
12475
+ return true;
12476
+ return couldBe(a, b);
12131
12477
  }
12132
- function display(type) {
12133
- const names = (v, fn) => (0, import_chunk_X7QCZR3F.map)(v, fn).sort().filter((s, i, arr) => !i || s !== arr[i - 1]).join(" or ");
12134
- const parts = [];
12135
- const displayOne = (tv) => {
12136
- switch (tv.type) {
12137
- case 1:
12138
- case 2:
12139
- case 4:
12140
- throw new Error("Unexpected value for SingletonTypeTag");
12141
- case 8:
12142
- case 16:
12143
- case 32:
12144
- case 64:
12145
- return tv.value.toString();
12146
- case 128:
12147
- return `'${JSON.stringify(tv.value).slice(1, -1)}'`;
12148
- case 256:
12149
- return JSON.stringify(tv.value);
12150
- case 512:
12151
- return tupleMap(
12152
- tv.value,
12153
- (v) => `[${v.map((t) => display(t)).join(", ")}]`,
12154
- (v) => `Array<${display(v)}>`,
12155
- (v) => v.join(" or ")
12156
- );
12157
- case 1024:
12158
- return tv.value.value ? `Dictionary<${display(tv.value.key)}, ${display(tv.value.value)}>` : `{ ${Array.from(tv.value).map(
12159
- ([key, value2]) => `${display(typeFromObjectLiteralKey(key))} as ${display(
12160
- value2
12161
- )}`
12162
- ).join(", ")} }`;
12163
- case 2048:
12164
- return `Method(${tv.value.args.map((arg, i) => `a${i + 1} as ${display(arg)}`).join(", ")}) as ${display(tv.value.result)}`;
12165
- case 4096:
12166
- case 8192:
12167
- case 16384:
12168
- case 262144:
12169
- return names(tv.value, (v) => v.fullName.slice(2));
12170
- case 32768: {
12171
- const klass = tv.value.klass;
12172
- if (!klass.value)
12173
- return void 0;
12174
- const obj = tv.value.obj;
12175
- const ret = displayOne({ type: 16384, value: klass.value });
12176
- return obj ? `${ret}<{${Object.entries(obj).map(([key, value2]) => `${key}: ${display(value2)}`).join(", ")}}>` : ret;
12177
- }
12178
- case 65536: {
12179
- const v = tv.value;
12180
- const name = v.enum ? (0, import_chunk_X7QCZR3F.map)(v.enum, (e) => e.fullName.slice(2)).join(" or ") : "";
12181
- return v.value != null ? `${display(v.value)} as ${name}` : name;
12478
+ function couldBeShallow(a, b) {
12479
+ return couldBeHelper(a, b, true);
12480
+ }
12481
+ function couldBeValue(pair, shallow) {
12482
+ switch (pair.type) {
12483
+ case 1:
12484
+ case 2:
12485
+ case 4:
12486
+ case 262144:
12487
+ throw new Error(`Unexpected TypeTag '${typeTagName(pair.type)}'`);
12488
+ case 8:
12489
+ case 16:
12490
+ case 32:
12491
+ case 64:
12492
+ case 256:
12493
+ case 128:
12494
+ case 131072:
12495
+ return pair.avalue === pair.bvalue;
12496
+ case 512: {
12497
+ if (shallow)
12498
+ return true;
12499
+ let result = false;
12500
+ tupleForEach(
12501
+ pair.avalue,
12502
+ (av) => {
12503
+ tupleForEach(
12504
+ pair.bvalue,
12505
+ (bv) => {
12506
+ result = av.length === bv.length && bv.every((b, i) => couldBe(av[i], b));
12507
+ return result === false;
12508
+ },
12509
+ (bv) => {
12510
+ result = av.every((a) => couldBe(a, bv));
12511
+ return result === false;
12512
+ }
12513
+ );
12514
+ return result === false;
12515
+ },
12516
+ (av) => {
12517
+ tupleForEach(
12518
+ pair.bvalue,
12519
+ (bv) => {
12520
+ result = bv.every((b) => couldBe(av, b));
12521
+ return result === false;
12522
+ },
12523
+ (bv) => (result = couldBe(av, bv)) === false
12524
+ );
12525
+ return result === false;
12526
+ }
12527
+ );
12528
+ return result;
12529
+ }
12530
+ case 1024: {
12531
+ if (shallow)
12532
+ return true;
12533
+ if (!pair.avalue.value || !pair.bvalue.value) {
12534
+ return true;
12182
12535
  }
12183
- case 131072:
12184
- return `:${tv.value}`;
12185
- default:
12186
- unhandledType(tv);
12536
+ return couldBe(pair.avalue.key, pair.bvalue.key) && couldBe(pair.avalue.value, pair.bvalue.value);
12187
12537
  }
12188
- };
12189
- let bits = type.type;
12190
- if (!bits)
12191
- return "Never";
12192
- if (bits === 524287 && type.value == null) {
12193
- return "Any";
12194
- }
12195
- while (bits) {
12196
- const next = bits & bits - 1;
12197
- const bit = bits - next;
12198
- if (bit === 2 && next & 4) {
12199
- parts.push("Boolean");
12200
- bits = next - 4;
12201
- continue;
12538
+ case 2048: {
12539
+ return pair.avalue.args.length === pair.bvalue.args.length && couldBe(pair.avalue.result, pair.bvalue.result) && pair.avalue.args.every((arg, i) => couldBe(arg, pair.bvalue.args[i]));
12202
12540
  }
12203
- const name = typeTagName(bit);
12204
- const value2 = getUnionComponent(type, bit);
12205
- const valueStr = value2 != null && displayOne({ type: bit, value: value2 });
12206
- if (!valueStr) {
12207
- parts.push(name);
12208
- } else if (bit & (32768 | 65536 | 262144 | 131072 | 2048 | 256 | 512 | 1024)) {
12209
- parts.push(valueStr);
12210
- } else {
12211
- parts.push(`${name}<${valueStr}${valueStr.endsWith(">") ? " " : ""}>`);
12541
+ case 4096:
12542
+ case 8192: {
12543
+ return (0, import_chunk_X7QCZR3F.some)(
12544
+ pair.avalue,
12545
+ (sna) => (0, import_chunk_X7QCZR3F.some)(pair.bvalue, (snb) => sna === snb)
12546
+ );
12547
+ }
12548
+ case 16384: {
12549
+ return (0, import_chunk_X7QCZR3F.some)(pair.avalue, (sna) => {
12550
+ const superA = getSuperClasses(sna);
12551
+ return (0, import_chunk_X7QCZR3F.some)(pair.bvalue, (snb) => {
12552
+ if (sna === snb || superA && superA.has(snb)) {
12553
+ return true;
12554
+ }
12555
+ const superB = getSuperClasses(snb);
12556
+ return superB ? superB.has(sna) : false;
12557
+ });
12558
+ });
12559
+ }
12560
+ case 32768: {
12561
+ return couldBe(pair.avalue.klass, pair.bvalue.klass) && (shallow || couldBeObj(pair.avalue.obj, pair.bvalue.obj));
12562
+ }
12563
+ case 65536: {
12564
+ return (!pair.avalue.value || !pair.bvalue.value || couldBe(pair.avalue.value, pair.bvalue.value)) && (0, import_chunk_X7QCZR3F.some)(
12565
+ pair.avalue.enum,
12566
+ (sna) => (0, import_chunk_X7QCZR3F.some)(pair.bvalue.enum, (snb) => sna === snb)
12567
+ );
12212
12568
  }
12213
- bits = next;
12569
+ default:
12570
+ unhandledType(pair);
12214
12571
  }
12215
- return parts.join(" or ");
12216
12572
  }
12217
- function hasUnionData(tag) {
12218
- tag &= UnionDataTypeTagsConst;
12219
- return (tag & tag - 1) !== 0;
12573
+ function couldBeObj(a, b) {
12574
+ if (!a || !b)
12575
+ return true;
12576
+ return Object.entries(a).every(([key, value2]) => {
12577
+ if (!(0, import_chunk_JDC43A3I.hasProperty)(b, key))
12578
+ return true;
12579
+ return couldBe(value2, b[key]);
12580
+ });
12220
12581
  }
12221
- function getObjectValue(t) {
12222
- if (!(t.type & 32768) || t.value == null)
12223
- return null;
12224
- if (hasUnionData(t.type)) {
12225
- return t.value[
12226
- 32768
12227
- /* Object */
12228
- ];
12582
+ var init_could_be = (0, import_chunk_ABYVSU2C.__esm)({
12583
+ "src/type-flow/could-be.ts"() {
12584
+ "use strict";
12585
+ init_api();
12586
+ init_data_flow();
12587
+ (0, import_chunk_X7QCZR3F.init_util)();
12588
+ init_array_type();
12589
+ init_types();
12229
12590
  }
12230
- return t.value;
12231
- }
12232
- function forEachUnionComponent(v, bits, fn) {
12233
- bits &= ~SingletonTypeTagsConst;
12234
- if (!bits)
12235
- return;
12236
- if ((v.type | bits) & UnionDataTypeTagsConst) {
12237
- bits &= ~ValueTypeTagsConst;
12238
- } else if (bits & bits - 1) {
12239
- return;
12591
+ });
12592
+ function subtypeOf(a, b) {
12593
+ if (a.type & 262144 && a.value != null) {
12594
+ return subtypeOf(expandTypedef(a), b);
12240
12595
  }
12241
- const hasUnion = hasUnionData(v.type);
12242
- const unionData = v.value;
12243
- do {
12244
- const next = bits & bits - 1;
12245
- const bit = bits - next;
12246
- const data = hasUnion ? unionData[bit] : bit & v.type ? v.value : null;
12247
- if (fn({ type: bit, value: data }) === false)
12248
- break;
12249
- bits = next;
12250
- } while (bits);
12251
- }
12252
- function getUnionComponent(v, tag) {
12253
- if (v.value == null)
12254
- return null;
12255
- let bits = v.type & ~SingletonTypeTagsConst;
12256
- if (!bits)
12257
- return null;
12258
- if (bits & bits - 1) {
12259
- bits &= UnionDataTypeTagsConst;
12260
- if (!bits) {
12261
- throw new Error(`Non-exact type had no union bits set`);
12262
- }
12596
+ if (b.type & 262144 && b.value != null) {
12597
+ return subtypeOf(a, expandTypedef(b));
12263
12598
  }
12264
- if (bits === tag) {
12265
- return v.value;
12266
- } else if (bits & tag) {
12267
- const unionData = v.value;
12268
- return unionData[tag] || null;
12599
+ if (a.type & 65536 && !(b.type & 65536) && b.type & EnumTagsConst) {
12600
+ const value2 = getUnionComponent(
12601
+ a,
12602
+ 65536
12603
+ /* Enum */
12604
+ );
12605
+ if (!subtypeOf(typeFromEnumValue(value2), b)) {
12606
+ return false;
12607
+ }
12608
+ if (a.type === 65536)
12609
+ return true;
12610
+ const a2 = cloneType(a);
12611
+ clearValuesUnder(a2, 65536, true);
12612
+ return subtypeOf(a2, b);
12269
12613
  }
12270
- return null;
12271
- }
12272
- function setUnionComponent(v, tag, c) {
12273
- if (hasUnionData(v.type)) {
12274
- const value2 = v.value ? { ...v.value } : { mask: 0 };
12275
- value2[tag] = c;
12276
- value2.mask |= tag;
12277
- v.value = value2;
12278
- } else {
12279
- v.value = c;
12614
+ let common = a.type & b.type;
12615
+ if (common !== a.type) {
12616
+ if (b.type & 32768 && getObjectValue(b) == null) {
12617
+ common |= a.type & ObjectLikeTagsConst;
12618
+ }
12619
+ if (common !== a.type)
12620
+ return false;
12280
12621
  }
12622
+ if (b.value == null)
12623
+ return true;
12624
+ let result = true;
12625
+ forEachUnionComponent(b, common, (bc) => {
12626
+ const avalue = getUnionComponent(a, bc.type);
12627
+ if (bc.value == null || avalue === bc.value)
12628
+ return true;
12629
+ if (avalue == null || !subtypeOfValue({ type: bc.type, avalue, bvalue: bc.value })) {
12630
+ result = false;
12631
+ return false;
12632
+ }
12633
+ return true;
12634
+ });
12635
+ return result;
12281
12636
  }
12282
- function getStateNodeDeclsFromType(state, object) {
12283
- return getStateNodeDeclsWithExactFromType(state, object).map(({ sn }) => sn);
12284
- }
12285
- function getStateNodeDeclsWithExactFromType(state, object) {
12286
- const decls = [];
12287
- if (object.value != null && object.type & (4096 | 16384 | 32768)) {
12288
- forEachUnionComponent(
12289
- object,
12290
- object.type & (4096 | 16384 | 32768),
12291
- (type) => {
12292
- if (type.value == null)
12293
- return;
12294
- switch (type.type) {
12295
- case 32768:
12296
- if (type.value.klass.type === 16384 && type.value.klass.value) {
12297
- (0, import_chunk_X7QCZR3F.forEach)(
12298
- type.value.klass.value,
12299
- (sn) => decls.push({ sn, exact: false })
12300
- );
12301
- }
12302
- break;
12303
- case 4096:
12304
- case 16384:
12305
- (0, import_chunk_X7QCZR3F.forEach)(type.value, (sn) => decls.push({ sn, exact: true }));
12306
- break;
12637
+ function subtypeOfValue(pair) {
12638
+ switch (pair.type) {
12639
+ case 1:
12640
+ case 2:
12641
+ case 4:
12642
+ case 262144:
12643
+ throw new Error(`Unexpected TypeTag '${typeTagName(pair.type)}'`);
12644
+ case 8:
12645
+ case 16:
12646
+ case 32:
12647
+ case 64:
12648
+ case 256:
12649
+ case 128:
12650
+ case 131072:
12651
+ return pair.avalue === pair.bvalue;
12652
+ case 512: {
12653
+ let result = true;
12654
+ tupleForEach(
12655
+ pair.avalue,
12656
+ (av) => {
12657
+ let some2 = false;
12658
+ tupleForEach(
12659
+ pair.bvalue,
12660
+ (bv) => {
12661
+ some2 = av.length === bv.length && bv.every((b, i) => subtypeOf(av[i], b));
12662
+ return some2 === false;
12663
+ },
12664
+ (bv) => (some2 = av.every((a) => subtypeOf(a, bv))) === false
12665
+ );
12666
+ return result = some2;
12667
+ },
12668
+ (av) => {
12669
+ let some2 = false;
12670
+ tupleForEach(
12671
+ pair.bvalue,
12672
+ () => {
12673
+ return true;
12674
+ },
12675
+ (bv) => (some2 = subtypeOf(av, bv)) === false
12676
+ );
12677
+ return result = some2;
12678
+ }
12679
+ );
12680
+ return result;
12681
+ }
12682
+ case 1024: {
12683
+ const adict = pair.avalue;
12684
+ const bdict = pair.bvalue;
12685
+ if (!adict.value) {
12686
+ if (!bdict.value) {
12687
+ return Array.from(adict).every(([key, av]) => {
12688
+ const bv = bdict.get(key);
12689
+ return !bv || subtypeOf(av, bv);
12690
+ });
12307
12691
  }
12692
+ return false;
12308
12693
  }
12309
- );
12310
- }
12311
- let bits = object.type & (ObjectLikeTagsConst | 32768);
12312
- if (bits & 32768 && getObjectValue(object)) {
12313
- bits -= 32768;
12314
- }
12315
- if (bits) {
12316
- do {
12317
- let next = bits & bits - 1;
12318
- let bit = bits - next;
12319
- if (bit & 6) {
12320
- bit = 6;
12321
- next &= ~6;
12694
+ if (!bdict.value) {
12695
+ return Array.from(bdict).every(([key, bv]) => {
12696
+ const kt = typeFromObjectLiteralKey(key);
12697
+ return !couldBe(kt, adict.key) || subtypeOf(adict.value, bv);
12698
+ });
12699
+ }
12700
+ return subtypeOf(adict.key, bdict.key) && subtypeOf(adict.value, bdict.value);
12701
+ }
12702
+ case 2048: {
12703
+ return pair.avalue.args.length === pair.bvalue.args.length && subtypeOf(pair.avalue.result, pair.bvalue.result) && pair.avalue.args.every((arg, i) => subtypeOf(pair.bvalue.args[i], arg));
12704
+ }
12705
+ case 4096:
12706
+ case 8192: {
12707
+ const asd = pair.avalue;
12708
+ const bsd = pair.bvalue;
12709
+ return (0, import_chunk_X7QCZR3F.every)(asd, (sna) => (0, import_chunk_X7QCZR3F.some)(bsd, (snb) => sna === snb));
12710
+ }
12711
+ case 16384: {
12712
+ const asd = pair.avalue;
12713
+ const bsd = pair.bvalue;
12714
+ return (0, import_chunk_X7QCZR3F.every)(asd, (sna) => {
12715
+ const superA = getSuperClasses(sna);
12716
+ return (0, import_chunk_X7QCZR3F.some)(bsd, (snb) => {
12717
+ if (sna === snb || superA && superA.has(snb)) {
12718
+ return true;
12719
+ }
12720
+ return false;
12721
+ });
12722
+ });
12723
+ }
12724
+ case 32768: {
12725
+ const aobj = pair.avalue;
12726
+ const bobj = pair.bvalue;
12727
+ return subtypeOf(aobj.klass, bobj.klass) && subtypeOfObj(aobj.obj, bobj.obj);
12728
+ }
12729
+ case 65536: {
12730
+ const aenum = pair.avalue;
12731
+ const benum = pair.bvalue;
12732
+ if (benum.value) {
12733
+ if (!aenum.value || !subtypeOf(aenum.value, benum.value)) {
12734
+ return false;
12735
+ }
12322
12736
  }
12323
- const name = `Toybox.Lang.${typeTagName(bit)}`;
12324
- const sns = lookupByFullName(state, name);
12325
- sns.forEach((sn) => isStateNode(sn) && decls.push({ sn, exact: true }));
12326
- bits = next;
12327
- } while (bits);
12737
+ return (0, import_chunk_X7QCZR3F.every)(aenum.enum, (ea) => (0, import_chunk_X7QCZR3F.some)(benum.enum, (eb) => ea === eb));
12738
+ }
12739
+ default:
12740
+ unhandledType(pair);
12328
12741
  }
12329
- return decls;
12330
12742
  }
12743
+ function subtypeOfObj(a, b) {
12744
+ if (!a || !b)
12745
+ return true;
12746
+ return Object.entries(b).every(([key, value2]) => {
12747
+ if (!(0, import_chunk_JDC43A3I.hasProperty)(a, key))
12748
+ return false;
12749
+ return subtypeOf(a[key], value2);
12750
+ });
12751
+ }
12752
+ var init_sub_type = (0, import_chunk_ABYVSU2C.__esm)({
12753
+ "src/type-flow/sub-type.ts"() {
12754
+ "use strict";
12755
+ init_api();
12756
+ init_data_flow();
12757
+ (0, import_chunk_X7QCZR3F.init_util)();
12758
+ init_array_type();
12759
+ init_could_be();
12760
+ init_intersection_type();
12761
+ init_types();
12762
+ init_union_type();
12763
+ }
12764
+ });
12331
12765
  function tupleForEach(t, tupleFn, arrayFn) {
12332
12766
  if (t instanceof Set) {
12333
12767
  for (const v of t) {
@@ -12356,6 +12790,11 @@ function reducedArrayType(t) {
12356
12790
  }
12357
12791
  return reducedType(t);
12358
12792
  }
12793
+ function restrictArrayData(constraint, tracked) {
12794
+ const trackedType = { type: 512, value: tracked };
12795
+ const result = (constraint instanceof Set ? Array.from(constraint) : [constraint]).filter((value2) => couldBe({ type: 512, value: value2 }, trackedType));
12796
+ return result.length === 0 ? constraint : result.length === 1 ? result[0] : new Set(result);
12797
+ }
12359
12798
  function checkArrayCovariance(arg, param) {
12360
12799
  let ok = true;
12361
12800
  tupleForEach(
@@ -12401,220 +12840,12 @@ function checkArrayCovariance(arg, param) {
12401
12840
  function safeReferenceArg(arg) {
12402
12841
  return arg.type === "ArrayExpression" || arg.type === "ObjectExpression" || arg.type === "NewExpression";
12403
12842
  }
12404
- function typeFromEnumValue(arg) {
12405
- return arg?.value ?? (arg && reducedType(
12406
- (0, import_chunk_X7QCZR3F.map)(
12407
- arg.enum,
12408
- (e) => e.resolvedType ?? {
12409
- type: EnumTagsConst
12410
- }
12411
- )
12412
- )) ?? {
12413
- type: EnumTagsConst
12414
- };
12415
- }
12416
- var LastTypeTag, SingletonTypeTagsConst, UnionDataTypeTagsConst, ValueTypeTagsConst, ObjectLikeTagsConst, EnumTagsConst, TruthyTypes;
12417
- var init_types = (0, import_chunk_ABYVSU2C.__esm)({
12418
- "src/type-flow/types.ts"() {
12843
+ var init_array_type = (0, import_chunk_ABYVSU2C.__esm)({
12844
+ "src/type-flow/array-type.ts"() {
12419
12845
  "use strict";
12420
- init_api();
12421
- (0, import_chunk_JDC43A3I.init_ast)();
12422
- init_data_flow();
12423
- (0, import_chunk_X7QCZR3F.init_util)();
12424
- init_interp();
12425
- init_intersection_type();
12426
- init_union_type();
12427
12846
  init_sub_type();
12428
- LastTypeTag = 262144;
12429
- SingletonTypeTagsConst = 1 | 2 | 4;
12430
- UnionDataTypeTagsConst = 512 | 1024 | 2048 | 4096 | 8192 | 16384 | 32768 | 65536 | 262144;
12431
- ValueTypeTagsConst = 8 | 16 | 32 | 64 | 128 | 256 | 131072;
12432
- ObjectLikeTagsConst = 6 | ValueTypeTagsConst | 512 | 1024 | 2048 | 65536;
12433
- EnumTagsConst = SingletonTypeTagsConst | ValueTypeTagsConst & ~131072;
12434
- TruthyTypes = 4 | // TypeTag.Object | // omit because of missing null on various Toybox types
12435
- 4096 | 16384 | 8192;
12436
- }
12437
- });
12438
- function couldBeHelper(a, b, shallow) {
12439
- const common = a.type & b.type & ~262144;
12440
- if (common) {
12441
- if (a.value == null || b.value == null || a.value === b.value) {
12442
- return true;
12443
- }
12444
- if (common & SingletonTypeTagsConst) {
12445
- return true;
12446
- }
12447
- if (common & ValueTypeTagsConst && common & UnionDataTypeTagsConst) {
12448
- return true;
12449
- }
12450
- let result = false;
12451
- forEachUnionComponent(a, common, (ac) => {
12452
- if (ac.value == null) {
12453
- result = true;
12454
- return false;
12455
- }
12456
- const bvalue = getUnionComponent(b, ac.type);
12457
- if (bvalue == null || ac.value === bvalue || couldBeValue(
12458
- { type: ac.type, avalue: ac.value, bvalue },
12459
- shallow
12460
- )) {
12461
- result = true;
12462
- return false;
12463
- }
12464
- return true;
12465
- });
12466
- if (result)
12467
- return true;
12468
- }
12469
- if (a.type & 65536 && b.type & (EnumTagsConst | 65536) || b.type & 65536 && a.type & (EnumTagsConst | 65536)) {
12470
- return true;
12471
- }
12472
- if (a.type & 32768 && b.type & ObjectLikeTagsConst && getObjectValue(a) == null) {
12473
- return true;
12474
- }
12475
- if (b.type & 32768 && a.type & ObjectLikeTagsConst && getObjectValue(b) == null) {
12476
- return true;
12477
- }
12478
- const checkTypedef = (t, other) => {
12479
- const typedef = getUnionComponent(
12480
- t,
12481
- 262144
12482
- /* Typedef */
12483
- );
12484
- return typedef && (0, import_chunk_X7QCZR3F.some)(typedef, (td) => {
12485
- if (!td.resolvedType) {
12486
- throw new Error(`No resolved type for ${td.fullName} in 'couldBe'`);
12487
- }
12488
- return couldBe(td.resolvedType, other);
12489
- });
12490
- };
12491
- if (a.type & 262144 && checkTypedef(a, b)) {
12492
- return true;
12493
- }
12494
- if (b.type & 262144 && checkTypedef(b, a)) {
12495
- return true;
12496
- }
12497
- return false;
12498
- }
12499
- function couldBe(a, b) {
12500
- return couldBeHelper(a, b, false);
12501
- }
12502
- function couldBeWeak(a, b) {
12503
- if (a.type === 0 || b.type === 0)
12504
- return true;
12505
- return couldBe(a, b);
12506
- }
12507
- function couldBeShallow(a, b) {
12508
- return couldBeHelper(a, b, true);
12509
- }
12510
- function couldBeValue(pair, shallow) {
12511
- switch (pair.type) {
12512
- case 1:
12513
- case 2:
12514
- case 4:
12515
- case 262144:
12516
- throw new Error(`Unexpected TypeTag '${typeTagName(pair.type)}'`);
12517
- case 8:
12518
- case 16:
12519
- case 32:
12520
- case 64:
12521
- case 256:
12522
- case 128:
12523
- case 131072:
12524
- return pair.avalue === pair.bvalue;
12525
- case 512: {
12526
- if (shallow)
12527
- return true;
12528
- let result = false;
12529
- tupleForEach(
12530
- pair.avalue,
12531
- (av) => {
12532
- tupleForEach(
12533
- pair.bvalue,
12534
- (bv) => {
12535
- result = av.length === bv.length && bv.every((b, i) => couldBe(av[i], b));
12536
- return result === false;
12537
- },
12538
- (bv) => {
12539
- result = av.every((a) => couldBe(a, bv));
12540
- return result === false;
12541
- }
12542
- );
12543
- return result === false;
12544
- },
12545
- (av) => {
12546
- tupleForEach(
12547
- pair.bvalue,
12548
- (bv) => {
12549
- result = bv.every((b) => couldBe(av, b));
12550
- return result === false;
12551
- },
12552
- (bv) => (result = couldBe(av, bv)) === false
12553
- );
12554
- return result === false;
12555
- }
12556
- );
12557
- return result;
12558
- }
12559
- case 1024: {
12560
- if (shallow)
12561
- return true;
12562
- if (!pair.avalue.value || !pair.bvalue.value) {
12563
- return true;
12564
- }
12565
- return couldBe(pair.avalue.key, pair.bvalue.key) && couldBe(pair.avalue.value, pair.bvalue.value);
12566
- }
12567
- case 2048: {
12568
- return pair.avalue.args.length === pair.bvalue.args.length && couldBe(pair.avalue.result, pair.bvalue.result) && pair.avalue.args.every((arg, i) => couldBe(arg, pair.bvalue.args[i]));
12569
- }
12570
- case 4096:
12571
- case 8192: {
12572
- return (0, import_chunk_X7QCZR3F.some)(
12573
- pair.avalue,
12574
- (sna) => (0, import_chunk_X7QCZR3F.some)(pair.bvalue, (snb) => sna === snb)
12575
- );
12576
- }
12577
- case 16384: {
12578
- return (0, import_chunk_X7QCZR3F.some)(pair.avalue, (sna) => {
12579
- const superA = getSuperClasses(sna);
12580
- return (0, import_chunk_X7QCZR3F.some)(pair.bvalue, (snb) => {
12581
- if (sna === snb || superA && superA.has(snb)) {
12582
- return true;
12583
- }
12584
- const superB = getSuperClasses(snb);
12585
- return superB ? superB.has(sna) : false;
12586
- });
12587
- });
12588
- }
12589
- case 32768: {
12590
- return couldBe(pair.avalue.klass, pair.bvalue.klass) && (shallow || couldBeObj(pair.avalue.obj, pair.bvalue.obj));
12591
- }
12592
- case 65536: {
12593
- return (!pair.avalue.value || !pair.bvalue.value || couldBe(pair.avalue.value, pair.bvalue.value)) && (0, import_chunk_X7QCZR3F.some)(
12594
- pair.avalue.enum,
12595
- (sna) => (0, import_chunk_X7QCZR3F.some)(pair.bvalue.enum, (snb) => sna === snb)
12596
- );
12597
- }
12598
- default:
12599
- unhandledType(pair);
12600
- }
12601
- }
12602
- function couldBeObj(a, b) {
12603
- if (!a || !b)
12604
- return true;
12605
- return Object.entries(a).every(([key, value2]) => {
12606
- if (!(0, import_chunk_JDC43A3I.hasProperty)(b, key))
12607
- return true;
12608
- return couldBe(value2, b[key]);
12609
- });
12610
- }
12611
- var init_could_be = (0, import_chunk_ABYVSU2C.__esm)({
12612
- "src/type-flow/could-be.ts"() {
12613
- "use strict";
12614
- init_api();
12615
- init_data_flow();
12616
- (0, import_chunk_X7QCZR3F.init_util)();
12617
12847
  init_types();
12848
+ init_could_be();
12618
12849
  }
12619
12850
  });
12620
12851
  function cloneAnt(antMap) {
@@ -13827,7 +14058,8 @@ function propagateTypes(state, root, graph, optimizeEquivalencies, copyPropStore
13827
14058
  istate,
13828
14059
  callee,
13829
14060
  calleeObj,
13830
- () => node.arguments.map((arg) => evaluateExpr(state, arg, typeMap).value)
14061
+ () => node.arguments.map((arg) => evaluateExpr(state, arg, typeMap).value),
14062
+ node
13831
14063
  );
13832
14064
  if (!result.effectFree) {
13833
14065
  effectFree = false;
@@ -14992,6 +15224,7 @@ var init_type_flow = (0, import_chunk_ABYVSU2C.__esm)({
14992
15224
  init_function_info();
14993
15225
  init_inliner();
14994
15226
  init_optimizer_types();
15227
+ init_array_type();
14995
15228
  init_could_be();
14996
15229
  init_dead_store();
14997
15230
  init_interp();
@@ -17184,7 +17417,7 @@ async function analyze(fnMap, resourcesMap, manifestXML, config, allowParseError
17184
17417
  allClasses: [],
17185
17418
  nestedClasses: {},
17186
17419
  allModules: /* @__PURE__ */ new Set(),
17187
- allTypedefs: /* @__PURE__ */ new Set(),
17420
+ allCached: /* @__PURE__ */ new Set(),
17188
17421
  shouldExclude(node) {
17189
17422
  if ("attrs" in node && node.attrs && "attributes" in node.attrs && node.attrs.attributes && node.loc?.source) {
17190
17423
  const excludeAnnotations = fnMap[node.loc.source].excludeAnnotations;
@@ -17876,6 +18109,7 @@ async function optimizeMonkeyCHelper(fnMap, resourcesMap, manifestXML, config) {
17876
18109
  if (ret === false) {
17877
18110
  changes |= 1;
17878
18111
  this.removeNodeComments(node, f.ast);
18112
+ clearDiagnostics(this, node);
17879
18113
  } else if (ret) {
17880
18114
  if (node.type === "EnumDeclaration" && ret.type === "TypedefDeclaration") {
17881
18115
  changes |= 2;
@@ -17887,7 +18121,7 @@ async function optimizeMonkeyCHelper(fnMap, resourcesMap, manifestXML, config) {
17887
18121
  };
17888
18122
  collectNamespaces(f.ast, state2);
17889
18123
  if (changes & 2) {
17890
- state2.allTypedefs?.forEach((t) => delete t.resolvedType);
18124
+ state2.allCached?.forEach((t) => delete t.resolvedType);
17891
18125
  }
17892
18126
  return changes;
17893
18127
  },
@@ -19828,9 +20062,8 @@ function stateFuncs() {
19828
20062
  parent.type_decls[name].push(decl);
19829
20063
  if (decl.type === "EnumDeclaration") {
19830
20064
  currentEnum = decl;
19831
- } else {
19832
- this.allTypedefs?.add(decl);
19833
20065
  }
20066
+ this.allCached?.add(decl);
19834
20067
  break;
19835
20068
  }
19836
20069
  case "VariableDeclaration": {
@@ -19849,19 +20082,21 @@ function stateFuncs() {
19849
20082
  return;
19850
20083
  }
19851
20084
  decl.kind = node.kind;
19852
- decls[name].push({
20085
+ const vsn = {
19853
20086
  type: "VariableDeclarator",
19854
20087
  node: decl,
19855
20088
  name,
19856
20089
  fullName: parent.fullName + "." + name,
19857
20090
  stack,
19858
20091
  attributes: stateNodeAttrs(node.attrs)
19859
- });
20092
+ };
20093
+ decls[name].push(vsn);
19860
20094
  if (node.kind === "const") {
19861
20095
  if (!(0, import_chunk_JDC43A3I.hasProperty)(this.index, name)) {
19862
20096
  this.index[name] = [];
19863
20097
  }
19864
20098
  (0, import_chunk_X7QCZR3F.pushUnique)(this.index[name], parent);
20099
+ this.allCached?.add(vsn);
19865
20100
  }
19866
20101
  });
19867
20102
  break;
@@ -20391,6 +20626,20 @@ function resolveDiagnosticsMap(diagnosticsMap) {
20391
20626
  )
20392
20627
  ).then(() => diagnosticsMap);
20393
20628
  }
20629
+ function clearDiagnostics(state, node) {
20630
+ const loc = node.loc;
20631
+ if (!loc?.source)
20632
+ return;
20633
+ const diagnostics = state.diagnostics?.[loc.source];
20634
+ if (!diagnostics)
20635
+ return;
20636
+ for (let i = diagnostics.length; i--; ) {
20637
+ const diagnostic2 = diagnostics[i];
20638
+ if (diagnostic2.loc.start.offset >= loc.start.offset && diagnostic2.loc.end.offset <= loc.end.offset) {
20639
+ diagnostics.splice(i, 1);
20640
+ }
20641
+ }
20642
+ }
20394
20643
  function diagnostic(state, node, message, type = "INFO", extra) {
20395
20644
  if (!state.diagnostics)
20396
20645
  state.diagnostics = {};
@@ -30413,7 +30662,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
30413
30662
  const opt_time = await (0, import_chunk_X7QCZR3F.first_modified)(
30414
30663
  Object.values(fnMap).map((v) => v.output)
30415
30664
  );
30416
- if (source_time < opt_time && 1732680967178 < opt_time) {
30665
+ if (source_time < opt_time && 1733273606476 < opt_time) {
30417
30666
  return {
30418
30667
  hasTests,
30419
30668
  diagnostics: prevDiagnostics,
@@ -30451,7 +30700,7 @@ async function generateOneConfig(buildConfig, manifestXML, dependencyFiles, conf
30451
30700
  hasTests: hasTests2,
30452
30701
  diagnostics,
30453
30702
  sdkVersion,
30454
- optimizerVersion: "1.1.83",
30703
+ optimizerVersion: "1.1.84",
30455
30704
  ...Object.fromEntries(
30456
30705
  configOptionsToCheck.map((option) => [option, config[option]])
30457
30706
  )
@@ -31282,6 +31531,7 @@ var init_sdk_util = (0, import_chunk_ABYVSU2C.__esm)({
31282
31531
  buildConfigDescription,
31283
31532
  buildOptimizedProject,
31284
31533
  checkCompilerVersion,
31534
+ clearDiagnostics,
31285
31535
  collectNamespaces,
31286
31536
  connectiq,
31287
31537
  couldBe,