mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-13 03:28:33 -05:00
Refresh master with initial release/0.24 snapshot (#332)
* Initial port of release/0.24 source code * Fix additional headers * Fix a typo in launch.json
This commit is contained in:
@@ -6,11 +6,12 @@
|
||||
'use strict';
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { dirname, basename } from 'path';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import * as json from 'vs/base/common/json';
|
||||
import * as extfs from 'vs/base/node/extfs';
|
||||
|
||||
export interface IConfigurationChangeEvent<T> {
|
||||
config: T;
|
||||
@@ -49,9 +50,11 @@ export class ConfigWatcher<T> implements IConfigWatcher<T>, IDisposable {
|
||||
private timeoutHandle: NodeJS.Timer;
|
||||
private disposables: IDisposable[];
|
||||
private _onDidUpdateConfiguration: Emitter<IConfigurationChangeEvent<T>>;
|
||||
private configName: string;
|
||||
|
||||
constructor(private _path: string, private options: IConfigOptions<T> = { changeBufferDelay: 0, defaultConfig: Object.create(null), onError: error => console.error(error) }) {
|
||||
this.disposables = [];
|
||||
this.configName = basename(this._path);
|
||||
|
||||
this._onDidUpdateConfiguration = new Emitter<IConfigurationChangeEvent<T>>();
|
||||
this.disposables.push(this._onDidUpdateConfiguration);
|
||||
@@ -121,8 +124,8 @@ export class ConfigWatcher<T> implements IConfigWatcher<T>, IDisposable {
|
||||
private registerWatcher(): void {
|
||||
|
||||
// Watch the parent of the path so that we detect ADD and DELETES
|
||||
const parentFolder = path.dirname(this._path);
|
||||
this.watch(parentFolder);
|
||||
const parentFolder = dirname(this._path);
|
||||
this.watch(parentFolder, true);
|
||||
|
||||
// Check if the path is a symlink and watch its target if so
|
||||
fs.lstat(this._path, (err, stat) => {
|
||||
@@ -137,20 +140,19 @@ export class ConfigWatcher<T> implements IConfigWatcher<T>, IDisposable {
|
||||
return; // path is not a valid symlink
|
||||
}
|
||||
|
||||
this.watch(realPath);
|
||||
this.watch(realPath, false);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private watch(path: string): void {
|
||||
private watch(path: string, isParentFolder: boolean): void {
|
||||
if (this.disposed) {
|
||||
return; // avoid watchers that will never get disposed by checking for being disposed
|
||||
}
|
||||
|
||||
try {
|
||||
const watcher = fs.watch(path);
|
||||
watcher.on('change', () => this.onConfigFileChange());
|
||||
const watcher = extfs.watch(path, (type, file) => this.onConfigFileChange(type, file, isParentFolder));
|
||||
watcher.on('error', (code, signal) => this.options.onError(`Error watching ${path} for configuration changes (${code}, ${signal})`));
|
||||
|
||||
this.disposables.push(toDisposable(() => {
|
||||
@@ -166,7 +168,11 @@ export class ConfigWatcher<T> implements IConfigWatcher<T>, IDisposable {
|
||||
}
|
||||
}
|
||||
|
||||
private onConfigFileChange(): void {
|
||||
private onConfigFileChange(eventType: string, filename: string, isParentFolder: boolean): void {
|
||||
if (isParentFolder && filename !== this.configName) {
|
||||
return; // a change to a sibling file that is not our config file
|
||||
}
|
||||
|
||||
if (this.timeoutHandle) {
|
||||
global.clearTimeout(this.timeoutHandle);
|
||||
this.timeoutHandle = null;
|
||||
|
||||
128
src/vs/base/node/console.ts
Normal file
128
src/vs/base/node/console.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
|
||||
export interface IRemoteConsoleLog {
|
||||
type: string;
|
||||
severity: string;
|
||||
arguments: string;
|
||||
}
|
||||
|
||||
interface IStackArgument {
|
||||
__$stack: string;
|
||||
}
|
||||
|
||||
export interface IStackFrame {
|
||||
uri: URI;
|
||||
line: number;
|
||||
column: number;
|
||||
}
|
||||
|
||||
export function isRemoteConsoleLog(obj: any): obj is IRemoteConsoleLog {
|
||||
const entry = obj as IRemoteConsoleLog;
|
||||
|
||||
return entry && typeof entry.type === 'string' && typeof entry.severity === 'string';
|
||||
}
|
||||
|
||||
export function parse(entry: IRemoteConsoleLog): { args: any[], stack?: string } {
|
||||
const args: any[] = [];
|
||||
let stack: string;
|
||||
|
||||
// Parse Entry
|
||||
try {
|
||||
const parsedArguments: any[] = JSON.parse(entry.arguments);
|
||||
|
||||
// Check for special stack entry as last entry
|
||||
const stackArgument = parsedArguments[parsedArguments.length - 1] as IStackArgument;
|
||||
if (stackArgument && stackArgument.__$stack) {
|
||||
parsedArguments.pop(); // stack is handled specially
|
||||
stack = stackArgument.__$stack;
|
||||
}
|
||||
|
||||
args.push(...parsedArguments);
|
||||
} catch (error) {
|
||||
args.push('Unable to log remote console arguments', entry.arguments);
|
||||
}
|
||||
|
||||
return { args, stack };
|
||||
}
|
||||
|
||||
export function getFirstFrame(entry: IRemoteConsoleLog): IStackFrame;
|
||||
export function getFirstFrame(stack: string): IStackFrame;
|
||||
export function getFirstFrame(arg0: IRemoteConsoleLog | string): IStackFrame {
|
||||
if (typeof arg0 !== 'string') {
|
||||
return getFirstFrame(parse(arg0).stack);
|
||||
}
|
||||
|
||||
// Parse a source information out of the stack if we have one. Format can be:
|
||||
// at vscode.commands.registerCommand (/Users/someone/Desktop/test-ts/out/src/extension.js:18:17)
|
||||
// or
|
||||
// at /Users/someone/Desktop/test-ts/out/src/extension.js:18:17
|
||||
// or
|
||||
// at c:\Users\someone\Desktop\end-js\extension.js:19:17
|
||||
// or
|
||||
// at e.$executeContributedCommand(c:\Users\someone\Desktop\end-js\extension.js:19:17)
|
||||
const stack = arg0;
|
||||
if (stack) {
|
||||
const topFrame = stack.split('\n')[0];
|
||||
|
||||
// at [^\/]* => line starts with "at" followed by any character except '/' (to not capture unix paths too late)
|
||||
// (?:(?:[a-zA-Z]+:)|(?:[\/])|(?:\\\\) => windows drive letter OR unix root OR unc root
|
||||
// (?:.+) => simple pattern for the path, only works because of the line/col pattern after
|
||||
// :(?:\d+):(?:\d+) => :line:column data
|
||||
const matches = /at [^\/]*((?:(?:[a-zA-Z]+:)|(?:[\/])|(?:\\\\))(?:.+)):(\d+):(\d+)/.exec(topFrame);
|
||||
if (matches && matches.length === 4) {
|
||||
return {
|
||||
uri: URI.file(matches[1]),
|
||||
line: Number(matches[2]),
|
||||
column: Number(matches[3])
|
||||
} as IStackFrame;
|
||||
}
|
||||
}
|
||||
|
||||
return void 0;
|
||||
}
|
||||
|
||||
export function log(entry: IRemoteConsoleLog, label: string): void {
|
||||
const { args, stack } = parse(entry);
|
||||
|
||||
const isOneStringArg = typeof args[0] === 'string' && args.length === 1;
|
||||
|
||||
let topFrame = stack && stack.split('\n')[0];
|
||||
if (topFrame) {
|
||||
topFrame = `(${topFrame.trim()})`;
|
||||
}
|
||||
|
||||
let consoleArgs = [];
|
||||
|
||||
// First arg is a string
|
||||
if (typeof args[0] === 'string') {
|
||||
if (topFrame && isOneStringArg) {
|
||||
consoleArgs = [`%c[${label}] %c${args[0]} %c${topFrame}`, color('blue'), color('black'), color('grey')];
|
||||
} else {
|
||||
consoleArgs = [`%c[${label}] %c${args[0]}`, color('blue'), color('black'), ...args.slice(1)];
|
||||
}
|
||||
}
|
||||
|
||||
// First arg is something else, just apply all
|
||||
else {
|
||||
consoleArgs = [`%c[${label}]%`, color('blue'), ...args];
|
||||
}
|
||||
|
||||
// Stack: add to args unless already aded
|
||||
if (topFrame && !isOneStringArg) {
|
||||
consoleArgs.push(topFrame);
|
||||
}
|
||||
|
||||
// Log it
|
||||
console[entry.severity].apply(console, consoleArgs);
|
||||
}
|
||||
|
||||
function color(color: string): string {
|
||||
return `color: ${color}`;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ export function checksum(path: string, sha1hash: string): TPromise<void> {
|
||||
input.once('error', done);
|
||||
input.once('end', done);
|
||||
hashStream.once('error', done);
|
||||
hashStream.once('data', data => done(null, data.toString('hex')));
|
||||
hashStream.once('data', (data: NodeBuffer) => done(null, data.toString('hex')));
|
||||
});
|
||||
|
||||
return promise.then(hash => {
|
||||
|
||||
@@ -95,17 +95,12 @@ export function detectEncodingByBOM(file: string): TPromise<string> {
|
||||
}
|
||||
|
||||
const MINIMUM_THRESHOLD = 0.2;
|
||||
|
||||
const IGNORE_ENCODINGS = ['ascii', 'utf-8', 'utf-16', 'utf-32'];
|
||||
const MAPPED_ENCODINGS = {
|
||||
'ibm866': 'cp866'
|
||||
};
|
||||
|
||||
/**
|
||||
* Guesses the encoding from buffer.
|
||||
*/
|
||||
export async function guessEncodingByBuffer(buffer: NodeBuffer): TPromise<string> {
|
||||
|
||||
const jschardet = await import('jschardet');
|
||||
|
||||
jschardet.Constants.MINIMUM_THRESHOLD = MINIMUM_THRESHOLD;
|
||||
@@ -126,9 +121,14 @@ export async function guessEncodingByBuffer(buffer: NodeBuffer): TPromise<string
|
||||
return toIconvLiteEncoding(guessed.encoding);
|
||||
}
|
||||
|
||||
const JSCHARDET_TO_ICONV_ENCODINGS: { [name: string]: string } = {
|
||||
'ibm866': 'cp866',
|
||||
'big5': 'cp950'
|
||||
};
|
||||
|
||||
function toIconvLiteEncoding(encodingName: string): string {
|
||||
const normalizedEncodingName = encodingName.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
|
||||
const mapped = MAPPED_ENCODINGS[normalizedEncodingName];
|
||||
const mapped = JSCHARDET_TO_ICONV_ENCODINGS[normalizedEncodingName];
|
||||
|
||||
return mapped || normalizedEncodingName;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ export function readdir(path: string, callback: (error: Error, files: string[])
|
||||
}
|
||||
|
||||
export function mkdirp(path: string, mode: number, callback: (error: Error) => void): void {
|
||||
fs.exists(path, (exists) => {
|
||||
fs.exists(path, exists => {
|
||||
if (exists) {
|
||||
return isDirectory(path, (err: Error, itIs?: boolean) => {
|
||||
if (err) {
|
||||
@@ -61,7 +61,7 @@ export function mkdirp(path: string, mode: number, callback: (error: Error) => v
|
||||
if (err) { callback(err); return; }
|
||||
|
||||
if (mode) {
|
||||
fs.mkdir(path, mode, (error) => {
|
||||
fs.mkdir(path, mode, error => {
|
||||
if (error) {
|
||||
return callback(error);
|
||||
}
|
||||
@@ -98,10 +98,10 @@ export function copy(source: string, target: string, callback: (error: Error) =>
|
||||
copiedSources[source] = true; // remember as copied
|
||||
}
|
||||
|
||||
mkdirp(target, stat.mode & 511, (err) => {
|
||||
mkdirp(target, stat.mode & 511, err => {
|
||||
readdir(source, (err, files) => {
|
||||
loop(files, (file: string, clb: (error: Error, _result) => void) => {
|
||||
copy(paths.join(source, file), paths.join(target, file), (error: Error) => clb(error, undefined), copiedSources);
|
||||
loop(files, (file: string, clb: (error: Error, result: string[]) => void) => {
|
||||
copy(paths.join(source, file), paths.join(target, file), (error: Error) => clb(error, void 0), copiedSources);
|
||||
}, callback);
|
||||
});
|
||||
});
|
||||
@@ -147,7 +147,7 @@ function pipeFs(source: string, target: string, mode: number, callback: (error:
|
||||
// will fail in case any file is used by another process. fs.unlink() in node will not bail if a file unlinked is used by another process.
|
||||
// However, the consequences are bad as outlined in all the related bugs from https://github.com/joyent/node/issues/7164
|
||||
export function del(path: string, tmpFolder: string, callback: (error: Error) => void, done?: (error: Error) => void): void {
|
||||
fs.exists(path, (exists) => {
|
||||
fs.exists(path, exists => {
|
||||
if (!exists) {
|
||||
return callback(null);
|
||||
}
|
||||
@@ -173,7 +173,7 @@ export function del(path: string, tmpFolder: string, callback: (error: Error) =>
|
||||
callback(null);
|
||||
|
||||
// do the heavy deletion outside the callers callback
|
||||
rmRecursive(pathInTemp, (error) => {
|
||||
rmRecursive(pathInTemp, error => {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
}
|
||||
@@ -192,7 +192,7 @@ function rmRecursive(path: string, callback: (error: Error) => void): void {
|
||||
return callback(new Error('Will not delete root!'));
|
||||
}
|
||||
|
||||
fs.exists(path, (exists) => {
|
||||
fs.exists(path, exists => {
|
||||
if (!exists) {
|
||||
callback(null);
|
||||
} else {
|
||||
@@ -221,7 +221,7 @@ function rmRecursive(path: string, callback: (error: Error) => void): void {
|
||||
} else {
|
||||
let firstError: Error = null;
|
||||
let childrenLeft = children.length;
|
||||
children.forEach((child) => {
|
||||
children.forEach(child => {
|
||||
rmRecursive(paths.join(path, child), (err: Error) => {
|
||||
childrenLeft--;
|
||||
if (err) {
|
||||
@@ -348,13 +348,13 @@ export function writeFileAndFlush(path: string, data: string | NodeBuffer, optio
|
||||
}
|
||||
|
||||
// It is valid to pass a fd handle to fs.writeFile() and this will keep the handle open!
|
||||
fs.writeFile(fd, data, (writeError) => {
|
||||
fs.writeFile(fd, data, writeError => {
|
||||
if (writeError) {
|
||||
return fs.close(fd, () => callback(writeError)); // still need to close the handle on error!
|
||||
}
|
||||
|
||||
// Flush contents (not metadata) of the file to disk
|
||||
fs.fdatasync(fd, (syncError) => {
|
||||
fs.fdatasync(fd, (syncError: Error) => {
|
||||
|
||||
// In some exotic setups it is well possible that node fails to sync
|
||||
// In that case we disable flushing and warn to the console
|
||||
@@ -363,7 +363,7 @@ export function writeFileAndFlush(path: string, data: string | NodeBuffer, optio
|
||||
canFlush = false;
|
||||
}
|
||||
|
||||
return fs.close(fd, (closeError) => callback(closeError));
|
||||
return fs.close(fd, closeError => callback(closeError));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -450,3 +450,19 @@ export function realpath(path: string, callback: (error: Error, realpath: string
|
||||
function normalizePath(path: string): string {
|
||||
return strings.rtrim(paths.normalize(path), paths.sep);
|
||||
}
|
||||
|
||||
export function watch(path: string, onChange: (type: string, path: string) => void): fs.FSWatcher {
|
||||
const watcher = fs.watch(path);
|
||||
watcher.on('change', (type, raw) => {
|
||||
let file = raw.toString();
|
||||
if (platform.isMacintosh) {
|
||||
// Mac: uses NFD unicode form on disk, but we want NFC
|
||||
// See also https://github.com/nodejs/node/issues/2165
|
||||
file = strings.normalizeNFC(file);
|
||||
}
|
||||
|
||||
onChange(type, file);
|
||||
});
|
||||
|
||||
return watcher;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import * as uuid from 'vs/base/common/uuid';
|
||||
import { networkInterfaces } from 'os';
|
||||
import { TrieMap } from 'vs/base/common/map';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
|
||||
// http://www.techrepublic.com/blog/data-center/mac-address-scorecard-for-common-virtual-machine-platforms/
|
||||
// VMware ESX 3, Server, Workstation, Player 00-50-56, 00-0C-29, 00-05-69
|
||||
@@ -23,21 +23,30 @@ import { TrieMap } from 'vs/base/common/map';
|
||||
// Sun xVM VirtualBox 08-00-27
|
||||
export const virtualMachineHint: { value(): number } = new class {
|
||||
|
||||
private _virtualMachineOUIs: TrieMap<boolean>;
|
||||
private _virtualMachineOUIs: TernarySearchTree<boolean>;
|
||||
private _value: number;
|
||||
|
||||
private _isVirtualMachineMacAdress(mac: string): boolean {
|
||||
if (!this._virtualMachineOUIs) {
|
||||
this._virtualMachineOUIs = new TrieMap<boolean>(s => s.split(/[-:]/));
|
||||
// this._virtualMachineOUIs.insert('00-00-00', true);
|
||||
this._virtualMachineOUIs.insert('00-50-56', true);
|
||||
this._virtualMachineOUIs.insert('00-0C-29', true);
|
||||
this._virtualMachineOUIs.insert('00-05-69', true);
|
||||
this._virtualMachineOUIs.insert('00-03-FF', true);
|
||||
this._virtualMachineOUIs.insert('00-1C-42', true);
|
||||
this._virtualMachineOUIs.insert('00-16-3E', true);
|
||||
this._virtualMachineOUIs.insert('08-00-27', true);
|
||||
this._virtualMachineOUIs = TernarySearchTree.forStrings<boolean>();
|
||||
|
||||
// dash-separated
|
||||
this._virtualMachineOUIs.set('00-50-56', true);
|
||||
this._virtualMachineOUIs.set('00-0C-29', true);
|
||||
this._virtualMachineOUIs.set('00-05-69', true);
|
||||
this._virtualMachineOUIs.set('00-03-FF', true);
|
||||
this._virtualMachineOUIs.set('00-1C-42', true);
|
||||
this._virtualMachineOUIs.set('00-16-3E', true);
|
||||
this._virtualMachineOUIs.set('08-00-27', true);
|
||||
|
||||
// colon-separated
|
||||
this._virtualMachineOUIs.set('00:50:56', true);
|
||||
this._virtualMachineOUIs.set('00:0C:29', true);
|
||||
this._virtualMachineOUIs.set('00:05:69', true);
|
||||
this._virtualMachineOUIs.set('00:03:FF', true);
|
||||
this._virtualMachineOUIs.set('00:1C:42', true);
|
||||
this._virtualMachineOUIs.set('00:16:3E', true);
|
||||
this._virtualMachineOUIs.set('08:00:27', true);
|
||||
}
|
||||
return this._virtualMachineOUIs.findSubstr(mac);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ const ZERO_BYTE_DETECTION_BUFFER_MAX_LEN = 512; // number of bytes to look at to
|
||||
const NO_GUESS_BUFFER_MAX_LEN = 512; // when not auto guessing the encoding, small number of bytes are enough
|
||||
const AUTO_GUESS_BUFFER_MAX_LEN = 512 * 8; // with auto guessing we want a lot more content to be read for guessing
|
||||
|
||||
function maxBufferLen(arg1?: DetectMimesOption | boolean): number {
|
||||
export function maxBufferLen(arg1?: DetectMimesOption | boolean): number {
|
||||
let autoGuessEncoding: boolean;
|
||||
if (typeof arg1 === 'boolean') {
|
||||
autoGuessEncoding = arg1;
|
||||
|
||||
@@ -189,3 +189,24 @@ const tmpDir = os.tmpdir();
|
||||
export function del(path: string, tmp = tmpDir): TPromise<void> {
|
||||
return nfcall(extfs.del, path, tmp);
|
||||
}
|
||||
|
||||
export function whenDeleted(path: string): TPromise<void> {
|
||||
|
||||
// Complete when wait marker file is deleted
|
||||
return new TPromise<void>(c => {
|
||||
let running = false;
|
||||
const interval = setInterval(() => {
|
||||
if (!running) {
|
||||
running = true;
|
||||
fs.exists(path, exists => {
|
||||
running = false;
|
||||
|
||||
if (!exists) {
|
||||
clearInterval(interval);
|
||||
c(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
@@ -46,6 +46,10 @@ function doFindFreePort(startPort: number, giveUpAfter: number, clb: (port: numb
|
||||
return doFindFreePort(startPort + 1, giveUpAfter - 1, clb);
|
||||
});
|
||||
|
||||
client.once('data', () => {
|
||||
// this listener is required since node.js 8.x
|
||||
});
|
||||
|
||||
client.once('error', (err: Error & { code?: string }) => {
|
||||
dispose(client);
|
||||
|
||||
|
||||
@@ -455,7 +455,7 @@ export interface IQueuedSender {
|
||||
// On Windows we always wait for the send() method to return before sending the next message
|
||||
// to workaround https://github.com/nodejs/node/issues/7657 (IPC can freeze process)
|
||||
export function createQueuedSender(childProcess: ChildProcess | NodeJS.Process): IQueuedSender {
|
||||
let msgQueue = [];
|
||||
let msgQueue: string[] = [];
|
||||
let useQueue = false;
|
||||
|
||||
const send = function (msg: any): void {
|
||||
@@ -464,7 +464,7 @@ export function createQueuedSender(childProcess: ChildProcess | NodeJS.Process):
|
||||
return;
|
||||
}
|
||||
|
||||
let result = childProcess.send(msg, error => {
|
||||
let result = childProcess.send(msg, (error: Error) => {
|
||||
if (error) {
|
||||
console.error(error); // unlikely to happen, best we can do is log this error
|
||||
}
|
||||
|
||||
@@ -62,14 +62,14 @@ export function removePiiPaths(profile: Profile) {
|
||||
}
|
||||
|
||||
declare interface Profiler {
|
||||
startProfiling(name: string);
|
||||
startProfiling(name: string): void;
|
||||
stopProfiling(): Profile;
|
||||
}
|
||||
|
||||
export declare interface Profile {
|
||||
title: string;
|
||||
export(callback: (err, data) => void);
|
||||
delete();
|
||||
export(callback: (err, data) => void): void;
|
||||
delete(): void;
|
||||
head: ProfileSample;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ export function asText(context: IRequestContext): TPromise<string> {
|
||||
}
|
||||
|
||||
let buffer: string[] = [];
|
||||
context.stream.on('data', d => buffer.push(d));
|
||||
context.stream.on('data', (d: string) => buffer.push(d));
|
||||
context.stream.on('end', () => c(buffer.join('')));
|
||||
context.stream.on('error', e);
|
||||
});
|
||||
@@ -165,7 +165,7 @@ export function asJson<T>(context: IRequestContext): TPromise<T> {
|
||||
}
|
||||
|
||||
const buffer: string[] = [];
|
||||
context.stream.on('data', d => buffer.push(d));
|
||||
context.stream.on('data', (d: string) => buffer.push(d));
|
||||
context.stream.on('end', () => c(JSON.parse(buffer.join(''))));
|
||||
context.stream.on('error', e);
|
||||
});
|
||||
|
||||
2
src/vs/base/node/startupTimers.d.ts
vendored
2
src/vs/base/node/startupTimers.d.ts
vendored
@@ -28,7 +28,7 @@ declare interface TickController {
|
||||
|
||||
export function startTimer(name: string): TickController;
|
||||
|
||||
export function stopTimer(name: string);
|
||||
export function stopTimer(name: string): void;
|
||||
|
||||
export function ticks(): Tick[];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user