From 1f7ff07c88363a909736489c813de6a3fd993187 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Sat, 27 Aug 2016 10:02:08 -0700 Subject: [PATCH] Fix whitespace in server.ts --- src/omnisharp/server.ts | 1012 +++++++++++++++++++-------------------- 1 file changed, 506 insertions(+), 506 deletions(-) diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index 72b6318..f760b35 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -22,17 +22,17 @@ import TelemetryReporter from 'vscode-extension-telemetry'; import * as vscode from 'vscode'; enum ServerState { - Starting, - Started, - Stopped + Starting, + Started, + Stopped } interface Request { - path: string; - data?: any; - onSuccess(value: any): void; - onError(err: any): void; - _enqueued: number; + path: string; + data?: any; + onSuccess(value: any): void; + onError(err: any): void; + _enqueued: number; } module Events { @@ -54,7 +54,7 @@ module Events { export const MsBuildProjectDiagnostics = 'MsBuildProjectDiagnostics'; - export const BeforeServerInstall = 'BeforeServerInstall'; + export const BeforeServerInstall = 'BeforeServerInstall'; export const BeforeServerStart = 'BeforeServerStart'; export const ServerStart = 'ServerStart'; export const ServerStop = 'ServerStop'; @@ -70,43 +70,43 @@ export abstract class OmnisharpServer { private _reporter: TelemetryReporter; private _delayTrackers: { [requestName: string]: DelayTracker }; - private _telemetryIntervalId: NodeJS.Timer = undefined; + private _telemetryIntervalId: NodeJS.Timer = undefined; - private _eventBus = new EventEmitter(); - private _state: ServerState = ServerState.Stopped; - private _launchTarget: LaunchTarget; - private _queue: Request[] = []; - private _isProcessingQueue = false; - private _channel: vscode.OutputChannel; - protected _logger: Logger; + private _eventBus = new EventEmitter(); + private _state: ServerState = ServerState.Stopped; + private _launchTarget: LaunchTarget; + private _queue: Request[] = []; + private _isProcessingQueue = false; + private _channel: vscode.OutputChannel; + protected _logger: Logger; - private _isDebugEnable: boolean = false; + private _isDebugEnable: boolean = false; - protected _serverProcess: ChildProcess; - protected _extraArgs: string[]; + protected _serverProcess: ChildProcess; + protected _extraArgs: string[]; - constructor(reporter: TelemetryReporter) { - this._extraArgs = []; + constructor(reporter: TelemetryReporter) { + this._extraArgs = []; this._reporter = reporter; - this._channel = vscode.window.createOutputChannel('OmniSharp Log'); - this._logger = new Logger(message => this._channel.append(message)); - } + this._channel = vscode.window.createOutputChannel('OmniSharp Log'); + this._logger = new Logger(message => this._channel.append(message)); + } - public isRunning(): boolean { - return this._state === ServerState.Started; - } + public isRunning(): boolean { + return this._state === ServerState.Started; + } - private _getState(): ServerState { - return this._state; - } + private _getState(): ServerState { + return this._state; + } - private _setState(value: ServerState): void { - if (typeof value !== 'undefined' && value !== this._state) { - this._state = value; - this._fireEvent(Events.StateChanged, this._state); - } - } + private _setState(value: ServerState): void { + if (typeof value !== 'undefined' && value !== this._state) { + this._state = value; + this._fireEvent(Events.StateChanged, this._state); + } + } private _recordRequestDelay(requestName: string, elapsedTime: number) { let tracker = this._delayTrackers[requestName]; @@ -119,593 +119,593 @@ export abstract class OmnisharpServer { } private _reportTelemetry() { - const delayTrackers = this._delayTrackers; + const delayTrackers = this._delayTrackers; for (const path in delayTrackers) { - const tracker = delayTrackers[path]; + const tracker = delayTrackers[path]; const eventName = 'omnisharp' + path; - if (tracker.hasMeasures()) { - const measures = tracker.getMeasures(); - tracker.clearMeasures(); + if (tracker.hasMeasures()) { + const measures = tracker.getMeasures(); + tracker.clearMeasures(); - this._reporter.sendTelemetryEvent(eventName, null, measures); - } + this._reporter.sendTelemetryEvent(eventName, null, measures); + } } } - public getSolutionPathOrFolder(): string { - return this._launchTarget - ? this._launchTarget.target - : undefined; - } + public getSolutionPathOrFolder(): string { + return this._launchTarget + ? this._launchTarget.target + : undefined; + } - public getChannel(): vscode.OutputChannel { - return this._channel; - } + public getChannel(): vscode.OutputChannel { + return this._channel; + } - public isDebugEnable(): boolean { - return this._isDebugEnable; - } + public isDebugEnable(): boolean { + return this._isDebugEnable; + } - // --- eventing + // --- eventing - public onStdout(listener: (e: string) => any, thisArg?: any) { - return this._addListener(Events.StdOut, listener, thisArg); - } + public onStdout(listener: (e: string) => any, thisArg?: any) { + return this._addListener(Events.StdOut, listener, thisArg); + } - public onStderr(listener: (e: string) => any, thisArg?: any) { - return this._addListener(Events.StdErr, listener, thisArg); - } + public onStderr(listener: (e: string) => any, thisArg?: any) { + return this._addListener(Events.StdErr, listener, thisArg); + } - public onError(listener: (e: protocol.ErrorMessage) => any, thisArg?: any) { - return this._addListener(Events.Error, listener, thisArg); - } + public onError(listener: (e: protocol.ErrorMessage) => any, thisArg?: any) { + return this._addListener(Events.Error, listener, thisArg); + } - public onServerError(listener: (err: any) => any, thisArg?: any) { - return this._addListener(Events.ServerError, listener, thisArg); - } + public onServerError(listener: (err: any) => any, thisArg?: any) { + return this._addListener(Events.ServerError, listener, thisArg); + } - public onUnresolvedDependencies(listener: (e: protocol.UnresolvedDependenciesMessage) => any, thisArg?: any) { - return this._addListener(Events.UnresolvedDependencies, listener, thisArg); - } + public onUnresolvedDependencies(listener: (e: protocol.UnresolvedDependenciesMessage) => any, thisArg?: any) { + return this._addListener(Events.UnresolvedDependencies, listener, thisArg); + } - public onBeforePackageRestore(listener: () => any, thisArg?: any) { - return this._addListener(Events.PackageRestoreStarted, listener, thisArg); - } + public onBeforePackageRestore(listener: () => any, thisArg?: any) { + return this._addListener(Events.PackageRestoreStarted, listener, thisArg); + } - public onPackageRestore(listener: () => any, thisArg?: any) { - return this._addListener(Events.PackageRestoreFinished, listener, thisArg); - } + public onPackageRestore(listener: () => any, thisArg?: any) { + return this._addListener(Events.PackageRestoreFinished, listener, thisArg); + } - public onProjectChange(listener: (e: protocol.ProjectInformationResponse) => any, thisArg?: any) { - return this._addListener(Events.ProjectChanged, listener, thisArg); - } + public onProjectChange(listener: (e: protocol.ProjectInformationResponse) => any, thisArg?: any) { + return this._addListener(Events.ProjectChanged, listener, thisArg); + } - public onProjectAdded(listener: (e: protocol.ProjectInformationResponse) => any, thisArg?: any) { - return this._addListener(Events.ProjectAdded, listener, thisArg); - } + public onProjectAdded(listener: (e: protocol.ProjectInformationResponse) => any, thisArg?: any) { + return this._addListener(Events.ProjectAdded, listener, thisArg); + } - public onProjectRemoved(listener: (e: protocol.ProjectInformationResponse) => any, thisArg?: any) { - return this._addListener(Events.ProjectRemoved, listener, thisArg); - } + public onProjectRemoved(listener: (e: protocol.ProjectInformationResponse) => any, thisArg?: any) { + return this._addListener(Events.ProjectRemoved, listener, thisArg); + } - public onMsBuildProjectDiagnostics(listener: (e: protocol.MSBuildProjectDiagnostics) => any, thisArg?: any) { - return this._addListener(Events.MsBuildProjectDiagnostics, listener, thisArg); - } + public onMsBuildProjectDiagnostics(listener: (e: protocol.MSBuildProjectDiagnostics) => any, thisArg?: any) { + return this._addListener(Events.MsBuildProjectDiagnostics, listener, thisArg); + } - public onBeforeServerInstall(listener: () => any) { - return this._addListener(Events.BeforeServerInstall, listener); - } + public onBeforeServerInstall(listener: () => any) { + return this._addListener(Events.BeforeServerInstall, listener); + } - public onBeforeServerStart(listener: (e: string) => any) { - return this._addListener(Events.BeforeServerStart, listener); - } + public onBeforeServerStart(listener: (e: string) => any) { + return this._addListener(Events.BeforeServerStart, listener); + } - public onServerStart(listener: (e: string) => any) { - return this._addListener(Events.ServerStart, listener); - } + public onServerStart(listener: (e: string) => any) { + return this._addListener(Events.ServerStart, listener); + } - public onServerStop(listener: () => any) { - return this._addListener(Events.ServerStop, listener); - } + public onServerStop(listener: () => any) { + return this._addListener(Events.ServerStop, listener); + } - public onMultipleLaunchTargets(listener: (targets: LaunchTarget[]) => any, thisArg?: any) { - return this._addListener(Events.MultipleLaunchTargets, listener, thisArg); - } + public onMultipleLaunchTargets(listener: (targets: LaunchTarget[]) => any, thisArg?: any) { + return this._addListener(Events.MultipleLaunchTargets, listener, thisArg); + } - public onOmnisharpStart(listener: () => any) { - return this._addListener(Events.Started, listener); - } + public onOmnisharpStart(listener: () => any) { + return this._addListener(Events.Started, listener); + } - private _addListener(event: string, listener: (e: any) => any, thisArg?: any): vscode.Disposable { - listener = thisArg ? listener.bind(thisArg) : listener; - this._eventBus.addListener(event, listener); - return new vscode.Disposable(() => this._eventBus.removeListener(event, listener)); - } + private _addListener(event: string, listener: (e: any) => any, thisArg?: any): vscode.Disposable { + listener = thisArg ? listener.bind(thisArg) : listener; + this._eventBus.addListener(event, listener); + return new vscode.Disposable(() => this._eventBus.removeListener(event, listener)); + } - protected _fireEvent(event: string, args: any): void { - this._eventBus.emit(event, args); - } + protected _fireEvent(event: string, args: any): void { + this._eventBus.emit(event, args); + } - // --- start, stop, and connect + // --- start, stop, and connect - private _start(launchTarget: LaunchTarget): Promise { - const options = readOptions(); + private _start(launchTarget: LaunchTarget): Promise { + const options = readOptions(); - let flavor: omnisharp.Flavor; - if (options.path !== undefined && options.useMono === true) { - flavor = omnisharp.Flavor.Mono; - } - else { - flavor = getDefaultFlavor(launchTarget.kind); - } - - return this._getServerPath(flavor).then(serverPath => { - this._setState(ServerState.Starting); - this._launchTarget = launchTarget; - - const solutionPath = launchTarget.target; - const cwd = dirname(solutionPath); - let args = [ - '-s', solutionPath, - '--hostPID', process.pid.toString(), - 'DotNet:enablePackageRestore=false' - ]; - - if (options.loggingLevel === 'verbose') { - args.push('-v'); - } - - args = args.concat(this._extraArgs); - - this._logger.appendLine(`Starting OmniSharp server at ${new Date().toLocaleString()}`); - this._logger.increaseIndent(); - this._logger.appendLine(`Target: ${solutionPath}`); - this._logger.decreaseIndent(); - this._logger.appendLine(); - - this._fireEvent(Events.BeforeServerStart, solutionPath); - - return launchOmniSharp({serverPath, flavor, cwd, args}).then(value => { - if (value.usingMono) { - this._logger.appendLine(`OmniSharp server started wth Mono`); - } - else { - this._logger.appendLine(`OmniSharp server started`); - } - - this._logger.increaseIndent(); - this._logger.appendLine(`Path: ${value.command}`); - this._logger.appendLine(`PID: ${value.process.pid}`); - this._logger.decreaseIndent(); - this._logger.appendLine(); - - this._serverProcess = value.process; - this._delayTrackers = {}; - this._setState(ServerState.Started); - this._fireEvent(Events.ServerStart, solutionPath); - - return this._doConnect(); - }).then(() => { - return vscode.commands.getCommands() - .then(commands => { - if (commands.find(c => c === 'vscode.startDebug')) { - this._isDebugEnable = true; - } - }); - }).then(() => { - // Start telemetry reporting - this._telemetryIntervalId = setInterval(() => this._reportTelemetry(), TelemetryReportingDelay); - }).then(() => { - this._processQueue(); - }, err => { - this._fireEvent(Events.ServerError, err); - this._setState(ServerState.Stopped); - throw err; - }); - }); - } - - protected abstract _doConnect(): Promise; - - public stop(): Promise { - - let ret: Promise; - - if (this._telemetryIntervalId !== undefined) { - // Stop reporting telemetry - clearInterval(this._telemetryIntervalId); - this._telemetryIntervalId = undefined; - this._reportTelemetry(); - } - - if (!this._serverProcess) { - // nothing to kill - ret = Promise.resolve(); - } - else if (process.platform === 'win32') { - // when killing a process in windows its child - // processes are *not* killed but become root - // processes. Therefore we use TASKKILL.EXE - ret = new Promise((resolve, reject) => { - const killer = exec(`taskkill /F /T /PID ${this._serverProcess.pid}`, (err, stdout, stderr) => { - if (err) { - return reject(err); - } - }); - - killer.on('exit', resolve); - killer.on('error', reject); - }); - } + let flavor: omnisharp.Flavor; + if (options.path !== undefined && options.useMono === true) { + flavor = omnisharp.Flavor.Mono; + } else { - // Kill Unix process - this._serverProcess.kill('SIGTERM'); - ret = Promise.resolve(); - } + flavor = getDefaultFlavor(launchTarget.kind); + } - return ret.then(() => { - this._serverProcess = null; - this._setState(ServerState.Stopped); - this._fireEvent(Events.ServerStop, this); - return; - }); - } + return this._getServerPath(flavor).then(serverPath => { + this._setState(ServerState.Starting); + this._launchTarget = launchTarget; - public restart(launchTarget: LaunchTarget = this._launchTarget): Promise { - if (launchTarget) { - return this.stop().then(() => { - this._start(launchTarget); - }); - } - } + const solutionPath = launchTarget.target; + const cwd = dirname(solutionPath); + let args = [ + '-s', solutionPath, + '--hostPID', process.pid.toString(), + 'DotNet:enablePackageRestore=false' + ]; - public autoStart(preferredPath: string): Thenable { - return findLaunchTargets().then(launchTargets => { - // If there aren't any potential launch targets, we create file watcher and - // try to start the server again once a *.sln or project.json file is created. - if (launchTargets.length === 0) { - return new Promise((resolve, reject) => { - // 1st watch for files - let watcher = vscode.workspace.createFileSystemWatcher('{**/*.sln,**/project.json}', false, true, true); - watcher.onDidCreate(uri => { - watcher.dispose(); - resolve(); - }); - }).then(() => { - // 2nd try again - return this.autoStart(preferredPath); - }); - } + if (options.loggingLevel === 'verbose') { + args.push('-v'); + } - // If there's more than one launch target, we start the server if one of the targets - // matches the preferred path. Otherwise, we fire the "MultipleLaunchTargets" event, - // which is handled in status.ts to display the launch target selector. - if (launchTargets.length > 1 && preferredPath) { + args = args.concat(this._extraArgs); - for (let launchTarget of launchTargets) { - if (launchTarget.target === preferredPath) { - // start preferred path - return this.restart(launchTarget); - } - } + this._logger.appendLine(`Starting OmniSharp server at ${new Date().toLocaleString()}`); + this._logger.increaseIndent(); + this._logger.appendLine(`Target: ${solutionPath}`); + this._logger.decreaseIndent(); + this._logger.appendLine(); - this._fireEvent(Events.MultipleLaunchTargets, launchTargets); - return Promise.reject(undefined); - } + this._fireEvent(Events.BeforeServerStart, solutionPath); - // If there's only one target, just start - return this.restart(launchTargets[0]); - }); - } + return launchOmniSharp({serverPath, flavor, cwd, args}).then(value => { + if (value.usingMono) { + this._logger.appendLine(`OmniSharp server started wth Mono`); + } + else { + this._logger.appendLine(`OmniSharp server started`); + } - private _getServerPath(flavor: omnisharp.Flavor): Promise { - // Attempt to find launch file path first from options, and then from the default install location. - // If OmniSharp can't be found, download it. + this._logger.increaseIndent(); + this._logger.appendLine(`Path: ${value.command}`); + this._logger.appendLine(`PID: ${value.process.pid}`); + this._logger.decreaseIndent(); + this._logger.appendLine(); - const options = readOptions(); - const installDirectory = omnisharp.getInstallDirectory(flavor); + this._serverProcess = value.process; + this._delayTrackers = {}; + this._setState(ServerState.Started); + this._fireEvent(Events.ServerStart, solutionPath); - return new Promise((resolve, reject) => { - if (options.path) { - return omnisharp.findServerPath(options.path).then(serverPath => { - return resolve(serverPath); - }).catch(err => { - vscode.window.showWarningMessage(`Invalid value specified for "omnisharp.path" ('${options.path}).`); - return reject(err); - }); - } + return this._doConnect(); + }).then(() => { + return vscode.commands.getCommands() + .then(commands => { + if (commands.find(c => c === 'vscode.startDebug')) { + this._isDebugEnable = true; + } + }); + }).then(() => { + // Start telemetry reporting + this._telemetryIntervalId = setInterval(() => this._reportTelemetry(), TelemetryReportingDelay); + }).then(() => { + this._processQueue(); + }, err => { + this._fireEvent(Events.ServerError, err); + this._setState(ServerState.Stopped); + throw err; + }); + }); + } - return reject('No option specified.'); - }).catch(err => { - return omnisharp.findServerPath(installDirectory); - }).catch(err => { - const platform = getCurrentPlatform(); - if (platform == Platform.Unknown && process.platform === 'linux') { - this._channel.appendLine("[ERROR] Could not locate an OmniSharp server that supports your Linux distribution."); - this._channel.appendLine(""); - this._channel.appendLine("OmniSharp provides a richer C# editing experience, with features like IntelliSense and Find All References."); - this._channel.appendLine("It is recommend that you download the version of OmniSharp that runs on Mono using the following steps:"); - this._channel.appendLine(" 1. If it's not already installed, download and install Mono (https://www.mono-project.com)"); - this._channel.appendLine(" 2. Download and untar the latest OmniSharp Mono release from https://github.com/OmniSharp/omnisharp-roslyn/releases/"); - this._channel.appendLine(" 3. In Visual Studio Code, select Preferences->User Settings to open settings.json."); - this._channel.appendLine(" 4. In settings.json, add a new setting: \"omnisharp.path\": \"/path/to/omnisharp/OmniSharp.exe\""); - this._channel.appendLine(" 5. In settings.json, add a new setting: \"omnisharp.useMono\": true"); - this._channel.appendLine(" 6. Restart Visual Studio Code."); - this._channel.show(); + protected abstract _doConnect(): Promise; - throw err; - } + public stop(): Promise { - const config = vscode.workspace.getConfiguration(); - const proxy = config.get('http.proxy'); - const strictSSL = config.get('http.proxyStrictSSL', true); - const logger = (message: string) => { this._logger.appendLine(message); }; + let ret: Promise; - this._fireEvent(Events.BeforeServerInstall, this); + if (this._telemetryIntervalId !== undefined) { + // Stop reporting telemetry + clearInterval(this._telemetryIntervalId); + this._telemetryIntervalId = undefined; + this._reportTelemetry(); + } - return download.go(flavor, platform, this._logger, proxy, strictSSL).then(_ => { - return omnisharp.findServerPath(installDirectory); - }); - }); - } + if (!this._serverProcess) { + // nothing to kill + ret = Promise.resolve(); + } + else if (process.platform === 'win32') { + // when killing a process in windows its child + // processes are *not* killed but become root + // processes. Therefore we use TASKKILL.EXE + ret = new Promise((resolve, reject) => { + const killer = exec(`taskkill /F /T /PID ${this._serverProcess.pid}`, (err, stdout, stderr) => { + if (err) { + return reject(err); + } + }); - // --- requests et al + killer.on('exit', resolve); + killer.on('error', reject); + }); + } + else { + // Kill Unix process + this._serverProcess.kill('SIGTERM'); + ret = Promise.resolve(); + } - public makeRequest(path: string, data?: any, token?: vscode.CancellationToken): Promise { + return ret.then(() => { + this._serverProcess = null; + this._setState(ServerState.Stopped); + this._fireEvent(Events.ServerStop, this); + return; + }); + } - if (this._getState() !== ServerState.Started) { - return Promise.reject('server has been stopped or not started'); - } + public restart(launchTarget: LaunchTarget = this._launchTarget): Promise { + if (launchTarget) { + return this.stop().then(() => { + this._start(launchTarget); + }); + } + } + + public autoStart(preferredPath: string): Thenable { + return findLaunchTargets().then(launchTargets => { + // If there aren't any potential launch targets, we create file watcher and + // try to start the server again once a *.sln or project.json file is created. + if (launchTargets.length === 0) { + return new Promise((resolve, reject) => { + // 1st watch for files + let watcher = vscode.workspace.createFileSystemWatcher('{**/*.sln,**/project.json}', false, true, true); + watcher.onDidCreate(uri => { + watcher.dispose(); + resolve(); + }); + }).then(() => { + // 2nd try again + return this.autoStart(preferredPath); + }); + } + + // If there's more than one launch target, we start the server if one of the targets + // matches the preferred path. Otherwise, we fire the "MultipleLaunchTargets" event, + // which is handled in status.ts to display the launch target selector. + if (launchTargets.length > 1 && preferredPath) { + + for (let launchTarget of launchTargets) { + if (launchTarget.target === preferredPath) { + // start preferred path + return this.restart(launchTarget); + } + } + + this._fireEvent(Events.MultipleLaunchTargets, launchTargets); + return Promise.reject(undefined); + } + + // If there's only one target, just start + return this.restart(launchTargets[0]); + }); + } + + private _getServerPath(flavor: omnisharp.Flavor): Promise { + // Attempt to find launch file path first from options, and then from the default install location. + // If OmniSharp can't be found, download it. + + const options = readOptions(); + const installDirectory = omnisharp.getInstallDirectory(flavor); + + return new Promise((resolve, reject) => { + if (options.path) { + return omnisharp.findServerPath(options.path).then(serverPath => { + return resolve(serverPath); + }).catch(err => { + vscode.window.showWarningMessage(`Invalid value specified for "omnisharp.path" ('${options.path}).`); + return reject(err); + }); + } + + return reject('No option specified.'); + }).catch(err => { + return omnisharp.findServerPath(installDirectory); + }).catch(err => { + const platform = getCurrentPlatform(); + if (platform == Platform.Unknown && process.platform === 'linux') { + this._channel.appendLine("[ERROR] Could not locate an OmniSharp server that supports your Linux distribution."); + this._channel.appendLine(""); + this._channel.appendLine("OmniSharp provides a richer C# editing experience, with features like IntelliSense and Find All References."); + this._channel.appendLine("It is recommend that you download the version of OmniSharp that runs on Mono using the following steps:"); + this._channel.appendLine(" 1. If it's not already installed, download and install Mono (https://www.mono-project.com)"); + this._channel.appendLine(" 2. Download and untar the latest OmniSharp Mono release from https://github.com/OmniSharp/omnisharp-roslyn/releases/"); + this._channel.appendLine(" 3. In Visual Studio Code, select Preferences->User Settings to open settings.json."); + this._channel.appendLine(" 4. In settings.json, add a new setting: \"omnisharp.path\": \"/path/to/omnisharp/OmniSharp.exe\""); + this._channel.appendLine(" 5. In settings.json, add a new setting: \"omnisharp.useMono\": true"); + this._channel.appendLine(" 6. Restart Visual Studio Code."); + this._channel.show(); + + throw err; + } + + const config = vscode.workspace.getConfiguration(); + const proxy = config.get('http.proxy'); + const strictSSL = config.get('http.proxyStrictSSL', true); + const logger = (message: string) => { this._logger.appendLine(message); }; + + this._fireEvent(Events.BeforeServerInstall, this); + + return download.go(flavor, platform, this._logger, proxy, strictSSL).then(_ => { + return omnisharp.findServerPath(installDirectory); + }); + }); + } + + // --- requests et al + + public makeRequest(path: string, data?: any, token?: vscode.CancellationToken): Promise { + + if (this._getState() !== ServerState.Started) { + return Promise.reject('server has been stopped or not started'); + } let startTime: number; - let request: Request; + let request: Request; - let promise = new Promise((resolve, reject) => { + let promise = new Promise((resolve, reject) => { startTime = Date.now(); - request = { - path, - data, - onSuccess: value => resolve(value), - onError: err => reject(err), - _enqueued: Date.now() - }; + request = { + path, + data, + onSuccess: value => resolve(value), + onError: err => reject(err), + _enqueued: Date.now() + }; - this._queue.push(request); + this._queue.push(request); - if (this._getState() === ServerState.Started && !this._isProcessingQueue) { - this._processQueue(); - } - }); + if (this._getState() === ServerState.Started && !this._isProcessingQueue) { + this._processQueue(); + } + }); - if (token) { - token.onCancellationRequested(() => { - let idx = this._queue.indexOf(request); - if (idx !== -1) { - this._queue.splice(idx, 1); - let err = new Error('Canceled'); - err.message = 'Canceled'; - request.onError(err); - } - }); - } + if (token) { + token.onCancellationRequested(() => { + let idx = this._queue.indexOf(request); + if (idx !== -1) { + this._queue.splice(idx, 1); + let err = new Error('Canceled'); + err.message = 'Canceled'; + request.onError(err); + } + }); + } - return promise.then(response => { + return promise.then(response => { let endTime = Date.now(); let elapsedTime = endTime - startTime; this._recordRequestDelay(path, elapsedTime); return response; }); - } + } - private _processQueue(): void { + private _processQueue(): void { - if (this._queue.length === 0) { - // nothing to do - this._isProcessingQueue = false; - return; - } + if (this._queue.length === 0) { + // nothing to do + this._isProcessingQueue = false; + return; + } - // signal that we are working on it - this._isProcessingQueue = true; + // signal that we are working on it + this._isProcessingQueue = true; - // send next request and recurse when done - const thisRequest = this._queue.shift(); - this._makeNextRequest(thisRequest.path, thisRequest.data).then(value => { - thisRequest.onSuccess(value); - this._processQueue(); - }, err => { - thisRequest.onError(err); - this._processQueue(); - }).catch(err => { - console.error(err); - this._processQueue(); - }); - } + // send next request and recurse when done + const thisRequest = this._queue.shift(); + this._makeNextRequest(thisRequest.path, thisRequest.data).then(value => { + thisRequest.onSuccess(value); + this._processQueue(); + }, err => { + thisRequest.onError(err); + this._processQueue(); + }).catch(err => { + console.error(err); + this._processQueue(); + }); + } - protected abstract _makeNextRequest(path: string, data: any): Promise; + protected abstract _makeNextRequest(path: string, data: any): Promise; } namespace WireProtocol { - export interface Packet { - Type: string; - Seq: number; - } + export interface Packet { + Type: string; + Seq: number; + } - export interface RequestPacket extends Packet { - Command: string; - Arguments: any; - } + export interface RequestPacket extends Packet { + Command: string; + Arguments: any; + } - export interface ResponsePacket extends Packet { - Command: string; - Request_seq: number; - Running: boolean; - Success: boolean; - Message: string; - Body: any; - } + export interface ResponsePacket extends Packet { + Command: string; + Request_seq: number; + Running: boolean; + Success: boolean; + Message: string; + Body: any; + } - export interface EventPacket extends Packet { - Event: string; - Body: any; - } + export interface EventPacket extends Packet { + Event: string; + Body: any; + } } export class StdioOmnisharpServer extends OmnisharpServer { - private static _seqPool = 1; - private static StartupTimeout = 1000 * 60; + private static _seqPool = 1; + private static StartupTimeout = 1000 * 60; - private _rl: ReadLine; - private _activeRequest: { [seq: number]: { onSuccess: Function; onError: Function; } } = Object.create(null); - private _callOnStop: Function[] = []; + private _rl: ReadLine; + private _activeRequest: { [seq: number]: { onSuccess: Function; onError: Function; } } = Object.create(null); + private _callOnStop: Function[] = []; - constructor(reporter: TelemetryReporter) { - super(reporter); + constructor(reporter: TelemetryReporter) { + super(reporter); - // extra argv - this._extraArgs.push('--stdio'); - } + // extra argv + this._extraArgs.push('--stdio'); + } - public stop(): Promise { - while (this._callOnStop.length) { - this._callOnStop.pop()(); - } + public stop(): Promise { + while (this._callOnStop.length) { + this._callOnStop.pop()(); + } - return super.stop(); - } + return super.stop(); + } - protected _doConnect(): Promise { + protected _doConnect(): Promise { - this._serverProcess.stderr.on('data', (data: any) => { - this._fireEvent('stderr', String(data)); - }); + this._serverProcess.stderr.on('data', (data: any) => { + this._fireEvent('stderr', String(data)); + }); - this._rl = createInterface({ - input: this._serverProcess.stdout, - output: this._serverProcess.stdin, - terminal: false - }); + this._rl = createInterface({ + input: this._serverProcess.stdout, + output: this._serverProcess.stdin, + terminal: false + }); - const p = new Promise((resolve, reject) => { - let listener: vscode.Disposable; + const p = new Promise((resolve, reject) => { + let listener: vscode.Disposable; - // timeout logic - const handle = setTimeout(() => { + // timeout logic + const handle = setTimeout(() => { if (listener) { listener.dispose(); } - reject(new Error('Failed to start OmniSharp')); - }, StdioOmnisharpServer.StartupTimeout); + reject(new Error('Failed to start OmniSharp')); + }, StdioOmnisharpServer.StartupTimeout); - // handle started-event - listener = this.onOmnisharpStart(() => { + // handle started-event + listener = this.onOmnisharpStart(() => { if (listener) { - listener.dispose(); + listener.dispose(); } - clearTimeout(handle); - resolve(); - }); - }); + clearTimeout(handle); + resolve(); + }); + }); - this._startListening(); + this._startListening(); - return p; - } + return p; + } - private _startListening(): void { + private _startListening(): void { - const onLineReceived = (line: string) => { - if (line[0] !== '{') { - this._logger.appendLine(line); - return; - } + const onLineReceived = (line: string) => { + if (line[0] !== '{') { + this._logger.appendLine(line); + return; + } - let packet: WireProtocol.Packet; - try { - packet = JSON.parse(line); - } + let packet: WireProtocol.Packet; + try { + packet = JSON.parse(line); + } catch (e) { - // not json - return; - } + // not json + return; + } - if (!packet.Type) { - // bogous packet - return; - } + if (!packet.Type) { + // bogous packet + return; + } - switch (packet.Type) { - case 'response': - this._handleResponsePacket(packet); - break; - case 'event': - this._handleEventPacket(packet); - break; - default: - console.warn('unknown packet: ', packet); - break; - } - }; + switch (packet.Type) { + case 'response': + this._handleResponsePacket(packet); + break; + case 'event': + this._handleEventPacket(packet); + break; + default: + console.warn('unknown packet: ', packet); + break; + } + }; - this._rl.addListener('line', onLineReceived); - this._callOnStop.push(() => this._rl.removeListener('line', onLineReceived)); - } + this._rl.addListener('line', onLineReceived); + this._callOnStop.push(() => this._rl.removeListener('line', onLineReceived)); + } - private _handleResponsePacket(packet: WireProtocol.ResponsePacket): void { + private _handleResponsePacket(packet: WireProtocol.ResponsePacket): void { - const requestSeq = packet.Request_seq, - entry = this._activeRequest[requestSeq]; + const requestSeq = packet.Request_seq, + entry = this._activeRequest[requestSeq]; - if (!entry) { - console.warn('Received a response WITHOUT a request', packet); - return; - } + if (!entry) { + console.warn('Received a response WITHOUT a request', packet); + return; + } - delete this._activeRequest[requestSeq]; + delete this._activeRequest[requestSeq]; - if (packet.Success) { - entry.onSuccess(packet.Body); - } else { - entry.onError(packet.Message || packet.Body); - } - } + if (packet.Success) { + entry.onSuccess(packet.Body); + } else { + entry.onError(packet.Message || packet.Body); + } + } - private _handleEventPacket(packet: WireProtocol.EventPacket): void { + private _handleEventPacket(packet: WireProtocol.EventPacket): void { - if (packet.Event === 'log') { - // handle log events - const entry = <{ LogLevel: string; Name: string; Message: string; }>packet.Body; - this._logger.appendLine(`[${entry.LogLevel}:${entry.Name}] ${entry.Message}`); - return; - } else { - // fwd all other events - this._fireEvent(packet.Event, packet.Body); - } - } + if (packet.Event === 'log') { + // handle log events + const entry = <{ LogLevel: string; Name: string; Message: string; }>packet.Body; + this._logger.appendLine(`[${entry.LogLevel}:${entry.Name}] ${entry.Message}`); + return; + } else { + // fwd all other events + this._fireEvent(packet.Event, packet.Body); + } + } - protected _makeNextRequest(path: string, data: any): Promise { + protected _makeNextRequest(path: string, data: any): Promise { - const thisRequestPacket: WireProtocol.RequestPacket = { - Type: 'request', - Seq: StdioOmnisharpServer._seqPool++, - Command: path, - Arguments: data - }; + const thisRequestPacket: WireProtocol.RequestPacket = { + Type: 'request', + Seq: StdioOmnisharpServer._seqPool++, + Command: path, + Arguments: data + }; - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { - this._activeRequest[thisRequestPacket.Seq] = { - onSuccess: value => resolve(value), - onError: err => reject(err) - }; + this._activeRequest[thisRequestPacket.Seq] = { + onSuccess: value => resolve(value), + onError: err => reject(err) + }; - this._serverProcess.stdin.write(JSON.stringify(thisRequestPacket) + '\n'); - }); - } + this._serverProcess.stdin.write(JSON.stringify(thisRequestPacket) + '\n'); + }); + } }