Merge from vscode cfc1ab4c5f816765b91fb7ead3c3427a7c8581a3

This commit is contained in:
ADS Merger
2020-03-11 04:19:23 +00:00
parent 16fab722d5
commit 4c3e48773d
880 changed files with 20441 additions and 11232 deletions

View File

@@ -8,7 +8,7 @@ import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { keys } from 'vs/base/common/map';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ContextKeyExpr, IContext, IContextKey, IContextKeyChangeEvent, IContextKeyService, IContextKeyServiceTarget, IReadableSet, SET_CONTEXT_COMMAND_ID } from 'vs/platform/contextkey/common/contextkey';
import { IContext, IContextKey, IContextKeyChangeEvent, IContextKeyService, IContextKeyServiceTarget, IReadableSet, SET_CONTEXT_COMMAND_ID, ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
const KEYBINDING_CONTEXT_ATTR = 'data-keybinding-context';
@@ -142,6 +142,10 @@ class ConfigAwareContextValuesContainer extends Context {
case 'string':
value = configValue;
break;
default:
if (Array.isArray(configValue)) {
value = JSON.stringify(configValue);
}
}
this._values.set(key, value);
@@ -265,7 +269,7 @@ export abstract class AbstractContextKeyService implements IContextKeyService {
return new ScopedContextKeyService(this, domNode);
}
public contextMatchesRules(rules: ContextKeyExpr | undefined): boolean {
public contextMatchesRules(rules: ContextKeyExpression | undefined): boolean {
if (this._isDisposed) {
throw new Error(`AbstractContextKeyService has been disposed`);
}

View File

@@ -6,69 +6,106 @@
import { Event } from 'vs/base/common/event';
import { isFalsyOrWhitespace } from 'vs/base/common/strings';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { isMacintosh, isLinux, isWindows, isWeb } from 'vs/base/common/platform';
const STATIC_VALUES = new Map<string, boolean>();
STATIC_VALUES.set('false', false);
STATIC_VALUES.set('true', true);
STATIC_VALUES.set('isMac', isMacintosh);
STATIC_VALUES.set('isLinux', isLinux);
STATIC_VALUES.set('isWindows', isWindows);
STATIC_VALUES.set('isWeb', isWeb);
STATIC_VALUES.set('isMacNative', isMacintosh && !isWeb);
export const enum ContextKeyExprType {
Defined = 1,
Not = 2,
Equals = 3,
NotEquals = 4,
And = 5,
Regex = 6,
NotRegex = 7,
Or = 8,
GreaterThanEquals = 9, // {{SQL CARBON EDIT}} add value
LessThanEquals = 10 // {{SQL CARBON EDIT}} add value
False = 0,
True = 1,
Defined = 2,
Not = 3,
Equals = 4,
NotEquals = 5,
And = 6,
Regex = 7,
NotRegex = 8,
Or = 9,
GreaterThanEquals = 10, // {{SQL CARBON EDIT}} add value
LessThanEquals = 11 // {{SQL CARBON EDIT}} add value
}
export interface IContextKeyExprMapper {
mapDefined(key: string): ContextKeyExpr;
mapNot(key: string): ContextKeyExpr;
mapEquals(key: string, value: any): ContextKeyExpr;
mapNotEquals(key: string, value: any): ContextKeyExpr;
mapDefined(key: string): ContextKeyExpression;
mapNot(key: string): ContextKeyExpression;
mapEquals(key: string, value: any): ContextKeyExpression;
mapNotEquals(key: string, value: any): ContextKeyExpression;
mapRegex(key: string, regexp: RegExp | null): ContextKeyRegexExpr;
}
export interface IContextKeyExpression {
cmp(other: ContextKeyExpression): number;
equals(other: ContextKeyExpression): boolean;
evaluate(context: IContext): boolean;
serialize(): string;
keys(): string[];
map(mapFnc: IContextKeyExprMapper): ContextKeyExpression;
negate(): ContextKeyExpression;
}
export type ContextKeyExpression = (
ContextKeyFalseExpr | ContextKeyTrueExpr | ContextKeyDefinedExpr | ContextKeyNotExpr
| ContextKeyEqualsExpr | ContextKeyNotEqualsExpr | ContextKeyRegexExpr
| ContextKeyNotRegexExpr | ContextKeyAndExpr | ContextKeyOrExpr | ContextKeyGreaterThanEqualsExpr | ContextKeyLessThanEqualsExpr
);
export abstract class ContextKeyExpr {
public static has(key: string): ContextKeyExpr {
public static false(): ContextKeyExpression {
return ContextKeyFalseExpr.INSTANCE;
}
public static true(): ContextKeyExpression {
return ContextKeyTrueExpr.INSTANCE;
}
public static has(key: string): ContextKeyExpression {
return ContextKeyDefinedExpr.create(key);
}
public static equals(key: string, value: any): ContextKeyExpr {
public static equals(key: string, value: any): ContextKeyExpression {
return ContextKeyEqualsExpr.create(key, value);
}
public static notEquals(key: string, value: any): ContextKeyExpr {
public static notEquals(key: string, value: any): ContextKeyExpression {
return ContextKeyNotEqualsExpr.create(key, value);
}
public static regex(key: string, value: RegExp): ContextKeyExpr {
public static regex(key: string, value: RegExp): ContextKeyExpression {
return ContextKeyRegexExpr.create(key, value);
}
public static not(key: string): ContextKeyExpr {
public static not(key: string): ContextKeyExpression {
return ContextKeyNotExpr.create(key);
}
public static and(...expr: Array<ContextKeyExpr | undefined | null>): ContextKeyExpr | undefined {
public static and(...expr: Array<ContextKeyExpression | undefined | null>): ContextKeyExpression | undefined {
return ContextKeyAndExpr.create(expr);
}
public static or(...expr: Array<ContextKeyExpr | undefined | null>): ContextKeyExpr | undefined {
public static or(...expr: Array<ContextKeyExpression | undefined | null>): ContextKeyExpression | undefined {
return ContextKeyOrExpr.create(expr);
}
// {{SQL CARBON EDIT}}
public static greaterThanEquals(key: string, value: any): ContextKeyExpr {
return new ContextKeyGreaterThanEqualsExpr(key, value);
public static greaterThanEquals(key: string, value: any): ContextKeyExpression {
return ContextKeyGreaterThanEqualsExpr.create(key, value);
}
public static lessThanEquals(key: string, value: any): ContextKeyExpr {
return new ContextKeyLessThanEqualsExpr(key, value);
public static lessThanEquals(key: string, value: any): ContextKeyExpression {
return ContextKeyLessThanEqualsExpr.create(key, value);
}
//
public static deserialize(serialized: string | null | undefined, strict: boolean = false): ContextKeyExpr | undefined {
public static deserialize(serialized: string | null | undefined, strict: boolean = false): ContextKeyExpression | undefined {
if (!serialized) {
return undefined;
}
@@ -76,17 +113,17 @@ export abstract class ContextKeyExpr {
return this._deserializeOrExpression(serialized, strict);
}
private static _deserializeOrExpression(serialized: string, strict: boolean): ContextKeyExpr | undefined {
private static _deserializeOrExpression(serialized: string, strict: boolean): ContextKeyExpression | undefined {
let pieces = serialized.split('||');
return ContextKeyOrExpr.create(pieces.map(p => this._deserializeAndExpression(p, strict)));
}
private static _deserializeAndExpression(serialized: string, strict: boolean): ContextKeyExpr | undefined {
private static _deserializeAndExpression(serialized: string, strict: boolean): ContextKeyExpression | undefined {
let pieces = serialized.split('&&');
return ContextKeyAndExpr.create(pieces.map(p => this._deserializeOne(p, strict)));
}
private static _deserializeOne(serializedOne: string, strict: boolean): ContextKeyExpr {
private static _deserializeOne(serializedOne: string, strict: boolean): ContextKeyExpression {
serializedOne = serializedOne.trim();
if (serializedOne.indexOf('!=') >= 0) {
@@ -107,11 +144,11 @@ export abstract class ContextKeyExpr {
// {{SQL CARBON EDIT}}
if (serializedOne.indexOf('>=') >= 0) {
let pieces = serializedOne.split('>=');
return new ContextKeyGreaterThanEqualsExpr(pieces[0].trim(), this._deserializeValue(pieces[1], strict));
return ContextKeyGreaterThanEqualsExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict));
}
if (serializedOne.indexOf('<=') >= 0) {
let pieces = serializedOne.split('<=');
return new ContextKeyLessThanEqualsExpr(pieces[0].trim(), this._deserializeValue(pieces[1], strict));
return ContextKeyLessThanEqualsExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict));
}
//
@@ -176,59 +213,104 @@ export abstract class ContextKeyExpr {
return null;
}
}
public abstract getType(): ContextKeyExprType;
public abstract equals(other: ContextKeyExpr): boolean;
public abstract evaluate(context: IContext): boolean;
public abstract serialize(): string;
public abstract keys(): string[];
public abstract map(mapFnc: IContextKeyExprMapper): ContextKeyExpr;
public abstract negate(): ContextKeyExpr;
}
function cmp(a: ContextKeyExpr, b: ContextKeyExpr): number {
let aType = a.getType();
let bType = b.getType();
if (aType !== bType) {
return aType - bType;
function cmp(a: ContextKeyExpression, b: ContextKeyExpression): number {
return a.cmp(b);
}
export class ContextKeyFalseExpr implements IContextKeyExpression {
public static INSTANCE = new ContextKeyFalseExpr();
public readonly type = ContextKeyExprType.False;
protected constructor() {
}
switch (aType) {
case ContextKeyExprType.Defined:
return (<ContextKeyDefinedExpr>a).cmp(<ContextKeyDefinedExpr>b);
case ContextKeyExprType.Not:
return (<ContextKeyNotExpr>a).cmp(<ContextKeyNotExpr>b);
case ContextKeyExprType.Equals:
return (<ContextKeyEqualsExpr>a).cmp(<ContextKeyEqualsExpr>b);
case ContextKeyExprType.NotEquals:
return (<ContextKeyNotEqualsExpr>a).cmp(<ContextKeyNotEqualsExpr>b);
case ContextKeyExprType.Regex:
return (<ContextKeyRegexExpr>a).cmp(<ContextKeyRegexExpr>b);
case ContextKeyExprType.GreaterThanEquals: // {{SQL CARBON EDIT}} add case
return (<ContextKeyGreaterThanEqualsExpr>a).cmp(<ContextKeyGreaterThanEqualsExpr>b);
case ContextKeyExprType.LessThanEquals: // {{SQL CARBON EDIT}} add case
return (<ContextKeyLessThanEqualsExpr>a).cmp(<ContextKeyLessThanEqualsExpr>b);
case ContextKeyExprType.NotRegex:
return (<ContextKeyNotRegexExpr>a).cmp(<ContextKeyNotRegexExpr>b);
case ContextKeyExprType.And:
return (<ContextKeyAndExpr>a).cmp(<ContextKeyAndExpr>b);
default:
throw new Error('Unknown ContextKeyExpr!');
public cmp(other: ContextKeyExpression): number {
return this.type - other.type;
}
public equals(other: ContextKeyExpression): boolean {
return (other.type === this.type);
}
public evaluate(context: IContext): boolean {
return false;
}
public serialize(): string {
return 'false';
}
public keys(): string[] {
return [];
}
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
return this;
}
public negate(): ContextKeyExpression {
return ContextKeyTrueExpr.INSTANCE;
}
}
export class ContextKeyDefinedExpr implements ContextKeyExpr {
public static create(key: string): ContextKeyDefinedExpr {
export class ContextKeyTrueExpr implements IContextKeyExpression {
public static INSTANCE = new ContextKeyTrueExpr();
public readonly type = ContextKeyExprType.True;
protected constructor() {
}
public cmp(other: ContextKeyExpression): number {
return this.type - other.type;
}
public equals(other: ContextKeyExpression): boolean {
return (other.type === this.type);
}
public evaluate(context: IContext): boolean {
return true;
}
public serialize(): string {
return 'true';
}
public keys(): string[] {
return [];
}
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
return this;
}
public negate(): ContextKeyExpression {
return ContextKeyFalseExpr.INSTANCE;
}
}
export class ContextKeyDefinedExpr implements IContextKeyExpression {
public static create(key: string): ContextKeyExpression {
const staticValue = STATIC_VALUES.get(key);
if (typeof staticValue === 'boolean') {
return staticValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE;
}
return new ContextKeyDefinedExpr(key);
}
protected constructor(protected key: string) {
public readonly type = ContextKeyExprType.Defined;
protected constructor(protected readonly key: string) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.Defined;
}
public cmp(other: ContextKeyDefinedExpr): number {
public cmp(other: ContextKeyExpression): number {
if (other.type !== this.type) {
return this.type - other.type;
}
if (this.key < other.key) {
return -1;
}
@@ -238,8 +320,8 @@ export class ContextKeyDefinedExpr implements ContextKeyExpr {
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyDefinedExpr) {
public equals(other: ContextKeyExpression): boolean {
if (other.type === this.type) {
return (this.key === other.key);
}
return false;
@@ -257,35 +339,38 @@ export class ContextKeyDefinedExpr implements ContextKeyExpr {
return [this.key];
}
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr {
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
return mapFnc.mapDefined(this.key);
}
public negate(): ContextKeyExpr {
public negate(): ContextKeyExpression {
return ContextKeyNotExpr.create(this.key);
}
}
export class ContextKeyEqualsExpr implements ContextKeyExpr {
export class ContextKeyEqualsExpr implements IContextKeyExpression {
public static create(key: string, value: any): ContextKeyExpr {
public static create(key: string, value: any): ContextKeyExpression {
if (typeof value === 'boolean') {
if (value) {
return ContextKeyDefinedExpr.create(key);
}
return ContextKeyNotExpr.create(key);
return (value ? ContextKeyDefinedExpr.create(key) : ContextKeyNotExpr.create(key));
}
const staticValue = STATIC_VALUES.get(key);
if (typeof staticValue === 'boolean') {
const trueValue = staticValue ? 'true' : 'false';
return (value === trueValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE);
}
return new ContextKeyEqualsExpr(key, value);
}
public readonly type = ContextKeyExprType.Equals;
private constructor(private readonly key: string, private readonly value: any) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.Equals;
}
public cmp(other: ContextKeyEqualsExpr): number {
public cmp(other: ContextKeyExpression): number {
if (other.type !== this.type) {
return this.type - other.type;
}
if (this.key < other.key) {
return -1;
}
@@ -301,8 +386,8 @@ export class ContextKeyEqualsExpr implements ContextKeyExpr {
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyEqualsExpr) {
public equals(other: ContextKeyExpression): boolean {
if (other.type === this.type) {
return (this.key === other.key && this.value === other.value);
}
return false;
@@ -322,35 +407,41 @@ export class ContextKeyEqualsExpr implements ContextKeyExpr {
return [this.key];
}
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr {
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
return mapFnc.mapEquals(this.key, this.value);
}
public negate(): ContextKeyExpr {
public negate(): ContextKeyExpression {
return ContextKeyNotEqualsExpr.create(this.key, this.value);
}
}
export class ContextKeyNotEqualsExpr implements ContextKeyExpr {
export class ContextKeyNotEqualsExpr implements IContextKeyExpression {
public static create(key: string, value: any): ContextKeyExpr {
public static create(key: string, value: any): ContextKeyExpression {
if (typeof value === 'boolean') {
if (value) {
return ContextKeyNotExpr.create(key);
}
return ContextKeyDefinedExpr.create(key);
}
const staticValue = STATIC_VALUES.get(key);
if (typeof staticValue === 'boolean') {
const falseValue = staticValue ? 'true' : 'false';
return (value === falseValue ? ContextKeyFalseExpr.INSTANCE : ContextKeyTrueExpr.INSTANCE);
}
return new ContextKeyNotEqualsExpr(key, value);
}
private constructor(private key: string, private value: any) {
public readonly type = ContextKeyExprType.NotEquals;
private constructor(private readonly key: string, private readonly value: any) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.NotEquals;
}
public cmp(other: ContextKeyNotEqualsExpr): number {
public cmp(other: ContextKeyExpression): number {
if (other.type !== this.type) {
return this.type - other.type;
}
if (this.key < other.key) {
return -1;
}
@@ -366,8 +457,8 @@ export class ContextKeyNotEqualsExpr implements ContextKeyExpr {
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyNotEqualsExpr) {
public equals(other: ContextKeyExpression): boolean {
if (other.type === this.type) {
return (this.key === other.key && this.value === other.value);
}
return false;
@@ -387,29 +478,34 @@ export class ContextKeyNotEqualsExpr implements ContextKeyExpr {
return [this.key];
}
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr {
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
return mapFnc.mapNotEquals(this.key, this.value);
}
public negate(): ContextKeyExpr {
public negate(): ContextKeyExpression {
return ContextKeyEqualsExpr.create(this.key, this.value);
}
}
export class ContextKeyNotExpr implements ContextKeyExpr {
export class ContextKeyNotExpr implements IContextKeyExpression {
public static create(key: string): ContextKeyExpr {
public static create(key: string): ContextKeyExpression {
const staticValue = STATIC_VALUES.get(key);
if (typeof staticValue === 'boolean') {
return (staticValue ? ContextKeyFalseExpr.INSTANCE : ContextKeyTrueExpr.INSTANCE);
}
return new ContextKeyNotExpr(key);
}
private constructor(private key: string) {
public readonly type = ContextKeyExprType.Not;
private constructor(private readonly key: string) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.Not;
}
public cmp(other: ContextKeyNotExpr): number {
public cmp(other: ContextKeyExpression): number {
if (other.type !== this.type) {
return this.type - other.type;
}
if (this.key < other.key) {
return -1;
}
@@ -419,8 +515,8 @@ export class ContextKeyNotExpr implements ContextKeyExpr {
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyNotExpr) {
public equals(other: ContextKeyExpression): boolean {
if (other.type === this.type) {
return (this.key === other.key);
}
return false;
@@ -438,30 +534,31 @@ export class ContextKeyNotExpr implements ContextKeyExpr {
return [this.key];
}
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr {
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
return mapFnc.mapNot(this.key);
}
public negate(): ContextKeyExpr {
public negate(): ContextKeyExpression {
return ContextKeyDefinedExpr.create(this.key);
}
}
export class ContextKeyRegexExpr implements ContextKeyExpr {
export class ContextKeyRegexExpr implements IContextKeyExpression {
public static create(key: string, regexp: RegExp | null): ContextKeyRegexExpr {
return new ContextKeyRegexExpr(key, regexp);
}
private constructor(private key: string, private regexp: RegExp | null) {
public readonly type = ContextKeyExprType.Regex;
private constructor(private readonly key: string, private readonly regexp: RegExp | null) {
//
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.Regex;
}
public cmp(other: ContextKeyRegexExpr): number {
public cmp(other: ContextKeyExpression): number {
if (other.type !== this.type) {
return this.type - other.type;
}
if (this.key < other.key) {
return -1;
}
@@ -479,8 +576,8 @@ export class ContextKeyRegexExpr implements ContextKeyExpr {
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyRegexExpr) {
public equals(other: ContextKeyExpression): boolean {
if (other.type === this.type) {
const thisSource = this.regexp ? this.regexp.source : '';
const otherSource = other.regexp ? other.regexp.source : '';
return (this.key === other.key && thisSource === otherSource);
@@ -508,31 +605,32 @@ export class ContextKeyRegexExpr implements ContextKeyExpr {
return mapFnc.mapRegex(this.key, this.regexp);
}
public negate(): ContextKeyExpr {
public negate(): ContextKeyExpression {
return ContextKeyNotRegexExpr.create(this);
}
}
export class ContextKeyNotRegexExpr implements ContextKeyExpr {
export class ContextKeyNotRegexExpr implements IContextKeyExpression {
public static create(actual: ContextKeyRegexExpr): ContextKeyExpr {
public static create(actual: ContextKeyRegexExpr): ContextKeyExpression {
return new ContextKeyNotRegexExpr(actual);
}
public readonly type = ContextKeyExprType.NotRegex;
private constructor(private readonly _actual: ContextKeyRegexExpr) {
//
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.NotRegex;
}
public cmp(other: ContextKeyNotRegexExpr): number {
public cmp(other: ContextKeyExpression): number {
if (other.type !== this.type) {
return this.type - other.type;
}
return this._actual.cmp(other._actual);
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyNotRegexExpr) {
public equals(other: ContextKeyExpression): boolean {
if (other.type === this.type) {
return this._actual.equals(other._actual);
}
return false;
@@ -550,18 +648,18 @@ export class ContextKeyNotRegexExpr implements ContextKeyExpr {
return this._actual.keys();
}
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr {
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
return new ContextKeyNotRegexExpr(this._actual.map(mapFnc));
}
public negate(): ContextKeyExpr {
public negate(): ContextKeyExpression {
return this._actual;
}
}
export class ContextKeyAndExpr implements ContextKeyExpr {
export class ContextKeyAndExpr implements IContextKeyExpression {
public static create(_expr: ReadonlyArray<ContextKeyExpr | null | undefined>): ContextKeyExpr | undefined {
public static create(_expr: ReadonlyArray<ContextKeyExpression | null | undefined>): ContextKeyExpression | undefined {
const expr = ContextKeyAndExpr._normalizeArr(_expr);
if (expr.length === 0) {
return undefined;
@@ -574,14 +672,15 @@ export class ContextKeyAndExpr implements ContextKeyExpr {
return new ContextKeyAndExpr(expr);
}
private constructor(public readonly expr: ContextKeyExpr[]) {
public readonly type = ContextKeyExprType.And;
private constructor(public readonly expr: ContextKeyExpression[]) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.And;
}
public cmp(other: ContextKeyAndExpr): number {
public cmp(other: ContextKeyExpression): number {
if (other.type !== this.type) {
return this.type - other.type;
}
if (this.expr.length < other.expr.length) {
return -1;
}
@@ -597,8 +696,8 @@ export class ContextKeyAndExpr implements ContextKeyExpr {
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyAndExpr) {
public equals(other: ContextKeyExpression): boolean {
if (other.type === this.type) {
if (this.expr.length !== other.expr.length) {
return false;
}
@@ -621,20 +720,32 @@ export class ContextKeyAndExpr implements ContextKeyExpr {
return true;
}
private static _normalizeArr(arr: ReadonlyArray<ContextKeyExpr | null | undefined>): ContextKeyExpr[] {
const expr: ContextKeyExpr[] = [];
private static _normalizeArr(arr: ReadonlyArray<ContextKeyExpression | null | undefined>): ContextKeyExpression[] {
const expr: ContextKeyExpression[] = [];
let hasTrue = false;
for (const e of arr) {
if (!e) {
continue;
}
if (e instanceof ContextKeyAndExpr) {
if (e.type === ContextKeyExprType.True) {
// anything && true ==> anything
hasTrue = true;
continue;
}
if (e.type === ContextKeyExprType.False) {
// anything && false ==> false
return [ContextKeyFalseExpr.INSTANCE];
}
if (e.type === ContextKeyExprType.And) {
expr.push(...e.expr);
continue;
}
if (e instanceof ContextKeyOrExpr) {
if (e.type === ContextKeyExprType.Or) {
// Not allowed, because we don't have parens!
throw new Error(`It is not allowed to have an or expression here due to lack of parens! For example "a && (b||c)" is not supported, use "(a&&b) || (a&&c)" instead.`);
}
@@ -642,6 +753,10 @@ export class ContextKeyAndExpr implements ContextKeyExpr {
expr.push(e);
}
if (expr.length === 0 && hasTrue) {
return [ContextKeyTrueExpr.INSTANCE];
}
expr.sort(cmp);
return expr;
@@ -659,12 +774,12 @@ export class ContextKeyAndExpr implements ContextKeyExpr {
return result;
}
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr {
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
return new ContextKeyAndExpr(this.expr.map(expr => expr.map(mapFnc)));
}
public negate(): ContextKeyExpr {
let result: ContextKeyExpr[] = [];
public negate(): ContextKeyExpression {
let result: ContextKeyExpression[] = [];
for (let expr of this.expr) {
result.push(expr.negate());
}
@@ -672,9 +787,9 @@ export class ContextKeyAndExpr implements ContextKeyExpr {
}
}
export class ContextKeyOrExpr implements ContextKeyExpr {
export class ContextKeyOrExpr implements IContextKeyExpression {
public static create(_expr: ReadonlyArray<ContextKeyExpr | null | undefined>): ContextKeyExpr | undefined {
public static create(_expr: ReadonlyArray<ContextKeyExpression | null | undefined>): ContextKeyExpression | undefined {
const expr = ContextKeyOrExpr._normalizeArr(_expr);
if (expr.length === 0) {
return undefined;
@@ -687,15 +802,32 @@ export class ContextKeyOrExpr implements ContextKeyExpr {
return new ContextKeyOrExpr(expr);
}
private constructor(public readonly expr: ContextKeyExpr[]) {
public readonly type = ContextKeyExprType.Or;
private constructor(public readonly expr: ContextKeyExpression[]) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.Or;
public cmp(other: ContextKeyExpression): number {
if (other.type !== this.type) {
return this.type - other.type;
}
if (this.expr.length < other.expr.length) {
return -1;
}
if (this.expr.length > other.expr.length) {
return 1;
}
for (let i = 0, len = this.expr.length; i < len; i++) {
const r = cmp(this.expr[i], other.expr[i]);
if (r !== 0) {
return r;
}
}
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyOrExpr) {
public equals(other: ContextKeyExpression): boolean {
if (other.type === this.type) {
if (this.expr.length !== other.expr.length) {
return false;
}
@@ -718,17 +850,29 @@ export class ContextKeyOrExpr implements ContextKeyExpr {
return false;
}
private static _normalizeArr(arr: ReadonlyArray<ContextKeyExpr | null | undefined>): ContextKeyExpr[] {
let expr: ContextKeyExpr[] = [];
private static _normalizeArr(arr: ReadonlyArray<ContextKeyExpression | null | undefined>): ContextKeyExpression[] {
let expr: ContextKeyExpression[] = [];
let hasFalse = false;
if (arr) {
for (let i = 0, len = arr.length; i < len; i++) {
let e: ContextKeyExpr | null | undefined = arr[i];
const e = arr[i];
if (!e) {
continue;
}
if (e instanceof ContextKeyOrExpr) {
if (e.type === ContextKeyExprType.False) {
// anything || false ==> anything
hasFalse = true;
continue;
}
if (e.type === ContextKeyExprType.True) {
// anything || true ==> true
return [ContextKeyTrueExpr.INSTANCE];
}
if (e.type === ContextKeyExprType.Or) {
expr = expr.concat(e.expr);
continue;
}
@@ -736,6 +880,10 @@ export class ContextKeyOrExpr implements ContextKeyExpr {
expr.push(e);
}
if (expr.length === 0 && hasFalse) {
return [ContextKeyFalseExpr.INSTANCE];
}
expr.sort(cmp);
}
@@ -754,18 +902,18 @@ export class ContextKeyOrExpr implements ContextKeyExpr {
return result;
}
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr {
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
return new ContextKeyOrExpr(this.expr.map(expr => expr.map(mapFnc)));
}
public negate(): ContextKeyExpr {
let result: ContextKeyExpr[] = [];
public negate(): ContextKeyExpression {
let result: ContextKeyExpression[] = [];
for (let expr of this.expr) {
result.push(expr.negate());
}
const terminals = (node: ContextKeyExpr) => {
if (node instanceof ContextKeyOrExpr) {
const terminals = (node: ContextKeyExpression) => {
if (node.type === ContextKeyExprType.Or) {
return node.expr;
}
return [node];
@@ -777,7 +925,7 @@ export class ContextKeyOrExpr implements ContextKeyExpr {
const LEFT = result.shift()!;
const RIGHT = result.shift()!;
const all: ContextKeyExpr[] = [];
const all: ContextKeyExpression[] = [];
for (const left of terminals(LEFT)) {
for (const right of terminals(RIGHT)) {
all.push(ContextKeyExpr.and(left, right)!);
@@ -791,15 +939,29 @@ export class ContextKeyOrExpr implements ContextKeyExpr {
}
// {{SQL CARBON EDIT}}
export class ContextKeyGreaterThanEqualsExpr implements ContextKeyExpr {
export class ContextKeyGreaterThanEqualsExpr implements IContextKeyExpression {
public static create(key: string, value: any): ContextKeyExpression {
if (typeof value === 'boolean') {
return (value ? ContextKeyDefinedExpr.create(key) : ContextKeyNotExpr.create(key));
}
const staticValue = STATIC_VALUES.get(key);
if (typeof staticValue === 'boolean') {
const trueValue = staticValue ? 'true' : 'false';
return (value === trueValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE);
}
return new ContextKeyGreaterThanEqualsExpr(key, value);
}
public readonly type = ContextKeyExprType.GreaterThanEquals;
constructor(private key: string, private value: any) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.GreaterThanEquals;
}
public cmp(other: ContextKeyGreaterThanEqualsExpr): number {
public cmp(other: ContextKeyExpression): number {
if (other.type !== this.type) {
return this.type - other.type;
}
if (this.key < other.key) {
return -1;
}
@@ -815,14 +977,14 @@ export class ContextKeyGreaterThanEqualsExpr implements ContextKeyExpr {
return 0;
}
public equals(other: ContextKeyExpr): boolean {
if (other instanceof ContextKeyGreaterThanEqualsExpr) {
public equals(other: ContextKeyExpression): boolean {
if (other.type === this.type) {
return (this.key === other.key && this.value === other.value);
}
return false;
}
public negate(): ContextKeyExpr {
public negate(): ContextKeyExpression {
throw new Error('Method not implemented.'); // @TODO anthonydresser need to figure out what to do in this case
}
@@ -836,10 +998,6 @@ export class ContextKeyGreaterThanEqualsExpr implements ContextKeyExpr {
return (keyInt >= valueInt);
}
public normalize(): ContextKeyExpr {
return this;
}
public serialize(): string {
return this.key + ' >= \'' + this.value + '\'';
}
@@ -848,21 +1006,35 @@ export class ContextKeyGreaterThanEqualsExpr implements ContextKeyExpr {
return [this.key];
}
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr {
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
return mapFnc.mapEquals(this.key, this.value);
}
}
// {{SQL CARBON EDIT}}
export class ContextKeyLessThanEqualsExpr implements ContextKeyExpr {
export class ContextKeyLessThanEqualsExpr implements IContextKeyExpression {
public static create(key: string, value: any): ContextKeyExpression {
if (typeof value === 'boolean') {
return (value ? ContextKeyDefinedExpr.create(key) : ContextKeyNotExpr.create(key));
}
const staticValue = STATIC_VALUES.get(key);
if (typeof staticValue === 'boolean') {
const trueValue = staticValue ? 'true' : 'false';
return (value === trueValue ? ContextKeyTrueExpr.INSTANCE : ContextKeyFalseExpr.INSTANCE);
}
return new ContextKeyLessThanEqualsExpr(key, value);
}
constructor(private key: string, private value: any) {
}
public getType(): ContextKeyExprType {
return ContextKeyExprType.LessThanEquals;
}
public readonly type = ContextKeyExprType.LessThanEquals;
public cmp(other: ContextKeyLessThanEqualsExpr): number {
public cmp(other: ContextKeyExpression): number {
if (other.type !== this.type) {
return this.type - other.type;
}
if (this.key < other.key) {
return -1;
}
@@ -878,7 +1050,7 @@ export class ContextKeyLessThanEqualsExpr implements ContextKeyExpr {
return 0;
}
public equals(other: ContextKeyExpr): boolean {
public equals(other: ContextKeyExpression): boolean {
if (other instanceof ContextKeyLessThanEqualsExpr) {
return (this.key === other.key && this.value === other.value);
}
@@ -895,11 +1067,7 @@ export class ContextKeyLessThanEqualsExpr implements ContextKeyExpr {
return (keyInt <= valueInt);
}
public normalize(): ContextKeyExpr {
return this;
}
public negate(): ContextKeyExpr {
public negate(): ContextKeyExpression {
throw new Error('Method not implemented.'); // @TODO anthonydresser need to figure out what to do in this case
}
@@ -911,14 +1079,14 @@ export class ContextKeyLessThanEqualsExpr implements ContextKeyExpr {
return [this.key];
}
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr {
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
return mapFnc.mapEquals(this.key, this.value);
}
}
export class RawContextKey<T> extends ContextKeyDefinedExpr {
private _defaultValue: T | undefined;
private readonly _defaultValue: T | undefined;
constructor(key: string, defaultValue: T | undefined) {
super(key);
@@ -933,15 +1101,15 @@ export class RawContextKey<T> extends ContextKeyDefinedExpr {
return target.getContextKeyValue<T>(this.key);
}
public toNegated(): ContextKeyExpr {
public toNegated(): ContextKeyExpression {
return ContextKeyExpr.not(this.key);
}
public isEqualTo(value: string): ContextKeyExpr {
public isEqualTo(value: string): ContextKeyExpression {
return ContextKeyExpr.equals(this.key, value);
}
public notEqualsTo(value: string): ContextKeyExpr {
public notEqualsTo(value: string): ContextKeyExpression {
return ContextKeyExpr.notEquals(this.key, value);
}
}
@@ -983,7 +1151,7 @@ export interface IContextKeyService {
createKey<T>(key: string, defaultValue: T | undefined): IContextKey<T>;
contextMatchesRules(rules: ContextKeyExpr | undefined): boolean;
contextMatchesRules(rules: ContextKeyExpression | undefined): boolean;
getContextKeyValue<T>(key: string): T | undefined;
createScoped(target?: IContextKeyServiceTarget): IContextKeyService;

View File

@@ -3,9 +3,17 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { isMacintosh, isLinux, isWindows, isWeb } from 'vs/base/common/platform';
export const IsMacContext = new RawContextKey<boolean>('isMac', isMacintosh);
export const IsLinuxContext = new RawContextKey<boolean>('isLinux', isLinux);
export const IsWindowsContext = new RawContextKey<boolean>('isWindows', isWindows);
export const IsWebContext = new RawContextKey<boolean>('isWeb', isWeb);
export const IsMacNativeContext = new RawContextKey<boolean>('isMacNative', isMacintosh && !isWeb);
export const IsDevelopmentContext = new RawContextKey<boolean>('isDevelopment', false);
export const InputFocusedContextKey = 'inputFocus';
export const InputFocusedContext = new RawContextKey<boolean>(InputFocusedContextKey, false);
export const FalseContext: ContextKeyExpr = new RawContextKey<boolean>('__false', false);

View File

@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { isMacintosh, isLinux, isWindows } from 'vs/base/common/platform';
function createContext(ctx: any) {
return {
@@ -101,6 +102,8 @@ suite('ContextKeyExpr', () => {
testBatch('d', 'd');
testBatch('z', undefined);
testExpression('true', true);
testExpression('false', false);
testExpression('a && !b', true && !false);
testExpression('a && b', true && false);
testExpression('a && !b && c == 5', true && !false && '5' === '5');
@@ -119,10 +122,30 @@ suite('ContextKeyExpr', () => {
const actual = ContextKeyExpr.deserialize(expr)!.negate().serialize();
assert.strictEqual(actual, expected);
}
testNegate('true', 'false');
testNegate('false', 'true');
testNegate('a', '!a');
testNegate('a && b || c', '!a && !c || !b && !c');
testNegate('a && b || c || d', '!a && !c && !d || !b && !c && !d');
testNegate('!a && !b || !c && !d', 'a && c || a && d || b && c || b && d');
testNegate('!a && !b || !c && !d || !e && !f', 'a && c && e || a && c && f || a && d && e || a && d && f || b && c && e || b && c && f || b && d && e || b && d && f');
});
test('false, true', () => {
function testNormalize(expr: string, expected: string): void {
const actual = ContextKeyExpr.deserialize(expr)!.serialize();
assert.strictEqual(actual, expected);
}
testNormalize('true', 'true');
testNormalize('!true', 'false');
testNormalize('false', 'false');
testNormalize('!false', 'true');
testNormalize('a && true', 'a');
testNormalize('a && false', 'false');
testNormalize('a || true', 'true');
testNormalize('a || false', 'a');
testNormalize('isMac', isMacintosh ? 'true' : 'false');
testNormalize('isLinux', isLinux ? 'true' : 'false');
testNormalize('isWindows', isWindows ? 'true' : 'false');
});
});