[ci] yarn format
This commit is contained in:
parent
2c5380a266
commit
16790aee7b
10 changed files with 280 additions and 340 deletions
2
tools/language-server/astro.d.ts
vendored
2
tools/language-server/astro.d.ts
vendored
|
@ -24,4 +24,4 @@ interface Astro {
|
||||||
|
|
||||||
declare const Astro: Astro;
|
declare const Astro: Astro;
|
||||||
|
|
||||||
export default function(): string;
|
export default function (): string;
|
||||||
|
|
|
@ -67,8 +67,8 @@ export function startServer() {
|
||||||
hoverProvider: true,
|
hoverProvider: true,
|
||||||
signatureHelpProvider: {
|
signatureHelpProvider: {
|
||||||
triggerCharacters: ['(', ',', '<'],
|
triggerCharacters: ['(', ',', '<'],
|
||||||
retriggerCharacters: [')']
|
retriggerCharacters: [')'],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,7 +7,7 @@ import type {
|
||||||
Position,
|
Position,
|
||||||
SignatureHelp,
|
SignatureHelp,
|
||||||
SignatureHelpContext,
|
SignatureHelpContext,
|
||||||
TextDocumentIdentifier
|
TextDocumentIdentifier,
|
||||||
} from 'vscode-languageserver';
|
} from 'vscode-languageserver';
|
||||||
import type { DocumentManager } from '../core/documents';
|
import type { DocumentManager } from '../core/documents';
|
||||||
import type * as d from './interfaces';
|
import type * as d from './interfaces';
|
||||||
|
@ -74,7 +74,7 @@ export class PluginHost {
|
||||||
async doHover(textDocument: TextDocumentIdentifier, position: Position): Promise<Hover | null> {
|
async doHover(textDocument: TextDocumentIdentifier, position: Position): Promise<Hover | null> {
|
||||||
const document = this.getDocument(textDocument.uri);
|
const document = this.getDocument(textDocument.uri);
|
||||||
if (!document) {
|
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);
|
return this.execute<Hover>('doHover', [document, position], ExecuteMode.FirstNonNull);
|
||||||
|
@ -121,16 +121,12 @@ export class PluginHost {
|
||||||
context: SignatureHelpContext | undefined,
|
context: SignatureHelpContext | undefined,
|
||||||
cancellationToken: CancellationToken
|
cancellationToken: CancellationToken
|
||||||
): Promise<SignatureHelp | null> {
|
): Promise<SignatureHelp | null> {
|
||||||
const document = this.getDocument(textDocument.uri);
|
const document = this.getDocument(textDocument.uri);
|
||||||
if (!document) {
|
if (!document) {
|
||||||
throw new Error('Cannot call methods on an unopened document');
|
throw new Error('Cannot call methods on an unopened document');
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this.execute<any>(
|
return await this.execute<any>('getSignatureHelp', [document, position, context, cancellationToken], ExecuteMode.FirstNonNull);
|
||||||
'getSignatureHelp',
|
|
||||||
[document, position, context, cancellationToken],
|
|
||||||
ExecuteMode.FirstNonNull
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onWatchFileChanges(onWatchFileChangesParams: any[]): void {
|
onWatchFileChanges(onWatchFileChangesParams: any[]): void {
|
||||||
|
@ -159,10 +155,12 @@ export class PluginHost {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
case ExecuteMode.Collect:
|
case ExecuteMode.Collect:
|
||||||
return Promise.all(plugins.map((plugin) => {
|
return Promise.all(
|
||||||
let ret = this.tryExecutePlugin(plugin, name, args, []);
|
plugins.map((plugin) => {
|
||||||
return ret;
|
let ret = this.tryExecutePlugin(plugin, name, args, []);
|
||||||
}));
|
return ret;
|
||||||
|
})
|
||||||
|
);
|
||||||
case ExecuteMode.None:
|
case ExecuteMode.None:
|
||||||
await Promise.all(plugins.map((plugin) => this.tryExecutePlugin(plugin, name, args, null)));
|
await Promise.all(plugins.map((plugin) => this.tryExecutePlugin(plugin, name, args, null)));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { isInTag, positionAt, offsetAt } from '../../core/documents/utils';
|
||||||
import { pathToUrl } from '../../utils';
|
import { pathToUrl } from '../../utils';
|
||||||
import { getScriptKindFromFileName, isAstroFilePath, toVirtualAstroFilePath } 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.
|
* The mapper to get from original snapshot positions to generated and vice versa.
|
||||||
|
@ -75,9 +75,11 @@ class AstroDocumentSnapshot implements DocumentSnapshot {
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
private transformContent(content: string) {
|
private transformContent(content: string) {
|
||||||
return content.replace(/---/g, '///') +
|
return (
|
||||||
// Add TypeScript definitions
|
content.replace(/---/g, '///') +
|
||||||
ASTRO_DEFINITION;
|
// Add TypeScript definitions
|
||||||
|
ASTRO_DEFINITION
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get filePath() {
|
get filePath() {
|
||||||
|
@ -139,9 +141,11 @@ export class DocumentFragmentSnapshot implements Omit<DocumentSnapshot, 'getFrag
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
private transformContent(content: string) {
|
private transformContent(content: string) {
|
||||||
return content.replace(/---/g, '///') +
|
return (
|
||||||
// Add TypeScript definitions
|
content.replace(/---/g, '///') +
|
||||||
ASTRO_DEFINITION;
|
// Add TypeScript definitions
|
||||||
|
ASTRO_DEFINITION
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getText(start: number, end: number) {
|
getText(start: number, end: number) {
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
import type { ConfigManager } from '../../core/config';
|
import type { ConfigManager } from '../../core/config';
|
||||||
import type { CompletionsProvider, AppCompletionItem, AppCompletionList } from '../interfaces';
|
import type { CompletionsProvider, AppCompletionItem, AppCompletionList } from '../interfaces';
|
||||||
import type {
|
import type { CancellationToken, Hover, SignatureHelp, SignatureHelpContext } from 'vscode-languageserver';
|
||||||
CancellationToken,
|
|
||||||
Hover,
|
|
||||||
SignatureHelp,
|
|
||||||
SignatureHelpContext
|
|
||||||
} from 'vscode-languageserver';
|
|
||||||
import { join as pathJoin, dirname as pathDirname } from 'path';
|
import { join as pathJoin, dirname as pathDirname } from 'path';
|
||||||
import { Document, DocumentManager, isInsideFrontmatter } from '../../core/documents';
|
import { Document, DocumentManager, isInsideFrontmatter } from '../../core/documents';
|
||||||
import { SourceFile, ImportDeclaration, Node, SyntaxKind } from 'typescript';
|
import { SourceFile, ImportDeclaration, Node, SyntaxKind } from 'typescript';
|
||||||
|
@ -134,18 +129,8 @@ export class TypeScriptPlugin implements CompletionsProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSignatureHelp(
|
async getSignatureHelp(document: Document, position: Position, context: SignatureHelpContext | undefined, cancellationToken?: CancellationToken): Promise<SignatureHelp | null> {
|
||||||
document: Document,
|
return this.signatureHelpProvider.getSignatureHelp(document, position, context, cancellationToken);
|
||||||
position: Position,
|
|
||||||
context: SignatureHelpContext | undefined,
|
|
||||||
cancellationToken?: CancellationToken
|
|
||||||
): Promise<SignatureHelp | null> {
|
|
||||||
return this.signatureHelpProvider.getSignatureHelp(
|
|
||||||
document,
|
|
||||||
position,
|
|
||||||
context,
|
|
||||||
cancellationToken
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,8 +34,7 @@ export class CompletionsProviderImpl implements CompletionsProvider<CompletionEn
|
||||||
|
|
||||||
const offset = document.offsetAt(position);
|
const offset = document.offsetAt(position);
|
||||||
|
|
||||||
const entries =
|
const entries = lang.getCompletionsAtPosition(fragment.filePath, offset, completionOptions)?.entries || [];
|
||||||
lang.getCompletionsAtPosition(fragment.filePath, offset, completionOptions)?.entries || [];
|
|
||||||
|
|
||||||
const completionItems = entries
|
const completionItems = entries
|
||||||
.map((entry: ts.CompletionEntry) => this.toCompletionItem(fragment, entry, document.uri, position, new Set()))
|
.map((entry: ts.CompletionEntry) => this.toCompletionItem(fragment, entry, document.uri, position, new Set()))
|
||||||
|
|
|
@ -7,36 +7,34 @@ import { getMarkdownDocumentation } from '../previewer';
|
||||||
import { convertRange, toVirtualAstroFilePath } from '../utils';
|
import { convertRange, toVirtualAstroFilePath } from '../utils';
|
||||||
|
|
||||||
export class HoverProviderImpl implements HoverProvider {
|
export class HoverProviderImpl implements HoverProvider {
|
||||||
constructor(private readonly lang: LanguageServiceManager) {}
|
constructor(private readonly lang: LanguageServiceManager) {}
|
||||||
|
|
||||||
async doHover(document: Document, position: Position): Promise<Hover | null> {
|
async doHover(document: Document, position: Position): Promise<Hover | null> {
|
||||||
const { lang, tsDoc } = await this.getLSAndTSDoc(document);
|
const { lang, tsDoc } = await this.getLSAndTSDoc(document);
|
||||||
const fragment = await tsDoc.getFragment();
|
const fragment = await tsDoc.getFragment();
|
||||||
|
|
||||||
const offset = fragment.offsetAt(fragment.getGeneratedPosition(position));
|
const offset = fragment.offsetAt(fragment.getGeneratedPosition(position));
|
||||||
const filePath = toVirtualAstroFilePath(tsDoc.filePath);
|
const filePath = toVirtualAstroFilePath(tsDoc.filePath);
|
||||||
let info = lang.getQuickInfoAtPosition(filePath, offset);
|
let info = lang.getQuickInfoAtPosition(filePath, offset);
|
||||||
if (!info) {
|
if (!info) {
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
const textSpan = info.textSpan;
|
|
||||||
|
|
||||||
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');
|
|
||||||
|
|
||||||
return mapObjWithRangeToOriginal(fragment, {
|
|
||||||
range: convertRange(fragment, textSpan),
|
|
||||||
contents
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getLSAndTSDoc(document: Document) {
|
const textSpan = info.textSpan;
|
||||||
return this.lang.getTypeScriptDoc(document);
|
|
||||||
}
|
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');
|
||||||
|
|
||||||
|
return mapObjWithRangeToOriginal(fragment, {
|
||||||
|
range: convertRange(fragment, textSpan),
|
||||||
|
contents,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getLSAndTSDoc(document: Document) {
|
||||||
|
return this.lang.getTypeScriptDoc(document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,157 +2,128 @@ import type { LanguageServiceManager } from '../LanguageServiceManager';
|
||||||
import type { SignatureHelpProvider } from '../../interfaces';
|
import type { SignatureHelpProvider } from '../../interfaces';
|
||||||
import ts from 'typescript';
|
import ts from 'typescript';
|
||||||
import {
|
import {
|
||||||
Position,
|
Position,
|
||||||
SignatureHelpContext,
|
SignatureHelpContext,
|
||||||
SignatureHelp,
|
SignatureHelp,
|
||||||
SignatureHelpTriggerKind,
|
SignatureHelpTriggerKind,
|
||||||
SignatureInformation,
|
SignatureInformation,
|
||||||
ParameterInformation,
|
ParameterInformation,
|
||||||
MarkupKind,
|
MarkupKind,
|
||||||
CancellationToken
|
CancellationToken,
|
||||||
} from 'vscode-languageserver';
|
} from 'vscode-languageserver';
|
||||||
import { Document } from '../../../core/documents';
|
import { Document } from '../../../core/documents';
|
||||||
import { getMarkdownDocumentation } from '../previewer';
|
import { getMarkdownDocumentation } from '../previewer';
|
||||||
import { toVirtualAstroFilePath } from '../utils';
|
import { toVirtualAstroFilePath } from '../utils';
|
||||||
|
|
||||||
export class SignatureHelpProviderImpl implements SignatureHelpProvider {
|
export class SignatureHelpProviderImpl implements SignatureHelpProvider {
|
||||||
constructor(private readonly lang: LanguageServiceManager) {}
|
constructor(private readonly lang: LanguageServiceManager) {}
|
||||||
|
|
||||||
private static readonly triggerCharacters = ['(', ',', '<'];
|
private static readonly triggerCharacters = ['(', ',', '<'];
|
||||||
private static readonly retriggerCharacters = [')'];
|
private static readonly retriggerCharacters = [')'];
|
||||||
|
|
||||||
async getSignatureHelp(
|
async getSignatureHelp(document: Document, position: Position, context: SignatureHelpContext | undefined, cancellationToken?: CancellationToken): Promise<SignatureHelp | null> {
|
||||||
document: Document,
|
const { lang, tsDoc } = await this.lang.getTypeScriptDoc(document);
|
||||||
position: Position,
|
const fragment = await tsDoc.getFragment();
|
||||||
context: SignatureHelpContext | undefined,
|
|
||||||
cancellationToken?: CancellationToken
|
|
||||||
): Promise<SignatureHelp | null> {
|
|
||||||
const { lang, tsDoc } = await this.lang.getTypeScriptDoc(document);
|
|
||||||
const fragment = await tsDoc.getFragment();
|
|
||||||
|
|
||||||
if (cancellationToken?.isCancellationRequested) {
|
if (cancellationToken?.isCancellationRequested) {
|
||||||
return null;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return { kind: 'invoked' };
|
||||||
|
case SignatureHelpTriggerKind.ContentChange:
|
||||||
|
return context.isRetrigger ? { kind: 'retrigger' } : { kind: 'invoked' };
|
||||||
|
|
||||||
const offset = fragment.offsetAt(fragment.getGeneratedPosition(position));
|
case SignatureHelpTriggerKind.Invoked:
|
||||||
const triggerReason = this.toTsTriggerReason(context);
|
default:
|
||||||
const info = lang.getSignatureHelpItems(
|
return { kind: 'invoked' };
|
||||||
toVirtualAstroFilePath(tsDoc.filePath),
|
|
||||||
offset,
|
|
||||||
triggerReason ? { triggerReason } : undefined
|
|
||||||
);
|
|
||||||
if (
|
|
||||||
!info ||
|
|
||||||
info.items.some((signature) => this.isInSvelte2tsxGeneratedFunction(signature))
|
|
||||||
) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const signatures = info.items.map(this.toSignatureHelpInformation);
|
|
||||||
|
|
||||||
return {
|
|
||||||
signatures,
|
|
||||||
activeSignature: info.selectedItemIndex,
|
|
||||||
activeParameter: info.argumentIndex
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private isReTrigger(
|
/**
|
||||||
isRetrigger: boolean,
|
* adopted from https://github.com/microsoft/vscode/blob/265a2f6424dfbd3a9788652c7d376a7991d049a3/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts#L73
|
||||||
triggerCharacter: string
|
*/
|
||||||
): triggerCharacter is ts.SignatureHelpRetriggerCharacter {
|
private toSignatureHelpInformation(item: ts.SignatureHelpItem): SignatureInformation {
|
||||||
return (
|
const [prefixLabel, separatorLabel, suffixLabel] = [item.prefixDisplayParts, item.separatorDisplayParts, item.suffixDisplayParts].map(ts.displayPartsToString);
|
||||||
isRetrigger &&
|
|
||||||
(this.isTriggerCharacter(triggerCharacter) ||
|
|
||||||
SignatureHelpProviderImpl.retriggerCharacters.includes(triggerCharacter))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private isTriggerCharacter(
|
let textIndex = prefixLabel.length;
|
||||||
triggerCharacter: string
|
let signatureLabel = '';
|
||||||
): triggerCharacter is ts.SignatureHelpTriggerCharacter {
|
const parameters: ParameterInformation[] = [];
|
||||||
return SignatureHelpProviderImpl.triggerCharacters.includes(triggerCharacter);
|
const lastIndex = item.parameters.length - 1;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
item.parameters.forEach((parameter, index) => {
|
||||||
* adopted from https://github.com/microsoft/vscode/blob/265a2f6424dfbd3a9788652c7d376a7991d049a3/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts#L103
|
const label = ts.displayPartsToString(parameter.displayParts);
|
||||||
*/
|
|
||||||
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:
|
const startIndex = textIndex;
|
||||||
default:
|
const endIndex = textIndex + label.length;
|
||||||
return { kind: 'invoked' };
|
const doc = ts.displayPartsToString(parameter.documentation);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
signatureLabel += label;
|
||||||
* adopted from https://github.com/microsoft/vscode/blob/265a2f6424dfbd3a9788652c7d376a7991d049a3/extensions/typescript-language-features/src/languageFeatures/signatureHelp.ts#L73
|
parameters.push(ParameterInformation.create([startIndex, endIndex], doc));
|
||||||
*/
|
|
||||||
private toSignatureHelpInformation(item: ts.SignatureHelpItem): SignatureInformation {
|
|
||||||
const [prefixLabel, separatorLabel, suffixLabel] = [
|
|
||||||
item.prefixDisplayParts,
|
|
||||||
item.separatorDisplayParts,
|
|
||||||
item.suffixDisplayParts
|
|
||||||
].map(ts.displayPartsToString);
|
|
||||||
|
|
||||||
let textIndex = prefixLabel.length;
|
if (index < lastIndex) {
|
||||||
let signatureLabel = '';
|
textIndex = endIndex + separatorLabel.length;
|
||||||
const parameters: ParameterInformation[] = [];
|
signatureLabel += separatorLabel;
|
||||||
const lastIndex = item.parameters.length - 1;
|
}
|
||||||
|
});
|
||||||
|
const signatureDocumentation = getMarkdownDocumentation(
|
||||||
|
item.documentation,
|
||||||
|
item.tags.filter((tag) => tag.name !== 'param')
|
||||||
|
);
|
||||||
|
|
||||||
item.parameters.forEach((parameter, index) => {
|
return {
|
||||||
const label = ts.displayPartsToString(parameter.displayParts);
|
label: prefixLabel + signatureLabel + suffixLabel,
|
||||||
|
documentation: signatureDocumentation
|
||||||
|
? {
|
||||||
|
value: signatureDocumentation,
|
||||||
|
kind: MarkupKind.Markdown,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
parameters,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const startIndex = textIndex;
|
private isInSvelte2tsxGeneratedFunction(signatureHelpItem: ts.SignatureHelpItem) {
|
||||||
const endIndex = textIndex + label.length;
|
return signatureHelpItem.prefixDisplayParts.some((part) => part.text.includes('__sveltets'));
|
||||||
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')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,134 +7,119 @@
|
||||||
* adopted from https://github.com/microsoft/vscode/blob/10722887b8629f90cc38ee7d90d54e8246dc895f/extensions/typescript-language-features/src/utils/previewer.ts
|
* adopted from https://github.com/microsoft/vscode/blob/10722887b8629f90cc38ee7d90d54e8246dc895f/extensions/typescript-language-features/src/utils/previewer.ts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ts from 'typescript';
|
import ts from 'typescript';
|
||||||
import { isNotNullOrUndefined } from '../../utils';
|
import { isNotNullOrUndefined } from '../../utils';
|
||||||
|
|
||||||
function replaceLinks(text: string): string {
|
function replaceLinks(text: string): string {
|
||||||
return (
|
return (
|
||||||
text
|
text
|
||||||
// Http(s) links
|
// Http(s) links
|
||||||
.replace(
|
.replace(/\{@(link|linkplain|linkcode) (https?:\/\/[^ |}]+?)(?:[| ]([^{}\n]+?))?\}/gi, (_, tag: string, link: string, text?: string) => {
|
||||||
/\{@(link|linkplain|linkcode) (https?:\/\/[^ |}]+?)(?:[| ]([^{}\n]+?))?\}/gi,
|
switch (tag) {
|
||||||
(_, tag: string, link: string, text?: string) => {
|
case 'linkcode':
|
||||||
switch (tag) {
|
return `[\`${text ? text.trim() : link}\`](${link})`;
|
||||||
case 'linkcode':
|
|
||||||
return `[\`${text ? text.trim() : link}\`](${link})`;
|
default:
|
||||||
|
return `[${text ? text.trim() : link}](${link})`;
|
||||||
default:
|
}
|
||||||
return `[${text ? text.trim() : link}](${link})`;
|
})
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
)
|
|
||||||
);
|
function processInlineTags(text: string): string {
|
||||||
}
|
return replaceLinks(text);
|
||||||
|
}
|
||||||
function processInlineTags(text: string): string {
|
|
||||||
return replaceLinks(text);
|
function getTagBodyText(tag: ts.JSDocTagInfo): string | undefined {
|
||||||
}
|
if (!tag.text) {
|
||||||
|
return undefined;
|
||||||
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)) {
|
||||||
// Convert to markdown code block if it is not already one
|
return text;
|
||||||
function makeCodeblock(text: string): string {
|
}
|
||||||
if (text.match(/^\s*[~`]{3}/g)) {
|
return '```\n' + text + '\n```';
|
||||||
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)/);
|
||||||
function makeExampleTag(text: string) {
|
if (captionTagMatches && captionTagMatches.index === 0) {
|
||||||
// check for caption tags, fix for https://github.com/microsoft/vscode/issues/79704
|
return captionTagMatches[1] + '\n\n' + makeCodeblock(text.substr(captionTagMatches[0].length));
|
||||||
const captionTagMatches = text.match(/<caption>(.*?)<\/caption>\s*(\r\n|\n)/);
|
} else {
|
||||||
if (captionTagMatches && captionTagMatches.index === 0) {
|
return makeCodeblock(text);
|
||||||
return (
|
}
|
||||||
captionTagMatches[1] +
|
}
|
||||||
'\n\n' +
|
|
||||||
makeCodeblock(text.substr(captionTagMatches[0].length))
|
function makeEmailTag(text: string) {
|
||||||
);
|
// fix obsucated email address, https://github.com/microsoft/vscode/issues/80898
|
||||||
} else {
|
const emailMatch = text.match(/(.+)\s<([-.\w]+@[-.\w]+)>/);
|
||||||
return makeCodeblock(text);
|
|
||||||
}
|
if (emailMatch === null) {
|
||||||
}
|
return text;
|
||||||
|
} else {
|
||||||
function makeEmailTag(text: string) {
|
return `${emailMatch[1]} ${emailMatch[2]}`;
|
||||||
// fix obsucated email address, https://github.com/microsoft/vscode/issues/80898
|
}
|
||||||
const emailMatch = text.match(/(.+)\s<([-.\w]+@[-.\w]+)>/);
|
}
|
||||||
|
|
||||||
if (emailMatch === null) {
|
switch (tag.name) {
|
||||||
return text;
|
case 'example':
|
||||||
} else {
|
return makeExampleTag(ts.displayPartsToString(tag.text));
|
||||||
return `${emailMatch[1]} ${emailMatch[2]}`;
|
case 'author':
|
||||||
}
|
return makeEmailTag(ts.displayPartsToString(tag.text));
|
||||||
}
|
case 'default':
|
||||||
|
return makeCodeblock(ts.displayPartsToString(tag.text));
|
||||||
switch (tag.name) {
|
}
|
||||||
case 'example':
|
|
||||||
return makeExampleTag(ts.displayPartsToString(tag.text));
|
return processInlineTags(ts.displayPartsToString(tag.text));
|
||||||
case 'author':
|
}
|
||||||
return makeEmailTag(ts.displayPartsToString(tag.text));
|
|
||||||
case 'default':
|
export function getTagDocumentation(tag: ts.JSDocTagInfo): string | undefined {
|
||||||
return makeCodeblock(ts.displayPartsToString(tag.text));
|
function getWithType() {
|
||||||
}
|
const body = (ts.displayPartsToString(tag.text) || '').split(/^(\S+)\s*-?\s*/);
|
||||||
|
if (body?.length === 3) {
|
||||||
return processInlineTags(ts.displayPartsToString(tag.text));
|
const param = body[1];
|
||||||
}
|
const doc = body[2];
|
||||||
|
const label = `*@${tag.name}* \`${param}\``;
|
||||||
export function getTagDocumentation(tag: ts.JSDocTagInfo): string | undefined {
|
if (!doc) {
|
||||||
function getWithType() {
|
return label;
|
||||||
const body = (ts.displayPartsToString(tag.text) || '').split(/^(\S+)\s*-?\s*/);
|
}
|
||||||
if (body?.length === 3) {
|
return label + (doc.match(/\r\n|\n/g) ? ' \n' + processInlineTags(doc) : ` — ${processInlineTags(doc)}`);
|
||||||
const param = body[1];
|
}
|
||||||
const doc = body[2];
|
}
|
||||||
const label = `*@${tag.name}* \`${param}\``;
|
|
||||||
if (!doc) {
|
switch (tag.name) {
|
||||||
return label;
|
case 'augments':
|
||||||
}
|
case 'extends':
|
||||||
return (
|
case 'param':
|
||||||
label +
|
case 'template':
|
||||||
(doc.match(/\r\n|\n/g)
|
return getWithType();
|
||||||
? ' \n' + processInlineTags(doc)
|
}
|
||||||
: ` — ${processInlineTags(doc)}`)
|
|
||||||
);
|
// Generic tag
|
||||||
}
|
const label = `*@${tag.name}*`;
|
||||||
}
|
const text = getTagBodyText(tag);
|
||||||
|
if (!text) {
|
||||||
switch (tag.name) {
|
return label;
|
||||||
case 'augments':
|
}
|
||||||
case 'extends':
|
return label + (text.match(/\r\n|\n/g) ? ' \n' + text : ` — ${text}`);
|
||||||
case 'param':
|
}
|
||||||
case 'template':
|
|
||||||
return getWithType();
|
export function plain(parts: ts.SymbolDisplayPart[] | string): string {
|
||||||
}
|
return processInlineTags(typeof parts === 'string' ? parts : ts.displayPartsToString(parts));
|
||||||
|
}
|
||||||
// Generic tag
|
|
||||||
const label = `*@${tag.name}*`;
|
export function getMarkdownDocumentation(documentation: ts.SymbolDisplayPart[] | undefined, tags: ts.JSDocTagInfo[] | undefined) {
|
||||||
const text = getTagBodyText(tag);
|
let result: Array<string | undefined> = [];
|
||||||
if (!text) {
|
if (documentation) {
|
||||||
return label;
|
result.push(plain(documentation));
|
||||||
}
|
}
|
||||||
return label + (text.match(/\r\n|\n/g) ? ' \n' + text : ` — ${text}`);
|
|
||||||
}
|
if (tags) {
|
||||||
|
result = result.concat(tags.map(getTagDocumentation));
|
||||||
export function plain(parts: ts.SymbolDisplayPart[] | string): string {
|
}
|
||||||
return processInlineTags(typeof parts === 'string' ? parts : ts.displayPartsToString(parts));
|
|
||||||
}
|
return result.filter(isNotNullOrUndefined).join('\n\n');
|
||||||
|
}
|
||||||
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');
|
|
||||||
}
|
|
||||||
|
|
|
@ -178,7 +178,7 @@ export function isVirtualFilePath(filePath: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toVirtualAstroFilePath(filePath: string) {
|
export function toVirtualAstroFilePath(filePath: string) {
|
||||||
if(isVirtualFrameworkFilePath('astro', filePath)) {
|
if (isVirtualFrameworkFilePath('astro', filePath)) {
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
return `${filePath}.ts`;
|
return `${filePath}.ts`;
|
||||||
|
|
Loading…
Add table
Reference in a new issue