in patched-vscode/src/vs/workbench/contrib/debug/browser/debugService.ts [450:574]
private async createSession(launch: ILaunch | undefined, config: IConfig | undefined, options?: IDebugSessionOptions): Promise<boolean> {
// We keep the debug type in a separate variable 'type' so that a no-folder config has no attributes.
// Storing the type in the config would break extensions that assume that the no-folder case is indicated by an empty config.
let type: string | undefined;
if (config) {
type = config.type;
} else {
// a no-folder workspace has no launch.config
config = Object.create(null);
}
if (options && options.noDebug) {
config!.noDebug = true;
} else if (options && typeof options.noDebug === 'undefined' && options.parentSession && options.parentSession.configuration.noDebug) {
config!.noDebug = true;
}
const unresolvedConfig = deepClone(config);
let guess: Debugger | undefined;
let activeEditor: EditorInput | undefined;
if (!type) {
activeEditor = this.editorService.activeEditor;
if (activeEditor && activeEditor.resource) {
type = this.chosenEnvironments[activeEditor.resource.toString()];
}
if (!type) {
guess = await this.adapterManager.guessDebugger(false);
if (guess) {
type = guess.type;
}
}
}
const initCancellationToken = new CancellationTokenSource();
const sessionId = generateUuid();
this.sessionCancellationTokens.set(sessionId, initCancellationToken);
const configByProviders = await this.configurationManager.resolveConfigurationByProviders(launch && launch.workspace ? launch.workspace.uri : undefined, type, config!, initCancellationToken.token);
// a falsy config indicates an aborted launch
if (configByProviders && configByProviders.type) {
try {
let resolvedConfig = await this.substituteVariables(launch, configByProviders);
if (!resolvedConfig) {
// User cancelled resolving of interactive variables, silently return
return false;
}
if (initCancellationToken.token.isCancellationRequested) {
// User cancelled, silently return
return false;
}
const workspace = launch?.workspace || this.contextService.getWorkspace();
const taskResult = await this.taskRunner.runTaskAndCheckErrors(workspace, resolvedConfig.preLaunchTask);
if (taskResult === TaskRunResult.Failure) {
return false;
}
const cfg = await this.configurationManager.resolveDebugConfigurationWithSubstitutedVariables(launch && launch.workspace ? launch.workspace.uri : undefined, resolvedConfig.type, resolvedConfig, initCancellationToken.token);
if (!cfg) {
if (launch && type && cfg === null && !initCancellationToken.token.isCancellationRequested) { // show launch.json only for "config" being "null".
await launch.openConfigFile({ preserveFocus: true, type }, initCancellationToken.token);
}
return false;
}
resolvedConfig = cfg;
const dbg = this.adapterManager.getDebugger(resolvedConfig.type);
if (!dbg || (configByProviders.request !== 'attach' && configByProviders.request !== 'launch')) {
let message: string;
if (configByProviders.request !== 'attach' && configByProviders.request !== 'launch') {
message = configByProviders.request ? nls.localize('debugRequestNotSupported', "Attribute '{0}' has an unsupported value '{1}' in the chosen debug configuration.", 'request', configByProviders.request)
: nls.localize('debugRequesMissing', "Attribute '{0}' is missing from the chosen debug configuration.", 'request');
} else {
message = resolvedConfig.type ? nls.localize('debugTypeNotSupported', "Configured debug type '{0}' is not supported.", resolvedConfig.type) :
nls.localize('debugTypeMissing', "Missing property 'type' for the chosen launch configuration.");
}
const actionList: IAction[] = [];
actionList.push(new Action(
'installAdditionalDebuggers',
nls.localize({ key: 'installAdditionalDebuggers', comment: ['Placeholder is the debug type, so for example "node", "python"'] }, "Install {0} Extension", resolvedConfig.type),
undefined,
true,
async () => this.commandService.executeCommand('debug.installAdditionalDebuggers', resolvedConfig?.type)
));
await this.showError(message, actionList);
return false;
}
if (!dbg.enabled) {
await this.showError(debuggerDisabledMessage(dbg.type), []);
return false;
}
const result = await this.doCreateSession(sessionId, launch?.workspace, { resolved: resolvedConfig, unresolved: unresolvedConfig }, options);
if (result && guess && activeEditor && activeEditor.resource) {
// Remeber user choice of environment per active editor to make starting debugging smoother #124770
this.chosenEnvironments[activeEditor.resource.toString()] = guess.type;
this.debugStorage.storeChosenEnvironments(this.chosenEnvironments);
}
return result;
} catch (err) {
if (err && err.message) {
await this.showError(err.message);
} else if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
await this.showError(nls.localize('noFolderWorkspaceDebugError', "The active file can not be debugged. Make sure it is saved and that you have a debug extension installed for that file type."));
}
if (launch && !initCancellationToken.token.isCancellationRequested) {
await launch.openConfigFile({ preserveFocus: true }, initCancellationToken.token);
}
return false;
}
}
if (launch && type && configByProviders === null && !initCancellationToken.token.isCancellationRequested) { // show launch.json only for "config" being "null".
await launch.openConfigFile({ preserveFocus: true, type }, initCancellationToken.token);
}
return false;
}