mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-27 02:27:53 +01:00
merge master
This commit is contained in:
Vendored
+3
-1
@@ -48,5 +48,7 @@
|
||||
}, {
|
||||
"fileMatch": [ "cglicenses.json" ],
|
||||
"url": "./.vscode/cglicenses.schema.json"
|
||||
}]
|
||||
}
|
||||
],
|
||||
"git.ignoreLimitWarning": true
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ steps:
|
||||
- script: |
|
||||
set -e
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libxkbfile-dev pkg-config libsecret-1-dev libxss1 libgconf-2-4 dbus xvfb libgtk-3-0
|
||||
sudo apt-get install -y libxkbfile-dev pkg-config libsecret-1-dev libxss1 dbus xvfb libgtk-3-0
|
||||
sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb
|
||||
sudo chmod +x /etc/init.d/xvfb
|
||||
sudo update-rc.d xvfb defaults
|
||||
|
||||
@@ -100,7 +100,7 @@ gulp.task('optimize-vscode', ['clean-optimized-vscode', 'compile-build', 'compil
|
||||
|
||||
|
||||
gulp.task('optimize-index-js', ['optimize-vscode'], () => {
|
||||
const fullpath = path.join(process.cwd(), 'out-vscode/vs/code/electron-browser/workbench/workbench.js');
|
||||
const fullpath = path.join(process.cwd(), 'out-vscode/bootstrap-window.js');
|
||||
const contents = fs.readFileSync(fullpath).toString();
|
||||
const newContents = contents.replace('[/*BUILD->INSERT_NODE_MODULES*/]', JSON.stringify(nodeModules));
|
||||
fs.writeFileSync(fullpath, newContents);
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@
|
||||
"vscode-ripgrep": "^1.2.5",
|
||||
"vscode-sqlite3": "4.0.5",
|
||||
"vscode-textmate": "^4.0.1",
|
||||
"vscode-xterm": "3.10.0-beta7",
|
||||
"vscode-xterm": "3.10.0-beta9",
|
||||
"winreg": "^1.2.4",
|
||||
"yauzl": "^2.9.1",
|
||||
"yazl": "^2.4.3"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Package: @@NAME@@
|
||||
Version: @@VERSION@@
|
||||
Section: devel
|
||||
Depends: libnotify4, libnss3 (>= 2:3.26), gnupg, apt, libxkbfile1, libgconf-2-4, libsecret-1-0, libgtk-3-0 (>= 3.10.0), libxss1
|
||||
Depends: libnotify4, libnss3 (>= 2:3.26), gnupg, apt, libxkbfile1, libsecret-1-0, libgtk-3-0 (>= 3.10.0), libxss1
|
||||
Priority: optional
|
||||
Architecture: @@ARCHITECTURE@@
|
||||
Maintainer: Microsoft Corporation <vscode-linux@microsoft.com>
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
"libX11.so.6()(64bit)",
|
||||
"libXss.so.1()(64bit)",
|
||||
"libXtst.so.6()(64bit)",
|
||||
"libgconf-2.so.4()(64bit)",
|
||||
"libgmodule-2.0.so.0()(64bit)",
|
||||
"librt.so.1()(64bit)",
|
||||
"libglib-2.0.so.0()(64bit)",
|
||||
@@ -107,7 +106,6 @@
|
||||
"libgcc_s.so.1",
|
||||
"libgcc_s.so.1(GCC_4.0.0)",
|
||||
"libgcc_s.so.1(GLIBC_2.0)",
|
||||
"libgconf-2.so.4",
|
||||
"libgdk-x11-2.0.so.0",
|
||||
"libgdk_pixbuf-2.0.so.0",
|
||||
"libgio-2.0.so.0",
|
||||
|
||||
@@ -16,7 +16,6 @@ parts:
|
||||
stage-packages:
|
||||
- libasound2
|
||||
- libc++1
|
||||
- libgconf2-4
|
||||
- libnotify4
|
||||
- libnspr4
|
||||
- libnss3
|
||||
|
||||
@@ -319,7 +319,6 @@
|
||||
"./vs/nls.mock.ts",
|
||||
"./vs/platform/actions/browser/menuItemActionItem.ts",
|
||||
"./vs/platform/actions/common/actions.ts",
|
||||
"./vs/platform/actions/common/menu.ts",
|
||||
"./vs/platform/actions/common/menuService.ts",
|
||||
"./vs/platform/actions/test/common/menuService.test.ts",
|
||||
"./vs/platform/backup/common/backup.ts",
|
||||
@@ -607,7 +606,6 @@
|
||||
"./vs/workbench/parts/output/common/output.ts",
|
||||
"./vs/workbench/parts/output/common/outputLinkComputer.ts",
|
||||
"./vs/workbench/parts/output/common/outputLinkProvider.ts",
|
||||
"./vs/workbench/parts/performance/electron-browser/stats.ts",
|
||||
"./vs/workbench/parts/preferences/browser/settingsWidgets.ts",
|
||||
"./vs/workbench/parts/preferences/common/smartSnippetInserter.ts",
|
||||
"./vs/workbench/parts/preferences/test/common/smartSnippetInserter.test.ts",
|
||||
@@ -812,4 +810,4 @@
|
||||
"exclude": [
|
||||
"./typings/require-monaco.d.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,11 +38,11 @@ suite('QuickOpen', () => {
|
||||
model.addEntries([entry1, entry2, entry3]);
|
||||
|
||||
const ds = new DataSource(model);
|
||||
assert.equal(entry1.getId(), ds.getId(null, entry1));
|
||||
assert.equal(true, ds.hasChildren(null, model));
|
||||
assert.equal(false, ds.hasChildren(null, entry1));
|
||||
assert.equal(entry1.getId(), ds.getId(null!, entry1));
|
||||
assert.equal(true, ds.hasChildren(null!, model));
|
||||
assert.equal(false, ds.hasChildren(null!, entry1));
|
||||
|
||||
ds.getChildren(null, model).then((children: any[]) => {
|
||||
ds.getChildren(null!, model).then((children: any[]) => {
|
||||
assert.equal(3, children.length);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ export class FakeRenderer {
|
||||
|
||||
class TreeContext implements _.ITreeContext {
|
||||
|
||||
public tree: _.ITree = null;
|
||||
public tree: _.ITree = null!;
|
||||
public options: _.ITreeOptions = { autoExpandSingleChildren: true };
|
||||
public dataSource: _.IDataSource;
|
||||
public renderer: _.IRenderer;
|
||||
|
||||
@@ -17,7 +17,7 @@ function makeItem(id, height): any {
|
||||
}
|
||||
|
||||
function makeItems(...args: any[]) {
|
||||
var r = [];
|
||||
var r: any[] = [];
|
||||
|
||||
for (var i = 0; i < args.length; i += 2) {
|
||||
r.push(makeItem(args[i], args[i + 1]));
|
||||
@@ -59,7 +59,7 @@ suite('TreeView - HeightMap', () => {
|
||||
|
||||
teardown(() => {
|
||||
rangeMap.dispose();
|
||||
rangeMap = null;
|
||||
rangeMap = null!;
|
||||
});
|
||||
|
||||
test('simple', () => {
|
||||
|
||||
@@ -96,7 +96,7 @@ function attachTo(item: ProcessItem) {
|
||||
config.port = parseInt(matches[2]);
|
||||
}
|
||||
|
||||
ipcRenderer.send('vscode:workbenchCommand', { id: 'workbench.action.debug.start', from: 'processExplorer', args: [config] });
|
||||
ipcRenderer.send('vscode:workbenchCommand', { id: 'debug.startFromConfig', from: 'processExplorer', args: [config] });
|
||||
}
|
||||
|
||||
function getProcessIdWithHighestProperty(processList, propertyName: string) {
|
||||
@@ -299,4 +299,4 @@ export function startup(data: ProcessExplorerData): void {
|
||||
applyZoom(webFrame.getZoomLevel() - 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,7 +455,10 @@ export class CodeApplication extends Disposable {
|
||||
|
||||
const appInstantiationService = this.instantiationService.createChild(services);
|
||||
|
||||
return appInstantiationService.invokeFunction(accessor => this.initStorageService(accessor)).then(() => appInstantiationService);
|
||||
return appInstantiationService.invokeFunction(accessor => Promise.all([
|
||||
this.initStorageService(accessor),
|
||||
this.initBackupService(accessor)
|
||||
])).then(() => appInstantiationService);
|
||||
}
|
||||
|
||||
private initStorageService(accessor: ServicesAccessor): Promise<void> {
|
||||
@@ -495,6 +498,12 @@ export class CodeApplication extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
private initBackupService(accessor: ServicesAccessor): Promise<void> {
|
||||
const backupMainService = accessor.get(IBackupMainService) as BackupMainService;
|
||||
|
||||
return backupMainService.initialize();
|
||||
}
|
||||
|
||||
private openFirstWindow(accessor: ServicesAccessor): ICodeWindow[] {
|
||||
const appInstantiationService = accessor.get(IInstantiationService);
|
||||
|
||||
|
||||
@@ -82,16 +82,16 @@ suite('OutlineModel', function () {
|
||||
}
|
||||
|
||||
function fakeMarker(range: Range): IMarker {
|
||||
return { ...range, owner: 'ffff', message: 'test', severity: MarkerSeverity.Error, resource: null };
|
||||
return { ...range, owner: 'ffff', message: 'test', severity: MarkerSeverity.Error, resource: null! };
|
||||
}
|
||||
|
||||
test('OutlineElement - updateMarker', function () {
|
||||
|
||||
let e0 = new OutlineElement('foo1', null, fakeSymbolInformation(new Range(1, 1, 1, 10)));
|
||||
let e1 = new OutlineElement('foo2', null, fakeSymbolInformation(new Range(2, 1, 5, 1)));
|
||||
let e2 = new OutlineElement('foo3', null, fakeSymbolInformation(new Range(6, 1, 10, 10)));
|
||||
let e0 = new OutlineElement('foo1', null!, fakeSymbolInformation(new Range(1, 1, 1, 10)));
|
||||
let e1 = new OutlineElement('foo2', null!, fakeSymbolInformation(new Range(2, 1, 5, 1)));
|
||||
let e2 = new OutlineElement('foo3', null!, fakeSymbolInformation(new Range(6, 1, 10, 10)));
|
||||
|
||||
let group = new OutlineGroup('group', null, null, 1);
|
||||
let group = new OutlineGroup('group', null!, null!, 1);
|
||||
group.children[e0.id] = e0;
|
||||
group.children[e1.id] = e1;
|
||||
group.children[e2.id] = e2;
|
||||
@@ -113,11 +113,11 @@ suite('OutlineModel', function () {
|
||||
|
||||
test('OutlineElement - updateMarker, 2', function () {
|
||||
|
||||
let p = new OutlineElement('A', null, fakeSymbolInformation(new Range(1, 1, 11, 1)));
|
||||
let c1 = new OutlineElement('A/B', null, fakeSymbolInformation(new Range(2, 4, 5, 4)));
|
||||
let c2 = new OutlineElement('A/C', null, fakeSymbolInformation(new Range(6, 4, 9, 4)));
|
||||
let p = new OutlineElement('A', null!, fakeSymbolInformation(new Range(1, 1, 11, 1)));
|
||||
let c1 = new OutlineElement('A/B', null!, fakeSymbolInformation(new Range(2, 4, 5, 4)));
|
||||
let c2 = new OutlineElement('A/C', null!, fakeSymbolInformation(new Range(6, 4, 9, 4)));
|
||||
|
||||
let group = new OutlineGroup('group', null, null, 1);
|
||||
let group = new OutlineGroup('group', null!, null!, 1);
|
||||
group.children[p.id] = p;
|
||||
p.children[c1.id] = c1;
|
||||
p.children[c2.id] = c2;
|
||||
@@ -155,16 +155,16 @@ suite('OutlineModel', function () {
|
||||
|
||||
let model = new class extends OutlineModel {
|
||||
constructor() {
|
||||
super(null);
|
||||
super(null!);
|
||||
}
|
||||
readyForTesting() {
|
||||
this._groups = this.children as any;
|
||||
}
|
||||
};
|
||||
model.children['g1'] = new OutlineGroup('g1', model, null, 1);
|
||||
model.children['g1'] = new OutlineGroup('g1', model, null!, 1);
|
||||
model.children['g1'].children['c1'] = new OutlineElement('c1', model.children['g1'], fakeSymbolInformation(new Range(1, 1, 11, 1)));
|
||||
|
||||
model.children['g2'] = new OutlineGroup('g2', model, null, 1);
|
||||
model.children['g2'] = new OutlineGroup('g2', model, null!, 1);
|
||||
model.children['g2'].children['c2'] = new OutlineElement('c2', model.children['g2'], fakeSymbolInformation(new Range(1, 1, 7, 1)));
|
||||
model.children['g2'].children['c2'].children['c2.1'] = new OutlineElement('c2.1', model.children['g2'].children['c2'], fakeSymbolInformation(new Range(1, 3, 2, 19)));
|
||||
model.children['g2'].children['c2'].children['c2.2'] = new OutlineElement('c2.2', model.children['g2'].children['c2'], fakeSymbolInformation(new Range(4, 1, 6, 10)));
|
||||
|
||||
@@ -22,7 +22,7 @@ class TestSnippetController extends SnippetController2 {
|
||||
}
|
||||
|
||||
isInSnippetMode(): boolean {
|
||||
return SnippetController2.InSnippetMode.getValue(this._contextKeyService);
|
||||
return SnippetController2.InSnippetMode.getValue(this._contextKeyService)!;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,7 +42,7 @@ suite('SnippetController', () => {
|
||||
}
|
||||
|
||||
withTestCodeEditor(lines, {}, (editor, cursor) => {
|
||||
editor.getModel().updateOptions({
|
||||
editor.getModel()!.updateOptions({
|
||||
insertSpaces: false
|
||||
});
|
||||
let snippetController = editor.registerAndInstantiateContribution<TestSnippetController>(TestSnippetController);
|
||||
@@ -63,30 +63,30 @@ suite('SnippetController', () => {
|
||||
editor.setPosition({ lineNumber: 4, column: 2 });
|
||||
|
||||
snippetController.insert(template, 0, 0);
|
||||
assert.equal(editor.getModel().getLineContent(4), '\tfor (var index; index < array.length; index++) {');
|
||||
assert.equal(editor.getModel().getLineContent(5), '\t\tvar element = array[index];');
|
||||
assert.equal(editor.getModel().getLineContent(6), '\t\t');
|
||||
assert.equal(editor.getModel().getLineContent(7), '\t}');
|
||||
assert.equal(editor.getModel()!.getLineContent(4), '\tfor (var index; index < array.length; index++) {');
|
||||
assert.equal(editor.getModel()!.getLineContent(5), '\t\tvar element = array[index];');
|
||||
assert.equal(editor.getModel()!.getLineContent(6), '\t\t');
|
||||
assert.equal(editor.getModel()!.getLineContent(7), '\t}');
|
||||
|
||||
editor.trigger('test', 'type', { text: 'i' });
|
||||
assert.equal(editor.getModel().getLineContent(4), '\tfor (var i; i < array.length; i++) {');
|
||||
assert.equal(editor.getModel().getLineContent(5), '\t\tvar element = array[i];');
|
||||
assert.equal(editor.getModel().getLineContent(6), '\t\t');
|
||||
assert.equal(editor.getModel().getLineContent(7), '\t}');
|
||||
assert.equal(editor.getModel()!.getLineContent(4), '\tfor (var i; i < array.length; i++) {');
|
||||
assert.equal(editor.getModel()!.getLineContent(5), '\t\tvar element = array[i];');
|
||||
assert.equal(editor.getModel()!.getLineContent(6), '\t\t');
|
||||
assert.equal(editor.getModel()!.getLineContent(7), '\t}');
|
||||
|
||||
snippetController.next();
|
||||
editor.trigger('test', 'type', { text: 'arr' });
|
||||
assert.equal(editor.getModel().getLineContent(4), '\tfor (var i; i < arr.length; i++) {');
|
||||
assert.equal(editor.getModel().getLineContent(5), '\t\tvar element = arr[i];');
|
||||
assert.equal(editor.getModel().getLineContent(6), '\t\t');
|
||||
assert.equal(editor.getModel().getLineContent(7), '\t}');
|
||||
assert.equal(editor.getModel()!.getLineContent(4), '\tfor (var i; i < arr.length; i++) {');
|
||||
assert.equal(editor.getModel()!.getLineContent(5), '\t\tvar element = arr[i];');
|
||||
assert.equal(editor.getModel()!.getLineContent(6), '\t\t');
|
||||
assert.equal(editor.getModel()!.getLineContent(7), '\t}');
|
||||
|
||||
snippetController.prev();
|
||||
editor.trigger('test', 'type', { text: 'j' });
|
||||
assert.equal(editor.getModel().getLineContent(4), '\tfor (var j; j < arr.length; j++) {');
|
||||
assert.equal(editor.getModel().getLineContent(5), '\t\tvar element = arr[j];');
|
||||
assert.equal(editor.getModel().getLineContent(6), '\t\t');
|
||||
assert.equal(editor.getModel().getLineContent(7), '\t}');
|
||||
assert.equal(editor.getModel()!.getLineContent(4), '\tfor (var j; j < arr.length; j++) {');
|
||||
assert.equal(editor.getModel()!.getLineContent(5), '\t\tvar element = arr[j];');
|
||||
assert.equal(editor.getModel()!.getLineContent(6), '\t\t');
|
||||
assert.equal(editor.getModel()!.getLineContent(7), '\t}');
|
||||
|
||||
snippetController.next();
|
||||
snippetController.next();
|
||||
@@ -99,10 +99,10 @@ suite('SnippetController', () => {
|
||||
editor.setPosition({ lineNumber: 4, column: 2 });
|
||||
|
||||
snippetController.insert(template, 0, 0);
|
||||
assert.equal(editor.getModel().getLineContent(4), '\tfor (var index; index < array.length; index++) {');
|
||||
assert.equal(editor.getModel().getLineContent(5), '\t\tvar element = array[index];');
|
||||
assert.equal(editor.getModel().getLineContent(6), '\t\t');
|
||||
assert.equal(editor.getModel().getLineContent(7), '\t}');
|
||||
assert.equal(editor.getModel()!.getLineContent(4), '\tfor (var index; index < array.length; index++) {');
|
||||
assert.equal(editor.getModel()!.getLineContent(5), '\t\tvar element = array[index];');
|
||||
assert.equal(editor.getModel()!.getLineContent(6), '\t\t');
|
||||
assert.equal(editor.getModel()!.getLineContent(7), '\t}');
|
||||
|
||||
snippetController.cancel();
|
||||
assert.deepEqual(editor.getPosition(), new Position(4, 16));
|
||||
@@ -114,7 +114,7 @@ suite('SnippetController', () => {
|
||||
// editor.setPosition({ lineNumber: 4, column: 2 });
|
||||
// snippetController.insert(codeSnippet, 0, 0);
|
||||
|
||||
// editor.getModel().applyEdits([{
|
||||
// editor.getModel()!.applyEdits([{
|
||||
// forceMoveMarkers: false,
|
||||
// identifier: null,
|
||||
// isAutoWhitespaceEdit: false,
|
||||
@@ -131,7 +131,7 @@ suite('SnippetController', () => {
|
||||
// editor.setPosition({ lineNumber: 4, column: 2 });
|
||||
// snippetController.run(codeSnippet, 0, 0);
|
||||
|
||||
// editor.getModel().applyEdits([{
|
||||
// editor.getModel()!.applyEdits([{
|
||||
// forceMoveMarkers: false,
|
||||
// identifier: null,
|
||||
// isAutoWhitespaceEdit: false,
|
||||
@@ -148,7 +148,7 @@ suite('SnippetController', () => {
|
||||
// editor.setPosition({ lineNumber: 4, column: 2 });
|
||||
// snippetController.run(codeSnippet, 0, 0);
|
||||
|
||||
// editor.getModel().applyEdits([{
|
||||
// editor.getModel()!.applyEdits([{
|
||||
// forceMoveMarkers: false,
|
||||
// identifier: null,
|
||||
// isAutoWhitespaceEdit: false,
|
||||
@@ -165,7 +165,7 @@ suite('SnippetController', () => {
|
||||
// editor.setPosition({ lineNumber: 4, column: 2 });
|
||||
// snippetController.run(codeSnippet, 0, 0);
|
||||
|
||||
// editor.getModel().applyEdits([{
|
||||
// editor.getModel()!.applyEdits([{
|
||||
// forceMoveMarkers: false,
|
||||
// identifier: null,
|
||||
// isAutoWhitespaceEdit: false,
|
||||
@@ -182,7 +182,7 @@ suite('SnippetController', () => {
|
||||
editor.setPosition({ lineNumber: 4, column: 2 });
|
||||
snippetController.insert(codeSnippet, 0, 0);
|
||||
|
||||
editor.getModel().setValue('goodbye');
|
||||
editor.getModel()!.setValue('goodbye');
|
||||
|
||||
assert.equal(snippetController.isInSnippetMode(), false);
|
||||
});
|
||||
@@ -193,7 +193,7 @@ suite('SnippetController', () => {
|
||||
editor.setPosition({ lineNumber: 4, column: 2 });
|
||||
snippetController.insert(codeSnippet, 0, 0);
|
||||
|
||||
editor.getModel().undo();
|
||||
editor.getModel()!.undo();
|
||||
|
||||
assert.equal(snippetController.isInSnippetMode(), false);
|
||||
});
|
||||
@@ -242,8 +242,8 @@ suite('SnippetController', () => {
|
||||
codeSnippet = 'foo$0';
|
||||
snippetController.insert(codeSnippet, 0, 0);
|
||||
|
||||
assert.equal(editor.getSelections().length, 2);
|
||||
const [first, second] = editor.getSelections();
|
||||
assert.equal(editor.getSelections()!.length, 2);
|
||||
const [first, second] = editor.getSelections()!;
|
||||
assert.ok(first.equalsRange({ startLineNumber: 1, startColumn: 4, endLineNumber: 1, endColumn: 4 }), first.toString());
|
||||
assert.ok(second.equalsRange({ startLineNumber: 2, startColumn: 4, endLineNumber: 2, endColumn: 4 }), second.toString());
|
||||
});
|
||||
@@ -257,8 +257,8 @@ suite('SnippetController', () => {
|
||||
codeSnippet = 'foo$0bar';
|
||||
snippetController.insert(codeSnippet, 0, 0);
|
||||
|
||||
assert.equal(editor.getSelections().length, 2);
|
||||
const [first, second] = editor.getSelections();
|
||||
assert.equal(editor.getSelections()!.length, 2);
|
||||
const [first, second] = editor.getSelections()!;
|
||||
assert.ok(first.equalsRange({ startLineNumber: 1, startColumn: 4, endLineNumber: 1, endColumn: 4 }), first.toString());
|
||||
assert.ok(second.equalsRange({ startLineNumber: 2, startColumn: 4, endLineNumber: 2, endColumn: 4 }), second.toString());
|
||||
});
|
||||
@@ -272,8 +272,8 @@ suite('SnippetController', () => {
|
||||
codeSnippet = 'foo$0bar';
|
||||
snippetController.insert(codeSnippet, 0, 0);
|
||||
|
||||
assert.equal(editor.getSelections().length, 2);
|
||||
const [first, second] = editor.getSelections();
|
||||
assert.equal(editor.getSelections()!.length, 2);
|
||||
const [first, second] = editor.getSelections()!;
|
||||
assert.ok(first.equalsRange({ startLineNumber: 1, startColumn: 4, endLineNumber: 1, endColumn: 4 }), first.toString());
|
||||
assert.ok(second.equalsRange({ startLineNumber: 1, startColumn: 14, endLineNumber: 1, endColumn: 14 }), second.toString());
|
||||
});
|
||||
@@ -287,8 +287,8 @@ suite('SnippetController', () => {
|
||||
codeSnippet = 'foo\n$0\nbar';
|
||||
snippetController.insert(codeSnippet, 0, 0);
|
||||
|
||||
assert.equal(editor.getSelections().length, 2);
|
||||
const [first, second] = editor.getSelections();
|
||||
assert.equal(editor.getSelections()!.length, 2);
|
||||
const [first, second] = editor.getSelections()!;
|
||||
assert.ok(first.equalsRange({ startLineNumber: 2, startColumn: 1, endLineNumber: 2, endColumn: 1 }), first.toString());
|
||||
assert.ok(second.equalsRange({ startLineNumber: 4, startColumn: 1, endLineNumber: 4, endColumn: 1 }), second.toString());
|
||||
});
|
||||
@@ -302,8 +302,8 @@ suite('SnippetController', () => {
|
||||
codeSnippet = 'foo\n$0\nbar';
|
||||
snippetController.insert(codeSnippet, 0, 0);
|
||||
|
||||
assert.equal(editor.getSelections().length, 2);
|
||||
const [first, second] = editor.getSelections();
|
||||
assert.equal(editor.getSelections()!.length, 2);
|
||||
const [first, second] = editor.getSelections()!;
|
||||
assert.ok(first.equalsRange({ startLineNumber: 2, startColumn: 1, endLineNumber: 2, endColumn: 1 }), first.toString());
|
||||
assert.ok(second.equalsRange({ startLineNumber: 4, startColumn: 1, endLineNumber: 4, endColumn: 1 }), second.toString());
|
||||
});
|
||||
@@ -316,8 +316,8 @@ suite('SnippetController', () => {
|
||||
codeSnippet = 'xo$0r';
|
||||
snippetController.insert(codeSnippet, 1, 0);
|
||||
|
||||
assert.equal(editor.getSelections().length, 1);
|
||||
assert.ok(editor.getSelection().equalsRange({ startLineNumber: 2, startColumn: 8, endColumn: 8, endLineNumber: 2 }));
|
||||
assert.equal(editor.getSelections()!.length, 1);
|
||||
assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 2, startColumn: 8, endColumn: 8, endLineNumber: 2 }));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -329,9 +329,9 @@ suite('SnippetController', () => {
|
||||
codeSnippet = '{{% url_**$1** %}}';
|
||||
controller.insert(codeSnippet, 2, 0);
|
||||
|
||||
assert.equal(editor.getSelections().length, 1);
|
||||
assert.ok(editor.getSelection().equalsRange({ startLineNumber: 1, startColumn: 27, endLineNumber: 1, endColumn: 27 }));
|
||||
assert.equal(editor.getModel().getValue(), 'example example {{% url_**** %}}');
|
||||
assert.equal(editor.getSelections()!.length, 1);
|
||||
assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 1, startColumn: 27, endLineNumber: 1, endColumn: 27 }));
|
||||
assert.equal(editor.getModel()!.getValue(), 'example example {{% url_**** %}}');
|
||||
|
||||
}, ['example example sc']);
|
||||
|
||||
@@ -347,9 +347,9 @@ suite('SnippetController', () => {
|
||||
|
||||
controller.insert(codeSnippet, 2, 0);
|
||||
|
||||
assert.equal(editor.getSelections().length, 1);
|
||||
assert.ok(editor.getSelection().equalsRange({ startLineNumber: 2, startColumn: 2, endLineNumber: 2, endColumn: 2 }), editor.getSelection().toString());
|
||||
assert.equal(editor.getModel().getValue(), 'afterEach((done) => {\n\ttest\n});');
|
||||
assert.equal(editor.getSelections()!.length, 1);
|
||||
assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 2, startColumn: 2, endLineNumber: 2, endColumn: 2 }), editor.getSelection()!.toString());
|
||||
assert.equal(editor.getModel()!.getValue(), 'afterEach((done) => {\n\ttest\n});');
|
||||
|
||||
}, ['af']);
|
||||
|
||||
@@ -365,9 +365,9 @@ suite('SnippetController', () => {
|
||||
|
||||
controller.insert(codeSnippet, 2, 0);
|
||||
|
||||
assert.equal(editor.getSelections().length, 1);
|
||||
assert.ok(editor.getSelection().equalsRange({ startLineNumber: 2, startColumn: 1, endLineNumber: 2, endColumn: 1 }), editor.getSelection().toString());
|
||||
assert.equal(editor.getModel().getValue(), 'afterEach((done) => {\n\ttest\n});');
|
||||
assert.equal(editor.getSelections()!.length, 1);
|
||||
assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 2, startColumn: 1, endLineNumber: 2, endColumn: 1 }), editor.getSelection()!.toString());
|
||||
assert.equal(editor.getModel()!.getValue(), 'afterEach((done) => {\n\ttest\n});');
|
||||
|
||||
}, ['af']);
|
||||
|
||||
@@ -381,9 +381,9 @@ suite('SnippetController', () => {
|
||||
|
||||
controller.insert(codeSnippet, 8, 0);
|
||||
|
||||
assert.equal(editor.getModel().getValue(), 'after');
|
||||
assert.equal(editor.getSelections().length, 1);
|
||||
assert.ok(editor.getSelection().equalsRange({ startLineNumber: 1, startColumn: 4, endLineNumber: 1, endColumn: 4 }), editor.getSelection().toString());
|
||||
assert.equal(editor.getModel()!.getValue(), 'after');
|
||||
assert.equal(editor.getSelections()!.length, 1);
|
||||
assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 1, startColumn: 4, endLineNumber: 1, endColumn: 4 }), editor.getSelection()!.toString());
|
||||
|
||||
}, ['afterone']);
|
||||
});
|
||||
@@ -405,8 +405,8 @@ suite('SnippetController', () => {
|
||||
|
||||
controller.insert(codeSnippet, 2, 0);
|
||||
|
||||
assert.equal(editor.getSelections().length, 2);
|
||||
const [first, second] = editor.getSelections();
|
||||
assert.equal(editor.getSelections()!.length, 2);
|
||||
const [first, second] = editor.getSelections()!;
|
||||
|
||||
assert.ok(first.equalsRange({ startLineNumber: 5, startColumn: 3, endLineNumber: 5, endColumn: 3 }), first.toString());
|
||||
assert.ok(second.equalsRange({ startLineNumber: 2, startColumn: 2, endLineNumber: 2, endColumn: 2 }), second.toString());
|
||||
@@ -430,8 +430,8 @@ suite('SnippetController', () => {
|
||||
|
||||
controller.insert(codeSnippet, 2, 0);
|
||||
|
||||
assert.equal(editor.getSelections().length, 1);
|
||||
const [first] = editor.getSelections();
|
||||
assert.equal(editor.getSelections()!.length, 1);
|
||||
const [first] = editor.getSelections()!;
|
||||
|
||||
assert.ok(first.equalsRange({ startLineNumber: 2, startColumn: 3, endLineNumber: 2, endColumn: 3 }), first.toString());
|
||||
|
||||
@@ -450,7 +450,7 @@ suite('SnippetController', () => {
|
||||
|
||||
controller.insert(codeSnippet, 2, 0);
|
||||
|
||||
assert.ok(editor.getSelection().equalsRange({ startLineNumber: 1, startColumn: 10, endLineNumber: 1, endColumn: 10 }));
|
||||
assert.ok(editor.getSelection()!.equalsRange({ startLineNumber: 1, startColumn: 10, endLineNumber: 1, endColumn: 10 }));
|
||||
|
||||
}, ['af', '\taf']);
|
||||
});
|
||||
@@ -466,7 +466,7 @@ suite('SnippetController', () => {
|
||||
|
||||
codeSnippet = '_foo';
|
||||
controller.insert(codeSnippet, 1, 0);
|
||||
assert.equal(editor.getModel().getValue(), 'this._foo\nabc_foo');
|
||||
assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc_foo');
|
||||
|
||||
}, ['this._', 'abc']);
|
||||
|
||||
@@ -479,7 +479,7 @@ suite('SnippetController', () => {
|
||||
|
||||
codeSnippet = 'XX';
|
||||
controller.insert(codeSnippet, 1, 0);
|
||||
assert.equal(editor.getModel().getValue(), 'this.XX\nabcXX');
|
||||
assert.equal(editor.getModel()!.getValue(), 'this.XX\nabcXX');
|
||||
|
||||
}, ['this._', 'abc']);
|
||||
|
||||
@@ -493,7 +493,7 @@ suite('SnippetController', () => {
|
||||
|
||||
codeSnippet = '_foo';
|
||||
controller.insert(codeSnippet, 1, 0);
|
||||
assert.equal(editor.getModel().getValue(), 'this._foo\nabc_foo\ndef_foo');
|
||||
assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc_foo\ndef_foo');
|
||||
|
||||
}, ['this._', 'abc', 'def_']);
|
||||
|
||||
@@ -507,7 +507,7 @@ suite('SnippetController', () => {
|
||||
|
||||
codeSnippet = '._foo';
|
||||
controller.insert(codeSnippet, 2, 0);
|
||||
assert.equal(editor.getModel().getValue(), 'this._foo\nabc._foo\ndef._foo');
|
||||
assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc._foo\ndef._foo');
|
||||
|
||||
}, ['this._', 'abc', 'def._']);
|
||||
|
||||
@@ -521,7 +521,7 @@ suite('SnippetController', () => {
|
||||
|
||||
codeSnippet = '._foo';
|
||||
controller.insert(codeSnippet, 2, 0);
|
||||
assert.equal(editor.getModel().getValue(), 'this._foo\nabc._foo\ndef._foo');
|
||||
assert.equal(editor.getModel()!.getValue(), 'this._foo\nabc._foo\ndef._foo');
|
||||
|
||||
}, ['this._', 'abc', 'def._']);
|
||||
|
||||
@@ -535,7 +535,7 @@ suite('SnippetController', () => {
|
||||
|
||||
codeSnippet = '._foo';
|
||||
controller.insert(codeSnippet, 2, 0);
|
||||
assert.equal(editor.getModel().getValue(), 'this._._foo\na._foo\ndef._._foo');
|
||||
assert.equal(editor.getModel()!.getValue(), 'this._._foo\na._foo\ndef._._foo');
|
||||
|
||||
}, ['this._', 'abc', 'def._']);
|
||||
|
||||
@@ -551,7 +551,7 @@ suite('SnippetController', () => {
|
||||
|
||||
codeSnippet = 'document';
|
||||
controller.insert(codeSnippet, 3, 0);
|
||||
assert.equal(editor.getModel().getValue(), '{document}\n{document && true}');
|
||||
assert.equal(editor.getModel()!.getValue(), '{document}\n{document && true}');
|
||||
|
||||
}, ['{foo}', '{foo && true}']);
|
||||
});
|
||||
@@ -566,7 +566,7 @@ suite('SnippetController', () => {
|
||||
|
||||
codeSnippet = 'for (var ${1:i}=0; ${1:i}<len; ${1:i}++) { $0 }';
|
||||
controller.insert(codeSnippet, 0, 0);
|
||||
assert.equal(editor.getModel().getValue(), 'for (var i=0; i<len; i++) { }for (var i=0; i<len; i++) { }');
|
||||
assert.equal(editor.getModel()!.getValue(), 'for (var i=0; i<len; i++) { }for (var i=0; i<len; i++) { }');
|
||||
|
||||
}, ['for (var i=0; i<len; i++) { }']);
|
||||
|
||||
@@ -579,7 +579,7 @@ suite('SnippetController', () => {
|
||||
|
||||
codeSnippet = 'for (let ${1:i}=0; ${1:i}<len; ${1:i}++) { $0 }';
|
||||
controller.insert(codeSnippet, 0, 0);
|
||||
assert.equal(editor.getModel().getValue(), 'for (let i=0; i<len; i++) { }for (var i=0; i<len; i++) { }');
|
||||
assert.equal(editor.getModel()!.getValue(), 'for (let i=0; i<len; i++) { }for (var i=0; i<len; i++) { }');
|
||||
|
||||
}, ['for (var i=0; i<len; i++) { }']);
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ import { Handler } from 'vs/editor/common/editorCommon';
|
||||
suite('SnippetController2', function () {
|
||||
|
||||
function assertSelections(editor: ICodeEditor, ...s: Selection[]) {
|
||||
for (const selection of editor.getSelections()) {
|
||||
const actual = s.shift();
|
||||
for (const selection of editor.getSelections()!) {
|
||||
const actual = s.shift()!;
|
||||
assert.ok(selection.equalsSelection(actual), `actual=${selection.toString()} <> expected=${actual.toString()}`);
|
||||
}
|
||||
assert.equal(s.length, 0);
|
||||
|
||||
@@ -74,7 +74,7 @@ suite('SuggestMemories', function () {
|
||||
assert.equal(mem.select(buffer, pos, []), 0);
|
||||
|
||||
mem.memorize(buffer, pos, items[0]);
|
||||
mem.memorize(buffer, pos, null);
|
||||
mem.memorize(buffer, pos, null!);
|
||||
});
|
||||
|
||||
test('LRUMemory', () => {
|
||||
|
||||
@@ -71,7 +71,7 @@ suite('SuggestModel - Context', function () {
|
||||
|
||||
this._register(TokenizationRegistry.register(this.getLanguageIdentifier().language, {
|
||||
getInitialState: (): IState => NULL_STATE,
|
||||
tokenize: undefined,
|
||||
tokenize: undefined!,
|
||||
tokenize2: (line: string, state: IState): TokenizationResult2 => {
|
||||
const tokensArr: number[] = [];
|
||||
let prevLanguageId: LanguageIdentifier | undefined = undefined;
|
||||
@@ -418,7 +418,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
|
||||
|
||||
return withOracle((model, editor) => {
|
||||
|
||||
editor.getModel().setValue('fo');
|
||||
editor.getModel()!.setValue('fo');
|
||||
editor.setPosition({ lineNumber: 1, column: 3 });
|
||||
|
||||
return assertEvent(model.onDidSuggest, () => {
|
||||
@@ -443,7 +443,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
|
||||
|
||||
return withOracle((model, editor) => {
|
||||
|
||||
editor.getModel().setValue('fo');
|
||||
editor.getModel()!.setValue('fo');
|
||||
editor.setPosition({ lineNumber: 1, column: 3 });
|
||||
|
||||
return assertEvent(model.onDidSuggest, () => {
|
||||
@@ -480,7 +480,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
|
||||
|
||||
return withOracle((model, editor) => {
|
||||
|
||||
editor.getModel().setValue('foo');
|
||||
editor.getModel()!.setValue('foo');
|
||||
editor.setPosition({ lineNumber: 1, column: 4 });
|
||||
|
||||
return assertEvent(model.onDidSuggest, () => {
|
||||
@@ -517,7 +517,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
|
||||
|
||||
return withOracle((model, editor) => {
|
||||
|
||||
editor.getModel().setValue('foo');
|
||||
editor.getModel()!.setValue('foo');
|
||||
editor.setPosition({ lineNumber: 1, column: 4 });
|
||||
|
||||
return assertEvent(model.onDidSuggest, () => {
|
||||
@@ -548,7 +548,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
|
||||
triggerCharacters: ['.'],
|
||||
provideCompletionItems(doc, pos, context): CompletionList {
|
||||
assert.equal(context.triggerKind, CompletionTriggerKind.TriggerCharacter);
|
||||
triggerCharacter = context.triggerCharacter;
|
||||
triggerCharacter = context.triggerCharacter!;
|
||||
return {
|
||||
incomplete: false,
|
||||
suggestions: [
|
||||
|
||||
@@ -22,7 +22,7 @@ suite('TokenizationSupport2Adapter', () => {
|
||||
class MockTokenTheme extends TokenTheme {
|
||||
private counter = 0;
|
||||
constructor() {
|
||||
super(null, null);
|
||||
super(null!, null!);
|
||||
}
|
||||
public match(languageId: LanguageId, token: string): number {
|
||||
return (
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { MenuId, MenuRegistry, MenuItemAction, IMenu, IMenuItem, IMenuActionOptions, ISubmenuItem, SubmenuItemAction, isIMenuItem } from 'vs/platform/actions/common/actions';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
|
||||
type MenuItemGroup = [string, Array<IMenuItem | ISubmenuItem>];
|
||||
|
||||
export class Menu implements IMenu {
|
||||
|
||||
private readonly _onDidChange = new Emitter<IMenu>();
|
||||
private readonly _disposables: IDisposable[] = [];
|
||||
|
||||
private _menuGroups: MenuItemGroup[];
|
||||
private _contextKeys: Set<string>;
|
||||
|
||||
constructor(
|
||||
private readonly _id: MenuId,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@IContextKeyService private readonly _contextKeyService: IContextKeyService
|
||||
) {
|
||||
this._build();
|
||||
|
||||
// rebuild this menu whenever the menu registry reports an
|
||||
// event for this MenuId
|
||||
Event.debounce(
|
||||
Event.filter(MenuRegistry.onDidChangeMenu, menuId => menuId === this._id),
|
||||
() => { },
|
||||
50
|
||||
)(this._build, this, this._disposables);
|
||||
|
||||
// when context keys change we need to check if the menu also
|
||||
// has changed
|
||||
Event.debounce(
|
||||
this._contextKeyService.onDidChangeContext,
|
||||
(last, event) => last || event.affectsSome(this._contextKeys),
|
||||
50
|
||||
)(e => e && this._onDidChange.fire(), this, this._disposables);
|
||||
}
|
||||
|
||||
private _build(): void {
|
||||
|
||||
// reset
|
||||
this._menuGroups = [];
|
||||
this._contextKeys = new Set();
|
||||
|
||||
const menuItems = MenuRegistry.getMenuItems(this._id);
|
||||
|
||||
let group: MenuItemGroup | undefined;
|
||||
menuItems.sort(Menu._compareMenuItems);
|
||||
|
||||
for (let item of menuItems) {
|
||||
// group by groupId
|
||||
const groupName = item.group || '';
|
||||
if (!group || group[0] !== groupName) {
|
||||
group = [groupName, []];
|
||||
this._menuGroups.push(group);
|
||||
}
|
||||
group![1].push(item);
|
||||
|
||||
// keep keys for eventing
|
||||
Menu._fillInKbExprKeys(item.when, this._contextKeys);
|
||||
|
||||
// keep precondition keys for event if applicable
|
||||
if (isIMenuItem(item) && item.command.precondition) {
|
||||
Menu._fillInKbExprKeys(item.command.precondition, this._contextKeys);
|
||||
}
|
||||
|
||||
// keep toggled keys for event if applicable
|
||||
if (isIMenuItem(item) && item.command.toggled) {
|
||||
Menu._fillInKbExprKeys(item.command.toggled, this._contextKeys);
|
||||
}
|
||||
}
|
||||
this._onDidChange.fire(this);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
dispose(this._disposables);
|
||||
this._onDidChange.dispose();
|
||||
}
|
||||
|
||||
get onDidChange(): Event<IMenu> {
|
||||
return this._onDidChange.event;
|
||||
}
|
||||
|
||||
getActions(options: IMenuActionOptions): [string, Array<MenuItemAction | SubmenuItemAction>][] {
|
||||
const result: [string, Array<MenuItemAction | SubmenuItemAction>][] = [];
|
||||
for (let group of this._menuGroups) {
|
||||
const [id, items] = group;
|
||||
const activeActions: Array<MenuItemAction | SubmenuItemAction> = [];
|
||||
for (const item of items) {
|
||||
if (this._contextKeyService.contextMatchesRules(item.when || null)) {
|
||||
const action = isIMenuItem(item) ? new MenuItemAction(item.command, item.alt, options, this._contextKeyService, this._commandService) : new SubmenuItemAction(item);
|
||||
activeActions.push(action);
|
||||
}
|
||||
}
|
||||
if (activeActions.length > 0) {
|
||||
result.push([id, activeActions]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static _fillInKbExprKeys(exp: ContextKeyExpr | undefined, set: Set<string>): void {
|
||||
if (exp) {
|
||||
for (let key of exp.keys()) {
|
||||
set.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static _compareMenuItems(a: IMenuItem, b: IMenuItem): number {
|
||||
|
||||
let aGroup = a.group;
|
||||
let bGroup = b.group;
|
||||
|
||||
if (aGroup !== bGroup) {
|
||||
|
||||
// Falsy groups come last
|
||||
if (!aGroup) {
|
||||
return 1;
|
||||
} else if (!bGroup) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 'navigation' group comes first
|
||||
if (aGroup === 'navigation') {
|
||||
return -1;
|
||||
} else if (bGroup === 'navigation') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// lexical sort for groups
|
||||
let value = aGroup.localeCompare(bGroup);
|
||||
if (value !== 0) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// sort on priority - default is 0
|
||||
let aPrio = a.order || 0;
|
||||
let bPrio = b.order || 0;
|
||||
if (aPrio < bPrio) {
|
||||
return -1;
|
||||
} else if (aPrio > bPrio) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// sort on titles
|
||||
const aTitle = typeof a.command.title === 'string' ? a.command.title : a.command.title.value;
|
||||
const bTitle = typeof b.command.title === 'string' ? b.command.title : b.command.title.value;
|
||||
return aTitle.localeCompare(bTitle);
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,11 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { MenuId, IMenu, IMenuService } from 'vs/platform/actions/common/actions';
|
||||
import { Menu } from 'vs/platform/actions/common/menu';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IMenu, IMenuActionOptions, IMenuItem, IMenuService, isIMenuItem, ISubmenuItem, MenuId, MenuItemAction, MenuRegistry, SubmenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
export class MenuService implements IMenuService {
|
||||
|
||||
@@ -22,3 +23,153 @@ export class MenuService implements IMenuService {
|
||||
return new Menu(id, this._commandService, contextKeyService);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
type MenuItemGroup = [string, Array<IMenuItem | ISubmenuItem>];
|
||||
|
||||
class Menu implements IMenu {
|
||||
|
||||
private readonly _onDidChange = new Emitter<IMenu>();
|
||||
private readonly _disposables: IDisposable[] = [];
|
||||
|
||||
private _menuGroups: MenuItemGroup[];
|
||||
private _contextKeys: Set<string>;
|
||||
|
||||
constructor(
|
||||
private readonly _id: MenuId,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@IContextKeyService private readonly _contextKeyService: IContextKeyService
|
||||
) {
|
||||
this._build();
|
||||
|
||||
// rebuild this menu whenever the menu registry reports an
|
||||
// event for this MenuId
|
||||
Event.debounce(
|
||||
Event.filter(MenuRegistry.onDidChangeMenu, menuId => menuId === this._id),
|
||||
() => { },
|
||||
50
|
||||
)(this._build, this, this._disposables);
|
||||
|
||||
// when context keys change we need to check if the menu also
|
||||
// has changed
|
||||
Event.debounce(
|
||||
this._contextKeyService.onDidChangeContext,
|
||||
(last, event) => last || event.affectsSome(this._contextKeys),
|
||||
50
|
||||
)(e => e && this._onDidChange.fire(), this, this._disposables);
|
||||
}
|
||||
|
||||
private _build(): void {
|
||||
|
||||
// reset
|
||||
this._menuGroups = [];
|
||||
this._contextKeys = new Set();
|
||||
|
||||
const menuItems = MenuRegistry.getMenuItems(this._id);
|
||||
|
||||
let group: MenuItemGroup | undefined;
|
||||
menuItems.sort(Menu._compareMenuItems);
|
||||
|
||||
for (let item of menuItems) {
|
||||
// group by groupId
|
||||
const groupName = item.group || '';
|
||||
if (!group || group[0] !== groupName) {
|
||||
group = [groupName, []];
|
||||
this._menuGroups.push(group);
|
||||
}
|
||||
group![1].push(item);
|
||||
|
||||
// keep keys for eventing
|
||||
Menu._fillInKbExprKeys(item.when, this._contextKeys);
|
||||
|
||||
// keep precondition keys for event if applicable
|
||||
if (isIMenuItem(item) && item.command.precondition) {
|
||||
Menu._fillInKbExprKeys(item.command.precondition, this._contextKeys);
|
||||
}
|
||||
|
||||
// keep toggled keys for event if applicable
|
||||
if (isIMenuItem(item) && item.command.toggled) {
|
||||
Menu._fillInKbExprKeys(item.command.toggled, this._contextKeys);
|
||||
}
|
||||
}
|
||||
this._onDidChange.fire(this);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
dispose(this._disposables);
|
||||
this._onDidChange.dispose();
|
||||
}
|
||||
|
||||
get onDidChange(): Event<IMenu> {
|
||||
return this._onDidChange.event;
|
||||
}
|
||||
|
||||
getActions(options: IMenuActionOptions): [string, Array<MenuItemAction | SubmenuItemAction>][] {
|
||||
const result: [string, Array<MenuItemAction | SubmenuItemAction>][] = [];
|
||||
for (let group of this._menuGroups) {
|
||||
const [id, items] = group;
|
||||
const activeActions: Array<MenuItemAction | SubmenuItemAction> = [];
|
||||
for (const item of items) {
|
||||
if (this._contextKeyService.contextMatchesRules(item.when || null)) {
|
||||
const action = isIMenuItem(item) ? new MenuItemAction(item.command, item.alt, options, this._contextKeyService, this._commandService) : new SubmenuItemAction(item);
|
||||
activeActions.push(action);
|
||||
}
|
||||
}
|
||||
if (activeActions.length > 0) {
|
||||
result.push([id, activeActions]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static _fillInKbExprKeys(exp: ContextKeyExpr | undefined, set: Set<string>): void {
|
||||
if (exp) {
|
||||
for (let key of exp.keys()) {
|
||||
set.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static _compareMenuItems(a: IMenuItem, b: IMenuItem): number {
|
||||
|
||||
let aGroup = a.group;
|
||||
let bGroup = b.group;
|
||||
|
||||
if (aGroup !== bGroup) {
|
||||
|
||||
// Falsy groups come last
|
||||
if (!aGroup) {
|
||||
return 1;
|
||||
} else if (!bGroup) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 'navigation' group comes first
|
||||
if (aGroup === 'navigation') {
|
||||
return -1;
|
||||
} else if (bGroup === 'navigation') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// lexical sort for groups
|
||||
let value = aGroup.localeCompare(bGroup);
|
||||
if (value !== 0) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// sort on priority - default is 0
|
||||
let aPrio = a.order || 0;
|
||||
let bPrio = b.order || 0;
|
||||
if (aPrio < bPrio) {
|
||||
return -1;
|
||||
} else if (aPrio > bPrio) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// sort on titles
|
||||
const aTitle = typeof a.command.title === 'string' ? a.command.title : a.command.title.value;
|
||||
const bTitle = typeof b.command.title === 'string' ? b.command.title : b.command.title.value;
|
||||
return aTitle.localeCompare(bTitle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,19 +7,19 @@ import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as crypto from 'crypto';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { writeFileAndFlushSync, readdirSync, delSync } from 'vs/base/node/extfs';
|
||||
import { writeFileAndFlushSync } from 'vs/base/node/extfs';
|
||||
import * as arrays from 'vs/base/common/arrays';
|
||||
import { IBackupMainService, IBackupWorkspacesFormat, IEmptyWindowBackupInfo } from 'vs/platform/backup/common/backup';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IFilesConfiguration, HotExitConfiguration } from 'vs/platform/files/common/files';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
|
||||
import { IWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { isEqual as areResourcesEquals, getComparisonKey, hasToIgnoreCase } from 'vs/base/common/resources';
|
||||
import { isEqual } from 'vs/base/common/paths';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { writeFile, readFile, readdir, exists, del, rename } from 'vs/base/node/pfs';
|
||||
|
||||
export class BackupMainService implements IBackupMainService {
|
||||
|
||||
@@ -39,8 +39,55 @@ export class BackupMainService implements IBackupMainService {
|
||||
) {
|
||||
this.backupHome = environmentService.backupHome;
|
||||
this.workspacesJsonPath = environmentService.backupWorkspacesPath;
|
||||
}
|
||||
|
||||
this.loadSync();
|
||||
async initialize(): Promise<void> {
|
||||
let backups: IBackupWorkspacesFormat;
|
||||
try {
|
||||
backups = JSON.parse(await readFile(this.workspacesJsonPath, 'utf8')); // invalid JSON or permission issue can happen here
|
||||
} catch (error) {
|
||||
backups = Object.create(null);
|
||||
}
|
||||
|
||||
// read empty workspaces backups first
|
||||
if (backups.emptyWorkspaceInfos) {
|
||||
this.emptyWorkspaces = await this.validateEmptyWorkspaces(backups.emptyWorkspaceInfos);
|
||||
} else if (Array.isArray(backups.emptyWorkspaces)) {
|
||||
// read legacy entries
|
||||
this.emptyWorkspaces = await this.validateEmptyWorkspaces(backups.emptyWorkspaces.map(backupFolder => ({ backupFolder })));
|
||||
} else {
|
||||
this.emptyWorkspaces = [];
|
||||
}
|
||||
|
||||
// read workspace backups
|
||||
this.rootWorkspaces = await this.validateWorkspaces(backups.rootWorkspaces);
|
||||
|
||||
// read folder backups
|
||||
let workspaceFolders: URI[] = [];
|
||||
try {
|
||||
if (Array.isArray(backups.folderURIWorkspaces)) {
|
||||
workspaceFolders = backups.folderURIWorkspaces.map(f => URI.parse(f));
|
||||
} else if (Array.isArray(backups.folderWorkspaces)) {
|
||||
// migrate legacy folder paths
|
||||
workspaceFolders = [];
|
||||
for (const folderPath of backups.folderWorkspaces) {
|
||||
const oldFolderHash = this.getLegacyFolderHash(folderPath);
|
||||
const folderUri = URI.file(folderPath);
|
||||
const newFolderHash = this.getFolderHash(folderUri);
|
||||
if (newFolderHash !== oldFolderHash) {
|
||||
await this.moveBackupFolder(this.getBackupPath(newFolderHash), this.getBackupPath(oldFolderHash));
|
||||
}
|
||||
workspaceFolders.push(folderUri);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore URI parsing exceptions
|
||||
}
|
||||
|
||||
this.folderWorkspaces = await this.validateFolders(workspaceFolders);
|
||||
|
||||
// save again in case some workspaces or folders have been removed
|
||||
await this.save();
|
||||
}
|
||||
|
||||
getWorkspaceBackups(): IWorkspaceIdentifier[] {
|
||||
@@ -100,7 +147,7 @@ export class BackupMainService implements IBackupMainService {
|
||||
|
||||
// Target exists: make sure to convert existing backups to empty window backups
|
||||
if (fs.existsSync(backupPath)) {
|
||||
this.convertToEmptyWindowBackup(backupPath);
|
||||
this.convertToEmptyWindowBackupSync(backupPath);
|
||||
}
|
||||
|
||||
// When we have data to migrate from, move it over to the target location
|
||||
@@ -113,6 +160,23 @@ export class BackupMainService implements IBackupMainService {
|
||||
}
|
||||
}
|
||||
|
||||
private async moveBackupFolder(backupPath: string, moveFromPath: string): Promise<void> {
|
||||
|
||||
// Target exists: make sure to convert existing backups to empty window backups
|
||||
if (await exists(backupPath)) {
|
||||
await this.convertToEmptyWindowBackup(backupPath);
|
||||
}
|
||||
|
||||
// When we have data to migrate from, move it over to the target location
|
||||
if (await exists(moveFromPath)) {
|
||||
try {
|
||||
await rename(moveFromPath, backupPath);
|
||||
} catch (ex) {
|
||||
this.logService.error(`Backup: Could not move backup folder to new location: ${ex.toString()}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unregisterWorkspaceBackupSync(workspace: IWorkspaceIdentifier): void {
|
||||
let index = arrays.firstIndex(this.rootWorkspaces, w => w.id === workspace.id);
|
||||
if (index !== -1) {
|
||||
@@ -163,60 +227,11 @@ export class BackupMainService implements IBackupMainService {
|
||||
}
|
||||
}
|
||||
|
||||
protected loadSync(): void {
|
||||
let backups: IBackupWorkspacesFormat;
|
||||
try {
|
||||
backups = JSON.parse(fs.readFileSync(this.workspacesJsonPath, 'utf8').toString()); // invalid JSON or permission issue can happen here
|
||||
} catch (error) {
|
||||
backups = Object.create(null);
|
||||
}
|
||||
|
||||
// read empty workspaces backups first
|
||||
if (backups.emptyWorkspaceInfos) {
|
||||
this.emptyWorkspaces = this.validateEmptyWorkspaces(backups.emptyWorkspaceInfos);
|
||||
} else if (Array.isArray(backups.emptyWorkspaces)) {
|
||||
// read legacy entries
|
||||
this.emptyWorkspaces = this.validateEmptyWorkspaces(backups.emptyWorkspaces.map(backupFolder => ({ backupFolder })));
|
||||
} else {
|
||||
this.emptyWorkspaces = [];
|
||||
}
|
||||
|
||||
// read workspace backups
|
||||
this.rootWorkspaces = this.validateWorkspaces(backups.rootWorkspaces);
|
||||
|
||||
// read folder backups
|
||||
let workspaceFolders: URI[] = [];
|
||||
try {
|
||||
if (Array.isArray(backups.folderURIWorkspaces)) {
|
||||
workspaceFolders = backups.folderURIWorkspaces.map(f => URI.parse(f));
|
||||
} else if (Array.isArray(backups.folderWorkspaces)) {
|
||||
// migrate legacy folder paths
|
||||
workspaceFolders = [];
|
||||
for (const folderPath of backups.folderWorkspaces) {
|
||||
const oldFolderHash = this.getLegacyFolderHash(folderPath);
|
||||
const folderUri = URI.file(folderPath);
|
||||
const newFolderHash = this.getFolderHash(folderUri);
|
||||
if (newFolderHash !== oldFolderHash) {
|
||||
this.moveBackupFolderSync(this.getBackupPath(newFolderHash), this.getBackupPath(oldFolderHash));
|
||||
}
|
||||
workspaceFolders.push(folderUri);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore URI parsing exceptions
|
||||
}
|
||||
|
||||
this.folderWorkspaces = this.validateFolders(workspaceFolders);
|
||||
|
||||
// save again in case some workspaces or folders have been removed
|
||||
this.saveSync();
|
||||
}
|
||||
|
||||
private getBackupPath(oldFolderHash: string): string {
|
||||
return path.join(this.backupHome, oldFolderHash);
|
||||
}
|
||||
|
||||
private validateWorkspaces(rootWorkspaces: IWorkspaceIdentifier[]): IWorkspaceIdentifier[] {
|
||||
private async validateWorkspaces(rootWorkspaces: IWorkspaceIdentifier[]): Promise<IWorkspaceIdentifier[]> {
|
||||
if (!Array.isArray(rootWorkspaces)) {
|
||||
return [];
|
||||
}
|
||||
@@ -234,18 +249,18 @@ export class BackupMainService implements IBackupMainService {
|
||||
seenIds[workspace.id] = true;
|
||||
|
||||
const backupPath = this.getBackupPath(workspace.id);
|
||||
const hasBackups = this.hasBackupsSync(backupPath);
|
||||
const hasBackups = await this.hasBackups(backupPath);
|
||||
|
||||
// If the workspace has no backups, ignore it
|
||||
if (hasBackups) {
|
||||
if (fs.existsSync(workspace.configPath)) {
|
||||
if (await exists(workspace.configPath)) {
|
||||
result.push(workspace);
|
||||
} else {
|
||||
// If the workspace has backups, but the target workspace is missing, convert backups to empty ones
|
||||
this.convertToEmptyWindowBackup(backupPath);
|
||||
await this.convertToEmptyWindowBackup(backupPath);
|
||||
}
|
||||
} else {
|
||||
this.deleteStaleBackup(backupPath);
|
||||
await this.deleteStaleBackup(backupPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,7 +268,7 @@ export class BackupMainService implements IBackupMainService {
|
||||
return result;
|
||||
}
|
||||
|
||||
private validateFolders(folderWorkspaces: URI[]): URI[] {
|
||||
private async validateFolders(folderWorkspaces: URI[]): Promise<URI[]> {
|
||||
if (!Array.isArray(folderWorkspaces)) {
|
||||
return [];
|
||||
}
|
||||
@@ -266,18 +281,18 @@ export class BackupMainService implements IBackupMainService {
|
||||
seen[key] = true;
|
||||
|
||||
const backupPath = this.getBackupPath(this.getFolderHash(folderURI));
|
||||
const hasBackups = this.hasBackupsSync(backupPath);
|
||||
const hasBackups = await this.hasBackups(backupPath);
|
||||
|
||||
// If the folder has no backups, ignore it
|
||||
if (hasBackups) {
|
||||
if (folderURI.scheme !== Schemas.file || fs.existsSync(folderURI.fsPath)) {
|
||||
if (folderURI.scheme !== Schemas.file || await exists(folderURI.fsPath)) {
|
||||
result.push(folderURI);
|
||||
} else {
|
||||
// If the folder has backups, but the target workspace is missing, convert backups to empty ones
|
||||
this.convertToEmptyWindowBackup(backupPath);
|
||||
await this.convertToEmptyWindowBackup(backupPath);
|
||||
}
|
||||
} else {
|
||||
this.deleteStaleBackup(backupPath);
|
||||
await this.deleteStaleBackup(backupPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -285,7 +300,7 @@ export class BackupMainService implements IBackupMainService {
|
||||
return result;
|
||||
}
|
||||
|
||||
private validateEmptyWorkspaces(emptyWorkspaces: IEmptyWindowBackupInfo[]): IEmptyWindowBackupInfo[] {
|
||||
private async validateEmptyWorkspaces(emptyWorkspaces: IEmptyWindowBackupInfo[]): Promise<IEmptyWindowBackupInfo[]> {
|
||||
if (!Array.isArray(emptyWorkspaces)) {
|
||||
return [];
|
||||
}
|
||||
@@ -304,10 +319,10 @@ export class BackupMainService implements IBackupMainService {
|
||||
seen[backupFolder] = true;
|
||||
|
||||
const backupPath = this.getBackupPath(backupFolder);
|
||||
if (this.hasBackupsSync(backupPath)) {
|
||||
if (await this.hasBackups(backupPath)) {
|
||||
result.push(backupInfo);
|
||||
} else {
|
||||
this.deleteStaleBackup(backupPath);
|
||||
await this.deleteStaleBackup(backupPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -315,17 +330,38 @@ export class BackupMainService implements IBackupMainService {
|
||||
return result;
|
||||
}
|
||||
|
||||
private deleteStaleBackup(backupPath: string) {
|
||||
private async deleteStaleBackup(backupPath: string): Promise<void> {
|
||||
try {
|
||||
if (fs.existsSync(backupPath)) {
|
||||
delSync(backupPath);
|
||||
if (await exists(backupPath)) {
|
||||
await del(backupPath);
|
||||
}
|
||||
} catch (ex) {
|
||||
this.logService.error(`Backup: Could not delete stale backup: ${ex.toString()}`);
|
||||
}
|
||||
}
|
||||
|
||||
private convertToEmptyWindowBackup(backupPath: string): boolean {
|
||||
private async convertToEmptyWindowBackup(backupPath: string): Promise<boolean> {
|
||||
|
||||
// New empty window backup
|
||||
let newBackupFolder = this.getRandomEmptyWindowId();
|
||||
while (this.emptyWorkspaces.some(w => isEqual(w.backupFolder, newBackupFolder, platform.isLinux))) {
|
||||
newBackupFolder = this.getRandomEmptyWindowId();
|
||||
}
|
||||
|
||||
// Rename backupPath to new empty window backup path
|
||||
const newEmptyWindowBackupPath = this.getBackupPath(newBackupFolder);
|
||||
try {
|
||||
await rename(backupPath, newEmptyWindowBackupPath);
|
||||
} catch (ex) {
|
||||
this.logService.error(`Backup: Could not rename backup folder: ${ex.toString()}`);
|
||||
return false;
|
||||
}
|
||||
this.emptyWorkspaces.push({ backupFolder: newBackupFolder });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private convertToEmptyWindowBackupSync(backupPath: string): boolean {
|
||||
|
||||
// New empty window backup
|
||||
let newBackupFolder = this.getRandomEmptyWindowId();
|
||||
@@ -346,40 +382,53 @@ export class BackupMainService implements IBackupMainService {
|
||||
return true;
|
||||
}
|
||||
|
||||
private hasBackupsSync(backupPath: string): boolean {
|
||||
private async hasBackups(backupPath: string): Promise<boolean> {
|
||||
try {
|
||||
const backupSchemas = readdirSync(backupPath);
|
||||
if (backupSchemas.length === 0) {
|
||||
return false; // empty backups
|
||||
}
|
||||
const backupSchemas = await readdir(backupPath);
|
||||
|
||||
return backupSchemas.some(backupSchema => {
|
||||
for (let i = 0; i < backupSchemas.length; i++) {
|
||||
const backupSchema = backupSchemas[i];
|
||||
try {
|
||||
return readdirSync(path.join(backupPath, backupSchema)).length > 0;
|
||||
const backupSchemaChildren = await readdir(path.join(backupPath, backupSchema));
|
||||
if (backupSchemaChildren.length > 0) {
|
||||
return true;
|
||||
}
|
||||
} catch (error) {
|
||||
return false; // invalid folder
|
||||
// invalid folder
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
return false; // backup path does not exist
|
||||
// backup path does not exist
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private saveSync(): void {
|
||||
try {
|
||||
const backups: IBackupWorkspacesFormat = {
|
||||
rootWorkspaces: this.rootWorkspaces,
|
||||
folderURIWorkspaces: this.folderWorkspaces.map(f => f.toString()),
|
||||
emptyWorkspaceInfos: this.emptyWorkspaces,
|
||||
emptyWorkspaces: this.emptyWorkspaces.map(info => info.backupFolder)
|
||||
};
|
||||
|
||||
writeFileAndFlushSync(this.workspacesJsonPath, JSON.stringify(backups));
|
||||
writeFileAndFlushSync(this.workspacesJsonPath, JSON.stringify(this.serializeBackups()));
|
||||
} catch (ex) {
|
||||
this.logService.error(`Backup: Could not save workspaces.json: ${ex.toString()}`);
|
||||
}
|
||||
}
|
||||
|
||||
private async save(): Promise<void> {
|
||||
try {
|
||||
await writeFile(this.workspacesJsonPath, JSON.stringify(this.serializeBackups()));
|
||||
} catch (ex) {
|
||||
this.logService.error(`Backup: Could not save workspaces.json: ${ex.toString()}`);
|
||||
}
|
||||
}
|
||||
|
||||
private serializeBackups(): IBackupWorkspacesFormat {
|
||||
return {
|
||||
rootWorkspaces: this.rootWorkspaces,
|
||||
folderURIWorkspaces: this.folderWorkspaces.map(f => f.toString()),
|
||||
emptyWorkspaceInfos: this.emptyWorkspaces,
|
||||
emptyWorkspaces: this.emptyWorkspaces.map(info => info.backupFolder)
|
||||
} as IBackupWorkspacesFormat;
|
||||
}
|
||||
|
||||
private getRandomEmptyWindowId(): string {
|
||||
return (Date.now() + Math.round(Math.random() * 1000)).toString();
|
||||
}
|
||||
|
||||
@@ -41,13 +41,6 @@ suite('BackupMainService', () => {
|
||||
|
||||
this.backupHome = backupHome;
|
||||
this.workspacesJsonPath = backupWorkspacesPath;
|
||||
|
||||
// Force a reload with the new paths
|
||||
this.loadSync();
|
||||
}
|
||||
|
||||
public loadSync(): void {
|
||||
super.loadSync();
|
||||
}
|
||||
|
||||
public toBackupPath(arg: Uri | string): string {
|
||||
@@ -116,6 +109,8 @@ suite('BackupMainService', () => {
|
||||
}).then(() => {
|
||||
configService = new TestConfigurationService();
|
||||
service = new TestBackupMainService(backupHome, backupWorkspacesPath, configService);
|
||||
|
||||
return service.initialize();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -123,13 +118,13 @@ suite('BackupMainService', () => {
|
||||
return pfs.del(backupHome, os.tmpdir());
|
||||
});
|
||||
|
||||
test('service validates backup workspaces on startup and cleans up (folder workspaces)', function () {
|
||||
test('service validates backup workspaces on startup and cleans up (folder workspaces)', async function () {
|
||||
this.timeout(1000 * 10); // increase timeout for this test
|
||||
|
||||
// 1) backup workspace path does not exist
|
||||
service.registerFolderBackupSync(fooFile);
|
||||
service.registerFolderBackupSync(barFile);
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
|
||||
// 2) backup workspace path exists with empty contents within
|
||||
@@ -137,7 +132,7 @@ suite('BackupMainService', () => {
|
||||
fs.mkdirSync(service.toBackupPath(barFile));
|
||||
service.registerFolderBackupSync(fooFile);
|
||||
service.registerFolderBackupSync(barFile);
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
assert.ok(!fs.existsSync(service.toBackupPath(fooFile)));
|
||||
assert.ok(!fs.existsSync(service.toBackupPath(barFile)));
|
||||
@@ -149,7 +144,7 @@ suite('BackupMainService', () => {
|
||||
fs.mkdirSync(path.join(service.toBackupPath(barFile), Schemas.untitled));
|
||||
service.registerFolderBackupSync(fooFile);
|
||||
service.registerFolderBackupSync(barFile);
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
assert.ok(!fs.existsSync(service.toBackupPath(fooFile)));
|
||||
assert.ok(!fs.existsSync(service.toBackupPath(barFile)));
|
||||
@@ -164,18 +159,18 @@ suite('BackupMainService', () => {
|
||||
assert.equal(service.getFolderBackupPaths().length, 1);
|
||||
assert.equal(service.getEmptyWindowBackupPaths().length, 0);
|
||||
fs.writeFileSync(path.join(fileBackups, 'backup.txt'), '');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.equal(service.getFolderBackupPaths().length, 0);
|
||||
assert.equal(service.getEmptyWindowBackupPaths().length, 1);
|
||||
});
|
||||
|
||||
test('service validates backup workspaces on startup and cleans up (root workspaces)', function () {
|
||||
test('service validates backup workspaces on startup and cleans up (root workspaces)', async function () {
|
||||
this.timeout(1000 * 10); // increase timeout for this test
|
||||
|
||||
// 1) backup workspace path does not exist
|
||||
service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath));
|
||||
service.registerWorkspaceBackupSync(toWorkspace(barFile.fsPath));
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
|
||||
// 2) backup workspace path exists with empty contents within
|
||||
@@ -183,7 +178,7 @@ suite('BackupMainService', () => {
|
||||
fs.mkdirSync(service.toBackupPath(barFile));
|
||||
service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath));
|
||||
service.registerWorkspaceBackupSync(toWorkspace(barFile.fsPath));
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
assert.ok(!fs.existsSync(service.toBackupPath(fooFile)));
|
||||
assert.ok(!fs.existsSync(service.toBackupPath(barFile)));
|
||||
@@ -195,7 +190,7 @@ suite('BackupMainService', () => {
|
||||
fs.mkdirSync(path.join(service.toBackupPath(barFile), Schemas.untitled));
|
||||
service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath));
|
||||
service.registerWorkspaceBackupSync(toWorkspace(barFile.fsPath));
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
assert.ok(!fs.existsSync(service.toBackupPath(fooFile)));
|
||||
assert.ok(!fs.existsSync(service.toBackupPath(barFile)));
|
||||
@@ -210,7 +205,7 @@ suite('BackupMainService', () => {
|
||||
assert.equal(service.getWorkspaceBackups().length, 1);
|
||||
assert.equal(service.getEmptyWindowBackupPaths().length, 0);
|
||||
fs.writeFileSync(path.join(fileBackups, 'backup.txt'), '');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.equal(service.getWorkspaceBackups().length, 0);
|
||||
assert.equal(service.getEmptyWindowBackupPaths().length, 1);
|
||||
});
|
||||
@@ -285,17 +280,15 @@ suite('BackupMainService', () => {
|
||||
}
|
||||
|
||||
const workspacesJson = { rootWorkspaces: [], folderWorkspaces: [path1, path2], emptyWorkspaces: [] };
|
||||
await pfs.writeFile(backupWorkspacesPath, JSON.stringify(workspacesJson)).then(() => {
|
||||
service.loadSync();
|
||||
return pfs.readFile(backupWorkspacesPath, 'utf-8').then(content => {
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(content);
|
||||
assert.deepEqual(json.folderURIWorkspaces, [uri1.toString(), uri2.toString()]);
|
||||
const newBackupFolder1 = service.toBackupPath(uri1);
|
||||
assert.ok(fs.existsSync(path.join(newBackupFolder1, Schemas.file, 'unsaved1.txt')));
|
||||
const newBackupFolder2 = service.toBackupPath(uri2);
|
||||
assert.ok(fs.existsSync(path.join(newBackupFolder2, Schemas.file, 'unsaved2.txt')));
|
||||
});
|
||||
});
|
||||
await pfs.writeFile(backupWorkspacesPath, JSON.stringify(workspacesJson));
|
||||
await service.initialize();
|
||||
const content = await pfs.readFile(backupWorkspacesPath, 'utf-8');
|
||||
const json = (<IBackupWorkspacesFormat>JSON.parse(content));
|
||||
assert.deepEqual(json.folderURIWorkspaces, [uri1.toString(), uri2.toString()]);
|
||||
const newBackupFolder1 = service.toBackupPath(uri1);
|
||||
assert.ok(fs.existsSync(path.join(newBackupFolder1, Schemas.file, 'unsaved1.txt')));
|
||||
const newBackupFolder2 = service.toBackupPath(uri2);
|
||||
assert.ok(fs.existsSync(path.join(newBackupFolder2, Schemas.file, 'unsaved2.txt')));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -304,50 +297,50 @@ suite('BackupMainService', () => {
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
});
|
||||
|
||||
test('getFolderBackupPaths() should return [] when workspaces.json is not properly formed JSON', () => {
|
||||
test('getFolderBackupPaths() should return [] when workspaces.json is not properly formed JSON', async () => {
|
||||
fs.writeFileSync(backupWorkspacesPath, '');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{]');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, 'foo');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
});
|
||||
|
||||
test('getFolderBackupPaths() should return [] when folderWorkspaces in workspaces.json is absent', () => {
|
||||
test('getFolderBackupPaths() should return [] when folderWorkspaces in workspaces.json is absent', async () => {
|
||||
fs.writeFileSync(backupWorkspacesPath, '{}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
});
|
||||
|
||||
test('getFolderBackupPaths() should return [] when folderWorkspaces in workspaces.json is not a string array', () => {
|
||||
test('getFolderBackupPaths() should return [] when folderWorkspaces in workspaces.json is not a string array', async () => {
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":{}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":{"foo": ["bar"]}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":{"foo": []}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":{"foo": "bar"}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":"foo"}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"folderWorkspaces":1}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
});
|
||||
|
||||
test('getFolderBackupPaths() should return [] when files.hotExit = "onExitAndWindowClose"', () => {
|
||||
test('getFolderBackupPaths() should return [] when files.hotExit = "onExitAndWindowClose"', async () => {
|
||||
service.registerFolderBackupSync(Uri.file(fooFile.fsPath.toUpperCase()));
|
||||
assertEqualUris(service.getFolderBackupPaths(), [Uri.file(fooFile.fsPath.toUpperCase())]);
|
||||
configService.setUserConfiguration('files.hotExit', HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE);
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assertEqualUris(service.getFolderBackupPaths(), []);
|
||||
});
|
||||
|
||||
@@ -355,51 +348,51 @@ suite('BackupMainService', () => {
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
});
|
||||
|
||||
test('getWorkspaceBackups() should return [] when workspaces.json is not properly formed JSON', () => {
|
||||
test('getWorkspaceBackups() should return [] when workspaces.json is not properly formed JSON', async () => {
|
||||
fs.writeFileSync(backupWorkspacesPath, '');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{]');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, 'foo');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
});
|
||||
|
||||
test('getWorkspaceBackups() should return [] when folderWorkspaces in workspaces.json is absent', () => {
|
||||
test('getWorkspaceBackups() should return [] when folderWorkspaces in workspaces.json is absent', async () => {
|
||||
fs.writeFileSync(backupWorkspacesPath, '{}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
});
|
||||
|
||||
test('getWorkspaceBackups() should return [] when rootWorkspaces in workspaces.json is not a object array', () => {
|
||||
test('getWorkspaceBackups() should return [] when rootWorkspaces in workspaces.json is not a object array', async () => {
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{"foo": ["bar"]}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{"foo": []}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":{"foo": "bar"}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":"foo"}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"rootWorkspaces":1}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
});
|
||||
|
||||
test('getWorkspaceBackups() should return [] when files.hotExit = "onExitAndWindowClose"', () => {
|
||||
test('getWorkspaceBackups() should return [] when files.hotExit = "onExitAndWindowClose"', async () => {
|
||||
service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath.toUpperCase()));
|
||||
assert.equal(service.getWorkspaceBackups().length, 1);
|
||||
assert.deepEqual(service.getWorkspaceBackups().map(r => r.configPath), [fooFile.fsPath.toUpperCase()]);
|
||||
configService.setUserConfiguration('files.hotExit', HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE);
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getWorkspaceBackups(), []);
|
||||
});
|
||||
|
||||
@@ -407,43 +400,43 @@ suite('BackupMainService', () => {
|
||||
assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
|
||||
});
|
||||
|
||||
test('getEmptyWorkspaceBackupPaths() should return [] when workspaces.json is not properly formed JSON', () => {
|
||||
test('getEmptyWorkspaceBackupPaths() should return [] when workspaces.json is not properly formed JSON', async () => {
|
||||
fs.writeFileSync(backupWorkspacesPath, '');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{]');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, 'foo');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
|
||||
});
|
||||
|
||||
test('getEmptyWorkspaceBackupPaths() should return [] when folderWorkspaces in workspaces.json is absent', () => {
|
||||
test('getEmptyWorkspaceBackupPaths() should return [] when folderWorkspaces in workspaces.json is absent', async () => {
|
||||
fs.writeFileSync(backupWorkspacesPath, '{}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
|
||||
});
|
||||
|
||||
test('getEmptyWorkspaceBackupPaths() should return [] when folderWorkspaces in workspaces.json is not a string array', function () {
|
||||
test('getEmptyWorkspaceBackupPaths() should return [] when folderWorkspaces in workspaces.json is not a string array', async function () {
|
||||
this.timeout(5000);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":{}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":{"foo": ["bar"]}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":{"foo": []}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":{"foo": "bar"}}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":"foo"}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
|
||||
fs.writeFileSync(backupWorkspacesPath, '{"emptyWorkspaces":1}');
|
||||
service.loadSync();
|
||||
await service.initialize();
|
||||
assert.deepEqual(service.getEmptyWindowBackupPaths(), []);
|
||||
});
|
||||
});
|
||||
@@ -458,13 +451,12 @@ suite('BackupMainService', () => {
|
||||
folderURIWorkspaces: [existingTestFolder1.toString(), existingTestFolder1.toString()],
|
||||
emptyWorkspaceInfos: []
|
||||
};
|
||||
return pfs.writeFile(backupWorkspacesPath, JSON.stringify(workspacesJson)).then(() => {
|
||||
service.loadSync();
|
||||
return pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.deepEqual(json.folderURIWorkspaces, [existingTestFolder1.toString()]);
|
||||
});
|
||||
});
|
||||
await pfs.writeFile(backupWorkspacesPath, JSON.stringify(workspacesJson));
|
||||
await service.initialize();
|
||||
|
||||
const buffer = await pfs.readFile(backupWorkspacesPath, 'utf-8');
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.deepEqual(json.folderURIWorkspaces, [existingTestFolder1.toString()]);
|
||||
});
|
||||
|
||||
test('should ignore duplicates on Windows and Mac (folder workspace)', async () => {
|
||||
@@ -476,13 +468,11 @@ suite('BackupMainService', () => {
|
||||
folderURIWorkspaces: [existingTestFolder1.toString(), existingTestFolder1.toString().toLowerCase()],
|
||||
emptyWorkspaceInfos: []
|
||||
};
|
||||
return pfs.writeFile(backupWorkspacesPath, JSON.stringify(workspacesJson)).then(() => {
|
||||
service.loadSync();
|
||||
return pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.deepEqual(json.folderURIWorkspaces, [existingTestFolder1.toString()]);
|
||||
});
|
||||
});
|
||||
await pfs.writeFile(backupWorkspacesPath, JSON.stringify(workspacesJson));
|
||||
await service.initialize();
|
||||
const buffer = await pfs.readFile(backupWorkspacesPath, 'utf-8');
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.deepEqual(json.folderURIWorkspaces, [existingTestFolder1.toString()]);
|
||||
});
|
||||
|
||||
test('should ignore duplicates on Windows and Mac (root workspace)', async () => {
|
||||
@@ -501,34 +491,31 @@ suite('BackupMainService', () => {
|
||||
folderURIWorkspaces: [],
|
||||
emptyWorkspaceInfos: []
|
||||
};
|
||||
return pfs.writeFile(backupWorkspacesPath, JSON.stringify(workspacesJson)).then(() => {
|
||||
service.loadSync();
|
||||
return pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.equal(json.rootWorkspaces.length, platform.isLinux ? 3 : 1);
|
||||
if (platform.isLinux) {
|
||||
assert.deepEqual(json.rootWorkspaces.map(r => r.configPath), [workspacePath, workspacePath.toUpperCase(), workspacePath.toLowerCase()]);
|
||||
} else {
|
||||
assert.deepEqual(json.rootWorkspaces.map(r => r.configPath), [workspacePath], 'should return the first duplicated entry');
|
||||
}
|
||||
});
|
||||
});
|
||||
await pfs.writeFile(backupWorkspacesPath, JSON.stringify(workspacesJson));
|
||||
await service.initialize();
|
||||
|
||||
const buffer = await pfs.readFile(backupWorkspacesPath, 'utf-8');
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.equal(json.rootWorkspaces.length, platform.isLinux ? 3 : 1);
|
||||
if (platform.isLinux) {
|
||||
assert.deepEqual(json.rootWorkspaces.map(r => r.configPath), [workspacePath, workspacePath.toUpperCase(), workspacePath.toLowerCase()]);
|
||||
} else {
|
||||
assert.deepEqual(json.rootWorkspaces.map(r => r.configPath), [workspacePath], 'should return the first duplicated entry');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
suite('registerWindowForBackups', () => {
|
||||
test('should persist paths to workspaces.json (folder workspace)', () => {
|
||||
test('should persist paths to workspaces.json (folder workspace)', async () => {
|
||||
service.registerFolderBackupSync(fooFile);
|
||||
service.registerFolderBackupSync(barFile);
|
||||
assertEqualUris(service.getFolderBackupPaths(), [fooFile, barFile]);
|
||||
return pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.deepEqual(json.folderURIWorkspaces, [fooFile.toString(), barFile.toString()]);
|
||||
});
|
||||
const buffer = await pfs.readFile(backupWorkspacesPath, 'utf-8');
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.deepEqual(json.folderURIWorkspaces, [fooFile.toString(), barFile.toString()]);
|
||||
});
|
||||
|
||||
test('should persist paths to workspaces.json (root workspace)', () => {
|
||||
test('should persist paths to workspaces.json (root workspace)', async () => {
|
||||
const ws1 = toWorkspace(fooFile.fsPath);
|
||||
service.registerWorkspaceBackupSync(ws1);
|
||||
const ws2 = toWorkspace(barFile.fsPath);
|
||||
@@ -538,31 +525,30 @@ suite('BackupMainService', () => {
|
||||
assert.equal(ws1.id, service.getWorkspaceBackups()[0].id);
|
||||
assert.equal(ws2.id, service.getWorkspaceBackups()[1].id);
|
||||
|
||||
return pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
const buffer = await pfs.readFile(backupWorkspacesPath, 'utf-8');
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
|
||||
assert.deepEqual(json.rootWorkspaces.map(b => b.configPath), [fooFile.fsPath, barFile.fsPath]);
|
||||
assert.equal(ws1.id, json.rootWorkspaces[0].id);
|
||||
assert.equal(ws2.id, json.rootWorkspaces[1].id);
|
||||
});
|
||||
assert.deepEqual(json.rootWorkspaces.map(b => b.configPath), [fooFile.fsPath, barFile.fsPath]);
|
||||
assert.equal(ws1.id, json.rootWorkspaces[0].id);
|
||||
assert.equal(ws2.id, json.rootWorkspaces[1].id);
|
||||
});
|
||||
});
|
||||
|
||||
test('should always store the workspace path in workspaces.json using the case given, regardless of whether the file system is case-sensitive (folder workspace)', () => {
|
||||
service.registerFolderBackupSync(Uri.file(fooFile.fsPath.toUpperCase()));
|
||||
assertEqualUris(service.getFolderBackupPaths(), [Uri.file(fooFile.fsPath.toUpperCase())]);
|
||||
return pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.deepEqual(json.folderURIWorkspaces, [Uri.file(fooFile.fsPath.toUpperCase()).toString()]);
|
||||
});
|
||||
test('should always store the workspace path in workspaces.json using the case given, regardless of whether the file system is case-sensitive (folder workspace)', () => {
|
||||
service.registerFolderBackupSync(Uri.file(fooFile.fsPath.toUpperCase()));
|
||||
assertEqualUris(service.getFolderBackupPaths(), [Uri.file(fooFile.fsPath.toUpperCase())]);
|
||||
return pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.deepEqual(json.folderURIWorkspaces, [Uri.file(fooFile.fsPath.toUpperCase()).toString()]);
|
||||
});
|
||||
});
|
||||
|
||||
test('should always store the workspace path in workspaces.json using the case given, regardless of whether the file system is case-sensitive (root workspace)', () => {
|
||||
service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath.toUpperCase()));
|
||||
assert.deepEqual(service.getWorkspaceBackups().map(b => b.configPath), [fooFile.fsPath.toUpperCase()]);
|
||||
return pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.deepEqual(json.rootWorkspaces.map(b => b.configPath), [fooFile.fsPath.toUpperCase()]);
|
||||
});
|
||||
test('should always store the workspace path in workspaces.json using the case given, regardless of whether the file system is case-sensitive (root workspace)', () => {
|
||||
service.registerWorkspaceBackupSync(toWorkspace(fooFile.fsPath.toUpperCase()));
|
||||
assert.deepEqual(service.getWorkspaceBackups().map(b => b.configPath), [fooFile.fsPath.toUpperCase()]);
|
||||
return pfs.readFile(backupWorkspacesPath, 'utf-8').then(buffer => {
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(buffer);
|
||||
assert.deepEqual(json.rootWorkspaces.map(b => b.configPath), [fooFile.fsPath.toUpperCase()]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -619,15 +605,13 @@ suite('BackupMainService', () => {
|
||||
await ensureFolderExists(existingTestFolder1); // make sure backup folder exists, so the folder is not removed on loadSync
|
||||
|
||||
const workspacesJson: IBackupWorkspacesFormat = { rootWorkspaces: [], folderURIWorkspaces: [existingTestFolder1.toString()], emptyWorkspaceInfos: [] };
|
||||
return pfs.writeFile(backupWorkspacesPath, JSON.stringify(workspacesJson)).then(() => {
|
||||
service.loadSync();
|
||||
service.unregisterFolderBackupSync(barFile);
|
||||
service.unregisterEmptyWindowBackupSync('test');
|
||||
return pfs.readFile(backupWorkspacesPath, 'utf-8').then(content => {
|
||||
const json = <IBackupWorkspacesFormat>JSON.parse(content);
|
||||
assert.deepEqual(json.folderURIWorkspaces, [existingTestFolder1.toString()]);
|
||||
});
|
||||
});
|
||||
await pfs.writeFile(backupWorkspacesPath, JSON.stringify(workspacesJson));
|
||||
await service.initialize();
|
||||
service.unregisterFolderBackupSync(barFile);
|
||||
service.unregisterEmptyWindowBackupSync('test');
|
||||
const content = await pfs.readFile(backupWorkspacesPath, 'utf-8');
|
||||
const json = (<IBackupWorkspacesFormat>JSON.parse(content));
|
||||
assert.deepEqual(json.folderURIWorkspaces, [existingTestFolder1.toString()]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
suite('Command Tests', function () {
|
||||
|
||||
test('register command - no handler', function () {
|
||||
assert.throws(() => CommandsRegistry.registerCommand('foo', null));
|
||||
assert.throws(() => CommandsRegistry.registerCommand('foo', null!));
|
||||
});
|
||||
|
||||
test('register/dispose', () => {
|
||||
const command = function () { };
|
||||
const reg = CommandsRegistry.registerCommand('foo', command);
|
||||
assert.ok(CommandsRegistry.getCommand('foo').handler === command);
|
||||
assert.ok(CommandsRegistry.getCommand('foo')!.handler === command);
|
||||
reg.dispose();
|
||||
assert.ok(CommandsRegistry.getCommand('foo') === undefined);
|
||||
});
|
||||
@@ -25,23 +25,23 @@ suite('Command Tests', function () {
|
||||
|
||||
// dispose overriding command
|
||||
let reg1 = CommandsRegistry.registerCommand('foo', command1);
|
||||
assert.ok(CommandsRegistry.getCommand('foo').handler === command1);
|
||||
assert.ok(CommandsRegistry.getCommand('foo')!.handler === command1);
|
||||
|
||||
let reg2 = CommandsRegistry.registerCommand('foo', command2);
|
||||
assert.ok(CommandsRegistry.getCommand('foo').handler === command2);
|
||||
assert.ok(CommandsRegistry.getCommand('foo')!.handler === command2);
|
||||
reg2.dispose();
|
||||
|
||||
assert.ok(CommandsRegistry.getCommand('foo').handler === command1);
|
||||
assert.ok(CommandsRegistry.getCommand('foo')!.handler === command1);
|
||||
reg1.dispose();
|
||||
assert.ok(CommandsRegistry.getCommand('foo') === void 0);
|
||||
|
||||
// dispose override command first
|
||||
reg1 = CommandsRegistry.registerCommand('foo', command1);
|
||||
reg2 = CommandsRegistry.registerCommand('foo', command2);
|
||||
assert.ok(CommandsRegistry.getCommand('foo').handler === command2);
|
||||
assert.ok(CommandsRegistry.getCommand('foo')!.handler === command2);
|
||||
|
||||
reg1.dispose();
|
||||
assert.ok(CommandsRegistry.getCommand('foo').handler === command2);
|
||||
assert.ok(CommandsRegistry.getCommand('foo')!.handler === command2);
|
||||
|
||||
reg2.dispose();
|
||||
assert.ok(CommandsRegistry.getCommand('foo') === void 0);
|
||||
@@ -68,10 +68,10 @@ suite('Command Tests', function () {
|
||||
}
|
||||
});
|
||||
|
||||
CommandsRegistry.getCommands()['test'].handler.apply(undefined, [undefined, 'string']);
|
||||
CommandsRegistry.getCommands()['test2'].handler.apply(undefined, [undefined, 'string']);
|
||||
assert.throws(() => CommandsRegistry.getCommands()['test3'].handler.apply(undefined, [undefined, 'string']));
|
||||
assert.equal(CommandsRegistry.getCommands()['test3'].handler.apply(undefined, [undefined, 1]), true);
|
||||
CommandsRegistry.getCommands()['test'].handler.apply(undefined, [undefined!, 'string']);
|
||||
CommandsRegistry.getCommands()['test2'].handler.apply(undefined, [undefined!, 'string']);
|
||||
assert.throws(() => CommandsRegistry.getCommands()['test3'].handler.apply(undefined, [undefined!, 'string']));
|
||||
assert.equal(CommandsRegistry.getCommands()['test3'].handler.apply(undefined, [undefined!, 1]), true);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,10 +25,10 @@ export interface ParsedArgs {
|
||||
'reuse-window'?: boolean;
|
||||
locale?: string;
|
||||
'user-data-dir'?: string;
|
||||
performance?: boolean;
|
||||
'prof-startup'?: string;
|
||||
'prof-startup-prefix'?: string;
|
||||
'prof-append-timers'?: string;
|
||||
'prof-modules'?: string;
|
||||
verbose?: boolean;
|
||||
trace?: boolean;
|
||||
'trace-category-filter'?: string;
|
||||
@@ -126,7 +126,6 @@ export interface IEnvironmentService {
|
||||
isBuilt: boolean;
|
||||
wait: boolean;
|
||||
status: boolean;
|
||||
performance: boolean;
|
||||
|
||||
// logging
|
||||
log?: string;
|
||||
|
||||
@@ -51,8 +51,8 @@ const options: minimist.Opts = {
|
||||
'unity-launch',
|
||||
'reuse-window',
|
||||
'open-url',
|
||||
'performance',
|
||||
'prof-startup',
|
||||
'prof-code-loading',
|
||||
'verbose',
|
||||
'logExtensionHostCommunication',
|
||||
'disable-extensions',
|
||||
@@ -175,8 +175,8 @@ const troubleshootingHelp: { [name: string]: string; } = {
|
||||
'--verbose': localize('verbose', "Print verbose output (implies --wait)."),
|
||||
'--log <level>': localize('log', "Log level to use. Default is 'info'. Allowed values are 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'."),
|
||||
'-s, --status': localize('status', "Print process usage and diagnostics information."),
|
||||
'-p, --performance': localize('performance', "Start with the 'Developer: Startup Performance' command enabled."),
|
||||
'--prof-startup': localize('prof-startup', "Run CPU profiler during startup"),
|
||||
'--prof-startup': localize('prof-startup', "Run CPU profilers during startup."),
|
||||
'--prof-modules': localize('prof-modules', "Capture performance markers while loading JS modules and print them with 'F1 > Developer: Startup Performance'"),
|
||||
'--disable-extensions': localize('disableExtensions', "Disable all installed extensions."),
|
||||
'--disable-extension <extension-id>': localize('disableExtension', "Disable an extension."),
|
||||
'--inspect-extensions': localize('inspect-extensions', "Allow debugging and profiling of extensions. Check the developer tools for the connection URI."),
|
||||
@@ -265,4 +265,4 @@ export function hasArgs(arg: string | string[] | undefined): boolean {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +222,6 @@ export class EnvironmentService implements IEnvironmentService {
|
||||
|
||||
get logExtensionHostCommunication(): boolean { return !!this._args.logExtensionHostCommunication; }
|
||||
|
||||
get performance(): boolean { return !!this._args.performance; }
|
||||
get status(): boolean { return !!this._args.status; }
|
||||
|
||||
@memoize
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ suite('ExtensionEnablementService Test', () => {
|
||||
|
||||
setup(() => {
|
||||
instantiationService = new TestInstantiationService();
|
||||
instantiationService.stub(IExtensionManagementService, { onDidUninstallExtension: didUninstallEvent.event, onDidInstallExtension: didInstallEvent.event, getInstalled: () => Promise.resolve([]) } as IExtensionManagementService);
|
||||
instantiationService.stub(IExtensionManagementService, { onDidUninstallExtension: didUninstallEvent.event, onDidInstallExtension: didInstallEvent.event, getInstalled: () => Promise.resolve([] as ILocalExtension[]) } as IExtensionManagementService);
|
||||
testObject = new TestExtensionEnablementService(instantiationService);
|
||||
});
|
||||
|
||||
|
||||
@@ -77,15 +77,15 @@ suite('AbstractKeybindingService', () => {
|
||||
altKey: keybinding.altKey,
|
||||
metaKey: keybinding.metaKey,
|
||||
keyCode: keybinding.keyCode,
|
||||
code: null
|
||||
}, null);
|
||||
code: null!
|
||||
}, null!);
|
||||
}
|
||||
}
|
||||
|
||||
let createTestKeybindingService: (items: ResolvedKeybindingItem[], contextValue?: any) => TestKeybindingService = null;
|
||||
let createTestKeybindingService: (items: ResolvedKeybindingItem[], contextValue?: any) => TestKeybindingService = null!;
|
||||
let currentContextValue: IContext | null = null;
|
||||
let executeCommandCalls: { commandId: string; args: any[]; }[] = null;
|
||||
let showMessageCalls: { sev: Severity, message: any; }[] = null;
|
||||
let executeCommandCalls: { commandId: string; args: any[]; }[] = null!;
|
||||
let showMessageCalls: { sev: Severity, message: any; }[] = null!;
|
||||
let statusMessageCalls: string[] | null = null;
|
||||
let statusMessageCallsDisposed: string[] | null = null;
|
||||
|
||||
@@ -99,12 +99,12 @@ suite('AbstractKeybindingService', () => {
|
||||
|
||||
let contextKeyService: IContextKeyService = {
|
||||
_serviceBrand: undefined,
|
||||
dispose: undefined,
|
||||
onDidChangeContext: undefined,
|
||||
createKey: undefined,
|
||||
contextMatchesRules: undefined,
|
||||
getContextKeyValue: undefined,
|
||||
createScoped: undefined,
|
||||
dispose: undefined!,
|
||||
onDidChangeContext: undefined!,
|
||||
createKey: undefined!,
|
||||
contextMatchesRules: undefined!,
|
||||
getContextKeyValue: undefined!,
|
||||
createScoped: undefined!,
|
||||
getContext: (target: IContextKeyServiceTarget): any => {
|
||||
return currentContextValue;
|
||||
}
|
||||
@@ -147,12 +147,12 @@ suite('AbstractKeybindingService', () => {
|
||||
|
||||
let statusbarService: IStatusbarService = {
|
||||
_serviceBrand: undefined,
|
||||
addEntry: undefined,
|
||||
addEntry: undefined!,
|
||||
setStatusMessage: (message: string, autoDisposeAfter?: number, delayBy?: number): IDisposable => {
|
||||
statusMessageCalls.push(message);
|
||||
statusMessageCalls!.push(message);
|
||||
return {
|
||||
dispose: () => {
|
||||
statusMessageCallsDisposed.push(message);
|
||||
statusMessageCallsDisposed!.push(message);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -166,15 +166,15 @@ suite('AbstractKeybindingService', () => {
|
||||
|
||||
teardown(() => {
|
||||
currentContextValue = null;
|
||||
executeCommandCalls = null;
|
||||
showMessageCalls = null;
|
||||
createTestKeybindingService = null;
|
||||
executeCommandCalls = null!;
|
||||
showMessageCalls = null!;
|
||||
createTestKeybindingService = null!;
|
||||
statusMessageCalls = null;
|
||||
statusMessageCallsDisposed = null;
|
||||
});
|
||||
|
||||
function kbItem(keybinding: number, command: string, when: ContextKeyExpr | null = null): ResolvedKeybindingItem {
|
||||
const resolvedKeybinding = (keybinding !== 0 ? new USLayoutResolvedKeybinding(createKeybinding(keybinding, OS), OS) : null);
|
||||
const resolvedKeybinding = (keybinding !== 0 ? new USLayoutResolvedKeybinding(createKeybinding(keybinding, OS)!, OS) : null);
|
||||
return new ResolvedKeybindingItem(
|
||||
resolvedKeybinding,
|
||||
command,
|
||||
@@ -185,8 +185,8 @@ suite('AbstractKeybindingService', () => {
|
||||
}
|
||||
|
||||
function toUsLabel(keybinding: number): string {
|
||||
const usResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keybinding, OS), OS);
|
||||
return usResolvedKeybinding.getLabel();
|
||||
const usResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keybinding, OS)!, OS);
|
||||
return usResolvedKeybinding.getLabel()!;
|
||||
}
|
||||
|
||||
test('issue #16498: chord mode is quit for invalid chords', () => {
|
||||
|
||||
@@ -30,10 +30,10 @@ suite('StorageService', () => {
|
||||
const storage = new TestStorageService();
|
||||
|
||||
storage.store('Monaco.IDE.Core.Storage.Test.remove', 'foobar', scope);
|
||||
strictEqual('foobar', storage.get('Monaco.IDE.Core.Storage.Test.remove', scope, void 0));
|
||||
strictEqual('foobar', storage.get('Monaco.IDE.Core.Storage.Test.remove', scope, (void 0)!));
|
||||
|
||||
storage.remove('Monaco.IDE.Core.Storage.Test.remove', scope);
|
||||
ok(!storage.get('Monaco.IDE.Core.Storage.Test.remove', scope, void 0));
|
||||
ok(!storage.get('Monaco.IDE.Core.Storage.Test.remove', scope, (void 0)!));
|
||||
}
|
||||
|
||||
test('Get Data, Integer, Boolean (global, in-memory)', () => {
|
||||
@@ -55,22 +55,22 @@ suite('StorageService', () => {
|
||||
strictEqual(storage.getBoolean('Monaco.IDE.Core.Storage.Test.getBoolean', scope, false), false);
|
||||
|
||||
storage.store('Monaco.IDE.Core.Storage.Test.get', 'foobar', scope);
|
||||
strictEqual(storage.get('Monaco.IDE.Core.Storage.Test.get', scope, void 0), 'foobar');
|
||||
strictEqual(storage.get('Monaco.IDE.Core.Storage.Test.get', scope, (void 0)!), 'foobar');
|
||||
|
||||
storage.store('Monaco.IDE.Core.Storage.Test.get', '', scope);
|
||||
strictEqual(storage.get('Monaco.IDE.Core.Storage.Test.get', scope, void 0), '');
|
||||
strictEqual(storage.get('Monaco.IDE.Core.Storage.Test.get', scope, (void 0)!), '');
|
||||
|
||||
storage.store('Monaco.IDE.Core.Storage.Test.getInteger', 5, scope);
|
||||
strictEqual(storage.getInteger('Monaco.IDE.Core.Storage.Test.getInteger', scope, void 0), 5);
|
||||
strictEqual(storage.getInteger('Monaco.IDE.Core.Storage.Test.getInteger', scope, (void 0)!), 5);
|
||||
|
||||
storage.store('Monaco.IDE.Core.Storage.Test.getInteger', 0, scope);
|
||||
strictEqual(storage.getInteger('Monaco.IDE.Core.Storage.Test.getInteger', scope, void 0), 0);
|
||||
strictEqual(storage.getInteger('Monaco.IDE.Core.Storage.Test.getInteger', scope, (void 0)!), 0);
|
||||
|
||||
storage.store('Monaco.IDE.Core.Storage.Test.getBoolean', true, scope);
|
||||
strictEqual(storage.getBoolean('Monaco.IDE.Core.Storage.Test.getBoolean', scope, void 0), true);
|
||||
strictEqual(storage.getBoolean('Monaco.IDE.Core.Storage.Test.getBoolean', scope, (void 0)!), true);
|
||||
|
||||
storage.store('Monaco.IDE.Core.Storage.Test.getBoolean', false, scope);
|
||||
strictEqual(storage.getBoolean('Monaco.IDE.Core.Storage.Test.getBoolean', scope, void 0), false);
|
||||
strictEqual(storage.getBoolean('Monaco.IDE.Core.Storage.Test.getBoolean', scope, (void 0)!), false);
|
||||
|
||||
strictEqual(storage.get('Monaco.IDE.Core.Storage.Test.getDefault', scope, 'getDefault'), 'getDefault');
|
||||
strictEqual(storage.getInteger('Monaco.IDE.Core.Storage.Test.getIntegerDefault', scope, 5), 5);
|
||||
|
||||
@@ -17,8 +17,8 @@ suite('Telemetry - common properties', function () {
|
||||
const parentDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'telemetryservice');
|
||||
const installSource = path.join(parentDir, 'installSource');
|
||||
|
||||
const commit: string = void 0;
|
||||
const version: string = void 0;
|
||||
const commit: string = (void 0)!;
|
||||
const version: string = (void 0)!;
|
||||
let testStorageService: IStorageService;
|
||||
|
||||
setup(() => {
|
||||
|
||||
@@ -41,7 +41,7 @@ suite('Color Registry', function () {
|
||||
|
||||
test('all colors documented', async function () {
|
||||
const reqContext = await request({ url: 'https://raw.githubusercontent.com/Microsoft/vscode-docs/vnext/docs/getstarted/theme-color-reference.md' }, CancellationToken.None);
|
||||
const content = await asText(reqContext);
|
||||
const content = (await asText(reqContext))!;
|
||||
|
||||
const expression = /\-\s*\`([\w\.]+)\`: (.*)/g;
|
||||
|
||||
|
||||
@@ -177,9 +177,9 @@ suite('WorkspacesMainService', () => {
|
||||
workspace.configPath = newPath;
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(2, resolved.folders.length);
|
||||
assert.equal(resolved.configPath, workspace.configPath);
|
||||
assert.ok(resolved.id);
|
||||
assert.equal(2, resolved!.folders.length);
|
||||
assert.equal(resolved!.configPath, workspace.configPath);
|
||||
assert.ok(resolved!.id);
|
||||
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ something: 'something' })); // invalid workspace
|
||||
const resolvedInvalid = service.resolveWorkspaceSync(workspace.configPath);
|
||||
@@ -192,7 +192,7 @@ suite('WorkspacesMainService', () => {
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib' }] }));
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(resolved.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
assert.equal(resolved!.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -201,7 +201,7 @@ suite('WorkspacesMainService', () => {
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib/../other' }] }));
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(resolved.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'other')).fsPath);
|
||||
assert.equal(resolved!.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'other')).fsPath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -210,7 +210,7 @@ suite('WorkspacesMainService', () => {
|
||||
fs.writeFileSync(workspace.configPath, JSON.stringify({ folders: [{ path: 'ticino-playground/lib' }] }));
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(resolved.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
assert.equal(resolved!.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -219,7 +219,7 @@ suite('WorkspacesMainService', () => {
|
||||
fs.writeFileSync(workspace.configPath, '{ "folders": [ { "path": "./ticino-playground/lib" } , ] }'); // trailing comma
|
||||
|
||||
const resolved = service.resolveWorkspaceSync(workspace.configPath);
|
||||
assert.equal(resolved.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
assert.equal(resolved!.folders[0].uri.fsPath, URI.file(path.join(path.dirname(workspace.configPath), 'ticino-playground', 'lib')).fsPath);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -7929,7 +7929,7 @@ declare module 'vscode' {
|
||||
export function registerReferenceProvider(selector: DocumentSelector, provider: ReferenceProvider): Disposable;
|
||||
|
||||
/**
|
||||
* Register a reference provider.
|
||||
* Register a rename provider.
|
||||
*
|
||||
* Multiple providers can be registered for a language. In that case providers are sorted
|
||||
* by their [score](#languages.match) and the best-matching provider is used. Failure
|
||||
|
||||
Vendored
+1
-1
@@ -47,7 +47,7 @@ declare module 'vscode' {
|
||||
export class SelectionRange {
|
||||
kind: SelectionRangeKind;
|
||||
range: Range;
|
||||
constructor(kind: SelectionRangeKind, range: Range);
|
||||
constructor(range: Range, kind: SelectionRangeKind);
|
||||
}
|
||||
|
||||
export interface SelectionRangeProvider {
|
||||
|
||||
@@ -855,7 +855,7 @@ export namespace SelectionRange {
|
||||
}
|
||||
|
||||
export function to(obj: modes.SelectionRange): vscode.SelectionRange {
|
||||
return new types.SelectionRange(SelectionRangeKind.to(obj.kind), Range.to(obj.range));
|
||||
return new types.SelectionRange(Range.to(obj.range), SelectionRangeKind.to(obj.kind));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -491,7 +491,7 @@ export class TextEdit {
|
||||
|
||||
constructor(range: Range, newText: string) {
|
||||
this.range = range;
|
||||
this.newText = newText || '';
|
||||
this.newText = newText;
|
||||
}
|
||||
|
||||
toJSON(): any {
|
||||
@@ -1060,9 +1060,9 @@ export class SelectionRange {
|
||||
kind: SelectionRangeKind;
|
||||
range: Range;
|
||||
|
||||
constructor(kind: SelectionRangeKind, range: Range) {
|
||||
this.kind = kind;
|
||||
constructor(range: Range, kind: SelectionRangeKind, ) {
|
||||
this.range = range;
|
||||
this.kind = kind;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1059,7 +1059,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
element = (e as GestureEvent).initialTarget as HTMLElement;
|
||||
}
|
||||
|
||||
return !!findParentWithClass(element, 'monaco-action-bar', 'tab');
|
||||
return !!findParentWithClass(element, 'action-item', 'tab');
|
||||
}
|
||||
|
||||
private onDrop(e: DragEvent, targetIndex: number): void {
|
||||
|
||||
@@ -886,6 +886,11 @@ configurationRegistry.registerConfiguration({
|
||||
'default': true,
|
||||
'description': nls.localize('zenMode.hideActivityBar', "Controls whether turning on Zen Mode also hides the activity bar at the left of the workbench.")
|
||||
},
|
||||
'zenMode.hideLineNumbers': {
|
||||
'type': 'boolean',
|
||||
'default': true,
|
||||
'description': nls.localize('zenMode.hideLineNumbers', "Controls whether turning on Zen Mode also hides the editor line numbers.")
|
||||
},
|
||||
'zenMode.restore': {
|
||||
'type': 'boolean',
|
||||
'default': false,
|
||||
|
||||
@@ -113,6 +113,7 @@ import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/work
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { FileDialogService } from 'vs/workbench/services/dialogs/electron-browser/dialogService';
|
||||
import { LogStorageAction } from 'vs/platform/storage/node/storageService';
|
||||
import { IEditor } from 'vs/editor/common/editorCommon';
|
||||
|
||||
interface WorkbenchParams {
|
||||
configuration: IWindowConfiguration;
|
||||
@@ -125,6 +126,7 @@ interface IZenModeSettings {
|
||||
hideTabs: boolean;
|
||||
hideActivityBar: boolean;
|
||||
hideStatusBar: boolean;
|
||||
hideLineNumbers: boolean;
|
||||
restore: boolean;
|
||||
}
|
||||
|
||||
@@ -1236,6 +1238,14 @@ export class Workbench extends Disposable implements IPartService {
|
||||
// Check if zen mode transitioned to full screen and if now we are out of zen mode
|
||||
// -> we need to go out of full screen (same goes for the centered editor layout)
|
||||
let toggleFullScreen = false;
|
||||
const setLineNumbers = (lineNumbers: any) => {
|
||||
this.editorService.visibleControls.forEach(editor => {
|
||||
const control = <IEditor>editor.getControl();
|
||||
if (control) {
|
||||
control.updateOptions({ lineNumbers });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Zen Mode Active
|
||||
if (this.zenMode.active) {
|
||||
@@ -1258,6 +1268,11 @@ export class Workbench extends Disposable implements IPartService {
|
||||
this.setStatusBarHidden(true, true);
|
||||
}
|
||||
|
||||
if (config.hideLineNumbers) {
|
||||
setLineNumbers('off');
|
||||
this.zenMode.transitionDisposeables.push(this.editorService.onDidVisibleEditorsChange(() => setLineNumbers('off')));
|
||||
}
|
||||
|
||||
if (config.hideTabs && this.editorPart.partOptions.showTabs) {
|
||||
this.zenMode.transitionDisposeables.push(this.editorPart.enforcePartOptions({ showTabs: false }));
|
||||
}
|
||||
@@ -1280,6 +1295,7 @@ export class Workbench extends Disposable implements IPartService {
|
||||
if (this.zenMode.transitionedToCenteredEditorLayout) {
|
||||
this.centerEditorLayout(false, true);
|
||||
}
|
||||
setLineNumbers(this.configurationService.getValue('editor.lineNumbers'));
|
||||
|
||||
// Status bar and activity bar visibility come from settings -> update their visibility.
|
||||
this.onDidUpdateConfiguration(true);
|
||||
|
||||
@@ -190,6 +190,11 @@ export abstract class AbstractExpressionsRenderer
|
||||
data.toDispose.push(dom.addDisposableListener(inputBox.inputElement, 'blur', () => {
|
||||
wrapUp(true);
|
||||
}));
|
||||
data.toDispose.push(dom.addDisposableListener(inputBox.inputElement, 'click', e => {
|
||||
// Do not expand / collapse selected elements
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}));
|
||||
};
|
||||
|
||||
return data;
|
||||
|
||||
@@ -10,7 +10,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IDebugService, State, IDebugSession, IThread, IEnablement, IBreakpoint, IStackFrame, REPL_ID, IConfig }
|
||||
import { IDebugService, State, IDebugSession, IThread, IEnablement, IBreakpoint, IStackFrame, REPL_ID }
|
||||
from 'vs/workbench/parts/debug/common/debug';
|
||||
import { Variable, Expression, Thread, Breakpoint } from 'vs/workbench/parts/debug/common/debugModel';
|
||||
import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
@@ -135,11 +135,7 @@ export class StartAction extends AbstractDebugAction {
|
||||
|
||||
// Note: When this action is executed from the process explorer, a config is passed. For all
|
||||
// other cases it is run with no arguments.
|
||||
public run(config?: IConfig): Promise<any> {
|
||||
if (config && 'type' in config && 'request' in config) {
|
||||
return this.debugService.startDebugging(undefined, config, this.isNoDebug());
|
||||
}
|
||||
|
||||
public run(): Promise<any> {
|
||||
const configurationManager = this.debugService.getConfigurationManager();
|
||||
let launch = configurationManager.selectedConfiguration.launch;
|
||||
if (!launch || launch.getConfigurationNames().length === 0) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { List } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IListService } from 'vs/platform/list/browser/listService';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IDebugService, IEnablement, CONTEXT_BREAKPOINTS_FOCUSED, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_VARIABLES_FOCUSED, EDITOR_CONTRIBUTION_ID, IDebugEditorContribution, CONTEXT_IN_DEBUG_MODE, CONTEXT_EXPRESSION_SELECTED, CONTEXT_BREAKPOINT_SELECTED } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IDebugService, IEnablement, CONTEXT_BREAKPOINTS_FOCUSED, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_VARIABLES_FOCUSED, EDITOR_CONTRIBUTION_ID, IDebugEditorContribution, CONTEXT_IN_DEBUG_MODE, CONTEXT_EXPRESSION_SELECTED, CONTEXT_BREAKPOINT_SELECTED, IConfig } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { Expression, Variable, Breakpoint, FunctionBreakpoint } from 'vs/workbench/parts/debug/common/debugModel';
|
||||
import { IExtensionsViewlet, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/parts/extensions/common/extensions';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
@@ -23,12 +23,22 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
|
||||
import { InputFocusedContext } from 'vs/platform/workbench/common/contextkeys';
|
||||
import { ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
||||
import { PanelFocusContext } from 'vs/workbench/browser/parts/panel/panelPart';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
|
||||
export const ADD_CONFIGURATION_ID = 'debug.addConfiguration';
|
||||
export const TOGGLE_INLINE_BREAKPOINT_ID = 'editor.debug.action.toggleInlineBreakpoint';
|
||||
|
||||
export function registerCommands(): void {
|
||||
|
||||
CommandsRegistry.registerCommand({
|
||||
id: 'debug.startFromConfig',
|
||||
handler: (accessor, config: IConfig) => {
|
||||
const debugService = accessor.get(IDebugService);
|
||||
debugService.startDebugging(undefined, config).then(undefined, onUnexpectedError);
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'debug.toggleBreakpoint',
|
||||
weight: KeybindingWeight.WorkbenchContrib + 5,
|
||||
|
||||
@@ -155,15 +155,21 @@
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.monaco-workbench .monaco-list-row:not(.selected) .expression .name {
|
||||
/* White color when element is selected and list is focused. White looks better on blue selection background. */
|
||||
.monaco-workbench .monaco-list:focus .monaco-list-row.selected .expression .name,
|
||||
.monaco-workbench .monaco-list:focus .monaco-list-row.selected .expression .value {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.monaco-workbench .monaco-list-row .expression .name {
|
||||
color: #9B46B0;
|
||||
}
|
||||
|
||||
.monaco-workbench .monaco-list-row:not(.selected) .expression .name.virtual {
|
||||
.monaco-workbench .monaco-list-row .expression .name.virtual {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.monaco-workbench > .monaco-list-row:not(.selected) .expression .value {
|
||||
.monaco-workbench > .monaco-list-row .expression .value {
|
||||
color: rgba(108, 108, 108, 0.8);
|
||||
}
|
||||
|
||||
@@ -171,67 +177,67 @@
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.monaco-workbench .monaco-list-row:not(.selected) .expression .error {
|
||||
.monaco-workbench .monaco-list-row .expression .error {
|
||||
color: #E51400;
|
||||
}
|
||||
|
||||
.monaco-workbench .monaco-list-row:not(.selected) .expression .value.number {
|
||||
.monaco-workbench .monaco-list-row .expression .value.number {
|
||||
color: #09885A;
|
||||
}
|
||||
|
||||
.monaco-workbench .monaco-list-row:not(.selected) .expression .value.boolean {
|
||||
.monaco-workbench .monaco-list-row .expression .value.boolean {
|
||||
color: #0000FF;
|
||||
}
|
||||
|
||||
.monaco-workbench .monaco-list-row:not(.selected) .expression .value.string {
|
||||
.monaco-workbench .monaco-list-row .expression .value.string {
|
||||
color: #A31515;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench > .monaco-list-row:not(.selected) .expression .value {
|
||||
.vs-dark .monaco-workbench > .monaco-list-row .expression .value {
|
||||
color: rgba(204, 204, 204, 0.6);
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench .monaco-list-row:not(.selected) .expression .error {
|
||||
.vs-dark .monaco-workbench .monaco-list-row .expression .error {
|
||||
color: #F48771;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench .monaco-list-row:not(.selected) .expression .value.number {
|
||||
.vs-dark .monaco-workbench .monaco-list-row .expression .value.number {
|
||||
color: #B5CEA8;
|
||||
}
|
||||
|
||||
.hc-black .monaco-workbench .monaco-list-row:not(.selected) .expression .value.number {
|
||||
.hc-black .monaco-workbench .monaco-list-row .expression .value.number {
|
||||
color: #89d185;
|
||||
}
|
||||
|
||||
.hc-black .monaco-workbench .monaco-list-row:not(.selected) .expression .value.boolean {
|
||||
.hc-black .monaco-workbench .monaco-list-row .expression .value.boolean {
|
||||
color: #75bdfe;
|
||||
}
|
||||
|
||||
.hc-black .monaco-workbench .monaco-list-row:not(.selected) .expression .value.string {
|
||||
.hc-black .monaco-workbench .monaco-list-row .expression .value.string {
|
||||
color: #f48771;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench .monaco-list-row:not(.selected) .expression .value.boolean {
|
||||
.vs-dark .monaco-workbench .monaco-list-row .expression .value.boolean {
|
||||
color: #4E94CE;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench .monaco-list-row:not(.selected) .expression .value.string {
|
||||
.vs-dark .monaco-workbench .monaco-list-row .expression .value.string {
|
||||
color: #CE9178;
|
||||
}
|
||||
|
||||
.hc-black .monaco-workbench .monaco-list-row:not(.selected) .expression .error {
|
||||
.hc-black .monaco-workbench .monaco-list-row .expression .error {
|
||||
color: #F48771;
|
||||
}
|
||||
|
||||
/* Dark theme */
|
||||
|
||||
.vs-dark .monaco-workbench .monaco-list-row:not(.selected) .expression .name {
|
||||
.vs-dark .monaco-workbench .monaco-list-row .expression .name {
|
||||
color: #C586C0;
|
||||
}
|
||||
|
||||
/* High Contrast Theming */
|
||||
|
||||
.hc-black .monaco-workbench .monaco-list-row:not(.selected) .expression .name {
|
||||
.hc-black .monaco-workbench .monaco-list-row .expression .name {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/* Debug repl */
|
||||
|
||||
.repl {
|
||||
.composite.panel .repl {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -393,7 +393,7 @@ export interface IDebugModel extends ITreeElement {
|
||||
getWatchExpressions(): ReadonlyArray<IExpression & IEvaluate>;
|
||||
|
||||
onDidChangeBreakpoints: Event<IBreakpointsChangeEvent>;
|
||||
onDidChangeCallStack: Event<void>;
|
||||
onDidChangeCallStack: Event<IThread | undefined>;
|
||||
onDidChangeWatchExpressions: Event<IExpression>;
|
||||
}
|
||||
|
||||
|
||||
@@ -644,6 +644,13 @@ export class Breakpoint extends BaseBreakpoint implements IBreakpoint {
|
||||
return data ? data.endColumn : undefined;
|
||||
}
|
||||
|
||||
setSessionData(sessionId: string, data: DebugProtocol.Breakpoint): void {
|
||||
super.setSessionData(sessionId, data);
|
||||
if (!this._adapterData) {
|
||||
this._adapterData = this.adapterData;
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(): any {
|
||||
const result = super.toJSON();
|
||||
result.uri = this.uri;
|
||||
@@ -737,7 +744,7 @@ export class DebugModel implements IDebugModel {
|
||||
private schedulers = new Map<string, RunOnceScheduler>();
|
||||
private breakpointsSessionId: string;
|
||||
private readonly _onDidChangeBreakpoints: Emitter<IBreakpointsChangeEvent>;
|
||||
private readonly _onDidChangeCallStack: Emitter<void>;
|
||||
private readonly _onDidChangeCallStack: Emitter<IThread | undefined>;
|
||||
private readonly _onDidChangeWatchExpressions: Emitter<IExpression>;
|
||||
|
||||
constructor(
|
||||
@@ -751,7 +758,7 @@ export class DebugModel implements IDebugModel {
|
||||
this.sessions = [];
|
||||
this.toDispose = [];
|
||||
this._onDidChangeBreakpoints = new Emitter<IBreakpointsChangeEvent>();
|
||||
this._onDidChangeCallStack = new Emitter<void>();
|
||||
this._onDidChangeCallStack = new Emitter<IThread | undefined>();
|
||||
this._onDidChangeWatchExpressions = new Emitter<IExpression>();
|
||||
}
|
||||
|
||||
@@ -786,7 +793,7 @@ export class DebugModel implements IDebugModel {
|
||||
return this._onDidChangeBreakpoints.event;
|
||||
}
|
||||
|
||||
get onDidChangeCallStack(): Event<void> {
|
||||
get onDidChangeCallStack(): Event<IThread | undefined> {
|
||||
return this._onDidChangeCallStack.event;
|
||||
}
|
||||
|
||||
@@ -819,12 +826,12 @@ export class DebugModel implements IDebugModel {
|
||||
return thread.fetchCallStack(1).then(() => {
|
||||
if (!this.schedulers.has(thread.getId())) {
|
||||
this.schedulers.set(thread.getId(), new RunOnceScheduler(() => {
|
||||
thread.fetchCallStack(19).then(() => this._onDidChangeCallStack.fire());
|
||||
thread.fetchCallStack(19).then(() => this._onDidChangeCallStack.fire(thread));
|
||||
}, 420));
|
||||
}
|
||||
|
||||
this.schedulers.get(thread.getId()).schedule();
|
||||
this._onDidChangeCallStack.fire();
|
||||
this._onDidChangeCallStack.fire(thread);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { KeybindingWeight, IKeybindings, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { KeybindingWeight, IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IWorkbenchActionRegistry, Extensions as WorkbenchActionRegistryExtensions } from 'vs/workbench/common/actions';
|
||||
import { ShowViewletAction, Extensions as ViewletExtensions, ViewletRegistry, ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
@@ -49,13 +49,11 @@ import { DebugViewlet } from 'vs/workbench/parts/debug/browser/debugViewlet';
|
||||
import { Repl, ClearReplAction } from 'vs/workbench/parts/debug/electron-browser/repl';
|
||||
import { DebugQuickOpenHandler } from 'vs/workbench/parts/debug/browser/debugQuickOpen';
|
||||
import { DebugStatus } from 'vs/workbench/parts/debug/browser/debugStatus';
|
||||
import { LifecyclePhase, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { launchSchemaId } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { LoadedScriptsView } from 'vs/workbench/parts/debug/browser/loadedScriptsView';
|
||||
import { TOGGLE_LOG_POINT_ID, TOGGLE_CONDITIONAL_BREAKPOINT_ID, TOGGLE_BREAKPOINT_ID } from 'vs/workbench/parts/debug/browser/debugEditorActions';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
class OpenDebugViewletAction extends ShowViewletAction {
|
||||
public static readonly ID = VIEWLET_ID;
|
||||
@@ -132,58 +130,7 @@ Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).regi
|
||||
|
||||
const debugCategory = nls.localize('debugCategory', "Debug");
|
||||
|
||||
const startDebugDescriptor = new SyncActionDescriptor(StartAction, StartAction.ID, StartAction.LABEL, { primary: KeyCode.F5 }, CONTEXT_IN_DEBUG_MODE.toNegated());
|
||||
|
||||
function startDebugHandler(accessor, args): Promise<void> {
|
||||
const notificationService = accessor.get(INotificationService);
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const lifecycleService = accessor.get(ILifecycleService);
|
||||
|
||||
return Promise.resolve(lifecycleService.when(LifecyclePhase.Ready).then(() => {
|
||||
const actionInstance = instantiationService.createInstance(startDebugDescriptor.syncDescriptor);
|
||||
try {
|
||||
// don't run the action when not enabled
|
||||
if (!actionInstance.enabled) {
|
||||
actionInstance.dispose();
|
||||
|
||||
return void 0;
|
||||
}
|
||||
|
||||
const from = args && args.from || 'keybinding';
|
||||
|
||||
if (args) {
|
||||
delete args.from;
|
||||
}
|
||||
|
||||
return Promise.resolve(actionInstance.run(args, { from })).then(() => {
|
||||
actionInstance.dispose();
|
||||
}, err => {
|
||||
actionInstance.dispose();
|
||||
|
||||
return Promise.reject(err);
|
||||
});
|
||||
} catch (err) {
|
||||
actionInstance.dispose();
|
||||
|
||||
return Promise.reject(err);
|
||||
}
|
||||
})).then(void 0, err => notificationService.error(err));
|
||||
}
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: StartAction.ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: CONTEXT_IN_DEBUG_MODE.toNegated(),
|
||||
primary: KeyCode.F5,
|
||||
handler: startDebugHandler
|
||||
});
|
||||
|
||||
MenuRegistry.addCommand({
|
||||
id: StartAction.ID,
|
||||
title: StartAction.LABEL,
|
||||
category: debugCategory
|
||||
});
|
||||
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(StartAction, StartAction.ID, StartAction.LABEL, { primary: KeyCode.F5 }), 'Debug: Start Debugging', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(StepOverAction, StepOverAction.ID, StepOverAction.LABEL, { primary: KeyCode.F10 }, CONTEXT_IN_DEBUG_MODE), 'Debug: Step Over', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(StepIntoAction, StepIntoAction.ID, StepIntoAction.LABEL, { primary: KeyCode.F11 }, CONTEXT_IN_DEBUG_MODE, KeybindingWeight.WorkbenchContrib + 1), 'Debug: Step Into', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(StepOutAction, StepOutAction.ID, StepOutAction.LABEL, { primary: KeyMod.Shift | KeyCode.F11 }, CONTEXT_IN_DEBUG_MODE), 'Debug: Step Out', debugCategory);
|
||||
|
||||
@@ -778,7 +778,7 @@ export class DebugService implements IDebugService {
|
||||
if (!stackFrame) {
|
||||
if (thread) {
|
||||
const callStack = thread.getCallStack();
|
||||
stackFrame = first(callStack, sf => sf.source && sf.source.available, undefined);
|
||||
stackFrame = first(callStack, sf => sf.source && sf.source.available && sf.source.presentationHint !== 'deemphasize', undefined);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -611,6 +611,16 @@ export class DebugSession implements IDebugSession {
|
||||
this.model.fetchCallStack(<Thread>thread).then(() => {
|
||||
if (!event.body.preserveFocusHint && thread.getCallStack().length) {
|
||||
this.debugService.focusStackFrame(undefined, thread);
|
||||
if (!this.debugService.getViewModel().focusedStackFrame) {
|
||||
// There were no appropriate stack frames to focus.
|
||||
// We need to listen on additional stack frame fetching and try to refocus #65012
|
||||
const listener = this.model.onDidChangeCallStack(t => {
|
||||
if (t && t.getId() === thread.getId()) {
|
||||
dispose(listener);
|
||||
this.debugService.focusStackFrame(undefined, thread);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (thread.stoppedDetails) {
|
||||
if (this.configurationService.getValue<IDebugConfiguration>('debug').openDebug === 'openOnDebugBreak') {
|
||||
this.viewletService.openViewlet(VIEWLET_ID);
|
||||
|
||||
@@ -118,7 +118,7 @@ export class WatchExpressionsView extends ViewletPanel {
|
||||
|
||||
const element = e.element;
|
||||
// double click on primitive value: open input box to be able to select and copy value.
|
||||
if (element instanceof Expression) {
|
||||
if (element instanceof Expression && element !== this.debugService.getViewModel().getSelectedExpression()) {
|
||||
this.debugService.getViewModel().setSelectedExpression(element);
|
||||
} else if (!element) {
|
||||
// Double click in watch panel triggers to add a new watch expression
|
||||
|
||||
@@ -34,7 +34,7 @@ suite('Debug - ANSI Handling', () => {
|
||||
|
||||
assert.equal(2, root.children.length);
|
||||
|
||||
child = root.firstChild;
|
||||
child = root.firstChild!;
|
||||
if (child instanceof HTMLSpanElement) {
|
||||
assert.equal('content1', child.textContent);
|
||||
assert(dom.hasClass(child, 'class1'));
|
||||
@@ -43,7 +43,7 @@ suite('Debug - ANSI Handling', () => {
|
||||
assert.fail('Unexpected assertion error');
|
||||
}
|
||||
|
||||
child = root.lastChild;
|
||||
child = root.lastChild!;
|
||||
if (child instanceof HTMLSpanElement) {
|
||||
assert.equal('content2', child.textContent);
|
||||
assert(dom.hasClass(child, 'class2'));
|
||||
@@ -62,12 +62,12 @@ suite('Debug - ANSI Handling', () => {
|
||||
function getSequenceOutput(sequence: string): HTMLSpanElement {
|
||||
const root: HTMLSpanElement = handleANSIOutput(sequence, linkDetector);
|
||||
assert.equal(1, root.children.length);
|
||||
const child: Node = root.lastChild;
|
||||
const child: Node = root.lastChild!;
|
||||
if (child instanceof HTMLSpanElement) {
|
||||
return child;
|
||||
} else {
|
||||
assert.fail('Unexpected assertion error');
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ suite('Debug - Debugger', () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
variables: null,
|
||||
variables: null!,
|
||||
initialConfigurations: [
|
||||
{
|
||||
name: 'Mock-Debug',
|
||||
@@ -57,7 +57,7 @@ suite('Debug - Debugger', () => {
|
||||
extensionLocation: URI.file(extensionFolderPath),
|
||||
isBuiltin: false,
|
||||
isUnderDevelopment: false,
|
||||
engines: null,
|
||||
engines: null!,
|
||||
contributes: {
|
||||
'debuggers': [
|
||||
debuggerContribution
|
||||
@@ -74,7 +74,7 @@ suite('Debug - Debugger', () => {
|
||||
extensionLocation: URI.file('/e1/b/c/'),
|
||||
isBuiltin: false,
|
||||
isUnderDevelopment: false,
|
||||
engines: null,
|
||||
engines: null!,
|
||||
contributes: {
|
||||
'debuggers': [
|
||||
{
|
||||
@@ -97,7 +97,7 @@ suite('Debug - Debugger', () => {
|
||||
extensionLocation: URI.file('/e2/b/c/'),
|
||||
isBuiltin: false,
|
||||
isUnderDevelopment: false,
|
||||
engines: null,
|
||||
engines: null!,
|
||||
contributes: {
|
||||
'debuggers': [
|
||||
{
|
||||
@@ -130,11 +130,11 @@ suite('Debug - Debugger', () => {
|
||||
const testResourcePropertiesService = new TestTextResourcePropertiesService(configurationService);
|
||||
|
||||
setup(() => {
|
||||
_debugger = new Debugger(configurationManager, debuggerContribution, extensionDescriptor0, configurationService, testResourcePropertiesService, undefined, undefined, undefined);
|
||||
_debugger = new Debugger(configurationManager, debuggerContribution, extensionDescriptor0, configurationService, testResourcePropertiesService, undefined!, undefined!, undefined!);
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
_debugger = null;
|
||||
_debugger = null!;
|
||||
});
|
||||
|
||||
test('attributes', () => {
|
||||
@@ -143,8 +143,8 @@ suite('Debug - Debugger', () => {
|
||||
|
||||
const ae = ExecutableDebugAdapter.platformAdapterExecutable([extensionDescriptor0], 'mock');
|
||||
|
||||
assert.equal(ae.command, paths.join(extensionFolderPath, debuggerContribution.program));
|
||||
assert.deepEqual(ae.args, debuggerContribution.args);
|
||||
assert.equal(ae!.command, paths.join(extensionFolderPath, debuggerContribution.program));
|
||||
assert.deepEqual(ae!.args, debuggerContribution.args);
|
||||
});
|
||||
|
||||
test('schema attributes', () => {
|
||||
@@ -155,14 +155,14 @@ suite('Debug - Debugger', () => {
|
||||
});
|
||||
|
||||
assert.equal(schemaAttribute['additionalProperties'], false);
|
||||
assert.equal(!!schemaAttribute['properties']['request'], true);
|
||||
assert.equal(!!schemaAttribute['properties']['name'], true);
|
||||
assert.equal(!!schemaAttribute['properties']['type'], true);
|
||||
assert.equal(!!schemaAttribute['properties']['preLaunchTask'], true);
|
||||
assert.equal(!!schemaAttribute['properties']!['request'], true);
|
||||
assert.equal(!!schemaAttribute['properties']!['name'], true);
|
||||
assert.equal(!!schemaAttribute['properties']!['type'], true);
|
||||
assert.equal(!!schemaAttribute['properties']!['preLaunchTask'], true);
|
||||
});
|
||||
|
||||
test('merge platform specific attributes', () => {
|
||||
const ae = ExecutableDebugAdapter.platformAdapterExecutable([extensionDescriptor1, extensionDescriptor2], 'mock');
|
||||
const ae = ExecutableDebugAdapter.platformAdapterExecutable([extensionDescriptor1, extensionDescriptor2], 'mock')!;
|
||||
assert.equal(ae.command, platform.isLinux ? 'linuxRuntime' : (platform.isMacintosh ? 'osxRuntime' : 'winRuntime'));
|
||||
const xprogram = platform.isLinux ? 'linuxProgram' : (platform.isMacintosh ? 'osxProgram' : 'winProgram');
|
||||
assert.deepEqual(ae.args, ['rarg', '/e2/b/c/' + xprogram, 'parg']);
|
||||
|
||||
+19
-13
@@ -27,7 +27,13 @@ import { URI } from 'vs/base/common/uri';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { lastSessionDateStorageKey } from 'vs/platform/telemetry/node/workbenchCommonProperties';
|
||||
|
||||
let experimentData = {
|
||||
interface ExperimentSettings {
|
||||
enabled?: boolean;
|
||||
id?: string;
|
||||
state?: ExperimentState;
|
||||
}
|
||||
|
||||
let experimentData: { [i: string]: any } = {
|
||||
experiments: []
|
||||
};
|
||||
|
||||
@@ -495,9 +501,9 @@ suite('Experiment Service', () => {
|
||||
]
|
||||
};
|
||||
|
||||
let storageDataExperiment1 = { enabled: false };
|
||||
let storageDataExperiment2 = { enabled: false };
|
||||
let storageDataAllExperiments = ['experiment1', 'experiment2', 'experiment3'];
|
||||
let storageDataExperiment1: ExperimentSettings | null = { enabled: false };
|
||||
let storageDataExperiment2: ExperimentSettings | null = { enabled: false };
|
||||
let storageDataAllExperiments: string[] | null = ['experiment1', 'experiment2', 'experiment3'];
|
||||
instantiationService.stub(IStorageService, {
|
||||
get: (a, b, c) => {
|
||||
switch (a) {
|
||||
@@ -554,8 +560,8 @@ suite('Experiment Service', () => {
|
||||
assert.equal(!!storageDataExperiment2, false);
|
||||
});
|
||||
return Promise.all([disabledExperiment, deletedExperiment]).then(() => {
|
||||
assert.equal(storageDataAllExperiments.length, 1);
|
||||
assert.equal(storageDataAllExperiments[0], 'experiment3');
|
||||
assert.equal(storageDataAllExperiments!.length, 1);
|
||||
assert.equal(storageDataAllExperiments![0], 'experiment3');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -565,11 +571,11 @@ suite('Experiment Service', () => {
|
||||
experiments: null
|
||||
};
|
||||
|
||||
let storageDataExperiment1 = { enabled: true, state: ExperimentState.Run };
|
||||
let storageDataExperiment2 = { enabled: true, state: ExperimentState.NoRun };
|
||||
let storageDataExperiment3 = { enabled: true, state: ExperimentState.Evaluating };
|
||||
let storageDataExperiment4 = { enabled: true, state: ExperimentState.Complete };
|
||||
let storageDataAllExperiments = ['experiment1', 'experiment2', 'experiment3', 'experiment4'];
|
||||
let storageDataExperiment1: ExperimentSettings | null = { enabled: true, state: ExperimentState.Run };
|
||||
let storageDataExperiment2: ExperimentSettings | null = { enabled: true, state: ExperimentState.NoRun };
|
||||
let storageDataExperiment3: ExperimentSettings | null = { enabled: true, state: ExperimentState.Evaluating };
|
||||
let storageDataExperiment4: ExperimentSettings | null = { enabled: true, state: ExperimentState.Complete };
|
||||
let storageDataAllExperiments: string[] | null = ['experiment1', 'experiment2', 'experiment3', 'experiment4'];
|
||||
instantiationService.stub(IStorageService, {
|
||||
get: (a, b, c) => {
|
||||
switch (a) {
|
||||
@@ -718,9 +724,9 @@ suite('Experiment Service', () => {
|
||||
assert.equal(result.length, 3);
|
||||
assert.equal(result[0].id, 'simple-experiment');
|
||||
assert.equal(result[1].id, 'custom-experiment');
|
||||
assert.equal(result[1].action.properties, customProperties);
|
||||
assert.equal(result[1].action!.properties, customProperties);
|
||||
assert.equal(result[2].id, 'custom-experiment-no-properties');
|
||||
assert.equal(!!result[2].action.properties, true);
|
||||
assert.equal(!!result[2].action!.properties, true);
|
||||
});
|
||||
const prompt = testObject.getExperimentsByType(ExperimentActionType.Prompt).then(result => {
|
||||
assert.equal(result.length, 2);
|
||||
|
||||
@@ -1285,7 +1285,7 @@ suite('ExtensionsActions Test', () => {
|
||||
}
|
||||
|
||||
function aPage<T>(...objects: T[]): IPager<T> {
|
||||
return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null };
|
||||
return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null! };
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
+5
-5
@@ -139,18 +139,18 @@ const mockTestData = {
|
||||
};
|
||||
|
||||
function aPage<T>(...objects: T[]): IPager<T> {
|
||||
return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null };
|
||||
return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null! };
|
||||
}
|
||||
|
||||
const noAssets: IGalleryExtensionAssets = {
|
||||
changelog: null,
|
||||
download: null,
|
||||
icon: null,
|
||||
download: null!,
|
||||
icon: null!,
|
||||
license: null,
|
||||
manifest: null,
|
||||
readme: null,
|
||||
repository: null,
|
||||
coreTranslations: null
|
||||
coreTranslations: null!
|
||||
};
|
||||
|
||||
function aGalleryExtension(name: string, properties: any = {}, galleryExtensionProperties: any = {}, assets: IGalleryExtensionAssets = noAssets): IGalleryExtension {
|
||||
@@ -235,7 +235,7 @@ suite('ExtensionsTipsService Test', () => {
|
||||
class TestNotificationService2 extends TestNotificationService {
|
||||
public prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions) {
|
||||
prompted = true;
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -324,10 +324,10 @@ suite('ExtensionsListView Tests', () => {
|
||||
return testableView.show('@recommended:workspace').then(result => {
|
||||
assert.ok(target.calledOnce);
|
||||
const options: IQueryOptions = target.args[0][0];
|
||||
assert.equal(options.names.length, workspaceRecommendedExtensions.length);
|
||||
assert.equal(options.names!.length, workspaceRecommendedExtensions.length);
|
||||
assert.equal(result.length, workspaceRecommendedExtensions.length);
|
||||
for (let i = 0; i < workspaceRecommendedExtensions.length; i++) {
|
||||
assert.equal(options.names[i], workspaceRecommendedExtensions[i].identifier.id);
|
||||
assert.equal(options.names![i], workspaceRecommendedExtensions[i].identifier.id);
|
||||
assert.equal(result.get(i).identifier.id, workspaceRecommendedExtensions[i].identifier.id);
|
||||
}
|
||||
});
|
||||
@@ -345,10 +345,10 @@ suite('ExtensionsListView Tests', () => {
|
||||
const options: IQueryOptions = target.args[0][0];
|
||||
|
||||
assert.ok(target.calledOnce);
|
||||
assert.equal(options.names.length, allRecommendedExtensions.length);
|
||||
assert.equal(options.names!.length, allRecommendedExtensions.length);
|
||||
assert.equal(result.length, allRecommendedExtensions.length);
|
||||
for (let i = 0; i < allRecommendedExtensions.length; i++) {
|
||||
assert.equal(options.names[i], allRecommendedExtensions[i].identifier.id);
|
||||
assert.equal(options.names![i], allRecommendedExtensions[i].identifier.id);
|
||||
assert.equal(result.get(i).identifier.id, allRecommendedExtensions[i].identifier.id);
|
||||
}
|
||||
});
|
||||
@@ -369,10 +369,10 @@ suite('ExtensionsListView Tests', () => {
|
||||
const options: IQueryOptions = target.args[0][0];
|
||||
|
||||
assert.ok(target.calledOnce);
|
||||
assert.equal(options.names.length, allRecommendedExtensions.length);
|
||||
assert.equal(options.names!.length, allRecommendedExtensions.length);
|
||||
assert.equal(result.length, allRecommendedExtensions.length);
|
||||
for (let i = 0; i < allRecommendedExtensions.length; i++) {
|
||||
assert.equal(options.names[i], allRecommendedExtensions[i].identifier.id);
|
||||
assert.equal(options.names![i], allRecommendedExtensions[i].identifier.id);
|
||||
assert.equal(result.get(i).identifier.id, allRecommendedExtensions[i].identifier.id);
|
||||
}
|
||||
});
|
||||
@@ -392,10 +392,10 @@ suite('ExtensionsListView Tests', () => {
|
||||
|
||||
assert.ok(experimentTarget.calledOnce);
|
||||
assert.ok(queryTarget.calledOnce);
|
||||
assert.equal(options.names.length, curatedList.length);
|
||||
assert.equal(options.names!.length, curatedList.length);
|
||||
assert.equal(result.length, curatedList.length);
|
||||
for (let i = 0; i < curatedList.length; i++) {
|
||||
assert.equal(options.names[i], curatedList[i].identifier.id);
|
||||
assert.equal(options.names![i], curatedList[i].identifier.id);
|
||||
assert.equal(result.get(i).identifier.id, curatedList[i].identifier.id);
|
||||
}
|
||||
assert.equal(curatedKey, 'mykey');
|
||||
@@ -518,7 +518,7 @@ suite('ExtensionsListView Tests', () => {
|
||||
}
|
||||
|
||||
function aPage<T>(...objects: T[]): IPager<T> {
|
||||
return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null };
|
||||
return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null! };
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+41
-41
@@ -488,28 +488,28 @@ suite('ExtensionsWorkbenchServiceTest', () => {
|
||||
return testObject.queryGallery().then(page => {
|
||||
const extension = page.firstPage[0];
|
||||
return testObject.loadDependencies(extension, CancellationToken.None).then(actual => {
|
||||
assert.ok(actual.hasDependencies);
|
||||
assert.equal(extension, actual.extension);
|
||||
assert.equal(null, actual.dependent);
|
||||
assert.equal(3, actual.dependencies.length);
|
||||
assert.equal('pub.a', actual.identifier);
|
||||
assert.ok(actual!.hasDependencies);
|
||||
assert.equal(extension, actual!.extension);
|
||||
assert.equal(null, actual!.dependent);
|
||||
assert.equal(3, actual!.dependencies.length);
|
||||
assert.equal('pub.a', actual!.identifier);
|
||||
let dependent = actual;
|
||||
|
||||
actual = dependent.dependencies[0];
|
||||
actual = dependent!.dependencies[0];
|
||||
assert.ok(!actual.hasDependencies);
|
||||
assert.equal('pub.b', actual.extension.identifier.id);
|
||||
assert.equal('pub.b', actual.identifier);
|
||||
assert.equal(dependent, actual.dependent);
|
||||
assert.equal(0, actual.dependencies.length);
|
||||
|
||||
actual = dependent.dependencies[1];
|
||||
actual = dependent!.dependencies[1];
|
||||
assert.ok(!actual.hasDependencies);
|
||||
assert.equal('pub.c', actual.extension.identifier.id);
|
||||
assert.equal('pub.c', actual.identifier);
|
||||
assert.equal(dependent, actual.dependent);
|
||||
assert.equal(0, actual.dependencies.length);
|
||||
|
||||
actual = dependent.dependencies[2];
|
||||
actual = dependent!.dependencies[2];
|
||||
assert.ok(!actual.hasDependencies);
|
||||
assert.equal('pub.d', actual.extension.identifier.id);
|
||||
assert.equal('pub.d', actual.identifier);
|
||||
@@ -527,21 +527,21 @@ suite('ExtensionsWorkbenchServiceTest', () => {
|
||||
return testObject.queryGallery().then(page => {
|
||||
const extension = page.firstPage[0];
|
||||
return testObject.loadDependencies(extension, CancellationToken.None).then(actual => {
|
||||
assert.ok(actual.hasDependencies);
|
||||
assert.equal(extension, actual.extension);
|
||||
assert.equal(null, actual.dependent);
|
||||
assert.equal(2, actual.dependencies.length);
|
||||
assert.equal('pub.a', actual.identifier);
|
||||
assert.ok(actual!.hasDependencies);
|
||||
assert.equal(extension, actual!.extension);
|
||||
assert.equal(null, actual!.dependent);
|
||||
assert.equal(2, actual!.dependencies.length);
|
||||
assert.equal('pub.a', actual!.identifier);
|
||||
let dependent = actual;
|
||||
|
||||
actual = dependent.dependencies[0];
|
||||
actual = dependent!.dependencies[0]!;
|
||||
assert.ok(!actual.hasDependencies);
|
||||
assert.equal('pub.b', actual.extension.identifier.id);
|
||||
assert.equal('pub.b', actual.identifier);
|
||||
assert.equal(dependent, actual.dependent);
|
||||
assert.equal(0, actual.dependencies.length);
|
||||
|
||||
actual = dependent.dependencies[1];
|
||||
actual = dependent!.dependencies[1]!;
|
||||
assert.ok(!actual.hasDependencies);
|
||||
assert.equal('pub.a', actual.extension.identifier.id);
|
||||
assert.equal('pub.a', actual.identifier);
|
||||
@@ -559,21 +559,21 @@ suite('ExtensionsWorkbenchServiceTest', () => {
|
||||
return testObject.queryGallery().then(page => {
|
||||
const extension = page.firstPage[0];
|
||||
return testObject.loadDependencies(extension, CancellationToken.None).then(actual => {
|
||||
assert.ok(actual.hasDependencies);
|
||||
assert.equal(extension, actual.extension);
|
||||
assert.equal(null, actual.dependent);
|
||||
assert.equal(2, actual.dependencies.length);
|
||||
assert.equal('pub.a', actual.identifier);
|
||||
assert.ok(actual!.hasDependencies);
|
||||
assert.equal(extension, actual!.extension);
|
||||
assert.equal(null, actual!.dependent);
|
||||
assert.equal(2, actual!.dependencies.length);
|
||||
assert.equal('pub.a', actual!.identifier);
|
||||
let dependent = actual;
|
||||
|
||||
actual = dependent.dependencies[0];
|
||||
actual = dependent!.dependencies[0]!;
|
||||
assert.ok(!actual.hasDependencies);
|
||||
assert.equal(null, actual.extension);
|
||||
assert.equal('pub.b', actual.identifier);
|
||||
assert.equal(dependent, actual.dependent);
|
||||
assert.equal(0, actual.dependencies.length);
|
||||
|
||||
actual = dependent.dependencies[1];
|
||||
actual = dependent!.dependencies[1]!;
|
||||
assert.ok(!actual.hasDependencies);
|
||||
assert.equal('pub.a', actual.extension.identifier.id);
|
||||
assert.equal('pub.a', actual.identifier);
|
||||
@@ -593,14 +593,14 @@ suite('ExtensionsWorkbenchServiceTest', () => {
|
||||
return testObject.queryGallery().then(page => {
|
||||
const extension = page.firstPage[0];
|
||||
return testObject.loadDependencies(extension, CancellationToken.None).then(actual => {
|
||||
assert.ok(actual.hasDependencies);
|
||||
assert.equal(extension, actual.extension);
|
||||
assert.equal(null, actual.dependent);
|
||||
assert.equal(2, actual.dependencies.length);
|
||||
assert.equal('pub.a', actual.identifier);
|
||||
assert.ok(actual!.hasDependencies);
|
||||
assert.equal(extension, actual!.extension);
|
||||
assert.equal(null, actual!.dependent);
|
||||
assert.equal(2, actual!.dependencies.length);
|
||||
assert.equal('pub.a', actual!.identifier);
|
||||
let dependent = actual;
|
||||
|
||||
actual = dependent.dependencies[0];
|
||||
actual = dependent!.dependencies[0]!;
|
||||
assert.ok(!actual.hasDependencies);
|
||||
assert.equal('pub.inbuilt', actual.extension.identifier.id);
|
||||
assert.equal('pub.inbuilt', actual.identifier);
|
||||
@@ -608,7 +608,7 @@ suite('ExtensionsWorkbenchServiceTest', () => {
|
||||
assert.equal(0, actual.dependencies.length);
|
||||
|
||||
|
||||
actual = dependent.dependencies[1];
|
||||
actual = dependent!.dependencies[1]!;
|
||||
assert.ok(!actual.hasDependencies);
|
||||
assert.equal('pub.a', actual.extension.identifier.id);
|
||||
assert.equal('pub.a', actual.identifier);
|
||||
@@ -631,20 +631,20 @@ suite('ExtensionsWorkbenchServiceTest', () => {
|
||||
return testObject.queryGallery().then(page => {
|
||||
const extension = page.firstPage[0];
|
||||
return testObject.loadDependencies(extension, CancellationToken.None).then(a => {
|
||||
assert.ok(a.hasDependencies);
|
||||
assert.equal(extension, a.extension);
|
||||
assert.equal(null, a.dependent);
|
||||
assert.equal(2, a.dependencies.length);
|
||||
assert.equal('pub.a', a.identifier);
|
||||
assert.ok(a!.hasDependencies);
|
||||
assert.equal(extension, a!.extension);
|
||||
assert.equal(null, a!.dependent);
|
||||
assert.equal(2, a!.dependencies.length);
|
||||
assert.equal('pub.a', a!.identifier);
|
||||
|
||||
let b = a.dependencies[0];
|
||||
let b = a!.dependencies[0];
|
||||
assert.ok(b.hasDependencies);
|
||||
assert.equal('pub.b', b.extension.identifier.id);
|
||||
assert.equal('pub.b', b.identifier);
|
||||
assert.equal(a, b.dependent);
|
||||
assert.equal(2, b.dependencies.length);
|
||||
|
||||
let c = a.dependencies[1];
|
||||
let c = a!.dependencies[1];
|
||||
assert.ok(c.hasDependencies);
|
||||
assert.equal('pub.c', c.extension.identifier.id);
|
||||
assert.equal('pub.c', c.identifier);
|
||||
@@ -686,7 +686,7 @@ suite('ExtensionsWorkbenchServiceTest', () => {
|
||||
assert.equal(c, d.dependent);
|
||||
assert.equal(0, d.dependencies.length);
|
||||
|
||||
c = a.dependencies[1];
|
||||
c = a!.dependencies[1];
|
||||
d = c.dependencies[0];
|
||||
assert.ok(d.hasDependencies);
|
||||
assert.equal('pub.d', d.extension.identifier.id);
|
||||
@@ -1192,13 +1192,13 @@ suite('ExtensionsWorkbenchServiceTest', () => {
|
||||
|
||||
const noAssets: IGalleryExtensionAssets = {
|
||||
changelog: null,
|
||||
download: null,
|
||||
icon: null,
|
||||
download: null!,
|
||||
icon: null!,
|
||||
license: null,
|
||||
manifest: null,
|
||||
readme: null,
|
||||
repository: null,
|
||||
coreTranslations: null
|
||||
coreTranslations: null!
|
||||
};
|
||||
|
||||
function aGalleryExtension(name: string, properties: any = {}, galleryExtensionProperties: any = {}, assets: IGalleryExtensionAssets = noAssets): IGalleryExtension {
|
||||
@@ -1211,7 +1211,7 @@ suite('ExtensionsWorkbenchServiceTest', () => {
|
||||
}
|
||||
|
||||
function aPage<T>(...objects: T[]): IPager<T> {
|
||||
return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null };
|
||||
return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null! };
|
||||
}
|
||||
|
||||
function eventToPromise(event: Event<any>, count: number = 1): Promise<void> {
|
||||
|
||||
@@ -277,7 +277,7 @@ export class OpenEditorsView extends ViewletPanel {
|
||||
const element = focused.length ? focused[0] : undefined;
|
||||
if (element instanceof OpenEditor) {
|
||||
this.openEditor(element, { preserveFocus: isSingleClick, pinned: isDoubleClick, sideBySide: openToSide });
|
||||
} else {
|
||||
} else if (element) {
|
||||
this.editorGroupService.activateGroup(element);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -189,7 +189,7 @@ suite('Files - View Model', () => {
|
||||
const sChild = createStat('/path/to/stat/alles.klar', 'alles.klar', true, true, 8096, d);
|
||||
s.addChild(sChild);
|
||||
|
||||
assert(validateFileName(s, null) !== null);
|
||||
assert(validateFileName(s, null!) !== null);
|
||||
assert(validateFileName(s, '') !== null);
|
||||
assert(validateFileName(s, ' ') !== null);
|
||||
assert(validateFileName(s, 'Read Me') === null, 'name containing space');
|
||||
@@ -282,6 +282,6 @@ suite('Files - View Model', () => {
|
||||
// Verify that merge does not replace existing children, but updates properties in that case
|
||||
const existingChild = merge1.getChild('foo.html');
|
||||
ExplorerItem.mergeLocalWithDisk(merge2, merge1);
|
||||
assert.ok(existingChild === merge1.getChild(existingChild.name));
|
||||
assert.ok(existingChild === merge1.getChild(existingChild!.name));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,311 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { IWindowService } from 'vs/platform/windows/common/windows';
|
||||
import * as nls from 'vs/nls';
|
||||
import product from 'vs/platform/node/product';
|
||||
import pkg from 'vs/platform/node/package';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IIntegrityService } from 'vs/platform/integrity/common/integrity';
|
||||
import { ITimerService, IStartupMetrics } from 'vs/workbench/services/timer/electron-browser/timerService';
|
||||
import * as os from 'os';
|
||||
import { IExtensionService, ActivationTimes } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { getEntries } from 'vs/base/common/performance';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { StartupKindToString } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { forEach } from 'vs/base/common/collections';
|
||||
import { mergeSort } from 'vs/base/common/arrays';
|
||||
|
||||
class Info {
|
||||
|
||||
static getTimerInfo(metrics: IStartupMetrics, nodeModuleLoadTime?: number): { [name: string]: Info } {
|
||||
const table: { [name: string]: Info } = Object.create(null);
|
||||
table['start => app.isReady'] = new Info(metrics.timers.ellapsedAppReady, '[main]', `initial startup: ${metrics.initialStartup}`);
|
||||
table['nls:start => nls:end'] = new Info(metrics.timers.ellapsedNlsGeneration, '[main]', `initial startup: ${metrics.initialStartup}`);
|
||||
table['app.isReady => window.loadUrl()'] = new Info(metrics.timers.ellapsedWindowLoad, '[main]', `initial startup: ${metrics.initialStartup}`);
|
||||
|
||||
table['require & init global storage'] = new Info(metrics.timers.ellapsedGlobalStorageInitMain, '[main]', `initial startup: ${metrics.initialStartup}`);
|
||||
|
||||
table['window.loadUrl() => begin to require(workbench.main.js)'] = new Info(metrics.timers.ellapsedWindowLoadToRequire, '[main->renderer]', StartupKindToString(metrics.windowKind));
|
||||
table['require(workbench.main.js)'] = new Info(metrics.timers.ellapsedRequire, '[renderer]', `cached data: ${(metrics.didUseCachedData ? 'YES' : 'NO')}${nodeModuleLoadTime ? `, node_modules took ${nodeModuleLoadTime}ms` : ''}`);
|
||||
|
||||
table['init global storage'] = new Info(metrics.timers.ellapsedGlobalStorageInitRenderer, '[renderer]');
|
||||
table['require workspace storage'] = new Info(metrics.timers.ellapsedWorkspaceStorageRequire, '[renderer]');
|
||||
table['require & init workspace storage'] = new Info(metrics.timers.ellapsedWorkspaceStorageInit, '[renderer]');
|
||||
|
||||
table['init workspace service'] = new Info(metrics.timers.ellapsedWorkspaceServiceInit, '[renderer]');
|
||||
|
||||
table['register extensions & spawn extension host'] = new Info(metrics.timers.ellapsedExtensions, '[renderer]');
|
||||
table['restore viewlet'] = new Info(metrics.timers.ellapsedViewletRestore, '[renderer]', metrics.viewletId);
|
||||
table['restore panel'] = new Info(metrics.timers.ellapsedPanelRestore, '[renderer]', metrics.panelId);
|
||||
table['restore editors'] = new Info(metrics.timers.ellapsedEditorRestore, '[renderer]', `${metrics.editorIds.length}: ${metrics.editorIds.join(', ')}`);
|
||||
table['overall workbench load'] = new Info(metrics.timers.ellapsedWorkbench, '[renderer]');
|
||||
|
||||
table['workbench ready'] = new Info(metrics.ellapsed, '[main->renderer]');
|
||||
table['extensions registered'] = new Info(metrics.timers.ellapsedExtensionsReady, '[renderer]');
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private constructor(readonly duration: number, readonly process: string, readonly info: string | boolean = '') { }
|
||||
}
|
||||
|
||||
class LoaderStat {
|
||||
|
||||
static getLoaderStats() {
|
||||
|
||||
let seq = 1;
|
||||
const amdLoad = new Map<string, LoaderStat>();
|
||||
const amdInvoke = new Map<string, LoaderStat>();
|
||||
const nodeRequire = new Map<string, LoaderStat>();
|
||||
const nodeEval = new Map<string, LoaderStat>();
|
||||
|
||||
function mark(map: Map<string, LoaderStat>, stat: LoaderEvent) {
|
||||
if (map.has(stat.detail)) {
|
||||
// console.warn('BAD events, DOUBLE start', stat);
|
||||
// map.delete(stat.detail);
|
||||
return;
|
||||
}
|
||||
map.set(stat.detail, new LoaderStat(-stat.timestamp, seq++));
|
||||
}
|
||||
|
||||
function diff(map: Map<string, LoaderStat>, stat: LoaderEvent) {
|
||||
let obj = map.get(stat.detail);
|
||||
if (!obj) {
|
||||
// console.warn('BAD events, end WITHOUT start', stat);
|
||||
// map.delete(stat.detail);
|
||||
return;
|
||||
}
|
||||
if (obj.duration >= 0) {
|
||||
// console.warn('BAD events, DOUBLE end', stat);
|
||||
// map.delete(stat.detail);
|
||||
return;
|
||||
}
|
||||
obj.duration = (obj.duration + stat.timestamp);
|
||||
}
|
||||
|
||||
const stats = mergeSort(require.getStats().slice(0), (a, b) => a.timestamp - b.timestamp);
|
||||
|
||||
for (const stat of stats) {
|
||||
switch (stat.type) {
|
||||
case LoaderEventType.BeginLoadingScript:
|
||||
mark(amdLoad, stat);
|
||||
break;
|
||||
case LoaderEventType.EndLoadingScriptOK:
|
||||
case LoaderEventType.EndLoadingScriptError:
|
||||
diff(amdLoad, stat);
|
||||
break;
|
||||
|
||||
case LoaderEventType.BeginInvokeFactory:
|
||||
mark(amdInvoke, stat);
|
||||
break;
|
||||
case LoaderEventType.EndInvokeFactory:
|
||||
diff(amdInvoke, stat);
|
||||
break;
|
||||
|
||||
case LoaderEventType.NodeBeginNativeRequire:
|
||||
mark(nodeRequire, stat);
|
||||
break;
|
||||
case LoaderEventType.NodeEndNativeRequire:
|
||||
diff(nodeRequire, stat);
|
||||
break;
|
||||
|
||||
case LoaderEventType.NodeBeginEvaluatingScript:
|
||||
mark(nodeEval, stat);
|
||||
break;
|
||||
case LoaderEventType.NodeEndEvaluatingScript:
|
||||
diff(nodeEval, stat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function toObject(map: Map<string, any>): { [name: string]: any } {
|
||||
const result = Object.create(null);
|
||||
map.forEach((value, index) => result[index] = value);
|
||||
return result;
|
||||
}
|
||||
|
||||
let nodeRequireTotal = 0;
|
||||
nodeRequire.forEach(value => nodeRequireTotal += value.duration);
|
||||
|
||||
return {
|
||||
amdLoad: toObject(amdLoad),
|
||||
amdInvoke: toObject(amdInvoke),
|
||||
nodeRequire: toObject(nodeRequire),
|
||||
nodeEval: toObject(nodeEval),
|
||||
nodeRequireTotal
|
||||
};
|
||||
}
|
||||
|
||||
constructor(public duration: number, public seq: number) { }
|
||||
}
|
||||
|
||||
export class ShowStartupPerformance extends Action {
|
||||
|
||||
static readonly ID = 'workbench.action.appPerf';
|
||||
static readonly LABEL = nls.localize('appPerf', "Startup Performance");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IWindowService private windowService: IWindowService,
|
||||
@ITimerService private timerService: ITimerService,
|
||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||
@IExtensionService private extensionService: IExtensionService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Promise<boolean> {
|
||||
|
||||
// Show dev tools
|
||||
this.windowService.openDevTools();
|
||||
|
||||
Promise.all([
|
||||
timeout(1000), // needed to print a table
|
||||
this.timerService.startupMetrics
|
||||
]).then(([, metrics]) => {
|
||||
|
||||
console.group('Startup Performance Measurement');
|
||||
console.log(`OS: ${metrics.platform}(${metrics.release})`);
|
||||
console.log(`CPUs: ${metrics.cpus.model}(${metrics.cpus.count} x ${metrics.cpus.speed})`);
|
||||
console.log(`Memory(System): ${(metrics.totalmem / (1024 * 1024 * 1024)).toFixed(2)} GB(${(metrics.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free)`);
|
||||
console.log(`Memory(Process): ${(metrics.meminfo.workingSetSize / 1024).toFixed(2)} MB working set(${(metrics.meminfo.peakWorkingSetSize / 1024).toFixed(2)}MB peak, ${(metrics.meminfo.privateBytes / 1024).toFixed(2)}MB private, ${(metrics.meminfo.sharedBytes / 1024).toFixed(2)}MB shared)`);
|
||||
console.log(`VM(likelyhood): ${metrics.isVMLikelyhood}% `);
|
||||
|
||||
console.log(`Initial Startup: ${metrics.initialStartup} `);
|
||||
console.log(`Has ${metrics.windowCount - 1} other windows`);
|
||||
console.log(`Screen Reader Active: ${metrics.hasAccessibilitySupport} `);
|
||||
console.log(`Empty Workspace: ${metrics.emptyWorkbench} `);
|
||||
|
||||
|
||||
const loaderStats = this.environmentService.performance && LoaderStat.getLoaderStats();
|
||||
|
||||
console.table(Info.getTimerInfo(metrics, loaderStats && loaderStats.nodeRequireTotal));
|
||||
|
||||
if (loaderStats) {
|
||||
for (const key in loaderStats) {
|
||||
console.groupCollapsed(`Loader: ${key} `);
|
||||
console.table(loaderStats[key]);
|
||||
console.groupEnd();
|
||||
}
|
||||
}
|
||||
|
||||
console.groupEnd();
|
||||
|
||||
console.group('Extension Activation Stats');
|
||||
let extensionsActivationTimes: { [id: string]: ActivationTimes; } = {};
|
||||
let extensionsStatus = this.extensionService.getExtensionsStatus();
|
||||
for (let id in extensionsStatus) {
|
||||
const status = extensionsStatus[id];
|
||||
if (status.activationTimes) {
|
||||
extensionsActivationTimes[id] = status.activationTimes;
|
||||
}
|
||||
}
|
||||
console.table(extensionsActivationTimes);
|
||||
console.groupEnd();
|
||||
|
||||
console.group('Raw Startup Timers (CSV)');
|
||||
let value = `Name\tStart\n`;
|
||||
let entries = getEntries('mark');
|
||||
for (const entry of entries) {
|
||||
value += `${entry.name} \t${entry.startTime} \n`;
|
||||
}
|
||||
console.log(value);
|
||||
console.groupEnd();
|
||||
});
|
||||
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// NOTE: This is still used when running --prof-startup, which already opens a dialog, so the reporter is not used.
|
||||
export class ReportPerformanceIssueAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.action.reportPerformanceIssue';
|
||||
static readonly LABEL = nls.localize('reportPerformanceIssue', "Report Performance Issue");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IIntegrityService private integrityService: IIntegrityService,
|
||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||
@ITimerService private timerService: ITimerService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(appendix?: string): Promise<boolean> {
|
||||
Promise.all([
|
||||
this.timerService.startupMetrics,
|
||||
this.integrityService.isPure()
|
||||
]).then(([metrics, integrity]) => {
|
||||
const issueUrl = this.generatePerformanceIssueUrl(metrics, product.reportIssueUrl, pkg.name, pkg.version, product.commit, product.date, integrity.isPure, appendix);
|
||||
|
||||
window.open(issueUrl);
|
||||
});
|
||||
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
private generatePerformanceIssueUrl(metrics: IStartupMetrics, baseUrl: string, name: string, version: string, _commit: string, _date: string, isPure: boolean, appendix?: string): string {
|
||||
|
||||
if (!appendix) {
|
||||
appendix = `Additional Steps to Reproduce(if any):
|
||||
|
||||
1.
|
||||
2.`;
|
||||
}
|
||||
|
||||
let nodeModuleLoadTime: number;
|
||||
if (this.environmentService.performance) {
|
||||
nodeModuleLoadTime = LoaderStat.getLoaderStats().nodeRequireTotal;
|
||||
}
|
||||
|
||||
|
||||
const osVersion = `${os.type()} ${os.arch()} ${os.release()}`;
|
||||
const queryStringPrefix = baseUrl.indexOf('?') === -1 ? '?' : '&';
|
||||
const body = encodeURIComponent(
|
||||
`- VSCode Version: <code>${name} ${version} ${isPure ? '' : ' **[Unsupported]**'} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'})</code>
|
||||
- OS Version: <code>${ osVersion} </code>
|
||||
- CPUs: <code>${ metrics.cpus.model} (${metrics.cpus.count} x ${metrics.cpus.speed})</code>
|
||||
- Memory(System): <code>${ (metrics.totalmem / (1024 * 1024 * 1024)).toFixed(2)} GB(${(metrics.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free) </code>
|
||||
- Memory(Process): <code>${ (metrics.meminfo.workingSetSize / 1024).toFixed(2)} MB working set(${(metrics.meminfo.peakWorkingSetSize / 1024).toFixed(2)}MB peak, ${(metrics.meminfo.privateBytes / 1024).toFixed(2)}MB private, ${(metrics.meminfo.sharedBytes / 1024).toFixed(2)}MB shared) </code>
|
||||
- Load(avg): <code>${ metrics.loadavg.map(l => Math.round(l)).join(', ')} </code>
|
||||
- VM: <code>${ metrics.isVMLikelyhood}% </code>
|
||||
- Initial Startup: <code>${ metrics.initialStartup ? 'yes' : 'no'} </code>
|
||||
- Screen Reader: <code>${ metrics.hasAccessibilitySupport ? 'yes' : 'no'} </code>
|
||||
- Empty Workspace: <code>${ metrics.emptyWorkbench ? 'yes' : 'no'} </code>
|
||||
- Timings:
|
||||
|
||||
${this.generatePerformanceTable(metrics, nodeModuleLoadTime)}
|
||||
---
|
||||
|
||||
${appendix}`);
|
||||
|
||||
return `${baseUrl}${queryStringPrefix}body=${body}`;
|
||||
}
|
||||
|
||||
private generatePerformanceTable(metrics: IStartupMetrics, nodeModuleLoadTime?: number): string {
|
||||
let tableHeader = `| Component | Task | Duration(ms) | Info |
|
||||
| ---| ---| ---| ---| `;
|
||||
|
||||
let table = '';
|
||||
forEach(Info.getTimerInfo(metrics, nodeModuleLoadTime), e => {
|
||||
table += `| ${e.value.process}| ${e.key}| ${e.value.duration}| ${e.value.info}|\n`;
|
||||
});
|
||||
|
||||
return `${tableHeader} \n${table} `;
|
||||
}
|
||||
}
|
||||
|
||||
Registry
|
||||
.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions)
|
||||
.registerWorkbenchAction(new SyncActionDescriptor(ShowStartupPerformance, ShowStartupPerformance.ID, ShowStartupPerformance.LABEL), 'Developer: Startup Performance', nls.localize('developer', "Developer"));
|
||||
@@ -7,13 +7,21 @@ import { localize } from 'vs/nls';
|
||||
import { MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Extensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
|
||||
import { Extensions as Input, IEditorInputFactory, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor';
|
||||
import { PerfviewInput } from 'vs/workbench/parts/performance/electron-browser/perfviewEditor';
|
||||
import { PerfviewContrib, PerfviewInput } from 'vs/workbench/parts/performance/electron-browser/perfviewEditor';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import './startupProfiler';
|
||||
import './startupTimings';
|
||||
import './stats';
|
||||
import { StartupProfiler } from './startupProfiler';
|
||||
import { StartupTimings } from './startupTimings';
|
||||
|
||||
// -- startup performance view
|
||||
|
||||
Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench).registerWorkbenchContribution(
|
||||
PerfviewContrib,
|
||||
LifecyclePhase.Ready
|
||||
);
|
||||
|
||||
Registry.as<IEditorInputFactoryRegistry>(Input.EditorInputFactories).registerEditorInputFactory(
|
||||
PerfviewInput.Id,
|
||||
@@ -28,7 +36,6 @@ Registry.as<IEditorInputFactoryRegistry>(Input.EditorInputFactories).registerEdi
|
||||
);
|
||||
|
||||
CommandsRegistry.registerCommand('perfview.show', accessor => {
|
||||
|
||||
const editorService = accessor.get(IEditorService);
|
||||
const instaService = accessor.get(IInstantiationService);
|
||||
return editorService.openEditor(instaService.createInstance(PerfviewInput));
|
||||
@@ -37,5 +44,20 @@ CommandsRegistry.registerCommand('perfview.show', accessor => {
|
||||
MenuRegistry.addCommand({
|
||||
id: 'perfview.show',
|
||||
category: localize('show.cat', "Developer"),
|
||||
title: localize('show.label', "Startup Performance (2)")
|
||||
title: localize('show.label', "Startup Performance")
|
||||
});
|
||||
|
||||
|
||||
// -- startup profiler
|
||||
|
||||
Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench).registerWorkbenchContribution(
|
||||
StartupProfiler,
|
||||
LifecyclePhase.Restored
|
||||
);
|
||||
|
||||
// -- startup timings
|
||||
|
||||
Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench).registerWorkbenchContribution(
|
||||
StartupTimings,
|
||||
LifecyclePhase.Eventually
|
||||
);
|
||||
|
||||
@@ -9,7 +9,6 @@ import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorIn
|
||||
import { ITextModelService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService';
|
||||
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { ITextEditorModel } from 'vs/workbench/common/editor';
|
||||
import { ILifecycleService, LifecyclePhase, StartupKindToString } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -21,6 +20,26 @@ import * as perf from 'vs/base/common/performance';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { writeTransientState } from 'vs/workbench/parts/codeEditor/electron-browser/toggleWordWrap';
|
||||
import { mergeSort } from 'vs/base/common/arrays';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import product from 'vs/platform/node/product';
|
||||
import pkg from 'vs/platform/node/package';
|
||||
|
||||
export class PerfviewContrib {
|
||||
|
||||
private readonly _registration: IDisposable;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService instaService: IInstantiationService,
|
||||
@ITextModelService textModelResolverService: ITextModelService
|
||||
) {
|
||||
this._registration = textModelResolverService.registerTextModelContentProvider('perf', instaService.createInstance(PerfModelContentProvider));
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._registration.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export class PerfviewInput extends ResourceEditorInput {
|
||||
|
||||
@@ -28,28 +47,20 @@ export class PerfviewInput extends ResourceEditorInput {
|
||||
static readonly Uri = URI.from({ scheme: 'perf', path: 'Startup Performance' });
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly _instaService: IInstantiationService,
|
||||
@ITextModelService private _textModelResolverService: ITextModelService,
|
||||
@ITextModelService textModelResolverService: ITextModelService,
|
||||
@IHashService hashService: IHashService
|
||||
) {
|
||||
super(
|
||||
localize('name', "Startup Performance"),
|
||||
undefined,
|
||||
PerfviewInput.Uri,
|
||||
_textModelResolverService, hashService
|
||||
textModelResolverService, hashService
|
||||
);
|
||||
}
|
||||
|
||||
getTypeId(): string {
|
||||
return PerfviewInput.Id;
|
||||
}
|
||||
|
||||
resolve(): Promise<ITextEditorModel> {
|
||||
if (!this._textModelResolverService.hasTextModelContentProvider(PerfviewInput.Uri.scheme)) {
|
||||
this._textModelResolverService.registerTextModelContentProvider(PerfviewInput.Uri.scheme, this._instaService.createInstance(PerfModelContentProvider));
|
||||
}
|
||||
return super.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
class PerfModelContentProvider implements ITextModelContentProvider {
|
||||
@@ -63,12 +74,13 @@ class PerfModelContentProvider implements ITextModelContentProvider {
|
||||
@ICodeEditorService private readonly _editorService: ICodeEditorService,
|
||||
@ILifecycleService private readonly _lifecycleService: ILifecycleService,
|
||||
@ITimerService private readonly _timerService: ITimerService,
|
||||
@IEnvironmentService private readonly _envService: IEnvironmentService,
|
||||
@IExtensionService private readonly _extensionService: IExtensionService,
|
||||
) { }
|
||||
|
||||
provideTextContent(resource: URI): Promise<ITextModel> {
|
||||
|
||||
if (!this._model) {
|
||||
if (!this._model || this._model.isDisposed()) {
|
||||
dispose(this._modelDisposables);
|
||||
const langId = this._modeService.create('markdown');
|
||||
this._model = this._modelService.getModel(resource) || this._modelService.createModel('Loading...', langId, resource);
|
||||
@@ -85,21 +97,25 @@ class PerfModelContentProvider implements ITextModelContentProvider {
|
||||
|
||||
private _updateModel(): void {
|
||||
|
||||
|
||||
Promise.all([
|
||||
this._timerService.startupMetrics,
|
||||
this._lifecycleService.when(LifecyclePhase.Eventually),
|
||||
this._extensionService.whenInstalledExtensionsRegistered()
|
||||
]).then(([metrics]) => {
|
||||
if (!this._model.isDisposed()) {
|
||||
|
||||
let stats = this._envService.args['prof-modules'] ? LoaderStats.get() : undefined;
|
||||
let md = new MarkdownBuilder();
|
||||
this._addSummary(md, metrics);
|
||||
md.blank();
|
||||
this._addSummaryTable(md, metrics);
|
||||
this._addSummaryTable(md, metrics, stats);
|
||||
md.blank();
|
||||
this._addExtensionsTable(md);
|
||||
md.blank();
|
||||
this._addRawPerfMarks(md);
|
||||
md.blank();
|
||||
this._addLoaderStats(md, stats);
|
||||
|
||||
this._model.setValue(md.value);
|
||||
}
|
||||
});
|
||||
@@ -108,6 +124,7 @@ class PerfModelContentProvider implements ITextModelContentProvider {
|
||||
|
||||
private _addSummary(md: MarkdownBuilder, metrics: IStartupMetrics): void {
|
||||
md.heading(2, 'System Info');
|
||||
md.li(`${product.nameShort}: ${pkg.version} (${product.commit || '0000000'})`);
|
||||
md.li(`OS: ${metrics.platform}(${metrics.release})`);
|
||||
md.li(`CPUs: ${metrics.cpus.model}(${metrics.cpus.count} x ${metrics.cpus.speed})`);
|
||||
md.li(`Memory(System): ${(metrics.totalmem / (1024 * 1024 * 1024)).toFixed(2)} GB(${(metrics.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free)`);
|
||||
@@ -119,7 +136,7 @@ class PerfModelContentProvider implements ITextModelContentProvider {
|
||||
md.li(`Empty Workspace: ${metrics.emptyWorkbench}`);
|
||||
}
|
||||
|
||||
private _addSummaryTable(md: MarkdownBuilder, metrics: IStartupMetrics, nodeModuleLoadTime?: number): void {
|
||||
private _addSummaryTable(md: MarkdownBuilder, metrics: IStartupMetrics, stats?: LoaderStats): void {
|
||||
|
||||
const table: (string | number)[][] = [];
|
||||
table.push(['start => app.isReady', metrics.timers.ellapsedAppReady, '[main]', `initial startup: ${metrics.initialStartup}`]);
|
||||
@@ -127,7 +144,7 @@ class PerfModelContentProvider implements ITextModelContentProvider {
|
||||
table.push(['app.isReady => window.loadUrl()', metrics.timers.ellapsedWindowLoad, '[main]', `initial startup: ${metrics.initialStartup}`]);
|
||||
table.push(['require & init global storage', metrics.timers.ellapsedGlobalStorageInitMain, '[main]', `initial startup: ${metrics.initialStartup}`]);
|
||||
table.push(['window.loadUrl() => begin to require(workbench.main.js)', metrics.timers.ellapsedWindowLoadToRequire, '[main->renderer]', StartupKindToString(metrics.windowKind)]);
|
||||
table.push(['require(workbench.main.js)', metrics.timers.ellapsedRequire, '[renderer]', `cached data: ${(metrics.didUseCachedData ? 'YES' : 'NO')}${nodeModuleLoadTime ? `, node_modules took ${nodeModuleLoadTime}ms` : ''}`]);
|
||||
table.push(['require(workbench.main.js)', metrics.timers.ellapsedRequire, '[renderer]', `cached data: ${(metrics.didUseCachedData ? 'YES' : 'NO')}${stats ? `, node_modules took ${stats.nodeRequireTotal}ms` : ''}`]);
|
||||
table.push(['init global storage', metrics.timers.ellapsedGlobalStorageInitRenderer, '[renderer]', undefined]);
|
||||
table.push(['require workspace storage', metrics.timers.ellapsedWorkspaceStorageRequire, '[renderer]', undefined]);
|
||||
table.push(['require & init workspace storage', metrics.timers.ellapsedWorkspaceStorageInit, '[renderer]', undefined]);
|
||||
@@ -146,15 +163,22 @@ class PerfModelContentProvider implements ITextModelContentProvider {
|
||||
|
||||
private _addExtensionsTable(md: MarkdownBuilder): void {
|
||||
|
||||
const table: ({ toString(): string })[][] = [];
|
||||
const eager: ({ toString(): string })[][] = [];
|
||||
const normal: ({ toString(): string })[][] = [];
|
||||
let extensionsStatus = this._extensionService.getExtensionsStatus();
|
||||
for (let id in extensionsStatus) {
|
||||
const { activationTimes: times } = extensionsStatus[id];
|
||||
if (!times) {
|
||||
continue;
|
||||
}
|
||||
table.push([id, times.startup, times.codeLoadingTime, times.activateCallTime, times.activateResolvedTime, times.activationEvent]);
|
||||
if (times.startup) {
|
||||
eager.push([id, times.startup, times.codeLoadingTime, times.activateCallTime, times.activateResolvedTime, times.activationEvent]);
|
||||
} else {
|
||||
normal.push([id, times.startup, times.codeLoadingTime, times.activateCallTime, times.activateResolvedTime, times.activationEvent]);
|
||||
}
|
||||
}
|
||||
|
||||
const table = eager.concat(normal);
|
||||
if (table.length > 0) {
|
||||
md.heading(2, 'Extension Activation Stats');
|
||||
md.table(
|
||||
@@ -167,11 +191,125 @@ class PerfModelContentProvider implements ITextModelContentProvider {
|
||||
private _addRawPerfMarks(md: MarkdownBuilder): void {
|
||||
md.heading(2, 'Raw Perf Marks');
|
||||
md.value += '```\n';
|
||||
md.value += `Name\tTimestamp\tDelta\n`;
|
||||
let lastStartTime = -1;
|
||||
for (const { name, startTime } of perf.getEntries('mark')) {
|
||||
md.value += `${name}\t${startTime}\n`;
|
||||
md.value += `${name}\t${startTime}\t${lastStartTime !== -1 ? startTime - lastStartTime : 0}\n`;
|
||||
lastStartTime = startTime;
|
||||
}
|
||||
md.value += '```\n';
|
||||
}
|
||||
|
||||
private _addLoaderStats(md: MarkdownBuilder, stats?: LoaderStats): void {
|
||||
if (stats) {
|
||||
md.heading(2, 'Loader Stats');
|
||||
md.heading(3, 'Load AMD-module');
|
||||
md.table(['Module', 'Duration'], stats.amdLoad);
|
||||
md.blank();
|
||||
md.heading(3, 'Load commonjs-module');
|
||||
md.table(['Module', 'Duration'], stats.nodeRequire);
|
||||
md.blank();
|
||||
md.heading(3, 'Invoke AMD-module factory');
|
||||
md.table(['Module', 'Duration'], stats.amdInvoke);
|
||||
md.blank();
|
||||
md.heading(3, 'Invoke commonjs-module');
|
||||
md.table(['Module', 'Duration'], stats.nodeEval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class LoaderStats {
|
||||
readonly amdLoad: (string | number)[][];
|
||||
readonly amdInvoke: (string | number)[][];
|
||||
readonly nodeRequire: (string | number)[][];
|
||||
readonly nodeEval: (string | number)[][];
|
||||
readonly nodeRequireTotal: number;
|
||||
|
||||
|
||||
static get(): LoaderStats {
|
||||
|
||||
|
||||
const amdLoadScript = new Map<string, number>();
|
||||
const amdInvokeFactory = new Map<string, number>();
|
||||
const nodeRequire = new Map<string, number>();
|
||||
const nodeEval = new Map<string, number>();
|
||||
|
||||
function mark(map: Map<string, number>, stat: LoaderEvent) {
|
||||
if (map.has(stat.detail)) {
|
||||
// console.warn('BAD events, DOUBLE start', stat);
|
||||
// map.delete(stat.detail);
|
||||
return;
|
||||
}
|
||||
map.set(stat.detail, -stat.timestamp);
|
||||
}
|
||||
|
||||
function diff(map: Map<string, number>, stat: LoaderEvent) {
|
||||
let duration = map.get(stat.detail);
|
||||
if (!duration) {
|
||||
// console.warn('BAD events, end WITHOUT start', stat);
|
||||
// map.delete(stat.detail);
|
||||
return;
|
||||
}
|
||||
if (duration >= 0) {
|
||||
// console.warn('BAD events, DOUBLE end', stat);
|
||||
// map.delete(stat.detail);
|
||||
return;
|
||||
}
|
||||
map.set(stat.detail, duration + stat.timestamp);
|
||||
}
|
||||
|
||||
const stats = mergeSort(require.getStats().slice(0), (a, b) => a.timestamp - b.timestamp);
|
||||
|
||||
for (const stat of stats) {
|
||||
switch (stat.type) {
|
||||
case LoaderEventType.BeginLoadingScript:
|
||||
mark(amdLoadScript, stat);
|
||||
break;
|
||||
case LoaderEventType.EndLoadingScriptOK:
|
||||
case LoaderEventType.EndLoadingScriptError:
|
||||
diff(amdLoadScript, stat);
|
||||
break;
|
||||
|
||||
case LoaderEventType.BeginInvokeFactory:
|
||||
mark(amdInvokeFactory, stat);
|
||||
break;
|
||||
case LoaderEventType.EndInvokeFactory:
|
||||
diff(amdInvokeFactory, stat);
|
||||
break;
|
||||
|
||||
case LoaderEventType.NodeBeginNativeRequire:
|
||||
mark(nodeRequire, stat);
|
||||
break;
|
||||
case LoaderEventType.NodeEndNativeRequire:
|
||||
diff(nodeRequire, stat);
|
||||
break;
|
||||
|
||||
case LoaderEventType.NodeBeginEvaluatingScript:
|
||||
mark(nodeEval, stat);
|
||||
break;
|
||||
case LoaderEventType.NodeEndEvaluatingScript:
|
||||
diff(nodeEval, stat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let nodeRequireTotal = 0;
|
||||
nodeRequire.forEach(value => nodeRequireTotal += value);
|
||||
|
||||
function to2dArray(map: Map<string, number>): (string | number)[][] {
|
||||
let res: (string | number)[][] = [];
|
||||
map.forEach((value, index) => res.push([index, value]));
|
||||
return res;
|
||||
}
|
||||
|
||||
return {
|
||||
amdLoad: to2dArray(amdLoadScript),
|
||||
amdInvoke: to2dArray(amdInvokeFactory),
|
||||
nodeRequire: to2dArray(nodeRequire),
|
||||
nodeEval: to2dArray(nodeEval),
|
||||
nodeRequireTotal
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class MarkdownBuilder {
|
||||
@@ -200,7 +338,7 @@ class MarkdownBuilder {
|
||||
});
|
||||
rows.forEach(row => {
|
||||
row.forEach((cell, ci) => {
|
||||
if (!cell) {
|
||||
if (typeof cell === 'undefined') {
|
||||
cell = row[ci] = '-';
|
||||
}
|
||||
const len = cell.toString().length;
|
||||
|
||||
@@ -6,24 +6,26 @@
|
||||
import { dirname, join } from 'path';
|
||||
import { basename } from 'vs/base/common/paths';
|
||||
import { del, exists, readdir, readFile } from 'vs/base/node/pfs';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import product from 'vs/platform/node/product';
|
||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { Extensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
|
||||
import { ReportPerformanceIssueAction } from 'vs/workbench/parts/performance/electron-browser/actions';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { PerfviewInput } from 'vs/workbench/parts/performance/electron-browser/perfviewEditor';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
|
||||
class StartupProfiler implements IWorkbenchContribution {
|
||||
export class StartupProfiler implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@IWindowsService private readonly _windowsService: IWindowsService,
|
||||
@IDialogService private readonly _dialogService: IDialogService,
|
||||
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@ITextModelService private readonly _textModelResolverService: ITextModelService,
|
||||
@IClipboardService private readonly _clipboardService: IClipboardService,
|
||||
@ILifecycleService lifecycleService: ILifecycleService,
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
) {
|
||||
@@ -76,10 +78,9 @@ class StartupProfiler implements IWorkbenchContribution {
|
||||
secondaryButton: localize('prof.restart', "Restart")
|
||||
}).then(res => {
|
||||
if (res.confirmed) {
|
||||
const action = this._instantiationService.createInstance(ReportPerformanceIssueAction, ReportPerformanceIssueAction.ID, ReportPerformanceIssueAction.LABEL);
|
||||
Promise.all<any>([
|
||||
this._windowsService.showItemInFolder(join(dir, files[0])),
|
||||
action.run(`:warning: Make sure to **attach** these files from your *home*-directory: :warning:\n${files.map(file => `-\`${file}\``).join('\n')}`)
|
||||
this._createPerfIssue(files)
|
||||
]).then(() => {
|
||||
// keep window stable until restart is selected
|
||||
return this._dialogService.confirm({
|
||||
@@ -101,7 +102,22 @@ class StartupProfiler implements IWorkbenchContribution {
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const registry = Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench);
|
||||
registry.registerWorkbenchContribution(StartupProfiler, LifecyclePhase.Restored);
|
||||
private _createPerfIssue(files: string[]): Promise<void> {
|
||||
return this._textModelResolverService.createModelReference(PerfviewInput.Uri).then(ref => {
|
||||
|
||||
this._clipboardService.writeText(ref.object.textEditorModel.getValue());
|
||||
ref.dispose();
|
||||
|
||||
const body = `
|
||||
1. :warning: We have copied additional data to your clipboard. Make sure to **paste** here. :warning:
|
||||
1. :warning: Make sure to **attach** these files from your *home*-directory: :warning:\n${files.map(file => `-\`${file}\``).join('\n')}
|
||||
`;
|
||||
|
||||
const baseUrl = product.reportIssueUrl;
|
||||
const queryStringPrefix = baseUrl.indexOf('?') === -1 ? '?' : '&';
|
||||
|
||||
window.open(`${baseUrl}${queryStringPrefix}body=${encodeURIComponent(body)}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,26 +3,25 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { appendFile } from 'fs';
|
||||
import { nfcall, timeout } from 'vs/base/common/async';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { isCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ILifecycleService, LifecyclePhase, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ILifecycleService, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import product from 'vs/platform/node/product';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IUpdateService } from 'vs/platform/update/common/update';
|
||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { Extensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import * as files from 'vs/workbench/parts/files/common/files';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { ITimerService, didUseCachedData } from 'vs/workbench/services/timer/electron-browser/timerService';
|
||||
import { didUseCachedData, ITimerService } from 'vs/workbench/services/timer/electron-browser/timerService';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import product from 'vs/platform/node/product';
|
||||
import { timeout, nfcall } from 'vs/base/common/async';
|
||||
import { appendFile } from 'fs';
|
||||
|
||||
class StartupTimings implements IWorkbenchContribution {
|
||||
export class StartupTimings implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
@@ -138,5 +137,3 @@ class StartupTimings implements IWorkbenchContribution {
|
||||
}
|
||||
}
|
||||
|
||||
const registry = Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench);
|
||||
registry.registerWorkbenchContribution(StartupTimings, LifecyclePhase.Eventually);
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
|
||||
|
||||
interface IRequire {
|
||||
(...a: any[]): any;
|
||||
getStats(): ILoaderEvent[];
|
||||
}
|
||||
|
||||
declare var require: IRequire;
|
||||
|
||||
/* Copied from loader.ts */
|
||||
enum LoaderEventType {
|
||||
LoaderAvailable = 1,
|
||||
|
||||
BeginLoadingScript = 10,
|
||||
EndLoadingScriptOK = 11,
|
||||
EndLoadingScriptError = 12,
|
||||
|
||||
BeginInvokeFactory = 21,
|
||||
EndInvokeFactory = 22,
|
||||
|
||||
NodeBeginEvaluatingScript = 31,
|
||||
NodeEndEvaluatingScript = 32,
|
||||
|
||||
NodeBeginNativeRequire = 33,
|
||||
NodeEndNativeRequire = 34
|
||||
}
|
||||
|
||||
interface ILoaderEvent {
|
||||
type: LoaderEventType;
|
||||
timestamp: number;
|
||||
detail: string;
|
||||
}
|
||||
|
||||
class Tick {
|
||||
|
||||
public readonly duration: number;
|
||||
public readonly detail: string;
|
||||
|
||||
constructor(public readonly start: ILoaderEvent, public readonly end: ILoaderEvent) {
|
||||
console.assert(start.detail === end.detail);
|
||||
|
||||
this.duration = this.end.timestamp - this.start.timestamp;
|
||||
this.detail = start.detail;
|
||||
}
|
||||
|
||||
static compareUsingStartTimestamp(a: Tick, b: Tick): number {
|
||||
if (a.start.timestamp < b.start.timestamp) {
|
||||
return -1;
|
||||
} else if (a.start.timestamp > b.start.timestamp) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getStats(): Map<LoaderEventType, Tick[]> {
|
||||
|
||||
const stats = require.getStats().slice(0).sort((a: ILoaderEvent, b: ILoaderEvent) => {
|
||||
if (a.detail < b.detail) {
|
||||
return -1;
|
||||
} else if (a.detail > b.detail) {
|
||||
return 1;
|
||||
} else if (a.type < b.type) {
|
||||
return -1;
|
||||
} else if (a.type > b.type) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
const ticks = new Map<LoaderEventType, Tick[]>();
|
||||
ticks.set(LoaderEventType.BeginLoadingScript, []);
|
||||
ticks.set(LoaderEventType.BeginInvokeFactory, []);
|
||||
ticks.set(LoaderEventType.NodeBeginEvaluatingScript, []);
|
||||
ticks.set(LoaderEventType.NodeBeginNativeRequire, []);
|
||||
|
||||
for (let i = 1; i < stats.length - 1; i++) {
|
||||
const stat = stats[i];
|
||||
const nextStat = stats[i + 1];
|
||||
|
||||
if (nextStat.type - stat.type > 2) {
|
||||
//bad?!
|
||||
break;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
ticks.get(stat.type).push(new Tick(stat, nextStat));
|
||||
}
|
||||
|
||||
ticks.get(LoaderEventType.BeginLoadingScript).sort(Tick.compareUsingStartTimestamp);
|
||||
ticks.get(LoaderEventType.BeginInvokeFactory).sort(Tick.compareUsingStartTimestamp);
|
||||
ticks.get(LoaderEventType.NodeBeginEvaluatingScript).sort(Tick.compareUsingStartTimestamp);
|
||||
ticks.get(LoaderEventType.NodeBeginNativeRequire).sort(Tick.compareUsingStartTimestamp);
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
CommandsRegistry.registerCommand('dev.stats.loader', accessor => {
|
||||
|
||||
const clipboard = accessor.get(IClipboardService);
|
||||
|
||||
let value = `Name\tDuration\n`;
|
||||
for (let tick of getStats().get(LoaderEventType.BeginInvokeFactory)) {
|
||||
value += `${tick.detail}\t${tick.duration.toPrecision(2)}\n`;
|
||||
}
|
||||
console.log(value);
|
||||
clipboard.writeText(value);
|
||||
});
|
||||
@@ -167,7 +167,7 @@ suite('CacheState', () => {
|
||||
cacheKey => cache.query(cacheKey),
|
||||
query => cache.load(query),
|
||||
cacheKey => cache.dispose(cacheKey),
|
||||
previous
|
||||
previous!
|
||||
);
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ suite('CacheState', () => {
|
||||
|
||||
public load(query: IFileQuery): Promise<any> {
|
||||
const promise = new DeferredPromise<any>();
|
||||
this.loading[query.cacheKey] = promise;
|
||||
this.loading[query.cacheKey!] = promise;
|
||||
return promise.p;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,8 +67,8 @@ suite('Search - Viewlet', () => {
|
||||
const resultIterator = createIterator(result, 'auto');
|
||||
const first = resultIterator.next();
|
||||
|
||||
assert(!!first.value.children);
|
||||
assert.equal((<Iterator<ITreeElement<RenderableMatch>>>first.value.children).next().value.element.id(), 'file:///c%3A/foo>[2,1 -> 2,2]b');
|
||||
assert(!!first.value!.children);
|
||||
assert.equal((<Iterator<ITreeElement<RenderableMatch>>>first.value!.children).next().value!.element.id(), 'file:///c%3A/foo>[2,1 -> 2,2]b');
|
||||
});
|
||||
|
||||
test('Comparer', () => {
|
||||
|
||||
@@ -817,7 +817,7 @@ function assertEqualQueries(actual: ITextQuery | IFileQuery, expected: ITextQuer
|
||||
}
|
||||
|
||||
if (expected.extraFileResources) {
|
||||
assert.deepEqual(actual.extraFileResources.map(extraFile => extraFile.fsPath), expected.extraFileResources.map(extraFile => extraFile.fsPath));
|
||||
assert.deepEqual(actual.extraFileResources!.map(extraFile => extraFile.fsPath), expected.extraFileResources.map(extraFile => extraFile.fsPath));
|
||||
delete expected.extraFileResources;
|
||||
delete actual.extraFileResources;
|
||||
}
|
||||
@@ -837,7 +837,7 @@ function assertEqualSearchPathResults(actual: ISearchPathsResult, expected: ISea
|
||||
assert.equal(actual.searchPaths && actual.searchPaths.length, expected.searchPaths && expected.searchPaths.length);
|
||||
if (actual.searchPaths) {
|
||||
actual.searchPaths.forEach((searchPath, i) => {
|
||||
const expectedSearchPath = expected.searchPaths[i];
|
||||
const expectedSearchPath = expected.searchPaths![i];
|
||||
assert.equal(searchPath.pattern, expectedSearchPath.pattern);
|
||||
assert.equal(searchPath.searchPath.toString(), expectedSearchPath.searchPath.toString());
|
||||
});
|
||||
@@ -885,7 +885,7 @@ function fixPath(...slashPathParts: string[]): string {
|
||||
return paths.join(...slashPathParts);
|
||||
}
|
||||
|
||||
function normalizeExpression(expression: IExpression): IExpression {
|
||||
function normalizeExpression(expression: IExpression | undefined): IExpression | undefined {
|
||||
if (!expression) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@@ -84,8 +84,8 @@ suite('SearchModel', () => {
|
||||
textSearch(query: ISearchQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): Promise<ISearchComplete> {
|
||||
return new Promise(resolve => {
|
||||
process.nextTick(() => {
|
||||
results.forEach(onProgress);
|
||||
resolve(complete);
|
||||
results.forEach(onProgress!);
|
||||
resolve(complete!);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ suite('SearchResult', () => {
|
||||
});
|
||||
|
||||
test('Line Match', function () {
|
||||
let fileMatch = aFileMatch('folder/file.txt', null);
|
||||
let fileMatch = aFileMatch('folder/file.txt', null!);
|
||||
let lineMatch = new Match(fileMatch, ['foo bar'], new OneLineRange(0, 0, 3), new OneLineRange(1, 0, 3));
|
||||
assert.equal(lineMatch.text(), 'foo bar');
|
||||
assert.equal(lineMatch.range().startLineNumber, 2);
|
||||
@@ -307,7 +307,7 @@ suite('SearchResult', () => {
|
||||
aRawMatch('file://c:/2',
|
||||
new TextSearchMatch('preview 2', lineOneRange))]);
|
||||
|
||||
testObject.replaceAll(null);
|
||||
testObject.replaceAll(null!);
|
||||
|
||||
return voidPromise.then(() => assert.ok(testObject.isEmpty()));
|
||||
});
|
||||
|
||||
@@ -169,7 +169,7 @@ class CommandConfigurationBuilder {
|
||||
}
|
||||
|
||||
public done(taskName: string): void {
|
||||
this.result.args = this.result.args.map(arg => arg === '$name' ? taskName : arg);
|
||||
this.result.args = this.result.args!.map(arg => arg === '$name' ? taskName : arg);
|
||||
this.presentationBuilder.done();
|
||||
}
|
||||
}
|
||||
@@ -227,7 +227,7 @@ class CustomTaskBuilder {
|
||||
|
||||
public problemMatcher(): ProblemMatcherBuilder {
|
||||
let builder = new ProblemMatcherBuilder(this);
|
||||
this.result.configurationProperties.problemMatchers.push(builder.result);
|
||||
this.result.configurationProperties.problemMatchers!.push(builder.result);
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ class CustomTaskBuilder {
|
||||
}
|
||||
|
||||
public done(): void {
|
||||
this.commandBuilder.done(this.result.configurationProperties.name);
|
||||
this.commandBuilder.done(this.result.configurationProperties.name!);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ class ProblemMatcherBuilder {
|
||||
severity: undefined,
|
||||
fileLocation: FileLocationKind.Relative,
|
||||
filePrefix: '${workspaceFolder}',
|
||||
pattern: undefined
|
||||
pattern: undefined!
|
||||
};
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, re
|
||||
assert.strictEqual(result.custom.length, 1);
|
||||
let task = result.custom[0];
|
||||
assert.ok(task);
|
||||
assert.strictEqual(task.configurationProperties.problemMatchers.length, resolved);
|
||||
assert.strictEqual(task.configurationProperties.problemMatchers!.length, resolved);
|
||||
}
|
||||
|
||||
function testConfiguration(external: ExternalTaskRunnerConfiguration, builder: ConfiguationBuilder): void {
|
||||
@@ -409,8 +409,8 @@ class TaskGroupMap {
|
||||
return;
|
||||
}
|
||||
let expectedTaskMap: { [key: string]: boolean } = Object.create(null);
|
||||
expectedTasks.forEach(task => expectedTaskMap[task.configurationProperties.name] = true);
|
||||
actualTasks.forEach(task => delete expectedTaskMap[task.configurationProperties.name]);
|
||||
expectedTasks.forEach(task => expectedTaskMap[task.configurationProperties.name!] = true);
|
||||
actualTasks.forEach(task => delete expectedTaskMap[task.configurationProperties.name!]);
|
||||
assert.strictEqual(Object.keys(expectedTaskMap).length, 0);
|
||||
});
|
||||
}
|
||||
@@ -430,9 +430,9 @@ function assertConfiguration(result: ParseResult, expected: Tasks.Task[]): void
|
||||
let actualId2Name: { [key: string]: string; } = Object.create(null);
|
||||
let actualTaskGroups = new TaskGroupMap();
|
||||
actual.forEach(task => {
|
||||
assert.ok(!actualTasks[task.configurationProperties.name]);
|
||||
actualTasks[task.configurationProperties.name] = task;
|
||||
actualId2Name[task._id] = task.configurationProperties.name;
|
||||
assert.ok(!actualTasks[task.configurationProperties.name!]);
|
||||
actualTasks[task.configurationProperties.name!] = task;
|
||||
actualId2Name[task._id] = task.configurationProperties.name!;
|
||||
if (task.configurationProperties.group) {
|
||||
actualTaskGroups.add(task.configurationProperties.group, task);
|
||||
}
|
||||
@@ -440,8 +440,8 @@ function assertConfiguration(result: ParseResult, expected: Tasks.Task[]): void
|
||||
let expectedTasks: { [key: string]: Tasks.Task; } = Object.create(null);
|
||||
let expectedTaskGroup = new TaskGroupMap();
|
||||
expected.forEach(task => {
|
||||
assert.ok(!expectedTasks[task.configurationProperties.name]);
|
||||
expectedTasks[task.configurationProperties.name] = task;
|
||||
assert.ok(!expectedTasks[task.configurationProperties.name!]);
|
||||
expectedTasks[task.configurationProperties.name!] = task;
|
||||
if (task.configurationProperties.group) {
|
||||
expectedTaskGroup.add(task.configurationProperties.group, task);
|
||||
}
|
||||
@@ -479,7 +479,7 @@ function assertTask(actual: Tasks.Task, expected: Tasks.Task) {
|
||||
function assertCommandConfiguration(actual: Tasks.CommandConfiguration, expected: Tasks.CommandConfiguration) {
|
||||
assert.strictEqual(typeof actual, typeof expected);
|
||||
if (actual && expected) {
|
||||
assertPresentation(actual.presentation, expected.presentation);
|
||||
assertPresentation(actual.presentation!, expected.presentation!);
|
||||
assert.strictEqual(actual.name, expected.name, 'name');
|
||||
assert.strictEqual(actual.runtime, expected.runtime, 'runtime type');
|
||||
assert.strictEqual(actual.suppressTaskName, expected.suppressTaskName, 'suppressTaskName');
|
||||
@@ -1070,7 +1070,7 @@ suite('Tasks version 0.1.0', () => {
|
||||
applyTo(ApplyToKind.closedDocuments).
|
||||
severity(Severity.Warning).
|
||||
fileLocation(FileLocationKind.Absolute).
|
||||
filePrefix(undefined).
|
||||
filePrefix(undefined!).
|
||||
pattern(/abc/);
|
||||
testConfiguration(external, builder);
|
||||
});
|
||||
|
||||
@@ -226,6 +226,11 @@ export class TerminalConfigHelper implements ITerminalConfigHelper {
|
||||
shell.executable = path.join(process.env.windir, 'System32', shell.executable.substr(sysnativePath.length));
|
||||
}
|
||||
}
|
||||
|
||||
// Convert / to \ on Windows for convenience
|
||||
if (platform.isWindows) {
|
||||
shell.executable = shell.executable.replace(/\//g, '\\');
|
||||
}
|
||||
}
|
||||
|
||||
private _toInteger(source: any, minimum: number, maximum: number, fallback: number): number {
|
||||
|
||||
@@ -688,6 +688,8 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
c(this._escapeNonWindowsPath(stdout.trim()));
|
||||
});
|
||||
return;
|
||||
} else if (hasSpace && (exe.indexOf('powershell') !== -1)) {
|
||||
c('& \'' + path + '\'');
|
||||
} else if (hasSpace) {
|
||||
c('"' + path + '"');
|
||||
} else {
|
||||
|
||||
@@ -65,9 +65,10 @@ export function sanitizeEnvironment(env: ITerminalEnvironment): void {
|
||||
'VSCODE_IPC_HOOK',
|
||||
'VSCODE_LOGS',
|
||||
'VSCODE_NLS_CONFIG',
|
||||
'VSCODE_NODE_CACHED_DATA_DIR',
|
||||
'VSCODE_PORTABLE',
|
||||
'VSCODE_PID',
|
||||
'VSCODE_NODE_CACHED_DATA_DIR'
|
||||
'VSCODE_PREVENT_FOREIGN_INSPECT'
|
||||
];
|
||||
keysToRemove.forEach((key) => {
|
||||
if (env[key]) {
|
||||
|
||||
@@ -92,7 +92,7 @@ suite('BackupFileService', () => {
|
||||
service = new TestBackupFileService(workspaceResource, backupHome, workspacesJsonPath);
|
||||
return service.loadBackupResource(fooFile).then(resource => {
|
||||
assert.ok(resource);
|
||||
assert.equal(path.basename(resource.fsPath), path.basename(fooBackupPath));
|
||||
assert.equal(path.basename(resource!.fsPath), path.basename(fooBackupPath));
|
||||
return service.hasBackups().then(hasBackups => {
|
||||
assert.ok(hasBackups);
|
||||
});
|
||||
|
||||
+3
-3
@@ -122,7 +122,7 @@ suite('ConfigurationEditingService', () => {
|
||||
if (configuraitonService) {
|
||||
configuraitonService.dispose();
|
||||
}
|
||||
instantiationService = null;
|
||||
instantiationService = null!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ suite('ConfigurationEditingService', () => {
|
||||
} else {
|
||||
c(void 0);
|
||||
}
|
||||
}).then(() => parentDir = null);
|
||||
}).then(() => parentDir = null!);
|
||||
}
|
||||
|
||||
test('errors cases - invalid key', () => {
|
||||
@@ -178,7 +178,7 @@ suite('ConfigurationEditingService', () => {
|
||||
test('do not notify error', () => {
|
||||
instantiationService.stub(ITextFileService, 'isDirty', true);
|
||||
const target = sinon.stub();
|
||||
instantiationService.stub(INotificationService, <INotificationService>{ prompt: target, _serviceBrand: null, notify: null, error: null, info: null, warn: null });
|
||||
instantiationService.stub(INotificationService, <INotificationService>{ prompt: target, _serviceBrand: null, notify: null!, error: null!, info: null!, warn: null! });
|
||||
return testObject.writeConfiguration(ConfigurationTarget.USER, { key: 'configurationEditing.service.testSetting', value: 'value' }, { donotNotifyError: true })
|
||||
.then(() => assert.fail('Should fail with ERROR_CONFIGURATION_FILE_DIRTY error.'),
|
||||
(error: ConfigurationEditingError) => {
|
||||
|
||||
+10
-10
@@ -293,7 +293,7 @@ suite('WorkspaceContextService - Workspace', () => {
|
||||
done();
|
||||
});
|
||||
const workspace = { folders: [{ path: folders[0].uri.fsPath }, { path: folders[1].uri.fsPath }] };
|
||||
fs.writeFileSync(testObject.getWorkspace().configuration.fsPath, JSON.stringify(workspace, null, '\t'));
|
||||
fs.writeFileSync(testObject.getWorkspace().configuration!.fsPath, JSON.stringify(workspace, null, '\t'));
|
||||
}, done);
|
||||
});
|
||||
|
||||
@@ -350,7 +350,7 @@ suite('WorkspaceContextService - Workspace', () => {
|
||||
const target = sinon.spy();
|
||||
testObject.onDidChangeWorkspaceFolders(target);
|
||||
const workspace = { folders: [{ path: testObject.getWorkspace().folders[1].uri.fsPath }, { path: testObject.getWorkspace().folders[0].uri.fsPath }] };
|
||||
fs.writeFileSync(testObject.getWorkspace().configuration.fsPath, JSON.stringify(workspace, null, '\t'));
|
||||
fs.writeFileSync(testObject.getWorkspace().configuration!.fsPath, JSON.stringify(workspace, null, '\t'));
|
||||
return testObject.reloadConfiguration()
|
||||
.then(() => {
|
||||
assert.equal(target.callCount, 1, `Should be called only once but called ${target.callCount} times`);
|
||||
@@ -365,7 +365,7 @@ suite('WorkspaceContextService - Workspace', () => {
|
||||
const target = sinon.spy();
|
||||
testObject.onDidChangeWorkspaceFolders(target);
|
||||
const workspace = { folders: [{ path: testObject.getWorkspace().folders[0].uri.fsPath, name: '1' }, { path: testObject.getWorkspace().folders[1].uri.fsPath }] };
|
||||
fs.writeFileSync(testObject.getWorkspace().configuration.fsPath, JSON.stringify(workspace, null, '\t'));
|
||||
fs.writeFileSync(testObject.getWorkspace().configuration!.fsPath, JSON.stringify(workspace, null, '\t'));
|
||||
return testObject.reloadConfiguration()
|
||||
.then(() => {
|
||||
assert.equal(target.callCount, 1, `Should be called only once but called ${target.callCount} times`);
|
||||
@@ -977,14 +977,14 @@ suite('WorkspaceConfigurationService-Multiroot', () => {
|
||||
|
||||
test('application settings are not read from workspace', () => {
|
||||
fs.writeFileSync(environmentService.appSettingsPath, '{ "configurationService.workspace.applicationSetting": "userValue" }');
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration, { key: 'settings', value: { 'configurationService.workspace.applicationSetting': 'workspaceValue' } }, true)
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'settings', value: { 'configurationService.workspace.applicationSetting': 'workspaceValue' } }, true)
|
||||
.then(() => testObject.reloadConfiguration())
|
||||
.then(() => assert.equal(testObject.getValue('configurationService.workspace.applicationSetting'), 'userValue'));
|
||||
});
|
||||
|
||||
test('workspace settings override user settings after defaults are registered ', () => {
|
||||
fs.writeFileSync(environmentService.appSettingsPath, '{ "configurationService.workspace.newSetting": "userValue" }');
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration, { key: 'settings', value: { 'configurationService.workspace.newSetting': 'workspaceValue' } }, true)
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'settings', value: { 'configurationService.workspace.newSetting': 'workspaceValue' } }, true)
|
||||
.then(() => testObject.reloadConfiguration())
|
||||
.then(() => {
|
||||
configurationRegistry.registerConfiguration({
|
||||
@@ -1030,7 +1030,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => {
|
||||
|
||||
test('resource setting in folder is read after it is registered later', () => {
|
||||
fs.writeFileSync(workspaceContextService.getWorkspace().folders[0].toResource('.vscode/settings.json').fsPath, '{ "configurationService.workspace.testNewResourceSetting2": "workspaceFolderValue" }');
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration, { key: 'settings', value: { 'configurationService.workspace.testNewResourceSetting2': 'workspaceValue' } }, true)
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'settings', value: { 'configurationService.workspace.testNewResourceSetting2': 'workspaceValue' } }, true)
|
||||
.then(() => testObject.reloadConfiguration())
|
||||
.then(() => {
|
||||
configurationRegistry.registerConfiguration({
|
||||
@@ -1073,7 +1073,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => {
|
||||
assert.equal(actual.workspaceFolder, void 0);
|
||||
assert.equal(actual.value, 'userValue');
|
||||
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration, { key: 'settings', value: { 'configurationService.workspace.testResourceSetting': 'workspaceValue' } }, true)
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'settings', value: { 'configurationService.workspace.testResourceSetting': 'workspaceValue' } }, true)
|
||||
.then(() => testObject.reloadConfiguration())
|
||||
.then(() => {
|
||||
actual = testObject.inspect('configurationService.workspace.testResourceSetting');
|
||||
@@ -1115,7 +1115,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => {
|
||||
}
|
||||
]
|
||||
};
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration, { key: 'launch', value: expectedLaunchConfiguration }, true)
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'launch', value: expectedLaunchConfiguration }, true)
|
||||
.then(() => testObject.reloadConfiguration())
|
||||
.then(() => {
|
||||
const actual = testObject.getValue('launch');
|
||||
@@ -1140,7 +1140,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => {
|
||||
}
|
||||
]
|
||||
};
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration, { key: 'launch', value: expectedLaunchConfiguration }, true)
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'launch', value: expectedLaunchConfiguration }, true)
|
||||
.then(() => testObject.reloadConfiguration())
|
||||
.then(() => {
|
||||
const actual = testObject.inspect('launch').workspace;
|
||||
@@ -1221,7 +1221,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => {
|
||||
});
|
||||
|
||||
test('task configurations are not read from workspace', () => {
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration, { key: 'tasks', value: { 'version': '1.0' } }, true)
|
||||
return jsonEditingServce.write(workspaceContextService.getWorkspace().configuration!, { key: 'tasks', value: { 'version': '1.0' } }, true)
|
||||
.then(() => testObject.reloadConfiguration())
|
||||
.then(() => {
|
||||
const actual = testObject.inspect('tasks.version');
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@ import { Delayer } from 'vs/base/common/async';
|
||||
import { IRawFileChange } from 'vs/workbench/services/files/node/watcher/common';
|
||||
import { FileChangeType } from 'vs/platform/files/common/files';
|
||||
|
||||
function newRequest(basePath: string, ignored = []): IWatcherRequest {
|
||||
function newRequest(basePath: string, ignored: string[] = []): IWatcherRequest {
|
||||
return { basePath, ignored };
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ suite.skip('Chockidar watching', () => {
|
||||
|
||||
const service = new ChokidarWatcherService();
|
||||
const result: IRawFileChange[] = [];
|
||||
let error = null;
|
||||
let error: string | null = null;
|
||||
|
||||
suiteSetup(async () => {
|
||||
await pfs.mkdirp(testDir);
|
||||
|
||||
@@ -58,7 +58,7 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.CREATE);
|
||||
assert.equal(event.target.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.target!.resource.fsPath, resource.fsPath);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -93,7 +93,7 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.CREATE);
|
||||
assert.equal(event.target.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.target!.resource.fsPath, resource.fsPath);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -114,8 +114,8 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.CREATE);
|
||||
assert.equal(event.target.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.target.isDirectory, true);
|
||||
assert.equal(event.target!.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.target!.isDirectory, true);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -139,8 +139,8 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.CREATE);
|
||||
assert.equal(event.target.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.target.isDirectory, true);
|
||||
assert.equal(event.target!.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.target!.isDirectory, true);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -161,7 +161,7 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.MOVE);
|
||||
assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
|
||||
assert.equal(event.target!.resource.fsPath, renamed.resource.fsPath);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -185,7 +185,7 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.MOVE);
|
||||
assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
|
||||
assert.equal(event.target!.resource.fsPath, renamed.resource.fsPath);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -206,7 +206,7 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.MOVE);
|
||||
assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
|
||||
assert.equal(event.target!.resource.fsPath, renamed.resource.fsPath);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -230,7 +230,7 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.MOVE);
|
||||
assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
|
||||
assert.equal(event.target!.resource.fsPath, renamed.resource.fsPath);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -250,7 +250,7 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.MOVE);
|
||||
assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
|
||||
assert.equal(event.target!.resource.fsPath, renamed.resource.fsPath);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -271,7 +271,7 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.MOVE);
|
||||
assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
|
||||
assert.equal(event.target!.resource.fsPath, renamed.resource.fsPath);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -324,7 +324,7 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.MOVE);
|
||||
assert.equal(event.target.resource.fsPath, renamed.resource.fsPath);
|
||||
assert.equal(event.target!.resource.fsPath, renamed.resource.fsPath);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -357,7 +357,7 @@ suite('FileService', () => {
|
||||
assert.ok(moveEvent);
|
||||
|
||||
assert.equal(moveEvent.resource.fsPath, resource.fsPath);
|
||||
assert.equal(moveEvent.target.resource.fsPath, moved.resource.fsPath);
|
||||
assert.equal(moveEvent!.target!.resource.fsPath, moved.resource.fsPath);
|
||||
|
||||
assert.equal(deleteEvent.resource.fsPath, folderResource.fsPath);
|
||||
|
||||
@@ -382,7 +382,7 @@ suite('FileService', () => {
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, source.resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.COPY);
|
||||
assert.equal(event.target.resource.fsPath, copied.resource.fsPath);
|
||||
assert.equal(event.target!.resource.fsPath, copied.resource.fsPath);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
@@ -415,7 +415,7 @@ suite('FileService', () => {
|
||||
assert.ok(copyEvent);
|
||||
|
||||
assert.equal(copyEvent.resource.fsPath, resource.fsPath);
|
||||
assert.equal(copyEvent.target.resource.fsPath, copied.resource.fsPath);
|
||||
assert.equal(copyEvent.target!.resource.fsPath, copied.resource.fsPath);
|
||||
|
||||
assert.equal(deleteEvent.resource.fsPath, folderResource.fsPath);
|
||||
|
||||
@@ -505,10 +505,10 @@ suite('FileService', () => {
|
||||
|
||||
test('resolveFile', () => {
|
||||
return service.resolveFile(uri.file(testDir), { resolveTo: [uri.file(path.join(testDir, 'deep'))] }).then(r => {
|
||||
assert.equal(r.children.length, 8);
|
||||
assert.equal(r.children!.length, 8);
|
||||
|
||||
const deep = utils.getByName(r, 'deep');
|
||||
assert.equal(deep.children.length, 4);
|
||||
const deep = utils.getByName(r, 'deep')!;
|
||||
assert.equal(deep.children!.length, 4);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -519,13 +519,13 @@ suite('FileService', () => {
|
||||
]).then(res => {
|
||||
const r1 = res[0].stat;
|
||||
|
||||
assert.equal(r1.children.length, 8);
|
||||
assert.equal(r1.children!.length, 8);
|
||||
|
||||
const deep = utils.getByName(r1, 'deep');
|
||||
assert.equal(deep.children.length, 4);
|
||||
const deep = utils.getByName(r1, 'deep')!;
|
||||
assert.equal(deep.children!.length, 4);
|
||||
|
||||
const r2 = res[1].stat;
|
||||
assert.equal(r2.children.length, 4);
|
||||
assert.equal(r2.children!.length, 4);
|
||||
assert.equal(r2.name, 'deep');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,7 +45,7 @@ export class TestEditorInput extends EditorInput implements IFileEditorInput {
|
||||
resolve(): Promise<IEditorModel> { return Promise.resolve(); }
|
||||
matches(other: TestEditorInput): boolean { return other && this.resource.toString() === other.resource.toString() && other instanceof TestEditorInput; }
|
||||
setEncoding(encoding: string) { }
|
||||
getEncoding(): string { return null; }
|
||||
getEncoding(): string { return null!; }
|
||||
setPreferredEncoding(encoding: string) { }
|
||||
getResource(): URI { return this.resource; }
|
||||
setForceOpenAsBinary(): void { }
|
||||
@@ -225,12 +225,12 @@ suite('Editor groups service', () => {
|
||||
assert.equal(mru[0], rightGroup);
|
||||
assert.equal(mru[1], rootGroup);
|
||||
|
||||
let rightGroupInstantiator: IInstantiationService;
|
||||
let rightGroupInstantiator!: IInstantiationService;
|
||||
part.activeGroup.invokeWithinContext(accessor => {
|
||||
rightGroupInstantiator = accessor.get(IInstantiationService);
|
||||
});
|
||||
|
||||
let rootGroupInstantiator: IInstantiationService;
|
||||
let rootGroupInstantiator!: IInstantiationService;
|
||||
rootGroup.invokeWithinContext(accessor => {
|
||||
rootGroupInstantiator = accessor.get(IInstantiationService);
|
||||
});
|
||||
@@ -353,8 +353,8 @@ suite('Editor groups service', () => {
|
||||
test('options', () => {
|
||||
const part = createPart();
|
||||
|
||||
let oldOptions: IEditorPartOptions;
|
||||
let newOptions: IEditorPartOptions;
|
||||
let oldOptions!: IEditorPartOptions;
|
||||
let newOptions!: IEditorPartOptions;
|
||||
part.onDidEditorPartOptionsChange(event => {
|
||||
oldOptions = event.oldPartOptions;
|
||||
newOptions = event.newPartOptions;
|
||||
|
||||
@@ -476,7 +476,7 @@ export class HistoryService extends Disposable implements IHistoryService {
|
||||
|
||||
private clearOnEditorDispose(editor: IEditorInput | IResourceInput | FileChangesEvent, mapEditorToDispose: Map<EditorInput, IDisposable[]>): void {
|
||||
if (editor instanceof EditorInput) {
|
||||
const disposables = this.editorHistoryListeners.get(editor);
|
||||
const disposables = mapEditorToDispose.get(editor);
|
||||
if (disposables) {
|
||||
dispose(disposables);
|
||||
mapEditorToDispose.delete(editor);
|
||||
|
||||
+2
-2
@@ -115,7 +115,7 @@ suite('KeybindingsEditing', () => {
|
||||
} else {
|
||||
c(void 0);
|
||||
}
|
||||
}).then(() => testDir = null);
|
||||
}).then(() => testDir = null!);
|
||||
});
|
||||
|
||||
test('errors cases - parse errors', () => {
|
||||
@@ -247,7 +247,7 @@ suite('KeybindingsEditing', () => {
|
||||
function aResolvedKeybindingItem({ command, when, isDefault, firstPart, chordPart }: { command?: string, when?: string, isDefault?: boolean, firstPart?: { keyCode: KeyCode, modifiers?: Modifiers }, chordPart?: { keyCode: KeyCode, modifiers?: Modifiers } }): ResolvedKeybindingItem {
|
||||
const aSimpleKeybinding = function (part: { keyCode: KeyCode, modifiers?: Modifiers }): SimpleKeybinding {
|
||||
const { ctrlKey, shiftKey, altKey, metaKey } = part.modifiers || { ctrlKey: false, shiftKey: false, altKey: false, metaKey: false };
|
||||
return new SimpleKeybinding(ctrlKey, shiftKey, altKey, metaKey, part.keyCode);
|
||||
return new SimpleKeybinding(ctrlKey!, shiftKey!, altKey!, metaKey!, part.keyCode);
|
||||
};
|
||||
const keybinding = firstPart ? chordPart ? new ChordKeybinding(aSimpleKeybinding(firstPart), aSimpleKeybinding(chordPart)) : aSimpleKeybinding(firstPart) : null;
|
||||
return new ResolvedKeybindingItem(keybinding ? new USLayoutResolvedKeybinding(keybinding, OS) : null, command || 'some command', null, when ? ContextKeyExpr.deserialize(when) : null, isDefault === void 0 ? true : isDefault);
|
||||
|
||||
@@ -37,7 +37,7 @@ suite('keyboardMapper - MAC de_ch', () => {
|
||||
}
|
||||
|
||||
function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void {
|
||||
assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh), expected);
|
||||
assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh)!, expected);
|
||||
}
|
||||
|
||||
test('kb => hw', () => {
|
||||
@@ -463,7 +463,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
|
||||
}
|
||||
|
||||
function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void {
|
||||
assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux), expected);
|
||||
assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux)!, expected);
|
||||
}
|
||||
|
||||
test('kb => hw', () => {
|
||||
@@ -808,7 +808,7 @@ suite('keyboardMapper - LINUX en_us', () => {
|
||||
});
|
||||
|
||||
function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void {
|
||||
assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux), expected);
|
||||
assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux)!, expected);
|
||||
}
|
||||
|
||||
test('resolveKeybinding Ctrl+A', () => {
|
||||
@@ -1251,7 +1251,7 @@ suite('keyboardMapper', () => {
|
||||
assertNumpadKeyboardEvent(KeyCode.DownArrow, 'Numpad2', 'DownArrow', 'Down', 'down', '[ArrowDown]');
|
||||
assertNumpadKeyboardEvent(KeyCode.PageDown, 'Numpad3', 'PageDown', 'PageDown', 'pagedown', '[PageDown]');
|
||||
assertNumpadKeyboardEvent(KeyCode.LeftArrow, 'Numpad4', 'LeftArrow', 'Left', 'left', '[ArrowLeft]');
|
||||
assertNumpadKeyboardEvent(KeyCode.Unknown, 'Numpad5', 'NumPad5', null, 'numpad5', '[Numpad5]');
|
||||
assertNumpadKeyboardEvent(KeyCode.Unknown, 'Numpad5', 'NumPad5', null!, 'numpad5', '[Numpad5]');
|
||||
assertNumpadKeyboardEvent(KeyCode.RightArrow, 'Numpad6', 'RightArrow', 'Right', 'right', '[ArrowRight]');
|
||||
assertNumpadKeyboardEvent(KeyCode.Home, 'Numpad7', 'Home', 'Home', 'home', '[Home]');
|
||||
assertNumpadKeyboardEvent(KeyCode.UpArrow, 'Numpad8', 'UpArrow', 'Up', 'up', '[ArrowUp]');
|
||||
@@ -1326,7 +1326,7 @@ suite('keyboardMapper - LINUX ru', () => {
|
||||
});
|
||||
|
||||
function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void {
|
||||
assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux), expected);
|
||||
assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux)!, expected);
|
||||
}
|
||||
|
||||
test('resolveKeybinding Ctrl+S', () => {
|
||||
@@ -1396,7 +1396,7 @@ suite('keyboardMapper - MAC zh_hant', () => {
|
||||
});
|
||||
|
||||
function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void {
|
||||
assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh), expected);
|
||||
assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh)!, expected);
|
||||
}
|
||||
|
||||
test('issue #28237 resolveKeybinding Cmd+C', () => {
|
||||
@@ -1427,7 +1427,7 @@ function _assertKeybindingTranslation(mapper: MacLinuxKeyboardMapper, OS: Operat
|
||||
|
||||
const runtimeKeybinding = createKeybinding(kb, OS);
|
||||
|
||||
const keybindingLabel = new USLayoutResolvedKeybinding(runtimeKeybinding, OS).getUserSettingsLabel();
|
||||
const keybindingLabel = new USLayoutResolvedKeybinding(runtimeKeybinding!, OS).getUserSettingsLabel();
|
||||
|
||||
const actualHardwareKeypresses = mapper.simpleKeybindingToScanCodeBinding(<SimpleKeybinding>runtimeKeybinding);
|
||||
if (actualHardwareKeypresses.length === 0) {
|
||||
|
||||
@@ -106,8 +106,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
aResolvedKeybindingItem({ command: 'd' + uuid.generateUuid(), firstPart: { keyCode: KeyCode.Escape }, chordPart: { keyCode: KeyCode.Escape } })
|
||||
);
|
||||
|
||||
registerCommandWithTitle(keybindings[1].command, 'B Title');
|
||||
registerCommandWithTitle(keybindings[3].command, 'A Title');
|
||||
registerCommandWithTitle(keybindings[1].command!, 'B Title');
|
||||
registerCommandWithTitle(keybindings[3].command!, 'A Title');
|
||||
|
||||
const expected = [keybindings[3], keybindings[1], keybindings[0], keybindings[2]];
|
||||
instantiationService.stub(IKeybindingService, 'getKeybindings', () => keybindings);
|
||||
@@ -127,8 +127,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
aResolvedKeybindingItem({ command: sameId, firstPart: { keyCode: KeyCode.Escape }, isDefault: false })
|
||||
);
|
||||
|
||||
registerCommandWithTitle(keybindings[1].command, 'Same Title');
|
||||
registerCommandWithTitle(keybindings[3].command, 'Same Title');
|
||||
registerCommandWithTitle(keybindings[1].command!, 'Same Title');
|
||||
registerCommandWithTitle(keybindings[3].command!, 'Same Title');
|
||||
const expected = [keybindings[3], keybindings[1], keybindings[0], keybindings[2]];
|
||||
|
||||
await testObject.resolve({});
|
||||
@@ -157,22 +157,22 @@ suite('KeybindingsEditorModel test', () => {
|
||||
assert.equal(actual.keybindingItem.command, expected.command);
|
||||
assert.equal(actual.keybindingItem.commandLabel, '');
|
||||
assert.equal(actual.keybindingItem.commandDefaultLabel, null);
|
||||
assert.equal(actual.keybindingItem.keybinding.getAriaLabel(), expected.resolvedKeybinding.getAriaLabel());
|
||||
assert.equal(actual.keybindingItem.when, expected.when.serialize());
|
||||
assert.equal(actual.keybindingItem.keybinding.getAriaLabel(), expected.resolvedKeybinding!.getAriaLabel());
|
||||
assert.equal(actual.keybindingItem.when, expected.when!.serialize());
|
||||
});
|
||||
|
||||
test('convert keybinding with title to entry', async () => {
|
||||
const expected = aResolvedKeybindingItem({ command: 'a' + uuid.generateUuid(), firstPart: { keyCode: KeyCode.Escape }, when: 'context1 && context2' });
|
||||
prepareKeybindingService(expected);
|
||||
registerCommandWithTitle(expected.command, 'Some Title');
|
||||
registerCommandWithTitle(expected.command!, 'Some Title');
|
||||
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('')[0];
|
||||
assert.equal(actual.keybindingItem.command, expected.command);
|
||||
assert.equal(actual.keybindingItem.commandLabel, 'Some Title');
|
||||
assert.equal(actual.keybindingItem.commandDefaultLabel, null);
|
||||
assert.equal(actual.keybindingItem.keybinding.getAriaLabel(), expected.resolvedKeybinding.getAriaLabel());
|
||||
assert.equal(actual.keybindingItem.when, expected.when.serialize());
|
||||
assert.equal(actual.keybindingItem.keybinding.getAriaLabel(), expected.resolvedKeybinding!.getAriaLabel());
|
||||
assert.equal(actual.keybindingItem.when, expected.when!.serialize());
|
||||
});
|
||||
|
||||
test('convert without title and binding to entry', async () => {
|
||||
@@ -282,8 +282,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('cmd').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { metaKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by meta key', async () => {
|
||||
@@ -296,8 +296,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('meta').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { metaKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by command key', async () => {
|
||||
@@ -310,8 +310,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('command').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { metaKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by windows key', async () => {
|
||||
@@ -324,8 +324,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('windows').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { metaKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by alt key', async () => {
|
||||
@@ -336,8 +336,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('alt').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { altKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { altKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by option key', async () => {
|
||||
@@ -348,8 +348,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('option').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { altKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { altKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by ctrl key', async () => {
|
||||
@@ -360,8 +360,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('ctrl').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { ctrlKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { ctrlKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by control key', async () => {
|
||||
@@ -372,8 +372,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('control').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { ctrlKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { ctrlKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by shift key', async () => {
|
||||
@@ -384,8 +384,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('shift').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { shiftKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { shiftKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by arrow', async () => {
|
||||
@@ -396,8 +396,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('arrow').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by modifier and key', async () => {
|
||||
@@ -408,8 +408,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('alt right').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { altKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { altKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by key and modifier', async () => {
|
||||
@@ -431,8 +431,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('alt cmd esc').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { altKey: true, metaKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { altKey: true, metaKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by modifiers in random order and key', async () => {
|
||||
@@ -444,8 +444,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('cmd shift esc').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { metaKey: true, shiftKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true, shiftKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter by first part', async () => {
|
||||
@@ -457,8 +457,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('cmd shift esc').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { metaKey: true, shiftKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true, shiftKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter matches in chord part', async () => {
|
||||
@@ -470,8 +470,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('cmd del').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { metaKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, { keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { metaKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, { keyCode: true });
|
||||
});
|
||||
|
||||
test('filter matches first part and in chord part', async () => {
|
||||
@@ -483,8 +483,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('cmd shift esc del').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { shiftKey: true, metaKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, { keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { shiftKey: true, metaKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, { keyCode: true });
|
||||
});
|
||||
|
||||
test('filter exact matches', async () => {
|
||||
@@ -495,8 +495,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('"ctrl c"').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { ctrlKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { ctrlKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter exact matches with first and chord part', async () => {
|
||||
@@ -507,8 +507,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('"shift meta escape ctrl c"').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { shiftKey: true, metaKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, { ctrlKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { shiftKey: true, metaKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, { ctrlKey: true, keyCode: true });
|
||||
});
|
||||
|
||||
test('filter exact matches with first and chord part no results', async () => {
|
||||
@@ -530,8 +530,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('"control+c"').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { ctrlKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, {});
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { ctrlKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, {});
|
||||
});
|
||||
|
||||
test('filter matches with + separator in first and chord parts', async () => {
|
||||
@@ -542,8 +542,8 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('"shift+meta+escape ctrl+c"').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { shiftKey: true, metaKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches.chordPart, { keyCode: true, ctrlKey: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { shiftKey: true, metaKey: true, keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.chordPart, { keyCode: true, ctrlKey: true });
|
||||
});
|
||||
|
||||
test('filter exact matches with space #32993', async () => {
|
||||
@@ -565,7 +565,7 @@ suite('KeybindingsEditorModel test', () => {
|
||||
await testObject.resolve({});
|
||||
const actual = testObject.fetch('"down"').filter(element => element.keybindingItem.command === command);
|
||||
assert.equal(1, actual.length);
|
||||
assert.deepEqual(actual[0].keybindingMatches.firstPart, { keyCode: true });
|
||||
assert.deepEqual(actual[0].keybindingMatches!.firstPart, { keyCode: true });
|
||||
});
|
||||
|
||||
function prepareKeybindingService(...keybindingItems: ResolvedKeybindingItem[]): ResolvedKeybindingItem[] {
|
||||
@@ -591,7 +591,7 @@ suite('KeybindingsEditorModel test', () => {
|
||||
assert.equal(actual.command, expected.command);
|
||||
if (actual.when) {
|
||||
assert.ok(!!expected.when);
|
||||
assert.equal(actual.when.serialize(), expected.when.serialize());
|
||||
assert.equal(actual.when.serialize(), expected.when!.serialize());
|
||||
} else {
|
||||
assert.ok(!expected.when);
|
||||
}
|
||||
@@ -599,7 +599,7 @@ suite('KeybindingsEditorModel test', () => {
|
||||
|
||||
if (actual.resolvedKeybinding) {
|
||||
assert.ok(!!expected.resolvedKeybinding);
|
||||
assert.equal(actual.resolvedKeybinding.getLabel(), expected.resolvedKeybinding.getLabel());
|
||||
assert.equal(actual.resolvedKeybinding.getLabel(), expected.resolvedKeybinding!.getLabel());
|
||||
} else {
|
||||
assert.ok(!expected.resolvedKeybinding);
|
||||
}
|
||||
@@ -608,7 +608,7 @@ suite('KeybindingsEditorModel test', () => {
|
||||
function aResolvedKeybindingItem({ command, when, isDefault, firstPart, chordPart }: { command?: string, when?: string, isDefault?: boolean, firstPart?: { keyCode: KeyCode, modifiers?: Modifiers }, chordPart?: { keyCode: KeyCode, modifiers?: Modifiers } }): ResolvedKeybindingItem {
|
||||
const aSimpleKeybinding = function (part: { keyCode: KeyCode, modifiers?: Modifiers }): SimpleKeybinding {
|
||||
const { ctrlKey, shiftKey, altKey, metaKey } = part.modifiers || { ctrlKey: false, shiftKey: false, altKey: false, metaKey: false };
|
||||
return new SimpleKeybinding(ctrlKey, shiftKey, altKey, metaKey, part.keyCode);
|
||||
return new SimpleKeybinding(ctrlKey!, shiftKey!, altKey!, metaKey!, part.keyCode);
|
||||
};
|
||||
const keybinding = firstPart ? chordPart ? new ChordKeybinding(aSimpleKeybinding(firstPart), aSimpleKeybinding(chordPart)) : aSimpleKeybinding(firstPart) : null;
|
||||
return new ResolvedKeybindingItem(keybinding ? new USLayoutResolvedKeybinding(keybinding, OS) : null, command || 'some command', null, when ? ContextKeyExpr.deserialize(when) : null, isDefault === void 0 ? true : isDefault);
|
||||
|
||||
@@ -13,7 +13,7 @@ suite('Preferences Model test', () => {
|
||||
private validator: (value: any) => string;
|
||||
|
||||
constructor(private settings: IConfigurationPropertySchema) {
|
||||
this.validator = createValidator(settings);
|
||||
this.validator = createValidator(settings)!;
|
||||
}
|
||||
|
||||
public accepts(input) {
|
||||
|
||||
@@ -29,8 +29,8 @@ class TestViewletService implements IViewletService {
|
||||
onDidViewletClose = this.onDidViewletCloseEmitter.event;
|
||||
onDidViewletEnablementChange = this.onDidViewletEnableEmitter.event;
|
||||
|
||||
public openViewlet(id: string, focus?: boolean): Promise<IViewlet | null> {
|
||||
return Promise.resolve(null);
|
||||
public openViewlet(id: string, focus?: boolean): Promise<IViewlet> {
|
||||
return Promise.resolve(null!);
|
||||
}
|
||||
|
||||
public getViewlets(): ViewletDescriptor[] {
|
||||
@@ -54,11 +54,11 @@ class TestViewletService implements IViewletService {
|
||||
}
|
||||
|
||||
public getViewlet(id: string): ViewletDescriptor {
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
|
||||
public getProgressIndicator(id: string) {
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class TestPanelService implements IPanelService {
|
||||
onDidPanelClose = new Emitter<IPanel>().event;
|
||||
|
||||
public openPanel(id: string, focus?: boolean): IPanel {
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
|
||||
public getPanels(): any[] {
|
||||
@@ -130,14 +130,14 @@ class TestViewlet implements IViewlet {
|
||||
* Returns the action item for a specific action.
|
||||
*/
|
||||
getActionItem(action: IAction): IActionItem {
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying control of this composite.
|
||||
*/
|
||||
getControl(): IEditorControl {
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,14 +176,14 @@ class TestProgressBar {
|
||||
}
|
||||
|
||||
public infinite() {
|
||||
this.fDone = null;
|
||||
this.fDone = null!;
|
||||
this.fInfinite = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public total(total: number) {
|
||||
this.fDone = null;
|
||||
this.fDone = null!;
|
||||
this.fTotal = total;
|
||||
|
||||
return this;
|
||||
@@ -194,7 +194,7 @@ class TestProgressBar {
|
||||
}
|
||||
|
||||
public worked(worked: number) {
|
||||
this.fDone = null;
|
||||
this.fDone = null!;
|
||||
|
||||
if (this.fWorked) {
|
||||
this.fWorked += worked;
|
||||
@@ -208,9 +208,9 @@ class TestProgressBar {
|
||||
public done() {
|
||||
this.fDone = true;
|
||||
|
||||
this.fInfinite = null;
|
||||
this.fWorked = null;
|
||||
this.fTotal = null;
|
||||
this.fInfinite = null!;
|
||||
this.fWorked = null!;
|
||||
this.fTotal = null!;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class TestSearchEngine implements ISearchEngine<IRawFileMatch> {
|
||||
(function next() {
|
||||
process.nextTick(() => {
|
||||
if (self.isCanceled) {
|
||||
done(null, {
|
||||
done(null!, {
|
||||
limitHit: false,
|
||||
stats: stats
|
||||
});
|
||||
@@ -55,7 +55,7 @@ class TestSearchEngine implements ISearchEngine<IRawFileMatch> {
|
||||
}
|
||||
const result = self.result();
|
||||
if (!result) {
|
||||
done(null, {
|
||||
done(null!, {
|
||||
limitHit: false,
|
||||
stats: stats
|
||||
});
|
||||
@@ -109,7 +109,7 @@ suite('RawSearchService', () => {
|
||||
}
|
||||
};
|
||||
|
||||
await service.doFileSearchWithEngine(Engine, rawSearch, cb, null, 0);
|
||||
await service.doFileSearchWithEngine(Engine, rawSearch, cb, null!, 0);
|
||||
return assert.strictEqual(results, 5);
|
||||
});
|
||||
|
||||
@@ -119,7 +119,7 @@ suite('RawSearchService', () => {
|
||||
const Engine = TestSearchEngine.bind(null, () => i-- && rawMatch);
|
||||
const service = new RawSearchService();
|
||||
|
||||
const results = [];
|
||||
const results: number[] = [];
|
||||
const cb: (p: ISerializedSearchProgressItem) => void = value => {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach(m => {
|
||||
@@ -158,7 +158,7 @@ suite('RawSearchService', () => {
|
||||
return emitter.event;
|
||||
}
|
||||
|
||||
const progressResults = [];
|
||||
const progressResults: any[] = [];
|
||||
const onProgress = match => {
|
||||
assert.strictEqual(match.resource.path, uriPath);
|
||||
progressResults.push(match);
|
||||
@@ -218,7 +218,7 @@ suite('RawSearchService', () => {
|
||||
const Engine = TestSearchEngine.bind(null, () => matches.shift());
|
||||
const service = new RawSearchService();
|
||||
|
||||
const results = [];
|
||||
const results: any[] = [];
|
||||
const cb = value => {
|
||||
if (Array.isArray(value)) {
|
||||
results.push(...value.map(v => v.path));
|
||||
@@ -234,7 +234,7 @@ suite('RawSearchService', () => {
|
||||
sortByScore: true,
|
||||
maxResults: 2
|
||||
}, cb, undefined, 1);
|
||||
assert.notStrictEqual(typeof TestSearchEngine.last.config.maxResults, 'number');
|
||||
assert.notStrictEqual(typeof TestSearchEngine.last.config!.maxResults, 'number');
|
||||
assert.deepStrictEqual(results, [path.normalize('/some/where/bbc'), path.normalize('/some/where/bab')]);
|
||||
});
|
||||
|
||||
@@ -244,7 +244,7 @@ suite('RawSearchService', () => {
|
||||
const Engine = TestSearchEngine.bind(null, () => i-- && rawMatch);
|
||||
const service = new RawSearchService();
|
||||
|
||||
const results = [];
|
||||
const results: number[] = [];
|
||||
const cb = value => {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach(m => {
|
||||
@@ -277,7 +277,7 @@ suite('RawSearchService', () => {
|
||||
const Engine = TestSearchEngine.bind(null, () => matches.shift());
|
||||
const service = new RawSearchService();
|
||||
|
||||
const results = [];
|
||||
const results: any[] = [];
|
||||
const cb = value => {
|
||||
if (Array.isArray(value)) {
|
||||
results.push(...value.map(v => v.path));
|
||||
@@ -295,7 +295,7 @@ suite('RawSearchService', () => {
|
||||
assert.strictEqual((<IFileSearchStats>complete.stats).fromCache, false);
|
||||
assert.deepStrictEqual(results, [path.normalize('/some/where/bcb'), path.normalize('/some/where/bbc'), path.normalize('/some/where/aab')]);
|
||||
}).then(async () => {
|
||||
const results = [];
|
||||
const results: any[] = [];
|
||||
const cb = value => {
|
||||
if (Array.isArray(value)) {
|
||||
results.push(...value.map(v => v.path));
|
||||
@@ -324,7 +324,7 @@ suite('RawSearchService', () => {
|
||||
basename: 'bc',
|
||||
size: 3
|
||||
});
|
||||
const results = [];
|
||||
const results: any[] = [];
|
||||
const cb = value => {
|
||||
if (Array.isArray(value)) {
|
||||
results.push(...value.map(v => v.path));
|
||||
|
||||
@@ -779,8 +779,8 @@ suite('FileWalker', () => {
|
||||
const cmd1 = walker.spawnFindCmd(TEST_ROOT_FOLDER);
|
||||
walker.readStdout(cmd1, 'utf8', /*isRipgrep=*/false, (err1, stdout1) => {
|
||||
assert.equal(err1, null);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file1), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file1), -1, stdout1);
|
||||
|
||||
const walker = new FileWalker({
|
||||
type: QueryType.File,
|
||||
@@ -790,8 +790,8 @@ suite('FileWalker', () => {
|
||||
const cmd2 = walker.spawnFindCmd(TEST_ROOT_FOLDER);
|
||||
walker.readStdout(cmd2, 'utf8', /*isRipgrep=*/false, (err2, stdout2) => {
|
||||
assert.equal(err2, null);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.strictEqual(stdout2.split('\n').indexOf(file1), -1, stdout2);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.strictEqual(stdout2!.split('\n').indexOf(file1), -1, stdout2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -818,8 +818,8 @@ suite('FileWalker', () => {
|
||||
const cmd1 = walker.spawnFindCmd(folderQueries[0]);
|
||||
walker.readStdout(cmd1, 'utf8', /*isRipgrep=*/false, (err1, stdout1) => {
|
||||
assert.equal(err1, null);
|
||||
assert(outputContains(stdout1, file0), stdout1);
|
||||
assert(!outputContains(stdout1, file1), stdout1);
|
||||
assert(outputContains(stdout1!, file0), stdout1);
|
||||
assert(!outputContains(stdout1!, file1), stdout1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -839,17 +839,17 @@ suite('FileWalker', () => {
|
||||
const cmd1 = walker.spawnFindCmd(TEST_ROOT_FOLDER);
|
||||
walker.readStdout(cmd1, 'utf8', /*isRipgrep=*/false, (err1, stdout1) => {
|
||||
assert.equal(err1, null);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file1), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file2), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file1), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file2), -1, stdout1);
|
||||
|
||||
const walker = new FileWalker({ type: QueryType.File, folderQueries: ROOT_FOLDER_QUERY, excludePattern: { '{**/examples,**/more}': true } });
|
||||
const cmd2 = walker.spawnFindCmd(TEST_ROOT_FOLDER);
|
||||
walker.readStdout(cmd2, 'utf8', /*isRipgrep=*/false, (err2, stdout2) => {
|
||||
assert.equal(err2, null);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.strictEqual(stdout2.split('\n').indexOf(file1), -1, stdout2);
|
||||
assert.strictEqual(stdout2.split('\n').indexOf(file2), -1, stdout2);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.strictEqual(stdout2!.split('\n').indexOf(file1), -1, stdout2);
|
||||
assert.strictEqual(stdout2!.split('\n').indexOf(file2), -1, stdout2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -869,15 +869,15 @@ suite('FileWalker', () => {
|
||||
const cmd1 = walker.spawnFindCmd(TEST_ROOT_FOLDER);
|
||||
walker.readStdout(cmd1, 'utf8', /*isRipgrep=*/false, (err1, stdout1) => {
|
||||
assert.equal(err1, null);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file1), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file1), -1, stdout1);
|
||||
|
||||
const walker = new FileWalker({ type: QueryType.File, folderQueries: ROOT_FOLDER_QUERY, excludePattern: { '**/examples/subfolder': true } });
|
||||
const cmd2 = walker.spawnFindCmd(TEST_ROOT_FOLDER);
|
||||
walker.readStdout(cmd2, 'utf8', /*isRipgrep=*/false, (err2, stdout2) => {
|
||||
assert.equal(err2, null);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.strictEqual(stdout2.split('\n').indexOf(file1), -1, stdout2);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.strictEqual(stdout2!.split('\n').indexOf(file1), -1, stdout2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -897,15 +897,15 @@ suite('FileWalker', () => {
|
||||
const cmd1 = walker.spawnFindCmd(TEST_ROOT_FOLDER);
|
||||
walker.readStdout(cmd1, 'utf8', /*isRipgrep=*/false, (err1, stdout1) => {
|
||||
assert.equal(err1, null);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file1), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file1), -1, stdout1);
|
||||
|
||||
const walker = new FileWalker({ type: QueryType.File, folderQueries: ROOT_FOLDER_QUERY, excludePattern: { '**/subfolder/anotherfolder': true } });
|
||||
const cmd2 = walker.spawnFindCmd(TEST_ROOT_FOLDER);
|
||||
walker.readStdout(cmd2, 'utf8', /*isRipgrep=*/false, (err2, stdout2) => {
|
||||
assert.equal(err2, null);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.strictEqual(stdout2.split('\n').indexOf(file1), -1, stdout2);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.strictEqual(stdout2!.split('\n').indexOf(file1), -1, stdout2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -925,15 +925,15 @@ suite('FileWalker', () => {
|
||||
const cmd1 = walker.spawnFindCmd(TEST_ROOT_FOLDER);
|
||||
walker.readStdout(cmd1, 'utf8', /*isRipgrep=*/false, (err1, stdout1) => {
|
||||
assert.equal(err1, null);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file1), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file1), -1, stdout1);
|
||||
|
||||
const walker = new FileWalker({ type: QueryType.File, folderQueries: ROOT_FOLDER_QUERY, excludePattern: { 'examples/subfolder': true } });
|
||||
const cmd2 = walker.spawnFindCmd(TEST_ROOT_FOLDER);
|
||||
walker.readStdout(cmd2, 'utf8', /*isRipgrep=*/false, (err2, stdout2) => {
|
||||
assert.equal(err2, null);
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.strictEqual(stdout2.split('\n').indexOf(file1), -1, stdout2);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(file0), -1, stdout1);
|
||||
assert.strictEqual(stdout2!.split('\n').indexOf(file1), -1, stdout2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -970,10 +970,10 @@ suite('FileWalker', () => {
|
||||
walker.readStdout(cmd1, 'utf8', /*isRipgrep=*/false, (err1, stdout1) => {
|
||||
assert.equal(err1, null);
|
||||
for (const fileIn of filesIn) {
|
||||
assert.notStrictEqual(stdout1.split('\n').indexOf(fileIn), -1, stdout1);
|
||||
assert.notStrictEqual(stdout1!.split('\n').indexOf(fileIn), -1, stdout1);
|
||||
}
|
||||
for (const fileOut of filesOut) {
|
||||
assert.strictEqual(stdout1.split('\n').indexOf(fileOut), -1, stdout1);
|
||||
assert.strictEqual(stdout1!.split('\n').indexOf(fileOut), -1, stdout1);
|
||||
}
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ import { ISerializedFileMatch } from 'vs/workbench/services/search/node/search';
|
||||
import { TextSearchEngineAdapter } from 'vs/workbench/services/search/node/textSearchAdapter';
|
||||
|
||||
function countAll(matches: ISerializedFileMatch[]): number {
|
||||
return matches.reduce((acc, m) => acc + m.numMatches, 0);
|
||||
return matches.reduce((acc, m) => acc + m.numMatches!, 0);
|
||||
}
|
||||
|
||||
const TEST_FIXTURES = path.normalize(getPathFromAmdModule(require, './fixtures'));
|
||||
@@ -39,7 +39,7 @@ function doLegacySearchTest(config: ITextQuery, expectedResultCount: number | Fu
|
||||
if (result && Array.isArray(result)) {
|
||||
c += countAll(result);
|
||||
}
|
||||
}, null).then(() => {
|
||||
}, null!).then(() => {
|
||||
if (typeof expectedResultCount === 'function') {
|
||||
assert(expectedResultCount(c));
|
||||
} else {
|
||||
@@ -55,7 +55,7 @@ function doRipgrepSearchTest(query: ITextQuery, expectedResultCount: number | Fu
|
||||
const results: ISerializedFileMatch[] = [];
|
||||
return engine.search(new CancellationTokenSource().token, _results => {
|
||||
if (_results) {
|
||||
c += _results.reduce((acc, cur) => acc + cur.numMatches, 0);
|
||||
c += _results.reduce((acc, cur) => acc + cur.numMatches!, 0);
|
||||
results.push(..._results);
|
||||
}
|
||||
}, () => { }).then(() => {
|
||||
@@ -319,7 +319,7 @@ suite('Search-integration', function () {
|
||||
};
|
||||
|
||||
return doRipgrepSearchTest(config, 1).then(results => {
|
||||
const matchRange = (<ITextSearchMatch>results[0].results[0]).ranges;
|
||||
const matchRange = (<ITextSearchMatch>results[0].results![0]).ranges;
|
||||
assert.deepEqual(matchRange, [{
|
||||
startLineNumber: 0,
|
||||
startColumn: 1,
|
||||
@@ -338,8 +338,8 @@ suite('Search-integration', function () {
|
||||
|
||||
return doRipgrepSearchTest(config, 15).then(results => {
|
||||
assert.equal(results.length, 3);
|
||||
assert.equal(results[0].results.length, 1);
|
||||
const match = <ITextSearchMatch>results[0].results[0];
|
||||
assert.equal(results[0].results!.length, 1);
|
||||
const match = <ITextSearchMatch>results[0].results![0];
|
||||
assert.equal((<ISearchRange[]>match.ranges).length, 5);
|
||||
});
|
||||
});
|
||||
@@ -355,13 +355,13 @@ suite('Search-integration', function () {
|
||||
|
||||
return doRipgrepSearchTest(config, 4).then(results => {
|
||||
assert.equal(results.length, 4);
|
||||
assert.equal((<ITextSearchContext>results[0].results[0]).lineNumber, 25);
|
||||
assert.equal((<ITextSearchContext>results[0].results[0]).text, ' compiler.addUnit(prog,"input.ts");');
|
||||
assert.equal((<ITextSearchContext>results[0].results![0]).lineNumber, 25);
|
||||
assert.equal((<ITextSearchContext>results[0].results![0]).text, ' compiler.addUnit(prog,"input.ts");');
|
||||
// assert.equal((<ITextSearchMatch>results[1].results[0]).preview.text, ' compiler.typeCheck();\n'); // See https://github.com/BurntSushi/ripgrep/issues/1095
|
||||
assert.equal((<ITextSearchContext>results[2].results[0]).lineNumber, 27);
|
||||
assert.equal((<ITextSearchContext>results[2].results[0]).text, ' compiler.emit();');
|
||||
assert.equal((<ITextSearchContext>results[3].results[0]).lineNumber, 28);
|
||||
assert.equal((<ITextSearchContext>results[3].results[0]).text, '');
|
||||
assert.equal((<ITextSearchContext>results[2].results![0]).lineNumber, 27);
|
||||
assert.equal((<ITextSearchContext>results[2].results![0]).text, ' compiler.emit();');
|
||||
assert.equal((<ITextSearchContext>results[3].results![0]).lineNumber, 28);
|
||||
assert.equal((<ITextSearchContext>results[3].results![0]).text, '');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -219,9 +219,9 @@ suite('Files - TextFileService', () => {
|
||||
assert.equal(res.results.length, 1);
|
||||
assert.ok(res.results[0].success);
|
||||
|
||||
assert.equal(res.results[0].target.scheme, Schemas.file);
|
||||
assert.equal(res.results[0].target.authority, untitledUncUri.authority);
|
||||
assert.equal(res.results[0].target.path, untitledUncUri.path);
|
||||
assert.equal(res.results[0].target!.scheme, Schemas.file);
|
||||
assert.equal(res.results[0].target!.authority, untitledUncUri.authority);
|
||||
assert.equal(res.results[0].target!.path, untitledUncUri.path);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -47,7 +47,7 @@ suite('Workbench - TextModelResolverService', () => {
|
||||
teardown(() => {
|
||||
if (model) {
|
||||
model.dispose();
|
||||
model = void 0;
|
||||
model = (void 0)!;
|
||||
}
|
||||
(<TextFileEditorModelManager>accessor.textFileService.models).clear();
|
||||
(<TextFileEditorModelManager>accessor.textFileService.models).dispose();
|
||||
@@ -63,11 +63,11 @@ suite('Workbench - TextModelResolverService', () => {
|
||||
return Promise.resolve(accessor.modelService.createModel(modelContent, languageSelection, resource));
|
||||
}
|
||||
|
||||
return Promise.resolve(null);
|
||||
return Promise.resolve(null!);
|
||||
}
|
||||
});
|
||||
|
||||
let resource = URI.from({ scheme: 'test', authority: null, path: 'thePath' });
|
||||
let resource = URI.from({ scheme: 'test', authority: null!, path: 'thePath' });
|
||||
let input: ResourceEditorInput = instantiationService.createInstance(ResourceEditorInput, 'The Name', 'The Description', resource);
|
||||
|
||||
return input.resolve().then(async model => {
|
||||
@@ -132,7 +132,7 @@ suite('Workbench - TextModelResolverService', () => {
|
||||
});
|
||||
|
||||
test('even loading documents should be refcounted', async () => {
|
||||
let resolveModel: Function;
|
||||
let resolveModel!: Function;
|
||||
let waitForIt = new Promise(c => resolveModel = c);
|
||||
|
||||
const disposable = accessor.textModelResolverService.registerTextModelContentProvider('test', {
|
||||
@@ -145,7 +145,7 @@ suite('Workbench - TextModelResolverService', () => {
|
||||
}
|
||||
});
|
||||
|
||||
const uri = URI.from({ scheme: 'test', authority: null, path: 'thePath' });
|
||||
const uri = URI.from({ scheme: 'test', authority: null!, path: 'thePath' });
|
||||
|
||||
const modelRefPromise1 = accessor.textModelResolverService.createModelReference(uri);
|
||||
const modelRefPromise2 = accessor.textModelResolverService.createModelReference(uri);
|
||||
|
||||
@@ -19,12 +19,12 @@ class MyPart extends Part {
|
||||
|
||||
createTitleArea(parent: HTMLElement): HTMLElement {
|
||||
assert.strictEqual(parent, this.expectedParent);
|
||||
return super.createTitleArea(parent);
|
||||
return super.createTitleArea(parent)!;
|
||||
}
|
||||
|
||||
createContentArea(parent: HTMLElement): HTMLElement {
|
||||
assert.strictEqual(parent, this.expectedParent);
|
||||
return super.createContentArea(parent);
|
||||
return super.createContentArea(parent)!;
|
||||
}
|
||||
|
||||
getMemento(scope: StorageScope) {
|
||||
@@ -68,7 +68,7 @@ class MyPart3 extends Part {
|
||||
}
|
||||
|
||||
createTitleArea(parent: HTMLElement): HTMLElement {
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
|
||||
createContentArea(parent: HTMLElement): HTMLElement {
|
||||
@@ -97,7 +97,7 @@ suite('Workbench parts', () => {
|
||||
|
||||
test('Creation', () => {
|
||||
let b = document.createElement('div');
|
||||
document.getElementById(fixtureId).appendChild(b);
|
||||
document.getElementById(fixtureId)!.appendChild(b);
|
||||
hide(b);
|
||||
|
||||
let part = new MyPart(b);
|
||||
@@ -134,7 +134,7 @@ suite('Workbench parts', () => {
|
||||
|
||||
test('Part Layout with Title and Content', function () {
|
||||
let b = document.createElement('div');
|
||||
document.getElementById(fixtureId).appendChild(b);
|
||||
document.getElementById(fixtureId)!.appendChild(b);
|
||||
hide(b);
|
||||
|
||||
let part = new MyPart2();
|
||||
@@ -146,7 +146,7 @@ suite('Workbench parts', () => {
|
||||
|
||||
test('Part Layout with Content only', function () {
|
||||
let b = document.createElement('div');
|
||||
document.getElementById(fixtureId).appendChild(b);
|
||||
document.getElementById(fixtureId)!.appendChild(b);
|
||||
hide(b);
|
||||
|
||||
let part = new MyPart3();
|
||||
|
||||
@@ -267,7 +267,7 @@ suite('Workbench base editor', () => {
|
||||
super();
|
||||
}
|
||||
public getTypeId() { return 'testEditorInput'; }
|
||||
public resolve(): Promise<IEditorModel> { return Promise.resolve(null); }
|
||||
public resolve(): Promise<IEditorModel> { return Promise.resolve(null!); }
|
||||
|
||||
public matches(other: TestEditorInput): boolean {
|
||||
return other && this.id === other.id && other instanceof TestEditorInput;
|
||||
|
||||
@@ -40,7 +40,7 @@ suite('Editor - Range decorations', () => {
|
||||
model = aModel(URI.file('some_file'));
|
||||
codeEditor = createTestCodeEditor({ model: model });
|
||||
|
||||
instantiationService.stub(IEditorService, 'activeEditor', { getResource: () => { return codeEditor.getModel().uri; } });
|
||||
instantiationService.stub(IEditorService, 'activeEditor', { getResource: () => { return codeEditor.getModel()!.uri; } });
|
||||
instantiationService.stub(IEditorService, 'activeTextEditorWidget', codeEditor);
|
||||
|
||||
testObject = instantiationService.createInstance(RangeHighlightDecorations);
|
||||
|
||||
@@ -13,9 +13,9 @@ import { QuickOpenHandlerDescriptor, IQuickOpenRegistry, Extensions as QuickOpen
|
||||
export class TestQuickOpenService implements IQuickOpenService {
|
||||
public _serviceBrand: any;
|
||||
|
||||
private callback: (prefix: string) => void;
|
||||
private callback?: (prefix?: string) => void;
|
||||
|
||||
constructor(callback?: (prefix: string) => void) {
|
||||
constructor(callback?: (prefix?: string) => void) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ export class TestQuickOpenService implements IQuickOpenService {
|
||||
}
|
||||
|
||||
get onShow(): Event<void> {
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
|
||||
get onHide(): Event<void> {
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
|
||||
public dispose() { }
|
||||
@@ -59,7 +59,7 @@ suite('QuickOpen', () => {
|
||||
'testhandler',
|
||||
',',
|
||||
'Handler',
|
||||
null
|
||||
null!
|
||||
);
|
||||
|
||||
registry.registerQuickOpenHandler(handler);
|
||||
@@ -71,7 +71,7 @@ suite('QuickOpen', () => {
|
||||
});
|
||||
|
||||
test('QuickOpen Action', () => {
|
||||
let defaultAction = new QuickOpenAction('id', 'label', void 0, new TestQuickOpenService((prefix: string) => assert(!prefix)));
|
||||
let defaultAction = new QuickOpenAction('id', 'label', (void 0)!, new TestQuickOpenService((prefix: string) => assert(!prefix)));
|
||||
let prefixAction = new QuickOpenAction('id', 'label', ',', new TestQuickOpenService((prefix: string) => assert(!!prefix)));
|
||||
|
||||
defaultAction.run();
|
||||
|
||||
@@ -13,7 +13,7 @@ suite('Viewlets', () => {
|
||||
class TestViewlet extends Viewlet {
|
||||
|
||||
constructor() {
|
||||
super('id', null, null, null, null, null);
|
||||
super('id', null!, null!, null!, null!, null!);
|
||||
}
|
||||
|
||||
public layout(dimension: any): void {
|
||||
|
||||
@@ -44,12 +44,12 @@ suite('Workbench editor model', () => {
|
||||
return Promise.resolve(accessor.modelService.createModel(modelContent, languageSelection, resource));
|
||||
}
|
||||
|
||||
return Promise.resolve(null);
|
||||
return Promise.resolve(null!);
|
||||
}
|
||||
});
|
||||
|
||||
let input = instantiationService.createInstance(ResourceEditorInput, 'name', 'description', URI.from({ scheme: 'test', authority: null, path: 'thePath' }));
|
||||
let otherInput = instantiationService.createInstance(ResourceEditorInput, 'name2', 'description', URI.from({ scheme: 'test', authority: null, path: 'thePath' }));
|
||||
let input = instantiationService.createInstance(ResourceEditorInput, 'name', 'description', URI.from({ scheme: 'test', authority: null!, path: 'thePath' }));
|
||||
let otherInput = instantiationService.createInstance(ResourceEditorInput, 'name2', 'description', URI.from({ scheme: 'test', authority: null!, path: 'thePath' }));
|
||||
let diffInput = new DiffEditorInput('name', 'description', input, otherInput);
|
||||
|
||||
return diffInput.resolve().then((model: any) => {
|
||||
|
||||
@@ -77,7 +77,7 @@ class TestEditorInput extends EditorInput {
|
||||
super();
|
||||
}
|
||||
getTypeId() { return 'testEditorInputForGroups'; }
|
||||
resolve(): Promise<IEditorModel> { return Promise.resolve(null); }
|
||||
resolve(): Promise<IEditorModel> { return Promise.resolve(null!); }
|
||||
|
||||
matches(other: TestEditorInput): boolean {
|
||||
return other && this.id === other.id && other instanceof TestEditorInput;
|
||||
@@ -97,7 +97,7 @@ class NonSerializableTestEditorInput extends EditorInput {
|
||||
super();
|
||||
}
|
||||
getTypeId() { return 'testEditorInputForGroups-nonSerializable'; }
|
||||
resolve(): Promise<IEditorModel> { return Promise.resolve(null); }
|
||||
resolve(): Promise<IEditorModel> { return Promise.resolve(null!); }
|
||||
|
||||
matches(other: NonSerializableTestEditorInput): boolean {
|
||||
return other && this.id === other.id && other instanceof NonSerializableTestEditorInput;
|
||||
@@ -110,7 +110,7 @@ class TestFileEditorInput extends EditorInput implements IFileEditorInput {
|
||||
super();
|
||||
}
|
||||
getTypeId() { return 'testFileEditorInputForGroups'; }
|
||||
resolve(): Promise<IEditorModel> { return Promise.resolve(null); }
|
||||
resolve(): Promise<IEditorModel> { return Promise.resolve(null!); }
|
||||
|
||||
matches(other: TestFileEditorInput): boolean {
|
||||
return other && this.id === other.id && other instanceof TestFileEditorInput;
|
||||
@@ -120,7 +120,7 @@ class TestFileEditorInput extends EditorInput implements IFileEditorInput {
|
||||
}
|
||||
|
||||
getEncoding(): string {
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
|
||||
setPreferredEncoding(encoding: string) {
|
||||
@@ -781,7 +781,7 @@ suite('Workbench editor groups', () => {
|
||||
group.openEditor(input5, { active: true, pinned: true });
|
||||
|
||||
// Close Others
|
||||
group.closeEditors(group.activeEditor);
|
||||
group.closeEditors(group.activeEditor!);
|
||||
assert.equal(group.activeEditor, input5);
|
||||
assert.equal(group.count, 1);
|
||||
|
||||
@@ -795,7 +795,7 @@ suite('Workbench editor groups', () => {
|
||||
|
||||
// Close Left
|
||||
assert.equal(group.activeEditor, input3);
|
||||
group.closeEditors(group.activeEditor, CloseDirection.LEFT);
|
||||
group.closeEditors(group.activeEditor!, CloseDirection.LEFT);
|
||||
assert.equal(group.activeEditor, input3);
|
||||
assert.equal(group.count, 3);
|
||||
assert.equal(group.getEditors()[0], input3);
|
||||
@@ -812,7 +812,7 @@ suite('Workbench editor groups', () => {
|
||||
|
||||
// Close Right
|
||||
assert.equal(group.activeEditor, input3);
|
||||
group.closeEditors(group.activeEditor, CloseDirection.RIGHT);
|
||||
group.closeEditors(group.activeEditor!, CloseDirection.RIGHT);
|
||||
assert.equal(group.activeEditor, input3);
|
||||
assert.equal(group.count, 3);
|
||||
assert.equal(group.getEditors()[0], input1);
|
||||
@@ -953,16 +953,16 @@ suite('Workbench editor groups', () => {
|
||||
group.openEditor(input1);
|
||||
|
||||
assert.equal(group.count, 1);
|
||||
assert.equal(group.activeEditor.matches(input1), true);
|
||||
assert.equal(group.previewEditor.matches(input1), true);
|
||||
assert.equal(group.activeEditor!.matches(input1), true);
|
||||
assert.equal(group.previewEditor!.matches(input1), true);
|
||||
assert.equal(group.isActive(input1), true);
|
||||
|
||||
// Create model again - should load from storage
|
||||
group = inst.createInstance(EditorGroup, group.serialize());
|
||||
|
||||
assert.equal(group.count, 1);
|
||||
assert.equal(group.activeEditor.matches(input1), true);
|
||||
assert.equal(group.previewEditor.matches(input1), true);
|
||||
assert.equal(group.activeEditor!.matches(input1), true);
|
||||
assert.equal(group.previewEditor!.matches(input1), true);
|
||||
assert.equal(group.isActive(input1), true);
|
||||
});
|
||||
|
||||
@@ -1003,10 +1003,10 @@ suite('Workbench editor groups', () => {
|
||||
|
||||
assert.equal(group1.count, 3);
|
||||
assert.equal(group2.count, 3);
|
||||
assert.equal(group1.activeEditor.matches(g1_input2), true);
|
||||
assert.equal(group2.activeEditor.matches(g2_input1), true);
|
||||
assert.equal(group1.previewEditor.matches(g1_input2), true);
|
||||
assert.equal(group2.previewEditor.matches(g2_input2), true);
|
||||
assert.equal(group1.activeEditor!.matches(g1_input2), true);
|
||||
assert.equal(group2.activeEditor!.matches(g2_input1), true);
|
||||
assert.equal(group1.previewEditor!.matches(g1_input2), true);
|
||||
assert.equal(group2.previewEditor!.matches(g2_input2), true);
|
||||
|
||||
assert.equal(group1.getEditors(true)[0].matches(g1_input2), true);
|
||||
assert.equal(group1.getEditors(true)[1].matches(g1_input1), true);
|
||||
@@ -1022,10 +1022,10 @@ suite('Workbench editor groups', () => {
|
||||
|
||||
assert.equal(group1.count, 3);
|
||||
assert.equal(group2.count, 3);
|
||||
assert.equal(group1.activeEditor.matches(g1_input2), true);
|
||||
assert.equal(group2.activeEditor.matches(g2_input1), true);
|
||||
assert.equal(group1.previewEditor.matches(g1_input2), true);
|
||||
assert.equal(group2.previewEditor.matches(g2_input2), true);
|
||||
assert.equal(group1.activeEditor!.matches(g1_input2), true);
|
||||
assert.equal(group2.activeEditor!.matches(g2_input1), true);
|
||||
assert.equal(group1.previewEditor!.matches(g1_input2), true);
|
||||
assert.equal(group2.previewEditor!.matches(g2_input2), true);
|
||||
|
||||
assert.equal(group1.getEditors(true)[0].matches(g1_input2), true);
|
||||
assert.equal(group1.getEditors(true)[1].matches(g1_input1), true);
|
||||
@@ -1062,8 +1062,8 @@ suite('Workbench editor groups', () => {
|
||||
group.openEditor(serializableInput2, { active: false, pinned: true });
|
||||
|
||||
assert.equal(group.count, 3);
|
||||
assert.equal(group.activeEditor.matches(nonSerializableInput2), true);
|
||||
assert.equal(group.previewEditor.matches(nonSerializableInput2), true);
|
||||
assert.equal(group.activeEditor!.matches(nonSerializableInput2), true);
|
||||
assert.equal(group.previewEditor!.matches(nonSerializableInput2), true);
|
||||
|
||||
assert.equal(group.getEditors(true)[0].matches(nonSerializableInput2), true);
|
||||
assert.equal(group.getEditors(true)[1].matches(serializableInput1), true);
|
||||
@@ -1073,7 +1073,7 @@ suite('Workbench editor groups', () => {
|
||||
group = inst.createInstance(EditorGroup, group.serialize());
|
||||
|
||||
assert.equal(group.count, 2);
|
||||
assert.equal(group.activeEditor.matches(serializableInput1), true);
|
||||
assert.equal(group.activeEditor!.matches(serializableInput1), true);
|
||||
assert.equal(group.previewEditor, null);
|
||||
|
||||
assert.equal(group.getEditors(true)[0].matches(serializableInput1), true);
|
||||
|
||||
@@ -64,7 +64,7 @@ suite('Workbench editor model', () => {
|
||||
let m = new MyTextEditorModel(modelService, modeService);
|
||||
return m.load().then((model: MyTextEditorModel) => {
|
||||
assert(model === m);
|
||||
model.createTextEditorModel(createTextBufferFactory('foo'), null, 'text/plain');
|
||||
model.createTextEditorModel(createTextBufferFactory('foo'), null!, 'text/plain');
|
||||
assert.strictEqual(m.isResolved(), true);
|
||||
}).then(() => {
|
||||
m.dispose();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user