@astrojs/ts-plugin 1.0.9 → 1.0.10

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.
Files changed (46) hide show
  1. package/dist/astro-snapshots.js +234 -0
  2. package/dist/astro-sys.js +30 -0
  3. package/dist/astro2tsx.js +26 -0
  4. package/dist/index.js +50 -0
  5. package/dist/language-service/completions.js +45 -0
  6. package/dist/language-service/definition.js +38 -0
  7. package/dist/language-service/diagnostics.js +62 -0
  8. package/dist/language-service/file-references.js +30 -0
  9. package/dist/language-service/find-references.js +66 -0
  10. package/dist/language-service/implementation.js +30 -0
  11. package/dist/language-service/index.js +44 -0
  12. package/dist/language-service/line-column-offset.js +21 -0
  13. package/dist/language-service/rename.js +34 -0
  14. package/dist/logger.js +40 -0
  15. package/dist/module-loader.js +146 -0
  16. package/dist/project-astro-files.js +102 -0
  17. package/dist/utils.js +61 -0
  18. package/package.json +5 -1
  19. package/.turbo/turbo-build.log +0 -4
  20. package/CHANGELOG.md +0 -113
  21. package/src/astro-snapshots.ts +0 -285
  22. package/src/astro-sys.ts +0 -35
  23. package/src/astro2tsx.ts +0 -26
  24. package/src/index.ts +0 -84
  25. package/src/language-service/completions.ts +0 -73
  26. package/src/language-service/definition.ts +0 -42
  27. package/src/language-service/diagnostics.ts +0 -73
  28. package/src/language-service/file-references.ts +0 -34
  29. package/src/language-service/find-references.ts +0 -90
  30. package/src/language-service/implementation.ts +0 -34
  31. package/src/language-service/index.ts +0 -56
  32. package/src/language-service/line-column-offset.ts +0 -24
  33. package/src/language-service/rename.ts +0 -46
  34. package/src/logger.ts +0 -41
  35. package/src/module-loader.ts +0 -219
  36. package/src/project-astro-files.ts +0 -138
  37. package/src/utils.ts +0 -77
  38. package/test/fixtures/MyAstroComponent.astro +0 -5
  39. package/test/fixtures/script.ts +0 -9
  40. package/test/fixtures/tsconfig.json +0 -3
  41. package/test/runTest.js +0 -43
  42. package/test/suite/extension.test.js +0 -78
  43. package/test/suite/index.js +0 -38
  44. package/test/tsconfig.json +0 -14
  45. package/test/utils.js +0 -69
  46. package/tsconfig.json +0 -13
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AstroSnapshotManager = exports.AstroSnapshot = void 0;
4
+ const trace_mapping_1 = require("@jridgewell/trace-mapping");
5
+ const astro2tsx_js_1 = require("./astro2tsx.js");
6
+ const utils_js_1 = require("./utils.js");
7
+ class AstroSnapshot {
8
+ constructor(typescript, fileName, astroCode, traceMap, logger) {
9
+ this.typescript = typescript;
10
+ this.fileName = fileName;
11
+ this.astroCode = astroCode;
12
+ this.traceMap = traceMap;
13
+ this.logger = logger;
14
+ this.convertInternalCodePositions = false;
15
+ }
16
+ update(astroCode, traceMap) {
17
+ this.astroCode = astroCode;
18
+ this.traceMap = traceMap;
19
+ this.lineOffsets = undefined;
20
+ this.log('Updated Snapshot');
21
+ }
22
+ getOriginalTextSpan(textSpan) {
23
+ const start = this.getOriginalOffset(textSpan.start);
24
+ if (start === -1) {
25
+ return null;
26
+ }
27
+ // Assumption: We don't change identifiers itself, so we don't change ranges.
28
+ return {
29
+ start,
30
+ length: textSpan.length,
31
+ };
32
+ }
33
+ getOriginalOffset(generatedOffset) {
34
+ if (!this.scriptInfo) {
35
+ return generatedOffset;
36
+ }
37
+ this.toggleMappingMode(true);
38
+ const lineOffset = this.scriptInfo.positionToLineOffset(generatedOffset);
39
+ this.debug('try convert offset', generatedOffset, '/', lineOffset);
40
+ const original = (0, trace_mapping_1.originalPositionFor)(this.traceMap, {
41
+ line: lineOffset.line,
42
+ column: lineOffset.offset,
43
+ });
44
+ this.toggleMappingMode(false);
45
+ if (!original.line) {
46
+ return -1;
47
+ }
48
+ const originalOffset = this.scriptInfo.lineOffsetToPosition(original.line, original.column);
49
+ this.debug('converted offset to', original, '/', originalOffset);
50
+ return originalOffset;
51
+ }
52
+ setAndPatchScriptInfo(scriptInfo) {
53
+ // @ts-expect-error
54
+ scriptInfo.scriptKind = this.typescript.ScriptKind.TSX;
55
+ const positionToLineOffset = scriptInfo.positionToLineOffset.bind(scriptInfo);
56
+ scriptInfo.positionToLineOffset = (position) => {
57
+ if (this.convertInternalCodePositions) {
58
+ const lineOffset = positionToLineOffset(position);
59
+ this.debug('positionToLineOffset for generated code', position, lineOffset);
60
+ return lineOffset;
61
+ }
62
+ const lineOffset = this.positionAt(position);
63
+ this.debug('positionToLineOffset for original code', position, lineOffset);
64
+ return { line: lineOffset.line + 1, offset: lineOffset.character + 1 };
65
+ };
66
+ const lineOffsetToPosition = scriptInfo.lineOffsetToPosition.bind(scriptInfo);
67
+ scriptInfo.lineOffsetToPosition = (line, offset) => {
68
+ if (this.convertInternalCodePositions) {
69
+ const position = lineOffsetToPosition(line, offset);
70
+ this.debug('lineOffsetToPosition for generated code', { line, offset }, position);
71
+ return position;
72
+ }
73
+ const position = this.offsetAt({ line: line - 1, character: offset - 1 });
74
+ this.debug('lineOffsetToPosition for original code', { line, offset }, position);
75
+ return position;
76
+ };
77
+ this.scriptInfo = scriptInfo;
78
+ this.log('patched scriptInfo');
79
+ }
80
+ /**
81
+ * Get the line and character based on the offset
82
+ * @param offset The index of the position
83
+ */
84
+ positionAt(offset) {
85
+ offset = this.clamp(offset, 0, this.astroCode.length);
86
+ const lineOffsets = this.getLineOffsets();
87
+ let low = 0;
88
+ let high = lineOffsets.length;
89
+ if (high === 0) {
90
+ return { line: 0, character: offset };
91
+ }
92
+ while (low < high) {
93
+ const mid = Math.floor((low + high) / 2);
94
+ if (lineOffsets[mid] > offset) {
95
+ high = mid;
96
+ }
97
+ else {
98
+ low = mid + 1;
99
+ }
100
+ }
101
+ // low is the least x for which the line offset is larger than the current offset
102
+ // or array.length if no line offset is larger than the current offset
103
+ const line = low - 1;
104
+ return { line, character: offset - lineOffsets[line] };
105
+ }
106
+ /**
107
+ * Get the index of the line and character position
108
+ * @param position Line and character position
109
+ */
110
+ offsetAt(position) {
111
+ const lineOffsets = this.getLineOffsets();
112
+ if (position.line >= lineOffsets.length) {
113
+ return this.astroCode.length;
114
+ }
115
+ else if (position.line < 0) {
116
+ return 0;
117
+ }
118
+ const lineOffset = lineOffsets[position.line];
119
+ const nextLineOffset = position.line + 1 < lineOffsets.length
120
+ ? lineOffsets[position.line + 1]
121
+ : this.astroCode.length;
122
+ return this.clamp(nextLineOffset, lineOffset, lineOffset + position.character);
123
+ }
124
+ getLineOffsets() {
125
+ if (this.lineOffsets) {
126
+ return this.lineOffsets;
127
+ }
128
+ const lineOffsets = [];
129
+ const text = this.astroCode;
130
+ let isLineStart = true;
131
+ for (let i = 0; i < text.length; i++) {
132
+ if (isLineStart) {
133
+ lineOffsets.push(i);
134
+ isLineStart = false;
135
+ }
136
+ const ch = text.charAt(i);
137
+ isLineStart = ch === '\r' || ch === '\n';
138
+ if (ch === '\r' && i + 1 < text.length && text.charAt(i + 1) === '\n') {
139
+ i++;
140
+ }
141
+ }
142
+ if (isLineStart && text.length > 0) {
143
+ lineOffsets.push(text.length);
144
+ }
145
+ this.lineOffsets = lineOffsets;
146
+ return lineOffsets;
147
+ }
148
+ clamp(num, min, max) {
149
+ return Math.max(min, Math.min(max, num));
150
+ }
151
+ log(...args) {
152
+ this.logger.log('AstroSnapshot:', this.fileName, '-', ...args);
153
+ }
154
+ debug(...args) {
155
+ this.logger.debug('AstroSnapshot:', this.fileName, '-', ...args);
156
+ }
157
+ toggleMappingMode(convertInternalCodePositions) {
158
+ this.convertInternalCodePositions = convertInternalCodePositions;
159
+ }
160
+ getText() {
161
+ const snapshot = this.scriptInfo?.getSnapshot();
162
+ if (!snapshot) {
163
+ return '';
164
+ }
165
+ return snapshot.getText(0, snapshot.getLength());
166
+ }
167
+ }
168
+ exports.AstroSnapshot = AstroSnapshot;
169
+ class AstroSnapshotManager {
170
+ constructor(typescript, projectService, logger) {
171
+ this.typescript = typescript;
172
+ this.projectService = projectService;
173
+ this.logger = logger;
174
+ this.snapshots = new Map();
175
+ this.patchProjectServiceReadFile();
176
+ }
177
+ get(fileName) {
178
+ return this.snapshots.get(fileName);
179
+ }
180
+ create(fileName) {
181
+ if (this.snapshots.has(fileName)) {
182
+ return this.snapshots.get(fileName);
183
+ }
184
+ // This will trigger projectService.host.readFile which is patched below
185
+ const scriptInfo = this.projectService.getOrCreateScriptInfoForNormalizedPath(this.typescript.server.toNormalizedPath(fileName), false);
186
+ if (!scriptInfo) {
187
+ this.logger.log('Was not able get snapshot for', fileName);
188
+ return;
189
+ }
190
+ try {
191
+ scriptInfo.getSnapshot(); // needed to trigger readFile
192
+ }
193
+ catch (e) {
194
+ this.logger.log('Loading Snapshot failed', fileName);
195
+ }
196
+ const snapshot = this.snapshots.get(fileName);
197
+ if (!snapshot) {
198
+ this.logger.log('Astro snapshot was not found after trying to load script snapshot for', fileName);
199
+ return; // should never get here
200
+ }
201
+ snapshot.setAndPatchScriptInfo(scriptInfo);
202
+ this.snapshots.set(fileName, snapshot);
203
+ return snapshot;
204
+ }
205
+ patchProjectServiceReadFile() {
206
+ const readFile = this.projectService.host.readFile;
207
+ this.projectService.host.readFile = (path) => {
208
+ if ((0, utils_js_1.isAstroFilePath)(path)) {
209
+ this.logger.debug('Read Astro file:', path);
210
+ const astroCode = readFile(path) || '';
211
+ try {
212
+ const result = (0, astro2tsx_js_1.astro2tsx)(astroCode, path);
213
+ const existingSnapshot = this.snapshots.get(path);
214
+ if (existingSnapshot) {
215
+ existingSnapshot.update(astroCode, new trace_mapping_1.TraceMap(result.map));
216
+ }
217
+ else {
218
+ this.snapshots.set(path, new AstroSnapshot(this.typescript, path, astroCode, new trace_mapping_1.TraceMap(result.map), this.logger));
219
+ }
220
+ this.logger.log('Successfully read Astro file contents of', path);
221
+ return result.code;
222
+ }
223
+ catch (e) {
224
+ this.logger.log('Error loading Astro file:', path);
225
+ this.logger.debug('Error:', e);
226
+ }
227
+ }
228
+ else {
229
+ return readFile(path);
230
+ }
231
+ };
232
+ }
233
+ }
234
+ exports.AstroSnapshotManager = AstroSnapshotManager;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAstroSys = void 0;
4
+ const utils_js_1 = require("./utils.js");
5
+ /**
6
+ * This should only be accessed by TS astro module resolution.
7
+ */
8
+ function createAstroSys(logger, typescript) {
9
+ const astroSys = {
10
+ ...typescript.sys,
11
+ fileExists(path) {
12
+ return typescript.sys.fileExists((0, utils_js_1.ensureRealAstroFilePath)(path));
13
+ },
14
+ readDirectory(path, extensions, exclude, include, depth) {
15
+ const extensionsWithAstro = (extensions ?? []).concat('.astro');
16
+ return typescript.sys.readDirectory(path, extensionsWithAstro, exclude, include, depth);
17
+ },
18
+ };
19
+ if (typescript.sys.realpath) {
20
+ const realpath = typescript.sys.realpath;
21
+ astroSys.realpath = function (path) {
22
+ if ((0, utils_js_1.isVirtualAstroFilePath)(path)) {
23
+ return realpath((0, utils_js_1.toRealAstroFilePath)(path)) + '.ts';
24
+ }
25
+ return realpath(path);
26
+ };
27
+ }
28
+ return astroSys;
29
+ }
30
+ exports.createAstroSys = createAstroSys;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.astro2tsx = void 0;
4
+ const sync_1 = require("@astrojs/compiler/sync");
5
+ function astro2tsx(content, fileName) {
6
+ try {
7
+ const tsx = (0, sync_1.convertToTSX)(content, { filename: fileName });
8
+ return tsx;
9
+ }
10
+ catch (e) {
11
+ console.error(`There was an error transforming ${fileName} to TSX. An empty file will be returned instead. Please create an issue: https://github.com/withastro/language-tools/issues\nError: ${e}.`);
12
+ return {
13
+ code: '',
14
+ map: {
15
+ file: fileName,
16
+ sources: [],
17
+ sourcesContent: [],
18
+ names: [],
19
+ mappings: '',
20
+ version: 0,
21
+ },
22
+ diagnostics: [],
23
+ };
24
+ }
25
+ }
26
+ exports.astro2tsx = astro2tsx;
package/dist/index.js ADDED
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ const astro_snapshots_js_1 = require("./astro-snapshots.js");
3
+ const index_js_1 = require("./language-service/index.js");
4
+ const logger_js_1 = require("./logger.js");
5
+ const module_loader_js_1 = require("./module-loader.js");
6
+ const project_astro_files_js_1 = require("./project-astro-files.js");
7
+ const utils_js_1 = require("./utils.js");
8
+ function init(modules) {
9
+ const ts = modules.typescript;
10
+ function create(info) {
11
+ const logger = new logger_js_1.Logger(info.project.projectService.logger);
12
+ const parsedCommandLine = info.languageServiceHost.getParsedCommandLine?.((0, utils_js_1.getConfigPathForProject)(info.project));
13
+ if (!isAstroProject(info.project, parsedCommandLine)) {
14
+ logger.log('Detected that this is not an Astro project, abort patching TypeScript');
15
+ return info.languageService;
16
+ }
17
+ if ((0, index_js_1.isPatched)(info.languageService)) {
18
+ return info.languageService;
19
+ }
20
+ logger.log('Starting Astro plugin');
21
+ const snapshotManager = new astro_snapshots_js_1.AstroSnapshotManager(modules.typescript, info.project.projectService, logger);
22
+ if (parsedCommandLine) {
23
+ new project_astro_files_js_1.ProjectAstroFilesManager(modules.typescript, info.project, info.serverHost, snapshotManager, parsedCommandLine);
24
+ }
25
+ (0, module_loader_js_1.patchModuleLoader)(logger, snapshotManager, modules.typescript, info.languageServiceHost, info.project);
26
+ return (0, index_js_1.decorateLanguageService)(info.languageService, snapshotManager, ts, logger);
27
+ }
28
+ function getExternalFiles(project) {
29
+ return project_astro_files_js_1.ProjectAstroFilesManager.getInstance(project.getProjectName())?.getFiles() ?? [];
30
+ }
31
+ function isAstroProject(project, parsedCommandLine) {
32
+ if (parsedCommandLine) {
33
+ const astroFiles = (0, utils_js_1.readProjectAstroFilesFromFs)(ts, project, parsedCommandLine);
34
+ if (astroFiles.length > 0)
35
+ return true;
36
+ }
37
+ try {
38
+ const compilerOptions = project.getCompilerOptions();
39
+ const hasAstroInstalled = typeof compilerOptions.configFilePath !== 'string' ||
40
+ require.resolve('astro', { paths: [compilerOptions.configFilePath] });
41
+ return hasAstroInstalled;
42
+ }
43
+ catch (e) {
44
+ project.projectService.logger.info(e);
45
+ return false;
46
+ }
47
+ }
48
+ return { create, getExternalFiles };
49
+ }
50
+ module.exports = init;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decorateCompletions = void 0;
4
+ const utils_js_1 = require("../utils.js");
5
+ const componentPostfix = '__AstroComponent_';
6
+ function decorateCompletions(ls, logger) {
7
+ const getCompletionsAtPosition = ls.getCompletionsAtPosition;
8
+ ls.getCompletionsAtPosition = (fileName, position, options) => {
9
+ const completions = getCompletionsAtPosition(fileName, position, options);
10
+ if (!completions) {
11
+ return completions;
12
+ }
13
+ return {
14
+ ...completions,
15
+ entries: completions.entries.map((entry) => {
16
+ if (!(0, utils_js_1.isAstroFilePath)(entry.source || '') || !entry.name.endsWith(componentPostfix)) {
17
+ return entry;
18
+ }
19
+ return {
20
+ ...entry,
21
+ name: entry.name.slice(0, -componentPostfix.length),
22
+ };
23
+ }),
24
+ };
25
+ };
26
+ const getCompletionEntryDetails = ls.getCompletionEntryDetails;
27
+ ls.getCompletionEntryDetails = (fileName, position, entryName, formatOptions, source, preferences, data) => {
28
+ if (!(0, utils_js_1.isAstroFilePath)(source || '')) {
29
+ const details = getCompletionEntryDetails(fileName, position, entryName, formatOptions, source, preferences, data);
30
+ if (details) {
31
+ return details;
32
+ }
33
+ }
34
+ // In the completion list we removed the component postfix. Internally,
35
+ // the language service saved the list with the postfix, so details
36
+ // won't match anything. Therefore add it back and remove it afterwards again.
37
+ const astroDetails = getCompletionEntryDetails(fileName, position, entryName + componentPostfix, formatOptions, source, preferences, data);
38
+ if (!astroDetails) {
39
+ return undefined;
40
+ }
41
+ logger.debug('Found Astro Component import completion details');
42
+ return (0, utils_js_1.replaceDeep)(astroDetails, componentPostfix, '');
43
+ };
44
+ }
45
+ exports.decorateCompletions = decorateCompletions;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decorateGetDefinition = void 0;
4
+ const utils_1 = require("../utils");
5
+ function decorateGetDefinition(ls, snapshotManager) {
6
+ const getDefinitionAndBoundSpan = ls.getDefinitionAndBoundSpan;
7
+ ls.getDefinitionAndBoundSpan = (fileName, position) => {
8
+ const definition = getDefinitionAndBoundSpan(fileName, position);
9
+ if (!definition?.definitions) {
10
+ return definition;
11
+ }
12
+ return {
13
+ ...definition,
14
+ definitions: definition.definitions
15
+ .map((def) => {
16
+ if (!(0, utils_1.isAstroFilePath)(def.fileName)) {
17
+ return def;
18
+ }
19
+ let textSpan = snapshotManager.get(def.fileName)?.getOriginalTextSpan(def.textSpan);
20
+ if (!textSpan) {
21
+ // Unmapped positions are for example the default export.
22
+ // Fall back to the start of the file to at least go to the correct file.
23
+ textSpan = { start: 0, length: 1 };
24
+ }
25
+ return {
26
+ ...def,
27
+ textSpan,
28
+ // Spare the work for now
29
+ originalTextSpan: undefined,
30
+ contextSpan: undefined,
31
+ originalContextSpan: undefined,
32
+ };
33
+ })
34
+ .filter(utils_1.isNotNullOrUndefined),
35
+ };
36
+ };
37
+ }
38
+ exports.decorateGetDefinition = decorateGetDefinition;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decorateDiagnostics = exports.DiagnosticCodes = void 0;
4
+ const utils_js_1 = require("../utils.js");
5
+ var DiagnosticCodes;
6
+ (function (DiagnosticCodes) {
7
+ DiagnosticCodes[DiagnosticCodes["CANNOT_FIND_MODULE"] = 2307] = "CANNOT_FIND_MODULE";
8
+ })(DiagnosticCodes || (exports.DiagnosticCodes = DiagnosticCodes = {}));
9
+ function decorateDiagnostics(ls, typescript) {
10
+ decorateSyntacticDiagnostics(ls);
11
+ decorateSemanticDiagnostics(ls, typescript);
12
+ decorateSuggestionDiagnostics(ls);
13
+ }
14
+ exports.decorateDiagnostics = decorateDiagnostics;
15
+ function decorateSyntacticDiagnostics(ls) {
16
+ const getSyntacticDiagnostics = ls.getSyntacticDiagnostics;
17
+ ls.getSyntacticDiagnostics = (fileName) => {
18
+ // Diagnostics inside Astro files are done
19
+ // by the @astrojs/language-server / Astro for VS Code extension
20
+ if ((0, utils_js_1.isAstroFilePath)(fileName)) {
21
+ return [];
22
+ }
23
+ return getSyntacticDiagnostics(fileName);
24
+ };
25
+ }
26
+ function decorateSemanticDiagnostics(ls, typescript) {
27
+ const getSemanticDiagnostics = ls.getSemanticDiagnostics;
28
+ ls.getSemanticDiagnostics = (fileName) => {
29
+ // Diagnostics inside Astro files are done
30
+ // by the @astrojs/language-server / Astro for VS Code extension
31
+ if ((0, utils_js_1.isAstroFilePath)(fileName)) {
32
+ return [];
33
+ }
34
+ let diagnostics = getSemanticDiagnostics(fileName);
35
+ diagnostics = diagnostics.map((diag) => {
36
+ const message = typescript.flattenDiagnosticMessageText(diag.messageText, typescript.sys.newLine);
37
+ if (diag.code === DiagnosticCodes.CANNOT_FIND_MODULE &&
38
+ message.includes('astro:content') &&
39
+ // TypeScript will keep the diagnostics here in cache, so if we just blindly always add to it, our added message will be there twice
40
+ // Not sure if there's a generic way to ensure that we only add it once, so for now we'll just check for the message we want to add
41
+ !message.includes('content collections')) {
42
+ diag.messageText =
43
+ message +
44
+ `${typescript.sys.newLine}${typescript.sys.newLine}` +
45
+ "If you're using content collections, make sure to run `astro dev`, `astro build` or `astro sync` to first generate the types so you can import from them. If you already ran one of those commands, restarting the TS Server might be necessary in order for the change to take effect.";
46
+ }
47
+ return diag;
48
+ });
49
+ return diagnostics;
50
+ };
51
+ }
52
+ function decorateSuggestionDiagnostics(ls) {
53
+ const getSuggestionDiagnostics = ls.getSuggestionDiagnostics;
54
+ ls.getSuggestionDiagnostics = (fileName) => {
55
+ // Diagnostics inside Astro files are done
56
+ // by the @astrojs/language-server / Astro for VS Code extension
57
+ if ((0, utils_js_1.isAstroFilePath)(fileName)) {
58
+ return [];
59
+ }
60
+ return getSuggestionDiagnostics(fileName);
61
+ };
62
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decorateGetFileReferences = void 0;
4
+ const utils_js_1 = require("../utils.js");
5
+ function decorateGetFileReferences(ls, snapshotManager) {
6
+ const getFileReferences = ls.getFileReferences;
7
+ ls.getFileReferences = (fileName) => {
8
+ const references = getFileReferences(fileName);
9
+ return references
10
+ ?.map((ref) => {
11
+ if (!(0, utils_js_1.isAstroFilePath)(ref.fileName)) {
12
+ return ref;
13
+ }
14
+ const textSpan = snapshotManager.get(ref.fileName)?.getOriginalTextSpan(ref.textSpan);
15
+ if (!textSpan) {
16
+ return undefined;
17
+ }
18
+ return {
19
+ ...ref,
20
+ textSpan,
21
+ // Spare the work for now
22
+ contextSpan: undefined,
23
+ originalTextSpan: undefined,
24
+ originalContextSpan: undefined,
25
+ };
26
+ })
27
+ .filter(utils_js_1.isNotNullOrUndefined);
28
+ };
29
+ }
30
+ exports.decorateGetFileReferences = decorateGetFileReferences;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decorateFindReferences = void 0;
4
+ const utils_js_1 = require("../utils.js");
5
+ function decorateFindReferences(ls, snapshotManager, logger) {
6
+ decorateGetReferencesAtPosition(ls, snapshotManager, logger);
7
+ _decorateFindReferences(ls, snapshotManager, logger);
8
+ }
9
+ exports.decorateFindReferences = decorateFindReferences;
10
+ function _decorateFindReferences(ls, snapshotManager, logger) {
11
+ const findReferences = ls.findReferences;
12
+ ls.findReferences = (fileName, position) => {
13
+ const references = findReferences(fileName, position);
14
+ return references
15
+ ?.map((reference) => {
16
+ const snapshot = snapshotManager.get(reference.definition.fileName);
17
+ if (!(0, utils_js_1.isAstroFilePath)(reference.definition.fileName) || !snapshot) {
18
+ return reference;
19
+ }
20
+ const textSpan = snapshot.getOriginalTextSpan(reference.definition.textSpan);
21
+ if (!textSpan) {
22
+ return null;
23
+ }
24
+ return {
25
+ definition: {
26
+ ...reference.definition,
27
+ textSpan,
28
+ // Spare the work for now
29
+ originalTextSpan: undefined,
30
+ },
31
+ references: mapReferences(reference.references, snapshotManager, logger),
32
+ };
33
+ })
34
+ .filter(utils_js_1.isNotNullOrUndefined);
35
+ };
36
+ }
37
+ function decorateGetReferencesAtPosition(ls, snapshotManager, logger) {
38
+ const getReferencesAtPosition = ls.getReferencesAtPosition;
39
+ ls.getReferencesAtPosition = (fileName, position) => {
40
+ const references = getReferencesAtPosition(fileName, position);
41
+ return references && mapReferences(references, snapshotManager, logger);
42
+ };
43
+ }
44
+ function mapReferences(references, snapshotManager, logger) {
45
+ return references
46
+ .map((reference) => {
47
+ const snapshot = snapshotManager.get(reference.fileName);
48
+ if (!(0, utils_js_1.isAstroFilePath)(reference.fileName) || !snapshot) {
49
+ return reference;
50
+ }
51
+ const textSpan = snapshot.getOriginalTextSpan(reference.textSpan);
52
+ if (!textSpan) {
53
+ return null;
54
+ }
55
+ logger.debug('Find references; map textSpan: changed', reference.textSpan, 'to', textSpan);
56
+ return {
57
+ ...reference,
58
+ textSpan,
59
+ // Spare the work for now
60
+ contextSpan: undefined,
61
+ originalTextSpan: undefined,
62
+ originalContextSpan: undefined,
63
+ };
64
+ })
65
+ .filter(utils_js_1.isNotNullOrUndefined);
66
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decorateGetImplementation = void 0;
4
+ const utils_js_1 = require("../utils.js");
5
+ function decorateGetImplementation(ls, snapshotManager) {
6
+ const getImplementationAtPosition = ls.getImplementationAtPosition;
7
+ ls.getImplementationAtPosition = (fileName, position) => {
8
+ const implementation = getImplementationAtPosition(fileName, position);
9
+ return implementation
10
+ ?.map((impl) => {
11
+ if (!(0, utils_js_1.isAstroFilePath)(impl.fileName)) {
12
+ return impl;
13
+ }
14
+ const textSpan = snapshotManager.get(impl.fileName)?.getOriginalTextSpan(impl.textSpan);
15
+ if (!textSpan) {
16
+ return undefined;
17
+ }
18
+ return {
19
+ ...impl,
20
+ textSpan,
21
+ // Spare the work for now
22
+ contextSpan: undefined,
23
+ originalTextSpan: undefined,
24
+ originalContextSpan: undefined,
25
+ };
26
+ })
27
+ .filter(utils_js_1.isNotNullOrUndefined);
28
+ };
29
+ }
30
+ exports.decorateGetImplementation = decorateGetImplementation;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decorateLanguageService = exports.isPatched = void 0;
4
+ const completions_js_1 = require("./completions.js");
5
+ const definition_js_1 = require("./definition.js");
6
+ const diagnostics_js_1 = require("./diagnostics.js");
7
+ const file_references_js_1 = require("./file-references.js");
8
+ const find_references_js_1 = require("./find-references.js");
9
+ const implementation_js_1 = require("./implementation.js");
10
+ const line_column_offset_js_1 = require("./line-column-offset.js");
11
+ const rename_js_1 = require("./rename.js");
12
+ const astroPluginPatchSymbol = Symbol('astroPluginPatchSymbol');
13
+ function isPatched(ls) {
14
+ return ls[astroPluginPatchSymbol] === true;
15
+ }
16
+ exports.isPatched = isPatched;
17
+ function decorateLanguageService(ls, snapshotManager, ts, logger) {
18
+ const proxy = new Proxy(ls, createProxyHandler());
19
+ (0, line_column_offset_js_1.decorateLineColumnOffset)(proxy, snapshotManager);
20
+ (0, rename_js_1.decorateRename)(proxy, snapshotManager, logger);
21
+ (0, diagnostics_js_1.decorateDiagnostics)(proxy, ts);
22
+ (0, find_references_js_1.decorateFindReferences)(proxy, snapshotManager, logger);
23
+ (0, completions_js_1.decorateCompletions)(proxy, logger);
24
+ (0, definition_js_1.decorateGetDefinition)(proxy, snapshotManager);
25
+ (0, implementation_js_1.decorateGetImplementation)(proxy, snapshotManager);
26
+ (0, file_references_js_1.decorateGetFileReferences)(proxy, snapshotManager);
27
+ return proxy;
28
+ }
29
+ exports.decorateLanguageService = decorateLanguageService;
30
+ function createProxyHandler() {
31
+ const decorated = {};
32
+ return {
33
+ get(target, p) {
34
+ if (p === astroPluginPatchSymbol) {
35
+ return true;
36
+ }
37
+ return decorated[p] ?? target[p];
38
+ },
39
+ set(_, p, value) {
40
+ decorated[p] = value;
41
+ return true;
42
+ },
43
+ };
44
+ }