Merge pull request #41646 from Microsoft/chrisdias/contextkeyglobexpr

Chrisdias/contextkeyglobexpr
This commit is contained in:
Alexandru Dima
2018-01-23 10:37:25 +01:00
committed by GitHub
2 changed files with 73 additions and 2 deletions
@@ -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 (<ContextKeyEqualsExpr>a).cmp(<ContextKeyEqualsExpr>b);
case ContextKeyExprType.NotEquals:
return (<ContextKeyNotEqualsExpr>a).cmp(<ContextKeyNotEqualsExpr>b);
case ContextKeyExprType.Glob:
return (<ContextKeyGlobExpr>a).cmp(<ContextKeyGlobExpr>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[];
@@ -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 == <any>'5');
testExpression(expr + ' != 5', value != <any>'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);