Skip to content

Commit fb1e59f

Browse files
committed
Same Quick Debugging in Test Explorer as in Project Outline
1 parent ebf1d23 commit fb1e59f

File tree

2 files changed

+40
-106
lines changed

2 files changed

+40
-106
lines changed

src/cmakeProject.ts

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import paths from './paths';
4848
import { ProjectController } from './projectController';
4949
import { MessageItem } from 'vscode';
5050
import { DebugTrackerFactory, DebuggerInformation, getDebuggerPipeName } from './debug/debuggerConfigureDriver';
51+
import { VSCodeDebugConfiguration } from './debugger';
5152

5253
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
5354
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
@@ -2303,10 +2304,17 @@ export class CMakeProject {
23032304
return EnvironmentUtils.merge([env, configureEnv]);
23042305
}
23052306

2306-
/**
2307-
* Implementation of `cmake.debugTarget`
2308-
*/
2309-
async debugTarget(name?: string): Promise<vscode.DebugSession | null> {
2307+
async getDebugConfiguration(name?: string): Promise<VSCodeDebugConfiguration | null> {
2308+
const targetExecutable = await this.prepareLaunchTargetExecutable(name);
2309+
if (!targetExecutable) {
2310+
log.error(localize('failed.to.prepare.target', 'Failed to prepare executable target with name {0}', `"${name}"`));
2311+
return null;
2312+
}
2313+
2314+
if (!targetExecutable) {
2315+
return null;
2316+
}
2317+
23102318
const drv = await this.getCMakeDriverInstance();
23112319
if (!drv) {
23122320
void vscode.window.showErrorMessage(localize('set.up.and.build.project.before.debugging', 'Set up and build your CMake project before debugging.'));
@@ -2326,12 +2334,6 @@ export class CMakeProject {
23262334
return null;
23272335
}
23282336

2329-
const targetExecutable = await this.prepareLaunchTargetExecutable(name);
2330-
if (!targetExecutable) {
2331-
log.error(localize('failed.to.prepare.target', 'Failed to prepare executable target with name {0}', `"${name}"`));
2332-
return null;
2333-
}
2334-
23352337
let debugConfig;
23362338
try {
23372339
const cache = await CMakeCache.fromPath(drv.cachePath);
@@ -2370,10 +2372,25 @@ export class CMakeProject {
23702372
config: debugConfig
23712373
}));
23722374

2375+
return debugConfig;
2376+
}
2377+
2378+
/**
2379+
* Implementation of `cmake.debugTarget`
2380+
*/
2381+
async debugTarget(name?: string): Promise<vscode.DebugSession | null> {
2382+
2383+
const debugConfig = await this.getDebugConfiguration(name);
2384+
2385+
if (debugConfig === null) {
2386+
return null;
2387+
}
2388+
23732389
const cfg = vscode.workspace.getConfiguration('cmake', this.workspaceFolder.uri).inspect<object>('debugConfig');
23742390
const customSetting = (cfg?.globalValue !== undefined || cfg?.workspaceValue !== undefined || cfg?.workspaceFolderValue !== undefined);
2375-
let dbg = debugConfig.MIMode?.toString();
2376-
if (!dbg && debugConfig.type === "cppvsdbg") {
2391+
2392+
let dbg = debugConfig?.MIMode?.toString();
2393+
if (!dbg && debugConfig?.type === "cppvsdbg") {
23772394
dbg = "vsdbg";
23782395
} else {
23792396
dbg = "(unset)";

src/ctest.ts

Lines changed: 11 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -758,54 +758,22 @@ export class CTestDriver implements vscode.Disposable {
758758

759759
private async debugCTestImpl(workspaceFolder: vscode.WorkspaceFolder, testName: string, cancellation: vscode.CancellationToken): Promise<void> {
760760
const magicValue = sessionNum++;
761-
const launchConfig = vscode.workspace.getConfiguration(
762-
'launch',
763-
workspaceFolder.uri
764-
);
765-
const workspaceLaunchConfig = vscode.workspace.workspaceFile ? vscode.workspace.getConfiguration(
766-
'launch',
767-
vscode.workspace.workspaceFile
768-
) : undefined;
769-
const configs = launchConfig.get<vscode.DebugConfiguration[]>('configurations') ?? [];
770-
const workspaceConfigs = workspaceLaunchConfig?.get<vscode.DebugConfiguration[]>('configurations') ?? [];
771-
if (configs.length === 0 && workspaceConfigs.length === 0) {
761+
762+
const testProgram = this.testProgram(testName);
763+
const basename = path.parse(testProgram).name;
764+
const debugConfig = await this.projectController?.getActiveCMakeProject()?.getDebugConfiguration(basename);
765+
766+
if (debugConfig === null || debugConfig === undefined) {
772767
log.error(localize('no.launch.config', 'No launch configurations found.'));
773768
return;
774769
}
775770

776-
interface ConfigItem extends vscode.QuickPickItem {
777-
label: string;
778-
config: vscode.DebugConfiguration;
779-
detail: string;
780-
// Undefined for workspace launch config
781-
folder?: vscode.WorkspaceFolder;
782-
}
783-
let allConfigItems: ConfigItem[] = configs.map(config => ({ label: config.name, config, folder: workspaceFolder, detail: workspaceFolder.uri.fsPath }));
784-
allConfigItems = allConfigItems.concat(workspaceConfigs.map(config => ({ label: config.name, config, detail: vscode.workspace.workspaceFile!.fsPath })));
785-
let chosenConfig: ConfigItem | undefined;
786-
if (allConfigItems.length === 1) {
787-
chosenConfig = allConfigItems[0];
788-
} else {
789-
// TODO: we can remember the last choice once the CMake side panel work is done
790-
const chosen = await vscode.window.showQuickPick(allConfigItems, { placeHolder: localize('choose.launch.config', 'Choose a launch configuration to debug the test with.') });
791-
if (chosen) {
792-
chosenConfig = chosen;
793-
} else {
794-
return;
795-
}
796-
}
797-
798-
// Commands can't be used to replace array (i.e., args); and both test program and test args requires folder and
799-
// test name as parameters, which means one lauch config for each test. So replacing them here is a better way.
800-
chosenConfig.config = this.replaceAllInObject<vscode.DebugConfiguration>(chosenConfig.config, '${cmake.testProgram}', this.testProgram(testName));
801-
chosenConfig.config = this.replaceAllInObject<vscode.DebugConfiguration>(chosenConfig.config, '${cmake.testWorkingDirectory}', this.testWorkingDirectory(testName));
802-
803-
// Replace cmake.testArgs wrapped in quotes, like `"${command:cmake.testArgs}"`, without any spaces in between,
804-
// since we need to repalce the quotes as well.
805-
chosenConfig.config = this.replaceArrayItems(chosenConfig.config, '${cmake.testArgs}', this.testArgs(testName)) as vscode.DebugConfiguration;
771+
debugConfig.cwd = this.testWorkingDirectory(testName)!;
772+
debugConfig.args = this.testArgs(testName)!;
806773

807774
// Identify the session we started
808-
chosenConfig.config[magicKey] = magicValue;
775+
debugConfig[magicKey] = magicValue;
776+
809777
let onDidStartDebugSession: vscode.Disposable | undefined;
810778
let onDidTerminateDebugSession: vscode.Disposable | undefined;
811779
let sessionId: string | undefined;
@@ -828,7 +796,7 @@ export class CTestDriver implements vscode.Disposable {
828796
log.info('debugSessionTerminated');
829797
});
830798

831-
const debugStarted = await vscode.debug.startDebugging(chosenConfig.folder, chosenConfig.config!);
799+
const debugStarted = await vscode.debug.startDebugging(workspaceFolder, debugConfig!);
832800
if (debugStarted) {
833801
const session = await started;
834802
if (session) {
@@ -879,57 +847,6 @@ export class CTestDriver implements vscode.Disposable {
879847
return [];
880848
}
881849

882-
private replaceAllInObject<T>(obj: any, str: string, replace: string): T {
883-
const regex = new RegExp(util.escapeStringForRegex(str), 'g');
884-
if (util.isString(obj)) {
885-
obj = obj.replace(regex, replace);
886-
} else if (util.isArray(obj)) {
887-
for (let i = 0; i < obj.length; i++) {
888-
obj[i] = this.replaceAllInObject(obj[i], str, replace);
889-
}
890-
} else if (typeof obj === 'object') {
891-
for (const key of Object.keys(obj)) {
892-
obj[key] = this.replaceAllInObject(obj[key], str, replace);
893-
}
894-
}
895-
return obj;
896-
}
897-
898-
private replaceArrayItems(obj: any, str: string, replace: string[]) {
899-
if (util.isArray(obj) && obj.length !== 0) {
900-
const result: any[] = [];
901-
for (let i = 0; i < obj.length; i++) {
902-
if (util.isArray(obj[i]) || typeof obj[i] === 'object') {
903-
result.push(this.replaceArrayItems(obj[i], str, replace));
904-
} else if (util.isString(obj[i])) {
905-
const replacedItem = this.replaceArrayItemsHelper(obj[i] as string, str, replace);
906-
if (util.isArray(replacedItem)) {
907-
result.push(...replacedItem);
908-
} else {
909-
result.push(replacedItem);
910-
}
911-
} else {
912-
result.push(obj[i]);
913-
}
914-
}
915-
return result;
916-
}
917-
if (typeof obj === 'object') {
918-
for (const key of Object.keys(obj)) {
919-
obj[key] = this.replaceArrayItems(obj[key], str, replace);
920-
}
921-
return obj;
922-
}
923-
return obj;
924-
}
925-
926-
private replaceArrayItemsHelper(orig: string, str: string, replace: string[]): string | string[] {
927-
if (orig === str) {
928-
return replace;
929-
}
930-
return orig;
931-
}
932-
933850
private async debugTestHandler(request: vscode.TestRunRequest, cancellation: vscode.CancellationToken) {
934851
if (!testExplorer) {
935852
return;

0 commit comments

Comments
 (0)