Skip to content

Commit 69a8dc4

Browse files
committed
Add 'View DFG' command, similar to 'View CFG'
1 parent 39140f2 commit 69a8dc4

File tree

6 files changed

+119
-43
lines changed

6 files changed

+119
-43
lines changed

extensions/ql-vscode/package.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,18 @@
807807
"command": "codeQL.viewCfgContextEditor",
808808
"title": "CodeQL: View CFG"
809809
},
810+
{
811+
"command": "codeQL.viewDfg",
812+
"title": "CodeQL: View DFG"
813+
},
814+
{
815+
"command": "codeQL.viewDfgContextExplorer",
816+
"title": "CodeQL: View DFG"
817+
},
818+
{
819+
"command": "codeQL.viewDfgContextEditor",
820+
"title": "CodeQL: View DFG"
821+
},
810822
{
811823
"command": "codeQL.upgradeCurrentDatabase",
812824
"title": "CodeQL: Upgrade Current Database"
@@ -1402,6 +1414,11 @@
14021414
"group": "9_qlCommands",
14031415
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
14041416
},
1417+
{
1418+
"command": "codeQL.viewDfgContextExplorer",
1419+
"group": "9_qlCommands",
1420+
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
1421+
},
14051422
{
14061423
"command": "codeQL.runQueries",
14071424
"group": "9_qlCommands",
@@ -1615,6 +1632,18 @@
16151632
"command": "codeQL.viewCfgContextEditor",
16161633
"when": "false"
16171634
},
1635+
{
1636+
"command": "codeQL.viewDfg",
1637+
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
1638+
},
1639+
{
1640+
"command": "codeQL.viewDfgContextExplorer",
1641+
"when": "false"
1642+
},
1643+
{
1644+
"command": "codeQL.viewDfgContextEditor",
1645+
"when": "false"
1646+
},
16181647
{
16191648
"command": "codeQL.openModelEditor"
16201649
},
@@ -1907,6 +1936,10 @@
19071936
"command": "codeQL.viewCfgContextEditor",
19081937
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
19091938
},
1939+
{
1940+
"command": "codeQL.viewDfgContextEditor",
1941+
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
1942+
},
19101943
{
19111944
"command": "codeQL.quickEvalContextEditor",
19121945
"when": "editorLangId == ql && debugState == inactive"

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,9 @@ export type AstCfgCommands = {
318318
"codeQL.viewCfg": () => Promise<void>;
319319
"codeQL.viewCfgContextExplorer": () => Promise<void>;
320320
"codeQL.viewCfgContextEditor": () => Promise<void>;
321+
"codeQL.viewDfg": () => Promise<void>;
322+
"codeQL.viewDfgContextExplorer": () => Promise<void>;
323+
"codeQL.viewDfgContextEditor": () => Promise<void>;
321324
};
322325

323326
export type AstViewerCommands = {

extensions/ql-vscode/src/extension.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ import {
4040
createLanguageClient,
4141
getQueryEditorCommands,
4242
install,
43+
KeyType,
4344
TemplatePrintAstProvider,
44-
TemplatePrintCfgProvider,
45+
TemplatePrintGraphProvider,
4546
TemplateQueryDefinitionProvider,
4647
TemplateQueryReferenceProvider,
4748
} from "./language-support";
@@ -1075,7 +1076,18 @@ async function activateWithInstalledDistribution(
10751076
dbm,
10761077
contextualQueryStorageDir,
10771078
);
1078-
const cfgTemplateProvider = new TemplatePrintCfgProvider(cliServer, dbm);
1079+
const cfgTemplateProvider = new TemplatePrintGraphProvider(
1080+
cliServer,
1081+
dbm,
1082+
KeyType.PrintCfgQuery,
1083+
"CFG",
1084+
);
1085+
const dfgTemplateProvider = new TemplatePrintGraphProvider(
1086+
cliServer,
1087+
dbm,
1088+
KeyType.PrintDfgQuery,
1089+
"DFG",
1090+
);
10791091

10801092
ctx.subscriptions.push(astViewer);
10811093

@@ -1111,6 +1123,7 @@ async function activateWithInstalledDistribution(
11111123
astViewer,
11121124
astTemplateProvider,
11131125
cfgTemplateProvider,
1126+
dfgTemplateProvider,
11141127
}),
11151128
...astViewer.getCommands(),
11161129
...getPackagingCommands({

extensions/ql-vscode/src/language-support/ast-viewer/ast-cfg-commands.ts

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,23 @@ import type { LocalQueries } from "../../local-queries";
77
import { QuickEvalType } from "../../local-queries";
88
import type {
99
TemplatePrintAstProvider,
10-
TemplatePrintCfgProvider,
10+
TemplatePrintGraphProvider,
1111
} from "../contextual/template-provider";
1212

1313
type AstCfgOptions = {
1414
localQueries: LocalQueries;
1515
astViewer: AstViewer;
1616
astTemplateProvider: TemplatePrintAstProvider;
17-
cfgTemplateProvider: TemplatePrintCfgProvider;
17+
cfgTemplateProvider: TemplatePrintGraphProvider;
18+
dfgTemplateProvider: TemplatePrintGraphProvider;
1819
};
1920

2021
export function getAstCfgCommands({
2122
localQueries,
2223
astViewer,
2324
astTemplateProvider,
2425
cfgTemplateProvider,
26+
dfgTemplateProvider,
2527
}: AstCfgOptions): AstCfgCommands {
2628
const viewAst = async (selectedFile: Uri) =>
2729
withProgress(
@@ -41,35 +43,49 @@ export function getAstCfgCommands({
4143
},
4244
);
4345

44-
const viewCfg = async () =>
45-
withProgress(
46-
async (progress, token) => {
47-
const editor = window.activeTextEditor;
48-
const res = !editor
49-
? undefined
50-
: await cfgTemplateProvider.provideCfgUri(
51-
editor.document,
52-
editor.selection.active.line + 1,
53-
editor.selection.active.character + 1,
46+
const viewGraph = (
47+
provider: TemplatePrintGraphProvider,
48+
title: string,
49+
) => {
50+
return async () =>
51+
withProgress(
52+
async (progress, token) => {
53+
const editor = window.activeTextEditor;
54+
const res = !editor
55+
? undefined
56+
: await provider.provideGraphUri(
57+
editor.document,
58+
editor.selection.active.line + 1,
59+
editor.selection.active.character + 1,
60+
);
61+
if (res) {
62+
await localQueries.compileAndRunQuery(
63+
QuickEvalType.None,
64+
res[0],
65+
progress,
66+
token,
67+
undefined,
68+
false,
69+
undefined,
70+
res[1],
5471
);
55-
if (res) {
56-
await localQueries.compileAndRunQuery(
57-
QuickEvalType.None,
58-
res[0],
59-
progress,
60-
token,
61-
undefined,
62-
false,
63-
undefined,
64-
res[1],
65-
);
66-
}
67-
},
68-
{
69-
title: "Calculating Control Flow Graph",
70-
cancellable: true,
71-
},
72-
);
72+
}
73+
},
74+
{
75+
title,
76+
cancellable: true,
77+
},
78+
);
79+
};
80+
81+
const viewCfg = viewGraph(
82+
cfgTemplateProvider,
83+
"Calculating Control Flow Graph",
84+
);
85+
const viewDfg = viewGraph(
86+
dfgTemplateProvider,
87+
"Calculating Data Flow Graph",
88+
);
7389

7490
return {
7591
"codeQL.viewAst": viewAst,
@@ -78,5 +94,8 @@ export function getAstCfgCommands({
7894
"codeQL.viewCfg": viewCfg,
7995
"codeQL.viewCfgContextExplorer": viewCfg,
8096
"codeQL.viewCfgContextEditor": viewCfg,
97+
"codeQL.viewDfg": viewDfg,
98+
"codeQL.viewDfgContextExplorer": viewDfg,
99+
"codeQL.viewDfgContextEditor": viewDfg,
81100
};
82101
}

extensions/ql-vscode/src/language-support/contextual/key-type.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export enum KeyType {
33
ReferenceQuery = "ReferenceQuery",
44
PrintAstQuery = "PrintAstQuery",
55
PrintCfgQuery = "PrintCfgQuery",
6+
PrintDfgQuery = "PrintDfgQuery",
67
}
78

89
export function tagOfKeyType(keyType: KeyType): string {
@@ -15,6 +16,8 @@ export function tagOfKeyType(keyType: KeyType): string {
1516
return "ide-contextual-queries/print-ast";
1617
case KeyType.PrintCfgQuery:
1718
return "ide-contextual-queries/print-cfg";
19+
case KeyType.PrintDfgQuery:
20+
return "ide-contextual-queries/print-dfg";
1821
}
1922
}
2023

@@ -28,6 +31,8 @@ export function nameOfKeyType(keyType: KeyType): string {
2831
return "print AST";
2932
case KeyType.PrintCfgQuery:
3033
return "print CFG";
34+
case KeyType.PrintDfgQuery:
35+
return "print DFG";
3136
}
3237
}
3338

@@ -38,6 +43,7 @@ export function kindOfKeyType(keyType: KeyType): string {
3843
return "definitions";
3944
case KeyType.PrintAstQuery:
4045
case KeyType.PrintCfgQuery:
46+
case KeyType.PrintDfgQuery:
4147
return "graph";
4248
}
4349
}

extensions/ql-vscode/src/language-support/contextual/template-provider.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,10 @@ export class TemplatePrintAstProvider {
282282
}
283283

284284
/**
285-
* Run templated CodeQL queries to produce CFG information for
286-
* source-language files.
285+
* Run templated CodeQL queries to produce graph information (e.g. CFG or DFG)
286+
* for source-language files.
287287
*/
288-
export class TemplatePrintCfgProvider {
288+
export class TemplatePrintGraphProvider {
289289
private cache: CachedOperation<
290290
[number, number],
291291
[Uri, Record<string, string>]
@@ -294,11 +294,13 @@ export class TemplatePrintCfgProvider {
294294
constructor(
295295
private cli: CodeQLCliServer,
296296
private dbm: DatabaseManager,
297+
private keyType: KeyType,
298+
private displayName: string,
297299
) {
298-
this.cache = new CachedOperation(this.getCfgUri.bind(this));
300+
this.cache = new CachedOperation(this.getGraphUri.bind(this));
299301
}
300302

301-
async provideCfgUri(
303+
async provideGraphUri(
302304
document: TextDocument,
303305
line: number,
304306
character: number,
@@ -309,22 +311,22 @@ export class TemplatePrintCfgProvider {
309311
line,
310312
character,
311313
)
312-
: await this.getCfgUri(document.uri.toString(), line, character);
314+
: await this.getGraphUri(document.uri.toString(), line, character);
313315
}
314316

315317
private shouldUseCache() {
316318
return !(isCanary() && NO_CACHE_AST_VIEWER.getValue<boolean>());
317319
}
318320

319-
private async getCfgUri(
321+
private async getGraphUri(
320322
uriString: string,
321323
line: number,
322324
character: number,
323325
): Promise<[Uri, Record<string, string>]> {
324326
const uri = Uri.parse(uriString, true);
325327
if (uri.scheme !== zipArchiveScheme) {
326328
throw new Error(
327-
"CFG Viewing is only available for databases with zipped source archives.",
329+
`${this.displayName} Viewing is only available for databases with zipped source archives.`,
328330
);
329331
}
330332

@@ -345,16 +347,16 @@ export class TemplatePrintCfgProvider {
345347
const queries = await resolveContextualQueries(
346348
this.cli,
347349
qlpack,
348-
KeyType.PrintCfgQuery,
350+
this.keyType,
349351
);
350352
if (queries.length > 1) {
351353
throw new Error(
352-
`Found multiple Print CFG queries. Can't continue. Make sure there is exacly one query with the tag ${KeyType.PrintCfgQuery}`,
354+
`Found multiple Print ${this.displayName} queries. Can't continue. Make sure there is exacly one query with the tag ${this.keyType}`,
353355
);
354356
}
355357
if (queries.length === 0) {
356358
throw new Error(
357-
`Did not find any Print CFG queries. Can't continue. Make sure there is exacly one query with the tag ${KeyType.PrintCfgQuery}`,
359+
`Did not find any Print ${this.displayName} queries. Can't continue. Make sure there is exacly one query with the tag ${this.keyType}`,
358360
);
359361
}
360362

0 commit comments

Comments
 (0)