Skip to content

Commit

Permalink
make =~ actually be a regex test operation, microsoft#26044
Browse files Browse the repository at this point in the history
  • Loading branch information
jrieken committed Jan 23, 2018
1 parent 6531827 commit 24ecf49
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 24 deletions.
41 changes: 24 additions & 17 deletions src/vs/platform/contextkey/common/contextkey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@

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,
Glob = 6
Regex = 6
}

export abstract class ContextKeyExpr {
Expand All @@ -31,8 +30,8 @@ export abstract class ContextKeyExpr {
return new ContextKeyNotEqualsExpr(key, value);
}

public static glob(key: string, value: string): ContextKeyExpr {
return new ContextKeyGlobExpr(key, value);
public static regex(key: string, value: string): ContextKeyExpr {
return new ContextKeyRegexExpr(key, value);
}

public static not(key: string): ContextKeyExpr {
Expand Down Expand Up @@ -68,7 +67,7 @@ export abstract class ContextKeyExpr {

if (serializedOne.indexOf('=~') >= 0) {
let pieces = serializedOne.split('=~');
return new ContextKeyGlobExpr(pieces[0].trim(), this._deserializeValue(pieces[1]));
return new ContextKeyRegexExpr(pieces[0].trim(), this._deserializeValue(pieces[1]));
}

if (/^\!\s*/.test(serializedOne)) {
Expand Down Expand Up @@ -120,8 +119,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);
case ContextKeyExprType.Regex:
return (<ContextKeyRegexExpr>a).cmp(<ContextKeyRegexExpr>b);
default:
throw new Error('Unknown ContextKeyExpr!');
}
Expand Down Expand Up @@ -333,48 +332,56 @@ export class ContextKeyNotExpr implements ContextKeyExpr {
}
}

export class ContextKeyGlobExpr implements ContextKeyExpr {
export class ContextKeyRegexExpr implements ContextKeyExpr {

constructor(private key: string, private value: any) {
private regexp: { source: string, test(s: string): boolean };

constructor(private key: string, value: any) {
try {
this.regexp = new RegExp(value);
} catch (e) {
this.regexp = { source: '', test() { return false; } };
console.warn(`Bad value for glob-context key expression: ${value}`);
}
}

public getType(): ContextKeyExprType {
return ContextKeyExprType.Glob;
return ContextKeyExprType.Regex;
}

public cmp(other: ContextKeyGlobExpr): number {
public cmp(other: ContextKeyRegexExpr): number {
if (this.key < other.key) {
return -1;
}
if (this.key > other.key) {
return 1;
}
if (this.value < other.value) {
if (this.regexp.source < other.regexp.source) {
return -1;
}
if (this.value > other.value) {
if (this.regexp.source > other.regexp.source) {
return 1;
}
return 0;
}

public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyGlobExpr) {
return (this.key === other.key && this.value === other.value);
if (other instanceof ContextKeyRegexExpr) {
return (this.key === other.key && this.regexp.source === other.regexp.source);
}
return false;
}

public evaluate(context: IContext): boolean {
return match(this.value, context.getValue(this.key));
return this.regexp.test(context.getValue(this.key));
}

public normalize(): ContextKeyExpr {
return this;
}

public serialize(): string {
return this.key + ' =~ \'' + this.value + '\'';
return this.key + ' =~ \'' + this.regexp.source + '\'';
}

public keys(): string[] {
Expand Down
13 changes: 6 additions & 7 deletions src/vs/platform/contextkey/test/common/contextkey.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

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 {
Expand All @@ -22,8 +21,8 @@ suite('ContextKeyExpr', () => {
ContextKeyExpr.has('a1'),
ContextKeyExpr.and(ContextKeyExpr.has('and.a')),
ContextKeyExpr.has('a2'),
ContextKeyExpr.glob('d3', '**/d*'),
ContextKeyExpr.glob('d4', '**/3*'),
ContextKeyExpr.regex('d3', 'd.*'),
ContextKeyExpr.regex('d4', '\\*\\*/3*'),
ContextKeyExpr.equals('b1', 'bb1'),
ContextKeyExpr.equals('b2', 'bb2'),
ContextKeyExpr.notEquals('c1', 'cc1'),
Expand All @@ -35,11 +34,11 @@ suite('ContextKeyExpr', () => {
ContextKeyExpr.equals('b2', 'bb2'),
ContextKeyExpr.notEquals('c1', 'cc1'),
ContextKeyExpr.not('d1'),
ContextKeyExpr.glob('d4', '**/3*'),
ContextKeyExpr.regex('d4', '\\*\\*/3*'),
ContextKeyExpr.notEquals('c2', 'cc2'),
ContextKeyExpr.has('a2'),
ContextKeyExpr.equals('b1', 'bb1'),
ContextKeyExpr.glob('d3', '**/d*'),
ContextKeyExpr.regex('d3', 'd.*'),
ContextKeyExpr.has('a1'),
ContextKeyExpr.and(ContextKeyExpr.equals('and.a', true)),
ContextKeyExpr.not('d2')
Expand Down Expand Up @@ -68,7 +67,7 @@ suite('ContextKeyExpr', () => {
'd': 'd'
});
function testExpression(expr: string, expected: boolean): void {
console.log(expr + ' ' + expected);
// console.log(expr + ' ' + expected);
let rules = ContextKeyExpr.deserialize(expr);
assert.equal(rules.evaluate(context), expected, expr);
}
Expand All @@ -81,7 +80,7 @@ suite('ContextKeyExpr', () => {
testExpression(expr + ' == 5', value == <any>'5');
testExpression(expr + ' != 5', value != <any>'5');
testExpression('!' + expr, !value);
testExpression(expr + ' =~ **/d*', match('**/d*', value));
testExpression(expr + ' =~ d.*', /d.*/.test(value));
}

testBatch('a', true);
Expand Down

0 comments on commit 24ecf49

Please sign in to comment.