Merge pull request #2196 from github/koesie10/ast-cfg-typed-commands

Convert AST and CFG commands to typed commands
This commit is contained in:
Koen Vlaswinkel
2023-03-22 13:32:34 +01:00
committed by GitHub
3 changed files with 132 additions and 199 deletions

View File

@@ -0,0 +1,90 @@
import { Uri, window } from "vscode";
import { withProgress } from "./commandRunner";
import { AstViewer } from "./astViewer";
import {
TemplatePrintAstProvider,
TemplatePrintCfgProvider,
} from "./contextual/templateProvider";
import { compileAndRunQuery } from "./local-queries";
import { QueryRunner } from "./queryRunner";
import { QueryHistoryManager } from "./query-history/query-history-manager";
import { DatabaseUI } from "./local-databases-ui";
import { ResultsView } from "./interface";
import { AstCfgCommands } from "./common/commands";
type AstCfgOptions = {
queryRunner: QueryRunner;
queryHistoryManager: QueryHistoryManager;
databaseUI: DatabaseUI;
localQueryResultsView: ResultsView;
queryStorageDir: string;
astViewer: AstViewer;
astTemplateProvider: TemplatePrintAstProvider;
cfgTemplateProvider: TemplatePrintCfgProvider;
};
export function getAstCfgCommands({
queryRunner,
queryHistoryManager,
databaseUI,
localQueryResultsView,
queryStorageDir,
astViewer,
astTemplateProvider,
cfgTemplateProvider,
}: AstCfgOptions): AstCfgCommands {
const viewAst = async (selectedFile: Uri) =>
withProgress(
async (progress, token) => {
const ast = await astTemplateProvider.provideAst(
progress,
token,
selectedFile ?? window.activeTextEditor?.document.uri,
);
if (ast) {
astViewer.updateRoots(await ast.getRoots(), ast.db, ast.fileName);
}
},
{
cancellable: true,
title: "Calculate AST",
},
);
const viewCfg = async () =>
withProgress(
async (progress, token) => {
const res = await cfgTemplateProvider.provideCfgUri(
window.activeTextEditor?.document,
);
if (res) {
await compileAndRunQuery(
queryRunner,
queryHistoryManager,
databaseUI,
localQueryResultsView,
queryStorageDir,
false,
res[0],
progress,
token,
undefined,
);
}
},
{
title: "Calculating Control Flow Graph",
cancellable: true,
},
);
return {
"codeQL.viewAst": viewAst,
"codeQL.viewAstContextExplorer": viewAst,
"codeQL.viewAstContextEditor": viewAst,
"codeQL.viewCfg": viewCfg,
"codeQL.viewCfgContextExplorer": viewCfg,
"codeQL.viewCfgContextEditor": viewCfg,
};
}

View File

