"use strict"; /* -------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ Object.defineProperty(exports, "__esModule", { value: true }); exports.createConverter = void 0; const code = require("vscode"); const proto = require("vscode-languageserver-protocol"); const Is = require("./utils/is"); const protocolCompletionItem_1 = require("./protocolCompletionItem"); const protocolCodeLens_1 = require("./protocolCodeLens"); const protocolDocumentLink_1 = require("./protocolDocumentLink"); const protocolCodeAction_1 = require("./protocolCodeAction"); const protocolDiagnostic_1 = require("./protocolDiagnostic"); const protocolCallHierarchyItem_1 = require("./protocolCallHierarchyItem"); const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol"); var InsertReplaceRange; (function (InsertReplaceRange) { function is(value) { const candidate = value; return candidate && !!candidate.inserting && !!candidate.replacing; } InsertReplaceRange.is = is; })(InsertReplaceRange || (InsertReplaceRange = {})); function createConverter(uriConverter) { const nullConverter = (value) => value.toString(); const _uriConverter = uriConverter || nullConverter; function asUri(value) { return _uriConverter(value); } function asTextDocumentIdentifier(textDocument) { return { uri: _uriConverter(textDocument.uri) }; } function asVersionedTextDocumentIdentifier(textDocument) { return { uri: _uriConverter(textDocument.uri), version: textDocument.version }; } function asOpenTextDocumentParams(textDocument) { return { textDocument: { uri: _uriConverter(textDocument.uri), languageId: textDocument.languageId, version: textDocument.version, text: textDocument.getText() } }; } function isTextDocumentChangeEvent(value) { let candidate = value; return !!candidate.document && !!candidate.contentChanges; } function isTextDocument(value) { let candidate = value; return !!candidate.uri && !!candidate.version; } function asChangeTextDocumentParams(arg) { if (isTextDocument(arg)) { let result = { textDocument: { uri: _uriConverter(arg.uri), version: arg.version }, contentChanges: [{ text: arg.getText() }] }; return result; } else if (isTextDocumentChangeEvent(arg)) { let document = arg.document; let result = { textDocument: { uri: _uriConverter(document.uri), version: document.version }, contentChanges: arg.contentChanges.map((change) => { let range = change.range; return { range: { start: { line: range.start.line, character: range.start.character }, end: { line: range.end.line, character: range.end.character } }, rangeLength: change.rangeLength, text: change.text }; }) }; return result; } else { throw Error('Unsupported text document change parameter'); } } function asCloseTextDocumentParams(textDocument) { return { textDocument: asTextDocumentIdentifier(textDocument) }; } function asSaveTextDocumentParams(textDocument, includeContent = false) { let result = { textDocument: asTextDocumentIdentifier(textDocument) }; if (includeContent) { result.text = textDocument.getText(); } return result; } function asTextDocumentSaveReason(reason) { switch (reason) { case code.TextDocumentSaveReason.Manual: return proto.TextDocumentSaveReason.Manual; case code.TextDocumentSaveReason.AfterDelay: return proto.TextDocumentSaveReason.AfterDelay; case code.TextDocumentSaveReason.FocusOut: return proto.TextDocumentSaveReason.FocusOut; } return proto.TextDocumentSaveReason.Manual; } function asWillSaveTextDocumentParams(event) { return { textDocument: asTextDocumentIdentifier(event.document), reason: asTextDocumentSaveReason(event.reason) }; } function asDidCreateFilesParams(event) { return { files: event.files.map((fileUri) => ({ uri: _uriConverter(fileUri), })), }; } function asDidRenameFilesParams(event) { return { files: event.files.map((file) => ({ oldUri: _uriConverter(file.oldUri), newUri: _uriConverter(file.newUri), })), }; } function asDidDeleteFilesParams(event) { return { files: event.files.map((fileUri) => ({ uri: _uriConverter(fileUri), })), }; } function asWillCreateFilesParams(event) { return { files: event.files.map((fileUri) => ({ uri: _uriConverter(fileUri), })), }; } function asWillRenameFilesParams(event) { return { files: event.files.map((file) => ({ oldUri: _uriConverter(file.oldUri), newUri: _uriConverter(file.newUri), })), }; } function asWillDeleteFilesParams(event) { return { files: event.files.map((fileUri) => ({ uri: _uriConverter(fileUri), })), }; } function asTextDocumentPositionParams(textDocument, position) { return { textDocument: asTextDocumentIdentifier(textDocument), position: asWorkerPosition(position) }; } function asCompletionTriggerKind(triggerKind) { switch (triggerKind) { case code.CompletionTriggerKind.TriggerCharacter: return proto.CompletionTriggerKind.TriggerCharacter; case code.CompletionTriggerKind.TriggerForIncompleteCompletions: return proto.CompletionTriggerKind.TriggerForIncompleteCompletions; default: return proto.CompletionTriggerKind.Invoked; } } function asCompletionParams(textDocument, position, context) { return { textDocument: asTextDocumentIdentifier(textDocument), position: asWorkerPosition(position), context: { triggerKind: asCompletionTriggerKind(context.triggerKind), triggerCharacter: context.triggerCharacter } }; } function asSignatureHelpTriggerKind(triggerKind) { switch (triggerKind) { case code.SignatureHelpTriggerKind.Invoke: return proto.SignatureHelpTriggerKind.Invoked; case code.SignatureHelpTriggerKind.TriggerCharacter: return proto.SignatureHelpTriggerKind.TriggerCharacter; case code.SignatureHelpTriggerKind.ContentChange: return proto.SignatureHelpTriggerKind.ContentChange; } } function asParameterInformation(value) { // We leave the documentation out on purpose since it usually adds no // value for the server. return { label: value.label }; } function asParameterInformations(values) { return values.map(asParameterInformation); } function asSignatureInformation(value) { // We leave the documentation out on purpose since it usually adds no // value for the server. return { label: value.label, parameters: asParameterInformations(value.parameters) }; } function asSignatureInformations(values) { return values.map(asSignatureInformation); } function asSignatureHelp(value) { if (value === undefined) { return value; } return { signatures: asSignatureInformations(value.signatures), activeSignature: value.activeSignature, activeParameter: value.activeParameter }; } function asSignatureHelpParams(textDocument, position, context) { return { textDocument: asTextDocumentIdentifier(textDocument), position: asWorkerPosition(position), context: { isRetrigger: context.isRetrigger, triggerCharacter: context.triggerCharacter, triggerKind: asSignatureHelpTriggerKind(context.triggerKind), activeSignatureHelp: asSignatureHelp(context.activeSignatureHelp) } }; } function asWorkerPosition(position) { return { line: position.line, character: position.character }; } function asPosition(value) { if (value === undefined || value === null) { return value; } return { line: value.line, character: value.character }; } function asPositions(value) { let result = []; for (let elem of value) { result.push(asPosition(elem)); } return result; } function asRange(value) { if (value === undefined || value === null) { return value; } return { start: asPosition(value.start), end: asPosition(value.end) }; } function asLocation(value) { if (value === undefined || value === null) { return value; } return proto.Location.create(asUri(value.uri), asRange(value.range)); } function asDiagnosticSeverity(value) { switch (value) { case code.DiagnosticSeverity.Error: return proto.DiagnosticSeverity.Error; case code.DiagnosticSeverity.Warning: return proto.DiagnosticSeverity.Warning; case code.DiagnosticSeverity.Information: return proto.DiagnosticSeverity.Information; case code.DiagnosticSeverity.Hint: return proto.DiagnosticSeverity.Hint; } } function asDiagnosticTags(tags) { if (!tags) { return undefined; } let result = []; for (let tag of tags) { let converted = asDiagnosticTag(tag); if (converted !== undefined) { result.push(converted); } } return result.length > 0 ? result : undefined; } function asDiagnosticTag(tag) { switch (tag) { case code.DiagnosticTag.Unnecessary: return proto.DiagnosticTag.Unnecessary; case code.DiagnosticTag.Deprecated: return proto.DiagnosticTag.Deprecated; default: return undefined; } } function asRelatedInformation(item) { return { message: item.message, location: asLocation(item.location) }; } function asRelatedInformations(items) { return items.map(asRelatedInformation); } function asDiagnosticCode(value) { if (value === undefined || value === null) { return undefined; } if (Is.number(value) || Is.string(value)) { return value; } return { value: value.value, target: asUri(value.target) }; } function asDiagnostic(item) { const result = proto.Diagnostic.create(asRange(item.range), item.message); const protocolDiagnostic = item instanceof protocolDiagnostic_1.ProtocolDiagnostic ? item : undefined; if (protocolDiagnostic !== undefined && protocolDiagnostic.data !== undefined) { result.data = protocolDiagnostic.data; } const code = asDiagnosticCode(item.code); if (protocolDiagnostic_1.DiagnosticCode.is(code)) { if (protocolDiagnostic !== undefined && protocolDiagnostic.hasDiagnosticCode) { result.code = code; } else { result.code = code.value; result.codeDescription = { href: code.target }; } } else { result.code = code; } if (Is.number(item.severity)) { result.severity = asDiagnosticSeverity(item.severity); } if (Array.isArray(item.tags)) { result.tags = asDiagnosticTags(item.tags); } if (item.relatedInformation) { result.relatedInformation = asRelatedInformations(item.relatedInformation); } if (item.source) { result.source = item.source; } return result; } function asDiagnostics(items) { if (items === undefined || items === null) { return items; } return items.map(asDiagnostic); } function asDocumentation(format, documentation) { switch (format) { case '$string': return documentation; case proto.MarkupKind.PlainText: return { kind: format, value: documentation }; case proto.MarkupKind.Markdown: return { kind: format, value: documentation.value }; default: return `Unsupported Markup content received. Kind is: ${format}`; } } function asCompletionItemTag(tag) { switch (tag) { case code.CompletionItemTag.Deprecated: return proto.CompletionItemTag.Deprecated; } return undefined; } function asCompletionItemTags(tags) { if (tags === undefined) { return tags; } const result = []; for (let tag of tags) { const converted = asCompletionItemTag(tag); if (converted !== undefined) { result.push(converted); } } return result; } function asCompletionItemKind(value, original) { if (original !== undefined) { return original; } return value + 1; } function asCompletionItem(item) { let result = { label: item.label }; let protocolItem = item instanceof protocolCompletionItem_1.default ? item : undefined; if (item.detail) { result.detail = item.detail; } // We only send items back we created. So this can't be something else than // a string right now. if (item.documentation) { if (!protocolItem || protocolItem.documentationFormat === '$string') { result.documentation = item.documentation; } else { result.documentation = asDocumentation(protocolItem.documentationFormat, item.documentation); } } if (item.filterText) { result.filterText = item.filterText; } fillPrimaryInsertText(result, item); if (Is.number(item.kind)) { result.kind = asCompletionItemKind(item.kind, protocolItem && protocolItem.originalItemKind); } if (item.sortText) { result.sortText = item.sortText; } if (item.additionalTextEdits) { result.additionalTextEdits = asTextEdits(item.additionalTextEdits); } if (item.commitCharacters) { result.commitCharacters = item.commitCharacters.slice(); } if (item.command) { result.command = asCommand(item.command); } if (item.preselect === true || item.preselect === false) { result.preselect = item.preselect; } const tags = asCompletionItemTags(item.tags); if (protocolItem) { if (protocolItem.data !== undefined) { result.data = protocolItem.data; } if (protocolItem.deprecated === true || protocolItem.deprecated === false) { if (protocolItem.deprecated === true && tags !== undefined && tags.length > 0) { const index = tags.indexOf(code.CompletionItemTag.Deprecated); if (index !== -1) { tags.splice(index, 1); } } result.deprecated = protocolItem.deprecated; } if (protocolItem.insertTextMode !== undefined) { result.insertTextMode = protocolItem.insertTextMode; } } if (tags !== undefined && tags.length > 0) { result.tags = tags; } if (result.insertTextMode === undefined && item.keepWhitespace === true) { result.insertTextMode = vscode_languageserver_protocol_1.InsertTextMode.adjustIndentation; } return result; } function fillPrimaryInsertText(target, source) { let format = proto.InsertTextFormat.PlainText; let text = undefined; let range = undefined; if (source.textEdit) { text = source.textEdit.newText; range = source.textEdit.range; } else if (source.insertText instanceof code.SnippetString) { format = proto.InsertTextFormat.Snippet; text = source.insertText.value; } else { text = source.insertText; } if (source.range) { range = source.range; } target.insertTextFormat = format; if (source.fromEdit && text !== undefined && range !== undefined) { target.textEdit = asCompletionTextEdit(text, range); } else { target.insertText = text; } } function asCompletionTextEdit(newText, range) { if (InsertReplaceRange.is(range)) { return proto.InsertReplaceEdit.create(newText, asRange(range.inserting), asRange(range.replacing)); } else { return { newText, range: asRange(range) }; } } function asTextEdit(edit) { return { range: asRange(edit.range), newText: edit.newText }; } function asTextEdits(edits) { if (edits === undefined || edits === null) { return edits; } return edits.map(asTextEdit); } function asSymbolKind(item) { if (item <= code.SymbolKind.TypeParameter) { // Symbol kind is one based in the protocol and zero based in code. return (item + 1); } return proto.SymbolKind.Property; } function asSymbolTag(item) { return item; } function asSymbolTags(items) { return items.map(asSymbolTag); } function asReferenceParams(textDocument, position, options) { return { textDocument: asTextDocumentIdentifier(textDocument), position: asWorkerPosition(position), context: { includeDeclaration: options.includeDeclaration } }; } function asCodeAction(item) { let result = proto.CodeAction.create(item.title); if (item instanceof protocolCodeAction_1.default && item.data !== undefined) { result.data = item.data; } if (item.kind !== undefined) { result.kind = asCodeActionKind(item.kind); } if (item.diagnostics !== undefined) { result.diagnostics = asDiagnostics(item.diagnostics); } if (item.edit !== undefined) { throw new Error(`VS Code code actions can only be converted to a protocol code action without an edit.`); } if (item.command !== undefined) { result.command = asCommand(item.command); } if (item.isPreferred !== undefined) { result.isPreferred = item.isPreferred; } if (item.disabled !== undefined) { result.disabled = { reason: item.disabled.reason }; } return result; } function asCodeActionContext(context) { if (context === undefined || context === null) { return context; } let only; if (context.only && Is.string(context.only.value)) { only = [context.only.value]; } return proto.CodeActionContext.create(asDiagnostics(context.diagnostics), only); } function asCodeActionKind(item) { if (item === undefined || item === null) { return undefined; } return item.value; } function asCommand(item) { let result = proto.Command.create(item.title, item.command); if (item.arguments) { result.arguments = item.arguments; } return result; } function asCodeLens(item) { let result = proto.CodeLens.create(asRange(item.range)); if (item.command) { result.command = asCommand(item.command); } if (item instanceof protocolCodeLens_1.default) { if (item.data) { result.data = item.data; } } return result; } function asFormattingOptions(options, fileOptions) { const result = { tabSize: options.tabSize, insertSpaces: options.insertSpaces }; if (fileOptions.trimTrailingWhitespace) { result.trimTrailingWhitespace = true; } if (fileOptions.trimFinalNewlines) { result.trimFinalNewlines = true; } if (fileOptions.insertFinalNewline) { result.insertFinalNewline = true; } return result; } function asDocumentSymbolParams(textDocument) { return { textDocument: asTextDocumentIdentifier(textDocument) }; } function asCodeLensParams(textDocument) { return { textDocument: asTextDocumentIdentifier(textDocument) }; } function asDocumentLink(item) { let result = proto.DocumentLink.create(asRange(item.range)); if (item.target) { result.target = asUri(item.target); } if (item.tooltip !== undefined) { result.tooltip = item.tooltip; } let protocolItem = item instanceof protocolDocumentLink_1.default ? item : undefined; if (protocolItem && protocolItem.data) { result.data = protocolItem.data; } return result; } function asDocumentLinkParams(textDocument) { return { textDocument: asTextDocumentIdentifier(textDocument) }; } function asCallHierarchyItem(value) { const result = { name: value.name, kind: asSymbolKind(value.kind), uri: asUri(value.uri), range: asRange(value.range), selectionRange: asRange(value.selectionRange) }; if (value.detail !== undefined && value.detail.length > 0) { result.detail = value.detail; } if (value.tags !== undefined) { result.tags = asSymbolTags(value.tags); } if (value instanceof protocolCallHierarchyItem_1.default && value.data !== undefined) { result.data = value.data; } return result; } return { asUri, asTextDocumentIdentifier, asVersionedTextDocumentIdentifier, asOpenTextDocumentParams, asChangeTextDocumentParams, asCloseTextDocumentParams, asSaveTextDocumentParams, asWillSaveTextDocumentParams, asDidCreateFilesParams, asDidRenameFilesParams, asDidDeleteFilesParams, asWillCreateFilesParams, asWillRenameFilesParams, asWillDeleteFilesParams, asTextDocumentPositionParams, asCompletionParams, asSignatureHelpParams, asWorkerPosition, asRange, asPosition, asPositions, asLocation, asDiagnosticSeverity, asDiagnosticTag, asDiagnostic, asDiagnostics, asCompletionItem, asTextEdit, asSymbolKind, asSymbolTag, asSymbolTags, asReferenceParams, asCodeAction, asCodeActionContext, asCommand, asCodeLens, asFormattingOptions, asDocumentSymbolParams, asCodeLensParams, asDocumentLink, asDocumentLinkParams, asCallHierarchyItem }; } exports.createConverter = createConverter; //# sourceMappingURL=codeConverter.js.map