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 type { LocalQueries } from "../../local-queries";
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,43 @@ export function getAstCfgCommands({
},
);

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) => {
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");

return {
"codeQL.viewAst": viewAst,
Expand All @@ -78,5 +88,8 @@ export function getAstCfgCommands({
"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 @@ -20,7 +20,7 @@ import type { DatabaseManager } from "../../databases/local-databases";
import { CachedOperation } from "./cached-operation";
import type { ProgressCallback } from "../../common/vscode/progress";
import { withProgress } from "../../common/vscode/progress";
import { KeyType } from "./key-type";
import { KeyType, tagOfKeyType } from "./key-type";
import type { FullLocationLink } from "./location-finder";
import {
getLocationsForUriString,
Expand Down 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 exactly one query with the tag ${tagOfKeyType(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 exactly one query with the tag ${tagOfKeyType(this.keyType)}`,
);
}

Expand Down