Merge from vscode 2b0b9136329c181a9e381463a1f7dc3a2d105a34 (#4880)

This commit is contained in:
Karl Burtram
2019-04-05 10:09:18 -07:00
committed by GitHub
parent 9bd7e30d18
commit cb5bcf2248
433 changed files with 8915 additions and 8361 deletions

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Emitter, Event } from 'vs/base/common/event';
import { Emitter, Event, PauseableEmitter } from 'vs/base/common/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { keys } from 'vs/base/common/map';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
@@ -95,7 +95,7 @@ class ConfigAwareContextValuesContainer extends Context {
constructor(
id: number,
private readonly _configurationService: IConfigurationService,
emitter: Emitter<string | string[]>
emitter: Emitter<IContextKeyChangeEvent>
) {
super(id, null);
@@ -104,7 +104,7 @@ class ConfigAwareContextValuesContainer extends Context {
// new setting, reset everything
const allKeys = keys(this._values);
this._values.clear();
emitter.fire(allKeys);
emitter.fire(new ArrayContextKeyChangeEvent(allKeys));
} else {
const changedKeys: string[] = [];
for (const configKey of event.affectedKeys) {
@@ -114,7 +114,7 @@ class ConfigAwareContextValuesContainer extends Context {
changedKeys.push(contextKey);
}
}
emitter.fire(changedKeys);
emitter.fire(new ArrayContextKeyChangeEvent(changedKeys));
}
});
}
@@ -165,44 +165,45 @@ class ConfigAwareContextValuesContainer extends Context {
class ContextKey<T> implements IContextKey<T> {
private _parent: AbstractContextKeyService;
private _service: AbstractContextKeyService;
private _key: string;
private _defaultValue: T | undefined;
constructor(parent: AbstractContextKeyService, key: string, defaultValue: T | undefined) {
this._parent = parent;
constructor(service: AbstractContextKeyService, key: string, defaultValue: T | undefined) {
this._service = service;
this._key = key;
this._defaultValue = defaultValue;
this.reset();
}
public set(value: T): void {
this._parent.setContext(this._key, value);
this._service.setContext(this._key, value);
}
public reset(): void {
if (typeof this._defaultValue === 'undefined') {
this._parent.removeContext(this._key);
this._service.removeContext(this._key);
} else {
this._parent.setContext(this._key, this._defaultValue);
this._service.setContext(this._key, this._defaultValue);
}
}
public get(): T | undefined {
return this._parent.getContextKeyValue<T>(this._key);
return this._service.getContextKeyValue<T>(this._key);
}
}
class SimpleContextKeyChangeEvent implements IContextKeyChangeEvent {
constructor(private readonly _key: string) { }
constructor(readonly key: string) { }
affectsSome(keys: IReadableSet<string>): boolean {
return keys.has(this._key);
return keys.has(this.key);
}
}
class ArrayContextKeyChangeEvent implements IContextKeyChangeEvent {
constructor(private readonly _keys: string[]) { }
constructor(readonly keys: string[]) { }
affectsSome(keys: IReadableSet<string>): boolean {
for (const key of this._keys) {
for (const key of this.keys) {
if (keys.has(key)) {
return true;
}
@@ -211,18 +212,28 @@ class ArrayContextKeyChangeEvent implements IContextKeyChangeEvent {
}
}
class CompositeContextKeyChangeEvent implements IContextKeyChangeEvent {
constructor(readonly events: IContextKeyChangeEvent[]) { }
affectsSome(keys: IReadableSet<string>): boolean {
for (const e of this.events) {
if (e.affectsSome(keys)) {
return true;
}
}
return false;
}
}
export abstract class AbstractContextKeyService implements IContextKeyService {
public _serviceBrand: any;
protected _isDisposed: boolean;
protected _onDidChangeContext: Event<IContextKeyChangeEvent>;
protected _onDidChangeContextKey: Emitter<string | string[]>;
protected _onDidChangeContext = new PauseableEmitter<IContextKeyChangeEvent>({ merge: input => new CompositeContextKeyChangeEvent(input) });
protected _myContextId: number;
constructor(myContextId: number) {
this._isDisposed = false;
this._myContextId = myContextId;
this._onDidChangeContextKey = new Emitter<string>();
}
abstract dispose(): void;
@@ -235,21 +246,23 @@ export abstract class AbstractContextKeyService implements IContextKeyService {
}
public get onDidChangeContext(): Event<IContextKeyChangeEvent> {
if (!this._onDidChangeContext) {
this._onDidChangeContext = Event.map(this._onDidChangeContextKey.event, ((changedKeyOrKeys): IContextKeyChangeEvent => {
return typeof changedKeyOrKeys === 'string'
? new SimpleContextKeyChangeEvent(changedKeyOrKeys)
: new ArrayContextKeyChangeEvent(changedKeyOrKeys);
}));
return this._onDidChangeContext.event;
}
bufferChangeEvents(callback: Function): void {
this._onDidChangeContext.pause();
try {
callback();
} finally {
this._onDidChangeContext.resume();
}
return this._onDidChangeContext;
}
public createScoped(domNode: IContextKeyServiceTarget): IContextKeyService {
if (this._isDisposed) {
throw new Error(`AbstractContextKeyService has been disposed`);
}
return new ScopedContextKeyService(this, this._onDidChangeContextKey, domNode);
return new ScopedContextKeyService(this, domNode);
}
public contextMatchesRules(rules: ContextKeyExpr | undefined): boolean {
@@ -280,7 +293,7 @@ export abstract class AbstractContextKeyService implements IContextKeyService {
return;
}
if (myContext.setValue(key, value)) {
this._onDidChangeContextKey.fire(key);
this._onDidChangeContext.fire(new SimpleContextKeyChangeEvent(key));
}
}
@@ -289,7 +302,7 @@ export abstract class AbstractContextKeyService implements IContextKeyService {
return;
}
if (this.getContextValuesContainer(this._myContextId).removeValue(key)) {
this._onDidChangeContextKey.fire(key);
this._onDidChangeContext.fire(new SimpleContextKeyChangeEvent(key));
}
}
@@ -308,19 +321,17 @@ export abstract class AbstractContextKeyService implements IContextKeyService {
export class ContextKeyService extends AbstractContextKeyService implements IContextKeyService {
private _lastContextId: number;
private _contexts: {
[contextId: string]: Context;
};
private readonly _contexts = new Map<number, Context>();
private _toDispose: IDisposable[] = [];
constructor(@IConfigurationService configurationService: IConfigurationService) {
super(0);
this._lastContextId = 0;
this._contexts = Object.create(null);
const myContext = new ConfigAwareContextValuesContainer(this._myContextId, configurationService, this._onDidChangeContextKey);
this._contexts[String(this._myContextId)] = myContext;
const myContext = new ConfigAwareContextValuesContainer(this._myContextId, configurationService, this._onDidChangeContext);
this._contexts.set(this._myContextId, myContext);
this._toDispose.push(myContext);
// Uncomment this to see the contexts continuously logged
@@ -344,7 +355,7 @@ export class ContextKeyService extends AbstractContextKeyService implements ICon
if (this._isDisposed) {
return NullContext.INSTANCE;
}
return this._contexts[String(contextId)];
return this._contexts.get(contextId) || NullContext.INSTANCE;
}
public createChildContext(parentContextId: number = this._myContextId): number {
@@ -352,15 +363,14 @@ export class ContextKeyService extends AbstractContextKeyService implements ICon
throw new Error(`ContextKeyService has been disposed`);
}
let id = (++this._lastContextId);
this._contexts[String(id)] = new Context(id, this.getContextValuesContainer(parentContextId));
this._contexts.set(id, new Context(id, this.getContextValuesContainer(parentContextId)));
return id;
}
public disposeContext(contextId: number): void {
if (this._isDisposed) {
return;
if (!this._isDisposed) {
this._contexts.delete(contextId);
}
delete this._contexts[String(contextId)];
}
}
@@ -369,10 +379,9 @@ class ScopedContextKeyService extends AbstractContextKeyService {
private _parent: AbstractContextKeyService;
private _domNode: IContextKeyServiceTarget | undefined;
constructor(parent: AbstractContextKeyService, emitter: Emitter<string | string[]>, domNode?: IContextKeyServiceTarget) {
constructor(parent: AbstractContextKeyService, domNode?: IContextKeyServiceTarget) {
super(parent.createChildContext());
this._parent = parent;
this._onDidChangeContextKey = emitter;
if (domNode) {
this._domNode = domNode;
@@ -390,7 +399,7 @@ class ScopedContextKeyService extends AbstractContextKeyService {
}
public get onDidChangeContext(): Event<IContextKeyChangeEvent> {
return this._parent.onDidChangeContext;
return Event.any(this._parent.onDidChangeContext, this._onDidChangeContext.event);
}
public getContextValuesContainer(contextId: number): Context {

View File

@@ -762,6 +762,9 @@ export interface IContextKeyService {
dispose(): void;
onDidChangeContext: Event<IContextKeyChangeEvent>;
bufferChangeEvents(callback: Function): void;
createKey<T>(key: string, defaultValue: T | undefined): IContextKey<T>;
contextMatchesRules(rules: ContextKeyExpr | undefined): boolean;
getContextKeyValue<T>(key: string): T | undefined;