@markw65/monkeyc-optimizer 1.0.43 → 1.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -518,3 +518,13 @@ Bug Fixes
518
518
  - Add Symbols (`:name`) to the list of things the inliner knows are constants
519
519
  - Propagate `:typecheck(false)` to the caller when inlining
520
520
  - Fix an issue with bogus undefined symbols being reported against manifest.xml in some projects that use barrels.
521
+
522
+ ### 1.0.44
523
+
524
+ - Update to [@markw65/prettier-plugin-monkeyc@1.0.40](https://github.com/markw65/prettier-plugin-monkeyc#1040)
525
+
526
+ - Fixes location ranges associated with parenthesized expressions
527
+ - Fixes parsing of Lang.Char literals
528
+
529
+ - Add more parsing of expressions embedded in resource files. This should now be complete, in that the analasis pass should see every symbol definition and reference from anywhere in the project.
530
+ - Generalize constant folding to (nearly) all supported types. We don't fold additions between Float or Double and String, because the exact behavior is [buggy and upredictable](https://forums.garmin.com/developer/connect-iq/i/bug-reports/sdk-4-1-7-constant-folds-floats-strings-incorrectly)
package/build/api.cjs CHANGED
@@ -524,7 +524,9 @@ function ast_getNodeValue(node) {
524
524
  return [node, "Long"];
525
525
  }
526
526
  if (type === "string") {
527
- return [node, "String"];
527
+ return node.raw.startsWith("'")
528
+ ? [node, "Char"]
529
+ : [node, "String"];
528
530
  }
529
531
  if (type === "boolean") {
530
532
  return [node, "Boolean"];
@@ -1622,7 +1624,7 @@ function pragma_checker_pragmaChecker(state, ast, diagnostics) {
1622
1624
  if (quote == '"') {
1623
1625
  return haystack.includes(needle);
1624
1626
  }
1625
- const re = new RegExp(needle.replace(/@([\d\w]+)/g, "(pre_)?$1(_\\d+)?"));
1627
+ const re = new RegExp(needle.replace(/@([-\d.\w]+|"[^"]*")/g, (_match, pat) => `(?:${pat}|pre_${pat.replace(/[".]/g, "_")}(?:_\\d+)?)`));
1626
1628
  return re.test(haystack);
1627
1629
  };
1628
1630
  next();
@@ -3572,7 +3574,7 @@ function getLiteralNode(node) {
3572
3574
  case "-": {
3573
3575
  const [arg, type] = ast_getNodeValue(node.argument);
3574
3576
  if (type === "Number" || type === "Long") {
3575
- return replacementLiteral(arg, -arg.value, type);
3577
+ return replacementLiteral(node, -arg.value, type);
3576
3578
  }
3577
3579
  }
3578
3580
  }
@@ -3622,8 +3624,14 @@ function isBooleanExpression(state, node) {
3622
3624
  }
3623
3625
  return false;
3624
3626
  }
3627
+ function roundToFloat(value) {
3628
+ return new Float32Array([value])[0];
3629
+ }
3625
3630
  function replacementLiteral(arg, value, type) {
3626
- if (typeof value === "boolean") {
3631
+ if (value === null) {
3632
+ type = "Null";
3633
+ }
3634
+ else if (typeof value === "boolean") {
3627
3635
  type = "Boolean";
3628
3636
  }
3629
3637
  else if (type === "Number") {
@@ -3632,32 +3640,189 @@ function replacementLiteral(arg, value, type) {
3632
3640
  else if (type === "Long") {
3633
3641
  value = BigInt.asIntN(64, BigInt(value));
3634
3642
  }
3643
+ else if (type === "Float") {
3644
+ value = roundToFloat(Number(value));
3645
+ }
3646
+ let raw = type === "String"
3647
+ ? JSON.stringify(value)
3648
+ : type === "Char"
3649
+ ? value === "'"
3650
+ ? "'\\''"
3651
+ : "'" + JSON.stringify(value).slice(1, -1) + "'"
3652
+ : value == null
3653
+ ? "null"
3654
+ : value.toString();
3655
+ if (type === "Long") {
3656
+ raw += "l";
3657
+ }
3658
+ else if (type === "Double") {
3659
+ raw += "d";
3660
+ }
3661
+ else if (type === "Float" && prettier_plugin_monkeyc_namespaceObject.LiteralIntegerRe.test(raw)) {
3662
+ raw += "f";
3663
+ }
3664
+ const { start, end, loc } = arg;
3635
3665
  return {
3636
- ...arg,
3666
+ type: "Literal",
3637
3667
  value,
3638
- raw: value.toString() + (type === "Long" ? "l" : ""),
3668
+ raw,
3669
+ start,
3670
+ end,
3671
+ loc,
3639
3672
  };
3640
3673
  }
3674
+ function classify(arg) {
3675
+ switch (arg) {
3676
+ case "Number":
3677
+ return { big: false, int: true };
3678
+ case "Long":
3679
+ return { big: true, int: true };
3680
+ case "Float":
3681
+ return { big: false, int: false };
3682
+ case "Double":
3683
+ return { big: true, int: false };
3684
+ }
3685
+ return null;
3686
+ }
3687
+ function common_arith_types(left, right) {
3688
+ const l = classify(left);
3689
+ if (!l)
3690
+ return null;
3691
+ const r = classify(right);
3692
+ if (!r)
3693
+ return null;
3694
+ if (l.big || r.big) {
3695
+ return l.int && r.int
3696
+ ? ["Long", (v) => BigInt.asIntN(64, BigInt(v))]
3697
+ : ["Double", (v) => Number(v)];
3698
+ }
3699
+ else {
3700
+ return l.int && r.int
3701
+ ? ["Number", (v) => BigInt.asIntN(32, BigInt(v))]
3702
+ : ["Float", (v) => roundToFloat(Number(v))];
3703
+ }
3704
+ }
3705
+ function common_bitwise_types(left, right) {
3706
+ if (left === "Boolean" && right === "Boolean") {
3707
+ return ["Boolean", (v) => (v ? true : false)];
3708
+ }
3709
+ const l = classify(left);
3710
+ if (!l)
3711
+ return null;
3712
+ const r = classify(right);
3713
+ if (!r)
3714
+ return null;
3715
+ if (!l.int || !r.int)
3716
+ return null;
3717
+ return l.big || r.big
3718
+ ? ["Long", (v) => BigInt.asIntN(64, BigInt(v))]
3719
+ : ["Number", (v) => Number(BigInt.asIntN(32, BigInt(v)))];
3720
+ }
3721
+ function plus_types(left, right) {
3722
+ if (left === "String" || right === "String") {
3723
+ // Boolean + String is an error, and
3724
+ // Float/Double + String is legal, but its hard to predict
3725
+ // the way the float will be formatted (and it won't match
3726
+ // what javascript would do by default)
3727
+ if (/Float|Double|Boolean/.test(left + right)) {
3728
+ return null;
3729
+ }
3730
+ return ["String", String];
3731
+ }
3732
+ if (left === "Char" || right === "Char") {
3733
+ if (left === right) {
3734
+ // adding two chars produces a string
3735
+ return ["String", String];
3736
+ }
3737
+ if (/Number|Long/.test(left + right)) {
3738
+ return ["Char", (v) => v];
3739
+ }
3740
+ }
3741
+ return common_arith_types(left, right);
3742
+ }
3743
+ function shift_mod_types(left, right) {
3744
+ const result = common_bitwise_types(left, right);
3745
+ if (result && result[0] === "Boolean") {
3746
+ return null;
3747
+ }
3748
+ return result;
3749
+ }
3641
3750
  const operators = {
3642
- "+": (left, right) => left + right,
3643
- "-": (left, right) => left - right,
3644
- "*": (left, right) => left * right,
3645
- "/": (left, right) => left / right,
3646
- "%": (left, right) => left % right,
3647
- "&": (left, right) => left & right,
3648
- "|": (left, right) => left | right,
3649
- "^": (left, right) => left ^ right,
3650
- "<<": (left, right) => left << (right & 127n),
3651
- ">>": (left, right) => left >> (right & 127n),
3652
- "==": (left, right) =>
3653
- // two string literals will compare unequal, becuase string
3654
- // equality is object equality.
3655
- typeof left === "string" ? false : left === right,
3656
- "!=": (left, right) => typeof left === "string" ? true : left !== right,
3657
- "<=": (left, right) => left <= right,
3658
- ">=": (left, right) => left >= right,
3659
- "<": (left, right) => left < right,
3660
- ">": (left, right) => left > right,
3751
+ "+": {
3752
+ typeFn: plus_types,
3753
+ valueFn: (left, right) => typeof left === "string" && typeof right !== "string"
3754
+ ? String.fromCharCode(left.charCodeAt(0) + Number(right))
3755
+ : typeof left !== "string" && typeof right === "string"
3756
+ ? String.fromCharCode(right.charCodeAt(0) + Number(left))
3757
+ : left + right,
3758
+ },
3759
+ "-": {
3760
+ typeFn: common_arith_types,
3761
+ valueFn: (left, right) => left - right,
3762
+ },
3763
+ "*": {
3764
+ typeFn: common_arith_types,
3765
+ valueFn: (left, right) => left * right,
3766
+ },
3767
+ "/": {
3768
+ typeFn: common_arith_types,
3769
+ valueFn: (left, right) => left / right,
3770
+ },
3771
+ "%": {
3772
+ typeFn: shift_mod_types,
3773
+ valueFn: (left, right) => left % right,
3774
+ },
3775
+ "&": {
3776
+ typeFn: common_bitwise_types,
3777
+ valueFn: (left, right) => left & right,
3778
+ },
3779
+ "|": {
3780
+ typeFn: common_bitwise_types,
3781
+ valueFn: (left, right) => left | right,
3782
+ },
3783
+ "^": {
3784
+ typeFn: common_bitwise_types,
3785
+ valueFn: (left, right) => left ^ right,
3786
+ },
3787
+ "<<": {
3788
+ typeFn: shift_mod_types,
3789
+ valueFn: (left, right) => typeof right === "bigint"
3790
+ ? left << right
3791
+ : left << right,
3792
+ },
3793
+ ">>": {
3794
+ typeFn: shift_mod_types,
3795
+ valueFn: (left, right) => typeof right === "bigint"
3796
+ ? left >> right
3797
+ : left >> right,
3798
+ },
3799
+ "==": {
3800
+ typeFn: () => ["Boolean", (v) => v],
3801
+ valueFn: (left, right) =>
3802
+ // two string literals will compare unequal, becuase string
3803
+ // equality is object equality.
3804
+ typeof left === "string" ? false : left === right,
3805
+ },
3806
+ "!=": {
3807
+ typeFn: () => ["Boolean", (v) => v],
3808
+ valueFn: (left, right) => typeof left === "string" ? true : left !== right,
3809
+ },
3810
+ "<=": {
3811
+ typeFn: common_arith_types,
3812
+ valueFn: (left, right) => left <= right,
3813
+ },
3814
+ ">=": {
3815
+ typeFn: common_arith_types,
3816
+ valueFn: (left, right) => left >= right,
3817
+ },
3818
+ "<": {
3819
+ typeFn: common_arith_types,
3820
+ valueFn: (left, right) => left < right,
3821
+ },
3822
+ ">": {
3823
+ typeFn: common_arith_types,
3824
+ valueFn: (left, right) => left > right,
3825
+ },
3661
3826
  as: null,
3662
3827
  instanceof: null,
3663
3828
  has: null,
@@ -3670,23 +3835,31 @@ function optimizeNode(state, node) {
3670
3835
  break;
3671
3836
  switch (node.operator) {
3672
3837
  case "+":
3673
- if (type === "Number" || type === "Long") {
3838
+ if (type === "Number" ||
3839
+ type === "Long" ||
3840
+ type === "Float" ||
3841
+ type === "Double" ||
3842
+ type === "Char" ||
3843
+ type === "String") {
3674
3844
  return arg;
3675
3845
  }
3676
3846
  break;
3677
3847
  case "-":
3678
- if (type === "Number" || type === "Long") {
3679
- return replacementLiteral(arg, -arg.value, type);
3848
+ if (type === "Number" ||
3849
+ type === "Long" ||
3850
+ type === "Float" ||
3851
+ type === "Double") {
3852
+ return replacementLiteral(node, -arg.value, type);
3680
3853
  }
3681
3854
  break;
3682
3855
  case "!":
3683
3856
  case "~":
3684
3857
  {
3685
3858
  if (type === "Number" || type === "Long") {
3686
- return replacementLiteral(arg, ~BigInt(arg.value), type);
3859
+ return replacementLiteral(node, ~BigInt(arg.value), type);
3687
3860
  }
3688
3861
  if (type === "Boolean" && node.operator == "!") {
3689
- return replacementLiteral(arg, !arg.value, type);
3862
+ return replacementLiteral(node, !arg.value, type);
3690
3863
  }
3691
3864
  }
3692
3865
  break;
@@ -3700,23 +3873,13 @@ function optimizeNode(state, node) {
3700
3873
  const [right, right_type] = getNodeValue(node.right);
3701
3874
  if (!left || !right)
3702
3875
  break;
3703
- let value = null;
3704
- let type;
3705
- if ((left_type != "Number" && left_type != "Long") ||
3706
- left_type != right_type) {
3707
- if (node.operator !== "==" && node.operator !== "!=") {
3708
- break;
3709
- }
3710
- value = operators[node.operator](left.value, right.value);
3711
- type = "Boolean";
3712
- }
3713
- else {
3714
- type = left_type;
3715
- value = op(BigInt(left.value), BigInt(right.value));
3716
- }
3876
+ const type = op.typeFn(left_type, right_type);
3877
+ if (!type)
3878
+ break;
3879
+ const value = op.valueFn(type[1](left.value), type[1](right.value));
3717
3880
  if (value === null)
3718
3881
  break;
3719
- return replacementLiteral(left, value, type);
3882
+ return replacementLiteral(node, value, type[0]);
3720
3883
  }
3721
3884
  break;
3722
3885
  }
@@ -4607,6 +4770,8 @@ const external_sdk_util_cjs_namespaceObject = require("./sdk-util.cjs");
4607
4770
  ;// CONCATENATED MODULE: ./src/resources.ts
4608
4771
 
4609
4772
 
4773
+
4774
+
4610
4775
  /*
4611
4776
  * This is unavoidably ad-hoc. Garmin has arbitrary rules for how
4612
4777
  * resources can be nested, which we need to mimic here.
@@ -4759,7 +4924,7 @@ function visit_resources(elements, parent, v) {
4759
4924
  visitor.post(e);
4760
4925
  });
4761
4926
  }
4762
- function add_resources_to_ast(ast, resources, manifestXML) {
4927
+ function add_resources_to_ast(state, ast, resources, manifestXML) {
4763
4928
  const modules = {
4764
4929
  Drawables: true,
4765
4930
  Fonts: true,
@@ -4801,7 +4966,7 @@ function add_resources_to_ast(ast, resources, manifestXML) {
4801
4966
  manifestXML.body instanceof external_sdk_util_cjs_namespaceObject.xmlUtil.Nodes) {
4802
4967
  manifestXML.body
4803
4968
  .children("iq:application")
4804
- .elements.forEach((e) => add_one_resource(rez, e));
4969
+ .elements.forEach((e) => add_one_resource(state, manifestXML, rez, e));
4805
4970
  }
4806
4971
  const rezModules = Object.fromEntries(Object.entries(modules).map(([moduleName, isPublic]) => {
4807
4972
  const module = makeModule(moduleName);
@@ -4817,7 +4982,7 @@ function add_resources_to_ast(ast, resources, manifestXML) {
4817
4982
  if (!ast_hasProperty(rezModules, s))
4818
4983
  return;
4819
4984
  const module = rezModules[s];
4820
- add_one_resource(module, e);
4985
+ add_one_resource(state, rez, module, e);
4821
4986
  });
4822
4987
  });
4823
4988
  });
@@ -4835,7 +5000,7 @@ function makeMemberExpression(object, property) {
4835
5000
  }
4836
5001
  function makeScopedName(dotted, l) {
4837
5002
  const loc = l && adjustLoc(l, 0, l.start.offset - l.end.offset);
4838
- return dotted.split(".").reduce(({ cur, offset }, next) => {
5003
+ return dotted.split(/\s*\.\s*/).reduce(({ cur, offset }, next) => {
4839
5004
  const id = makeIdentifier(next, loc && adjustLoc(loc, offset, offset + next.length));
4840
5005
  if (!cur) {
4841
5006
  cur = id;
@@ -4847,44 +5012,144 @@ function makeScopedName(dotted, l) {
4847
5012
  return { cur, offset };
4848
5013
  }, { cur: null, offset: 0 }).cur;
4849
5014
  }
4850
- function visit_resource_refs(e) {
5015
+ const drawableSkips = {
5016
+ x: { center: true, left: true, right: true, start: true },
5017
+ y: { center: true, top: true, bottom: true, start: true },
5018
+ width: { fill: true },
5019
+ height: { fill: true },
5020
+ a: { fill: true },
5021
+ b: { fill: true },
5022
+ color: {},
5023
+ corner_radius: {},
5024
+ radius: {},
5025
+ border_width: {},
5026
+ border_color: {},
5027
+ foreground: {},
5028
+ background: {},
5029
+ font: {},
5030
+ justification: {},
5031
+ };
5032
+ function addPositions(base, pos) {
5033
+ const result = { ...base };
5034
+ if (pos.line > 1) {
5035
+ result.line += pos.line - 1;
5036
+ result.column = pos.column;
5037
+ }
5038
+ else {
5039
+ result.column += pos.column - 1;
5040
+ }
5041
+ result.offset += pos.offset;
5042
+ return result;
5043
+ }
5044
+ function visit_resource_refs(state, doc, e) {
4851
5045
  const result = [];
4852
- const stringToScopedName = (element, id, dotted, l) => {
4853
- const match = dotted.match(/^(@)?([\w_$]+\s*\.\s*)*[\w_$]+$/);
4854
- if (!match)
4855
- return;
4856
- let offset = 0;
4857
- if (match[1]) {
4858
- offset = 1;
5046
+ const parseArg = (name, loc, skip) => {
5047
+ if (name.startsWith("@")) {
5048
+ name = name.substring(1);
5049
+ loc = adjustLoc(loc, 1, 0);
4859
5050
  }
4860
- else if ((element === "drawable" && id === "class") ||
4861
- (element === "iq:application" && id === "entry")) {
4862
- // nothing to do
5051
+ if (ast_hasProperty(skip, name)) {
5052
+ return;
4863
5053
  }
4864
- else {
5054
+ if (/^([\w_$]+\s*\.\s*)*[\w_$]+$/.test(name)) {
5055
+ const dn = makeScopedName(name, loc);
5056
+ if (dn)
5057
+ result.push(dn);
4865
5058
  return;
4866
5059
  }
4867
- const dn = makeScopedName(dotted.substring(offset), adjustLoc(l, offset, 0));
4868
- if (dn)
4869
- result.push(dn);
5060
+ // We wrap the expression in parentheses, so adjust
5061
+ // the start position by 1 character to compensate
5062
+ // for the opening '('
5063
+ const startPos = adjustLoc(loc, -1, 0).start;
5064
+ try {
5065
+ const expr = prettier_plugin_monkeyc_default().parsers.monkeyc.parse(`(${name})`, null, {
5066
+ filepath: loc.source || undefined,
5067
+ singleExpression: true,
5068
+ });
5069
+ ast_traverseAst(expr, (node) => {
5070
+ if (node.loc) {
5071
+ node.loc = {
5072
+ source: node.loc.source,
5073
+ start: addPositions(startPos, node.loc.start),
5074
+ end: addPositions(startPos, node.loc.end),
5075
+ };
5076
+ node.start = (node.start || 0) + startPos.offset;
5077
+ node.end = (node.end || 0) + startPos.offset;
5078
+ }
5079
+ });
5080
+ result.push(expr);
5081
+ }
5082
+ catch (ex) {
5083
+ if (state) {
5084
+ const check = state.config?.checkInvalidSymbols;
5085
+ if (check !== "OFF" && ex instanceof Error) {
5086
+ const error = ex;
5087
+ if (error.location) {
5088
+ const location = {
5089
+ source: error.location.source,
5090
+ start: addPositions(startPos, error.location.start),
5091
+ end: addPositions(startPos, error.location.end),
5092
+ };
5093
+ inliner_diagnostic(state, location, ex.message, check || "WARNING");
5094
+ }
5095
+ }
5096
+ }
5097
+ }
4870
5098
  };
4871
- visit_resources([e], null, {
4872
- pre(node) {
4873
- if (node.type === "element") {
4874
- Object.values(node.attr).forEach((attr) => {
4875
- if (!attr || !attr.value.loc)
4876
- return;
4877
- const loc = adjustLoc(attr.value.loc);
4878
- attr &&
4879
- stringToScopedName(node.name, attr.name.value, attr.value.value, loc);
4880
- });
4881
- if (node.children &&
4882
- node.children.length === 1 &&
4883
- node.children[0].type === "chardata") {
4884
- stringToScopedName(node.name, null, node.children[0].value, node.children[0].loc);
5099
+ const stringToScopedName = (element, id, dotted, l) => {
5100
+ dotted = doc.processRefs(dotted);
5101
+ if (dotted.startsWith("@")) {
5102
+ return parseArg(dotted, l);
5103
+ }
5104
+ if (/^\s*(true|false|null|NaN|(0x|#)[0-9a-f]+|[-+]?\d+%?)\s*$/i.test(dotted)) {
5105
+ return;
5106
+ }
5107
+ switch (element.name) {
5108
+ case "param":
5109
+ if (id === null) {
5110
+ parseArg(dotted, l);
5111
+ }
5112
+ return;
5113
+ case "drawable":
5114
+ if (id === "class") {
5115
+ parseArg(dotted, l);
5116
+ }
5117
+ return;
5118
+ case "shape":
5119
+ case "bitmap":
5120
+ case "drawable-list":
5121
+ case "text-area":
5122
+ case "label":
5123
+ if (id && ast_hasProperty(drawableSkips, id)) {
5124
+ parseArg(dotted, l, drawableSkips[id]);
4885
5125
  }
4886
5126
  return;
5127
+ case "iq:application":
5128
+ if (id === "entry") {
5129
+ parseArg(dotted, l);
5130
+ }
5131
+ return;
5132
+ default:
5133
+ return;
5134
+ }
5135
+ };
5136
+ external_sdk_util_cjs_namespaceObject.xmlUtil.visit_xml([e], {
5137
+ pre(node) {
5138
+ if (node.type !== "element")
5139
+ return false;
5140
+ Object.values(node.attr).forEach((attr) => {
5141
+ if (!attr || !attr.value.loc)
5142
+ return;
5143
+ const loc = adjustLoc(attr.value.loc);
5144
+ attr &&
5145
+ stringToScopedName(node, attr.name.value, attr.value.value, loc);
5146
+ });
5147
+ const content = doc.textContent(node);
5148
+ if (content) {
5149
+ stringToScopedName(node, null, content, locRange(node.children[0].loc, node.children[node.children.length - 1].loc));
5150
+ return false;
4887
5151
  }
5152
+ return;
4888
5153
  },
4889
5154
  });
4890
5155
  return result;
@@ -4920,7 +5185,7 @@ function adjustLoc(loc, start = 1, end = -1) {
4920
5185
  },
4921
5186
  };
4922
5187
  }
4923
- function add_one_resource(module, e) {
5188
+ function add_one_resource(state, doc, module, e) {
4924
5189
  let id;
4925
5190
  let func;
4926
5191
  const varDecl = () => {
@@ -4933,24 +5198,24 @@ function add_one_resource(module, e) {
4933
5198
  kind: "var",
4934
5199
  id: makeIdentifier(id ? id.value.value : "*invalid*", loc),
4935
5200
  init,
4936
- }, loc),
5201
+ }, e.loc),
4937
5202
  ],
4938
5203
  kind: "var",
4939
- }, loc);
5204
+ }, e.loc);
4940
5205
  };
4941
5206
  const classDecl = (parent) => {
4942
5207
  if (!id)
4943
5208
  return null;
4944
5209
  const loc = id.value.loc;
4945
5210
  const items = init
4946
- ? [{ type: "ClassElement", item: varDecl(), loc }]
5211
+ ? [{ type: "ClassElement", item: varDecl(), loc: e.loc }]
4947
5212
  : [];
4948
5213
  return {
4949
5214
  type: "ClassDeclaration",
4950
- body: { type: "ClassBody", body: items, loc },
5215
+ body: { type: "ClassBody", body: items, loc: e.loc },
4951
5216
  id: makeIdentifier(id.value.value, loc),
4952
5217
  superClass: makeScopedName(parent),
4953
- loc,
5218
+ loc: e.loc,
4954
5219
  };
4955
5220
  };
4956
5221
  switch (e.name) {
@@ -4992,7 +5257,7 @@ function add_one_resource(module, e) {
4992
5257
  }
4993
5258
  if (!func)
4994
5259
  return;
4995
- const elements = visit_resource_refs(e);
5260
+ const elements = visit_resource_refs(state, doc, e);
4996
5261
  const init = elements.length
4997
5262
  ? { type: "ArrayExpression", elements }
4998
5263
  : undefined;
@@ -5228,7 +5493,7 @@ async function api_getApiMapping(state, resourcesMap, manifestXML) {
5228
5493
  const rezAst = state
5229
5494
  ? state.rezAst || { type: "Program", body: [] }
5230
5495
  : ast;
5231
- add_resources_to_ast(rezAst, resourcesMap, manifestXML);
5496
+ add_resources_to_ast(state, rezAst, resourcesMap, manifestXML);
5232
5497
  if (state) {
5233
5498
  state.rezAst = rezAst;
5234
5499
  state.manifestXML = manifestXML;