@ripple-ts/language-server 0.3.61 → 0.3.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.
@@ -50,6 +50,7 @@ fs = __toESM(fs, 1);
50
50
  let typescript = require("typescript");
51
51
  typescript = __toESM(typescript, 1);
52
52
  let module$1 = require("module");
53
+ let _tsrx_core = require("@tsrx/core");
53
54
  let node_module = require("node:module");
54
55
  let volar_service_css = require("volar-service-css");
55
56
 
@@ -19995,14 +19996,14 @@ var import_node = require_node();
19995
19996
  * @import {TextDocument} from 'vscode-languageserver-textdocument';
19996
19997
  * @import {TSRXVirtualCodeInstance} from '@tsrx/typescript-plugin/src/language.js';
19997
19998
  */
19998
- /** @import {TSRXCompileError} from '@tsrx/ripple'; */
19999
+ /** @import {CompileError} from '@tsrx/core/types'; */
19999
20000
  var import_language_server = require_language_server();
20000
- const { log: log$8 } = createLogging("[Ripple Compile Error Diagnostic Plugin]");
20001
+ const { log: log$9 } = createLogging("[Ripple Compile Error Diagnostic Plugin]");
20001
20002
  /**
20002
20003
  * @returns {LanguageServicePlugin}
20003
20004
  */
20004
20005
  function createCompileErrorDiagnosticPlugin() {
20005
- log$8("Creating Ripple diagnostic plugin...");
20006
+ log$9("Creating Ripple diagnostic plugin...");
20006
20007
  return {
20007
20008
  name: "ripple-diagnostics",
20008
20009
  capabilities: { diagnosticProvider: {
@@ -20011,7 +20012,7 @@ function createCompileErrorDiagnosticPlugin() {
20011
20012
  } },
20012
20013
  create(context) {
20013
20014
  return { provideDiagnostics(document, _token) {
20014
- log$8("Providing Ripple diagnostics for:", document.uri);
20015
+ log$9("Providing Ripple diagnostics for:", document.uri);
20015
20016
  /** @type {Diagnostic[]} */
20016
20017
  const diagnostics = [];
20017
20018
  const { virtualCode, sourceMap } = getVirtualCode(document, context);
@@ -20021,14 +20022,14 @@ function createCompileErrorDiagnosticPlugin() {
20021
20022
  const diagnostic = parseCompilationErrorWithDocument(error, virtualCode, sourceMap, document);
20022
20023
  diagnostics.push(diagnostic);
20023
20024
  }
20024
- log$8("Generated", diagnostics.length, "diagnostics");
20025
+ log$9("Generated", diagnostics.length, "diagnostics");
20025
20026
  return diagnostics;
20026
20027
  } };
20027
20028
  }
20028
20029
  };
20029
20030
  }
20030
20031
  /**
20031
- * @param {TSRXCompileError} error
20032
+ * @param {CompileError} error
20032
20033
  * @param {TSRXVirtualCodeInstance} virtualCode
20033
20034
  * @param {Mapper | undefined} sourceMap
20034
20035
  * @param {TextDocument} document
@@ -20084,7 +20085,7 @@ function parseCompilationErrorWithDocument(error, virtualCode, sourceMap, docume
20084
20085
  };
20085
20086
  }
20086
20087
  /**
20087
- * @param {TSRXCompileError} error
20088
+ * @param {CompileError} error
20088
20089
  * @param {TextDocument} document
20089
20090
  * @returns {Range}
20090
20091
  */
@@ -20096,7 +20097,7 @@ function get_error_range_from_source(error, document) {
20096
20097
  };
20097
20098
  }
20098
20099
  /**
20099
- * @param {TSRXCompileError} error
20100
+ * @param {CompileError} error
20100
20101
  * @param {number} [start_offset]
20101
20102
  * @returns {number}
20102
20103
  */
@@ -20105,7 +20106,7 @@ function get_end_offset_from_error(error, start_offset) {
20105
20106
  return error.end ? error.end : error.raisedAt && (error.raisedAt ?? 0) > start_offset ? error.raisedAt : start_offset + 1;
20106
20107
  }
20107
20108
  /**
20108
- * @param {TSRXCompileError} error
20109
+ * @param {CompileError} error
20109
20110
  * @returns {number}
20110
20111
  */
