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:
Karl Burtram
2021-02-09 16:15:05 -08:00
committed by GitHub
parent 6f192f9af5
commit ce612a3d96
1929 changed files with 68012 additions and 34564 deletions

View File

@@ -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 {

View File

@@ -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';

View File

@@ -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);
});
});