diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 6b04f0a2621..44a758109b1 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -33,6 +33,7 @@ "./vs/workbench/contrib/tasks/**/*.ts", "./vs/workbench/services/commands/**/*", "./vs/workbench/services/configuration/common/**/*", + "./vs/workbench/services/configurationResolver/**/*.ts", "./vs/workbench/services/files/node/watcher/**/*", "./vs/workbench/services/themes/**/*.ts", "./vs/workbench/services/bulkEdit/**/*.ts", diff --git a/src/vs/workbench/api/electron-browser/mainThreadTask.ts b/src/vs/workbench/api/electron-browser/mainThreadTask.ts index eb4892a794b..0a08156ce69 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTask.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTask.ts @@ -597,7 +597,7 @@ export class MainThreadTask implements MainThreadTaskShape { }; for (let i = 0; i < partiallyResolvedVars.length; i++) { const variableName = vars[i].substring(2, vars[i].length - 1); - if (values.variables[vars[i]] === vars[i]) { + if (resolvedVars && values.variables[vars[i]] === vars[i]) { result.variables.set(variableName, resolvedVars.get(variableName)); } else { result.variables.set(variableName, partiallyResolvedVars[i]); diff --git a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts index 71aa1fd6d00..461c06aec32 100644 --- a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts @@ -23,6 +23,7 @@ import { ConfiguredInput, IConfigurationResolverService } from 'vs/workbench/ser import { IWindowService } from 'vs/platform/windows/common/windows'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; + export class ConfigurationResolverService extends AbstractVariableResolverService { static INPUT_OR_COMMAND_VARIABLES_PATTERN = /\${((input|command):(.*?))}/g; @@ -37,17 +38,17 @@ export class ConfigurationResolverService extends AbstractVariableResolverServic @IQuickInputService private readonly quickInputService: IQuickInputService ) { super({ - getFolderUri: (folderName: string): uri => { + getFolderUri: (folderName: string): uri | undefined => { const folder = workspaceContextService.getWorkspace().folders.filter(f => f.name === folderName).pop(); return folder ? folder.uri : undefined; }, getWorkspaceFolderCount: (): number => { return workspaceContextService.getWorkspace().folders.length; }, - getConfigurationValue: (folderUri: uri, suffix: string) => { - return configurationService.getValue(suffix, folderUri ? { resource: folderUri } : undefined); + getConfigurationValue: (folderUri: uri, suffix: string): string | undefined => { + return configurationService.getValue(suffix, folderUri ? { resource: folderUri } : {}); }, - getExecPath: () => { + getExecPath: (): string | undefined => { return environmentService['execPath']; }, getFilePath: (): string | undefined => { @@ -72,18 +73,21 @@ export class ConfigurationResolverService extends AbstractVariableResolverServic } return undefined; }, - getLineNumber: (): string => { + getLineNumber: (): string | undefined => { const activeTextEditorWidget = editorService.activeTextEditorWidget; if (isCodeEditor(activeTextEditorWidget)) { - const lineNumber = activeTextEditorWidget.getSelection().positionLineNumber; - return String(lineNumber); + const selection = activeTextEditorWidget.getSelection(); + if (selection) { + const lineNumber = selection.positionLineNumber; + return String(lineNumber); + } } return undefined; } }, windowService.getConfiguration().userEnv); } - public resolveWithInteractionReplace(folder: IWorkspaceFolder, config: any, section?: string, variables?: IStringDictionary): Promise { + public resolveWithInteractionReplace(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary): Promise { // resolve any non-interactive variables config = this.resolveAny(folder, config); @@ -100,7 +104,7 @@ export class ConfigurationResolverService extends AbstractVariableResolverServic }); } - public resolveWithInteraction(folder: IWorkspaceFolder, config: any, section?: string, variables?: IStringDictionary): Promise> { + public resolveWithInteraction(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary): Promise | undefined> { // resolve any non-interactive variables const resolved = this.resolveAnyMap(folder, config); config = resolved.newConfig; @@ -118,7 +122,7 @@ export class ConfigurationResolverService extends AbstractVariableResolverServic /** * Add all items from newMapping to fullMapping. Returns false if newMapping is undefined. */ - private updateMapping(newMapping: IStringDictionary, fullMapping: Map): boolean { + private updateMapping(newMapping: IStringDictionary | undefined, fullMapping: Map): boolean { if (!newMapping) { return false; } @@ -136,15 +140,15 @@ export class ConfigurationResolverService extends AbstractVariableResolverServic * * @param variableToCommandMap Aliases for commands */ - private async resolveWithInputAndCommands(folder: IWorkspaceFolder, configuration: any, variableToCommandMap: IStringDictionary, section: string): Promise> { + private async resolveWithInputAndCommands(folder: IWorkspaceFolder | undefined, configuration: any, variableToCommandMap?: IStringDictionary, section?: string): Promise | undefined> { if (!configuration) { return Promise.resolve(undefined); } // get all "inputs" - let inputs: ConfiguredInput[] = undefined; - if (folder && this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY) { + let inputs: ConfiguredInput[] = []; + if (folder && this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY && section) { let result = this.configurationService.getValue(section, { resource: folder.uri }); if (result) { inputs = result.inputs; @@ -222,7 +226,7 @@ export class ConfigurationResolverService extends AbstractVariableResolverServic * @param variable Name of the input variable. * @param inputInfos Information about each possible input variable. */ - private showUserInput(variable: string, inputInfos: ConfiguredInput[]): Promise { + private showUserInput(variable: string, inputInfos: ConfiguredInput[]): Promise { // find info for the given input variable const info = inputInfos.filter(item => item.id === variable).pop(); diff --git a/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts b/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts index 451127046f8..fafa3c35e17 100644 --- a/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts @@ -35,7 +35,7 @@ export interface IConfigurationResolverService { * Similar to resolveWithInteractionReplace, except without the replace. Returns a map of variables and their resolution. * Keys in the map will be of the format input:variableName or command:variableName. */ - resolveWithInteraction(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary): Promise>; + resolveWithInteraction(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary): Promise | undefined>; } export interface PromptStringInputInfo { diff --git a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts index c87f1af38fe..3d1e2a813c7 100644 --- a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts @@ -82,11 +82,11 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe return { newConfig, resolvedVariables }; } - public resolveWithInteractionReplace(folder: IWorkspaceFolder, config: any): Promise { + public resolveWithInteractionReplace(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary): Promise { throw new Error('resolveWithInteractionReplace not implemented.'); } - public resolveWithInteraction(folder: IWorkspaceFolder, config: any): Promise { + public resolveWithInteraction(folder: IWorkspaceFolder | undefined, config: any, section?: string, variables?: IStringDictionary): Promise | undefined> { throw new Error('resolveWithInteraction not implemented.'); } diff --git a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts index 4fc62f2dfbc..7fa386cdafc 100644 --- a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts +++ b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts @@ -37,7 +37,7 @@ suite('Configuration Resolver Service', () => { uri: uri.parse('file:///VSCode/workspaceLocation'), name: 'hey', index: 0, - toResource: () => null + toResource: (path: string) => uri.file(path) }; configurationResolverService = new ConfigurationResolverService(windowService, editorService, TestEnvironmentService, new MockInputsConfigurationService(), mockCommandService, new TestContextService(), quickInputService); }); @@ -528,7 +528,7 @@ class MockQuickInputService implements IQuickInputService { public pick(picks: Promise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: true }, token?: CancellationToken): Promise; public pick(picks: Promise[]> | QuickPickInput[], options?: IPickOptions & { canPickMany: false }, token?: CancellationToken): Promise; - public pick(picks: Promise[]> | QuickPickInput[], options?: Omit, 'canPickMany'>, token?: CancellationToken): Promise { + public pick(picks: Promise[]> | QuickPickInput[], options?: Omit, 'canPickMany'>, token?: CancellationToken): Promise { if (Types.isArray(picks)) { return Promise.resolve({ label: 'selectedPick', description: 'pick description' }); } else { @@ -537,7 +537,7 @@ class MockQuickInputService implements IQuickInputService { } public input(options?: IInputOptions, token?: CancellationToken): Promise { - return Promise.resolve('resolved' + options.prompt); + return Promise.resolve(options ? 'resolved' + options.prompt : 'resolved'); } backButton: IQuickInputButton;