@astrojs/language-server 0.26.2 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugins/PluginHost.d.ts +7 -4
- package/dist/plugins/PluginHost.js +17 -5
- package/dist/plugins/astro/features/CompletionsProvider.js +2 -2
- package/dist/plugins/html/HTMLPlugin.js +1 -1
- package/dist/plugins/html/features/astro-attributes.js +3 -0
- package/dist/plugins/interfaces.d.ts +10 -4
- package/dist/plugins/typescript/LanguageServiceManager.d.ts +6 -1
- package/dist/plugins/typescript/LanguageServiceManager.js +8 -2
- package/dist/plugins/typescript/TypeScriptPlugin.d.ts +13 -3
- package/dist/plugins/typescript/TypeScriptPlugin.js +27 -5
- package/dist/plugins/typescript/astro-sys.js +1 -1
- package/dist/plugins/typescript/features/CodeActionsProvider.js +2 -1
- package/dist/plugins/typescript/features/FileReferencesProvider.d.ts +9 -0
- package/dist/plugins/typescript/features/FileReferencesProvider.js +28 -0
- package/dist/plugins/typescript/features/ImplementationsProvider.d.ts +9 -0
- package/dist/plugins/typescript/features/ImplementationsProvider.js +51 -0
- package/dist/plugins/typescript/features/ReferencesProvider.d.ts +9 -0
- package/dist/plugins/typescript/features/ReferencesProvider.js +54 -0
- package/dist/plugins/typescript/features/TypeDefinitionsProvider.d.ts +2 -2
- package/dist/plugins/typescript/language-service.d.ts +1 -1
- package/dist/plugins/typescript/language-service.js +3 -3
- package/dist/plugins/typescript/snapshots/DocumentSnapshot.d.ts +2 -3
- package/dist/plugins/typescript/snapshots/DocumentSnapshot.js +2 -2
- package/dist/plugins/typescript/snapshots/SnapshotManager.d.ts +2 -3
- package/dist/plugins/typescript/snapshots/SnapshotManager.js +9 -21
- package/dist/plugins/typescript/snapshots/utils.d.ts +3 -3
- package/dist/plugins/typescript/snapshots/utils.js +9 -9
- package/dist/server.js +13 -6
- package/package.json +3 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CancellationToken, CodeAction, CodeActionContext, Color, ColorInformation, ColorPresentation, CompletionContext, CompletionItem, CompletionList, DefinitionLink, Diagnostic, FoldingRange, FormattingOptions, Hover, InlayHint, LinkedEditingRanges, Location, Position, Range, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, TextDocumentIdentifier, TextEdit, WorkspaceEdit } from 'vscode-languageserver';
|
|
1
|
+
import { CancellationToken, CodeAction, CodeActionContext, Color, ColorInformation, ColorPresentation, CompletionContext, CompletionItem, CompletionList, DefinitionLink, Diagnostic, FoldingRange, FormattingOptions, Hover, InlayHint, LinkedEditingRanges, Location, Position, Range, ReferenceContext, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, TextDocumentIdentifier, TextEdit, WorkspaceEdit } from 'vscode-languageserver';
|
|
2
2
|
import type { DocumentManager } from '../core/documents/DocumentManager';
|
|
3
3
|
import type { AppCompletionItem, Plugin } from './interfaces';
|
|
4
4
|
export interface PluginHostConfig {
|
|
@@ -23,15 +23,18 @@ export declare class PluginHost {
|
|
|
23
23
|
getDocumentSymbols(textDocument: TextDocumentIdentifier, cancellationToken?: CancellationToken): Promise<SymbolInformation[]>;
|
|
24
24
|
getSemanticTokens(textDocument: TextDocumentIdentifier, range?: Range, cancellationToken?: CancellationToken): Promise<SemanticTokens | null>;
|
|
25
25
|
getLinkedEditingRanges(textDocument: TextDocumentIdentifier, position: Position): Promise<LinkedEditingRanges | null>;
|
|
26
|
+
fileReferences(textDocument: TextDocumentIdentifier): Promise<Location[] | null>;
|
|
26
27
|
getDefinitions(textDocument: TextDocumentIdentifier, position: Position): Promise<DefinitionLink[] | Location[]>;
|
|
27
|
-
|
|
28
|
+
getTypeDefinitions(textDocument: TextDocumentIdentifier, position: Position): Promise<Location[] | null>;
|
|
29
|
+
getImplementations(textDocument: TextDocumentIdentifier, position: Position): Promise<Location[] | null>;
|
|
30
|
+
getReferences(textdocument: TextDocumentIdentifier, position: Position, context: ReferenceContext): Promise<Location[] | null>;
|
|
28
31
|
rename(textDocument: TextDocumentIdentifier, position: Position, newName: string): Promise<WorkspaceEdit | null>;
|
|
29
32
|
getDocumentColors(textDocument: TextDocumentIdentifier): Promise<ColorInformation[]>;
|
|
30
33
|
getColorPresentations(textDocument: TextDocumentIdentifier, range: Range, color: Color): Promise<ColorPresentation[]>;
|
|
31
34
|
getInlayHints(textDocument: TextDocumentIdentifier, range: Range, cancellationToken?: CancellationToken): Promise<InlayHint[]>;
|
|
32
35
|
getSignatureHelp(textDocument: TextDocumentIdentifier, position: Position, context: SignatureHelpContext | undefined, cancellationToken?: CancellationToken): Promise<SignatureHelp | null>;
|
|
33
|
-
onWatchFileChanges(onWatchFileChangesParams: any[]): void
|
|
34
|
-
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[]): void;
|
|
36
|
+
onWatchFileChanges(onWatchFileChangesParams: any[]): Promise<void>;
|
|
37
|
+
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[], text?: string): void;
|
|
35
38
|
private getDocument;
|
|
36
39
|
private execute;
|
|
37
40
|
private tryExecutePlugin;
|
|
@@ -105,6 +105,10 @@ class PluginHost {
|
|
|
105
105
|
const document = this.getDocument(textDocument.uri);
|
|
106
106
|
return await this.execute('getLinkedEditingRanges', [document, position], ExecuteMode.FirstNonNull);
|
|
107
107
|
}
|
|
108
|
+
async fileReferences(textDocument) {
|
|
109
|
+
const document = this.getDocument(textDocument.uri);
|
|
110
|
+
return await this.execute('fileReferences', [document], ExecuteMode.FirstNonNull);
|
|
111
|
+
}
|
|
108
112
|
async getDefinitions(textDocument, position) {
|
|
109
113
|
const document = this.getDocument(textDocument.uri);
|
|
110
114
|
const definitions = await this.execute('getDefinitions', [document, position], ExecuteMode.Collect);
|
|
@@ -115,10 +119,18 @@ class PluginHost {
|
|
|
115
119
|
return definitions.map((def) => ({ range: def.targetSelectionRange, uri: def.targetUri }));
|
|
116
120
|
}
|
|
117
121
|
}
|
|
118
|
-
|
|
122
|
+
getTypeDefinitions(textDocument, position) {
|
|
119
123
|
const document = this.getDocument(textDocument.uri);
|
|
120
124
|
return this.execute('getTypeDefinitions', [document, position], ExecuteMode.FirstNonNull);
|
|
121
125
|
}
|
|
126
|
+
getImplementations(textDocument, position) {
|
|
127
|
+
const document = this.getDocument(textDocument.uri);
|
|
128
|
+
return this.execute('getImplementation', [document, position], ExecuteMode.FirstNonNull);
|
|
129
|
+
}
|
|
130
|
+
getReferences(textdocument, position, context) {
|
|
131
|
+
const document = this.getDocument(textdocument.uri);
|
|
132
|
+
return this.execute('findReferences', [document, position, context], ExecuteMode.FirstNonNull);
|
|
133
|
+
}
|
|
122
134
|
async rename(textDocument, position, newName) {
|
|
123
135
|
const document = this.getDocument(textDocument.uri);
|
|
124
136
|
return this.execute('rename', [document, position, newName], ExecuteMode.FirstNonNull);
|
|
@@ -139,14 +151,14 @@ class PluginHost {
|
|
|
139
151
|
const document = this.getDocument(textDocument.uri);
|
|
140
152
|
return await this.execute('getSignatureHelp', [document, position, context, cancellationToken], ExecuteMode.FirstNonNull);
|
|
141
153
|
}
|
|
142
|
-
onWatchFileChanges(onWatchFileChangesParams) {
|
|
154
|
+
async onWatchFileChanges(onWatchFileChangesParams) {
|
|
143
155
|
for (const support of this.plugins) {
|
|
144
|
-
support.onWatchFileChanges?.(onWatchFileChangesParams);
|
|
156
|
+
await support.onWatchFileChanges?.(onWatchFileChangesParams);
|
|
145
157
|
}
|
|
146
158
|
}
|
|
147
|
-
updateNonAstroFile(fileName, changes) {
|
|
159
|
+
updateNonAstroFile(fileName, changes, text) {
|
|
148
160
|
for (const support of this.plugins) {
|
|
149
|
-
support.updateNonAstroFile?.(fileName, changes);
|
|
161
|
+
support.updateNonAstroFile?.(fileName, changes, text);
|
|
150
162
|
}
|
|
151
163
|
}
|
|
152
164
|
getDocument(uri) {
|
|
@@ -34,7 +34,7 @@ class CompletionsProviderImpl {
|
|
|
34
34
|
items.push(...props);
|
|
35
35
|
}
|
|
36
36
|
const isAstro = componentFilePath?.endsWith('.astro');
|
|
37
|
-
if (!isAstro) {
|
|
37
|
+
if (!isAstro && node.tag !== 'Fragment') {
|
|
38
38
|
const directives = (0, utils_2.removeDataAttrCompletion)(this.directivesHTMLLang.doComplete(document, position, html).items);
|
|
39
39
|
items.push(...directives);
|
|
40
40
|
}
|
|
@@ -157,7 +157,7 @@ class CompletionsProviderImpl {
|
|
|
157
157
|
if (this.ts.isImportDeclaration(node)) {
|
|
158
158
|
let clauses = node.importClause;
|
|
159
159
|
if (!clauses)
|
|
160
|
-
|
|
160
|
+
continue;
|
|
161
161
|
let namedImport = clauses.getChildAt(0);
|
|
162
162
|
if (this.ts.isNamedImports(namedImport)) {
|
|
163
163
|
for (let imp of namedImport.elements) {
|
|
@@ -37,7 +37,7 @@ class HTMLPlugin {
|
|
|
37
37
|
return null;
|
|
38
38
|
}
|
|
39
39
|
// If the node we're hovering on is a component, instead only provide astro-specific hover info
|
|
40
|
-
if ((0, utils_1.isPossibleComponent)(node)) {
|
|
40
|
+
if ((0, utils_1.isPossibleComponent)(node) && node.tag !== 'Fragment') {
|
|
41
41
|
return this.componentLang.doHover(document, position, html);
|
|
42
42
|
}
|
|
43
43
|
return this.lang.doHover(document, position, html);
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.astroDirectives = exports.astroAttributes = exports.astroElements = exports.classListAttribute = void 0;
|
|
4
4
|
const vscode_html_languageservice_1 = require("vscode-html-languageservice");
|
|
5
|
+
const defaultProvider = (0, vscode_html_languageservice_1.getDefaultHTMLDataProvider)();
|
|
6
|
+
const slotAttr = defaultProvider.provideAttributes('div').find((attr) => attr.name === 'slot');
|
|
5
7
|
exports.classListAttribute = (0, vscode_html_languageservice_1.newHTMLDataProvider)('class-list', {
|
|
6
8
|
version: 1,
|
|
7
9
|
globalAttributes: [
|
|
@@ -169,6 +171,7 @@ exports.astroAttributes = (0, vscode_html_languageservice_1.newHTMLDataProvider)
|
|
|
169
171
|
},
|
|
170
172
|
],
|
|
171
173
|
},
|
|
174
|
+
slotAttr,
|
|
172
175
|
],
|
|
173
176
|
});
|
|
174
177
|
exports.astroDirectives = (0, vscode_html_languageservice_1.newHTMLDataProvider)('astro-directives', {
|
|
@@ -35,6 +35,9 @@ export interface ColorPresentationsProvider {
|
|
|
35
35
|
export interface DocumentSymbolsProvider {
|
|
36
36
|
getDocumentSymbols(document: TextDocument): Resolvable<SymbolInformation[]>;
|
|
37
37
|
}
|
|
38
|
+
export interface FileReferencesProvider {
|
|
39
|
+
fileReferences(document: TextDocument): Promise<Location[] | null>;
|
|
40
|
+
}
|
|
38
41
|
export interface DefinitionsProvider {
|
|
39
42
|
getDefinitions(document: TextDocument, position: Position): Resolvable<DefinitionLink[]>;
|
|
40
43
|
}
|
|
@@ -74,7 +77,10 @@ export interface SemanticTokensProvider {
|
|
|
74
77
|
export interface LinkedEditingRangesProvider {
|
|
75
78
|
getLinkedEditingRanges(document: TextDocument, position: Position): Resolvable<LinkedEditingRanges | null>;
|
|
76
79
|
}
|
|
77
|
-
export interface
|
|
80
|
+
export interface ImplementationProvider {
|
|
81
|
+
getImplementation(document: TextDocument, position: Position): Resolvable<Location[] | null>;
|
|
82
|
+
}
|
|
83
|
+
export interface TypeDefinitionsProvider {
|
|
78
84
|
getTypeDefinitions(document: TextDocument, position: Position): Resolvable<Location[] | null>;
|
|
79
85
|
}
|
|
80
86
|
export interface OnWatchFileChangesParam {
|
|
@@ -82,12 +88,12 @@ export interface OnWatchFileChangesParam {
|
|
|
82
88
|
changeType: FileChangeType;
|
|
83
89
|
}
|
|
84
90
|
export interface OnWatchFileChangesProvider {
|
|
85
|
-
onWatchFileChanges(onWatchFileChangesParams: OnWatchFileChangesParam[]): void
|
|
91
|
+
onWatchFileChanges(onWatchFileChangesParams: OnWatchFileChangesParam[]): Promise<void>;
|
|
86
92
|
}
|
|
87
93
|
export interface UpdateNonAstroFile {
|
|
88
|
-
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[]): void;
|
|
94
|
+
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[], text?: string): void;
|
|
89
95
|
}
|
|
90
|
-
declare type ProviderBase = DiagnosticsProvider & HoverProvider & CompletionsProvider & DefinitionsProvider &
|
|
96
|
+
declare type ProviderBase = DiagnosticsProvider & HoverProvider & CompletionsProvider & FileReferencesProvider & DefinitionsProvider & TypeDefinitionsProvider & ImplementationProvider & FormattingProvider & FoldingRangesProvider & TagCompleteProvider & DocumentColorsProvider & ColorPresentationsProvider & DocumentSymbolsProvider & UpdateImportsProvider & CodeActionsProvider & FindReferencesProvider & RenameProvider & SignatureHelpProvider & SemanticTokensProvider & SelectionRangeProvider & OnWatchFileChangesProvider & LinkedEditingRangesProvider & InlayHintsProvider & UpdateNonAstroFile;
|
|
91
97
|
export declare type LSProvider = ProviderBase;
|
|
92
98
|
export declare type Plugin = Partial<ProviderBase> & {
|
|
93
99
|
__name: string;
|
|
@@ -3,6 +3,7 @@ import type { ConfigManager } from '../../core/config';
|
|
|
3
3
|
import type { AstroDocument, DocumentManager } from '../../core/documents';
|
|
4
4
|
import { LanguageServiceContainer, LanguageServiceDocumentContext } from './language-service';
|
|
5
5
|
import type { DocumentSnapshot } from './snapshots/DocumentSnapshot';
|
|
6
|
+
import { SnapshotManager } from './snapshots/SnapshotManager';
|
|
6
7
|
export declare class LanguageServiceManager {
|
|
7
8
|
private readonly docManager;
|
|
8
9
|
private readonly workspaceUris;
|
|
@@ -31,11 +32,15 @@ export declare class LanguageServiceManager {
|
|
|
31
32
|
/**
|
|
32
33
|
* Updates file in all ts services where it exists
|
|
33
34
|
*/
|
|
34
|
-
updateExistingNonAstroFile(path: string, changes?: TextDocumentContentChangeEvent[]): Promise<void>;
|
|
35
|
+
updateExistingNonAstroFile(path: string, changes?: TextDocumentContentChangeEvent[], text?: string): Promise<void>;
|
|
35
36
|
getLSAndTSDoc(document: AstroDocument): Promise<{
|
|
36
37
|
tsDoc: DocumentSnapshot;
|
|
37
38
|
lang: ts.LanguageService;
|
|
38
39
|
}>;
|
|
39
40
|
getLSForPath(path: string): Promise<import("typescript/lib/tsserverlibrary").LanguageService>;
|
|
40
41
|
getTypeScriptLanguageService(filePath: string): Promise<LanguageServiceContainer>;
|
|
42
|
+
/**
|
|
43
|
+
* @internal Public for tests only
|
|
44
|
+
*/
|
|
45
|
+
getSnapshotManager(filePath: string): Promise<SnapshotManager>;
|
|
41
46
|
}
|
|
@@ -63,7 +63,7 @@ class LanguageServiceManager {
|
|
|
63
63
|
/**
|
|
64
64
|
* Updates file in all ts services where it exists
|
|
65
65
|
*/
|
|
66
|
-
async updateExistingNonAstroFile(path, changes) {
|
|
66
|
+
async updateExistingNonAstroFile(path, changes, text) {
|
|
67
67
|
path = (0, utils_1.normalizePath)(path);
|
|
68
68
|
// Only update once because all snapshots are shared between
|
|
69
69
|
// services. Since we don't have a current version of TS/JS
|
|
@@ -72,7 +72,7 @@ class LanguageServiceManager {
|
|
|
72
72
|
await (0, language_service_1.forAllLanguageServices)((service) => {
|
|
73
73
|
if (service.hasFile(path) && !didUpdate) {
|
|
74
74
|
didUpdate = true;
|
|
75
|
-
service.updateNonAstroFile(path, changes);
|
|
75
|
+
service.updateNonAstroFile(path, changes, text);
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
78
|
}
|
|
@@ -87,5 +87,11 @@ class LanguageServiceManager {
|
|
|
87
87
|
async getTypeScriptLanguageService(filePath) {
|
|
88
88
|
return (0, language_service_1.getLanguageService)(filePath, this.workspaceUris, this.docContext);
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* @internal Public for tests only
|
|
92
|
+
*/
|
|
93
|
+
async getSnapshotManager(filePath) {
|
|
94
|
+
return (await this.getTypeScriptLanguageService(filePath)).snapshotManager;
|
|
95
|
+
}
|
|
90
96
|
}
|
|
91
97
|
exports.LanguageServiceManager = LanguageServiceManager;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CancellationToken, CodeAction, CodeActionContext, CompletionContext, DefinitionLink, Diagnostic, FoldingRange, Hover, InlayHint, Location, Position, Range, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, WorkspaceEdit } from 'vscode-languageserver';
|
|
1
|
+
import { CancellationToken, CodeAction, CodeActionContext, CompletionContext, DefinitionLink, Diagnostic, FoldingRange, Hover, InlayHint, Location, Position, Range, ReferenceContext, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, WorkspaceEdit } from 'vscode-languageserver';
|
|
2
2
|
import type { ConfigManager } from '../../core/config';
|
|
3
3
|
import type { AstroDocument } from '../../core/documents';
|
|
4
4
|
import type { AppCompletionItem, AppCompletionList, OnWatchFileChangesParam, Plugin } from '../interfaces';
|
|
@@ -12,8 +12,11 @@ export declare class TypeScriptPlugin implements Plugin {
|
|
|
12
12
|
private readonly codeActionsProvider;
|
|
13
13
|
private readonly completionProvider;
|
|
14
14
|
private readonly hoverProvider;
|
|
15
|
+
private readonly fileReferencesProvider;
|
|
15
16
|
private readonly definitionsProvider;
|
|
16
17
|
private readonly typeDefinitionsProvider;
|
|
18
|
+
private readonly implementationsProvider;
|
|
19
|
+
private readonly referencesProvider;
|
|
17
20
|
private readonly signatureHelpProvider;
|
|
18
21
|
private readonly diagnosticsProvider;
|
|
19
22
|
private readonly documentSymbolsProvider;
|
|
@@ -31,12 +34,19 @@ export declare class TypeScriptPlugin implements Plugin {
|
|
|
31
34
|
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext, cancellationToken?: CancellationToken): Promise<AppCompletionList<CompletionItemData> | null>;
|
|
32
35
|
resolveCompletion(document: AstroDocument, completionItem: AppCompletionItem<CompletionItemData>, cancellationToken?: CancellationToken): Promise<AppCompletionItem<CompletionItemData>>;
|
|
33
36
|
getInlayHints(document: AstroDocument, range: Range): Promise<InlayHint[]>;
|
|
37
|
+
fileReferences(document: AstroDocument): Promise<Location[] | null>;
|
|
34
38
|
getDefinitions(document: AstroDocument, position: Position): Promise<DefinitionLink[]>;
|
|
35
|
-
|
|
39
|
+
getTypeDefinitions(document: AstroDocument, position: Position): Promise<Location[] | null>;
|
|
40
|
+
getImplementation(document: AstroDocument, position: Position): Promise<Location[] | null>;
|
|
41
|
+
findReferences(document: AstroDocument, position: Position, context: ReferenceContext): Promise<Location[] | null>;
|
|
36
42
|
getDiagnostics(document: AstroDocument, cancellationToken?: CancellationToken): Promise<Diagnostic[]>;
|
|
37
43
|
onWatchFileChanges(onWatchFileChangesParas: OnWatchFileChangesParam[]): Promise<void>;
|
|
38
|
-
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[]): Promise<void>;
|
|
44
|
+
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[], text?: string): Promise<void>;
|
|
39
45
|
getSignatureHelp(document: AstroDocument, position: Position, context: SignatureHelpContext | undefined, cancellationToken?: CancellationToken): Promise<SignatureHelp | null>;
|
|
40
46
|
getTSXForDocument(document: AstroDocument): Astro2TSXResult;
|
|
47
|
+
/**
|
|
48
|
+
* @internal Public for tests only
|
|
49
|
+
*/
|
|
50
|
+
getSnapshotManager(fileName: string): Promise<import("./snapshots/SnapshotManager").SnapshotManager>;
|
|
41
51
|
private featureEnabled;
|
|
42
52
|
}
|
|
@@ -11,9 +11,12 @@ const CompletionsProvider_1 = require("./features/CompletionsProvider");
|
|
|
11
11
|
const DefinitionsProvider_1 = require("./features/DefinitionsProvider");
|
|
12
12
|
const DiagnosticsProvider_1 = require("./features/DiagnosticsProvider");
|
|
13
13
|
const DocumentSymbolsProvider_1 = require("./features/DocumentSymbolsProvider");
|
|
14
|
+
const FileReferencesProvider_1 = require("./features/FileReferencesProvider");
|
|
14
15
|
const FoldingRangesProvider_1 = require("./features/FoldingRangesProvider");
|
|
15
16
|
const HoverProvider_1 = require("./features/HoverProvider");
|
|
17
|
+
const ImplementationsProvider_1 = require("./features/ImplementationsProvider");
|
|
16
18
|
const InlayHintsProvider_1 = require("./features/InlayHintsProvider");
|
|
19
|
+
const ReferencesProvider_1 = require("./features/ReferencesProvider");
|
|
17
20
|
const SemanticTokenProvider_1 = require("./features/SemanticTokenProvider");
|
|
18
21
|
const SignatureHelpProvider_1 = require("./features/SignatureHelpProvider");
|
|
19
22
|
const TypeDefinitionsProvider_1 = require("./features/TypeDefinitionsProvider");
|
|
@@ -28,8 +31,11 @@ class TypeScriptPlugin {
|
|
|
28
31
|
this.codeActionsProvider = new CodeActionsProvider_1.CodeActionsProviderImpl(this.languageServiceManager, this.configManager);
|
|
29
32
|
this.completionProvider = new CompletionsProvider_1.CompletionsProviderImpl(this.languageServiceManager, this.configManager);
|
|
30
33
|
this.hoverProvider = new HoverProvider_1.HoverProviderImpl(this.languageServiceManager);
|
|
34
|
+
this.fileReferencesProvider = new FileReferencesProvider_1.FileReferencesProviderImpl(this.languageServiceManager);
|
|
31
35
|
this.definitionsProvider = new DefinitionsProvider_1.DefinitionsProviderImpl(this.languageServiceManager);
|
|
32
36
|
this.typeDefinitionsProvider = new TypeDefinitionsProvider_1.TypeDefinitionsProviderImpl(this.languageServiceManager);
|
|
37
|
+
this.implementationsProvider = new ImplementationsProvider_1.ImplementationsProviderImpl(this.languageServiceManager);
|
|
38
|
+
this.referencesProvider = new ReferencesProvider_1.FindReferencesProviderImpl(this.languageServiceManager);
|
|
33
39
|
this.signatureHelpProvider = new SignatureHelpProvider_1.SignatureHelpProviderImpl(this.languageServiceManager);
|
|
34
40
|
this.diagnosticsProvider = new DiagnosticsProvider_1.DiagnosticsProviderImpl(this.languageServiceManager);
|
|
35
41
|
this.documentSymbolsProvider = new DocumentSymbolsProvider_1.DocumentSymbolsProviderImpl(this.languageServiceManager);
|
|
@@ -101,12 +107,21 @@ class TypeScriptPlugin {
|
|
|
101
107
|
async getInlayHints(document, range) {
|
|
102
108
|
return this.inlayHintsProvider.getInlayHints(document, range);
|
|
103
109
|
}
|
|
110
|
+
async fileReferences(document) {
|
|
111
|
+
return this.fileReferencesProvider.fileReferences(document);
|
|
112
|
+
}
|
|
104
113
|
async getDefinitions(document, position) {
|
|
105
114
|
return this.definitionsProvider.getDefinitions(document, position);
|
|
106
115
|
}
|
|
107
|
-
async
|
|
116
|
+
async getTypeDefinitions(document, position) {
|
|
108
117
|
return this.typeDefinitionsProvider.getTypeDefinitions(document, position);
|
|
109
118
|
}
|
|
119
|
+
async getImplementation(document, position) {
|
|
120
|
+
return this.implementationsProvider.getImplementation(document, position);
|
|
121
|
+
}
|
|
122
|
+
async findReferences(document, position, context) {
|
|
123
|
+
return this.referencesProvider.findReferences(document, position, context);
|
|
124
|
+
}
|
|
110
125
|
async getDiagnostics(document, cancellationToken) {
|
|
111
126
|
if (!(await this.featureEnabled(document, 'diagnostics'))) {
|
|
112
127
|
return [];
|
|
@@ -117,7 +132,7 @@ class TypeScriptPlugin {
|
|
|
117
132
|
let doneUpdateProjectFiles = false;
|
|
118
133
|
for (const { fileName, changeType } of onWatchFileChangesParas) {
|
|
119
134
|
const scriptKind = (0, utils_2.getScriptKindFromFileName)(fileName, this.ts);
|
|
120
|
-
if (scriptKind === this.ts.ScriptKind.Unknown) {
|
|
135
|
+
if (scriptKind === this.ts.ScriptKind.Unknown && !(0, utils_2.isFrameworkFilePath)(fileName) && !(0, utils_2.isAstroFilePath)(fileName)) {
|
|
121
136
|
continue;
|
|
122
137
|
}
|
|
123
138
|
if (changeType === vscode_languageserver_1.FileChangeType.Created && !doneUpdateProjectFiles) {
|
|
@@ -127,13 +142,14 @@ class TypeScriptPlugin {
|
|
|
127
142
|
else if (changeType === vscode_languageserver_1.FileChangeType.Deleted) {
|
|
128
143
|
await this.languageServiceManager.deleteSnapshot(fileName);
|
|
129
144
|
}
|
|
130
|
-
else {
|
|
145
|
+
else if (!(0, utils_2.isAstroFilePath)(fileName)) {
|
|
146
|
+
// Content updates for Astro files are handled through the documentManager and the 'documentChange' event
|
|
131
147
|
await this.languageServiceManager.updateExistingNonAstroFile(fileName);
|
|
132
148
|
}
|
|
133
149
|
}
|
|
134
150
|
}
|
|
135
|
-
async updateNonAstroFile(fileName, changes) {
|
|
136
|
-
await this.languageServiceManager.updateExistingNonAstroFile(fileName, changes);
|
|
151
|
+
async updateNonAstroFile(fileName, changes, text) {
|
|
152
|
+
await this.languageServiceManager.updateExistingNonAstroFile(fileName, changes, text);
|
|
137
153
|
}
|
|
138
154
|
async getSignatureHelp(document, position, context, cancellationToken) {
|
|
139
155
|
return this.signatureHelpProvider.getSignatureHelp(document, position, context, cancellationToken);
|
|
@@ -141,6 +157,12 @@ class TypeScriptPlugin {
|
|
|
141
157
|
getTSXForDocument(document) {
|
|
142
158
|
return (0, astro2tsx_1.default)(document.getText(), (0, utils_1.classNameFromFilename)(document.getURL()));
|
|
143
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* @internal Public for tests only
|
|
162
|
+
*/
|
|
163
|
+
getSnapshotManager(fileName) {
|
|
164
|
+
return this.languageServiceManager.getSnapshotManager(fileName);
|
|
165
|
+
}
|
|
144
166
|
async featureEnabled(document, feature) {
|
|
145
167
|
return ((await this.configManager.isEnabled(document, 'typescript')) &&
|
|
146
168
|
(await this.configManager.isEnabled(document, 'typescript', feature)));
|
|
@@ -20,7 +20,7 @@ function createAstroSys(getSnapshot, ts) {
|
|
|
20
20
|
return snapshot.getText(0, snapshot.getLength());
|
|
21
21
|
},
|
|
22
22
|
readDirectory(path, extensions, exclude, include, depth) {
|
|
23
|
-
const extensionsWithAstro = (extensions ?? []).concat(...['.astro', '.svelte', '.vue']);
|
|
23
|
+
const extensionsWithAstro = (extensions ?? []).concat(...['.astro', '.svelte', '.vue', '.md', '.mdx', '.html']);
|
|
24
24
|
const result = ts.sys.readDirectory(path, extensionsWithAstro, exclude, include, depth);
|
|
25
25
|
return result;
|
|
26
26
|
},
|
|
@@ -166,7 +166,8 @@ class CodeActionsProviderImpl {
|
|
|
166
166
|
// Since our last line is a (virtual) export, organize imports will try to rewrite it, so let's only take
|
|
167
167
|
// changes that actually happens inside the script tag
|
|
168
168
|
.filter((change) => {
|
|
169
|
-
return scriptTagSnapshot.isInGenerated(document.positionAt(change.span.start))
|
|
169
|
+
return (scriptTagSnapshot.isInGenerated(document.positionAt(change.span.start)) &&
|
|
170
|
+
!change.newText.includes('export { }'));
|
|
170
171
|
});
|
|
171
172
|
return edit;
|
|
172
173
|
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Location } from 'vscode-languageserver';
|
|
2
|
+
import { AstroDocument } from '../../../core/documents';
|
|
3
|
+
import { FileReferencesProvider } from '../../interfaces';
|
|
4
|
+
import { LanguageServiceManager } from '../LanguageServiceManager';
|
|
5
|
+
export declare class FileReferencesProviderImpl implements FileReferencesProvider {
|
|
6
|
+
private languageServiceManager;
|
|
7
|
+
constructor(languageServiceManager: LanguageServiceManager);
|
|
8
|
+
fileReferences(document: AstroDocument): Promise<Location[] | null>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FileReferencesProviderImpl = void 0;
|
|
4
|
+
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
5
|
+
const utils_1 = require("../../../utils");
|
|
6
|
+
const utils_2 = require("../utils");
|
|
7
|
+
const utils_3 = require("./utils");
|
|
8
|
+
class FileReferencesProviderImpl {
|
|
9
|
+
constructor(languageServiceManager) {
|
|
10
|
+
this.languageServiceManager = languageServiceManager;
|
|
11
|
+
}
|
|
12
|
+
async fileReferences(document) {
|
|
13
|
+
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
14
|
+
const mainFragment = await tsDoc.createFragment();
|
|
15
|
+
const references = lang.getFileReferences(tsDoc.filePath);
|
|
16
|
+
if (!references) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const docs = new utils_3.SnapshotFragmentMap(this.languageServiceManager);
|
|
20
|
+
docs.set(tsDoc.filePath, { fragment: mainFragment, snapshot: tsDoc });
|
|
21
|
+
const locations = await Promise.all(references.map(async (ref) => {
|
|
22
|
+
const defDoc = await docs.retrieveFragment(ref.fileName);
|
|
23
|
+
return vscode_languageserver_1.Location.create((0, utils_1.pathToUrl)(ref.fileName), (0, utils_2.convertToLocationRange)(defDoc, ref.textSpan));
|
|
24
|
+
}));
|
|
25
|
+
return locations;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.FileReferencesProviderImpl = FileReferencesProviderImpl;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Location, Position } from 'vscode-languageserver-types';
|
|
2
|
+
import { AstroDocument } from '../../../core/documents';
|
|
3
|
+
import { ImplementationProvider } from '../../interfaces';
|
|
4
|
+
import { LanguageServiceManager } from '../LanguageServiceManager';
|
|
5
|
+
export declare class ImplementationsProviderImpl implements ImplementationProvider {
|
|
6
|
+
private languageServiceManager;
|
|
7
|
+
constructor(languageServiceManager: LanguageServiceManager);
|
|
8
|
+
getImplementation(document: AstroDocument, position: Position): Promise<Location[] | null>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ImplementationsProviderImpl = void 0;
|
|
4
|
+
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
|
5
|
+
const documents_1 = require("../../../core/documents");
|
|
6
|
+
const utils_1 = require("../../../utils");
|
|
7
|
+
const utils_2 = require("../utils");
|
|
8
|
+
const utils_3 = require("./utils");
|
|
9
|
+
class ImplementationsProviderImpl {
|
|
10
|
+
constructor(languageServiceManager) {
|
|
11
|
+
this.languageServiceManager = languageServiceManager;
|
|
12
|
+
}
|
|
13
|
+
async getImplementation(document, position) {
|
|
14
|
+
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
15
|
+
const mainFragment = await tsDoc.createFragment();
|
|
16
|
+
const offset = mainFragment.offsetAt(mainFragment.getGeneratedPosition(position));
|
|
17
|
+
const node = document.html.findNodeAt(offset);
|
|
18
|
+
let implementations;
|
|
19
|
+
if (node.tag === 'script') {
|
|
20
|
+
const { snapshot: scriptTagSnapshot, filePath: scriptFilePath, offset: scriptOffset, } = (0, utils_2.getScriptTagSnapshot)(tsDoc, document, node, position);
|
|
21
|
+
implementations = lang.getImplementationAtPosition(scriptFilePath, scriptOffset);
|
|
22
|
+
if (implementations) {
|
|
23
|
+
implementations = implementations.map((impl) => {
|
|
24
|
+
const isInSameFile = impl.fileName === scriptFilePath;
|
|
25
|
+
impl.fileName = isInSameFile ? tsDoc.filePath : impl.fileName;
|
|
26
|
+
if (isInSameFile) {
|
|
27
|
+
impl.textSpan.start = mainFragment.offsetAt(scriptTagSnapshot.getOriginalPosition(scriptTagSnapshot.positionAt(impl.textSpan.start)));
|
|
28
|
+
}
|
|
29
|
+
return impl;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
implementations = lang.getImplementationAtPosition(tsDoc.filePath, offset);
|
|
35
|
+
}
|
|
36
|
+
const docs = new utils_3.SnapshotFragmentMap(this.languageServiceManager);
|
|
37
|
+
docs.set(tsDoc.filePath, { fragment: mainFragment, snapshot: tsDoc });
|
|
38
|
+
if (!implementations) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const result = await Promise.all(implementations.map(async (implementation) => {
|
|
42
|
+
const { fragment } = await docs.retrieve(implementation.fileName);
|
|
43
|
+
const range = (0, documents_1.mapRangeToOriginal)(fragment, (0, utils_2.convertRange)(fragment, implementation.textSpan));
|
|
44
|
+
if (range.start.line >= 0 && range.end.line >= 0) {
|
|
45
|
+
return vscode_languageserver_types_1.Location.create((0, utils_1.pathToUrl)(implementation.fileName), range);
|
|
46
|
+
}
|
|
47
|
+
}));
|
|
48
|
+
return result.filter(utils_1.isNotNullOrUndefined);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.ImplementationsProviderImpl = ImplementationsProviderImpl;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Location, Position, ReferenceContext } from 'vscode-languageserver-types';
|
|
2
|
+
import { AstroDocument } from '../../../core/documents';
|
|
3
|
+
import type { FindReferencesProvider } from '../../interfaces';
|
|
4
|
+
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
|
5
|
+
export declare class FindReferencesProviderImpl implements FindReferencesProvider {
|
|
6
|
+
private languageServiceManager;
|
|
7
|
+
constructor(languageServiceManager: LanguageServiceManager);
|
|
8
|
+
findReferences(document: AstroDocument, position: Position, context: ReferenceContext): Promise<Location[] | null>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FindReferencesProviderImpl = void 0;
|
|
4
|
+
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
|
5
|
+
const documents_1 = require("../../../core/documents");
|
|
6
|
+
const utils_1 = require("../../../utils");
|
|
7
|
+
const utils_2 = require("../utils");
|
|
8
|
+
const utils_3 = require("./utils");
|
|
9
|
+
class FindReferencesProviderImpl {
|
|
10
|
+
constructor(languageServiceManager) {
|
|
11
|
+
this.languageServiceManager = languageServiceManager;
|
|
12
|
+
}
|
|
13
|
+
async findReferences(document, position, context) {
|
|
14
|
+
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
15
|
+
const mainFragment = await tsDoc.createFragment();
|
|
16
|
+
const offset = mainFragment.offsetAt(mainFragment.getGeneratedPosition(position));
|
|
17
|
+
const node = document.html.findNodeAt(offset);
|
|
18
|
+
let references;
|
|
19
|
+
if (node.tag === 'script') {
|
|
20
|
+
const { snapshot: scriptTagSnapshot, filePath: scriptFilePath, offset: scriptOffset, } = (0, utils_2.getScriptTagSnapshot)(tsDoc, document, node, position);
|
|
21
|
+
references = lang.getReferencesAtPosition(scriptFilePath, scriptOffset);
|
|
22
|
+
if (references) {
|
|
23
|
+
references = references.map((ref) => {
|
|
24
|
+
const isInSameFile = ref.fileName === scriptFilePath;
|
|
25
|
+
ref.fileName = isInSameFile ? tsDoc.filePath : ref.fileName;
|
|
26
|
+
if (isInSameFile) {
|
|
27
|
+
ref.textSpan.start = mainFragment.offsetAt(scriptTagSnapshot.getOriginalPosition(scriptTagSnapshot.positionAt(ref.textSpan.start)));
|
|
28
|
+
}
|
|
29
|
+
return ref;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
references = lang.getReferencesAtPosition(tsDoc.filePath, offset);
|
|
35
|
+
}
|
|
36
|
+
if (!references) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const docs = new utils_3.SnapshotFragmentMap(this.languageServiceManager);
|
|
40
|
+
docs.set(tsDoc.filePath, { fragment: mainFragment, snapshot: tsDoc });
|
|
41
|
+
const result = await Promise.all(references.map(async (reference) => {
|
|
42
|
+
if (!context.includeDeclaration) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const { fragment } = await docs.retrieve(reference.fileName);
|
|
46
|
+
const range = (0, documents_1.mapRangeToOriginal)(fragment, (0, utils_2.convertRange)(fragment, reference.textSpan));
|
|
47
|
+
if (range.start.line >= 0 && range.end.line >= 0) {
|
|
48
|
+
return vscode_languageserver_types_1.Location.create((0, utils_1.pathToUrl)(reference.fileName), range);
|
|
49
|
+
}
|
|
50
|
+
}));
|
|
51
|
+
return result.filter(utils_1.isNotNullOrUndefined);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.FindReferencesProviderImpl = FindReferencesProviderImpl;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Location, Position } from 'vscode-languageserver-protocol';
|
|
2
2
|
import { AstroDocument } from '../../../core/documents';
|
|
3
|
-
import type {
|
|
3
|
+
import type { TypeDefinitionsProvider } from '../../interfaces';
|
|
4
4
|
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
|
5
|
-
export declare class TypeDefinitionsProviderImpl implements
|
|
5
|
+
export declare class TypeDefinitionsProviderImpl implements TypeDefinitionsProvider {
|
|
6
6
|
private languageServiceManager;
|
|
7
7
|
constructor(languageServiceManager: LanguageServiceManager);
|
|
8
8
|
getTypeDefinitions(document: AstroDocument, position: Position): Promise<Location[]>;
|
|
@@ -14,7 +14,7 @@ export interface LanguageServiceContainer {
|
|
|
14
14
|
updateSnapshot(documentOrFilePath: AstroDocument | string, ts: typeof import('typescript/lib/tsserverlibrary')): DocumentSnapshot;
|
|
15
15
|
deleteSnapshot(filePath: string): void;
|
|
16
16
|
updateProjectFiles(): void;
|
|
17
|
-
updateNonAstroFile(fileName: string, changes?: TextDocumentContentChangeEvent[]): void;
|
|
17
|
+
updateNonAstroFile(fileName: string, changes?: TextDocumentContentChangeEvent[], text?: string): void;
|
|
18
18
|
/**
|
|
19
19
|
* Checks if a file is present in the project.
|
|
20
20
|
* Unlike `fileBelongsToProject`, this doesn't run a file search on disk.
|
|
@@ -214,11 +214,11 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
|
|
|
214
214
|
filePath = (0, utils_1.normalizePath)(filePath);
|
|
215
215
|
return hasFile(filePath) || getParsedTSConfig().fileNames.includes(filePath);
|
|
216
216
|
}
|
|
217
|
-
function updateNonAstroFile(fileName, changes) {
|
|
217
|
+
function updateNonAstroFile(fileName, changes, text) {
|
|
218
218
|
if (!snapshotManager.has(fileName)) {
|
|
219
219
|
astroModuleLoader.deleteUnresolvedResolutionsFromCache(fileName);
|
|
220
220
|
}
|
|
221
|
-
snapshotManager.updateNonAstroFile(fileName, changes);
|
|
221
|
+
snapshotManager.updateNonAstroFile(fileName, changes, text);
|
|
222
222
|
}
|
|
223
223
|
function createScriptTagsSnapshots(fileName, document) {
|
|
224
224
|
return document.scriptTags.map((scriptTag, index) => {
|
|
@@ -229,7 +229,7 @@ async function createLanguageService(tsconfigPath, docContext, workspaceUris) {
|
|
|
229
229
|
});
|
|
230
230
|
}
|
|
231
231
|
function createDocumentSymbolSnapshot(doc) {
|
|
232
|
-
return new DocumentSnapshot_1.TypeScriptDocumentSnapshot(doc.version, doc.filePath, doc.parent.getText(), docContext.ts.ScriptKind.Unknown);
|
|
232
|
+
return new DocumentSnapshot_1.TypeScriptDocumentSnapshot(doc.version, doc.filePath, doc.parent.getText(), docContext.ts.ScriptKind.Unknown, false);
|
|
233
233
|
}
|
|
234
234
|
function getParsedTSConfig() {
|
|
235
235
|
let configJson = (tsconfigPath && docContext.ts.readConfigFile(tsconfigPath, docContext.ts.sys.readFile).config) || {};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Position, TextDocumentContentChangeEvent } from 'vscode-languageserver';
|
|
2
2
|
import { AstroDocument, DocumentMapper, FragmentMapper, IdentityMapper, TagInformation } from '../../../core/documents';
|
|
3
|
-
import type { FrameworkExt } from '../utils';
|
|
4
3
|
export interface DocumentSnapshot extends ts.IScriptSnapshot {
|
|
5
4
|
version: number;
|
|
6
5
|
filePath: string;
|
|
@@ -92,10 +91,10 @@ export declare class TypeScriptDocumentSnapshot extends IdentityMapper implement
|
|
|
92
91
|
version: number;
|
|
93
92
|
readonly filePath: string;
|
|
94
93
|
private text;
|
|
95
|
-
readonly
|
|
94
|
+
readonly supportPartialUpdate: boolean;
|
|
96
95
|
scriptKind: ts.ScriptKind;
|
|
97
96
|
private lineOffsets?;
|
|
98
|
-
constructor(version: number, filePath: string, text: string, scriptKind: ts.ScriptKind,
|
|
97
|
+
constructor(version: number, filePath: string, text: string, scriptKind: ts.ScriptKind, supportPartialUpdate: boolean);
|
|
99
98
|
getText(start: number, end: number): string;
|
|
100
99
|
getLength(): number;
|
|
101
100
|
getFullText(): string;
|
|
@@ -119,12 +119,12 @@ exports.ScriptTagDocumentSnapshot = ScriptTagDocumentSnapshot;
|
|
|
119
119
|
* It's both used for .js(x)/.ts(x) files and .svelte/.vue files
|
|
120
120
|
*/
|
|
121
121
|
class TypeScriptDocumentSnapshot extends documents_1.IdentityMapper {
|
|
122
|
-
constructor(version, filePath, text, scriptKind,
|
|
122
|
+
constructor(version, filePath, text, scriptKind, supportPartialUpdate) {
|
|
123
123
|
super((0, utils_1.pathToUrl)(filePath));
|
|
124
124
|
this.version = version;
|
|
125
125
|
this.filePath = filePath;
|
|
126
126
|
this.text = text;
|
|
127
|
-
this.
|
|
127
|
+
this.supportPartialUpdate = supportPartialUpdate;
|
|
128
128
|
this.scriptKind = scriptKind;
|
|
129
129
|
}
|
|
130
130
|
getText(start, end) {
|
|
@@ -13,7 +13,7 @@ export declare class GlobalSnapshotManager {
|
|
|
13
13
|
get(fileName: string): DocumentSnapshot | undefined;
|
|
14
14
|
set(fileName: string, document: DocumentSnapshot): void;
|
|
15
15
|
delete(fileName: string): void;
|
|
16
|
-
updateNonAstroFile(fileName: string, changes?: TextDocumentContentChangeEvent[]): TypeScriptDocumentSnapshot | undefined;
|
|
16
|
+
updateNonAstroFile(fileName: string, changes?: TextDocumentContentChangeEvent[], newText?: string): TypeScriptDocumentSnapshot | undefined;
|
|
17
17
|
onChange(listener: (fileName: string, newDocument: DocumentSnapshot | undefined) => void): void;
|
|
18
18
|
}
|
|
19
19
|
export interface TsFilesSpec {
|
|
@@ -31,10 +31,9 @@ export declare class SnapshotManager {
|
|
|
31
31
|
private ts;
|
|
32
32
|
private documents;
|
|
33
33
|
private lastLogged;
|
|
34
|
-
private readonly watchExtensions;
|
|
35
34
|
constructor(globalSnapshotsManager: GlobalSnapshotManager, projectFiles: string[], fileSpec: TsFilesSpec, workspaceRoot: string, ts: typeof import('typescript/lib/tsserverlibrary'));
|
|
36
35
|
updateProjectFiles(): void;
|
|
37
|
-
updateNonAstroFile(fileName: string, changes?: TextDocumentContentChangeEvent[]): void;
|
|
36
|
+
updateNonAstroFile(fileName: string, changes?: TextDocumentContentChangeEvent[], text?: string): void;
|
|
38
37
|
has(fileName: string): boolean;
|
|
39
38
|
set(fileName: string, snapshot: DocumentSnapshot): void;
|
|
40
39
|
get(fileName: string): DocumentSnapshot | undefined;
|
|
@@ -26,7 +26,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.SnapshotManager = exports.GlobalSnapshotManager = void 0;
|
|
27
27
|
const events_1 = require("events");
|
|
28
28
|
const utils_1 = require("../../../utils");
|
|
29
|
-
const utils_2 = require("../utils");
|
|
30
29
|
const DocumentSnapshot_1 = require("./DocumentSnapshot");
|
|
31
30
|
const DocumentSnapshotUtils = __importStar(require("./utils"));
|
|
32
31
|
/**
|
|
@@ -58,20 +57,17 @@ class GlobalSnapshotManager {
|
|
|
58
57
|
this.documents.delete(fileName);
|
|
59
58
|
this.emitter.emit('change', fileName, undefined);
|
|
60
59
|
}
|
|
61
|
-
updateNonAstroFile(fileName, changes) {
|
|
60
|
+
updateNonAstroFile(fileName, changes, newText) {
|
|
62
61
|
fileName = (0, utils_1.normalizePath)(fileName);
|
|
63
62
|
const previousSnapshot = this.get(fileName);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (!(previousSnapshot instanceof DocumentSnapshot_1.TypeScriptDocumentSnapshot) || previousSnapshot.framework) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
63
|
+
const canBePartiallyUpdated = changes && previousSnapshot instanceof DocumentSnapshot_1.TypeScriptDocumentSnapshot && previousSnapshot.supportPartialUpdate;
|
|
64
|
+
if (canBePartiallyUpdated) {
|
|
69
65
|
previousSnapshot.update(changes);
|
|
70
66
|
this.emitter.emit('change', fileName, previousSnapshot);
|
|
71
67
|
return previousSnapshot;
|
|
72
68
|
}
|
|
73
69
|
else {
|
|
74
|
-
const newSnapshot = DocumentSnapshotUtils.createFromNonAstroFilePath(fileName, this.ts);
|
|
70
|
+
const newSnapshot = DocumentSnapshotUtils.createFromNonAstroFilePath(fileName, this.ts, newText);
|
|
75
71
|
if (previousSnapshot) {
|
|
76
72
|
newSnapshot.version = previousSnapshot.version + 1;
|
|
77
73
|
}
|
|
@@ -81,6 +77,7 @@ class GlobalSnapshotManager {
|
|
|
81
77
|
newSnapshot.version += 1;
|
|
82
78
|
}
|
|
83
79
|
this.set(fileName, newSnapshot);
|
|
80
|
+
this.emitter.emit('change', fileName, newSnapshot);
|
|
84
81
|
return newSnapshot;
|
|
85
82
|
}
|
|
86
83
|
}
|
|
@@ -101,14 +98,6 @@ class SnapshotManager {
|
|
|
101
98
|
this.ts = ts;
|
|
102
99
|
this.documents = new Map();
|
|
103
100
|
this.lastLogged = new Date(new Date().getTime() - 60001);
|
|
104
|
-
this.watchExtensions = [
|
|
105
|
-
this.ts.Extension.Dts,
|
|
106
|
-
this.ts.Extension.Js,
|
|
107
|
-
this.ts.Extension.Jsx,
|
|
108
|
-
this.ts.Extension.Ts,
|
|
109
|
-
this.ts.Extension.Tsx,
|
|
110
|
-
this.ts.Extension.Json,
|
|
111
|
-
];
|
|
112
101
|
this.globalSnapshotsManager.onChange((fileName, document) => {
|
|
113
102
|
// Only delete/update snapshots, don't add new ones,
|
|
114
103
|
// as they could be from another TS service and this
|
|
@@ -131,12 +120,12 @@ class SnapshotManager {
|
|
|
131
120
|
return;
|
|
132
121
|
}
|
|
133
122
|
const projectFiles = this.ts.sys
|
|
134
|
-
.readDirectory(this.workspaceRoot, this.
|
|
123
|
+
.readDirectory(this.workspaceRoot, [...Object.values(this.ts.Extension), '.astro', '.svelte', '.vue'], exclude, include)
|
|
135
124
|
.map(utils_1.normalizePath);
|
|
136
125
|
this.projectFiles = Array.from(new Set([...this.projectFiles, ...projectFiles]));
|
|
137
126
|
}
|
|
138
|
-
updateNonAstroFile(fileName, changes) {
|
|
139
|
-
const snapshot = this.globalSnapshotsManager.updateNonAstroFile(fileName, changes);
|
|
127
|
+
updateNonAstroFile(fileName, changes, text) {
|
|
128
|
+
const snapshot = this.globalSnapshotsManager.updateNonAstroFile(fileName, changes, text);
|
|
140
129
|
// This isn't duplicated logic to the listener, because this could
|
|
141
130
|
// be a new snapshot which the listener wouldn't add.
|
|
142
131
|
if (snapshot) {
|
|
@@ -181,8 +170,7 @@ class SnapshotManager {
|
|
|
181
170
|
if (date.getTime() - this.lastLogged.getTime() > 60000) {
|
|
182
171
|
this.lastLogged = date;
|
|
183
172
|
const projectFiles = this.getProjectFileNames();
|
|
184
|
-
|
|
185
|
-
allFiles = allFiles.map((file) => (0, utils_2.ensureRealFilePath)(file));
|
|
173
|
+
const allFiles = Array.from(new Set([...projectFiles, ...this.getFileNames()]));
|
|
186
174
|
// eslint-disable-next-line no-console
|
|
187
175
|
console.log('SnapshotManager File Statistics:\n' +
|
|
188
176
|
`Project files: ${projectFiles.length}\n` +
|
|
@@ -12,18 +12,18 @@ export declare function createFromFilePath(filePath: string, createDocument: (fi
|
|
|
12
12
|
* Return a Framework or a TS snapshot from a file path, depending on the file contents
|
|
13
13
|
* Unlike createFromFilePath, this does not support creating an Astro snapshot
|
|
14
14
|
*/
|
|
15
|
-
export declare function createFromNonAstroFilePath(filePath: string, ts: typeof import('typescript/lib/tsserverlibrary')): TypeScriptDocumentSnapshot;
|
|
15
|
+
export declare function createFromNonAstroFilePath(filePath: string, ts: typeof import('typescript/lib/tsserverlibrary'), forceText?: string): TypeScriptDocumentSnapshot;
|
|
16
16
|
/**
|
|
17
17
|
* Returns a ts/js snapshot from a file path.
|
|
18
18
|
* @param filePath path to the js/ts file
|
|
19
19
|
* @param options options that apply in case it's a svelte file
|
|
20
20
|
*/
|
|
21
|
-
export declare function createFromTSFilePath(filePath: string, ts: typeof import('typescript/lib/tsserverlibrary')): TypeScriptDocumentSnapshot;
|
|
21
|
+
export declare function createFromTSFilePath(filePath: string, ts: typeof import('typescript/lib/tsserverlibrary'), forceText?: string): TypeScriptDocumentSnapshot;
|
|
22
22
|
/**
|
|
23
23
|
* Returns an Astro snapshot from a file path.
|
|
24
24
|
* @param filePath path to the Astro file
|
|
25
25
|
* @param createDocument function that is used to create a document
|
|
26
26
|
*/
|
|
27
27
|
export declare function createFromAstroFilePath(filePath: string, createDocument: (filePath: string, text: string) => AstroDocument, ts: typeof import('typescript/lib/tsserverlibrary')): AstroSnapshot;
|
|
28
|
-
export declare function createFromFrameworkFilePath(filePath: string, framework: FrameworkExt, ts: typeof import('typescript/lib/tsserverlibrary')): TypeScriptDocumentSnapshot;
|
|
28
|
+
export declare function createFromFrameworkFilePath(filePath: string, framework: FrameworkExt, ts: typeof import('typescript/lib/tsserverlibrary'), forceText?: string): TypeScriptDocumentSnapshot;
|
|
29
29
|
export declare function classNameFromFilename(filename: string): string;
|
|
@@ -38,13 +38,13 @@ exports.createFromFilePath = createFromFilePath;
|
|
|
38
38
|
* Return a Framework or a TS snapshot from a file path, depending on the file contents
|
|
39
39
|
* Unlike createFromFilePath, this does not support creating an Astro snapshot
|
|
40
40
|
*/
|
|
41
|
-
function createFromNonAstroFilePath(filePath, ts) {
|
|
41
|
+
function createFromNonAstroFilePath(filePath, ts, forceText) {
|
|
42
42
|
if ((0, utils_2.isFrameworkFilePath)(filePath)) {
|
|
43
43
|
const framework = (0, utils_2.getFrameworkFromFilePath)(filePath);
|
|
44
|
-
return createFromFrameworkFilePath(filePath, framework, ts);
|
|
44
|
+
return createFromFrameworkFilePath(filePath, framework, ts, forceText);
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
47
|
-
return createFromTSFilePath(filePath, ts);
|
|
47
|
+
return createFromTSFilePath(filePath, ts, forceText);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
exports.createFromNonAstroFilePath = createFromNonAstroFilePath;
|
|
@@ -53,9 +53,9 @@ exports.createFromNonAstroFilePath = createFromNonAstroFilePath;
|
|
|
53
53
|
* @param filePath path to the js/ts file
|
|
54
54
|
* @param options options that apply in case it's a svelte file
|
|
55
55
|
*/
|
|
56
|
-
function createFromTSFilePath(filePath, ts) {
|
|
57
|
-
const originalText = ts.sys.readFile(filePath) ?? '';
|
|
58
|
-
return new DocumentSnapshot_1.TypeScriptDocumentSnapshot(0, filePath, originalText, (0, utils_2.getScriptKindFromFileName)(filePath, ts));
|
|
56
|
+
function createFromTSFilePath(filePath, ts, forceText) {
|
|
57
|
+
const originalText = forceText ?? ts.sys.readFile(filePath) ?? '';
|
|
58
|
+
return new DocumentSnapshot_1.TypeScriptDocumentSnapshot(0, filePath, originalText, (0, utils_2.getScriptKindFromFileName)(filePath, ts), true);
|
|
59
59
|
}
|
|
60
60
|
exports.createFromTSFilePath = createFromTSFilePath;
|
|
61
61
|
/**
|
|
@@ -68,9 +68,9 @@ function createFromAstroFilePath(filePath, createDocument, ts) {
|
|
|
68
68
|
return createFromDocument(createDocument(filePath, originalText), ts);
|
|
69
69
|
}
|
|
70
70
|
exports.createFromAstroFilePath = createFromAstroFilePath;
|
|
71
|
-
function createFromFrameworkFilePath(filePath, framework, ts) {
|
|
71
|
+
function createFromFrameworkFilePath(filePath, framework, ts, forceText) {
|
|
72
72
|
const className = classNameFromFilename(filePath);
|
|
73
|
-
const originalText = ts.sys.readFile(filePath) ?? '';
|
|
73
|
+
const originalText = forceText ?? ts.sys.readFile(filePath) ?? '';
|
|
74
74
|
let code = '';
|
|
75
75
|
if (framework === 'svelte') {
|
|
76
76
|
const svelteIntegration = (0, importPackage_1.importSvelteIntegration)(filePath);
|
|
@@ -84,7 +84,7 @@ function createFromFrameworkFilePath(filePath, framework, ts) {
|
|
|
84
84
|
code = vueIntegration.toTSX(originalText, className);
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
return new DocumentSnapshot_1.TypeScriptDocumentSnapshot(0, filePath, code, ts.ScriptKind.TSX);
|
|
87
|
+
return new DocumentSnapshot_1.TypeScriptDocumentSnapshot(0, filePath, code, ts.ScriptKind.TSX, false);
|
|
88
88
|
}
|
|
89
89
|
exports.createFromFrameworkFilePath = createFromFrameworkFilePath;
|
|
90
90
|
function classNameFromFilename(filename) {
|
package/dist/server.js
CHANGED
|
@@ -103,6 +103,8 @@ function startLanguageServer(connection, env) {
|
|
|
103
103
|
foldingRangeProvider: true,
|
|
104
104
|
definitionProvider: true,
|
|
105
105
|
typeDefinitionProvider: true,
|
|
106
|
+
referencesProvider: true,
|
|
107
|
+
implementationProvider: true,
|
|
106
108
|
renameProvider: true,
|
|
107
109
|
documentFormattingProvider: true,
|
|
108
110
|
codeActionProvider: {
|
|
@@ -184,20 +186,22 @@ function startLanguageServer(connection, env) {
|
|
|
184
186
|
});
|
|
185
187
|
const diagnosticsManager = new DiagnosticsManager_1.DiagnosticsManager(connection.sendDiagnostics, documentManager, pluginHost.getDiagnostics.bind(pluginHost));
|
|
186
188
|
const updateAllDiagnostics = (0, utils_2.debounceThrottle)(() => diagnosticsManager.updateAll(), 1000);
|
|
187
|
-
connection.onDidChangeWatchedFiles((evt) => {
|
|
189
|
+
connection.onDidChangeWatchedFiles(async (evt) => {
|
|
188
190
|
const params = evt.changes
|
|
189
191
|
.map((change) => ({
|
|
190
192
|
fileName: (0, utils_2.urlToPath)(change.uri),
|
|
191
193
|
changeType: change.type,
|
|
192
194
|
}))
|
|
193
195
|
.filter((change) => !!change.fileName);
|
|
194
|
-
pluginHost.onWatchFileChanges(params);
|
|
196
|
+
await pluginHost.onWatchFileChanges(params);
|
|
195
197
|
updateAllDiagnostics();
|
|
196
198
|
});
|
|
197
199
|
// Features
|
|
198
200
|
connection.onHover((params) => pluginHost.doHover(params.textDocument, params.position));
|
|
199
201
|
connection.onDefinition((evt) => pluginHost.getDefinitions(evt.textDocument, evt.position));
|
|
200
|
-
connection.onTypeDefinition((evt) => pluginHost.
|
|
202
|
+
connection.onTypeDefinition((evt) => pluginHost.getTypeDefinitions(evt.textDocument, evt.position));
|
|
203
|
+
connection.onReferences((evt) => pluginHost.getReferences(evt.textDocument, evt.position, evt.context));
|
|
204
|
+
connection.onImplementation((evt) => pluginHost.getImplementations(evt.textDocument, evt.position));
|
|
201
205
|
connection.onFoldingRanges((evt) => pluginHost.getFoldingRanges(evt.textDocument));
|
|
202
206
|
connection.onCodeAction((evt, cancellationToken) => pluginHost.getCodeActions(evt.textDocument, evt.range, evt.context, cancellationToken));
|
|
203
207
|
connection.onCompletion(async (evt) => {
|
|
@@ -226,21 +230,24 @@ function startLanguageServer(connection, env) {
|
|
|
226
230
|
connection.onNotification('$/onDidChangeNonAstroFile', async (e) => {
|
|
227
231
|
const path = (0, utils_2.urlToPath)(e.uri);
|
|
228
232
|
if (path) {
|
|
229
|
-
pluginHost.updateNonAstroFile(path, e.changes);
|
|
233
|
+
pluginHost.updateNonAstroFile(path, e.changes, e.text);
|
|
230
234
|
}
|
|
231
235
|
updateAllDiagnostics();
|
|
232
236
|
});
|
|
237
|
+
connection.onRequest('$/getFileReferences', async (uri) => {
|
|
238
|
+
return pluginHost.fileReferences({ uri });
|
|
239
|
+
});
|
|
233
240
|
connection.onRequest('$/getTSXOutput', async (uri) => {
|
|
234
241
|
const doc = documentManager.get(uri);
|
|
235
242
|
if (!doc) {
|
|
236
243
|
return undefined;
|
|
237
244
|
}
|
|
238
|
-
if (doc) {
|
|
245
|
+
if (doc && typescriptPlugin) {
|
|
239
246
|
const tsxOutput = typescriptPlugin.getTSXForDocument(doc);
|
|
240
247
|
return tsxOutput.code;
|
|
241
248
|
}
|
|
242
249
|
});
|
|
243
|
-
documentManager.on('documentChange',
|
|
250
|
+
documentManager.on('documentChange', updateAllDiagnostics);
|
|
244
251
|
documentManager.on('documentClose', (document) => {
|
|
245
252
|
diagnosticsManager.removeDiagnostics(document);
|
|
246
253
|
configManager.removeDocument(document.uri);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/language-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"author": "withastro",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "tsc --project tsconfig.build.json",
|
|
51
51
|
"dev": "astro-scripts dev \"src/**/*.ts\"",
|
|
52
|
-
"test": "cross-env TS_NODE_TRANSPILE_ONLY=true mocha --timeout 20000 --require ts-node/register \"test/**/*.ts\" --exclude \"test/**/*.d.ts\""
|
|
52
|
+
"test": "cross-env TS_NODE_TRANSPILE_ONLY=true mocha --timeout 20000 --require ts-node/register \"test/**/*.ts\" --exclude \"test/**/*.d.ts\"",
|
|
53
|
+
"test:match": "pnpm run test -g"
|
|
53
54
|
}
|
|
54
55
|
}
|