Skip to content

Commit a4c0365

Browse files
Move components for rendering locations to a separate file
1 parent 2abc4d5 commit a4c0365

4 files changed

Lines changed: 270 additions & 186 deletions

File tree

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from "react";
22

3-
import { renderLocation } from "./result-table-utils";
3+
import { Location } from "./locations";
44
import { CellValue } from "../../common/bqrs-cli-types";
55

66
interface Props {
@@ -16,14 +16,15 @@ export default function RawTableValue(props: Props): JSX.Element {
1616
typeof rawValue === "number" ||
1717
typeof rawValue === "boolean"
1818
) {
19-
return <span>{renderLocation(undefined, rawValue.toString())}</span>;
19+
return <Location label={rawValue.toString()} />;
2020
}
2121

22-
return renderLocation(
23-
rawValue.url,
24-
rawValue.label,
25-
props.databaseUri,
26-
undefined,
27-
props.onSelected,
22+
return (
23+
<Location
24+
loc={rawValue.url}
25+
label={rawValue.label}
26+
databaseUri={props.databaseUri}
27+
jumpToLocationCallback={props.onSelected}
28+
/>
2829
);
2930
}

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

Lines changed: 47 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import { basename } from "path";
21
import * as React from "react";
32
import * as Sarif from "sarif";
43
import * as Keys from "./result-keys";
54
import { chevronDown, chevronRight, info, listUnordered } from "./octicons";
65
import {
76
className,
8-
renderLocation,
97
ResultTableProps,
108
selectableZebraStripe,
119
jumpToLocation,
@@ -18,15 +16,11 @@ import {
1816
NavigationDirection,
1917
SarifInterpretationData,
2018
} from "../../common/interface-types";
21-
import {
22-
parseSarifPlainTextMessage,
23-
parseSarifLocation,
24-
isNoLocation,
25-
} from "../../common/sarif-utils";
26-
import { isWholeFileLoc, isLineColumnLoc } from "../../common/bqrs-utils";
19+
import { parseSarifLocation, isNoLocation } from "../../common/sarif-utils";
2720
import { ScrollIntoViewHelper } from "./scroll-into-view-helper";
2821
import { sendTelemetry } from "../common/telemetry";
2922
import { AlertTableHeader } from "./alert-table-header";
23+
import { SarifLocation, SarifMessageWithLocations } from "./locations";
3024

3125
export type AlertTableProps = ResultTableProps & {
3226
resultSet: InterpretedResultSet<SarifInterpretationData>;
@@ -100,41 +94,6 @@ export class AlertTable extends React.Component<
10094
const { numTruncatedResults, sourceLocationPrefix } =
10195
resultSet.interpretation;
10296

103-
function renderRelatedLocations(
104-
msg: string,
105-
relatedLocations: Sarif.Location[],
106-
resultKey: Keys.PathNode | Keys.Result | undefined,
107-
): JSX.Element[] {
108-
const relatedLocationsById: { [k: string]: Sarif.Location } = {};
109-
for (const loc of relatedLocations) {
110-
relatedLocationsById[loc.id!] = loc;
111-
}
112-
113-
// match things like `[link-text](related-location-id)`
114-
const parts = parseSarifPlainTextMessage(msg);
115-
116-
return parts.map((part, i) => {
117-
if (typeof part === "string") {
118-
return <span key={i}>{part}</span>;
119-
} else {
120-
const renderedLocation = renderSarifLocationWithText(
121-
part.text,
122-
relatedLocationsById[part.dest],
123-
resultKey,
124-
);
125-
return <span key={i}>{renderedLocation}</span>;
126-
}
127-
});
128-
}
129-
130-
function renderNonLocation(
131-
msg: string | undefined,
132-
locationHint: string,
133-
): JSX.Element | undefined {
134-
if (msg === undefined) return undefined;
135-
return <span title={locationHint}>{msg}</span>;
136-
}
137-
13897
const updateSelectionCallback = (
13998
resultKey: Keys.PathNode | Keys.Result | undefined,
14099
) => {
@@ -147,65 +106,6 @@ export class AlertTable extends React.Component<
147106
};
148107
};
149108

150-
function renderSarifLocationWithText(
151-
text: string | undefined,
152-
loc: Sarif.Location,
153-
resultKey: Keys.PathNode | Keys.Result | undefined,
154-
): JSX.Element | undefined {
155-
const parsedLoc = parseSarifLocation(loc, sourceLocationPrefix);
156-
if ("hint" in parsedLoc) {
157-
return renderNonLocation(text, parsedLoc.hint);
158-
} else if (isWholeFileLoc(parsedLoc) || isLineColumnLoc(parsedLoc)) {
159-
return renderLocation(
160-
parsedLoc,
161-
text,
162-
databaseUri,
163-
undefined,
164-
updateSelectionCallback(resultKey),
165-
);
166-
} else {
167-
return undefined;
168-
}
169-
}
170-
171-
/**
172-
* Render sarif location as a link with the text being simply a
173-
* human-readable form of the location itself.
174-
*/
175-
function renderSarifLocation(
176-
loc: Sarif.Location,
177-
pathNodeKey: Keys.PathNode | Keys.Result | undefined,
178-
): JSX.Element | undefined {
179-
const parsedLoc = parseSarifLocation(loc, sourceLocationPrefix);
180-
if ("hint" in parsedLoc) {
181-
return renderNonLocation("[no location]", parsedLoc.hint);
182-
} else if (isWholeFileLoc(parsedLoc)) {
183-
const shortLocation = `${basename(parsedLoc.userVisibleFile)}`;
184-
const longLocation = `${parsedLoc.userVisibleFile}`;
185-
return renderLocation(
186-
parsedLoc,
187-
shortLocation,
188-
databaseUri,
189-
longLocation,
190-
updateSelectionCallback(pathNodeKey),
191-
);
192-
} else if (isLineColumnLoc(parsedLoc)) {
193-
const shortLocation = `${basename(parsedLoc.userVisibleFile)}:${
194-
parsedLoc.startLine
195-
}:${parsedLoc.startColumn}`;
196-
const longLocation = `${parsedLoc.userVisibleFile}`;
197-
return renderLocation(
198-
parsedLoc,
199-
shortLocation,
200-
databaseUri,
201-
longLocation,
202-
updateSelectionCallback(pathNodeKey),
203-
);
204-
} else {
205-
return undefined;
206-
}
207-
}
208-
209109
const toggler: (keys: Keys.ResultKey[]) => (e: React.MouseEvent) => void = (
210110
indices,
211111
) => {
@@ -220,19 +120,32 @@ export class AlertTable extends React.Component<
220120
(result, resultIndex) => {
221121
const resultKey: Keys.Result = { resultIndex };
222122
const text = result.message.text || "[no text]";
223-
const msg: JSX.Element[] =
224-
result.relatedLocations === undefined
225-
? [<span key="0">{text}</span>]
226-
: renderRelatedLocations(text, result.relatedLocations, resultKey);
123+
const msg =
124+
result.relatedLocations === undefined ? (
125+
<span key="0">{text}</span>
126+
) : (
127+
<SarifMessageWithLocations
128+
msg={text}
129+
relatedLocations={result.relatedLocations}
130+
sourceLocationPrefix={sourceLocationPrefix}
131+
databaseUri={databaseUri}
132+
jumpToLocationCallback={updateSelectionCallback(resultKey)}
133+
/>
134+
);
227135

228136
const currentResultExpanded = this.state.expanded.has(
229137
Keys.keyToString(resultKey),
230138
);
231139
const indicator = currentResultExpanded ? chevronDown : chevronRight;
232-
const location =
233-
result.locations !== undefined &&
234-
result.locations.length > 0 &&
235-
renderSarifLocation(result.locations[0], resultKey);
140+
const location = result.locations !== undefined &&
141+
result.locations.length > 0 && (
142+
<SarifLocation
143+
loc={result.locations[0]}
144+
sourceLocationPrefix={sourceLocationPrefix}
145+
databaseUri={databaseUri}
146+
jumpToLocationCallback={updateSelectionCallback(resultKey)}
147+
/>
148+
);
236149
const locationCells = (
237150
<td className="vscode-codeql__location-cell">{location}</td>
238151
);
@@ -342,17 +255,32 @@ export class AlertTable extends React.Component<
342255
const step = pathNodes[pathNodeIndex];
343256
const msg =
344257
step.location !== undefined &&
345-
step.location.message !== undefined
346-
? renderSarifLocationWithText(
347-
step.location.message.text,
348-
step.location,
258+
step.location.message !== undefined ? (
259+
<SarifLocation
260+
text={step.location.message.text}
261+
loc={step.location}
262+
sourceLocationPrefix={sourceLocationPrefix}
263+
databaseUri={databaseUri}
264+
jumpToLocationCallback={updateSelectionCallback(
349265
pathNodeKey,
350-
)
351-
: "[no location]";
266+
)}
267+
/>
268+
) : (
269+
"[no location]"
270+
);
352271
const additionalMsg =
353-
step.location !== undefined
354-
? renderSarifLocation(step.location, pathNodeKey)
355-
: "";
272+
step.location !== undefined ? (
273+
<SarifLocation
274+
loc={step.location}
275+
sourceLocationPrefix={sourceLocationPrefix}
276+
databaseUri={databaseUri}
277+
jumpToLocationCallback={updateSelectionCallback(
278+
pathNodeKey,
279+
)}
280+
/>
281+
) : (
282+
""
283+
);
356284
const isSelected = Keys.equalsNotUndefined(
357285
this.state.selectedItem,
358286
pathNodeKey,

0 commit comments

Comments
 (0)