diff --git a/packages/client/src/converters.ts b/packages/client/src/converters.ts new file mode 100644 index 00000000..b806d4c7 --- /dev/null +++ b/packages/client/src/converters.ts @@ -0,0 +1,155 @@ +import * as p2c from 'vscode-languageclient/lib/common/protocolConverter'; +import * as c2p from 'vscode-languageclient/lib/common/codeConverter'; +import { WillSaveTextDocumentParams } from 'vscode-languageclient'; +import * as code from 'vscode'; +import * as proto from 'vscode-languageserver-protocol'; + +type NotAPromise = T extends object & { then(onfulfilled: infer F): any } ? F extends ((value: infer V, ...args: any) => any) ? NotAPromise : never : T; + +function bypassConversion(param: any): NotAPromise { + return param +} + +function toPromise(param: any): Promise { + return Promise.resolve(param) +} + +export class MonacoP2CConverter implements p2c.Converter { + constructor(private delegate: p2c.Converter) { } + + asUri = this.delegate.asUri.bind(this.delegate) + asDocumentSelector = bypassConversion + asPosition = bypassConversion + asRange = bypassConversion + asRanges = toPromise + asDiagnostic = bypassConversion + asDiagnostics = toPromise + asDiagnosticSeverity = bypassConversion + asDiagnosticTag = bypassConversion + asHover = bypassConversion + asCompletionResult = bypassConversion + asCompletionItem = bypassConversion + asTextEdit = bypassConversion + asTextEdits = bypassConversion + asSignatureHelp = bypassConversion + asSignatureInformation = toPromise + asSignatureInformations = toPromise + asParameterInformation = bypassConversion + asParameterInformations = toPromise + asLocation = bypassConversion + asDeclarationResult = bypassConversion + asDefinitionResult = bypassConversion + asReferences = bypassConversion + asDocumentHighlightKind = bypassConversion + asDocumentHighlight = bypassConversion + asDocumentHighlights = bypassConversion + asSymbolKind = bypassConversion + asSymbolTag = bypassConversion + asSymbolTags = bypassConversion + asSymbolInformation = bypassConversion + asSymbolInformations = bypassConversion + asDocumentSymbol = bypassConversion + asDocumentSymbols = bypassConversion + asCommand = bypassConversion + asCommands = bypassConversion + asCodeAction = bypassConversion + asCodeActionKind = bypassConversion + asCodeActionKinds = bypassConversion + asCodeActionResult = toPromise + asCodeLens = bypassConversion + asCodeLenses = bypassConversion + asWorkspaceEdit = bypassConversion + asDocumentLink = bypassConversion + asDocumentLinks = bypassConversion + asColor = bypassConversion + asColorInformation = bypassConversion + asColorInformations = bypassConversion + asColorPresentation = bypassConversion + asColorPresentations = bypassConversion + asFoldingRangeKind = bypassConversion + asFoldingRange = bypassConversion + asFoldingRanges = bypassConversion + asSelectionRange = bypassConversion + asSelectionRanges = bypassConversion + asInlineValue = bypassConversion + asInlineValues = bypassConversion + asInlayHint = toPromise + asInlayHints = bypassConversion + asSemanticTokensLegend = bypassConversion + asSemanticTokens = bypassConversion + asSemanticTokensEdit = bypassConversion + asSemanticTokensEdits = bypassConversion + asCallHierarchyItem = bypassConversion + asCallHierarchyItems = bypassConversion + asCallHierarchyIncomingCall = toPromise + asCallHierarchyIncomingCalls = bypassConversion + asCallHierarchyOutgoingCall = toPromise + asCallHierarchyOutgoingCalls = bypassConversion + asLinkedEditingRanges = bypassConversion + asTypeHierarchyItem = bypassConversion + asTypeHierarchyItems = bypassConversion + asGlobPattern = bypassConversion +} + +export class MonacoC2PConverter implements c2p.Converter { + constructor(private delegate: c2p.Converter) { } + + asUri = this.delegate.asUri.bind(this.delegate) + asTextDocumentItem = bypassConversion + asTextDocumentIdentifier = bypassConversion + asVersionedTextDocumentIdentifier = bypassConversion + asOpenTextDocumentParams = this.delegate.asOpenTextDocumentParams.bind(this.delegate) + asChangeTextDocumentParams = this.delegate.asChangeTextDocumentParams.bind(this.delegate) + asCloseTextDocumentParams = this.delegate.asCloseTextDocumentParams.bind(this.delegate) + asSaveTextDocumentParams = this.delegate.asSaveTextDocumentParams.bind(this.delegate) + asWillSaveTextDocumentParams = (event: code.TextDocumentWillSaveEvent): WillSaveTextDocumentParams => { + return { + textDocument: this.delegate.asTextDocumentIdentifier(event.document), + reason: event.reason + } + } + asDidCreateFilesParams = this.delegate.asDidCreateFilesParams.bind(this.delegate) + asDidRenameFilesParams = this.delegate.asDidRenameFilesParams.bind(this.delegate) + asDidDeleteFilesParams = this.delegate.asDidDeleteFilesParams.bind(this.delegate) + asWillCreateFilesParams = this.delegate.asWillCreateFilesParams.bind(this.delegate) + asWillRenameFilesParams = this.delegate.asWillRenameFilesParams.bind(this.delegate) + asWillDeleteFilesParams = this.delegate.asWillDeleteFilesParams.bind(this.delegate) + asTextDocumentPositionParams = this.delegate.asTextDocumentPositionParams.bind(this.delegate) + asCompletionParams = (textDocument: code.TextDocument, position: code.Position, context: code.CompletionContext): proto.CompletionParams => { + return { + textDocument: this.delegate.asTextDocumentIdentifier(textDocument), + position, + context + } as proto.CompletionParams + } + asSignatureHelpParams = this.delegate.asSignatureHelpParams.bind(this.delegate) + asWorkerPosition = bypassConversion + asPosition = bypassConversion + asPositions = toPromise + asRange = bypassConversion + asLocation = bypassConversion + asDiagnosticSeverity = bypassConversion + asDiagnosticTag = bypassConversion + asDiagnostic = bypassConversion + asDiagnostics = toPromise + asCompletionItem = bypassConversion + asSymbolKind = bypassConversion + asSymbolTag = bypassConversion + asSymbolTags = bypassConversion + asTextEdit = bypassConversion + asReferenceParams = this.delegate.asReferenceParams.bind(this.delegate) + asCodeAction = toPromise + asCodeActionContext = toPromise + asInlineValueContext = bypassConversion + asCommand = bypassConversion + asCodeLens = bypassConversion + asFormattingOptions = bypassConversion + asDocumentSymbolParams = this.delegate.asDocumentSymbolParams.bind(this.delegate) + asCodeLensParams = this.delegate.asCodeLensParams.bind(this.delegate) + asDocumentLink = bypassConversion + asDocumentLinkParams = this.delegate.asDocumentLinkParams.bind(this.delegate) + asCallHierarchyItem = bypassConversion + asTypeHierarchyItem = bypassConversion + asWorkspaceSymbol = bypassConversion + asInlayHint = bypassConversion +} diff --git a/packages/client/src/monaco-language-client.ts b/packages/client/src/monaco-language-client.ts index 9927b9fe..5fc8b86f 100644 --- a/packages/client/src/monaco-language-client.ts +++ b/packages/client/src/monaco-language-client.ts @@ -8,10 +8,10 @@ import { import * as p2c from 'vscode-languageclient/lib/common/protocolConverter'; import * as c2p from 'vscode-languageclient/lib/common/codeConverter'; import { IConnectionProvider } from './connection'; -import { CompletionParams, WillSaveTextDocumentParams } from './services' export * from 'vscode-languageclient/lib/common/client'; import type * as vscode from 'vscode' +import { MonacoC2PConverter, MonacoP2CConverter } from "./converters"; export class MonacoLanguageClient extends BaseLanguageClient { @@ -28,42 +28,8 @@ export class MonacoLanguageClient extends BaseLanguageClient { _p2c: p2c.Converter, _c2p: c2p.Converter } = this as any; - self._p2c = new Proxy(self._p2c, { - get: (target: any, prop: string) => { - if (prop === 'asUri') { - return target[prop]; - } - return MonacoLanguageClient.bypassConversion; - } - }); - self._c2p = new Proxy(self._c2p, { - get: (target: c2p.Converter, prop: string) => { - if (prop === 'asUri') { - return target[prop]; - } - if (prop === 'asCompletionParams') { - return (textDocument: any, position: any, context: any): CompletionParams => { - return { - textDocument: target.asTextDocumentIdentifier(textDocument), - position, - context - } - } - } - if (prop === 'asWillSaveTextDocumentParams') { - return (event: any): WillSaveTextDocumentParams => { - return { - textDocument: target.asTextDocumentIdentifier(event.document), - reason: event.reason - } - } - } - if (prop.endsWith('Params')) { - return (target as any)[prop]; - } - return MonacoLanguageClient.bypassConversion; - } - }); + self._p2c = new MonacoP2CConverter(self._p2c); + self._c2p = new MonacoC2PConverter(self._c2p); } protected createMessageTransports(encoding: string): Promise {