summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar matthewp <matthewp@users.noreply.github.com> 2021-08-10 13:31:09 +0000
committerGravatar GitHub Actions <actions@github.com> 2021-08-10 13:31:09 +0000
commit16790aee7b10db30e556679d30bba3d40094a124 (patch)
treed5edc58f0c7210503503690ee8dbbc364c7eccb4
parent2c5380a26631f720bfbbcec78295c71b562e647d (diff)
downloadastro-16790aee7b10db30e556679d30bba3d40094a124.tar.gz
astro-16790aee7b10db30e556679d30bba3d40094a124.tar.zst
astro-16790aee7b10db30e556679d30bba3d40094a124.zip
[ci] yarn format
-rw-r--r--tools/language-server/astro.d.ts2
-rw-r--r--tools/language-server/src/index.ts4
-rw-r--r--tools/language-server/src/plugins/PluginHost.ts30
-rw-r--r--tools/language-server/src/plugins/typescript/DocumentSnapshot.ts18
-rw-r--r--tools/language-server/src/plugins/typescript/TypeScriptPlugin.ts21
-rw-r--r--tools/language-server/src/plugins/typescript/features/CompletionsProvider.ts3
-rw-r--r--tools/language-server/src/plugins/typescript/features/HoverProvider.ts50
-rw-r--r--tools/language-server/src/plugins/typescript/features/SignatureHelpProvider.ts247
-rw-r--r--tools/language-server/src/plugins/typescript/previewer.ts247
-rw-r--r--tools/language-server/src/plugins/typescript/utils.ts2
10 files changed, 282 insertions, 342 deletions
diff --git a/tools/language-server/astro.d.ts b/tools/language-server/astro.d.ts
index 267f6f108..3c35bf911 100644
--- a/tools/language-server/astro.d.ts
+++ b/tools/language-server/astro.d.ts
@@ -24,4 +24,4 @@ interface Astro {
declare const Astro: Astro;
-export default function(): string; \ No newline at end of file
+export default function (): string;
diff --git a/tools/language-server/src/index.ts b/tools/language-server/src/index.ts
index 1ca7172c8..5f741d1f7 100644
--- a/tools/language-server/src/index.ts
+++ b/tools/language-server/src/index.ts
@@ -67,8 +67,8 @@ export function startServer() {
hoverProvider: true,
signatureHelpProvider: {
triggerCharacters: ['(', ',', '<'],
- retriggerCharacters: [')']
- }
+ retriggerCharacters: [')'],
+ },
},
};
});
diff --git a/tools/language-server/src/plugins/PluginHost.ts b/tools/language-server/src/plugins/PluginHost.ts
index f3e50e4d0..3ad21a21c 100644
--- a/tools/language-server/src/plugins/PluginHost.ts
+++ b/tools/language-server/src/plugins/PluginHost.ts
@@ -7,7 +7,7 @@ import type {
Position,
SignatureHelp,
SignatureHelpContext,
- TextDocumentIdentifier
+ TextDocumentIdentifier,
} from 'vscode-languageserver';
import type { DocumentManager } from '../core/documents';
import type * as d from './interfaces';
@@ -74,7 +74,7 @@ export class PluginHost {
async doHover(textDocument: TextDocumentIdentifier, position: Position): Promise<Hover | null> {
const document = this.getDocument(textDocument.uri);
if (!document) {
- throw new Error('Cannot call methods on an unopened document');
+ throw new Error('Cannot call methods on an unopened document');
}
return this.execute<Hover>('doHover', [document, position], ExecuteMode.FirstNonNull);
@@ -121,16 +121,12 @@ export class PluginHost {
context: SignatureHelpContext | undefined,
cancellationToken: CancellationToken
): Promise<SignatureHelp | null> {
- const document = this.getDocument(textDocument.uri);
- if (!document) {
- throw new Error('Cannot call methods on an unopened document');
- }
-
- return await this.execute<any>(
- 'getSignatureHelp',
- [document, position, context, cancellationToken],
- ExecuteMode.FirstNonNull
- );
+ const document = this.getDocument(textDocument.uri);
+ if (!document) {
+ throw new Error('Cannot call methods on an unopened document');
+ }
+
+ return await this.execute<any>('getSignatureHelp', [document, position, context, cancellationToken], ExecuteMode.FirstNonNull);
}
onWatchFileChanges(onWatchFileChangesParams: any[]): void {
@@ -159,10 +155,12 @@ export class PluginHost {
}
return null;
case ExecuteMode.Collect:
- return Promise.all(plugins.map((plugin) => {
- let ret = this.tryExecutePlugin(plugin, name, args, []);
- return ret;
- }));
+ return Promise.all(
+ plugins.map((plugin) => {
+ let ret = this.tryExecutePlugin(plugin, name, args, []);
+ return ret;
+ })
+ );
case ExecuteMode.None:
await Promise.all(plugins.map((plugin) => this.tryExecutePlugin(plugin, name, args, null)));
return;
diff --git a/tools/language-server/src/plugins/typescript/DocumentSnapshot.ts b/tools/language-server/src/plugins/typescript/DocumentSnapshot.ts
index d7473c7b3..89f8c400e 100644
--- a/tools/language-server/src/plugins/typescript/DocumentSnapshot.ts
+++ b/tools/language-server/src/plugins/typescript/DocumentSnapshot.ts
@@ -6,7 +6,7 @@ import { isInTag, positionAt, offsetAt } from '../../core/documents/utils';
import { pathToUrl } from '../../utils';
import { getScriptKindFromFileName, isAstroFilePath, toVirtualAstroFilePath } from './utils';
-const ASTRO_DEFINITION = readFileSync(require.resolve('../../../astro.d.ts'));
+const ASTRO_DEFINITION = readFileSync(require.resolve('../../../astro.d.ts'));
/**
* The mapper to get from original snapshot positions to generated and vice versa.
@@ -75,9 +75,11 @@ class AstroDocumentSnapshot implements DocumentSnapshot {
/** @internal */
private transformContent(content: string) {
- return content.replace(/---/g, '///') +
- // Add TypeScript definitions
- ASTRO_DEFINITION;
+ return (
+ content.replace(/---/g, '///') +
+ // Add TypeScript definitions
+ ASTRO_DEFINITION
+ );
}
get filePath() {
@@ -139,9 +141,11 @@ export class DocumentFragmentSnapshot implements Omit<DocumentSnapshot, 'getFrag
/** @internal */
private transformContent(content: string) {
- return content.replace(/---/g, '///') +
- // Add TypeScript definitions
- ASTRO_DEFINITION;
+ return (
+ content.replace(/---/g, '///') +
+ // Add TypeScript definitions
+ ASTRO_DEFINITION
+ );
}
getText(start: number, end: number) {
diff --git a/tools/language-server/src/plugins/typescript/TypeScriptPlugin.ts b/tools/language-server/src/plugins/typescript/TypeScriptPlugin.ts
index e953452d3..db5e701b4 100644
--- a/tools/language-server/src/plugins/typescript/TypeScriptPlugin.ts
+++ b/tools/language-server/src/plugins/typescript/TypeScriptPlugin.ts
@@ -1,11 +1,6 @@
import type { ConfigManager } from '../../core/config';
import type { CompletionsProvider, AppCompletionItem, AppCompletionList } from '../interfaces';
-import type {
- CancellationToken,
- Hover,
- SignatureHelp,
- SignatureHelpContext
-} from 'vscode-languageserver';
+import type { CancellationToken, Hover, SignatureHelp, SignatureHelpContext } from 'vscode-languageserver';
import { join as pathJoin, dirname as pathDirname } from 'path';
import { Document, DocumentManager, isInsideFrontmatter } from '../../core/documents';
import { SourceFile, ImportDeclaration, Node, SyntaxKind } from 'typescript';
@@ -134,18 +129,8 @@ export class TypeScriptPlugin implements CompletionsProvider {
}
}
- async getSignatureHelp(
- document: Document,
- position: Position,
- context: SignatureHelpContext | undefined,
- cancellationToken?: CancellationToken
- ): Promise<SignatureHelp | null> {
- return this.signatureHelpProvider.getSignatureHelp(
- document,
- position,
- context,
- cancellationToken
- );
+ async getSignatureHelp(document: Document, position: Position, context: SignatureHelpContext | undefined, cancellationToken?: CancellationToken): Promise<SignatureHelp | null> {
+ return this.signatureHelpProvider.getSignatureHelp(document, position, context, cancellationToken);
}
/**
diff --git a/tools/language-server/src/plugins/typescript/features/CompletionsProvider.ts b/tools/language-server/src/plugins/typescript/features/CompletionsProvider.ts
index daeed9766..da4a5cd54 100644
--- a/tools/language-server/src/plugins/typescript/features/CompletionsProvider.ts
+++ b/tools/language-server/src/plugins/typescript/features/CompletionsProvider.ts
@@ -34,8 +34,7 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionEn
const offset = document.offsetAt(position);
- const entries =
- lang.getCompletionsAtPosition(fragment.filePath, offset, completionOptions)?.entries || [];
+ const entries = lang.getCompletionsAtPosition(fragment.filePath, offset, completionOptions)?.entries || [];
const completionItems = entries
.map((entry: ts.CompletionEntry) => this.toCompletionItem(fragment, entry, document.uri, position, new Set()))
diff --git a/tools/language-server/src/plugins/typescript/features/HoverProvider.ts b/tools/language-server/src/plugins/typescript/features/HoverProvider.ts
index 2757ed4cd..f772bc390 100644
--- a/tools/language-server/src/plugins/typescript/features/HoverProvider.ts
+++ b/tools/language-server/src/plugins/typescript/features/HoverProvider.ts
@@ -7,36 +7,34 @@ import { getMarkdownDocumentation } from '../previewer';
import { convertRange, toVirtualAstroFilePath } from '../utils';
export class HoverProviderImpl implements HoverProvider {
- constructor(private readonly lang: LanguageServiceManager) {}
+ constructor(private readonly lang: LanguageServiceManager) {}
- async doHover(document: Document, position: Position): Promise<Hover | null> {
- const { lang, tsDoc } = await this.getLSAndTSDoc(document);
- const fragment = await tsDoc.getFragment();
+ async doHover(document: Document, position: Position): Promise<Hover | null> {
+ const { lang, tsDoc } = await this.getLSAndTSDoc(document);
+ const fragment = await tsDoc.getFragment();
- const offset = fragment.offsetAt(fragment.getGeneratedPosition(position));
- const filePath = toVirtualAstroFilePath(tsDoc.filePath);
- let info = lang.getQuickInfoAtPosition(filePath, offset);
- if (!info) {
- return null;
- }
+ const offset = fragment.offsetAt(fragment.getGeneratedPosition(position));
+ const filePath = toVirtualAstroFilePath(tsDoc.filePath);
+ let info = lang.getQuickInfoAtPosition(filePath, offset);
+ if (!info) {
+ return null;
+ }
- const textSpan = info.textSpan;
+ const textSpan = info.textSpan;
- const declaration = ts.displayPartsToString(info.displayParts);
- const documentation = getMarkdownDocumentation(info.documentation, info.tags);
+ const declaration = ts.displayPartsToString(info.displayParts);
+ const documentation = getMarkdownDocumentation(info.documentation, info.tags);
- // https://microsoft.github.io/language-server-protocol/specification#textDocument_hover
- const contents = ['```typescript', declaration, '```']
- .concat(documentation ? ['---', documentation] : [])
- .join('\n');
+ // https://microsoft.github.io/language-server-protocol/specification#textDocument_hover
+ const contents = ['```typescript', declaration, '```'].concat(documentation ? ['---', documentation] : []).join('\n');
- return mapObjWithRangeToOriginal(fragment, {
- range: convertRange(fragment, textSpan),
- contents
- });
- }
+ return mapObjWithRangeToOriginal(fragment, {
+ range: convertRange(fragment, textSpan),
+ contents,
+ });
+ }
- private async getLSAndTSDoc(document: Document) {
- return this.lang.getTypeScriptDoc(document);
- }
-} \ No newline at end of file
+ private async getLSAndTSDoc(document: Document) {
+ return this.lang.getTypeScriptDoc(document);
+ }
+}
diff --git a/tools/language-server/src/plugins/typescript/features/SignatureHelpProvider.ts b/tools/language-server/src/plugins/typescript/features/SignatureHelpProvider.ts
index 1be286246..93bad724f 100644
--- a/tools/language-server/src/plugins/typescript/features/SignatureHelpProvider.ts
+++ b/tools/language-server/src/plugins/typescript/features/SignatureHelpProvider.ts
@@ -2,157 +2,128 @@ import type { LanguageServiceManager } from '../LanguageServiceManager';
import type { SignatureHelpProvider } from '../../interfaces';
import ts from 'typescript';
import {
- Position,
- SignatureHelpContext,
- SignatureHelp,
- SignatureHelpTriggerKind,
- SignatureInformation,
- ParameterInformation,
- MarkupKind,
- CancellationToken
+ Position,
+ SignatureHelpContext,
+ SignatureHelp,
+ SignatureHelpTriggerKind,
+ SignatureInformation,
+ ParameterInformation,
+ MarkupKind,
+ CancellationToken,
} from 'vscode-languageserver';
import { Document } from '../../../core/documents';
import { getMarkdownDocumentation } from '../previewer';
import { toVirtualAstroFilePath } from '../utils';
export class SignatureHelpProviderImpl implements SignatureHelpProvider {
- constructor(private readonly lang: LanguageServiceManager) {}
-
- private static readonly triggerCharacters = ['(', ',', '<'];
- private static readonly retriggerCharacters = [')'];
-
- async getSignatureHelp(
- document: Document,
- position: Position,
- context: SignatureHelpContext | undefined,
- cancellationToken?: CancellationToken
- ): Promise<SignatureHelp | null> {
- const { lang, tsDoc } = await this.lang.getTypeScriptDoc(document);
- const fragment = await tsDoc.getFragment();
-
- if (cancellationToken?.isCancellationRequested) {
- return null;
- }
-
- const offset = fragment.offsetAt(fragment.getGeneratedPosition(position));
- const triggerReason = this.toTsTriggerReason(context);
- const info = lang.getSignatureHelpItems(
- toVirtualAstroFilePath(tsDoc.filePath),
- offset,
- triggerReason ? { triggerReason } : undefined
- );
- if (
- !info ||
- info.items.some((signature) => this.isInSvelte2tsxGeneratedFunction(signature))
- ) {
- return null;
- }
+ constructor(private readonly lang: LanguageServiceManager) {}
- const signatures = info.items.map(this.toSignatureHelpInformation);
+ private static readonly triggerCharacters = ['(', ',', '<'];
+ private static readonly retriggerCharacters = [')'];
- return {
- signatures,
- activeSignature: info.selectedItemIndex,
- activeParameter: info.argumentIndex
- };
- }
+ async getSignatureHelp(document: Document, position: Position, context: SignatureHelpContext | undefined, cancellationToken?: CancellationToken): Promise<SignatureHelp | null> {
+ const { lang, tsDoc } = await this.lang.getTypeScriptDoc(document);
+ const fragment = await tsDoc.getFragment();
- private isReTrigger(
- isRetrigger: boolean,
- triggerCharacter: string
- ): triggerCharacter is ts.SignatureHelpRetriggerCharacter {
- return (
- isRetrigger &&
- (this.isTriggerCharacter(triggerCharacter) ||
- SignatureHelpProviderImpl.retriggerCharacters.includes(triggerCharacter))
- );
+ if (cancellationToken?.isCancellationRequested) {
+ return null;
}
- private isTriggerCharacter(
- triggerCharacter: string
- ): triggerCharacter is ts.SignatureHelpTriggerCharacter {
- return SignatureHelpProviderImpl.triggerCharacters.includes(triggerCharacter);
+ const offset = fragment.offsetAt(fragment.getGeneratedPosition(position));
+ const triggerReason = this.toTsTriggerReason(context);
+ const info = lang.getSignatureHelpItems(toVirtualAstroFilePath(tsDoc.filePath), offset, triggerReason ? { triggerReason } : undefined);
+ if (!info || info.items.some((signature) => this.isInSvelte2tsxGeneratedFunction(signature))) {
+ return null;
}
- /**
- * adopted from https://github.com/microsoft/vscode/blob/265a2f6424dfbd3a9788652c7d376a7991d049a3/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts#L103
- */
- private toTsTriggerReason(
- context: SignatureHelpContext | undefined
- ): ts.SignatureHelpTriggerReason {
- switch (context?.triggerKind) {
- case 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 SignatureHelpTriggerKind.ContentChange:
- return context.isRetrigger ? { kind: 'retrigger' } : { kind: 'invoked' };
-
- case SignatureHelpTriggerKind.Invoked:
- default:
- return { kind: 'invoked' };
+ const signatures = info.items.map(this.toSignatureHelpInformation);
+
+ return {
+ signatures,
+ activeSignature: info.selectedItemIndex,
+ activeParameter: info.argumentIndex,
+ };
+ }
+
+ private isReTrigger(isRetrigger: boolean, triggerCharacter: string): triggerCharacter is ts.SignatureHelpRetriggerCharacter {
+ return isRetrigger && (this.isTriggerCharacter(triggerCharacter) || SignatureHelpProviderImpl.retriggerCharacters.includes(triggerCharacter));
+ }
+
+ private isTriggerCharacter(triggerCharacter: string): triggerCharacter is ts.SignatureHelpTriggerCharacter {
+ return SignatureHelpProviderImpl.triggerCharacters.includes(triggerCharacter);
+ }
+
+ /**
+ * adopted from https://github.com/microsoft/vscode/blob/265a2f6424dfbd3a9788652c7d376a7991d049a3/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts#L103
+ */
+ private toTsTriggerReason(context: SignatureHelpContext | undefined): ts.SignatureHelpTriggerReason {
+ switch (context?.triggerKind) {
+ case 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,
+ };
+ }
}
- }
-
- /**
- * adopted from https://github.com/microsoft/vscode/blob/265a2f6424dfbd3a9788652c7d376a7991d049a3/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts#L73
- */
- private toSignatureHelpInformation(item: ts.SignatureHelpItem): SignatureInformation {
- const [prefixLabel, separatorLabel, suffixLabel] = [
- item.prefixDisplayParts,
- item.separatorDisplayParts,
- item.suffixDisplayParts
- ].map(ts.displayPartsToString);
-
- let textIndex = prefixLabel.length;
- let signatureLabel = '';
- const parameters: ParameterInformation[] = [];
- 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(ParameterInformation.create([startIndex, endIndex], doc));
-
- if (index < lastIndex) {
- textIndex = endIndex + separatorLabel.length;
- signatureLabel += separatorLabel;
- }
- });
- const signatureDocumentation = getMarkdownDocumentation(
- item.documentation,
- item.tags.filter((tag) => tag.name !== 'param')
- );
-
- return {
- label: prefixLabel + signatureLabel + suffixLabel,
- documentation: signatureDocumentation
- ? {
- value: signatureDocumentation,
- kind: MarkupKind.Markdown
- }
- : undefined,
- parameters
- };
- }
+ return { kind: 'invoked' };
+ case SignatureHelpTriggerKind.ContentChange:
+ return context.isRetrigger ? { kind: 'retrigger' } : { kind: 'invoked' };
- private isInSvelte2tsxGeneratedFunction(signatureHelpItem: ts.SignatureHelpItem) {
- return signatureHelpItem.prefixDisplayParts.some((part) =>
- part.text.includes('__sveltets')
- );
+ case SignatureHelpTriggerKind.Invoked:
+ default:
+ return { kind: 'invoked' };
}
-} \ No newline at end of file
+ }
+
+ /**
+ * adopted from https://github.com/microsoft/vscode/blob/265a2f6424dfbd3a9788652c7d376a7991d049a3/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts#L73
+ */
+ private toSignatureHelpInformation(item: ts.SignatureHelpItem): SignatureInformation {
+ const [prefixLabel, separatorLabel, suffixLabel] = [item.prefixDisplayParts, item.separatorDisplayParts, item.suffixDisplayParts].map(ts.displayPartsToString);
+
+ let textIndex = prefixLabel.length;
+ let signatureLabel = '';
+ const parameters: ParameterInformation[] = [];
+ 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(ParameterInformation.create([startIndex, endIndex], doc));
+
+ if (index < lastIndex) {
+ textIndex = endIndex + separatorLabel.length;
+ signatureLabel += separatorLabel;
+ }
+ });
+ const signatureDocumentation = getMarkdownDocumentation(
+ item.documentation,
+ item.tags.filter((tag) => tag.name !== 'param')
+ );
+
+ return {
+ label: prefixLabel + signatureLabel + suffixLabel,
+ documentation: signatureDocumentation
+ ? {
+ value: signatureDocumentation,
+ kind: MarkupKind.Markdown,
+ }
+ : undefined,
+ parameters,
+ };
+ }
+
+ private isInSvelte2tsxGeneratedFunction(signatureHelpItem: ts.SignatureHelpItem) {
+ return signatureHelpItem.prefixDisplayParts.some((part) => part.text.includes('__sveltets'));
+ }
+}
diff --git a/tools/language-server/src/plugins/typescript/previewer.ts b/tools/language-server/src/plugins/typescript/previewer.ts
index deedae1e8..710da4c17 100644
--- a/tools/language-server/src/plugins/typescript/previewer.ts
+++ b/tools/language-server/src/plugins/typescript/previewer.ts
@@ -7,134 +7,119 @@
* adopted from https://github.com/microsoft/vscode/blob/10722887b8629f90cc38ee7d90d54e8246dc895f/extensions/typescript-language-features/src/utils/previewer.ts
*/
- import ts from 'typescript';
- import { isNotNullOrUndefined } from '../../utils';
-
- function replaceLinks(text: string): string {
- return (
- text
- // Http(s) links
- .replace(
- /\{@(link|linkplain|linkcode) (https?:\/\/[^ |}]+?)(?:[| ]([^{}\n]+?))?\}/gi,
- (_, tag: string, link: string, text?: string) => {
- switch (tag) {
- case 'linkcode':
- return `[\`${text ? text.trim() : link}\`](${link})`;
-
- default:
- return `[${text ? text.trim() : link}](${link})`;
- }
- }
- )
- );
- }
-
- function processInlineTags(text: string): string {
- return replaceLinks(text);
- }
-
- function getTagBodyText(tag: ts.JSDocTagInfo): string | undefined {
- if (!tag.text) {
- return undefined;
- }
-
- // Convert to markdown code block if it is not already one
- function makeCodeblock(text: string): string {
- if (text.match(/^\s*[~`]{3}/g)) {
- return text;
- }
- return '```\n' + text + '\n```';
- }
-
- function makeExampleTag(text: string) {
- // check for caption tags, fix for https://github.com/microsoft/vscode/issues/79704
- const captionTagMatches = text.match(/<caption>(.*?)<\/caption>\s*(\r\n|\n)/);
- if (captionTagMatches && captionTagMatches.index === 0) {
- return (
- captionTagMatches[1] +
- '\n\n' +
- makeCodeblock(text.substr(captionTagMatches[0].length))
- );
- } else {
- return makeCodeblock(text);
- }
- }
-
- function makeEmailTag(text: string) {
- // fix obsucated email address, https://github.com/microsoft/vscode/issues/80898
- const emailMatch = text.match(/(.+)\s<([-.\w]+@[-.\w]+)>/);
-
- if (emailMatch === null) {
- return text;
- } else {
- return `${emailMatch[1]} ${emailMatch[2]}`;
- }
- }
-
- switch (tag.name) {
- case 'example':
- return makeExampleTag(ts.displayPartsToString(tag.text));
- case 'author':
- return makeEmailTag(ts.displayPartsToString(tag.text));
- case 'default':
- return makeCodeblock(ts.displayPartsToString(tag.text));
- }
-
- return processInlineTags(ts.displayPartsToString(tag.text));
- }
-
- export function getTagDocumentation(tag: ts.JSDocTagInfo): string | undefined {
- function getWithType() {
- const body = (ts.displayPartsToString(tag.text) || '').split(/^(\S+)\s*-?\s*/);
- if (body?.length === 3) {
- const param = body[1];
- const doc = body[2];
- const label = `*@${tag.name}* \`${param}\``;
- if (!doc) {
- return label;
- }
- return (
- label +
- (doc.match(/\r\n|\n/g)
- ? ' \n' + processInlineTags(doc)
- : ` — ${processInlineTags(doc)}`)
- );
- }
- }
-
- switch (tag.name) {
- case 'augments':
- case 'extends':
- case 'param':
- case 'template':
- return getWithType();
- }
-
- // Generic tag
- const label = `*@${tag.name}*`;
- const text = getTagBodyText(tag);
- if (!text) {
- return label;
- }
- return label + (text.match(/\r\n|\n/g) ? ' \n' + text : ` — ${text}`);
- }
-
- export function plain(parts: ts.SymbolDisplayPart[] | string): string {
- return processInlineTags(typeof parts === 'string' ? parts : ts.displayPartsToString(parts));
- }
-
- export function getMarkdownDocumentation(
- documentation: ts.SymbolDisplayPart[] | undefined,
- tags: ts.JSDocTagInfo[] | undefined
- ) {
- let result: Array<string | undefined> = [];
- if (documentation) {
- result.push(plain(documentation));
- }
-
- if (tags) {
- result = result.concat(tags.map(getTagDocumentation));
- }
-
- return result.filter(isNotNullOrUndefined).join('\n\n');
- } \ No newline at end of file
+import ts from 'typescript';
+import { isNotNullOrUndefined } from '../../utils';
+
+function replaceLinks(text: string): string {
+ return (
+ text
+ // Http(s) links
+ .replace(/\{@(link|linkplain|linkcode) (https?:\/\/[^ |}]+?)(?:[| ]([^{}\n]+?))?\}/gi, (_, tag: string, link: string, text?: string) => {
+ switch (tag) {
+ case 'linkcode':
+ return `[\`${text ? text.trim() : link}\`](${link})`;
+
+ default:
+ return `[${text ? text.trim() : link}](${link})`;
+ }
+ })
+ );
+}
+
+function processInlineTags(text: string): string {
+ return replaceLinks(text);
+}
+
+function getTagBodyText(tag: ts.JSDocTagInfo): string | undefined {
+ if (!tag.text) {
+ return undefined;
+ }
+
+ // Convert to markdown code block if it is not already one
+ function makeCodeblock(text: string): string {
+ if (text.match(/^\s*[~`]{3}/g)) {
+ return text;
+ }
+ return '```\n' + text + '\n```';
+ }
+
+ function makeExampleTag(text: string) {
+ // check for caption tags, fix for https://github.com/microsoft/vscode/issues/79704
+ const captionTagMatches = text.match(/<caption>(.*?)<\/caption>\s*(\r\n|\n)/);
+ if (captionTagMatches && captionTagMatches.index === 0) {
+ return captionTagMatches[1] + '\n\n' + makeCodeblock(text.substr(captionTagMatches[0].length));
+ } else {
+ return makeCodeblock(text);
+ }
+ }
+
+ function makeEmailTag(text: string) {
+ // fix obsucated email address, https://github.com/microsoft/vscode/issues/80898
+ const emailMatch = text.match(/(.+)\s<([-.\w]+@[-.\w]+)>/);
+
+ if (emailMatch === null) {
+ return text;
+ } else {
+ return `${emailMatch[1]} ${emailMatch[2]}`;
+ }
+ }
+
+ switch (tag.name) {
+ case 'example':
+ return makeExampleTag(ts.displayPartsToString(tag.text));
+ case 'author':
+ return makeEmailTag(ts.displayPartsToString(tag.text));
+ case 'default':
+ return makeCodeblock(ts.displayPartsToString(tag.text));
+ }
+
+ return processInlineTags(ts.displayPartsToString(tag.text));
+}
+
+export function getTagDocumentation(tag: ts.JSDocTagInfo): string | undefined {
+ function getWithType() {
+ const body = (ts.displayPartsToString(tag.text) || '').split(/^(\S+)\s*-?\s*/);
+ if (body?.length === 3) {
+ const param = body[1];
+ const doc = body[2];
+ const label = `*@${tag.name}* \`${param}\``;
+ if (!doc) {
+ return label;
+ }
+ return label + (doc.match(/\r\n|\n/g) ? ' \n' + processInlineTags(doc) : ` — ${processInlineTags(doc)}`);
+ }
+ }
+
+ switch (tag.name) {
+ case 'augments':
+ case 'extends':
+ case 'param':
+ case 'template':
+ return getWithType();
+ }
+
+ // Generic tag
+ const label = `*@${tag.name}*`;
+ const text = getTagBodyText(tag);
+ if (!text) {
+ return label;
+ }
+ return label + (text.match(/\r\n|\n/g) ? ' \n' + text : ` — ${text}`);
+}
+
+export function plain(parts: ts.SymbolDisplayPart[] | string): string {
+ return processInlineTags(typeof parts === 'string' ? parts : ts.displayPartsToString(parts));
+}
+
+export function getMarkdownDocumentation(documentation: ts.SymbolDisplayPart[] | undefined, tags: ts.JSDocTagInfo[] | undefined) {
+ let result: Array<string | undefined> = [];
+ if (documentation) {
+ result.push(plain(documentation));
+ }
+
+ if (tags) {
+ result = result.concat(tags.map(getTagDocumentation));
+ }
+
+ return result.filter(isNotNullOrUndefined).join('\n\n');
+}
diff --git a/tools/language-server/src/plugins/typescript/utils.ts b/tools/language-server/src/plugins/typescript/utils.ts
index 4b767c8e1..a1a748946 100644
--- a/tools/language-server/src/plugins/typescript/utils.ts
+++ b/tools/language-server/src/plugins/typescript/utils.ts
@@ -178,7 +178,7 @@ export function isVirtualFilePath(filePath: string) {
}
export function toVirtualAstroFilePath(filePath: string) {
- if(isVirtualFrameworkFilePath('astro', filePath)) {
+ if (isVirtualFrameworkFilePath('astro', filePath)) {
return filePath;
}
return `${filePath}.ts`;