vscode-languageserver
Advanced tools
Comparing version 0.10.0-pre.28 to 0.10.0-pre.29
import { LanguageServerError, MessageKind } from './languageServerError'; | ||
import { RequestType, IRequestHandler, NotificationType, INotificationHandler, ResponseError, ErrorCodes } from 'vscode-jsonrpc'; | ||
import { InitializeParams, InitializeResult, InitializeError, ShutdownParams, ExitParams, DidChangeConfigurationParams, DidOpenTextDocumentParams, DidChangeTextDocumentParams, DidCloseTextDocumentParams, DidChangeFilesParams, FileEvent, FileChangeType, PublishDiagnosticsParams, Diagnostic, Severity, Position } from './protocol'; | ||
import { ISimpleTextDocument } from './textDocuments'; | ||
export { RequestType, IRequestHandler, NotificationType, INotificationHandler, InitializeResult, InitializeError, Diagnostic, Severity, Position, FileEvent, FileChangeType, ErrorCodes, ResponseError }; | ||
import { InitializeParams, InitializeResult, InitializeError, ShutdownParams, ExitParams, DidChangeConfigurationParams, DidOpenTextDocumentParams, DidChangeTextDocumentParams, DidCloseTextDocumentParams, DidChangeFilesParams, FileEvent, FileChangeType, PublishDiagnosticsParams, Diagnostic, Severity, Position, TextDocumentIdentifier, TextDocumentPosition, HoverResult } from './protocol'; | ||
import { Event, Emitter } from './utils/events'; | ||
export { RequestType, IRequestHandler, NotificationType, INotificationHandler, ErrorCodes, ResponseError, InitializeResult, InitializeError, Diagnostic, Severity, Position, FileEvent, FileChangeType, TextDocumentIdentifier, TextDocumentPosition, HoverResult }; | ||
export { LanguageServerError, MessageKind }; | ||
export { ISimpleTextDocument }; | ||
export { Event }; | ||
import * as fm from './files'; | ||
@@ -13,14 +13,26 @@ export declare namespace Files { | ||
} | ||
export declare type Result<T> = T | Thenable<T>; | ||
export interface IValidationRequestor { | ||
single(uri: string): boolean; | ||
all(): void; | ||
export interface ITextDocument { | ||
uri: string; | ||
getText(): string; | ||
} | ||
export interface SingleFileValidator { | ||
initialize?(rootFolder: string): Result<InitializeResult | ResponseError<InitializeError>>; | ||
validate(document: ISimpleTextDocument): Result<Diagnostic[]>; | ||
onConfigurationChange?(settings: any, requestor: IValidationRequestor): void; | ||
onFileEvents?(changes: FileEvent[], requestor: IValidationRequestor): void; | ||
shutdown?(): void; | ||
export interface TextDocumentHandler { | ||
incremental?: boolean; | ||
onDidOpenTextDocument(event: DidOpenTextDocumentParams): void; | ||
onDidChangeTextDocument(event: DidChangeTextDocumentParams): void; | ||
onDidCloseTextDocument(event: DidCloseTextDocumentParams): void; | ||
} | ||
export declare class TextDocumentChangeEvent { | ||
document: ITextDocument; | ||
} | ||
export declare class TextDocuments { | ||
private _documents; | ||
private _handler; | ||
_onDidContentChange: Emitter<TextDocumentChangeEvent>; | ||
constructor(); | ||
onDidContentChange: Event<TextDocumentChangeEvent>; | ||
get(uri: string): ITextDocument; | ||
all(): ITextDocument[]; | ||
keys(): string[]; | ||
observe(connection: IConnection): void; | ||
} | ||
export interface RemoteConsole { | ||
@@ -38,2 +50,3 @@ error(message: string): any; | ||
export interface IConnection { | ||
listen(): void; | ||
onRequest<P, R, E>(type: RequestType<P, R, E>, handler: IRequestHandler<P, R, E>): void; | ||
@@ -49,18 +62,7 @@ sendNotification<P>(type: NotificationType<P>, params?: P): void; | ||
onDidChangeFiles(handler: INotificationHandler<DidChangeFilesParams>): void; | ||
onDidOpenTextDocument(handler: INotificationHandler<DidOpenTextDocumentParams>): void; | ||
onDidChangeTextDocument(handler: INotificationHandler<DidChangeTextDocumentParams>): void; | ||
onDidCloseTextDocument(handler: INotificationHandler<DidCloseTextDocumentParams>): void; | ||
onTextDocument(handler: TextDocumentHandler): void; | ||
publishDiagnostics(args: PublishDiagnosticsParams): void; | ||
onHover(handler: IRequestHandler<TextDocumentPosition, HoverResult, void>): void; | ||
dispose(): void; | ||
} | ||
export declare function createConnection(inputStream: NodeJS.ReadableStream, outputStream: NodeJS.WritableStream): IConnection; | ||
export interface IValidatorConnection { | ||
console: RemoteConsole; | ||
window: RemoteWindow; | ||
onRequest<P, R, E>(type: RequestType<P, R, E>, handler: IRequestHandler<P, R, E>): void; | ||
sendNotification<P>(type: NotificationType<P>, params?: P): void; | ||
onNotification<P>(type: NotificationType<P>, handler: INotificationHandler<P>): void; | ||
run(handler: SingleFileValidator): void; | ||
} | ||
export declare function createValidatorConnection(inputStream: NodeJS.ReadableStream, outputStream: NodeJS.WritableStream): IValidatorConnection; | ||
export declare function runSingleFileValidator(inputStream: NodeJS.ReadableStream, outputStream: NodeJS.WritableStream, handler: SingleFileValidator): void; |
314
lib/main.js
@@ -14,3 +14,4 @@ /*--------------------------------------------------------- | ||
exports.Severity = protocol_1.Severity; | ||
var textDocuments_1 = require('./textDocuments'); | ||
var events_1 = require('./utils/events'); | ||
var is = require('./utils/is'); | ||
// ------------- Reexport the API surface of the language worker API ---------------------- | ||
@@ -23,37 +24,73 @@ var fm = require('./files'); | ||
})(Files = exports.Files || (exports.Files = {})); | ||
// ------------------------- implementation of the language worker protocol --------------------------------------------- | ||
function isFunction(arg) { | ||
return Object.prototype.toString.call(arg) === '[object Function]'; | ||
} | ||
function isArray(array) { | ||
if (Array.isArray) { | ||
return Array.isArray(array); | ||
var TextDocument = (function () { | ||
function TextDocument(uri, content) { | ||
this._uri = uri; | ||
this._content = content; | ||
} | ||
if (array && typeof (array.length) === 'number' && array.constructor === Array) { | ||
return true; | ||
Object.defineProperty(TextDocument.prototype, "uri", { | ||
get: function () { | ||
return this._uri; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
TextDocument.prototype.getText = function () { | ||
return this._content; | ||
}; | ||
TextDocument.prototype.update = function (event) { | ||
this._content = event.text; | ||
}; | ||
return TextDocument; | ||
})(); | ||
var TextDocumentChangeEvent = (function () { | ||
function TextDocumentChangeEvent() { | ||
} | ||
return false; | ||
} | ||
var DocumentManager = (function () { | ||
function DocumentManager() { | ||
this.trackedDocuments = Object.create(null); | ||
return TextDocumentChangeEvent; | ||
})(); | ||
exports.TextDocumentChangeEvent = TextDocumentChangeEvent; | ||
var TextDocuments = (function () { | ||
function TextDocuments() { | ||
var _this = this; | ||
this._documents = Object.create(null); | ||
this._onDidContentChange = new events_1.Emitter(); | ||
this._handler = { | ||
onDidOpenTextDocument: function (event) { | ||
var document = new TextDocument(event.uri, event.text); | ||
_this._documents[event.uri] = document; | ||
_this._onDidContentChange.fire({ document: document }); | ||
}, | ||
onDidChangeTextDocument: function (event) { | ||
var document = _this._documents[event.uri]; | ||
document.update(event); | ||
_this._onDidContentChange.fire({ document: document }); | ||
}, | ||
onDidCloseTextDocument: function (event) { | ||
delete _this._documents[event.uri]; | ||
} | ||
}; | ||
} | ||
DocumentManager.prototype.add = function (uri, document) { | ||
this.trackedDocuments[uri] = document; | ||
Object.defineProperty(TextDocuments.prototype, "onDidContentChange", { | ||
get: function () { | ||
return this._onDidContentChange.event; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
TextDocuments.prototype.get = function (uri) { | ||
return this._documents[uri]; | ||
}; | ||
DocumentManager.prototype.remove = function (uri) { | ||
return delete this.trackedDocuments[uri]; | ||
TextDocuments.prototype.all = function () { | ||
var _this = this; | ||
return Object.keys(this._documents).map(function (key) { return _this._documents[key]; }); | ||
}; | ||
DocumentManager.prototype.get = function (uri) { | ||
return this.trackedDocuments[uri]; | ||
TextDocuments.prototype.keys = function () { | ||
return Object.keys(this._documents); | ||
}; | ||
DocumentManager.prototype.all = function () { | ||
var _this = this; | ||
return Object.keys(this.trackedDocuments).map(function (key) { return _this.trackedDocuments[key]; }); | ||
TextDocuments.prototype.observe = function (connection) { | ||
connection.onTextDocument(this._handler); | ||
}; | ||
DocumentManager.prototype.keys = function () { | ||
return Object.keys(this.trackedDocuments); | ||
}; | ||
return DocumentManager; | ||
return TextDocuments; | ||
})(); | ||
exports.TextDocuments = TextDocuments; | ||
// ------------------------- implementation of the language server protocol --------------------------------------------- | ||
var ErrorMessageTracker = (function () { | ||
@@ -130,2 +167,10 @@ function ErrorMessageTracker() { | ||
var remoteWindow = new RemoteWindowImpl(connection); | ||
function asThenable(value) { | ||
if (is.thenable(value)) { | ||
return value; | ||
} | ||
else { | ||
return Promise.resolve(value); | ||
} | ||
} | ||
var shutdownHandler = null; | ||
@@ -141,3 +186,28 @@ connection.onRequest(protocol_1.ShutdownRequest.type, function (params) { | ||
}); | ||
var incrementalSync = undefined; | ||
var initializeHandler = null; | ||
connection.onRequest(protocol_1.InitializeRequest.type, function (params) { | ||
if (initializeHandler) { | ||
var result_1 = initializeHandler(params); | ||
if (is.undefined(incrementalSync)) { | ||
return result_1; | ||
} | ||
return asThenable(result_1).then(function (value) { | ||
if (value instanceof vscode_jsonrpc_1.ResponseError) { | ||
return value; | ||
} | ||
var capabilities = value.capabilities; | ||
if (capabilities) { | ||
capabilities.incrementalTextDocumentSync = incrementalSync; | ||
} | ||
return value; | ||
}); | ||
} | ||
else { | ||
var result_2 = { capabilities: { incrementalTextDocumentSync: false } }; | ||
return result_2; | ||
} | ||
}); | ||
var result = { | ||
listen: function () { return connection.listen(); }, | ||
onRequest: function (type, handler) { return connection.onRequest(type, handler); }, | ||
@@ -153,6 +223,12 @@ sendNotification: function (type, params) { return connection.sendNotification(type, params); }, | ||
onDidChangeFiles: function (handler) { return connection.onNotification(protocol_1.DidChangeFilesNotification.type, handler); }, | ||
onDidOpenTextDocument: function (handler) { return connection.onNotification(protocol_1.DidOpenTextDocumentNotification.type, handler); }, | ||
onDidChangeTextDocument: function (handler) { return connection.onNotification(protocol_1.DidChangeTextDocumentNotification.type, handler); }, | ||
onDidCloseTextDocument: function (handler) { return connection.onNotification(protocol_1.DidCloseTextDocumentNotification.type, handler); }, | ||
onTextDocument: function (handler) { | ||
if (handler.incremental === true || handler.incremental === false) { | ||
incrementalSync = handler.incremental; | ||
} | ||
connection.onNotification(protocol_1.DidOpenTextDocumentNotification.type, handler.onDidOpenTextDocument); | ||
connection.onNotification(protocol_1.DidChangeTextDocumentNotification.type, handler.onDidChangeTextDocument); | ||
connection.onNotification(protocol_1.DidCloseTextDocumentNotification.type, handler.onDidCloseTextDocument); | ||
}, | ||
publishDiagnostics: function (params) { return connection.sendNotification(protocol_1.PublishDiagnosticsNotification.type, params); }, | ||
onHover: function (handler) { return connection.onRequest(protocol_1.HoverRequest.type, handler); }, | ||
dispose: function () { return connection.dispose(); } | ||
@@ -163,177 +239,1 @@ }; | ||
exports.createConnection = createConnection; | ||
var ValidationRequestor = (function () { | ||
function ValidationRequestor(documents) { | ||
this.documents = documents; | ||
this._toValidate = Object.create(null); | ||
} | ||
Object.defineProperty(ValidationRequestor.prototype, "toValidate", { | ||
get: function () { | ||
var _this = this; | ||
return Object.keys(this._toValidate).map(function (key) { return _this._toValidate[key]; }); | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
ValidationRequestor.prototype.all = function () { | ||
var _this = this; | ||
this.documents.keys().forEach(function (key) { return _this._toValidate[key] = _this.documents.get(key); }); | ||
}; | ||
ValidationRequestor.prototype.single = function (uri) { | ||
var document = this.documents.get(uri); | ||
if (document) { | ||
this._toValidate[uri] = document; | ||
} | ||
return !!document; | ||
}; | ||
return ValidationRequestor; | ||
})(); | ||
function createValidatorConnection(inputStream, outputStream) { | ||
var connection = createConnection(inputStream, outputStream); | ||
var documents = new DocumentManager(); | ||
function run(handler) { | ||
var rootFolder; | ||
function doProcess(result, complete, error) { | ||
if (isFunction(result.then)) { | ||
return result.then(complete, error); | ||
} | ||
else { | ||
return complete(result); | ||
} | ||
} | ||
function safeRunner(values, func) { | ||
var messageTracker = new ErrorMessageTracker(); | ||
var runSingle = function (value) { | ||
try { | ||
func(value); | ||
} | ||
catch (error) { | ||
if (error instanceof languageServerError_1.LanguageServerError) { | ||
var workerError = error; | ||
switch (workerError.messageKind) { | ||
case languageServerError_1.MessageKind.Show: | ||
messageTracker.add(workerError.message); | ||
break; | ||
case languageServerError_1.MessageKind.Log: | ||
logSafeRunnerMessage(workerError.message); | ||
break; | ||
} | ||
} | ||
else { | ||
logSafeRunnerMessage(error.message); | ||
} | ||
} | ||
}; | ||
if (isArray(values)) { | ||
for (var _i = 0, _a = values; _i < _a.length; _i++) { | ||
var value = _a[_i]; | ||
runSingle(value); | ||
} | ||
} | ||
else { | ||
runSingle(values); | ||
} | ||
messageTracker.publish(connection); | ||
} | ||
function logSafeRunnerMessage(message) { | ||
if (message) { | ||
connection.console.error("Safe Runner failed with message: " + message); | ||
} | ||
else { | ||
connection.console.error('Safe Runner failed unexpectedly.'); | ||
} | ||
} | ||
function validate(document) { | ||
var result = handler.validate(document); | ||
doProcess(result, function (diagnostics) { | ||
connection.publishDiagnostics({ | ||
uri: document.uri, | ||
diagnostics: diagnostics | ||
}); | ||
}, function (error) { | ||
// We need a log event to tell the client that a diagnostic | ||
// failed. | ||
}); | ||
} | ||
function createInitializeResult(initArgs) { | ||
var resultCapabilities = { | ||
incrementalTextDocumentSync: false | ||
}; | ||
return { capabilities: resultCapabilities }; | ||
} | ||
connection.onInitialize(function (initArgs) { | ||
rootFolder = initArgs.rootFolder; | ||
if (isFunction(handler.initialize)) { | ||
return doProcess(handler.initialize(rootFolder), function (resultOrError) { | ||
if (resultOrError) { | ||
return resultOrError; | ||
} | ||
else { | ||
return createInitializeResult(initArgs); | ||
} | ||
}); | ||
} | ||
else { | ||
return createInitializeResult(initArgs); | ||
} | ||
}); | ||
connection.onShutdown(function (params) { | ||
if (isFunction(handler.shutdown)) { | ||
handler.shutdown(); | ||
} | ||
return undefined; | ||
}); | ||
connection.onExit(function () { | ||
process.exit(0); | ||
}); | ||
connection.onDidOpenTextDocument(function (event) { | ||
var document = new textDocuments_1.SimpleTextDocument(event.uri, event.text); | ||
documents.add(event.uri, document); | ||
process.nextTick(function () { return safeRunner(document, validate); }); | ||
}); | ||
connection.onDidChangeTextDocument(function (event) { | ||
var document = documents.get(event.uri); | ||
if (document) { | ||
document.setText(event.text); | ||
process.nextTick(function () { return safeRunner(document, validate); }); | ||
} | ||
}); | ||
connection.onDidCloseTextDocument(function (event) { | ||
documents.remove(event.uri); | ||
}); | ||
connection.onDidChangeConfiguration(function (eventBody) { | ||
var settings = eventBody.settings; | ||
var requestor = new ValidationRequestor(documents); | ||
if (isFunction(handler.onConfigurationChange)) { | ||
handler.onConfigurationChange(settings, requestor); | ||
} | ||
else { | ||
requestor.all(); | ||
} | ||
process.nextTick(function () { return safeRunner(requestor.toValidate, validate); }); | ||
}); | ||
connection.onDidChangeFiles(function (args) { | ||
var requestor = new ValidationRequestor(documents); | ||
if (isFunction(handler.onFileEvents)) { | ||
handler.onFileEvents(args.changes, requestor); | ||
} | ||
else { | ||
requestor.all(); | ||
} | ||
process.nextTick(function () { return safeRunner(requestor.toValidate, validate); }); | ||
}); | ||
} | ||
var result = { | ||
onRequest: function (type, handler) { return connection.onRequest(type, handler); }, | ||
sendNotification: function (type, params) { return connection.sendNotification(type, params); }, | ||
onNotification: function (type, handler) { return connection.onNotification(type, handler); }, | ||
get console() { return connection.console; }, | ||
get window() { return connection.window; }, | ||
run: run | ||
}; | ||
return result; | ||
} | ||
exports.createValidatorConnection = createValidatorConnection; | ||
function runSingleFileValidator(inputStream, outputStream, handler) { | ||
createValidatorConnection(inputStream, outputStream).run(handler); | ||
} | ||
exports.runSingleFileValidator = runSingleFileValidator; |
@@ -6,2 +6,3 @@ import { RequestType, NotificationType } from 'vscode-jsonrpc'; | ||
incrementalTextDocumentSync?: boolean; | ||
hoverProvider?: boolean; | ||
} | ||
@@ -108,2 +109,12 @@ /** | ||
} | ||
export interface HTMLContentElement { | ||
formattedText?: string; | ||
text?: string; | ||
className?: string; | ||
style?: string; | ||
customStyle?: any; | ||
tagName?: string; | ||
children?: HTMLContentElement[]; | ||
isText?: boolean; | ||
} | ||
export interface TextDocumentIdentifier { | ||
@@ -115,2 +126,8 @@ /** | ||
} | ||
export interface TextDocumentPosition extends TextDocumentIdentifier { | ||
/** | ||
* The position inside the text document. | ||
*/ | ||
position: Position; | ||
} | ||
/** | ||
@@ -219,1 +236,17 @@ * The document event is send from the client to the worker to signal | ||
} | ||
export declare namespace HoverRequest { | ||
let type: RequestType<TextDocumentPosition, HoverResult, void>; | ||
} | ||
/** | ||
* The result of a hove request. | ||
*/ | ||
export interface HoverResult { | ||
/** | ||
* The hover's content | ||
*/ | ||
content: string | HTMLContentElement; | ||
/** | ||
* An optional range | ||
*/ | ||
range?: Range; | ||
} |
@@ -93,3 +93,3 @@ /*--------------------------------------------------------- | ||
(function (PublishDiagnosticsNotification) { | ||
PublishDiagnosticsNotification.type = { method: 'document/publishDiagnostics' }; | ||
PublishDiagnosticsNotification.type = { method: 'textDocument/publishDiagnostics' }; | ||
})(PublishDiagnosticsNotification = exports.PublishDiagnosticsNotification || (exports.PublishDiagnosticsNotification = {})); | ||
@@ -103,1 +103,6 @@ var Severity; | ||
})(Severity = exports.Severity || (exports.Severity = {})); | ||
//---- Hover support ------------------------------- | ||
var HoverRequest; | ||
(function (HoverRequest) { | ||
HoverRequest.type = { method: 'textDocument/hover' }; | ||
})(HoverRequest = exports.HoverRequest || (exports.HoverRequest = {})); |
@@ -5,22 +5,1 @@ /*--------------------------------------------------------- | ||
'use strict'; | ||
var SimpleTextDocument = (function () { | ||
function SimpleTextDocument(uri, content) { | ||
this._uri = uri; | ||
this._content = content; | ||
} | ||
Object.defineProperty(SimpleTextDocument.prototype, "uri", { | ||
get: function () { | ||
return this._uri; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
SimpleTextDocument.prototype.getText = function () { | ||
return this._content; | ||
}; | ||
SimpleTextDocument.prototype.setText = function (content) { | ||
this._content = content; | ||
}; | ||
return SimpleTextDocument; | ||
})(); | ||
exports.SimpleTextDocument = SimpleTextDocument; |
{ | ||
"name": "vscode-languageserver", | ||
"description": "Language server implementation for node", | ||
"version": "0.10.0-pre.28", | ||
"version": "0.10.0-pre.29", | ||
"author": "Microsoft Corporation", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
54587
23
1287