Skip to content

Commit 19e083e

Browse files
author
Dave Bartolomeo
committed
Use type-safe VSCode commands
1 parent 7dfa52b commit 19e083e

6 files changed

Lines changed: 56 additions & 45 deletions

File tree

extensions/ql-vscode/src/common/commands.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
VariantAnalysisScannedRepository,
1212
VariantAnalysisScannedRepositoryResult,
1313
} from "../variant-analysis/shared/variant-analysis";
14+
import { QLDebugConfiguration } from "../debugger/debug-configuration";
1415

1516
// A command function matching the signature that VS Code calls when
1617
// a command on a selection is invoked.
@@ -52,6 +53,15 @@ export type BuiltInVsCodeCommands = {
5253
) => Promise<void>;
5354
"vscode.open": (uri: Uri) => Promise<void>;
5455
"vscode.openFolder": (uri: Uri) => Promise<void>;
56+
// We type the `config` property specifically as a CodeQL debug configuration, since that's the
57+
// only kinds we specify anyway.
58+
"workbench.action.debug.start": (options?: {
59+
config?: Partial<QLDebugConfiguration>;
60+
noDebug?: boolean;
61+
}) => Promise<void>;
62+
"workbench.action.debug.stepInto": () => Promise<void>;
63+
"workbench.action.debug.stepOver": () => Promise<void>;
64+
"workbench.action.debug.stepOut": () => Promise<void>;
5565
};
5666

5767
// Commands that are available before the extension is fully activated.

extensions/ql-vscode/src/debugger/debugger-ui.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
debug,
77
Uri,
88
CancellationTokenSource,
9-
commands,
109
} from "vscode";
1110
import { DebuggerCommands } from "../common/commands";
1211
import { isCanary } from "../config";
@@ -24,6 +23,7 @@ import {
2423
} from "../run-queries-shared";
2524
import { QLResolvedDebugConfiguration } from "./debug-configuration";
2625
import * as CodeQLProtocol from "./debug-protocol";
26+
import { App } from "../common/app";
2727

2828
/**
2929
* Listens to messages passing between VS Code and the debug adapter, so that we can supplement the
@@ -144,6 +144,7 @@ export class DebuggerUI
144144
private readonly sessions = new Map<string, QLDebugAdapterTracker>();
145145

146146
constructor(
147+
private readonly app: App,
147148
private readonly localQueryResultsView: ResultsView,
148149
private readonly localQueries: LocalQueries,
149150
private readonly dbm: DatabaseManager,
@@ -204,7 +205,7 @@ export class DebuggerUI
204205

205206
private async startDebuggingSelection(): Promise<void> {
206207
// Launch the currently selected debug configuration, but specifying QuickEval mode.
207-
await commands.executeCommand("workbench.action.debug.start", {
208+
await this.app.commands.execute("workbench.action.debug.start", {
208209
config: {
209210
quickEval: true,
210211
},

extensions/ql-vscode/src/extension.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,12 @@ async function activateWithInstalledDistribution(
873873
);
874874

875875
void extLogger.log("Initializing debugger UI.");
876-
const debuggerUI = new DebuggerUI(localQueryResultsView, localQueries, dbm);
876+
const debuggerUI = new DebuggerUI(
877+
app,
878+
localQueryResultsView,
879+
localQueries,
880+
dbm,
881+
);
877882
ctx.subscriptions.push(debuggerUI);
878883

879884
const dataExtensionsEditorModule =

extensions/ql-vscode/test/vscode-tests/cli-integration/debug-controller.ts

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@ import {
44
DebugSession,
55
ProviderResult,
66
Uri,
7-
commands,
87
debug,
98
workspace,
109
} from "vscode";
1110
import * as CodeQLProtocol from "../../../src/debugger/debug-protocol";
12-
import { DebuggerCommands } from "../../../src/common/commands";
13-
import { CommandManager } from "../../../src/packages/commands";
1411
import { DisposableObject } from "../../../src/pure/disposable-object";
1512
import { QueryResultType } from "../../../src/pure/legacy-messages";
1613
import { CoreCompletedQuery } from "../../../src/queryRunner";
@@ -22,6 +19,7 @@ import {
2219
import { join } from "path";
2320
import { writeFile } from "fs-extra";
2421
import { expect } from "@jest/globals";
22+
import { AppCommandManager } from "../../../src/common/commands";
2523

2624
type Resolver<T> = (value: T) => void;
2725

@@ -190,9 +188,7 @@ export class DebugController
190188
*/
191189
private resolver: Resolver<AnyDebugEvent> | undefined = undefined;
192190

