572 lines
20 KiB
JavaScript
572 lines
20 KiB
JavaScript
|
/* --------------------------------------------------------------------------------------------
|
||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||
|
* ------------------------------------------------------------------------------------------ */
|
||
|
'use strict';
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
const code = require("vscode");
|
||
|
const ls = require("vscode-languageserver-protocol");
|
||
|
const Is = require("./utils/is");
|
||
|
const protocolCompletionItem_1 = require("./protocolCompletionItem");
|
||
|
const protocolCodeLens_1 = require("./protocolCodeLens");
|
||
|
const protocolDocumentLink_1 = require("./protocolDocumentLink");
|
||
|
var CodeBlock;
|
||
|
(function (CodeBlock) {
|
||
|
function is(value) {
|
||
|
let candidate = value;
|
||
|
return candidate && Is.string(candidate.language) && Is.string(candidate.value);
|
||
|
}
|
||
|
CodeBlock.is = is;
|
||
|
})(CodeBlock || (CodeBlock = {}));
|
||
|
function createConverter(uriConverter) {
|
||
|
const nullConverter = (value) => code.Uri.parse(value);
|
||
|
const _uriConverter = uriConverter || nullConverter;
|
||
|
function asUri(value) {
|
||
|
return _uriConverter(value);
|
||
|
}
|
||
|
function asDiagnostics(diagnostics) {
|
||
|
return diagnostics.map(asDiagnostic);
|
||
|
}
|
||
|
function asDiagnostic(diagnostic) {
|
||
|
let result = new code.Diagnostic(asRange(diagnostic.range), diagnostic.message, asDiagnosticSeverity(diagnostic.severity));
|
||
|
if (Is.number(diagnostic.code) || Is.string(diagnostic.code)) {
|
||
|
result.code = diagnostic.code;
|
||
|
}
|
||
|
if (diagnostic.source) {
|
||
|
result.source = diagnostic.source;
|
||
|
}
|
||
|
if (diagnostic.relatedInformation) {
|
||
|
result.relatedInformation = asRelatedInformation(diagnostic.relatedInformation);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asRelatedInformation(relatedInformation) {
|
||
|
return relatedInformation.map(asDiagnosticRelatedInformation);
|
||
|
}
|
||
|
function asDiagnosticRelatedInformation(information) {
|
||
|
return new code.DiagnosticRelatedInformation(asLocation(information.location), information.message);
|
||
|
}
|
||
|
function asPosition(value) {
|
||
|
if (!value) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return new code.Position(value.line, value.character);
|
||
|
}
|
||
|
function asRange(value) {
|
||
|
if (!value) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return new code.Range(asPosition(value.start), asPosition(value.end));
|
||
|
}
|
||
|
function asDiagnosticSeverity(value) {
|
||
|
if (value === void 0 || value === null) {
|
||
|
return code.DiagnosticSeverity.Error;
|
||
|
}
|
||
|
switch (value) {
|
||
|
case ls.DiagnosticSeverity.Error:
|
||
|
return code.DiagnosticSeverity.Error;
|
||
|
case ls.DiagnosticSeverity.Warning:
|
||
|
return code.DiagnosticSeverity.Warning;
|
||
|
case ls.DiagnosticSeverity.Information:
|
||
|
return code.DiagnosticSeverity.Information;
|
||
|
case ls.DiagnosticSeverity.Hint:
|
||
|
return code.DiagnosticSeverity.Hint;
|
||
|
}
|
||
|
return code.DiagnosticSeverity.Error;
|
||
|
}
|
||
|
function asHoverContent(value) {
|
||
|
if (Is.string(value)) {
|
||
|
return new code.MarkdownString(value);
|
||
|
}
|
||
|
else if (CodeBlock.is(value)) {
|
||
|
let result = new code.MarkdownString();
|
||
|
return result.appendCodeblock(value.value, value.language);
|
||
|
}
|
||
|
else if (Array.isArray(value)) {
|
||
|
let result = [];
|
||
|
for (let element of value) {
|
||
|
let item = new code.MarkdownString();
|
||
|
if (CodeBlock.is(element)) {
|
||
|
item.appendCodeblock(element.value, element.language);
|
||
|
}
|
||
|
else {
|
||
|
item.appendMarkdown(element);
|
||
|
}
|
||
|
result.push(item);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
else {
|
||
|
let result;
|
||
|
switch (value.kind) {
|
||
|
case ls.MarkupKind.Markdown:
|
||
|
return new code.MarkdownString(value.value);
|
||
|
case ls.MarkupKind.PlainText:
|
||
|
result = new code.MarkdownString();
|
||
|
result.appendText(value.value);
|
||
|
return result;
|
||
|
default:
|
||
|
result = new code.MarkdownString();
|
||
|
result.appendText(`Unsupported Markup content received. Kind is: ${value.kind}`);
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function asDocumentation(value) {
|
||
|
if (Is.string(value)) {
|
||
|
return value;
|
||
|
}
|
||
|
else {
|
||
|
switch (value.kind) {
|
||
|
case ls.MarkupKind.Markdown:
|
||
|
return new code.MarkdownString(value.value);
|
||
|
case ls.MarkupKind.PlainText:
|
||
|
return value.value;
|
||
|
default:
|
||
|
return `Unsupported Markup content received. Kind is: ${value.kind}`;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function asHover(hover) {
|
||
|
if (!hover) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return new code.Hover(asHoverContent(hover.contents), asRange(hover.range));
|
||
|
}
|
||
|
function asCompletionResult(result) {
|
||
|
if (!result) {
|
||
|
return undefined;
|
||
|
}
|
||
|
if (Array.isArray(result)) {
|
||
|
let items = result;
|
||
|
return items.map(asCompletionItem);
|
||
|
}
|
||
|
let list = result;
|
||
|
return new code.CompletionList(list.items.map(asCompletionItem), list.isIncomplete);
|
||
|
}
|
||
|
function asCompletionItemKind(value) {
|
||
|
// Protocol item kind is 1 based, codes item kind is zero based.
|
||
|
if (ls.CompletionItemKind.Text <= value && value <= ls.CompletionItemKind.TypeParameter) {
|
||
|
return [value - 1, undefined];
|
||
|
}
|
||
|
;
|
||
|
return [code.CompletionItemKind.Text, value];
|
||
|
}
|
||
|
function asCompletionItem(item) {
|
||
|
let result = new protocolCompletionItem_1.default(item.label);
|
||
|
if (item.detail) {
|
||
|
result.detail = item.detail;
|
||
|
}
|
||
|
if (item.documentation) {
|
||
|
result.documentation = asDocumentation(item.documentation);
|
||
|
result.documentationFormat = Is.string(item.documentation) ? '$string' : item.documentation.kind;
|
||
|
}
|
||
|
;
|
||
|
if (item.filterText) {
|
||
|
result.filterText = item.filterText;
|
||
|
}
|
||
|
let insertText = asCompletionInsertText(item);
|
||
|
if (insertText) {
|
||
|
result.insertText = insertText.text;
|
||
|
result.range = insertText.range;
|
||
|
result.fromEdit = insertText.fromEdit;
|
||
|
}
|
||
|
if (Is.number(item.kind)) {
|
||
|
let [itemKind, original] = asCompletionItemKind(item.kind);
|
||
|
result.kind = itemKind;
|
||
|
if (original) {
|
||
|
result.originalItemKind = original;
|
||
|
}
|
||
|
}
|
||
|
if (item.sortText) {
|
||
|
result.sortText = item.sortText;
|
||
|
}
|
||
|
if (item.additionalTextEdits) {
|
||
|
result.additionalTextEdits = asTextEdits(item.additionalTextEdits);
|
||
|
}
|
||
|
if (Is.stringArray(item.commitCharacters)) {
|
||
|
result.commitCharacters = item.commitCharacters.slice();
|
||
|
}
|
||
|
if (item.command) {
|
||
|
result.command = asCommand(item.command);
|
||
|
}
|
||
|
if (item.deprecated === true || item.deprecated === false) {
|
||
|
result.deprecated = item.deprecated;
|
||
|
}
|
||
|
if (item.preselect === true || item.preselect === false) {
|
||
|
result.preselect = item.preselect;
|
||
|
}
|
||
|
if (item.data !== void 0) {
|
||
|
result.data = item.data;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asCompletionInsertText(item) {
|
||
|
if (item.textEdit) {
|
||
|
if (item.insertTextFormat === ls.InsertTextFormat.Snippet) {
|
||
|
return { text: new code.SnippetString(item.textEdit.newText), range: asRange(item.textEdit.range), fromEdit: true };
|
||
|
}
|
||
|
else {
|
||
|
return { text: item.textEdit.newText, range: asRange(item.textEdit.range), fromEdit: true };
|
||
|
}
|
||
|
}
|
||
|
else if (item.insertText) {
|
||
|
if (item.insertTextFormat === ls.InsertTextFormat.Snippet) {
|
||
|
return { text: new code.SnippetString(item.insertText), fromEdit: false };
|
||
|
}
|
||
|
else {
|
||
|
return { text: item.insertText, fromEdit: false };
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
return undefined;
|
||
|
}
|
||
|
}
|
||
|
function asTextEdit(edit) {
|
||
|
if (!edit) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return new code.TextEdit(asRange(edit.range), edit.newText);
|
||
|
}
|
||
|
function asTextEdits(items) {
|
||
|
if (!items) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return items.map(asTextEdit);
|
||
|
}
|
||
|
function asSignatureHelp(item) {
|
||
|
if (!item) {
|
||
|
return undefined;
|
||
|
}
|
||
|
let result = new code.SignatureHelp();
|
||
|
if (Is.number(item.activeSignature)) {
|
||
|
result.activeSignature = item.activeSignature;
|
||
|
}
|
||
|
else {
|
||
|
// activeSignature was optional in the past
|
||
|
result.activeSignature = 0;
|
||
|
}
|
||
|
if (Is.number(item.activeParameter)) {
|
||
|
result.activeParameter = item.activeParameter;
|
||
|
}
|
||
|
else {
|
||
|
// activeParameter was optional in the past
|
||
|
result.activeParameter = 0;
|
||
|
}
|
||
|
if (item.signatures) {
|
||
|
result.signatures = asSignatureInformations(item.signatures);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asSignatureInformations(items) {
|
||
|
return items.map(asSignatureInformation);
|
||
|
}
|
||
|
function asSignatureInformation(item) {
|
||
|
let result = new code.SignatureInformation(item.label);
|
||
|
if (item.documentation) {
|
||
|
result.documentation = asDocumentation(item.documentation);
|
||
|
}
|
||
|
if (item.parameters) {
|
||
|
result.parameters = asParameterInformations(item.parameters);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asParameterInformations(item) {
|
||
|
return item.map(asParameterInformation);
|
||
|
}
|
||
|
function asParameterInformation(item) {
|
||
|
let result = new code.ParameterInformation(item.label);
|
||
|
if (item.documentation) {
|
||
|
result.documentation = asDocumentation(item.documentation);
|
||
|
}
|
||
|
;
|
||
|
return result;
|
||
|
}
|
||
|
function asDefinitionResult(item) {
|
||
|
if (!item) {
|
||
|
return undefined;
|
||
|
}
|
||
|
if (Is.array(item)) {
|
||
|
return item.map((location) => asLocation(location));
|
||
|
}
|
||
|
else {
|
||
|
return asLocation(item);
|
||
|
}
|
||
|
}
|
||
|
function asLocation(item) {
|
||
|
if (!item) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return new code.Location(_uriConverter(item.uri), asRange(item.range));
|
||
|
}
|
||
|
function asReferences(values) {
|
||
|
if (!values) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return values.map(location => asLocation(location));
|
||
|
}
|
||
|
function asDocumentHighlights(values) {
|
||
|
if (!values) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return values.map(asDocumentHighlight);
|
||
|
}
|
||
|
function asDocumentHighlight(item) {
|
||
|
let result = new code.DocumentHighlight(asRange(item.range));
|
||
|
if (Is.number(item.kind)) {
|
||
|
result.kind = asDocumentHighlightKind(item.kind);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asDocumentHighlightKind(item) {
|
||
|
switch (item) {
|
||
|
case ls.DocumentHighlightKind.Text:
|
||
|
return code.DocumentHighlightKind.Text;
|
||
|
case ls.DocumentHighlightKind.Read:
|
||
|
return code.DocumentHighlightKind.Read;
|
||
|
case ls.DocumentHighlightKind.Write:
|
||
|
return code.DocumentHighlightKind.Write;
|
||
|
}
|
||
|
return code.DocumentHighlightKind.Text;
|
||
|
}
|
||
|
function asSymbolInformations(values, uri) {
|
||
|
if (!values) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return values.map(information => asSymbolInformation(information, uri));
|
||
|
}
|
||
|
function asSymbolKind(item) {
|
||
|
if (item <= ls.SymbolKind.TypeParameter) {
|
||
|
// Symbol kind is one based in the protocol and zero based in code.
|
||
|
return item - 1;
|
||
|
}
|
||
|
return code.SymbolKind.Property;
|
||
|
}
|
||
|
function asSymbolInformation(item, uri) {
|
||
|
// Symbol kind is one based in the protocol and zero based in code.
|
||
|
let result = new code.SymbolInformation(item.name, asSymbolKind(item.kind), asRange(item.location.range), item.location.uri ? _uriConverter(item.location.uri) : uri);
|
||
|
if (item.containerName) {
|
||
|
result.containerName = item.containerName;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asDocumentSymbols(values) {
|
||
|
if (values === void 0 || values === null) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return values.map(asDocumentSymbol);
|
||
|
}
|
||
|
function asDocumentSymbol(value) {
|
||
|
let result = new code.DocumentSymbol(value.name, value.detail || '', asSymbolKind(value.kind), asRange(value.range), asRange(value.selectionRange));
|
||
|
if (value.children !== void 0 && value.children.length > 0) {
|
||
|
let children = [];
|
||
|
for (let child of value.children) {
|
||
|
children.push(asDocumentSymbol(child));
|
||
|
}
|
||
|
result.children = children;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asCommand(item) {
|
||
|
let result = { title: item.title, command: item.command };
|
||
|
if (item.arguments) {
|
||
|
result.arguments = item.arguments;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asCommands(items) {
|
||
|
if (!items) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return items.map(asCommand);
|
||
|
}
|
||
|
const kindMapping = new Map();
|
||
|
kindMapping.set('', code.CodeActionKind.Empty);
|
||
|
kindMapping.set(ls.CodeActionKind.QuickFix, code.CodeActionKind.QuickFix);
|
||
|
kindMapping.set(ls.CodeActionKind.Refactor, code.CodeActionKind.Refactor);
|
||
|
kindMapping.set(ls.CodeActionKind.RefactorExtract, code.CodeActionKind.RefactorExtract);
|
||
|
kindMapping.set(ls.CodeActionKind.RefactorInline, code.CodeActionKind.RefactorInline);
|
||
|
kindMapping.set(ls.CodeActionKind.RefactorRewrite, code.CodeActionKind.RefactorRewrite);
|
||
|
kindMapping.set(ls.CodeActionKind.Source, code.CodeActionKind.Source);
|
||
|
kindMapping.set(ls.CodeActionKind.SourceOrganizeImports, code.CodeActionKind.SourceOrganizeImports);
|
||
|
function asCodeActionKind(item) {
|
||
|
if (item === void 0 || item === null) {
|
||
|
return undefined;
|
||
|
}
|
||
|
let result = kindMapping.get(item);
|
||
|
if (result) {
|
||
|
return result;
|
||
|
}
|
||
|
let parts = item.split('.');
|
||
|
result = code.CodeActionKind.Empty;
|
||
|
for (let part of parts) {
|
||
|
result = result.append(part);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asCodeAction(item) {
|
||
|
if (item === void 0 || item === null) {
|
||
|
return undefined;
|
||
|
}
|
||
|
let result = new code.CodeAction(item.title);
|
||
|
if (item.kind !== void 0) {
|
||
|
result.kind = asCodeActionKind(item.kind);
|
||
|
}
|
||
|
if (item.diagnostics) {
|
||
|
result.diagnostics = asDiagnostics(item.diagnostics);
|
||
|
}
|
||
|
if (item.edit) {
|
||
|
result.edit = asWorkspaceEdit(item.edit);
|
||
|
}
|
||
|
if (item.command) {
|
||
|
result.command = asCommand(item.command);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asCodeLens(item) {
|
||
|
if (!item) {
|
||
|
return undefined;
|
||
|
}
|
||
|
let result = new protocolCodeLens_1.default(asRange(item.range));
|
||
|
if (item.command) {
|
||
|
result.command = asCommand(item.command);
|
||
|
}
|
||
|
if (item.data !== void 0 && item.data !== null) {
|
||
|
result.data = item.data;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asCodeLenses(items) {
|
||
|
if (!items) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return items.map((codeLens) => asCodeLens(codeLens));
|
||
|
}
|
||
|
function asWorkspaceEdit(item) {
|
||
|
if (!item) {
|
||
|
return undefined;
|
||
|
}
|
||
|
let result = new code.WorkspaceEdit();
|
||
|
if (item.documentChanges) {
|
||
|
item.documentChanges.forEach(change => {
|
||
|
result.set(_uriConverter(change.textDocument.uri), asTextEdits(change.edits));
|
||
|
});
|
||
|
}
|
||
|
else if (item.changes) {
|
||
|
Object.keys(item.changes).forEach(key => {
|
||
|
result.set(_uriConverter(key), asTextEdits(item.changes[key]));
|
||
|
});
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function asDocumentLink(item) {
|
||
|
let range = asRange(item.range);
|
||
|
let target = item.target ? asUri(item.target) : undefined;
|
||
|
// target must be optional in DocumentLink
|
||
|
let link = new protocolDocumentLink_1.default(range, target);
|
||
|
if (item.data !== void 0 && item.data !== null) {
|
||
|
link.data = item.data;
|
||
|
}
|
||
|
return link;
|
||
|
}
|
||
|
function asDocumentLinks(items) {
|
||
|
if (!items) {
|
||
|
return undefined;
|
||
|
}
|
||
|
return items.map(asDocumentLink);
|
||
|
}
|
||
|
function asColor(color) {
|
||
|
return new code.Color(color.red, color.green, color.blue, color.alpha);
|
||
|
}
|
||
|
function asColorInformation(ci) {
|
||
|
return new code.ColorInformation(asRange(ci.range), asColor(ci.color));
|
||
|
}
|
||
|
function asColorInformations(colorInformation) {
|
||
|
if (Array.isArray(colorInformation)) {
|
||
|
return colorInformation.map(asColorInformation);
|
||
|
}
|
||
|
return undefined;
|
||
|
}
|
||
|
function asColorPresentation(cp) {
|
||
|
let presentation = new code.ColorPresentation(cp.label);
|
||
|
presentation.additionalTextEdits = asTextEdits(cp.additionalTextEdits);
|
||
|
if (cp.textEdit) {
|
||
|
presentation.textEdit = asTextEdit(cp.textEdit);
|
||
|
}
|
||
|
return presentation;
|
||
|
}
|
||
|
function asColorPresentations(colorPresentations) {
|
||
|
if (Array.isArray(colorPresentations)) {
|
||
|
return colorPresentations.map(asColorPresentation);
|
||
|
}
|
||
|
return undefined;
|
||
|
}
|
||
|
function asFoldingRangeKind(kind) {
|
||
|
if (kind) {
|
||
|
switch (kind) {
|
||
|
case ls.FoldingRangeKind.Comment:
|
||
|
return code.FoldingRangeKind.Comment;
|
||
|
case ls.FoldingRangeKind.Imports:
|
||
|
return code.FoldingRangeKind.Imports;
|
||
|
case ls.FoldingRangeKind.Region:
|
||
|
return code.FoldingRangeKind.Region;
|
||
|
}
|
||
|
}
|
||
|
return void 0;
|
||
|
}
|
||
|
function asFoldingRange(r) {
|
||
|
return new code.FoldingRange(r.startLine, r.endLine, asFoldingRangeKind(r.kind));
|
||
|
}
|
||
|
function asFoldingRanges(foldingRanges) {
|
||
|
if (Array.isArray(foldingRanges)) {
|
||
|
return foldingRanges.map(asFoldingRange);
|
||
|
}
|
||
|
return void 0;
|
||
|
}
|
||
|
return {
|
||
|
asUri,
|
||
|
asDiagnostics,
|
||
|
asDiagnostic,
|
||
|
asRange,
|
||
|
asPosition,
|
||
|
asDiagnosticSeverity,
|
||
|
asHover,
|
||
|
asCompletionResult,
|
||
|
asCompletionItem,
|
||
|
asTextEdit,
|
||
|
asTextEdits,
|
||
|
asSignatureHelp,
|
||
|
asSignatureInformations,
|
||
|
asSignatureInformation,
|
||
|
asParameterInformations,
|
||
|
asParameterInformation,
|
||
|
asDefinitionResult,
|
||
|
asLocation,
|
||
|
asReferences,
|
||
|
asDocumentHighlights,
|
||
|
asDocumentHighlight,
|
||
|
asDocumentHighlightKind,
|
||
|
asSymbolInformations,
|
||
|
asSymbolInformation,
|
||
|
asDocumentSymbols,
|
||
|
asDocumentSymbol,
|
||
|
asCommand,
|
||
|
asCommands,
|
||
|
asCodeAction,
|
||
|
asCodeLens,
|
||
|
asCodeLenses,
|
||
|
asWorkspaceEdit,
|
||
|
asDocumentLink,
|
||
|
asDocumentLinks,
|
||
|
asFoldingRangeKind,
|
||
|
asFoldingRange,
|
||
|
asFoldingRanges,
|
||
|
asColor,
|
||
|
asColorInformation,
|
||
|
asColorInformations,
|
||
|
asColorPresentation,
|
||
|
asColorPresentations
|
||
|
};
|
||
|
}
|
||
|
exports.createConverter = createConverter;
|