Skip to content

Commit bb61b5e

Browse files
committed
Replace the expansion index with the result key
1 parent 2949fc3 commit bb61b5e

2 files changed

Lines changed: 24 additions & 19 deletions

File tree

extensions/ql-vscode/src/pure/result-keys.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,11 @@ export function getAllPaths(result: sarif.Result): sarif.ThreadFlow[] {
108108
}
109109
return paths;
110110
}
111+
112+
/**
113+
* Creates a unique string representation of the given key, suitable for use
114+
* as the key in a map or set.
115+
*/
116+
export function keyToString(key: ResultKey) {
117+
return key.resultIndex + '-' + (key.pathIndex ?? '') + '-' + (key.pathNodeIndex ?? '');
118+
}

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

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,31 @@ import { isWholeFileLoc, isLineColumnLoc } from '../../pure/bqrs-utils';
1717

1818
export type PathTableProps = ResultTableProps & { resultSet: InterpretedResultSet<SarifInterpretationData> };
1919
export interface PathTableState {
20-
expanded: Set<number>;
20+
expanded: Set<string>;
2121
selectedItem: undefined | Keys.PathNode | Keys.Result;
2222
}
2323

2424
export class PathTable extends React.Component<PathTableProps, PathTableState> {
2525
constructor(props: PathTableProps) {
2626
super(props);
27-
this.state = { expanded: new Set<number>(), selectedItem: undefined };
27+
this.state = { expanded: new Set<string>(), selectedItem: undefined };
2828
this.handleNavigationEvent = this.handleNavigationEvent.bind(this);
2929
}
3030

3131
/**
32-
* Given a list of `indices`, toggle the first, and if we 'open' the
32+
* Given a list of `ids`, toggle the first, and if we 'open' the
3333
* first item, open all the rest as well. This mimics vscode's file
3434
* explorer tree view behavior.
3535
*/
36-
toggle(e: React.MouseEvent, indices: number[]) {
36+
toggle(e: React.MouseEvent, keys: Keys.ResultKey[]) {
37+
const keyStrings = keys.map(Keys.keyToString);
3738
this.setState(previousState => {
3839
const expanded = new Set(previousState.expanded);
39-
if (previousState.expanded.has(indices[0])) {
40-
expanded.delete(indices[0]);
40+
if (previousState.expanded.has(keyStrings[0])) {
41+
expanded.delete(keyStrings[0]);
4142
} else {
42-
for (const index of indices) {
43-
expanded.add(index);
43+
for (const str of keyStrings) {
44+
expanded.add(str);
4445
}
4546
}
4647
return { expanded };
@@ -183,16 +184,14 @@ export class PathTable extends React.Component<PathTableProps, PathTableState> {
183184
}
184185
}
185186

186-
const toggler: (indices: number[]) => (e: React.MouseEvent) => void = (indices) => {
187+
const toggler: (keys: Keys.ResultKey[]) => (e: React.MouseEvent) => void = (indices) => {
187188
return (e) => this.toggle(e, indices);
188189
};
189190

190191
if (!resultSet.interpretation.data.runs?.[0]?.results?.length) {
191192
return this.renderNoResults();
192193
}
193194

194-
let expansionIndex = 0;
195-
196195
resultSet.interpretation.data.runs[0].results.forEach((result, resultIndex) => {
197196
const resultKey: Keys.Result = { resultIndex };
198197
const text = result.message.text || '[no text]';
@@ -201,7 +200,7 @@ export class PathTable extends React.Component<PathTableProps, PathTableState> {
201200
[<span key="0">{text}</span>] :
202201
renderRelatedLocations(text, result.relatedLocations, resultKey);
203202

204-
const currentResultExpanded = this.state.expanded.has(expansionIndex);
203+
const currentResultExpanded = this.state.expanded.has(Keys.keyToString(resultKey));
205204
const indicator = currentResultExpanded ? octicons.chevronDown : octicons.chevronRight;
206205
const location = result.locations !== undefined && result.locations.length > 0 &&
207206
renderSarifLocation(result.locations[0], resultKey);
@@ -223,9 +222,9 @@ export class PathTable extends React.Component<PathTableProps, PathTableState> {
223222
const paths: Sarif.ThreadFlow[] = Keys.getAllPaths(result);
224223

225224
const indices = paths.length == 1 ?
226-
[expansionIndex, expansionIndex + 1] : /* if there's exactly one path, auto-expand
227-
* the path when expanding the result */
228-
[expansionIndex];
225+
[resultKey, { ...resultKey, pathIndex: 0 }] : /* if there's exactly one path, auto-expand
226+
* the path when expanding the result */
227+
[resultKey];
229228

230229
rows.push(
231230
<tr {...selectableZebraStripe(resultRowIsSelected, resultIndex)} key={resultIndex}>
@@ -241,24 +240,22 @@ export class PathTable extends React.Component<PathTableProps, PathTableState> {
241240
{locationCells}
242241
</tr >
243242
);
244-
expansionIndex++;
245243

246244
paths.forEach((path, pathIndex) => {
247245
const pathKey = { resultIndex, pathIndex };
248-
const currentPathExpanded = this.state.expanded.has(expansionIndex);
246+
const currentPathExpanded = this.state.expanded.has(Keys.keyToString(pathKey));
249247
if (currentResultExpanded) {
250248
const indicator = currentPathExpanded ? octicons.chevronDown : octicons.chevronRight;
251249
rows.push(
252250
<tr {...zebraStripe(resultIndex)} key={`${resultIndex}-${pathIndex}`}>
253251
<td className="vscode-codeql__icon-cell"><span className="vscode-codeql__vertical-rule"></span></td>
254-
<td className="vscode-codeql__icon-cell vscode-codeql__dropdown-cell" onMouseDown={toggler([expansionIndex])}>{indicator}</td>
252+
<td className="vscode-codeql__icon-cell vscode-codeql__dropdown-cell" onMouseDown={toggler([pathKey])}>{indicator}</td>
255253
<td className="vscode-codeql__text-center" colSpan={3}>
256254
Path
257255
</td>
258256
</tr>
259257
);
260258
}
261-
expansionIndex++;
262259

263260
if (currentResultExpanded && currentPathExpanded) {
264261
const pathNodes = path.locations;

0 commit comments

Comments
 (0)