Skip to content

Commit f99f465

Browse files
author
Dave Bartolomeo
committed
Refactor query evaluation code to separate UI concerns
1 parent 1e4672b commit f99f465

16 files changed

Lines changed: 819 additions & 606 deletions

File tree

extensions/ql-vscode/src/common/logging/logger.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ export interface LogOptions {
33
trailingNewline?: boolean;
44
}
55

6-
export interface Logger {
6+
/** Minimal logger interface. */
7+
export interface BaseLogger {
78
/**
89
* Writes the given log message, optionally followed by a newline.
910
* This function is asynchronous and will only resolve once the message is written
@@ -15,7 +16,10 @@ export interface Logger {
1516
* @param options Optional settings.
1617
*/
1718
log(message: string, options?: LogOptions): Promise<void>;
19+
}
1820

21+
/** Full logger interface, including a function to show the log in the UI. */
22+
export interface Logger extends BaseLogger {
1923
/**
2024
* Reveal the logger channel in the UI.
2125
*

extensions/ql-vscode/src/contextual/astBuilder.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { DatabaseItem } from "../local-databases";
44
import { ChildAstItem, AstItem } from "../astViewer";
55
import fileRangeFromURI from "./fileRangeFromURI";
66
import { Uri } from "vscode";
7-
import { QueryWithResults } from "../run-queries-shared";
7+
import { QueryOutputDir } from "../run-queries-shared";
88

99
/**
1010
* A class that wraps a tree of QL results from a query that
@@ -14,12 +14,12 @@ export default class AstBuilder {
1414
private roots: AstItem[] | undefined;
1515
private bqrsPath: string;
1616
constructor(
17-
queryResults: QueryWithResults,
17+
outputDir: QueryOutputDir,
1818
private cli: CodeQLCliServer,
1919
public db: DatabaseItem,
2020
public fileName: Uri,
2121
) {
22-
this.bqrsPath = queryResults.query.resultsPaths.resultsPath;
22+
this.bqrsPath = outputDir.bqrsPath;
2323
}
2424

2525
async getRoots(): Promise<AstItem[]> {

extensions/ql-vscode/src/contextual/locationFinder.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ import {
1919
runContextualQuery,
2020
} from "./queryResolver";
2121
import { CancellationToken, LocationLink, Uri } from "vscode";
22-
import { QueryWithResults } from "../run-queries-shared";
22+
import { QueryOutputDir } from "../run-queries-shared";
2323
import { QueryRunner } from "../queryRunner";
24+
import { QueryResultType } from "../pure/new-messages";
2425

2526
export const SELECT_QUERY_NAME = "#select";
2627
export const TEMPLATE_NAME = "selectedSourceFile";
@@ -78,21 +79,23 @@ export async function getLocationsForUriString(
7879
token,
7980
templates,
8081
);
81-
if (results.successful) {
82-
links.push(...(await getLinksFromResults(results, cli, db, filter)));
82+
if (results.resultType === QueryResultType.SUCCESS) {
83+
links.push(
84+
...(await getLinksFromResults(results.outputDir, cli, db, filter)),
85+
);
8386
}
8487
}
8588
return links;
8689
}
8790

8891
async function getLinksFromResults(
89-
results: QueryWithResults,
92+
outputDir: QueryOutputDir,
9093
cli: CodeQLCliServer,
9194
db: DatabaseItem,
9295
filter: (srcFile: string, destFile: string) => boolean,
9396
): Promise<FullLocationLink[]> {
9497
const localLinks: FullLocationLink[] = [];
95-
const bqrsPath = results.query.resultsPaths.resultsPath;
98+
const bqrsPath = outputDir.bqrsPath;
9699
const info = await cli.bqrsInfo(bqrsPath);
97100
const selectInfo = getResultSetSchema(SELECT_QUERY_NAME, info);
98101
if (isValidSelect(selectInfo)) {

extensions/ql-vscode/src/contextual/queryResolver.ts

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ import {
1313
import { KeyType, kindOfKeyType, nameOfKeyType, tagOfKeyType } from "./keyType";
1414
import { CodeQLCliServer } from "../cli";
1515
import { DatabaseItem } from "../local-databases";
16-
import { extLogger } from "../common";
17-
import { createInitialQueryInfo } from "../run-queries-shared";
18-
import { CancellationToken, Uri } from "vscode";
16+
import { extLogger, TeeLogger } from "../common";
17+
import { CancellationToken } from "vscode";
1918
import { ProgressCallback } from "../progress";
20-
import { QueryRunner } from "../queryRunner";
19+
import { CoreCompletedQuery, QueryRunner } from "../queryRunner";
2120
import { redactableError } from "../pure/errors";
2221
import { QLPACK_FILENAMES } from "../pure/ql";
2322

@@ -169,32 +168,30 @@ export async function runContextualQuery(
169168
progress: ProgressCallback,
170169
token: CancellationToken,
171170
templates: Record<string, string>,
172-
) {
171+
): Promise<CoreCompletedQuery> {
173172
const { packPath, createdTempLockFile } = await resolveContextualQuery(
174173
cli,
175174
query,
176175
);
177-
const initialInfo = await createInitialQueryInfo(
178-
Uri.file(query),
179-
{
180-
name: db.name,
181-
databaseUri: db.databaseUri.toString(),
182-
},
176+
const queryRun = qs.createQueryRun(
177+
db.databaseUri.fsPath,
178+
{ queryPath: query, quickEvalPosition: undefined },
183179
false,
180+
getOnDiskWorkspaceFolders(),
181+
queryStorageDir,
182+
undefined,
183+
templates,
184184
);
185185
void extLogger.log(
186-
`Running contextual query ${query}; results will be stored in ${queryStorageDir}`,
186+
`Running contextual query ${query}; results will be stored in ${queryRun.outputDir}`,
187187
);
188-
const queryResult = await qs.compileAndRunQueryAgainstDatabase(
189-
db,
190-
initialInfo,
191-
queryStorageDir,
188+
const results = await queryRun.evaluate(
192189
progress,
193190
token,
194-
templates,
191+
new TeeLogger(qs.logger, queryRun.outputDir.logPath),
195192
);
196193
if (createdTempLockFile) {
197194
await removeTemporaryLockFile(packPath);
198195
}
199-
return queryResult;
196+
return results;
200197
}

extensions/ql-vscode/src/contextual/templateProvider.ts

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ import {
3232
runContextualQuery,
3333
} from "./queryResolver";
3434
import { isCanary, NO_CACHE_AST_VIEWER } from "../config";
35-
import { QueryWithResults } from "../run-queries-shared";
36-
import { QueryRunner } from "../queryRunner";
35+
import { CoreCompletedQuery, QueryRunner } from "../queryRunner";
3736

3837
/**
3938
* Runs templated CodeQL queries to find definitions in
@@ -155,25 +154,22 @@ export class TemplateQueryReferenceProvider implements ReferenceProvider {
155154
}
156155
}
157156

158-
type QueryWithDb = {
159-
query: QueryWithResults;
160-
dbUri: Uri;
161-
};
162-
163157
/**
164158
* Run templated CodeQL queries to produce AST information for
165159
* source-language files.
166160
*/
167161
export class TemplatePrintAstProvider {
168-
private cache: CachedOperation<QueryWithDb>;
162+
private cache: CachedOperation<CoreCompletedQuery>;
169163

170164
constructor(
171165
private cli: CodeQLCliServer,
172166
private qs: QueryRunner,
173167
private dbm: DatabaseManager,
174168
private queryStorageDir: string,
175169
) {
176-
this.cache = new CachedOperation<QueryWithDb>(this.getAst.bind(this));
170+
this.cache = new CachedOperation<CoreCompletedQuery>(
171+
this.getAst.bind(this),
172+
);
177173
}
178174

179175
async provideAst(
@@ -186,14 +182,14 @@ export class TemplatePrintAstProvider {
186182
"Cannot view the AST. Please select a valid source file inside a CodeQL database.",
187183
);
188184
}
189-
const { query, dbUri } = this.shouldCache()
185+
const completedQuery = this.shouldCache()
190186
? await this.cache.get(fileUri.toString(), progress, token)
191187
: await this.getAst(fileUri.toString(), progress, token);
192188

193189
return new AstBuilder(
194-
query,
190+
completedQuery.outputDir,
195191
this.cli,
196-
this.dbm.findDatabaseItem(dbUri)!,
192+
this.dbm.findDatabaseItem(Uri.file(completedQuery.dbPath))!,
197193
fileUri,
198194
);
199195
}
@@ -206,7 +202,7 @@ export class TemplatePrintAstProvider {
206202
uriString: string,
207203
progress: ProgressCallback,
208204
token: CancellationToken,
209-
): Promise<QueryWithDb> {
205+
): Promise<CoreCompletedQuery> {
210206
const uri = Uri.parse(uriString, true);
211207
if (uri.scheme !== zipArchiveScheme) {
212208
throw new Error(
@@ -242,7 +238,7 @@ export class TemplatePrintAstProvider {
242238
[TEMPLATE_NAME]: zippedArchive.pathWithinSourceArchive,
243239
};
244240

245-
const queryResult = await runContextualQuery(
241+
const results = await runContextualQuery(
246242
query,
247243
db,
248244
this.queryStorageDir,
@@ -252,10 +248,7 @@ export class TemplatePrintAstProvider {
252248
token,
253249
templates,
254250
);
255-
return {
256-
query: queryResult,
257-
dbUri: db.databaseUri,
258-
};
251+
return results;
259252
}
260253
}
261254

extensions/ql-vscode/src/helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ export async function tryGetQueryMetadata(
754754
* Creates a file in the query directory that indicates when this query was created.
755755
* This is important for keeping track of when queries should be removed.
756756
*
757-
* @param queryPath The directory that will containt all files relevant to a query result.
757+
* @param queryPath The directory that will contain all files relevant to a query result.
758758
* It does not need to exist.
759759
*/
760760
export async function createTimestampFile(storagePath: string) {

extensions/ql-vscode/src/legacy-query-server/legacyRunner.ts

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import { CancellationToken } from "vscode";
2+
import { CodeQLCliServer } from "../cli";
23
import { ProgressCallback } from "../progress";
4+
import { Logger } from "../common";
35
import { DatabaseItem } from "../local-databases";
46
import {
57
Dataset,
68
deregisterDatabases,
79
registerDatabases,
810
} from "../pure/legacy-messages";
9-
import { InitialQueryInfo, LocalQueryInfo } from "../query-results";
10-
import { QueryRunner } from "../queryRunner";
11-
import { QueryWithResults } from "../run-queries-shared";
11+
import { CoreQueryResults, CoreQueryTarget, QueryRunner } from "../queryRunner";
12+
import { QueryOutputDir } from "../run-queries-shared";
1213
import { QueryServerClient } from "./queryserver-client";
1314
import {
1415
clearCacheInDatabase,
15-
compileAndRunQueryAgainstDatabase,
16+
compileAndRunQueryAgainstDatabaseCore,
1617
} from "./run-queries";
1718
import { upgradeDatabaseExplicit } from "./upgrades";
1819

@@ -21,10 +22,18 @@ export class LegacyQueryRunner extends QueryRunner {
2122
super();
2223
}
2324

24-
get cliServer() {
25+
get cliServer(): CodeQLCliServer {
2526
return this.qs.cliServer;
2627
}
2728

29+
get customLogDirectory(): string | undefined {
30+
return undefined;
31+
}
32+
33+
get logger(): Logger {
34+
return this.qs.logger;
35+
}
36+
2837
async restartQueryServer(
2938
progress: ProgressCallback,
3039
token: CancellationToken,
@@ -47,25 +56,29 @@ export class LegacyQueryRunner extends QueryRunner {
4756
): Promise<void> {
4857
await clearCacheInDatabase(this.qs, dbItem, progress, token);
4958
}
50-
async compileAndRunQueryAgainstDatabase(
51-
dbItem: DatabaseItem,
52-
initialInfo: InitialQueryInfo,
53-
queryStorageDir: string,
59+
60+
protected async compileAndRunQueryAgainstDatabaseCore(
61+
dbPath: string,
62+
query: CoreQueryTarget,
63+
additionalPacks: string[],
64+
generateEvalLog: boolean,
65+
outputDir: QueryOutputDir,
5466
progress: ProgressCallback,
5567
token: CancellationToken,
56-
templates?: Record<string, string>,
57-
queryInfo?: LocalQueryInfo,
58-
): Promise<QueryWithResults> {
59-
return await compileAndRunQueryAgainstDatabase(
60-
this.qs.cliServer,
68+
templates: Record<string, string> | undefined,
69+
logger: Logger,
70+
): Promise<CoreQueryResults> {
71+
return await compileAndRunQueryAgainstDatabaseCore(
6172
this.qs,
62-
dbItem,
63-
initialInfo,
64-
queryStorageDir,
73+
dbPath,
74+
query,
75+
generateEvalLog,
76+
additionalPacks,
77+
outputDir,
6578
progress,
6679
token,
6780
templates,
68-
queryInfo,
81+
logger,
6982
);
7083
}
7184

0 commit comments

Comments
 (0)