@@ -167,6 +167,15 @@ export type DatabasePanelCommands = {
"codeQLVariantAnalysisRepositories.removeItemContextMenu": SingleSelectionCommandFunction<DbTreeViewItem>;
};
export type AstCfgCommands = {
"codeQL.viewAst": (selectedFile: Uri) => Promise<void>;
"codeQL.viewAstContextExplorer": (selectedFile: Uri) => Promise<void>;
"codeQL.viewAstContextEditor": (selectedFile: Uri) => Promise<void>;
"codeQL.viewCfg": () => Promise<void>;
"codeQL.viewCfgContextExplorer": () => Promise<void>;
"codeQL.viewCfgContextEditor": () => Promise<void>;
};
export type PackagingCommands = {
"codeQL.installPackDependencies": () => Promise<void>;
"codeQL.downloadPacks": () => Promise<void>;
@@ -181,6 +190,7 @@ export type AllCommands = BaseCommands &
LocalDatabasesCommands &
VariantAnalysisCommands &
DatabasePanelCommands &
AstCfgCommands &
PackagingCommands &
EvalLogViewerCommands;

View File

@@ -89,12 +89,7 @@ import { QLTestAdapterFactory } from "./test-adapter";
import { TestUIService } from "./test-ui";
import { CompareView } from "./compare/compare-view";
import { initializeTelemetry } from "./telemetry";
import {
commandRunner,
commandRunnerWithProgress,
ProgressCallback,
withProgress,
} from "./commandRunner";
import { commandRunner, ProgressCallback, withProgress } from "./commandRunner";
import { CodeQlStatusBarHandler } from "./status-bar";
import { getPackagingCommands } from "./packaging";
import { HistoryItemLabelProvider } from "./query-history/history-item-label-provider";
@@ -122,10 +117,10 @@ import {
QueryServerCommands,
} from "./common/commands";
import {
compileAndRunQuery,
getLocalQueryCommands,
showResultsForCompletedQuery,
} from "./local-queries";
import { getAstCfgCommands } from "./ast-cfg-commands";
/**
* extension.ts
@@ -668,6 +663,15 @@ async function activateWithInstalledDistribution(
);
const queryStorageDir = join(ctx.globalStorageUri.fsPath, "queries");
await ensureDir(queryStorageDir);
// Store contextual queries in a temporary folder so that they are removed
// when the application closes. There is no need for the user to interact with them.
const contextualQueryStorageDir = join(
tmpDir.name,
"contextual-query-storage",
);
await ensureDir(contextualQueryStorageDir);
const labelProvider = new HistoryItemLabelProvider(
queryHistoryConfigurationListener,
);
@@ -804,6 +808,17 @@ async function activateWithInstalledDistribution(
ctx.subscriptions.push(testUIService);
}
const astViewer = new AstViewer();
const astTemplateProvider = new TemplatePrintAstProvider(
cliServer,
qs,
dbm,
contextualQueryStorageDir,
);
const cfgTemplateProvider = new TemplatePrintCfgProvider(cliServer, dbm);
ctx.subscriptions.push(astViewer);
void extLogger.log("Registering top-level command palette commands.");
const allCommands: AllCommands = {
@@ -812,6 +827,16 @@ async function activateWithInstalledDistribution(
...variantAnalysisManager.getCommands(),
...databaseUI.getCommands(),
...dbModule.getCommands(),
...getAstCfgCommands({
queryRunner: qs,
queryHistoryManager: qhm,
databaseUI,
localQueryResultsView,
queryStorageDir,
astViewer,
astTemplateProvider,
cfgTemplateProvider,
}),
...getPackagingCommands({
cliServer,
}),
@@ -924,13 +949,6 @@ async function activateWithInstalledDistribution(
// Jump-to-definition and find-references
void extLogger.log("Registering jump-to-definition handlers.");
// Store contextual queries in a temporary folder so that they are removed
// when the application closes. There is no need for the user to interact with them.
const contextualQueryStorageDir = join(
tmpDir.name,
"contextual-query-storage",
);
await ensureDir(contextualQueryStorageDir);
languages.registerDefinitionProvider(
{ scheme: zipArchiveScheme },
new TemplateQueryDefinitionProvider(
@@ -951,174 +969,6 @@ async function activateWithInstalledDistribution(
),
);
const astViewer = new AstViewer();
const printAstTemplateProvider = new TemplatePrintAstProvider(
cliServer,
qs,
dbm,
contextualQueryStorageDir,
);
const cfgTemplateProvider = new TemplatePrintCfgProvider(cliServer, dbm);
ctx.subscriptions.push(astViewer);
ctx.subscriptions.push(
commandRunnerWithProgress(
"codeQL.viewAst",
async (
progress: ProgressCallback,
token: CancellationToken,
selectedFile: Uri,
) =>
await viewAst(
astViewer,
printAstTemplateProvider,
progress,
token,
selectedFile,
),
{
cancellable: true,
title: "Calculate AST",
},
),
);
// Since we are tracking extension usage through commands, this command mirrors the "codeQL.viewAst" command
ctx.subscriptions.push(
commandRunnerWithProgress(
"codeQL.viewAstContextExplorer",
async (
progress: ProgressCallback,
token: CancellationToken,
selectedFile: Uri,
) =>
await viewAst(
astViewer,
printAstTemplateProvider,
progress,
token,
selectedFile,
),
{
cancellable: true,
title: "Calculate AST",
},
),
);
// Since we are tracking extension usage through commands, this command mirrors the "codeQL.viewAst" command
ctx.subscriptions.push(
commandRunnerWithProgress(
"codeQL.viewAstContextEditor",
async (
progress: ProgressCallback,
token: CancellationToken,
selectedFile: Uri,
) =>
await viewAst(
astViewer,
printAstTemplateProvider,
progress,
token,
selectedFile,
),
{
cancellable: true,
title: "Calculate AST",
},
),
);
ctx.subscriptions.push(
commandRunnerWithProgress(
"codeQL.viewCfg",
async (progress: ProgressCallback, token: CancellationToken) => {
const res = await cfgTemplateProvider.provideCfgUri(
window.activeTextEditor?.document,
);
if (res) {
await compileAndRunQuery(
qs,
qhm,
databaseUI,
localQueryResultsView,
queryStorageDir,
false,
res[0],
progress,
token,
undefined,
);
}
},
{
title: "Calculating Control Flow Graph",
cancellable: true,
},
),
);
// Since we are tracking extension usage through commands, this command mirrors the "codeQL.viewCfg" command
ctx.subscriptions.push(
commandRunnerWithProgress(
"codeQL.viewCfgContextExplorer",
async (progress: ProgressCallback, token: CancellationToken) => {
const res = await cfgTemplateProvider.provideCfgUri(
window.activeTextEditor?.document,
);
if (res) {
await compileAndRunQuery(
qs,
qhm,
databaseUI,
localQueryResultsView,
queryStorageDir,
false,
res[0],
progress,
token,
undefined,
);
}
},
{
title: "Calculating Control Flow Graph",
cancellable: true,
},
),
);
// Since we are tracking extension usage through commands, this command mirrors the "codeQL.viewCfg" command
ctx.subscriptions.push(
commandRunnerWithProgress(
"codeQL.viewCfgContextEditor",
async (progress: ProgressCallback, token: CancellationToken) => {
const res = await cfgTemplateProvider.provideCfgUri(
window.activeTextEditor?.document,
);
if (res) {
await compileAndRunQuery(
qs,
qhm,
databaseUI,
localQueryResultsView,
queryStorageDir,
false,
res[0],
progress,
token,
undefined,
);
}
},
{
title: "Calculating Control Flow Graph",
cancellable: true,
},
),
);
const mockServer = new VSCodeMockGitHubApiServer(ctx);
ctx.subscriptions.push(mockServer);
ctx.subscriptions.push(
@@ -1234,23 +1084,6 @@ async function openReferencedFile(
}
}
async function viewAst(
astViewer: AstViewer,
printAstTemplateProvider: TemplatePrintAstProvider,
progress: ProgressCallback,
token: CancellationToken,
selectedFile: Uri,
): Promise<void> {
const ast = await printAstTemplateProvider.provideAst(
progress,
token,
selectedFile ?? window.activeTextEditor?.document.uri,
);
if (ast) {
astViewer.updateRoots(await ast.getRoots(), ast.db, ast.fileName);
}
}
function addUnhandledRejectionListener() {
const handler = (error: unknown) => {
// This listener will be triggered for errors from other extensions as