@@ -27,7 +27,9 @@ export const enum ContextKeyExprType {
2727 And = 6 ,
2828 Regex = 7 ,
2929 NotRegex = 8 ,
30- Or = 9
30+ Or = 9 ,
31+ In = 10 ,
32+ NotIn = 11 ,
3133}
3234
3335export interface IContextKeyExprMapper {
@@ -36,6 +38,7 @@ export interface IContextKeyExprMapper {
3638 mapEquals ( key : string , value : any ) : ContextKeyExpression ;
3739 mapNotEquals ( key : string , value : any ) : ContextKeyExpression ;
3840 mapRegex ( key : string , regexp : RegExp | null ) : ContextKeyRegexExpr ;
41+ mapIn ( key : string , valueKey : string ) : ContextKeyInExpr ;
3942}
4043
4144export interface IContextKeyExpression {
@@ -52,7 +55,7 @@ export interface IContextKeyExpression {
5255export type ContextKeyExpression = (
5356 ContextKeyFalseExpr | ContextKeyTrueExpr | ContextKeyDefinedExpr | ContextKeyNotExpr
5457 | ContextKeyEqualsExpr | ContextKeyNotEqualsExpr | ContextKeyRegexExpr
55- | ContextKeyNotRegexExpr | ContextKeyAndExpr | ContextKeyOrExpr
58+ | ContextKeyNotRegexExpr | ContextKeyAndExpr | ContextKeyOrExpr | ContextKeyInExpr | ContextKeyNotInExpr
5659) ;
5760
5861export abstract class ContextKeyExpr {
@@ -81,6 +84,10 @@ export abstract class ContextKeyExpr {
8184 return ContextKeyRegexExpr . create ( key , value ) ;
8285 }
8386
87+ public static in ( key : string , value : string ) : ContextKeyExpression {
88+ return ContextKeyInExpr . create ( key , value ) ;
89+ }
90+
8491 public static not ( key : string ) : ContextKeyExpression {
8592 return ContextKeyNotExpr . create ( key ) ;
8693 }
@@ -129,6 +136,11 @@ export abstract class ContextKeyExpr {
129136 return ContextKeyRegexExpr . create ( pieces [ 0 ] . trim ( ) , this . _deserializeRegexValue ( pieces [ 1 ] , strict ) ) ;
130137 }
131138
139+ if ( serializedOne . indexOf ( ' in ' ) >= 0 ) {
140+ let pieces = serializedOne . split ( ' in ' ) ;
141+ return ContextKeyInExpr . create ( pieces [ 0 ] . trim ( ) , this . _deserializeValue ( pieces [ 1 ] , strict ) ) ;
142+ }
143+
132144 if ( / ^ \! \s * / . test ( serializedOne ) ) {
133145 return ContextKeyNotExpr . create ( serializedOne . substr ( 1 ) . trim ( ) ) ;
134146 }
@@ -393,6 +405,122 @@ export class ContextKeyEqualsExpr implements IContextKeyExpression {
393405 }
394406}
395407
408+ export class ContextKeyInExpr implements IContextKeyExpression {
409+
410+ public static create ( key : string , valueKey : string ) : ContextKeyExpression {
411+ return new ContextKeyInExpr ( key , valueKey ) ;
412+ }
413+
414+ public readonly type = ContextKeyExprType . In ;
415+
416+ private constructor ( private readonly key : string , private readonly valueKey : string ) {
417+ }
418+
419+ public cmp ( other : ContextKeyExpression ) : number {
420+ if ( other . type !== this . type ) {
421+ return this . type - other . type ;
422+ }
423+ if ( this . key < other . key ) {
424+ return - 1 ;
425+ }
426+ if ( this . key > other . key ) {
427+ return 1 ;
428+ }
429+ if ( this . valueKey < other . valueKey ) {
430+ return - 1 ;
431+ }
432+ if ( this . valueKey > other . valueKey ) {
433+ return 1 ;
434+ }
435+ return 0 ;
436+ }
437+
438+ public equals ( other : ContextKeyExpression ) : boolean {
439+ if ( other . type === this . type ) {
440+ return ( this . key === other . key && this . valueKey === other . valueKey ) ;
441+ }
442+ return false ;
443+ }
444+
445+ public evaluate ( context : IContext ) : boolean {
446+ const source = context . getValue ( this . valueKey ) ;
447+
448+ const item = context . getValue ( this . key ) ;
449+
450+ if ( Array . isArray ( source ) ) {
451+ return source . includes ( item ) ;
452+ }
453+
454+ if ( typeof item === 'string' && typeof source === 'object' && source !== undefined && source !== null ) {
455+ return item in source ;
456+ }
457+ return false ;
458+ }
459+
460+ public serialize ( ) : string {
461+ return this . key + ' in \'' + this . valueKey + '\'' ;
462+ }
463+
464+ public keys ( ) : string [ ] {
465+ return [ this . key ] ;
466+ }
467+
468+ public map ( mapFnc : IContextKeyExprMapper ) : ContextKeyInExpr {
469+ return mapFnc . mapIn ( this . key , this . valueKey ) ;
470+ }
471+
472+ public negate ( ) : ContextKeyExpression {
473+ return ContextKeyNotInExpr . create ( this ) ;
474+ }
475+ }
476+
477+ export class ContextKeyNotInExpr implements IContextKeyExpression {
478+
479+ public static create ( actual : ContextKeyInExpr ) : ContextKeyExpression {
480+ return new ContextKeyNotInExpr ( actual ) ;
481+ }
482+
483+ public readonly type = ContextKeyExprType . NotIn ;
484+
485+ private constructor ( private readonly _actual : ContextKeyInExpr ) {
486+ //
487+ }
488+
489+ public cmp ( other : ContextKeyExpression ) : number {
490+ if ( other . type !== this . type ) {
491+ return this . type - other . type ;
492+ }
493+ return this . _actual . cmp ( other . _actual ) ;
494+ }
495+
496+ public equals ( other : ContextKeyExpression ) : boolean {
497+ if ( other . type === this . type ) {
498+ return this . _actual . equals ( other . _actual ) ;
499+ }
500+ return false ;
501+ }
502+
503+ public evaluate ( context : IContext ) : boolean {
504+ return ! this . _actual . evaluate ( context ) ;
505+ }
506+
507+ public serialize ( ) : string {
508+ throw new Error ( 'Method not implemented.' ) ;
509+ }
510+
511+ public keys ( ) : string [ ] {
512+ return this . _actual . keys ( ) ;
513+ }
514+
515+ public map ( mapFnc : IContextKeyExprMapper ) : ContextKeyExpression {
516+ return new ContextKeyNotInExpr ( this . _actual . map ( mapFnc ) ) ;
517+ }
518+
519+ public negate ( ) : ContextKeyExpression {
520+ return this . _actual ;
521+ }
522+ }
523+
396524export class ContextKeyNotEqualsExpr implements IContextKeyExpression {
397525
398526 public static create ( key : string , value : any ) : ContextKeyExpression {
0 commit comments