Skip to content

Commit f521072

Browse files
committed
Strict null check configurationEditingService
1 parent a6c498b commit f521072

2 files changed

Lines changed: 35 additions & 18 deletions

File tree

src/tsconfig.strictNullChecks.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@
381381
"./vs/workbench/services/configuration/common/configurationModels.ts",
382382
"./vs/workbench/services/configuration/common/jsonEditing.ts",
383383
"./vs/workbench/services/configuration/node/configuration.ts",
384+
"./vs/workbench/services/configuration/node/configurationEditingService.ts",
384385
"./vs/workbench/services/configuration/node/jsonEditingService.ts",
385386
"./vs/workbench/services/configuration/test/common/configurationModels.test.ts",
386387
"./vs/workbench/services/configurationResolver/common/configurationResolver.ts",

src/vs/workbench/services/configuration/node/configurationEditingService.ts

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile
2222
import { IConfigurationService, IConfigurationOverrides, keyFromOverrideIdentifier, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
2323
import { FOLDER_SETTINGS_PATH, WORKSPACE_STANDALONE_CONFIGURATIONS, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY } from 'vs/workbench/services/configuration/common/configuration';
2424
import { IFileService } from 'vs/platform/files/common/files';
25-
import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService';
25+
import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService';
2626
import { OVERRIDE_PROPERTY_PATTERN, IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
2727
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
2828
import { ITextModel } from 'vs/editor/common/model';
@@ -106,7 +106,7 @@ export interface IConfigurationEditingOptions {
106106
interface IConfigurationEditOperation extends IConfigurationValue {
107107
target: ConfigurationTarget;
108108
jsonPath: json.JSONPath;
109-
resource: URI;
109+
resource?: URI;
110110
workspaceStandAloneConfigurationKey?: string;
111111

112112
}
@@ -158,7 +158,7 @@ export class ConfigurationEditingService {
158158
private async writeToBuffer(model: ITextModel, operation: IConfigurationEditOperation, save: boolean): Promise<any> {
159159
const edit = this.getEdits(model, operation)[0];
160160
if (edit && this.applyEditsToBuffer(edit, model) && save) {
161-
return this.textFileService.save(operation.resource, { skipSaveParticipants: true /* programmatic change */ });
161+
return this.textFileService.save(operation.resource!, { skipSaveParticipants: true /* programmatic change */ });
162162
}
163163
}
164164

@@ -175,7 +175,7 @@ export class ConfigurationEditingService {
175175
return false;
176176
}
177177

178-
private onError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationOverrides): void {
178+
private onError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationOverrides | undefined): void {
179179
switch (error.code) {
180180
case ConfigurationEditingErrorCode.ERROR_INVALID_CONFIGURATION:
181181
this.onInvalidConfigurationError(error, operation);
@@ -196,7 +196,7 @@ export class ConfigurationEditingService {
196196
this.notificationService.prompt(Severity.Error, error.message,
197197
[{
198198
label: openStandAloneConfigurationActionLabel,
199-
run: () => this.openFile(operation.resource)
199+
run: () => this.openFile(operation.resource!)
200200
}]
201201
);
202202
} else {
@@ -209,7 +209,7 @@ export class ConfigurationEditingService {
209209
}
210210
}
211211

212-
private onConfigurationFileDirtyError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationOverrides): void {
212+
private onConfigurationFileDirtyError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationOverrides | undefined): void {
213213
const openStandAloneConfigurationActionLabel = operation.workspaceStandAloneConfigurationKey === TASKS_CONFIGURATION_KEY ? nls.localize('openTasksConfiguration', "Open Tasks Configuration")
214214
: operation.workspaceStandAloneConfigurationKey === LAUNCH_CONFIGURATION_KEY ? nls.localize('openLaunchConfiguration', "Open Launch Configuration")
215215
: null;
@@ -218,13 +218,13 @@ export class ConfigurationEditingService {
218218
[{
219219
label: nls.localize('saveAndRetry', "Save and Retry"),
220220
run: () => {
221-
const key = operation.key ? `${operation.workspaceStandAloneConfigurationKey}.${operation.key}` : operation.workspaceStandAloneConfigurationKey;
221+
const key = operation.key ? `${operation.workspaceStandAloneConfigurationKey}.${operation.key}` : operation.workspaceStandAloneConfigurationKey!;
222222
this.writeConfiguration(operation.target, { key, value: operation.value }, <ConfigurationEditingOptions>{ force: true, scopes });
223223
}
224224
},
225225
{
226226
label: openStandAloneConfigurationActionLabel,
227-
run: () => this.openFile(operation.resource)
227+
run: () => this.openFile(operation.resource!)
228228
}]
229229
);
230230
} else {
@@ -296,7 +296,13 @@ export class ConfigurationEditingService {
296296
case ConfigurationTarget.WORKSPACE:
297297
return nls.localize('errorInvalidConfigurationWorkspace', "Unable to write into workspace settings. Please open the workspace settings to correct errors/warnings in the file and try again.");
298298
case ConfigurationTarget.WORKSPACE_FOLDER:
299-
const workspaceFolderName = this.contextService.getWorkspaceFolder(operation.resource).name;
299+
let workspaceFolderName: string = '<<unknown>>';
300+
if (operation.resource) {
301+
const folder = this.contextService.getWorkspaceFolder(operation.resource);
302+
if (folder) {
303+
workspaceFolderName = folder.name;
304+
}
305+
}
300306
return nls.localize('errorInvalidConfigurationFolder', "Unable to write into folder settings. Please open the '{0}' folder settings to correct errors/warnings in it and try again.", workspaceFolderName);
301307
}
302308
return '';
@@ -314,7 +320,13 @@ export class ConfigurationEditingService {
314320
case ConfigurationTarget.WORKSPACE:
315321
return nls.localize('errorConfigurationFileDirtyWorkspace', "Unable to write into workspace settings because the file is dirty. Please save the workspace settings file first and then try again.");
316322
case ConfigurationTarget.WORKSPACE_FOLDER:
317-
const workspaceFolderName = this.contextService.getWorkspaceFolder(operation.resource).name;
323+
let workspaceFolderName: string = '<<unknown>>';
324+
if (operation.resource) {
325+
const folder = this.contextService.getWorkspaceFolder(operation.resource);
326+
if (folder) {
327+
workspaceFolderName = folder.name;
328+
}
329+
}
318330
return nls.localize('errorConfigurationFileDirtyFolder', "Unable to write into folder settings because the file is dirty. Please save the '{0}' folder settings file first and then try again.", workspaceFolderName);
319331
}
320332
return '';
@@ -352,7 +364,7 @@ export class ConfigurationEditingService {
352364
return setProperty(model.getValue(), jsonPath, value, { tabSize, insertSpaces, eol });
353365
}
354366

355-
private async resolveModelReference(resource: URI): Promise<IReference<ITextEditorModel>> {
367+
private async resolveModelReference(resource: URI): Promise<IReference<IResolvedTextEditorModel>> {
356368
const exists = await this.fileService.existsFile(resource);
357369
if (!exists) {
358370
await this.fileService.updateContent(resource, '{}', { encoding: encoding.UTF8 });
@@ -371,7 +383,7 @@ export class ConfigurationEditingService {
371383
return parseErrors.length > 0;
372384
}
373385

374-
private resolveAndValidate(target: ConfigurationTarget, operation: IConfigurationEditOperation, checkDirty: boolean, overrides: IConfigurationOverrides): Promise<IReference<ITextEditorModel>> {
386+
private resolveAndValidate(target: ConfigurationTarget, operation: IConfigurationEditOperation, checkDirty: boolean, overrides: IConfigurationOverrides): Promise<IReference<IResolvedTextEditorModel>> {
375387

376388
// Any key must be a known setting from the registry (unless this is a standalone config)
377389
if (!operation.workspaceStandAloneConfigurationKey) {
@@ -420,6 +432,10 @@ export class ConfigurationEditingService {
420432
}
421433
}
422434

435+
if (!operation.resource) {
436+
return this.reject(ConfigurationEditingErrorCode.ERROR_INVALID_FOLDER_TARGET, target, operation);
437+
}
438+
423439
return this.resolveModelReference(operation.resource)
424440
.then(reference => {
425441
const model = reference.object.textEditorModel;
@@ -447,14 +463,14 @@ export class ConfigurationEditingService {
447463
// Check for prefix
448464
if (config.key === key) {
449465
const jsonPath = this.isWorkspaceConfigurationResource(resource) ? [key] : [];
450-
return { key: jsonPath[jsonPath.length - 1], jsonPath, value: config.value, resource, workspaceStandAloneConfigurationKey: key, target };
466+
return { key: jsonPath[jsonPath.length - 1], jsonPath, value: config.value, resource: resource || undefined, workspaceStandAloneConfigurationKey: key, target };
451467
}
452468

453469
// Check for prefix.<setting>
454470
const keyPrefix = `${key}.`;
455471
if (config.key.indexOf(keyPrefix) === 0) {
456472
const jsonPath = this.isWorkspaceConfigurationResource(resource) ? [key, config.key.substr(keyPrefix.length)] : [config.key.substr(keyPrefix.length)];
457-
return { key: jsonPath[jsonPath.length - 1], jsonPath, value: config.value, resource, workspaceStandAloneConfigurationKey: key, target };
473+
return { key: jsonPath[jsonPath.length - 1], jsonPath, value: config.value, resource: resource || undefined, workspaceStandAloneConfigurationKey: key, target };
458474
}
459475
}
460476
}
@@ -469,15 +485,15 @@ export class ConfigurationEditingService {
469485
if (this.isWorkspaceConfigurationResource(resource)) {
470486
jsonPath = ['settings', ...jsonPath];
471487
}
472-
return { key, jsonPath, value: config.value, resource, target };
488+
return { key, jsonPath, value: config.value, resource: resource || undefined, target };
473489
}
474490

475-
private isWorkspaceConfigurationResource(resource: URI): boolean {
491+
private isWorkspaceConfigurationResource(resource: URI | null | undefined): boolean {
476492
const workspace = this.contextService.getWorkspace();
477493
return !!(workspace.configuration && resource && workspace.configuration.fsPath === resource.fsPath);
478494
}
479495

480-
private getConfigurationFileResource(target: ConfigurationTarget, relativePath: string, resource: URI): URI {
496+
private getConfigurationFileResource(target: ConfigurationTarget, relativePath: string, resource: URI | null | undefined): URI | null {
481497
if (target === ConfigurationTarget.USER) {
482498
return URI.file(this.environmentService.appSettingsPath);
483499
}
@@ -489,7 +505,7 @@ export class ConfigurationEditingService {
489505

490506
if (target === ConfigurationTarget.WORKSPACE) {
491507
if (workbenchState === WorkbenchState.WORKSPACE) {
492-
return workspace.configuration;
508+
return workspace.configuration || null;
493509
}
494510
if (workbenchState === WorkbenchState.FOLDER) {
495511
return workspace.folders[0].toResource(relativePath);

0 commit comments

Comments
 (0)