Revert "Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d (#5949)" (#5983)

This reverts commit d15a3fcc98.
This commit is contained in:
Karl Burtram
2019-06-11 12:35:58 -07:00
committed by GitHub
parent 95a50b7892
commit 5a7562a37b
926 changed files with 11394 additions and 19540 deletions

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { IDisposable, combinedDisposable, Disposable } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
export interface ITelemetryData {
@@ -29,13 +29,14 @@ export interface IActionRunner extends IDisposable {
onDidBeforeRun: Event<IRunEvent>;
}
export interface IActionViewItem extends IDisposable {
export interface IActionViewItem {
actionRunner: IActionRunner;
setActionContext(context: any): void;
render(element: any /* HTMLElement */): void;
isEnabled(): boolean;
focus(): void;
blur(): void;
dispose(): void;
}
export interface IActionChangeEvent {
@@ -47,9 +48,9 @@ export interface IActionChangeEvent {
radio?: boolean;
}
export class Action extends Disposable implements IAction {
export class Action implements IAction {
protected _onDidChange = this._register(new Emitter<IActionChangeEvent>());
protected _onDidChange = new Emitter<IActionChangeEvent>();
readonly onDidChange: Event<IActionChangeEvent> = this._onDidChange.event;
protected _id: string;
@@ -62,7 +63,6 @@ export class Action extends Disposable implements IAction {
protected _actionCallback?: (event?: any) => Promise<any>;
constructor(id: string, label: string = '', cssClass: string = '', enabled: boolean = true, actionCallback?: (event?: any) => Promise<any>) {
super();
this._id = id;
this._label = label;
this._cssClass = cssClass;
@@ -171,6 +171,10 @@ export class Action extends Disposable implements IAction {
return Promise.resolve(true);
}
dispose() {
this._onDidChange.dispose();
}
}
export interface IRunEvent {
@@ -213,8 +217,8 @@ export class RadioGroup extends Disposable {
constructor(readonly actions: Action[]) {
super();
for (const action of actions) {
this._register(action.onDidChange(e => {
this._register(combinedDisposable(actions.map(action => {
return action.onDidChange(e => {
if (e.checked && action.checked) {
for (const candidate of actions) {
if (candidate !== action) {
@@ -222,7 +226,7 @@ export class RadioGroup extends Disposable {
}
}
}
}));
}
});
})));
}
}

View File

@@ -6,7 +6,7 @@
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import * as errors from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
export function isThenable<T>(obj: any): obj is Promise<T> {
@@ -415,11 +415,11 @@ export class Limiter<T> {
this._onFinished = new Emitter<void>();
}
get onFinished(): Event<void> {
public get onFinished(): Event<void> {
return this._onFinished.event;
}
get size(): number {
public get size(): number {
return this._size;
// return this.runningPromises + this.outstandingPromises.length;
}
@@ -455,7 +455,7 @@ export class Limiter<T> {
}
}
dispose(): void {
public dispose(): void {
this._onFinished.dispose();
}
}
@@ -475,30 +475,35 @@ export class Queue<T> extends Limiter<T> {
* by disposing them once the queue is empty.
*/
export class ResourceQueue {
private queues: Map<string, Queue<void>> = new Map();
private queues: { [path: string]: Queue<void> };
queueFor(resource: URI): Queue<void> {
constructor() {
this.queues = Object.create(null);
}
public queueFor(resource: URI): Queue<void> {
const key = resource.toString();
if (!this.queues.has(key)) {
if (!this.queues[key]) {
const queue = new Queue<void>();
queue.onFinished(() => {
queue.dispose();
this.queues.delete(key);
delete this.queues[key];
});
this.queues.set(key, queue);
this.queues[key] = queue;
}
return this.queues.get(key)!;
return this.queues[key];
}
}
export class TimeoutTimer implements IDisposable {
export class TimeoutTimer extends Disposable {
private _token: any;
constructor();
constructor(runner: () => void, timeout: number);
constructor(runner?: () => void, timeout?: number) {
super();
this._token = -1;
if (typeof runner === 'function' && typeof timeout === 'number') {
@@ -508,6 +513,7 @@ export class TimeoutTimer implements IDisposable {
dispose(): void {
this.cancel();
super.dispose();
}
cancel(): void {
@@ -537,16 +543,18 @@ export class TimeoutTimer implements IDisposable {
}
}
export class IntervalTimer implements IDisposable {
export class IntervalTimer extends Disposable {
private _token: any;
constructor() {
super();
this._token = -1;
}
dispose(): void {
this.cancel();
super.dispose();
}
cancel(): void {

View File

@@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { IDisposable } from 'vs/base/common/lifecycle';
export interface CacheResult<T> extends IDisposable {
export interface CacheResult<T> {
promise: Promise<T>;
dispose(): void;
}
export class Cache<T> {

View File

@@ -6,11 +6,11 @@
import { IAction } from 'vs/base/common/actions';
export interface IErrorOptions {
actions?: ReadonlyArray<IAction>;
actions?: IAction[];
}
export interface IErrorWithActions {
actions?: ReadonlyArray<IAction>;
actions?: IAction[];
}
export function isErrorWithActions(obj: any): obj is IErrorWithActions {

View File

@@ -5,7 +5,7 @@
import { onUnexpectedError } from 'vs/base/common/errors';
import { once as onceFn } from 'vs/base/common/functional';
import { Disposable, IDisposable, toDisposable, combinedDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { combinedDisposable, Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { LinkedList } from 'vs/base/common/linkedList';
/**
@@ -13,11 +13,12 @@ import { LinkedList } from 'vs/base/common/linkedList';
* can be subscribed. The event is the subscriber function itself.
*/
export interface Event<T> {
(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;
(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[]): IDisposable;
}
export namespace Event {
export const None: Event<any> = () => Disposable.None;
const _disposable = { dispose() { } };
export const None: Event<any> = function () { return _disposable; };
/**
* Given an event, returns another event which only fires once.
@@ -85,7 +86,7 @@ export namespace Event {
* whenever any of the provided events emit.
*/
export function any<T>(...events: Event<T>[]): Event<T> {
return (listener, thisArgs = null, disposables?) => combinedDisposable(...events.map(event => event(e => listener.call(thisArgs, e), null, disposables)));
return (listener, thisArgs = null, disposables?) => combinedDisposable(events.map(event => event(e => listener.call(thisArgs, e), null, disposables)));
}
/**
@@ -476,7 +477,7 @@ export class Emitter<T> {
*/
get event(): Event<T> {
if (!this._event) {
this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {
this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[]) => {
if (!this._listeners) {
this._listeners = new LinkedList();
}
@@ -521,9 +522,7 @@ export class Emitter<T> {
}
}
};
if (disposables instanceof DisposableStore) {
disposables.add(result);
} else if (Array.isArray(disposables)) {
if (Array.isArray(disposables)) {
disposables.push(result);
}

View File

@@ -458,14 +458,14 @@ export function parse(arg1: string | IExpression | IRelativePattern, options: IG
if (parsedPattern === NULL) {
return FALSE;
}
const resultPattern: ParsedPattern & { allBasenames?: string[]; allPaths?: string[]; } = function (path: string, basename: string) {
const resultPattern = function (path: string, basename: string) {
return !!parsedPattern(path, basename);
};
if (parsedPattern.allBasenames) {
resultPattern.allBasenames = parsedPattern.allBasenames;
(<ParsedStringPattern><any>resultPattern).allBasenames = parsedPattern.allBasenames;
}
if (parsedPattern.allPaths) {
resultPattern.allPaths = parsedPattern.allPaths;
(<ParsedStringPattern><any>resultPattern).allPaths = parsedPattern.allPaths;
}
return resultPattern;
}

View File

@@ -5,44 +5,6 @@
import { once } from 'vs/base/common/functional';
/**
* Enables logging of potentially leaked disposables.
*
* A disposable is considered leaked if it is not disposed or not registered as the child of
* another disposable. This tracking is very simple an only works for classes that either
* extend Disposable or use a DisposableStore. This means there are a lot of false positives.
*/
const TRACK_DISPOSABLES = false;
const __is_disposable_tracked__ = '__is_disposable_tracked__';
function markTracked<T extends IDisposable>(x: T): void {
if (!TRACK_DISPOSABLES) {
return;
}
if (x && x !== Disposable.None) {
try {
x[__is_disposable_tracked__] = true;
} catch {
// noop
}
}
}
function trackDisposable<T extends IDisposable>(x: T): void {
if (!TRACK_DISPOSABLES) {
return;
}
const stack = new Error().stack!;
setTimeout(() => {
if (!x[__is_disposable_tracked__]) {
console.log(stack);
}
}, 3000);
}
export interface IDisposable {
dispose(): void;
}
@@ -53,94 +15,56 @@ export function isDisposable<E extends object>(thing: E): thing is E & IDisposab
}
export function dispose<T extends IDisposable>(disposable: T): T;
export function dispose<T extends IDisposable>(disposable: T | undefined): T | undefined;
export function dispose<T extends IDisposable>(disposables: Array<T>): Array<T>;
export function dispose<T extends IDisposable>(disposables: ReadonlyArray<T>): ReadonlyArray<T>;
export function dispose<T extends IDisposable>(disposables: T | T[] | undefined): T | T[] | undefined {
if (Array.isArray(disposables)) {
disposables.forEach(d => {
if (d) {
markTracked(d);
d.dispose();
}
});
export function dispose<T extends IDisposable>(...disposables: Array<T | undefined>): T[];
export function dispose<T extends IDisposable>(disposables: T[]): T[];
export function dispose<T extends IDisposable>(first: T | T[], ...rest: T[]): T | T[] | undefined {
if (Array.isArray(first)) {
first.forEach(d => d && d.dispose());
return [];
} else if (disposables) {
markTracked(disposables);
disposables.dispose();
return disposables;
} else {
} else if (rest.length === 0) {
if (first) {
first.dispose();
return first;
}
return undefined;
} else {
dispose(first);
dispose(rest);
return [];
}
}
export function combinedDisposable(...disposables: IDisposable[]): IDisposable {
disposables.forEach(markTracked);
export function combinedDisposable(disposables: IDisposable[]): IDisposable {
return { dispose: () => dispose(disposables) };
}
export function toDisposable(fn: () => void): IDisposable {
return { dispose: fn };
}
export class DisposableStore implements IDisposable {
private _toDispose = new Set<IDisposable>();
private _isDisposed = false;
/**
* Dispose of all registered disposables and mark this object as disposed.
*
* Any future disposables added to this object will be disposed of on `add`.
*/
public dispose(): void {
markTracked(this);
this._isDisposed = true;
this.clear();
}
/**
* Dispose of all registered disposables but do not mark this object as disposed.
*/
public clear(): void {
this._toDispose.forEach(item => item.dispose());
this._toDispose.clear();
}
public add<T extends IDisposable>(t: T): T {
if (!t) {
return t;
}
markTracked(t);
if (this._isDisposed) {
console.warn(new Error('Registering disposable on object that has already been disposed of').stack);
t.dispose();
} else {
this._toDispose.add(t);
}
return t;
}
return { dispose() { fn(); } };
}
export abstract class Disposable implements IDisposable {
static None = Object.freeze<IDisposable>({ dispose() { } });
private readonly _store = new DisposableStore();
protected _toDispose: IDisposable[] = [];
protected get toDispose(): IDisposable[] { return this._toDispose; }
constructor() {
trackDisposable(this);
}
private _lifecycle_disposable_isDisposed = false;
public dispose(): void {
markTracked(this);
this._store.dispose();
this._lifecycle_disposable_isDisposed = true;
this._toDispose = dispose(this._toDispose);
}
protected _register<T extends IDisposable>(t: T): T {
return this._store.add(t);
if (this._lifecycle_disposable_isDisposed) {
console.warn('Registering disposable on object that has already been disposed.');
t.dispose();
} else {
this._toDispose.push(t);
}
return t;
}
}
@@ -150,23 +74,22 @@ export interface IReference<T> extends IDisposable {
export abstract class ReferenceCollection<T> {
private references: Map<string, { readonly object: T; counter: number; }> = new Map();
private references: { [key: string]: { readonly object: T; counter: number; } } = Object.create(null);
constructor() { }
acquire(key: string): IReference<T> {
let reference = this.references.get(key);
let reference = this.references[key];
if (!reference) {
reference = { counter: 0, object: this.createReferencedObject(key) };
this.references.set(key, reference);
reference = this.references[key] = { counter: 0, object: this.createReferencedObject(key) };
}
const { object } = reference;
const dispose = once(() => {
if (--reference!.counter === 0) {
this.destroyReferencedObject(key, reference!.object);
this.references.delete(key);
if (--reference.counter === 0) {
this.destroyReferencedObject(key, reference.object);
delete this.references[key];
}
});

View File

@@ -96,16 +96,6 @@ const _empty = '';
const _slash = '/';
const _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
function _isQueryStringScheme(scheme: string) {
switch (scheme.toLowerCase()) {
case 'http':
case 'https':
case 'ftp':
return true;
}
return false;
}
/**
* Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.
* This class is a simple parser which creates the basic component parts
@@ -292,14 +282,14 @@ export class URI implements UriComponents {
static parse(value: string, _strict: boolean = false): URI {
const match = _regexp.exec(value);
if (!match) {
return new _URI(_empty, _empty, _empty, _empty, _empty, _strict);
return new _URI(_empty, _empty, _empty, _empty, _empty);
}
return new _URI(
match[2] || _empty,
decodeURIComponentFast(match[4] || _empty, false, false),
decodeURIComponentFast(match[5] || _empty, true, false),
decodeURIComponentFast(match[7] || _empty, false, _isQueryStringScheme(match[2])),
decodeURIComponentFast(match[9] || _empty, false, false),
decodeURIComponent(match[4] || _empty),
decodeURIComponent(match[5] || _empty),
decodeURIComponent(match[7] || _empty),
decodeURIComponent(match[9] || _empty),
_strict
);
}
@@ -331,7 +321,7 @@ export class URI implements UriComponents {
// normalize to fwd-slashes on windows,
// on other systems bwd-slashes are valid
// filename character, e.g. /f\oo/ba\r.txt
// filename character, eg /f\oo/ba\r.txt
if (isWindows) {
path = path.replace(/\\/g, _slash);
}
@@ -395,8 +385,8 @@ export class URI implements UriComponents {
return data;
} else {
const result = new _URI(data);
result._fsPath = (<UriState>data).fsPath;
result._formatted = (<UriState>data).external;
result._fsPath = (<UriState>data)._sep === _pathSepMarker ? (<UriState>data).fsPath : null;
return result;
}
}
@@ -412,12 +402,10 @@ export interface UriComponents {
interface UriState extends UriComponents {
$mid: number;
external: string;
fsPath: string;
_sep: 1 | undefined;
external: string;
}
const _pathSepMarker = isWindows ? 1 : undefined;
// tslint:disable-next-line:class-name
class _URI extends URI {
@@ -451,7 +439,6 @@ class _URI extends URI {
// cached state
if (this._fsPath) {
res.fsPath = this._fsPath;
res._sep = _pathSepMarker;
}
if (this._formatted) {
res.external = this._formatted;
@@ -476,84 +463,6 @@ class _URI extends URI {
}
}
function isHex(value: string, pos: number): boolean {
if (pos >= value.length) {
return false;
}
const code = value.charCodeAt(pos);
return (code >= CharCode.Digit0 && code <= CharCode.Digit9)// 0-9
|| (code >= CharCode.a && code <= CharCode.f) //a-f
|| (code >= CharCode.A && code <= CharCode.F); //A-F
}
function decodeURIComponentFast(uriComponent: string, isPath: boolean, isQueryString: boolean): string {
let res: string | undefined;
let nativeDecodePos = -1;
for (let pos = 0; pos < uriComponent.length; pos++) {
const code = uriComponent.charCodeAt(pos);
// decoding needed
if (code === CharCode.PercentSign && isHex(uriComponent, pos + 1) && isHex(uriComponent, pos + 2)) {
const chA = uriComponent.charCodeAt(pos + 1);
const chB = uriComponent.charCodeAt(pos + 2);
// when in a path -> check and accept %2f and %2F (fwd slash)
// when in a query string -> check and accept %3D, %26, and %3B (equals, ampersand, semi-colon)
if (
(isPath && chA === CharCode.Digit2 && (chB === CharCode.F || chB === CharCode.f))
||
(isQueryString && (
(chA === CharCode.Digit2 && chB === CharCode.Digit6) // %26
||
(chA === CharCode.Digit3 && (chB === CharCode.B || chB === CharCode.b || chB === CharCode.D || chB === CharCode.d)) // %3D, %3D
))
) {
if (nativeDecodePos !== -1) {
res += decodeURIComponent(uriComponent.substring(nativeDecodePos, pos));
nativeDecodePos = -1;
}
if (res !== undefined) {
res += uriComponent.substr(pos, 3);
}
pos += 2;
continue;
}
if (res === undefined) {
res = uriComponent.substring(0, pos);
}
if (nativeDecodePos === -1) {
nativeDecodePos = pos;
}
pos += 2;
} else {
if (nativeDecodePos !== -1) {
res += decodeURIComponent(uriComponent.substring(nativeDecodePos, pos));
nativeDecodePos = -1;
}
if (res !== undefined) {
res += String.fromCharCode(code);
}
}
}
if (nativeDecodePos !== -1) {
res += decodeURIComponent(uriComponent.substr(nativeDecodePos));
}
return res !== undefined ? res : uriComponent;
}
// reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2
const encodeTable: { [ch: number]: string } = {
[CharCode.Colon]: '%3A', // gen-delims
@@ -579,7 +488,7 @@ const encodeTable: { [ch: number]: string } = {
[CharCode.Space]: '%20',
};
function encodeURIComponentFast(uriComponent: string, isPath: boolean, isQueryString: boolean): string {
function encodeURIComponentFast(uriComponent: string, allowSlash: boolean): string {
let res: string | undefined = undefined;
let nativeEncodePos = -1;
@@ -595,8 +504,7 @@ function encodeURIComponentFast(uriComponent: string, isPath: boolean, isQuerySt
|| code === CharCode.Period
|| code === CharCode.Underline
|| code === CharCode.Tilde
|| (isPath && code === CharCode.Slash) // path => allow slash AS-IS
|| (isQueryString && (code === CharCode.Equals || code === CharCode.Ampersand || code === CharCode.Semicolon)) // query string => allow &=;
|| (allowSlash && code === CharCode.Slash)
) {
// check if we are delaying native encode
if (nativeEncodePos !== -1) {
@@ -608,20 +516,6 @@ function encodeURIComponentFast(uriComponent: string, isPath: boolean, isQuerySt
res += uriComponent.charAt(pos);
}
} else if (code === CharCode.PercentSign && isHex(uriComponent, pos + 1) && isHex(uriComponent, pos + 2)) {
// at percentage encoded value
// check if we are delaying native encode
if (nativeEncodePos !== -1) {
res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));
nativeEncodePos = -1;
}
// check if we write into a new string (by default we try to return the param)
if (res !== undefined) {
res += uriComponent.substr(pos, 3);
}
pos += 2;
} else {
// encoding needed, we need to allocate a new string
if (res === undefined) {
@@ -710,7 +604,6 @@ function _asFormatted(uri: URI, skipEncoding: boolean): string {
let res = '';
let { scheme, authority, path, query, fragment } = uri;
if (scheme) {
res += scheme;
res += ':';
@@ -727,22 +620,22 @@ function _asFormatted(uri: URI, skipEncoding: boolean): string {
authority = authority.substr(idx + 1);
idx = userinfo.indexOf(':');
if (idx === -1) {
res += encoder(userinfo, false, false);
res += encoder(userinfo, false);
} else {
// <user>:<pass>@<auth>
res += encoder(userinfo.substr(0, idx), false, false);
res += encoder(userinfo.substr(0, idx), false);
res += ':';
res += encoder(userinfo.substr(idx + 1), false, false);
res += encoder(userinfo.substr(idx + 1), false);
}
res += '@';
}
authority = authority.toLowerCase();
idx = authority.indexOf(':');
if (idx === -1) {
res += encoder(authority, false, false);
res += encoder(authority, false);
} else {
// <auth>:<port>
res += encoder(authority.substr(0, idx), false, false);
res += encoder(authority.substr(0, idx), false);
res += authority.substr(idx);
}
}
@@ -760,15 +653,15 @@ function _asFormatted(uri: URI, skipEncoding: boolean): string {
}
}
// encode the rest of the path
res += encoder(path, true, false);
res += encoder(path, true);
}
if (query) {
res += '?';
res += encoder(query, false, _isQueryStringScheme(scheme));
res += encoder(query, false);
}
if (fragment) {
res += '#';
res += !skipEncoding ? encodeURIComponentFast(fragment, false, false) : fragment;
res += !skipEncoding ? encodeURIComponentFast(fragment, false) : fragment;
}
return res;
}

View File

@@ -10,51 +10,6 @@ export interface IURITransformer {
transformIncoming(uri: UriComponents): UriComponents;
transformOutgoing(uri: UriComponents): UriComponents;
transformOutgoingURI(uri: URI): URI;
transformOutgoingScheme(scheme: string): string;
}
export interface UriParts {
scheme: string;
authority?: string;
path?: string;
}
export interface IRawURITransformer {
transformIncoming(uri: UriParts): UriParts;
transformOutgoing(uri: UriParts): UriParts;
transformOutgoingScheme(scheme: string): string;
}
function toJSON(uri: URI): UriComponents {
return <UriComponents><any>uri.toJSON();
}
export class URITransformer implements IURITransformer {
private readonly _uriTransformer: IRawURITransformer;
constructor(uriTransformer: IRawURITransformer) {
this._uriTransformer = uriTransformer;
}
public transformIncoming(uri: UriComponents): UriComponents {
const result = this._uriTransformer.transformIncoming(uri);
return (result === uri ? uri : toJSON(URI.from(result)));
}
public transformOutgoing(uri: UriComponents): UriComponents {
const result = this._uriTransformer.transformOutgoing(uri);
return (result === uri ? uri : toJSON(URI.from(result)));
}
public transformOutgoingURI(uri: URI): URI {
const result = this._uriTransformer.transformOutgoing(uri);
return (result === uri ? uri : URI.from(result));
}
public transformOutgoingScheme(scheme: string): string {
return this._uriTransformer.transformOutgoingScheme(scheme);
}
}
export const DefaultURITransformer: IURITransformer = new class {
@@ -69,10 +24,6 @@ export const DefaultURITransformer: IURITransformer = new class {
transformOutgoingURI(uri: URI): URI {
return uri;
}
transformOutgoingScheme(scheme: string): string {
return scheme;
}
};
function _transformOutgoingURIs(obj: any, transformer: IURITransformer, depth: number): any {

View File

@@ -4,15 +4,16 @@
*--------------------------------------------------------------------------------------------*/
import { transformErrorForSerialization } from 'vs/base/common/errors';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { Disposable } from 'vs/base/common/lifecycle';
import { isWeb } from 'vs/base/common/platform';
import { getAllPropertyNames } from 'vs/base/common/types';
const INITIALIZE = '$initialize';
export interface IWorker extends IDisposable {
export interface IWorker {
getId(): number;
postMessage(message: string): void;
dispose(): void;
}
export interface IWorkerCallback {