From a89ed2b1ee82fe72e1370e2f8d709ba2c1bafcff Mon Sep 17 00:00:00 2001 From: chrisdias Date: Mon, 15 Jan 2018 17:39:50 -0800 Subject: [PATCH 1/2] fixes #26044 --- .../platform/contextkey/common/contextkey.ts | 64 ++++++++++++++++++- .../contextkey/test/common/contextkey.test.ts | 11 +++- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/contextkey/common/contextkey.ts b/src/vs/platform/contextkey/common/contextkey.ts index 69381904e0a..f578e60070a 100644 --- a/src/vs/platform/contextkey/common/contextkey.ts +++ b/src/vs/platform/contextkey/common/contextkey.ts @@ -6,13 +6,15 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import Event from 'vs/base/common/event'; +import { match } from 'vs/base/common/glob'; export enum ContextKeyExprType { Defined = 1, Not = 2, Equals = 3, NotEquals = 4, - And = 5 + And = 5, + Glob = 6 } export abstract class ContextKeyExpr { @@ -29,6 +31,10 @@ export abstract class ContextKeyExpr { return new ContextKeyNotEqualsExpr(key, value); } + public static glob(key: string, value: string): ContextKeyExpr { + return new ContextKeyGlobExpr(key, value); + } + public static not(key: string): ContextKeyExpr { return new ContextKeyNotExpr(key); } @@ -60,6 +66,11 @@ export abstract class ContextKeyExpr { return new ContextKeyEqualsExpr(pieces[0].trim(), this._deserializeValue(pieces[1])); } + if (serializedOne.indexOf('=~') >= 0) { + let pieces = serializedOne.split('=~'); + return new ContextKeyGlobExpr(pieces[0].trim(), this._deserializeValue(pieces[1])); + } + if (/^\!\s*/.test(serializedOne)) { return new ContextKeyNotExpr(serializedOne.substr(1).trim()); } @@ -109,6 +120,8 @@ function cmp(a: ContextKeyExpr, b: ContextKeyExpr): number { return (a).cmp(b); case ContextKeyExprType.NotEquals: return (a).cmp(b); + case ContextKeyExprType.Glob: + return (a).cmp(b); default: throw new Error('Unknown ContextKeyExpr!'); } @@ -320,6 +333,55 @@ export class ContextKeyNotExpr implements ContextKeyExpr { } } +export class ContextKeyGlobExpr implements ContextKeyExpr { + + constructor(private key: string, private value: any) { + } + + public getType(): ContextKeyExprType { + return ContextKeyExprType.Glob; + } + + public cmp(other: ContextKeyGlobExpr): number { + if (this.key < other.key) { + return -1; + } + if (this.key > other.key) { + return 1; + } + if (this.value < other.value) { + return -1; + } + if (this.value > other.value) { + return 1; + } + return 0; + } + + public equals(other: ContextKeyExpr): boolean { + if (other instanceof ContextKeyGlobExpr) { + return (this.key === other.key && this.value === other.value); + } + return false; + } + + public evaluate(context: IContext): boolean { + return match(this.value, context.getValue(this.key)) + } + + public normalize(): ContextKeyExpr { + return this; + } + + public serialize(): string { + return this.key + ' =~ \'' + this.value + '\''; + } + + public keys(): string[] { + return [this.key]; + } +} + export class ContextKeyAndExpr implements ContextKeyExpr { public readonly expr: ContextKeyExpr[]; diff --git a/src/vs/platform/contextkey/test/common/contextkey.test.ts b/src/vs/platform/contextkey/test/common/contextkey.test.ts index 69f8bca0930..4cdda5588c5 100644 --- a/src/vs/platform/contextkey/test/common/contextkey.test.ts +++ b/src/vs/platform/contextkey/test/common/contextkey.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { match } from 'vs/base/common/glob'; function createContext(ctx: any) { return { @@ -21,6 +22,8 @@ suite('ContextKeyExpr', () => { ContextKeyExpr.has('a1'), ContextKeyExpr.and(ContextKeyExpr.has('and.a')), ContextKeyExpr.has('a2'), + ContextKeyExpr.glob('d3', '**/d*'), + ContextKeyExpr.glob('d4', '**/3*'), ContextKeyExpr.equals('b1', 'bb1'), ContextKeyExpr.equals('b2', 'bb2'), ContextKeyExpr.notEquals('c1', 'cc1'), @@ -32,9 +35,11 @@ suite('ContextKeyExpr', () => { ContextKeyExpr.equals('b2', 'bb2'), ContextKeyExpr.notEquals('c1', 'cc1'), ContextKeyExpr.not('d1'), + ContextKeyExpr.glob('d4', '**/3*'), ContextKeyExpr.notEquals('c2', 'cc2'), ContextKeyExpr.has('a2'), ContextKeyExpr.equals('b1', 'bb1'), + ContextKeyExpr.glob('d3', '**/d*'), ContextKeyExpr.has('a1'), ContextKeyExpr.and(ContextKeyExpr.equals('and.a', true)), ContextKeyExpr.not('d2') @@ -59,9 +64,11 @@ suite('ContextKeyExpr', () => { let context = createContext({ 'a': true, 'b': false, - 'c': '5' + 'c': '5', + 'd': 'd' }); function testExpression(expr: string, expected: boolean): void { + console.log(expr + ' ' + expected); let rules = ContextKeyExpr.deserialize(expr); assert.equal(rules.evaluate(context), expected, expr); } @@ -74,11 +81,13 @@ suite('ContextKeyExpr', () => { testExpression(expr + ' == 5', value == '5'); testExpression(expr + ' != 5', value != '5'); testExpression('!' + expr, !value); + testExpression(expr + ' =~ **/d*', match('**/d*', value)); } testBatch('a', true); testBatch('b', false); testBatch('c', '5'); + testBatch('d', 'd'); testBatch('z', undefined); testExpression('a && !b', true && !false); From df96558335782a39ef4b2df9bdbee0612ec63eed Mon Sep 17 00:00:00 2001 From: chrisdias Date: Mon, 15 Jan 2018 17:40:10 -0800 Subject: [PATCH 2/2] hygene --- src/vs/platform/contextkey/common/contextkey.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/contextkey/common/contextkey.ts b/src/vs/platform/contextkey/common/contextkey.ts index f578e60070a..5461a40cf07 100644 --- a/src/vs/platform/contextkey/common/contextkey.ts +++ b/src/vs/platform/contextkey/common/contextkey.ts @@ -366,7 +366,7 @@ export class ContextKeyGlobExpr implements ContextKeyExpr { } public evaluate(context: IContext): boolean { - return match(this.value, context.getValue(this.key)) + return match(this.value, context.getValue(this.key)); } public normalize(): ContextKeyExpr {