20111
20112
  function get_start_offset_from_error(error) {
@@ -20115,9 +20116,9 @@ function get_start_offset_from_error(error) {
20115
20116
  //#endregion
20116
20117
  //#region ../typescript-plugin/src/language.js
20117
20118
  init_main();
20118
- /** @import { CodeMapping } from '@tsrx/ripple' */
20119
- /** @import {TSRXCompileError, VolarMappingsResult} from '@tsrx/ripple' */
20120
- /** @typedef {{ code?: string, errors?: TSRXCompileError[] }} TSRXCompileResult */
20119
+ /** @import * as AST from 'estree'; */
20120
+ /** @import {CompileError, VolarMappingsResult, CodeMapping} from '@tsrx/core/types' */
20121
+ /** @typedef {{ code?: string, errors?: CompileError[] }} TSRXCompileResult */
20121
20122
  /** @typedef {{ compile?: (source: string, filename: string, options?: { loose?: boolean }) => TSRXCompileResult, compile_to_volar_mappings(source: string, filename: string, options?: { loose?: boolean }): VolarMappingsResult }} TSRXCompilerModule */
20122
20123
  /** @typedef {Map<string, CodeMapping>} CachedMappings */
20123
20124
  /** @typedef {import('typescript').CompilerOptions} CompilerOptions */
@@ -20130,7 +20131,7 @@ init_main();
20130
20131
  var import_language_core = require_language_core();
20131
20132
  const require$2 = (0, module$1.createRequire)(require("url").pathToFileURL(__filename).href);
20132
20133
  const root_dirname = path.default.dirname((0, url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
20133
- const { log: log$7, logWarning, logError: logError$3 } = createLogging("[Ripple Language]");
20134
+ const { log: log$8, logWarning, logError: logError$4 } = createLogging("[Ripple Language]");
20134
20135
  /** @type {Set<string>} */
20135
20136
  const loggedCompilationFailures = /* @__PURE__ */ new Set();
20136
20137
  const RIPPLE_EXTENSIONS = [".tsrx"];
@@ -20204,12 +20205,12 @@ function is_ripple_file(file_name) {
20204
20205
  * @returns {RippleLanguagePlugin}
20205
20206
  */
20206
20207
  function getRippleLanguagePlugin() {
20207
- log$7("Creating Ripple language plugin...");
20208
+ log$8("Creating Ripple language plugin...");
20208
20209
  return {
20209
20210
  getLanguageId(fileNameOrUri) {
20210
20211
  const file_name = typeof fileNameOrUri === "string" ? fileNameOrUri : fileNameOrUri.fsPath.replace(/\\/g, "/");
20211
20212
  if (is_ripple_file(file_name)) {
20212
- log$7("Identified Ripple file:", file_name);
20213
+ log$8("Identified Ripple file:", file_name);
20213
20214
  return "ripple";
20214
20215
  }
20215
20216
  },
@@ -20218,21 +20219,21 @@ function getRippleLanguagePlugin() {
20218
20219
  const file_name = normalizeFileNameOrUri(fileNameOrUri);
20219
20220
  const ripple = get_tsrx_compiler(file_name);
20220
20221
  if (!ripple) {
20221
- logError$3(`Ripple compiler not found for file: ${file_name}`);
20222
+ logError$4(`Ripple compiler not found for file: ${file_name}`);
20222
20223
  return;
20223
20224
  }
20224
- log$7("Creating virtual code for:", file_name);
20225
+ log$8("Creating virtual code for:", file_name);
20225
20226
  try {
20226
20227
  return new TSRXVirtualCode(file_name, snapshot, ripple);
20227
20228
  } catch (err) {
20228
- logError$3("Failed to create virtual code for:", file_name, ":", err);
20229
+ logError$4("Failed to create virtual code for:", file_name, ":", err);
20229
20230
  throw err;
20230
20231
  }
20231
20232
  }
20232
20233
  },
20233
20234
  updateVirtualCode(fileNameOrUri, virtualCode, snapshot) {
20234
20235
  if (virtualCode instanceof TSRXVirtualCode) {
20235
- log$7("Updating existing virtual code for:", virtualCode.fileName);
20236
+ log$8("Updating existing virtual code for:", virtualCode.fileName);
20236
20237
  virtualCode.update(snapshot);
20237
20238
  return virtualCode;
20238
20239
  }
@@ -20274,9 +20275,9 @@ var TSRXVirtualCode = class {
20274
20275
  embeddedCodes = [];
20275
20276
  /** @type {CodeMapping[]} */
20276
20277
  mappings = [];
20277
- /** @type {TSRXCompileError[]} */
20278
+ /** @type {CompileError[]} */
20278
20279
  fatalErrors = [];
20279
- /** @type {TSRXCompileError[]} */
20280
+ /** @type {CompileError[]} */
20280
20281
  usageErrors = [];
20281
20282
  /** @type {IScriptSnapshot} */
20282
20283
  snapshot;
@@ -20284,6 +20285,10 @@ var TSRXVirtualCode = class {
20284
20285
  sourceSnapshot;
20285
20286
  /** @type {string} */
20286
20287
  originalCode = "";
20288
+ /** @type {AST.Program | null} */
20289
+ sourceAst = null;
20290
+ /** @type {boolean} */
20291
+ isDotCompletionMode = false;
20287
20292
  /** @type {unknown[]} */
20288
20293
  diagnostics = [];
20289
20294
  /** @type {CachedMappings | null} */
@@ -20296,14 +20301,14 @@ var TSRXVirtualCode = class {
20296
20301
  * @param {TSRXCompilerModule} tsrx
20297
20302
  */
20298
20303
  constructor(file_name, snapshot, tsrx) {
20299
- log$7("Initializing TSRXVirtualCode for:", file_name);
20304
+ log$8("Initializing TSRXVirtualCode for:", file_name);
20300
20305
  this.fileName = file_name;
20301
20306
  this.tsrx = tsrx;
20302
20307
  this.snapshot = snapshot;
20303
20308
  this.sourceSnapshot = snapshot;
20304
20309
  this.originalCode = snapshot.getText(0, snapshot.getLength());
20305
20310
  if (!tsrx || typeof tsrx.compile_to_volar_mappings !== "function") {
20306
- logError$3("Invalid ripple compiler - missing compile_to_volar_mappings method");
20311
+ logError$4("Invalid ripple compiler - missing compile_to_volar_mappings method");
20307
20312
  throw new Error("Invalid ripple compiler");
20308
20313
  }
20309
20314
  this.update(snapshot);
@@ -20313,7 +20318,7 @@ var TSRXVirtualCode = class {
20313
20318
  * @returns {void}
20314
20319
  */
20315
20320
  update(snapshot) {
20316
- log$7("Updating virtual code for:", this.fileName);
20321
+ log$8("Updating virtual code for:", this.fileName);
20317
20322
  const newCode = snapshot.getText(0, snapshot.getLength());
20318
20323
  const changeRange = snapshot.getChangeRange(this.sourceSnapshot);
20319
20324
  this.sourceSnapshot = snapshot;
@@ -20321,50 +20326,53 @@ var TSRXVirtualCode = class {
20321
20326
  this.#mappingSourceToGen = null;
20322
20327
  this.fatalErrors = [];
20323
20328
  this.usageErrors = [];
20329
+ this.sourceAst = null;
20330
+ this.isDotCompletionMode = false;
20324
20331
  /** @type {VolarMappingsResult | undefined} */
20325
20332
  let transpiled;
20326
20333
  let isDotTyped = false;
20327
20334
  let dotPosition = -1;
20328
- log$7("changeRange:", JSON.stringify(changeRange));
20335
+ log$8("changeRange:", JSON.stringify(changeRange));
20329
20336
  if (changeRange) {
20330
20337
  const changeStart = changeRange.span.start;
20331
20338
  const changeEnd = changeStart + changeRange.span.length;
20332
20339
  const newEnd = changeStart + changeRange.newLength;
20333
20340
  const oldText = this.originalCode.substring(changeStart, changeEnd);
20334
20341
  const newText = newCode.substring(changeStart, newEnd);
20335
- log$7("Change details:");
20336
- log$7(" Position:", changeStart, "-", changeEnd, "(length:", changeRange.span.length, ")");
20337
- log$7(" Old text:", JSON.stringify(oldText));
20338
- log$7(" New text:", JSON.stringify(newText), "(length:", changeRange.newLength, ")");
20342
+ log$8("Change details:");
20343
+ log$8(" Position:", changeStart, "-", changeEnd, "(length:", changeRange.span.length, ")");
20344
+ log$8(" Old text:", JSON.stringify(oldText));
20345
+ log$8(" New text:", JSON.stringify(newText), "(length:", changeRange.newLength, ")");
20339
20346
  if (newText.endsWith(".")) {
20340
20347
  const charBeforeDot = newEnd > 1 ? newCode[newEnd - 2] : "";
20341
- log$7(" Char before dot:", JSON.stringify(charBeforeDot));
20348
+ log$8(" Char before dot:", JSON.stringify(charBeforeDot));
20342
20349
  if (/[$#_\u200C\u200D\p{ID_Continue}\)\]\}]/u.test(charBeforeDot)) {
20343
20350
  isDotTyped = true;
20344
20351
  dotPosition = newEnd - 1;
20345
- log$7("ChangeRange detected dot typed at position", dotPosition);
20352
+ log$8("ChangeRange detected dot typed at position", dotPosition);
20346
20353
  }
20347
20354
  }
20348
20355
  }
20349
20356
  try {
20350
20357
  if (isDotTyped && dotPosition >= 0) {
20358
+ this.isDotCompletionMode = true;
20351
20359
  const codeWithoutDot = newCode.substring(0, dotPosition) + newCode.substring(dotPosition + 1);
20352
- log$7("Compiling without typed dot at position", dotPosition);
20360
+ log$8("Compiling without typed dot at position", dotPosition);
20353
20361
  transpiled = this.tsrx.compile_to_volar_mappings(codeWithoutDot, this.fileName, { loose: true });
20354
- log$7("Compilation without dot successful");
20362
+ log$8("Compilation without dot successful");
20355
20363
  if (transpiled && transpiled.code && transpiled.mappings.length > 0) {
20356
20364
  const insertedDotPosition = restore_typed_dot_in_transpiled_code(transpiled, dotPosition);
20357
20365
  if (insertedDotPosition === null) logWarning("Failed to restore typed dot into transpiled output");
20358
- else log$7("Inserted typed dot at generated position", insertedDotPosition);
20366
+ else log$8("Inserted typed dot at generated position", insertedDotPosition);
20359
20367
  }
20360
20368
  } else {
20361
- log$7("Compiling Ripple code...");
20369
+ log$8("Compiling Ripple code...");
20362
20370
  transpiled = this.tsrx.compile_to_volar_mappings(newCode, this.fileName, { loose: true });
20363
- log$7("Compilation successful, generated code length:", transpiled?.code?.length || 0);
20371
+ log$8("Compilation successful, generated code length:", transpiled?.code?.length || 0);
20364
20372
  }
20365
20373
  } catch (e) {
20366
20374
  const error = e;
20367
- logError$3("Ripple compilation failed for", this.fileName, ":", error);
20375
+ logError$4("Ripple compilation failed for", this.fileName, ":", error);
20368
20376
  if (process.env.TSRX_TSC === "true") logTSRXErrors(this.fileName, [error]);
20369
20377
  error.type = "fatal";
20370
20378
  this.fatalErrors.push(error);
@@ -20374,13 +20382,14 @@ var TSRXVirtualCode = class {
20374
20382
  this.generatedCode = transpiled.code;
20375
20383
  this.mappings = transpiled.mappings ?? [];
20376
20384
  this.usageErrors = transpiled.errors;
20385
+ this.sourceAst = transpiled.sourceAst;
20377
20386
  if (process.env.TSRX_TSC === "true" && transpiled.errors.length > 0) logTSRXErrors(this.fileName, transpiled.errors);
20378
20387
  const cssMappings = transpiled.cssMappings;
20379
20388
  if (cssMappings.length > 0) {
20380
- log$7("Creating", cssMappings.length, "CSS embedded codes");
20389
+ log$8("Creating", cssMappings.length, "CSS embedded codes");
20381
20390
  this.embeddedCodes = cssMappings.map((mapping, index) => {
20382
20391
  const cssContent = mapping.data?.customData?.content;
20383
- log$7(`CSS region ${index}: \
20392
+ log$8(`CSS region ${index}: \
20384
20393
  offset ${mapping.sourceOffsets[0]}-${mapping.sourceOffsets[0] + mapping.lengths[0]}, \
20385
20394
  length ${mapping.lengths[0]}`);
20386
20395
  return {
@@ -20397,17 +20406,17 @@ var TSRXVirtualCode = class {
20397
20406
  });
20398
20407
  } else this.embeddedCodes = [];
20399
20408
  if (DEBUG) {
20400
- log$7("CSS embedded codes:", (this.embeddedCodes || []).length);
20401
- log$7("Using transpiled code, mapping count:", this.mappings.length);
20402
- log$7("Original code length:", newCode.length);
20403
- log$7("Generated code length:", this.generatedCode.length);
20404
- log$7("Last 100 chars of original:", JSON.stringify(newCode.slice(-100)));
20405
- log$7("Last 200 chars of generated:", JSON.stringify(this.generatedCode.slice(-200)));
20406
- log$7("Last few mappings:");
20409
+ log$8("CSS embedded codes:", (this.embeddedCodes || []).length);
20410
+ log$8("Using transpiled code, mapping count:", this.mappings.length);
20411
+ log$8("Original code length:", newCode.length);
20412
+ log$8("Generated code length:", this.generatedCode.length);
20413
+ log$8("Last 100 chars of original:", JSON.stringify(newCode.slice(-100)));
20414
+ log$8("Last 200 chars of generated:", JSON.stringify(this.generatedCode.slice(-200)));
20415
+ log$8("Last few mappings:");
20407
20416
  const startIdx = Math.max(0, this.mappings.length - 5);
20408
20417
  for (let i = startIdx; i < this.mappings.length; i++) {
20409
20418
  const m = this.mappings[i];
20410
- log$7(` Mapping ${i}: source[${m.sourceOffsets[0]}:${m.sourceOffsets[0] + m.lengths[0]}] -> gen[${m.generatedOffsets[0]}:${m.generatedOffsets[0] + m.lengths[0]}], len=${m.lengths[0]}, completion=${m.data?.completion}`);
20419
+ log$8(` Mapping ${i}: source[${m.sourceOffsets[0]}:${m.sourceOffsets[0] + m.lengths[0]}] -> gen[${m.generatedOffsets[0]}:${m.generatedOffsets[0] + m.lengths[0]}], len=${m.lengths[0]}, completion=${m.data?.completion}`);
20411
20420
  }
20412
20421
  }
20413
20422
  this.snapshot = {
@@ -20416,7 +20425,7 @@ var TSRXVirtualCode = class {
20416
20425
  getChangeRange: () => void 0
20417
20426
  };
20418
20427
  } else {
20419
- log$7("Compilation failed, only display where the compilation error occurred.");
20428
+ log$8("Compilation failed, only display where the compilation error occurred.");
20420
20429
  this.originalCode = newCode;
20421
20430
  this.generatedCode = newCode;
20422
20431
  this.mappings = [{
@@ -20510,7 +20519,7 @@ function extractCssFromSource(code) {
20510
20519
  const cssContent = match[1];
20511
20520
  const cssStart = match.index + (fullMatch.indexOf(">") + 1);
20512
20521
  const cssLength = cssContent.length;
20513
- log$7(`Extracted CSS region ${index}: offset ${cssStart}, length ${cssLength}`);
20522
+ log$8(`Extracted CSS region ${index}: offset ${cssStart}, length ${cssLength}`);
20514
20523
  /** @type {CodeMapping} */
20515
20524
  const mapping = {
20516
20525
  sourceOffsets: [cssStart],
@@ -20543,7 +20552,7 @@ function extractCssFromSource(code) {
20543
20552
  });
20544
20553
  index++;
20545
20554
  }
20546
- if (embeddedCodes.length > 0) log$7(`Extracted ${embeddedCodes.length} CSS embedded codes from style tags`);
20555
+ if (embeddedCodes.length > 0) log$8(`Extracted ${embeddedCodes.length} CSS embedded codes from style tags`);
20547
20556
  return embeddedCodes;
20548
20557
  }
20549
20558
  /**
@@ -20724,7 +20733,7 @@ function find_workspace_compiler_entry_for_file(normalized_file_name, exists_syn
20724
20733
  if (available_candidates.length > 0) {
20725
20734
  const package_manifest = get_nearest_package_manifest(dir, exists_sync);
20726
20735
  found_path = available_candidates.find(([compiler_name, , package_hints]) => package_manifest_matches_compiler(package_manifest, compiler_name, package_hints))?.[1] ?? available_candidates[0][1];
20727
- log$7("Found tsrx compiler at:", found_path, "for extension:", ext);
20736
+ log$8("Found tsrx compiler at:", found_path, "for extension:", ext);
20728
20737
  }
20729
20738
  compiler_path_map.set(cache_key, found_path);
20730
20739
  }
@@ -20777,7 +20786,7 @@ function getCachedTypeDefinitionFile(typesFilePath) {
20777
20786
  logWarning(`Types file does not exist at path: ${typesFilePath}`);
20778
20787
  return;
20779
20788
  }
20780
- log$7(`Found ripple types at: ${typesFilePath}`);
20789
+ log$8(`Found ripple types at: ${typesFilePath}`);
20781
20790
  const fileContent = fs.default.readFileSync(typesFilePath, "utf8");
20782
20791
  if (!fileContent) {
20783
20792
  logWarning(`Failed to read content of types file at: ${typesFilePath}`);
@@ -20813,8 +20822,8 @@ function get_compiler_dir_for_file(normalized_file_name) {
20813
20822
  //#endregion
20814
20823
  //#region src/definitionPlugin.js
20815
20824
  /** @import { LanguageServicePlugin, LocationLink } from '@volar/language-server'; */
20816
- /** @import { DefinitionLocation } from '@tsrx/ripple'; */
20817
- const { log: log$6 } = createLogging("[Ripple Definition Plugin]");
20825
+ /** @import { DefinitionLocation } from '@tsrx/core/types'; */
20826
+ const { log: log$7 } = createLogging("[Ripple Definition Plugin]");
20818
20827
  /** @type {string | undefined} */
20819
20828
  let ripple_dir;
20820
20829
  /**
@@ -20835,21 +20844,21 @@ function createDefinitionPlugin() {
20835
20844
  }
20836
20845
  const { virtualCode, sourceUri } = getVirtualCode(document, context);
20837
20846
  if (virtualCode.languageId !== "ripple") {
20838
- log$6(`Skipping definitions processing in the '${virtualCode.languageId}' context`);
20847
+ log$7(`Skipping definitions processing in the '${virtualCode.languageId}' context`);
20839
20848
  return tsDefinitions;
20840
20849
  }
20841
20850
  const offset = document.offsetAt(position);
20842
20851
  const { word, start, end } = getWordFromPosition(document.getText(), offset);
20843
20852
  const customMapping = virtualCode.findMappingByGeneratedRange(start, end);
20844
- log$6(`Cursor position in generated code for word '${word}':`, position);
20845
- log$6(`Cursor offset in generated code for word '${word}':`, offset);
20853
+ log$7(`Cursor position in generated code for word '${word}':`, position);
20854
+ log$7(`Cursor offset in generated code for word '${word}':`, offset);
20846
20855
  if (customMapping?.data.customData.definition !== false && customMapping?.data.customData.definition?.typeReplace) {
20847
20856
  const { name: typeName, path: typePath } = customMapping.data.customData.definition.typeReplace;
20848
- log$6(`Found replace definition for ${typeName}`);
20857
+ log$7(`Found replace definition for ${typeName}`);
20849
20858
  const filePath = sourceUri.fsPath || sourceUri.path;
20850
20859
  ripple_dir = ripple_dir ?? get_compiler_dir_for_file(normalizeFileNameOrUri(filePath));
20851
20860
  if (!ripple_dir) {
20852
- log$6(`Could not determine Ripple source directory for file: ${filePath}`);
20861
+ log$7(`Could not determine Ripple source directory for file: ${filePath}`);
20853
20862
  return;
20854
20863
  }
20855
20864
  const typesFilePath = path.default.join(ripple_dir, ...typePath.split("/"));
@@ -20897,7 +20906,7 @@ function createDefinitionPlugin() {
20897
20906
  end: originEnd
20898
20907
  }
20899
20908
  };
20900
- log$6(`Created definition link to ${typesFilePath}:${line}:${character}`);
20909
+ log$7(`Created definition link to ${typesFilePath}:${line}:${character}`);
20901
20910
  return [locationLink];
20902
20911
  }
20903
20912
  }
@@ -20908,16 +20917,16 @@ function createDefinitionPlugin() {
20908
20917
  const embedMapping = embeddedCode.mappings[0];
20909
20918
  const sourceStartOffset = embedMapping.sourceOffsets[0] + loc.start;
20910
20919
  const sourceEndOffset = embedMapping.sourceOffsets[0] + loc.end;
20911
- log$6("Source document offsets - start for matching css:", sourceStartOffset, "end:", sourceEndOffset);
20920
+ log$7("Source document offsets - start for matching css:", sourceStartOffset, "end:", sourceEndOffset);
20912
20921
  const sourceDocument = TextDocument.create(sourceUri.toString(), "ripple", 0, virtualCode.originalCode);
20913
20922
  const targetStart = sourceDocument.positionAt(sourceStartOffset);
20914
20923
  const targetEnd = sourceDocument.positionAt(sourceEndOffset);
20915
- log$6("Target positions in source - start:", targetStart, "end:", targetEnd);
20924
+ log$7("Target positions in source - start:", targetStart, "end:", targetEnd);
20916
20925
  const generatedStart = customMapping.generatedOffsets[0];
20917
20926
  const generatedEnd = generatedStart + customMapping.generatedLengths[0];
20918
20927
  const originStart = document.positionAt(generatedStart);
20919
20928
  const originEnd = document.positionAt(generatedEnd);
20920
- log$6("Origin positions - start:", originStart, "end:", originEnd);
20929
+ log$7("Origin positions - start:", originStart, "end:", originEnd);
20921
20930
  /** @type {LocationLink} */
20922
20931
  tsDefinitions.push({
20923
20932
  targetUri: sourceUri.toString(),
@@ -20951,7 +20960,7 @@ LanguageServicePlugin,
20951
20960
  LanguageServicePluginInstance,
20952
20961
  MarkupContent,
20953
20962
  } from '@volar/language-server'; */
20954
- const { log: log$5, logError: logError$2 } = createLogging("[Ripple Hover Plugin]");
20963
+ const { log: log$6, logError: logError$3 } = createLogging("[Ripple Hover Plugin]");
20955
20964
  /**
20956
20965
  * @returns {LanguageServicePlugin}
20957
20966
  */
@@ -20970,7 +20979,7 @@ function createHoverPlugin() {
20970
20979
  instance.provideHover = void 0;
20971
20980
  break;
20972
20981
  }
20973
- if (!originalProvideHover) logError$2("'typescript-semantic plugin' was not found or has no 'provideHover'. This plugin must be loaded after Volar's typescript-semantic plugin.");
20982
+ if (!originalProvideHover) logError$3("'typescript-semantic plugin' was not found or has no 'provideHover'. This plugin must be loaded after Volar's typescript-semantic plugin.");
20974
20983
  return { async provideHover(document, position, token) {
20975
20984
  let tsHover = null;
20976
20985
  if (originalProvideHover) tsHover = await originalProvideHover.call(originalInstance, document, position, token);
@@ -20993,11 +21002,11 @@ function createHoverPlugin() {
20993
21002
  const { word, start, end } = getWordFromPosition(document.getText(), offset);
20994
21003
  starOffset = start;
20995
21004
  endOffset = end;
20996
- log$5(`Cursor position in generated code for word '${word}':`, position);
20997
- log$5(`Cursor offset in generated code for word '${word}':`, offset);
21005
+ log$6(`Cursor position in generated code for word '${word}':`, position);
21006
+ log$6(`Cursor offset in generated code for word '${word}':`, offset);
20998
21007
  }
20999
21008
  if (virtualCode.languageId !== "ripple") {
21000
- log$5(`Skipping hover processing in the '${virtualCode.languageId}' context`);
21009
+ log$6(`Skipping hover processing in the '${virtualCode.languageId}' context`);
21001
21010
  return tsHover;
21002
21011
  }
21003
21012
  const mapping = virtualCode.findMappingByGeneratedRange(starOffset, endOffset);
@@ -21010,7 +21019,7 @@ function createHoverPlugin() {
21010
21019
  /** @type {MarkupContent} **/
21011
21020
  tsHover.contents.value
21012
21021
  );
21013
- log$5("Modified hover contents using custom hover function");
21022
+ log$6("Modified hover contents using custom hover function");
21014
21023
  }
21015
21024
  return tsHover;
21016
21025
  } else if (typeof customHover === "string") {
@@ -21019,7 +21028,7 @@ function createHoverPlugin() {
21019
21028
  tsHover.contents.value,
21020
21029
  customHover
21021
21030
  ) : customHover;
21022
- log$5("Found custom hover data in mapping");
21031
+ log$6("Found custom hover data in mapping");
21023
21032
  return {
21024
21033
  contents: {
21025
21034
  kind: "markdown",
@@ -21031,10 +21040,10 @@ function createHoverPlugin() {
21031
21040
  }
21032
21041
  };
21033
21042
  } else if (customHover === false) {
21034
- log$5(`Hover explicitly suppressed in mapping at range start: ${starOffset}, end: ${endOffset}`);
21043
+ log$6(`Hover explicitly suppressed in mapping at range start: ${starOffset}, end: ${endOffset}`);
21035
21044
  return null;
21036
21045
  }
21037
- log$5("Found mapping for hover at range", "start: ", starOffset, "end: ", endOffset);
21046
+ log$6("Found mapping for hover at range", "start: ", starOffset, "end: ", endOffset);
21038
21047
  return tsHover;
21039
21048
  } };
21040
21049
  }
@@ -21044,7 +21053,7 @@ function createHoverPlugin() {
21044
21053
  //#endregion
21045
21054
  //#region src/completionPlugin.js
21046
21055
  /** @import { LanguageServicePlugin, TextEdit, CompletionItem } from '@volar/language-server'; */
21047
- const { log: log$4 } = createLogging("[Ripple Completion Plugin]");
21056
+ const { log: log$5 } = createLogging("[Ripple Completion Plugin]");
21048
21057
  /**
21049
21058
  * Snippets that require auto-import from 'ripple'
21050
21059
  * @type {Array<{label: string, filterText: string, detail: string, documentation: string, insertText: string, importName: string | null}>}
@@ -21380,7 +21389,7 @@ function createCompletionPlugin() {
21380
21389
  };
21381
21390
  const { virtualCode } = getVirtualCode(document, context);
21382
21391
  if (virtualCode && virtualCode.languageId !== "ripple") {
21383
- log$4(`Skipping Ripple completions in the '${virtualCode.languageId}' context`);
21392
+ log$5(`Skipping Ripple completions in the '${virtualCode.languageId}' context`);
21384
21393
  return {
21385
21394
  items: [],
21386
21395
  isIncomplete: false
@@ -21395,7 +21404,7 @@ function createCompletionPlugin() {
21395
21404
  });
21396
21405
  /** @type {CompletionItem[]} */
21397
21406
  const items = [];
21398
- log$4("🔔 Completion triggered:", {
21407
+ log$5("🔔 Completion triggered:", {
21399
21408
  triggerKind: completionContext.triggerKind,
21400
21409
  triggerKindName: completionContext.triggerKind === 1 ? "Invoked" : completionContext.triggerKind === 2 ? "TriggerCharacter" : completionContext.triggerKind === 3 ? "Incomplete" : "Unknown",
21401
21410
  triggerCharacter: completionContext.triggerCharacter || "(none)",
@@ -21454,7 +21463,7 @@ function createCompletionPlugin() {
21454
21463
  }
21455
21464
  const wordMatch = line.match(/(\w+)$/);
21456
21465
  const currentWord = wordMatch ? wordMatch[1] : "";
21457
- log$4("Current word:", currentWord, "length:", currentWord.length);
21466
+ log$5("Current word:", currentWord, "length:", currentWord.length);
21458
21467
  items.push(...RIPPLE_SNIPPETS);
21459
21468
  return {
21460
21469
  items,
@@ -21469,7 +21478,7 @@ function createCompletionPlugin() {
21469
21478
  //#endregion
21470
21479
  //#region src/autoInsertPlugin.js
21471
21480
  /** @import { LanguageServicePlugin } from '@volar/language-server' */
21472
- const { log: log$3 } = createLogging("[Ripple Auto-Insert Plugin]");
21481
+ const { log: log$4 } = createLogging("[Ripple Auto-Insert Plugin]");
21473
21482
  /**
21474
21483
  * List of HTML void/self-closing elements that don't need closing tags
21475
21484
  * https://developer.mozilla.org/en-US/docs/Glossary/Void_element
@@ -21521,7 +21530,7 @@ async provideAutoInsertSnippet(document, position, lastChange, _token) {
21521
21530
  if (!lastChange.text.endsWith(">")) return null;
21522
21531
  const { virtualCode } = getVirtualCode(document, context);
21523
21532
  if (virtualCode.languageId !== "ripple") {
21524
- log$3(`Skipping auto-insert processing in the '${virtualCode.languageId}' context`);
21533
+ log$4(`Skipping auto-insert processing in the '${virtualCode.languageId}' context`);
21525
21534
  return null;
21526
21535
  }
21527
21536
  const offset = document.offsetAt(position);
@@ -21544,11 +21553,11 @@ async provideAutoInsertSnippet(document, position, lastChange, _token) {
21544
21553
  if (attempts === 3) break;
21545
21554
  }
21546
21555
  if (!found) {
21547
- log$3(`No opening tag position found from source position ${sourceOffset}`);
21556
+ log$4(`No opening tag position found from source position ${sourceOffset}`);
21548
21557
  return null;
21549
21558
  }
21550
21559
  const line = sourceCode.slice(i, sourceOffset + 1);
21551
- log$3("Auto-insert triggered at:", {
21560
+ log$4("Auto-insert triggered at:", {
21552
21561
  selection: `${position.line}:${position.character}`,
21553
21562
  line,
21554
21563
  change: lastChange,
@@ -21556,13 +21565,13 @@ async provideAutoInsertSnippet(document, position, lastChange, _token) {
21556
21565
  });
21557
21566
  const tagMatch = line.match(/<([@$\w][\w.-]*)[^>]*?(?<!\/)>$/);
21558
21567
  if (!tagMatch) {
21559
- log$3("No tag match found");
21568
+ log$4("No tag match found");
21560
21569
  return null;
21561
21570
  }
21562
21571
  const tagName = tagMatch[1];
21563
- log$3("Tag matched:", tagName);
21572
+ log$4("Tag matched:", tagName);
21564
21573
  if (VOID_ELEMENTS.has(tagName.toLowerCase())) {
21565
- log$3("Void element, skipping auto-close:", tagName);
21574
+ log$4("Void element, skipping auto-close:", tagName);
21566
21575
  return null;
21567
21576
  }
21568
21577
  if (document.getText({
@@ -21572,11 +21581,11 @@ async provideAutoInsertSnippet(document, position, lastChange, _token) {
21572
21581
  character: position.character + 100
21573
21582
  }
21574
21583
  }).startsWith(`</${tagName}>`)) {
21575
- log$3("Closing tag already exists, skipping");
21584
+ log$4("Closing tag already exists, skipping");
21576
21585
  return null;
21577
21586
  }
21578
21587
  const closingTag = `</${tagName}>`;
21579
- log$3("Inserting closing tag:", closingTag);
21588
+ log$4("Inserting closing tag:", closingTag);
21580
21589
  return `$0${closingTag}`;
21581
21590
  } };
21582
21591
  }
@@ -21594,7 +21603,7 @@ Diagnostic,
21594
21603
  } from '@volar/language-server';
21595
21604
  @import {TextDocument} from 'vscode-languageserver-textdocument';
21596
21605
  */
21597
- const { log: log$2, logError: logError$1 } = createLogging("[Ripple TypeScript Diagnostic Plugin]");
21606
+ const { log: log$3, logError: logError$2 } = createLogging("[Ripple TypeScript Diagnostic Plugin]");
21598
21607
  /**
21599
21608
  * @param {Diagnostic} diagnostic
21600
21609
  * @param {Diagnostic[]} items
@@ -21612,7 +21621,7 @@ function process$1(diagnostic, items) {
21612
21621
  */
21613
21622
  function processDiagnostics(document, context, diagnostics) {
21614
21623
  if (!diagnostics || diagnostics.length === 0) return diagnostics;
21615
- log$2(`Filtering ${diagnostics.length} TypeScript diagnostics for ${document.uri}`);
21624
+ log$3(`Filtering ${diagnostics.length} TypeScript diagnostics for ${document.uri}`);
21616
21625
  const { virtualCode } = getVirtualCode(document, context);
21617
21626
  if (!virtualCode || virtualCode.languageId !== "ripple") return diagnostics;
21618
21627
  /** @type {Diagnostic[]} */
@@ -21634,12 +21643,12 @@ function processDiagnostics(document, context, diagnostics) {
21634
21643
  }
21635
21644
  const diagnosticCode = typeof diagnostic.code === "number" ? diagnostic.code : typeof diagnostic.code === "string" ? parseInt(diagnostic.code) : null;
21636
21645
  if (diagnosticCode && suppressedCodes.includes(diagnosticCode)) {
21637
- log$2(`Suppressing diagnostic ${diagnosticCode}: ${diagnostic.message}`);
21646
+ log$3(`Suppressing diagnostic ${diagnosticCode}: ${diagnostic.message}`);
21638
21647
  continue;
21639
21648
  }
21640
21649
  process$1(diagnostic, result);
21641
21650
  }
21642
- log$2(`Filtered from ${diagnostics.length} to ${result.length} diagnostics`);
21651
+ log$3(`Filtered from ${diagnostics.length} to ${result.length} diagnostics`);
21643
21652
  return result;
21644
21653
  }
21645
21654
  /**
@@ -21650,7 +21659,7 @@ function processDiagnostics(document, context, diagnostics) {
21650
21659
  * @returns {LanguageServicePlugin}
21651
21660
  */
21652
21661
  function createTypeScriptDiagnosticFilterPlugin() {
21653
- log$2("Creating TypeScript diagnostic filter plugin...");
21662
+ log$3("Creating TypeScript diagnostic filter plugin...");
21654
21663
  return {
21655
21664
  name: "ripple-typescript-diagnostic-filter",
21656
21665
  capabilities: {},
@@ -21665,10 +21674,10 @@ function createTypeScriptDiagnosticFilterPlugin() {
21665
21674
  instance.provideDiagnostics = async function(document, token) {
21666
21675
  return processDiagnostics(document, context, await originalProvider?.call(originalInstance, document, token) ?? []);
21667
21676
  };
21668
- log$2("Successfully wrapped typescript-semantic provideDiagnostics");
21677
+ log$3("Successfully wrapped typescript-semantic provideDiagnostics");
21669
21678
  break;
21670
21679
  }
21671
- if (!originalProvider) logError$1("'typescript-semantic plugin' was not found or has no 'provideDiagnostics'. This plugin must be loaded after Volar's typescript-semantic plugin.");
21680
+ if (!originalProvider) logError$2("'typescript-semantic plugin' was not found or has no 'provideDiagnostics'. This plugin must be loaded after Volar's typescript-semantic plugin.");
21672
21681
  return {};
21673
21682
  }
21674
21683
  };
@@ -21678,7 +21687,7 @@ function createTypeScriptDiagnosticFilterPlugin() {
21678
21687
  //#region src/documentHighlightPlugin.js
21679
21688
  /** @import { LanguageServicePlugin } from '@volar/language-server' */
21680
21689
  /** @import { LanguageServicePluginInstance } from '@volar/language-server' */
21681
- const { log: log$1 } = createLogging("[Ripple Document Highlight Plugin]");
21690
+ const { log: log$2 } = createLogging("[Ripple Document Highlight Plugin]");
21682
21691
  /**
21683
21692
  * Document Highlight plugin for Ripple
21684
21693
  * Provides word highlighting (grey background) for custom Ripple keywords like 'pending'
@@ -21699,14 +21708,14 @@ function createDocumentHighlightPlugin() {
21699
21708
  instance.provideDocumentHighlights = void 0;
21700
21709
  break;
21701
21710
  }
21702
- if (!originalProvideDocumentHighlights) log$1("'typescript-semantic plugin' was not found or has no 'provideDocumentHighlights'. Document highlights will be limited to custom Ripple keywords only.");
21711
+ if (!originalProvideDocumentHighlights) log$2("'typescript-semantic plugin' was not found or has no 'provideDocumentHighlights'. Document highlights will be limited to custom Ripple keywords only.");
21703
21712
  return { async provideDocumentHighlights(document, position, token) {
21704
21713
  if (!originalProvideDocumentHighlights) return null;
21705
21714
  let tsHighlights = await originalProvideDocumentHighlights.call(originalInstance, document, position, token);
21706
21715
  if (!tsHighlights || tsHighlights.length > 0) return tsHighlights;
21707
21716
  const { virtualCode } = getVirtualCode(document, context);
21708
21717
  if (virtualCode.languageId !== "ripple") {
21709
- log$1(`Skipping highlight processing in the '${virtualCode.languageId}' context`);
21718
+ log$2(`Skipping highlight processing in the '${virtualCode.languageId}' context`);
21710
21719
  return tsHighlights;
21711
21720
  }
21712
21721
  const offset = document.offsetAt(position);
@@ -21729,13 +21738,409 @@ function createDocumentHighlightPlugin() {
21729
21738
  kind: mapping.data.customData.wordHighlight.kind
21730
21739
  });
21731
21740
  }
21732
- if (tsHighlights.length > 0) log$1(`Found ${tsHighlights.length} occurrences of '${word}'`);
21741
+ if (tsHighlights.length > 0) log$2(`Found ${tsHighlights.length} occurrences of '${word}'`);
21733
21742
  return [...tsHighlights];
21734
21743
  } };
21735
21744
  }
21736
21745
  };
21737
21746
  }
21738
21747
 
21748
+ //#endregion
21749
+ //#region src/documentSymbolPlugin.js
21750
+ /** @import * as AST from 'estree' */
21751
+ /** @import { LanguageServicePlugin } from '@volar/language-server' */
21752
+ /** @import { DocumentSymbol, Mapper, Range, SymbolKind as SymbolKindType } from '@volar/language-server' */
21753
+ /** @import { CodeInformation } from '@volar/language-core'; */
21754
+ /** @import { TSRXVirtualCodeInstance } from '@tsrx/typescript-plugin/src/language.js'; */
21755
+ /** @import { CodeMapping } from '@tsrx/core/types'; */
21756
+ init_main();
21757
+ /**
21758
+ * @typedef {AST.Node & {
21759
+ * body?: AST.Node[] | { body?: AST.Node[] };
21760
+ * }} NodeWithBody;
21761
+ */
21762
+ /**
21763
+ * @typedef {AST.Node & {
21764
+ * id?: AST.Identifier
21765
+ * }} NodeWithId;
21766
+ */
21767
+ /**
21768
+ * @typedef {[
21769
+ * Omit<DocumentSymbol, 'children'> & { children: SymbolInfo[] }, {
21770
+ * rangeNode: AST.Node;
21771
+ * selectionNode: AST.Node;
21772
+ * }]} SymbolInfo;
21773
+ */
21774
+ const { log: log$1, logError: logError$1 } = createLogging("[Ripple Document Symbol Plugin]");
21775
+ /** @type {Map<string, DocumentSymbol[]>} */
21776
+ const documentSymbolCache = /* @__PURE__ */ new Map();
21777
+ /**
21778
+ * @returns {LanguageServicePlugin}
21779
+ */
21780
+ function createDocumentSymbolPlugin() {
21781
+ return {
21782
+ name: "ripple-document-symbol",
21783
+ capabilities: { documentSymbolProvider: true },
21784
+ create(context) {
21785
+ return { async provideDocumentSymbols(document) {
21786
+ if (!is_ripple_document(document.uri)) return [];
21787
+ const { virtualCode, sourceMap, sourceUri } = getVirtualCode(document, context);
21788
+ const { sourceAst, languageId, originalCode } = virtualCode || {};
21789
+ if (languageId !== "ripple") {
21790
+ log$1(`Skipping symbols in the '${languageId}' context`);
21791
+ return [];
21792
+ }
21793
+ const cacheKey = sourceUri.toString();
21794
+ const cachedSymbols = documentSymbolCache.get(cacheKey) ?? [];
21795
+ if (virtualCode?.fatalErrors?.length || virtualCode?.isDotCompletionMode) return cachedSymbols;
21796
+ if (!sourceMap || !sourceAst) return [];
21797
+ const sourceDocument = TextDocument.create(sourceUri.toString(), "ripple", 0, originalCode);
21798
+ const symbols = mapDocumentSymbolsToGenerated(collectDocumentSymbols(sourceAst, sourceDocument), virtualCode, sourceDocument, document, sourceMap);
21799
+ documentSymbolCache.set(cacheKey, symbols);
21800
+ return symbols;
21801
+ } };
21802
+ }
21803
+ };
21804
+ }
21805
+ /**
21806
+ * @param {SymbolInfo[]} symbols
21807
+ * @param {TSRXVirtualCodeInstance} virtualCode
21808
+ * @param {TextDocument} sourceDocument
21809
+ * @param {TextDocument} generatedDocument
21810
+ * @param {Mapper} sourceMap
21811
+ * @returns {DocumentSymbol[]}
21812
+ */
21813
+ function mapDocumentSymbolsToGenerated(symbols, virtualCode, sourceDocument, generatedDocument, sourceMap) {
21814
+ /** @type {DocumentSymbol[]} */
21815
+ const mapped = [];
21816
+ /** @type {CodeMapping | null} */
21817
+ let mapping = null;
21818
+ for (const [symbol, { rangeNode, selectionNode }] of symbols) {
21819
+ /** @type {Range | null} */
21820
+ let generatedSelectionRange = null;
21821
+ mapping = virtualCode.findMappingBySourceRange(
21822
+ /** @type {AST.NodeWithLocation} */
21823
+ selectionNode.start,
21824
+ /** @type {AST.NodeWithLocation} */
21825
+ selectionNode.end
21826
+ );
21827
+ if (mapping && isSymbolMapping(mapping.data)) generatedSelectionRange = {
21828
+ start: generatedDocument.positionAt(mapping.generatedOffsets[0]),
21829
+ end: generatedDocument.positionAt(mapping.generatedOffsets[0] + mapping.generatedLengths[0])
21830
+ };
21831
+ if (!generatedSelectionRange) generatedSelectionRange = sourceRangeToGeneratedRange(symbol.selectionRange, sourceDocument, generatedDocument, sourceMap);
21832
+ if (!generatedSelectionRange) continue;
21833
+ const children = symbol.children ? mapDocumentSymbolsToGenerated(symbol.children, virtualCode, sourceDocument, generatedDocument, sourceMap) : void 0;
21834
+ /** @type {Range | null} */
21835
+ let generatedRange = null;
21836
+ mapping = virtualCode.findMappingBySourceRange(
21837
+ /** @type {AST.NodeWithLocation} */
21838
+ rangeNode.start,
21839
+ /** @type {AST.NodeWithLocation} */
21840
+ rangeNode.end
21841
+ );
21842
+ if (mapping && isSymbolMapping(mapping.data)) generatedRange = {
21843
+ start: generatedDocument.positionAt(mapping.generatedOffsets[0]),
21844
+ end: generatedDocument.positionAt(mapping.generatedOffsets[0] + mapping.generatedLengths[0])
21845
+ };
21846
+ if (!generatedRange) generatedRange = sourceRangeToGeneratedRange(symbol.range, sourceDocument, generatedDocument, sourceMap);
21847
+ if (!generatedRange) {
21848
+ generatedRange = generatedSelectionRange;
21849
+ if (children?.length) generatedRange = ensureRangeContainsChildren(generatedRange, children);
21850
+ }
21851
+ mapped.push({
21852
+ ...symbol,
21853
+ range: generatedRange,
21854
+ selectionRange: generatedSelectionRange,
21855
+ children
21856
+ });
21857
+ }
21858
+ return mapped;
21859
+ }
21860
+ /**
21861
+ * Breadcrumb providers expect parent symbol ranges to contain child symbol
21862
+ * ranges. Full component/function bodies may not have one continuous source
21863
+ * mapping after TSRX transforms, so widen the selection-range fallback around
21864
+ * any mapped child declarations.
21865
+ *
21866
+ * @param {Range} range
21867
+ * @param {DocumentSymbol[]} children
21868
+ * @returns {Range}
21869
+ */
21870
+ function ensureRangeContainsChildren(range, children) {
21871
+ let start = range.start;
21872
+ let end = range.end;
21873
+ for (const child of children) {
21874
+ if (comparePositions(child.range.start, start) < 0) start = child.range.start;
21875
+ if (comparePositions(child.range.end, end) > 0) end = child.range.end;
21876
+ }
21877
+ return {
21878
+ start,
21879
+ end
21880
+ };
21881
+ }
21882
+ /**
21883
+ * @param {Range['start']} a
21884
+ * @param {Range['start']} b
21885
+ * @returns {number}
21886
+ */
21887
+ function comparePositions(a, b) {
21888
+ return a.line === b.line ? a.character - b.character : a.line - b.line;
21889
+ }
21890
+ /**
21891
+ * @param {Range} range
21892
+ * @param {TextDocument} sourceDocument
21893
+ * @param {TextDocument} generatedDocument
21894
+ * @param {Mapper} sourceMap
21895
+ * @returns {Range | null}
21896
+ */
21897
+ function sourceRangeToGeneratedRange(range, sourceDocument, generatedDocument, sourceMap) {
21898
+ const start = sourceDocument.offsetAt(range.start);
21899
+ const end = sourceDocument.offsetAt(range.end);
21900
+ for (const [generatedStart, generatedEnd] of sourceMap.toGeneratedRange(start, end, true, isSymbolMapping)) return {
21901
+ start: generatedDocument.positionAt(generatedStart),
21902
+ end: generatedDocument.positionAt(generatedEnd)
21903
+ };
21904
+ return null;
21905
+ }
21906
+ /**
21907
+ * @param {CodeInformation} data
21908
+ * @returns {boolean}
21909
+ */
21910
+ function isSymbolMapping(data) {
21911
+ return !!data.structure;
21912
+ }
21913
+ /**
21914
+ * @param {AST.Program} ast
21915
+ * @param {TextDocument} document
21916
+ * @returns {SymbolInfo[]}
21917
+ */
21918
+ function collectDocumentSymbols(ast, document) {
21919
+ return collectSymbolsFromStatements(Array.isArray(ast.body) ? ast.body : [], document);
21920
+ }
21921
+ /**
21922
+ * @param {AST.Node[]} statements
21923
+ * @param {TextDocument} document
21924
+ * @returns {SymbolInfo[]}
21925
+ */
21926
+ function collectSymbolsFromStatements(statements, document) {
21927
+ /** @type {SymbolInfo[]} */
21928
+ const symbols = [];
21929
+ for (const statement of statements) {
21930
+ if (!statement) continue;
21931
+ if (statement.type === "ExportNamedDeclaration" || statement.type === "ExportDefaultDeclaration") {
21932
+ if (statement.declaration) symbols.push(...createSymbolForDeclaration(statement.declaration, document, statement.type === "ExportDefaultDeclaration" ? "default" : void 0));
21933
+ continue;
21934
+ }
21935
+ symbols.push(...createSymbolForDeclaration(statement, document));
21936
+ }
21937
+ return symbols;
21938
+ }
21939
+ /**
21940
+ * @param {AST.Node} node
21941
+ * @param {TextDocument} document
21942
+ * @param {string} [fallbackName]
21943
+ * @returns { SymbolInfo[]}
21944
+ */
21945
+ function createSymbolForDeclaration(node, document, fallbackName) {
21946
+ const type = node.type;
21947
+ let id = node.id ?? null;
21948
+ let name = id ? getIdentifierName(id) : null;
21949
+ switch (type) {
21950
+ case "Component":
21951
+ case "FunctionDeclaration": {
21952
+ const children = getChildSymbols(node, document);
21953
+ if (!id || !name) if (fallbackName) {
21954
+ name = fallbackName;
21955
+ id = createFallbackIdentifierNode(node, type === "Component" ? "component" : "function");
21956
+ } else return children;
21957
+ return [createNamedNodeSymbol(name, import_language_server.SymbolKind.Function, node, id, document, children)];
21958
+ }
21959
+ case "ClassDeclaration": {
21960
+ const children = getClassChildSymbols(node, document);
21961
+ if (!id || !name) if (fallbackName) {
21962
+ name = fallbackName;
21963
+ id = createFallbackIdentifierNode(node, "class");
21964
+ } else return children;
21965
+ return [createNamedNodeSymbol(name, import_language_server.SymbolKind.Class, node, id, document, children)];
21966
+ }
21967
+ case "VariableDeclaration": return createVariableDeclarationSymbols(node, document);
21968
+ case "TSInterfaceDeclaration":
21969
+ if (!id || !name) return [];
21970
+ return [createNamedNodeSymbol(name, import_language_server.SymbolKind.Interface, node, id, document)];
21971
+ case "TSTypeAliasDeclaration":
21972
+ if (!id || !name) return [];
21973
+ return [createNamedNodeSymbol(name, import_language_server.SymbolKind.TypeParameter, node, id, document)];
21974
+ default: return [];
21975
+ }
21976
+ }
21977
+ /**
21978
+ * @param {AST.VariableDeclaration} node
21979
+ * @param {TextDocument} document
21980
+ * @returns {SymbolInfo[]}
21981
+ */
21982
+ function createVariableDeclarationSymbols(node, document) {
21983
+ const kind = node.kind === "const" ? import_language_server.SymbolKind.Constant : import_language_server.SymbolKind.Variable;
21984
+ /** @type {SymbolInfo[]} */
21985
+ const symbols = [];
21986
+ for (const declaration of node.declarations) {
21987
+ if (declaration.id.type === "Identifier") {
21988
+ symbols.push(createNamedNodeSymbol(declaration.id.name, kind, declaration, declaration.id, document, declaration.init ? getInitializerChildSymbols(declaration.init, document) : []));
21989
+ continue;
21990
+ }
21991
+ symbols.push(...createBindingPatternSymbols(declaration.id, kind, document));
21992
+ }
21993
+ return symbols;
21994
+ }
21995
+ /**
21996
+ * @param {AST.Pattern} pattern
21997
+ * @param {SymbolKindType} kind
21998
+ * @param {TextDocument} document
21999
+ * @param {AST.Node} [rangeNode]
22000
+ * @returns {SymbolInfo[]}
22001
+ */
22002
+ function createBindingPatternSymbols(pattern, kind, document, rangeNode = pattern) {
22003
+ switch (pattern.type) {
22004
+ case "Identifier": return [createNamedNodeSymbol(pattern.name, kind, rangeNode, pattern, document)];
22005
+ case "ObjectPattern": {
22006
+ /** @type {SymbolInfo[]} */
22007
+ const symbols = [];
22008
+ for (const property of pattern.properties) if (property.type === "RestElement") symbols.push(...createBindingPatternSymbols(property.argument, kind, document, property));
22009
+ else symbols.push(...createBindingPatternSymbols(property.value, kind, document, property));
22010
+ return symbols;
22011
+ }
22012
+ case "ArrayPattern": {
22013
+ /** @type {SymbolInfo[]} */
22014
+ const symbols = [];
22015
+ for (const element of pattern.elements) if (element) symbols.push(...createBindingPatternSymbols(element, kind, document, element));
22016
+ return symbols;
22017
+ }
22018
+ case "RestElement": return createBindingPatternSymbols(pattern.argument, kind, document, pattern);
22019
+ case "AssignmentPattern": return createBindingPatternSymbols(pattern.left, kind, document, pattern);
22020
+ default: return [];
22021
+ }
22022
+ }
22023
+ /**
22024
+ * @param {AST.Node} node
22025
+ * @param {TextDocument} document
22026
+ * @returns {SymbolInfo[]}
22027
+ */
22028
+ function getInitializerChildSymbols(node, document) {
22029
+ if (node.type === "Component" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") return getChildSymbols(node, document);
22030
+ return [];
22031
+ }
22032
+ /**
22033
+ * @param {AST.Node | NodeWithBody} node
22034
+ * @param {TextDocument} document
22035
+ * @returns {SymbolInfo[]}
22036
+ */
22037
+ function getChildSymbols(node, document) {
22038
+ const body = node.body;
22039
+ if (Array.isArray(body)) return collectSymbolsFromStatements(body, document);
22040
+ else if (Array.isArray(body?.body)) return collectSymbolsFromStatements(body.body, document);
22041
+ return [];
22042
+ }
22043
+ /**
22044
+ * @param {AST.ClassDeclaration} node
22045
+ * @param {TextDocument} document
22046
+ * @returns {SymbolInfo[]}
22047
+ */
22048
+ function getClassChildSymbols(node, document) {
22049
+ const body = !Array.isArray(node.body) && node.body?.body ? node.body.body : [];
22050
+ /** @type {SymbolInfo[]} */
22051
+ const symbols = [];
22052
+ for (const member of body) {
22053
+ if (member.type !== "MethodDefinition" && member.type !== "PropertyDefinition") continue;
22054
+ const name = getPropertyName(member.key);
22055
+ if (!name) continue;
22056
+ symbols.push(createNamedNodeSymbol(name, member.type === "PropertyDefinition" ? import_language_server.SymbolKind.Property : import_language_server.SymbolKind.Method, member, member.key || member, document));
22057
+ }
22058
+ return symbols;
22059
+ }
22060
+ /**
22061
+ * @param {AST.Node | undefined | null} node
22062
+ * @returns {string | null}
22063
+ */
22064
+ function getPropertyName(node) {
22065
+ if (!node) return null;
22066
+ if (node.type === "Identifier") return node.name || null;
22067
+ if (node.type === "Literal" && typeof node.value === "string") return node.value;
22068
+ return null;
22069
+ }
22070
+ /**
22071
+ * @param {AST.Identifier | null | undefined } node
22072
+ * @returns {string | null}
22073
+ */
22074
+ function getIdentifierName(node) {
22075
+ return node?.name || null;
22076
+ }
22077
+ /**
22078
+ * @param {AST.Node} node
22079
+ * @param {string} keyword
22080
+ * @returns {AST.Identifier}
22081
+ */
22082
+ function createFallbackIdentifierNode(node, keyword) {
22083
+ let { start, loc } = node;
22084
+ loc = {
22085
+ start: { ...loc.start },
22086
+ end: {
22087
+ line: loc.start.line,
22088
+ column: loc.start.column + keyword.length
22089
+ }
22090
+ };
22091
+ return _tsrx_core.builders.id(keyword, {
22092
+ start,
22093
+ end: start + keyword.length,
22094
+ loc
22095
+ });
22096
+ }
22097
+ /**
22098
+ * @param {string} name
22099
+ * @param {SymbolKindType} kind
22100
+ * @param {AST.Node} rangeNode
22101
+ * @param {AST.Node} selectionNode
22102
+ * @param {TextDocument} document
22103
+ * @param {SymbolInfo[]} [children]
22104
+ * @returns {SymbolInfo}
22105
+ */
22106
+ function createNamedNodeSymbol(name, kind, rangeNode, selectionNode, document, children = []) {
22107
+ const adjustedSelectionNode = adjustNodeEnd(selectionNode);
22108
+ return [{
22109
+ name,
22110
+ kind,
22111
+ range: createRange(rangeNode, document),
22112
+ selectionRange: createRange(adjustedSelectionNode, document),
22113
+ children
22114
+ }, {
22115
+ rangeNode,
22116
+ selectionNode: adjustedSelectionNode
22117
+ }];
22118
+ }
22119
+ /**
22120
+ * @param {AST.Node} node
22121
+ * @param {TextDocument} document
22122
+ * @returns {Range}
22123
+ */
22124
+ function createRange(node, document) {
22125
+ const start = node.start;
22126
+ const end = node.type === "Identifier" && typeof node.name === "string" ? start + node.name.length : /** @type {AST.NodeWithLocation} */ node.end;
22127
+ return {
22128
+ start: document.positionAt(start),
22129
+ end: document.positionAt(end)
22130
+ };
22131
+ }
22132
+ /**
22133
+ * @param {AST.Node} node
22134
+ * @returns {AST.Node}
22135
+ */
22136
+ function adjustNodeEnd(node) {
22137
+ if (node.type === "Identifier" && typeof node.name === "string") return {
22138
+ ...node,
22139
+ end: node.start + node.name.length
22140
+ };
22141
+ return node;
22142
+ }
22143
+
21739
22144
  //#endregion
21740
22145
  //#region src/typescriptService.js
21741
22146
  /**
@@ -21828,6 +22233,7 @@ function createRippleLanguageServer() {
21828
22233
  createCompletionPlugin(),
21829
22234
  createCompileErrorDiagnosticPlugin(),
21830
22235
  createDefinitionPlugin(),
22236
+ createDocumentSymbolPlugin(),
21831
22237
  (0, volar_service_css.create)(),
21832
22238
  ...createTypeScriptServices(ts),
21833
22239
  createTypeScriptDiagnosticFilterPlugin(),
@@ -21888,4 +22294,4 @@ Object.defineProperty(exports, 'createRippleLanguageServer', {
21888
22294
  return createRippleLanguageServer;
21889
22295
  }
21890
22296
  });
21891
- //# sourceMappingURL=server-BNcMp4pJ.js.map
22297
+ //# sourceMappingURL=server-CPmlKSwW.js.map