@marko/language-server 1.0.0 → 1.0.1

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
@@ -1447,6 +1447,7 @@ function patch(ts2, scriptLang, cache, host) {
1447
1447
  var IGNORE_DIAG_REG = /^(?:Expression|Identifier|['"][^\w]['"]) expected.$/;
1448
1448
  var extractCache = /* @__PURE__ */ new Map();
1449
1449
  var snapshotCache = /* @__PURE__ */ new Map();
1450
+ var insertModuleStatementLocCache = /* @__PURE__ */ new WeakMap();
1450
1451
  var markoFileReg = /\.marko$/;
1451
1452
  var tsTriggerChars = /* @__PURE__ */ new Set([".", '"', "'", "`", "/", "@", "<", "#", " "]);
1452
1453
  var optionalModifierReg = /\boptional\b/;
@@ -1627,18 +1628,29 @@ var ScriptService = {
1627
1628
  for (const change of action.changes) {
1628
1629
  if (change.fileName !== fileName)
1629
1630
  continue;
1630
- for (const { span, newText } of change.textChanges) {
1631
- const sourceRange = /^\s*(?:import|export) /.test(newText) ? (
1632
- // Ensure import inserts are always in the program root.
1633
- // TODO: this could probably be updated to more closely reflect
1634
- // where typescript wants to put the import/export.
1635
- START_LOCATION
1636
- ) : sourceLocationAtTextSpan(extracted, span);
1637
- if (sourceRange) {
1638
- textEdits.push({
1639
- newText,
1640
- range: sourceRange
1641
- });
1631
+ for (const { span, newText: rawText } of change.textChanges) {
1632
+ let range;
1633
+ let newText = rawText;
1634
+ if (span.length === 0 && /^\s*(?:import|export) /.test(newText)) {
1635
+ const cached = insertModuleStatementLocCache.get(extracted);
1636
+ newText = newText.replace(/\n\s*$/, "\n");
1637
+ if (cached) {
1638
+ range = cached;
1639
+ } else {
1640
+ const { parsed } = getMarkoFile(doc);
1641
+ const offset = getInsertModuleStatementOffset(parsed);
1642
+ const start = parsed.positionAt(offset);
1643
+ range = {
1644
+ start,
1645
+ end: start
1646
+ };
1647
+ insertModuleStatementLocCache.set(extracted, range);
1648
+ }
1649
+ } else {
1650
+ range = sourceLocationAtTextSpan(extracted, span);
1651
+ }
1652
+ if (range) {
1653
+ textEdits.push({ newText, range });
1642
1654
  }
1643
1655
  }
1644
1656
  }
@@ -1844,6 +1856,42 @@ function processScript(doc, tsProject) {
1844
1856
  });
1845
1857
  });
1846
1858
  }
1859
+ function getInsertModuleStatementOffset(parsed) {
1860
+ const { program } = parsed;
1861
+ let firstNode;
1862
+ if (program.static.length) {
1863
+ let lastImport;
1864
+ for (const node of program.static) {
1865
+ switch (node.type) {
1866
+ case import_language_tools14.NodeType.Export:
1867
+ return node.start;
1868
+ case import_language_tools14.NodeType.Import:
1869
+ lastImport = node;
1870
+ break;
1871
+ }
1872
+ }
1873
+ if (lastImport) {
1874
+ return lastImport.end + 1;
1875
+ }
1876
+ firstNode = program.static[0];
1877
+ }
1878
+ if (program.body.length) {
1879
+ if (!firstNode || firstNode.start > program.body[0].start) {
1880
+ firstNode = program.body[0];
1881
+ }
1882
+ }
1883
+ if (firstNode) {
1884
+ return getOffsetAfterComments(firstNode);
1885
+ }
1886
+ return 0;
1887
+ }
1888
+ function getOffsetAfterComments(node) {
1889
+ const { comments } = node;
1890
+ if (comments) {
1891
+ return comments.at(-1).end + 1;
1892
+ }
1893
+ return Math.max(0, node.start - 1);
1894
+ }
1847
1895
  function sourceLocationAtTextSpan(extracted, { start, length }) {
1848
1896
  if (start === 0 && length === 0)
1849
1897
  return START_LOCATION;