diff --git a/.vscode/settings.json b/.vscode/settings.json index 8b9ca6cd07b..2cb6c48fce4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -48,5 +48,7 @@ }, { "fileMatch": [ "cglicenses.json" ], "url": "./.vscode/cglicenses.schema.json" - }] + } +], +"git.ignoreLimitWarning": true } diff --git a/build/azure-pipelines/linux/continuous-build-linux.yml b/build/azure-pipelines/linux/continuous-build-linux.yml index 91891e6da94..fc124c5bf45 100644 --- a/build/azure-pipelines/linux/continuous-build-linux.yml +++ b/build/azure-pipelines/linux/continuous-build-linux.yml @@ -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 diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 5ed1e395d49..e366afdfb70 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -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); diff --git a/package.json b/package.json index ba4990a1ea0..a00168c03a2 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/resources/linux/debian/control.template b/resources/linux/debian/control.template index 5e7617824cd..27d36308c88 100644 --- a/resources/linux/debian/control.template +++ b/resources/linux/debian/control.template @@ -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 diff --git a/resources/linux/rpm/dependencies.json b/resources/linux/rpm/dependencies.json index c2ae8b8fe31..d0b64c4fa68 100644 --- a/resources/linux/rpm/dependencies.json +++ b/resources/linux/rpm/dependencies.json @@ -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", diff --git a/resources/linux/snap/snapcraft.yaml b/resources/linux/snap/snapcraft.yaml index e0772308684..e7971e8a7af 100644 --- a/resources/linux/snap/snapcraft.yaml +++ b/resources/linux/snap/snapcraft.yaml @@ -16,7 +16,6 @@ parts: stage-packages: - libasound2 - libc++1 - - libgconf2-4 - libnotify4 - libnspr4 - libnss3 diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 0e833acce0c..22a4caef006 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -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" ] -} \ No newline at end of file +} diff --git a/src/vs/base/parts/quickopen/test/browser/quickopen.test.ts b/src/vs/base/parts/quickopen/test/browser/quickopen.test.ts index f42a2f73e9b..f53d0b4e1ed 100644 --- a/src/vs/base/parts/quickopen/test/browser/quickopen.test.ts +++ b/src/vs/base/parts/quickopen/test/browser/quickopen.test.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); }); }); diff --git a/src/vs/base/parts/tree/test/browser/treeModel.test.ts b/src/vs/base/parts/tree/test/browser/treeModel.test.ts index baa5350b49d..7e034192aba 100644 --- a/src/vs/base/parts/tree/test/browser/treeModel.test.ts +++ b/src/vs/base/parts/tree/test/browser/treeModel.test.ts @@ -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; diff --git a/src/vs/base/parts/tree/test/browser/treeViewModel.test.ts b/src/vs/base/parts/tree/test/browser/treeViewModel.test.ts index 0f0a1f81644..da11e8cfba3 100644 --- a/src/vs/base/parts/tree/test/browser/treeViewModel.test.ts +++ b/src/vs/base/parts/tree/test/browser/treeViewModel.test.ts @@ -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', () => { diff --git a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts index aa8210ae770..a3a47fd39a9 100644 --- a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts @@ -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); } }; -} \ No newline at end of file +} diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 205c1ee3e67..ef2349e6b59 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -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 { @@ -495,6 +498,12 @@ export class CodeApplication extends Disposable { }); } + private initBackupService(accessor: ServicesAccessor): Promise { + const backupMainService = accessor.get(IBackupMainService) as BackupMainService; + + return backupMainService.initialize(); + } + private openFirstWindow(accessor: ServicesAccessor): ICodeWindow[] { const appInstantiationService = accessor.get(IInstantiationService); diff --git a/src/vs/editor/contrib/documentSymbols/test/outlineModel.test.ts b/src/vs/editor/contrib/documentSymbols/test/outlineModel.test.ts index b8543a78062..057bdfbea2c 100644 --- a/src/vs/editor/contrib/documentSymbols/test/outlineModel.test.ts +++ b/src/vs/editor/contrib/documentSymbols/test/outlineModel.test.ts @@ -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))); diff --git a/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts b/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts index 4460011c007..9770cb36420 100644 --- a/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetController2.old.test.ts @@ -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); @@ -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} { codeSnippet = 'for (let ${1:i}=0; ${1:i} expected=${actual.toString()}`); } assert.equal(s.length, 0); diff --git a/src/vs/editor/contrib/suggest/test/suggestMemory.test.ts b/src/vs/editor/contrib/suggest/test/suggestMemory.test.ts index 54e76d19e85..3dda6f9f6fb 100644 --- a/src/vs/editor/contrib/suggest/test/suggestMemory.test.ts +++ b/src/vs/editor/contrib/suggest/test/suggestMemory.test.ts @@ -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', () => { diff --git a/src/vs/editor/contrib/suggest/test/suggestModel.test.ts b/src/vs/editor/contrib/suggest/test/suggestModel.test.ts index 49048da1339..db6af2b0fbf 100644 --- a/src/vs/editor/contrib/suggest/test/suggestModel.test.ts +++ b/src/vs/editor/contrib/suggest/test/suggestModel.test.ts @@ -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: [ diff --git a/src/vs/editor/standalone/test/browser/standaloneLanguages.test.ts b/src/vs/editor/standalone/test/browser/standaloneLanguages.test.ts index baa5c568f05..395c611acf2 100644 --- a/src/vs/editor/standalone/test/browser/standaloneLanguages.test.ts +++ b/src/vs/editor/standalone/test/browser/standaloneLanguages.test.ts @@ -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 ( diff --git a/src/vs/platform/actions/common/menu.ts b/src/vs/platform/actions/common/menu.ts deleted file mode 100644 index 3d1a65b2d95..00000000000 --- a/src/vs/platform/actions/common/menu.ts +++ /dev/null @@ -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]; - -export class Menu implements IMenu { - - private readonly _onDidChange = new Emitter(); - private readonly _disposables: IDisposable[] = []; - - private _menuGroups: MenuItemGroup[]; - private _contextKeys: Set; - - 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 { - return this._onDidChange.event; - } - - getActions(options: IMenuActionOptions): [string, Array][] { - const result: [string, Array][] = []; - for (let group of this._menuGroups) { - const [id, items] = group; - const activeActions: Array = []; - 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): 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); - } -} diff --git a/src/vs/platform/actions/common/menuService.ts b/src/vs/platform/actions/common/menuService.ts index e5013e1854e..e75485c4770 100644 --- a/src/vs/platform/actions/common/menuService.ts +++ b/src/vs/platform/actions/common/menuService.ts @@ -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]; + +class Menu implements IMenu { + + private readonly _onDidChange = new Emitter(); + private readonly _disposables: IDisposable[] = []; + + private _menuGroups: MenuItemGroup[]; + private _contextKeys: Set; + + 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 { + return this._onDidChange.event; + } + + getActions(options: IMenuActionOptions): [string, Array][] { + const result: [string, Array][] = []; + for (let group of this._menuGroups) { + const [id, items] = group; + const activeActions: Array = []; + 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): 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); + } +} diff --git a/src/vs/platform/backup/electron-main/backupMainService.ts b/src/vs/platform/backup/electron-main/backupMainService.ts index 38ba6e62460..a42c5afc30e 100644 --- a/src/vs/platform/backup/electron-main/backupMainService.ts +++ b/src/vs/platform/backup/electron-main/backupMainService.ts @@ -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 { + 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 { + + // 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 { 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 { 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 { 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 { 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 { + + // 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 { 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 { + 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(); } diff --git a/src/vs/platform/backup/test/electron-main/backupMainService.test.ts b/src/vs/platform/backup/test/electron-main/backupMainService.test.ts index 7921caa38c0..35808ca924e 100644 --- a/src/vs/platform/backup/test/electron-main/backupMainService.test.ts +++ b/src/vs/platform/backup/test/electron-main/backupMainService.test.ts @@ -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 = 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 = (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 = 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 = 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 = 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 = 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 = 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 = 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 = JSON.parse(buffer); - assert.deepEqual(json.folderURIWorkspaces, [fooFile.toString(), barFile.toString()]); - }); + const buffer = await pfs.readFile(backupWorkspacesPath, 'utf-8'); + const json = 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 = JSON.parse(buffer); + const buffer = await pfs.readFile(backupWorkspacesPath, 'utf-8'); + const json = 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 = 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 = 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 = 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 = 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 = 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 = (JSON.parse(content)); + assert.deepEqual(json.folderURIWorkspaces, [existingTestFolder1.toString()]); }); }); diff --git a/src/vs/platform/commands/test/commands.test.ts b/src/vs/platform/commands/test/commands.test.ts index 3ec89a65d3a..054c0ff4997 100644 --- a/src/vs/platform/commands/test/commands.test.ts +++ b/src/vs/platform/commands/test/commands.test.ts @@ -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); }); }); diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 87c7e26a361..23e84ca2f83 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -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; diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index f61de15990b..61302275e2c 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -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 ': 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 ': 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; -} \ No newline at end of file +} diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 1cbd2aad856..4a151193697 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -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 diff --git a/src/vs/platform/extensionManagement/test/electron-browser/extensionEnablementService.test.ts b/src/vs/platform/extensionManagement/test/electron-browser/extensionEnablementService.test.ts index b898a8f1350..e4b15d11db7 100644 --- a/src/vs/platform/extensionManagement/test/electron-browser/extensionEnablementService.test.ts +++ b/src/vs/platform/extensionManagement/test/electron-browser/extensionEnablementService.test.ts @@ -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); }); diff --git a/src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts b/src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts index d75b1cbdec5..1a3107370cb 100644 --- a/src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts +++ b/src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts @@ -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', () => { diff --git a/src/vs/platform/storage/test/node/storageService.test.ts b/src/vs/platform/storage/test/node/storageService.test.ts index 411af79487d..3e4da70f096 100644 --- a/src/vs/platform/storage/test/node/storageService.test.ts +++ b/src/vs/platform/storage/test/node/storageService.test.ts @@ -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); diff --git a/src/vs/platform/telemetry/test/electron-browser/commonProperties.test.ts b/src/vs/platform/telemetry/test/electron-browser/commonProperties.test.ts index f40ff181d7e..d21422f49e2 100644 --- a/src/vs/platform/telemetry/test/electron-browser/commonProperties.test.ts +++ b/src/vs/platform/telemetry/test/electron-browser/commonProperties.test.ts @@ -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(() => { diff --git a/src/vs/platform/theme/test/electron-browser/colorRegistry.releaseTest.ts b/src/vs/platform/theme/test/electron-browser/colorRegistry.releaseTest.ts index 5cb6611edea..30e0d0ca05e 100644 --- a/src/vs/platform/theme/test/electron-browser/colorRegistry.releaseTest.ts +++ b/src/vs/platform/theme/test/electron-browser/colorRegistry.releaseTest.ts @@ -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; diff --git a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts index 4e24cd819f8..cc09cbec886 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts @@ -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); }); }); diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 945417405a4..a36e27aa168 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -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 diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index f4cf361cd18..647ca26252a 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -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 { diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index 6a0e7d9f7f1..49059e84543 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -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)); } } diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index ba390e1ff49..4d8eb68180d 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -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; } } diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index f9bee82ba94..f819048ab29 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -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 { diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 458497b4f46..7a13bd59574 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -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, diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index e7eea355c12..e69e99c189b 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -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 = 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); diff --git a/src/vs/workbench/parts/debug/browser/baseDebugView.ts b/src/vs/workbench/parts/debug/browser/baseDebugView.ts index 6230949044e..74949f48d0e 100644 --- a/src/vs/workbench/parts/debug/browser/baseDebugView.ts +++ b/src/vs/workbench/parts/debug/browser/baseDebugView.ts @@ -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; diff --git a/src/vs/workbench/parts/debug/browser/debugActions.ts b/src/vs/workbench/parts/debug/browser/debugActions.ts index 26f3536fe9c..7485fe71b15 100644 --- a/src/vs/workbench/parts/debug/browser/debugActions.ts +++ b/src/vs/workbench/parts/debug/browser/debugActions.ts @@ -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 { - if (config && 'type' in config && 'request' in config) { - return this.debugService.startDebugging(undefined, config, this.isNoDebug()); - } - + public run(): Promise { const configurationManager = this.debugService.getConfigurationManager(); let launch = configurationManager.selectedConfiguration.launch; if (!launch || launch.getConfigurationNames().length === 0) { diff --git a/src/vs/workbench/parts/debug/browser/debugCommands.ts b/src/vs/workbench/parts/debug/browser/debugCommands.ts index 88d709b6eaa..f983c1cc2d0 100644 --- a/src/vs/workbench/parts/debug/browser/debugCommands.ts +++ b/src/vs/workbench/parts/debug/browser/debugCommands.ts @@ -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, diff --git a/src/vs/workbench/parts/debug/browser/media/debug.contribution.css b/src/vs/workbench/parts/debug/browser/media/debug.contribution.css index 1fa7c82fd09..264cfcb3b07 100644 --- a/src/vs/workbench/parts/debug/browser/media/debug.contribution.css +++ b/src/vs/workbench/parts/debug/browser/media/debug.contribution.css @@ -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; } diff --git a/src/vs/workbench/parts/debug/browser/media/repl.css b/src/vs/workbench/parts/debug/browser/media/repl.css index 7c6c277950a..a1fde30cbfe 100644 --- a/src/vs/workbench/parts/debug/browser/media/repl.css +++ b/src/vs/workbench/parts/debug/browser/media/repl.css @@ -5,7 +5,7 @@ /* Debug repl */ -.repl { +.composite.panel .repl { height: 100%; box-sizing: border-box; overflow: hidden; diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 02e86fa4ec7..31e94ae80b2 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -393,7 +393,7 @@ export interface IDebugModel extends ITreeElement { getWatchExpressions(): ReadonlyArray; onDidChangeBreakpoints: Event; - onDidChangeCallStack: Event; + onDidChangeCallStack: Event; onDidChangeWatchExpressions: Event; } diff --git a/src/vs/workbench/parts/debug/common/debugModel.ts b/src/vs/workbench/parts/debug/common/debugModel.ts index fc820a376e6..f0100fbc7db 100644 --- a/src/vs/workbench/parts/debug/common/debugModel.ts +++ b/src/vs/workbench/parts/debug/common/debugModel.ts @@ -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(); private breakpointsSessionId: string; private readonly _onDidChangeBreakpoints: Emitter; - private readonly _onDidChangeCallStack: Emitter; + private readonly _onDidChangeCallStack: Emitter; private readonly _onDidChangeWatchExpressions: Emitter; constructor( @@ -751,7 +758,7 @@ export class DebugModel implements IDebugModel { this.sessions = []; this.toDispose = []; this._onDidChangeBreakpoints = new Emitter(); - this._onDidChangeCallStack = new Emitter(); + this._onDidChangeCallStack = new Emitter(); this._onDidChangeWatchExpressions = new Emitter(); } @@ -786,7 +793,7 @@ export class DebugModel implements IDebugModel { return this._onDidChangeBreakpoints.event; } - get onDidChangeCallStack(): Event { + get onDidChangeCallStack(): Event { 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); }); } diff --git a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts index 47228bbe56b..e99c0bc453e 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -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(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 { - 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); diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 562c430b66d..e99893b1190 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -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); } } diff --git a/src/vs/workbench/parts/debug/electron-browser/debugSession.ts b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts index bf8f17e9dce..d2bbc24eccb 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugSession.ts @@ -611,6 +611,16 @@ export class DebugSession implements IDebugSession { this.model.fetchCallStack(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('debug').openDebug === 'openOnDebugBreak') { this.viewletService.openViewlet(VIEWLET_ID); diff --git a/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts b/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts index 0512fa8bb90..769472f0bb3 100644 --- a/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts @@ -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 diff --git a/src/vs/workbench/parts/debug/test/browser/debugANSIHandling.test.ts b/src/vs/workbench/parts/debug/test/browser/debugANSIHandling.test.ts index c8e8ed02750..fe95a2e055a 100644 --- a/src/vs/workbench/parts/debug/test/browser/debugANSIHandling.test.ts +++ b/src/vs/workbench/parts/debug/test/browser/debugANSIHandling.test.ts @@ -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!; } } diff --git a/src/vs/workbench/parts/debug/test/node/debugger.test.ts b/src/vs/workbench/parts/debug/test/node/debugger.test.ts index d4f9160f8dd..2c89689d5d1 100644 --- a/src/vs/workbench/parts/debug/test/node/debugger.test.ts +++ b/src/vs/workbench/parts/debug/test/node/debugger.test.ts @@ -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']); diff --git a/src/vs/workbench/parts/experiments/test/electron-browser/experimentService.test.ts b/src/vs/workbench/parts/experiments/test/electron-browser/experimentService.test.ts index 6b117c4c2b2..fae51e767ad 100644 --- a/src/vs/workbench/parts/experiments/test/electron-browser/experimentService.test.ts +++ b/src/vs/workbench/parts/experiments/test/electron-browser/experimentService.test.ts @@ -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); diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts index b0dd6e41b18..9e0266724f2 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts @@ -1285,7 +1285,7 @@ suite('ExtensionsActions Test', () => { } function aPage(...objects: T[]): IPager { - return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null }; + return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null! }; } }); diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts index 78d93df69e7..662d97098fe 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts @@ -139,18 +139,18 @@ const mockTestData = { }; function aPage(...objects: T[]): IPager { - 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!; } } diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsViews.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsViews.test.ts index 79848955185..d93c65516c7 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsViews.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsViews.test.ts @@ -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(...objects: T[]): IPager { - return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null }; + return { firstPage: objects, total: objects.length, pageSize: objects.length, getPage: () => null! }; } }); diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index dac3ad9d2bd..3205c28f36d 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -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(...objects: T[]): IPager { - 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, count: number = 1): Promise { diff --git a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts index 3a8abb1ed6f..14ff323868b 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts @@ -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); } })); diff --git a/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts b/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts index 6f366a97b49..e37d12d7ce6 100644 --- a/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts +++ b/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts @@ -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)); }); }); diff --git a/src/vs/workbench/parts/performance/electron-browser/actions.ts b/src/vs/workbench/parts/performance/electron-browser/actions.ts deleted file mode 100644 index b95a0e62457..00000000000 --- a/src/vs/workbench/parts/performance/electron-browser/actions.ts +++ /dev/null @@ -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(); - const amdInvoke = new Map(); - const nodeRequire = new Map(); - const nodeEval = new Map(); - - function mark(map: Map, 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, 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): { [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 { - - // 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 { - 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: ${name} ${version} ${isPure ? '' : ' **[Unsupported]**'} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'}) -- OS Version: ${ osVersion} -- CPUs: ${ metrics.cpus.model} (${metrics.cpus.count} x ${metrics.cpus.speed}) -- Memory(System): ${ (metrics.totalmem / (1024 * 1024 * 1024)).toFixed(2)} GB(${(metrics.freemem / (1024 * 1024 * 1024)).toFixed(2)}GB free) -- 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) -- Load(avg): ${ metrics.loadavg.map(l => Math.round(l)).join(', ')} -- VM: ${ metrics.isVMLikelyhood}% -- Initial Startup: ${ metrics.initialStartup ? 'yes' : 'no'} -- Screen Reader: ${ metrics.hasAccessibilitySupport ? 'yes' : 'no'} -- Empty Workspace: ${ metrics.emptyWorkbench ? 'yes' : 'no'} -- 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(Extensions.WorkbenchActions) - .registerWorkbenchAction(new SyncActionDescriptor(ShowStartupPerformance, ShowStartupPerformance.ID, ShowStartupPerformance.LABEL), 'Developer: Startup Performance', nls.localize('developer', "Developer")); diff --git a/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts b/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts index bdfb8746810..45434d18c48 100644 --- a/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts +++ b/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts @@ -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(Extensions.Workbench).registerWorkbenchContribution( + PerfviewContrib, + LifecyclePhase.Ready +); Registry.as(Input.EditorInputFactories).registerEditorInputFactory( PerfviewInput.Id, @@ -28,7 +36,6 @@ Registry.as(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(Extensions.Workbench).registerWorkbenchContribution( + StartupProfiler, + LifecyclePhase.Restored +); + +// -- startup timings + +Registry.as(Extensions.Workbench).registerWorkbenchContribution( + StartupTimings, + LifecyclePhase.Eventually +); diff --git a/src/vs/workbench/parts/performance/electron-browser/perfviewEditor.ts b/src/vs/workbench/parts/performance/electron-browser/perfviewEditor.ts index 25823f7606d..55b3f1ff095 100644 --- a/src/vs/workbench/parts/performance/electron-browser/perfviewEditor.ts +++ b/src/vs/workbench/parts/performance/electron-browser/perfviewEditor.ts @@ -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 { - 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 { - 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(); + const amdInvokeFactory = new Map(); + const nodeRequire = new Map(); + const nodeEval = new Map(); + + function mark(map: Map, 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, 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)[][] { + 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; diff --git a/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts b/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts index 141db91bea2..86c0b153da5 100644 --- a/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts +++ b/src/vs/workbench/parts/performance/electron-browser/startupProfiler.ts @@ -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([ 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(Extensions.Workbench); -registry.registerWorkbenchContribution(StartupProfiler, LifecyclePhase.Restored); + private _createPerfIssue(files: string[]): Promise { + 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)}`); + }); + } +} diff --git a/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts b/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts index 981a7bc27b8..ba77db5110e 100644 --- a/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts +++ b/src/vs/workbench/parts/performance/electron-browser/startupTimings.ts @@ -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(Extensions.Workbench); -registry.registerWorkbenchContribution(StartupTimings, LifecyclePhase.Eventually); diff --git a/src/vs/workbench/parts/performance/electron-browser/stats.ts b/src/vs/workbench/parts/performance/electron-browser/stats.ts deleted file mode 100644 index c58bb81d111..00000000000 --- a/src/vs/workbench/parts/performance/electron-browser/stats.ts +++ /dev/null @@ -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 { - - 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(); - 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); -}); diff --git a/src/vs/workbench/parts/search/test/browser/openFileHandler.test.ts b/src/vs/workbench/parts/search/test/browser/openFileHandler.test.ts index df2516f3941..e9d82ebec33 100644 --- a/src/vs/workbench/parts/search/test/browser/openFileHandler.test.ts +++ b/src/vs/workbench/parts/search/test/browser/openFileHandler.test.ts @@ -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 { const promise = new DeferredPromise(); - this.loading[query.cacheKey] = promise; + this.loading[query.cacheKey!] = promise; return promise.p; } diff --git a/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts b/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts index 51e291fc8e5..8cfe81dba7f 100644 --- a/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts +++ b/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts @@ -67,8 +67,8 @@ suite('Search - Viewlet', () => { const resultIterator = createIterator(result, 'auto'); const first = resultIterator.next(); - assert(!!first.value.children); - assert.equal((>>first.value.children).next().value.element.id(), 'file:///c%3A/foo>[2,1 -> 2,2]b'); + assert(!!first.value!.children); + assert.equal((>>first.value!.children).next().value!.element.id(), 'file:///c%3A/foo>[2,1 -> 2,2]b'); }); test('Comparer', () => { diff --git a/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts b/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts index 6cc1ddd654b..57d3b65c16e 100644 --- a/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts +++ b/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts @@ -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; } diff --git a/src/vs/workbench/parts/search/test/common/searchModel.test.ts b/src/vs/workbench/parts/search/test/common/searchModel.test.ts index 5918e0b1f8f..0a3bd31742f 100644 --- a/src/vs/workbench/parts/search/test/common/searchModel.test.ts +++ b/src/vs/workbench/parts/search/test/common/searchModel.test.ts @@ -84,8 +84,8 @@ suite('SearchModel', () => { textSearch(query: ISearchQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): Promise { return new Promise(resolve => { process.nextTick(() => { - results.forEach(onProgress); - resolve(complete); + results.forEach(onProgress!); + resolve(complete!); }); }); } diff --git a/src/vs/workbench/parts/search/test/common/searchResult.test.ts b/src/vs/workbench/parts/search/test/common/searchResult.test.ts index 66c5074904c..50680e31632 100644 --- a/src/vs/workbench/parts/search/test/common/searchResult.test.ts +++ b/src/vs/workbench/parts/search/test/common/searchResult.test.ts @@ -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())); }); diff --git a/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts b/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts index 986a57782a9..30591e7eef1 100644 --- a/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts +++ b/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts @@ -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); }); diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts index ac2991031ea..3321227befc 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts @@ -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 { diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index 814e8aaf1d5..e1f81f7b804 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -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 { diff --git a/src/vs/workbench/parts/terminal/node/terminalEnvironment.ts b/src/vs/workbench/parts/terminal/node/terminalEnvironment.ts index e4e226e3645..f3acc29ec5a 100644 --- a/src/vs/workbench/parts/terminal/node/terminalEnvironment.ts +++ b/src/vs/workbench/parts/terminal/node/terminalEnvironment.ts @@ -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]) { diff --git a/src/vs/workbench/services/backup/test/electron-browser/backupFileService.test.ts b/src/vs/workbench/services/backup/test/electron-browser/backupFileService.test.ts index eae982fa587..2e0085dbe06 100644 --- a/src/vs/workbench/services/backup/test/electron-browser/backupFileService.test.ts +++ b/src/vs/workbench/services/backup/test/electron-browser/backupFileService.test.ts @@ -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); }); diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts index 86b0a03d1e9..d29fd761b24 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts @@ -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, { prompt: target, _serviceBrand: null, notify: null, error: null, info: null, warn: null }); + instantiationService.stub(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) => { diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts index 3d34e15f165..d3920ed67bd 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts @@ -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'); diff --git a/src/vs/workbench/services/files/node/watcher/unix/test/chockidarWatcherService.test.ts b/src/vs/workbench/services/files/node/watcher/unix/test/chockidarWatcherService.test.ts index 180de3e850e..43ac686e8bb 100644 --- a/src/vs/workbench/services/files/node/watcher/unix/test/chockidarWatcherService.test.ts +++ b/src/vs/workbench/services/files/node/watcher/unix/test/chockidarWatcherService.test.ts @@ -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); diff --git a/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts b/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts index 9807f419e5d..597621ee31a 100644 --- a/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts +++ b/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts @@ -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'); }); }); diff --git a/src/vs/workbench/services/group/test/browser/editorGroupsService.test.ts b/src/vs/workbench/services/group/test/browser/editorGroupsService.test.ts index 173e001cdec..1fbe4a573c1 100644 --- a/src/vs/workbench/services/group/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/group/test/browser/editorGroupsService.test.ts @@ -45,7 +45,7 @@ export class TestEditorInput extends EditorInput implements IFileEditorInput { resolve(): Promise { 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; diff --git a/src/vs/workbench/services/history/electron-browser/history.ts b/src/vs/workbench/services/history/electron-browser/history.ts index e06e34f286a..cbe72164380 100644 --- a/src/vs/workbench/services/history/electron-browser/history.ts +++ b/src/vs/workbench/services/history/electron-browser/history.ts @@ -476,7 +476,7 @@ export class HistoryService extends Disposable implements IHistoryService { private clearOnEditorDispose(editor: IEditorInput | IResourceInput | FileChangesEvent, mapEditorToDispose: Map): void { if (editor instanceof EditorInput) { - const disposables = this.editorHistoryListeners.get(editor); + const disposables = mapEditorToDispose.get(editor); if (disposables) { dispose(disposables); mapEditorToDispose.delete(editor); diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts index 75dc0ad53da..1b07bf60776 100644 --- a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts +++ b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts @@ -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); diff --git a/src/vs/workbench/services/keybinding/test/macLinuxKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/macLinuxKeyboardMapper.test.ts index 0e0c5c7bead..19b5cef5e04 100644 --- a/src/vs/workbench/services/keybinding/test/macLinuxKeyboardMapper.test.ts +++ b/src/vs/workbench/services/keybinding/test/macLinuxKeyboardMapper.test.ts @@ -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(runtimeKeybinding); if (actualHardwareKeypresses.length === 0) { diff --git a/src/vs/workbench/services/preferences/test/common/keybindingsEditorModel.test.ts b/src/vs/workbench/services/preferences/test/common/keybindingsEditorModel.test.ts index 658777f1428..cf17bb6de9b 100644 --- a/src/vs/workbench/services/preferences/test/common/keybindingsEditorModel.test.ts +++ b/src/vs/workbench/services/preferences/test/common/keybindingsEditorModel.test.ts @@ -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); diff --git a/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts b/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts index 8550a177cf4..d4dae17cbc3 100644 --- a/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts +++ b/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts @@ -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) { diff --git a/src/vs/workbench/services/progress/test/progressService.test.ts b/src/vs/workbench/services/progress/test/progressService.test.ts index ae98bbd35af..2f1e0fbf611 100644 --- a/src/vs/workbench/services/progress/test/progressService.test.ts +++ b/src/vs/workbench/services/progress/test/progressService.test.ts @@ -29,8 +29,8 @@ class TestViewletService implements IViewletService { onDidViewletClose = this.onDidViewletCloseEmitter.event; onDidViewletEnablementChange = this.onDidViewletEnableEmitter.event; - public openViewlet(id: string, focus?: boolean): Promise { - return Promise.resolve(null); + public openViewlet(id: string, focus?: boolean): Promise { + 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().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; } diff --git a/src/vs/workbench/services/search/test/node/rawSearchService.test.ts b/src/vs/workbench/services/search/test/node/rawSearchService.test.ts index cf3b096d221..2a2c687542f 100644 --- a/src/vs/workbench/services/search/test/node/rawSearchService.test.ts +++ b/src/vs/workbench/services/search/test/node/rawSearchService.test.ts @@ -47,7 +47,7 @@ class TestSearchEngine implements ISearchEngine { (function next() { process.nextTick(() => { if (self.isCanceled) { - done(null, { + done(null!, { limitHit: false, stats: stats }); @@ -55,7 +55,7 @@ class TestSearchEngine implements ISearchEngine { } 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((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)); diff --git a/src/vs/workbench/services/search/test/node/search.test.ts b/src/vs/workbench/services/search/test/node/search.test.ts index 1c32b06c8a6..9bc9f8436b5 100644 --- a/src/vs/workbench/services/search/test/node/search.test.ts +++ b/src/vs/workbench/services/search/test/node/search.test.ts @@ -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(); }); diff --git a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts index f4edf8a3bff..2493f8ee852 100644 --- a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts +++ b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts @@ -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 = (results[0].results[0]).ranges; + const matchRange = (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 = results[0].results[0]; + assert.equal(results[0].results!.length, 1); + const match = results[0].results![0]; assert.equal((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((results[0].results[0]).lineNumber, 25); - assert.equal((results[0].results[0]).text, ' compiler.addUnit(prog,"input.ts");'); + assert.equal((results[0].results![0]).lineNumber, 25); + assert.equal((results[0].results![0]).text, ' compiler.addUnit(prog,"input.ts");'); // assert.equal((results[1].results[0]).preview.text, ' compiler.typeCheck();\n'); // See https://github.com/BurntSushi/ripgrep/issues/1095 - assert.equal((results[2].results[0]).lineNumber, 27); - assert.equal((results[2].results[0]).text, ' compiler.emit();'); - assert.equal((results[3].results[0]).lineNumber, 28); - assert.equal((results[3].results[0]).text, ''); + assert.equal((results[2].results![0]).lineNumber, 27); + assert.equal((results[2].results![0]).text, ' compiler.emit();'); + assert.equal((results[3].results![0]).lineNumber, 28); + assert.equal((results[3].results![0]).text, ''); }); }); diff --git a/src/vs/workbench/services/textfile/test/textFileService.test.ts b/src/vs/workbench/services/textfile/test/textFileService.test.ts index 1dfdc4bdcc2..f5222c90e32 100644 --- a/src/vs/workbench/services/textfile/test/textFileService.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileService.test.ts @@ -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); }); }); }); diff --git a/src/vs/workbench/services/textmodelResolver/test/textModelResolverService.test.ts b/src/vs/workbench/services/textmodelResolver/test/textModelResolverService.test.ts index 0ddaa02741b..81e41897659 100644 --- a/src/vs/workbench/services/textmodelResolver/test/textModelResolverService.test.ts +++ b/src/vs/workbench/services/textmodelResolver/test/textModelResolverService.test.ts @@ -47,7 +47,7 @@ suite('Workbench - TextModelResolverService', () => { teardown(() => { if (model) { model.dispose(); - model = void 0; + model = (void 0)!; } (accessor.textFileService.models).clear(); (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); diff --git a/src/vs/workbench/test/browser/part.test.ts b/src/vs/workbench/test/browser/part.test.ts index c94fb997d5f..c1aae31346a 100644 --- a/src/vs/workbench/test/browser/part.test.ts +++ b/src/vs/workbench/test/browser/part.test.ts @@ -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(); diff --git a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts index 98dc31ccfe4..5c6f6e9e13b 100644 --- a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts @@ -267,7 +267,7 @@ suite('Workbench base editor', () => { super(); } public getTypeId() { return 'testEditorInput'; } - public resolve(): Promise { return Promise.resolve(null); } + public resolve(): Promise { return Promise.resolve(null!); } public matches(other: TestEditorInput): boolean { return other && this.id === other.id && other instanceof TestEditorInput; diff --git a/src/vs/workbench/test/browser/parts/editor/rangeDecorations.test.ts b/src/vs/workbench/test/browser/parts/editor/rangeDecorations.test.ts index 4fdcb2b7cef..22b8c35cbce 100644 --- a/src/vs/workbench/test/browser/parts/editor/rangeDecorations.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/rangeDecorations.test.ts @@ -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); diff --git a/src/vs/workbench/test/browser/quickopen.test.ts b/src/vs/workbench/test/browser/quickopen.test.ts index 9e9cf9515a9..30b61a2633c 100644 --- a/src/vs/workbench/test/browser/quickopen.test.ts +++ b/src/vs/workbench/test/browser/quickopen.test.ts @@ -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 { - return null; + return null!; } get onHide(): Event { - 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(); diff --git a/src/vs/workbench/test/browser/viewlet.test.ts b/src/vs/workbench/test/browser/viewlet.test.ts index ed9c3a678dd..6545d38ced2 100644 --- a/src/vs/workbench/test/browser/viewlet.test.ts +++ b/src/vs/workbench/test/browser/viewlet.test.ts @@ -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 { diff --git a/src/vs/workbench/test/common/editor/editorDiffModel.test.ts b/src/vs/workbench/test/common/editor/editorDiffModel.test.ts index 599f44c7bbc..3023add68ca 100644 --- a/src/vs/workbench/test/common/editor/editorDiffModel.test.ts +++ b/src/vs/workbench/test/common/editor/editorDiffModel.test.ts @@ -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) => { diff --git a/src/vs/workbench/test/common/editor/editorGroups.test.ts b/src/vs/workbench/test/common/editor/editorGroups.test.ts index bb4dccb4605..8ddb989641f 100644 --- a/src/vs/workbench/test/common/editor/editorGroups.test.ts +++ b/src/vs/workbench/test/common/editor/editorGroups.test.ts @@ -77,7 +77,7 @@ class TestEditorInput extends EditorInput { super(); } getTypeId() { return 'testEditorInputForGroups'; } - resolve(): Promise { return Promise.resolve(null); } + resolve(): Promise { 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 { return Promise.resolve(null); } + resolve(): Promise { 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 { return Promise.resolve(null); } + resolve(): Promise { 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); diff --git a/src/vs/workbench/test/common/editor/editorModel.test.ts b/src/vs/workbench/test/common/editor/editorModel.test.ts index 86a83a75997..513d2783fa1 100644 --- a/src/vs/workbench/test/common/editor/editorModel.test.ts +++ b/src/vs/workbench/test/common/editor/editorModel.test.ts @@ -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(); diff --git a/src/vs/workbench/test/common/editor/resourceEditorInput.test.ts b/src/vs/workbench/test/common/editor/resourceEditorInput.test.ts index 873c498d0aa..e3195191ae4 100644 --- a/src/vs/workbench/test/common/editor/resourceEditorInput.test.ts +++ b/src/vs/workbench/test/common/editor/resourceEditorInput.test.ts @@ -32,7 +32,7 @@ suite('Workbench resource editor input', () => { }); test('simple', () => { - let resource = URI.from({ scheme: 'inmemory', authority: null, path: 'thePath' }); + let resource = URI.from({ scheme: 'inmemory', authority: null!, path: 'thePath' }); accessor.modelService.createModel('function test() {}', accessor.modeService.create('text'), resource); let input: ResourceEditorInput = instantiationService.createInstance(ResourceEditorInput, 'The Name', 'The Description', resource); diff --git a/src/vs/workbench/test/common/editor/untitledEditor.test.ts b/src/vs/workbench/test/common/editor/untitledEditor.test.ts index 2a185efab0b..c5df4077e8c 100644 --- a/src/vs/workbench/test/common/editor/untitledEditor.test.ts +++ b/src/vs/workbench/test/common/editor/untitledEditor.test.ts @@ -202,7 +202,7 @@ suite('Workbench untitled editors', () => { config.setUserConfiguration('files', { 'defaultLanguage': defaultLanguage }); const service = accessor.untitledEditorService; - const input = service.createOrGet(null, modeId); + const input = service.createOrGet(null!, modeId); assert.equal(input.getModeId(), modeId); diff --git a/src/vs/workbench/test/common/memento.test.ts b/src/vs/workbench/test/common/memento.test.ts index 1e733586323..b6179a6506a 100644 --- a/src/vs/workbench/test/common/memento.test.ts +++ b/src/vs/workbench/test/common/memento.test.ts @@ -44,12 +44,12 @@ suite('Memento', () => { assert.deepEqual(memento, { foo: 'Hello World' }); // Assert the Mementos are stored properly in storage - assert.deepEqual(JSON.parse(storage.get('memento/memento.test', StorageScope.GLOBAL)), { foo: [1, 2, 3] }); + assert.deepEqual(JSON.parse(storage.get('memento/memento.test', StorageScope.GLOBAL)!), { foo: [1, 2, 3] }); - assert.deepEqual(JSON.parse(storage.get('memento/memento.test', StorageScope.WORKSPACE)), { foo: 'Hello World' }); + assert.deepEqual(JSON.parse(storage.get('memento/memento.test', StorageScope.WORKSPACE)!), { foo: 'Hello World' }); // Delete Global - memento = myMemento.getMemento(context); + memento = myMemento.getMemento(context!); delete memento.foo; // Delete Workspace @@ -59,7 +59,7 @@ suite('Memento', () => { myMemento.saveMemento(); // Global - memento = myMemento.getMemento(context); + memento = myMemento.getMemento(context!); assert.deepEqual(memento, {}); // Workspace @@ -67,16 +67,16 @@ suite('Memento', () => { assert.deepEqual(memento, {}); // Assert the Mementos are also removed from storage - assert.strictEqual(storage.get('memento/memento.test', StorageScope.GLOBAL, null), null); + assert.strictEqual(storage.get('memento/memento.test', StorageScope.GLOBAL, null!), null); - assert.strictEqual(storage.get('memento/memento.test', StorageScope.WORKSPACE, null), null); + assert.strictEqual(storage.get('memento/memento.test', StorageScope.WORKSPACE, null!), null); }); test('Save and Load', () => { let myMemento = new Memento('memento.test', storage); // Global - let memento: any = myMemento.getMemento(context); + let memento: any = myMemento.getMemento(context!); memento.foo = [1, 2, 3]; // Workspace @@ -87,7 +87,7 @@ suite('Memento', () => { myMemento.saveMemento(); // Global - memento = myMemento.getMemento(context); + memento = myMemento.getMemento(context!); assert.deepEqual(memento, { foo: [1, 2, 3] }); let globalMemento = myMemento.getMemento(StorageScope.GLOBAL); assert.deepEqual(globalMemento, memento); @@ -97,7 +97,7 @@ suite('Memento', () => { assert.deepEqual(memento, { foo: 'Hello World' }); // Global - memento = myMemento.getMemento(context); + memento = myMemento.getMemento(context!); memento.foo = [4, 5, 6]; // Workspace @@ -108,7 +108,7 @@ suite('Memento', () => { myMemento.saveMemento(); // Global - memento = myMemento.getMemento(context); + memento = myMemento.getMemento(context!); assert.deepEqual(memento, { foo: [4, 5, 6] }); globalMemento = myMemento.getMemento(StorageScope.GLOBAL); assert.deepEqual(globalMemento, memento); @@ -118,7 +118,7 @@ suite('Memento', () => { assert.deepEqual(memento, { foo: 'World Hello' }); // Delete Global - memento = myMemento.getMemento(context); + memento = myMemento.getMemento(context!); delete memento.foo; // Delete Workspace @@ -128,7 +128,7 @@ suite('Memento', () => { myMemento.saveMemento(); // Global - memento = myMemento.getMemento(context); + memento = myMemento.getMemento(context!); assert.deepEqual(memento, {}); // Workspace @@ -141,10 +141,10 @@ suite('Memento', () => { let myMemento2 = new Memento('memento.test', storage); // Global - let memento: any = myMemento.getMemento(context); + let memento: any = myMemento.getMemento(context!); memento.foo = [1, 2, 3]; - memento = myMemento2.getMemento(context); + memento = myMemento2.getMemento(context!); memento.bar = [1, 2, 3]; // Workspace @@ -160,12 +160,12 @@ suite('Memento', () => { myMemento2.saveMemento(); // Global - memento = myMemento.getMemento(context); + memento = myMemento.getMemento(context!); assert.deepEqual(memento, { foo: [1, 2, 3], bar: [1, 2, 3] }); let globalMemento = myMemento.getMemento(StorageScope.GLOBAL); assert.deepEqual(globalMemento, memento); - memento = myMemento2.getMemento(context); + memento = myMemento2.getMemento(context!); assert.deepEqual(memento, { foo: [1, 2, 3], bar: [1, 2, 3] }); globalMemento = myMemento2.getMemento(StorageScope.GLOBAL); assert.deepEqual(globalMemento, memento); diff --git a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts index f73279a7c6f..83cbe12ea65 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -802,8 +802,8 @@ suite('ExtHostLanguageFeatureCommands', function () { disposables.push(extHost.registerSelectionRangeProvider(nullExtensionDescription, defaultSelector, { provideSelectionRanges() { return [ - new types.SelectionRange(types.SelectionRangeKind.Empty, new types.Range(0, 10, 0, 18)), - new types.SelectionRange(types.SelectionRangeKind.Empty, new types.Range(0, 2, 0, 20)) + new types.SelectionRange(new types.Range(0, 10, 0, 18), types.SelectionRangeKind.Empty), + new types.SelectionRange(new types.Range(0, 2, 0, 20), types.SelectionRangeKind.Empty) ]; } })); diff --git a/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts index 3d43c5d745b..979d764834e 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts @@ -26,9 +26,9 @@ suite('ExtHostCommands', function () { } }; - const commands = new ExtHostCommands(SingleProxyRPCProtocol(shape), undefined, new NullLogService()); + const commands = new ExtHostCommands(SingleProxyRPCProtocol(shape), undefined!, new NullLogService()); commands.registerCommand(true, 'foo', (): any => { }).dispose(); - assert.equal(lastUnregister, 'foo'); + assert.equal(lastUnregister!, 'foo'); assert.equal(CommandsRegistry.getCommand('foo'), undefined); }); @@ -46,7 +46,7 @@ suite('ExtHostCommands', function () { } }; - const commands = new ExtHostCommands(SingleProxyRPCProtocol(shape), undefined, new NullLogService()); + const commands = new ExtHostCommands(SingleProxyRPCProtocol(shape), undefined!, new NullLogService()); const reg = commands.registerCommand(true, 'foo', (): any => { }); reg.dispose(); reg.dispose(); diff --git a/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts index 32d0c456cf2..de772e5d024 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts @@ -37,7 +37,7 @@ suite('ExtHostDiagnostics', () => { assert.throws(() => collection.get(URI.parse('aa:bb'))); assert.throws(() => collection.has(URI.parse('aa:bb'))); assert.throws(() => collection.set(URI.parse('aa:bb'), [])); - assert.throws(() => collection.set(URI.parse('aa:bb'), undefined)); + assert.throws(() => collection.set(URI.parse('aa:bb'), undefined!)); }); @@ -132,7 +132,7 @@ suite('ExtHostDiagnostics', () => { collection.set([ [uri, [new Diagnostic(new Range(0, 0, 0, 1), 'message-1')]], [URI.parse('some:thing'), [new Diagnostic(new Range(0, 0, 1, 1), 'something')]], - [uri, undefined] + [uri, undefined!] ]); assert.ok(!collection.has(uri)); @@ -144,7 +144,7 @@ suite('ExtHostDiagnostics', () => { collection.set([ [uri, [new Diagnostic(new Range(0, 0, 0, 1), 'message-1')]], [URI.parse('some:thing'), [new Diagnostic(new Range(0, 0, 1, 1), 'something')]], - [uri, undefined], + [uri, undefined!], [uri, [new Diagnostic(new Range(0, 0, 0, 1), 'message-2')]], [uri, [new Diagnostic(new Range(0, 0, 0, 1), 'message-3')]], ]); @@ -160,7 +160,7 @@ suite('ExtHostDiagnostics', () => { test('diagnostics collection, set tuple overrides, #11547', function () { - let lastEntries: [UriComponents, IMarkerData[]][]; + let lastEntries!: [UriComponents, IMarkerData[]][]; let collection = new DiagnosticCollection('test', 'test', 100, new class extends DiagnosticsShape { $changeMany(owner: string, entries: [UriComponents, IMarkerData[]][]): void { lastEntries = entries; @@ -176,7 +176,7 @@ suite('ExtHostDiagnostics', () => { let [[, data1]] = lastEntries; assert.equal(data1.length, 1); assert.equal(data1[0].message, 'error'); - lastEntries = undefined; + lastEntries = undefined!; collection.set([[uri, [new Diagnostic(new Range(0, 0, 1, 1), 'warning')]]]); assert.equal(collection.get(uri).length, 1); @@ -185,7 +185,7 @@ suite('ExtHostDiagnostics', () => { let [[, data2]] = lastEntries; assert.equal(data2.length, 1); assert.equal(data2[0].message, 'warning'); - lastEntries = undefined; + lastEntries = undefined!; }); test('don\'t send message when not making a change', function () { @@ -222,11 +222,11 @@ suite('ExtHostDiagnostics', () => { collection.set([ [uri, [diag, diag, diag]], - [uri, undefined], + [uri, undefined!], [uri, [diag]], [uri2, [diag, diag]], - [uri2, undefined], + [uri2, undefined!], [uri2, [diag]], ]); @@ -244,7 +244,7 @@ suite('ExtHostDiagnostics', () => { let diag = new Diagnostic(new Range(0, 0, 0, 1), i.toString()); tuples.push([uri, [diag, diag, diag]]); - tuples.push([uri, undefined]); + tuples.push([uri, undefined!]); tuples.push([uri, [diag]]); } @@ -259,7 +259,7 @@ suite('ExtHostDiagnostics', () => { test('diagnostic capping', function () { - let lastEntries: [UriComponents, IMarkerData[]][]; + let lastEntries!: [UriComponents, IMarkerData[]][]; let collection = new DiagnosticCollection('test', 'test', 250, new class extends DiagnosticsShape { $changeMany(owner: string, entries: [UriComponents, IMarkerData[]][]): void { lastEntries = entries; @@ -341,7 +341,7 @@ suite('ExtHostDiagnostics', () => { p = Event.toPromise(emitter.event).then(e => { assert.equal(e[0].toString(), 'aa:bb'); }); - collection.set(URI.parse('aa:bb'), undefined); + collection.set(URI.parse('aa:bb'), undefined!); await p; }); @@ -355,9 +355,9 @@ suite('ExtHostDiagnostics', () => { assert.equal(data.length, 1); let [diag] = data; - assert.equal(diag.relatedInformation.length, 2); - assert.equal(diag.relatedInformation[0].message, 'more1'); - assert.equal(diag.relatedInformation[1].message, 'more2'); + assert.equal(diag.relatedInformation!.length, 2); + assert.equal(diag.relatedInformation![0].message, 'more1'); + assert.equal(diag.relatedInformation![1].message, 'more2'); done(); } }, new Emitter()); diff --git a/src/vs/workbench/test/electron-browser/api/extHostDocumentData.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDocumentData.test.ts index c6bf32b0bfd..0c55c052e4b 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDocumentData.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDocumentData.test.ts @@ -30,7 +30,7 @@ suite('ExtHostDocumentData', () => { } setup(function () { - data = new ExtHostDocumentData(undefined, URI.file(''), [ + data = new ExtHostDocumentData(undefined!, URI.file(''), [ 'This is line one', //16 'and this is line number two', //27 'it is followed by #3', //20 @@ -39,7 +39,7 @@ suite('ExtHostDocumentData', () => { }); test('readonly-ness', () => { - assert.throws((): void => (data as any).document.uri = null); + assert.throws(() => (data as any).document.uri = null); assert.throws(() => (data as any).document.fileName = 'foofile'); assert.throws(() => (data as any).document.isDirty = false); assert.throws(() => (data as any).document.isUntitled = false); @@ -98,12 +98,12 @@ suite('ExtHostDocumentData', () => { data.onEvents({ changes: [{ range: { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 }, - rangeOffset: undefined, - rangeLength: undefined, + rangeOffset: undefined!, + rangeLength: undefined!, text: '\t ' }], - eol: undefined, - versionId: undefined, + eol: undefined!, + versionId: undefined!, }); // line didn't change @@ -155,12 +155,12 @@ suite('ExtHostDocumentData', () => { data.onEvents({ changes: [{ range: { startLineNumber: 1, startColumn: 3, endLineNumber: 1, endColumn: 6 }, - rangeOffset: undefined, - rangeLength: undefined, + rangeOffset: undefined!, + rangeLength: undefined!, text: '' }], - eol: undefined, - versionId: undefined, + eol: undefined!, + versionId: undefined!, }); assertOffsetAt(0, 1, 1); @@ -173,12 +173,12 @@ suite('ExtHostDocumentData', () => { data.onEvents({ changes: [{ range: { startLineNumber: 1, startColumn: 3, endLineNumber: 1, endColumn: 6 }, - rangeOffset: undefined, - rangeLength: undefined, + rangeOffset: undefined!, + rangeLength: undefined!, text: 'is could be' }], - eol: undefined, - versionId: undefined, + eol: undefined!, + versionId: undefined!, }); assertOffsetAt(0, 1, 1); @@ -191,12 +191,12 @@ suite('ExtHostDocumentData', () => { data.onEvents({ changes: [{ range: { startLineNumber: 1, startColumn: 3, endLineNumber: 1, endColumn: 6 }, - rangeOffset: undefined, - rangeLength: undefined, + rangeOffset: undefined!, + rangeLength: undefined!, text: 'is could be\na line with number' }], - eol: undefined, - versionId: undefined, + eol: undefined!, + versionId: undefined!, }); assertOffsetAt(0, 1, 1); @@ -212,12 +212,12 @@ suite('ExtHostDocumentData', () => { data.onEvents({ changes: [{ range: { startLineNumber: 1, startColumn: 3, endLineNumber: 2, endColumn: 6 }, - rangeOffset: undefined, - rangeLength: undefined, + rangeOffset: undefined!, + rangeLength: undefined!, text: '' }], - eol: undefined, - versionId: undefined, + eol: undefined!, + versionId: undefined!, }); assertOffsetAt(0, 1, 1); @@ -240,41 +240,41 @@ suite('ExtHostDocumentData', () => { }); test('getWordRangeAtPosition', () => { - data = new ExtHostDocumentData(undefined, URI.file(''), [ + data = new ExtHostDocumentData(undefined!, URI.file(''), [ 'aaaa bbbb+cccc abc' ], '\n', 'text', 1, false); - let range = data.document.getWordRangeAtPosition(new Position(0, 2)); + let range = data.document.getWordRangeAtPosition(new Position(0, 2))!; assert.equal(range.start.line, 0); assert.equal(range.start.character, 0); assert.equal(range.end.line, 0); assert.equal(range.end.character, 4); // ignore bad regular expresson /.*/ - range = data.document.getWordRangeAtPosition(new Position(0, 2), /.*/); + range = data.document.getWordRangeAtPosition(new Position(0, 2), /.*/)!; assert.equal(range.start.line, 0); assert.equal(range.start.character, 0); assert.equal(range.end.line, 0); assert.equal(range.end.character, 4); - range = data.document.getWordRangeAtPosition(new Position(0, 5), /[a-z+]+/); + range = data.document.getWordRangeAtPosition(new Position(0, 5), /[a-z+]+/)!; assert.equal(range.start.line, 0); assert.equal(range.start.character, 5); assert.equal(range.end.line, 0); assert.equal(range.end.character, 14); - range = data.document.getWordRangeAtPosition(new Position(0, 17), /[a-z+]+/); + range = data.document.getWordRangeAtPosition(new Position(0, 17), /[a-z+]+/)!; assert.equal(range.start.line, 0); assert.equal(range.start.character, 15); assert.equal(range.end.line, 0); assert.equal(range.end.character, 18); - range = data.document.getWordRangeAtPosition(new Position(0, 11), /yy/); + range = data.document.getWordRangeAtPosition(new Position(0, 11), /yy/)!; assert.equal(range, undefined); }); test('getWordRangeAtPosition doesn\'t quite use the regex as expected, #29102', function () { - data = new ExtHostDocumentData(undefined, URI.file(''), [ + data = new ExtHostDocumentData(undefined!, URI.file(''), [ 'some text here', '/** foo bar */', 'function() {', @@ -285,7 +285,7 @@ suite('ExtHostDocumentData', () => { let range = data.document.getWordRangeAtPosition(new Position(0, 0), /\/\*.+\*\//); assert.equal(range, undefined); - range = data.document.getWordRangeAtPosition(new Position(1, 0), /\/\*.+\*\//); + range = data.document.getWordRangeAtPosition(new Position(1, 0), /\/\*.+\*\//)!; assert.equal(range.start.line, 1); assert.equal(range.start.character, 0); assert.equal(range.end.line, 1); @@ -294,7 +294,7 @@ suite('ExtHostDocumentData', () => { range = data.document.getWordRangeAtPosition(new Position(3, 0), /("|').*\1/); assert.equal(range, undefined); - range = data.document.getWordRangeAtPosition(new Position(3, 1), /("|').*\1/); + range = data.document.getWordRangeAtPosition(new Position(3, 1), /("|').*\1/)!; assert.equal(range.start.line, 3); assert.equal(range.start.character, 1); assert.equal(range.end.line, 3); @@ -346,17 +346,17 @@ suite('ExtHostDocumentData updates line mapping', () => { return { changes: [{ range: range, - rangeOffset: undefined, - rangeLength: undefined, + rangeOffset: undefined!, + rangeLength: undefined!, text: text }], - eol: eol, - versionId: undefined, + eol: eol!, + versionId: undefined!, }; } function testLineMappingDirectionAfterEvents(lines: string[], eol: string, direction: AssertDocumentLineMappingDirection, e: IModelChangedEvent): void { - let myDocument = new ExtHostDocumentData(undefined, URI.file(''), lines.slice(0), eol, 'text', 1, false); + let myDocument = new ExtHostDocumentData(undefined!, URI.file(''), lines.slice(0), eol, 'text', 1, false); assertDocumentLineMapping(myDocument, direction); myDocument.onEvents(e); @@ -377,7 +377,7 @@ suite('ExtHostDocumentData updates line mapping', () => { 'and this is line number two', 'it is followed by #3', 'and finished with the fourth.', - ], { changes: [], eol: undefined, versionId: 7 }); + ], { changes: [], eol: undefined!, versionId: 7 }); }); test('after remove', () => { diff --git a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts index 695bb6098f7..e631e129ef5 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts @@ -30,11 +30,11 @@ suite('ExtHostDocumentSaveParticipant', () => { name: 'Null Extension Description', publisher: 'vscode', enableProposedApi: false, - engines: undefined, - extensionLocation: undefined, + engines: undefined!, + extensionLocation: undefined!, isBuiltin: false, isUnderDevelopment: false, - version: undefined + version: undefined! }; setup(() => { @@ -86,7 +86,7 @@ suite('ExtHostDocumentSaveParticipant', () => { sub.dispose(); assert.ok(event); - assert.throws(() => { event.document = null; }); + assert.throws(() => { event.document = null!; }); }); }); @@ -301,11 +301,11 @@ suite('ExtHostDocumentSaveParticipant', () => { documents.$acceptModelChanged(resource, { changes: [{ range: { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 }, - rangeOffset: undefined, - rangeLength: undefined, + rangeOffset: undefined!, + rangeLength: undefined!, text: 'bar' }], - eol: undefined, + eol: undefined!, versionId: 2 }, true); @@ -337,10 +337,10 @@ suite('ExtHostDocumentSaveParticipant', () => { changes: [{ range, text, - rangeOffset: undefined, - rangeLength: undefined, + rangeOffset: undefined!, + rangeLength: undefined!, }], - eol: undefined, + eol: undefined!, versionId: documents.getDocumentData(uri).version + 1 }, true); } diff --git a/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts index 9230a858c78..64ea0f9f7f9 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts @@ -13,9 +13,9 @@ suite('ExtHostDocumentsAndEditors', () => { setup(function () { editors = new ExtHostDocumentsAndEditors({ - getProxy: () => { return undefined; }, - set: undefined, - assertRegistered: undefined + getProxy: () => { return undefined!; }, + set: undefined!, + assertRegistered: undefined! }); }); diff --git a/src/vs/workbench/test/electron-browser/api/extHostFileSystemEventService.test.ts b/src/vs/workbench/test/electron-browser/api/extHostFileSystemEventService.test.ts index 93d64572b33..b9a299dc60c 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostFileSystemEventService.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostFileSystemEventService.test.ts @@ -12,17 +12,17 @@ suite('ExtHostFileSystemEventService', () => { test('FileSystemWatcher ignore events properties are reversed #26851', function () { const protocol: IMainContext = { - getProxy: () => { return undefined; }, - set: undefined, - assertRegistered: undefined + getProxy: () => { return undefined!; }, + set: undefined!, + assertRegistered: undefined! }; - const watcher1 = new ExtHostFileSystemEventService(protocol, undefined).createFileSystemWatcher('**/somethingInteresting', false, false, false); + const watcher1 = new ExtHostFileSystemEventService(protocol, undefined!).createFileSystemWatcher('**/somethingInteresting', false, false, false); assert.equal(watcher1.ignoreChangeEvents, false); assert.equal(watcher1.ignoreCreateEvents, false); assert.equal(watcher1.ignoreDeleteEvents, false); - const watcher2 = new ExtHostFileSystemEventService(protocol, undefined).createFileSystemWatcher('**/somethingBoring', true, true, true); + const watcher2 = new ExtHostFileSystemEventService(protocol, undefined!).createFileSystemWatcher('**/somethingBoring', true, true, true); assert.equal(watcher2.ignoreChangeEvents, true); assert.equal(watcher2.ignoreCreateEvents, true); assert.equal(watcher2.ignoreDeleteEvents, true); diff --git a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts index daad32a2850..66c740fbaa3 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts @@ -1230,8 +1230,8 @@ suite('ExtHostLanguageFeatures', function () { disposables.push(extHost.registerSelectionRangeProvider(defaultExtension, defaultSelector, { provideSelectionRanges() { return [ - new types.SelectionRange(types.SelectionRangeKind.Empty, new types.Range(0, 10, 0, 18)), - new types.SelectionRange(types.SelectionRangeKind.Empty, new types.Range(0, 2, 0, 20)) + new types.SelectionRange(new types.Range(0, 10, 0, 18), types.SelectionRangeKind.Empty), + new types.SelectionRange(new types.Range(0, 2, 0, 20), types.SelectionRangeKind.Empty) ]; } })); diff --git a/src/vs/workbench/test/electron-browser/api/extHostMessagerService.test.ts b/src/vs/workbench/test/electron-browser/api/extHostMessagerService.test.ts index 49136918e5d..e403ec1ebe9 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostMessagerService.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostMessagerService.test.ts @@ -78,9 +78,9 @@ suite('ExtHostMessageService', function () { test('propagte handle on select', async function () { - let service = new MainThreadMessageService(null, new EmptyNotificationService(notification => { - assert.equal(notification.actions.primary.length, 1); - setImmediate(() => notification.actions.primary[0].run()); + let service = new MainThreadMessageService(null!, new EmptyNotificationService(notification => { + assert.equal(notification.actions!.primary!.length, 1); + setImmediate(() => notification.actions!.primary![0].run()); }), emptyCommandService, emptyDialogService); const handle = await service.$showMessage(1, 'h', {}, [{ handle: 42, title: 'a thing', isCloseAffordance: true }]); @@ -89,7 +89,7 @@ suite('ExtHostMessageService', function () { suite('modal', () => { test('calls dialog service', async () => { - const service = new MainThreadMessageService(null, emptyNotificationService, emptyCommandService, new class extends mock() { + const service = new MainThreadMessageService(null!, emptyNotificationService, emptyCommandService, new class extends mock() { show(severity, message, buttons) { assert.equal(severity, 1); assert.equal(message, 'h'); @@ -104,7 +104,7 @@ suite('ExtHostMessageService', function () { }); test('returns undefined when cancelled', async () => { - const service = new MainThreadMessageService(null, emptyNotificationService, emptyCommandService, new class extends mock() { + const service = new MainThreadMessageService(null!, emptyNotificationService, emptyCommandService, new class extends mock() { show(severity, message, buttons) { return Promise.resolve(1); } @@ -115,7 +115,7 @@ suite('ExtHostMessageService', function () { }); test('hides Cancel button when not needed', async () => { - const service = new MainThreadMessageService(null, emptyNotificationService, emptyCommandService, new class extends mock() { + const service = new MainThreadMessageService(null!, emptyNotificationService, emptyCommandService, new class extends mock() { show(severity, message, buttons) { assert.equal(buttons.length, 1); return Promise.resolve(0); diff --git a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts index a94f9d7f7ed..1eb1b00694f 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts @@ -100,7 +100,7 @@ suite('ExtHostSearch', () => { await rpcProtocol.sync(); return { results: (mockMainThreadSearch.results).map(r => URI.revive(r)), - stats + stats: stats! }; } @@ -130,7 +130,7 @@ suite('ExtHostSearch', () => { } })); - return { results, stats }; + return { results, stats: stats! }; } setup(() => { @@ -143,7 +143,7 @@ suite('ExtHostSearch', () => { rpcProtocol.set(MainContext.MainThreadSearch, mockMainThreadSearch); mockExtfs = {}; - extHostSearch = new ExtHostSearch(rpcProtocol, null, logService, ehConfiguration, mockExtfs as typeof extfs); + extHostSearch = new ExtHostSearch(rpcProtocol, null!, logService, ehConfiguration, mockExtfs as typeof extfs); }); teardown(() => { @@ -180,7 +180,7 @@ suite('ExtHostSearch', () => { test('no results', async () => { await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Promise { - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -230,7 +230,7 @@ suite('ExtHostSearch', () => { test('provider returns null', async () => { await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Promise { - return null; + return null!; } }); @@ -246,7 +246,7 @@ suite('ExtHostSearch', () => { await registerTestFileSearchProvider({ provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Promise { assert(options.excludes.length === 2 && options.includes.length === 2, 'Missing global include/excludes'); - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -282,7 +282,7 @@ suite('ExtHostSearch', () => { assert.deepEqual(options.excludes.sort(), ['*.js']); } - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -319,7 +319,7 @@ suite('ExtHostSearch', () => { assert.deepEqual(options.includes.sort(), ['*.jsx', '*.ts']); assert.deepEqual(options.excludes.sort(), []); - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -661,7 +661,7 @@ suite('ExtHostSearch', () => { const actualTextSearchResults: vscode.TextSearchResult[] = []; for (let fileMatch of actual) { // Make relative - for (let lineResult of fileMatch.results) { + for (let lineResult of fileMatch.results!) { if (resultIsMatch(lineResult)) { actualTextSearchResults.push({ preview: { @@ -715,7 +715,7 @@ suite('ExtHostSearch', () => { test('no results', async () => { await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Promise { - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -733,7 +733,7 @@ suite('ExtHostSearch', () => { await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Promise { providedResults.forEach(r => progress.report(r)); - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -747,7 +747,7 @@ suite('ExtHostSearch', () => { provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Promise { assert.equal(options.includes.length, 1); assert.equal(options.excludes.length, 1); - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -783,7 +783,7 @@ suite('ExtHostSearch', () => { assert.deepEqual(options.excludes.sort(), ['*.js']); } - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -820,7 +820,7 @@ suite('ExtHostSearch', () => { assert.deepEqual(options.includes.sort(), ['*.jsx', '*.ts']); assert.deepEqual(options.excludes.sort(), []); - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -870,12 +870,12 @@ suite('ExtHostSearch', () => { test('basic sibling clause', async () => { mockExtfs.readdir = (_path: string, callback: (error: Error, files: string[]) => void) => { if (_path === rootFolderA.fsPath) { - callback(null, [ + callback(null!, [ 'file1.js', 'file1.ts' ]); } else { - callback(new Error('Wrong path'), null); + callback(new Error('Wrong path'), null!); } }; @@ -887,7 +887,7 @@ suite('ExtHostSearch', () => { await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Promise { providedResults.forEach(r => progress.report(r)); - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -913,19 +913,19 @@ suite('ExtHostSearch', () => { test('multiroot sibling clause', async () => { mockExtfs.readdir = (_path: string, callback: (error: Error, files: string[]) => void) => { if (_path === joinPath(rootFolderA, 'folder').fsPath) { - callback(null, [ + callback(null!, [ 'fileA.scss', 'fileA.css', 'file2.css' ]); } else if (_path === rootFolderB.fsPath) { - callback(null, [ + callback(null!, [ 'fileB.ts', 'fileB.js', 'file3.js' ]); } else { - callback(new Error('Wrong path'), null); + callback(new Error('Wrong path'), null!); } }; @@ -947,7 +947,7 @@ suite('ExtHostSearch', () => { } reportedResults.forEach(r => progress.report(r)); - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -997,7 +997,7 @@ suite('ExtHostSearch', () => { await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Promise { providedResults.forEach(r => progress.report(r)); - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -1029,7 +1029,7 @@ suite('ExtHostSearch', () => { provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Promise { token.onCancellationRequested(() => wasCanceled = true); providedResults.forEach(r => progress.report(r)); - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -1062,7 +1062,7 @@ suite('ExtHostSearch', () => { provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Promise { token.onCancellationRequested(() => wasCanceled = true); providedResults.forEach(r => progress.report(r)); - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -1094,7 +1094,7 @@ suite('ExtHostSearch', () => { provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Promise { token.onCancellationRequested(() => wasCanceled = true); providedResults.forEach(r => progress.report(r)); - return Promise.resolve(null); + return Promise.resolve(null!); } }); @@ -1156,7 +1156,7 @@ suite('ExtHostSearch', () => { 'file2.ts', 'file3.ts', ].forEach(f => progress.report(makeTextResult(options.folder, f))); - return null; + return null!; } }); @@ -1187,7 +1187,7 @@ suite('ExtHostSearch', () => { await registerTestTextSearchProvider({ provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, token: vscode.CancellationToken): Promise { providedResults.forEach(r => progress.report(r)); - return Promise.resolve(null); + return Promise.resolve(null!); } }, fancyScheme); diff --git a/src/vs/workbench/test/electron-browser/api/extHostTextEditor.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTextEditor.test.ts index f61888da153..a8f269a3dad 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTextEditor.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTextEditor.test.ts @@ -14,12 +14,12 @@ import { mock } from 'vs/workbench/test/electron-browser/api/mock'; suite('ExtHostTextEditor', () => { let editor: ExtHostTextEditor; - let doc = new ExtHostDocumentData(undefined, URI.file(''), [ + let doc = new ExtHostDocumentData(undefined!, URI.file(''), [ 'aaaa bbbb+cccc abc' ], '\n', 'text', 1, false); setup(() => { - editor = new ExtHostTextEditor(null, 'fake', doc, [], { cursorStyle: 0, insertSpaces: true, lineNumbers: 1, tabSize: 4 }, [], 1); + editor = new ExtHostTextEditor(null!, 'fake', doc, [], { cursorStyle: 0, insertSpaces: true, lineNumbers: 1, tabSize: 4 }, [], 1); }); test('disposed editor', () => { @@ -34,7 +34,7 @@ suite('ExtHostTextEditor', () => { assert.equal(3, editor.viewColumn); assert.ok(editor.document); - assert.throws(() => editor._acceptOptions(null)); + assert.throws(() => editor._acceptOptions(null!)); assert.throws(() => editor._acceptSelections([])); }); @@ -66,25 +66,25 @@ suite('ExtHostTextEditorOptions', () => { setup(() => { calls = []; let mockProxy: MainThreadTextEditorsShape = { - dispose: undefined, + dispose: undefined!, $trySetOptions: (id: string, options: ITextEditorConfigurationUpdate) => { assert.equal(id, '1'); calls.push(options); return Promise.resolve(void 0); }, - $tryShowTextDocument: undefined, - $registerTextEditorDecorationType: undefined, - $removeTextEditorDecorationType: undefined, - $tryShowEditor: undefined, - $tryHideEditor: undefined, - $trySetDecorations: undefined, - $trySetDecorationsFast: undefined, - $tryRevealRange: undefined, - $trySetSelections: undefined, - $tryApplyEdits: undefined, - $tryApplyWorkspaceEdit: undefined, - $tryInsertSnippet: undefined, - $getDiffInformation: undefined + $tryShowTextDocument: undefined!, + $registerTextEditorDecorationType: undefined!, + $removeTextEditorDecorationType: undefined!, + $tryShowEditor: undefined!, + $tryHideEditor: undefined!, + $trySetDecorations: undefined!, + $trySetDecorationsFast: undefined!, + $tryRevealRange: undefined!, + $trySetSelections: undefined!, + $tryApplyEdits: undefined!, + $tryApplyWorkspaceEdit: undefined!, + $tryInsertSnippet: undefined!, + $getDiffInformation: undefined! }; opts = new ExtHostTextEditorOptions(mockProxy, '1', { tabSize: 4, @@ -95,8 +95,8 @@ suite('ExtHostTextEditorOptions', () => { }); teardown(() => { - opts = null; - calls = null; + opts = null!; + calls = null!; }); function assertState(opts: ExtHostTextEditorOptions, expected: IResolvedTextEditorConfiguration): void { @@ -165,7 +165,7 @@ suite('ExtHostTextEditorOptions', () => { }); test('ignores invalid tabSize 1', () => { - opts.tabSize = null; + opts.tabSize = null!; assertState(opts, { tabSize: 4, insertSpaces: false, diff --git a/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts index 0190c3baa51..10cb6493faf 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts @@ -19,7 +19,7 @@ suite('ExtHostTextEditors.applyWorkspaceEdit', () => { let workspaceResourceEdits: WorkspaceEditDto; setup(() => { - workspaceResourceEdits = null; + workspaceResourceEdits = null!; let rpcProtocol = new TestRPCProtocol(); rpcProtocol.set(MainContext.MainThreadTextEditors, new class extends mock() { diff --git a/src/vs/workbench/test/electron-browser/api/extHostTypeConverter.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTypeConverter.test.ts index 7f67a1cea9d..748289d7fea 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTypeConverter.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTypeConverter.test.ts @@ -29,34 +29,34 @@ suite('ExtHostTypeConverter', function () { data = MarkdownString.from('Hello [link](foo:path)'); assert.equal(data.value, 'Hello [link](foo:path)'); - assert.equal(size(data.uris), 1); - assert.ok(!!data.uris['foo:path']); + assert.equal(size(data.uris!), 1); + assert.ok(!!data.uris!['foo:path']); data = MarkdownString.from('hello@foo.bar'); assert.equal(data.value, 'hello@foo.bar'); - assert.equal(size(data.uris), 1); - assert.ok(!!data.uris['mailto:hello@foo.bar']); + assert.equal(size(data.uris!), 1); + assert.ok(!!data.uris!['mailto:hello@foo.bar']); data = MarkdownString.from('*hello* [click](command:me)'); assert.equal(data.value, '*hello* [click](command:me)'); - assert.equal(size(data.uris), 1); - assert.ok(!!data.uris['command:me']); + assert.equal(size(data.uris!), 1); + assert.ok(!!data.uris!['command:me']); data = MarkdownString.from('*hello* [click](file:///somepath/here). [click](file:///somepath/here)'); assert.equal(data.value, '*hello* [click](file:///somepath/here). [click](file:///somepath/here)'); - assert.equal(size(data.uris), 1); - assert.ok(!!data.uris['file:///somepath/here']); + assert.equal(size(data.uris!), 1); + assert.ok(!!data.uris!['file:///somepath/here']); data = MarkdownString.from('*hello* [click](file:///somepath/here). [click](file:///somepath/here)'); assert.equal(data.value, '*hello* [click](file:///somepath/here). [click](file:///somepath/here)'); - assert.equal(size(data.uris), 1); - assert.ok(!!data.uris['file:///somepath/here']); + assert.equal(size(data.uris!), 1); + assert.ok(!!data.uris!['file:///somepath/here']); data = MarkdownString.from('*hello* [click](file:///somepath/here). [click](file:///somepath/here2)'); assert.equal(data.value, '*hello* [click](file:///somepath/here). [click](file:///somepath/here2)'); - assert.equal(size(data.uris), 2); - assert.ok(!!data.uris['file:///somepath/here']); - assert.ok(!!data.uris['file:///somepath/here2']); + assert.equal(size(data.uris!), 2); + assert.ok(!!data.uris!['file:///somepath/here']); + assert.ok(!!data.uris!['file:///somepath/here2']); }); test('LogLevel', () => { diff --git a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts index 17af41aaced..557aa5868c9 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts @@ -23,11 +23,11 @@ suite('ExtHostWorkspace', function () { name: 'ext', publisher: 'vscode', enableProposedApi: false, - engines: undefined, - extensionLocation: undefined, + engines: undefined!, + extensionLocation: undefined!, isBuiltin: false, isUnderDevelopment: false, - version: undefined + version: undefined! }; function assertAsRelativePath(workspace: ExtHostWorkspace, input: string, expected: string, includeWorkspace?: boolean) { @@ -64,7 +64,7 @@ suite('ExtHostWorkspace', function () { }); test('asRelativePath, no workspace', function () { - const ws = new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter()); + const ws = new ExtHostWorkspace(new TestRPCProtocol(), null!, new NullLogService(), new Counter()); assertAsRelativePath(ws, (''), ''); assertAsRelativePath(ws, ('/foo/bar'), '/foo/bar'); }); @@ -102,10 +102,10 @@ suite('ExtHostWorkspace', function () { let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); assert.equal(ws.getPath(), undefined); - ws = new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter()); + ws = new ExtHostWorkspace(new TestRPCProtocol(), null!, new NullLogService(), new Counter()); assert.equal(ws.getPath(), undefined); - ws = new ExtHostWorkspace(new TestRPCProtocol(), undefined, new NullLogService(), new Counter()); + ws = new ExtHostWorkspace(new TestRPCProtocol(), undefined!, new NullLogService(), new Counter()); assert.equal(ws.getPath(), undefined); ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('Folder'), 0), aWorkspaceFolderData(URI.file('Another/Folder'), 1)] }, new NullLogService(), new Counter()); @@ -260,7 +260,7 @@ suite('ExtHostWorkspace', function () { test('updateWorkspaceFolders - invalid arguments', function () { let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); - assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, null, null)); + assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, null!, null!)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 0, 0)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 0, 1)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 1, 0)); @@ -284,9 +284,9 @@ suite('ExtHostWorkspace', function () { }; const protocol: IMainContext = { - getProxy: () => { return undefined; }, - set: undefined, - assertRegistered: undefined + getProxy: () => { return undefined!; }, + set: undefined!, + assertRegistered: undefined! }; const ws = new ExtHostWorkspace(protocol, { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadCommands.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadCommands.test.ts index 506f1f152b6..5902e8e757b 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadCommands.test.ts @@ -12,7 +12,7 @@ suite('MainThreadCommands', function () { test('dispose on unregister', function () { - const commands = new MainThreadCommands(SingleProxyRPCProtocol(null), undefined); + const commands = new MainThreadCommands(SingleProxyRPCProtocol(null), undefined!); assert.equal(CommandsRegistry.getCommand('foo'), undefined); // register @@ -26,7 +26,7 @@ suite('MainThreadCommands', function () { test('unregister all on dispose', function () { - const commands = new MainThreadCommands(SingleProxyRPCProtocol(null), undefined); + const commands = new MainThreadCommands(SingleProxyRPCProtocol(null), undefined!); assert.equal(CommandsRegistry.getCommand('foo'), undefined); commands.$registerCommand('foo'); diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadDiagnostics.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadDiagnostics.test.ts index 733bb3eae4b..8d855237d59 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadDiagnostics.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadDiagnostics.test.ts @@ -19,7 +19,7 @@ suite('MainThreadDiagnostics', function () { test('clear markers on dispose', function () { - let diag = new MainThreadDiagnostics(null, markerService); + let diag = new MainThreadDiagnostics(null!, markerService); diag.$changeMany('foo', [[URI.file('a'), [{ code: '666', diff --git a/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts b/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts index 4078a988a68..9b3374803ba 100644 --- a/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts +++ b/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts @@ -137,7 +137,7 @@ suite.skip('QuickOpen performance (integration)', () => { let i = n; return (function iterate(): Promise { if (!i--) { - return undefined; + return undefined!; } return measure() .then(([uncachedEvent, cachedEvent]) => { diff --git a/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts b/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts index eb19c5d741c..61591b0584c 100644 --- a/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts +++ b/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts @@ -117,7 +117,7 @@ suite.skip('TextSearch performance (integration)', () => { }); } - const finishedEvents = []; + const finishedEvents: any[] = []; return runSearch() // Warm-up first .then(() => { if (testWorkspaceArg) { // Don't measure by default diff --git a/yarn.lock b/yarn.lock index 32c2ce044dd..8a70317950e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9428,10 +9428,10 @@ vscode-uri@^1.0.6: resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.6.tgz#6b8f141b0bbc44ad7b07e94f82f168ac7608ad4d" integrity sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww== -vscode-xterm@3.10.0-beta7: - version "3.10.0-beta7" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.10.0-beta7.tgz#eab6afd4d29a1328a9e7aca3ac670618ef05fb9f" - integrity sha512-9gCIfVIPfXjXXeiy2Qji94OgQOwgUwrLIU4QBffj2JUMhSzSzFxl90l5ciED0J+dXLkS1+w+W0jO0n907jAX7g== +vscode-xterm@3.10.0-beta9: + version "3.10.0-beta9" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.10.0-beta9.tgz#7922712efcd12cec39eab376dce071fe80b9a1c0" + integrity sha512-KXLIAu/4kkxcFFdiA5DXaHDofkhFJ4jEsGx7g+Oczz3GUEqF2vTKi8d3DyvsWVQfbpqlP8C65gv+RpM/0qApZA== vso-node-api@6.1.2-preview: version "6.1.2-preview"