Skip to content

Commit

Permalink
Fix #2193
Browse files Browse the repository at this point in the history
  • Loading branch information
octref committed Aug 25, 2020
1 parent 4dc4d0c commit e21fe22
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 20 deletions.
59 changes: 39 additions & 20 deletions server/src/modes/script/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import { DependencyService, T_TypeScript, State } from '../../services/dependenc
import { RefactorAction } from '../../types';
import { IServiceHost } from '../../services/typescriptService/serviceHost';
import { toCompletionItemKind, toSymbolKind } from '../../services/typescriptService/util';
import { provideCompletionItems } from '../style/stylus/completion-item';
import { getTagDocumentation } from './previewer';

// Todo: After upgrading to LS server 4.0, use CompletionContext for filtering trigger chars
// https://microsoft.github.io/language-server-protocol/specification#completion-request-leftwards_arrow_with_hook
Expand Down Expand Up @@ -275,39 +277,56 @@ export async function getJavascriptMode(
}

const fileFsPath = getFileFsPath(doc.uri);
const signHelp = service.getSignatureHelpItems(fileFsPath, scriptDoc.offsetAt(position), undefined);
if (!signHelp) {
const signatureHelpItems = service.getSignatureHelpItems(fileFsPath, scriptDoc.offsetAt(position), undefined);
if (!signatureHelpItems) {
return NULL_SIGNATURE;
}
const ret: SignatureHelp = {
activeSignature: signHelp.selectedItemIndex,
activeParameter: signHelp.argumentIndex,
signatures: []
};
signHelp.items.forEach(item => {
const signature: SignatureInformation = {
label: '',
documentation: undefined,
parameters: []
};

signature.label += tsModule.displayPartsToString(item.prefixDisplayParts);
const signatures: SignatureInformation[] = [];
signatureHelpItems.items.forEach(item => {
let sigLabel = '';
let sigMarkdownDoc = '';
const sigParamemterInfos: ParameterInformation[] = [];

sigLabel += tsModule.displayPartsToString(item.prefixDisplayParts);
item.parameters.forEach((p, i, a) => {
const label = tsModule.displayPartsToString(p.displayParts);
const parameter: ParameterInformation = {
label,
documentation: tsModule.displayPartsToString(p.documentation)
};
signature.label += label;
signature.parameters!.push(parameter);
sigLabel += label;
sigParamemterInfos.push(parameter);
if (i < a.length - 1) {
signature.label += tsModule.displayPartsToString(item.separatorDisplayParts);
sigLabel += tsModule.displayPartsToString(item.separatorDisplayParts);
}
});
signature.label += tsModule.displayPartsToString(item.suffixDisplayParts);
ret.signatures.push(signature);
sigLabel += tsModule.displayPartsToString(item.suffixDisplayParts);

item.tags
.filter(x => x.name !== 'param')
.forEach(x => {
const tagDoc = getTagDocumentation(x);
if (tagDoc) {
sigMarkdownDoc += tagDoc;
}
});

signatures.push({
label: sigLabel,
documentation: {
kind: 'markdown',
value: sigMarkdownDoc
},
parameters: sigParamemterInfos
});
});
return ret;

return {
activeSignature: signatureHelpItems.selectedItemIndex,
activeParameter: signatureHelpItems.argumentIndex,
signatures
};
},
findDocumentHighlight(doc: TextDocument, position: Position): DocumentHighlight[] {
const { scriptDoc, service } = updateCurrentVueTextDocument(doc);
Expand Down
99 changes: 99 additions & 0 deletions server/src/modes/script/previewer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

/* tslint:disable:max-line-length */
/**
* Adapted from https://github.com/microsoft/vscode/blob/8ba70d8bdc3a10e3143cc4a131f333263bc48eef/extensions/typescript-language-features/src/utils/previewer.ts
*/

import * as ts from 'typescript';

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```';
}

switch (tag.name) {
case 'example':
// check for caption tags, fix for #79704
const captionTagMatches = tag.text.match(/<caption>(.*?)<\/caption>\s*(\r\n|\n)/);
if (captionTagMatches && captionTagMatches.index === 0) {
return captionTagMatches[1] + '\n\n' + makeCodeblock(tag.text.substr(captionTagMatches[0].length));
} else {
return makeCodeblock(tag.text);
}
case 'author':
// fix obsucated email address, #80898
const emailMatch = tag.text.match(/(.+)\s<([-.\w]+@[-.\w]+)>/);

if (emailMatch === null) {
return tag.text;
} else {
return `${emailMatch[1]} ${emailMatch[2]}`;
}
case 'default':
return makeCodeblock(tag.text);
}

return processInlineTags(tag.text);
}

export function getTagDocumentation(tag: ts.JSDocTagInfo): string | undefined {
switch (tag.name) {
case 'augments':
case 'extends':
case 'param':
case 'template':
const body = (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)}`);
}
}

// 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}`);
}

0 comments on commit e21fe22

Please sign in to comment.