Merge from vscode 2cfc8172e533e50c90e6a3152f6bfb1f82f963f3 (#6516)

* Merge from vscode 2cfc8172e533e50c90e6a3152f6bfb1f82f963f3

* fix tests
This commit is contained in:
Anthony Dresser
2019-07-28 15:15:24 -07:00
committed by GitHub
parent aacf1e7f1c
commit 1d56a17f32
292 changed files with 19784 additions and 1873 deletions

View File

@@ -6,7 +6,7 @@
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { MenuRegistry } from 'vs/platform/actions/common/actions';
import { CommandsRegistry, ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
import { ContextKeyAndExpr, ContextKeyExpr, IContext } from 'vs/platform/contextkey/common/contextkey';
import { ContextKeyExpr, IContext, ContextKeyOrExpr } from 'vs/platform/contextkey/common/contextkey';
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
import { keys } from 'vs/base/common/map';
@@ -171,7 +171,6 @@ export class KeybindingResolver {
/**
* Returns true if it is provable `a` implies `b`.
* **Precondition**: Assumes `a` and `b` are normalized!
*/
public static whenIsEntirelyIncluded(a: ContextKeyExpr | null | undefined, b: ContextKeyExpr | null | undefined): boolean {
if (!b) {
@@ -181,26 +180,35 @@ export class KeybindingResolver {
return false;
}
const aExpressions: ContextKeyExpr[] = ((a instanceof ContextKeyAndExpr) ? a.expr : [a]);
const bExpressions: ContextKeyExpr[] = ((b instanceof ContextKeyAndExpr) ? b.expr : [b]);
return this._implies(a, b);
}
let aIndex = 0;
for (const bExpr of bExpressions) {
let bExprMatched = false;
while (!bExprMatched && aIndex < aExpressions.length) {
let aExpr = aExpressions[aIndex];
if (aExpr.equals(bExpr)) {
bExprMatched = true;
}
aIndex++;
/**
* Returns true if it is provable `p` implies `q`.
*/
private static _implies(p: ContextKeyExpr, q: ContextKeyExpr): boolean {
const notP = p.negate();
const terminals = (node: ContextKeyExpr) => {
if (node instanceof ContextKeyOrExpr) {
return node.expr;
}
return [node];
};
if (!bExprMatched) {
return false;
let expr = terminals(notP).concat(terminals(q));
for (let i = 0; i < expr.length; i++) {
const a = expr[i];
const notA = a.negate();
for (let j = i + 1; j < expr.length; j++) {
const b = expr[j];
if (notA.equals(b)) {
return true;
}
}
}
return true;
return false;
}
public getDefaultBoundCommands(): Map<string, boolean> {

View File

@@ -121,6 +121,7 @@ suite('AbstractKeybindingService', () => {
let commandService: ICommandService = {
_serviceBrand: undefined,
onWillExecuteCommand: () => ({ dispose: () => { } }),
onDidExecuteCommand: () => ({ dispose: () => { } }),
executeCommand: (commandId: string, ...args: any[]): Promise<any> => {
executeCommandCalls.push({
commandId: commandId,

View File

@@ -5,7 +5,7 @@
import * as assert from 'assert';
import { KeyChord, KeyCode, KeyMod, SimpleKeybinding, createKeybinding, createSimpleKeybinding } from 'vs/base/common/keyCodes';
import { OS } from 'vs/base/common/platform';
import { ContextKeyAndExpr, ContextKeyExpr, IContext } from 'vs/platform/contextkey/common/contextkey';
import { ContextKeyExpr, IContext } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
@@ -20,13 +20,13 @@ function createContext(ctx: any) {
suite('KeybindingResolver', () => {
function kbItem(keybinding: number, command: string, commandArgs: any, when: ContextKeyExpr, isDefault: boolean): ResolvedKeybindingItem {
function kbItem(keybinding: number, command: string, commandArgs: any, when: ContextKeyExpr | undefined, isDefault: boolean): ResolvedKeybindingItem {
const resolvedKeybinding = (keybinding !== 0 ? new USLayoutResolvedKeybinding(createKeybinding(keybinding, OS)!, OS) : undefined);
return new ResolvedKeybindingItem(
resolvedKeybinding,
command,
commandArgs,
when ? when.normalize() : undefined,
when,
isDefault
);
}
@@ -191,64 +191,41 @@ suite('KeybindingResolver', () => {
});
test('contextIsEntirelyIncluded', () => {
let assertIsIncluded = (a: ContextKeyExpr[], b: ContextKeyExpr[]) => {
let tmpA = new ContextKeyAndExpr(a).normalize();
let tmpB = new ContextKeyAndExpr(b).normalize();
assert.equal(KeybindingResolver.whenIsEntirelyIncluded(tmpA, tmpB), true);
const assertIsIncluded = (a: string | null, b: string | null) => {
assert.equal(KeybindingResolver.whenIsEntirelyIncluded(ContextKeyExpr.deserialize(a), ContextKeyExpr.deserialize(b)), true);
};
let assertIsNotIncluded = (a: ContextKeyExpr[], b: ContextKeyExpr[]) => {
let tmpA = new ContextKeyAndExpr(a).normalize();
let tmpB = new ContextKeyAndExpr(b).normalize();
assert.equal(KeybindingResolver.whenIsEntirelyIncluded(tmpA, tmpB), false);
const assertIsNotIncluded = (a: string | null, b: string | null) => {
assert.equal(KeybindingResolver.whenIsEntirelyIncluded(ContextKeyExpr.deserialize(a), ContextKeyExpr.deserialize(b)), false);
};
let key1IsTrue = ContextKeyExpr.equals('key1', true);
let key1IsNotFalse = ContextKeyExpr.notEquals('key1', false);
let key1IsFalse = ContextKeyExpr.equals('key1', false);
let key1IsNotTrue = ContextKeyExpr.notEquals('key1', true);
let key2IsTrue = ContextKeyExpr.equals('key2', true);
let key2IsNotFalse = ContextKeyExpr.notEquals('key2', false);
let key3IsTrue = ContextKeyExpr.equals('key3', true);
let key4IsTrue = ContextKeyExpr.equals('key4', true);
assertIsIncluded([key1IsTrue], null!);
assertIsIncluded([key1IsTrue], []);
assertIsIncluded([key1IsTrue], [key1IsTrue]);
assertIsIncluded([key1IsTrue], [key1IsNotFalse]);
assertIsIncluded('key1', null);
assertIsIncluded('key1', '');
assertIsIncluded('key1', 'key1');
assertIsIncluded('!key1', '');
assertIsIncluded('!key1', '!key1');
assertIsIncluded('key2', '');
assertIsIncluded('key2', 'key2');
assertIsIncluded('key1 && key1 && key2 && key2', 'key2');
assertIsIncluded('key1 && key2', 'key2');
assertIsIncluded('key1 && key2', 'key1');
assertIsIncluded('key1 && key2', '');
assertIsIncluded('key1', 'key1 || key2');
assertIsIncluded('key1 || !key1', 'key2 || !key2');
assertIsIncluded('key1', 'key1 || key2 && key3');
assertIsIncluded([key1IsFalse], []);
assertIsIncluded([key1IsFalse], [key1IsFalse]);
assertIsIncluded([key1IsFalse], [key1IsNotTrue]);
assertIsIncluded([key2IsNotFalse], []);
assertIsIncluded([key2IsNotFalse], [key2IsNotFalse]);
assertIsIncluded([key2IsNotFalse], [key2IsTrue]);
assertIsIncluded([key1IsTrue, key2IsNotFalse], [key2IsTrue]);
assertIsIncluded([key1IsTrue, key2IsNotFalse], [key2IsNotFalse]);
assertIsIncluded([key1IsTrue, key2IsNotFalse], [key1IsTrue]);
assertIsIncluded([key1IsTrue, key2IsNotFalse], [key1IsNotFalse]);
assertIsIncluded([key1IsTrue, key2IsNotFalse], []);
assertIsNotIncluded([key1IsTrue], [key1IsFalse]);
assertIsNotIncluded([key1IsTrue], [key1IsNotTrue]);
assertIsNotIncluded([key1IsNotFalse], [key1IsFalse]);
assertIsNotIncluded([key1IsNotFalse], [key1IsNotTrue]);
assertIsNotIncluded([key1IsFalse], [key1IsTrue]);
assertIsNotIncluded([key1IsFalse], [key1IsNotFalse]);
assertIsNotIncluded([key1IsNotTrue], [key1IsTrue]);
assertIsNotIncluded([key1IsNotTrue], [key1IsNotFalse]);
assertIsNotIncluded([key1IsTrue, key2IsNotFalse], [key3IsTrue]);
assertIsNotIncluded([key1IsTrue, key2IsNotFalse], [key4IsTrue]);
assertIsNotIncluded([key1IsTrue], [key2IsTrue]);
assertIsNotIncluded([], [key2IsTrue]);
assertIsNotIncluded(null!, [key2IsTrue]);
assertIsNotIncluded('key1', '!key1');
assertIsNotIncluded('!key1', 'key1');
assertIsNotIncluded('key1 && key2', 'key3');
assertIsNotIncluded('key1 && key2', 'key4');
assertIsNotIncluded('key1', 'key2');
assertIsNotIncluded('key1 || key2', 'key2');
assertIsNotIncluded('', 'key2');
assertIsNotIncluded(null, 'key2');
});
test('resolve command', function () {
function _kbItem(keybinding: number, command: string, when: ContextKeyExpr): ResolvedKeybindingItem {
function _kbItem(keybinding: number, command: string, when: ContextKeyExpr | undefined): ResolvedKeybindingItem {
return kbItem(keybinding, command, null, when, true);
}