@marko/language-tools 2.5.60 → 2.5.62

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/dist/index.js CHANGED
@@ -689,8 +689,14 @@ var emptyView = {
689
689
  offsetAt(_offset) {
690
690
  return;
691
691
  },
692
+ offsetsAt(_offset) {
693
+ return [];
694
+ },
692
695
  rangeAt(_start, _end) {
693
696
  return;
697
+ },
698
+ tokensIn(_start, _end) {
699
+ return [];
694
700
  }
695
701
  };
696
702
  var Extractor = class {
@@ -709,16 +715,46 @@ var Extractor = class {
709
715
  if (typeof range === "string") {
710
716
  this.#generated += range;
711
717
  } else {
718
+ let linkedSources;
719
+ let mapping = 0 /* full */;
720
+ if (Array.isArray(range)) {
721
+ if (!range.length) return this;
722
+ if (range.length > 1) linkedSources = range.slice(1);
723
+ mapping = 1 /* alias */;
724
+ range = range[0];
725
+ }
726
+ const { code } = this.#parsed;
727
+ const sourceStart = Math.min(range.start, code.length);
728
+ const length = Math.max(sourceStart, Math.min(code.length, range.end)) - sourceStart;
712
729
  this.#tokens.push({
713
730
  generatedStart: this.#generated.length,
714
- sourceStart: range.start,
715
- length: Math.min(this.#parsed.code.length, range.end) - range.start
731
+ sourceStart,
732
+ generatedLength: length,
733
+ sourceLength: length,
734
+ mapping,
735
+ linkedSources
716
736
  });
717
- this.#generated += this.#parsed.read(range);
737
+ this.#generated += code.slice(sourceStart, sourceStart + length);
718
738
  }
719
739
  }
720
740
  return this;
721
741
  }
742
+ anchor(range) {
743
+ if (range) {
744
+ const { code } = this.#parsed;
745
+ const sourceStart = Math.min(range.start, code.length);
746
+ const length = Math.max(sourceStart, Math.min(code.length, range.end)) - sourceStart;
747
+ this.#tokens.push({
748
+ generatedStart: this.#generated.length,
749
+ sourceStart,
750
+ generatedLength: 0,
751
+ sourceLength: length,
752
+ mapping: 2 /* anchor */,
753
+ linkedSources: void 0
754
+ });
755
+ }
756
+ return this;
757
+ }
722
758
  end() {
723
759
  return new Extracted(this.#parsed, this.#generated, this.#tokens);
724
760
  }
@@ -727,32 +763,78 @@ var Extracted = class {
727
763
  constructor(parsed, generated, tokens) {
728
764
  this.parsed = parsed;
729
765
  this.#generated = generated;
730
- if (tokens.length === 0) {
731
- this.#generatedToSource = this.#sourceToGenerated = emptyView;
732
- } else {
733
- this.#generatedToSource = new GeneratedToSourceView(tokens);
734
- this.#sourceToGenerated = new SourceToGeneratedView(
735
- [...tokens].sort(sortBySourceThenGenerated)
736
- );
737
- }
766
+ this.#tokens = tokens;
738
767
  }
739
768
  parsed;
740
769
  #generated;
770
+ #tokens;
741
771
  #sourceToGenerated;
772
+ #sourceToGeneratedAll;
742
773
  #generatedToSource;
743
774
  #cachedGeneratedLines;
744
775
  get #generatedLines() {
745
776
  return this.#cachedGeneratedLines || (this.#cachedGeneratedLines = (0, import_htmljs_parser2.getLines)(this.#generated));
746
777
  }
778
+ get #generatedToSourceView() {
779
+ return this.#generatedToSource ??= this.#tokens.length ? new GeneratedToSourceView(this.#tokens) : emptyView;
780
+ }
781
+ get #sourceToGeneratedView() {
782
+ if (this.#sourceToGenerated) return this.#sourceToGenerated;
783
+ let tokens;
784
+ for (const token of this.#tokens) {
785
+ if (token.mapping === 0 /* full */) {
786
+ if (tokens) tokens.push(token);
787
+ else tokens = [token];
788
+ }
789
+ }
790
+ return this.#sourceToGenerated = tokens ? new SourceToGeneratedView(tokens.sort(sortBySourceThenGenerated)) : emptyView;
791
+ }
792
+ get #sourceToGeneratedAllView() {
793
+ if (this.#sourceToGeneratedAll) return this.#sourceToGeneratedAll;
794
+ let hasAliases = false;
795
+ for (const token of this.#tokens) {
796
+ if (token.mapping === 1 /* alias */) {
797
+ hasAliases = true;
798
+ break;
799
+ }
800
+ }
801
+ if (!hasAliases) {
802
+ return this.#sourceToGeneratedAll = this.#sourceToGeneratedView;
803
+ }
804
+ const tokens = [];
805
+ for (const token of this.#tokens) {
806
+ if (token.mapping === 2 /* anchor */) continue;
807
+ tokens.push(token);
808
+ if (token.linkedSources) {
809
+ for (const link of token.linkedSources) {
810
+ const length = Math.min(
811
+ token.generatedLength,
812
+ Math.max(0, link.end - link.start)
813
+ );
814
+ tokens.push({
815
+ generatedStart: token.generatedStart,
816
+ sourceStart: link.start,
817
+ generatedLength: length,
818
+ sourceLength: length,
819
+ mapping: 1 /* alias */,
820
+ linkedSources: void 0
821
+ });
822
+ }
823
+ }
824
+ }
825
+ return this.#sourceToGeneratedAll = new SourceToGeneratedView(
826
+ tokens.sort(sortBySourceThenGenerated)
827
+ );
828
+ }
747
829
  sourceOffsetAt(generatedOffset) {
748
- return this.#generatedToSource.offsetAt(generatedOffset);
830
+ return this.#generatedToSourceView.offsetAt(generatedOffset);
749
831
  }
750
832
  sourcePositionAt(generatedOffset) {
751
833
  const sourceOffset = this.sourceOffsetAt(generatedOffset);
752
834
  if (sourceOffset !== void 0) return this.parsed.positionAt(sourceOffset);
753
835
  }
754
836
  sourceRangeAt(generatedStart, generatedEnd) {
755
- return this.#generatedToSource.rangeAt(generatedStart, generatedEnd);
837
+ return this.#generatedToSourceView.rangeAt(generatedStart, generatedEnd);
756
838
  }
757
839
  sourceLocationAt(generatedStart, generatedEnd) {
758
840
  const sourceRange = this.sourceRangeAt(generatedStart, generatedEnd);
@@ -761,7 +843,48 @@ var Extracted = class {
761
843
  }
762
844
  }
