javascript-typescript-langserver
Version:
Implementation of the Language Server Protocol for JavaScript and TypeScript
134 lines • 5.42 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const opentracing_1 = require("opentracing");
const rxjs_1 = require("rxjs");
const util_1 = require("util");
const messages_1 = require("vscode-jsonrpc/lib/messages");
const tracing_1 = require("./tracing");
/**
* Provides an interface to call methods on the remote client.
* Methods are named after the camelCase version of the LSP method name
*/
class RemoteLanguageClient {
/**
* @param input MessageEmitter to listen on for responses
* @param output MessageWriter to write requests/notifications to
*/
constructor(input, output) {
this.input = input;
this.output = output;
/** The next request ID to use */
this.idCounter = 1;
}
/**
* Sends a Request
*
* @param method The method to call
* @param params The params to pass to the method
* @return Emits the value of the result field or the error
*/
request(method, params, childOf = new opentracing_1.Span()) {
return tracing_1.traceObservable(`Request ${method}`, childOf, span => {
span.setTag('params', util_1.inspect(params));
return new rxjs_1.Observable(subscriber => {
// Generate a request ID
const id = this.idCounter++;
const message = { jsonrpc: '2.0', method, id, params, meta: {} };
childOf.tracer().inject(span, opentracing_1.FORMAT_TEXT_MAP, message.meta);
// Send request
this.output.write(message);
let receivedResponse = false;
// Subscribe to message events
const messageSub = rxjs_1.Observable.fromEvent(this.input, 'message')
// Find response message with the correct ID
.filter(msg => messages_1.isResponseMessage(msg) && msg.id === id)
.take(1)
// Emit result or error
.map((msg) => {
receivedResponse = true;
if (msg.error) {
throw Object.assign(new Error(msg.error.message), msg.error);
}
return msg.result;
})
// Forward events to subscriber
.subscribe(subscriber);
// Handler for unsubscribe()
return () => {
// Unsubscribe message event subscription (removes listener)
messageSub.unsubscribe();
if (!receivedResponse) {
// Send LSP $/cancelRequest to client
this.notify('$/cancelRequest', { id });
}
};
});
});
}
/**
* Sends a Notification
*
* @param method The method to notify
* @param params The params to pass to the method
*/
notify(method, params) {
const message = { jsonrpc: '2.0', method, params };
this.output.write(message);
}
/**
* The content request is sent from the server to the client to request the current content of
* any text document. This allows language servers to operate without accessing the file system
* directly.
*/
textDocumentXcontent(params, childOf = new opentracing_1.Span()) {
return this.request('textDocument/xcontent', params, childOf);
}
/**
* The files request is sent from the server to the client to request a list of all files in the
* workspace or inside the directory of the `base` parameter, if given.
*/
workspaceXfiles(params, childOf = new opentracing_1.Span()) {
return this.request('workspace/xfiles', params, childOf);
}
/**
* The log message notification is sent from the server to the client to ask
* the client to log a particular message.
*/
windowLogMessage(params) {
this.notify('window/logMessage', params);
}
/**
* The cache get request is sent from the server to the client to request the value of a cache
* item identified by the provided key.
*/
xcacheGet(params, childOf = new opentracing_1.Span()) {
return this.request('xcache/get', params, childOf);
}
/**
* The cache set notification is sent from the server to the client to set the value of a cache
* item identified by the provided key. This is a intentionally notification and not a request
* because the server is not supposed to act differently if the cache set failed.
*/
xcacheSet(params) {
this.notify('xcache/set', params);
}
/**
* Diagnostics are sent from the server to the client to notify the user of errors/warnings
* in a source file
* @param params The diagnostics to send to the client
*/
textDocumentPublishDiagnostics(params) {
this.notify('textDocument/publishDiagnostics', params);
}
/**
* The workspace/applyEdit request is sent from the server to the client to modify resource on
* the client side.
*
* @param params The edits to apply.
*/
workspaceApplyEdit(params, childOf = new opentracing_1.Span()) {
return this.request('workspace/applyEdit', params, childOf);
}
}
exports.RemoteLanguageClient = RemoteLanguageClient;
//# sourceMappingURL=lang-handler.js.map
;