🎉 initiate project *astro_rewrite*
This commit is contained in:
parent
ffd4d5e86c
commit
2ba37bfbe3
8658 changed files with 2268794 additions and 2538 deletions
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;
|
||||
Loading…
Add table
Add a link
Reference in a new issue