From 8ca857a92eab6ea49210d032c510edbe3fabe4e1 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Fri, 14 Aug 2020 02:18:04 -0400 Subject: [PATCH] Closes #97544 - adds in operator to when clauses --- .../platform/contextkey/common/contextkey.ts | 132 +++++++++++++++++- 1 file changed, 130 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/contextkey/common/contextkey.ts b/src/vs/platform/contextkey/common/contextkey.ts index 55e154645ec..9f1fbde97a2 100644 --- a/src/vs/platform/contextkey/common/contextkey.ts +++ b/src/vs/platform/contextkey/common/contextkey.ts @@ -27,7 +27,9 @@ export const enum ContextKeyExprType { And = 6, Regex = 7, NotRegex = 8, - Or = 9 + Or = 9, + In = 10, + NotIn = 11, } export interface IContextKeyExprMapper { @@ -36,6 +38,7 @@ export interface IContextKeyExprMapper { mapEquals(key: string, value: any): ContextKeyExpression; mapNotEquals(key: string, value: any): ContextKeyExpression; mapRegex(key: string, regexp: RegExp | null): ContextKeyRegexExpr; + mapIn(key: string, valueKey: string): ContextKeyInExpr; } export interface IContextKeyExpression { @@ -52,7 +55,7 @@ export interface IContextKeyExpression { export type ContextKeyExpression = ( ContextKeyFalseExpr | ContextKeyTrueExpr | ContextKeyDefinedExpr | ContextKeyNotExpr | ContextKeyEqualsExpr | ContextKeyNotEqualsExpr | ContextKeyRegexExpr - | ContextKeyNotRegexExpr | ContextKeyAndExpr | ContextKeyOrExpr + | ContextKeyNotRegexExpr | ContextKeyAndExpr | ContextKeyOrExpr | ContextKeyInExpr | ContextKeyNotInExpr ); export abstract class ContextKeyExpr { @@ -81,6 +84,10 @@ export abstract class ContextKeyExpr { return ContextKeyRegexExpr.create(key, value); } + public static in(key: string, value: string): ContextKeyExpression { + return ContextKeyInExpr.create(key, value); + } + public static not(key: string): ContextKeyExpression { return ContextKeyNotExpr.create(key); } @@ -129,6 +136,11 @@ export abstract class ContextKeyExpr { return ContextKeyRegexExpr.create(pieces[0].trim(), this._deserializeRegexValue(pieces[1], strict)); } + if (serializedOne.indexOf(' in ') >= 0) { + let pieces = serializedOne.split(' in '); + return ContextKeyInExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict)); + } + if (/^\!\s*/.test(serializedOne)) { return ContextKeyNotExpr.create(serializedOne.substr(1).trim()); } @@ -393,6 +405,122 @@ export class ContextKeyEqualsExpr implements IContextKeyExpression { } } +export class ContextKeyInExpr implements IContextKeyExpression { + + public static create(key: string, valueKey: string): ContextKeyExpression { + return new ContextKeyInExpr(key, valueKey); + } + + public readonly type = ContextKeyExprType.In; + + private constructor(private readonly key: string, private readonly valueKey: string) { + } + + public cmp(other: ContextKeyExpression): number { + if (other.type !== this.type) { + return this.type - other.type; + } + if (this.key < other.key) { + return -1; + } + if (this.key > other.key) { + return 1; + } + if (this.valueKey < other.valueKey) { + return -1; + } + if (this.valueKey > other.valueKey) { + return 1; + } + return 0; + } + + public equals(other: ContextKeyExpression): boolean { + if (other.type === this.type) { + return (this.key === other.key && this.valueKey === other.valueKey); + } + return false; + } + + public evaluate(context: IContext): boolean { + const source = context.getValue(this.valueKey); + + const item = context.getValue(this.key); + + if (Array.isArray(source)) { + return source.includes(item); + } + + if (typeof item === 'string' && typeof source === 'object' && source !== undefined && source !== null) { + return item in source; + } + return false; + } + + public serialize(): string { + return this.key + ' in \'' + this.valueKey + '\''; + } + + public keys(): string[] { + return [this.key]; + } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyInExpr { + return mapFnc.mapIn(this.key, this.valueKey); + } + + public negate(): ContextKeyExpression { + return ContextKeyNotInExpr.create(this); + } +} + +export class ContextKeyNotInExpr implements IContextKeyExpression { + + public static create(actual: ContextKeyInExpr): ContextKeyExpression { + return new ContextKeyNotInExpr(actual); + } + + public readonly type = ContextKeyExprType.NotIn; + + private constructor(private readonly _actual: ContextKeyInExpr) { + // + } + + public cmp(other: ContextKeyExpression): number { + if (other.type !== this.type) { + return this.type - other.type; + } + return this._actual.cmp(other._actual); + } + + public equals(other: ContextKeyExpression): boolean { + if (other.type === this.type) { + return this._actual.equals(other._actual); + } + return false; + } + + public evaluate(context: IContext): boolean { + return !this._actual.evaluate(context); + } + + public serialize(): string { + throw new Error('Method not implemented.'); + } + + public keys(): string[] { + return this._actual.keys(); + } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression { + return new ContextKeyNotInExpr(this._actual.map(mapFnc)); + } + + public negate(): ContextKeyExpression { + return this._actual; + } +} + export class ContextKeyNotEqualsExpr implements IContextKeyExpression { public static create(key: string, value: any): ContextKeyExpression {