🎉 initiate project *astro_rewrite*
This commit is contained in:
parent
ffd4d5e86c
commit
2ba37bfbe3
8658 changed files with 2268794 additions and 2538 deletions
1
node_modules/@astrojs/language-server/dist/browser.d.ts
generated
vendored
Normal file
1
node_modules/@astrojs/language-server/dist/browser.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
export {};
|
||||
15
node_modules/@astrojs/language-server/dist/browser.js
generated
vendored
Normal file
15
node_modules/@astrojs/language-server/dist/browser.js
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const browser_1 = require("vscode-languageserver/browser");
|
||||
const server_1 = require("./server");
|
||||
const messageReader = new browser_1.BrowserMessageReader(self);
|
||||
const messageWriter = new browser_1.BrowserMessageWriter(self);
|
||||
const connection = (0, browser_1.createConnection)(messageReader, messageWriter);
|
||||
(0, server_1.startLanguageServer)(connection, {
|
||||
loadTypescript(options) {
|
||||
return undefined; // TODO: Full browser support
|
||||
},
|
||||
loadTypescriptLocalized(options) {
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
23
node_modules/@astrojs/language-server/dist/check.d.ts
generated
vendored
Normal file
23
node_modules/@astrojs/language-server/dist/check.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import type { Diagnostic } from 'vscode-languageserver-types';
|
||||
import { LSConfig } from './core/config';
|
||||
export { DiagnosticSeverity } from 'vscode-languageserver-types';
|
||||
export { Diagnostic };
|
||||
export interface GetDiagnosticsResult {
|
||||
fileUri: string;
|
||||
text: string;
|
||||
diagnostics: Diagnostic[];
|
||||
}
|
||||
export declare class AstroCheck {
|
||||
private docManager;
|
||||
private configManager;
|
||||
private pluginHost;
|
||||
constructor(workspacePath: string, typescriptPath: string, options?: LSConfig);
|
||||
upsertDocument(doc: {
|
||||
text: string;
|
||||
uri: string;
|
||||
}): void;
|
||||
removeDocument(uri: string): void;
|
||||
getDiagnostics(): Promise<GetDiagnosticsResult[]>;
|
||||
private initialize;
|
||||
private getDiagnosticsForFile;
|
||||
}
|
||||
60
node_modules/@astrojs/language-server/dist/check.js
generated
vendored
Normal file
60
node_modules/@astrojs/language-server/dist/check.js
generated
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AstroCheck = exports.DiagnosticSeverity = void 0;
|
||||
const config_1 = require("./core/config");
|
||||
const documents_1 = require("./core/documents");
|
||||
const plugins_1 = require("./plugins");
|
||||
const LanguageServiceManager_1 = require("./plugins/typescript/LanguageServiceManager");
|
||||
const utils_1 = require("./utils");
|
||||
var vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
||||
Object.defineProperty(exports, "DiagnosticSeverity", { enumerable: true, get: function () { return vscode_languageserver_types_1.DiagnosticSeverity; } });
|
||||
class AstroCheck {
|
||||
constructor(workspacePath, typescriptPath, options) {
|
||||
this.docManager = documents_1.DocumentManager.newInstance();
|
||||
this.configManager = new config_1.ConfigManager();
|
||||
this.pluginHost = new plugins_1.PluginHost(this.docManager);
|
||||
try {
|
||||
const ts = require(typescriptPath);
|
||||
this.initialize(workspacePath, ts);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Couldn't load TypeScript from path ${typescriptPath}`);
|
||||
}
|
||||
if (options) {
|
||||
this.configManager.updateGlobalConfig(options);
|
||||
}
|
||||
}
|
||||
upsertDocument(doc) {
|
||||
this.docManager.openDocument({
|
||||
text: doc.text,
|
||||
uri: doc.uri,
|
||||
});
|
||||
this.docManager.markAsOpenedInClient(doc.uri);
|
||||
}
|
||||
removeDocument(uri) {
|
||||
if (!this.docManager.get(uri)) {
|
||||
return;
|
||||
}
|
||||
this.docManager.closeDocument(uri);
|
||||
this.docManager.releaseDocument(uri);
|
||||
}
|
||||
async getDiagnostics() {
|
||||
return await Promise.all(this.docManager.getAllOpenedByClient().map(async (doc) => {
|
||||
const uri = doc[1].uri;
|
||||
return await this.getDiagnosticsForFile(uri);
|
||||
}));
|
||||
}
|
||||
initialize(workspacePath, ts) {
|
||||
const languageServiceManager = new LanguageServiceManager_1.LanguageServiceManager(this.docManager, [(0, utils_1.normalizeUri)(workspacePath)], this.configManager, ts);
|
||||
this.pluginHost.registerPlugin(new plugins_1.TypeScriptPlugin(this.configManager, languageServiceManager));
|
||||
}
|
||||
async getDiagnosticsForFile(uri) {
|
||||
const diagnostics = await this.pluginHost.getDiagnostics({ uri });
|
||||
return {
|
||||
fileUri: uri || '',
|
||||
text: this.docManager.get(uri)?.getText() || '',
|
||||
diagnostics,
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.AstroCheck = AstroCheck;
|
||||
13
node_modules/@astrojs/language-server/dist/core/DiagnosticsManager.d.ts
generated
vendored
Normal file
13
node_modules/@astrojs/language-server/dist/core/DiagnosticsManager.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import type { Connection, Diagnostic, TextDocumentIdentifier } from 'vscode-languageserver';
|
||||
import type { AstroDocument, DocumentManager } from './documents';
|
||||
export type SendDiagnostics = Connection['sendDiagnostics'];
|
||||
export type GetDiagnostics = (doc: TextDocumentIdentifier) => Thenable<Diagnostic[]>;
|
||||
export declare class DiagnosticsManager {
|
||||
private sendDiagnostics;
|
||||
private docManager;
|
||||
private getDiagnostics;
|
||||
constructor(sendDiagnostics: SendDiagnostics, docManager: DocumentManager, getDiagnostics: GetDiagnostics);
|
||||
updateAll(): void;
|
||||
update(document: AstroDocument): Promise<void>;
|
||||
removeDiagnostics(document: AstroDocument): void;
|
||||
}
|
||||
29
node_modules/@astrojs/language-server/dist/core/DiagnosticsManager.js
generated
vendored
Normal file
29
node_modules/@astrojs/language-server/dist/core/DiagnosticsManager.js
generated
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.DiagnosticsManager = void 0;
|
||||
class DiagnosticsManager {
|
||||
constructor(sendDiagnostics, docManager, getDiagnostics) {
|
||||
this.sendDiagnostics = sendDiagnostics;
|
||||
this.docManager = docManager;
|
||||
this.getDiagnostics = getDiagnostics;
|
||||
}
|
||||
updateAll() {
|
||||
this.docManager.getAllOpenedByClient().forEach((doc) => {
|
||||
this.update(doc[1]);
|
||||
});
|
||||
}
|
||||
async update(document) {
|
||||
const diagnostics = await this.getDiagnostics({ uri: document.getURL() });
|
||||
this.sendDiagnostics({
|
||||
uri: document.getURL(),
|
||||
diagnostics,
|
||||
});
|
||||
}
|
||||
removeDiagnostics(document) {
|
||||
this.sendDiagnostics({
|
||||
uri: document.getURL(),
|
||||
diagnostics: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.DiagnosticsManager = DiagnosticsManager;
|
||||
43
node_modules/@astrojs/language-server/dist/core/config/ConfigManager.d.ts
generated
vendored
Normal file
43
node_modules/@astrojs/language-server/dist/core/config/ConfigManager.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import type { VSCodeEmmetConfig } from '@vscode/emmet-helper';
|
||||
import type { FormatCodeSettings, UserPreferences } from 'typescript';
|
||||
import type { Connection, FormattingOptions } from 'vscode-languageserver';
|
||||
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
import type { LSConfig, LSCSSConfig, LSHTMLConfig, LSTypescriptConfig } from './interfaces';
|
||||
export declare const defaultLSConfig: LSConfig;
|
||||
type DeepPartial<T> = T extends Record<string, unknown> ? {
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
} : T;
|
||||
/**
|
||||
* Manager class to facilitate accessing and updating the user's config
|
||||
* Not to be confused with other kind of configurations (such as the Astro project configuration and the TypeScript/Javascript one)
|
||||
* For more info on this, see the [internal docs](../../../../../docs/internal/language-server/config.md)
|
||||
*/
|
||||
export declare class ConfigManager {
|
||||
private connection?;
|
||||
private hasConfigurationCapability?;
|
||||
private globalConfig;
|
||||
private documentSettings;
|
||||
shouldRefreshTSServices: boolean;
|
||||
private isTrusted;
|
||||
constructor(connection?: Connection | undefined, hasConfigurationCapability?: boolean | undefined);
|
||||
updateConfig(): void;
|
||||
removeDocument(scopeUri: string): void;
|
||||
getConfig<T>(section: string, scopeUri: string): Promise<T | Record<string, any>>;
|
||||
getEmmetConfig(document: TextDocument): Promise<VSCodeEmmetConfig>;
|
||||
getPrettierVSConfig(document: TextDocument): Promise<Record<string, any>>;
|
||||
getTSFormatConfig(document: TextDocument, vscodeOptions?: FormattingOptions): Promise<FormatCodeSettings>;
|
||||
getTSPreferences(document: TextDocument): Promise<UserPreferences>;
|
||||
/**
|
||||
* Return true if a plugin and an optional feature is enabled
|
||||
*/
|
||||
isEnabled(document: TextDocument, plugin: keyof LSConfig, feature?: keyof LSTypescriptConfig | keyof LSCSSConfig | keyof LSHTMLConfig): Promise<boolean>;
|
||||
/**
|
||||
* Updating the global config should only be done in cases where the client doesn't support `workspace/configuration`
|
||||
* or inside of tests.
|
||||
*
|
||||
* The `outsideAstro` parameter can be set to true to change configurations in the global scope.
|
||||
* For example, to change TypeScript settings
|
||||
*/
|
||||
updateGlobalConfig(config: DeepPartial<LSConfig> | any, outsideAstro?: boolean): void;
|
||||
}
|
||||
export {};
|
||||
226
node_modules/@astrojs/language-server/dist/core/config/ConfigManager.js
generated
vendored
Normal file
226
node_modules/@astrojs/language-server/dist/core/config/ConfigManager.js
generated
vendored
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ConfigManager = exports.defaultLSConfig = void 0;
|
||||
const utils_1 = require("../../utils");
|
||||
// The default language server configuration is used only in two cases:
|
||||
// 1. When the client does not support `workspace/configuration` requests and as such, needs a global config
|
||||
// 2. Inside tests, where we don't have a client connection because.. well.. we don't have a client
|
||||
// Additionally, the default config is used to set default settings for some settings (ex: formatting settings)
|
||||
exports.defaultLSConfig = {
|
||||
typescript: {
|
||||
enabled: true,
|
||||
allowArbitraryAttributes: false,
|
||||
diagnostics: { enabled: true },
|
||||
hover: { enabled: true },
|
||||
completions: { enabled: true },
|
||||
definitions: { enabled: true },
|
||||
documentSymbols: { enabled: true },
|
||||
codeActions: { enabled: true },
|
||||
rename: { enabled: true },
|
||||
signatureHelp: { enabled: true },
|
||||
semanticTokens: { enabled: true },
|
||||
},
|
||||
css: {
|
||||
enabled: true,
|
||||
hover: { enabled: true },
|
||||
completions: { enabled: true, emmet: true },
|
||||
documentColors: { enabled: true },
|
||||
documentSymbols: { enabled: true },
|
||||
},
|
||||
html: {
|
||||
enabled: true,
|
||||
hover: { enabled: true },
|
||||
completions: { enabled: true, emmet: true },
|
||||
tagComplete: { enabled: true },
|
||||
documentSymbols: { enabled: true },
|
||||
},
|
||||
format: {
|
||||
indentFrontmatter: false,
|
||||
newLineAfterFrontmatter: true,
|
||||
},
|
||||
};
|
||||
/**
|
||||
* Manager class to facilitate accessing and updating the user's config
|
||||
* Not to be confused with other kind of configurations (such as the Astro project configuration and the TypeScript/Javascript one)
|
||||
* For more info on this, see the [internal docs](../../../../../docs/internal/language-server/config.md)
|
||||
*/
|
||||
class ConfigManager {
|
||||
constructor(connection, hasConfigurationCapability) {
|
||||
this.connection = connection;
|
||||
this.hasConfigurationCapability = hasConfigurationCapability;
|
||||
this.globalConfig = { astro: exports.defaultLSConfig };
|
||||
this.documentSettings = {};
|
||||
// If set to true, the next time we need a TypeScript language service, we'll rebuild it so it gets the new config
|
||||
this.shouldRefreshTSServices = false;
|
||||
this.isTrusted = true;
|
||||
}
|
||||
updateConfig() {
|
||||
// Reset all cached document settings
|
||||
this.documentSettings = {};
|
||||
this.shouldRefreshTSServices = true;
|
||||
}
|
||||
removeDocument(scopeUri) {
|
||||
delete this.documentSettings[scopeUri];
|
||||
}
|
||||
async getConfig(section, scopeUri) {
|
||||
if (!this.connection || !this.hasConfigurationCapability) {
|
||||
return (0, utils_1.get)(this.globalConfig, section) ?? {};
|
||||
}
|
||||
if (!this.documentSettings[scopeUri]) {
|
||||
this.documentSettings[scopeUri] = {};
|
||||
}
|
||||
if (!this.documentSettings[scopeUri][section]) {
|
||||
this.documentSettings[scopeUri][section] = await this.connection.workspace.getConfiguration({
|
||||
scopeUri,
|
||||
section,
|
||||
});
|
||||
}
|
||||
return this.documentSettings[scopeUri][section];
|
||||
}
|
||||
async getEmmetConfig(document) {
|
||||
const emmetConfig = (await this.getConfig('emmet', document.uri)) ?? {};
|
||||
return {
|
||||
...emmetConfig,
|
||||
preferences: emmetConfig.preferences ?? {},
|
||||
showExpandedAbbreviation: emmetConfig.showExpandedAbbreviation ?? 'always',
|
||||
showAbbreviationSuggestions: emmetConfig.showAbbreviationSuggestions ?? true,
|
||||
syntaxProfiles: emmetConfig.syntaxProfiles ?? {},
|
||||
variables: emmetConfig.variables ?? {},
|
||||
excludeLanguages: emmetConfig.excludeLanguages ?? [],
|
||||
showSuggestionsAsSnippets: emmetConfig.showSuggestionsAsSnippets ?? false,
|
||||
};
|
||||
}
|
||||
async getPrettierVSConfig(document) {
|
||||
const prettierVSConfig = (await this.getConfig('prettier', document.uri)) ?? {};
|
||||
return prettierVSConfig;
|
||||
}
|
||||
async getTSFormatConfig(document, vscodeOptions) {
|
||||
const formatConfig = (await this.getConfig('typescript.format', document.uri)) ?? {};
|
||||
return {
|
||||
tabSize: vscodeOptions?.tabSize,
|
||||
indentSize: vscodeOptions?.tabSize,
|
||||
convertTabsToSpaces: vscodeOptions?.insertSpaces,
|
||||
// We can use \n here since the editor normalizes later on to its line endings.
|
||||
newLineCharacter: '\n',
|
||||
insertSpaceAfterCommaDelimiter: formatConfig.insertSpaceAfterCommaDelimiter ?? true,
|
||||
insertSpaceAfterConstructor: formatConfig.insertSpaceAfterConstructor ?? false,
|
||||
insertSpaceAfterSemicolonInForStatements: formatConfig.insertSpaceAfterSemicolonInForStatements ?? true,
|
||||
insertSpaceBeforeAndAfterBinaryOperators: formatConfig.insertSpaceBeforeAndAfterBinaryOperators ?? true,
|
||||
insertSpaceAfterKeywordsInControlFlowStatements: formatConfig.insertSpaceAfterKeywordsInControlFlowStatements ?? true,
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions: formatConfig.insertSpaceAfterFunctionKeywordForAnonymousFunctions ?? true,
|
||||
insertSpaceBeforeFunctionParenthesis: formatConfig.insertSpaceBeforeFunctionParenthesis ?? false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: formatConfig.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis ?? false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: formatConfig.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets ?? false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: formatConfig.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces ?? true,
|
||||
insertSpaceAfterOpeningAndBeforeClosingEmptyBraces: formatConfig.insertSpaceAfterOpeningAndBeforeClosingEmptyBraces ?? true,
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: formatConfig.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces ?? false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: formatConfig.insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces ?? false,
|
||||
insertSpaceAfterTypeAssertion: formatConfig.insertSpaceAfterTypeAssertion ?? false,
|
||||
placeOpenBraceOnNewLineForFunctions: formatConfig.placeOpenBraceOnNewLineForFunctions ?? false,
|
||||
placeOpenBraceOnNewLineForControlBlocks: formatConfig.placeOpenBraceOnNewLineForControlBlocks ?? false,
|
||||
semicolons: formatConfig.semicolons ?? 'ignore',
|
||||
};
|
||||
}
|
||||
async getTSPreferences(document) {
|
||||
const config = (await this.getConfig('typescript', document.uri)) ?? {};
|
||||
const preferences = (await this.getConfig('typescript.preferences', document.uri)) ?? {};
|
||||
return {
|
||||
quotePreference: getQuoteStylePreference(preferences),
|
||||
importModuleSpecifierPreference: getImportModuleSpecifierPreference(preferences),
|
||||
importModuleSpecifierEnding: getImportModuleSpecifierEndingPreference(preferences),
|
||||
allowTextChangesInNewFiles: document.uri.startsWith('file://'),
|
||||
providePrefixAndSuffixTextForRename: (preferences.renameShorthandProperties ?? true) === false ? false : preferences.useAliasesForRenames ?? true,
|
||||
includeAutomaticOptionalChainCompletions: config.suggest?.includeAutomaticOptionalChainCompletions ?? true,
|
||||
includeCompletionsForImportStatements: config.suggest?.includeCompletionsForImportStatements ?? true,
|
||||
includeCompletionsWithSnippetText: config.suggest?.includeCompletionsWithSnippetText ?? true,
|
||||
includeCompletionsForModuleExports: config.suggest?.autoImports ?? true,
|
||||
allowIncompleteCompletions: true,
|
||||
includeCompletionsWithInsertText: true,
|
||||
// Inlay Hints
|
||||
includeInlayParameterNameHints: getInlayParameterNameHintsPreference(config),
|
||||
includeInlayParameterNameHintsWhenArgumentMatchesName: !(config.inlayHints?.parameterNames?.suppressWhenArgumentMatchesName ?? true),
|
||||
includeInlayFunctionParameterTypeHints: config.inlayHints?.parameterTypes?.enabled ?? false,
|
||||
includeInlayVariableTypeHints: config.inlayHints?.variableTypes?.enabled ?? false,
|
||||
includeInlayPropertyDeclarationTypeHints: config.inlayHints?.propertyDeclarationTypes?.enabled ?? false,
|
||||
includeInlayFunctionLikeReturnTypeHints: config.inlayHints?.functionLikeReturnTypes?.enabled ?? false,
|
||||
includeInlayEnumMemberValueHints: config.inlayHints?.enumMemberValues?.enabled ?? false,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Return true if a plugin and an optional feature is enabled
|
||||
*/
|
||||
async isEnabled(document, plugin, feature) {
|
||||
const config = (await this.getConfig('astro', document.uri)) ?? {};
|
||||
if (config[plugin]) {
|
||||
let res = config[plugin].enabled ?? true;
|
||||
if (feature && config[plugin][feature]) {
|
||||
res = (res && config[plugin][feature].enabled) ?? true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Updating the global config should only be done in cases where the client doesn't support `workspace/configuration`
|
||||
* or inside of tests.
|
||||
*
|
||||
* The `outsideAstro` parameter can be set to true to change configurations in the global scope.
|
||||
* For example, to change TypeScript settings
|
||||
*/
|
||||
updateGlobalConfig(config, outsideAstro) {
|
||||
if (outsideAstro) {
|
||||
this.globalConfig = (0, utils_1.mergeDeep)({}, this.globalConfig, config);
|
||||
}
|
||||
else {
|
||||
this.globalConfig.astro = (0, utils_1.mergeDeep)({}, exports.defaultLSConfig, this.globalConfig.astro, config);
|
||||
}
|
||||
this.shouldRefreshTSServices = true;
|
||||
}
|
||||
}
|
||||
exports.ConfigManager = ConfigManager;
|
||||
function getQuoteStylePreference(config) {
|
||||
switch (config.quoteStyle) {
|
||||
case 'single':
|
||||
return 'single';
|
||||
case 'double':
|
||||
return 'double';
|
||||
default:
|
||||
return 'auto';
|
||||
}
|
||||
}
|
||||
function getImportModuleSpecifierPreference(config) {
|
||||
switch (config.importModuleSpecifier) {
|
||||
case 'project-relative':
|
||||
return 'project-relative';
|
||||
case 'relative':
|
||||
return 'relative';
|
||||
case 'non-relative':
|
||||
return 'non-relative';
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
function getImportModuleSpecifierEndingPreference(config) {
|
||||
switch (config.importModuleSpecifierEnding) {
|
||||
case 'minimal':
|
||||
return 'minimal';
|
||||
case 'index':
|
||||
return 'index';
|
||||
case 'js':
|
||||
return 'js';
|
||||
default:
|
||||
return 'auto';
|
||||
}
|
||||
}
|
||||
function getInlayParameterNameHintsPreference(config) {
|
||||
switch (config.inlayHints?.parameterNames?.enabled) {
|
||||
case 'none':
|
||||
return 'none';
|
||||
case 'literals':
|
||||
return 'literals';
|
||||
case 'all':
|
||||
return 'all';
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
2
node_modules/@astrojs/language-server/dist/core/config/index.d.ts
generated
vendored
Normal file
2
node_modules/@astrojs/language-server/dist/core/config/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export * from './ConfigManager';
|
||||
export * from './interfaces';
|
||||
18
node_modules/@astrojs/language-server/dist/core/config/index.js
generated
vendored
Normal file
18
node_modules/@astrojs/language-server/dist/core/config/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./ConfigManager"), exports);
|
||||
__exportStar(require("./interfaces"), exports);
|
||||
77
node_modules/@astrojs/language-server/dist/core/config/interfaces.d.ts
generated
vendored
Normal file
77
node_modules/@astrojs/language-server/dist/core/config/interfaces.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* Representation of the language server config.
|
||||
* Make sure that this is kept in sync with the `package.json` of the VS Code extension
|
||||
*/
|
||||
export interface LSConfig {
|
||||
typescript?: LSTypescriptConfig;
|
||||
html?: LSHTMLConfig;
|
||||
css?: LSCSSConfig;
|
||||
format?: LSFormatConfig;
|
||||
}
|
||||
export interface LSFormatConfig {
|
||||
indentFrontmatter?: boolean;
|
||||
newLineAfterFrontmatter?: boolean;
|
||||
}
|
||||
export interface LSTypescriptConfig {
|
||||
enabled?: boolean;
|
||||
allowArbitraryAttributes?: boolean;
|
||||
diagnostics?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
hover?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
documentSymbols?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
completions?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
definitions?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
codeActions?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
rename?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
signatureHelp?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
semanticTokens?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
}
|
||||
export interface LSHTMLConfig {
|
||||
enabled?: boolean;
|
||||
hover?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
completions?: {
|
||||
enabled?: boolean;
|
||||
emmet?: boolean;
|
||||
};
|
||||
tagComplete?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
documentSymbols?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
}
|
||||
export interface LSCSSConfig {
|
||||
enabled?: boolean;
|
||||
hover?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
completions?: {
|
||||
enabled?: boolean;
|
||||
emmet?: boolean;
|
||||
};
|
||||
documentColors?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
documentSymbols?: {
|
||||
enabled?: boolean;
|
||||
};
|
||||
}
|
||||
2
node_modules/@astrojs/language-server/dist/core/config/interfaces.js
generated
vendored
Normal file
2
node_modules/@astrojs/language-server/dist/core/config/interfaces.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
19
node_modules/@astrojs/language-server/dist/core/documents/AstroDocument.d.ts
generated
vendored
Normal file
19
node_modules/@astrojs/language-server/dist/core/documents/AstroDocument.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import type { HTMLDocument, Range } from 'vscode-html-languageservice';
|
||||
import { WritableDocument } from './DocumentBase';
|
||||
import { AstroMetadata } from './parseAstro';
|
||||
import { TagInformation } from './utils';
|
||||
export declare class AstroDocument extends WritableDocument {
|
||||
url: string;
|
||||
content: string;
|
||||
languageId: string;
|
||||
astroMeta: AstroMetadata;
|
||||
html: HTMLDocument;
|
||||
styleTags: TagInformation[];
|
||||
scriptTags: TagInformation[];
|
||||
constructor(url: string, content: string);
|
||||
private updateDocInfo;
|
||||
setText(text: string): void;
|
||||
getText(range?: Range | undefined): string;
|
||||
getURL(): string;
|
||||
getFilePath(): string | null;
|
||||
}
|
||||
43
node_modules/@astrojs/language-server/dist/core/documents/AstroDocument.js
generated
vendored
Normal file
43
node_modules/@astrojs/language-server/dist/core/documents/AstroDocument.js
generated
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AstroDocument = void 0;
|
||||
const utils_1 = require("../../utils");
|
||||
const DocumentBase_1 = require("./DocumentBase");
|
||||
const parseAstro_1 = require("./parseAstro");
|
||||
const parseHtml_1 = require("./parseHtml");
|
||||
const utils_2 = require("./utils");
|
||||
class AstroDocument extends DocumentBase_1.WritableDocument {
|
||||
constructor(url, content) {
|
||||
super();
|
||||
this.url = url;
|
||||
this.content = content;
|
||||
this.languageId = 'astro';
|
||||
this.updateDocInfo();
|
||||
}
|
||||
updateDocInfo() {
|
||||
this.astroMeta = (0, parseAstro_1.parseAstro)(this.content);
|
||||
this.html = (0, parseHtml_1.parseHtml)(this.content, this.astroMeta);
|
||||
this.styleTags = (0, utils_2.extractStyleTags)(this.content, this.html);
|
||||
this.scriptTags = (0, utils_2.extractScriptTags)(this.content, this.html);
|
||||
}
|
||||
setText(text) {
|
||||
this.content = text;
|
||||
this.version++;
|
||||
this.updateDocInfo();
|
||||
}
|
||||
getText(range) {
|
||||
if (range) {
|
||||
const start = this.offsetAt(range.start);
|
||||
const end = this.offsetAt(range.end);
|
||||
return this.content.substring(start, end);
|
||||
}
|
||||
return this.content;
|
||||
}
|
||||
getURL() {
|
||||
return this.url;
|
||||
}
|
||||
getFilePath() {
|
||||
return (0, utils_1.urlToPath)(this.url);
|
||||
}
|
||||
}
|
||||
exports.AstroDocument = AstroDocument;
|
||||
68
node_modules/@astrojs/language-server/dist/core/documents/DocumentBase.d.ts
generated
vendored
Normal file
68
node_modules/@astrojs/language-server/dist/core/documents/DocumentBase.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import type { Position } from 'vscode-languageserver';
|
||||
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
/**
|
||||
* Represents a textual document.
|
||||
*/
|
||||
export declare abstract class ReadableDocument implements TextDocument {
|
||||
/**
|
||||
* Get the text content of the document
|
||||
*/
|
||||
abstract getText(): string;
|
||||
/**
|
||||
* Returns the url of the document
|
||||
*/
|
||||
abstract getURL(): string;
|
||||
/**
|
||||
* Returns the file path if the url scheme is file
|
||||
*/
|
||||
abstract getFilePath(): string | null;
|
||||
/**
|
||||
* Current version of the document.
|
||||
*/
|
||||
version: number;
|
||||
/**
|
||||
* Should be cleared when there's an update to the text
|
||||
*/
|
||||
protected lineOffsets?: number[];
|
||||
/**
|
||||
* Get the length of the document's content
|
||||
*/
|
||||
getTextLength(): number;
|
||||
/**
|
||||
* Get the line and character based on the offset
|
||||
* @param offset The index of the position
|
||||
*/
|
||||
positionAt(offset: number): Position;
|
||||
/**
|
||||
* Get the index of the line and character position
|
||||
* @param position Line and character position
|
||||
*/
|
||||
offsetAt(position: Position): number;
|
||||
getLineUntilOffset(offset: number): string;
|
||||
private getLineOffsets;
|
||||
/**
|
||||
* Implements TextDocument
|
||||
*/
|
||||
get uri(): string;
|
||||
get lines(): string[];
|
||||
get lineCount(): number;
|
||||
abstract languageId: string;
|
||||
}
|
||||
/**
|
||||
* Represents a textual document that can be manipulated.
|
||||
*/
|
||||
export declare abstract class WritableDocument extends ReadableDocument {
|
||||
/**
|
||||
* Set the text content of the document.
|
||||
* Implementers should set `lineOffsets` to `undefined` here.
|
||||
* @param text The new text content
|
||||
*/
|
||||
abstract setText(text: string): void;
|
||||
/**
|
||||
* Update the text between two positions.
|
||||
* @param text The new text slice
|
||||
* @param start Start offset of the new text
|
||||
* @param end End offset of the new text
|
||||
*/
|
||||
update(text: string, start: number, end: number): void;
|
||||
}
|
||||
75
node_modules/@astrojs/language-server/dist/core/documents/DocumentBase.js
generated
vendored
Normal file
75
node_modules/@astrojs/language-server/dist/core/documents/DocumentBase.js
generated
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.WritableDocument = exports.ReadableDocument = void 0;
|
||||
const utils_1 = require("./utils");
|
||||
/**
|
||||
* Represents a textual document.
|
||||
*/
|
||||
class ReadableDocument {
|
||||
constructor() {
|
||||
/**
|
||||
* Current version of the document.
|
||||
*/
|
||||
this.version = 0;
|
||||
}
|
||||
/**
|
||||
* Get the length of the document's content
|
||||
*/
|
||||
getTextLength() {
|
||||
return this.getText().length;
|
||||
}
|
||||
/**
|
||||
* Get the line and character based on the offset
|
||||
* @param offset The index of the position
|
||||
*/
|
||||
positionAt(offset) {
|
||||
return (0, utils_1.positionAt)(offset, this.getText(), this.getLineOffsets());
|
||||
}
|
||||
/**
|
||||
* Get the index of the line and character position
|
||||
* @param position Line and character position
|
||||
*/
|
||||
offsetAt(position) {
|
||||
return (0, utils_1.offsetAt)(position, this.getText(), this.getLineOffsets());
|
||||
}
|
||||
getLineUntilOffset(offset) {
|
||||
const { line, character } = this.positionAt(offset);
|
||||
return this.lines[line].slice(0, character);
|
||||
}
|
||||
getLineOffsets() {
|
||||
if (!this.lineOffsets) {
|
||||
this.lineOffsets = (0, utils_1.getLineOffsets)(this.getText());
|
||||
}
|
||||
return this.lineOffsets;
|
||||
}
|
||||
/**
|
||||
* Implements TextDocument
|
||||
*/
|
||||
get uri() {
|
||||
return this.getURL();
|
||||
}
|
||||
get lines() {
|
||||
return this.getText().split(/\r?\n/);
|
||||
}
|
||||
get lineCount() {
|
||||
return this.lines.length;
|
||||
}
|
||||
}
|
||||
exports.ReadableDocument = ReadableDocument;
|
||||
/**
|
||||
* Represents a textual document that can be manipulated.
|
||||
*/
|
||||
class WritableDocument extends ReadableDocument {
|
||||
/**
|
||||
* Update the text between two positions.
|
||||
* @param text The new text slice
|
||||
* @param start Start offset of the new text
|
||||
* @param end End offset of the new text
|
||||
*/
|
||||
update(text, start, end) {
|
||||
this.lineOffsets = undefined;
|
||||
const content = this.getText();
|
||||
this.setText(content.slice(0, start) + text + content.slice(end));
|
||||
}
|
||||
}
|
||||
exports.WritableDocument = WritableDocument;
|
||||
23
node_modules/@astrojs/language-server/dist/core/documents/DocumentManager.d.ts
generated
vendored
Normal file
23
node_modules/@astrojs/language-server/dist/core/documents/DocumentManager.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import type { TextDocumentContentChangeEvent, TextDocumentItem, VersionedTextDocumentIdentifier } from 'vscode-languageserver';
|
||||
import { AstroDocument } from './AstroDocument';
|
||||
export type DocumentEvent = 'documentOpen' | 'documentChange' | 'documentClose';
|
||||
export declare class DocumentManager {
|
||||
private createDocument?;
|
||||
private emitter;
|
||||
private openedInClient;
|
||||
private documents;
|
||||
private locked;
|
||||
private deleteCandidates;
|
||||
constructor(createDocument?: ((textDocument: Pick<TextDocumentItem, 'text' | 'uri'>) => AstroDocument) | undefined);
|
||||
openDocument(textDocument: Pick<TextDocumentItem, 'text' | 'uri'>): AstroDocument;
|
||||
lockDocument(uri: string): void;
|
||||
markAsOpenedInClient(uri: string): void;
|
||||
getAllOpenedByClient(): [string, AstroDocument][];
|
||||
releaseDocument(uri: string): void;
|
||||
closeDocument(uri: string): void;
|
||||
updateDocument(textDocument: VersionedTextDocumentIdentifier, changes: TextDocumentContentChangeEvent[]): void;
|
||||
on(name: DocumentEvent, listener: (document: AstroDocument) => void): void;
|
||||
get(uri: string): AstroDocument | undefined;
|
||||
private notify;
|
||||
static newInstance(): DocumentManager;
|
||||
}
|
||||
100
node_modules/@astrojs/language-server/dist/core/documents/DocumentManager.js
generated
vendored
Normal file
100
node_modules/@astrojs/language-server/dist/core/documents/DocumentManager.js
generated
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.DocumentManager = void 0;
|
||||
const events_1 = require("events");
|
||||
const utils_1 = require("../../utils");
|
||||
const AstroDocument_1 = require("./AstroDocument");
|
||||
class DocumentManager {
|
||||
constructor(createDocument) {
|
||||
this.createDocument = createDocument;
|
||||
this.emitter = new events_1.EventEmitter();
|
||||
this.openedInClient = new Set();
|
||||
this.documents = new Map();
|
||||
this.locked = new Set();
|
||||
this.deleteCandidates = new Set();
|
||||
if (!createDocument) {
|
||||
this.createDocument = (textDocument) => new AstroDocument_1.AstroDocument(textDocument.uri, textDocument.text);
|
||||
}
|
||||
}
|
||||
openDocument(textDocument) {
|
||||
textDocument = { ...textDocument, uri: (0, utils_1.normalizeUri)(textDocument.uri) };
|
||||
let document;
|
||||
if (this.documents.has(textDocument.uri)) {
|
||||
document = this.documents.get(textDocument.uri);
|
||||
document.setText(textDocument.text);
|
||||
}
|
||||
else {
|
||||
document = this.createDocument(textDocument);
|
||||
this.documents.set(textDocument.uri, document);
|
||||
this.notify('documentOpen', document);
|
||||
}
|
||||
this.notify('documentChange', document);
|
||||
return document;
|
||||
}
|
||||
lockDocument(uri) {
|
||||
this.locked.add((0, utils_1.normalizeUri)(uri));
|
||||
}
|
||||
markAsOpenedInClient(uri) {
|
||||
this.openedInClient.add((0, utils_1.normalizeUri)(uri));
|
||||
}
|
||||
getAllOpenedByClient() {
|
||||
return Array.from(this.documents.entries()).filter((doc) => this.openedInClient.has(doc[0]));
|
||||
}
|
||||
releaseDocument(uri) {
|
||||
uri = (0, utils_1.normalizeUri)(uri);
|
||||
this.locked.delete(uri);
|
||||
this.openedInClient.delete(uri);
|
||||
if (this.deleteCandidates.has(uri)) {
|
||||
this.deleteCandidates.delete(uri);
|
||||
this.closeDocument(uri);
|
||||
}
|
||||
}
|
||||
closeDocument(uri) {
|
||||
uri = (0, utils_1.normalizeUri)(uri);
|
||||
const document = this.documents.get(uri);
|
||||
if (!document) {
|
||||
throw new Error('Cannot call methods on an unopened document');
|
||||
}
|
||||
this.notify('documentClose', document);
|
||||
// Some plugin may prevent a document from actually being closed.
|
||||
if (!this.locked.has(uri)) {
|
||||
this.documents.delete(uri);
|
||||
}
|
||||
else {
|
||||
this.deleteCandidates.add(uri);
|
||||
}
|
||||
this.openedInClient.delete(uri);
|
||||
}
|
||||
updateDocument(textDocument, changes) {
|
||||
const document = this.documents.get((0, utils_1.normalizeUri)(textDocument.uri));
|
||||
if (!document) {
|
||||
throw new Error('Cannot call methods on an unopened document');
|
||||
}
|
||||
for (const change of changes) {
|
||||
let start = 0;
|
||||
let end = 0;
|
||||
if ('range' in change) {
|
||||
start = document.offsetAt(change.range.start);
|
||||
end = document.offsetAt(change.range.end);
|
||||
}
|
||||
else {
|
||||
end = document.getTextLength();
|
||||
}
|
||||
document.update(change.text, start, end);
|
||||
}
|
||||
this.notify('documentChange', document);
|
||||
}
|
||||
on(name, listener) {
|
||||
this.emitter.on(name, listener);
|
||||
}
|
||||
get(uri) {
|
||||
return this.documents.get((0, utils_1.normalizeUri)(uri));
|
||||
}
|
||||
notify(name, document) {
|
||||
this.emitter.emit(name, document);
|
||||
}
|
||||
static newInstance() {
|
||||
return new DocumentManager(({ uri, text }) => new AstroDocument_1.AstroDocument(uri, text));
|
||||
}
|
||||
}
|
||||
exports.DocumentManager = DocumentManager;
|
||||
94
node_modules/@astrojs/language-server/dist/core/documents/DocumentMapper.d.ts
generated
vendored
Normal file
94
node_modules/@astrojs/language-server/dist/core/documents/DocumentMapper.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import { TraceMap } from '@jridgewell/trace-mapping';
|
||||
import type ts from 'typescript';
|
||||
import { CodeAction, ColorPresentation, CompletionItem, Diagnostic, FoldingRange, Hover, InsertReplaceEdit, LocationLink, Position, Range, SelectionRange, SymbolInformation, TextDocumentEdit, TextEdit } from 'vscode-languageserver';
|
||||
import { DocumentSnapshot, ScriptTagDocumentSnapshot } from '../../plugins/typescript/snapshots/DocumentSnapshot';
|
||||
import { TagInformation } from './utils';
|
||||
export interface DocumentMapper {
|
||||
/**
|
||||
* Map the generated position to the original position
|
||||
* @param generatedPosition Position in fragment
|
||||
*/
|
||||
getOriginalPosition(generatedPosition: Position): Position;
|
||||
/**
|
||||
* Map the original position to the generated position
|
||||
* @param originalPosition Position in parent
|
||||
*/
|
||||
getGeneratedPosition(originalPosition: Position): Position;
|
||||
/**
|
||||
* Returns true if the given original position is inside of the generated map
|
||||
* @param pos Position in original
|
||||
*/
|
||||
isInGenerated(pos: Position): boolean;
|
||||
/**
|
||||
* Get document URL
|
||||
*/
|
||||
getURL(): string;
|
||||
/**
|
||||
* Implement this if you need teardown logic before this mapper gets cleaned up.
|
||||
*/
|
||||
destroy?(): void;
|
||||
}
|
||||
/**
|
||||
* Does not map, returns positions as is.
|
||||
*/
|
||||
export declare class IdentityMapper implements DocumentMapper {
|
||||
private url;
|
||||
private parent?;
|
||||
constructor(url: string, parent?: DocumentMapper | undefined);
|
||||
getOriginalPosition(generatedPosition: Position): Position;
|
||||
getGeneratedPosition(originalPosition: Position): Position;
|
||||
isInGenerated(position: Position): boolean;
|
||||
getURL(): string;
|
||||
destroy(): void;
|
||||
}
|
||||
/**
|
||||
* Maps positions in a fragment relative to a parent.
|
||||
*/
|
||||
export declare class FragmentMapper implements DocumentMapper {
|
||||
private originalText;
|
||||
private tagInfo;
|
||||
private url;
|
||||
private lineOffsetsOriginal;
|
||||
private lineOffsetsGenerated;
|
||||
constructor(originalText: string, tagInfo: TagInformation, url: string);
|
||||
getOriginalPosition(generatedPosition: Position): Position;
|
||||
private offsetInParent;
|
||||
getGeneratedPosition(originalPosition: Position): Position;
|
||||
isInGenerated(pos: Position): boolean;
|
||||
getURL(): string;
|
||||
}
|
||||
export declare class SourceMapDocumentMapper implements DocumentMapper {
|
||||
protected traceMap: TraceMap;
|
||||
protected sourceUri: string;
|
||||
private parent?;
|
||||
constructor(traceMap: TraceMap, sourceUri: string, parent?: DocumentMapper | undefined);
|
||||
getOriginalPosition(generatedPosition: Position): Position;
|
||||
getGeneratedPosition(originalPosition: Position): Position;
|
||||
isInGenerated(position: Position): boolean;
|
||||
getURL(): string;
|
||||
}
|
||||
export declare class ConsumerDocumentMapper extends SourceMapDocumentMapper {
|
||||
private nrPrependesLines;
|
||||
constructor(traceMap: TraceMap, sourceUri: string, nrPrependesLines: number);
|
||||
getOriginalPosition(generatedPosition: Position): Position;
|
||||
getGeneratedPosition(originalPosition: Position): Position;
|
||||
isInGenerated(): boolean;
|
||||
}
|
||||
export declare function mapRangeToOriginal(fragment: Pick<DocumentMapper, 'getOriginalPosition'>, range: Range): Range;
|
||||
export declare function mapRangeToGenerated(fragment: DocumentMapper, range: Range): Range;
|
||||
export declare function mapCompletionItemToOriginal(fragment: Pick<DocumentMapper, 'getOriginalPosition'>, item: CompletionItem): CompletionItem;
|
||||
export declare function mapHoverToParent(fragment: Pick<DocumentMapper, 'getOriginalPosition'>, hover: Hover): Hover;
|
||||
export declare function mapObjWithRangeToOriginal<T extends {
|
||||
range: Range;
|
||||
}>(fragment: Pick<DocumentMapper, 'getOriginalPosition'>, objWithRange: T): T;
|
||||
export declare function mapInsertReplaceEditToOriginal(fragment: Pick<DocumentMapper, 'getOriginalPosition'>, edit: InsertReplaceEdit): InsertReplaceEdit;
|
||||
export declare function mapEditToOriginal(fragment: Pick<DocumentMapper, 'getOriginalPosition'>, edit: TextEdit | InsertReplaceEdit): TextEdit | InsertReplaceEdit;
|
||||
export declare function mapDiagnosticToGenerated(fragment: DocumentMapper, diagnostic: Diagnostic): Diagnostic;
|
||||
export declare function mapColorPresentationToOriginal(fragment: Pick<DocumentMapper, 'getOriginalPosition'>, presentation: ColorPresentation): ColorPresentation;
|
||||
export declare function mapSymbolInformationToOriginal(fragment: Pick<DocumentMapper, 'getOriginalPosition'>, info: SymbolInformation): SymbolInformation;
|
||||
export declare function mapLocationLinkToOriginal(fragment: DocumentMapper, def: LocationLink): LocationLink;
|
||||
export declare function mapTextDocumentEditToOriginal(fragment: DocumentMapper, edit: TextDocumentEdit): TextDocumentEdit;
|
||||
export declare function mapCodeActionToOriginal(fragment: DocumentMapper, codeAction: CodeAction): CodeAction;
|
||||
export declare function mapScriptSpanStartToSnapshot(span: ts.TextSpan, scriptTagSnapshot: ScriptTagDocumentSnapshot, tsSnapshot: DocumentSnapshot): number;
|
||||
export declare function mapFoldingRangeToParent(fragment: DocumentMapper, foldingRange: FoldingRange): FoldingRange;
|
||||
export declare function mapSelectionRangeToParent(fragment: Pick<DocumentMapper, 'getOriginalPosition'>, selectionRange: SelectionRange): SelectionRange;
|
||||
264
node_modules/@astrojs/language-server/dist/core/documents/DocumentMapper.js
generated
vendored
Normal file
264
node_modules/@astrojs/language-server/dist/core/documents/DocumentMapper.js
generated
vendored
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.mapSelectionRangeToParent = exports.mapFoldingRangeToParent = exports.mapScriptSpanStartToSnapshot = 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.ConsumerDocumentMapper = exports.SourceMapDocumentMapper = exports.FragmentMapper = exports.IdentityMapper = void 0;
|
||||
const trace_mapping_1 = require("@jridgewell/trace-mapping");
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const utils_1 = require("./utils");
|
||||
/**
|
||||
* Does not map, returns positions as is.
|
||||
*/
|
||||
class IdentityMapper {
|
||||
constructor(url, parent) {
|
||||
this.url = url;
|
||||
this.parent = parent;
|
||||
}
|
||||
getOriginalPosition(generatedPosition) {
|
||||
if (this.parent) {
|
||||
generatedPosition = this.getOriginalPosition(generatedPosition);
|
||||
}
|
||||
return generatedPosition;
|
||||
}
|
||||
getGeneratedPosition(originalPosition) {
|
||||
if (this.parent) {
|
||||
originalPosition = this.getGeneratedPosition(originalPosition);
|
||||
}
|
||||
return originalPosition;
|
||||
}
|
||||
isInGenerated(position) {
|
||||
if (this.parent && !this.parent.isInGenerated(position)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
getURL() {
|
||||
return this.url;
|
||||
}
|
||||
destroy() {
|
||||
this.parent?.destroy?.();
|
||||
}
|
||||
}
|
||||
exports.IdentityMapper = IdentityMapper;
|
||||
/**
|
||||
* Maps positions in a fragment relative to a parent.
|
||||
*/
|
||||
class FragmentMapper {
|
||||
constructor(originalText, tagInfo, url) {
|
||||
this.originalText = originalText;
|
||||
this.tagInfo = tagInfo;
|
||||
this.url = url;
|
||||
this.lineOffsetsOriginal = (0, utils_1.getLineOffsets)(this.originalText);
|
||||
this.lineOffsetsGenerated = (0, utils_1.getLineOffsets)(this.tagInfo.content);
|
||||
}
|
||||
getOriginalPosition(generatedPosition) {
|
||||
const parentOffset = this.offsetInParent((0, utils_1.offsetAt)(generatedPosition, this.tagInfo.content, this.lineOffsetsGenerated));
|
||||
return (0, utils_1.positionAt)(parentOffset, this.originalText, this.lineOffsetsOriginal);
|
||||
}
|
||||
offsetInParent(offset) {
|
||||
return this.tagInfo.start + offset;
|
||||
}
|
||||
getGeneratedPosition(originalPosition) {
|
||||
const fragmentOffset = (0, utils_1.offsetAt)(originalPosition, this.originalText, this.lineOffsetsOriginal) - this.tagInfo.start;
|
||||
return (0, utils_1.positionAt)(fragmentOffset, this.tagInfo.content, this.lineOffsetsGenerated);
|
||||
}
|
||||
isInGenerated(pos) {
|
||||
const offset = (0, utils_1.offsetAt)(pos, this.originalText, this.lineOffsetsOriginal);
|
||||
return offset >= this.tagInfo.start && offset <= this.tagInfo.end;
|
||||
}
|
||||
getURL() {
|
||||
return this.url;
|
||||
}
|
||||
}
|
||||
exports.FragmentMapper = FragmentMapper;
|
||||
class SourceMapDocumentMapper {
|
||||
constructor(traceMap, sourceUri, parent) {
|
||||
this.traceMap = traceMap;
|
||||
this.sourceUri = sourceUri;
|
||||
this.parent = parent;
|
||||
}
|
||||
getOriginalPosition(generatedPosition) {
|
||||
if (this.parent) {
|
||||
generatedPosition = this.parent.getOriginalPosition(generatedPosition);
|
||||
}
|
||||
if (generatedPosition.line < 0) {
|
||||
return { line: -1, character: -1 };
|
||||
}
|
||||
const mapped = (0, trace_mapping_1.originalPositionFor)(this.traceMap, {
|
||||
line: generatedPosition.line + 1,
|
||||
column: generatedPosition.character,
|
||||
});
|
||||
if (!mapped) {
|
||||
return { line: -1, character: -1 };
|
||||
}
|
||||
if (mapped.line === 0) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Got 0 mapped line from', generatedPosition, 'col was', mapped.column);
|
||||
}
|
||||
return {
|
||||
line: (mapped.line || 0) - 1,
|
||||
character: mapped.column || 0,
|
||||
};
|
||||
}
|
||||
getGeneratedPosition(originalPosition) {
|
||||
if (this.parent) {
|
||||
originalPosition = this.parent.getGeneratedPosition(originalPosition);
|
||||
}
|
||||
const mapped = (0, trace_mapping_1.generatedPositionFor)(this.traceMap, {
|
||||
line: originalPosition.line + 1,
|
||||
column: originalPosition.character,
|
||||
source: this.sourceUri,
|
||||
});
|
||||
if (!mapped) {
|
||||
return { line: -1, character: -1 };
|
||||
}
|
||||
const result = {
|
||||
line: (mapped.line || 0) - 1,
|
||||
character: mapped.column || 0,
|
||||
};
|
||||
if (result.line < 0) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
isInGenerated(position) {
|
||||
if (this.parent && !this.isInGenerated(position)) {
|
||||
return false;
|
||||
}
|
||||
const generated = this.getGeneratedPosition(position);
|
||||
return generated.line >= 0;
|
||||
}
|
||||
getURL() {
|
||||
return this.sourceUri;
|
||||
}
|
||||
}
|
||||
exports.SourceMapDocumentMapper = SourceMapDocumentMapper;
|
||||
class ConsumerDocumentMapper extends SourceMapDocumentMapper {
|
||||
constructor(traceMap, sourceUri, nrPrependesLines) {
|
||||
super(traceMap, sourceUri);
|
||||
this.nrPrependesLines = nrPrependesLines;
|
||||
}
|
||||
getOriginalPosition(generatedPosition) {
|
||||
return super.getOriginalPosition(vscode_languageserver_1.Position.create(generatedPosition.line - this.nrPrependesLines, generatedPosition.character));
|
||||
}
|
||||
getGeneratedPosition(originalPosition) {
|
||||
const result = super.getGeneratedPosition(originalPosition);
|
||||
result.line += this.nrPrependesLines;
|
||||
return result;
|
||||
}
|
||||
isInGenerated() {
|
||||
// always return true and map outliers case by case
|
||||
return true;
|
||||
}
|
||||
}
|
||||
exports.ConsumerDocumentMapper = ConsumerDocumentMapper;
|
||||
function mapRangeToOriginal(fragment, range) {
|
||||
// DON'T use Range.create here! Positions might not be mapped
|
||||
// and therefore return negative numbers, which makes Range.create throw.
|
||||
// These invalid position need to be handled
|
||||
// on a case-by-case basis in the calling functions.
|
||||
const originalRange = {
|
||||
start: fragment.getOriginalPosition(range.start),
|
||||
end: fragment.getOriginalPosition(range.end),
|
||||
};
|
||||
// Range may be mapped one character short - reverse that for "in the same line" cases
|
||||
if (originalRange.start.line === originalRange.end.line &&
|
||||
range.start.line === range.end.line &&
|
||||
originalRange.end.character - originalRange.start.character === range.end.character - range.start.character - 1) {
|
||||
originalRange.end.character += 1;
|
||||
}
|
||||
return originalRange;
|
||||
}
|
||||
exports.mapRangeToOriginal = mapRangeToOriginal;
|
||||
function mapRangeToGenerated(fragment, range) {
|
||||
return vscode_languageserver_1.Range.create(fragment.getGeneratedPosition(range.start), fragment.getGeneratedPosition(range.end));
|
||||
}
|
||||
exports.mapRangeToGenerated = mapRangeToGenerated;
|
||||
function mapCompletionItemToOriginal(fragment, item) {
|
||||
if (!item.textEdit) {
|
||||
return item;
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
textEdit: mapEditToOriginal(fragment, item.textEdit),
|
||||
};
|
||||
}
|
||||
exports.mapCompletionItemToOriginal = mapCompletionItemToOriginal;
|
||||
function mapHoverToParent(fragment, hover) {
|
||||
if (!hover.range) {
|
||||
return hover;
|
||||
}
|
||||
return { ...hover, range: mapRangeToOriginal(fragment, hover.range) };
|
||||
}
|
||||
exports.mapHoverToParent = mapHoverToParent;
|
||||
function mapObjWithRangeToOriginal(fragment, objWithRange) {
|
||||
return { ...objWithRange, range: mapRangeToOriginal(fragment, objWithRange.range) };
|
||||
}
|
||||
exports.mapObjWithRangeToOriginal = mapObjWithRangeToOriginal;
|
||||
function mapInsertReplaceEditToOriginal(fragment, edit) {
|
||||
return {
|
||||
...edit,
|
||||
insert: mapRangeToOriginal(fragment, edit.insert),
|
||||
replace: mapRangeToOriginal(fragment, edit.replace),
|
||||
};
|
||||
}
|
||||
exports.mapInsertReplaceEditToOriginal = mapInsertReplaceEditToOriginal;
|
||||
function mapEditToOriginal(fragment, edit) {
|
||||
return vscode_languageserver_1.TextEdit.is(edit) ? mapObjWithRangeToOriginal(fragment, edit) : mapInsertReplaceEditToOriginal(fragment, edit);
|
||||
}
|
||||
exports.mapEditToOriginal = mapEditToOriginal;
|
||||
function mapDiagnosticToGenerated(fragment, diagnostic) {
|
||||
return { ...diagnostic, range: mapRangeToGenerated(fragment, diagnostic.range) };
|
||||
}
|
||||
exports.mapDiagnosticToGenerated = mapDiagnosticToGenerated;
|
||||
function mapColorPresentationToOriginal(fragment, presentation) {
|
||||
const item = {
|
||||
...presentation,
|
||||
};
|
||||
if (item.textEdit) {
|
||||
item.textEdit = mapObjWithRangeToOriginal(fragment, item.textEdit);
|
||||
}
|
||||
if (item.additionalTextEdits) {
|
||||
item.additionalTextEdits = item.additionalTextEdits.map((edit) => mapObjWithRangeToOriginal(fragment, edit));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
exports.mapColorPresentationToOriginal = mapColorPresentationToOriginal;
|
||||
function mapSymbolInformationToOriginal(fragment, info) {
|
||||
return { ...info, location: mapObjWithRangeToOriginal(fragment, info.location) };
|
||||
}
|
||||
exports.mapSymbolInformationToOriginal = mapSymbolInformationToOriginal;
|
||||
function mapLocationLinkToOriginal(fragment, def) {
|
||||
return vscode_languageserver_1.LocationLink.create(def.targetUri, fragment.getURL() === def.targetUri ? mapRangeToOriginal(fragment, def.targetRange) : def.targetRange, fragment.getURL() === def.targetUri
|
||||
? mapRangeToOriginal(fragment, def.targetSelectionRange)
|
||||
: def.targetSelectionRange, def.originSelectionRange ? mapRangeToOriginal(fragment, def.originSelectionRange) : undefined);
|
||||
}
|
||||
exports.mapLocationLinkToOriginal = mapLocationLinkToOriginal;
|
||||
function mapTextDocumentEditToOriginal(fragment, edit) {
|
||||
if (edit.textDocument.uri !== fragment.getURL()) {
|
||||
return edit;
|
||||
}
|
||||
return vscode_languageserver_1.TextDocumentEdit.create(edit.textDocument, edit.edits.map((textEdit) => mapObjWithRangeToOriginal(fragment, textEdit)));
|
||||
}
|
||||
exports.mapTextDocumentEditToOriginal = mapTextDocumentEditToOriginal;
|
||||
function mapCodeActionToOriginal(fragment, codeAction) {
|
||||
return vscode_languageserver_1.CodeAction.create(codeAction.title, {
|
||||
documentChanges: codeAction.edit.documentChanges.map((edit) => mapTextDocumentEditToOriginal(fragment, edit)),
|
||||
}, codeAction.kind);
|
||||
}
|
||||
exports.mapCodeActionToOriginal = mapCodeActionToOriginal;
|
||||
function mapScriptSpanStartToSnapshot(span, scriptTagSnapshot, tsSnapshot) {
|
||||
const originalPosition = scriptTagSnapshot.getOriginalPosition(scriptTagSnapshot.positionAt(span.start));
|
||||
return tsSnapshot.offsetAt(tsSnapshot.getGeneratedPosition(originalPosition));
|
||||
}
|
||||
exports.mapScriptSpanStartToSnapshot = mapScriptSpanStartToSnapshot;
|
||||
function mapFoldingRangeToParent(fragment, foldingRange) {
|
||||
// Despite FoldingRange asking for a start and end line and a start and end character, FoldingRanges
|
||||
// don't use the Range type, instead asking for 4 number. Not sure why, but it's not convenient
|
||||
const range = mapRangeToOriginal(fragment, vscode_languageserver_1.Range.create(foldingRange.startLine, foldingRange.startCharacter || 0, foldingRange.endLine, foldingRange.endCharacter || 0));
|
||||
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);
|
||||
}
|
||||
exports.mapFoldingRangeToParent = mapFoldingRangeToParent;
|
||||
function mapSelectionRangeToParent(fragment, selectionRange) {
|
||||
const { range, parent } = selectionRange;
|
||||
return vscode_languageserver_1.SelectionRange.create(mapRangeToOriginal(fragment, range), parent && mapSelectionRangeToParent(fragment, parent));
|
||||
}
|
||||
exports.mapSelectionRangeToParent = mapSelectionRangeToParent;
|
||||
5
node_modules/@astrojs/language-server/dist/core/documents/index.d.ts
generated
vendored
Normal file
5
node_modules/@astrojs/language-server/dist/core/documents/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export * from './AstroDocument';
|
||||
export * from './DocumentBase';
|
||||
export * from './DocumentManager';
|
||||
export * from './DocumentMapper';
|
||||
export * from './utils';
|
||||
21
node_modules/@astrojs/language-server/dist/core/documents/index.js
generated
vendored
Normal file
21
node_modules/@astrojs/language-server/dist/core/documents/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./AstroDocument"), exports);
|
||||
__exportStar(require("./DocumentBase"), exports);
|
||||
__exportStar(require("./DocumentManager"), exports);
|
||||
__exportStar(require("./DocumentMapper"), exports);
|
||||
__exportStar(require("./utils"), exports);
|
||||
15
node_modules/@astrojs/language-server/dist/core/documents/parseAstro.d.ts
generated
vendored
Normal file
15
node_modules/@astrojs/language-server/dist/core/documents/parseAstro.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
interface Frontmatter {
|
||||
state: null | 'open' | 'closed';
|
||||
startOffset: null | number;
|
||||
endOffset: null | number;
|
||||
}
|
||||
interface Content {
|
||||
firstNonWhitespaceOffset: null | number;
|
||||
}
|
||||
export interface AstroMetadata {
|
||||
frontmatter: Frontmatter;
|
||||
content: Content;
|
||||
}
|
||||
/** Parses a document to collect metadata about Astro features */
|
||||
export declare function parseAstro(content: string): AstroMetadata;
|
||||
export {};
|
||||
63
node_modules/@astrojs/language-server/dist/core/documents/parseAstro.js
generated
vendored
Normal file
63
node_modules/@astrojs/language-server/dist/core/documents/parseAstro.js
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseAstro = void 0;
|
||||
const utils_1 = require("./utils");
|
||||
/** Parses a document to collect metadata about Astro features */
|
||||
function parseAstro(content) {
|
||||
const frontmatter = getFrontmatter(content);
|
||||
return {
|
||||
frontmatter,
|
||||
content: getContent(content, frontmatter),
|
||||
};
|
||||
}
|
||||
exports.parseAstro = parseAstro;
|
||||
/** Get frontmatter metadata */
|
||||
function getFrontmatter(content) {
|
||||
/** Quickly check how many `---` blocks are in the document */
|
||||
function getFrontmatterState() {
|
||||
const parts = content.trim().split('---').length;
|
||||
switch (parts) {
|
||||
case 1:
|
||||
return null;
|
||||
case 2:
|
||||
return 'open';
|
||||
default:
|
||||
return 'closed';
|
||||
}
|
||||
}
|
||||
const state = getFrontmatterState();
|
||||
/** Construct a range containing the document's frontmatter */
|
||||
function getFrontmatterOffsets() {
|
||||
const startOffset = content.indexOf('---');
|
||||
if (startOffset === -1)
|
||||
return [null, null];
|
||||
const endOffset = content.slice(startOffset + 3).indexOf('---') + 3;
|
||||
if (endOffset === -1)
|
||||
return [startOffset, null];
|
||||
return [startOffset, endOffset];
|
||||
}
|
||||
const [startOffset, endOffset] = getFrontmatterOffsets();
|
||||
return {
|
||||
state,
|
||||
startOffset,
|
||||
endOffset,
|
||||
};
|
||||
}
|
||||
/** Get content metadata */
|
||||
function getContent(content, frontmatter) {
|
||||
switch (frontmatter.state) {
|
||||
case null: {
|
||||
const offset = (0, utils_1.getFirstNonWhitespaceIndex)(content);
|
||||
return { firstNonWhitespaceOffset: offset === -1 ? null : offset };
|
||||
}
|
||||
case 'open': {
|
||||
return { firstNonWhitespaceOffset: null };
|
||||
}
|
||||
case 'closed': {
|
||||
const { endOffset } = frontmatter;
|
||||
const end = (endOffset ?? 0) + 3;
|
||||
const offset = (0, utils_1.getFirstNonWhitespaceIndex)(content.slice(end));
|
||||
return { firstNonWhitespaceOffset: end + offset };
|
||||
}
|
||||
}
|
||||
}
|
||||
13
node_modules/@astrojs/language-server/dist/core/documents/parseHtml.d.ts
generated
vendored
Normal file
13
node_modules/@astrojs/language-server/dist/core/documents/parseHtml.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { HTMLDocument, Position } from 'vscode-html-languageservice';
|
||||
import type { AstroDocument } from './AstroDocument';
|
||||
import { AstroMetadata } from './parseAstro';
|
||||
/**
|
||||
* Parses text as HTML
|
||||
*/
|
||||
export declare function parseHtml(text: string, frontmatter: AstroMetadata): HTMLDocument;
|
||||
export interface AttributeContext {
|
||||
name: string;
|
||||
inValue: boolean;
|
||||
valueRange?: [number, number];
|
||||
}
|
||||
export declare function getAttributeContextAtPosition(document: AstroDocument, position: Position): AttributeContext | null;
|
||||
126
node_modules/@astrojs/language-server/dist/core/documents/parseHtml.js
generated
vendored
Normal file
126
node_modules/@astrojs/language-server/dist/core/documents/parseHtml.js
generated
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getAttributeContextAtPosition = exports.parseHtml = void 0;
|
||||
const vscode_html_languageservice_1 = require("vscode-html-languageservice");
|
||||
const utils_1 = require("./utils");
|
||||
const parser = (0, vscode_html_languageservice_1.getLanguageService)();
|
||||
/**
|
||||
* Parses text as HTML
|
||||
*/
|
||||
function parseHtml(text, frontmatter) {
|
||||
const preprocessed = preprocess(text, frontmatter);
|
||||
// We can safely only set getText because only this is used for parsing
|
||||
const parsedDoc = parser.parseHTMLDocument({ getText: () => preprocessed });
|
||||
return parsedDoc;
|
||||
}
|
||||
exports.parseHtml = parseHtml;
|
||||
const createScanner = parser.createScanner;
|
||||
/**
|
||||
* scan the text and remove any `>` or `<` that cause the tag to end short,
|
||||
*/
|
||||
function preprocess(text, frontmatter) {
|
||||
let scanner = createScanner(text);
|
||||
let token = scanner.scan();
|
||||
let currentStartTagStart = null;
|
||||
const hasFrontmatter = frontmatter !== undefined;
|
||||
while (token !== vscode_html_languageservice_1.TokenType.EOS) {
|
||||
const offset = scanner.getTokenOffset();
|
||||
if (hasFrontmatter &&
|
||||
(scanner.getTokenText() === '>' || scanner.getTokenText() === '<') &&
|
||||
offset < (frontmatter.content.firstNonWhitespaceOffset ?? 0)) {
|
||||
blankStartOrEndTagLike(offset, vscode_html_languageservice_1.ScannerState.WithinContent);
|
||||
}
|
||||
if (token === vscode_html_languageservice_1.TokenType.StartTagOpen) {
|
||||
currentStartTagStart = offset;
|
||||
}
|
||||
if (token === vscode_html_languageservice_1.TokenType.StartTagClose) {
|
||||
if (shouldBlankStartOrEndTagLike(offset)) {
|
||||
blankStartOrEndTagLike(offset);
|
||||
}
|
||||
else {
|
||||
currentStartTagStart = null;
|
||||
}
|
||||
}
|
||||
if (token === vscode_html_languageservice_1.TokenType.StartTagSelfClose) {
|
||||
currentStartTagStart = null;
|
||||
}
|
||||
// <Foo checked={a < 1}>
|
||||
// https://github.com/microsoft/vscode-html-languageservice/blob/71806ef57be07e1068ee40900ef8b0899c80e68a/src/parser/htmlScanner.ts#L327
|
||||
if (token === vscode_html_languageservice_1.TokenType.Unknown &&
|
||||
scanner.getScannerState() === vscode_html_languageservice_1.ScannerState.WithinTag &&
|
||||
scanner.getTokenText() === '<' &&
|
||||
shouldBlankStartOrEndTagLike(offset)) {
|
||||
blankStartOrEndTagLike(offset);
|
||||
}
|
||||
// TODO: Handle TypeScript generics inside expressions / Use the compiler to parse HTML instead?
|
||||
token = scanner.scan();
|
||||
}
|
||||
return text;
|
||||
function shouldBlankStartOrEndTagLike(offset) {
|
||||
// not null rather than falsy, otherwise it won't work on first tag(0)
|
||||
return currentStartTagStart !== null && (0, utils_1.isInsideExpression)(text, currentStartTagStart, offset);
|
||||
}
|
||||
function blankStartOrEndTagLike(offset, state) {
|
||||
text = text.substring(0, offset) + ' ' + text.substring(offset + 1);
|
||||
scanner = createScanner(text, offset, state ?? vscode_html_languageservice_1.ScannerState.WithinTag);
|
||||
}
|
||||
}
|
||||
function getAttributeContextAtPosition(document, position) {
|
||||
const offset = document.offsetAt(position);
|
||||
const { html } = document;
|
||||
const tag = html.findNodeAt(offset);
|
||||
if (!inStartTag(offset, tag) || !tag.attributes) {
|
||||
return null;
|
||||
}
|
||||
const text = document.getText();
|
||||
const beforeStartTagEnd = text.substring(0, tag.start) + preprocess(text.substring(tag.start, tag.startTagEnd));
|
||||
const scanner = createScanner(beforeStartTagEnd, tag.start);
|
||||
let token = scanner.scan();
|
||||
let currentAttributeName;
|
||||
const inTokenRange = () => scanner.getTokenOffset() <= offset && offset <= scanner.getTokenEnd();
|
||||
while (token != vscode_html_languageservice_1.TokenType.EOS) {
|
||||
// adopted from https://github.com/microsoft/vscode-html-languageservice/blob/2f7ae4df298ac2c299a40e9024d118f4a9dc0c68/src/services/htmlCompletion.ts#L402
|
||||
if (token === vscode_html_languageservice_1.TokenType.AttributeName) {
|
||||
currentAttributeName = scanner.getTokenText();
|
||||
if (inTokenRange()) {
|
||||
return {
|
||||
name: currentAttributeName,
|
||||
inValue: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (token === vscode_html_languageservice_1.TokenType.DelimiterAssign) {
|
||||
if (scanner.getTokenEnd() === offset && currentAttributeName) {
|
||||
const nextToken = scanner.scan();
|
||||
return {
|
||||
name: currentAttributeName,
|
||||
inValue: true,
|
||||
valueRange: [offset, nextToken === vscode_html_languageservice_1.TokenType.AttributeValue ? scanner.getTokenEnd() : offset],
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (token === vscode_html_languageservice_1.TokenType.AttributeValue) {
|
||||
if (inTokenRange() && currentAttributeName) {
|
||||
let start = scanner.getTokenOffset();
|
||||
let end = scanner.getTokenEnd();
|
||||
const char = text[start];
|
||||
if (char === '"' || char === "'") {
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
return {
|
||||
name: currentAttributeName,
|
||||
inValue: true,
|
||||
valueRange: [start, end],
|
||||
};
|
||||
}
|
||||
currentAttributeName = undefined;
|
||||
}
|
||||
token = scanner.scan();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.getAttributeContextAtPosition = getAttributeContextAtPosition;
|
||||
function inStartTag(offset, node) {
|
||||
return offset > node.start && node.startTagEnd != undefined && offset < node.startTagEnd;
|
||||
}
|
||||
63
node_modules/@astrojs/language-server/dist/core/documents/utils.d.ts
generated
vendored
Normal file
63
node_modules/@astrojs/language-server/dist/core/documents/utils.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import type { HTMLDocument, Node } from 'vscode-html-languageservice';
|
||||
import { Position } from 'vscode-languageserver';
|
||||
export interface TagInformation {
|
||||
content: string;
|
||||
attributes: Record<string, string>;
|
||||
start: number;
|
||||
end: number;
|
||||
startPos: Position;
|
||||
endPos: Position;
|
||||
container: {
|
||||
start: number;
|
||||
end: number;
|
||||
};
|
||||
closed: boolean;
|
||||
}
|
||||
export declare function walk(node: Node): Generator<Node, void, unknown>;
|
||||
export declare function extractStyleTags(source: string, html: HTMLDocument): TagInformation[];
|
||||
export declare function extractScriptTags(source: string, html: HTMLDocument): TagInformation[];
|
||||
export declare function getLineAtPosition(position: Position, text: string): string;
|
||||
/**
|
||||
* Return if a given offset is inside the start tag of a component
|
||||
*/
|
||||
export declare function isInComponentStartTag(html: HTMLDocument, offset: number): boolean;
|
||||
/**
|
||||
* Return if a given offset is inside the name of a tag
|
||||
*/
|
||||
export declare function isInTagName(html: HTMLDocument, offset: number): boolean;
|
||||
/**
|
||||
* Return true if a specific node could be a component.
|
||||
* 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
|
||||
*/
|
||||
export declare function isPossibleComponent(node: Node): boolean;
|
||||
/**
|
||||
* Return if the current position is in a specific tag
|
||||
*/
|
||||
export declare function isInTag(position: Position, tagInfo: TagInformation | null): tagInfo is TagInformation;
|
||||
/**
|
||||
* Return if a given position is inside a JSX expression
|
||||
*/
|
||||
export declare function isInsideExpression(html: string, tagStart: number, position: number): boolean;
|
||||
/**
|
||||
* Returns if a given offset is inside of the document frontmatter
|
||||
*/
|
||||
export declare function isInsideFrontmatter(text: string, offset: number): boolean;
|
||||
/**
|
||||
* Get the line and character based on the offset
|
||||
* @param offset The index of the position
|
||||
* @param text The text for which the position should be retrived
|
||||
* @param lineOffsets number Array with offsets for each line. Computed if not given
|
||||
*/
|
||||
export declare function positionAt(offset: number, text: string, lineOffsets?: number[]): Position;
|
||||
/**
|
||||
* Get the offset of the line and character position
|
||||
* @param position Line and character position
|
||||
* @param text The text for which the offset should be retrived
|
||||
* @param lineOffsets number Array with offsets for each line. Computed if not given
|
||||
*/
|
||||
export declare function offsetAt(position: Position, text: string, lineOffsets?: number[]): number;
|
||||
export declare function getLineOffsets(text: string): number[];
|
||||
/**
|
||||
* Gets index of first-non-whitespace character.
|
||||
*/
|
||||
export declare function getFirstNonWhitespaceIndex(str: string): number;
|
||||
223
node_modules/@astrojs/language-server/dist/core/documents/utils.js
generated
vendored
Normal file
223
node_modules/@astrojs/language-server/dist/core/documents/utils.js
generated
vendored
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getFirstNonWhitespaceIndex = exports.getLineOffsets = exports.offsetAt = exports.positionAt = exports.isInsideFrontmatter = exports.isInsideExpression = exports.isInTag = exports.isPossibleComponent = exports.isInTagName = exports.isInComponentStartTag = exports.getLineAtPosition = exports.extractScriptTags = exports.extractStyleTags = exports.walk = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const utils_1 = require("../../utils");
|
||||
function* walk(node) {
|
||||
for (let child of node.children) {
|
||||
yield* walk(child);
|
||||
}
|
||||
yield node;
|
||||
}
|
||||
exports.walk = walk;
|
||||
/**
|
||||
* Extracts a tag (style or script) from the given text
|
||||
* and returns its start, end and the attributes on that tag.
|
||||
*
|
||||
* @param source text content to extract tag from
|
||||
* @param tag the tag to extract
|
||||
*/
|
||||
function extractTags(text, tag, html) {
|
||||
const rootNodes = html.roots;
|
||||
const matchedNodes = rootNodes.filter((node) => node.tag === tag);
|
||||
if (tag === 'style' && !matchedNodes.length && rootNodes.length) {
|
||||
for (let child of walk(rootNodes[0])) {
|
||||
if (child.tag === 'style') {
|
||||
matchedNodes.push(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tag === 'script' && !matchedNodes.length && rootNodes.length) {
|
||||
for (let child of walk(rootNodes[0])) {
|
||||
if (child.tag === 'script') {
|
||||
matchedNodes.push(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
return matchedNodes.map(transformToTagInfo);
|
||||
function transformToTagInfo(matchedNode) {
|
||||
const start = matchedNode.startTagEnd ?? matchedNode.start;
|
||||
const end = matchedNode.endTagStart ?? matchedNode.end;
|
||||
const startPos = positionAt(start, text);
|
||||
const endPos = positionAt(end, text);
|
||||
const container = {
|
||||
start: matchedNode.start,
|
||||
end: matchedNode.end,
|
||||
};
|
||||
const content = text.substring(start, end);
|
||||
return {
|
||||
content,
|
||||
attributes: parseAttributes(matchedNode.attributes),
|
||||
start,
|
||||
end,
|
||||
startPos,
|
||||
endPos,
|
||||
container,
|
||||
// vscode-html-languageservice types does not contain this, despite it existing. Annoying
|
||||
closed: matchedNode.closed,
|
||||
};
|
||||
}
|
||||
}
|
||||
function extractStyleTags(source, html) {
|
||||
const styles = extractTags(source, 'style', html);
|
||||
if (!styles.length) {
|
||||
return [];
|
||||
}
|
||||
return styles;
|
||||
}
|
||||
exports.extractStyleTags = extractStyleTags;
|
||||
function extractScriptTags(source, html) {
|
||||
const scripts = extractTags(source, 'script', html);
|
||||
if (!scripts.length) {
|
||||
return [];
|
||||
}
|
||||
return scripts;
|
||||
}
|
||||
exports.extractScriptTags = extractScriptTags;
|
||||
function parseAttributes(rawAttrs) {
|
||||
const attrs = {};
|
||||
if (!rawAttrs) {
|
||||
return attrs;
|
||||
}
|
||||
Object.keys(rawAttrs).forEach((attrName) => {
|
||||
const attrValue = rawAttrs[attrName];
|
||||
attrs[attrName] = attrValue === null ? attrName : removeOuterQuotes(attrValue);
|
||||
});
|
||||
return attrs;
|
||||
function removeOuterQuotes(attrValue) {
|
||||
if ((attrValue.startsWith('"') && attrValue.endsWith('"')) ||
|
||||
(attrValue.startsWith("'") && attrValue.endsWith("'"))) {
|
||||
return attrValue.slice(1, attrValue.length - 1);
|
||||
}
|
||||
return attrValue;
|
||||
}
|
||||
}
|
||||
function getLineAtPosition(position, text) {
|
||||
return text.substring(offsetAt({ line: position.line, character: 0 }, text), offsetAt({ line: position.line, character: Number.MAX_VALUE }, text));
|
||||
}
|
||||
exports.getLineAtPosition = getLineAtPosition;
|
||||
/**
|
||||
* Return if a given offset is inside the start tag of a component
|
||||
*/
|
||||
function isInComponentStartTag(html, offset) {
|
||||
const node = html.findNodeAt(offset);
|
||||
return isPossibleComponent(node) && (!node.startTagEnd || offset < node.startTagEnd);
|
||||
}
|
||||
exports.isInComponentStartTag = isInComponentStartTag;
|
||||
/**
|
||||
* Return if a given offset is inside the name of a tag
|
||||
*/
|
||||
function isInTagName(html, offset) {
|
||||
const node = html.findNodeAt(offset);
|
||||
return offset > node.start && offset < node.start + (node.tag?.length ?? 0);
|
||||
}
|
||||
exports.isInTagName = isInTagName;
|
||||
/**
|
||||
* Return true if a specific node could be a component.
|
||||
* 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
|
||||
*/
|
||||
function isPossibleComponent(node) {
|
||||
return !!node.tag?.[0].match(/[A-Z]/) || !!node.tag?.match(/.+[.][A-Z]?/);
|
||||
}
|
||||
exports.isPossibleComponent = isPossibleComponent;
|
||||
/**
|
||||
* Return if the current position is in a specific tag
|
||||
*/
|
||||
function isInTag(position, tagInfo) {
|
||||
return !!tagInfo && (0, utils_1.isInRange)(vscode_languageserver_1.Range.create(tagInfo.startPos, tagInfo.endPos), position);
|
||||
}
|
||||
exports.isInTag = isInTag;
|
||||
/**
|
||||
* Return if a given position is inside a JSX expression
|
||||
*/
|
||||
function isInsideExpression(html, tagStart, position) {
|
||||
const charactersInNode = html.substring(tagStart, position);
|
||||
return charactersInNode.lastIndexOf('{') > charactersInNode.lastIndexOf('}');
|
||||
}
|
||||
exports.isInsideExpression = isInsideExpression;
|
||||
/**
|
||||
* Returns if a given offset is inside of the document frontmatter
|
||||
*/
|
||||
function isInsideFrontmatter(text, offset) {
|
||||
let start = text.slice(0, offset).trim().split('---').length;
|
||||
let end = text.slice(offset).trim().split('---').length;
|
||||
return start > 1 && start < 3 && end >= 1;
|
||||
}
|
||||
exports.isInsideFrontmatter = isInsideFrontmatter;
|
||||
/**
|
||||
* Get the line and character based on the offset
|
||||
* @param offset The index of the position
|
||||
* @param text The text for which the position should be retrived
|
||||
* @param lineOffsets number Array with offsets for each line. Computed if not given
|
||||
*/
|
||||
function positionAt(offset, text, lineOffsets = getLineOffsets(text)) {
|
||||
offset = (0, utils_1.clamp)(offset, 0, text.length);
|
||||
let low = 0;
|
||||
let high = lineOffsets.length;
|
||||
if (high === 0) {
|
||||
return vscode_languageserver_1.Position.create(0, offset);
|
||||
}
|
||||
while (low <= high) {
|
||||
const mid = Math.floor((low + high) / 2);
|
||||
const lineOffset = lineOffsets[mid];
|
||||
if (lineOffset === offset) {
|
||||
return vscode_languageserver_1.Position.create(mid, 0);
|
||||
}
|
||||
else if (offset > lineOffset) {
|
||||
low = mid + 1;
|
||||
}
|
||||
else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
// low is the least x for which the line offset is larger than the current offset
|
||||
// or array.length if no line offset is larger than the current offset
|
||||
const line = low - 1;
|
||||
return vscode_languageserver_1.Position.create(line, offset - lineOffsets[line]);
|
||||
}
|
||||
exports.positionAt = positionAt;
|
||||
/**
|
||||
* Get the offset of the line and character position
|
||||
* @param position Line and character position
|
||||
* @param text The text for which the offset should be retrived
|
||||
* @param lineOffsets number Array with offsets for each line. Computed if not given
|
||||
*/
|
||||
function offsetAt(position, text, lineOffsets = getLineOffsets(text)) {
|
||||
if (position.line >= lineOffsets.length) {
|
||||
return text.length;
|
||||
}
|
||||
else if (position.line < 0) {
|
||||
return 0;
|
||||
}
|
||||
const lineOffset = lineOffsets[position.line];
|
||||
const nextLineOffset = position.line + 1 < lineOffsets.length ? lineOffsets[position.line + 1] : text.length;
|
||||
return (0, utils_1.clamp)(nextLineOffset, lineOffset, lineOffset + position.character);
|
||||
}
|
||||
exports.offsetAt = offsetAt;
|
||||
function getLineOffsets(text) {
|
||||
const lineOffsets = [];
|
||||
let isLineStart = true;
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
if (isLineStart) {
|
||||
lineOffsets.push(i);
|
||||
isLineStart = false;
|
||||
}
|
||||
const ch = text.charAt(i);
|
||||
isLineStart = ch === '\r' || ch === '\n';
|
||||
if (ch === '\r' && i + 1 < text.length && text.charAt(i + 1) === '\n') {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (isLineStart && text.length > 0) {
|
||||
lineOffsets.push(text.length);
|
||||
}
|
||||
return lineOffsets;
|
||||
}
|
||||
exports.getLineOffsets = getLineOffsets;
|
||||
/**
|
||||
* Gets index of first-non-whitespace character.
|
||||
*/
|
||||
function getFirstNonWhitespaceIndex(str) {
|
||||
return str.length - str.trimStart().length;
|
||||
}
|
||||
exports.getFirstNonWhitespaceIndex = getFirstNonWhitespaceIndex;
|
||||
9
node_modules/@astrojs/language-server/dist/importPackage.d.ts
generated
vendored
Normal file
9
node_modules/@astrojs/language-server/dist/importPackage.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import type * as svelte from '@astrojs/svelte/dist/editor.cjs';
|
||||
import type * as vue from '@astrojs/svelte/dist/editor.cjs';
|
||||
import type * as prettier from 'prettier';
|
||||
export declare function setIsTrusted(_isTrusted: boolean): void;
|
||||
export declare function getPackagePath(packageName: string, fromPath: string[]): string | undefined;
|
||||
export declare function importSvelteIntegration(fromPath: string): typeof svelte | undefined;
|
||||
export declare function importVueIntegration(fromPath: string): typeof vue | undefined;
|
||||
export declare function importPrettier(fromPath: string): typeof prettier;
|
||||
export declare function getPrettierPluginPath(fromPath: string): string;
|
||||
54
node_modules/@astrojs/language-server/dist/importPackage.js
generated
vendored
Normal file
54
node_modules/@astrojs/language-server/dist/importPackage.js
generated
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getPrettierPluginPath = exports.importPrettier = exports.importVueIntegration = exports.importSvelteIntegration = exports.getPackagePath = exports.setIsTrusted = void 0;
|
||||
const path_1 = require("path");
|
||||
let isTrusted = true;
|
||||
function setIsTrusted(_isTrusted) {
|
||||
isTrusted = _isTrusted;
|
||||
}
|
||||
exports.setIsTrusted = setIsTrusted;
|
||||
function getPackagePath(packageName, fromPath) {
|
||||
const paths = [];
|
||||
if (isTrusted) {
|
||||
paths.unshift(...fromPath);
|
||||
}
|
||||
try {
|
||||
return (0, path_1.dirname)(require.resolve(packageName + '/package.json', { paths }));
|
||||
}
|
||||
catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
exports.getPackagePath = getPackagePath;
|
||||
function importEditorIntegration(packageName, fromPath) {
|
||||
const pkgPath = getPackagePath(packageName, [fromPath]);
|
||||
if (pkgPath) {
|
||||
try {
|
||||
const main = (0, path_1.resolve)(pkgPath, 'dist', 'editor.cjs');
|
||||
return require(main);
|
||||
}
|
||||
catch (e) {
|
||||
console.error(`Couldn't load editor module from ${pkgPath}. Make sure you're using at least version v0.2.1 of the corresponding integration`);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
function importSvelteIntegration(fromPath) {
|
||||
return importEditorIntegration('@astrojs/svelte', fromPath);
|
||||
}
|
||||
exports.importSvelteIntegration = importSvelteIntegration;
|
||||
function importVueIntegration(fromPath) {
|
||||
return importEditorIntegration('@astrojs/vue', fromPath);
|
||||
}
|
||||
exports.importVueIntegration = importVueIntegration;
|
||||
function importPrettier(fromPath) {
|
||||
// This shouldn't ever fail, because we bundle Prettier in the extension itself
|
||||
const prettierPkg = getPackagePath('prettier', [fromPath, __dirname]);
|
||||
return require(prettierPkg);
|
||||
}
|
||||
exports.importPrettier = importPrettier;
|
||||
function getPrettierPluginPath(fromPath) {
|
||||
return getPackagePath('prettier-plugin-astro', [fromPath, __dirname]);
|
||||
}
|
||||
exports.getPrettierPluginPath = getPrettierPluginPath;
|
||||
2
node_modules/@astrojs/language-server/dist/index.d.ts
generated
vendored
Normal file
2
node_modules/@astrojs/language-server/dist/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export { AstroCheck, Diagnostic, DiagnosticSeverity, GetDiagnosticsResult } from './check';
|
||||
export { offsetAt } from './core/documents';
|
||||
8
node_modules/@astrojs/language-server/dist/index.js
generated
vendored
Normal file
8
node_modules/@astrojs/language-server/dist/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.offsetAt = exports.DiagnosticSeverity = exports.AstroCheck = void 0;
|
||||
var check_1 = require("./check");
|
||||
Object.defineProperty(exports, "AstroCheck", { enumerable: true, get: function () { return check_1.AstroCheck; } });
|
||||
Object.defineProperty(exports, "DiagnosticSeverity", { enumerable: true, get: function () { return check_1.DiagnosticSeverity; } });
|
||||
var documents_1 = require("./core/documents");
|
||||
Object.defineProperty(exports, "offsetAt", { enumerable: true, get: function () { return documents_1.offsetAt; } });
|
||||
1
node_modules/@astrojs/language-server/dist/node.d.ts
generated
vendored
Normal file
1
node_modules/@astrojs/language-server/dist/node.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
export {};
|
||||
43
node_modules/@astrojs/language-server/dist/node.js
generated
vendored
Normal file
43
node_modules/@astrojs/language-server/dist/node.js
generated
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const vscode = __importStar(require("vscode-languageserver/node"));
|
||||
const server_1 = require("./server");
|
||||
const connection = vscode.createConnection(vscode.ProposedFeatures.all);
|
||||
(0, server_1.startLanguageServer)(connection, {
|
||||
loadTypescript(options) {
|
||||
if (options?.typescript?.serverPath) {
|
||||
return require(options?.typescript?.serverPath);
|
||||
}
|
||||
},
|
||||
loadTypescriptLocalized(options) {
|
||||
if (options?.typescript?.localizedPath) {
|
||||
try {
|
||||
return require(options?.typescript?.localizedPath);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
},
|
||||
});
|
||||
42
node_modules/@astrojs/language-server/dist/plugins/PluginHost.d.ts
generated
vendored
Normal file
42
node_modules/@astrojs/language-server/dist/plugins/PluginHost.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import { CancellationToken, CodeAction, CodeActionContext, Color, ColorInformation, ColorPresentation, CompletionContext, CompletionItem, CompletionList, DefinitionLink, Diagnostic, FoldingRange, FormattingOptions, Hover, InlayHint, LinkedEditingRanges, Location, Position, Range, ReferenceContext, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, TextDocumentIdentifier, TextEdit, WorkspaceEdit } from 'vscode-languageserver';
|
||||
import type { DocumentManager } from '../core/documents/DocumentManager';
|
||||
import type { AppCompletionItem, Plugin } from './interfaces';
|
||||
export interface PluginHostConfig {
|
||||
filterIncompleteCompletions: boolean;
|
||||
definitionLinkSupport: boolean;
|
||||
}
|
||||
export declare class PluginHost {
|
||||
private docManager;
|
||||
private plugins;
|
||||
private pluginHostConfig;
|
||||
constructor(docManager: DocumentManager);
|
||||
initialize(pluginHostConfig: PluginHostConfig): void;
|
||||
registerPlugin(plugin: Plugin): void;
|
||||
getCompletions(textDocument: TextDocumentIdentifier, position: Position, completionContext?: CompletionContext, cancellationToken?: CancellationToken): Promise<CompletionList>;
|
||||
resolveCompletion(textDocument: TextDocumentIdentifier, completionItem: AppCompletionItem): Promise<CompletionItem>;
|
||||
getDiagnostics(textDocument: TextDocumentIdentifier): Promise<Diagnostic[]>;
|
||||
doHover(textDocument: TextDocumentIdentifier, position: Position): Promise<Hover | null>;
|
||||
formatDocument(textDocument: TextDocumentIdentifier, options: FormattingOptions): Promise<TextEdit[]>;
|
||||
getCodeActions(textDocument: TextDocumentIdentifier, range: Range, context: CodeActionContext, cancellationToken?: CancellationToken): Promise<CodeAction[]>;
|
||||
doTagComplete(textDocument: TextDocumentIdentifier, position: Position): Promise<string | null>;
|
||||
getFoldingRanges(textDocument: TextDocumentIdentifier): Promise<FoldingRange[] | null>;
|
||||
getDocumentSymbols(textDocument: TextDocumentIdentifier, cancellationToken?: CancellationToken): Promise<SymbolInformation[]>;
|
||||
getSemanticTokens(textDocument: TextDocumentIdentifier, range?: Range, cancellationToken?: CancellationToken): Promise<SemanticTokens | null>;
|
||||
getLinkedEditingRanges(textDocument: TextDocumentIdentifier, position: Position): Promise<LinkedEditingRanges | null>;
|
||||
fileReferences(textDocument: TextDocumentIdentifier): Promise<Location[] | null>;
|
||||
getDefinitions(textDocument: TextDocumentIdentifier, position: Position): Promise<DefinitionLink[] | Location[]>;
|
||||
getTypeDefinitions(textDocument: TextDocumentIdentifier, position: Position): Promise<Location[] | null>;
|
||||
getImplementations(textDocument: TextDocumentIdentifier, position: Position): Promise<Location[] | null>;
|
||||
getReferences(textdocument: TextDocumentIdentifier, position: Position, context: ReferenceContext): Promise<Location[] | null>;
|
||||
prepareRename(textDocument: TextDocumentIdentifier, position: Position): Promise<Range | null>;
|
||||
rename(textDocument: TextDocumentIdentifier, position: Position, newName: string): Promise<WorkspaceEdit | null>;
|
||||
getDocumentColors(textDocument: TextDocumentIdentifier): Promise<ColorInformation[]>;
|
||||
getColorPresentations(textDocument: TextDocumentIdentifier, range: Range, color: Color): Promise<ColorPresentation[]>;
|
||||
getInlayHints(textDocument: TextDocumentIdentifier, range: Range, cancellationToken?: CancellationToken): Promise<InlayHint[]>;
|
||||
getSignatureHelp(textDocument: TextDocumentIdentifier, position: Position, context: SignatureHelpContext | undefined, cancellationToken?: CancellationToken): Promise<SignatureHelp | null>;
|
||||
onWatchFileChanges(onWatchFileChangesParams: any[]): Promise<void>;
|
||||
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[], text?: string): void;
|
||||
private getDocument;
|
||||
private execute;
|
||||
private tryExecutePlugin;
|
||||
}
|
||||
206
node_modules/@astrojs/language-server/dist/plugins/PluginHost.js
generated
vendored
Normal file
206
node_modules/@astrojs/language-server/dist/plugins/PluginHost.js
generated
vendored
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PluginHost = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const documents_1 = require("../core/documents");
|
||||
const utils_1 = require("../utils");
|
||||
var ExecuteMode;
|
||||
(function (ExecuteMode) {
|
||||
ExecuteMode[ExecuteMode["None"] = 0] = "None";
|
||||
ExecuteMode[ExecuteMode["FirstNonNull"] = 1] = "FirstNonNull";
|
||||
ExecuteMode[ExecuteMode["Collect"] = 2] = "Collect";
|
||||
})(ExecuteMode || (ExecuteMode = {}));
|
||||
class PluginHost {
|
||||
constructor(docManager) {
|
||||
this.docManager = docManager;
|
||||
this.plugins = [];
|
||||
this.pluginHostConfig = {
|
||||
filterIncompleteCompletions: true,
|
||||
definitionLinkSupport: false,
|
||||
};
|
||||
}
|
||||
initialize(pluginHostConfig) {
|
||||
this.pluginHostConfig = pluginHostConfig;
|
||||
}
|
||||
registerPlugin(plugin) {
|
||||
this.plugins.push(plugin);
|
||||
}
|
||||
async getCompletions(textDocument, position, completionContext, cancellationToken) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
const completions = await Promise.all(this.plugins.map(async (plugin) => {
|
||||
const result = await this.tryExecutePlugin(plugin, 'getCompletions', [document, position, completionContext, cancellationToken], null);
|
||||
if (result) {
|
||||
return { result: result, plugin: plugin.__name };
|
||||
}
|
||||
})).then((fullCompletions) => fullCompletions.filter(utils_1.isNotNullOrUndefined));
|
||||
const html = completions.find((completion) => completion.plugin === 'html');
|
||||
const ts = completions.find((completion) => completion.plugin === 'typescript');
|
||||
const astro = completions.find((completion) => completion.plugin === 'astro');
|
||||
if (html && ts) {
|
||||
const inComponentStartTag = (0, documents_1.isInComponentStartTag)(document.html, document.offsetAt(position));
|
||||
// If the HTML plugin returned completions, it's highly likely that TS ones are duplicate
|
||||
if (html.result.items.length > 0) {
|
||||
ts.result.items = [];
|
||||
}
|
||||
// Inside components, if the Astro plugin has completions we don't want the TS ones are they're duplicates
|
||||
if (astro && astro.result.items.length > 0 && inComponentStartTag) {
|
||||
ts.result.items = [];
|
||||
}
|
||||
}
|
||||
let flattenedCompletions = completions.flatMap((completion) => completion.result.items);
|
||||
const isIncomplete = completions.reduce((incomplete, completion) => incomplete || completion.result.isIncomplete, false);
|
||||
// If the result is incomplete, we need to filter the results ourselves
|
||||
// to throw out non-matching results. VSCode does filter client-side,
|
||||
// but other IDEs might not.
|
||||
if (isIncomplete && this.pluginHostConfig.filterIncompleteCompletions) {
|
||||
const offset = document.offsetAt(position);
|
||||
// Assumption for performance reasons:
|
||||
// Noone types import names longer than 20 characters and still expects perfect autocompletion.
|
||||
const text = document.getText().substring(Math.max(0, offset - 20), offset);
|
||||
const start = (0, utils_1.regexLastIndexOf)(text, /[\W\s]/g) + 1;
|
||||
const filterValue = text.substring(start).toLowerCase();
|
||||
flattenedCompletions = flattenedCompletions.filter((comp) => comp.label.toLowerCase().includes(filterValue));
|
||||
}
|
||||
return vscode_languageserver_1.CompletionList.create(flattenedCompletions, isIncomplete);
|
||||
}
|
||||
async resolveCompletion(textDocument, completionItem) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
const result = await this.execute('resolveCompletion', [document, completionItem], ExecuteMode.FirstNonNull);
|
||||
return result ?? completionItem;
|
||||
}
|
||||
async getDiagnostics(textDocument) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
const diagnostics = await this.execute('getDiagnostics', [document], ExecuteMode.Collect);
|
||||
return diagnostics;
|
||||
}
|
||||
async doHover(textDocument, position) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return this.execute('doHover', [document, position], ExecuteMode.FirstNonNull);
|
||||
}
|
||||
async formatDocument(textDocument, options) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return await this.execute('formatDocument', [document, options], ExecuteMode.Collect);
|
||||
}
|
||||
async getCodeActions(textDocument, range, context, cancellationToken) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return await this.execute('getCodeActions', [document, range, context, cancellationToken], ExecuteMode.Collect);
|
||||
}
|
||||
async doTagComplete(textDocument, position) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return this.execute('doTagComplete', [document, position], ExecuteMode.FirstNonNull);
|
||||
}
|
||||
async getFoldingRanges(textDocument) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return await this.execute('getFoldingRanges', [document], ExecuteMode.Collect);
|
||||
}
|
||||
async getDocumentSymbols(textDocument, cancellationToken) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return await this.execute('getDocumentSymbols', [document, cancellationToken], ExecuteMode.Collect);
|
||||
}
|
||||
async getSemanticTokens(textDocument, range, cancellationToken) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return await this.execute('getSemanticTokens', [document, range, cancellationToken], ExecuteMode.FirstNonNull);
|
||||
}
|
||||
async getLinkedEditingRanges(textDocument, position) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return await this.execute('getLinkedEditingRanges', [document, position], ExecuteMode.FirstNonNull);
|
||||
}
|
||||
async fileReferences(textDocument) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return await this.execute('fileReferences', [document], ExecuteMode.FirstNonNull);
|
||||
}
|
||||
async getDefinitions(textDocument, position) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
const definitions = await this.execute('getDefinitions', [document, position], ExecuteMode.Collect);
|
||||
if (this.pluginHostConfig.definitionLinkSupport) {
|
||||
return definitions;
|
||||
}
|
||||
else {
|
||||
return definitions.map((def) => ({ range: def.targetSelectionRange, uri: def.targetUri }));
|
||||
}
|
||||
}
|
||||
getTypeDefinitions(textDocument, position) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return this.execute('getTypeDefinitions', [document, position], ExecuteMode.FirstNonNull);
|
||||
}
|
||||
getImplementations(textDocument, position) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return this.execute('getImplementation', [document, position], ExecuteMode.FirstNonNull);
|
||||
}
|
||||
getReferences(textdocument, position, context) {
|
||||
const document = this.getDocument(textdocument.uri);
|
||||
return this.execute('findReferences', [document, position, context], ExecuteMode.FirstNonNull);
|
||||
}
|
||||
async prepareRename(textDocument, position) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return await this.execute('prepareRename', [document, position], ExecuteMode.FirstNonNull);
|
||||
}
|
||||
async rename(textDocument, position, newName) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return this.execute('rename', [document, position, newName], ExecuteMode.FirstNonNull);
|
||||
}
|
||||
async getDocumentColors(textDocument) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return await this.execute('getDocumentColors', [document], ExecuteMode.Collect);
|
||||
}
|
||||
async getColorPresentations(textDocument, range, color) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return await this.execute('getColorPresentations', [document, range, color], ExecuteMode.Collect);
|
||||
}
|
||||
async getInlayHints(textDocument, range, cancellationToken) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return (await this.execute('getInlayHints', [document, range], ExecuteMode.FirstNonNull)) ?? [];
|
||||
}
|
||||
async getSignatureHelp(textDocument, position, context, cancellationToken) {
|
||||
const document = this.getDocument(textDocument.uri);
|
||||
return await this.execute('getSignatureHelp', [document, position, context, cancellationToken], ExecuteMode.FirstNonNull);
|
||||
}
|
||||
async onWatchFileChanges(onWatchFileChangesParams) {
|
||||
for (const support of this.plugins) {
|
||||
await support.onWatchFileChanges?.(onWatchFileChangesParams);
|
||||
}
|
||||
}
|
||||
updateNonAstroFile(fileName, changes, text) {
|
||||
for (const support of this.plugins) {
|
||||
support.updateNonAstroFile?.(fileName, changes, text);
|
||||
}
|
||||
}
|
||||
getDocument(uri) {
|
||||
const document = this.docManager.get(uri);
|
||||
if (!document) {
|
||||
throw new Error('Cannot call methods on an unopened document');
|
||||
}
|
||||
return document;
|
||||
}
|
||||
async execute(name, args, mode) {
|
||||
const plugins = this.plugins.filter((plugin) => typeof plugin[name] === 'function');
|
||||
switch (mode) {
|
||||
case ExecuteMode.FirstNonNull:
|
||||
for (const plugin of plugins) {
|
||||
const res = await this.tryExecutePlugin(plugin, name, args, null);
|
||||
if (res != null) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
case ExecuteMode.Collect:
|
||||
return (await Promise.all(plugins.map((plugin) => {
|
||||
let ret = this.tryExecutePlugin(plugin, name, args, []);
|
||||
return ret;
|
||||
}))).flat();
|
||||
case ExecuteMode.None:
|
||||
await Promise.all(plugins.map((plugin) => this.tryExecutePlugin(plugin, name, args, null)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
async tryExecutePlugin(plugin, fnName, args, failValue) {
|
||||
try {
|
||||
return await plugin[fnName](...args);
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e);
|
||||
return failValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.PluginHost = PluginHost;
|
||||
17
node_modules/@astrojs/language-server/dist/plugins/astro/AstroPlugin.d.ts
generated
vendored
Normal file
17
node_modules/@astrojs/language-server/dist/plugins/astro/AstroPlugin.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { CompletionContext, Diagnostic, FoldingRange, FormattingOptions, Position, TextEdit } from 'vscode-languageserver';
|
||||
import type { ConfigManager } from '../../core/config';
|
||||
import type { AstroDocument } from '../../core/documents';
|
||||
import type { AppCompletionList, Plugin } from '../interfaces';
|
||||
import type { LanguageServiceManager } from '../typescript/LanguageServiceManager';
|
||||
export declare class AstroPlugin implements Plugin {
|
||||
__name: string;
|
||||
private configManager;
|
||||
private readonly languageServiceManager;
|
||||
private readonly completionProvider;
|
||||
private readonly diagnosticsProvider;
|
||||
constructor(configManager: ConfigManager, languageServiceManager: LanguageServiceManager);
|
||||
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<AppCompletionList | null>;
|
||||
getDiagnostics(document: AstroDocument): Promise<Diagnostic[]>;
|
||||
formatDocument(document: AstroDocument, options: FormattingOptions): Promise<TextEdit[]>;
|
||||
getFoldingRanges(document: AstroDocument): FoldingRange[];
|
||||
}
|
||||
90
node_modules/@astrojs/language-server/dist/plugins/astro/AstroPlugin.js
generated
vendored
Normal file
90
node_modules/@astrojs/language-server/dist/plugins/astro/AstroPlugin.js
generated
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AstroPlugin = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const importPackage_1 = require("../../importPackage");
|
||||
const CompletionsProvider_1 = require("./features/CompletionsProvider");
|
||||
const DiagnosticsProvider_1 = require("./features/DiagnosticsProvider");
|
||||
class AstroPlugin {
|
||||
constructor(configManager, languageServiceManager) {
|
||||
this.__name = 'astro';
|
||||
this.configManager = configManager;
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.completionProvider = new CompletionsProvider_1.CompletionsProviderImpl(this.languageServiceManager);
|
||||
this.diagnosticsProvider = new DiagnosticsProvider_1.DiagnosticsProviderImpl(this.languageServiceManager);
|
||||
}
|
||||
async getCompletions(document, position, completionContext) {
|
||||
const completions = this.completionProvider.getCompletions(document, position, completionContext);
|
||||
return completions;
|
||||
}
|
||||
async getDiagnostics(document) {
|
||||
return await this.diagnosticsProvider.getDiagnostics(document);
|
||||
}
|
||||
async formatDocument(document, options) {
|
||||
const filePath = document.getFilePath();
|
||||
if (!filePath) {
|
||||
return [];
|
||||
}
|
||||
const prettier = (0, importPackage_1.importPrettier)(filePath);
|
||||
const prettierConfig = (await prettier.resolveConfig(filePath, { editorconfig: true, useCache: false })) ?? {};
|
||||
const prettierVSConfig = await this.configManager.getPrettierVSConfig(document);
|
||||
const editorFormatConfig = options !== undefined // We need to check for options existing here because some editors might not have it
|
||||
? {
|
||||
tabWidth: options.tabSize,
|
||||
useTabs: !options.insertSpaces,
|
||||
}
|
||||
: {};
|
||||
// Return a config with the following cascade:
|
||||
// - Prettier config file should always win if it exists, if it doesn't:
|
||||
// - Prettier config from the VS Code extension is used, if it doesn't exist:
|
||||
// - Use the editor's basic configuration settings
|
||||
const resultConfig = returnObjectIfHasKeys(prettierConfig) || returnObjectIfHasKeys(prettierVSConfig) || editorFormatConfig;
|
||||
const fileInfo = await prettier.getFileInfo(filePath, { ignorePath: '.prettierignore' });
|
||||
if (fileInfo.ignored) {
|
||||
return [];
|
||||
}
|
||||
const result = prettier.format(document.getText(), {
|
||||
...resultConfig,
|
||||
plugins: [...getAstroPrettierPlugin(), ...(resultConfig.plugins ?? [])],
|
||||
parser: 'astro',
|
||||
});
|
||||
return document.getText() === result
|
||||
? []
|
||||
: [vscode_languageserver_1.TextEdit.replace(vscode_languageserver_1.Range.create(document.positionAt(0), document.positionAt(document.getTextLength())), result)];
|
||||
function getAstroPrettierPlugin() {
|
||||
const hasPluginLoadedAlready = prettier.getSupportInfo().languages.some((l) => l.name === 'astro');
|
||||
return hasPluginLoadedAlready ? [] : [(0, importPackage_1.getPrettierPluginPath)(filePath)];
|
||||
}
|
||||
}
|
||||
getFoldingRanges(document) {
|
||||
const foldingRanges = [];
|
||||
const { frontmatter } = document.astroMeta;
|
||||
// Currently editing frontmatter, don't fold
|
||||
if (frontmatter.state !== 'closed')
|
||||
return foldingRanges;
|
||||
// The way folding ranges work is by folding anything between the starting position and the ending one, as such
|
||||
// the start in this case should be after the frontmatter start (after the starting ---) until the last character
|
||||
// of the last line of the frontmatter before its ending (before the closing ---)
|
||||
// ---
|
||||
// ^ -- start
|
||||
// console.log("Astro")
|
||||
// --- ^ -- end
|
||||
const start = document.positionAt(frontmatter.startOffset + 3);
|
||||
const end = document.positionAt(frontmatter.endOffset - 1);
|
||||
return [
|
||||
{
|
||||
startLine: start.line,
|
||||
startCharacter: start.character,
|
||||
endLine: end.line,
|
||||
endCharacter: end.character,
|
||||
kind: vscode_languageserver_1.FoldingRangeKind.Imports,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
exports.AstroPlugin = AstroPlugin;
|
||||
function returnObjectIfHasKeys(obj) {
|
||||
if (Object.keys(obj || {}).length > 0) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
17
node_modules/@astrojs/language-server/dist/plugins/astro/features/CompletionsProvider.d.ts
generated
vendored
Normal file
17
node_modules/@astrojs/language-server/dist/plugins/astro/features/CompletionsProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { CompletionContext, Position } from 'vscode-languageserver';
|
||||
import type { AstroDocument } from '../../../core/documents';
|
||||
import type { AppCompletionList, CompletionsProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../../typescript/LanguageServiceManager';
|
||||
export declare class CompletionsProviderImpl implements CompletionsProvider {
|
||||
private readonly languageServiceManager;
|
||||
private readonly ts;
|
||||
private lastCompletion;
|
||||
directivesHTMLLang: import("vscode-html-languageservice").LanguageService;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<AppCompletionList | null>;
|
||||
private getComponentScriptCompletion;
|
||||
private getPropCompletionsAndFilePath;
|
||||
private getImportedSymbol;
|
||||
private getPropType;
|
||||
private getCompletionItemForProperty;
|
||||
}
|
||||
242
node_modules/@astrojs/language-server/dist/plugins/astro/features/CompletionsProvider.js
generated
vendored
Normal file
242
node_modules/@astrojs/language-server/dist/plugins/astro/features/CompletionsProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CompletionsProviderImpl = void 0;
|
||||
const vscode_html_languageservice_1 = require("vscode-html-languageservice");
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const utils_1 = require("../../../core/documents/utils");
|
||||
const astro_attributes_1 = require("../../html/features/astro-attributes");
|
||||
const utils_2 = require("../../html/utils");
|
||||
const utils_3 = require("../../typescript/utils");
|
||||
class CompletionsProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.lastCompletion = null;
|
||||
this.directivesHTMLLang = (0, vscode_html_languageservice_1.getLanguageService)({
|
||||
customDataProviders: [astro_attributes_1.astroDirectives],
|
||||
useDefaultDataProvider: false,
|
||||
});
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
}
|
||||
async getCompletions(document, position, completionContext) {
|
||||
let items = [];
|
||||
const html = document.html;
|
||||
const offset = document.offsetAt(position);
|
||||
const node = html.findNodeAt(offset);
|
||||
const insideExpression = (0, utils_1.isInsideExpression)(document.getText(), node.start, offset);
|
||||
if (completionContext?.triggerCharacter === '-' && node.parent === undefined && !insideExpression) {
|
||||
const frontmatter = this.getComponentScriptCompletion(document, position);
|
||||
if (frontmatter)
|
||||
items.push(frontmatter);
|
||||
}
|
||||
if ((0, utils_1.isInComponentStartTag)(html, offset) && !insideExpression) {
|
||||
const { completions: props, componentFilePath } = await this.getPropCompletionsAndFilePath(document, position, completionContext);
|
||||
if (props.length) {
|
||||
items.push(...props);
|
||||
}
|
||||
const isAstro = componentFilePath?.endsWith('.astro');
|
||||
if (!isAstro && node.tag !== 'Fragment') {
|
||||
const directives = (0, utils_2.removeDataAttrCompletion)(this.directivesHTMLLang.doComplete(document, position, html).items);
|
||||
items.push(...directives);
|
||||
}
|
||||
}
|
||||
return vscode_languageserver_1.CompletionList.create(items, true);
|
||||
}
|
||||
getComponentScriptCompletion(document, position) {
|
||||
const base = {
|
||||
kind: vscode_languageserver_1.CompletionItemKind.Snippet,
|
||||
label: '---',
|
||||
sortText: '\0',
|
||||
preselect: true,
|
||||
detail: 'Create component script block',
|
||||
insertTextFormat: vscode_languageserver_1.InsertTextFormat.Snippet,
|
||||
commitCharacters: [],
|
||||
};
|
||||
const prefix = document.getLineUntilOffset(document.offsetAt(position));
|
||||
if (document.astroMeta.frontmatter.state === null) {
|
||||
return {
|
||||
...base,
|
||||
insertText: '---\n$0\n---',
|
||||
textEdit: prefix.match(/^\s*\-+/)
|
||||
? vscode_languageserver_1.TextEdit.replace({ start: { ...position, character: 0 }, end: position }, '---\n$0\n---')
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
if (document.astroMeta.frontmatter.state === 'open') {
|
||||
let insertText = '---';
|
||||
// If the current line is a full component script starter/ender, the user expects a full frontmatter
|
||||
// completion and not just a completion for "---" on the same line (which result in, well, nothing)
|
||||
if (prefix === '---') {
|
||||
insertText = '---\n$0\n---';
|
||||
}
|
||||
return {
|
||||
...base,
|
||||
insertText,
|
||||
detail: insertText === '---' ? 'Close component script block' : 'Create component script block',
|
||||
textEdit: prefix.match(/^\s*\-+/)
|
||||
? vscode_languageserver_1.TextEdit.replace({ start: { ...position, character: 0 }, end: position }, insertText)
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
async getPropCompletionsAndFilePath(document, position, completionContext) {
|
||||
const offset = document.offsetAt(position);
|
||||
const html = document.html;
|
||||
const node = html.findNodeAt(offset);
|
||||
if (!(0, utils_1.isPossibleComponent)(node)) {
|
||||
return { completions: [], componentFilePath: null };
|
||||
}
|
||||
const inAttribute = node.start + node.tag.length < offset;
|
||||
if (!inAttribute) {
|
||||
return { completions: [], componentFilePath: null };
|
||||
}
|
||||
if (completionContext?.triggerCharacter === '/' || completionContext?.triggerCharacter === '>') {
|
||||
return { completions: [], componentFilePath: null };
|
||||
}
|
||||
// If inside of attribute value, skip.
|
||||
if (completionContext &&
|
||||
completionContext.triggerKind === vscode_languageserver_1.CompletionTriggerKind.TriggerCharacter &&
|
||||
completionContext.triggerCharacter === '"') {
|
||||
return { completions: [], componentFilePath: null };
|
||||
}
|
||||
const componentName = node.tag;
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
// Get the source file
|
||||
const tsFilePath = tsDoc.filePath;
|
||||
const program = lang.getProgram();
|
||||
const sourceFile = program?.getSourceFile(tsFilePath);
|
||||
const typeChecker = program?.getTypeChecker();
|
||||
if (!sourceFile || !typeChecker) {
|
||||
return { completions: [], componentFilePath: null };
|
||||
}
|
||||
// Get the import statement
|
||||
const imp = this.getImportedSymbol(sourceFile, componentName);
|
||||
const importType = imp && typeChecker.getTypeAtLocation(imp);
|
||||
if (!importType) {
|
||||
return { completions: [], componentFilePath: null };
|
||||
}
|
||||
const symbol = importType.getSymbol();
|
||||
if (!symbol) {
|
||||
return { completions: [], componentFilePath: null };
|
||||
}
|
||||
const symbolDeclaration = symbol.declarations;
|
||||
if (!symbolDeclaration) {
|
||||
return { completions: [], componentFilePath: null };
|
||||
}
|
||||
const filePath = symbolDeclaration[0].getSourceFile().fileName;
|
||||
const componentSnapshot = await this.languageServiceManager.getSnapshot(filePath);
|
||||
if (this.lastCompletion) {
|
||||
if (this.lastCompletion.tag === componentName &&
|
||||
this.lastCompletion.documentVersion == componentSnapshot.version) {
|
||||
return { completions: this.lastCompletion.completions, componentFilePath: filePath };
|
||||
}
|
||||
}
|
||||
// Get the component's props type
|
||||
const componentType = this.getPropType(symbolDeclaration, typeChecker);
|
||||
if (!componentType) {
|
||||
return { completions: [], componentFilePath: null };
|
||||
}
|
||||
let completionItems = [];
|
||||
// Add completions for this component's props type properties
|
||||
const properties = componentType.getProperties().filter((property) => property.name !== 'children') || [];
|
||||
properties.forEach((property) => {
|
||||
const type = typeChecker.getTypeOfSymbolAtLocation(property, imp);
|
||||
let completionItem = this.getCompletionItemForProperty(property, typeChecker, type);
|
||||
completionItems.push(completionItem);
|
||||
});
|
||||
this.lastCompletion = {
|
||||
tag: componentName,
|
||||
documentVersion: componentSnapshot.version,
|
||||
completions: completionItems,
|
||||
};
|
||||
return { completions: completionItems, componentFilePath: filePath };
|
||||
}
|
||||
getImportedSymbol(sourceFile, identifier) {
|
||||
for (let list of sourceFile.getChildren()) {
|
||||
for (let node of list.getChildren()) {
|
||||
if (this.ts.isImportDeclaration(node)) {
|
||||
let clauses = node.importClause;
|
||||
if (!clauses)
|
||||
continue;
|
||||
let namedImport = clauses.getChildAt(0);
|
||||
if (this.ts.isNamedImports(namedImport)) {
|
||||
for (let imp of namedImport.elements) {
|
||||
// Iterate the named imports
|
||||
if (imp.name.getText() === identifier) {
|
||||
return imp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.ts.isIdentifier(namedImport)) {
|
||||
if (namedImport.getText() === identifier) {
|
||||
return namedImport;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
getPropType(declarations, typeChecker) {
|
||||
for (const decl of declarations) {
|
||||
const fileName = (0, utils_3.toVirtualFilePath)(decl.getSourceFile().fileName);
|
||||
if (fileName.endsWith('.tsx') || fileName.endsWith('.jsx') || fileName.endsWith('.d.ts')) {
|
||||
if (!this.ts.isFunctionDeclaration(decl) && !this.ts.isFunctionTypeNode(decl)) {
|
||||
console.error(`We only support functions declarations at the moment`);
|
||||
continue;
|
||||
}
|
||||
const fn = decl;
|
||||
if (!fn.parameters.length)
|
||||
continue;
|
||||
const param1 = fn.parameters[0];
|
||||
const propType = typeChecker.getTypeAtLocation(param1);
|
||||
return propType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
getCompletionItemForProperty(mem, typeChecker, type) {
|
||||
const typeString = typeChecker.typeToString(type);
|
||||
let insertText = mem.name;
|
||||
switch (typeString) {
|
||||
case 'string':
|
||||
insertText = `${mem.name}="$1"`;
|
||||
break;
|
||||
case 'boolean':
|
||||
insertText = mem.name;
|
||||
break;
|
||||
default:
|
||||
insertText = `${mem.name}={$1}`;
|
||||
break;
|
||||
}
|
||||
let item = {
|
||||
label: mem.name,
|
||||
detail: typeString,
|
||||
insertText: insertText,
|
||||
insertTextFormat: vscode_languageserver_1.InsertTextFormat.Snippet,
|
||||
commitCharacters: [],
|
||||
// Ensure that props shows up first as a completion, despite this plugin being ran after the HTML one
|
||||
sortText: '\0',
|
||||
};
|
||||
if (mem.flags & this.ts.SymbolFlags.Optional) {
|
||||
item.filterText = item.label;
|
||||
item.label += '?';
|
||||
// Put optional props at a lower priority
|
||||
item.sortText = '_';
|
||||
}
|
||||
mem.getDocumentationComment(typeChecker);
|
||||
let description = mem
|
||||
.getDocumentationComment(typeChecker)
|
||||
.map((val) => val.text)
|
||||
.join('\n');
|
||||
if (description) {
|
||||
let docs = {
|
||||
kind: vscode_languageserver_1.MarkupKind.Markdown,
|
||||
value: description,
|
||||
};
|
||||
item.documentation = docs;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
exports.CompletionsProviderImpl = CompletionsProviderImpl;
|
||||
10
node_modules/@astrojs/language-server/dist/plugins/astro/features/DiagnosticsProvider.d.ts
generated
vendored
Normal file
10
node_modules/@astrojs/language-server/dist/plugins/astro/features/DiagnosticsProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { Diagnostic } from 'vscode-languageserver-types';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import { DiagnosticsProvider } from '../../interfaces';
|
||||
import { LanguageServiceManager } from '../../typescript/LanguageServiceManager';
|
||||
export declare class DiagnosticsProviderImpl implements DiagnosticsProvider {
|
||||
private languageServiceManager;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
getDiagnostics(document: AstroDocument): Promise<Diagnostic[]>;
|
||||
private compilerMessageToDiagnostic;
|
||||
}
|
||||
23
node_modules/@astrojs/language-server/dist/plugins/astro/features/DiagnosticsProvider.js
generated
vendored
Normal file
23
node_modules/@astrojs/language-server/dist/plugins/astro/features/DiagnosticsProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.DiagnosticsProviderImpl = void 0;
|
||||
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
||||
class DiagnosticsProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
}
|
||||
async getDiagnostics(document) {
|
||||
const { tsDoc } = (await this.languageServiceManager.getLSAndTSDoc(document));
|
||||
return tsDoc.compilerDiagnostics.map(this.compilerMessageToDiagnostic);
|
||||
}
|
||||
compilerMessageToDiagnostic(message) {
|
||||
return {
|
||||
message: message.text + '\n\n' + message.hint,
|
||||
range: vscode_languageserver_types_1.Range.create(message.location.line - 1, message.location.column - 1, message.location.line, message.location.length),
|
||||
code: message.code,
|
||||
severity: message.severity,
|
||||
source: 'astro',
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.DiagnosticsProviderImpl = DiagnosticsProviderImpl;
|
||||
45
node_modules/@astrojs/language-server/dist/plugins/css/CSSDocument.d.ts
generated
vendored
Normal file
45
node_modules/@astrojs/language-server/dist/plugins/css/CSSDocument.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import type { Stylesheet, TextDocument } from 'vscode-css-languageservice';
|
||||
import type { Position } from 'vscode-languageserver';
|
||||
import { AstroDocument, DocumentMapper, ReadableDocument, TagInformation } from '../../core/documents';
|
||||
export interface CSSDocumentBase extends DocumentMapper, TextDocument {
|
||||
languageId: string;
|
||||
stylesheet: Stylesheet;
|
||||
}
|
||||
export declare class CSSDocument extends ReadableDocument implements DocumentMapper {
|
||||
private parent;
|
||||
private styleInfo;
|
||||
readonly version: number;
|
||||
stylesheet: Stylesheet;
|
||||
languageId: string;
|
||||
constructor(parent: AstroDocument, styleInfo: Pick<TagInformation, 'attributes' | 'start' | 'end'>);
|
||||
/**
|
||||
* Get the fragment position relative to the parent
|
||||
* @param pos Position in fragment
|
||||
*/
|
||||
getOriginalPosition(pos: Position): Position;
|
||||
/**
|
||||
* Get the position relative to the start of the fragment
|
||||
* @param pos Position in parent
|
||||
*/
|
||||
getGeneratedPosition(pos: Position): Position;
|
||||
/**
|
||||
* Returns true if the given parent position is inside of this fragment
|
||||
* @param pos Position in parent
|
||||
*/
|
||||
isInGenerated(pos: Position): boolean;
|
||||
/**
|
||||
* Get the fragment text from the parent
|
||||
*/
|
||||
getText(): string;
|
||||
/**
|
||||
* Returns the length of the fragment as calculated from the start and end position
|
||||
*/
|
||||
getTextLength(): number;
|
||||
/**
|
||||
* Return the parent file path
|
||||
*/
|
||||
getFilePath(): string | null;
|
||||
getURL(): string;
|
||||
getAttributes(): Record<string, string>;
|
||||
private get language();
|
||||
}
|
||||
68
node_modules/@astrojs/language-server/dist/plugins/css/CSSDocument.js
generated
vendored
Normal file
68
node_modules/@astrojs/language-server/dist/plugins/css/CSSDocument.js
generated
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CSSDocument = void 0;
|
||||
const documents_1 = require("../../core/documents");
|
||||
const language_service_1 = require("./language-service");
|
||||
class CSSDocument extends documents_1.ReadableDocument {
|
||||
constructor(parent, styleInfo) {
|
||||
super();
|
||||
this.parent = parent;
|
||||
this.styleInfo = styleInfo;
|
||||
this.version = this.parent.version;
|
||||
this.languageId = this.language;
|
||||
this.stylesheet = (0, language_service_1.getLanguageService)(this.language).parseStylesheet(this);
|
||||
}
|
||||
/**
|
||||
* Get the fragment position relative to the parent
|
||||
* @param pos Position in fragment
|
||||
*/
|
||||
getOriginalPosition(pos) {
|
||||
const parentOffset = this.styleInfo.start + this.offsetAt(pos);
|
||||
return this.parent.positionAt(parentOffset);
|
||||
}
|
||||
/**
|
||||
* Get the position relative to the start of the fragment
|
||||
* @param pos Position in parent
|
||||
*/
|
||||
getGeneratedPosition(pos) {
|
||||
const fragmentOffset = this.parent.offsetAt(pos) - this.styleInfo.start;
|
||||
return this.positionAt(fragmentOffset);
|
||||
}
|
||||
/**
|
||||
* Returns true if the given parent position is inside of this fragment
|
||||
* @param pos Position in parent
|
||||
*/
|
||||
isInGenerated(pos) {
|
||||
const offset = this.parent.offsetAt(pos);
|
||||
return offset >= this.styleInfo.start && offset <= this.styleInfo.end;
|
||||
}
|
||||
/**
|
||||
* Get the fragment text from the parent
|
||||
*/
|
||||
getText() {
|
||||
return this.parent.getText().slice(this.styleInfo.start, this.styleInfo.end);
|
||||
}
|
||||
/**
|
||||
* Returns the length of the fragment as calculated from the start and end position
|
||||
*/
|
||||
getTextLength() {
|
||||
return this.styleInfo.end - this.styleInfo.start;
|
||||
}
|
||||
/**
|
||||
* Return the parent file path
|
||||
*/
|
||||
getFilePath() {
|
||||
return this.parent.getFilePath();
|
||||
}
|
||||
getURL() {
|
||||
return this.parent.getURL();
|
||||
}
|
||||
getAttributes() {
|
||||
return this.styleInfo.attributes;
|
||||
}
|
||||
get language() {
|
||||
const attrs = this.getAttributes();
|
||||
return attrs.lang || attrs.type || 'css';
|
||||
}
|
||||
}
|
||||
exports.CSSDocument = CSSDocument;
|
||||
39
node_modules/@astrojs/language-server/dist/plugins/css/CSSPlugin.d.ts
generated
vendored
Normal file
39
node_modules/@astrojs/language-server/dist/plugins/css/CSSPlugin.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { Color, ColorInformation, ColorPresentation, CompletionContext, CompletionList, FoldingRange, Hover, Position, Range, SymbolInformation, WorkspaceEdit } from 'vscode-languageserver';
|
||||
import type { ConfigManager } from '../../core/config/ConfigManager';
|
||||
import { AstroDocument } from '../../core/documents';
|
||||
import type { Plugin } from '../interfaces';
|
||||
export declare class CSSPlugin implements Plugin {
|
||||
__name: string;
|
||||
private configManager;
|
||||
private cssDocuments;
|
||||
private triggerCharacters;
|
||||
constructor(configManager: ConfigManager);
|
||||
doHover(document: AstroDocument, position: Position): Promise<Hover | null>;
|
||||
private doHoverInternal;
|
||||
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext): Promise<CompletionList | null>;
|
||||
private getCompletionsInternal;
|
||||
getDocumentColors(document: AstroDocument): Promise<ColorInformation[]>;
|
||||
getColorPresentations(document: AstroDocument, range: Range, color: Color): Promise<ColorPresentation[]>;
|
||||
prepareRename(document: AstroDocument, position: Position): Range | null;
|
||||
rename(document: AstroDocument, position: Position, newName: string): WorkspaceEdit | null;
|
||||
getFoldingRanges(document: AstroDocument): FoldingRange[] | null;
|
||||
getDocumentSymbols(document: AstroDocument): Promise<SymbolInformation[]>;
|
||||
private inStyleAttributeWithoutInterpolation;
|
||||
/**
|
||||
* Get the associated CSS Document for a style tag
|
||||
*/
|
||||
private getCSSDocumentForStyleTag;
|
||||
/**
|
||||
* Get all the CSSDocuments in a document
|
||||
*/
|
||||
private getCSSDocumentsForDocument;
|
||||
/**
|
||||
* Get all the stylesheets (Stylesheet type) in a document
|
||||
*/
|
||||
private getStylesheetsForDocument;
|
||||
/**
|
||||
* Get style tag at position for a document
|
||||
*/
|
||||
private getStyleTagForPosition;
|
||||
private featureEnabled;
|
||||
}
|
||||
274
node_modules/@astrojs/language-server/dist/plugins/css/CSSPlugin.js
generated
vendored
Normal file
274
node_modules/@astrojs/language-server/dist/plugins/css/CSSPlugin.js
generated
vendored
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CSSPlugin = void 0;
|
||||
const emmet_helper_1 = require("@vscode/emmet-helper");
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const documents_1 = require("../../core/documents");
|
||||
const parseHtml_1 = require("../../core/documents/parseHtml");
|
||||
const CSSDocument_1 = require("./CSSDocument");
|
||||
const getIdClassCompletions_1 = require("./features/getIdClassCompletions");
|
||||
const language_service_1 = require("./language-service");
|
||||
const StyleAttributeDocument_1 = require("./StyleAttributeDocument");
|
||||
class CSSPlugin {
|
||||
constructor(configManager) {
|
||||
this.__name = 'css';
|
||||
this.cssDocuments = new WeakMap();
|
||||
this.triggerCharacters = new Set(['.', ':', '-', '/']);
|
||||
this.configManager = configManager;
|
||||
}
|
||||
async doHover(document, position) {
|
||||
if (!(await this.featureEnabled(document, 'hover'))) {
|
||||
return null;
|
||||
}
|
||||
if ((0, documents_1.isInsideFrontmatter)(document.getText(), document.offsetAt(position))) {
|
||||
return null;
|
||||
}
|
||||
const styleTag = this.getStyleTagForPosition(document, position);
|
||||
// We technically can return results even for open tags, however, a lot of the info returned is not valid
|
||||
// Since most editors will automatically close the tag before the user start working in them, this shouldn't be a problem
|
||||
if (styleTag && !styleTag.closed) {
|
||||
return null;
|
||||
}
|
||||
// If we don't have a style tag at this position, we might be in a style property instead, let's check
|
||||
if (!styleTag) {
|
||||
const attributeContext = (0, parseHtml_1.getAttributeContextAtPosition)(document, position);
|
||||
if (!attributeContext) {
|
||||
return null;
|
||||
}
|
||||
if (this.inStyleAttributeWithoutInterpolation(attributeContext, document.getText())) {
|
||||
const [start, end] = attributeContext.valueRange;
|
||||
return this.doHoverInternal(new StyleAttributeDocument_1.StyleAttributeDocument(document, start, end), position);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const cssDocument = this.getCSSDocumentForStyleTag(styleTag, document);
|
||||
const cssLang = extractLanguage(cssDocument);
|
||||
if (!isSupportedByLangService(cssLang)) {
|
||||
return null;
|
||||
}
|
||||
return this.doHoverInternal(cssDocument, position);
|
||||
}
|
||||
doHoverInternal(cssDocument, position) {
|
||||
const hoverInfo = (0, language_service_1.getLanguageService)(extractLanguage(cssDocument)).doHover(cssDocument, cssDocument.getGeneratedPosition(position), cssDocument.stylesheet);
|
||||
return hoverInfo ? (0, documents_1.mapHoverToParent)(cssDocument, hoverInfo) : hoverInfo;
|
||||
}
|
||||
async getCompletions(document, position, completionContext) {
|
||||
if (!(await this.featureEnabled(document, 'completions'))) {
|
||||
return null;
|
||||
}
|
||||
if ((0, documents_1.isInsideFrontmatter)(document.getText(), document.offsetAt(position))) {
|
||||
return null;
|
||||
}
|
||||
const triggerCharacter = completionContext?.triggerCharacter;
|
||||
const triggerKind = completionContext?.triggerKind;
|
||||
const isCustomTriggerCharacter = triggerKind === vscode_languageserver_1.CompletionTriggerKind.TriggerCharacter;
|
||||
if (isCustomTriggerCharacter && triggerCharacter && !this.triggerCharacters.has(triggerCharacter)) {
|
||||
return null;
|
||||
}
|
||||
const styleTag = this.getStyleTagForPosition(document, position);
|
||||
if (styleTag && !styleTag.closed) {
|
||||
return null;
|
||||
}
|
||||
if (!styleTag) {
|
||||
const attributeContext = (0, parseHtml_1.getAttributeContextAtPosition)(document, position);
|
||||
if (!attributeContext) {
|
||||
return null;
|
||||
}
|
||||
if (this.inStyleAttributeWithoutInterpolation(attributeContext, document.getText())) {
|
||||
const [start, end] = attributeContext.valueRange;
|
||||
return await this.getCompletionsInternal(document, position, new StyleAttributeDocument_1.StyleAttributeDocument(document, start, end));
|
||||
}
|
||||
// If we're not in a style attribute, instead give completions for ids and classes used in the current document
|
||||
else if ((attributeContext.name == 'id' || attributeContext.name == 'class') && attributeContext.inValue) {
|
||||
const stylesheets = this.getStylesheetsForDocument(document);
|
||||
return (0, getIdClassCompletions_1.getIdClassCompletion)(stylesheets, attributeContext);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const cssDocument = this.getCSSDocumentForStyleTag(styleTag, document);
|
||||
return await this.getCompletionsInternal(document, position, cssDocument);
|
||||
}
|
||||
async getCompletionsInternal(document, position, cssDocument) {
|
||||
const emmetConfig = await this.configManager.getEmmetConfig(document);
|
||||
if (isSASS(cssDocument)) {
|
||||
// The CSS language service does not support SASS (not to be confused with SCSS)
|
||||
// however we can at least still at least provide Emmet completions in SASS blocks
|
||||
return (0, emmet_helper_1.doComplete)(document, position, 'sass', emmetConfig) || null;
|
||||
}
|
||||
const cssLang = extractLanguage(cssDocument);
|
||||
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
||||
let emmetResults = {
|
||||
isIncomplete: false,
|
||||
items: [],
|
||||
};
|
||||
const extensionConfig = await this.configManager.getConfig('astro', document.uri);
|
||||
if (extensionConfig?.css?.completions?.emmet ?? true) {
|
||||
langService.setCompletionParticipants([
|
||||
{
|
||||
onCssProperty: (context) => {
|
||||
if (context?.propertyName) {
|
||||
emmetResults =
|
||||
(0, emmet_helper_1.doComplete)(cssDocument, cssDocument.getGeneratedPosition(position), (0, language_service_1.getLanguage)(cssLang), emmetConfig) || emmetResults;
|
||||
}
|
||||
},
|
||||
onCssPropertyValue: (context) => {
|
||||
if (context?.propertyValue) {
|
||||
emmetResults =
|
||||
(0, emmet_helper_1.doComplete)(cssDocument, cssDocument.getGeneratedPosition(position), (0, language_service_1.getLanguage)(cssLang), emmetConfig) || emmetResults;
|
||||
}
|
||||
},
|
||||
},
|
||||
]);
|
||||
}
|
||||
const results = langService.doComplete(cssDocument, cssDocument.getGeneratedPosition(position), cssDocument.stylesheet);
|
||||
return vscode_languageserver_1.CompletionList.create([...(results ? results.items : []), ...emmetResults.items].map((completionItem) => (0, documents_1.mapCompletionItemToOriginal)(cssDocument, completionItem)),
|
||||
// Emmet completions change on every keystroke, so they are never complete
|
||||
emmetResults.items.length > 0);
|
||||
}
|
||||
async getDocumentColors(document) {
|
||||
if (!(await this.featureEnabled(document, 'documentColors'))) {
|
||||
return [];
|
||||
}
|
||||
const allColorInfo = this.getCSSDocumentsForDocument(document).flatMap((cssDoc) => {
|
||||
const cssLang = extractLanguage(cssDoc);
|
||||
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
||||
if (!isSupportedByLangService(cssLang)) {
|
||||
return [];
|
||||
}
|
||||
return langService
|
||||
.findDocumentColors(cssDoc, cssDoc.stylesheet)
|
||||
.map((colorInfo) => (0, documents_1.mapObjWithRangeToOriginal)(cssDoc, colorInfo));
|
||||
});
|
||||
return allColorInfo;
|
||||
}
|
||||
async getColorPresentations(document, range, color) {
|
||||
if (!(await this.featureEnabled(document, 'documentColors'))) {
|
||||
return [];
|
||||
}
|
||||
const allColorPres = this.getCSSDocumentsForDocument(document).flatMap((cssDoc) => {
|
||||
const cssLang = extractLanguage(cssDoc);
|
||||
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
||||
if ((!cssDoc.isInGenerated(range.start) && !cssDoc.isInGenerated(range.end)) ||
|
||||
!isSupportedByLangService(cssLang)) {
|
||||
return [];
|
||||
}
|
||||
return langService
|
||||
.getColorPresentations(cssDoc, cssDoc.stylesheet, color, (0, documents_1.mapRangeToGenerated)(cssDoc, range))
|
||||
.map((colorPres) => (0, documents_1.mapColorPresentationToOriginal)(cssDoc, colorPres));
|
||||
});
|
||||
return allColorPres;
|
||||
}
|
||||
prepareRename(document, position) {
|
||||
const styleTag = this.getStyleTagForPosition(document, position);
|
||||
if (!styleTag) {
|
||||
return null;
|
||||
}
|
||||
const cssDocument = this.getCSSDocumentForStyleTag(styleTag, document);
|
||||
const cssLang = extractLanguage(cssDocument);
|
||||
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
||||
const range = langService.prepareRename(cssDocument, cssDocument.getGeneratedPosition(position), cssDocument.stylesheet);
|
||||
if (!range) {
|
||||
return null;
|
||||
}
|
||||
return (0, documents_1.mapRangeToOriginal)(cssDocument, range);
|
||||
}
|
||||
rename(document, position, newName) {
|
||||
const styleTag = this.getStyleTagForPosition(document, position);
|
||||
if (!styleTag) {
|
||||
return null;
|
||||
}
|
||||
const cssDocument = this.getCSSDocumentForStyleTag(styleTag, document);
|
||||
const cssLang = extractLanguage(cssDocument);
|
||||
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
||||
const renames = langService.doRename(cssDocument, cssDocument.getGeneratedPosition(position), newName, cssDocument.stylesheet);
|
||||
if (renames?.changes?.[document.uri]) {
|
||||
renames.changes[document.uri] = renames?.changes?.[document.uri].map((edit) => (0, documents_1.mapObjWithRangeToOriginal)(cssDocument, edit));
|
||||
}
|
||||
return renames;
|
||||
}
|
||||
getFoldingRanges(document) {
|
||||
const allFoldingRanges = this.getCSSDocumentsForDocument(document).flatMap((cssDoc) => {
|
||||
const cssLang = extractLanguage(cssDoc);
|
||||
const langService = (0, language_service_1.getLanguageService)(cssLang);
|
||||
return langService.getFoldingRanges(cssDoc).map((foldingRange) => (0, documents_1.mapFoldingRangeToParent)(cssDoc, foldingRange));
|
||||
});
|
||||
return allFoldingRanges;
|
||||
}
|
||||
async getDocumentSymbols(document) {
|
||||
if (!(await this.featureEnabled(document, 'documentSymbols'))) {
|
||||
return [];
|
||||
}
|
||||
const allDocumentSymbols = this.getCSSDocumentsForDocument(document).flatMap((cssDoc) => {
|
||||
return (0, language_service_1.getLanguageService)(extractLanguage(cssDoc))
|
||||
.findDocumentSymbols(cssDoc, cssDoc.stylesheet)
|
||||
.map((symbol) => (0, documents_1.mapSymbolInformationToOriginal)(cssDoc, symbol));
|
||||
});
|
||||
return allDocumentSymbols;
|
||||
}
|
||||
inStyleAttributeWithoutInterpolation(attrContext, text) {
|
||||
return (attrContext.name === 'style' &&
|
||||
!!attrContext.valueRange &&
|
||||
!text.substring(attrContext.valueRange[0], attrContext.valueRange[1]).includes('{'));
|
||||
}
|
||||
/**
|
||||
* Get the associated CSS Document for a style tag
|
||||
*/
|
||||
getCSSDocumentForStyleTag(tag, document) {
|
||||
let cssDoc = this.cssDocuments.get(tag);
|
||||
if (!cssDoc || cssDoc.version < document.version) {
|
||||
cssDoc = new CSSDocument_1.CSSDocument(document, tag);
|
||||
this.cssDocuments.set(tag, cssDoc);
|
||||
}
|
||||
return cssDoc;
|
||||
}
|
||||
/**
|
||||
* Get all the CSSDocuments in a document
|
||||
*/
|
||||
getCSSDocumentsForDocument(document) {
|
||||
return document.styleTags.map((tag) => this.getCSSDocumentForStyleTag(tag, document));
|
||||
}
|
||||
/**
|
||||
* Get all the stylesheets (Stylesheet type) in a document
|
||||
*/
|
||||
getStylesheetsForDocument(document) {
|
||||
return this.getCSSDocumentsForDocument(document).map((cssDoc) => cssDoc.stylesheet);
|
||||
}
|
||||
/**
|
||||
* Get style tag at position for a document
|
||||
*/
|
||||
getStyleTagForPosition(document, position) {
|
||||
return document.styleTags.find((styleTag) => {
|
||||
return (0, documents_1.isInTag)(position, styleTag);
|
||||
});
|
||||
}
|
||||
async featureEnabled(document, feature) {
|
||||
return ((await this.configManager.isEnabled(document, 'css')) &&
|
||||
(await this.configManager.isEnabled(document, 'css', feature)));
|
||||
}
|
||||
}
|
||||
exports.CSSPlugin = CSSPlugin;
|
||||
/**
|
||||
* Check is a CSSDocument's language is supported by the CSS language service
|
||||
*/
|
||||
function isSupportedByLangService(language) {
|
||||
switch (language) {
|
||||
case 'css':
|
||||
case 'scss':
|
||||
case 'less':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function isSASS(document) {
|
||||
switch (extractLanguage(document)) {
|
||||
case 'sass':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function extractLanguage(document) {
|
||||
const lang = document.languageId;
|
||||
return lang.replace(/^text\//, '');
|
||||
}
|
||||
40
node_modules/@astrojs/language-server/dist/plugins/css/StyleAttributeDocument.d.ts
generated
vendored
Normal file
40
node_modules/@astrojs/language-server/dist/plugins/css/StyleAttributeDocument.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import type { Stylesheet } from 'vscode-css-languageservice';
|
||||
import type { Position } from 'vscode-languageserver';
|
||||
import { AstroDocument, DocumentMapper, ReadableDocument } from '../../core/documents';
|
||||
export declare class StyleAttributeDocument extends ReadableDocument implements DocumentMapper {
|
||||
private readonly parent;
|
||||
private readonly attrStart;
|
||||
private readonly attrEnd;
|
||||
readonly version: number;
|
||||
stylesheet: Stylesheet;
|
||||
languageId: string;
|
||||
constructor(parent: AstroDocument, attrStart: number, attrEnd: number);
|
||||
/**
|
||||
* Get the fragment position relative to the parent
|
||||
* @param pos Position in fragment
|
||||
*/
|
||||
getOriginalPosition(pos: Position): Position;
|
||||
/**
|
||||
* Get the position relative to the start of the fragment
|
||||
* @param pos Position in parent
|
||||
*/
|
||||
getGeneratedPosition(pos: Position): Position;
|
||||
/**
|
||||
* Returns true if the given parent position is inside of this fragment
|
||||
* @param pos Position in parent
|
||||
*/
|
||||
isInGenerated(pos: Position): boolean;
|
||||
/**
|
||||
* Get the fragment text from the parent
|
||||
*/
|
||||
getText(): string;
|
||||
/**
|
||||
* Returns the length of the fragment as calculated from the start and end position
|
||||
*/
|
||||
getTextLength(): number;
|
||||
/**
|
||||
* Return the parent file path
|
||||
*/
|
||||
getFilePath(): string | null;
|
||||
getURL(): string;
|
||||
}
|
||||
64
node_modules/@astrojs/language-server/dist/plugins/css/StyleAttributeDocument.js
generated
vendored
Normal file
64
node_modules/@astrojs/language-server/dist/plugins/css/StyleAttributeDocument.js
generated
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.StyleAttributeDocument = void 0;
|
||||
const documents_1 = require("../../core/documents");
|
||||
const language_service_1 = require("./language-service");
|
||||
const PREFIX = '__ {';
|
||||
const SUFFIX = '}';
|
||||
class StyleAttributeDocument extends documents_1.ReadableDocument {
|
||||
constructor(parent, attrStart, attrEnd) {
|
||||
super();
|
||||
this.parent = parent;
|
||||
this.attrStart = attrStart;
|
||||
this.attrEnd = attrEnd;
|
||||
this.version = this.parent.version;
|
||||
this.languageId = 'css';
|
||||
this.stylesheet = (0, language_service_1.getLanguageService)(this.languageId).parseStylesheet(this);
|
||||
}
|
||||
/**
|
||||
* Get the fragment position relative to the parent
|
||||
* @param pos Position in fragment
|
||||
*/
|
||||
getOriginalPosition(pos) {
|
||||
const parentOffset = this.attrStart + this.offsetAt(pos) - PREFIX.length;
|
||||
return this.parent.positionAt(parentOffset);
|
||||
}
|
||||
/**
|
||||
* Get the position relative to the start of the fragment
|
||||
* @param pos Position in parent
|
||||
*/
|
||||
getGeneratedPosition(pos) {
|
||||
const fragmentOffset = this.parent.offsetAt(pos) - this.attrStart + PREFIX.length;
|
||||
return this.positionAt(fragmentOffset);
|
||||
}
|
||||
/**
|
||||
* Returns true if the given parent position is inside of this fragment
|
||||
* @param pos Position in parent
|
||||
*/
|
||||
isInGenerated(pos) {
|
||||
const offset = this.parent.offsetAt(pos);
|
||||
return offset >= this.attrStart && offset <= this.attrEnd;
|
||||
}
|
||||
/**
|
||||
* Get the fragment text from the parent
|
||||
*/
|
||||
getText() {
|
||||
return PREFIX + this.parent.getText().slice(this.attrStart, this.attrEnd) + SUFFIX;
|
||||
}
|
||||
/**
|
||||
* Returns the length of the fragment as calculated from the start and end position
|
||||
*/
|
||||
getTextLength() {
|
||||
return PREFIX.length + this.attrEnd - this.attrStart + SUFFIX.length;
|
||||
}
|
||||
/**
|
||||
* Return the parent file path
|
||||
*/
|
||||
getFilePath() {
|
||||
return this.parent.getFilePath();
|
||||
}
|
||||
getURL() {
|
||||
return this.parent.getURL();
|
||||
}
|
||||
}
|
||||
exports.StyleAttributeDocument = StyleAttributeDocument;
|
||||
2
node_modules/@astrojs/language-server/dist/plugins/css/features/astro-selectors.d.ts
generated
vendored
Normal file
2
node_modules/@astrojs/language-server/dist/plugins/css/features/astro-selectors.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import type { IPseudoClassData } from 'vscode-css-languageservice';
|
||||
export declare const pseudoClass: IPseudoClassData[];
|
||||
15
node_modules/@astrojs/language-server/dist/plugins/css/features/astro-selectors.js
generated
vendored
Normal file
15
node_modules/@astrojs/language-server/dist/plugins/css/features/astro-selectors.js
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.pseudoClass = void 0;
|
||||
exports.pseudoClass = [
|
||||
{
|
||||
name: ':global()',
|
||||
description: 'Apply styles to a selector globally',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro documentation',
|
||||
url: 'https://docs.astro.build/en/guides/styling/#global-styles-within-style-tag',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
19
node_modules/@astrojs/language-server/dist/plugins/css/features/getIdClassCompletions.d.ts
generated
vendored
Normal file
19
node_modules/@astrojs/language-server/dist/plugins/css/features/getIdClassCompletions.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import type { Stylesheet } from 'vscode-css-languageservice';
|
||||
import { CompletionItem, CompletionList } from 'vscode-languageserver';
|
||||
import type { AttributeContext } from '../../../core/documents/parseHtml';
|
||||
export declare function getIdClassCompletion(stylesheets: Stylesheet[], attributeContext: AttributeContext): CompletionList | null;
|
||||
/**
|
||||
* incomplete see
|
||||
* https://github.com/microsoft/vscode-css-languageservice/blob/master/src/parser/cssNodes.ts#L14
|
||||
* The enum is not exported. we have to update this whenever it changes
|
||||
*/
|
||||
export declare enum NodeType {
|
||||
ClassSelector = 14,
|
||||
IdentifierSelector = 15
|
||||
}
|
||||
export type CSSNode = {
|
||||
type: number;
|
||||
children: CSSNode[] | undefined;
|
||||
getText(): string;
|
||||
};
|
||||
export declare function collectSelectors(stylesheets: CSSNode[], type: number): CompletionItem[];
|
||||
57
node_modules/@astrojs/language-server/dist/plugins/css/features/getIdClassCompletions.js
generated
vendored
Normal file
57
node_modules/@astrojs/language-server/dist/plugins/css/features/getIdClassCompletions.js
generated
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.collectSelectors = exports.NodeType = exports.getIdClassCompletion = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
function getIdClassCompletion(stylesheets, attributeContext) {
|
||||
const collectingType = getCollectingType(attributeContext);
|
||||
if (!collectingType) {
|
||||
return null;
|
||||
}
|
||||
const items = collectSelectors(stylesheets, collectingType);
|
||||
return vscode_languageserver_1.CompletionList.create(items);
|
||||
}
|
||||
exports.getIdClassCompletion = getIdClassCompletion;
|
||||
function getCollectingType(attributeContext) {
|
||||
if (attributeContext.inValue) {
|
||||
if (attributeContext.name === 'class') {
|
||||
return NodeType.ClassSelector;
|
||||
}
|
||||
if (attributeContext.name === 'id') {
|
||||
return NodeType.IdentifierSelector;
|
||||
}
|
||||
}
|
||||
else if (attributeContext.name.startsWith('class:')) {
|
||||
return NodeType.ClassSelector;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* incomplete see
|
||||
* https://github.com/microsoft/vscode-css-languageservice/blob/master/src/parser/cssNodes.ts#L14
|
||||
* The enum is not exported. we have to update this whenever it changes
|
||||
*/
|
||||
var NodeType;
|
||||
(function (NodeType) {
|
||||
NodeType[NodeType["ClassSelector"] = 14] = "ClassSelector";
|
||||
NodeType[NodeType["IdentifierSelector"] = 15] = "IdentifierSelector";
|
||||
})(NodeType = exports.NodeType || (exports.NodeType = {}));
|
||||
function collectSelectors(stylesheets, type) {
|
||||
const result = [];
|
||||
stylesheets.forEach((stylesheet) => {
|
||||
walk(stylesheet, (node) => {
|
||||
if (node.type === type) {
|
||||
result.push(node);
|
||||
}
|
||||
});
|
||||
});
|
||||
return result.map((node) => ({
|
||||
label: node.getText().substring(1),
|
||||
kind: vscode_languageserver_1.CompletionItemKind.Keyword,
|
||||
}));
|
||||
}
|
||||
exports.collectSelectors = collectSelectors;
|
||||
function walk(node, callback) {
|
||||
callback(node);
|
||||
if (node.children) {
|
||||
node.children.forEach((childrenNode) => walk(childrenNode, callback));
|
||||
}
|
||||
}
|
||||
3
node_modules/@astrojs/language-server/dist/plugins/css/language-service.d.ts
generated
vendored
Normal file
3
node_modules/@astrojs/language-server/dist/plugins/css/language-service.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { LanguageService } from 'vscode-css-languageservice';
|
||||
export declare function getLanguage(kind?: string): "css" | "less" | "scss";
|
||||
export declare function getLanguageService(kind?: string): LanguageService;
|
||||
47
node_modules/@astrojs/language-server/dist/plugins/css/language-service.js
generated
vendored
Normal file
47
node_modules/@astrojs/language-server/dist/plugins/css/language-service.js
generated
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getLanguageService = exports.getLanguage = void 0;
|
||||
const vscode_css_languageservice_1 = require("vscode-css-languageservice");
|
||||
const astro_selectors_1 = require("./features/astro-selectors");
|
||||
const customDataProvider = {
|
||||
providePseudoClasses() {
|
||||
return astro_selectors_1.pseudoClass;
|
||||
},
|
||||
provideProperties() {
|
||||
return [];
|
||||
},
|
||||
provideAtDirectives() {
|
||||
return [];
|
||||
},
|
||||
providePseudoElements() {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
const [css, scss, less] = [vscode_css_languageservice_1.getCSSLanguageService, vscode_css_languageservice_1.getSCSSLanguageService, vscode_css_languageservice_1.getLESSLanguageService].map((getService) => getService({
|
||||
customDataProviders: [customDataProvider],
|
||||
}));
|
||||
const langs = {
|
||||
css,
|
||||
scss,
|
||||
less,
|
||||
};
|
||||
function getLanguage(kind) {
|
||||
switch (kind) {
|
||||
case 'scss':
|
||||
case 'text/scss':
|
||||
return 'scss';
|
||||
case 'less':
|
||||
case 'text/less':
|
||||
return 'less';
|
||||
case 'css':
|
||||
case 'text/css':
|
||||
default:
|
||||
return 'css';
|
||||
}
|
||||
}
|
||||
exports.getLanguage = getLanguage;
|
||||
function getLanguageService(kind) {
|
||||
const lang = getLanguage(kind);
|
||||
return langs[lang];
|
||||
}
|
||||
exports.getLanguageService = getLanguageService;
|
||||
33
node_modules/@astrojs/language-server/dist/plugins/html/HTMLPlugin.d.ts
generated
vendored
Normal file
33
node_modules/@astrojs/language-server/dist/plugins/html/HTMLPlugin.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import { CompletionList, FoldingRange, Hover, LinkedEditingRanges, Position, Range, SymbolInformation, WorkspaceEdit } from 'vscode-languageserver';
|
||||
import type { ConfigManager } from '../../core/config/ConfigManager';
|
||||
import type { AstroDocument } from '../../core/documents/AstroDocument';
|
||||
import type { Plugin } from '../interfaces';
|
||||
export declare class HTMLPlugin implements Plugin {
|
||||
__name: string;
|
||||
private lang;
|
||||
private attributeOnlyLang;
|
||||
private componentLang;
|
||||
private styleScriptTemplate;
|
||||
private configManager;
|
||||
constructor(configManager: ConfigManager);
|
||||
doHover(document: AstroDocument, position: Position): Promise<Hover | null>;
|
||||
/**
|
||||
* Get HTML completions
|
||||
*/
|
||||
getCompletions(document: AstroDocument, position: Position): Promise<CompletionList | null>;
|
||||
getFoldingRanges(document: AstroDocument): FoldingRange[] | null;
|
||||
getLinkedEditingRanges(document: AstroDocument, position: Position): LinkedEditingRanges | null;
|
||||
doTagComplete(document: AstroDocument, position: Position): Promise<string | null>;
|
||||
prepareRename(document: AstroDocument, position: Position): Range | null;
|
||||
rename(document: AstroDocument, position: Position, newName: string): WorkspaceEdit | null;
|
||||
getDocumentSymbols(document: AstroDocument): Promise<SymbolInformation[]>;
|
||||
/**
|
||||
* Get lang completions for style tags (ex: `<style lang="scss">`)
|
||||
*/
|
||||
private getLangCompletions;
|
||||
/**
|
||||
* Returns true if rename happens at the tag name, not anywhere inbetween.
|
||||
*/
|
||||
private isRenameAtTag;
|
||||
private featureEnabled;
|
||||
}
|
||||
198
node_modules/@astrojs/language-server/dist/plugins/html/HTMLPlugin.js
generated
vendored
Normal file
198
node_modules/@astrojs/language-server/dist/plugins/html/HTMLPlugin.js
generated
vendored
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.HTMLPlugin = void 0;
|
||||
const emmet_helper_1 = require("@vscode/emmet-helper");
|
||||
const vscode_html_languageservice_1 = require("vscode-html-languageservice");
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const utils_1 = require("../../core/documents/utils");
|
||||
const astro_attributes_1 = require("./features/astro-attributes");
|
||||
const utils_2 = require("./utils");
|
||||
class HTMLPlugin {
|
||||
constructor(configManager) {
|
||||
this.__name = 'html';
|
||||
this.lang = (0, vscode_html_languageservice_1.getLanguageService)({
|
||||
customDataProviders: [astro_attributes_1.astroAttributes, astro_attributes_1.astroElements, astro_attributes_1.classListAttribute],
|
||||
});
|
||||
this.attributeOnlyLang = (0, vscode_html_languageservice_1.getLanguageService)({
|
||||
customDataProviders: [astro_attributes_1.astroAttributes],
|
||||
useDefaultDataProvider: false,
|
||||
});
|
||||
this.componentLang = (0, vscode_html_languageservice_1.getLanguageService)({
|
||||
customDataProviders: [astro_attributes_1.astroAttributes, astro_attributes_1.astroDirectives],
|
||||
useDefaultDataProvider: false,
|
||||
});
|
||||
this.styleScriptTemplate = new Set(['style']);
|
||||
this.configManager = configManager;
|
||||
}
|
||||
async doHover(document, position) {
|
||||
if (!(await this.featureEnabled(document, 'hover'))) {
|
||||
return null;
|
||||
}
|
||||
const html = document.html;
|
||||
if (!html) {
|
||||
return null;
|
||||
}
|
||||
const node = html.findNodeAt(document.offsetAt(position));
|
||||
if (!node) {
|
||||
return null;
|
||||
}
|
||||
// If the node we're hovering on is a component, instead only provide astro-specific hover info
|
||||
if ((0, utils_1.isPossibleComponent)(node) && node.tag !== 'Fragment') {
|
||||
return this.componentLang.doHover(document, position, html);
|
||||
}
|
||||
return this.lang.doHover(document, position, html);
|
||||
}
|
||||
/**
|
||||
* Get HTML completions
|
||||
*/
|
||||
async getCompletions(document, position) {
|
||||
if (!(await this.featureEnabled(document, 'completions'))) {
|
||||
return null;
|
||||
}
|
||||
const html = document.html;
|
||||
const offset = document.offsetAt(position);
|
||||
if (!html ||
|
||||
(0, utils_1.isInsideFrontmatter)(document.getText(), offset) ||
|
||||
(0, utils_1.isInsideExpression)(document.getText(), html.findNodeAt(offset).start, offset)) {
|
||||
return null;
|
||||
}
|
||||
// Get Emmet completions
|
||||
let emmetResults = {
|
||||
isIncomplete: true,
|
||||
items: [],
|
||||
};
|
||||
const emmetConfig = await this.configManager.getEmmetConfig(document);
|
||||
const extensionConfig = (await this.configManager.getConfig('astro', document.uri)) ?? {};
|
||||
if (extensionConfig?.html?.completions?.emmet ?? true) {
|
||||
this.lang.setCompletionParticipants([
|
||||
{
|
||||
onHtmlContent: () => (emmetResults = (0, emmet_helper_1.doComplete)(document, position, 'html', emmetConfig) || emmetResults),
|
||||
},
|
||||
]);
|
||||
}
|
||||
// If we're in a component starting tag, we do not want HTML language completions
|
||||
// as HTML attributes are not valid for components
|
||||
const inComponentTag = (0, utils_1.isInComponentStartTag)(html, offset);
|
||||
const inTagName = (0, utils_1.isInTagName)(html, offset);
|
||||
const results = inComponentTag && !inTagName
|
||||
? (0, utils_2.removeDataAttrCompletion)(this.attributeOnlyLang.doComplete(document, position, html).items)
|
||||
: this.lang.doComplete(document, position, html).items.filter(isNoAddedTagWithNoDocumentation);
|
||||
const langCompletions = inComponentTag ? [] : this.getLangCompletions(results);
|
||||
return vscode_languageserver_1.CompletionList.create([...results, ...langCompletions, ...emmetResults.items],
|
||||
// Emmet completions change on every keystroke, so they are never complete
|
||||
emmetResults.items.length > 0);
|
||||
// Filter script and style completions with no documentation to prevent duplicates
|
||||
// due to our added definitions for those tags
|
||||
function isNoAddedTagWithNoDocumentation(item) {
|
||||
return !(['script', 'style'].includes(item.label) && item.documentation === undefined);
|
||||
}
|
||||
}
|
||||
getFoldingRanges(document) {
|
||||
const html = document.html;
|
||||
if (!html) {
|
||||
return null;
|
||||
}
|
||||
return this.lang.getFoldingRanges(document);
|
||||
}
|
||||
getLinkedEditingRanges(document, position) {
|
||||
const html = document.html;
|
||||
if (!html) {
|
||||
return null;
|
||||
}
|
||||
const ranges = this.lang.findLinkedEditingRanges(document, position, html);
|
||||
if (!ranges) {
|
||||
return null;
|
||||
}
|
||||
return { ranges };
|
||||
}
|
||||
async doTagComplete(document, position) {
|
||||
if (!(await this.featureEnabled(document, 'tagComplete'))) {
|
||||
return null;
|
||||
}
|
||||
const html = document.html;
|
||||
const offset = document.offsetAt(position);
|
||||
if (!html ||
|
||||
(0, utils_1.isInsideFrontmatter)(document.getText(), offset) ||
|
||||
(0, utils_1.isInsideExpression)(document.getText(), html.findNodeAt(offset).start, offset)) {
|
||||
return null;
|
||||
}
|
||||
return this.lang.doTagComplete(document, position, html);
|
||||
}
|
||||
prepareRename(document, position) {
|
||||
const html = document.html;
|
||||
const offset = document.offsetAt(position);
|
||||
const node = html.findNodeAt(offset);
|
||||
if (!node || (0, utils_1.isPossibleComponent)(node) || !node.tag || !this.isRenameAtTag(node, offset)) {
|
||||
return null;
|
||||
}
|
||||
const tagNameStart = node.start + '<'.length;
|
||||
return vscode_languageserver_1.Range.create(document.positionAt(tagNameStart), document.positionAt(tagNameStart + node.tag.length));
|
||||
}
|
||||
rename(document, position, newName) {
|
||||
const html = document.html;
|
||||
const offset = document.offsetAt(position);
|
||||
if (!html || (0, utils_1.isInsideFrontmatter)(document.getText(), offset)) {
|
||||
return null;
|
||||
}
|
||||
const node = html.findNodeAt(offset);
|
||||
// The TypeScript plugin handles renaming for components
|
||||
if (!node || (0, utils_1.isPossibleComponent)(node) || !this.isRenameAtTag(node, offset)) {
|
||||
return null;
|
||||
}
|
||||
return this.lang.doRename(document, position, newName, html);
|
||||
}
|
||||
async getDocumentSymbols(document) {
|
||||
if (!(await this.featureEnabled(document, 'documentSymbols'))) {
|
||||
return [];
|
||||
}
|
||||
const html = document.html;
|
||||
if (!html) {
|
||||
return [];
|
||||
}
|
||||
return this.lang.findDocumentSymbols(document, html);
|
||||
}
|
||||
/**
|
||||
* Get lang completions for style tags (ex: `<style lang="scss">`)
|
||||
*/
|
||||
getLangCompletions(completions) {
|
||||
const styleScriptTemplateCompletions = completions.filter((completion) => completion.kind === vscode_languageserver_1.CompletionItemKind.Property && this.styleScriptTemplate.has(completion.label));
|
||||
const langCompletions = [];
|
||||
addLangCompletion('style', ['scss', 'sass', 'less', 'styl', 'stylus']);
|
||||
return langCompletions;
|
||||
/** Add language completions */
|
||||
function addLangCompletion(tag, languages) {
|
||||
const existingCompletion = styleScriptTemplateCompletions.find((completion) => completion.label === tag);
|
||||
if (!existingCompletion) {
|
||||
return;
|
||||
}
|
||||
languages.forEach((lang) => langCompletions.push({
|
||||
...existingCompletion,
|
||||
label: `${tag} (lang="${lang}")`,
|
||||
insertText: existingCompletion.insertText && `${existingCompletion.insertText} lang="${lang}"`,
|
||||
textEdit: existingCompletion.textEdit && vscode_languageserver_1.TextEdit.is(existingCompletion.textEdit)
|
||||
? {
|
||||
range: existingCompletion.textEdit.range,
|
||||
newText: `${existingCompletion.textEdit.newText} lang="${lang}"`,
|
||||
}
|
||||
: undefined,
|
||||
}));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns true if rename happens at the tag name, not anywhere inbetween.
|
||||
*/
|
||||
isRenameAtTag(node, offset) {
|
||||
if (!node.tag) {
|
||||
return false;
|
||||
}
|
||||
const startTagNameEnd = node.start + `<${node.tag}`.length;
|
||||
const isAtStartTag = offset > node.start && offset <= startTagNameEnd;
|
||||
const isAtEndTag = node.endTagStart !== undefined && offset >= node.endTagStart && offset < node.end;
|
||||
return isAtStartTag || isAtEndTag;
|
||||
}
|
||||
async featureEnabled(document, feature) {
|
||||
return ((await this.configManager.isEnabled(document, 'html')) &&
|
||||
(await this.configManager.isEnabled(document, 'html', feature)));
|
||||
}
|
||||
}
|
||||
exports.HTMLPlugin = HTMLPlugin;
|
||||
4
node_modules/@astrojs/language-server/dist/plugins/html/features/astro-attributes.d.ts
generated
vendored
Normal file
4
node_modules/@astrojs/language-server/dist/plugins/html/features/astro-attributes.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export declare const classListAttribute: import("vscode-html-languageservice").IHTMLDataProvider;
|
||||
export declare const astroElements: import("vscode-html-languageservice").IHTMLDataProvider;
|
||||
export declare const astroAttributes: import("vscode-html-languageservice").IHTMLDataProvider;
|
||||
export declare const astroDirectives: import("vscode-html-languageservice").IHTMLDataProvider;
|
||||
235
node_modules/@astrojs/language-server/dist/plugins/html/features/astro-attributes.js
generated
vendored
Normal file
235
node_modules/@astrojs/language-server/dist/plugins/html/features/astro-attributes.js
generated
vendored
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.astroDirectives = exports.astroAttributes = exports.astroElements = exports.classListAttribute = void 0;
|
||||
const vscode_html_languageservice_1 = require("vscode-html-languageservice");
|
||||
const defaultProvider = (0, vscode_html_languageservice_1.getDefaultHTMLDataProvider)();
|
||||
const slotAttr = defaultProvider.provideAttributes('div').find((attr) => attr.name === 'slot');
|
||||
exports.classListAttribute = (0, vscode_html_languageservice_1.newHTMLDataProvider)('class-list', {
|
||||
version: 1,
|
||||
globalAttributes: [
|
||||
{
|
||||
name: 'class:list',
|
||||
description: 'Utility to provide a list of class',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#classlist',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
exports.astroElements = (0, vscode_html_languageservice_1.newHTMLDataProvider)('astro-elements', {
|
||||
version: 1,
|
||||
tags: [
|
||||
{
|
||||
name: 'slot',
|
||||
description: 'The slot element is a placeholder for external HTML content, allowing you to inject (or “slot”) child elements from other files into your component template.',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/core-concepts/astro-components/#slots',
|
||||
},
|
||||
],
|
||||
attributes: [
|
||||
{
|
||||
name: 'name',
|
||||
description: 'The name attribute allows you to pass only HTML elements with the corresponding slot name into a slot’s location.',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/core-concepts/astro-components/#named-slots',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'script',
|
||||
attributes: [
|
||||
{
|
||||
// The VS Code tag definitions does not provide a description for the deprecated `charset` attribute on script tags
|
||||
// Which mean that since we get no hover info for this, we instead get JSX hover info. So we'll just specify a description ourselves for this specific case
|
||||
name: 'charset',
|
||||
description: "**Deprecated**\n\nIt's unnecessary to specify the charset attribute, because documents must use UTF-8, and the script element inherits its character encoding from the document.",
|
||||
},
|
||||
{
|
||||
name: 'define:vars',
|
||||
description: 'Passes serializable server-side variables into a client-side script element',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#definevars',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'hoist',
|
||||
description: '**Deprecated in Astro >= 0.26.0**\n\nBuilds, optimizes, and bundles your script with the other JavaScript on the page',
|
||||
valueSet: 'v',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/core-concepts/astro-components/#using-hoisted-scripts',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'is:inline',
|
||||
description: 'Leave a script tag inline in the page template. No processing will be done on its content',
|
||||
valueSet: 'v',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#isinline',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'style',
|
||||
attributes: [
|
||||
{
|
||||
name: 'define:vars',
|
||||
description: 'Passes serializable server-side variables into a client-side style element',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#definevars',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'global',
|
||||
description: '**Deprecated in favor of `is:global` in >= Astro 0.26.0**\n\nOpts-out of automatic CSS scoping, all contents will be available globally',
|
||||
valueSet: 'v',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#isglobal',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'is:global',
|
||||
description: 'Opts-out of automatic CSS scoping, all contents will be available globally',
|
||||
valueSet: 'v',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#isglobal',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'is:inline',
|
||||
description: 'Leave a style tag inline in the page template. No processing will be done on its content',
|
||||
valueSet: 'v',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#isinline',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
exports.astroAttributes = (0, vscode_html_languageservice_1.newHTMLDataProvider)('astro-attributes', {
|
||||
version: 1,
|
||||
globalAttributes: [
|
||||
{
|
||||
name: 'set:html',
|
||||
description: 'Inject unescaped HTML into this tag',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#sethtml',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'set:text',
|
||||
description: 'Inject escaped text into this tag',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#settext',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'is:raw',
|
||||
description: 'Instructs the Astro compiler to treat any children of this element as text',
|
||||
valueSet: 'v',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#israw',
|
||||
},
|
||||
],
|
||||
},
|
||||
slotAttr,
|
||||
],
|
||||
});
|
||||
exports.astroDirectives = (0, vscode_html_languageservice_1.newHTMLDataProvider)('astro-directives', {
|
||||
version: 1,
|
||||
globalAttributes: [
|
||||
{
|
||||
name: 'client:load',
|
||||
description: 'Start importing the component JS at page load. Hydrate the component when import completes.',
|
||||
valueSet: 'v',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#clientload',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'client:idle',
|
||||
description: 'Start importing the component JS as soon as main thread is free (uses requestIdleCallback()). Hydrate the component when import completes.',
|
||||
valueSet: 'v',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#clientidle',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'client:visible',
|
||||
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.',
|
||||
valueSet: 'v',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#clientvisible',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'client:media',
|
||||
description: 'Start importing the component JS as soon as the browser matches the given media query (uses matchMedia). Hydrate the component when import completes. Useful for sidebar toggles, or other elements that should only display on mobile or desktop devices.',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#clientmedia',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'client:only',
|
||||
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.',
|
||||
valueSet: 'v',
|
||||
references: [
|
||||
{
|
||||
name: 'Astro reference',
|
||||
url: 'https://docs.astro.build/en/reference/directives-reference/#clientonly',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
6
node_modules/@astrojs/language-server/dist/plugins/html/utils.d.ts
generated
vendored
Normal file
6
node_modules/@astrojs/language-server/dist/plugins/html/utils.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import type { CompletionItem } from 'vscode-languageserver-types';
|
||||
/**
|
||||
* The VS Code HTML language service provides a completion for data attributes that is independent from
|
||||
* data providers, which mean that you can't disable it, so this function removes them from completions
|
||||
*/
|
||||
export declare function removeDataAttrCompletion(items: CompletionItem[]): CompletionItem[];
|
||||
11
node_modules/@astrojs/language-server/dist/plugins/html/utils.js
generated
vendored
Normal file
11
node_modules/@astrojs/language-server/dist/plugins/html/utils.js
generated
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.removeDataAttrCompletion = void 0;
|
||||
/**
|
||||
* The VS Code HTML language service provides a completion for data attributes that is independent from
|
||||
* data providers, which mean that you can't disable it, so this function removes them from completions
|
||||
*/
|
||||
function removeDataAttrCompletion(items) {
|
||||
return items.filter((item) => !item.label.startsWith('data-'));
|
||||
}
|
||||
exports.removeDataAttrCompletion = removeDataAttrCompletion;
|
||||
6
node_modules/@astrojs/language-server/dist/plugins/index.d.ts
generated
vendored
Normal file
6
node_modules/@astrojs/language-server/dist/plugins/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export * from './astro/AstroPlugin';
|
||||
export * from './css/CSSPlugin';
|
||||
export * from './html/HTMLPlugin';
|
||||
export * from './interfaces';
|
||||
export * from './PluginHost';
|
||||
export * from './typescript/TypeScriptPlugin';
|
||||
22
node_modules/@astrojs/language-server/dist/plugins/index.js
generated
vendored
Normal file
22
node_modules/@astrojs/language-server/dist/plugins/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./astro/AstroPlugin"), exports);
|
||||
__exportStar(require("./css/CSSPlugin"), exports);
|
||||
__exportStar(require("./html/HTMLPlugin"), exports);
|
||||
__exportStar(require("./interfaces"), exports);
|
||||
__exportStar(require("./PluginHost"), exports);
|
||||
__exportStar(require("./typescript/TypeScriptPlugin"), exports);
|
||||
101
node_modules/@astrojs/language-server/dist/plugins/interfaces.d.ts
generated
vendored
Normal file
101
node_modules/@astrojs/language-server/dist/plugins/interfaces.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
import type { CodeAction, CodeActionContext, Color, ColorInformation, ColorPresentation, CompletionContext, CompletionItem, CompletionList, DefinitionLink, Diagnostic, FileChangeType, FoldingRange, FormattingOptions, Hover, InlayHint, LinkedEditingRanges, Location, Position, Range, ReferenceContext, SelectionRange, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, TextDocumentIdentifier, TextEdit, WorkspaceEdit } from 'vscode-languageserver';
|
||||
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
||||
export type Resolvable<T> = T | Promise<T>;
|
||||
export interface AppCompletionItem<T extends TextDocumentIdentifier = any> extends CompletionItem {
|
||||
data?: T;
|
||||
}
|
||||
export interface AppCompletionList<T extends TextDocumentIdentifier = any> extends CompletionList {
|
||||
items: Array<AppCompletionItem<T>>;
|
||||
}
|
||||
export interface DiagnosticsProvider {
|
||||
getDiagnostics(document: TextDocument): Resolvable<Diagnostic[]>;
|
||||
}
|
||||
export interface HoverProvider {
|
||||
doHover(document: TextDocument, position: Position): Resolvable<Hover | null>;
|
||||
}
|
||||
export interface FoldingRangesProvider {
|
||||
getFoldingRanges(document: TextDocument): Resolvable<FoldingRange[] | null>;
|
||||
}
|
||||
export interface CompletionsProvider<T extends TextDocumentIdentifier = any> {
|
||||
getCompletions(document: TextDocument, position: Position, completionContext?: CompletionContext): Resolvable<AppCompletionList<T> | null>;
|
||||
resolveCompletion?(document: TextDocument, completionItem: AppCompletionItem<T>): Resolvable<AppCompletionItem<T>>;
|
||||
}
|
||||
export interface FormattingProvider {
|
||||
formatDocument(document: TextDocument, options: FormattingOptions): Resolvable<TextEdit[]>;
|
||||
}
|
||||
export interface TagCompleteProvider {
|
||||
doTagComplete(document: TextDocument, position: Position): Resolvable<string | null>;
|
||||
}
|
||||
export interface DocumentColorsProvider {
|
||||
getDocumentColors(document: TextDocument): Resolvable<ColorInformation[]>;
|
||||
}
|
||||
export interface ColorPresentationsProvider {
|
||||
getColorPresentations(document: TextDocument, range: Range, color: Color): Resolvable<ColorPresentation[]>;
|
||||
}
|
||||
export interface DocumentSymbolsProvider {
|
||||
getDocumentSymbols(document: TextDocument): Resolvable<SymbolInformation[]>;
|
||||
}
|
||||
export interface FileReferencesProvider {
|
||||
fileReferences(document: TextDocument): Promise<Location[] | null>;
|
||||
}
|
||||
export interface DefinitionsProvider {
|
||||
getDefinitions(document: TextDocument, position: Position): Resolvable<DefinitionLink[]>;
|
||||
}
|
||||
export interface BackwardsCompatibleDefinitionsProvider {
|
||||
getDefinitions(document: TextDocument, position: Position): Resolvable<DefinitionLink[] | Location[]>;
|
||||
}
|
||||
export interface CodeActionsProvider {
|
||||
getCodeActions(document: TextDocument, range: Range, context: CodeActionContext): Resolvable<CodeAction[]>;
|
||||
executeCommand?(document: TextDocument, command: string, args?: any[]): Resolvable<WorkspaceEdit | string | null>;
|
||||
}
|
||||
export interface FileRename {
|
||||
oldUri: string;
|
||||
newUri: string;
|
||||
}
|
||||
export interface UpdateImportsProvider {
|
||||
updateImports(fileRename: FileRename): Resolvable<WorkspaceEdit | null>;
|
||||
}
|
||||
export interface InlayHintsProvider {
|
||||
getInlayHints(document: TextDocument, range: Range): Resolvable<InlayHint[]>;
|
||||
}
|
||||
export interface RenameProvider {
|
||||
rename(document: TextDocument, position: Position, newName: string): Resolvable<WorkspaceEdit | null>;
|
||||
prepareRename(document: TextDocument, position: Position): Resolvable<Range | null>;
|
||||
}
|
||||
export interface FindReferencesProvider {
|
||||
findReferences(document: TextDocument, position: Position, context: ReferenceContext): Promise<Location[] | null>;
|
||||
}
|
||||
export interface SignatureHelpProvider {
|
||||
getSignatureHelp(document: TextDocument, position: Position, context: SignatureHelpContext | undefined): Resolvable<SignatureHelp | null>;
|
||||
}
|
||||
export interface SelectionRangeProvider {
|
||||
getSelectionRange(document: TextDocument, position: Position): Resolvable<SelectionRange | null>;
|
||||
}
|
||||
export interface SemanticTokensProvider {
|
||||
getSemanticTokens(textDocument: TextDocument, range?: Range): Resolvable<SemanticTokens | null>;
|
||||
}
|
||||
export interface LinkedEditingRangesProvider {
|
||||
getLinkedEditingRanges(document: TextDocument, position: Position): Resolvable<LinkedEditingRanges | null>;
|
||||
}
|
||||
export interface ImplementationProvider {
|
||||
getImplementation(document: TextDocument, position: Position): Resolvable<Location[] | null>;
|
||||
}
|
||||
export interface TypeDefinitionsProvider {
|
||||
getTypeDefinitions(document: TextDocument, position: Position): Resolvable<Location[] | null>;
|
||||
}
|
||||
export interface OnWatchFileChangesParam {
|
||||
fileName: string;
|
||||
changeType: FileChangeType;
|
||||
}
|
||||
export interface OnWatchFileChangesProvider {
|
||||
onWatchFileChanges(onWatchFileChangesParams: OnWatchFileChangesParam[]): Promise<void>;
|
||||
}
|
||||
export interface UpdateNonAstroFile {
|
||||
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[], text?: string): void;
|
||||
}
|
||||
type ProviderBase = DiagnosticsProvider & HoverProvider & CompletionsProvider & FileReferencesProvider & DefinitionsProvider & TypeDefinitionsProvider & ImplementationProvider & FormattingProvider & FoldingRangesProvider & TagCompleteProvider & DocumentColorsProvider & ColorPresentationsProvider & DocumentSymbolsProvider & UpdateImportsProvider & CodeActionsProvider & FindReferencesProvider & RenameProvider & SignatureHelpProvider & SemanticTokensProvider & SelectionRangeProvider & OnWatchFileChangesProvider & LinkedEditingRangesProvider & InlayHintsProvider & UpdateNonAstroFile;
|
||||
export type LSProvider = ProviderBase;
|
||||
export type Plugin = Partial<ProviderBase> & {
|
||||
__name: string;
|
||||
};
|
||||
export {};
|
||||
2
node_modules/@astrojs/language-server/dist/plugins/interfaces.js
generated
vendored
Normal file
2
node_modules/@astrojs/language-server/dist/plugins/interfaces.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
47
node_modules/@astrojs/language-server/dist/plugins/typescript/LanguageServiceManager.d.ts
generated
vendored
Normal file
47
node_modules/@astrojs/language-server/dist/plugins/typescript/LanguageServiceManager.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import type ts from 'typescript';
|
||||
import type { TextDocumentContentChangeEvent } from 'vscode-languageserver';
|
||||
import type { ConfigManager } from '../../core/config';
|
||||
import type { AstroDocument, DocumentManager } from '../../core/documents';
|
||||
import { LanguageServiceContainer, LanguageServiceDocumentContext } from './language-service';
|
||||
import type { DocumentSnapshot } from './snapshots/DocumentSnapshot';
|
||||
import { SnapshotManager } from './snapshots/SnapshotManager';
|
||||
export declare class LanguageServiceManager {
|
||||
private readonly docManager;
|
||||
private readonly workspaceUris;
|
||||
private readonly configManager;
|
||||
docContext: LanguageServiceDocumentContext;
|
||||
private globalSnapshotManager;
|
||||
constructor(docManager: DocumentManager, workspaceUris: string[], configManager: ConfigManager, ts: typeof import('typescript/lib/tsserverlibrary'), tsLocalized?: Record<string, string> | undefined);
|
||||
/**
|
||||
* Create an AstroDocument (only for astro files)
|
||||
*/
|
||||
private createDocument;
|
||||
getSnapshot(document: AstroDocument): Promise<DocumentSnapshot>;
|
||||
getSnapshot(pathOrDoc: string | AstroDocument): Promise<DocumentSnapshot>;
|
||||
/**
|
||||
* Updates snapshot path in all existing ts services and retrieves snapshot
|
||||
*/
|
||||
updateSnapshotPath(oldPath: string, newPath: string): Promise<DocumentSnapshot>;
|
||||
/**
|
||||
* Deletes snapshot in all existing ts services
|
||||
*/
|
||||
deleteSnapshot(filePath: string): Promise<void>;
|
||||
/**
|
||||
* Updates project files in all existing ts services
|
||||
*/
|
||||
updateProjectFiles(): Promise<void>;
|
||||
/**
|
||||
* Updates file in all ts services where it exists
|
||||
*/
|
||||
updateExistingNonAstroFile(path: string, changes?: TextDocumentContentChangeEvent[], text?: string): Promise<void>;
|
||||
getLSAndTSDoc(document: AstroDocument): Promise<{
|
||||
tsDoc: DocumentSnapshot;
|
||||
lang: ts.LanguageService;
|
||||
}>;
|
||||
getLSForPath(path: string): Promise<ts.LanguageService>;
|
||||
getTypeScriptLanguageService(filePath: string): Promise<LanguageServiceContainer>;
|
||||
/**
|
||||
* @internal Public for tests only
|
||||
*/
|
||||
getSnapshotManager(filePath: string): Promise<SnapshotManager>;
|
||||
}
|
||||
97
node_modules/@astrojs/language-server/dist/plugins/typescript/LanguageServiceManager.js
generated
vendored
Normal file
97
node_modules/@astrojs/language-server/dist/plugins/typescript/LanguageServiceManager.js
generated
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.LanguageServiceManager = void 0;
|
||||
const utils_1 = require("../../utils");
|
||||
const language_service_1 = require("./language-service");
|
||||
const SnapshotManager_1 = require("./snapshots/SnapshotManager");
|
||||
class LanguageServiceManager {
|
||||
constructor(docManager, workspaceUris, configManager, ts, tsLocalized) {
|
||||
this.docManager = docManager;
|
||||
this.workspaceUris = workspaceUris;
|
||||
this.configManager = configManager;
|
||||
/**
|
||||
* Create an AstroDocument (only for astro files)
|
||||
*/
|
||||
this.createDocument = (fileName, content) => {
|
||||
const uri = (0, utils_1.pathToUrl)(fileName);
|
||||
const document = this.docManager.openDocument({
|
||||
text: content,
|
||||
uri,
|
||||
});
|
||||
this.docManager.lockDocument(uri);
|
||||
return document;
|
||||
};
|
||||
this.globalSnapshotManager = new SnapshotManager_1.GlobalSnapshotManager(ts);
|
||||
this.docContext = {
|
||||
createDocument: this.createDocument,
|
||||
globalSnapshotManager: this.globalSnapshotManager,
|
||||
configManager: this.configManager,
|
||||
ts,
|
||||
tsLocalized: tsLocalized,
|
||||
};
|
||||
const handleDocumentChange = (document) => {
|
||||
this.getSnapshot(document);
|
||||
};
|
||||
docManager.on('documentChange', (0, utils_1.debounceSameArg)(handleDocumentChange, (newDoc, prevDoc) => newDoc.uri === prevDoc?.uri, 1000));
|
||||
docManager.on('documentOpen', handleDocumentChange);
|
||||
}
|
||||
async getSnapshot(pathOrDoc) {
|
||||
const filePath = typeof pathOrDoc === 'string' ? pathOrDoc : pathOrDoc.getFilePath() || '';
|
||||
const tsService = await this.getTypeScriptLanguageService(filePath);
|
||||
return tsService.updateSnapshot(pathOrDoc, this.docContext.ts);
|
||||
}
|
||||
/**
|
||||
* Updates snapshot path in all existing ts services and retrieves snapshot
|
||||
*/
|
||||
async updateSnapshotPath(oldPath, newPath) {
|
||||
await this.deleteSnapshot(oldPath);
|
||||
return this.getSnapshot(newPath);
|
||||
}
|
||||
/**
|
||||
* Deletes snapshot in all existing ts services
|
||||
*/
|
||||
async deleteSnapshot(filePath) {
|
||||
await (0, language_service_1.forAllLanguageServices)((service) => service.deleteSnapshot(filePath));
|
||||
this.docManager.releaseDocument((0, utils_1.pathToUrl)(filePath));
|
||||
}
|
||||
/**
|
||||
* Updates project files in all existing ts services
|
||||
*/
|
||||
async updateProjectFiles() {
|
||||
await (0, language_service_1.forAllLanguageServices)((service) => service.updateProjectFiles());
|
||||
}
|
||||
/**
|
||||
* Updates file in all ts services where it exists
|
||||
*/
|
||||
async updateExistingNonAstroFile(path, changes, text) {
|
||||
path = (0, utils_1.normalizePath)(path);
|
||||
// Only update once because all snapshots are shared between
|
||||
// services. Since we don't have a current version of TS/JS
|
||||
// files, the operation wouldn't be idempotent.
|
||||
let didUpdate = false;
|
||||
await (0, language_service_1.forAllLanguageServices)((service) => {
|
||||
if (service.hasFile(path) && !didUpdate) {
|
||||
didUpdate = true;
|
||||
service.updateNonAstroFile(path, changes, text);
|
||||
}
|
||||
});
|
||||
}
|
||||
async getLSAndTSDoc(document) {
|
||||
const lang = await this.getLSForPath(document.getFilePath() || '');
|
||||
const tsDoc = await this.getSnapshot(document);
|
||||
return { tsDoc, lang };
|
||||
}
|
||||
async getLSForPath(path) {
|
||||
return (await this.getTypeScriptLanguageService(path)).getService();
|
||||
}
|
||||
async getTypeScriptLanguageService(filePath) {
|
||||
return (0, language_service_1.getLanguageService)(filePath, this.workspaceUris, this.docContext);
|
||||
}
|
||||
/**
|
||||
* @internal Public for tests only
|
||||
*/
|
||||
async getSnapshotManager(filePath) {
|
||||
return (await this.getTypeScriptLanguageService(filePath)).snapshotManager;
|
||||
}
|
||||
}
|
||||
exports.LanguageServiceManager = LanguageServiceManager;
|
||||
54
node_modules/@astrojs/language-server/dist/plugins/typescript/TypeScriptPlugin.d.ts
generated
vendored
Normal file
54
node_modules/@astrojs/language-server/dist/plugins/typescript/TypeScriptPlugin.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import type { TSXResult } from '@astrojs/compiler/types';
|
||||
import { CancellationToken, CodeAction, CodeActionContext, CompletionContext, DefinitionLink, Diagnostic, FoldingRange, Hover, InlayHint, Location, Position, Range, ReferenceContext, SemanticTokens, SignatureHelp, SignatureHelpContext, SymbolInformation, TextDocumentContentChangeEvent, WorkspaceEdit } from 'vscode-languageserver';
|
||||
import type { ConfigManager } from '../../core/config';
|
||||
import type { AstroDocument } from '../../core/documents';
|
||||
import type { AppCompletionItem, AppCompletionList, OnWatchFileChangesParam, Plugin } from '../interfaces';
|
||||
import { CompletionItemData } from './features/CompletionsProvider';
|
||||
import type { LanguageServiceManager } from './LanguageServiceManager';
|
||||
export declare class TypeScriptPlugin implements Plugin {
|
||||
__name: string;
|
||||
private configManager;
|
||||
private readonly languageServiceManager;
|
||||
private readonly codeActionsProvider;
|
||||
private readonly completionProvider;
|
||||
private readonly hoverProvider;
|
||||
private readonly fileReferencesProvider;
|
||||
private readonly definitionsProvider;
|
||||
private readonly typeDefinitionsProvider;
|
||||
private readonly implementationsProvider;
|
||||
private readonly referencesProvider;
|
||||
private readonly signatureHelpProvider;
|
||||
private readonly diagnosticsProvider;
|
||||
private readonly documentSymbolsProvider;
|
||||
private readonly inlayHintsProvider;
|
||||
private readonly semanticTokensProvider;
|
||||
private readonly foldingRangesProvider;
|
||||
private readonly renameProvider;
|
||||
private readonly ts;
|
||||
constructor(configManager: ConfigManager, languageServiceManager: LanguageServiceManager);
|
||||
doHover(document: AstroDocument, position: Position): Promise<Hover | null>;
|
||||
prepareRename(document: AstroDocument, position: Position): Promise<Range | null>;
|
||||
rename(document: AstroDocument, position: Position, newName: string): Promise<WorkspaceEdit | null>;
|
||||
getFoldingRanges(document: AstroDocument): Promise<FoldingRange[] | null>;
|
||||
getSemanticTokens(document: AstroDocument, range?: Range, cancellationToken?: CancellationToken): Promise<SemanticTokens | null>;
|
||||
getDocumentSymbols(document: AstroDocument): Promise<SymbolInformation[]>;
|
||||
getCodeActions(document: AstroDocument, range: Range, context: CodeActionContext, cancellationToken?: CancellationToken): Promise<CodeAction[]>;
|
||||
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext, cancellationToken?: CancellationToken): Promise<AppCompletionList<CompletionItemData> | null>;
|
||||
resolveCompletion(document: AstroDocument, completionItem: AppCompletionItem<CompletionItemData>, cancellationToken?: CancellationToken): Promise<AppCompletionItem<CompletionItemData>>;
|
||||
getInlayHints(document: AstroDocument, range: Range): Promise<InlayHint[]>;
|
||||
fileReferences(document: AstroDocument): Promise<Location[] | null>;
|
||||
getDefinitions(document: AstroDocument, position: Position): Promise<DefinitionLink[]>;
|
||||
getTypeDefinitions(document: AstroDocument, position: Position): Promise<Location[] | null>;
|
||||
getImplementation(document: AstroDocument, position: Position): Promise<Location[] | null>;
|
||||
findReferences(document: AstroDocument, position: Position, context: ReferenceContext): Promise<Location[] | null>;
|
||||
getDiagnostics(document: AstroDocument, cancellationToken?: CancellationToken): Promise<Diagnostic[]>;
|
||||
onWatchFileChanges(onWatchFileChangesParas: OnWatchFileChangesParam[]): Promise<void>;
|
||||
updateNonAstroFile(fileName: string, changes: TextDocumentContentChangeEvent[], text?: string): Promise<void>;
|
||||
getSignatureHelp(document: AstroDocument, position: Position, context: SignatureHelpContext | undefined, cancellationToken?: CancellationToken): Promise<SignatureHelp | null>;
|
||||
getTSXForDocument(document: AstroDocument): TSXResult;
|
||||
/**
|
||||
* @internal Public for tests only
|
||||
*/
|
||||
getSnapshotManager(fileName: string): Promise<import("./snapshots/SnapshotManager").SnapshotManager>;
|
||||
private featureEnabled;
|
||||
}
|
||||
152
node_modules/@astrojs/language-server/dist/plugins/typescript/TypeScriptPlugin.js
generated
vendored
Normal file
152
node_modules/@astrojs/language-server/dist/plugins/typescript/TypeScriptPlugin.js
generated
vendored
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TypeScriptPlugin = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const astro2tsx_1 = require("./astro2tsx");
|
||||
const CodeActionsProvider_1 = require("./features/CodeActionsProvider");
|
||||
const CompletionsProvider_1 = require("./features/CompletionsProvider");
|
||||
const DefinitionsProvider_1 = require("./features/DefinitionsProvider");
|
||||
const DiagnosticsProvider_1 = require("./features/DiagnosticsProvider");
|
||||
const DocumentSymbolsProvider_1 = require("./features/DocumentSymbolsProvider");
|
||||
const FileReferencesProvider_1 = require("./features/FileReferencesProvider");
|
||||
const FoldingRangesProvider_1 = require("./features/FoldingRangesProvider");
|
||||
const HoverProvider_1 = require("./features/HoverProvider");
|
||||
const ImplementationsProvider_1 = require("./features/ImplementationsProvider");
|
||||
const InlayHintsProvider_1 = require("./features/InlayHintsProvider");
|
||||
const ReferencesProvider_1 = require("./features/ReferencesProvider");
|
||||
const RenameProvider_1 = require("./features/RenameProvider");
|
||||
const SemanticTokenProvider_1 = require("./features/SemanticTokenProvider");
|
||||
const SignatureHelpProvider_1 = require("./features/SignatureHelpProvider");
|
||||
const TypeDefinitionsProvider_1 = require("./features/TypeDefinitionsProvider");
|
||||
const utils_1 = require("./utils");
|
||||
class TypeScriptPlugin {
|
||||
constructor(configManager, languageServiceManager) {
|
||||
this.__name = 'typescript';
|
||||
this.configManager = configManager;
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
this.codeActionsProvider = new CodeActionsProvider_1.CodeActionsProviderImpl(this.languageServiceManager, this.configManager);
|
||||
this.completionProvider = new CompletionsProvider_1.CompletionsProviderImpl(this.languageServiceManager, this.configManager);
|
||||
this.hoverProvider = new HoverProvider_1.HoverProviderImpl(this.languageServiceManager);
|
||||
this.fileReferencesProvider = new FileReferencesProvider_1.FileReferencesProviderImpl(this.languageServiceManager);
|
||||
this.definitionsProvider = new DefinitionsProvider_1.DefinitionsProviderImpl(this.languageServiceManager);
|
||||
this.typeDefinitionsProvider = new TypeDefinitionsProvider_1.TypeDefinitionsProviderImpl(this.languageServiceManager);
|
||||
this.implementationsProvider = new ImplementationsProvider_1.ImplementationsProviderImpl(this.languageServiceManager);
|
||||
this.referencesProvider = new ReferencesProvider_1.FindReferencesProviderImpl(this.languageServiceManager);
|
||||
this.signatureHelpProvider = new SignatureHelpProvider_1.SignatureHelpProviderImpl(this.languageServiceManager);
|
||||
this.diagnosticsProvider = new DiagnosticsProvider_1.DiagnosticsProviderImpl(this.languageServiceManager);
|
||||
this.documentSymbolsProvider = new DocumentSymbolsProvider_1.DocumentSymbolsProviderImpl(this.languageServiceManager);
|
||||
this.semanticTokensProvider = new SemanticTokenProvider_1.SemanticTokensProviderImpl(this.languageServiceManager);
|
||||
this.inlayHintsProvider = new InlayHintsProvider_1.InlayHintsProviderImpl(this.languageServiceManager, this.configManager);
|
||||
this.foldingRangesProvider = new FoldingRangesProvider_1.FoldingRangesProviderImpl(this.languageServiceManager);
|
||||
this.renameProvider = new RenameProvider_1.RenameProviderImpl(this.languageServiceManager, this.configManager);
|
||||
}
|
||||
async doHover(document, position) {
|
||||
if (!(await this.featureEnabled(document, 'hover'))) {
|
||||
return null;
|
||||
}
|
||||
return this.hoverProvider.doHover(document, position);
|
||||
}
|
||||
async prepareRename(document, position) {
|
||||
return this.renameProvider.prepareRename(document, position);
|
||||
}
|
||||
async rename(document, position, newName) {
|
||||
return this.renameProvider.rename(document, position, newName);
|
||||
}
|
||||
async getFoldingRanges(document) {
|
||||
return this.foldingRangesProvider.getFoldingRanges(document);
|
||||
}
|
||||
async getSemanticTokens(document, range, cancellationToken) {
|
||||
if (!(await this.featureEnabled(document, 'semanticTokens'))) {
|
||||
return null;
|
||||
}
|
||||
return this.semanticTokensProvider.getSemanticTokens(document, range, cancellationToken);
|
||||
}
|
||||
async getDocumentSymbols(document) {
|
||||
if (!(await this.featureEnabled(document, 'documentSymbols'))) {
|
||||
return [];
|
||||
}
|
||||
const symbols = await this.documentSymbolsProvider.getDocumentSymbols(document);
|
||||
return symbols;
|
||||
}
|
||||
async getCodeActions(document, range, context, cancellationToken) {
|
||||
if (!(await this.featureEnabled(document, 'codeActions'))) {
|
||||
return [];
|
||||
}
|
||||
return this.codeActionsProvider.getCodeActions(document, range, context, cancellationToken);
|
||||
}
|
||||
async getCompletions(document, position, completionContext, cancellationToken) {
|
||||
if (!(await this.featureEnabled(document, 'completions'))) {
|
||||
return null;
|
||||
}
|
||||
const completions = await this.completionProvider.getCompletions(document, position, completionContext, cancellationToken);
|
||||
return completions;
|
||||
}
|
||||
async resolveCompletion(document, completionItem, cancellationToken) {
|
||||
return this.completionProvider.resolveCompletion(document, completionItem, cancellationToken);
|
||||
}
|
||||
async getInlayHints(document, range) {
|
||||
return this.inlayHintsProvider.getInlayHints(document, range);
|
||||
}
|
||||
async fileReferences(document) {
|
||||
return this.fileReferencesProvider.fileReferences(document);
|
||||
}
|
||||
async getDefinitions(document, position) {
|
||||
return this.definitionsProvider.getDefinitions(document, position);
|
||||
}
|
||||
async getTypeDefinitions(document, position) {
|
||||
return this.typeDefinitionsProvider.getTypeDefinitions(document, position);
|
||||
}
|
||||
async getImplementation(document, position) {
|
||||
return this.implementationsProvider.getImplementation(document, position);
|
||||
}
|
||||
async findReferences(document, position, context) {
|
||||
return this.referencesProvider.findReferences(document, position, context);
|
||||
}
|
||||
async getDiagnostics(document, cancellationToken) {
|
||||
if (!(await this.featureEnabled(document, 'diagnostics'))) {
|
||||
return [];
|
||||
}
|
||||
return this.diagnosticsProvider.getDiagnostics(document, cancellationToken);
|
||||
}
|
||||
async onWatchFileChanges(onWatchFileChangesParas) {
|
||||
let doneUpdateProjectFiles = false;
|
||||
for (const { fileName, changeType } of onWatchFileChangesParas) {
|
||||
const scriptKind = (0, utils_1.getScriptKindFromFileName)(fileName, this.ts);
|
||||
if (scriptKind === this.ts.ScriptKind.Unknown && !(0, utils_1.isFrameworkFilePath)(fileName) && !(0, utils_1.isAstroFilePath)(fileName)) {
|
||||
continue;
|
||||
}
|
||||
if (changeType === vscode_languageserver_1.FileChangeType.Created && !doneUpdateProjectFiles) {
|
||||
doneUpdateProjectFiles = true;
|
||||
await this.languageServiceManager.updateProjectFiles();
|
||||
}
|
||||
else if (changeType === vscode_languageserver_1.FileChangeType.Deleted) {
|
||||
await this.languageServiceManager.deleteSnapshot(fileName);
|
||||
}
|
||||
else if (!(0, utils_1.isAstroFilePath)(fileName)) {
|
||||
// Content updates for Astro files are handled through the documentManager and the 'documentChange' event
|
||||
await this.languageServiceManager.updateExistingNonAstroFile(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
async updateNonAstroFile(fileName, changes, text) {
|
||||
await this.languageServiceManager.updateExistingNonAstroFile(fileName, changes, text);
|
||||
}
|
||||
async getSignatureHelp(document, position, context, cancellationToken) {
|
||||
return this.signatureHelpProvider.getSignatureHelp(document, position, context, cancellationToken);
|
||||
}
|
||||
getTSXForDocument(document) {
|
||||
return (0, astro2tsx_1.astro2tsx)(document.getText(), document.getURL());
|
||||
}
|
||||
/**
|
||||
* @internal Public for tests only
|
||||
*/
|
||||
getSnapshotManager(fileName) {
|
||||
return this.languageServiceManager.getSnapshotManager(fileName);
|
||||
}
|
||||
async featureEnabled(document, feature) {
|
||||
return ((await this.configManager.isEnabled(document, 'typescript')) &&
|
||||
(await this.configManager.isEnabled(document, 'typescript', feature)));
|
||||
}
|
||||
}
|
||||
exports.TypeScriptPlugin = TypeScriptPlugin;
|
||||
8
node_modules/@astrojs/language-server/dist/plugins/typescript/astro-sys.d.ts
generated
vendored
Normal file
8
node_modules/@astrojs/language-server/dist/plugins/typescript/astro-sys.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import type ts from 'typescript';
|
||||
import type { DocumentSnapshot } from './snapshots/DocumentSnapshot';
|
||||
/**
|
||||
* This should only be accessed by TS Astro module resolution.
|
||||
*/
|
||||
export declare function createAstroSys(getSnapshot: (fileName: string) => DocumentSnapshot, ts: typeof import('typescript/lib/tsserverlibrary')): ts.System & {
|
||||
deleteFromCache: (path: string) => void;
|
||||
};
|
||||
46
node_modules/@astrojs/language-server/dist/plugins/typescript/astro-sys.js
generated
vendored
Normal file
46
node_modules/@astrojs/language-server/dist/plugins/typescript/astro-sys.js
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createAstroSys = void 0;
|
||||
const utils_1 = require("./utils");
|
||||
/**
|
||||
* This should only be accessed by TS Astro module resolution.
|
||||
*/
|
||||
function createAstroSys(getSnapshot, ts) {
|
||||
const fileExistsCache = new Map();
|
||||
const AstroSys = {
|
||||
...ts.sys,
|
||||
fileExists(path) {
|
||||
path = (0, utils_1.ensureRealFilePath)(path);
|
||||
const exists = fileExistsCache.get(path) ?? ts.sys.fileExists(path);
|
||||
fileExistsCache.set(path, exists);
|
||||
return exists;
|
||||
},
|
||||
readFile(path) {
|
||||
const snapshot = getSnapshot(path);
|
||||
return snapshot.getText(0, snapshot.getLength());
|
||||
},
|
||||
readDirectory(path, extensions, exclude, include, depth) {
|
||||
const extensionsWithAstro = (extensions ?? []).concat(...['.astro', '.svelte', '.vue', '.md', '.mdx', '.html']);
|
||||
const result = ts.sys.readDirectory(path, extensionsWithAstro, exclude, include, depth);
|
||||
return result;
|
||||
},
|
||||
deleteFile(path) {
|
||||
fileExistsCache.delete((0, utils_1.ensureRealFilePath)(path));
|
||||
return ts.sys.deleteFile?.(path);
|
||||
},
|
||||
deleteFromCache(path) {
|
||||
fileExistsCache.delete((0, utils_1.ensureRealFilePath)(path));
|
||||
},
|
||||
};
|
||||
if (ts.sys.realpath) {
|
||||
const realpath = ts.sys.realpath;
|
||||
AstroSys.realpath = function (path) {
|
||||
if ((0, utils_1.isVirtualFilePath)(path)) {
|
||||
return realpath((0, utils_1.ensureRealFilePath)(path)) + '.tsx';
|
||||
}
|
||||
return realpath(path);
|
||||
};
|
||||
}
|
||||
return AstroSys;
|
||||
}
|
||||
exports.createAstroSys = createAstroSys;
|
||||
2
node_modules/@astrojs/language-server/dist/plugins/typescript/astro2tsx.d.ts
generated
vendored
Normal file
2
node_modules/@astrojs/language-server/dist/plugins/typescript/astro2tsx.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import type { TSXResult } from '@astrojs/compiler/types';
|
||||
export declare function astro2tsx(content: string, fileName: string): TSXResult;
|
||||
26
node_modules/@astrojs/language-server/dist/plugins/typescript/astro2tsx.js
generated
vendored
Normal file
26
node_modules/@astrojs/language-server/dist/plugins/typescript/astro2tsx.js
generated
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.astro2tsx = void 0;
|
||||
const sync_1 = require("@astrojs/compiler/sync");
|
||||
function astro2tsx(content, fileName) {
|
||||
try {
|
||||
const tsx = (0, sync_1.convertToTSX)(content, { filename: fileName });
|
||||
return tsx;
|
||||
}
|
||||
catch (e) {
|
||||
console.error(`There was an error transforming ${fileName} to TSX. An empty file will be returned instead. Please create an issue: https://github.com/withastro/language-tools/issues\nError: ${e}.`);
|
||||
return {
|
||||
code: '',
|
||||
map: {
|
||||
file: fileName,
|
||||
sources: [],
|
||||
sourcesContent: [],
|
||||
names: [],
|
||||
mappings: '',
|
||||
version: 0,
|
||||
},
|
||||
diagnostics: [],
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.astro2tsx = astro2tsx;
|
||||
17
node_modules/@astrojs/language-server/dist/plugins/typescript/features/CodeActionsProvider.d.ts
generated
vendored
Normal file
17
node_modules/@astrojs/language-server/dist/plugins/typescript/features/CodeActionsProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import type { CancellationToken } from 'vscode-languageserver';
|
||||
import { CodeAction, CodeActionContext, Range } from 'vscode-languageserver-types';
|
||||
import type { ConfigManager } from '../../../core/config';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import type { CodeActionsProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare const sortImportKind: string;
|
||||
export declare class CodeActionsProviderImpl implements CodeActionsProvider {
|
||||
private languageServiceManager;
|
||||
private configManager;
|
||||
private ts;
|
||||
constructor(languageServiceManager: LanguageServiceManager, configManager: ConfigManager);
|
||||
getCodeActions(document: AstroDocument, range: Range, context: CodeActionContext, cancellationToken?: CancellationToken): Promise<CodeAction[]>;
|
||||
private getComponentQuickFix;
|
||||
private organizeSortImports;
|
||||
private fixIndentationOfImports;
|
||||
}
|
||||
212
node_modules/@astrojs/language-server/dist/plugins/typescript/features/CodeActionsProvider.js
generated
vendored
Normal file
212
node_modules/@astrojs/language-server/dist/plugins/typescript/features/CodeActionsProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CodeActionsProviderImpl = exports.sortImportKind = void 0;
|
||||
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
||||
const documents_1 = require("../../../core/documents");
|
||||
const utils_1 = require("../../../utils");
|
||||
const utils_2 = require("../utils");
|
||||
const CompletionsProvider_1 = require("./CompletionsProvider");
|
||||
const utils_3 = require("./utils");
|
||||
// These are VS Code specific CodeActionKind so they're not in the language server protocol
|
||||
exports.sortImportKind = `${vscode_languageserver_types_1.CodeActionKind.Source}.sortImports`;
|
||||
class CodeActionsProviderImpl {
|
||||
constructor(languageServiceManager, configManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.configManager = configManager;
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
}
|
||||
async getCodeActions(document, range, context, cancellationToken) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const tsPreferences = await this.configManager.getTSPreferences(document);
|
||||
const formatOptions = await this.configManager.getTSFormatConfig(document);
|
||||
let result = [];
|
||||
if (cancellationToken?.isCancellationRequested) {
|
||||
return [];
|
||||
}
|
||||
if (context.only?.[0] === vscode_languageserver_types_1.CodeActionKind.SourceOrganizeImports) {
|
||||
return await this.organizeSortImports(document, false, cancellationToken);
|
||||
}
|
||||
// The difference between Sort Imports and Organize Imports is that Sort Imports won't do anything destructive.
|
||||
// For example, it won't remove unused imports whereas Organize Imports will
|
||||
if (context.only?.[0] === exports.sortImportKind) {
|
||||
return await this.organizeSortImports(document, true, cancellationToken);
|
||||
}
|
||||
if (context.only?.[0] === vscode_languageserver_types_1.CodeActionKind.Source) {
|
||||
return [
|
||||
...(await this.organizeSortImports(document, true, cancellationToken)),
|
||||
...(await this.organizeSortImports(document, false, cancellationToken)),
|
||||
];
|
||||
}
|
||||
if (context.diagnostics.length && (!context.only || context.only.includes(vscode_languageserver_types_1.CodeActionKind.QuickFix))) {
|
||||
const errorCodes = context.diagnostics
|
||||
.map((diag) => Number(diag.code))
|
||||
// We currently cannot support quick fix for unreachable code properly due to the way our TSX output is structured
|
||||
.filter((code) => code !== 7027);
|
||||
const html = document.html;
|
||||
const node = html.findNodeAt(document.offsetAt(range.start));
|
||||
let codeFixes;
|
||||
let isInsideScript = false;
|
||||
if (node.tag === 'script') {
|
||||
const { snapshot: scriptTagSnapshot, filePath: scriptFilePath } = (0, utils_2.getScriptTagSnapshot)(tsDoc, document, node);
|
||||
const start = scriptTagSnapshot.offsetAt(scriptTagSnapshot.getGeneratedPosition(range.start));
|
||||
const end = scriptTagSnapshot.offsetAt(scriptTagSnapshot.getGeneratedPosition(range.end));
|
||||
codeFixes = lang.getCodeFixesAtPosition(scriptFilePath, start, end, errorCodes, formatOptions, tsPreferences);
|
||||
codeFixes = codeFixes.map((fix) => ({
|
||||
...fix,
|
||||
changes: mapScriptTagFixToOriginal(fix.changes, scriptTagSnapshot),
|
||||
}));
|
||||
isInsideScript = true;
|
||||
}
|
||||
else {
|
||||
const start = tsDoc.offsetAt(tsDoc.getGeneratedPosition(range.start));
|
||||
const end = tsDoc.offsetAt(tsDoc.getGeneratedPosition(range.end));
|
||||
codeFixes = errorCodes.includes(2304)
|
||||
? this.getComponentQuickFix(start, end, lang, tsDoc.filePath, formatOptions, tsPreferences)
|
||||
: undefined;
|
||||
codeFixes =
|
||||
codeFixes ??
|
||||
lang.getCodeFixesAtPosition(tsDoc.filePath, start, end, errorCodes, formatOptions, tsPreferences);
|
||||
}
|
||||
const codeActions = codeFixes.map((fix) => codeFixToCodeAction(fix, context.diagnostics, context.only ? vscode_languageserver_types_1.CodeActionKind.QuickFix : vscode_languageserver_types_1.CodeActionKind.Empty, isInsideScript, this.ts));
|
||||
result.push(...codeActions);
|
||||
}
|
||||
return result;
|
||||
function codeFixToCodeAction(codeFix, diagnostics, kind, isInsideScript, ts) {
|
||||
const documentChanges = codeFix.changes.map((change) => {
|
||||
return vscode_languageserver_types_1.TextDocumentEdit.create(vscode_languageserver_types_1.OptionalVersionedTextDocumentIdentifier.create(document.getURL(), null), change.textChanges.map((edit) => {
|
||||
let originalRange = (0, documents_1.mapRangeToOriginal)(tsDoc, (0, utils_2.convertRange)(tsDoc, edit.span));
|
||||
// Inside scripts, we don't need to restrain the insertion of code inside a specific zone as it will be
|
||||
// restricted to the area of the script tag by default
|
||||
if (!isInsideScript) {
|
||||
if (codeFix.fixName === 'import') {
|
||||
return (0, CompletionsProvider_1.codeActionChangeToTextEdit)(document, tsDoc, false, edit, ts);
|
||||
}
|
||||
if (codeFix.fixName === 'fixMissingFunctionDeclaration') {
|
||||
originalRange = (0, utils_2.checkEndOfFileCodeInsert)(originalRange, document);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Make sure new imports are not added on the file line of the script tag
|
||||
if (codeFix.fixName === 'import') {
|
||||
const existingLine = (0, documents_1.getLineAtPosition)(document.positionAt(edit.span.start), document.getText());
|
||||
const isNewImport = !existingLine.trim().startsWith('import');
|
||||
if (!(edit.newText.startsWith('\n') || edit.newText.startsWith('\r\n')) && isNewImport) {
|
||||
edit.newText = ts.sys.newLine + edit.newText;
|
||||
}
|
||||
}
|
||||
}
|
||||
return vscode_languageserver_types_1.TextEdit.replace(originalRange, edit.newText);
|
||||
}));
|
||||
});
|
||||
const codeAction = vscode_languageserver_types_1.CodeAction.create(codeFix.description, {
|
||||
documentChanges,
|
||||
}, kind);
|
||||
codeAction.diagnostics = diagnostics;
|
||||
return codeAction;
|
||||
}
|
||||
function mapScriptTagFixToOriginal(changes, scriptTagSnapshot) {
|
||||
return changes.map((change) => {
|
||||
change.textChanges.map((edit) => {
|
||||
edit.span.start = (0, documents_1.mapScriptSpanStartToSnapshot)(edit.span, scriptTagSnapshot, tsDoc);
|
||||
return edit;
|
||||
});
|
||||
return change;
|
||||
});
|
||||
}
|
||||
}
|
||||
getComponentQuickFix(start, end, lang, filePath, formatOptions, tsPreferences) {
|
||||
const sourceFile = lang.getProgram()?.getSourceFile(filePath);
|
||||
if (!sourceFile) {
|
||||
return;
|
||||
}
|
||||
const node = (0, utils_3.findContainingNode)(sourceFile, {
|
||||
start,
|
||||
length: end - start,
|
||||
}, (n) => this.ts.isJsxClosingElement(n) || this.ts.isJsxOpeningLikeElement(n));
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
const tagName = node.tagName;
|
||||
// Unlike quick fixes, completions will be able to find the component, so let's use those to get it
|
||||
const completion = lang.getCompletionsAtPosition(filePath, tagName.getEnd(), tsPreferences, formatOptions);
|
||||
if (!completion) {
|
||||
return;
|
||||
}
|
||||
const name = tagName.getText();
|
||||
const suffixedName = name + '__AstroComponent_';
|
||||
const toFix = (c) => lang.getCompletionEntryDetails(filePath, end, c.name, {}, c.source, {}, c.data)?.codeActions?.map((a) => ({
|
||||
...a,
|
||||
description: (0, utils_2.removeAstroComponentSuffix)(a.description),
|
||||
fixName: 'import',
|
||||
})) ?? [];
|
||||
return completion.entries.filter((c) => c.name === name || c.name === suffixedName).flatMap(toFix);
|
||||
}
|
||||
async organizeSortImports(document, skipDestructiveCodeActions = false, cancellationToken) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const filePath = tsDoc.filePath;
|
||||
if (cancellationToken?.isCancellationRequested) {
|
||||
return [];
|
||||
}
|
||||
let changes = [];
|
||||
if (document.astroMeta.frontmatter.state === 'closed') {
|
||||
changes.push(...lang.organizeImports({ fileName: filePath, type: 'file', skipDestructiveCodeActions }, {}, {}));
|
||||
}
|
||||
document.scriptTags.forEach((scriptTag) => {
|
||||
const { filePath: scriptFilePath, snapshot: scriptTagSnapshot } = (0, utils_2.getScriptTagSnapshot)(tsDoc, document, scriptTag.container);
|
||||
const edits = lang.organizeImports({ fileName: scriptFilePath, type: 'file', skipDestructiveCodeActions }, {}, {});
|
||||
edits.forEach((edit) => {
|
||||
edit.fileName = tsDoc.filePath;
|
||||
edit.textChanges = edit.textChanges
|
||||
.map((change) => {
|
||||
change.span.start = (0, documents_1.mapScriptSpanStartToSnapshot)(change.span, scriptTagSnapshot, tsDoc);
|
||||
// If the result ending position is unmapped, it usually means the ending position has a newline
|
||||
// inside the virtual part of the script tag, so let's just make it a character shorter
|
||||
const range = (0, documents_1.mapRangeToOriginal)(tsDoc, (0, utils_2.convertRange)(tsDoc, change.span));
|
||||
if (range.end.character === 0 && range.end.line === 0) {
|
||||
change.span.length -= 1;
|
||||
}
|
||||
return change;
|
||||
})
|
||||
// Since our last line is a (virtual) export, organize imports will try to rewrite it, so let's only take
|
||||
// changes that actually happens inside the script tag
|
||||
.filter((change) => {
|
||||
return (scriptTagSnapshot.isInGenerated(document.positionAt(change.span.start)) &&
|
||||
!change.newText.includes('export { }'));
|
||||
});
|
||||
return edit;
|
||||
});
|
||||
changes.push(...edits);
|
||||
});
|
||||
const documentChanges = changes.map((change) => {
|
||||
return vscode_languageserver_types_1.TextDocumentEdit.create(vscode_languageserver_types_1.OptionalVersionedTextDocumentIdentifier.create(document.url, null), change.textChanges.map((edit) => {
|
||||
const range = (0, documents_1.mapRangeToOriginal)(tsDoc, (0, utils_2.convertRange)(tsDoc, edit.span));
|
||||
if (document.offsetAt(range.start) < (document.astroMeta.content.firstNonWhitespaceOffset ?? 0)) {
|
||||
if (document.offsetAt(range.end) > document.astroMeta.frontmatter.endOffset) {
|
||||
range.end = document.positionAt(document.astroMeta.frontmatter.endOffset);
|
||||
}
|
||||
}
|
||||
return vscode_languageserver_types_1.TextEdit.replace(range, this.fixIndentationOfImports(edit.newText, range, document));
|
||||
}));
|
||||
});
|
||||
return [
|
||||
vscode_languageserver_types_1.CodeAction.create(skipDestructiveCodeActions ? 'Sort Imports' : 'Organize Imports', {
|
||||
documentChanges,
|
||||
}, skipDestructiveCodeActions ? exports.sortImportKind : vscode_languageserver_types_1.CodeActionKind.SourceOrganizeImports),
|
||||
];
|
||||
}
|
||||
// "Organize Imports" will have edits that delete all imports by return empty edits
|
||||
// and one edit which contains all the organized imports. Fix indentation
|
||||
// of that one by prepending all lines with the indentation of the first line.
|
||||
fixIndentationOfImports(edit, range, document) {
|
||||
if (!edit || range.start.character === 0) {
|
||||
return edit;
|
||||
}
|
||||
const existingLine = (0, documents_1.getLineAtPosition)(range.start, document.getText());
|
||||
const leadingChars = existingLine.substring(0, range.start.character);
|
||||
if (leadingChars.trim() !== '') {
|
||||
return edit;
|
||||
}
|
||||
return (0, utils_1.modifyLines)(edit, (line, idx) => (idx === 0 || !line ? line : leadingChars + line));
|
||||
}
|
||||
}
|
||||
exports.CodeActionsProviderImpl = CodeActionsProviderImpl;
|
||||
31
node_modules/@astrojs/language-server/dist/plugins/typescript/features/CompletionsProvider.d.ts
generated
vendored
Normal file
31
node_modules/@astrojs/language-server/dist/plugins/typescript/features/CompletionsProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import type ts from 'typescript';
|
||||
import { CancellationToken, CompletionContext, Position, TextDocumentIdentifier, TextEdit } from 'vscode-languageserver';
|
||||
import type { ConfigManager } from '../../../core/config';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import type { AppCompletionItem, AppCompletionList, CompletionsProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
import type { DocumentSnapshot } from '../snapshots/DocumentSnapshot';
|
||||
export interface CompletionItemData extends TextDocumentIdentifier {
|
||||
filePath: string;
|
||||
offset: number;
|
||||
scriptTagIndex: number | undefined;
|
||||
originalItem: ts.CompletionEntry;
|
||||
}
|
||||
export declare class CompletionsProviderImpl implements CompletionsProvider<CompletionItemData> {
|
||||
private languageServiceManager;
|
||||
private configManager;
|
||||
private ts;
|
||||
constructor(languageServiceManager: LanguageServiceManager, configManager: ConfigManager);
|
||||
private readonly validTriggerCharacters;
|
||||
private isValidTriggerCharacter;
|
||||
private lastCompletion?;
|
||||
getCompletions(document: AstroDocument, position: Position, completionContext?: CompletionContext, cancellationToken?: CancellationToken): Promise<AppCompletionList<CompletionItemData> | null>;
|
||||
resolveCompletion(document: AstroDocument, item: AppCompletionItem<CompletionItemData>, cancellationToken?: CancellationToken): Promise<AppCompletionItem<CompletionItemData>>;
|
||||
private toCompletionItem;
|
||||
private getCompletionDocument;
|
||||
private canReuseLastCompletion;
|
||||
private getExistingImports;
|
||||
private isAstroComponentImport;
|
||||
private isValidCompletion;
|
||||
}
|
||||
export declare function codeActionChangeToTextEdit(document: AstroDocument, snapshot: DocumentSnapshot, isInsideScriptTag: boolean, change: ts.TextChange, ts: typeof import('typescript/lib/tsserverlibrary')): TextEdit;
|
||||
294
node_modules/@astrojs/language-server/dist/plugins/typescript/features/CompletionsProvider.js
generated
vendored
Normal file
294
node_modules/@astrojs/language-server/dist/plugins/typescript/features/CompletionsProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.codeActionChangeToTextEdit = exports.CompletionsProviderImpl = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
|
||||
const documents_1 = require("../../../core/documents");
|
||||
const utils_1 = require("../../../core/documents/utils");
|
||||
const utils_2 = require("../../../utils");
|
||||
const previewer_1 = require("../previewer");
|
||||
const utils_3 = require("../utils");
|
||||
const utils_4 = require("./utils");
|
||||
// `import {...} from '..'` or `import ... from '..'`
|
||||
// Note: Does not take into account if import is within a comment.
|
||||
const scriptImportRegex = /\bimport\s+{([^}]*?)}\s+?from\s+['"`].+?['"`]|\bimport\s+(\w+?)\s+from\s+['"`].+?['"`]/g;
|
||||
// When Svelte components are imported, we have to reference the svelte2tsx's types to properly type the component
|
||||
// An unfortunate downside of this is that it polutes completions, so let's filter those internal types manually
|
||||
const svelte2tsxTypes = new Set([
|
||||
'Svelte2TsxComponent',
|
||||
'Svelte2TsxComponentConstructorParameters',
|
||||
'SvelteComponentConstructor',
|
||||
'SvelteActionReturnType',
|
||||
'SvelteTransitionConfig',
|
||||
'SvelteTransitionReturnType',
|
||||
'SvelteAnimationReturnType',
|
||||
'SvelteWithOptionalProps',
|
||||
'SvelteAllProps',
|
||||
'SveltePropsAnyFallback',
|
||||
'SvelteSlotsAnyFallback',
|
||||
'SvelteRestProps',
|
||||
'SvelteSlots',
|
||||
'SvelteStore',
|
||||
]);
|
||||
class CompletionsProviderImpl {
|
||||
constructor(languageServiceManager, configManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.configManager = configManager;
|
||||
this.validTriggerCharacters = ['.', '"', "'", '`', '/', '@', '<', '#'];
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
}
|
||||
isValidTriggerCharacter(character) {
|
||||
return this.validTriggerCharacters.includes(character);
|
||||
}
|
||||
async getCompletions(document, position, completionContext, cancellationToken) {
|
||||
const triggerCharacter = completionContext?.triggerCharacter;
|
||||
const triggerKind = completionContext?.triggerKind;
|
||||
const validTriggerCharacter = this.isValidTriggerCharacter(triggerCharacter) ? triggerCharacter : undefined;
|
||||
const isCustomTriggerCharacter = triggerKind === vscode_languageserver_1.CompletionTriggerKind.TriggerCharacter;
|
||||
if ((isCustomTriggerCharacter && !validTriggerCharacter) || cancellationToken?.isCancellationRequested) {
|
||||
return null;
|
||||
}
|
||||
if (this.canReuseLastCompletion(this.lastCompletion, triggerKind, triggerCharacter, document, position)) {
|
||||
this.lastCompletion.position = position;
|
||||
return this.lastCompletion.completionList;
|
||||
}
|
||||
else {
|
||||
this.lastCompletion = undefined;
|
||||
}
|
||||
const html = document.html;
|
||||
const documentOffset = document.offsetAt(position);
|
||||
const node = html.findNodeAt(documentOffset);
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const offset = tsDoc.offsetAt(tsDoc.getGeneratedPosition(position));
|
||||
let filePath = tsDoc.filePath;
|
||||
let completions;
|
||||
const isCompletionInsideFrontmatter = (0, utils_1.isInsideFrontmatter)(document.getText(), documentOffset);
|
||||
const isCompletionInsideExpression = (0, utils_1.isInsideExpression)(document.getText(), node.start, documentOffset);
|
||||
const tsPreferences = await this.configManager.getTSPreferences(document);
|
||||
const formatOptions = await this.configManager.getTSFormatConfig(document);
|
||||
let scriptTagIndex = undefined;
|
||||
if (node.tag === 'script') {
|
||||
const { filePath: scriptFilePath, offset: scriptOffset, index: scriptIndex, } = (0, utils_3.getScriptTagSnapshot)(tsDoc, document, node, position);
|
||||
filePath = scriptFilePath;
|
||||
scriptTagIndex = scriptIndex;
|
||||
completions = lang.getCompletionsAtPosition(scriptFilePath, scriptOffset, {
|
||||
...tsPreferences,
|
||||
triggerCharacter: validTriggerCharacter,
|
||||
}, formatOptions);
|
||||
}
|
||||
else {
|
||||
// PERF: Getting TS completions is fairly slow and I am currently not sure how to speed it up
|
||||
// As such, we'll try to avoid getting them when unneeded, such as when we're doing HTML stuff
|
||||
// If the user just typed `<` with nothing else, let's disable ourselves until we're more sure if the user wants TS completions
|
||||
if (!isCompletionInsideFrontmatter && node.parent && node.tag === undefined && !isCompletionInsideExpression) {
|
||||
return null;
|
||||
}
|
||||
// If the current node is not a component, let's disable ourselves as the user
|
||||
// is most likely looking for HTML completions
|
||||
if (!isCompletionInsideFrontmatter && !(0, utils_1.isPossibleComponent)(node) && !isCompletionInsideExpression) {
|
||||
return null;
|
||||
}
|
||||
completions = lang.getCompletionsAtPosition(filePath, offset, {
|
||||
...tsPreferences,
|
||||
triggerCharacter: validTriggerCharacter,
|
||||
}, formatOptions);
|
||||
}
|
||||
if (completions === undefined || completions.entries.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const existingImports = this.getExistingImports(document);
|
||||
const completionItems = completions.entries
|
||||
.filter((completion) => this.isValidCompletion(completion, this.ts))
|
||||
.map((entry) => this.toCompletionItem(tsDoc, entry, filePath, offset, isCompletionInsideFrontmatter, scriptTagIndex, existingImports))
|
||||
.filter(utils_2.isNotNullOrUndefined);
|
||||
const completionList = vscode_languageserver_1.CompletionList.create(completionItems, true);
|
||||
this.lastCompletion = { key: document.getFilePath() || '', position, completionList };
|
||||
return completionList;
|
||||
}
|
||||
async resolveCompletion(document, item, cancellationToken) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const tsPreferences = await this.configManager.getTSPreferences(document);
|
||||
const data = item.data;
|
||||
if (!data || !data.filePath || cancellationToken?.isCancellationRequested) {
|
||||
return item;
|
||||
}
|
||||
const detail = lang.getCompletionEntryDetails(data.filePath, // fileName
|
||||
data.offset, // position
|
||||
data.originalItem.name, // entryName
|
||||
{}, // formatOptions
|
||||
data.originalItem.source, // source
|
||||
tsPreferences, // preferences
|
||||
data.originalItem.data // data
|
||||
);
|
||||
if (detail) {
|
||||
const { detail: itemDetail, documentation: itemDocumentation } = this.getCompletionDocument(detail);
|
||||
// TODO: Add support for labelDetails
|
||||
// if (data.originalItem.source) {
|
||||
// item.labelDetails = { description: data.originalItem.source };
|
||||
// }
|
||||
item.detail = itemDetail;
|
||||
item.documentation = itemDocumentation;
|
||||
}
|
||||
const actions = detail?.codeActions;
|
||||
const isInsideScriptTag = data.scriptTagIndex !== undefined;
|
||||
let scriptTagSnapshot;
|
||||
if (isInsideScriptTag) {
|
||||
const { snapshot } = (0, utils_3.getScriptTagSnapshot)(tsDoc, document, document.scriptTags[data.scriptTagIndex].container);
|
||||
scriptTagSnapshot = snapshot;
|
||||
}
|
||||
if (actions) {
|
||||
const edit = [];
|
||||
for (const action of actions) {
|
||||
for (const change of action.changes) {
|
||||
if (isInsideScriptTag) {
|
||||
change.textChanges.forEach((textChange) => {
|
||||
const originalPosition = scriptTagSnapshot.getOriginalPosition(scriptTagSnapshot.positionAt(textChange.span.start));
|
||||
textChange.span.start = tsDoc.offsetAt(tsDoc.getGeneratedPosition(originalPosition));
|
||||
});
|
||||
}
|
||||
edit.push(...change.textChanges.map((textChange) => codeActionChangeToTextEdit(document, tsDoc, isInsideScriptTag, textChange, this.ts)));
|
||||
}
|
||||
}
|
||||
item.additionalTextEdits = (item.additionalTextEdits ?? []).concat(edit);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
toCompletionItem(snapshot, comp, filePath, offset, insideFrontmatter, scriptTagIndex, existingImports) {
|
||||
let item = vscode_languageserver_protocol_1.CompletionItem.create(comp.name);
|
||||
const isAstroComponent = this.isAstroComponentImport(comp.name);
|
||||
const isImport = comp.insertText?.includes('import');
|
||||
// Avoid showing completions for using components as functions
|
||||
if (isAstroComponent && !isImport && insideFrontmatter) {
|
||||
return null;
|
||||
}
|
||||
if (isAstroComponent) {
|
||||
item.label = (0, utils_3.removeAstroComponentSuffix)(comp.name);
|
||||
// Set component imports as file completion, that way we get cool icons
|
||||
item.kind = vscode_languageserver_protocol_1.CompletionItemKind.File;
|
||||
item.detail = comp.data?.moduleSpecifier;
|
||||
}
|
||||
else {
|
||||
item.kind = (0, utils_3.scriptElementKindToCompletionItemKind)(comp.kind, this.ts);
|
||||
}
|
||||
// TS may suggest another component even if there already exists an import with the same.
|
||||
// This happens because internally, components get suffixed with __AstroComponent_
|
||||
if (isAstroComponent && existingImports.has(item.label)) {
|
||||
return null;
|
||||
}
|
||||
if (comp.kindModifiers) {
|
||||
const kindModifiers = new Set(comp.kindModifiers.split(/,|\s+/g));
|
||||
if (kindModifiers.has(this.ts.ScriptElementKindModifier.optionalModifier)) {
|
||||
if (!item.insertText) {
|
||||
item.insertText = item.label;
|
||||
}
|
||||
if (!item.filterText) {
|
||||
item.filterText = item.label;
|
||||
}
|
||||
item.label += '?';
|
||||
}
|
||||
if (kindModifiers.has(this.ts.ScriptElementKindModifier.deprecatedModifier)) {
|
||||
item.tags = [vscode_languageserver_1.CompletionItemTag.Deprecated];
|
||||
}
|
||||
}
|
||||
// TODO: Add support for labelDetails
|
||||
// if (comp.sourceDisplay) {
|
||||
// item.labelDetails = { description: ts.displayPartsToString(comp.sourceDisplay) };
|
||||
// }
|
||||
item.commitCharacters = (0, utils_3.getCommitCharactersForScriptElement)(comp.kind, this.ts);
|
||||
item.sortText = comp.sortText;
|
||||
item.preselect = comp.isRecommended;
|
||||
if (comp.replacementSpan) {
|
||||
item.insertText = comp.insertText ? (0, utils_3.removeAstroComponentSuffix)(comp.insertText) : undefined;
|
||||
item.insertTextFormat = comp.isSnippet ? vscode_languageserver_1.InsertTextFormat.Snippet : vscode_languageserver_1.InsertTextFormat.PlainText;
|
||||
item.textEdit = comp.replacementSpan
|
||||
? vscode_languageserver_1.TextEdit.replace((0, utils_3.convertToLocationRange)(snapshot, comp.replacementSpan), item.insertText ?? item.label)
|
||||
: undefined;
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
data: {
|
||||
uri: snapshot.getURL(),
|
||||
filePath,
|
||||
scriptTagIndex,
|
||||
offset,
|
||||
originalItem: comp,
|
||||
},
|
||||
};
|
||||
}
|
||||
getCompletionDocument(compDetail) {
|
||||
const { sourceDisplay, documentation: tsDocumentation, displayParts } = compDetail;
|
||||
let detail = (0, utils_3.removeAstroComponentSuffix)(this.ts.displayPartsToString(displayParts));
|
||||
if (sourceDisplay) {
|
||||
const importPath = this.ts.displayPartsToString(sourceDisplay);
|
||||
detail = importPath;
|
||||
}
|
||||
const documentation = {
|
||||
kind: 'markdown',
|
||||
value: (0, previewer_1.getMarkdownDocumentation)(tsDocumentation, compDetail.tags, this.ts),
|
||||
};
|
||||
return {
|
||||
documentation,
|
||||
detail,
|
||||
};
|
||||
}
|
||||
canReuseLastCompletion(lastCompletion, triggerKind, triggerCharacter, document, position) {
|
||||
return (!!lastCompletion &&
|
||||
lastCompletion.key === document.getFilePath() &&
|
||||
lastCompletion.position.line === position.line &&
|
||||
Math.abs(lastCompletion.position.character - position.character) < 2 &&
|
||||
(triggerKind === vscode_languageserver_1.CompletionTriggerKind.TriggerForIncompleteCompletions ||
|
||||
// Special case: `.` is a trigger character, but inside import path completions
|
||||
// it shouldn't trigger another completion because we can reuse the old one
|
||||
(triggerCharacter === '.' && (0, utils_4.isPartOfImportStatement)(document.getText(), position))));
|
||||
}
|
||||
getExistingImports(document) {
|
||||
const rawImports = (0, utils_2.getRegExpMatches)(scriptImportRegex, document.getText()).map((match) => (match[1] ?? match[2]).split(','));
|
||||
const tidiedImports = rawImports.flat().map((match) => match.trim());
|
||||
return new Set(tidiedImports);
|
||||
}
|
||||
isAstroComponentImport(className) {
|
||||
return className.endsWith('__AstroComponent_');
|
||||
}
|
||||
isValidCompletion(completion, ts) {
|
||||
// Remove completion for default exported function
|
||||
const isDefaultExport = completion.name === 'default' && completion.kindModifiers == ts.ScriptElementKindModifier.exportedModifier;
|
||||
// Remove completion for svelte2tsx internal types
|
||||
const isSvelte2tsxCompletion = completion.name.startsWith('__sveltets_') || svelte2tsxTypes.has(completion.name);
|
||||
if (isDefaultExport || isSvelte2tsxCompletion) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
exports.CompletionsProviderImpl = CompletionsProviderImpl;
|
||||
function codeActionChangeToTextEdit(document, snapshot, isInsideScriptTag, change, ts) {
|
||||
change.newText = (0, utils_3.removeAstroComponentSuffix)(change.newText);
|
||||
const { span } = change;
|
||||
let range;
|
||||
const virtualRange = (0, utils_3.convertRange)(snapshot, span);
|
||||
range = (0, documents_1.mapRangeToOriginal)(snapshot, virtualRange);
|
||||
if (!isInsideScriptTag) {
|
||||
// If we don't have a frontmatter already, create one with the import
|
||||
const frontmatterState = document.astroMeta.frontmatter.state;
|
||||
if (frontmatterState === null) {
|
||||
return vscode_languageserver_1.TextEdit.replace(vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(0, 0), vscode_languageserver_1.Position.create(0, 0)), `---${ts.sys.newLine}${change.newText}---${ts.sys.newLine}${ts.sys.newLine}`);
|
||||
}
|
||||
if (!(0, utils_1.isInsideFrontmatter)(document.getText(), document.offsetAt(range.start))) {
|
||||
range = (0, utils_3.ensureFrontmatterInsert)(range, document);
|
||||
}
|
||||
// First import in a file will wrongly have a newline before it due to how the frontmatter is replaced by a comment
|
||||
if (range.start.line === 1 && (change.newText.startsWith('\n') || change.newText.startsWith('\r\n'))) {
|
||||
change.newText = change.newText.trimStart();
|
||||
}
|
||||
}
|
||||
else {
|
||||
const existingLine = (0, utils_1.getLineAtPosition)(document.positionAt(span.start), document.getText());
|
||||
const isNewImport = !existingLine.trim().startsWith('import');
|
||||
// Avoid putting new imports on the same line as the script tag opening
|
||||
if (!(change.newText.startsWith('\n') || change.newText.startsWith('\r\n')) && isNewImport) {
|
||||
change.newText = ts.sys.newLine + change.newText;
|
||||
}
|
||||
}
|
||||
return vscode_languageserver_1.TextEdit.replace(range, change.newText);
|
||||
}
|
||||
exports.codeActionChangeToTextEdit = codeActionChangeToTextEdit;
|
||||
9
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DefinitionsProvider.d.ts
generated
vendored
Normal file
9
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DefinitionsProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { LocationLink, Position } from 'vscode-languageserver-types';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import type { DefinitionsProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare class DefinitionsProviderImpl implements DefinitionsProvider {
|
||||
private languageServiceManager;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
getDefinitions(document: AstroDocument, position: Position): Promise<LocationLink[]>;
|
||||
}
|
||||
58
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DefinitionsProvider.js
generated
vendored
Normal file
58
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DefinitionsProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.DefinitionsProviderImpl = void 0;
|
||||
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
||||
const documents_1 = require("../../../core/documents");
|
||||
const utils_1 = require("../../../utils");
|
||||
const utils_2 = require("../utils");
|
||||
const utils_3 = require("./utils");
|
||||
class DefinitionsProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
}
|
||||
async getDefinitions(document, position) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const fragmentPosition = tsDoc.getGeneratedPosition(position);
|
||||
const fragmentOffset = tsDoc.offsetAt(fragmentPosition);
|
||||
let defs;
|
||||
const html = document.html;
|
||||
const offset = document.offsetAt(position);
|
||||
const node = html.findNodeAt(offset);
|
||||
if (node.tag === 'script') {
|
||||
const { snapshot: scriptTagSnapshot, filePath: scriptFilePath, offset: scriptOffset, } = (0, utils_2.getScriptTagSnapshot)(tsDoc, document, node, position);
|
||||
defs = lang.getDefinitionAndBoundSpan(scriptFilePath, scriptOffset);
|
||||
if (defs) {
|
||||
defs.definitions = defs.definitions?.map((def) => {
|
||||
const isInSameFile = def.fileName === scriptFilePath;
|
||||
def.fileName = isInSameFile ? tsDoc.filePath : def.fileName;
|
||||
if (isInSameFile) {
|
||||
def.textSpan.start = (0, documents_1.mapScriptSpanStartToSnapshot)(def.textSpan, scriptTagSnapshot, tsDoc);
|
||||
}
|
||||
return def;
|
||||
});
|
||||
defs.textSpan.start = (0, documents_1.mapScriptSpanStartToSnapshot)(defs.textSpan, scriptTagSnapshot, tsDoc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
defs = lang.getDefinitionAndBoundSpan(tsDoc.filePath, fragmentOffset);
|
||||
}
|
||||
if (!defs || !defs.definitions) {
|
||||
return [];
|
||||
}
|
||||
const snapshots = new utils_3.SnapshotMap(this.languageServiceManager);
|
||||
snapshots.set(tsDoc.filePath, tsDoc);
|
||||
const result = await Promise.all(defs.definitions.map(async (def) => {
|
||||
const snapshot = await snapshots.retrieve(def.fileName);
|
||||
const fileName = (0, utils_2.ensureRealFilePath)(def.fileName);
|
||||
// For Astro, Svelte and Vue, the position is wrongly mapped to the end of the file due to the TSX output
|
||||
// So we'll instead redirect to the beginning of the file
|
||||
const isFramework = ((0, utils_2.isFrameworkFilePath)(def.fileName) || (0, utils_2.isAstroFilePath)(def.fileName)) && tsDoc.filePath !== def.fileName;
|
||||
const targetRange = isFramework
|
||||
? (0, utils_2.convertRange)(document, { start: 0, length: 0 })
|
||||
: (0, utils_2.convertToLocationRange)(snapshot, def.textSpan);
|
||||
return vscode_languageserver_types_1.LocationLink.create((0, utils_1.pathToUrl)(fileName), targetRange, targetRange, (0, utils_2.convertToLocationRange)(tsDoc, defs.textSpan));
|
||||
}));
|
||||
return result.filter(utils_1.isNotNullOrUndefined);
|
||||
}
|
||||
}
|
||||
exports.DefinitionsProviderImpl = DefinitionsProviderImpl;
|
||||
25
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DiagnosticsProvider.d.ts
generated
vendored
Normal file
25
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DiagnosticsProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import type ts from 'typescript';
|
||||
import { CancellationToken, DiagnosticSeverity } from 'vscode-languageserver';
|
||||
import { Diagnostic } from 'vscode-languageserver-types';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import type { DiagnosticsProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare enum DiagnosticCodes {
|
||||
SPREAD_EXPECTED = 1005,
|
||||
IS_NOT_A_MODULE = 2306,
|
||||
CANNOT_FIND_MODULE = 2307,
|
||||
DUPLICATED_JSX_ATTRIBUTES = 17001,
|
||||
CANT_RETURN_OUTSIDE_FUNC = 1108,
|
||||
ISOLATED_MODULE_COMPILE_ERR = 1208,
|
||||
TYPE_NOT_ASSIGNABLE = 2322,
|
||||
JSX_NO_CLOSING_TAG = 17008,
|
||||
JSX_ELEMENT_NO_CALL = 2604
|
||||
}
|
||||
export declare class DiagnosticsProviderImpl implements DiagnosticsProvider {
|
||||
private languageServiceManager;
|
||||
private ts;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
getDiagnostics(document: AstroDocument, _cancellationToken?: CancellationToken): Promise<Diagnostic[]>;
|
||||
private getTagBoundaries;
|
||||
mapSeverity(category: ts.DiagnosticCategory): DiagnosticSeverity;
|
||||
}
|
||||
249
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DiagnosticsProvider.js
generated
vendored
Normal file
249
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DiagnosticsProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.DiagnosticsProviderImpl = exports.DiagnosticCodes = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
||||
const documents_1 = require("../../../core/documents");
|
||||
const utils_1 = require("../utils");
|
||||
// List of codes:
|
||||
// https://github.com/Microsoft/TypeScript/blob/main/src/compiler/diagnosticMessages.json
|
||||
var DiagnosticCodes;
|
||||
(function (DiagnosticCodes) {
|
||||
DiagnosticCodes[DiagnosticCodes["SPREAD_EXPECTED"] = 1005] = "SPREAD_EXPECTED";
|
||||
DiagnosticCodes[DiagnosticCodes["IS_NOT_A_MODULE"] = 2306] = "IS_NOT_A_MODULE";
|
||||
DiagnosticCodes[DiagnosticCodes["CANNOT_FIND_MODULE"] = 2307] = "CANNOT_FIND_MODULE";
|
||||
DiagnosticCodes[DiagnosticCodes["DUPLICATED_JSX_ATTRIBUTES"] = 17001] = "DUPLICATED_JSX_ATTRIBUTES";
|
||||
DiagnosticCodes[DiagnosticCodes["CANT_RETURN_OUTSIDE_FUNC"] = 1108] = "CANT_RETURN_OUTSIDE_FUNC";
|
||||
DiagnosticCodes[DiagnosticCodes["ISOLATED_MODULE_COMPILE_ERR"] = 1208] = "ISOLATED_MODULE_COMPILE_ERR";
|
||||
DiagnosticCodes[DiagnosticCodes["TYPE_NOT_ASSIGNABLE"] = 2322] = "TYPE_NOT_ASSIGNABLE";
|
||||
DiagnosticCodes[DiagnosticCodes["JSX_NO_CLOSING_TAG"] = 17008] = "JSX_NO_CLOSING_TAG";
|
||||
DiagnosticCodes[DiagnosticCodes["JSX_ELEMENT_NO_CALL"] = 2604] = "JSX_ELEMENT_NO_CALL";
|
||||
})(DiagnosticCodes = exports.DiagnosticCodes || (exports.DiagnosticCodes = {}));
|
||||
class DiagnosticsProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
}
|
||||
async getDiagnostics(document, _cancellationToken) {
|
||||
// Don't return diagnostics for files inside node_modules. These are considered read-only
|
||||
// and they would pollute the output for astro check
|
||||
if (document.getFilePath()?.includes('/node_modules/') || document.getFilePath()?.includes('\\node_modules\\')) {
|
||||
return [];
|
||||
}
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
// If we have compiler errors, our TSX isn't valid so don't bother showing TS errors
|
||||
if (tsDoc.isInErrorState) {
|
||||
return [];
|
||||
}
|
||||
let scriptDiagnostics = [];
|
||||
document.scriptTags.forEach((scriptTag) => {
|
||||
const { filePath: scriptFilePath, snapshot: scriptTagSnapshot } = (0, utils_1.getScriptTagSnapshot)(tsDoc, document, scriptTag.container);
|
||||
const scriptDiagnostic = [
|
||||
...lang.getSyntacticDiagnostics(scriptFilePath),
|
||||
...lang.getSuggestionDiagnostics(scriptFilePath),
|
||||
...lang.getSemanticDiagnostics(scriptFilePath),
|
||||
]
|
||||
// We need to duplicate the diagnostic creation here because we can't map TS's diagnostics range to the original
|
||||
// file due to some internal cache inside TS that would cause it to being mapped twice in some cases
|
||||
.map((diagnostic) => ({
|
||||
range: (0, utils_1.convertRange)(scriptTagSnapshot, diagnostic),
|
||||
severity: this.mapSeverity(diagnostic.category),
|
||||
source: 'ts',
|
||||
message: this.ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'),
|
||||
code: diagnostic.code,
|
||||
tags: getDiagnosticTag(diagnostic),
|
||||
}))
|
||||
.map(mapRange(scriptTagSnapshot, document));
|
||||
scriptDiagnostics.push(...scriptDiagnostic);
|
||||
});
|
||||
const { script: scriptBoundaries } = this.getTagBoundaries(lang, tsDoc.filePath);
|
||||
const diagnostics = [
|
||||
...lang.getSyntacticDiagnostics(tsDoc.filePath),
|
||||
...lang.getSuggestionDiagnostics(tsDoc.filePath),
|
||||
...lang.getSemanticDiagnostics(tsDoc.filePath),
|
||||
].filter((diag) => {
|
||||
return isNoWithinBoundary(scriptBoundaries, diag, this.ts);
|
||||
});
|
||||
return [
|
||||
...diagnostics
|
||||
.map((diagnostic) => ({
|
||||
range: (0, utils_1.convertRange)(tsDoc, diagnostic),
|
||||
severity: this.mapSeverity(diagnostic.category),
|
||||
source: 'ts',
|
||||
message: this.ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'),
|
||||
code: diagnostic.code,
|
||||
tags: getDiagnosticTag(diagnostic),
|
||||
}))
|
||||
.map(mapRange(tsDoc, document)),
|
||||
...scriptDiagnostics,
|
||||
]
|
||||
.filter((diag) => {
|
||||
return (
|
||||
// Make sure the diagnostic is inside the document and not in generated code
|
||||
diag.range.start.line <= document.lineCount &&
|
||||
hasNoNegativeLines(diag) &&
|
||||
isNoCantReturnOutsideFunction(diag) &&
|
||||
isNoIsolatedModuleError(diag) &&
|
||||
isNoJsxCannotHaveMultipleAttrsError(diag));
|
||||
})
|
||||
.map(enhanceIfNecessary);
|
||||
}
|
||||
getTagBoundaries(lang, tsFilePath) {
|
||||
const program = lang.getProgram();
|
||||
const sourceFile = program?.getSourceFile(tsFilePath);
|
||||
const boundaries = {
|
||||
script: [],
|
||||
};
|
||||
if (!sourceFile) {
|
||||
return boundaries;
|
||||
}
|
||||
function findTags(parent, ts) {
|
||||
ts.forEachChild(parent, (node) => {
|
||||
if (ts.isJsxElement(node)) {
|
||||
let tagName = node.openingElement.tagName.getText();
|
||||
switch (tagName) {
|
||||
case 'script': {
|
||||
ts.getLineAndCharacterOfPosition(sourceFile, node.getStart());
|
||||
boundaries.script.push([node.getStart(), node.getEnd()]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
findTags(node, ts);
|
||||
});
|
||||
}
|
||||
findTags(sourceFile, this.ts);
|
||||
return boundaries;
|
||||
}
|
||||
mapSeverity(category) {
|
||||
switch (category) {
|
||||
case this.ts.DiagnosticCategory.Error:
|
||||
return vscode_languageserver_1.DiagnosticSeverity.Error;
|
||||
case this.ts.DiagnosticCategory.Warning:
|
||||
return vscode_languageserver_1.DiagnosticSeverity.Warning;
|
||||
case this.ts.DiagnosticCategory.Suggestion:
|
||||
return vscode_languageserver_1.DiagnosticSeverity.Hint;
|
||||
case this.ts.DiagnosticCategory.Message:
|
||||
return vscode_languageserver_1.DiagnosticSeverity.Information;
|
||||
default:
|
||||
return vscode_languageserver_1.DiagnosticSeverity.Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.DiagnosticsProviderImpl = DiagnosticsProviderImpl;
|
||||
function isWithinBoundaries(boundaries, start) {
|
||||
for (let [bstart, bend] of boundaries) {
|
||||
if (start > bstart && start < bend) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function diagnosticIsWithinBoundaries(sourceFile, boundaries, diagnostic, ts) {
|
||||
if ('start' in diagnostic) {
|
||||
if (diagnostic.start == null)
|
||||
return false;
|
||||
return isWithinBoundaries(boundaries, diagnostic.start);
|
||||
}
|
||||
if (!sourceFile)
|
||||
return false;
|
||||
let startRange = diagnostic.range.start;
|
||||
let pos = ts.getPositionOfLineAndCharacter(sourceFile, startRange.line, startRange.character);
|
||||
return isWithinBoundaries(boundaries, pos);
|
||||
}
|
||||
function isNoWithinBoundary(boundaries, diagnostic, ts) {
|
||||
return !diagnosticIsWithinBoundaries(undefined, boundaries, diagnostic, ts);
|
||||
}
|
||||
function mapRange(snapshot, _document) {
|
||||
return (diagnostic) => {
|
||||
let range = (0, documents_1.mapRangeToOriginal)(snapshot, diagnostic.range);
|
||||
return { ...diagnostic, range };
|
||||
};
|
||||
}
|
||||
/**
|
||||
* In some rare cases mapping of diagnostics does not work and produces negative lines.
|
||||
* We filter out these diagnostics with negative lines because else the LSP
|
||||
* apparently has a hiccup and does not show any diagnostics at all.
|
||||
*/
|
||||
function hasNoNegativeLines(diagnostic) {
|
||||
return diagnostic.range.start.line >= 0 && diagnostic.range.end.line >= 0;
|
||||
}
|
||||
/**
|
||||
* Astro allows multiple attributes to have the same name
|
||||
*/
|
||||
function isNoJsxCannotHaveMultipleAttrsError(diagnostic) {
|
||||
return diagnostic.code !== DiagnosticCodes.DUPLICATED_JSX_ATTRIBUTES;
|
||||
}
|
||||
/**
|
||||
* Ignore "Can't return outside of function body"
|
||||
* Since the frontmatter is at the top level, users trying to return a Response for SSR mode run into this
|
||||
*/
|
||||
function isNoCantReturnOutsideFunction(diagnostic) {
|
||||
return diagnostic.code !== DiagnosticCodes.CANT_RETURN_OUTSIDE_FUNC;
|
||||
}
|
||||
/**
|
||||
* When the content of the file is invalid and can't be parsed properly for TSX generation, TS will show an error about
|
||||
* how the current module can't be compiled under --isolatedModule, this is confusing to users so let's ignore this
|
||||
*/
|
||||
function isNoIsolatedModuleError(diagnostic) {
|
||||
return diagnostic.code !== DiagnosticCodes.ISOLATED_MODULE_COMPILE_ERR;
|
||||
}
|
||||
/**
|
||||
* Some diagnostics have JSX-specific nomenclature or unclear description. Enhance them for more clarity.
|
||||
*/
|
||||
function enhanceIfNecessary(diagnostic) {
|
||||
// When the language integrations are not installed, the content of the imported snapshot is empty
|
||||
// As such, it triggers the "is not a module error", which we can enhance with a more helpful message for the related framework
|
||||
if (diagnostic.code === DiagnosticCodes.IS_NOT_A_MODULE) {
|
||||
if (diagnostic.message.includes('.svelte')) {
|
||||
diagnostic.message +=
|
||||
'\n\nIs the `@astrojs/svelte` package installed? You can add it to your project by running the following command: `astro add svelte`. If already installed, restarting the language server might be necessary in order for the change to take effect';
|
||||
}
|
||||
if (diagnostic.message.includes('.vue')) {
|
||||
diagnostic.message +=
|
||||
'\n\nIs the `@astrojs/vue` package installed? You can add it to your project by running the following command: `astro add vue`. If already installed, restarting the language server might be necessary in order for the change to take effect';
|
||||
}
|
||||
return diagnostic;
|
||||
}
|
||||
if (diagnostic.code === DiagnosticCodes.CANNOT_FIND_MODULE && diagnostic.message.includes('astro:content')) {
|
||||
diagnostic.message +=
|
||||
"\n\nIf you're using content collections, make sure to run `astro dev`, `astro build` or `astro sync` to first generate the types so you can import from them. If you already ran one of those commands, restarting the language server might be necessary in order for the change to take effect";
|
||||
return diagnostic;
|
||||
}
|
||||
// JSX element has no closing tag. JSX -> HTML
|
||||
if (diagnostic.code === DiagnosticCodes.JSX_NO_CLOSING_TAG) {
|
||||
return {
|
||||
...diagnostic,
|
||||
message: diagnostic.message.replace('JSX', 'HTML'),
|
||||
};
|
||||
}
|
||||
// JSX Element can't be constructed or called. This happens on syntax errors / invalid components
|
||||
if (diagnostic.code === DiagnosticCodes.JSX_ELEMENT_NO_CALL) {
|
||||
return {
|
||||
...diagnostic,
|
||||
message: diagnostic.message
|
||||
.replace('JSX element type', 'Component')
|
||||
.replace('does not have any construct or call signatures.', 'is not a valid component.\n\nIf this is a Svelte or Vue component, it might have a syntax error that makes it impossible to parse.'),
|
||||
};
|
||||
}
|
||||
// For the rare case where an user might try to put a client directive on something that is not a component
|
||||
if (diagnostic.code === DiagnosticCodes.TYPE_NOT_ASSIGNABLE) {
|
||||
if (diagnostic.message.includes("Property 'client:") && diagnostic.message.includes("to type 'HTMLAttributes")) {
|
||||
return {
|
||||
...diagnostic,
|
||||
message: 'Client directives are only available on framework components',
|
||||
};
|
||||
}
|
||||
}
|
||||
return diagnostic;
|
||||
}
|
||||
function getDiagnosticTag(diagnostic) {
|
||||
const tags = [];
|
||||
if (diagnostic.reportsUnnecessary) {
|
||||
tags.push(vscode_languageserver_types_1.DiagnosticTag.Unnecessary);
|
||||
}
|
||||
if (diagnostic.reportsDeprecated) {
|
||||
tags.push(vscode_languageserver_types_1.DiagnosticTag.Deprecated);
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
11
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DocumentSymbolsProvider.d.ts
generated
vendored
Normal file
11
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DocumentSymbolsProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { SymbolInformation } from 'vscode-languageserver-types';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import type { DocumentSymbolsProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare class DocumentSymbolsProviderImpl implements DocumentSymbolsProvider {
|
||||
private languageServiceManager;
|
||||
private ts;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
getDocumentSymbols(document: AstroDocument): Promise<SymbolInformation[]>;
|
||||
private collectSymbols;
|
||||
}
|
||||
67
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DocumentSymbolsProvider.js
generated
vendored
Normal file
67
node_modules/@astrojs/language-server/dist/plugins/typescript/features/DocumentSymbolsProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.DocumentSymbolsProviderImpl = void 0;
|
||||
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
||||
const utils_1 = require("../utils");
|
||||
class DocumentSymbolsProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
}
|
||||
async getDocumentSymbols(document) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const navTree = lang.getNavigationTree(tsDoc.filePath + '?documentSymbols');
|
||||
if (!navTree) {
|
||||
return [];
|
||||
}
|
||||
const symbols = [];
|
||||
this.collectSymbols(navTree, document, undefined, (symbol) => symbols.push(symbol));
|
||||
const originalContainerName = symbols[0].name;
|
||||
const result = [];
|
||||
// Add a "Frontmatter" namespace for the frontmatter if we have a closed one
|
||||
if (document.astroMeta.frontmatter.state === 'closed') {
|
||||
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)), document.getURL()));
|
||||
}
|
||||
// Add a "Template" namespace for everything under the frontmatter
|
||||
result.push(vscode_languageserver_types_1.SymbolInformation.create('Template', vscode_languageserver_types_1.SymbolKind.Namespace, vscode_languageserver_types_1.Range.create(document.positionAt(document.astroMeta.frontmatter.endOffset ?? 0), document.positionAt(document.getTextLength())), document.getURL()));
|
||||
for (let symbol of symbols.splice(1)) {
|
||||
if (document.offsetAt(symbol.location.range.end) >= (document.astroMeta.content.firstNonWhitespaceOffset ?? 0)) {
|
||||
if (symbol.containerName === originalContainerName) {
|
||||
symbol.containerName = 'Template';
|
||||
}
|
||||
// For some reason, it seems like TypeScript thinks that the "class" attribute is a real class, weird
|
||||
if (symbol.kind === vscode_languageserver_types_1.SymbolKind.Class && symbol.name === '<class>') {
|
||||
const node = document.html.findNodeAt(document.offsetAt(symbol.location.range.start));
|
||||
if (node.attributes?.class) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove the exported function in our TSX output from the symbols
|
||||
if (document.offsetAt(symbol.location.range.start) >= document.getTextLength()) {
|
||||
continue;
|
||||
}
|
||||
result.push(symbol);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
collectSymbols(item, document, container, cb) {
|
||||
for (const span of item.spans) {
|
||||
const symbol = vscode_languageserver_types_1.SymbolInformation.create(item.text, (0, utils_1.symbolKindFromString)(item.kind), vscode_languageserver_types_1.Range.create(document.positionAt(span.start), document.positionAt(span.start + span.length)), document.getURL(), container);
|
||||
// TypeScript gives us kind modifiers as a string instead of an array
|
||||
const kindModifiers = new Set(item.kindModifiers.split(/,|\s+/g));
|
||||
if (kindModifiers.has(this.ts.ScriptElementKindModifier.deprecatedModifier)) {
|
||||
if (!symbol.tags)
|
||||
symbol.tags = [];
|
||||
symbol.tags.push(vscode_languageserver_types_1.SymbolTag.Deprecated);
|
||||
}
|
||||
cb(symbol);
|
||||
}
|
||||
if (item.childItems) {
|
||||
for (const child of item.childItems) {
|
||||
this.collectSymbols(child, document, item.text, cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.DocumentSymbolsProviderImpl = DocumentSymbolsProviderImpl;
|
||||
9
node_modules/@astrojs/language-server/dist/plugins/typescript/features/FileReferencesProvider.d.ts
generated
vendored
Normal file
9
node_modules/@astrojs/language-server/dist/plugins/typescript/features/FileReferencesProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { Location } from 'vscode-languageserver';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import { FileReferencesProvider } from '../../interfaces';
|
||||
import { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare class FileReferencesProviderImpl implements FileReferencesProvider {
|
||||
private languageServiceManager;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
fileReferences(document: AstroDocument): Promise<Location[] | null>;
|
||||
}
|
||||
27
node_modules/@astrojs/language-server/dist/plugins/typescript/features/FileReferencesProvider.js
generated
vendored
Normal file
27
node_modules/@astrojs/language-server/dist/plugins/typescript/features/FileReferencesProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FileReferencesProviderImpl = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const utils_1 = require("../../../utils");
|
||||
const utils_2 = require("../utils");
|
||||
const utils_3 = require("./utils");
|
||||
class FileReferencesProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
}
|
||||
async fileReferences(document) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const references = lang.getFileReferences(tsDoc.filePath);
|
||||
if (!references) {
|
||||
return null;
|
||||
}
|
||||
const snapshots = new utils_3.SnapshotMap(this.languageServiceManager);
|
||||
snapshots.set(tsDoc.filePath, tsDoc);
|
||||
const locations = await Promise.all(references.map(async (ref) => {
|
||||
const snapshot = await snapshots.retrieve(ref.fileName);
|
||||
return vscode_languageserver_1.Location.create((0, utils_1.pathToUrl)(ref.fileName), (0, utils_2.convertToLocationRange)(snapshot, ref.textSpan));
|
||||
}));
|
||||
return locations;
|
||||
}
|
||||
}
|
||||
exports.FileReferencesProviderImpl = FileReferencesProviderImpl;
|
||||
12
node_modules/@astrojs/language-server/dist/plugins/typescript/features/FoldingRangesProvider.d.ts
generated
vendored
Normal file
12
node_modules/@astrojs/language-server/dist/plugins/typescript/features/FoldingRangesProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import type ts from 'typescript';
|
||||
import { FoldingRange } from 'vscode-languageserver';
|
||||
import type { AstroDocument } from '../../../core/documents';
|
||||
import type { FoldingRangesProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare class FoldingRangesProviderImpl implements FoldingRangesProvider {
|
||||
private languageServiceManager;
|
||||
private ts;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
getFoldingRanges(document: AstroDocument): Promise<FoldingRange[] | null>;
|
||||
transformFoldingRangeKind(tsKind: ts.OutliningSpanKind): "imports" | "comment" | "region" | undefined;
|
||||
}
|
||||
71
node_modules/@astrojs/language-server/dist/plugins/typescript/features/FoldingRangesProvider.js
generated
vendored
Normal file
71
node_modules/@astrojs/language-server/dist/plugins/typescript/features/FoldingRangesProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FoldingRangesProviderImpl = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const utils_1 = require("../utils");
|
||||
class FoldingRangesProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
}
|
||||
async getFoldingRanges(document) {
|
||||
const html = document.html;
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const outliningSpans = lang.getOutliningSpans(tsDoc.filePath).filter((span) => {
|
||||
const node = html.findNodeAt(span.textSpan.start);
|
||||
// Due to how our TSX output transform those tags into function calls or template literals
|
||||
// TypeScript thinks of those as outlining spans, which is fine but we don't want folding ranges for those
|
||||
return node.tag !== 'script' && node.tag !== 'style';
|
||||
});
|
||||
const scriptOutliningSpans = [];
|
||||
document.scriptTags.forEach((scriptTag) => {
|
||||
const { snapshot: scriptTagSnapshot, filePath: scriptFilePath } = (0, utils_1.getScriptTagSnapshot)(tsDoc, document, scriptTag.container);
|
||||
scriptOutliningSpans.push(...lang.getOutliningSpans(scriptFilePath).map((span) => {
|
||||
span.textSpan.start = document.offsetAt(scriptTagSnapshot.getOriginalPosition(scriptTagSnapshot.positionAt(span.textSpan.start)));
|
||||
return span;
|
||||
}));
|
||||
});
|
||||
const foldingRanges = [];
|
||||
for (const span of [...outliningSpans, ...scriptOutliningSpans]) {
|
||||
const start = tsDoc.getOriginalPosition(tsDoc.positionAt(span.textSpan.start));
|
||||
const end = adjustFoldingEnd(start, document.positionAt(document.offsetAt(start) + span.textSpan.length), document);
|
||||
// When using this method for generating folding ranges, TypeScript tend to return some
|
||||
// one line / one character ones that we should be able to safely ignore
|
||||
if (start.line === end.line && start.character === end.character) {
|
||||
continue;
|
||||
}
|
||||
// Ignore folding ranges that are from unmapped regions
|
||||
if (start.line < 0 || end.line < 0) {
|
||||
continue;
|
||||
}
|
||||
foldingRanges.push(vscode_languageserver_1.FoldingRange.create(start.line, end.line, start.character, end.character, this.transformFoldingRangeKind(span.kind)));
|
||||
}
|
||||
return foldingRanges;
|
||||
}
|
||||
transformFoldingRangeKind(tsKind) {
|
||||
switch (tsKind) {
|
||||
case this.ts.OutliningSpanKind.Comment:
|
||||
return vscode_languageserver_1.FoldingRangeKind.Comment;
|
||||
case this.ts.OutliningSpanKind.Imports:
|
||||
return vscode_languageserver_1.FoldingRangeKind.Imports;
|
||||
case this.ts.OutliningSpanKind.Region:
|
||||
return vscode_languageserver_1.FoldingRangeKind.Region;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.FoldingRangesProviderImpl = FoldingRangesProviderImpl;
|
||||
// https://github.com/microsoft/vscode/blob/bed61166fb604e519e82e4d1d1ed839bc45d65f8/extensions/typescript-language-features/src/languageFeatures/folding.ts#L61-L73
|
||||
function adjustFoldingEnd(start, end, document) {
|
||||
// workaround for #47240
|
||||
if (end.character > 0) {
|
||||
const foldEndCharacter = document.getText({
|
||||
start: { line: end.line, character: end.character - 1 },
|
||||
end,
|
||||
});
|
||||
if (['}', ']', ')', '`'].includes(foldEndCharacter)) {
|
||||
const endOffset = Math.max(document.offsetAt({ line: end.line, character: 0 }) - 1, document.offsetAt(start));
|
||||
return document.positionAt(endOffset);
|
||||
}
|
||||
}
|
||||
return end;
|
||||
}
|
||||
10
node_modules/@astrojs/language-server/dist/plugins/typescript/features/HoverProvider.d.ts
generated
vendored
Normal file
10
node_modules/@astrojs/language-server/dist/plugins/typescript/features/HoverProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import type { Hover, Position } from 'vscode-languageserver';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import type { HoverProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare class HoverProviderImpl implements HoverProvider {
|
||||
private languageServiceManager;
|
||||
private ts;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
doHover(document: AstroDocument, position: Position): Promise<Hover | null>;
|
||||
}
|
||||
50
node_modules/@astrojs/language-server/dist/plugins/typescript/features/HoverProvider.js
generated
vendored
Normal file
50
node_modules/@astrojs/language-server/dist/plugins/typescript/features/HoverProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.HoverProviderImpl = void 0;
|
||||
const documents_1 = require("../../../core/documents");
|
||||
const previewer_1 = require("../previewer");
|
||||
const utils_1 = require("../utils");
|
||||
const partsMap = new Map([['JSX attribute', 'HTML attribute']]);
|
||||
class HoverProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
}
|
||||
async doHover(document, position) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const offset = tsDoc.offsetAt(tsDoc.getGeneratedPosition(position));
|
||||
const html = document.html;
|
||||
const documentOffset = document.offsetAt(position);
|
||||
const node = html.findNodeAt(documentOffset);
|
||||
let info;
|
||||
if (node.tag === 'script') {
|
||||
const { snapshot: scriptTagSnapshot, filePath: scriptFilePath, offset: scriptOffset, } = (0, utils_1.getScriptTagSnapshot)(tsDoc, document, node, position);
|
||||
info = lang.getQuickInfoAtPosition(scriptFilePath, scriptOffset);
|
||||
if (info) {
|
||||
info.textSpan.start = (0, documents_1.mapScriptSpanStartToSnapshot)(info.textSpan, scriptTagSnapshot, tsDoc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
info = lang.getQuickInfoAtPosition(tsDoc.filePath, offset);
|
||||
}
|
||||
if (!info) {
|
||||
return null;
|
||||
}
|
||||
const textSpan = info.textSpan;
|
||||
const displayParts = (info.displayParts || []).map((value) => ({
|
||||
text: partsMap.has(value.text) ? partsMap.get(value.text) : value.text,
|
||||
kind: value.kind,
|
||||
}));
|
||||
const declaration = this.ts.displayPartsToString(displayParts);
|
||||
const documentation = (0, previewer_1.getMarkdownDocumentation)(info.documentation, info.tags, this.ts);
|
||||
// https://microsoft.github.io/language-server-protocol/specification#textDocument_hover
|
||||
const contents = ['```typescript', declaration, '```']
|
||||
.concat(documentation ? ['---', documentation] : [])
|
||||
.join('\n');
|
||||
return (0, documents_1.mapObjWithRangeToOriginal)(tsDoc, {
|
||||
range: (0, utils_1.convertRange)(tsDoc, textSpan),
|
||||
contents,
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.HoverProviderImpl = HoverProviderImpl;
|
||||
9
node_modules/@astrojs/language-server/dist/plugins/typescript/features/ImplementationsProvider.d.ts
generated
vendored
Normal file
9
node_modules/@astrojs/language-server/dist/plugins/typescript/features/ImplementationsProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { Location, Position } from 'vscode-languageserver-types';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import { ImplementationProvider } from '../../interfaces';
|
||||
import { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare class ImplementationsProviderImpl implements ImplementationProvider {
|
||||
private languageServiceManager;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
getImplementation(document: AstroDocument, position: Position): Promise<Location[] | null>;
|
||||
}
|
||||
53
node_modules/@astrojs/language-server/dist/plugins/typescript/features/ImplementationsProvider.js
generated
vendored
Normal file
53
node_modules/@astrojs/language-server/dist/plugins/typescript/features/ImplementationsProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ImplementationsProviderImpl = void 0;
|
||||
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
||||
const documents_1 = require("../../../core/documents");
|
||||
const utils_1 = require("../../../utils");
|
||||
const utils_2 = require("../utils");
|
||||
const utils_3 = require("./utils");
|
||||
class ImplementationsProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
}
|
||||
async getImplementation(document, position) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const fragmentPosition = tsDoc.getGeneratedPosition(position);
|
||||
const fragmentOffset = tsDoc.offsetAt(fragmentPosition);
|
||||
const html = document.html;
|
||||
const offset = document.offsetAt(position);
|
||||
const node = document.html.findNodeAt(offset);
|
||||
let implementations;
|
||||
if (node.tag === 'script') {
|
||||
const { snapshot: scriptTagSnapshot, filePath: scriptFilePath, offset: scriptOffset, } = (0, utils_2.getScriptTagSnapshot)(tsDoc, document, node, position);
|
||||
implementations = lang.getImplementationAtPosition(scriptFilePath, scriptOffset);
|
||||
if (implementations) {
|
||||
implementations = implementations.map((impl) => {
|
||||
const isInSameFile = impl.fileName === scriptFilePath;
|
||||
impl.fileName = isInSameFile ? tsDoc.filePath : impl.fileName;
|
||||
if (isInSameFile) {
|
||||
impl.textSpan.start = (0, documents_1.mapScriptSpanStartToSnapshot)(impl.textSpan, scriptTagSnapshot, tsDoc);
|
||||
}
|
||||
return impl;
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
implementations = lang.getImplementationAtPosition(tsDoc.filePath, fragmentOffset);
|
||||
}
|
||||
const snapshots = new utils_3.SnapshotMap(this.languageServiceManager);
|
||||
snapshots.set(tsDoc.filePath, tsDoc);
|
||||
if (!implementations) {
|
||||
return null;
|
||||
}
|
||||
const result = await Promise.all(implementations.map(async (implementation) => {
|
||||
const snapshot = await snapshots.retrieve(implementation.fileName);
|
||||
const range = (0, documents_1.mapRangeToOriginal)(snapshot, (0, utils_2.convertRange)(snapshot, implementation.textSpan));
|
||||
if (range.start.line >= 0 && range.end.line >= 0) {
|
||||
return vscode_languageserver_types_1.Location.create((0, utils_1.pathToUrl)(implementation.fileName), range);
|
||||
}
|
||||
}));
|
||||
return result.filter(utils_1.isNotNullOrUndefined);
|
||||
}
|
||||
}
|
||||
exports.ImplementationsProviderImpl = ImplementationsProviderImpl;
|
||||
13
node_modules/@astrojs/language-server/dist/plugins/typescript/features/InlayHintsProvider.d.ts
generated
vendored
Normal file
13
node_modules/@astrojs/language-server/dist/plugins/typescript/features/InlayHintsProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { InlayHint } from 'vscode-languageserver';
|
||||
import { Range } from 'vscode-languageserver-types';
|
||||
import type { ConfigManager } from '../../../core/config';
|
||||
import type { AstroDocument } from '../../../core/documents';
|
||||
import type { InlayHintsProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare class InlayHintsProviderImpl implements InlayHintsProvider {
|
||||
private languageServiceManager;
|
||||
private configManager;
|
||||
private ts;
|
||||
constructor(languageServiceManager: LanguageServiceManager, configManager: ConfigManager);
|
||||
getInlayHints(document: AstroDocument, range: Range): Promise<InlayHint[]>;
|
||||
}
|
||||
30
node_modules/@astrojs/language-server/dist/plugins/typescript/features/InlayHintsProvider.js
generated
vendored
Normal file
30
node_modules/@astrojs/language-server/dist/plugins/typescript/features/InlayHintsProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.InlayHintsProviderImpl = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
||||
class InlayHintsProviderImpl {
|
||||
constructor(languageServiceManager, configManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.configManager = configManager;
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
}
|
||||
async getInlayHints(document, range) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const start = tsDoc.offsetAt(tsDoc.getGeneratedPosition(range.start));
|
||||
const end = tsDoc.offsetAt(tsDoc.getGeneratedPosition(range.end));
|
||||
const tsPreferences = await this.configManager.getTSPreferences(document);
|
||||
const inlayHints = lang.provideInlayHints(tsDoc.filePath, { start, length: end - start }, tsPreferences);
|
||||
return inlayHints.map((hint) => {
|
||||
const result = vscode_languageserver_1.InlayHint.create(tsDoc.getOriginalPosition(tsDoc.positionAt(hint.position)), hint.text, hint.kind === this.ts.InlayHintKind.Type
|
||||
? vscode_languageserver_types_1.InlayHintKind.Type
|
||||
: hint.kind === this.ts.InlayHintKind.Parameter
|
||||
? vscode_languageserver_types_1.InlayHintKind.Parameter
|
||||
: undefined);
|
||||
result.paddingLeft = hint.whitespaceBefore;
|
||||
result.paddingRight = hint.whitespaceAfter;
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.InlayHintsProviderImpl = InlayHintsProviderImpl;
|
||||
9
node_modules/@astrojs/language-server/dist/plugins/typescript/features/ReferencesProvider.d.ts
generated
vendored
Normal file
9
node_modules/@astrojs/language-server/dist/plugins/typescript/features/ReferencesProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { Location, Position, ReferenceContext } from 'vscode-languageserver-types';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import type { FindReferencesProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare class FindReferencesProviderImpl implements FindReferencesProvider {
|
||||
private languageServiceManager;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
findReferences(document: AstroDocument, position: Position, context: ReferenceContext): Promise<Location[] | null>;
|
||||
}
|
||||
55
node_modules/@astrojs/language-server/dist/plugins/typescript/features/ReferencesProvider.js
generated
vendored
Normal file
55
node_modules/@astrojs/language-server/dist/plugins/typescript/features/ReferencesProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FindReferencesProviderImpl = void 0;
|
||||
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
||||
const documents_1 = require("../../../core/documents");
|
||||
const utils_1 = require("../../../utils");
|
||||
const utils_2 = require("../utils");
|
||||
const utils_3 = require("./utils");
|
||||
class FindReferencesProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
}
|
||||
async findReferences(document, position, context) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const fragmentPosition = tsDoc.getGeneratedPosition(position);
|
||||
const fragmentOffset = tsDoc.offsetAt(fragmentPosition);
|
||||
const offset = document.offsetAt(position);
|
||||
const node = document.html.findNodeAt(offset);
|
||||
let references;
|
||||
if (node.tag === 'script') {
|
||||
const { snapshot: scriptTagSnapshot, filePath: scriptFilePath, offset: scriptOffset, } = (0, utils_2.getScriptTagSnapshot)(tsDoc, document, node, position);
|
||||
references = lang.getReferencesAtPosition(scriptFilePath, scriptOffset);
|
||||
if (references) {
|
||||
references = references.map((ref) => {
|
||||
const isInSameFile = ref.fileName === scriptFilePath;
|
||||
ref.fileName = isInSameFile ? tsDoc.filePath : ref.fileName;
|
||||
if (isInSameFile) {
|
||||
ref.textSpan.start = (0, documents_1.mapScriptSpanStartToSnapshot)(ref.textSpan, scriptTagSnapshot, tsDoc);
|
||||
}
|
||||
return ref;
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
references = lang.getReferencesAtPosition(tsDoc.filePath, fragmentOffset);
|
||||
}
|
||||
if (!references) {
|
||||
return null;
|
||||
}
|
||||
const snapshots = new utils_3.SnapshotMap(this.languageServiceManager);
|
||||
snapshots.set(tsDoc.filePath, tsDoc);
|
||||
const result = await Promise.all(references.map(async (reference) => {
|
||||
if (!context.includeDeclaration) {
|
||||
return null;
|
||||
}
|
||||
const snapshot = await snapshots.retrieve(reference.fileName);
|
||||
const range = (0, documents_1.mapRangeToOriginal)(snapshot, (0, utils_2.convertRange)(snapshot, reference.textSpan));
|
||||
if (range.start.line >= 0 && range.end.line >= 0) {
|
||||
return vscode_languageserver_types_1.Location.create((0, utils_1.pathToUrl)(reference.fileName), range);
|
||||
}
|
||||
}));
|
||||
return result.filter(utils_1.isNotNullOrUndefined);
|
||||
}
|
||||
}
|
||||
exports.FindReferencesProviderImpl = FindReferencesProviderImpl;
|
||||
13
node_modules/@astrojs/language-server/dist/plugins/typescript/features/RenameProvider.d.ts
generated
vendored
Normal file
13
node_modules/@astrojs/language-server/dist/plugins/typescript/features/RenameProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import type { Position, Range, WorkspaceEdit } from 'vscode-languageserver-types';
|
||||
import type { ConfigManager } from '../../../core/config';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import type { RenameProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare class RenameProviderImpl implements RenameProvider {
|
||||
private languageServiceManager;
|
||||
private configManager;
|
||||
private ts;
|
||||
constructor(languageServiceManager: LanguageServiceManager, configManager: ConfigManager);
|
||||
prepareRename(document: AstroDocument, position: Position): Promise<Range | null>;
|
||||
rename(document: AstroDocument, position: Position, newName: string): Promise<WorkspaceEdit | null>;
|
||||
}
|
||||
60
node_modules/@astrojs/language-server/dist/plugins/typescript/features/RenameProvider.js
generated
vendored
Normal file
60
node_modules/@astrojs/language-server/dist/plugins/typescript/features/RenameProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RenameProviderImpl = void 0;
|
||||
const documents_1 = require("../../../core/documents");
|
||||
const utils_1 = require("../../../utils");
|
||||
const utils_2 = require("../utils");
|
||||
const utils_3 = require("./utils");
|
||||
class RenameProviderImpl {
|
||||
constructor(languageServiceManager, configManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.configManager = configManager;
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
}
|
||||
async prepareRename(document, position) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const offset = tsDoc.offsetAt(tsDoc.getGeneratedPosition(position));
|
||||
// If our TSX isn't valid, we can't rename safely, so let's abort
|
||||
if (tsDoc.isInErrorState) {
|
||||
return null;
|
||||
}
|
||||
// TODO: Allow renaming of import paths
|
||||
// This requires a bit of work, because we need to create files for the new import paths
|
||||
const renameInfo = lang.getRenameInfo(tsDoc.filePath, offset, { allowRenameOfImportPath: false });
|
||||
if (!renameInfo.canRename) {
|
||||
return null;
|
||||
}
|
||||
return (0, documents_1.mapRangeToOriginal)(tsDoc, (0, utils_2.convertRange)(tsDoc, renameInfo.triggerSpan));
|
||||
}
|
||||
async rename(document, position, newName) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
const offset = tsDoc.offsetAt(tsDoc.getGeneratedPosition(position));
|
||||
const { providePrefixAndSuffixTextForRename } = await this.configManager.getTSPreferences(document);
|
||||
let renames = lang.findRenameLocations(tsDoc.filePath, offset, false, false, providePrefixAndSuffixTextForRename);
|
||||
if (!renames) {
|
||||
return null;
|
||||
}
|
||||
const docs = new utils_3.SnapshotMap(this.languageServiceManager);
|
||||
docs.set(tsDoc.filePath, tsDoc);
|
||||
const mappedRenames = await Promise.all(renames.map(async (rename) => {
|
||||
const snapshot = await docs.retrieve(rename.fileName);
|
||||
return {
|
||||
...rename,
|
||||
range: (0, documents_1.mapRangeToOriginal)(snapshot, (0, utils_2.convertRange)(snapshot, rename.textSpan)),
|
||||
newName,
|
||||
};
|
||||
}));
|
||||
return mappedRenames.reduce((acc, loc) => {
|
||||
const uri = (0, utils_1.pathToUrl)(loc.fileName);
|
||||
if (!acc.changes[uri]) {
|
||||
acc.changes[uri] = [];
|
||||
}
|
||||
acc.changes[uri].push({
|
||||
newText: (loc.prefixText || '') + (loc.newName || newName) + (loc.suffixText || ''),
|
||||
range: loc.range,
|
||||
});
|
||||
return acc;
|
||||
}, { changes: {} });
|
||||
}
|
||||
}
|
||||
exports.RenameProviderImpl = RenameProviderImpl;
|
||||
16
node_modules/@astrojs/language-server/dist/plugins/typescript/features/SemanticTokenProvider.d.ts
generated
vendored
Normal file
16
node_modules/@astrojs/language-server/dist/plugins/typescript/features/SemanticTokenProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { CancellationToken, Range, SemanticTokens } from 'vscode-languageserver';
|
||||
import { AstroDocument } from '../../../core/documents';
|
||||
import type { SemanticTokensProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare class SemanticTokensProviderImpl implements SemanticTokensProvider {
|
||||
private languageServiceManager;
|
||||
private ts;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
getSemanticTokens(document: AstroDocument, range?: Range, cancellationToken?: CancellationToken): Promise<SemanticTokens | null>;
|
||||
private mapToOrigin;
|
||||
/**
|
||||
* TSClassification = (TokenType + 1) << TokenEncodingConsts.typeOffset + TokenModifier
|
||||
*/
|
||||
private getTokenTypeFromClassification;
|
||||
private getTokenModifierFromClassification;
|
||||
}
|
||||
75
node_modules/@astrojs/language-server/dist/plugins/typescript/features/SemanticTokenProvider.js
generated
vendored
Normal file
75
node_modules/@astrojs/language-server/dist/plugins/typescript/features/SemanticTokenProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SemanticTokensProviderImpl = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const documents_1 = require("../../../core/documents");
|
||||
class SemanticTokensProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
}
|
||||
async getSemanticTokens(document, range, cancellationToken) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
if (cancellationToken?.isCancellationRequested) {
|
||||
return null;
|
||||
}
|
||||
const start = range ? tsDoc.offsetAt(tsDoc.getGeneratedPosition(range.start)) : 0;
|
||||
const { spans } = lang.getEncodedSemanticClassifications(tsDoc.filePath, {
|
||||
start,
|
||||
length: range
|
||||
? tsDoc.offsetAt(tsDoc.getGeneratedPosition(range.end)) - start
|
||||
: // We don't want tokens for things added by astro2tsx
|
||||
tsDoc.getFullText().lastIndexOf('export default function ') || tsDoc.getLength(),
|
||||
}, this.ts.SemanticClassificationFormat.TwentyTwenty);
|
||||
const tokens = [];
|
||||
let i = 0;
|
||||
while (i < spans.length) {
|
||||
const offset = spans[i++];
|
||||
const generatedLength = spans[i++];
|
||||
const classification = spans[i++];
|
||||
const originalPosition = this.mapToOrigin(document, tsDoc, offset, generatedLength);
|
||||
if (!originalPosition) {
|
||||
continue;
|
||||
}
|
||||
const [line, character, length] = originalPosition;
|
||||
const classificationType = this.getTokenTypeFromClassification(classification);
|
||||
if (classificationType < 0) {
|
||||
continue;
|
||||
}
|
||||
const modifier = this.getTokenModifierFromClassification(classification);
|
||||
tokens.push([line, character, length, classificationType, modifier]);
|
||||
}
|
||||
const sorted = tokens.sort((a, b) => {
|
||||
const [lineA, charA] = a;
|
||||
const [lineB, charB] = b;
|
||||
return lineA - lineB || charA - charB;
|
||||
});
|
||||
const builder = new vscode_languageserver_1.SemanticTokensBuilder();
|
||||
sorted.forEach((tokenData) => builder.push(...tokenData));
|
||||
const build = builder.build();
|
||||
return build;
|
||||
}
|
||||
mapToOrigin(document, snapshot, generatedOffset, generatedLength) {
|
||||
const range = {
|
||||
start: snapshot.positionAt(generatedOffset),
|
||||
end: snapshot.positionAt(generatedOffset + generatedLength),
|
||||
};
|
||||
const { start: startPosition, end: endPosition } = (0, documents_1.mapRangeToOriginal)(snapshot, range);
|
||||
if (startPosition.line < 0 || endPosition.line < 0) {
|
||||
return;
|
||||
}
|
||||
const startOffset = document.offsetAt(startPosition);
|
||||
const endOffset = document.offsetAt(endPosition);
|
||||
return [startPosition.line, startPosition.character, endOffset - startOffset, startOffset];
|
||||
}
|
||||
/**
|
||||
* TSClassification = (TokenType + 1) << TokenEncodingConsts.typeOffset + TokenModifier
|
||||
*/
|
||||
getTokenTypeFromClassification(tsClassification) {
|
||||
return (tsClassification >> 8 /* TokenEncodingConsts.typeOffset */) - 1;
|
||||
}
|
||||
getTokenModifierFromClassification(tsClassification) {
|
||||
return tsClassification & 255 /* TokenEncodingConsts.modifierMask */;
|
||||
}
|
||||
}
|
||||
exports.SemanticTokensProviderImpl = SemanticTokensProviderImpl;
|
||||
22
node_modules/@astrojs/language-server/dist/plugins/typescript/features/SignatureHelpProvider.d.ts
generated
vendored
Normal file
22
node_modules/@astrojs/language-server/dist/plugins/typescript/features/SignatureHelpProvider.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { CancellationToken, Position, SignatureHelp, SignatureHelpContext } from 'vscode-languageserver';
|
||||
import type { AstroDocument } from '../../../core/documents';
|
||||
import type { SignatureHelpProvider } from '../../interfaces';
|
||||
import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||
export declare class SignatureHelpProviderImpl implements SignatureHelpProvider {
|
||||
private languageServiceManager;
|
||||
private ts;
|
||||
constructor(languageServiceManager: LanguageServiceManager);
|
||||
private static readonly triggerCharacters;
|
||||
private static readonly retriggerCharacters;
|
||||
getSignatureHelp(document: AstroDocument, position: Position, context: SignatureHelpContext | undefined, cancellationToken?: CancellationToken): Promise<SignatureHelp | null>;
|
||||
private isReTrigger;
|
||||
private isTriggerCharacter;
|
||||
/**
|
||||
* adopted from https://github.com/microsoft/vscode/blob/265a2f6424dfbd3a9788652c7d376a7991d049a3/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts#L103
|
||||
*/
|
||||
private toTsTriggerReason;
|
||||
/**
|
||||
* adopted from https://github.com/microsoft/vscode/blob/265a2f6424dfbd3a9788652c7d376a7991d049a3/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts#L73
|
||||
*/
|
||||
private toSignatureHelpInformation;
|
||||
}
|
||||
111
node_modules/@astrojs/language-server/dist/plugins/typescript/features/SignatureHelpProvider.js
generated
vendored
Normal file
111
node_modules/@astrojs/language-server/dist/plugins/typescript/features/SignatureHelpProvider.js
generated
vendored
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SignatureHelpProviderImpl = void 0;
|
||||
const vscode_languageserver_1 = require("vscode-languageserver");
|
||||
const previewer_1 = require("../previewer");
|
||||
const utils_1 = require("../utils");
|
||||
class SignatureHelpProviderImpl {
|
||||
constructor(languageServiceManager) {
|
||||
this.languageServiceManager = languageServiceManager;
|
||||
this.ts = languageServiceManager.docContext.ts;
|
||||
}
|
||||
async getSignatureHelp(document, position, context, cancellationToken) {
|
||||
const { lang, tsDoc } = await this.languageServiceManager.getLSAndTSDoc(document);
|
||||
if (cancellationToken?.isCancellationRequested) {
|
||||
return null;
|
||||
}
|
||||
const offset = tsDoc.offsetAt(tsDoc.getGeneratedPosition(position));
|
||||
const node = document.html.findNodeAt(offset);
|
||||
let info;
|
||||
const triggerReason = this.toTsTriggerReason(context);
|
||||
if (node.tag === 'script') {
|
||||
const { filePath: scriptFilePath, offset: scriptOffset } = (0, utils_1.getScriptTagSnapshot)(tsDoc, document, node, position);
|
||||
info = lang.getSignatureHelpItems(scriptFilePath, scriptOffset, triggerReason ? { triggerReason } : undefined);
|
||||
}
|
||||
else {
|
||||
info = lang.getSignatureHelpItems(tsDoc.filePath, offset, triggerReason ? { triggerReason } : undefined);
|
||||
}
|
||||
if (!info) {
|
||||
return null;
|
||||
}
|
||||
const signatures = info.items.map((item) => this.toSignatureHelpInformation(item, this.ts));
|
||||
return {
|
||||
signatures,
|
||||
activeSignature: info.selectedItemIndex,
|
||||
activeParameter: info.argumentIndex,
|
||||
};
|
||||
}
|
||||
isReTrigger(isRetrigger, triggerCharacter) {
|
||||
return (isRetrigger &&
|
||||
(this.isTriggerCharacter(triggerCharacter) ||
|
||||
SignatureHelpProviderImpl.retriggerCharacters.includes(triggerCharacter)));
|
||||
}
|
||||
isTriggerCharacter(triggerCharacter) {
|
||||
return SignatureHelpProviderImpl.triggerCharacters.includes(triggerCharacter);
|
||||
}
|
||||
/**
|
||||
* adopted from https://github.com/microsoft/vscode/blob/265a2f6424dfbd3a9788652c7d376a7991d049a3/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts#L103
|
||||
*/
|
||||
toTsTriggerReason(context) {
|
||||
switch (context?.triggerKind) {
|
||||
case vscode_languageserver_1.SignatureHelpTriggerKind.TriggerCharacter:
|
||||
if (context.triggerCharacter) {
|
||||
if (this.isReTrigger(context.isRetrigger, context.triggerCharacter)) {
|
||||
return { kind: 'retrigger', triggerCharacter: context.triggerCharacter };
|
||||
}
|
||||
if (this.isTriggerCharacter(context.triggerCharacter)) {
|
||||
return {
|
||||
kind: 'characterTyped',
|
||||
triggerCharacter: context.triggerCharacter,
|
||||
};
|
||||
}
|
||||
}
|
||||
return { kind: 'invoked' };
|
||||
case vscode_languageserver_1.SignatureHelpTriggerKind.ContentChange:
|
||||
return context.isRetrigger ? { kind: 'retrigger' } : { kind: 'invoked' };
|
||||
case vscode_languageserver_1.SignatureHelpTriggerKind.Invoked:
|
||||
default:
|
||||
return { kind: 'invoked' };
|
||||
}
|
||||
}
|
||||
/**
|
||||
* adopted from https://github.com/microsoft/vscode/blob/265a2f6424dfbd3a9788652c7d376a7991d049a3/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts#L73
|
||||
*/
|
||||
toSignatureHelpInformation(item, ts) {
|
||||
const [prefixLabel, separatorLabel, suffixLabel] = [
|
||||
item.prefixDisplayParts,
|
||||
item.separatorDisplayParts,
|
||||
item.suffixDisplayParts,
|
||||
].map(this.ts.displayPartsToString);
|
||||
let textIndex = prefixLabel.length;
|
||||
let signatureLabel = '';
|
||||
const parameters = [];
|
||||
const lastIndex = item.parameters.length - 1;
|
||||
item.parameters.forEach((parameter, index) => {
|
||||
const label = ts.displayPartsToString(parameter.displayParts);
|
||||
const startIndex = textIndex;
|
||||
const endIndex = textIndex + label.length;
|
||||
const doc = ts.displayPartsToString(parameter.documentation);
|
||||
signatureLabel += label;
|
||||
parameters.push(vscode_languageserver_1.ParameterInformation.create([startIndex, endIndex], doc));
|
||||
if (index < lastIndex) {
|
||||
textIndex = endIndex + separatorLabel.length;
|
||||
signatureLabel += separatorLabel;
|
||||
}
|
||||
});
|
||||
const signatureDocumentation = (0, previewer_1.getMarkdownDocumentation)(item.documentation, item.tags.filter((tag) => tag.name !== 'param'), ts);
|
||||
return {
|
||||
label: prefixLabel + signatureLabel + suffixLabel,
|
||||
documentation: signatureDocumentation
|
||||
? {
|
||||
value: signatureDocumentation,
|
||||
kind: vscode_languageserver_1.MarkupKind.Markdown,
|
||||
}
|
||||
: undefined,
|
||||
parameters,
|
||||
};
|
||||
}
|
||||
}
|
||||
SignatureHelpProviderImpl.triggerCharacters = ['(', ',', '<'];
|
||||
SignatureHelpProviderImpl.retriggerCharacters = [')'];
|
||||
exports.SignatureHelpProviderImpl = SignatureHelpProviderImpl;
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue