Skip to content

Commit d135507

Browse files
committed
Organize sort state for interpreted results
Rename existing sort state for raw results, and make some state for keeping track of sort state for interpreted results.
1 parent 81a6b23 commit d135507

File tree

7 files changed

+77
-34
lines changed

7 files changed

+77
-34
lines changed

extensions/ql-vscode/src/interface-types.ts

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ export interface DatabaseInfo {
1717
}
1818

1919
/** Arbitrary query metadata */
20-
export interface QueryMetadata {
21-
name?: string,
22-
description?: string,
23-
id?: string,
24-
kind?: string
20+
export interface QueryMetadata {
21+
name?: string,
22+
description?: string,
23+
id?: string,
24+
kind?: string
2525
}
2626

2727
export interface PreviousExecution {
@@ -34,6 +34,7 @@ export interface PreviousExecution {
3434
export interface Interpretation {
3535
sourceLocationPrefix: string;
3636
numTruncatedResults: number;
37+
sortState: InterpretedResultsSortState;
3738
sarif: sarif.Log;
3839
}
3940

@@ -44,7 +45,7 @@ export interface ResultsPaths {
4445

4546
export interface SortedResultSetInfo {
4647
resultsPath: string;
47-
sortState: SortState;
48+
sortState: RawResultsSortState;
4849
}
4950

5051
export type SortedResultsMap = { [resultSet: string]: SortedResultSetInfo };
@@ -84,7 +85,12 @@ export interface NavigatePathMsg {
8485

8586
export type IntoResultsViewMsg = ResultsUpdatingMsg | SetStateMsg | NavigatePathMsg;
8687

87-
export type FromResultsViewMsg = ViewSourceFileMsg | ToggleDiagnostics | ChangeSortMsg | ResultViewLoaded;
88+
export type FromResultsViewMsg =
89+
| ViewSourceFileMsg
90+
| ToggleDiagnostics
91+
| ChangeRawResultsSortMsg
92+
| ChangeInterpretedResultsSortMsg
93+
| ResultViewLoaded;
8894

8995
interface ViewSourceFileMsg {
9096
t: 'viewSourceFile';
@@ -109,13 +115,22 @@ export enum SortDirection {
109115
asc, desc
110116
}
111117

112-
export interface SortState {
118+
export interface RawResultsSortState {
113119
columnIndex: number;
114120
direction: SortDirection;
115121
}
116122

117-
interface ChangeSortMsg {
123+
export interface InterpretedResultsSortState {
124+
sortBy: 'file-position' | 'alert-message';
125+
}
126+
127+
interface ChangeRawResultsSortMsg {
118128
t: 'changeSort';
119129
resultSetName: string;
120-
sortState?: SortState;
130+
sortState?: RawResultsSortState;
131+
}
132+
133+
interface ChangeInterpretedResultsSortMsg {
134+
t: 'changeInterpretedSort';
135+
sortState?: InterpretedResultsSortState;
121136
}

extensions/ql-vscode/src/interface.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { CodeQLCliServer } from './cli';
1010
import { DatabaseItem, DatabaseManager } from './databases';
1111
import { showAndLogErrorMessage } from './helpers';
1212
import { assertNever } from './helpers-pure';
13-
import { FromResultsViewMsg, Interpretation, INTERPRETED_RESULTS_PER_RUN_LIMIT, IntoResultsViewMsg, QueryMetadata, ResultsPaths, SortedResultSetInfo, SortedResultsMap } from './interface-types';
13+
import { FromResultsViewMsg, Interpretation, INTERPRETED_RESULTS_PER_RUN_LIMIT, IntoResultsViewMsg, QueryMetadata, ResultsPaths, SortedResultSetInfo, SortedResultsMap, InterpretedResultsSortState } from './interface-types';
1414
import { Logger } from './logging';
1515
import * as messages from './messages';
1616
import { CompletedQuery, interpretResults } from './query-results';
@@ -190,6 +190,17 @@ export class InterfaceManager extends DisposableObject {
190190
await this.showResults(this._displayedQuery, WebviewReveal.NotForced, true);
191191
break;
192192
}
193+
case 'changeInterpretedSort': {
194+
if (this._displayedQuery === undefined) {
195+
showAndLogErrorMessage("Failed to sort results since evaluation info was unknown.");
196+
break;
197+
}
198+
// Notify the webview that it should expect new results.
199+
await this.postMessage({ t: 'resultsUpdating' });
200+
await this._displayedQuery.updateInterpretedSortState(this.cliServer, msg.sortState);
201+
await this.showResults(this._displayedQuery, WebviewReveal.NotForced, true);
202+
break;
203+
}
193204
default:
194205
assertNever(msg);
195206
}
@@ -223,7 +234,7 @@ export class InterfaceManager extends DisposableObject {
223234
return;
224235
}
225236

226-
const interpretation = await this.interpretResultsInfo(results.query);
237+
const interpretation = await this.interpretResultsInfo(results.query, results.interpretedResultsSortState);
227238

228239
const sortedResultsMap: SortedResultsMap = {};
229240
results.sortedResultsInfo.forEach((v, k) =>
@@ -268,7 +279,7 @@ export class InterfaceManager extends DisposableObject {
268279
});
269280
}
270281

271-
private async getTruncatedResults(metadata: QueryMetadata | undefined, resultsPaths: ResultsPaths, sourceInfo: cli.SourceInfo | undefined, sourceLocationPrefix: string): Promise<Interpretation> {
282+
private async getTruncatedResults(metadata: QueryMetadata | undefined, resultsPaths: ResultsPaths, sourceInfo: cli.SourceInfo | undefined, sourceLocationPrefix: string, sortState: InterpretedResultsSortState): Promise<Interpretation> {
272283
const sarif = await interpretResults(this.cliServer, metadata, resultsPaths.resultsPath, sourceInfo);
273284
// For performance reasons, limit the number of results we try
274285
// to serialize and send to the webview. TODO: possibly also
@@ -285,11 +296,10 @@ export class InterfaceManager extends DisposableObject {
285296
}
286297
}
287298
});
288-
return { sarif, sourceLocationPrefix, numTruncatedResults };
289-
;
299+
return { sarif, sourceLocationPrefix, numTruncatedResults, sortState };
290300
}
291301

292-
private async interpretResultsInfo(query: QueryInfo): Promise<Interpretation | undefined> {
302+
private async interpretResultsInfo(query: QueryInfo, sortState: InterpretedResultsSortState): Promise<Interpretation | undefined> {
293303
let interpretation: Interpretation | undefined = undefined;
294304
if (await query.hasInterpretedResults()
295305
&& query.quickEvalPosition === undefined // never do results interpretation if quickEval
@@ -300,7 +310,7 @@ export class InterfaceManager extends DisposableObject {
300310
const sourceInfo = sourceArchiveUri === undefined ?
301311
undefined :
302312
{ sourceArchive: sourceArchiveUri.fsPath, sourceLocationPrefix };
303-
interpretation = await this.getTruncatedResults(query.metadata, query.resultsPaths, sourceInfo, sourceLocationPrefix);
313+
interpretation = await this.getTruncatedResults(query.metadata, query.resultsPaths, sourceInfo, sourceLocationPrefix, sortState);
304314
}
305315
catch (e) {
306316
// If interpretation fails, accept the error and continue
@@ -318,7 +328,13 @@ export class InterfaceManager extends DisposableObject {
318328
const sourceInfo = sourceArchiveUri === undefined ?
319329
undefined :
320330
{ sourceArchive: sourceArchiveUri.fsPath, sourceLocationPrefix };
321-
const interpretation = await this.getTruncatedResults(metadata, resultsInfo, sourceInfo, sourceLocationPrefix);
331+
const interpretation = await this.getTruncatedResults(
332+
metadata,
333+
resultsInfo,
334+
sourceInfo,
335+
sourceLocationPrefix,
336+
{ sortBy: 'file-position' } // sort order doesn't matter for showing diagnostics in parallel
337+
);
322338

323339
try {
324340
await this.showProblemResultsAsDiagnostics(interpretation, database);

extensions/ql-vscode/src/query-results.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as cli from './cli';
55
import * as sarif from 'sarif';
66
import * as fs from 'fs-extra';
77
import * as path from 'path';
8-
import { SortState, SortedResultSetInfo, DatabaseInfo, QueryMetadata } from "./interface-types";
8+
import { RawResultsSortState, SortedResultSetInfo, DatabaseInfo, QueryMetadata, InterpretedResultsSortState } from "./interface-types";
99
import { QueryHistoryConfig } from "./config";
1010
import { QueryHistoryItemOptions } from "./query-history";
1111

@@ -15,11 +15,19 @@ export class CompletedQuery implements QueryWithResults {
1515
readonly result: messages.EvaluationResult;
1616
readonly database: DatabaseInfo;
1717
options: QueryHistoryItemOptions;
18+
1819
/**
1920
* Map from result set name to SortedResultSetInfo.
2021
*/
2122
sortedResultsInfo: Map<string, SortedResultSetInfo>;
2223

24+
/*
25+
* How we're currently sorting alerts. This is not mere interface
26+
* state due to truncation; on re-sort, we want to read in the file
27+
* again, sort it, and only ship off a reasonable number of results
28+
* to the webview.
29+
*/
30+
interpretedResultsSortState: InterpretedResultsSortState = { sortBy: 'file-position' };
2331

2432
constructor(
2533
evalaution: QueryWithResults,
@@ -92,7 +100,8 @@ export class CompletedQuery implements QueryWithResults {
92100
toString(): string {
93101
return this.interpolate(this.getLabel());
94102
}
95-
async updateSortState(server: cli.CodeQLCliServer, resultSetName: string, sortState: SortState | undefined): Promise<void> {
103+
104+
async updateSortState(server: cli.CodeQLCliServer, resultSetName: string, sortState: RawResultsSortState | undefined): Promise<void> {
96105
if (sortState === undefined) {
97106
this.sortedResultsInfo.delete(resultSetName);
98107
return;
@@ -107,6 +116,9 @@ export class CompletedQuery implements QueryWithResults {
107116
this.sortedResultsInfo.set(resultSetName, sortedResultSetInfo);
108117
}
109118

119+
async updateInterpretedSortState(_server: cli.CodeQLCliServer, _sortState: InterpretedResultsSortState | undefined): Promise<void> {
120+
121+
}
110122
}
111123

112124
/**

extensions/ql-vscode/src/view/raw-results-table.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import * as React from "react";
22
import { renderLocation, ResultTableProps, zebraStripe, className } from "./result-table-utils";
33
import { RawTableResultSet, ResultValue, vscode } from "./results";
44
import { assertNever } from "../helpers-pure";
5-
import { SortDirection, SortState, RAW_RESULTS_LIMIT } from "../interface-types";
5+
import { SortDirection, RAW_RESULTS_LIMIT, RawResultsSortState } from "../interface-types";
66

77
export type RawTableProps = ResultTableProps & {
88
resultSet: RawTableResultSet,
9-
sortState?: SortState;
9+
sortState?: RawResultsSortState;
1010
};
1111

1212
export class RawTable extends React.Component<RawTableProps, {}> {

extensions/ql-vscode/src/view/result-table-utils.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import * as React from 'react';
22
import { LocationValue, ResolvableLocationValue, tryGetResolvableLocation } from 'semmle-bqrs';
3-
import { SortState, QueryMetadata } from '../interface-types';
3+
import { RawResultsSortState, QueryMetadata } from '../interface-types';
44
import { ResultSet, vscode } from './results';
55

66
export interface ResultTableProps {
77
resultSet: ResultSet;
88
databaseUri: string;
99
metadata?: QueryMetadata
1010
resultsPath: string | undefined;
11-
sortState?: SortState;
11+
sortState?: RawResultsSortState;
1212
}
1313

1414
export const className = 'vscode-codeql__result-table';
@@ -80,6 +80,6 @@ export function zebraStripe(index: number, ...otherClasses: string[]): { classNa
8080
*/
8181
export function selectableZebraStripe(isSelected: boolean, index: number, ...otherClasses: string[]): { className: string } {
8282
return isSelected
83-
? { className: [selectedRowClassName, ...otherClasses].join(' ') }
84-
: zebraStripe(index, ...otherClasses)
83+
? { className: [selectedRowClassName, ...otherClasses].join(' ') }
84+
: zebraStripe(index, ...otherClasses)
8585
}

extensions/ql-vscode/src/view/result-tables.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import { DatabaseInfo, Interpretation, SortState, QueryMetadata, ResultsPaths } from '../interface-types';
2+
import { DatabaseInfo, Interpretation, RawResultsSortState, QueryMetadata, ResultsPaths } from '../interface-types';
33
import { PathTable } from './alert-table';
44
import { RawTable } from './raw-results-table';
55
import { ResultTableProps, tableSelectionHeaderClassName, toggleDiagnosticsClassName } from './result-table-utils';
@@ -12,10 +12,10 @@ export interface ResultTablesProps {
1212
rawResultSets: readonly ResultSet[];
1313
interpretation: Interpretation | undefined;
1414
database: DatabaseInfo;
15-
metadata? : QueryMetadata
16-
resultsPath: string ;
15+
metadata?: QueryMetadata
16+
resultsPath: string;
1717
origResultsPaths: ResultsPaths;
18-
sortStates: Map<string, SortState>;
18+
sortStates: Map<string, RawResultsSortState>;
1919
isLoadingNewResults: boolean;
2020
}
2121

extensions/ql-vscode/src/view/results.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as Rdom from 'react-dom';
33
import * as bqrs from 'semmle-bqrs';
44
import { ElementBase, LocationValue, PrimitiveColumnValue, PrimitiveTypeKind, ResultSetSchema, tryGetResolvableLocation } from 'semmle-bqrs';
55
import { assertNever } from '../helpers-pure';
6-
import { DatabaseInfo, FromResultsViewMsg, Interpretation, IntoResultsViewMsg, SortedResultSetInfo, SortState, NavigatePathMsg, QueryMetadata, ResultsPaths } from '../interface-types';
6+
import { DatabaseInfo, FromResultsViewMsg, Interpretation, IntoResultsViewMsg, SortedResultSetInfo, RawResultsSortState, NavigatePathMsg, QueryMetadata, ResultsPaths } from '../interface-types';
77
import { ResultTables } from './result-tables';
88
import { EventHandlers as EventHandlerList } from './event-handler-list';
99

@@ -140,7 +140,7 @@ interface ResultsInfo {
140140

141141
interface Results {
142142
resultSets: readonly ResultSet[];
143-
sortStates: Map<string, SortState>;
143+
sortStates: Map<string, RawResultsSortState>;
144144
database: DatabaseInfo;
145145
}
146146

@@ -298,7 +298,7 @@ class App extends React.Component<{}, ResultsViewState> {
298298
}));
299299
}
300300

301-
private getSortStates(resultsInfo: ResultsInfo): Map<string, SortState> {
301+
private getSortStates(resultsInfo: ResultsInfo): Map<string, RawResultsSortState> {
302302
const entries = Array.from(resultsInfo.sortedResultsMap.entries());
303303
return new Map(entries.map(([key, sortedResultSetInfo]) =>
304304
[key, sortedResultSetInfo.sortState]));
@@ -340,4 +340,4 @@ Rdom.render(
340340
document.getElementById('root')
341341
);
342342

343-
vscode.postMessage({ t: "resultViewLoaded" })
343+
vscode.postMessage({ t: "resultViewLoaded" })

0 commit comments

Comments
 (0)