193-
public constructor(
194-
private readonly debuggerCommands: CommandManager<DebuggerCommands>,
195-
) {
191+
public constructor(private readonly appCommands: AppCommandManager) {
196192
super();
197193
this.push(debug.registerDebugAdapterTrackerFactory("codeql", this));
198194
this.push(
@@ -232,7 +228,7 @@ export class DebugController
232228
* Starts a debug session via the "codeQL.debugQuery" copmmand.
233229
*/
234230
public debugQuery(uri: Uri): Promise<void> {
235-
return this.debuggerCommands.execute("codeQL.debugQuery", uri);
231+
return this.appCommands.execute("codeQL.debugQuery", uri);
236232
}
237233

238234
public async startDebugging(
@@ -251,7 +247,7 @@ export class DebugController
251247
}
252248
: {};
253249

254-
return await commands.executeCommand("workbench.action.debug.start", {
250+
return await this.appCommands.execute("workbench.action.debug.start", {
255251
config: fullConfig,
256252
...options,
257253
});
@@ -265,21 +261,19 @@ export class DebugController
265261
}
266262

267263
public async continueDebuggingSelection(): Promise<void> {
268-
return await this.debuggerCommands.execute(
269-
"codeQL.continueDebuggingSelection",
270-
);
264+
return await this.appCommands.execute("codeQL.continueDebuggingSelection");
271265
}
272266

273267
public async stepInto(): Promise<void> {
274-
return await commands.executeCommand("workbench.action.debug.stepInto");
268+
return await this.appCommands.execute("workbench.action.debug.stepInto");
275269
}
276270

277271
public async stepOver(): Promise<void> {
278-
return await commands.executeCommand("workbench.action.debug.stepOver");
272+
return await this.appCommands.execute("workbench.action.debug.stepOver");
279273
}
280274

281275
public async stepOut(): Promise<void> {
282-
return await commands.executeCommand("workbench.action.debug.stepOut");
276+
return await this.appCommands.execute("workbench.action.debug.stepOut");
283277
}
284278

285279
public handleEvent(event: AnyDebugEvent): void {
@@ -411,12 +405,12 @@ export class DebugController
411405
* debug controller is cleaned up.
412406
*/
413407
export async function withDebugController<T>(
414-
debuggerCommands: CommandManager<DebuggerCommands>,
408+
appCommands: AppCommandManager,
415409
op: (controller: DebugController) => Promise<T>,
416410
): Promise<T> {
417411
await workspace.getConfiguration().update("codeQL.canary", true);
418412
try {
419-
const controller = new DebugController(debuggerCommands);
413+
const controller = new DebugController(appCommands);
420414
try {
421415
try {
422416
const result = await op(controller);

extensions/ql-vscode/test/vscode-tests/cli-integration/debugger.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import {
88
getActivatedExtension,
99
} from "../global.helper";
1010
import { describeWithCodeQL } from "../cli";
11-
import { createVSCodeCommandManager } from "../../../src/common/vscode/commands";
12-
import { DebuggerCommands } from "../../../src/common/commands";
1311
import { withDebugController } from "./debug-controller";
1412
import { CodeQLCliServer } from "../../../src/cli";
1513
import { QueryOutputDir } from "../../../src/run-queries-shared";
14+
import { createVSCodeCommandManager } from "../../../src/common/vscode/commands";
15+
import { AllCommands } from "../../../src/common/commands";
1616

17-
jest.setTimeout(2000_000);
17+
jest.setTimeout(20_000);
1818

1919
async function selectForQuickEval(
2020
path: string,
@@ -43,7 +43,7 @@ async function getResultCount(
4343
describeWithCodeQL()("Debugger", () => {
4444
let databaseManager: DatabaseManager;
4545
let cli: CodeQLCliServer;
46-
const debuggerCommands = createVSCodeCommandManager<DebuggerCommands>();
46+
const appCommands = createVSCodeCommandManager<AllCommands>();
4747
const simpleQueryPath = join(__dirname, "data", "simple-query.ql");
4848
const quickEvalQueryPath = join(__dirname, "data", "QuickEvalQuery.ql");
4949
const quickEvalLibPath = join(__dirname, "data", "QuickEvalLib.qll");
@@ -62,7 +62,7 @@ describeWithCodeQL()("Debugger", () => {
6262
});
6363

6464
it("should debug a query and keep the session active", async () => {
65-
await withDebugController(debuggerCommands, async (controller) => {
65+
await withDebugController(appCommands, async (controller) => {
6666
await controller.debugQuery(Uri.file(simpleQueryPath));
6767
await controller.expectLaunched();
6868
await controller.expectSucceeded();
@@ -71,7 +71,7 @@ describeWithCodeQL()("Debugger", () => {
7171
});
7272

7373
it("should run a query and then stop debugging", async () => {
74-
await withDebugController(debuggerCommands, async (controller) => {
74+
await withDebugController(appCommands, async (controller) => {
7575
await controller.startDebugging(
7676
{
7777
query: simpleQueryPath,
@@ -87,7 +87,7 @@ describeWithCodeQL()("Debugger", () => {
8787
});
8888

8989
it("should run a quick evaluation", async () => {
90-
await withDebugController(debuggerCommands, async (controller) => {
90+
await withDebugController(appCommands, async (controller) => {
9191
await selectForQuickEval(quickEvalQueryPath, 18, 5, 18, 22);
9292

9393
// Don't specify a query path, so we'll default to the active document ("QuickEvalQuery.ql")
@@ -105,7 +105,7 @@ describeWithCodeQL()("Debugger", () => {
105105
});
106106

107107
it("should run a quick evaluation on a library without any query context", async () => {
108-
await withDebugController(debuggerCommands, async (controller) => {
108+
await withDebugController(appCommands, async (controller) => {
109109
await selectForQuickEval(quickEvalLibPath, 4, 15, 4, 32);
110110

111111
// Don't specify a query path, so we'll default to the active document ("QuickEvalLib.qll")
@@ -123,7 +123,7 @@ describeWithCodeQL()("Debugger", () => {
123123
});
124124

125125
it("should run a quick evaluation on a library in the context of a specific query", async () => {
126-
await withDebugController(debuggerCommands, async (controller) => {
126+
await withDebugController(appCommands, async (controller) => {
127127
await selectForQuickEval(quickEvalLibPath, 4, 15, 4, 32);
128128

129129
await controller.startDebuggingSelection({

extensions/ql-vscode/test/vscode-tests/cli-integration/queries.test.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { debug, CancellationToken, ExtensionContext, Range, Uri } from "vscode";
1+
import { CancellationToken, ExtensionContext, Range, Uri } from "vscode";
22
import { join, dirname } from "path";
33
import {
44
pathExistsSync,
@@ -24,19 +24,18 @@ import { QueryResultType } from "../../../src/pure/new-messages";
2424
import { createVSCodeCommandManager } from "../../../src/common/vscode/commands";
2525
import {
2626
AllCommands,
27-
DebuggerCommands,
27+
AppCommandManager,
2828
QueryServerCommands,
2929
} from "../../../src/common/commands";
3030
import { ProgressCallback } from "../../../src/progress";
31-
import { CommandManager } from "../../../src/packages/commands";
3231
import { withDebugController } from "./debug-controller";
3332

34-
type DebugMode = "localQueries" | "launch";
33+
type DebugMode = "localQueries" | "debug";
3534

3635
async function compileAndRunQuery(
3736
mode: DebugMode,
37+
appCommands: AppCommandManager,
3838
localQueries: LocalQueries,
39-
debuggerCommands: CommandManager<DebuggerCommands>,
4039
quickEval: boolean,
4140
queryUri: Uri,
4241
progress: ProgressCallback,
@@ -55,14 +54,17 @@ async function compileAndRunQuery(
5554
range,
5655
);
5756

58-
case "launch":
59-
return await withDebugController(debuggerCommands, async (controller) => {
60-
await controller.debugQuery(queryUri);
57+
case "debug":
58+
return await withDebugController(appCommands, async (controller) => {
59+
await controller.startDebugging(
60+
{
61+
query: queryUri.fsPath,
62+
},
63+
true,
64+
);
6165
await controller.expectLaunched();
6266
const succeeded = await controller.expectSucceeded();
63-
await controller.expectStopped();
64-
expect(debug.activeDebugSession?.name).not.toBeUndefined();
65-
await debug.stopDebugging();
67+
await controller.expectExited();
6668
await controller.expectTerminated();
6769
await controller.expectSessionClosed();
6870

@@ -71,9 +73,9 @@ async function compileAndRunQuery(
7173
}
7274
}
7375

74-
jest.setTimeout(2000_000);
76+
jest.setTimeout(20_000);
7577

76-
const MODES: DebugMode[] = ["localQueries", "launch"];
78+
const MODES: DebugMode[] = ["localQueries", "debug"];
7779

7880
/**
7981
* Integration tests for queries
@@ -90,7 +92,6 @@ describeWithCodeQL()("Queries", () => {
9092
const appCommandManager = createVSCodeCommandManager<AllCommands>();
9193
const queryServerCommandManager =
9294
createVSCodeCommandManager<QueryServerCommands>();
93-
const debuggerCommands = createVSCodeCommandManager<DebuggerCommands>();
9495

9596
let qlpackFile: string;
9697
let qlpackLockFile: string;
@@ -174,8 +175,8 @@ describeWithCodeQL()("Queries", () => {
174175
async function runQueryWithExtensions() {
175176
const result = await compileAndRunQuery(
176177
mode,
178+
appCommandManager,
177179
localQueries,
178-
debuggerCommands,
179180
false,
180181
Uri.file(queryUsingExtensionPath),
181182
progress,
@@ -208,8 +209,8 @@ describeWithCodeQL()("Queries", () => {
208209
const queryPath = join(__dirname, "data", "simple-query.ql");
209210
const result = await compileAndRunQuery(
210211
mode,
212+
appCommandManager,
211213
localQueries,
212-
debuggerCommands,
213214
false,
214215
Uri.file(queryPath),
215216
progress,
@@ -228,8 +229,8 @@ describeWithCodeQL()("Queries", () => {
228229
const queryPath = join(__dirname, "data", "simple-query.ql");
229230
const result = await compileAndRunQuery(
230231
mode,
232+
appCommandManager,
231233
localQueries,
232-
debuggerCommands,
233234
false,
234235
Uri.file(queryPath),
235236
progress,

0 commit comments

Comments
 (0)