mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode bead496a613e475819f89f08e9e882b841bc1fe8 (#14883)
* Merge from vscode bead496a613e475819f89f08e9e882b841bc1fe8 * Bump distro * Upgrade GCC to 4.9 due to yarn install errors * Update build image * Fix bootstrap base url * Bump distro * Fix build errors * Update source map file * Disable checkbox for blocking migration issues (#15131) * disable checkbox for blocking issues * wip * disable checkbox fixes * fix strings * Remove duplicate tsec command * Default to off for tab color if settings not present * re-skip failing tests * Fix mocha error * Bump sqlite version & fix notebooks search view * Turn off esbuild warnings * Update esbuild log level * Fix overflowactionbar tests * Fix ts-ignore in dropdown tests * cleanup/fixes * Fix hygiene * Bundle in entire zone.js module * Remove extra constructor param * bump distro for web compile break * bump distro for web compile break v2 * Undo log level change * New distro * Fix integration test scripts * remove the "no yarn.lock changes" workflow * fix scripts v2 * Update unit test scripts * Ensure ads-kerberos2 updates in .vscodeignore * Try fix unit tests * Upload crash reports * remove nogpu * always upload crashes * Use bash script * Consolidate data/ext dir names * Create in tmp directory Co-authored-by: chlafreniere <hichise@gmail.com> Co-authored-by: Christopher Suh <chsuh@microsoft.com> Co-authored-by: chgagnon <chgagnon@microsoft.com>
This commit is contained in:
@@ -3,9 +3,9 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event, PauseableEmitter } from 'vs/base/common/event';
|
||||
import { Emitter, PauseableEmitter } from 'vs/base/common/event';
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { TernarySearchTree } from 'vs/base/common/map';
|
||||
import { distinct } from 'vs/base/common/objects';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
@@ -244,12 +244,14 @@ class CompositeContextKeyChangeEvent implements IContextKeyChangeEvent {
|
||||
}
|
||||
|
||||
export abstract class AbstractContextKeyService implements IContextKeyService {
|
||||
public _serviceBrand: undefined;
|
||||
declare _serviceBrand: undefined;
|
||||
|
||||
protected _isDisposed: boolean;
|
||||
protected _onDidChangeContext = new PauseableEmitter<IContextKeyChangeEvent>({ merge: input => new CompositeContextKeyChangeEvent(input) });
|
||||
protected _myContextId: number;
|
||||
|
||||
protected _onDidChangeContext = new PauseableEmitter<IContextKeyChangeEvent>({ merge: input => new CompositeContextKeyChangeEvent(input) });
|
||||
readonly onDidChangeContext = this._onDidChangeContext.event;
|
||||
|
||||
constructor(myContextId: number) {
|
||||
this._isDisposed = false;
|
||||
this._myContextId = myContextId;
|
||||
@@ -268,9 +270,6 @@ export abstract class AbstractContextKeyService implements IContextKeyService {
|
||||
return new ContextKey(this, key, defaultValue);
|
||||
}
|
||||
|
||||
public get onDidChangeContext(): Event<IContextKeyChangeEvent> {
|
||||
return this._onDidChangeContext.event;
|
||||
}
|
||||
|
||||
bufferChangeEvents(callback: Function): void {
|
||||
this._onDidChangeContext.pause();
|
||||
@@ -371,6 +370,7 @@ export class ContextKeyService extends AbstractContextKeyService implements ICon
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._onDidChangeContext.dispose();
|
||||
this._isDisposed = true;
|
||||
this._toDispose.dispose();
|
||||
}
|
||||
@@ -407,34 +407,34 @@ class ScopedContextKeyService extends AbstractContextKeyService {
|
||||
private _parent: AbstractContextKeyService;
|
||||
private _domNode: IContextKeyServiceTarget | undefined;
|
||||
|
||||
private _parentChangeListener: IDisposable | undefined;
|
||||
private readonly _parentChangeListener = new MutableDisposable();
|
||||
|
||||
constructor(parent: AbstractContextKeyService, domNode?: IContextKeyServiceTarget) {
|
||||
super(parent.createChildContext());
|
||||
this._parent = parent;
|
||||
this.updateParentChangeListener();
|
||||
this._updateParentChangeListener();
|
||||
|
||||
if (domNode) {
|
||||
this._domNode = domNode;
|
||||
if (this._domNode.hasAttribute(KEYBINDING_CONTEXT_ATTR)) {
|
||||
console.error('Element already has context attribute');
|
||||
let extraInfo = '';
|
||||
if ((this._domNode as HTMLElement).classList) {
|
||||
extraInfo = Array.from((this._domNode as HTMLElement).classList.values()).join(', ');
|
||||
}
|
||||
|
||||
console.error(`Element already has context attribute${extraInfo ? ': ' + extraInfo : ''}`);
|
||||
}
|
||||
this._domNode.setAttribute(KEYBINDING_CONTEXT_ATTR, String(this._myContextId));
|
||||
}
|
||||
}
|
||||
|
||||
private updateParentChangeListener(): void {
|
||||
if (this._parentChangeListener) {
|
||||
this._parentChangeListener.dispose();
|
||||
}
|
||||
|
||||
this._parentChangeListener = this._parent.onDidChangeContext(e => {
|
||||
// Forward parent events to this listener. Parent will change.
|
||||
this._onDidChangeContext.fire(e);
|
||||
});
|
||||
private _updateParentChangeListener(): void {
|
||||
// Forward parent events to this listener. Parent will change.
|
||||
this._parentChangeListener.value = this._parent.onDidChangeContext(this._onDidChangeContext.fire, this._onDidChangeContext);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._onDidChangeContext.dispose();
|
||||
this._isDisposed = true;
|
||||
this._parent.disposeContext(this._myContextId);
|
||||
this._parentChangeListener?.dispose();
|
||||
@@ -444,10 +444,6 @@ class ScopedContextKeyService extends AbstractContextKeyService {
|
||||
}
|
||||
}
|
||||
|
||||
public get onDidChangeContext(): Event<IContextKeyChangeEvent> {
|
||||
return this._onDidChangeContext.event;
|
||||
}
|
||||
|
||||
public getContextValuesContainer(contextId: number): Context {
|
||||
if (this._isDisposed) {
|
||||
return NullContext.INSTANCE;
|
||||
@@ -473,7 +469,7 @@ class ScopedContextKeyService extends AbstractContextKeyService {
|
||||
const thisContainer = this._parent.getContextValuesContainer(this._myContextId);
|
||||
const oldAllValues = thisContainer.collectAllValues();
|
||||
this._parent = parentContextKeyService;
|
||||
this.updateParentChangeListener();
|
||||
this._updateParentChangeListener();
|
||||
const newParentContainer = this._parent.getContextValuesContainer(this._parent.contextId);
|
||||
thisContainer.updateParent(newParentContainer);
|
||||
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
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';
|
||||
import { userAgent, isMacintosh, isLinux, isWindows, isWeb } from 'vs/base/common/platform';
|
||||
|
||||
let _userAgent = userAgent || '';
|
||||
const STATIC_VALUES = new Map<string, boolean>();
|
||||
STATIC_VALUES.set('false', false);
|
||||
STATIC_VALUES.set('true', true);
|
||||
@@ -16,6 +17,11 @@ STATIC_VALUES.set('isLinux', isLinux);
|
||||
STATIC_VALUES.set('isWindows', isWindows);
|
||||
STATIC_VALUES.set('isWeb', isWeb);
|
||||
STATIC_VALUES.set('isMacNative', isMacintosh && !isWeb);
|
||||
STATIC_VALUES.set('isEdge', _userAgent.indexOf('Edg/') >= 0);
|
||||
STATIC_VALUES.set('isFirefox', _userAgent.indexOf('Firefox') >= 0);
|
||||
STATIC_VALUES.set('isChrome', _userAgent.indexOf('Chrome') >= 0);
|
||||
STATIC_VALUES.set('isSafari', _userAgent.indexOf('Safari') >= 0);
|
||||
STATIC_VALUES.set('isIPad', _userAgent.indexOf('iPad') >= 0);
|
||||
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
@@ -32,8 +38,10 @@ export const enum ContextKeyExprType {
|
||||
Or = 9,
|
||||
In = 10,
|
||||
NotIn = 11,
|
||||
GreaterThanEquals = 12, // {{SQL CARBON EDIT}} add value
|
||||
LessThanEquals = 13 // {{SQL CARBON EDIT}} add value
|
||||
Greater = 12,
|
||||
GreaterEquals = 13,
|
||||
Smaller = 14,
|
||||
SmallerEquals = 15,
|
||||
}
|
||||
|
||||
export interface IContextKeyExprMapper {
|
||||
@@ -41,6 +49,10 @@ export interface IContextKeyExprMapper {
|
||||
mapNot(key: string): ContextKeyExpression;
|
||||
mapEquals(key: string, value: any): ContextKeyExpression;
|
||||
mapNotEquals(key: string, value: any): ContextKeyExpression;
|
||||
mapGreater(key: string, value: any): ContextKeyExpression;
|
||||
mapGreaterEquals(key: string, value: any): ContextKeyExpression;
|
||||
mapSmaller(key: string, value: any): ContextKeyExpression;
|
||||
mapSmallerEquals(key: string, value: any): ContextKeyExpression;
|
||||
mapRegex(key: string, regexp: RegExp | null): ContextKeyRegexExpr;
|
||||
mapIn(key: string, valueKey: string): ContextKeyInExpr;
|
||||
}
|
||||
@@ -59,7 +71,9 @@ export interface IContextKeyExpression {
|
||||
export type ContextKeyExpression = (
|
||||
ContextKeyFalseExpr | ContextKeyTrueExpr | ContextKeyDefinedExpr | ContextKeyNotExpr
|
||||
| ContextKeyEqualsExpr | ContextKeyNotEqualsExpr | ContextKeyRegexExpr
|
||||
| ContextKeyNotRegexExpr | ContextKeyAndExpr | ContextKeyOrExpr | ContextKeyInExpr | ContextKeyNotInExpr | ContextKeyGreaterThanEqualsExpr | ContextKeyLessThanEqualsExpr // {{SQL CARBON EDIT}}
|
||||
| ContextKeyNotRegexExpr | ContextKeyAndExpr | ContextKeyOrExpr | ContextKeyInExpr
|
||||
| ContextKeyNotInExpr | ContextKeyGreaterExpr | ContextKeyGreaterEqualsExpr
|
||||
| ContextKeySmallerExpr | ContextKeySmallerEqualsExpr
|
||||
);
|
||||
|
||||
export abstract class ContextKeyExpr {
|
||||
@@ -104,15 +118,13 @@ export abstract class ContextKeyExpr {
|
||||
return ContextKeyOrExpr.create(expr);
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
public static greaterThanEquals(key: string, value: any): ContextKeyExpression {
|
||||
return ContextKeyGreaterThanEqualsExpr.create(key, value);
|
||||
public static greater(key: string, value: any): ContextKeyExpression {
|
||||
return ContextKeyGreaterExpr.create(key, value);
|
||||
}
|
||||
|
||||
public static lessThanEquals(key: string, value: any): ContextKeyExpression {
|
||||
return ContextKeyLessThanEqualsExpr.create(key, value);
|
||||
public static less(key: string, value: any): ContextKeyExpression {
|
||||
return ContextKeySmallerExpr.create(key, value);
|
||||
}
|
||||
//
|
||||
|
||||
public static deserialize(serialized: string | null | undefined, strict: boolean = false): ContextKeyExpression | undefined {
|
||||
if (!serialized) {
|
||||
@@ -150,21 +162,31 @@ export abstract class ContextKeyExpr {
|
||||
return ContextKeyRegexExpr.create(pieces[0].trim(), this._deserializeRegexValue(pieces[1], strict));
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
if (serializedOne.indexOf('>=') >= 0) {
|
||||
let pieces = serializedOne.split('>=');
|
||||
return ContextKeyGreaterThanEqualsExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict));
|
||||
}
|
||||
if (serializedOne.indexOf('<=') >= 0) {
|
||||
let pieces = serializedOne.split('<=');
|
||||
return ContextKeyLessThanEqualsExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict));
|
||||
}
|
||||
//
|
||||
if (serializedOne.indexOf(' in ') >= 0) {
|
||||
let pieces = serializedOne.split(' in ');
|
||||
return ContextKeyInExpr.create(pieces[0].trim(), pieces[1].trim());
|
||||
}
|
||||
|
||||
if (/^[^<=>]+>=[^<=>]+$/.test(serializedOne)) {
|
||||
const pieces = serializedOne.split('>=');
|
||||
return ContextKeyGreaterEqualsExpr.create(pieces[0].trim(), pieces[1].trim());
|
||||
}
|
||||
|
||||
if (/^[^<=>]+>[^<=>]+$/.test(serializedOne)) {
|
||||
const pieces = serializedOne.split('>');
|
||||
return ContextKeyGreaterExpr.create(pieces[0].trim(), pieces[1].trim());
|
||||
}
|
||||
|
||||
if (/^[^<=>]+<=[^<=>]+$/.test(serializedOne)) {
|
||||
const pieces = serializedOne.split('<=');
|
||||
return ContextKeySmallerEqualsExpr.create(pieces[0].trim(), pieces[1].trim());
|
||||
}
|
||||
|
||||
if (/^[^<=>]+<[^<=>]+$/.test(serializedOne)) {
|
||||
const pieces = serializedOne.split('<');
|
||||
return ContextKeySmallerExpr.create(pieces[0].trim(), pieces[1].trim());
|
||||
}
|
||||
|
||||
if (/^\!\s*/.test(serializedOne)) {
|
||||
return ContextKeyNotExpr.create(serializedOne.substr(1).trim());
|
||||
}
|
||||
@@ -324,13 +346,7 @@ export class ContextKeyDefinedExpr implements IContextKeyExpression {
|
||||
if (other.type !== this.type) {
|
||||
return this.type - other.type;
|
||||
}
|
||||
if (this.key < other.key) {
|
||||
return -1;
|
||||
}
|
||||
if (this.key > other.key) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return cmp1(this.key, other.key);
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpression): boolean {
|
||||
@@ -384,19 +400,7 @@ export class ContextKeyEqualsExpr implements IContextKeyExpression {
|
||||
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.value < other.value) {
|
||||
return -1;
|
||||
}
|
||||
if (this.value > other.value) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return cmp2(this.key, this.value, other.key, other.value);
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpression): boolean {
|
||||
@@ -444,19 +448,7 @@ export class ContextKeyInExpr implements IContextKeyExpression {
|
||||
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;
|
||||
return cmp2(this.key, this.valueKey, other.key, other.valueKey);
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpression): boolean {
|
||||
@@ -571,19 +563,7 @@ export class ContextKeyNotEqualsExpr implements IContextKeyExpression {
|
||||
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.value < other.value) {
|
||||
return -1;
|
||||
}
|
||||
if (this.value > other.value) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return cmp2(this.key, this.value, other.key, other.value);
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpression): boolean {
|
||||
@@ -635,13 +615,7 @@ export class ContextKeyNotExpr implements IContextKeyExpression {
|
||||
if (other.type !== this.type) {
|
||||
return this.type - other.type;
|
||||
}
|
||||
if (this.key < other.key) {
|
||||
return -1;
|
||||
}
|
||||
if (this.key > other.key) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return cmp1(this.key, other.key);
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpression): boolean {
|
||||
@@ -672,6 +646,200 @@ export class ContextKeyNotExpr implements IContextKeyExpression {
|
||||
}
|
||||
}
|
||||
|
||||
export class ContextKeyGreaterExpr implements IContextKeyExpression {
|
||||
|
||||
public static create(key: string, value: any): ContextKeyExpression {
|
||||
return new ContextKeyGreaterExpr(key, value);
|
||||
}
|
||||
|
||||
public readonly type = ContextKeyExprType.Greater;
|
||||
|
||||
private constructor(
|
||||
private readonly key: string,
|
||||
private readonly value: any
|
||||
) { }
|
||||
|
||||
public cmp(other: ContextKeyExpression): number {
|
||||
if (other.type !== this.type) {
|
||||
return this.type - other.type;
|
||||
}
|
||||
return cmp2(this.key, this.value, other.key, other.value);
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpression): boolean {
|
||||
if (other.type === this.type) {
|
||||
return (this.key === other.key && this.value === other.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public evaluate(context: IContext): boolean {
|
||||
return (parseFloat(<any>context.getValue(this.key)) > parseFloat(this.value));
|
||||
}
|
||||
|
||||
public serialize(): string {
|
||||
return `${this.key} > ${this.value}`;
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
return [this.key];
|
||||
}
|
||||
|
||||
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
|
||||
return mapFnc.mapGreater(this.key, this.value);
|
||||
}
|
||||
|
||||
public negate(): ContextKeyExpression {
|
||||
return ContextKeySmallerEqualsExpr.create(this.key, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
export class ContextKeyGreaterEqualsExpr implements IContextKeyExpression {
|
||||
|
||||
public static create(key: string, value: any): ContextKeyExpression {
|
||||
return new ContextKeyGreaterEqualsExpr(key, value);
|
||||
}
|
||||
|
||||
public readonly type = ContextKeyExprType.GreaterEquals;
|
||||
|
||||
private constructor(
|
||||
private readonly key: string,
|
||||
private readonly value: any
|
||||
) { }
|
||||
|
||||
public cmp(other: ContextKeyExpression): number {
|
||||
if (other.type !== this.type) {
|
||||
return this.type - other.type;
|
||||
}
|
||||
return cmp2(this.key, this.value, other.key, other.value);
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpression): boolean {
|
||||
if (other.type === this.type) {
|
||||
return (this.key === other.key && this.value === other.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public evaluate(context: IContext): boolean {
|
||||
return (parseFloat(<any>context.getValue(this.key)) >= parseFloat(this.value));
|
||||
}
|
||||
|
||||
public serialize(): string {
|
||||
return `${this.key} >= ${this.value}`;
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
return [this.key];
|
||||
}
|
||||
|
||||
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
|
||||
return mapFnc.mapGreaterEquals(this.key, this.value);
|
||||
}
|
||||
|
||||
public negate(): ContextKeyExpression {
|
||||
return ContextKeySmallerExpr.create(this.key, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
export class ContextKeySmallerExpr implements IContextKeyExpression {
|
||||
|
||||
public static create(key: string, value: any): ContextKeyExpression {
|
||||
return new ContextKeySmallerExpr(key, value);
|
||||
}
|
||||
|
||||
public readonly type = ContextKeyExprType.Smaller;
|
||||
|
||||
private constructor(
|
||||
private readonly key: string,
|
||||
private readonly value: any
|
||||
) {
|
||||
}
|
||||
|
||||
public cmp(other: ContextKeyExpression): number {
|
||||
if (other.type !== this.type) {
|
||||
return this.type - other.type;
|
||||
}
|
||||
return cmp2(this.key, this.value, other.key, other.value);
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpression): boolean {
|
||||
if (other.type === this.type) {
|
||||
return (this.key === other.key && this.value === other.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public evaluate(context: IContext): boolean {
|
||||
return (parseFloat(<any>context.getValue(this.key)) < parseFloat(this.value));
|
||||
}
|
||||
|
||||
public serialize(): string {
|
||||
return `${this.key} < ${this.value}`;
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
return [this.key];
|
||||
}
|
||||
|
||||
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
|
||||
return mapFnc.mapSmaller(this.key, this.value);
|
||||
}
|
||||
|
||||
public negate(): ContextKeyExpression {
|
||||
return ContextKeyGreaterEqualsExpr.create(this.key, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
export class ContextKeySmallerEqualsExpr implements IContextKeyExpression {
|
||||
|
||||
public static create(key: string, value: any): ContextKeyExpression {
|
||||
return new ContextKeySmallerEqualsExpr(key, value);
|
||||
}
|
||||
|
||||
public readonly type = ContextKeyExprType.SmallerEquals;
|
||||
|
||||
private constructor(
|
||||
private readonly key: string,
|
||||
private readonly value: any
|
||||
) {
|
||||
}
|
||||
|
||||
public cmp(other: ContextKeyExpression): number {
|
||||
if (other.type !== this.type) {
|
||||
return this.type - other.type;
|
||||
}
|
||||
return cmp2(this.key, this.value, other.key, other.value);
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpression): boolean {
|
||||
if (other.type === this.type) {
|
||||
return (this.key === other.key && this.value === other.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public evaluate(context: IContext): boolean {
|
||||
return (parseFloat(<any>context.getValue(this.key)) <= parseFloat(this.value));
|
||||
}
|
||||
|
||||
public serialize(): string {
|
||||
return `${this.key} <= ${this.value}`;
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
return [this.key];
|
||||
}
|
||||
|
||||
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
|
||||
return mapFnc.mapSmallerEquals(this.key, this.value);
|
||||
}
|
||||
|
||||
public negate(): ContextKeyExpression {
|
||||
return ContextKeyGreaterExpr.create(this.key, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
export class ContextKeyRegexExpr implements IContextKeyExpression {
|
||||
|
||||
public static create(key: string, regexp: RegExp | null): ContextKeyRegexExpr {
|
||||
@@ -1089,152 +1257,6 @@ export class ContextKeyOrExpr implements IContextKeyExpression {
|
||||
}
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
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 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.value < other.value) {
|
||||
return -1;
|
||||
}
|
||||
if (this.value > other.value) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpression): boolean {
|
||||
if (other.type === this.type) {
|
||||
return (this.key === other.key && this.value === other.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public negate(): ContextKeyExpression {
|
||||
throw new Error('Method not implemented.'); // @TODO anthonydresser need to figure out what to do in this case
|
||||
}
|
||||
|
||||
public evaluate(context: IContext): boolean {
|
||||
const keyVal = context.getValue<string>(this.key);
|
||||
if (!keyVal) {
|
||||
return false;
|
||||
}
|
||||
const keyInt = parseFloat(keyVal);
|
||||
const valueInt = parseFloat(this.value);
|
||||
return (keyInt >= valueInt);
|
||||
}
|
||||
|
||||
public serialize(): string {
|
||||
return this.key + ' >= \'' + this.value + '\'';
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
return [this.key];
|
||||
}
|
||||
|
||||
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
|
||||
return mapFnc.mapEquals(this.key, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
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 readonly type = ContextKeyExprType.LessThanEquals;
|
||||
|
||||
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.value < other.value) {
|
||||
return -1;
|
||||
}
|
||||
if (this.value > other.value) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public equals(other: ContextKeyExpression): boolean {
|
||||
if (other.type === this.type) {
|
||||
return (this.key === other.key && this.value === other.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public evaluate(context: IContext): boolean {
|
||||
const keyVal = context.getValue<string>(this.key);
|
||||
if (!keyVal) {
|
||||
return false;
|
||||
}
|
||||
const keyInt = parseFloat(keyVal);
|
||||
const valueInt = parseFloat(this.value);
|
||||
return (keyInt <= valueInt);
|
||||
}
|
||||
|
||||
public negate(): ContextKeyExpression {
|
||||
throw new Error('Method not implemented.'); // @TODO anthonydresser need to figure out what to do in this case
|
||||
}
|
||||
|
||||
public serialize(): string {
|
||||
return this.key + ' <= \'' + this.value + '\'';
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
return [this.key];
|
||||
}
|
||||
|
||||
public map(mapFnc: IContextKeyExprMapper): ContextKeyExpression {
|
||||
return mapFnc.mapEquals(this.key, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
export class RawContextKey<T> extends ContextKeyDefinedExpr {
|
||||
|
||||
private readonly _defaultValue: T | undefined;
|
||||
@@ -1256,11 +1278,11 @@ export class RawContextKey<T> extends ContextKeyDefinedExpr {
|
||||
return ContextKeyExpr.not(this.key);
|
||||
}
|
||||
|
||||
public isEqualTo(value: string): ContextKeyExpression {
|
||||
public isEqualTo(value: any): ContextKeyExpression {
|
||||
return ContextKeyExpr.equals(this.key, value);
|
||||
}
|
||||
|
||||
public notEqualsTo(value: string): ContextKeyExpression {
|
||||
public notEqualsTo(value: any): ContextKeyExpression {
|
||||
return ContextKeyExpr.notEquals(this.key, value);
|
||||
}
|
||||
}
|
||||
@@ -1311,3 +1333,29 @@ export interface IContextKeyService {
|
||||
}
|
||||
|
||||
export const SET_CONTEXT_COMMAND_ID = 'setContext';
|
||||
|
||||
function cmp1(key1: string, key2: string): number {
|
||||
if (key1 < key2) {
|
||||
return -1;
|
||||
}
|
||||
if (key1 > key2) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function cmp2(key1: string, value1: any, key2: string, value2: any): number {
|
||||
if (key1 < key2) {
|
||||
return -1;
|
||||
}
|
||||
if (key1 > key2) {
|
||||
return 1;
|
||||
}
|
||||
if (value1 < value2) {
|
||||
return -1;
|
||||
}
|
||||
if (value1 > value2) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -28,16 +28,8 @@ suite('ContextKeyExpr', () => {
|
||||
ContextKeyExpr.notEquals('c2', 'cc2'),
|
||||
ContextKeyExpr.not('d1'),
|
||||
ContextKeyExpr.not('d2'),
|
||||
ContextKeyExpr.greaterThanEquals('e1', 'ee1'), // {{SQL CARBON EDIT}} add test case
|
||||
ContextKeyExpr.greaterThanEquals('e2', 'ee2'), // {{SQL CARBON EDIT}} add test case
|
||||
ContextKeyExpr.lessThanEquals('f1', 'ff1'), // {{SQL CARBON EDIT}} add test case
|
||||
ContextKeyExpr.lessThanEquals('f2', 'ff2'), // {{SQL CARBON EDIT}} add test case
|
||||
)!;
|
||||
let b = ContextKeyExpr.and(
|
||||
ContextKeyExpr.lessThanEquals('f1', 'ff1'), // {{SQL CARBON EDIT}}
|
||||
ContextKeyExpr.lessThanEquals('f2', 'ff2'), // {{SQL CARBON EDIT}}
|
||||
ContextKeyExpr.greaterThanEquals('e2', 'ee2'), // {{SQL CARBON EDIT}}
|
||||
ContextKeyExpr.greaterThanEquals('e1', 'ee1'), // {{SQL CARBON EDIT}}
|
||||
ContextKeyExpr.equals('b2', 'bb2'),
|
||||
ContextKeyExpr.notEquals('c1', 'cc1'),
|
||||
ContextKeyExpr.not('d1'),
|
||||
@@ -75,7 +67,7 @@ suite('ContextKeyExpr', () => {
|
||||
function testExpression(expr: string, expected: boolean): void {
|
||||
// console.log(expr + ' ' + expected);
|
||||
let rules = ContextKeyExpr.deserialize(expr);
|
||||
assert.equal(rules!.evaluate(context), expected, expr);
|
||||
assert.strictEqual(rules!.evaluate(context), expected, expr);
|
||||
}
|
||||
function testBatch(expr: string, value: any): void {
|
||||
/* eslint-disable eqeqeq */
|
||||
@@ -165,17 +157,17 @@ suite('ContextKeyExpr', () => {
|
||||
|
||||
test('ContextKeyInExpr', () => {
|
||||
const ainb = ContextKeyExpr.deserialize('a in b')!;
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 3, 'b': [3, 2, 1] })), true);
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 3, 'b': [1, 2, 3] })), true);
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 3, 'b': [1, 2] })), false);
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 3 })), false);
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 3, 'b': null })), false);
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 'x', 'b': ['x'] })), true);
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 'x', 'b': ['y'] })), false);
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 'x', 'b': {} })), false);
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 'x', 'b': { 'x': false } })), true);
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 'x', 'b': { 'x': true } })), true);
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 'prototype', 'b': {} })), false);
|
||||
assert.strictEqual(ainb.evaluate(createContext({ 'a': 3, 'b': [3, 2, 1] })), true);
|
||||
assert.strictEqual(ainb.evaluate(createContext({ 'a': 3, 'b': [1, 2, 3] })), true);
|
||||
assert.strictEqual(ainb.evaluate(createContext({ 'a': 3, 'b': [1, 2] })), false);
|
||||
assert.strictEqual(ainb.evaluate(createContext({ 'a': 3 })), false);
|
||||
assert.strictEqual(ainb.evaluate(createContext({ 'a': 3, 'b': null })), false);
|
||||
assert.strictEqual(ainb.evaluate(createContext({ 'a': 'x', 'b': ['x'] })), true);
|
||||
assert.strictEqual(ainb.evaluate(createContext({ 'a': 'x', 'b': ['y'] })), false);
|
||||
assert.strictEqual(ainb.evaluate(createContext({ 'a': 'x', 'b': {} })), false);
|
||||
assert.strictEqual(ainb.evaluate(createContext({ 'a': 'x', 'b': { 'x': false } })), true);
|
||||
assert.strictEqual(ainb.evaluate(createContext({ 'a': 'x', 'b': { 'x': true } })), true);
|
||||
assert.strictEqual(ainb.evaluate(createContext({ 'a': 'prototype', 'b': {} })), false);
|
||||
});
|
||||
|
||||
test('issue #106524: distributing AND should normalize', () => {
|
||||
@@ -196,6 +188,86 @@ suite('ContextKeyExpr', () => {
|
||||
ContextKeyExpr.has('c')
|
||||
)
|
||||
);
|
||||
assert.equal(actual!.equals(expected!), true);
|
||||
assert.strictEqual(actual!.equals(expected!), true);
|
||||
});
|
||||
|
||||
test('Greater, GreaterEquals, Smaller, SmallerEquals evaluate', () => {
|
||||
function checkEvaluate(expr: string, ctx: any, expected: any): void {
|
||||
const _expr = ContextKeyExpr.deserialize(expr)!;
|
||||
assert.strictEqual(_expr.evaluate(createContext(ctx)), expected);
|
||||
}
|
||||
|
||||
checkEvaluate('a>1', {}, false);
|
||||
checkEvaluate('a>1', { a: 0 }, false);
|
||||
checkEvaluate('a>1', { a: 1 }, false);
|
||||
checkEvaluate('a>1', { a: 2 }, true);
|
||||
checkEvaluate('a>1', { a: '0' }, false);
|
||||
checkEvaluate('a>1', { a: '1' }, false);
|
||||
checkEvaluate('a>1', { a: '2' }, true);
|
||||
checkEvaluate('a>1', { a: 'a' }, false);
|
||||
|
||||
checkEvaluate('a>10', { a: 2 }, false);
|
||||
checkEvaluate('a>10', { a: 11 }, true);
|
||||
checkEvaluate('a>10', { a: '11' }, true);
|
||||
checkEvaluate('a>10', { a: '2' }, false);
|
||||
checkEvaluate('a>10', { a: '11' }, true);
|
||||
|
||||
checkEvaluate('a>1.1', { a: 1 }, false);
|
||||
checkEvaluate('a>1.1', { a: 2 }, true);
|
||||
checkEvaluate('a>1.1', { a: 11 }, true);
|
||||
checkEvaluate('a>1.1', { a: '1.1' }, false);
|
||||
checkEvaluate('a>1.1', { a: '2' }, true);
|
||||
checkEvaluate('a>1.1', { a: '11' }, true);
|
||||
|
||||
checkEvaluate('a>b', { a: 'b' }, false);
|
||||
checkEvaluate('a>b', { a: 'c' }, false);
|
||||
checkEvaluate('a>b', { a: 1000 }, false);
|
||||
|
||||
checkEvaluate('a >= 2', { a: '1' }, false);
|
||||
checkEvaluate('a >= 2', { a: '2' }, true);
|
||||
checkEvaluate('a >= 2', { a: '3' }, true);
|
||||
|
||||
checkEvaluate('a < 2', { a: '1' }, true);
|
||||
checkEvaluate('a < 2', { a: '2' }, false);
|
||||
checkEvaluate('a < 2', { a: '3' }, false);
|
||||
|
||||
checkEvaluate('a <= 2', { a: '1' }, true);
|
||||
checkEvaluate('a <= 2', { a: '2' }, true);
|
||||
checkEvaluate('a <= 2', { a: '3' }, false);
|
||||
});
|
||||
|
||||
test('Greater, GreaterEquals, Smaller, SmallerEquals negate', () => {
|
||||
function checkNegate(expr: string, expected: string): void {
|
||||
const a = ContextKeyExpr.deserialize(expr)!;
|
||||
const b = a.negate();
|
||||
assert.strictEqual(b.serialize(), expected);
|
||||
}
|
||||
|
||||
checkNegate('a>1', 'a <= 1');
|
||||
checkNegate('a>1.1', 'a <= 1.1');
|
||||
checkNegate('a>b', 'a <= b');
|
||||
|
||||
checkNegate('a>=1', 'a < 1');
|
||||
checkNegate('a>=1.1', 'a < 1.1');
|
||||
checkNegate('a>=b', 'a < b');
|
||||
|
||||
checkNegate('a<1', 'a >= 1');
|
||||
checkNegate('a<1.1', 'a >= 1.1');
|
||||
checkNegate('a<b', 'a >= b');
|
||||
|
||||
checkNegate('a<=1', 'a > 1');
|
||||
checkNegate('a<=1.1', 'a > 1.1');
|
||||
checkNegate('a<=b', 'a > b');
|
||||
});
|
||||
|
||||
test('issue #111899: context keys can use `<` or `>` ', () => {
|
||||
const actual = ContextKeyExpr.deserialize('editorTextFocus && vim.active && vim.use<C-r>')!;
|
||||
assert.ok(actual.equals(
|
||||
ContextKeyExpr.and(
|
||||
ContextKeyExpr.has('editorTextFocus'),
|
||||
ContextKeyExpr.has('vim.active'),
|
||||
ContextKeyExpr.has('vim.use<C-r>'),
|
||||
)!
|
||||
));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user