mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Merge from vscode 2c306f762bf9c3db82dc06c7afaa56ef46d72f79 (#14050)
* Merge from vscode 2c306f762bf9c3db82dc06c7afaa56ef46d72f79 * Fix breaks * Extension management fixes * Fix breaks in windows bundling * Fix/skip failing tests * Update distro * Add clear to nuget.config * Add hygiene task * Bump distro * Fix hygiene issue * Add build to hygiene exclusion * Update distro * Update hygiene * Hygiene exclusions * Update tsconfig * Bump distro for server breaks * Update build config * Update darwin path * Add done calls to notebook tests * Skip failing tests * Disable smoke tests
This commit is contained in:
@@ -4,7 +4,10 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event, PauseableEmitter } from 'vs/base/common/event';
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { IDisposable, DisposableStore } 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';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IContext, IContextKey, IContextKeyChangeEvent, IContextKeyService, IContextKeyServiceTarget, IReadableSet, SET_CONTEXT_COMMAND_ID, ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey';
|
||||
@@ -51,7 +54,11 @@ export class Context implements IContext {
|
||||
return ret;
|
||||
}
|
||||
|
||||
collectAllValues(): { [key: string]: any; } {
|
||||
public updateParent(parent: Context): void {
|
||||
this._parent = parent;
|
||||
}
|
||||
|
||||
public collectAllValues(): { [key: string]: any; } {
|
||||
let result = this._parent ? this._parent.collectAllValues() : Object.create(null);
|
||||
result = { ...result, ...this._value };
|
||||
delete result['_contextId'];
|
||||
@@ -85,10 +92,9 @@ class NullContext extends Context {
|
||||
}
|
||||
|
||||
class ConfigAwareContextValuesContainer extends Context {
|
||||
|
||||
private static readonly _keyPrefix = 'config.';
|
||||
|
||||
private readonly _values = new Map<string, any>();
|
||||
private readonly _values = TernarySearchTree.forConfigKeys<any>();
|
||||
private readonly _listener: IDisposable;
|
||||
|
||||
constructor(
|
||||
@@ -101,18 +107,26 @@ class ConfigAwareContextValuesContainer extends Context {
|
||||
this._listener = this._configurationService.onDidChangeConfiguration(event => {
|
||||
if (event.source === ConfigurationTarget.DEFAULT) {
|
||||
// new setting, reset everything
|
||||
const allKeys = Array.from(this._values.keys());
|
||||
const allKeys = Array.from(Iterable.map(this._values, ([k]) => k));
|
||||
this._values.clear();
|
||||
emitter.fire(new ArrayContextKeyChangeEvent(allKeys));
|
||||
} else {
|
||||
const changedKeys: string[] = [];
|
||||
for (const configKey of event.affectedKeys) {
|
||||
const contextKey = `config.${configKey}`;
|
||||
|
||||
const cachedItems = this._values.findSuperstr(contextKey);
|
||||
if (cachedItems !== undefined) {
|
||||
changedKeys.push(...Iterable.map(cachedItems, ([key]) => key));
|
||||
this._values.deleteSuperstr(contextKey);
|
||||
}
|
||||
|
||||
if (this._values.has(contextKey)) {
|
||||
this._values.delete(contextKey);
|
||||
changedKeys.push(contextKey);
|
||||
this._values.delete(contextKey);
|
||||
}
|
||||
}
|
||||
|
||||
emitter.fire(new ArrayContextKeyChangeEvent(changedKeys));
|
||||
}
|
||||
});
|
||||
@@ -144,6 +158,8 @@ class ConfigAwareContextValuesContainer extends Context {
|
||||
default:
|
||||
if (Array.isArray(configValue)) {
|
||||
value = JSON.stringify(configValue);
|
||||
} else {
|
||||
value = configValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,6 +255,10 @@ export abstract class AbstractContextKeyService implements IContextKeyService {
|
||||
this._myContextId = myContextId;
|
||||
}
|
||||
|
||||
public get contextId(): number {
|
||||
return this._myContextId;
|
||||
}
|
||||
|
||||
abstract dispose(): void;
|
||||
|
||||
public createKey<T>(key: string, defaultValue: T | undefined): IContextKey<T> {
|
||||
@@ -319,6 +339,7 @@ export abstract class AbstractContextKeyService implements IContextKeyService {
|
||||
public abstract getContextValuesContainer(contextId: number): Context;
|
||||
public abstract createChildContext(parentContextId?: number): number;
|
||||
public abstract disposeContext(contextId: number): void;
|
||||
public abstract updateParent(parentContextKeyService?: IContextKeyService): void;
|
||||
}
|
||||
|
||||
export class ContextKeyService extends AbstractContextKeyService implements IContextKeyService {
|
||||
@@ -375,6 +396,10 @@ export class ContextKeyService extends AbstractContextKeyService implements ICon
|
||||
this._contexts.delete(contextId);
|
||||
}
|
||||
}
|
||||
|
||||
public updateParent(_parentContextKeyService: IContextKeyService): void {
|
||||
throw new Error('Cannot update parent of root ContextKeyService');
|
||||
}
|
||||
}
|
||||
|
||||
class ScopedContextKeyService extends AbstractContextKeyService {
|
||||
@@ -382,19 +407,37 @@ class ScopedContextKeyService extends AbstractContextKeyService {
|
||||
private _parent: AbstractContextKeyService;
|
||||
private _domNode: IContextKeyServiceTarget | undefined;
|
||||
|
||||
private _parentChangeListener: IDisposable | undefined;
|
||||
|
||||
constructor(parent: AbstractContextKeyService, domNode?: IContextKeyServiceTarget) {
|
||||
super(parent.createChildContext());
|
||||
this._parent = parent;
|
||||
this.updateParentChangeListener();
|
||||
|
||||
if (domNode) {
|
||||
this._domNode = domNode;
|
||||
if (this._domNode.hasAttribute(KEYBINDING_CONTEXT_ATTR)) {
|
||||
console.error('Element already has context attribute');
|
||||
}
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._isDisposed = true;
|
||||
this._parent.disposeContext(this._myContextId);
|
||||
this._parentChangeListener?.dispose();
|
||||
if (this._domNode) {
|
||||
this._domNode.removeAttribute(KEYBINDING_CONTEXT_ATTR);
|
||||
this._domNode = undefined;
|
||||
@@ -402,7 +445,7 @@ class ScopedContextKeyService extends AbstractContextKeyService {
|
||||
}
|
||||
|
||||
public get onDidChangeContext(): Event<IContextKeyChangeEvent> {
|
||||
return Event.any(this._parent.onDidChangeContext, this._onDidChangeContext.event);
|
||||
return this._onDidChangeContext.event;
|
||||
}
|
||||
|
||||
public getContextValuesContainer(contextId: number): Context {
|
||||
@@ -425,6 +468,24 @@ class ScopedContextKeyService extends AbstractContextKeyService {
|
||||
}
|
||||
this._parent.disposeContext(contextId);
|
||||
}
|
||||
|
||||
public updateParent(parentContextKeyService: AbstractContextKeyService): void {
|
||||
const thisContainer = this._parent.getContextValuesContainer(this._myContextId);
|
||||
const oldAllValues = thisContainer.collectAllValues();
|
||||
this._parent = parentContextKeyService;
|
||||
this.updateParentChangeListener();
|
||||
const newParentContainer = this._parent.getContextValuesContainer(this._parent.contextId);
|
||||
thisContainer.updateParent(newParentContainer);
|
||||
|
||||
const newAllValues = thisContainer.collectAllValues();
|
||||
const allValuesDiff = {
|
||||
...distinct(oldAllValues, newAllValues),
|
||||
...distinct(newAllValues, oldAllValues)
|
||||
};
|
||||
const changedKeys = Object.keys(allValuesDiff);
|
||||
|
||||
this._onDidChangeContext.fire(new ArrayContextKeyChangeEvent(changedKeys));
|
||||
}
|
||||
}
|
||||
|
||||
function findContextAttr(domNode: IContextKeyServiceTarget | null): number {
|
||||
|
||||
@@ -413,7 +413,7 @@ export class ContextKeyEqualsExpr implements IContextKeyExpression {
|
||||
}
|
||||
|
||||
public serialize(): string {
|
||||
return this.key + ' == \'' + this.value + '\'';
|
||||
return `${this.key} == '${this.value}'`;
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
@@ -482,7 +482,7 @@ export class ContextKeyInExpr implements IContextKeyExpression {
|
||||
}
|
||||
|
||||
public serialize(): string {
|
||||
return this.key + ' in \'' + this.valueKey + '\'';
|
||||
return `${this.key} in '${this.valueKey}'`;
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
@@ -600,7 +600,7 @@ export class ContextKeyNotEqualsExpr implements IContextKeyExpression {
|
||||
}
|
||||
|
||||
public serialize(): string {
|
||||
return this.key + ' != \'' + this.value + '\'';
|
||||
return `${this.key} != '${this.value}'`;
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
@@ -656,7 +656,7 @@ export class ContextKeyNotExpr implements IContextKeyExpression {
|
||||
}
|
||||
|
||||
public serialize(): string {
|
||||
return '!' + this.key;
|
||||
return `!${this.key}`;
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
@@ -906,6 +906,10 @@ export class ContextKeyAndExpr implements IContextKeyExpression {
|
||||
}
|
||||
}
|
||||
|
||||
if (expr.length === 1) {
|
||||
return expr[0];
|
||||
}
|
||||
|
||||
return new ContextKeyAndExpr(expr);
|
||||
}
|
||||
|
||||
@@ -1302,6 +1306,8 @@ export interface IContextKeyService {
|
||||
|
||||
createScoped(target?: IContextKeyServiceTarget): IContextKeyService;
|
||||
getContext(target: IContextKeyServiceTarget | null): IContext;
|
||||
|
||||
updateParent(parentContextKeyService: IContextKeyService): void;
|
||||
}
|
||||
|
||||
export const SET_CONTEXT_COMMAND_ID = 'setContext';
|
||||
|
||||
@@ -158,7 +158,7 @@ suite('ContextKeyExpr', () => {
|
||||
}
|
||||
t('a', 'b', 'a && b');
|
||||
t('a || b', 'c', 'a && c || b && c');
|
||||
t('a || b', 'c || d', 'a && c || b && c || a && d || b && d');
|
||||
t('a || b', 'c || d', 'a && c || a && d || b && c || b && d');
|
||||
t('a || b', 'c && d', 'a && c && d || b && c && d');
|
||||
t('a || b', 'c && d || e', 'a && e || b && e || a && c && d || b && c && d');
|
||||
});
|
||||
@@ -177,4 +177,25 @@ suite('ContextKeyExpr', () => {
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 'x', 'b': { 'x': true } })), true);
|
||||
assert.equal(ainb.evaluate(createContext({ 'a': 'prototype', 'b': {} })), false);
|
||||
});
|
||||
|
||||
test('issue #106524: distributing AND should normalize', () => {
|
||||
const actual = ContextKeyExpr.and(
|
||||
ContextKeyExpr.or(
|
||||
ContextKeyExpr.has('a'),
|
||||
ContextKeyExpr.has('b')
|
||||
),
|
||||
ContextKeyExpr.has('c')
|
||||
);
|
||||
const expected = ContextKeyExpr.or(
|
||||
ContextKeyExpr.and(
|
||||
ContextKeyExpr.has('a'),
|
||||
ContextKeyExpr.has('c')
|
||||
),
|
||||
ContextKeyExpr.and(
|
||||
ContextKeyExpr.has('b'),
|
||||
ContextKeyExpr.has('c')
|
||||
)
|
||||
);
|
||||
assert.equal(actual!.equals(expected!), true);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user