Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -16,8 +16,8 @@ import { StorageService } from 'vs/platform/storage/node/storageService';
import { ConfigurationScope, IConfigurationRegistry, Extensions as ConfigurationExtensions, IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry';
import { Registry } from 'vs/platform/registry/common/platform';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { BackupFileService } from 'vs/workbench/services/backup/node/backupFileService';
import { IBackupFileService, toBackupWorkspaceResource } from 'vs/workbench/services/backup/common/backup';
import { BackupFileService } from 'vs/workbench/services/backup/common/backupFileService';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { distinct } from 'vs/base/common/arrays';
import { isLinux, isWindows, isMacintosh } from 'vs/base/common/platform';
@@ -32,10 +32,11 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ILabelService } from 'vs/platform/label/common/label';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
export class WorkspaceEditingService implements IWorkspaceEditingService {
_serviceBrand: any;
_serviceBrand: ServiceIdentifier<IWorkspaceEditingService>;
constructor(
@IJSONEditingService private readonly jsonEditingService: IJSONEditingService,
@@ -57,84 +58,93 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
@ILifecycleService readonly lifecycleService: ILifecycleService,
@ILabelService readonly labelService: ILabelService
) {
this.registerListeners();
}
lifecycleService.onBeforeShutdown(async e => {
private registerListeners(): void {
this.lifecycleService.onBeforeShutdown(async e => {
const saveOperation = this.saveUntitedBeforeShutdown(e.reason);
if (saveOperation) {
e.veto(saveOperation);
}
});
}
private saveUntitedBeforeShutdown(reason: ShutdownReason): Promise<boolean> | undefined {
private async saveUntitedBeforeShutdown(reason: ShutdownReason): Promise<boolean> {
if (reason !== ShutdownReason.LOAD && reason !== ShutdownReason.CLOSE) {
return undefined; // only interested when window is closing or loading
return false; // only interested when window is closing or loading
}
const workspaceIdentifier = this.getCurrentWorkspaceIdentifier();
if (!workspaceIdentifier || !isEqualOrParent(workspaceIdentifier.configPath, this.environmentService.untitledWorkspacesHome)) {
return undefined; // only care about untitled workspaces to ask for saving
return false; // only care about untitled workspaces to ask for saving
}
return this.windowsService.getWindowCount().then(windowCount => {
if (reason === ShutdownReason.CLOSE && !isMacintosh && windowCount === 1) {
return false; // Windows/Linux: quits when last window is closed, so do not ask then
}
enum ConfirmResult {
SAVE,
DONT_SAVE,
CANCEL
}
const windowCount = await this.windowsService.getWindowCount();
const save = { label: mnemonicButtonLabel(nls.localize('save', "Save")), result: ConfirmResult.SAVE };
const dontSave = { label: mnemonicButtonLabel(nls.localize('doNotSave', "Don't Save")), result: ConfirmResult.DONT_SAVE };
const cancel = { label: nls.localize('cancel', "Cancel"), result: ConfirmResult.CANCEL };
if (reason === ShutdownReason.CLOSE && !isMacintosh && windowCount === 1) {
return false; // Windows/Linux: quits when last window is closed, so do not ask then
}
const buttons: { label: string; result: ConfirmResult; }[] = [];
if (isWindows) {
buttons.push(save, dontSave, cancel);
} else if (isLinux) {
buttons.push(dontSave, cancel, save);
} else {
buttons.push(save, cancel, dontSave);
}
enum ConfirmResult {
SAVE,
DONT_SAVE,
CANCEL
}
const message = nls.localize('saveWorkspaceMessage', "Do you want to save your workspace configuration as a file?");
const detail = nls.localize('saveWorkspaceDetail', "Save your workspace if you plan to open it again.");
const cancelId = buttons.indexOf(cancel);
const save = { label: mnemonicButtonLabel(nls.localize('save', "Save")), result: ConfirmResult.SAVE };
const dontSave = { label: mnemonicButtonLabel(nls.localize('doNotSave', "Don't Save")), result: ConfirmResult.DONT_SAVE };
const cancel = { label: nls.localize('cancel', "Cancel"), result: ConfirmResult.CANCEL };
return this.dialogService.show(Severity.Warning, message, buttons.map(button => button.label), { detail, cancelId }).then(res => {
switch (buttons[res].result) {
const buttons: { label: string; result: ConfirmResult; }[] = [];
if (isWindows) {
buttons.push(save, dontSave, cancel);
} else if (isLinux) {
buttons.push(dontSave, cancel, save);
} else {
buttons.push(save, cancel, dontSave);
}
// Cancel: veto unload
case ConfirmResult.CANCEL:
return true;
const message = nls.localize('saveWorkspaceMessage', "Do you want to save your workspace configuration as a file?");
const detail = nls.localize('saveWorkspaceDetail', "Save your workspace if you plan to open it again.");
const cancelId = buttons.indexOf(cancel);
// Don't Save: delete workspace
case ConfirmResult.DONT_SAVE:
this.workspaceService.deleteUntitledWorkspace(workspaceIdentifier);
return false;
const res = await this.dialogService.show(Severity.Warning, message, buttons.map(button => button.label), { detail, cancelId });
// Save: save workspace, but do not veto unload
case ConfirmResult.SAVE: {
return this.pickNewWorkspacePath().then(newWorkspacePath => {
if (newWorkspacePath) {
return this.saveWorkspaceAs(workspaceIdentifier, newWorkspacePath).then(_ => {
return this.workspaceService.getWorkspaceIdentifier(newWorkspacePath).then(newWorkspaceIdentifier => {
const label = this.labelService.getWorkspaceLabel(newWorkspaceIdentifier, { verbose: true });
this.windowsService.addRecentlyOpened([{ label, workspace: newWorkspaceIdentifier }]);
this.workspaceService.deleteUntitledWorkspace(workspaceIdentifier);
return false;
});
}, () => false);
}
return true; // keep veto if no target was provided
});
}
switch (buttons[res].result) {
// Cancel: veto unload
case ConfirmResult.CANCEL:
return true;
// Don't Save: delete workspace
case ConfirmResult.DONT_SAVE:
this.workspaceService.deleteUntitledWorkspace(workspaceIdentifier);
return false;
// Save: save workspace, but do not veto unload if path provided
case ConfirmResult.SAVE: {
const newWorkspacePath = await this.pickNewWorkspacePath();
if (!newWorkspacePath) {
return true; // keep veto if no target was provided
}
});
});
try {
await this.saveWorkspaceAs(workspaceIdentifier, newWorkspacePath);
const newWorkspaceIdentifier = await this.workspaceService.getWorkspaceIdentifier(newWorkspacePath);
const label = this.labelService.getWorkspaceLabel(newWorkspaceIdentifier, { verbose: true });
this.windowService.addRecentlyOpened([{ label, workspace: newWorkspaceIdentifier }]);
this.workspaceService.deleteUntitledWorkspace(workspaceIdentifier);
} catch (error) {
// ignore
}
return false;
}
}
}
pickNewWorkspacePath(): Promise<URI | undefined> {
@@ -209,6 +219,13 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
private async doAddFolders(foldersToAdd: IWorkspaceFolderCreationData[], index?: number, donotNotifyError: boolean = false): Promise<void> {
const state = this.contextService.getWorkbenchState();
if (this.environmentService.configuration.remoteAuthority) {
// Do not allow workspace folders with scheme different than the current remote scheme
const schemas = this.contextService.getWorkspace().folders.map(f => f.uri.scheme);
if (schemas.length && foldersToAdd.some(f => schemas.indexOf(f.uri.scheme) === -1)) {
return Promise.reject(new Error(nls.localize('differentSchemeRoots', "Workspace folders from different providers are not allowed in the same workspace.")));
}
}
// If we are in no-workspace or single-folder workspace, adding folders has to
// enter a workspace.
@@ -218,7 +235,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
newWorkspaceFolders = distinct(newWorkspaceFolders, folder => getComparisonKey(folder.uri));
if (state === WorkbenchState.EMPTY && newWorkspaceFolders.length === 0 || state === WorkbenchState.FOLDER && newWorkspaceFolders.length === 1) {
return Promise.resolve(); // return if the operation is a no-op for the current state
return; // return if the operation is a no-op for the current state
}
return this.createAndEnterWorkspace(newWorkspaceFolders);
@@ -267,7 +284,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
async createAndEnterWorkspace(folders: IWorkspaceFolderCreationData[], path?: URI): Promise<void> {
if (path && !await this.isValidTargetWorkspacePath(path)) {
return Promise.reject(null);
return;
}
const remoteAuthority = this.environmentService.configuration.remoteAuthority;
const untitledWorkspace = await this.workspaceService.createUntitledWorkspace(folders, remoteAuthority);
@@ -281,11 +298,11 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
async saveAndEnterWorkspace(path: URI): Promise<void> {
if (!await this.isValidTargetWorkspacePath(path)) {
return Promise.reject(null);
return;
}
const workspaceIdentifier = this.getCurrentWorkspaceIdentifier();
if (!workspaceIdentifier) {
return Promise.reject(null);
return;
}
await this.saveWorkspaceAs(workspaceIdentifier, path);
@@ -318,7 +335,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
// Return early if target is same as source
if (isEqual(configPathURI, targetConfigPathURI)) {
return Promise.resolve(null);
return;
}
// Read the contents of the workspace file, update it to new location and save it.
@@ -327,18 +344,17 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
await this.textFileService.create(targetConfigPathURI, newRawWorkspaceContents, { overwrite: true });
}
private handleWorkspaceConfigurationEditingError(error: JSONEditingError): Promise<void> {
private handleWorkspaceConfigurationEditingError(error: JSONEditingError): void {
switch (error.code) {
case JSONEditingErrorCode.ERROR_INVALID_FILE:
this.onInvalidWorkspaceConfigurationFileError();
return Promise.resolve();
break;
case JSONEditingErrorCode.ERROR_FILE_DIRTY:
this.onWorkspaceConfigurationFileDirtyError();
return Promise.resolve();
break;
default:
this.notificationService.error(error.message);
}
this.notificationService.error(error.message);
return Promise.resolve();
}
private onInvalidWorkspaceConfigurationFileError(): void {
@@ -362,7 +378,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
async enterWorkspace(path: URI): Promise<void> {
if (!!this.environmentService.extensionTestsLocationURI) {
return Promise.reject(new Error('Entering a new workspace is not possible in tests.'));
throw new Error('Entering a new workspace is not possible in tests.');
}
const workspace = await this.workspaceService.getWorkspaceIdentifier(path);
@@ -382,7 +398,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
await this.migrateStorage(result.workspace);
// Reinitialize backup service
if (this.backupFileService instanceof BackupFileService) {
this.backupFileService.initialize(result.backupPath!);
this.backupFileService.initialize(toBackupWorkspaceResource(result.backupPath!, this.environmentService));
}
}
@@ -409,7 +425,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
private doCopyWorkspaceSettings(toWorkspace: IWorkspaceIdentifier, filter?: (config: IConfigurationPropertySchema) => boolean): Promise<void> {
const configurationProperties = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).getConfigurationProperties();
const targetWorkspaceConfiguration = {};
const targetWorkspaceConfiguration: any = {};
for (const key of this.configurationService.keys().workspace) {
if (configurationProperties[key]) {
if (filter && !filter(configurationProperties[key])) {