763
845
  generatedOffsetAt(sourceOffset) {
764
- return this.#sourceToGenerated.offsetAt(sourceOffset);
846
+ return this.#sourceToGeneratedView.offsetAt(sourceOffset);
847
+ }
848
+ generatedOffsetsAt(sourceOffset) {
849
+ const offsets = this.#sourceToGeneratedAllView.offsetsAt(sourceOffset);
850
+ return offsets.length > 1 ? [...new Set(offsets)].sort(compareNumbers) : offsets;
851
+ }
852
+ sourceRangesAt(generatedStart, generatedEnd) {
853
+ const result = [];
854
+ for (const token of this.#generatedToSourceView.tokensIn(
855
+ generatedStart,
856
+ generatedEnd
857
+ )) {
858
+ if (token.mapping === 2 /* anchor */) {
859
+ pushUniqueRange(
860
+ result,
861
+ token.sourceStart,
862
+ token.sourceStart + token.sourceLength
863
+ );
864
+ continue;
865
+ }
866
+ const relStart = Math.max(0, generatedStart - token.generatedStart);
867
+ const relEnd = Math.min(
868
+ token.generatedLength,
869
+ generatedEnd - token.generatedStart
870
+ );
871
+ pushUniqueRange(
872
+ result,
873
+ token.sourceStart + relStart,
874
+ token.sourceStart + relEnd
875
+ );
876
+ if (token.linkedSources) {
877
+ for (const link of token.linkedSources) {
878
+ const linkLength = Math.max(0, link.end - link.start);
879
+ pushUniqueRange(
880
+ result,
881
+ link.start + Math.min(relStart, linkLength),
882
+ link.start + Math.min(relEnd, linkLength)
883
+ );
884
+ }
885
+ }
886
+ }
887
+ return result;
765
888
  }
766
889
  generatedPositionAt(sourceOffset) {
767
890
  const generatedOffset = this.generatedOffsetAt(sourceOffset);
@@ -770,7 +893,7 @@ var Extracted = class {
770
893
  }
771
894
  }
772
895
  generatedRangeAt(sourceStart, sourceEnd) {
773
- return this.#sourceToGenerated.rangeAt(sourceStart, sourceEnd);
896
+ return this.#sourceToGeneratedView.rangeAt(sourceStart, sourceEnd);
774
897
  }
