@astrojs/language-server 0.12.0 → 0.13.1
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 +23 -0
- package/dist/core/documents/AstroDocument.d.ts +2 -2
- package/dist/core/documents/AstroDocument.js +6 -1
- package/dist/plugins/PluginHost.d.ts +4 -1
- package/dist/plugins/PluginHost.js +12 -0
- package/dist/plugins/css/CSSPlugin.d.ts +12 -1
- package/dist/plugins/css/CSSPlugin.js +111 -0
- package/dist/plugins/css/features/astro-selectors.js +2 -2
- package/dist/plugins/html/HTMLPlugin.d.ts +4 -1
- package/dist/plugins/html/HTMLPlugin.js +37 -1
- package/dist/plugins/html/features/astro-attributes.d.ts +2 -0
- package/dist/plugins/html/features/astro-attributes.js +126 -0
- package/dist/plugins/typescript/TypeScriptPlugin.d.ts +3 -1
- package/dist/plugins/typescript/TypeScriptPlugin.js +15 -0
- package/dist/plugins/typescript/features/CompletionsProvider.js +1 -1
- package/dist/plugins/typescript/features/DiagnosticsProvider.js +8 -29
- package/dist/plugins/typescript/features/DocumentSymbolsProvider.d.ts +10 -0
- package/dist/plugins/typescript/features/DocumentSymbolsProvider.js +69 -0
- package/dist/plugins/typescript/language-service.js +13 -10
- package/dist/plugins/typescript/snapshots/utils.js +1 -1
- package/dist/plugins/typescript/utils.d.ts +2 -1
- package/dist/plugins/typescript/utils.js +50 -1
- package/dist/server.js +5 -0
- package/dist/utils.d.ts +4 -8
- package/dist/utils.js +6 -10
- package/package.json +1 -1
- package/types/astro-jsx.d.ts +1077 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DocumentSymbolsProviderImpl = void 0;
|
|
4
|
+
const typescript_1 = require("typescript");
|
|
5
|
+
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
|
6
|
+
const documents_1 = require("../../../core/documents");
|
|
7
|
+
const utils_1 = require("../utils");
|
|
8
|
+
const vscode_languageserver_types_2 = require("vscode-languageserver-types");
|
|
9
|
+
class DocumentSymbolsProviderImpl {
|
|
10
|
+
constructor(languageServiceManager) {
|
|
11
|
+
this.languageServiceManager = languageServiceManager;
|
|
12
|
+
}
|
|
13
|
+
async getDocumentSymbols(document) {
|
|
14
|
+
var _a, _b, _c;
|
|
15
|
+
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
16
|
+
const fragment = await tsDoc.createFragment();
|
|
17
|
+
const navTree = lang.getNavigationTree(tsDoc.filePath);
|
|
18
|
+
if (!navTree) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
const symbols = [];
|
|
22
|
+
this.collectSymbols(navTree, fragment, undefined, (symbol) => symbols.push(symbol));
|
|
23
|
+
const result = [];
|
|
24
|
+
// Add a "Frontmatter" namespace for the frontmatter if we have a closed one
|
|
25
|
+
if (document.astroMeta.frontmatter.state === 'closed') {
|
|
26
|
+
result.push(vscode_languageserver_types_1.SymbolInformation.create('Frontmatter', vscode_languageserver_types_1.SymbolKind.Namespace, vscode_languageserver_types_1.Range.create(document.positionAt(document.astroMeta.frontmatter.startOffset), document.positionAt(document.astroMeta.frontmatter.endOffset))));
|
|
27
|
+
}
|
|
28
|
+
// Add a "Template" namespace for everything under the frontmatter
|
|
29
|
+
result.push(vscode_languageserver_types_1.SymbolInformation.create('Template', vscode_languageserver_types_1.SymbolKind.Namespace, vscode_languageserver_types_1.Range.create(document.positionAt((_a = document.astroMeta.frontmatter.endOffset) !== null && _a !== void 0 ? _a : 0), document.positionAt(document.getTextLength()))));
|
|
30
|
+
for (let symbol of symbols.splice(1)) {
|
|
31
|
+
symbol = (0, documents_1.mapSymbolInformationToOriginal)(fragment, symbol);
|
|
32
|
+
if (document.offsetAt(symbol.location.range.end) >= ((_b = document.astroMeta.content.firstNonWhitespaceOffset) !== null && _b !== void 0 ? _b : 0)) {
|
|
33
|
+
symbol.containerName = 'Template';
|
|
34
|
+
// For some reason, it seems like TypeScript thinks that the "class" attribute is a real class, weird
|
|
35
|
+
if (symbol.kind === vscode_languageserver_types_1.SymbolKind.Class && symbol.name === '<class>') {
|
|
36
|
+
const node = document.html.findNodeAt(document.offsetAt(symbol.location.range.start));
|
|
37
|
+
if ((_c = node.attributes) === null || _c === void 0 ? void 0 : _c.class) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Remove the default function detected in our TSX output
|
|
43
|
+
if (symbol.kind === vscode_languageserver_types_1.SymbolKind.Function && symbol.name == 'default') {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
result.push(symbol);
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
collectSymbols(item, fragment, container, cb) {
|
|
51
|
+
for (const span of item.spans) {
|
|
52
|
+
const symbol = vscode_languageserver_types_1.SymbolInformation.create(item.text, (0, utils_1.symbolKindFromString)(item.kind), vscode_languageserver_types_1.Range.create(fragment.positionAt(span.start), fragment.positionAt(span.start + span.length)), fragment.getURL(), container);
|
|
53
|
+
// TypeScript gives us kind modifiers as a string instead of an array
|
|
54
|
+
const kindModifiers = new Set(item.kindModifiers.split(/,|\s+/g));
|
|
55
|
+
if (kindModifiers.has(typescript_1.ScriptElementKindModifier.deprecatedModifier)) {
|
|
56
|
+
if (!symbol.tags)
|
|
57
|
+
symbol.tags = [];
|
|
58
|
+
symbol.tags.push(vscode_languageserver_types_2.SymbolTag.Deprecated);
|
|
59
|
+
}
|
|
60
|
+
cb(symbol);
|
|
61
|
+
}
|
|
62
|
+
if (item.childItems) {
|
|
63
|
+
for (const child of item.childItems) {
|
|
64
|
+
this.collectSymbols(child, fragment, item.text, cb);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.DocumentSymbolsProviderImpl = DocumentSymbolsProviderImpl;
|
|
@@ -70,6 +70,14 @@ async function createLanguageService(tsconfigPath, docContext) {
|
|
|
70
70
|
let projectVersion = 0;
|
|
71
71
|
const snapshotManager = new SnapshotManager_1.SnapshotManager(docContext.globalSnapshotManager, files, fullConfig, workspaceRoot || process.cwd());
|
|
72
72
|
const astroModuleLoader = (0, module_loader_1.createAstroModuleLoader)(getScriptSnapshot, compilerOptions);
|
|
73
|
+
let languageServerDirectory;
|
|
74
|
+
try {
|
|
75
|
+
languageServerDirectory = (0, path_1.dirname)(require.resolve('@astrojs/language-server'));
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
languageServerDirectory = __dirname;
|
|
79
|
+
}
|
|
80
|
+
const astroTSXFile = typescript_1.default.sys.resolvePath((0, path_1.resolve)(languageServerDirectory, '../types/astro-jsx.d.ts'));
|
|
73
81
|
const host = {
|
|
74
82
|
getNewLine: () => typescript_1.default.sys.newLine,
|
|
75
83
|
useCaseSensitiveFileNames: () => typescript_1.default.sys.useCaseSensitiveFileNames,
|
|
@@ -82,7 +90,7 @@ async function createLanguageService(tsconfigPath, docContext) {
|
|
|
82
90
|
getCurrentDirectory: () => workspaceRoot,
|
|
83
91
|
getDefaultLibFileName: typescript_1.default.getDefaultLibFilePath,
|
|
84
92
|
getProjectVersion: () => projectVersion.toString(),
|
|
85
|
-
getScriptFileNames: () => Array.from(new Set([...snapshotManager.getProjectFileNames(), ...snapshotManager.getFileNames()])),
|
|
93
|
+
getScriptFileNames: () => Array.from(new Set([...snapshotManager.getProjectFileNames(), ...snapshotManager.getFileNames(), astroTSXFile])),
|
|
86
94
|
getScriptSnapshot,
|
|
87
95
|
getScriptVersion: (fileName) => getScriptSnapshot(fileName).version.toString(),
|
|
88
96
|
};
|
|
@@ -168,31 +176,26 @@ async function createLanguageService(tsconfigPath, docContext) {
|
|
|
168
176
|
snapshotManager.updateNonAstroFile(fileName, changes);
|
|
169
177
|
}
|
|
170
178
|
function getParsedTSConfig() {
|
|
171
|
-
var _a, _b, _c
|
|
179
|
+
var _a, _b, _c;
|
|
172
180
|
let configJson = (tsconfigPath && typescript_1.default.readConfigFile(tsconfigPath, typescript_1.default.sys.readFile).config) || {};
|
|
173
181
|
// If our user has types in their config but it doesn't include the types needed for Astro, add them to the config
|
|
174
182
|
if (((_a = configJson.compilerOptions) === null || _a === void 0 ? void 0 : _a.types) && !((_b = configJson.compilerOptions) === null || _b === void 0 ? void 0 : _b.types.includes('astro/env'))) {
|
|
175
183
|
configJson.compilerOptions.types.push('astro/env');
|
|
176
184
|
}
|
|
177
185
|
configJson.compilerOptions = Object.assign(getDefaultCompilerOptions(), configJson.compilerOptions);
|
|
178
|
-
// If the user supplied exclude, let's use theirs
|
|
179
|
-
(_c = configJson.exclude) !== null && _c !== void 0 ? _c : (configJson.exclude = getDefaultExclude());
|
|
180
186
|
// Delete include so that .astro files don't get mistakenly excluded by the user
|
|
181
187
|
delete configJson.include;
|
|
182
188
|
// If the user supplied exclude, let's use theirs otherwise, use ours
|
|
183
|
-
(
|
|
189
|
+
(_c = configJson.exclude) !== null && _c !== void 0 ? _c : (configJson.exclude = getDefaultExclude());
|
|
184
190
|
// Everything here will always, unconditionally, be in the resulting config
|
|
185
191
|
const forcedCompilerOptions = {
|
|
186
|
-
// Our TSX is currently not typed, which unfortunately means that we can't support `noImplicitAny`
|
|
187
|
-
noImplicitAny: false,
|
|
188
|
-
// Most of the code people write in an .astro file is in the frontmatter which is executed server side
|
|
189
|
-
// Thus, we don't want the DOM lib. We'll need to overwrite this for script tags however
|
|
190
|
-
lib: ['ESNext'],
|
|
191
192
|
noEmit: true,
|
|
192
193
|
declaration: false,
|
|
193
194
|
allowNonTsExtensions: true,
|
|
194
195
|
allowJs: true,
|
|
195
196
|
jsx: typescript_1.default.JsxEmit.Preserve,
|
|
197
|
+
jsxImportSource: undefined,
|
|
198
|
+
jsxFactory: 'astroHTML',
|
|
196
199
|
module: typescript_1.default.ModuleKind.ESNext,
|
|
197
200
|
target: typescript_1.default.ScriptTarget.ESNext,
|
|
198
201
|
moduleResolution: typescript_1.default.ModuleResolutionKind.NodeJs,
|
|
@@ -77,7 +77,7 @@ function createFromFrameworkFilePath(filePath, framework) {
|
|
|
77
77
|
code = (0, svelte_language_integration_1.toTSX)(originalText);
|
|
78
78
|
}
|
|
79
79
|
else {
|
|
80
|
-
code = 'export default function() {}';
|
|
80
|
+
code = 'export default function(props: Record<string, any>): any {<div></div>}';
|
|
81
81
|
}
|
|
82
82
|
return new DocumentSnapshot_1.TypeScriptDocumentSnapshot(0, filePath, code, typescript_1.default.ScriptKind.TSX);
|
|
83
83
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import { CompletionItemKind, DiagnosticSeverity, Position, Range } from 'vscode-languageserver';
|
|
2
|
+
import { CompletionItemKind, DiagnosticSeverity, Position, Range, SymbolKind } from 'vscode-languageserver';
|
|
3
3
|
import { SnapshotFragment } from './snapshots/DocumentSnapshot';
|
|
4
|
+
export declare function symbolKindFromString(kind: string): SymbolKind;
|
|
4
5
|
export declare function scriptElementKindToCompletionItemKind(kind: ts.ScriptElementKind): CompletionItemKind;
|
|
5
6
|
export declare function getCommitCharactersForScriptElement(kind: ts.ScriptElementKind): string[] | undefined;
|
|
6
7
|
export declare function getExtensionFromScriptKind(kind: ts.ScriptKind | undefined): ts.Extension;
|
|
@@ -3,12 +3,61 @@ 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 = 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 = 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 symbolKindFromString(kind) {
|
|
13
|
+
switch (kind) {
|
|
14
|
+
case 'module':
|
|
15
|
+
return vscode_languageserver_1.SymbolKind.Module;
|
|
16
|
+
case 'class':
|
|
17
|
+
return vscode_languageserver_1.SymbolKind.Class;
|
|
18
|
+
case 'local class':
|
|
19
|
+
return vscode_languageserver_1.SymbolKind.Class;
|
|
20
|
+
case 'interface':
|
|
21
|
+
return vscode_languageserver_1.SymbolKind.Interface;
|
|
22
|
+
case 'enum':
|
|
23
|
+
return vscode_languageserver_1.SymbolKind.Enum;
|
|
24
|
+
case 'enum member':
|
|
25
|
+
return vscode_languageserver_1.SymbolKind.Constant;
|
|
26
|
+
case 'var':
|
|
27
|
+
return vscode_languageserver_1.SymbolKind.Variable;
|
|
28
|
+
case 'local var':
|
|
29
|
+
return vscode_languageserver_1.SymbolKind.Variable;
|
|
30
|
+
case 'function':
|
|
31
|
+
return vscode_languageserver_1.SymbolKind.Function;
|
|
32
|
+
case 'local function':
|
|
33
|
+
return vscode_languageserver_1.SymbolKind.Function;
|
|
34
|
+
case 'method':
|
|
35
|
+
return vscode_languageserver_1.SymbolKind.Method;
|
|
36
|
+
case 'getter':
|
|
37
|
+
return vscode_languageserver_1.SymbolKind.Method;
|
|
38
|
+
case 'setter':
|
|
39
|
+
return vscode_languageserver_1.SymbolKind.Method;
|
|
40
|
+
case 'property':
|
|
41
|
+
return vscode_languageserver_1.SymbolKind.Property;
|
|
42
|
+
case 'constructor':
|
|
43
|
+
return vscode_languageserver_1.SymbolKind.Constructor;
|
|
44
|
+
case 'parameter':
|
|
45
|
+
return vscode_languageserver_1.SymbolKind.Variable;
|
|
46
|
+
case 'type parameter':
|
|
47
|
+
return vscode_languageserver_1.SymbolKind.Variable;
|
|
48
|
+
case 'alias':
|
|
49
|
+
return vscode_languageserver_1.SymbolKind.Variable;
|
|
50
|
+
case 'let':
|
|
51
|
+
return vscode_languageserver_1.SymbolKind.Variable;
|
|
52
|
+
case 'const':
|
|
53
|
+
return vscode_languageserver_1.SymbolKind.Constant;
|
|
54
|
+
case 'JSX attribute':
|
|
55
|
+
return vscode_languageserver_1.SymbolKind.Property;
|
|
56
|
+
default:
|
|
57
|
+
return vscode_languageserver_1.SymbolKind.Variable;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.symbolKindFromString = symbolKindFromString;
|
|
12
61
|
function scriptElementKindToCompletionItemKind(kind) {
|
|
13
62
|
switch (kind) {
|
|
14
63
|
case typescript_1.default.ScriptElementKind.primitiveType:
|
package/dist/server.js
CHANGED
|
@@ -94,7 +94,9 @@ function startLanguageServer(connection) {
|
|
|
94
94
|
':',
|
|
95
95
|
],
|
|
96
96
|
},
|
|
97
|
+
colorProvider: true,
|
|
97
98
|
hoverProvider: true,
|
|
99
|
+
documentSymbolProvider: true,
|
|
98
100
|
signatureHelpProvider: {
|
|
99
101
|
triggerCharacters: ['(', ',', '<'],
|
|
100
102
|
retriggerCharacters: [')'],
|
|
@@ -143,6 +145,9 @@ function startLanguageServer(connection) {
|
|
|
143
145
|
}
|
|
144
146
|
return pluginHost.resolveCompletion(data, completionItem);
|
|
145
147
|
});
|
|
148
|
+
connection.onDocumentSymbol((params, cancellationToken) => pluginHost.getDocumentSymbols(params.textDocument, cancellationToken));
|
|
149
|
+
connection.onDocumentColor((params) => pluginHost.getDocumentColors(params.textDocument));
|
|
150
|
+
connection.onColorPresentation((params) => pluginHost.getColorPresentations(params.textDocument, params.range, params.color));
|
|
146
151
|
connection.onRequest(TagCloseRequest, (evt) => pluginHost.doTagComplete(evt.textDocument, evt.position));
|
|
147
152
|
connection.onSignatureHelp((evt, cancellationToken) => pluginHost.getSignatureHelp(evt.textDocument, evt.position, evt.context, cancellationToken));
|
|
148
153
|
connection.onRenameRequest((evt) => pluginHost.rename(evt.textDocument, evt.position, evt.newName));
|
package/dist/utils.d.ts
CHANGED
|
@@ -17,17 +17,13 @@ export declare function pathToUrl(path: string): string;
|
|
|
17
17
|
*/
|
|
18
18
|
export declare function getLastPartOfPath(path: string): string;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* hover info for Svelte components like `Option` which have
|
|
23
|
-
* the same name like a html tag.
|
|
20
|
+
* Return true if a specific node could be a component.
|
|
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
|
|
24
22
|
*/
|
|
25
23
|
export declare function isPossibleComponent(node: Node): boolean;
|
|
26
24
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* hover info for Svelte components like `Option` which have
|
|
30
|
-
* the same name like a html tag.
|
|
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
|
|
31
27
|
*/
|
|
32
28
|
export declare function isPossibleClientComponent(node: Node): boolean;
|
|
33
29
|
/** Flattens an array */
|
package/dist/utils.js
CHANGED
|
@@ -38,21 +38,17 @@ function getLastPartOfPath(path) {
|
|
|
38
38
|
}
|
|
39
39
|
exports.getLastPartOfPath = getLastPartOfPath;
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* hover info for Svelte components like `Option` which have
|
|
44
|
-
* the same name like a html tag.
|
|
41
|
+
* Return true if a specific node could be a component.
|
|
42
|
+
* 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
|
|
45
43
|
*/
|
|
46
44
|
function isPossibleComponent(node) {
|
|
47
|
-
var _a;
|
|
48
|
-
return !!((_a = node.tag) === null || _a === void 0 ? void 0 : _a[0].match(/[A-Z]/));
|
|
45
|
+
var _a, _b;
|
|
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]/));
|
|
49
47
|
}
|
|
50
48
|
exports.isPossibleComponent = isPossibleComponent;
|
|
51
49
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* hover info for Svelte components like `Option` which have
|
|
55
|
-
* the same name like a html tag.
|
|
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
|
|
56
52
|
*/
|
|
57
53
|
function isPossibleClientComponent(node) {
|
|
58
54
|
if (isPossibleComponent(node) && node.attributes) {
|