@astrojs/language-server 0.20.3 → 0.22.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/CHANGELOG.md +29 -0
- package/README.md +1 -2
- package/dist/check.js +4 -1
- package/dist/core/config/ConfigManager.d.ts +1 -2
- package/dist/core/config/ConfigManager.js +0 -7
- package/dist/importPackage.d.ts +4 -1
- package/dist/importPackage.js +22 -9
- package/dist/plugins/PluginHost.d.ts +1 -0
- package/dist/plugins/PluginHost.js +4 -0
- package/dist/plugins/astro/AstroPlugin.d.ts +5 -3
- package/dist/plugins/astro/AstroPlugin.js +35 -3
- package/dist/plugins/css/language-service.d.ts +1 -1
- package/dist/plugins/html/HTMLPlugin.d.ts +1 -2
- package/dist/plugins/html/HTMLPlugin.js +0 -18
- package/dist/plugins/interfaces.d.ts +5 -2
- package/dist/plugins/typescript/TypeScriptPlugin.d.ts +8 -5
- package/dist/plugins/typescript/TypeScriptPlugin.js +12 -8
- package/dist/plugins/typescript/astro2tsx.d.ts +1 -2
- package/dist/plugins/typescript/astro2tsx.js +0 -4
- package/dist/plugins/typescript/features/DiagnosticsProvider.js +0 -5
- package/dist/plugins/typescript/features/FoldingRangesProvider.js +1 -1
- package/dist/plugins/typescript/features/TypeDefinitionsProvider.d.ts +9 -0
- package/dist/plugins/typescript/features/TypeDefinitionsProvider.js +55 -0
- package/dist/plugins/typescript/language-service.js +12 -38
- package/dist/plugins/typescript/snapshots/utils.d.ts +1 -0
- package/dist/plugins/typescript/snapshots/utils.js +2 -1
- package/dist/server.js +22 -5
- package/dist/utils.d.ts +9 -7
- package/dist/utils.js +25 -16
- package/package.json +4 -1
- package/types/README.md +5 -0
- package/types/astro-jsx.d.ts +854 -477
- package/types/env.d.ts +22 -0
- package/dist/plugins/typescript/features/FormattingProvider.d.ts +0 -11
- package/dist/plugins/typescript/features/FormattingProvider.js +0 -132
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @astrojs/language-server
|
|
2
2
|
|
|
3
|
+
## 0.22.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- d5aafc0: Formatting is now powered by Prettier and our Prettier plugin. Going forward, this should result in a more stable and complete way of formatting Astro files
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 61620f1: Add support for Go To Type Definition
|
|
12
|
+
- 9337f00: Fix language server not working when no initlizationOptions were passed
|
|
13
|
+
|
|
14
|
+
## 0.21.1
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 0e9d7d0: Improve error handling in cases where we can't load types from the user's project and when the project isn't at the root of the folder
|
|
19
|
+
- 3f79dbf: Fix `tsconfig.json` not loading properly in certain contexts on Windows
|
|
20
|
+
|
|
21
|
+
## 0.21.0
|
|
22
|
+
|
|
23
|
+
### Minor Changes
|
|
24
|
+
|
|
25
|
+
- 574b75d: Remove support for the Markdown component
|
|
26
|
+
- d23ba22: Changed how Astro's types are consumed to avoid making type acquisition explicit inside Astro files
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- 81f3aa5: Added a debug command to show the currently opened document's TSX output
|
|
31
|
+
|
|
3
32
|
## 0.20.3
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -11,6 +11,5 @@ The Astro language server, implement the [language server protocol](https://micr
|
|
|
11
11
|
│ ├── core # Core code such as .astro file parsing, configuration manager, document definition etc
|
|
12
12
|
│ └── plugins # Modules for the different languages supported in .astro files
|
|
13
13
|
├── test # Tests
|
|
14
|
-
|
|
15
|
-
└── astro.d.ts # Types injected into .astro files by the language server
|
|
14
|
+
└── types # Types injected into Astro files by the language server under certain conditions
|
|
16
15
|
```
|
package/dist/check.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.AstroCheck = exports.DiagnosticSeverity = void 0;
|
|
|
4
4
|
const config_1 = require("./core/config");
|
|
5
5
|
const documents_1 = require("./core/documents");
|
|
6
6
|
const plugins_1 = require("./plugins");
|
|
7
|
+
const LanguageServiceManager_1 = require("./plugins/typescript/LanguageServiceManager");
|
|
8
|
+
const utils_1 = require("./utils");
|
|
7
9
|
var vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
|
8
10
|
Object.defineProperty(exports, "DiagnosticSeverity", { enumerable: true, get: function () { return vscode_languageserver_types_1.DiagnosticSeverity; } });
|
|
9
11
|
class AstroCheck {
|
|
@@ -37,7 +39,8 @@ class AstroCheck {
|
|
|
37
39
|
}));
|
|
38
40
|
}
|
|
39
41
|
initialize(workspacePath) {
|
|
40
|
-
|
|
42
|
+
const languageServiceManager = new LanguageServiceManager_1.LanguageServiceManager(this.docManager, [(0, utils_1.normalizeUri)(workspacePath)], this.configManager);
|
|
43
|
+
this.pluginHost.registerPlugin(new plugins_1.TypeScriptPlugin(this.configManager, languageServiceManager));
|
|
41
44
|
}
|
|
42
45
|
async getDiagnosticsForFile(uri) {
|
|
43
46
|
const diagnostics = await this.pluginHost.getDiagnostics({ uri });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VSCodeEmmetConfig } from '@vscode/emmet-helper';
|
|
2
|
-
import { LSConfig, LSCSSConfig,
|
|
2
|
+
import { LSConfig, LSCSSConfig, LSHTMLConfig, LSTypescriptConfig } from './interfaces';
|
|
3
3
|
import { Connection, FormattingOptions } from 'vscode-languageserver';
|
|
4
4
|
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
5
5
|
import { FormatCodeSettings, InlayHintsOptions, UserPreferences } from 'typescript';
|
|
@@ -23,7 +23,6 @@ export declare class ConfigManager {
|
|
|
23
23
|
removeDocument(scopeUri: string): void;
|
|
24
24
|
getConfig<T>(section: string, scopeUri: string): Promise<T | Record<string, any>>;
|
|
25
25
|
getEmmetConfig(document: TextDocument): Promise<VSCodeEmmetConfig>;
|
|
26
|
-
getAstroFormatConfig(document: TextDocument): Promise<LSFormatConfig>;
|
|
27
26
|
getTSFormatConfig(document: TextDocument, vscodeOptions?: FormattingOptions): Promise<FormatCodeSettings>;
|
|
28
27
|
getTSPreferences(document: TextDocument): Promise<UserPreferences>;
|
|
29
28
|
getTSInlayHintsPreferences(document: TextDocument): Promise<InlayHintsOptions>;
|
|
@@ -90,13 +90,6 @@ class ConfigManager {
|
|
|
90
90
|
showSuggestionsAsSnippets: emmetConfig.showSuggestionsAsSnippets ?? false,
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
|
-
async getAstroFormatConfig(document) {
|
|
94
|
-
const astroFormatConfig = (await this.getConfig('astro.format', document.uri)) ?? {};
|
|
95
|
-
return {
|
|
96
|
-
indentFrontmatter: astroFormatConfig.indentFrontmatter ?? exports.defaultLSConfig.format.indentFrontmatter,
|
|
97
|
-
newLineAfterFrontmatter: astroFormatConfig.newLineAfterFrontmatter ?? exports.defaultLSConfig.format.newLineAfterFrontmatter,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
93
|
async getTSFormatConfig(document, vscodeOptions) {
|
|
101
94
|
const formatConfig = (await this.getConfig('typescript.format', document.uri)) ?? {};
|
|
102
95
|
return {
|
package/dist/importPackage.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type * as svelte from '@astrojs/svelte/dist/editor.cjs';
|
|
2
2
|
import type * as vue from '@astrojs/svelte/dist/editor.cjs';
|
|
3
|
+
import type * as prettier from 'prettier';
|
|
3
4
|
export declare function setIsTrusted(_isTrusted: boolean): void;
|
|
4
|
-
export declare function getPackagePath(packageName: string, fromPath: string): string | undefined;
|
|
5
|
+
export declare function getPackagePath(packageName: string, fromPath: string[]): string | undefined;
|
|
5
6
|
export declare function importSvelteIntegration(fromPath: string): typeof svelte | undefined;
|
|
6
7
|
export declare function importVueIntegration(fromPath: string): typeof vue | undefined;
|
|
8
|
+
export declare function importPrettier(fromPath: string): typeof prettier;
|
|
9
|
+
export declare function getPrettierPluginPath(fromPath: string): string;
|
package/dist/importPackage.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.importVueIntegration = exports.importSvelteIntegration = exports.getPackagePath = exports.setIsTrusted = void 0;
|
|
3
|
+
exports.getPrettierPluginPath = exports.importPrettier = exports.importVueIntegration = exports.importSvelteIntegration = exports.getPackagePath = exports.setIsTrusted = void 0;
|
|
4
4
|
const path_1 = require("path");
|
|
5
5
|
let isTrusted = true;
|
|
6
6
|
function setIsTrusted(_isTrusted) {
|
|
@@ -10,13 +10,10 @@ exports.setIsTrusted = setIsTrusted;
|
|
|
10
10
|
function getPackagePath(packageName, fromPath) {
|
|
11
11
|
const paths = [];
|
|
12
12
|
if (isTrusted) {
|
|
13
|
-
paths.unshift(fromPath);
|
|
13
|
+
paths.unshift(...fromPath);
|
|
14
14
|
}
|
|
15
15
|
try {
|
|
16
|
-
|
|
17
|
-
paths,
|
|
18
|
-
});
|
|
19
|
-
return (0, path_1.dirname)(packageJSONPath);
|
|
16
|
+
return (0, path_1.dirname)(require.resolve(packageName + '/package.json', { paths }));
|
|
20
17
|
}
|
|
21
18
|
catch (e) {
|
|
22
19
|
return undefined;
|
|
@@ -24,10 +21,16 @@ function getPackagePath(packageName, fromPath) {
|
|
|
24
21
|
}
|
|
25
22
|
exports.getPackagePath = getPackagePath;
|
|
26
23
|
function importEditorIntegration(packageName, fromPath) {
|
|
27
|
-
const pkgPath = getPackagePath(packageName, fromPath);
|
|
24
|
+
const pkgPath = getPackagePath(packageName, [fromPath]);
|
|
28
25
|
if (pkgPath) {
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
try {
|
|
27
|
+
const main = (0, path_1.resolve)(pkgPath, 'dist', 'editor.cjs');
|
|
28
|
+
return require(main);
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
console.error(`Couldn't load editor module from ${pkgPath}. Make sure you're using at least version v0.2.1 of the corresponding integration`);
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
31
34
|
}
|
|
32
35
|
return undefined;
|
|
33
36
|
}
|
|
@@ -39,3 +42,13 @@ function importVueIntegration(fromPath) {
|
|
|
39
42
|
return importEditorIntegration('@astrojs/vue', fromPath);
|
|
40
43
|
}
|
|
41
44
|
exports.importVueIntegration = importVueIntegration;
|
|
45
|
+
function importPrettier(fromPath) {
|
|
46
|
+
// This shouldn't ever fail, because we bundle Prettier in the extension itself
|
|
47
|
+
const prettierPkg = getPackagePath('prettier', [fromPath, __dirname]);
|
|
48
|
+
return require(prettierPkg);
|
|
49
|
+
}
|
|
50
|
+
exports.importPrettier = importPrettier;
|
|
51
|
+
function getPrettierPluginPath(fromPath) {
|
|
52
|
+
return getPackagePath('prettier-plugin-astro', [fromPath, __dirname]);
|
|
53
|
+
}
|
|
54
|
+
exports.getPrettierPluginPath = getPrettierPluginPath;
|
|
@@ -24,6 +24,7 @@ export declare class PluginHost {
|
|
|
24
24
|
getSemanticTokens(textDocument: TextDocumentIdentifier, range?: Range, cancellationToken?: CancellationToken): Promise<SemanticTokens | null>;
|
|
25
25
|
getLinkedEditingRanges(textDocument: TextDocumentIdentifier, position: Position): Promise<LinkedEditingRanges | null>;
|
|
26
26
|
getDefinitions(textDocument: TextDocumentIdentifier, position: Position): Promise<DefinitionLink[] | Location[]>;
|
|
27
|
+
getTypeDefinition(textDocument: TextDocumentIdentifier, position: Position): Promise<Location[] | null>;
|
|
27
28
|
rename(textDocument: TextDocumentIdentifier, position: Position, newName: string): Promise<WorkspaceEdit | null>;
|
|
28
29
|
getDocumentColors(textDocument: TextDocumentIdentifier): Promise<ColorInformation[]>;
|
|
29
30
|
getColorPresentations(textDocument: TextDocumentIdentifier, range: Range, color: Color): Promise<ColorPresentation[]>;
|
|
@@ -115,6 +115,10 @@ class PluginHost {
|
|
|
115
115
|
return definitions.map((def) => ({ range: def.targetSelectionRange, uri: def.targetUri }));
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
+
getTypeDefinition(textDocument, position) {
|
|
119
|
+
const document = this.getDocument(textDocument.uri);
|
|
120
|
+
return this.execute('getTypeDefinitions', [document, position], ExecuteMode.FirstNonNull);
|
|
121
|
+
}
|
|
118
122
|
async rename(textDocument, position, newName) {
|
|
119
123
|
const document = this.getDocument(textDocument.uri);
|
|
120
124
|
return this.execute('rename', [document, position, newName], ExecuteMode.FirstNonNull);
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { CompletionContext, FoldingRange, Position } from 'vscode-languageserver';
|
|
1
|
+
import { CompletionContext, FoldingRange, Position, TextEdit, FormattingOptions } from 'vscode-languageserver';
|
|
2
2
|
import { ConfigManager } from '../../core/config';
|
|
3
|
-
import { AstroDocument
|
|
3
|
+
import { AstroDocument } from '../../core/documents';
|
|
4
4
|
import { AppCompletionList, Plugin } from '../interfaces';
|
|
5
|
+
import { LanguageServiceManager } from '../typescript/LanguageServiceManager';
|
|
5
6
|
export declare class AstroPlugin implements Plugin {
|
|
6
7
|
__name: string;
|
|
7
8
|
private configManager;
|
|
8
9
|
private readonly languageServiceManager;
|
|
9
10
|
private readonly completionProvider;
|
|
10
|
-
constructor(
|
|
11
|
+
constructor(configManager: ConfigManager, languageServiceManager: LanguageServiceManager);
|
|
11
12
|
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<AppCompletionList | null>;
|
|
13
|
+
formatDocument(document: AstroDocument, options: FormattingOptions): Promise<TextEdit[]>;
|
|
12
14
|
getFoldingRanges(document: AstroDocument): FoldingRange[];
|
|
13
15
|
}
|
|
@@ -2,19 +2,51 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AstroPlugin = void 0;
|
|
4
4
|
const vscode_languageserver_1 = require("vscode-languageserver");
|
|
5
|
-
const
|
|
5
|
+
const importPackage_1 = require("../../importPackage");
|
|
6
|
+
const utils_1 = require("../../utils");
|
|
6
7
|
const CompletionsProvider_1 = require("./features/CompletionsProvider");
|
|
7
8
|
class AstroPlugin {
|
|
8
|
-
constructor(
|
|
9
|
+
constructor(configManager, languageServiceManager) {
|
|
9
10
|
this.__name = 'astro';
|
|
10
11
|
this.configManager = configManager;
|
|
11
|
-
this.languageServiceManager =
|
|
12
|
+
this.languageServiceManager = languageServiceManager;
|
|
12
13
|
this.completionProvider = new CompletionsProvider_1.CompletionsProviderImpl(this.languageServiceManager);
|
|
13
14
|
}
|
|
14
15
|
async getCompletions(document, position, completionContext) {
|
|
15
16
|
const completions = this.completionProvider.getCompletions(document, position, completionContext);
|
|
16
17
|
return completions;
|
|
17
18
|
}
|
|
19
|
+
async formatDocument(document, options) {
|
|
20
|
+
const filePath = document.getFilePath();
|
|
21
|
+
if (!filePath) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
const prettier = (0, importPackage_1.importPrettier)(filePath);
|
|
25
|
+
const prettierConfig = await prettier.resolveConfig(filePath, { editorconfig: true, useCache: false });
|
|
26
|
+
const editorFormatConfig = options !== undefined
|
|
27
|
+
? {
|
|
28
|
+
tabWidth: prettierConfig?.tabWidth ?? options.tabSize,
|
|
29
|
+
useTabs: prettierConfig?.useTabs ?? !options.insertSpaces,
|
|
30
|
+
}
|
|
31
|
+
: {};
|
|
32
|
+
const resultConfig = (0, utils_1.mergeDeep)(prettierConfig ?? {}, editorFormatConfig);
|
|
33
|
+
const fileInfo = await prettier.getFileInfo(filePath, { ignorePath: '.prettierignore' });
|
|
34
|
+
if (fileInfo.ignored) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
const result = prettier.format(document.getText(), {
|
|
38
|
+
...resultConfig,
|
|
39
|
+
plugins: getAstroPrettierPlugin(),
|
|
40
|
+
parser: 'astro',
|
|
41
|
+
});
|
|
42
|
+
return document.getText() === result
|
|
43
|
+
? []
|
|
44
|
+
: [vscode_languageserver_1.TextEdit.replace(vscode_languageserver_1.Range.create(document.positionAt(0), document.positionAt(document.getTextLength())), result)];
|
|
45
|
+
function getAstroPrettierPlugin() {
|
|
46
|
+
const hasPluginLoadedAlready = prettier.getSupportInfo().languages.some((l) => l.name === 'astro');
|
|
47
|
+
return hasPluginLoadedAlready ? [] : [(0, importPackage_1.getPrettierPluginPath)(filePath)];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
18
50
|
getFoldingRanges(document) {
|
|
19
51
|
const foldingRanges = [];
|
|
20
52
|
const { frontmatter } = document.astroMeta;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { LanguageService } from 'vscode-css-languageservice';
|
|
2
|
-
export declare function getLanguage(kind?: string): "css" | "
|
|
2
|
+
export declare function getLanguage(kind?: string): "css" | "less" | "scss";
|
|
3
3
|
export declare function getLanguageService(kind?: string): LanguageService;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CompletionList, Position,
|
|
1
|
+
import { CompletionList, Position, FoldingRange, Hover, SymbolInformation, LinkedEditingRanges } from 'vscode-languageserver';
|
|
2
2
|
import type { Plugin } from '../interfaces';
|
|
3
3
|
import { ConfigManager } from '../../core/config/ConfigManager';
|
|
4
4
|
import { AstroDocument } from '../../core/documents/AstroDocument';
|
|
@@ -15,7 +15,6 @@ export declare class HTMLPlugin implements Plugin {
|
|
|
15
15
|
* Get HTML completions
|
|
16
16
|
*/
|
|
17
17
|
getCompletions(document: AstroDocument, position: Position): Promise<CompletionList | null>;
|
|
18
|
-
formatDocument(document: AstroDocument, options: FormattingOptions): Promise<TextEdit[]>;
|
|
19
18
|
getFoldingRanges(document: AstroDocument): FoldingRange[] | null;
|
|
20
19
|
getLinkedEditingRanges(document: AstroDocument, position: Position): LinkedEditingRanges | null;
|
|
21
20
|
doTagComplete(document: AstroDocument, position: Position): Promise<string | null>;
|
|
@@ -83,24 +83,6 @@ class HTMLPlugin {
|
|
|
83
83
|
// Emmet completions change on every keystroke, so they are never complete
|
|
84
84
|
emmetResults.items.length > 0);
|
|
85
85
|
}
|
|
86
|
-
async formatDocument(document, options) {
|
|
87
|
-
const start = document.positionAt(document.astroMeta.frontmatter.state === 'closed' ? document.astroMeta.frontmatter.endOffset + 3 : 0);
|
|
88
|
-
if (document.astroMeta.frontmatter.state === 'closed') {
|
|
89
|
-
start.line += 1;
|
|
90
|
-
start.character = 0;
|
|
91
|
-
}
|
|
92
|
-
const end = document.positionAt(document.getTextLength());
|
|
93
|
-
const htmlFormatConfig = (await this.configManager.getConfig('html.format', document.uri)) ?? {};
|
|
94
|
-
// The HTML plugin can't format script tags properly, we'll handle those inside the TypeScript plugin
|
|
95
|
-
if (htmlFormatConfig.contentUnformatted) {
|
|
96
|
-
htmlFormatConfig.contentUnformatted = htmlFormatConfig.contentUnformatted + ',script';
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
htmlFormatConfig.contentUnformatted = 'script';
|
|
100
|
-
}
|
|
101
|
-
const edits = this.lang.format(document, vscode_languageserver_1.Range.create(start, end), { ...htmlFormatConfig, ...options });
|
|
102
|
-
return edits;
|
|
103
|
-
}
|
|
104
86
|
getFoldingRanges(document) {
|
|
105
87
|
const html = document.html;
|
|
106
88
|
if (!html) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CodeAction, CodeActionContext, Color, ColorInformation, ColorPresentation, CompletionContext, CompletionItem, CompletionList, DefinitionLink, Diagnostic, FileChangeType, FoldingRange, FormattingOptions, Hover, InlayHint, LinkedEditingRanges, Position, Range, ReferenceContext, SelectionRange, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, TextDocumentIdentifier, TextEdit, WorkspaceEdit } from 'vscode-languageserver';
|
|
1
|
+
import { CodeAction, CodeActionContext, Color, Location, ColorInformation, ColorPresentation, CompletionContext, CompletionItem, CompletionList, DefinitionLink, Diagnostic, FileChangeType, FoldingRange, FormattingOptions, Hover, InlayHint, LinkedEditingRanges, Position, Range, ReferenceContext, SelectionRange, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, TextDocumentIdentifier, TextEdit, WorkspaceEdit } from 'vscode-languageserver';
|
|
2
2
|
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
3
3
|
export declare type Resolvable<T> = T | Promise<T>;
|
|
4
4
|
export interface AppCompletionItem<T extends TextDocumentIdentifier = any> extends CompletionItem {
|
|
@@ -74,6 +74,9 @@ export interface SemanticTokensProvider {
|
|
|
74
74
|
export interface LinkedEditingRangesProvider {
|
|
75
75
|
getLinkedEditingRanges(document: TextDocument, position: Position): Resolvable<LinkedEditingRanges | null>;
|
|
76
76
|
}
|
|
77
|
+
export interface TypeDefinitionProvider {
|
|
78
|
+
getTypeDefinitions(document: TextDocument, position: Position): Resolvable<Location[] | null>;
|
|
79
|
+
}
|
|
77
80
|
export interface OnWatchFileChangesParam {
|
|
78
81
|
fileName: string;
|
|
79
82
|
changeType: FileChangeType;
|
|
@@ -84,7 +87,7 @@ export interface OnWatchFileChangesProvider {
|
|
|
84
87
|
export interface UpdateNonAstroFile {
|
|
85
88
|
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[]): void;
|
|
86
89
|
}
|
|
87
|
-
declare type ProviderBase = DiagnosticsProvider & HoverProvider & CompletionsProvider & DefinitionsProvider & FormattingProvider & FoldingRangesProvider & TagCompleteProvider & DocumentColorsProvider & ColorPresentationsProvider & DocumentSymbolsProvider & UpdateImportsProvider & CodeActionsProvider & FindReferencesProvider & RenameProvider & SignatureHelpProvider & SemanticTokensProvider & SelectionRangeProvider & OnWatchFileChangesProvider & LinkedEditingRangesProvider & InlayHintsProvider & UpdateNonAstroFile;
|
|
90
|
+
declare type ProviderBase = DiagnosticsProvider & HoverProvider & CompletionsProvider & DefinitionsProvider & TypeDefinitionProvider & FormattingProvider & FoldingRangesProvider & TagCompleteProvider & DocumentColorsProvider & ColorPresentationsProvider & DocumentSymbolsProvider & UpdateImportsProvider & CodeActionsProvider & FindReferencesProvider & RenameProvider & SignatureHelpProvider & SemanticTokensProvider & SelectionRangeProvider & OnWatchFileChangesProvider & LinkedEditingRangesProvider & InlayHintsProvider & UpdateNonAstroFile;
|
|
88
91
|
export declare type LSProvider = ProviderBase;
|
|
89
92
|
export declare type Plugin = Partial<ProviderBase> & {
|
|
90
93
|
__name: string;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { CancellationToken, CodeAction, CodeActionContext, CompletionContext, DefinitionLink, Diagnostic, FoldingRange,
|
|
1
|
+
import { CancellationToken, CodeAction, CodeActionContext, CompletionContext, DefinitionLink, Location, Diagnostic, FoldingRange, Hover, InlayHint, Position, Range, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, WorkspaceEdit } from 'vscode-languageserver';
|
|
2
2
|
import { ConfigManager } from '../../core/config';
|
|
3
|
-
import { AstroDocument
|
|
3
|
+
import { AstroDocument } from '../../core/documents';
|
|
4
4
|
import { AppCompletionItem, AppCompletionList, OnWatchFileChangesParam, Plugin } from '../interfaces';
|
|
5
5
|
import { CompletionItemData } from './features/CompletionsProvider';
|
|
6
|
+
import { LanguageServiceManager } from './LanguageServiceManager';
|
|
7
|
+
import { Astro2TSXResult } from './astro2tsx';
|
|
6
8
|
export declare class TypeScriptPlugin implements Plugin {
|
|
7
9
|
__name: string;
|
|
8
10
|
private configManager;
|
|
@@ -11,17 +13,16 @@ export declare class TypeScriptPlugin implements Plugin {
|
|
|
11
13
|
private readonly completionProvider;
|
|
12
14
|
private readonly hoverProvider;
|
|
13
15
|
private readonly definitionsProvider;
|
|
16
|
+
private readonly typeDefinitionsProvider;
|
|
14
17
|
private readonly signatureHelpProvider;
|
|
15
18
|
private readonly diagnosticsProvider;
|
|
16
19
|
private readonly documentSymbolsProvider;
|
|
17
20
|
private readonly inlayHintsProvider;
|
|
18
21
|
private readonly semanticTokensProvider;
|
|
19
22
|
private readonly foldingRangesProvider;
|
|
20
|
-
|
|
21
|
-
constructor(docManager: DocumentManager, configManager: ConfigManager, workspaceUris: string[]);
|
|
23
|
+
constructor(configManager: ConfigManager, languageServiceManager: LanguageServiceManager);
|
|
22
24
|
doHover(document: AstroDocument, position: Position): Promise<Hover | null>;
|
|
23
25
|
rename(document: AstroDocument, position: Position, newName: string): Promise<WorkspaceEdit | null>;
|
|
24
|
-
formatDocument(document: AstroDocument, options: FormattingOptions): Promise<TextEdit[]>;
|
|
25
26
|
getFoldingRanges(document: AstroDocument): Promise<FoldingRange[] | null>;
|
|
26
27
|
getSemanticTokens(document: AstroDocument, range?: Range, cancellationToken?: CancellationToken): Promise<SemanticTokens | null>;
|
|
27
28
|
getDocumentSymbols(document: AstroDocument): Promise<SymbolInformation[]>;
|
|
@@ -30,9 +31,11 @@ export declare class TypeScriptPlugin implements Plugin {
|
|
|
30
31
|
resolveCompletion(document: AstroDocument, completionItem: AppCompletionItem<CompletionItemData>, cancellationToken?: CancellationToken): Promise<AppCompletionItem<CompletionItemData>>;
|
|
31
32
|
getInlayHints(document: AstroDocument, range: Range): Promise<InlayHint[]>;
|
|
32
33
|
getDefinitions(document: AstroDocument, position: Position): Promise<DefinitionLink[]>;
|
|
34
|
+
getTypeDefinition(document: AstroDocument, position: Position): Promise<Location[] | null>;
|
|
33
35
|
getDiagnostics(document: AstroDocument, cancellationToken?: CancellationToken): Promise<Diagnostic[]>;
|
|
34
36
|
onWatchFileChanges(onWatchFileChangesParas: OnWatchFileChangesParam[]): Promise<void>;
|
|
35
37
|
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[]): Promise<void>;
|
|
36
38
|
getSignatureHelp(document: AstroDocument, position: Position, context: SignatureHelpContext | undefined, cancellationToken?: CancellationToken): Promise<SignatureHelp | null>;
|
|
39
|
+
getTSXForDocument(document: AstroDocument): Astro2TSXResult;
|
|
37
40
|
private featureEnabled;
|
|
38
41
|
}
|
|
@@ -10,7 +10,6 @@ const CompletionsProvider_1 = require("./features/CompletionsProvider");
|
|
|
10
10
|
const DiagnosticsProvider_1 = require("./features/DiagnosticsProvider");
|
|
11
11
|
const HoverProvider_1 = require("./features/HoverProvider");
|
|
12
12
|
const SignatureHelpProvider_1 = require("./features/SignatureHelpProvider");
|
|
13
|
-
const LanguageServiceManager_1 = require("./LanguageServiceManager");
|
|
14
13
|
const utils_1 = require("./utils");
|
|
15
14
|
const DocumentSymbolsProvider_1 = require("./features/DocumentSymbolsProvider");
|
|
16
15
|
const SemanticTokenProvider_1 = require("./features/SemanticTokenProvider");
|
|
@@ -18,23 +17,25 @@ const FoldingRangesProvider_1 = require("./features/FoldingRangesProvider");
|
|
|
18
17
|
const CodeActionsProvider_1 = require("./features/CodeActionsProvider");
|
|
19
18
|
const DefinitionsProvider_1 = require("./features/DefinitionsProvider");
|
|
20
19
|
const InlayHintsProvider_1 = require("./features/InlayHintsProvider");
|
|
21
|
-
const
|
|
20
|
+
const astro2tsx_1 = __importDefault(require("./astro2tsx"));
|
|
21
|
+
const utils_2 = require("./snapshots/utils");
|
|
22
|
+
const TypeDefinitionsProvider_1 = require("./features/TypeDefinitionsProvider");
|
|
22
23
|
class TypeScriptPlugin {
|
|
23
|
-
constructor(
|
|
24
|
+
constructor(configManager, languageServiceManager) {
|
|
24
25
|
this.__name = 'typescript';
|
|
25
26
|
this.configManager = configManager;
|
|
26
|
-
this.languageServiceManager =
|
|
27
|
+
this.languageServiceManager = languageServiceManager;
|
|
27
28
|
this.codeActionsProvider = new CodeActionsProvider_1.CodeActionsProviderImpl(this.languageServiceManager, this.configManager);
|
|
28
29
|
this.completionProvider = new CompletionsProvider_1.CompletionsProviderImpl(this.languageServiceManager, this.configManager);
|
|
29
30
|
this.hoverProvider = new HoverProvider_1.HoverProviderImpl(this.languageServiceManager);
|
|
30
31
|
this.definitionsProvider = new DefinitionsProvider_1.DefinitionsProviderImpl(this.languageServiceManager);
|
|
32
|
+
this.typeDefinitionsProvider = new TypeDefinitionsProvider_1.TypeDefinitionsProviderImpl(this.languageServiceManager);
|
|
31
33
|
this.signatureHelpProvider = new SignatureHelpProvider_1.SignatureHelpProviderImpl(this.languageServiceManager);
|
|
32
34
|
this.diagnosticsProvider = new DiagnosticsProvider_1.DiagnosticsProviderImpl(this.languageServiceManager);
|
|
33
35
|
this.documentSymbolsProvider = new DocumentSymbolsProvider_1.DocumentSymbolsProviderImpl(this.languageServiceManager);
|
|
34
36
|
this.semanticTokensProvider = new SemanticTokenProvider_1.SemanticTokensProviderImpl(this.languageServiceManager);
|
|
35
37
|
this.inlayHintsProvider = new InlayHintsProvider_1.InlayHintsProviderImpl(this.languageServiceManager, this.configManager);
|
|
36
38
|
this.foldingRangesProvider = new FoldingRangesProvider_1.FoldingRangesProviderImpl(this.languageServiceManager);
|
|
37
|
-
this.formattingProvider = new FormattingProvider_1.FormattingProviderImpl(this.languageServiceManager, this.configManager);
|
|
38
39
|
}
|
|
39
40
|
async doHover(document, position) {
|
|
40
41
|
if (!(await this.featureEnabled(document, 'hover'))) {
|
|
@@ -65,9 +66,6 @@ class TypeScriptPlugin {
|
|
|
65
66
|
});
|
|
66
67
|
return edit;
|
|
67
68
|
}
|
|
68
|
-
async formatDocument(document, options) {
|
|
69
|
-
return this.formattingProvider.formatDocument(document, options);
|
|
70
|
-
}
|
|
71
69
|
async getFoldingRanges(document) {
|
|
72
70
|
return this.foldingRangesProvider.getFoldingRanges(document);
|
|
73
71
|
}
|
|
@@ -106,6 +104,9 @@ class TypeScriptPlugin {
|
|
|
106
104
|
async getDefinitions(document, position) {
|
|
107
105
|
return this.definitionsProvider.getDefinitions(document, position);
|
|
108
106
|
}
|
|
107
|
+
async getTypeDefinition(document, position) {
|
|
108
|
+
return this.typeDefinitionsProvider.getTypeDefinitions(document, position);
|
|
109
|
+
}
|
|
109
110
|
async getDiagnostics(document, cancellationToken) {
|
|
110
111
|
if (!(await this.featureEnabled(document, 'diagnostics'))) {
|
|
111
112
|
return [];
|
|
@@ -137,6 +138,9 @@ class TypeScriptPlugin {
|
|
|
137
138
|
async getSignatureHelp(document, position, context, cancellationToken) {
|
|
138
139
|
return this.signatureHelpProvider.getSignatureHelp(document, position, context, cancellationToken);
|
|
139
140
|
}
|
|
141
|
+
getTSXForDocument(document) {
|
|
142
|
+
return (0, astro2tsx_1.default)(document.getText(), (0, utils_2.classNameFromFilename)(document.getURL()));
|
|
143
|
+
}
|
|
140
144
|
async featureEnabled(document, feature) {
|
|
141
145
|
return ((await this.configManager.isEnabled(document, 'typescript')) &&
|
|
142
146
|
(await this.configManager.isEnabled(document, 'typescript', feature)));
|
|
@@ -41,10 +41,6 @@ function default_1(content, className) {
|
|
|
41
41
|
// Turn styles tags into internal strings
|
|
42
42
|
.replace(/<\s*style([^>]*)>(.*?)<\s*\/\s*style>/gs, (_whole, attrs, children) => {
|
|
43
43
|
return `<style${attrs}>{\`${escapeTemplateLiteralContent(children)}\`}</style>`;
|
|
44
|
-
})
|
|
45
|
-
// Turn Markdown tags into internal strings
|
|
46
|
-
.replace(/<\s*Markdown([^>]*)>(.*?)<\s*\/\s*Markdown>/gs, (_whole, attrs, children) => {
|
|
47
|
-
return `<Markdown${attrs}>{\`${escapeTemplateLiteralContent(children)}\`}</Markdown>`;
|
|
48
44
|
})
|
|
49
45
|
// Turn scripts into function calls
|
|
50
46
|
.replace(/<\s*script([^\/>]*)>(.*?)<\s*\/\s*script>/gs, (_whole, attrs, children, offset) => {
|
|
@@ -95,7 +95,6 @@ class DiagnosticsProviderImpl {
|
|
|
95
95
|
const sourceFile = program?.getSourceFile(tsFilePath);
|
|
96
96
|
const boundaries = {
|
|
97
97
|
script: [],
|
|
98
|
-
markdown: [],
|
|
99
98
|
};
|
|
100
99
|
if (!sourceFile) {
|
|
101
100
|
return boundaries;
|
|
@@ -110,10 +109,6 @@ class DiagnosticsProviderImpl {
|
|
|
110
109
|
boundaries.script.push([node.getStart(), node.getEnd()]);
|
|
111
110
|
break;
|
|
112
111
|
}
|
|
113
|
-
case 'Markdown': {
|
|
114
|
-
boundaries.markdown.push([node.getStart(), node.getEnd()]);
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
112
|
}
|
|
118
113
|
}
|
|
119
114
|
findTags(node);
|
|
@@ -19,7 +19,7 @@ class FoldingRangesProviderImpl {
|
|
|
19
19
|
const node = html.findNodeAt(span.textSpan.start);
|
|
20
20
|
// Due to how our TSX output transform those tags into function calls or template literals
|
|
21
21
|
// TypeScript thinks of those as outlining spans, which is fine but we don't want folding ranges for those
|
|
22
|
-
return node.tag !== 'script' && node.tag !== 'style'
|
|
22
|
+
return node.tag !== 'script' && node.tag !== 'style';
|
|
23
23
|
});
|
|
24
24
|
const scriptOutliningSpans = [];
|
|
25
25
|
document.scriptTags.forEach((scriptTag) => {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Position, Location } from 'vscode-languageserver-protocol';
|
|
2
|
+
import { AstroDocument } from '../../../core/documents';
|
|
3
|
+
import { TypeDefinitionProvider } from '../../interfaces';
|
|
4
|
+
import { LanguageServiceManager } from '../LanguageServiceManager';
|
|
5
|
+
export declare class TypeDefinitionsProviderImpl implements TypeDefinitionProvider {
|
|
6
|
+
private languageServiceManager;
|
|
7
|
+
constructor(languageServiceManager: LanguageServiceManager);
|
|
8
|
+
getTypeDefinitions(document: AstroDocument, position: Position): Promise<Location[]>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TypeDefinitionsProviderImpl = void 0;
|
|
4
|
+
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
|
|
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 TypeDefinitionsProviderImpl {
|
|
10
|
+
constructor(languageServiceManager) {
|
|
11
|
+
this.languageServiceManager = languageServiceManager;
|
|
12
|
+
}
|
|
13
|
+
async getTypeDefinitions(document, position) {
|
|
14
|
+
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
|
15
|
+
const mainFragment = await tsDoc.createFragment();
|
|
16
|
+
const fragmentOffset = mainFragment.offsetAt(mainFragment.getGeneratedPosition(position));
|
|
17
|
+
const tsFilePath = (0, utils_2.toVirtualAstroFilePath)(tsDoc.filePath);
|
|
18
|
+
const html = document.html;
|
|
19
|
+
const offset = document.offsetAt(position);
|
|
20
|
+
const node = html.findNodeAt(offset);
|
|
21
|
+
let typeDefs;
|
|
22
|
+
if (node.tag === 'script') {
|
|
23
|
+
const { snapshot: scriptTagSnapshot, filePath: scriptFilePath, offset: scriptOffset, } = (0, utils_2.getScriptTagSnapshot)(tsDoc, document, node, position);
|
|
24
|
+
typeDefs = lang.getTypeDefinitionAtPosition(scriptFilePath, scriptOffset);
|
|
25
|
+
if (typeDefs) {
|
|
26
|
+
typeDefs = typeDefs.map((def) => {
|
|
27
|
+
const isInSameFile = def.fileName === scriptFilePath;
|
|
28
|
+
def.fileName = isInSameFile ? tsFilePath : def.fileName;
|
|
29
|
+
if (isInSameFile) {
|
|
30
|
+
def.textSpan.start = mainFragment.offsetAt(scriptTagSnapshot.getOriginalPosition(scriptTagSnapshot.positionAt(def.textSpan.start)));
|
|
31
|
+
}
|
|
32
|
+
return def;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
typeDefs = lang.getTypeDefinitionAtPosition(tsFilePath, fragmentOffset);
|
|
38
|
+
}
|
|
39
|
+
const docs = new utils_3.SnapshotFragmentMap(this.languageServiceManager);
|
|
40
|
+
docs.set(tsFilePath, { fragment: mainFragment, snapshot: tsDoc });
|
|
41
|
+
if (!typeDefs) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
const result = await Promise.all(typeDefs.map(async (typeDef) => {
|
|
45
|
+
const { fragment } = await docs.retrieve(typeDef.fileName);
|
|
46
|
+
const fileName = (0, utils_2.ensureRealFilePath)(typeDef.fileName);
|
|
47
|
+
const range = (0, documents_1.mapRangeToOriginal)(fragment, (0, utils_2.convertRange)(fragment, typeDef.textSpan));
|
|
48
|
+
if (range.start.line >= 0 && range.end.line >= 0) {
|
|
49
|
+
return vscode_languageserver_protocol_1.Location.create((0, utils_1.pathToUrl)(fileName), range);
|
|
50
|
+
}
|
|
51
|
+
}));
|
|
52
|
+
return result.filter(utils_1.isNotNullOrUndefined);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.TypeDefinitionsProviderImpl = TypeDefinitionsProviderImpl;
|