775
898
  generatedLocationAt(sourceStart, sourceEnd) {
776
899
  const generatedRange = this.generatedRangeAt(sourceStart, sourceEnd);
@@ -789,69 +912,152 @@ var Extracted = class {
789
912
  var TokenView = class {
790
913
  #tokens;
791
914
  #last;
915
+ #maxEnds;
792
916
  constructor(tokens) {
793
917
  this.#tokens = tokens;
794
918
  this.#last = tokens.length - 1;
795
919
  }
920
+ get #inMaxEnds() {
921
+ if (this.#maxEnds) return this.#maxEnds;
922
+ const tokens = this.#tokens;
923
+ const maxEnds = new Array(tokens.length);
924
+ let max = -1;
925
+ for (let i = 0; i < tokens.length; i++) {
926
+ const token = tokens[i];
927
+ const end = this.inStart(token) + this.inLength(token);
928
+ if (end > max) max = end;
929
+ maxEnds[i] = max;
930
+ }
931
+ return this.#maxEnds = maxEnds;
932
+ }
796
933
  offsetAt(offset) {
934
+ const token = this.#tokenAt(offset);
935
+ if (token) {
936
+ return this.outStart(token) + (offset - this.inStart(token));
937
+ }
938
+ }
939
+ offsetsAt(offset) {
940
+ const result = [];
941
+ const tokens = this.#tokens;
797
942
  let min = 0;
798
943
  let max = this.#last;
799
944
  while (min < max) {
800
945
  const mid = 1 + min + max >>> 1;
801
- if (this.inStart(this.#tokens[mid]) <= offset) {
946
+ if (this.inStart(tokens[mid]) <= offset) {
802
947
  min = mid;
803
948
  } else {
804
949
  max = mid - 1;
805
950
  }
806
951
  }
807
- const token = this.#tokens[min];
808
- const index = offset - this.inStart(token);
809
- if (index >= 0 && index <= token.length) {
810
- return this.outStart(token) + index;
952
+ const maxEnds = this.#inMaxEnds;
953
+ for (let i = min; i >= 0 && maxEnds[i] >= offset; i--) {
954
+ const token = tokens[i];
955
+ const index = offset - this.inStart(token);
956
+ if (index >= 0 && index <= this.inLength(token)) {
957
+ result.push(this.outStart(token) + index);
958
+ }
811
959
  }
960
+ return result;
961
+ }
962
+ tokensIn(inStart, inEnd) {
963
+ const result = [];
964
+ const tokens = this.#tokens;
965
+ if (!tokens.length) return result;
966
+ const maxEnds = this.#inMaxEnds;
967
+ let min = 0;
968
+ let max = this.#last;
969
+ if (maxEnds[max] <= inStart) return result;
970
+ while (min < max) {
971
+ const mid = min + max >> 1;
972
+ if (maxEnds[mid] > inStart) {
973
+ max = mid;
974
+ } else {
975
+ min = mid + 1;
976
+ }
977
+ }
978
+ for (let i = max; i < tokens.length; i++) {
979
+ const token = tokens[i];
980
+ const tokenInStart = this.inStart(token);
981
+ if (tokenInStart >= inEnd) break;
982
+ if (tokenInStart + this.inLength(token) > inStart) {
983
+ result.push(token);
984
+ }
985
+ }
986
+ return result;
812
987
  }
813
988
  rangeAt(inStart, inEnd) {
989
+ if (inStart >= inEnd) {
990
+ return this.#pointAt(inStart);
991
+ }
992
+ const tokens = this.#tokens;
993
+ const maxEnds = this.#inMaxEnds;
814
994
  let min = 0;
815
995
  let max = this.#last;
996
+ if (maxEnds[max] <= inStart) return this.#pointAt(inStart);
816
997
  while (min < max) {
817
998
  const mid = min + max >> 1;
818
- const token = this.#tokens[mid];
819
- const tokenInEnd = this.inStart(token) + token.length;
820
- if (tokenInEnd > inStart) {
999
+ if (maxEnds[mid] > inStart) {
821
1000
  max = mid;
822
1001
  } else {
823
1002
  min = mid + 1;
824
1003
  }
825
1004
  }
826
- const startToken = this.#tokens[max];
1005
+ const startToken = tokens[max];
827
1006
  const startTokenInStart = this.inStart(startToken);
828
- if (startTokenInStart >= inEnd) return;
1007
+ if (startTokenInStart >= inEnd) return this.#pointAt(inStart);
829
1008
  max = this.#last;
830
1009
  while (min < max) {
831
1010
  const mid = 1 + min + max >>> 1;
832
- const token = this.#tokens[mid];
833
- const tokenEnd = this.inStart(token) + token.length;
834
- if (tokenEnd <= inEnd) {
1011
+ if (this.inStart(tokens[mid]) < inEnd) {
835
1012
  min = mid;
836
1013
  } else {
837
1014
  max = mid - 1;
838
1015
  }
839
1016
  }
840
- const endToken = this.#tokens[min];
841
- const endTokenInStart = this.inStart(endToken);
842
- const endTokenInEnd = endTokenInStart + endToken.length;
843
- if (endTokenInEnd < inStart) return;
844
- const startIndex = inStart - startTokenInStart;
845
- const endIndex = inEnd - endTokenInStart;
846
- const start = this.outStart(startToken) + Math.max(0, startIndex);
847
- const end = this.outStart(endToken) + Math.min(endToken.length, endIndex);
1017
+ const endToken = tokens[min];
1018
+ const start = this.outStart(startToken) + Math.max(0, inStart - startTokenInStart);
1019
+ const end = this.outStart(endToken) + (endToken.mapping === 2 /* anchor */ ? endToken.sourceLength : Math.min(this.inLength(endToken), inEnd - this.inStart(endToken)));
1020
+ if (end < start) {
1021
+ return {
1022
+ start,
1023
+ end: this.outStart(startToken) + (startToken.mapping === 2 /* anchor */ ? startToken.sourceLength : Math.min(this.inLength(startToken), inEnd - startTokenInStart))
1024
+ };
1025
+ }
848
1026
  return { start, end };
849
1027
  }
1028
+ #pointAt(offset) {
1029
+ const out = this.offsetAt(offset);
1030
+ if (out !== void 0) return { start: out, end: out };
1031
+ }
1032
+ #tokenAt(offset) {
1033
+ const tokens = this.#tokens;
1034
+ let min = 0;
1035
+ let max = this.#last;
1036
+ while (min < max) {
1037
+ const mid = 1 + min + max >>> 1;
1038
+ if (this.inStart(tokens[mid]) <= offset) {
1039
+ min = mid;
1040
+ } else {
1041
+ max = mid - 1;
1042
+ }
1043
+ }
1044
+ const maxEnds = this.#inMaxEnds;
1045
+ for (let i = min; i >= 0 && maxEnds[i] >= offset; i--) {
1046
+ const token = tokens[i];
1047
+ const index = offset - this.inStart(token);
1048
+ if (index >= 0 && index <= this.inLength(token)) {
1049
+ return token;
1050
+ }
1051
+ }
1052
+ }
850
1053
  };
851
1054
  var GeneratedToSourceView = class extends TokenView {
852
1055
  inStart(token) {
853
1056
  return token.generatedStart;
854
1057
  }
1058
+ inLength(token) {
1059
+ return token.generatedLength;
1060
+ }
855
1061
  outStart(token) {
856
1062
  return token.sourceStart;
857
1063
  }
@@ -860,6 +1066,9 @@ var SourceToGeneratedView = class extends TokenView {
860
1066
  inStart(token) {
861
1067
  return token.sourceStart;
862
1068
  }
1069
+ inLength(token) {
1070
+ return token.sourceLength;
1071
+ }
863
1072
  outStart(token) {
864
1073
  return token.generatedStart;
865
1074
  }
@@ -868,6 +1077,15 @@ function sortBySourceThenGenerated(a, b) {
868
1077
  const delta = a.sourceStart - b.sourceStart;
869
1078
  return delta === 0 ? b.generatedStart - a.generatedStart : delta;
870
1079
  }
1080
+ function compareNumbers(a, b) {
1081
+ return a - b;
1082
+ }
1083
+ function pushUniqueRange(ranges, start, end) {
1084
+ for (const range of ranges) {
1085
+ if (range.start === start && range.end === end) return;
1086
+ }
1087
+ ranges.push({ start, end });
1088
+ }
871
1089
 
872
1090
  // src/extractors/html/keywords.ts
873
1091
  var builtinTagsRegex = (
@@ -1281,6 +1499,7 @@ function crawlProgramScope(parsed, ast) {
1281
1499
  const mutations = [];
1282
1500
  const potentialHoists = [];
1283
1501
  const potentialMutations = /* @__PURE__ */ new Map();
1502
+ const analyzeMutations = hasTagVars(program.body);
1284
1503
  const programScope = {
1285
1504
  parent: void 0,
1286
1505
  hoists: false,
@@ -1356,7 +1575,7 @@ function crawlProgramScope(parsed, ast) {
1356
1575
  "",
1357
1576
  ATTR_UNNAMED
1358
1577
  )) {
1359
- const { name, objectPath, sourceName } = id;
1578
+ const { name, range, objectPath, sourceName } = id;
1360
1579
  const binding = parentScope.bindings[name] = {
1361
1580
  type: 0 /* var */,
1362
1581
  name,
@@ -1364,6 +1583,7 @@ function crawlProgramScope(parsed, ast) {
1364
1583
  scope: parentScope,
1365
1584
  hoisted: false,
1366
1585
  mutated: false,
1586
+ range,
1367
1587
  objectPath,
1368
1588
  sourceName
1369
1589
  };
@@ -1377,7 +1597,7 @@ function crawlProgramScope(parsed, ast) {
1377
1597
  hoists: false,
1378
1598
  bindings: {}
1379
1599
  };
1380
- if (child.params) {
1600
+ if (analyzeMutations && child.params) {
1381
1601
  bodyScope.bindings ??= {};
1382
1602
  const parsedParams = ast.tagParams(child.params);
1383
1603
  if (parsedParams) {
@@ -1395,7 +1615,7 @@ function crawlProgramScope(parsed, ast) {
1395
1615
  }
1396
1616
  }
1397
1617
  }
1398
- const scriptBody = ast.scriptBody(child);
1618
+ const scriptBody = analyzeMutations && ast.scriptBody(child);
1399
1619
  if (scriptBody) {
1400
1620
  const nodes = potentialMutations.get(parentScope);
1401
1621
  if (nodes) {
@@ -1414,12 +1634,15 @@ function crawlProgramScope(parsed, ast) {
1414
1634
  for (const attr of child.attrs) {
1415
1635
  switch (attr.type) {
1416
1636
  case 15 /* AttrSpread */: {
1417
- checkForMutations(parentScope, ast.attrSpread(attr));
1637
+ if (analyzeMutations) {
1638
+ checkForMutations(parentScope, ast.attrSpread(attr));
1639
+ }
1418
1640
  break;
1419
1641
  }
1420
1642
  case 10 /* AttrNamed */: {
1421
1643
  switch ((_a2 = attr.value) == null ? void 0 : _a2.type) {
1422
1644
  case 13 /* AttrValue */: {
1645
+ if (!analyzeMutations && !attr.value.bound) break;
1423
1646
  let parsedValue = ast.attrValue(attr.value);
1424
1647
  if (parsedValue) {
1425
1648
  if (!attr.value.bound) {
@@ -1468,10 +1691,12 @@ function crawlProgramScope(parsed, ast) {
1468
1691
  break;
1469
1692
  }
1470
1693
  case 14 /* AttrMethod */: {
1471
- checkForMutations(
1472
- parentScope,
1473
- ast.attrMethod(attr.value)
1474
- );
1694
+ if (analyzeMutations) {
1695
+ checkForMutations(
1696
+ parentScope,
1697
+ ast.attrMethod(attr.value)
1698
+ );
1699
+ }
1475
1700
  break;
1476
1701
  }
1477
1702
  }
@@ -1513,21 +1738,32 @@ function getProgramBindings(node) {
1513
1738
  let hoists;
1514
1739
  let vars;
1515
1740
  for (const key in bindings) {
1516
- switch (bindings[key].type) {
1517
- case 2 /* hoisted */:
1741
+ const binding = bindings[key];
1742
+ switch (binding.type) {
1743
+ case 2 /* hoisted */: {
1744
+ const hoist = {
1745
+ name: key,
1746
+ sources: binding.bindings.map((it) => it.range)
1747
+ };
1518
1748
  if (hoists) {
1519
- hoists.push(key);
1749
+ hoists.push(hoist);
1520
1750
  } else {
1521
- hoists = [key];
1751
+ hoists = [hoist];
1522
1752
  }
1523
1753
  break;
1524
- case 0 /* var */:
1754
+ }
1755
+ case 0 /* var */: {
1756
+ const tagVar = {
1757
+ name: key,
1758
+ sources: [binding.range]
1759
+ };
1525
1760
  if (vars) {
1526
- vars.push(key);
1761
+ vars.push(tagVar);
1527
1762
  } else {
1528
- vars = [key];
1763
+ vars = [tagVar];
1529
1764
  }
1530
1765
  break;
1766
+ }
1531
1767
  }
1532
1768
  }
1533
1769
  if (hoists || vars) {
@@ -1558,11 +1794,12 @@ function getHoistSources(body) {
1558
1794
  if (body) {
1559
1795
  const { bindings } = Scopes.get(body);
1560
1796
  for (const key in bindings) {
1561
- if (bindings[key].hoisted) {
1797
+ const binding = bindings[key];
1798
+ if (binding.hoisted) {
1562
1799
  if (result) {
1563
- result.push(key);
1800
+ result.push(binding);
1564
1801
  } else {
1565
- result = [key];
1802
+ result = [binding];
1566
1803
  }
1567
1804
  }
1568
1805
  }
@@ -1570,16 +1807,9 @@ function getHoistSources(body) {
1570
1807
  return result;
1571
1808
  }
1572
1809
  function isMutatedVar(node, name) {
1573
- var _a;
1574
- let scope = Scopes.get(node.body);
1575
- while (scope) {
1576
- const binding = (_a = scope.bindings) == null ? void 0 : _a[name];
1577
- if ((binding == null ? void 0 : binding.type) === 0 /* var */ && binding.mutated) {
1578
- return true;
1579
- }
1580
- scope = scope.parent;
1581
- }
1582
- return false;
1810
+ const scope = Scopes.get(node.body);
1811
+ const binding = scope && resolveWritableVar(scope, name);
1812
+ return binding ? binding.mutated : false;
1583
1813
  }
1584
1814
  function hasHoists(node) {
1585
1815
  return node.body ? Scopes.get(node.body).hoists : false;
@@ -1587,27 +1817,47 @@ function hasHoists(node) {
1587
1817
  function getBoundAttrRange(value) {
1588
1818
  return BoundAttrValueRange.get(value);
1589
1819
  }
1820
+ function hasTagVars(body) {
1821
+ if (body) {
1822
+ for (const child of body) {
1823
+ switch (child.type) {
1824
+ case 1 /* Tag */:
1825
+ case 16 /* AttrTag */:
1826
+ if (child.var || hasTagVars(child.body)) {
1827
+ return true;
1828
+ }
1829
+ break;
1830
+ }
1831
+ }
1832
+ }
1833
+ return false;
1834
+ }
1590
1835
  function resolveWritableVar(scope, name) {
1591
1836
  var _a;
1592
1837
  let curScope = scope;
1593
1838
  do {
1594
1839
  const binding = (_a = curScope.bindings) == null ? void 0 : _a[name];
1595
- if ((binding == null ? void 0 : binding.type) === 0 /* var */ && binding.sourceName !== void 0) {
1596
- return binding;
1840
+ if (binding) {
1841
+ return binding.type === 0 /* var */ && binding.sourceName !== void 0 ? binding : void 0;
1597
1842
  }
1598
1843
  } while (curScope = curScope.parent);
1599
1844
  }
1600
1845
  function* getIdentifiers(lVal) {
1846
+ for (const id of getIdentifierNodes(lVal)) {
1847
+ yield id.name;
1848
+ }
1849
+ }
1850
+ function* getIdentifierNodes(lVal) {
1601
1851
  switch (lVal.type) {
1602
1852
  case "Identifier":
1603
- yield lVal.name;
1853
+ yield lVal;
1604
1854
  break;
1605
1855
  case "ObjectPattern":
1606
1856
  for (const prop of lVal.properties) {
1607
1857
  if (prop.type === "RestElement") {
1608
- yield* getIdentifiers(prop.argument);
1858
+ yield* getIdentifierNodes(prop.argument);
1609
1859
  } else {
1610
- yield* getIdentifiers(prop.value);
1860
+ yield* getIdentifierNodes(prop.value);
1611
1861
  }
1612
1862
  }
1613
1863
  break;
@@ -1615,15 +1865,15 @@ function* getIdentifiers(lVal) {
1615
1865
  for (const element of lVal.elements) {
1616
1866
  if (element) {
1617
1867
  if (element.type === "RestElement") {
1618
- yield* getIdentifiers(element.argument);
1868
+ yield* getIdentifierNodes(element.argument);
1619
1869
  } else {
1620
- yield* getIdentifiers(element);
1870
+ yield* getIdentifierNodes(element);
1621
1871
  }
1622
1872
  }
1623
1873
  }
1624
1874
  break;
1625
1875
  case "AssignmentPattern":
1626
- yield* getIdentifiers(lVal.left);
1876
+ yield* getIdentifierNodes(lVal.left);
1627
1877
  break;
1628
1878
  }
1629
1879
  }
@@ -1632,6 +1882,7 @@ function* getVarIdentifiers(parsed, lVal, objectPath, sourceName) {
1632
1882
  case "Identifier":
1633
1883
  yield {
1634
1884
  name: lVal.name,
1885
+ range: { start: lVal.start, end: lVal.start + lVal.name.length },
1635
1886
  objectPath,
1636
1887
  sourceName
1637
1888
  };
@@ -1694,9 +1945,17 @@ function trackMutations(node, scope, mutations, parentBlockShadows, parentBlockM
1694
1945
  blockMutations = [];
1695
1946
  }
1696
1947
  break;
1697
- case "ForStatement":
1698
1948
  case "ForInStatement":
1699
1949
  case "ForOfStatement":
1950
+ if (node.left.type !== "VariableDeclaration") {
1951
+ for (const id of getIdentifierNodes(node.left)) {
1952
+ parentBlockMutations.push(id);
1953
+ }
1954
+ }
1955
+ blockShadows = new Set(blockShadows);
1956
+ blockMutations = [];
1957
+ break;
1958
+ case "ForStatement":
1700
1959
  blockShadows = new Set(blockShadows);
1701
1960
  blockMutations = [];
1702
1961
  break;
@@ -1727,7 +1986,9 @@ function trackMutations(node, scope, mutations, parentBlockShadows, parentBlockM
1727
1986
  }
1728
1987
  break;
1729
1988
  case "FunctionDeclaration":
1730
- trackShadows(node.id, scope, parentBlockShadows);
1989
+ if (node.id) {
1990
+ trackShadows(node.id, scope, parentBlockShadows);
1991
+ }
1731
1992
  blockShadows = new Set(blockShadows);
1732
1993
  blockMutations = [];
1733
1994
  for (const param of node.params) {
@@ -1768,6 +2029,10 @@ function trackMutations(node, scope, mutations, parentBlockShadows, parentBlockM
1768
2029
  case "AssignmentExpression":
1769
2030
  if (node.left.type === "Identifier") {
1770
2031
  parentBlockMutations.push(node.left);
2032
+ } else {
2033
+ for (const id of getIdentifierNodes(node.left)) {
2034
+ parentBlockMutations.push(id);
2035
+ }
1771
2036
  }
1772
2037
  break;
1773
2038
  }
@@ -2098,7 +2363,7 @@ var ATTR_UNNAMED2 = "value";
2098
2363
  var REG_EXT = /(?<=[/\\][^/\\]+)\.[^.]+$/;
2099
2364
  var REG_BLOCK = /\s*{/y;
2100
2365
  var REG_NEW_LINE = /^|(\r?\n)/g;
2101
- var REG_ATTR_ARG_LITERAL = /(?<=\s*)(["'])((?:[^"'\\]|\\.|(?!\1))*)\1\s*([,)])/my;
2366
+ var REG_ATTR_ARG_LITERAL = /(["'])((?:\\.|(?!\1)[^\\])*)\1\s*([,)])/y;
2102
2367
  var REG_TAG_IMPORT = /(?<=(['"]))<([^'">]+)>(?=\1)/;
2103
2368
  var REG_INPUT_TYPE = /\s*(interface|type)\s+Input\b/y;
2104
2369
  var REG_OBJECT_PROPERTY = /^[_$a-z][_$a-z0-9]*$/i;
@@ -2190,11 +2455,12 @@ var ScriptExtractor = class {
2190
2455
  if (templatePath) {
2191
2456
  const [{ length }] = tagImportMatch;
2192
2457
  const fromStart = node.start + tagImportMatch.index;
2458
+ const fromEnd = fromStart + length;
2193
2459
  this.#extractor.copy({
2194
2460
  start: node.start,
2195
2461
  end: fromStart
2196
2462
  }).write(templatePath).copy({
2197
- start: fromStart + length,
2463
+ start: fromEnd,
2198
2464
  end: node.end
2199
2465
  }).write("\n");
2200
2466
  break;
@@ -2326,9 +2592,9 @@ function ${templateName}() {
2326
2592
  const body = this.#processBody(program);
2327
2593
  const bindings = getProgramBindings(program);
2328
2594
  if (bindings) {
2329
- for (const name of bindings.all) {
2330
- this.#extractor.write(
2331
- `const ${name} = ${varShared("hoist")}(() => ${varLocal(`hoist__${name}`)});
2595
+ for (const binding of bindings.all) {
2596
+ this.#extractor.write("const ").copy(binding.sources).write(
2597
+ ` = ${varShared("hoist")}(() => ${varLocal(`hoist__${binding.name}`)});
2332
2598
  `
2333
2599
  );
2334
2600
  }
@@ -2337,16 +2603,17 @@ function ${templateName}() {
2337
2603
  this.#writeChildren(body.content);
2338
2604
  if (bindings) {
2339
2605
  if (bindings.vars) {
2340
- for (const name of bindings.vars) {
2341
- this.#extractor.write(
2342
- `var ${varLocal(`hoist__${name}`)} = ${name};
2343
- `
2344
- );
2606
+ for (const binding of bindings.vars) {
2607
+ this.#extractor.write(`var ${varLocal(`hoist__${binding.name}`)} = `).copy(binding.sources[0]).write(";\n");
2345
2608
  }
2346
2609
  }
2347
2610
  if (bindings.hoists) {
2348
2611
  this.#extractor.write(
2349
- `var {${bindings.hoists.map((name) => `${name}: ${varLocal(`hoist__${name}`)}`).join(SEP_COMMA_SPACE)}} = ${this.#getBodyHoistScopeExpression(program.body)};
2612
+ `var {${bindings.hoists.map(
2613
+ (binding) => `${binding.name}: ${varLocal(`hoist__${binding.name}`)}`
2614
+ ).join(
2615
+ SEP_COMMA_SPACE
2616
+ )}} = ${this.#getBodyHoistScopeExpression(program.body)};
2350
2617
  `
2351
2618
  );
2352
2619
  }
@@ -2354,7 +2621,7 @@ function ${templateName}() {
2354
2621
  this.#endChildren();
2355
2622
  }
2356
2623
  this.#extractor.write(
2357
- `${varShared("noop")}({ ${bindings ? bindings.all.join(SEP_COMMA_SPACE) + SEP_COMMA_SPACE : ""}${this.#api === RuntimeAPI.class ? "component, state, out, " : ""}input, $global, $signal });
2624
+ `${varShared("noop")}({ ${bindings ? bindings.all.map((binding) => binding.name).join(SEP_COMMA_SPACE) + SEP_COMMA_SPACE : ""}${this.#api === RuntimeAPI.class ? "component, state, out, " : ""}input, $global, $signal });
2358
2625
  `
2359
2626
  );
2360
2627
  if (didReturn) {
@@ -2389,14 +2656,14 @@ function ${templateName}() {
2389
2656
  -1
2390
2657
  )}>${renderAndReturn};` : `(): () => <${internalInputWithExtends}>${renderAndReturn};`}
2391
2658
  }>`;
2392
- this.#extractor.copy(START_OF_FILE);
2659
+ this.#extractor.write(`export default new `).anchor(START_OF_FILE);
2393
2660
  if (this.#scriptLang === "ts" /* ts */) {
2394
- this.#extractor.write(`export default new (
2661
+ this.#extractor.write(`(
2395
2662
  class Template extends ${templateOverrideClass} {}
2396
2663
  );
2397
2664
  `);
2398
2665
  } else {
2399
- this.#extractor.write(`export default new (
2666
+ this.#extractor.write(`(
2400
2667
  /**
2401
2668
  * @extends {${removeNewLines(templateOverrideClass)}}
2402
2669
  */
@@ -2444,24 +2711,42 @@ function ${templateName}() {
2444
2711
  }
2445
2712
  }
2446
2713
  #writeReturn(returned, body) {
2447
- const scopeExpr = this.#getScopeExpression(body);
2448
- if (!returned && !scopeExpr) {
2714
+ const hasScope = this.#hasScopeExpression(body);
2715
+ if (!returned && !hasScope) {
2449
2716
  this.#extractor.write(`return ${varShared("voidReturn")};
2450
2717
  `);
2451
2718
  return;
2452
2719
  }
2453
- this.#extractor.write(`return new (class MarkoReturn<Return = void> {
2720
+ if (this.#scriptLang === "ts" /* ts */) {
2721
+ this.#extractor.write(`return new (class MarkoReturn<Return = void> {
2454
2722
  `);
2455
- if (scopeExpr) {
2456
- this.#extractor.write(
2457
- `readonly [${varShared("scope")}] = ${scopeExpr};
2458
- `
2459
- );
2460
- }
2461
- this.#extractor.write(`declare return: Return;
2723
+ if (hasScope) {
2724
+ this.#extractor.write(`readonly [${varShared("scope")}] = `);
2725
+ this.#writeScopeExpression(body);
2726
+ this.#extractor.write(";\n");
2727
+ }
2728
+ this.#extractor.write(`declare return: Return;
2462
2729
  constructor(_?: Return) {}
2463
2730
  })(
2464
2731
  `);
2732
+ } else {
2733
+ this.#extractor.write(`return new (/**
2734
+ * @template [Return=void]
2735
+ */
2736
+ class MarkoReturn {
2737
+ `);
2738
+ if (hasScope) {
2739
+ this.#extractor.write(`[${varShared("scope")}] = `);
2740
+ this.#writeScopeExpression(body);
2741
+ this.#extractor.write(";\n");
2742
+ }
2743
+ this.#extractor.write(`/** @type {Return} */
2744
+ return;
2745
+ /** @param {Return} [_] */
2746
+ constructor(_) {}
2747
+ })(
2748
+ `);
2749
+ }
2465
2750
  this.#extractor.copy(returned);
2466
2751
  this.#extractor.write(");\n");
2467
2752
  }
@@ -2505,12 +2790,10 @@ constructor(_?: Return) {}
2505
2790
  const ifBody = this.#processBody(child);
2506
2791
  if (ifBody == null ? void 0 : ifBody.content) {
2507
2792
  this.#writeChildren(ifBody.content, true);
2508
- const scopeExpr = this.#getScopeExpression(child.body);
2509
- if (scopeExpr) {
2510
- this.#extractor.write(`return {
2511
- scope: ${scopeExpr}
2512
- };
2513
- `);
2793
+ if (this.#hasScopeExpression(child.body)) {
2794
+ this.#extractor.write("return {\nscope: ");
2795
+ this.#writeScopeExpression(child.body);
2796
+ this.#extractor.write("\n};\n");
2514
2797
  }
2515
2798
  this.#endChildren();
2516
2799
  }
@@ -2529,14 +2812,10 @@ scope: ${scopeExpr}
2529
2812
  const alternateBody = this.#processBody(node);
2530
2813
  if (alternateBody == null ? void 0 : alternateBody.content) {
2531
2814
  this.#writeChildren(alternateBody.content, true);
2532
- const scopeExpr = this.#getScopeExpression(node.body);
2533
- if (scopeExpr) {
2534
- this.#extractor.write(
2535
- `return {
2536
- scope: ${scopeExpr}
2537
- };
2538
- `
2539
- );
2815
+ if (this.#hasScopeExpression(node.body)) {
2816
+ this.#extractor.write("return {\nscope: ");
2817
+ this.#writeScopeExpression(node.body);
2818
+ this.#extractor.write("\n};\n");
2540
2819
  }
2541
2820
  this.#endChildren();
2542
2821
  }
@@ -2561,8 +2840,7 @@ scope: ${scopeExpr}
2561
2840
  this.#extractor.write(
2562
2841
  `${varShared(getForTagRuntime(this.#parsed, child))}({
2563
2842
  `
2564
- );
2565
- this.#writeTagNameComment(child);
2843
+ ).anchor(child.name);
2566
2844
  this.#writeAttrs(child);
2567
2845
  this.#extractor.write("\n}" + SEP_COMMA_NEW_LINE).copy(child.typeParams).write("(\n");
2568
2846
  this.#writeComments(child);
@@ -2684,9 +2962,7 @@ scope: ${scopeExpr}
2684
2962
  } else if (templateVar) {
2685
2963
  this.#extractor.write(
2686
2964
  `${varShared(isTemplate ? "renderTemplate" : "renderDynamicTag")}(${templateVar}`
2687
- );
2688
- this.#writeTagNameComment(tag);
2689
- this.#extractor.write(")");
2965
+ ).anchor(tag.name).write(")");
2690
2966
  } else {
2691
2967
  this.#extractor.write(varShared("missingTag"));
2692
2968
  }
@@ -2720,9 +2996,6 @@ scope: ${scopeExpr}
2720
2996
  this.#extractor.write(`${varShared("interpolated")}\``).copy(tag.name).write("`");
2721
2997
  }
2722
2998
  }
2723
- #writeTagNameComment(tag) {
2724
- this.#extractor.write("/*").copy(this.#getDynamicTagExpression(tag) || tag.name).write("*/");
2725
- }
2726
2999
  #writePlaceholder(placeholder) {
2727
3000
  this.#writeComments(placeholder);
2728
3001
  this.#extractor.write("(").copy(placeholder.value).write(");\n");
@@ -2732,7 +3005,6 @@ scope: ${scopeExpr}
2732
3005
  this.#extractor.copy(scriptlet.value).write(";\n");
2733
3006
  }
2734
3007
  #writeAttrs(tag) {
2735
- var _a, _b, _c, _d, _e, _f;
2736
3008
  let hasAttrs = false;
2737
3009
  if (tag.shorthandId) {
2738
3010
  hasAttrs = true;
@@ -2754,19 +3026,9 @@ scope: ${scopeExpr}
2754
3026
  }
2755
3027
  this.#extractor.write("`" + SEP_COMMA_NEW_LINE);
2756
3028
  }
2757
- let attrWhitespaceStart = Math.max(
2758
- tag.name.end,
2759
- ((_a = tag.shorthandId) == null ? void 0 : _a.end) ?? -1,
2760
- ((_c = (_b = tag.shorthandClassNames) == null ? void 0 : _b[tag.shorthandClassNames.length - 1]) == null ? void 0 : _c.end) ?? -1,
2761
- ((_d = tag.var) == null ? void 0 : _d.end) ?? -1,
2762
- ((_e = tag.args) == null ? void 0 : _e.end) ?? -1,
2763
- ((_f = tag.params) == null ? void 0 : _f.end) ?? -1
2764
- );
2765
3029
  if (tag.attrs) {
2766
3030
  hasAttrs = true;
2767
3031
  for (const attr of tag.attrs) {
2768
- this.#copyWhitespaceWithin(attrWhitespaceStart, attr.start);
2769
- attrWhitespaceStart = attr.end;
2770
3032
  switch (attr.type) {
2771
3033
  case 15 /* AttrSpread */:
2772
3034
  this.#extractor.write(`...(
@@ -2787,18 +3049,18 @@ scope: ${scopeExpr}
2787
3049
  if (value) {
2788
3050
  switch (value.type) {
2789
3051
  case 14 /* AttrMethod */:
2790
- this.#extractor.write('"').copy(defaultMapPosition).copy(name).write('"').copy(value.typeParams);
3052
+ this.#extractor.write('"').anchor(defaultMapPosition).copy(name).write('"').copy(value.typeParams);
2791
3053
  this.#copyWithMutationsReplaced(value.params);
2792
3054
  this.#copyWithMutationsReplaced(value.body);
2793
3055
  break;
2794
3056
  case 13 /* AttrValue */: {
2795
3057
  const boundRange = value.bound && getBoundAttrRange(value);
2796
- this.#extractor.write('"').copy(defaultMapPosition).copy(name).write('": (\n');
3058
+ this.#extractor.write('"').anchor(defaultMapPosition).copy(name).write('": (\n');
2797
3059
  if (boundRange) {
2798
3060
  if (!boundRange.member) {
2799
3061
  const valueLiteral = this.#read(boundRange.value);
2800
3062
  this.#extractor.copy(boundRange.value).write(" ").copy(boundRange.types).write(`
2801
- )${SEP_COMMA_NEW_LINE}"`).copy(defaultMapPosition).copy(name).write(
3063
+ )${SEP_COMMA_NEW_LINE}"`).anchor(defaultMapPosition).copy(name).write(
2802
3064
  `Change"(
2803
3065
  // @ts-ignore
2804
3066
  _${valueLiteral}
@@ -2814,7 +3076,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
2814
3076
  start: boundRange.member.end,
2815
3077
  end: boundRange.member.end + 1
2816
3078
  }).copy(boundRange.types).write(`
2817
- )${SEP_COMMA_NEW_LINE}"`).copy(defaultMapPosition).copy(name).write('Change": (\n');
3079
+ )${SEP_COMMA_NEW_LINE}"`).anchor(defaultMapPosition).copy(name).write('Change": (\n');
2818
3080
  if (modifier) {
2819
3081
  this.#extractor.copy(boundRange.value).write("[`${\n").copy(boundRange.member).write("\n}Change`] && ((\n// @ts-ignore\n_\n)=>{\n").copy(boundRange.value).write("[`${\n").copy(boundRange.member).write("\n}Change`](").copy(modifier).write("(_));\n})");
2820
3082
  } else {
@@ -2827,7 +3089,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
2827
3089
  end: boundRange.member.end
2828
3090
  };
2829
3091
  this.#extractor.copy(memberRange).copy(boundRange.types).write(`
2830
- )${SEP_COMMA_NEW_LINE}"`).copy(defaultMapPosition).copy(name).write('Change": (\n');
3092
+ )${SEP_COMMA_NEW_LINE}"`).anchor(defaultMapPosition).copy(name).write('Change": (\n');
2831
3093
  if (modifier) {
2832
3094
  this.#extractor.copy(memberRange).write("Change && ((\n// @ts-ignore\n_\n)=>{\n").copy(memberRange).write("Change(").copy(modifier).write("(_));\n})");
2833
3095
  } else {
@@ -2882,7 +3144,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
2882
3144
  this.#extractor.copy(attr.args);
2883
3145
  }
2884
3146
  } else {
2885
- this.#extractor.write('"').copy(defaultMapPosition).copy(name).write(`": ${modifier ? '""' : "true"}`);
3147
+ this.#extractor.write('"').anchor(defaultMapPosition).copy(name).write(`": ${modifier ? '""' : "true"}`);
2886
3148
  }
2887
3149
  break;
2888
3150
  }
@@ -2890,10 +3152,6 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
2890
3152
  this.#extractor.write(SEP_COMMA_NEW_LINE);
2891
3153
  }
2892
3154
  }
2893
- this.#copyWhitespaceWithin(
2894
- attrWhitespaceStart,
2895
- tag.open.end - (tag.concise ? this.#code[tag.open.end] === ";" ? 1 : 0 : tag.selfClosed ? 2 : 1)
2896
- );
2897
3155
  return hasAttrs;
2898
3156
  }
2899
3157
  #writeAttrTags({ staticAttrTags, dynamicAttrTagParents }, constraintExpr) {
@@ -2927,9 +3185,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
2927
3185
  const isRepeated = attrTag.length > 1;
2928
3186
  const [firstAttrTag] = attrTag;
2929
3187
  const name = this.#getAttrTagName(firstAttrTag);
2930
- this.#extractor.write(`["${name}"`);
2931
- this.#writeTagNameComment(firstAttrTag);
2932
- this.#extractor.write("]: ");
3188
+ this.#extractor.write(`["`).anchor(firstAttrTag.name).write(`${name}"]: `);
2933
3189
  if (isRepeated) {
2934
3190
  const templateVar = this.#getTemplateVar(firstAttrTag.owner);
2935
3191
  if (templateVar) {
@@ -2941,9 +3197,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
2941
3197
  }
2942
3198
  this.#extractor.write(`"${name}",`);
2943
3199
  for (const childNode of attrTag) {
2944
- this.#extractor.write(`{["${name}"`);
2945
- this.#writeTagNameComment(childNode);
2946
- this.#extractor.write("]: ");
3200
+ this.#extractor.write(`{["`).anchor(childNode.name).write(`${name}"]: `);
2947
3201
  this.#writeTagInputObject(childNode);
2948
3202
  this.#extractor.write(`}${SEP_COMMA_NEW_LINE}`);
2949
3203
  }
@@ -2989,11 +3243,8 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
2989
3243
  break;
2990
3244
  }
2991
3245
  case "for": {
2992
- this.#extractor.write(
2993
- `${varShared(getForAttrTagRuntime(this.#parsed, tag))}({
2994
- `
2995
- );
2996
- this.#writeTagNameComment(tag);
3246
+ this.#extractor.write(`${varShared(getForAttrTagRuntime(this.#parsed, tag))}({
3247
+ `).anchor(tag.name);
2997
3248
  this.#writeAttrs(tag);
2998
3249
  this.#extractor.write("\n}, \n");
2999
3250
  this.#writeComments(tag);
@@ -3067,7 +3318,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
3067
3318
  hasBodyContent = true;
3068
3319
  }
3069
3320
  if (tag.params || hasBodyContent) {
3070
- this.#extractor.write("[");
3321
+ this.#extractor.write("[").anchor(tag.name);
3071
3322
  if (this.#interop) {
3072
3323
  const templateVar = this.#getTemplateVar(
3073
3324
  tag.type === 16 /* AttrTag */ ? tag.owner : tag
@@ -3080,7 +3331,6 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
3080
3331
  } else {
3081
3332
  this.#extractor.write('"content"');
3082
3333
  }
3083
- this.#writeTagNameComment(tag);
3084
3334
  this.#extractor.write("]: ");
3085
3335
  if (tag.params) {
3086
3336
  this.#extractor.write("(");
@@ -3112,10 +3362,10 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
3112
3362
  this.#extractor.write(SEP_COMMA_NEW_LINE);
3113
3363
  }
3114
3364
  if (tag.type === 16 /* AttrTag */) {
3115
- this.#extractor.write("[/*").copy(tag.name).write(`*/Symbol.iterator]: ${varShared("any")}${SEP_COMMA_NEW_LINE}`);
3365
+ this.#extractor.write("[").anchor(tag.name).write(`Symbol.iterator]: ${varShared("any")}${SEP_COMMA_NEW_LINE}`);
3116
3366
  }
3117
3367
  if (!hasInput) {
3118
- this.#writeTagNameComment(tag);
3368
+ this.#extractor.anchor(tag.name);
3119
3369
  }
3120
3370
  if (writeInputObj) {
3121
3371
  this.#extractor.write("\n}");
@@ -3154,25 +3404,6 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
3154
3404
  minIndex = maxIndex + 1;
3155
3405
  } while (true);
3156
3406
  }
3157
- #copyWhitespaceWithin(start, end) {
3158
- const code = this.#code;
3159
- const max = Math.min(end, code.length);
3160
- let lastPos = start;
3161
- let pos = start;
3162
- while (pos < max) {
3163
- if (!isWhitespaceCode(code.charCodeAt(pos))) {
3164
- lastPos = pos + 1;
3165
- if (pos > lastPos) {
3166
- this.#extractor.copy({ start: lastPos, end: pos });
3167
- }
3168
- return;
3169
- }
3170
- pos++;
3171
- }
3172
- if (pos > lastPos) {
3173
- this.#extractor.copy({ start: lastPos, end: pos });
3174
- }
3175
- }
3176
3407
  #processBody(parent) {
3177
3408
  var _a;
3178
3409
  const { body } = parent;
@@ -3370,6 +3601,15 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
3370
3601
  })
3371
3602
  };
3372
3603
  }
3604
+ } else if (node.type === 24 /* Import */) {
3605
+ const imported = this.#ast.import(node);
3606
+ if (imported) {
3607
+ for (const specifier of imported.specifiers) {
3608
+ if (specifier.local.name === "Input") {
3609
+ return { typeParameters: void 0 };
3610
+ }
3611
+ }
3612
+ }
3373
3613
  }
3374
3614
  }
3375
3615
  }
@@ -3378,8 +3618,6 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
3378
3618
  }
3379
3619
  #getJSDocInputTypeFromNodes(nodes) {
3380
3620
  for (const node of nodes) {
3381
- const code = this.#read(node);
3382
- code;
3383
3621
  const info = this.#getJSDocInputTypeFromNode(node);
3384
3622
  if (info) return info;
3385
3623
  }
@@ -3426,10 +3664,23 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
3426
3664
  }
3427
3665
  return id;
3428
3666
  }
3429
- #getScopeExpression(body) {
3667
+ #hasScopeExpression(body) {
3668
+ return !!(getHoistSources(body) || this.#getBodyHoistScopeExpression(body));
3669
+ }
3670
+ #writeScopeExpression(body) {
3430
3671
  const sources = getHoistSources(body);
3431
3672
  const hoists = this.#getBodyHoistScopeExpression(body);
3432
- return sources ? `{ ${hoists ? `...${hoists}, ` : ""}${sources.join(SEP_COMMA_SPACE)} }` : hoists;
3673
+ if (!sources) {
3674
+ if (hoists) this.#extractor.write(hoists);
3675
+ return;
3676
+ }
3677
+ this.#extractor.write(`{ ${hoists ? `...${hoists}, ` : ""}`);
3678
+ let sep = SEP_EMPTY;
3679
+ for (const binding of sources) {
3680
+ this.#extractor.write(sep).copy(binding.range);
3681
+ sep = SEP_COMMA_SPACE;
3682
+ }
3683
+ this.#extractor.write(" }");
3433
3684
  }
3434
3685
  #getBodyHoistScopeExpression(body) {
3435
3686
  let hoistVars;
@@ -3688,8 +3939,8 @@ function extractStyle(opts) {
3688
3939
  attr.type === 10 /* AttrNamed */ && ((_a = attr.value) == null ? void 0 : _a.type) === 13 /* AttrValue */ && /^['"]$/.test(code[attr.value.value.start])
3689
3940
  ) {
3690
3941
  const name = read(attr.name);
3691
- if (name === "#style" || name === "style" && node.nameText && name === "style" && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html)) {
3692
- getExtractor("css").write(":root{").copy({
3942
+ if (name === "#style" || name === "style" && node.nameText && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html)) {
3943
+ getExtractor(".css").write(":root{").copy({
3693
3944
  start: attr.value.value.start + 1,
3694
3945
  end: attr.value.value.end - 1
3695
3946
  }).write("}");