@astrojs/language-server 0.13.2 → 0.13.3
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/CHANGELOG.md +8 -0
- package/dist/core/documents/DocumentMapper.d.ts +2 -1
- package/dist/core/documents/DocumentMapper.js +8 -1
- package/dist/plugins/PluginHost.d.ts +2 -1
- package/dist/plugins/PluginHost.js +4 -0
- package/dist/plugins/astro/features/CompletionsProvider.d.ts +3 -4
- package/dist/plugins/astro/features/CompletionsProvider.js +51 -59
- package/dist/plugins/css/CSSPlugin.d.ts +2 -1
- package/dist/plugins/css/CSSPlugin.js +18 -27
- package/dist/plugins/html/HTMLPlugin.d.ts +1 -0
- package/dist/plugins/html/HTMLPlugin.js +8 -3
- package/dist/plugins/html/features/astro-attributes.d.ts +1 -0
- package/dist/plugins/html/features/astro-attributes.js +11 -2
- package/dist/plugins/html/utils.d.ts +6 -0
- package/dist/plugins/html/utils.js +11 -0
- package/dist/plugins/typescript/TypeScriptPlugin.d.ts +3 -1
- package/dist/plugins/typescript/TypeScriptPlugin.js +5 -0
- package/dist/plugins/typescript/features/SemanticTokenProvider.d.ts +15 -0
- package/dist/plugins/typescript/features/SemanticTokenProvider.js +78 -0
- package/dist/plugins/typescript/utils.d.ts +24 -1
- package/dist/plugins/typescript/utils.js +32 -1
- package/dist/server.js +11 -2
- package/dist/utils.d.ts +0 -5
- package/dist/utils.js +1 -16
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Position, Range, CompletionItem, Hover, Diagnostic, ColorPresentation, SymbolInformation, LocationLink, TextDocumentEdit, CodeAction, SelectionRange, TextEdit, InsertReplaceEdit } from 'vscode-languageserver';
|
|
1
|
+
import { Position, Range, CompletionItem, Hover, Diagnostic, ColorPresentation, SymbolInformation, LocationLink, TextDocumentEdit, CodeAction, SelectionRange, TextEdit, InsertReplaceEdit, FoldingRange } from 'vscode-languageserver';
|
|
2
2
|
import { TagInformation } from './utils';
|
|
3
3
|
import { SourceMapConsumer } from 'source-map';
|
|
4
4
|
export interface DocumentMapper {
|
|
@@ -82,4 +82,5 @@ export declare function mapSymbolInformationToOriginal(fragment: Pick<DocumentMa
|
|
|
82
82
|
export declare function mapLocationLinkToOriginal(fragment: DocumentMapper, def: LocationLink): LocationLink;
|
|
83
83
|
export declare function mapTextDocumentEditToOriginal(fragment: DocumentMapper, edit: TextDocumentEdit): TextDocumentEdit;
|
|
84
84
|
export declare function mapCodeActionToOriginal(fragment: DocumentMapper, codeAction: CodeAction): CodeAction;
|
|
85
|
+
export declare function mapFoldingRangeToParent(fragment: DocumentMapper, foldingRange: FoldingRange): FoldingRange;
|
|
85
86
|
export declare function mapSelectionRangeToParent(fragment: Pick<DocumentMapper, 'getOriginalPosition'>, selectionRange: SelectionRange): SelectionRange;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.mapSelectionRangeToParent = exports.mapCodeActionToOriginal = exports.mapTextDocumentEditToOriginal = exports.mapLocationLinkToOriginal = exports.mapSymbolInformationToOriginal = exports.mapColorPresentationToOriginal = exports.mapDiagnosticToGenerated = exports.mapEditToOriginal = exports.mapInsertReplaceEditToOriginal = exports.mapObjWithRangeToOriginal = exports.mapHoverToParent = exports.mapCompletionItemToOriginal = exports.mapRangeToGenerated = exports.mapRangeToOriginal = exports.SourceMapDocumentMapper = exports.FragmentMapper = exports.IdentityMapper = void 0;
|
|
3
|
+
exports.mapSelectionRangeToParent = exports.mapFoldingRangeToParent = exports.mapCodeActionToOriginal = exports.mapTextDocumentEditToOriginal = exports.mapLocationLinkToOriginal = exports.mapSymbolInformationToOriginal = exports.mapColorPresentationToOriginal = exports.mapDiagnosticToGenerated = exports.mapEditToOriginal = exports.mapInsertReplaceEditToOriginal = exports.mapObjWithRangeToOriginal = exports.mapHoverToParent = exports.mapCompletionItemToOriginal = exports.mapRangeToGenerated = exports.mapRangeToOriginal = exports.SourceMapDocumentMapper = exports.FragmentMapper = exports.IdentityMapper = void 0;
|
|
4
4
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
5
5
|
const utils_1 = require("./utils");
|
|
6
6
|
/**
|
|
@@ -231,6 +231,13 @@ function mapCodeActionToOriginal(fragment, codeAction) {
|
|
|
231
231
|
}, codeAction.kind);
|
|
232
232
|
}
|
|
233
233
|
exports.mapCodeActionToOriginal = mapCodeActionToOriginal;
|
|
234
|
+
function mapFoldingRangeToParent(fragment, foldingRange) {
|
|
235
|
+
// Despite FoldingRange asking for a start and end line and a start and end character, FoldingRanges
|
|
236
|
+
// don't use the Range type, instead asking for 4 number. Not sure why, but it's not convenient
|
|
237
|
+
const range = mapRangeToOriginal(fragment, vscode_languageserver_1.Range.create(foldingRange.startLine, foldingRange.startCharacter || 0, foldingRange.endLine, foldingRange.endCharacter || 0));
|
|
238
|
+
return vscode_languageserver_1.FoldingRange.create(range.start.line, range.end.line, foldingRange.startCharacter ? range.start.character : undefined, foldingRange.endCharacter ? range.end.character : undefined, foldingRange.kind);
|
|
239
|
+
}
|
|
240
|
+
exports.mapFoldingRangeToParent = mapFoldingRangeToParent;
|
|
234
241
|
function mapSelectionRangeToParent(fragment, selectionRange) {
|
|
235
242
|
const { range, parent } = selectionRange;
|
|
236
243
|
return vscode_languageserver_1.SelectionRange.create(mapRangeToOriginal(fragment, range), parent && mapSelectionRangeToParent(fragment, parent));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CancellationToken, Color, ColorInformation, ColorPresentation, CompletionContext, CompletionItem, CompletionList, DefinitionLink, Diagnostic, FoldingRange, Hover, Position, Range, Location, SignatureHelp, SignatureHelpContext, TextDocumentContentChangeEvent, TextDocumentIdentifier, WorkspaceEdit, SymbolInformation } from 'vscode-languageserver';
|
|
1
|
+
import { CancellationToken, Color, ColorInformation, ColorPresentation, CompletionContext, CompletionItem, CompletionList, DefinitionLink, Diagnostic, FoldingRange, Hover, Position, Range, Location, SignatureHelp, SignatureHelpContext, TextDocumentContentChangeEvent, TextDocumentIdentifier, WorkspaceEdit, SymbolInformation, SemanticTokens } from 'vscode-languageserver';
|
|
2
2
|
import type { AppCompletionItem, Plugin } from './interfaces';
|
|
3
3
|
import { DocumentManager } from '../core/documents/DocumentManager';
|
|
4
4
|
interface PluginHostConfig {
|
|
@@ -19,6 +19,7 @@ export declare class PluginHost {
|
|
|
19
19
|
doTagComplete(textDocument: TextDocumentIdentifier, position: Position): Promise<string | null>;
|
|
20
20
|
getFoldingRanges(textDocument: TextDocumentIdentifier): Promise<FoldingRange[] | null>;
|
|
21
21
|
getDocumentSymbols(textDocument: TextDocumentIdentifier, cancellationToken: CancellationToken): Promise<SymbolInformation[]>;
|
|
22
|
+
getSemanticTokens(textDocument: TextDocumentIdentifier, range?: Range, cancellationToken?: CancellationToken): Promise<SemanticTokens | null>;
|
|
22
23
|
getDefinitions(textDocument: TextDocumentIdentifier, position: Position): Promise<DefinitionLink[] | Location[]>;
|
|
23
24
|
rename(textDocument: TextDocumentIdentifier, position: Position, newName: string): Promise<WorkspaceEdit | null>;
|
|
24
25
|
getDocumentColors(textDocument: TextDocumentIdentifier): Promise<ColorInformation[]>;
|
|
@@ -57,6 +57,10 @@ class PluginHost {
|
|
|
57
57
|
const document = this.getDocument(textDocument.uri);
|
|
58
58
|
return (0, lodash_1.flatten)(await this.execute('getDocumentSymbols', [document, cancellationToken], ExecuteMode.Collect));
|
|
59
59
|
}
|
|
60
|
+
async getSemanticTokens(textDocument, range, cancellationToken) {
|
|
61
|
+
const document = this.getDocument(textDocument.uri);
|
|
62
|
+
return await this.execute('getSemanticTokens', [document, range, cancellationToken], ExecuteMode.FirstNonNull);
|
|
63
|
+
}
|
|
60
64
|
async getDefinitions(textDocument, position) {
|
|
61
65
|
const document = this.getDocument(textDocument.uri);
|
|
62
66
|
const definitions = (0, lodash_1.flatten)(await this.execute('getDefinitions', [document, position], ExecuteMode.Collect));
|
|
@@ -5,14 +5,13 @@ import { LanguageServiceManager as TypeScriptLanguageServiceManager } from '../.
|
|
|
5
5
|
export declare class CompletionsProviderImpl {
|
|
6
6
|
private readonly docManager;
|
|
7
7
|
private readonly languageServiceManager;
|
|
8
|
+
directivesHTMLLang: import("vscode-html-languageservice").LanguageService;
|
|
8
9
|
constructor(docManager: DocumentManager, languageServiceManager: TypeScriptLanguageServiceManager);
|
|
9
10
|
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<AppCompletionList | null>;
|
|
10
|
-
private getClientHintCompletion;
|
|
11
11
|
private getComponentScriptCompletion;
|
|
12
12
|
private getPropCompletions;
|
|
13
13
|
private getImportedSymbol;
|
|
14
14
|
private getPropType;
|
|
15
|
-
private
|
|
16
|
-
private
|
|
17
|
-
private isInsideFrontmatter;
|
|
15
|
+
private getCompletionItemForProperty;
|
|
16
|
+
private isAstroComponent;
|
|
18
17
|
}
|
|
@@ -9,8 +9,15 @@ const typescript_1 = __importDefault(require("typescript"));
|
|
|
9
9
|
const utils_1 = require("../../../core/documents/utils");
|
|
10
10
|
const utils_2 = require("../../../utils");
|
|
11
11
|
const utils_3 = require("../../typescript/utils");
|
|
12
|
+
const vscode_html_languageservice_1 = require("vscode-html-languageservice");
|
|
13
|
+
const astro_attributes_1 = require("../../html/features/astro-attributes");
|
|
14
|
+
const utils_4 = require("../../html/utils");
|
|
12
15
|
class CompletionsProviderImpl {
|
|
13
16
|
constructor(docManager, languageServiceManager) {
|
|
17
|
+
this.directivesHTMLLang = (0, vscode_html_languageservice_1.getLanguageService)({
|
|
18
|
+
customDataProviders: [astro_attributes_1.astroDirectives],
|
|
19
|
+
useDefaultDataProvider: false,
|
|
20
|
+
});
|
|
14
21
|
this.docManager = docManager;
|
|
15
22
|
this.languageServiceManager = languageServiceManager;
|
|
16
23
|
}
|
|
@@ -24,46 +31,23 @@ class CompletionsProviderImpl {
|
|
|
24
31
|
if (frontmatter)
|
|
25
32
|
items.push(frontmatter);
|
|
26
33
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (clientHint)
|
|
30
|
-
items.push(...clientHint);
|
|
31
|
-
}
|
|
32
|
-
if (!this.isInsideFrontmatter(document, position)) {
|
|
34
|
+
const offset = document.offsetAt(position);
|
|
35
|
+
if (!(0, utils_1.isInsideFrontmatter)(document.getText(), offset)) {
|
|
33
36
|
const props = await this.getPropCompletions(document, position, completionContext);
|
|
34
37
|
if (props.length) {
|
|
35
38
|
items.push(...props);
|
|
36
39
|
}
|
|
37
40
|
}
|
|
41
|
+
const html = document.html;
|
|
42
|
+
if ((0, utils_1.isInComponentStartTag)(html, offset)) {
|
|
43
|
+
const node = html.findNodeAt(offset);
|
|
44
|
+
const isAstro = await this.isAstroComponent(document, node);
|
|
45
|
+
if (!isAstro) {
|
|
46
|
+
items.push(...(0, utils_4.removeDataAttrCompletion)(this.directivesHTMLLang.doComplete(document, position, html).items));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
38
49
|
return vscode_languageserver_1.CompletionList.create(items, true);
|
|
39
50
|
}
|
|
40
|
-
getClientHintCompletion(document, position, completionContext) {
|
|
41
|
-
const node = document.html.findNodeAt(document.offsetAt(position));
|
|
42
|
-
if (!(0, utils_2.isPossibleClientComponent)(node))
|
|
43
|
-
return null;
|
|
44
|
-
return [
|
|
45
|
-
{
|
|
46
|
-
label: ':load',
|
|
47
|
-
insertText: 'load',
|
|
48
|
-
commitCharacters: ['l'],
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
label: ':idle',
|
|
52
|
-
insertText: 'idle',
|
|
53
|
-
commitCharacters: ['i'],
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
label: ':visible',
|
|
57
|
-
insertText: 'visible',
|
|
58
|
-
commitCharacters: ['v'],
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
label: ':media',
|
|
62
|
-
insertText: 'media',
|
|
63
|
-
commitCharacters: ['m'],
|
|
64
|
-
},
|
|
65
|
-
];
|
|
66
|
-
}
|
|
67
51
|
getComponentScriptCompletion(document, position, completionContext) {
|
|
68
52
|
const base = {
|
|
69
53
|
kind: vscode_languageserver_1.CompletionItemKind.Snippet,
|
|
@@ -96,11 +80,10 @@ class CompletionsProviderImpl {
|
|
|
96
80
|
return null;
|
|
97
81
|
}
|
|
98
82
|
async getPropCompletions(document, position, completionContext) {
|
|
99
|
-
var _a, _b;
|
|
100
83
|
const offset = document.offsetAt(position);
|
|
101
84
|
const html = document.html;
|
|
102
85
|
const node = html.findNodeAt(offset);
|
|
103
|
-
if (!
|
|
86
|
+
if (!(0, utils_2.isPossibleComponent)(node)) {
|
|
104
87
|
return [];
|
|
105
88
|
}
|
|
106
89
|
const inAttribute = node.start + node.tag.length < offset;
|
|
@@ -119,8 +102,7 @@ class CompletionsProviderImpl {
|
|
|
119
102
|
const componentName = node.tag;
|
|
120
103
|
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
121
104
|
// Get the source file
|
|
122
|
-
const
|
|
123
|
-
const tsFilePath = (0, utils_3.toVirtualAstroFilePath)(filePath);
|
|
105
|
+
const tsFilePath = (0, utils_3.toVirtualAstroFilePath)(tsDoc.filePath);
|
|
124
106
|
const program = lang.getProgram();
|
|
125
107
|
const sourceFile = program === null || program === void 0 ? void 0 : program.getSourceFile(tsFilePath);
|
|
126
108
|
const typeChecker = program === null || program === void 0 ? void 0 : program.getTypeChecker();
|
|
@@ -133,26 +115,22 @@ class CompletionsProviderImpl {
|
|
|
133
115
|
if (!importType) {
|
|
134
116
|
return [];
|
|
135
117
|
}
|
|
136
|
-
// Get the
|
|
118
|
+
// Get the component's props type
|
|
137
119
|
const componentType = this.getPropType(importType, typeChecker);
|
|
138
120
|
if (!componentType) {
|
|
139
121
|
return [];
|
|
140
122
|
}
|
|
141
|
-
|
|
142
|
-
// Add completions for this
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
let completionItem = this.getCompletionItemForTypeMember(mem, typeChecker);
|
|
147
|
-
completionItems.push(completionItem);
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
// Add completions for this types base members
|
|
151
|
-
const members = ((_b = componentType.getSymbol()) === null || _b === void 0 ? void 0 : _b.members) || [];
|
|
152
|
-
members.forEach((mem) => {
|
|
153
|
-
let completionItem = this.getCompletionItemForTypeMember(mem, typeChecker);
|
|
123
|
+
let completionItems = [];
|
|
124
|
+
// Add completions for this component's props type properties
|
|
125
|
+
const properties = componentType.getProperties().filter((property) => property.name !== 'children') || [];
|
|
126
|
+
properties.forEach((property) => {
|
|
127
|
+
let completionItem = this.getCompletionItemForProperty(property, typeChecker);
|
|
154
128
|
completionItems.push(completionItem);
|
|
155
129
|
});
|
|
130
|
+
// Ensure that props shows up first as a completion, despite this plugin being ran after the HTML one
|
|
131
|
+
completionItems = completionItems.map((item) => {
|
|
132
|
+
return { ...item, sortText: '_' };
|
|
133
|
+
});
|
|
156
134
|
return completionItems;
|
|
157
135
|
}
|
|
158
136
|
getImportedSymbol(sourceFile, identifier) {
|
|
@@ -203,7 +181,7 @@ class CompletionsProviderImpl {
|
|
|
203
181
|
}
|
|
204
182
|
return null;
|
|
205
183
|
}
|
|
206
|
-
|
|
184
|
+
getCompletionItemForProperty(mem, typeChecker) {
|
|
207
185
|
let item = {
|
|
208
186
|
label: mem.name,
|
|
209
187
|
insertText: mem.name,
|
|
@@ -223,15 +201,29 @@ class CompletionsProviderImpl {
|
|
|
223
201
|
}
|
|
224
202
|
return item;
|
|
225
203
|
}
|
|
226
|
-
|
|
227
|
-
|
|
204
|
+
async isAstroComponent(document, node) {
|
|
205
|
+
var _a;
|
|
206
|
+
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
207
|
+
// Get the source file
|
|
208
|
+
const tsFilePath = (0, utils_3.toVirtualAstroFilePath)(tsDoc.filePath);
|
|
209
|
+
const program = lang.getProgram();
|
|
210
|
+
const sourceFile = program === null || program === void 0 ? void 0 : program.getSourceFile(tsFilePath);
|
|
211
|
+
const typeChecker = program === null || program === void 0 ? void 0 : program.getTypeChecker();
|
|
212
|
+
if (!sourceFile || !typeChecker) {
|
|
228
213
|
return false;
|
|
229
214
|
}
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
215
|
+
const componentName = node.tag;
|
|
216
|
+
const imp = this.getImportedSymbol(sourceFile, componentName);
|
|
217
|
+
const importType = imp && typeChecker.getTypeAtLocation(imp);
|
|
218
|
+
if (!importType) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
const symbolDeclaration = (_a = importType.getSymbol()) === null || _a === void 0 ? void 0 : _a.declarations;
|
|
222
|
+
if (symbolDeclaration) {
|
|
223
|
+
const fileName = symbolDeclaration[0].getSourceFile().fileName;
|
|
224
|
+
return fileName.endsWith('.astro');
|
|
225
|
+
}
|
|
226
|
+
return false;
|
|
235
227
|
}
|
|
236
228
|
}
|
|
237
229
|
exports.CompletionsProviderImpl = CompletionsProviderImpl;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Color, ColorInformation, ColorPresentation, CompletionContext, CompletionList, Hover, Position, Range, SymbolInformation } from 'vscode-languageserver';
|
|
1
|
+
import { Color, ColorInformation, ColorPresentation, CompletionContext, CompletionList, FoldingRange, Hover, Position, Range, SymbolInformation } from 'vscode-languageserver';
|
|
2
2
|
import { ConfigManager } from '../../core/config/ConfigManager';
|
|
3
3
|
import { AstroDocument } from '../../core/documents';
|
|
4
4
|
import type { Plugin } from '../interfaces';
|
|
@@ -14,6 +14,7 @@ export declare class CSSPlugin implements Plugin {
|
|
|
14
14
|
private getCompletionsInternal;
|
|
15
15
|
getDocumentColors(document: AstroDocument): ColorInformation[];
|
|
16
16
|
getColorPresentations(document: AstroDocument, range: Range, color: Color): ColorPresentation[];
|
|
17
|
+
getFoldingRanges(document: AstroDocument): FoldingRange[] | null;
|
|
17
18
|
getDocumentSymbols(document: AstroDocument): SymbolInformation[];
|
|
18
19
|
private inStyleAttributeWithoutInterpolation;
|
|
19
20
|
/**
|
|
@@ -37,7 +37,8 @@ class CSSPlugin {
|
|
|
37
37
|
return null;
|
|
38
38
|
}
|
|
39
39
|
const cssDocument = this.getCSSDocumentForStyleTag(styleTag, document);
|
|
40
|
-
|
|
40
|
+
const cssLang = extractLanguage(cssDocument);
|
|
41
|
+
if (!isSupportedByLangService(cssLang)) {
|
|
41
42
|
return null;
|
|
42
43
|
}
|
|
43
44
|
return this.doHoverInternal(cssDocument, position);
|
|
@@ -104,7 +105,7 @@ class CSSPlugin {
|
|
|
104
105
|
const allColorInfo = this.getCSSDocumentsForDocument(document).map((cssDoc) => {
|
|
105
106
|
const cssLang = extractLanguage(cssDoc);
|
|
106
107
|
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
|
107
|
-
if (
|
|
108
|
+
if (!isSupportedByLangService(cssLang)) {
|
|
108
109
|
return [];
|
|
109
110
|
}
|
|
110
111
|
return langService
|
|
@@ -120,7 +121,8 @@ class CSSPlugin {
|
|
|
120
121
|
const allColorPres = this.getCSSDocumentsForDocument(document).map((cssDoc) => {
|
|
121
122
|
const cssLang = extractLanguage(cssDoc);
|
|
122
123
|
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
|
123
|
-
if ((!cssDoc.isInGenerated(range.start) && !cssDoc.isInGenerated(range.end)) ||
|
|
124
|
+
if ((!cssDoc.isInGenerated(range.start) && !cssDoc.isInGenerated(range.end)) ||
|
|
125
|
+
!isSupportedByLangService(cssLang)) {
|
|
124
126
|
return [];
|
|
125
127
|
}
|
|
126
128
|
return langService
|
|
@@ -129,6 +131,14 @@ class CSSPlugin {
|
|
|
129
131
|
});
|
|
130
132
|
return (0, lodash_1.flatten)(allColorPres);
|
|
131
133
|
}
|
|
134
|
+
getFoldingRanges(document) {
|
|
135
|
+
const allFoldingRanges = this.getCSSDocumentsForDocument(document).map((cssDoc) => {
|
|
136
|
+
const cssLang = extractLanguage(cssDoc);
|
|
137
|
+
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
|
138
|
+
return langService.getFoldingRanges(cssDoc).map((foldingRange) => (0, documents_1.mapFoldingRangeToParent)(cssDoc, foldingRange));
|
|
139
|
+
});
|
|
140
|
+
return (0, lodash_1.flatten)(allFoldingRanges);
|
|
141
|
+
}
|
|
132
142
|
getDocumentSymbols(document) {
|
|
133
143
|
if (!this.featureEnabled('documentSymbols')) {
|
|
134
144
|
return [];
|
|
@@ -182,32 +192,13 @@ class CSSPlugin {
|
|
|
182
192
|
}
|
|
183
193
|
exports.CSSPlugin = CSSPlugin;
|
|
184
194
|
/**
|
|
185
|
-
*
|
|
186
|
-
* The CSS language service only supports CSS, LESS and SCSS,
|
|
187
|
-
* which mean that we cannot support hover info in other languages
|
|
195
|
+
* Check is a CSSDocument's language is supported by the CSS language service
|
|
188
196
|
*/
|
|
189
|
-
function
|
|
190
|
-
const language = typeof document === 'string' ? document : extractLanguage(document);
|
|
197
|
+
function isSupportedByLangService(language) {
|
|
191
198
|
switch (language) {
|
|
192
|
-
case '
|
|
193
|
-
case '
|
|
194
|
-
case '
|
|
195
|
-
return true;
|
|
196
|
-
default:
|
|
197
|
-
return false;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Exclude certain language when getting colors
|
|
202
|
-
* The CSS language service only supports CSS, LESS and SCSS,
|
|
203
|
-
* which mean that we cannot support colors in other languages
|
|
204
|
-
*/
|
|
205
|
-
function shouldExcludeColor(document) {
|
|
206
|
-
const language = typeof document === 'string' ? document : extractLanguage(document);
|
|
207
|
-
switch (language) {
|
|
208
|
-
case 'sass':
|
|
209
|
-
case 'stylus':
|
|
210
|
-
case 'styl':
|
|
199
|
+
case 'css':
|
|
200
|
+
case 'scss':
|
|
201
|
+
case 'less':
|
|
211
202
|
return true;
|
|
212
203
|
default:
|
|
213
204
|
return false;
|
|
@@ -7,11 +7,16 @@ const vscode_html_languageservice_1 = require("vscode-html-languageservice");
|
|
|
7
7
|
const utils_1 = require("../../core/documents/utils");
|
|
8
8
|
const utils_2 = require("../../utils");
|
|
9
9
|
const astro_attributes_1 = require("./features/astro-attributes");
|
|
10
|
+
const utils_3 = require("./utils");
|
|
10
11
|
class HTMLPlugin {
|
|
11
12
|
constructor(configManager) {
|
|
12
13
|
this.__name = 'html';
|
|
13
14
|
this.lang = (0, vscode_html_languageservice_1.getLanguageService)({
|
|
15
|
+
customDataProviders: [astro_attributes_1.astroAttributes, astro_attributes_1.classListAttribute],
|
|
16
|
+
});
|
|
17
|
+
this.attributeOnlyLang = (0, vscode_html_languageservice_1.getLanguageService)({
|
|
14
18
|
customDataProviders: [astro_attributes_1.astroAttributes],
|
|
19
|
+
useDefaultDataProvider: false,
|
|
15
20
|
});
|
|
16
21
|
this.componentLang = (0, vscode_html_languageservice_1.getLanguageService)({
|
|
17
22
|
customDataProviders: [astro_attributes_1.astroAttributes, astro_attributes_1.astroDirectives],
|
|
@@ -66,9 +71,9 @@ class HTMLPlugin {
|
|
|
66
71
|
// If we're in a component starting tag, we do not want HTML language completions
|
|
67
72
|
// as HTML attributes are not valid for components
|
|
68
73
|
const results = (0, utils_1.isInComponentStartTag)(html, document.offsetAt(position))
|
|
69
|
-
?
|
|
70
|
-
: this.lang.doComplete(document, position, html);
|
|
71
|
-
return vscode_languageserver_1.CompletionList.create([...results
|
|
74
|
+
? (0, utils_3.removeDataAttrCompletion)(this.attributeOnlyLang.doComplete(document, position, html).items)
|
|
75
|
+
: this.lang.doComplete(document, position, html).items;
|
|
76
|
+
return vscode_languageserver_1.CompletionList.create([...results, ...this.getLangCompletions(results), ...emmetResults.items],
|
|
72
77
|
// Emmet completions change on every keystroke, so they are never complete
|
|
73
78
|
emmetResults.items.length > 0);
|
|
74
79
|
}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
+
export declare const classListAttribute: import("vscode-html-languageservice").IHTMLDataProvider;
|
|
1
2
|
export declare const astroAttributes: import("vscode-html-languageservice").IHTMLDataProvider;
|
|
2
3
|
export declare const astroDirectives: import("vscode-html-languageservice").IHTMLDataProvider;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.astroDirectives = exports.astroAttributes = void 0;
|
|
3
|
+
exports.astroDirectives = exports.astroAttributes = exports.classListAttribute = void 0;
|
|
4
4
|
const vscode_html_languageservice_1 = require("vscode-html-languageservice");
|
|
5
|
-
exports.
|
|
5
|
+
exports.classListAttribute = (0, vscode_html_languageservice_1.newHTMLDataProvider)('class-list', {
|
|
6
6
|
version: 1,
|
|
7
7
|
globalAttributes: [
|
|
8
8
|
{
|
|
9
9
|
name: 'class:list',
|
|
10
10
|
description: 'Utility to provide a list of class',
|
|
11
11
|
},
|
|
12
|
+
],
|
|
13
|
+
});
|
|
14
|
+
exports.astroAttributes = (0, vscode_html_languageservice_1.newHTMLDataProvider)('astro-attributes', {
|
|
15
|
+
version: 1,
|
|
16
|
+
globalAttributes: [
|
|
12
17
|
{
|
|
13
18
|
name: 'set:html',
|
|
14
19
|
description: 'Inject unescaped HTML into this tag',
|
|
@@ -75,6 +80,7 @@ exports.astroDirectives = (0, vscode_html_languageservice_1.newHTMLDataProvider)
|
|
|
75
80
|
{
|
|
76
81
|
name: 'client:load',
|
|
77
82
|
description: 'Start importing the component JS at page load. Hydrate the component when import completes.',
|
|
83
|
+
valueSet: 'v',
|
|
78
84
|
references: [
|
|
79
85
|
{
|
|
80
86
|
name: 'Astro documentation',
|
|
@@ -85,6 +91,7 @@ exports.astroDirectives = (0, vscode_html_languageservice_1.newHTMLDataProvider)
|
|
|
85
91
|
{
|
|
86
92
|
name: 'client:idle',
|
|
87
93
|
description: 'Start importing the component JS as soon as main thread is free (uses requestIdleCallback()). Hydrate the component when import completes.',
|
|
94
|
+
valueSet: 'v',
|
|
88
95
|
references: [
|
|
89
96
|
{
|
|
90
97
|
name: 'Astro documentation',
|
|
@@ -95,6 +102,7 @@ exports.astroDirectives = (0, vscode_html_languageservice_1.newHTMLDataProvider)
|
|
|
95
102
|
{
|
|
96
103
|
name: 'client:visible',
|
|
97
104
|
description: 'Start importing the component JS as soon as the element enters the viewport (uses IntersectionObserver). Hydrate the component when import completes. Useful for content lower down on the page.',
|
|
105
|
+
valueSet: 'v',
|
|
98
106
|
references: [
|
|
99
107
|
{
|
|
100
108
|
name: 'Astro documentation',
|
|
@@ -115,6 +123,7 @@ exports.astroDirectives = (0, vscode_html_languageservice_1.newHTMLDataProvider)
|
|
|
115
123
|
{
|
|
116
124
|
name: 'client:only',
|
|
117
125
|
description: 'Start importing the component JS at page load and hydrate when the import completes, similar to client:load. The component will be skipped at build time, useful for components that are entirely dependent on client-side APIs. This is best avoided unless absolutely needed, in most cases it is best to render placeholder content on the server and delay any browser API calls until the component hydrates in the browser.',
|
|
126
|
+
valueSet: 'v',
|
|
118
127
|
references: [
|
|
119
128
|
{
|
|
120
129
|
name: 'Astro documentation',
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CompletionItem } from 'vscode-languageserver-types';
|
|
2
|
+
/**
|
|
3
|
+
* The VS Code HTML language service provides a completion for data attributes that is independent from
|
|
4
|
+
* data providers, which mean that you can't disable it, so this function removes them from a completionList
|
|
5
|
+
*/
|
|
6
|
+
export declare function removeDataAttrCompletion(items: CompletionItem[]): CompletionItem[];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.removeDataAttrCompletion = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The VS Code HTML language service provides a completion for data attributes that is independent from
|
|
6
|
+
* data providers, which mean that you can't disable it, so this function removes them from a completionList
|
|
7
|
+
*/
|
|
8
|
+
function removeDataAttrCompletion(items) {
|
|
9
|
+
return items.filter((item) => !item.label.startsWith('data-'));
|
|
10
|
+
}
|
|
11
|
+
exports.removeDataAttrCompletion = removeDataAttrCompletion;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CancellationToken, CompletionContext, DefinitionLink, Diagnostic, Hover, Position, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, WorkspaceEdit } from 'vscode-languageserver';
|
|
1
|
+
import { CancellationToken, CompletionContext, DefinitionLink, Diagnostic, Hover, Position, Range, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, WorkspaceEdit } from 'vscode-languageserver';
|
|
2
2
|
import { ConfigManager } from '../../core/config';
|
|
3
3
|
import { AstroDocument, DocumentManager } from '../../core/documents';
|
|
4
4
|
import { AppCompletionItem, AppCompletionList, OnWatchFileChangesParam, Plugin } from '../interfaces';
|
|
@@ -12,9 +12,11 @@ export declare class TypeScriptPlugin implements Plugin {
|
|
|
12
12
|
private readonly signatureHelpProvider;
|
|
13
13
|
private readonly diagnosticsProvider;
|
|
14
14
|
private readonly documentSymbolsProvider;
|
|
15
|
+
private readonly semanticTokensProvider;
|
|
15
16
|
constructor(docManager: DocumentManager, configManager: ConfigManager, workspaceUris: string[]);
|
|
16
17
|
doHover(document: AstroDocument, position: Position): Promise<Hover | null>;
|
|
17
18
|
rename(document: AstroDocument, position: Position, newName: string): Promise<WorkspaceEdit | null>;
|
|
19
|
+
getSemanticTokens(textDocument: AstroDocument, range?: Range, cancellationToken?: CancellationToken): Promise<SemanticTokens | null>;
|
|
18
20
|
getDocumentSymbols(document: AstroDocument): Promise<SymbolInformation[]>;
|
|
19
21
|
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<AppCompletionList<CompletionEntryWithIdentifer> | null>;
|
|
20
22
|
resolveCompletion(document: AstroDocument, completionItem: AppCompletionItem<CompletionEntryWithIdentifer>): Promise<AppCompletionItem<CompletionEntryWithIdentifer>>;
|
|
@@ -36,6 +36,7 @@ const utils_2 = require("./features/utils");
|
|
|
36
36
|
const LanguageServiceManager_1 = require("./LanguageServiceManager");
|
|
37
37
|
const utils_3 = require("./utils");
|
|
38
38
|
const DocumentSymbolsProvider_1 = require("./features/DocumentSymbolsProvider");
|
|
39
|
+
const SemanticTokenProvider_1 = require("./features/SemanticTokenProvider");
|
|
39
40
|
class TypeScriptPlugin {
|
|
40
41
|
constructor(docManager, configManager, workspaceUris) {
|
|
41
42
|
this.__name = 'typescript';
|
|
@@ -46,6 +47,7 @@ class TypeScriptPlugin {
|
|
|
46
47
|
this.signatureHelpProvider = new SignatureHelpProvider_1.SignatureHelpProviderImpl(this.languageServiceManager);
|
|
47
48
|
this.diagnosticsProvider = new DiagnosticsProvider_1.DiagnosticsProviderImpl(this.languageServiceManager);
|
|
48
49
|
this.documentSymbolsProvider = new DocumentSymbolsProvider_1.DocumentSymbolsProviderImpl(this.languageServiceManager);
|
|
50
|
+
this.semanticTokensProvider = new SemanticTokenProvider_1.SemanticTokensProviderImpl(this.languageServiceManager);
|
|
49
51
|
}
|
|
50
52
|
async doHover(document, position) {
|
|
51
53
|
if (!this.featureEnabled('hover')) {
|
|
@@ -76,6 +78,9 @@ class TypeScriptPlugin {
|
|
|
76
78
|
});
|
|
77
79
|
return edit;
|
|
78
80
|
}
|
|
81
|
+
async getSemanticTokens(textDocument, range, cancellationToken) {
|
|
82
|
+
return this.semanticTokensProvider.getSemanticTokens(textDocument, range, cancellationToken);
|
|
83
|
+
}
|
|
79
84
|
async getDocumentSymbols(document) {
|
|
80
85
|
if (!this.featureEnabled('documentSymbols')) {
|
|
81
86
|
return [];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CancellationToken, Range, SemanticTokens } from 'vscode-languageserver';
|
|
2
|
+
import { AstroDocument } from '../../../core/documents';
|
|
3
|
+
import { SemanticTokensProvider } from '../../interfaces';
|
|
4
|
+
import { LanguageServiceManager } from '../LanguageServiceManager';
|
|
5
|
+
export declare class SemanticTokensProviderImpl implements SemanticTokensProvider {
|
|
6
|
+
private languageServiceManager;
|
|
7
|
+
constructor(languageServiceManager: LanguageServiceManager);
|
|
8
|
+
getSemanticTokens(document: AstroDocument, range?: Range, cancellationToken?: CancellationToken): Promise<SemanticTokens | null>;
|
|
9
|
+
private mapToOrigin;
|
|
10
|
+
/**
|
|
11
|
+
* TSClassification = (TokenType + 1) << TokenEncodingConsts.typeOffset + TokenModifier
|
|
12
|
+
*/
|
|
13
|
+
private getTokenTypeFromClassification;
|
|
14
|
+
private getTokenModifierFromClassification;
|
|
15
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SemanticTokensProviderImpl = void 0;
|
|
7
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
8
|
+
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
9
|
+
const documents_1 = require("../../../core/documents");
|
|
10
|
+
const utils_1 = require("../utils");
|
|
11
|
+
class SemanticTokensProviderImpl {
|
|
12
|
+
constructor(languageServiceManager) {
|
|
13
|
+
this.languageServiceManager = languageServiceManager;
|
|
14
|
+
}
|
|
15
|
+
async getSemanticTokens(document, range, cancellationToken) {
|
|
16
|
+
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
17
|
+
const fragment = (await tsDoc.createFragment());
|
|
18
|
+
if (cancellationToken === null || cancellationToken === void 0 ? void 0 : cancellationToken.isCancellationRequested) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const filePath = (0, utils_1.toVirtualAstroFilePath)(tsDoc.filePath);
|
|
22
|
+
const start = range ? fragment.offsetAt(fragment.getGeneratedPosition(range.start)) : 0;
|
|
23
|
+
const { spans } = lang.getEncodedSemanticClassifications(filePath, {
|
|
24
|
+
start,
|
|
25
|
+
length: range ? fragment.offsetAt(fragment.getGeneratedPosition(range.end)) - start : fragment.text.length,
|
|
26
|
+
}, typescript_1.default.SemanticClassificationFormat.TwentyTwenty);
|
|
27
|
+
const tokens = [];
|
|
28
|
+
let i = 0;
|
|
29
|
+
while (i < spans.length) {
|
|
30
|
+
const offset = spans[i++];
|
|
31
|
+
const generatedLength = spans[i++];
|
|
32
|
+
const classification = spans[i++];
|
|
33
|
+
const originalPosition = this.mapToOrigin(document, fragment, offset, generatedLength);
|
|
34
|
+
if (!originalPosition) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const [line, character, length] = originalPosition;
|
|
38
|
+
const classificationType = this.getTokenTypeFromClassification(classification);
|
|
39
|
+
if (classificationType < 0) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const modifier = this.getTokenModifierFromClassification(classification);
|
|
43
|
+
tokens.push([line, character, length, classificationType, modifier]);
|
|
44
|
+
}
|
|
45
|
+
const sorted = tokens.sort((a, b) => {
|
|
46
|
+
const [lineA, charA] = a;
|
|
47
|
+
const [lineB, charB] = b;
|
|
48
|
+
return lineA - lineB || charA - charB;
|
|
49
|
+
});
|
|
50
|
+
const builder = new vscode_languageserver_1.SemanticTokensBuilder();
|
|
51
|
+
sorted.forEach((tokenData) => builder.push(...tokenData));
|
|
52
|
+
const build = builder.build();
|
|
53
|
+
return build;
|
|
54
|
+
}
|
|
55
|
+
mapToOrigin(document, fragment, generatedOffset, generatedLength) {
|
|
56
|
+
const range = {
|
|
57
|
+
start: fragment.positionAt(generatedOffset),
|
|
58
|
+
end: fragment.positionAt(generatedOffset + generatedLength),
|
|
59
|
+
};
|
|
60
|
+
const { start: startPosition, end: endPosition } = (0, documents_1.mapRangeToOriginal)(fragment, range);
|
|
61
|
+
if (startPosition.line < 0 || endPosition.line < 0) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const startOffset = document.offsetAt(startPosition);
|
|
65
|
+
const endOffset = document.offsetAt(endPosition);
|
|
66
|
+
return [startPosition.line, startPosition.character, endOffset - startOffset, startOffset];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* TSClassification = (TokenType + 1) << TokenEncodingConsts.typeOffset + TokenModifier
|
|
70
|
+
*/
|
|
71
|
+
getTokenTypeFromClassification(tsClassification) {
|
|
72
|
+
return (tsClassification >> 8 /* typeOffset */) - 1;
|
|
73
|
+
}
|
|
74
|
+
getTokenModifierFromClassification(tsClassification) {
|
|
75
|
+
return tsClassification & 255 /* modifierMask */;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.SemanticTokensProviderImpl = SemanticTokensProviderImpl;
|
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import { CompletionItemKind, DiagnosticSeverity, Position, Range, SymbolKind } from 'vscode-languageserver';
|
|
2
|
+
import { CompletionItemKind, DiagnosticSeverity, Position, Range, SymbolKind, SemanticTokensLegend } from 'vscode-languageserver';
|
|
3
3
|
import { SnapshotFragment } from './snapshots/DocumentSnapshot';
|
|
4
|
+
export declare const enum TokenType {
|
|
5
|
+
class = 0,
|
|
6
|
+
enum = 1,
|
|
7
|
+
interface = 2,
|
|
8
|
+
namespace = 3,
|
|
9
|
+
typeParameter = 4,
|
|
10
|
+
type = 5,
|
|
11
|
+
parameter = 6,
|
|
12
|
+
variable = 7,
|
|
13
|
+
enumMember = 8,
|
|
14
|
+
property = 9,
|
|
15
|
+
function = 10,
|
|
16
|
+
method = 11
|
|
17
|
+
}
|
|
18
|
+
export declare const enum TokenModifier {
|
|
19
|
+
declaration = 0,
|
|
20
|
+
static = 1,
|
|
21
|
+
async = 2,
|
|
22
|
+
readonly = 3,
|
|
23
|
+
defaultLibrary = 4,
|
|
24
|
+
local = 5
|
|
25
|
+
}
|
|
26
|
+
export declare function getSemanticTokenLegend(): SemanticTokensLegend;
|
|
4
27
|
export declare function symbolKindFromString(kind: string): SymbolKind;
|
|
5
28
|
export declare function scriptElementKindToCompletionItemKind(kind: ts.ScriptElementKind): CompletionItemKind;
|
|
6
29
|
export declare function getCommitCharactersForScriptElement(kind: ts.ScriptElementKind): string[] | undefined;
|
|
@@ -3,12 +3,43 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ensureRealFilePath = exports.ensureRealAstroFilePath = exports.toRealAstroFilePath = exports.toVirtualFilePath = exports.toVirtualAstroFilePath = exports.isVirtualFilePath = exports.isVirtualSvelteFilePath = exports.isVirtualVueFilePath = exports.isVirtualAstroFilePath = exports.isFrameworkFilePath = exports.isAstroFilePath = exports.isVirtualFrameworkFilePath = exports.getFrameworkFromFilePath = exports.convertToLocationRange = exports.convertRange = exports.mapSeverity = exports.getScriptKindFromFileName = exports.isSubPath = exports.findTsConfigPath = exports.getExtensionFromScriptKind = exports.getCommitCharactersForScriptElement = exports.scriptElementKindToCompletionItemKind = exports.symbolKindFromString = void 0;
|
|
6
|
+
exports.ensureRealFilePath = exports.ensureRealAstroFilePath = exports.toRealAstroFilePath = exports.toVirtualFilePath = exports.toVirtualAstroFilePath = exports.isVirtualFilePath = exports.isVirtualSvelteFilePath = exports.isVirtualVueFilePath = exports.isVirtualAstroFilePath = exports.isFrameworkFilePath = exports.isAstroFilePath = exports.isVirtualFrameworkFilePath = exports.getFrameworkFromFilePath = exports.convertToLocationRange = exports.convertRange = exports.mapSeverity = exports.getScriptKindFromFileName = exports.isSubPath = exports.findTsConfigPath = exports.getExtensionFromScriptKind = exports.getCommitCharactersForScriptElement = exports.scriptElementKindToCompletionItemKind = exports.symbolKindFromString = exports.getSemanticTokenLegend = void 0;
|
|
7
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
8
8
|
const path_1 = require("path");
|
|
9
9
|
const utils_1 = require("../../utils");
|
|
10
10
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
11
11
|
const documents_1 = require("../../core/documents");
|
|
12
|
+
function getSemanticTokenLegend() {
|
|
13
|
+
const tokenModifiers = [];
|
|
14
|
+
[
|
|
15
|
+
[0 /* declaration */, vscode_languageserver_1.SemanticTokenModifiers.declaration],
|
|
16
|
+
[1 /* static */, vscode_languageserver_1.SemanticTokenModifiers.static],
|
|
17
|
+
[2 /* async */, vscode_languageserver_1.SemanticTokenModifiers.async],
|
|
18
|
+
[3 /* readonly */, vscode_languageserver_1.SemanticTokenModifiers.readonly],
|
|
19
|
+
[4 /* defaultLibrary */, vscode_languageserver_1.SemanticTokenModifiers.defaultLibrary],
|
|
20
|
+
[5 /* local */, 'local'],
|
|
21
|
+
].forEach(([tsModifier, legend]) => (tokenModifiers[tsModifier] = legend));
|
|
22
|
+
const tokenTypes = [];
|
|
23
|
+
[
|
|
24
|
+
[0 /* class */, vscode_languageserver_1.SemanticTokenTypes.class],
|
|
25
|
+
[1 /* enum */, vscode_languageserver_1.SemanticTokenTypes.enum],
|
|
26
|
+
[2 /* interface */, vscode_languageserver_1.SemanticTokenTypes.interface],
|
|
27
|
+
[3 /* namespace */, vscode_languageserver_1.SemanticTokenTypes.namespace],
|
|
28
|
+
[4 /* typeParameter */, vscode_languageserver_1.SemanticTokenTypes.typeParameter],
|
|
29
|
+
[5 /* type */, vscode_languageserver_1.SemanticTokenTypes.type],
|
|
30
|
+
[6 /* parameter */, vscode_languageserver_1.SemanticTokenTypes.parameter],
|
|
31
|
+
[7 /* variable */, vscode_languageserver_1.SemanticTokenTypes.variable],
|
|
32
|
+
[8 /* enumMember */, vscode_languageserver_1.SemanticTokenTypes.enumMember],
|
|
33
|
+
[9 /* property */, vscode_languageserver_1.SemanticTokenTypes.property],
|
|
34
|
+
[10 /* function */, vscode_languageserver_1.SemanticTokenTypes.function],
|
|
35
|
+
[11 /* method */, vscode_languageserver_1.SemanticTokenTypes.method],
|
|
36
|
+
].forEach(([tokenType, legend]) => (tokenTypes[tokenType] = legend));
|
|
37
|
+
return {
|
|
38
|
+
tokenModifiers,
|
|
39
|
+
tokenTypes,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
exports.getSemanticTokenLegend = getSemanticTokenLegend;
|
|
12
43
|
function symbolKindFromString(kind) {
|
|
13
44
|
switch (kind) {
|
|
14
45
|
case 'module':
|
package/dist/server.js
CHANGED
|
@@ -25,6 +25,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.startLanguageServer = void 0;
|
|
27
27
|
const vscode = __importStar(require("vscode-languageserver"));
|
|
28
|
+
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
28
29
|
const ConfigManager_1 = require("./core/config/ConfigManager");
|
|
29
30
|
const DocumentManager_1 = require("./core/documents/DocumentManager");
|
|
30
31
|
const DiagnosticsManager_1 = require("./core/DiagnosticsManager");
|
|
@@ -32,8 +33,9 @@ const AstroPlugin_1 = require("./plugins/astro/AstroPlugin");
|
|
|
32
33
|
const CSSPlugin_1 = require("./plugins/css/CSSPlugin");
|
|
33
34
|
const HTMLPlugin_1 = require("./plugins/html/HTMLPlugin");
|
|
34
35
|
const PluginHost_1 = require("./plugins/PluginHost");
|
|
35
|
-
const
|
|
36
|
+
const plugins_1 = require("./plugins");
|
|
36
37
|
const utils_1 = require("./utils");
|
|
38
|
+
const utils_2 = require("./plugins/typescript/utils");
|
|
37
39
|
const TagCloseRequest = new vscode.RequestType('html/tag');
|
|
38
40
|
// Start the language server
|
|
39
41
|
function startLanguageServer(connection) {
|
|
@@ -54,7 +56,7 @@ function startLanguageServer(connection) {
|
|
|
54
56
|
// We don't currently support running the TypeScript and Astro plugin in the browser
|
|
55
57
|
if (params.initializationOptions.environment !== 'browser') {
|
|
56
58
|
pluginHost.registerPlugin(new AstroPlugin_1.AstroPlugin(documentManager, configManager, workspaceUris));
|
|
57
|
-
pluginHost.registerPlugin(new
|
|
59
|
+
pluginHost.registerPlugin(new plugins_1.TypeScriptPlugin(documentManager, configManager, workspaceUris));
|
|
58
60
|
}
|
|
59
61
|
// Update language-server config with what the user supplied to us at launch
|
|
60
62
|
configManager.updateConfig(params.initializationOptions.configuration.astro);
|
|
@@ -97,6 +99,11 @@ function startLanguageServer(connection) {
|
|
|
97
99
|
colorProvider: true,
|
|
98
100
|
hoverProvider: true,
|
|
99
101
|
documentSymbolProvider: true,
|
|
102
|
+
semanticTokensProvider: {
|
|
103
|
+
legend: (0, utils_2.getSemanticTokenLegend)(),
|
|
104
|
+
range: true,
|
|
105
|
+
full: true,
|
|
106
|
+
},
|
|
100
107
|
signatureHelpProvider: {
|
|
101
108
|
triggerCharacters: ['(', ',', '<'],
|
|
102
109
|
retriggerCharacters: [')'],
|
|
@@ -146,6 +153,8 @@ function startLanguageServer(connection) {
|
|
|
146
153
|
return pluginHost.resolveCompletion(data, completionItem);
|
|
147
154
|
});
|
|
148
155
|
connection.onDocumentSymbol((params, cancellationToken) => pluginHost.getDocumentSymbols(params.textDocument, cancellationToken));
|
|
156
|
+
connection.onRequest(vscode_languageserver_1.SemanticTokensRequest.type, (evt, cancellationToken) => pluginHost.getSemanticTokens(evt.textDocument, undefined, cancellationToken));
|
|
157
|
+
connection.onRequest(vscode_languageserver_1.SemanticTokensRangeRequest.type, (evt, cancellationToken) => pluginHost.getSemanticTokens(evt.textDocument, evt.range, cancellationToken));
|
|
149
158
|
connection.onDocumentColor((params) => pluginHost.getDocumentColors(params.textDocument));
|
|
150
159
|
connection.onColorPresentation((params) => pluginHost.getColorPresentations(params.textDocument, params.range, params.color));
|
|
151
160
|
connection.onRequest(TagCloseRequest, (evt) => pluginHost.doTagComplete(evt.textDocument, evt.position));
|
package/dist/utils.d.ts
CHANGED
|
@@ -21,11 +21,6 @@ export declare function getLastPartOfPath(path: string): string;
|
|
|
21
21
|
* This is not a 100% sure test as it'll return false for any component that does not match the standard format for a component
|
|
22
22
|
*/
|
|
23
23
|
export declare function isPossibleComponent(node: Node): boolean;
|
|
24
|
-
/**
|
|
25
|
-
* Return true if a specific node could be a component with a client directive on it.
|
|
26
|
-
* This is not a 100% sure test as it'll return false for any component that does not match the standard format for a component
|
|
27
|
-
*/
|
|
28
|
-
export declare function isPossibleClientComponent(node: Node): boolean;
|
|
29
24
|
/** Flattens an array */
|
|
30
25
|
export declare function flatten<T>(arr: T[][]): T[];
|
|
31
26
|
/** Clamps a number between min and max */
|
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.debounceThrottle = exports.debounceSameArg = exports.isBeforeOrEqualToPosition = exports.isInRange = exports.isNotNullOrUndefined = exports.clamp = exports.flatten = exports.
|
|
3
|
+
exports.debounceThrottle = exports.debounceSameArg = exports.isBeforeOrEqualToPosition = exports.isInRange = exports.isNotNullOrUndefined = exports.clamp = exports.flatten = exports.isPossibleComponent = exports.getLastPartOfPath = exports.pathToUrl = exports.urlToPath = exports.normalizePath = exports.normalizeUri = void 0;
|
|
4
4
|
const vscode_uri_1 = require("vscode-uri");
|
|
5
5
|
/** Normalizes a document URI */
|
|
6
6
|
function normalizeUri(uri) {
|
|
@@ -46,21 +46,6 @@ function isPossibleComponent(node) {
|
|
|
46
46
|
return !!((_a = node.tag) === null || _a === void 0 ? void 0 : _a[0].match(/[A-Z]/)) || !!((_b = node.tag) === null || _b === void 0 ? void 0 : _b.match(/.+[.][A-Z]/));
|
|
47
47
|
}
|
|
48
48
|
exports.isPossibleComponent = isPossibleComponent;
|
|
49
|
-
/**
|
|
50
|
-
* Return true if a specific node could be a component with a client directive on it.
|
|
51
|
-
* This is not a 100% sure test as it'll return false for any component that does not match the standard format for a component
|
|
52
|
-
*/
|
|
53
|
-
function isPossibleClientComponent(node) {
|
|
54
|
-
if (isPossibleComponent(node) && node.attributes) {
|
|
55
|
-
for (let [name] of Object.entries(node.attributes)) {
|
|
56
|
-
if (name.startsWith('client:')) {
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
exports.isPossibleClientComponent = isPossibleClientComponent;
|
|
64
49
|
/** Flattens an array */
|
|
65
50
|
function flatten(arr) {
|
|
66
51
|
return arr.reduce((all, item) => [...all, ...item], []);
|