Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions extensions/ql-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,18 @@
"command": "codeQL.viewCfgContextEditor",
"title": "CodeQL: View CFG"
},
{
"command": "codeQL.viewDfg",
"title": "CodeQL: View DFG"
},
{
"command": "codeQL.viewDfgContextExplorer",
"title": "CodeQL: View DFG"
},
{
"command": "codeQL.viewDfgContextEditor",
"title": "CodeQL: View DFG"
},
{
"command": "codeQL.upgradeCurrentDatabase",
"title": "CodeQL: Upgrade Current Database"
Expand Down Expand Up @@ -1402,6 +1414,11 @@
"group": "9_qlCommands",
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
},
{
"command": "codeQL.viewDfgContextExplorer",
"group": "9_qlCommands",
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
},
{
"command": "codeQL.runQueries",
"group": "9_qlCommands",
Expand Down Expand Up @@ -1615,6 +1632,18 @@
"command": "codeQL.viewCfgContextEditor",
"when": "false"
},
{
"command": "codeQL.viewDfg",
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
},
{
"command": "codeQL.viewDfgContextExplorer",
"when": "false"
},
{
"command": "codeQL.viewDfgContextEditor",
"when": "false"
},
{
"command": "codeQL.openModelEditor"
},
Expand Down Expand Up @@ -1907,6 +1936,10 @@
"command": "codeQL.viewCfgContextEditor",
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
},
{
"command": "codeQL.viewDfgContextEditor",
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
},
{
"command": "codeQL.quickEvalContextEditor",
"when": "editorLangId == ql && debugState == inactive"
Expand Down
3 changes: 3 additions & 0 deletions extensions/ql-vscode/src/common/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,9 @@ export type AstCfgCommands = {
"codeQL.viewCfg": () => Promise<void>;
"codeQL.viewCfgContextExplorer": () => Promise<void>;
"codeQL.viewCfgContextEditor": () => Promise<void>;
"codeQL.viewDfg": () => Promise<void>;
"codeQL.viewDfgContextExplorer": () => Promise<void>;
"codeQL.viewDfgContextEditor": () => Promise<void>;
};

export type AstViewerCommands = {
Expand Down
17 changes: 15 additions & 2 deletions extensions/ql-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ import {
createLanguageClient,
getQueryEditorCommands,
install,
KeyType,
TemplatePrintAstProvider,
TemplatePrintCfgProvider,
TemplatePrintGraphProvider,
TemplateQueryDefinitionProvider,
TemplateQueryReferenceProvider,
} from "./language-support";
Expand Down Expand Up @@ -1075,7 +1076,18 @@ async function activateWithInstalledDistribution(
dbm,
contextualQueryStorageDir,
);
const cfgTemplateProvider = new TemplatePrintCfgProvider(cliServer, dbm);
const cfgTemplateProvider = new TemplatePrintGraphProvider(
cliServer,
dbm,
KeyType.PrintCfgQuery,
"CFG",
);
const dfgTemplateProvider = new TemplatePrintGraphProvider(
cliServer,
dbm,
KeyType.PrintDfgQuery,
"DFG",
);

ctx.subscriptions.push(astViewer);

Expand Down Expand Up @@ -1111,6 +1123,7 @@ async function activateWithInstalledDistribution(
astViewer,
astTemplateProvider,
cfgTemplateProvider,
dfgTemplateProvider,
}),
...astViewer.getCommands(),
...getPackagingCommands({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@
import { QuickEvalType } from "../../local-queries";
import type {
TemplatePrintAstProvider,
TemplatePrintCfgProvider,
TemplatePrintGraphProvider,
} from "../contextual/template-provider";

type AstCfgOptions = {
localQueries: LocalQueries;
astViewer: AstViewer;
astTemplateProvider: TemplatePrintAstProvider;
cfgTemplateProvider: TemplatePrintCfgProvider;
cfgTemplateProvider: TemplatePrintGraphProvider;
dfgTemplateProvider: TemplatePrintGraphProvider;
};

export function getAstCfgCommands({
localQueries,
astViewer,
astTemplateProvider,
cfgTemplateProvider,
dfgTemplateProvider,
}: AstCfgOptions): AstCfgCommands {
const viewAst = async (selectedFile: Uri) =>
withProgress(
Expand All @@ -41,35 +43,49 @@
},
);

const viewCfg = async () =>
withProgress(
async (progress, token) => {
const editor = window.activeTextEditor;
const res = !editor
? undefined
: await cfgTemplateProvider.provideCfgUri(
editor.document,
editor.selection.active.line + 1,
editor.selection.active.character + 1,
const viewGraph = (
provider: TemplatePrintGraphProvider,
title: string,
) => {
Comment on lines +46 to +49

Check failure

Code scanning / ESLint

Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting. Error

Replace ⏎····provider:·TemplatePrintGraphProvider,⏎····title:·string,⏎·· with provider:·TemplatePrintGraphProvider,·title:·string
return async () =>
withProgress(
async (progress, token) => {
const editor = window.activeTextEditor;
const res = !editor
? undefined
: await provider.provideGraphUri(
editor.document,
editor.selection.active.line + 1,
editor.selection.active.character + 1,
);
if (res) {
await localQueries.compileAndRunQuery(
QuickEvalType.None,
res[0],
progress,
token,
undefined,
false,
undefined,
res[1],
);
if (res) {
await localQueries.compileAndRunQuery(
QuickEvalType.None,
res[0],
progress,
token,
undefined,
false,
undefined,
res[1],
);
}
},
{
title: "Calculating Control Flow Graph",
cancellable: true,
},
);
}
},
{
title,
cancellable: true,
},
);
};

const viewCfg = viewGraph(
cfgTemplateProvider,
"Calculating Control Flow Graph",
);
const viewDfg = viewGraph(
dfgTemplateProvider,
"Calculating Data Flow Graph",
);
Comment on lines +85 to +88

Check failure

Code scanning / ESLint

Ensure code is properly formatted, use insertion, deletion, or replacement to obtain desired formatting. Error

Replace ⏎····dfgTemplateProvider,⏎····"Calculating·Data·Flow·Graph",⏎·· with dfgTemplateProvider,·"Calculating·Data·Flow·Graph"

return {
"codeQL.viewAst": viewAst,
Expand All @@ -78,5 +94,8 @@
"codeQL.viewCfg": viewCfg,
"codeQL.viewCfgContextExplorer": viewCfg,
"codeQL.viewCfgContextEditor": viewCfg,
"codeQL.viewDfg": viewDfg,
"codeQL.viewDfgContextExplorer": viewDfg,
"codeQL.viewDfgContextEditor": viewDfg,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export enum KeyType {
ReferenceQuery = "ReferenceQuery",
PrintAstQuery = "PrintAstQuery",
PrintCfgQuery = "PrintCfgQuery",
PrintDfgQuery = "PrintDfgQuery",
}

export function tagOfKeyType(keyType: KeyType): string {
Expand All @@ -15,6 +16,8 @@ export function tagOfKeyType(keyType: KeyType): string {
return "ide-contextual-queries/print-ast";
case KeyType.PrintCfgQuery:
return "ide-contextual-queries/print-cfg";
case KeyType.PrintDfgQuery:
return "ide-contextual-queries/print-dfg";
}
}

Expand All @@ -28,6 +31,8 @@ export function nameOfKeyType(keyType: KeyType): string {
return "print AST";
case KeyType.PrintCfgQuery:
return "print CFG";
case KeyType.PrintDfgQuery:
return "print DFG";
}
}

Expand All @@ -38,6 +43,7 @@ export function kindOfKeyType(keyType: KeyType): string {
return "definitions";
case KeyType.PrintAstQuery:
case KeyType.PrintCfgQuery:
case KeyType.PrintDfgQuery:
return "graph";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,10 @@ export class TemplatePrintAstProvider {
}

/**
* Run templated CodeQL queries to produce CFG information for
* source-language files.
* Run templated CodeQL queries to produce graph information (e.g. CFG or DFG)
* for source-language files.
*/
export class TemplatePrintCfgProvider {
export class TemplatePrintGraphProvider {
private cache: CachedOperation<
[number, number],
[Uri, Record<string, string>]
Expand All @@ -294,11 +294,13 @@ export class TemplatePrintCfgProvider {
constructor(
private cli: CodeQLCliServer,
private dbm: DatabaseManager,
private keyType: KeyType,
private displayName: string,
) {
this.cache = new CachedOperation(this.getCfgUri.bind(this));
this.cache = new CachedOperation(this.getGraphUri.bind(this));
}

async provideCfgUri(
async provideGraphUri(
document: TextDocument,
line: number,
character: number,
Expand All @@ -309,22 +311,22 @@ export class TemplatePrintCfgProvider {
line,
character,
)
: await this.getCfgUri(document.uri.toString(), line, character);
: await this.getGraphUri(document.uri.toString(), line, character);
}

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

private async getCfgUri(
private async getGraphUri(
uriString: string,
line: number,
character: number,
): Promise<[Uri, Record<string, string>]> {
const uri = Uri.parse(uriString, true);
if (uri.scheme !== zipArchiveScheme) {
throw new Error(
"CFG Viewing is only available for databases with zipped source archives.",
`${this.displayName} Viewing is only available for databases with zipped source archives.`,
);
}

Expand All @@ -345,16 +347,16 @@ export class TemplatePrintCfgProvider {
const queries = await resolveContextualQueries(
this.cli,
qlpack,
KeyType.PrintCfgQuery,
this.keyType,
);
if (queries.length > 1) {
throw new Error(
`Found multiple Print CFG queries. Can't continue. Make sure there is exacly one query with the tag ${KeyType.PrintCfgQuery}`,
`Found multiple Print ${this.displayName} queries. Can't continue. Make sure there is exacly one query with the tag ${this.keyType}`,
);
}
if (queries.length === 0) {
throw new Error(
`Did not find any Print CFG queries. Can't continue. Make sure there is exacly one query with the tag ${KeyType.PrintCfgQuery}`,
`Did not find any Print ${this.displayName} queries. Can't continue. Make sure there is exacly one query with the tag ${this.keyType}`,
);
Comment on lines +359 to 360
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue here as above: the message uses tag ${this.keyType} (enum value) rather than the actual tag string used for lookup. Using tagOfKeyType(this.keyType) would make the error actionable, and "exacly" should be corrected to "exactly".

This issue also appears on line 354 of the same file.

Copilot uses AI. Check for mistakes.
}

Expand Down
Loading