Skip to content

Commit 4e2d923

Browse files
committed
🔨 create IContext
1 parent c5dc515 commit 4e2d923

8 files changed

Lines changed: 73 additions & 74 deletions

File tree

src/vs/platform/contextkey/browser/contextKeyService.ts

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,19 @@
77
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
88
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
99
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
10-
import { IContextKey, IContextKeyServiceTarget, IContextKeyService, SET_CONTEXT_COMMAND_ID, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
10+
import { IContextKey, IContext, IContextKeyServiceTarget, IContextKeyService, SET_CONTEXT_COMMAND_ID, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
1111
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
1212
import Event, { Emitter, debounceEvent } from 'vs/base/common/event';
1313

1414
const KEYBINDING_CONTEXT_ATTR = 'data-keybinding-context';
1515

16-
export class ContextValuesContainer {
17-
protected _parent: ContextValuesContainer;
16+
export class Context implements IContext {
17+
18+
protected _parent: Context;
1819
protected _value: { [key: string]: any; };
1920
protected _id: number;
2021

21-
constructor(id: number, parent: ContextValuesContainer) {
22+
constructor(id: number, parent: Context) {
2223
this._id = id;
2324
this._parent = parent;
2425
this._value = Object.create(null);
@@ -46,18 +47,9 @@ export class ContextValuesContainer {
4647
}
4748
return ret;
4849
}
49-
50-
public fillInContext(bucket: any): void {
51-
if (this._parent) {
52-
this._parent.fillInContext(bucket);
53-
}
54-
for (let key in this._value) {
55-
bucket[key] = this._value[key];
56-
}
57-
}
5850
}
5951

60-
class ConfigAwareContextValuesContainer extends ContextValuesContainer {
52+
class ConfigAwareContextValuesContainer extends Context {
6153

6254
private _emitter: Emitter<string>;
6355
private _subscription: IDisposable;
@@ -169,9 +161,8 @@ export abstract class AbstractContextKeyService {
169161
}
170162

171163
public contextMatchesRules(rules: ContextKeyExpr): boolean {
172-
const ctx = Object.create(null);
173-
this.getContextValuesContainer(this._myContextId).fillInContext(ctx);
174-
const result = KeybindingResolver.contextMatchesRules(ctx, rules);
164+
const context = this.getContextValuesContainer(this._myContextId);
165+
const result = KeybindingResolver.contextMatchesRules(context, rules);
175166
// console.group(rules.serialize() + ' -> ' + result);
176167
// rules.keys().forEach(key => { console.log(key, ctx[key]); });
177168
// console.groupEnd();
@@ -194,13 +185,11 @@ export abstract class AbstractContextKeyService {
194185
}
195186
}
196187

197-
public getContextValue(target: IContextKeyServiceTarget): any {
198-
let res = Object.create(null);
199-
this.getContextValuesContainer(findContextAttr(target)).fillInContext(res);
200-
return res;
188+
public getContext(target: IContextKeyServiceTarget): IContext {
189+
return this.getContextValuesContainer(findContextAttr(target));
201190
}
202191

203-
public abstract getContextValuesContainer(contextId: number): ContextValuesContainer;
192+
public abstract getContextValuesContainer(contextId: number): Context;
204193
public abstract createChildContext(parentContextId?: number): number;
205194
public abstract disposeContext(contextId: number): void;
206195
}
@@ -209,7 +198,7 @@ export class ContextKeyService extends AbstractContextKeyService implements ICon
209198

210199
private _lastContextId: number;
211200
private _contexts: {
212-
[contextId: string]: ContextValuesContainer;
201+
[contextId: string]: Context;
213202
};
214203

215204
private _toDispose: IDisposable[] = [];
@@ -239,13 +228,13 @@ export class ContextKeyService extends AbstractContextKeyService implements ICon
239228
this._toDispose = dispose(this._toDispose);
240229
}
241230

242-
public getContextValuesContainer(contextId: number): ContextValuesContainer {
231+
public getContextValuesContainer(contextId: number): Context {
243232
return this._contexts[String(contextId)];
244233
}
245234

246235
public createChildContext(parentContextId: number = this._myContextId): number {
247236
let id = (++this._lastContextId);
248-
this._contexts[String(id)] = new ContextValuesContainer(id, this.getContextValuesContainer(parentContextId));
237+
this._contexts[String(id)] = new Context(id, this.getContextValuesContainer(parentContextId));
249238
return id;
250239
}
251240

@@ -281,7 +270,7 @@ class ScopedContextKeyService extends AbstractContextKeyService {
281270
return this._parent.onDidChangeContext;
282271
}
283272

284-
public getContextValuesContainer(contextId: number): ContextValuesContainer {
273+
public getContextValuesContainer(contextId: number): Context {
285274
return this._parent.getContextValuesContainer(contextId);
286275
}
287276

src/vs/platform/contextkey/common/contextkey.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export abstract class ContextKeyExpr {
8888

8989
public abstract getType(): ContextKeyExprType;
9090
public abstract equals(other: ContextKeyExpr): boolean;
91-
public abstract evaluate(context: any): boolean;
91+
public abstract evaluate(context: IContext): boolean;
9292
public abstract normalize(): ContextKeyExpr;
9393
public abstract serialize(): string;
9494
public abstract keys(): string[];
@@ -139,8 +139,8 @@ export class ContextKeyDefinedExpr implements ContextKeyExpr {
139139
return false;
140140
}
141141

142-
public evaluate(context: any): boolean {
143-
return (!!context[this.key]);
142+
public evaluate(context: IContext): boolean {
143+
return (!!context.getValue(this.key));
144144
}
145145

146146
public normalize(): ContextKeyExpr {
@@ -187,10 +187,10 @@ export class ContextKeyEqualsExpr implements ContextKeyExpr {
187187
return false;
188188
}
189189

190-
public evaluate(context: any): boolean {
190+
public evaluate(context: IContext): boolean {
191191
/* tslint:disable:triple-equals */
192192
// Intentional ==
193-
return (context[this.key] == this.value);
193+
return (context.getValue(this.key) == this.value);
194194
/* tslint:enable:triple-equals */
195195
}
196196

@@ -248,10 +248,10 @@ export class ContextKeyNotEqualsExpr implements ContextKeyExpr {
248248
return false;
249249
}
250250

251-
public evaluate(context: any): boolean {
251+
public evaluate(context: IContext): boolean {
252252
/* tslint:disable:triple-equals */
253253
// Intentional !=
254-
return (context[this.key] != this.value);
254+
return (context.getValue(this.key) != this.value);
255255
/* tslint:enable:triple-equals */
256256
}
257257

@@ -303,8 +303,8 @@ export class ContextKeyNotExpr implements ContextKeyExpr {
303303
return false;
304304
}
305305

306-
public evaluate(context: any): boolean {
307-
return (!context[this.key]);
306+
public evaluate(context: IContext): boolean {
307+
return (!context.getValue(this.key));
308308
}
309309

310310
public normalize(): ContextKeyExpr {
@@ -346,7 +346,7 @@ export class ContextKeyAndExpr implements ContextKeyExpr {
346346
return false;
347347
}
348348

349-
public evaluate(context: any): boolean {
349+
public evaluate(context: IContext): boolean {
350350
for (let i = 0, len = this.expr.length; i < len; i++) {
351351
if (!this.expr[i].evaluate(context)) {
352352
return false;
@@ -441,6 +441,10 @@ export class RawContextKey<T> extends ContextKeyDefinedExpr {
441441
}
442442
}
443443

444+
export interface IContext {
445+
getValue<T>(key: string): T;
446+
}
447+
444448
export interface IContextKey<T> {
445449
set(value: T): void;
446450
reset(): void;
@@ -467,7 +471,7 @@ export interface IContextKeyService {
467471
getContextKeyValue<T>(key: string): T;
468472

469473
createScoped(target?: IContextKeyServiceTarget): IContextKeyService;
470-
getContextValue(target: IContextKeyServiceTarget): any;
474+
getContext(target: IContextKeyServiceTarget): IContext;
471475
}
472476

473477
export const SET_CONTEXT_COMMAND_ID = 'setContext';

src/vs/platform/contextkey/test/common/contextkey.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import * as assert from 'assert';
88
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
99

10+
const createContext = ctx => ({ getValue: key => ctx[key] });
11+
1012
suite('ContextKeyExpr', () => {
1113
test('ContextKeyExpr.equals', function () {
1214
let a = ContextKeyExpr.and(
@@ -48,11 +50,11 @@ suite('ContextKeyExpr', () => {
4850

4951
test('evaluate', function () {
5052
/* tslint:disable:triple-equals */
51-
let context = {
53+
let context = createContext({
5254
'a': true,
5355
'b': false,
5456
'c': '5'
55-
};
57+
});
5658
function testExpression(expr: string, expected: boolean): void {
5759
let rules = ContextKeyExpr.deserialize(expr);
5860
assert.equal(rules.evaluate(context), expected, expr);

src/vs/platform/keybinding/common/abstractKeybindingService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ export abstract class AbstractKeybindingService implements IKeybindingService {
230230
return null;
231231
}
232232

233-
const contextValue = this._contextKeyService.getContextValue(target);
233+
const contextValue = this._contextKeyService.getContext(target);
234234
const currentChord = this._currentChord ? this._currentChord.keypress : null;
235235
const keypress = keybinding.value.toString();
236236
return this._getResolver().resolve(contextValue, currentChord, keypress);
@@ -244,7 +244,7 @@ export abstract class AbstractKeybindingService implements IKeybindingService {
244244
return shouldPreventDefault;
245245
}
246246

247-
const contextValue = this._contextKeyService.getContextValue(target);
247+
const contextValue = this._contextKeyService.getContext(target);
248248
const currentChord = this._currentChord ? this._currentChord.keypress : null;
249249
const keypress = keybinding.value.toString();
250250
const keypressLabel = this._createResolvedKeybinding(keybinding).getLabel();

src/vs/platform/keybinding/common/keybindingResolver.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55
'use strict';
66

7-
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
7+
import { ContextKeyExpr, IContext } from 'vs/platform/contextkey/common/contextkey';
88
import { NormalizedKeybindingItem } from 'vs/platform/keybinding/common/normalizedKeybindingItem';
99

1010
export interface IResolveResult {
@@ -227,7 +227,7 @@ export class KeybindingResolver {
227227
return items[items.length - 1];
228228
}
229229

230-
public resolve(context: any, currentChord: string, keypress: string): IResolveResult {
230+
public resolve(context: IContext, currentChord: string, keypress: string): IResolveResult {
231231
let lookupMap: NormalizedKeybindingItem[] = null;
232232

233233
if (currentChord !== null) {
@@ -278,7 +278,7 @@ export class KeybindingResolver {
278278
};
279279
}
280280

281-
private _findCommand(context: any, matches: NormalizedKeybindingItem[]): NormalizedKeybindingItem {
281+
private _findCommand(context: IContext, matches: NormalizedKeybindingItem[]): NormalizedKeybindingItem {
282282
for (let i = matches.length - 1; i >= 0; i--) {
283283
let k = matches[i];
284284

@@ -292,7 +292,7 @@ export class KeybindingResolver {
292292
return null;
293293
}
294294

295-
public static contextMatchesRules(context: any, rules: ContextKeyExpr): boolean {
295+
public static contextMatchesRules(context: IContext, rules: ContextKeyExpr): boolean {
296296
if (!rules) {
297297
return true;
298298
}

src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ import { IDisposable } from 'vs/base/common/lifecycle';
1111
import Severity from 'vs/base/common/severity';
1212
import { ICommandService } from 'vs/platform/commands/common/commands';
1313
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
14-
import { ContextKeyExpr, IContextKeyService, IContextKeyServiceTarget } from 'vs/platform/contextkey/common/contextkey';
14+
import { IContext, ContextKeyExpr, IContextKeyService, IContextKeyServiceTarget } from 'vs/platform/contextkey/common/contextkey';
1515
import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
1616
import { IMessageService } from 'vs/platform/message/common/message';
1717
import { TPromise } from 'vs/base/common/winjs.base';
1818
import { NormalizedKeybindingItem } from 'vs/platform/keybinding/common/normalizedKeybindingItem';
1919
import { OS } from 'vs/base/common/platform';
2020

21+
const createContext = ctx => ({ getValue: key => ctx[key] });
22+
2123
suite('AbstractKeybindingService', () => {
2224

2325
class TestKeybindingService extends AbstractKeybindingService {
@@ -48,7 +50,7 @@ suite('AbstractKeybindingService', () => {
4850
}
4951

5052
let createTestKeybindingService: (items: NormalizedKeybindingItem[], contextValue?: any) => TestKeybindingService = null;
51-
let currentContextValue: any = null;
53+
let currentContextValue: IContext = null;
5254
let executeCommandCalls: { commandId: string; args: any[]; }[] = null;
5355
let showMessageCalls: { sev: Severity, message: any; }[] = null;
5456
let statusMessageCalls: string[] = null;
@@ -70,7 +72,7 @@ suite('AbstractKeybindingService', () => {
7072
contextMatchesRules: undefined,
7173
getContextKeyValue: undefined,
7274
createScoped: undefined,
73-
getContextValue: (target: IContextKeyServiceTarget): any => {
75+
getContext: (target: IContextKeyServiceTarget): any => {
7476
return currentContextValue;
7577
}
7678
};
@@ -248,9 +250,9 @@ suite('AbstractKeybindingService', () => {
248250

249251

250252
// send Ctrl/Cmd + K
251-
currentContextValue = {
253+
currentContextValue = createContext({
252254
key1: true
253-
};
255+
});
254256
let shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K));
255257
assert.equal(shouldPreventDefault, true);
256258
assert.deepEqual(executeCommandCalls, [{
@@ -266,7 +268,7 @@ suite('AbstractKeybindingService', () => {
266268
statusMessageCallsDisposed = [];
267269

268270
// send Ctrl/Cmd + K
269-
currentContextValue = {};
271+
currentContextValue = createContext({});
270272
shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K));
271273
assert.equal(shouldPreventDefault, true);
272274
assert.deepEqual(executeCommandCalls, []);
@@ -281,7 +283,7 @@ suite('AbstractKeybindingService', () => {
281283
statusMessageCallsDisposed = [];
282284

283285
// send Ctrl/Cmd + X
284-
currentContextValue = {};
286+
currentContextValue = createContext({});
285287
shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_X));
286288
assert.equal(shouldPreventDefault, true);
287289
assert.deepEqual(executeCommandCalls, [{
@@ -310,7 +312,7 @@ suite('AbstractKeybindingService', () => {
310312

311313

312314
// send Ctrl/Cmd + K
313-
currentContextValue = {};
315+
currentContextValue = createContext({});
314316
let shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K));
315317
assert.equal(shouldPreventDefault, true);
316318
assert.deepEqual(executeCommandCalls, [{
@@ -326,9 +328,9 @@ suite('AbstractKeybindingService', () => {
326328
statusMessageCallsDisposed = [];
327329

328330
// send Ctrl/Cmd + K
329-
currentContextValue = {
331+
currentContextValue = createContext({
330332
key1: true
331-
};
333+
});
332334
shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K));
333335
assert.equal(shouldPreventDefault, true);
334336
assert.deepEqual(executeCommandCalls, [{
@@ -344,9 +346,9 @@ suite('AbstractKeybindingService', () => {
344346
statusMessageCallsDisposed = [];
345347

346348
// send Ctrl/Cmd + X
347-
currentContextValue = {
349+
currentContextValue = createContext({
348350
key1: true
349-
};
351+
});
350352
shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_X));
351353
assert.equal(shouldPreventDefault, false);
352354
assert.deepEqual(executeCommandCalls, []);
@@ -368,7 +370,7 @@ suite('AbstractKeybindingService', () => {
368370
]);
369371

370372
// send Ctrl/Cmd + K
371-
currentContextValue = {};
373+
currentContextValue = createContext({});
372374
let shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K));
373375
assert.equal(shouldPreventDefault, false);
374376
assert.deepEqual(executeCommandCalls, [{

0 commit comments

Comments
 (0)