@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 {
|
|
19999
|
+
/** @import {CompileError} from '@tsrx/core/types'; */
|
|
19999
20000
|
var import_language_server = require_language_server();
|
|
20000
|
-
const { log: log$
|
|
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$
|
|
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$
|
|
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$
|
|
20025
|
+
log$9("Generated", diagnostics.length, "diagnostics");
|
|
20025
20026
|
return diagnostics;
|
|
20026
20027
|
} };
|
|
20027
20028
|
}
|
|
20028
20029
|
};
|
|
20029
20030
|
}
|
|
20030
20031
|
/**
|
|
20031
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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
|
|
20119
|
-
/** @import {
|
|
20120
|
-
/** @typedef {{ code?: string, errors?:
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
20222
|
+
logError$4(`Ripple compiler not found for file: ${file_name}`);
|
|
20222
20223
|
return;
|
|
20223
20224
|
}
|
|
20224
|
-
log$
|
|
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$
|
|
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$
|
|
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 {
|
|
20278
|
+
/** @type {CompileError[]} */
|
|
20278
20279
|
fatalErrors = [];
|
|
20279
|
-
/** @type {
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
20336
|
-
log$
|
|
20337
|
-
log$
|
|
20338
|
-
log$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
20366
|
+
else log$8("Inserted typed dot at generated position", insertedDotPosition);
|
|
20359
20367
|
}
|
|
20360
20368
|
} else {
|
|
20361
|
-
log$
|
|
20369
|
+
log$8("Compiling Ripple code...");
|
|
20362
20370
|
transpiled = this.tsrx.compile_to_volar_mappings(newCode, this.fileName, { loose: true });
|
|
20363
|
-
log$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
20401
|
-
log$
|
|
20402
|
-
log$
|
|
20403
|
-
log$
|
|
20404
|
-
log$
|
|
20405
|
-
log$
|
|
20406
|
-
log$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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/
|
|
20817
|
-
const { log: log$
|
|
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$
|
|
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$
|
|
20845
|
-
log$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
20997
|
-
log$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
21043
|
+
log$6(`Hover explicitly suppressed in mapping at range start: ${starOffset}, end: ${endOffset}`);
|
|
21035
21044
|
return null;
|
|
21036
21045
|
}
|
|
21037
|
-
log$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
21568
|
+
log$4("No tag match found");
|
|
21560
21569
|
return null;
|
|
21561
21570
|
}
|
|
21562
21571
|
const tagName = tagMatch[1];
|
|
21563
|
-
log$
|
|
21572
|
+
log$4("Tag matched:", tagName);
|
|
21564
21573
|
if (VOID_ELEMENTS.has(tagName.toLowerCase())) {
|
|
21565
|
-
log$
|
|
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$
|
|
21584
|
+
log$4("Closing tag already exists, skipping");
|
|
21576
21585
|
return null;
|
|
21577
21586
|
}
|
|
21578
21587
|
const closingTag = `</${tagName}>`;
|
|
21579
|
-
log$
|
|
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$
|
|
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$
|
|
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$
|
|
21646
|
+
log$3(`Suppressing diagnostic ${diagnosticCode}: ${diagnostic.message}`);
|
|
21638
21647
|
continue;
|
|
21639
21648
|
}
|
|
21640
21649
|
process$1(diagnostic, result);
|
|
21641
21650
|
}
|
|
21642
|
-
log$
|
|
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$
|
|
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$
|
|
21677
|
+
log$3("Successfully wrapped typescript-semantic provideDiagnostics");
|
|
21669
21678
|
break;
|
|
21670
21679
|
}
|
|
21671
|
-
if (!originalProvider) logError$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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-
|
|
22297
|
+
//# sourceMappingURL=server-CPmlKSwW.js.map
|