Skip to content

Commit 7914403

Browse files
authored
Wire up data flow paths view (#2182)
1 parent df24a70 commit 7914403

File tree

13 files changed

+298
-272
lines changed

13 files changed

+298
-272
lines changed

extensions/ql-vscode/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## [UNRELEASED]
44

5+
- Show data flow paths of a variant analysis in a new tab
6+
57
## 1.8.0 - 9 March 2023
68

79
- Send telemetry about unhandled errors happening within the extension. [#2125](https://github.com/github/vscode-codeql/pull/2125)

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,11 @@ export interface CancelVariantAnalysisMessage {
449449
t: "cancelVariantAnalysis";
450450
}
451451

452+
export interface ShowDataFlowPathsMessage {
453+
t: "showDataFlowPaths";
454+
dataFlowPaths: DataFlowPaths;
455+
}
456+
452457
export type ToVariantAnalysisMessage =
453458
| SetVariantAnalysisMessage
454459
| SetRepoResultsMessage
@@ -462,7 +467,8 @@ export type FromVariantAnalysisMessage =
462467
| CopyRepositoryListMessage
463468
| ExportResultsMessage
464469
| OpenLogsMessage
465-
| CancelVariantAnalysisMessage;
470+
| CancelVariantAnalysisMessage
471+
| ShowDataFlowPathsMessage;
466472

467473
export interface SetDataFlowPathsMessage {
468474
t: "setDataFlowPaths";

extensions/ql-vscode/src/stories/common/CodePaths.stories.tsx

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

33
import { ComponentStory, ComponentMeta } from "@storybook/react";
4-
import { ThemeProvider } from "@primer/react";
54

65
import { CodePaths } from "../../view/common";
76
import type { CodeFlow } from "../../variant-analysis/shared/analysis-result";
87

98
export default {
109
title: "Code Paths",
1110
component: CodePaths,
12-
decorators: [
13-
(Story) => (
14-
<ThemeProvider colorMode="auto">
15-
<Story />
16-
</ThemeProvider>
17-
),
18-
],
11+
decorators: [(Story) => <Story />],
1912
} as ComponentMeta<typeof CodePaths>;
2013

2114
const Template: ComponentStory<typeof CodePaths> = (args) => (
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from "react";
2+
3+
import { ComponentMeta, ComponentStory } from "@storybook/react";
4+
5+
import { DataFlowPaths as DataFlowPathsComponent } from "../../view/data-flow-paths/DataFlowPaths";
6+
import { createMockDataFlowPaths } from "../../../test/factories/variant-analysis/shared/data-flow-paths";
7+
export default {
8+
title: "Data Flow Paths/Data Flow Paths",
9+
component: DataFlowPathsComponent,
10+
} as ComponentMeta<typeof DataFlowPathsComponent>;
11+
12+
const Template: ComponentStory<typeof DataFlowPathsComponent> = (args) => (
13+
<DataFlowPathsComponent {...args} />
14+
);
15+
16+
export const PowerShell = Template.bind({});
17+
PowerShell.args = {
18+
dataFlowPaths: createMockDataFlowPaths(),
19+
};

extensions/ql-vscode/src/variant-analysis/variant-analysis-view.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@ import {
2121
} from "../helpers";
2222
import { telemetryListener } from "../telemetry";
2323
import { redactableError } from "../pure/errors";
24+
import { DataFlowPathsView } from "./data-flow-paths-view";
25+
import { DataFlowPaths } from "./shared/data-flow-paths";
2426

2527
export class VariantAnalysisView
2628
extends AbstractWebview<ToVariantAnalysisMessage, FromVariantAnalysisMessage>
2729
implements VariantAnalysisViewInterface
2830
{
2931
public static readonly viewType = "codeQL.variantAnalysis";
32+
private readonly dataFlowPathsView: DataFlowPathsView;
3033

3134
public constructor(
3235
ctx: ExtensionContext,
@@ -36,6 +39,8 @@ export class VariantAnalysisView
3639
super(ctx);
3740

3841
manager.registerView(this);
42+
43+
this.dataFlowPathsView = new DataFlowPathsView(ctx);
3944
}
4045

4146
public async openView() {
@@ -151,6 +156,9 @@ export class VariantAnalysisView
151156
this.variantAnalysisId,
152157
);
153158
break;
159+
case "showDataFlowPaths":
160+
await this.showDataFlows(msg.dataFlowPaths);
161+
break;
154162
case "telemetry":
155163
telemetryListener?.sendUIInteraction(msg.action);
156164
break;
@@ -201,4 +209,8 @@ export class VariantAnalysisView
201209
? `${variantAnalysis.query.name} - Variant Analysis Results`
202210
: `Variant Analysis ${this.variantAnalysisId} - Results`;
203211
}
212+
213+
private async showDataFlows(dataFlows: DataFlowPaths): Promise<void> {
214+
await this.dataFlowPathsView.showDataFlows(dataFlows);
215+
}
204216
}
Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
import * as React from "react";
2-
import { useRef, useState } from "react";
32
import styled from "styled-components";
43
import { VSCodeLink } from "@vscode/webview-ui-toolkit/react";
54

6-
import { Overlay, ThemeProvider } from "@primer/react";
7-
85
import {
96
AnalysisMessage,
107
CodeFlow,
118
ResultSeverity,
129
} from "../../../variant-analysis/shared/analysis-result";
13-
import { CodePathsOverlay } from "./CodePathsOverlay";
14-
import { useTelemetryOnChange } from "../telemetry";
10+
import { vscode } from "../../vscode-api";
1511

1612
const ShowPathsLink = styled(VSCodeLink)`
1713
cursor: pointer;
@@ -24,46 +20,27 @@ export type CodePathsProps = {
2420
severity: ResultSeverity;
2521
};
2622

27-
const filterIsOpenTelemetry = (v: boolean) => v;
28-
2923
export const CodePaths = ({
3024
codeFlows,
3125
ruleDescription,
3226
message,
3327
severity,
3428
}: CodePathsProps) => {
35-
const [isOpen, setIsOpen] = useState(false);
36-
useTelemetryOnChange(isOpen, "code-path-is-open", {
37-
filterTelemetryOnValue: filterIsOpenTelemetry,
38-
});
39-
40-
const linkRef = useRef<HTMLAnchorElement>(null);
41-
42-
const closeOverlay = () => setIsOpen(false);
29+
const onShowPathsClick = () => {
30+
vscode.postMessage({
31+
t: "showDataFlowPaths",
32+
dataFlowPaths: {
33+
codeFlows,
34+
ruleDescription,
35+
message,
36+
severity,
37+
},
38+
});
39+
};
4340

4441
return (
4542
<>
46-
<ShowPathsLink onClick={() => setIsOpen(true)} ref={linkRef}>
47-
Show paths
48-
</ShowPathsLink>
49-
{isOpen && (
50-
<ThemeProvider colorMode="auto">
51-
<Overlay
52-
returnFocusRef={linkRef}
53-
onEscape={closeOverlay}
54-
onClickOutside={closeOverlay}
55-
anchorSide="outside-top"
56-
>
57-
<CodePathsOverlay
58-
codeFlows={codeFlows}
59-
ruleDescription={ruleDescription}
60-
message={message}
61-
severity={severity}
62-
onClose={closeOverlay}
63-
/>
64-
</Overlay>
65-
</ThemeProvider>
66-
)}
43+
<ShowPathsLink onClick={onShowPathsClick}>Show paths</ShowPathsLink>
6744
</>
6845
);
6946
};

extensions/ql-vscode/src/view/common/CodePaths/CodePathsOverlay.tsx

Lines changed: 0 additions & 112 deletions
This file was deleted.

extensions/ql-vscode/src/view/common/CodePaths/__tests__/CodePaths.spec.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,25 @@ describe(CodePaths.name, () => {
1818
/>,
1919
);
2020

21-
it("renders correctly when unexpanded", () => {
21+
it("renders 'show paths' link", () => {
2222
render();
2323

2424
expect(screen.getByText("Show paths")).toBeInTheDocument();
25-
expect(screen.queryByText("Code snippet text")).not.toBeInTheDocument();
26-
expect(screen.queryByText("Rule description")).not.toBeInTheDocument();
2725
});
2826

29-
it("renders correctly when expanded", async () => {
27+
it("posts extension message when 'show paths' link clicked", async () => {
3028
render();
3129

3230
await userEvent.click(screen.getByText("Show paths"));
3331

34-
expect(screen.getByText("Code snippet text")).toBeInTheDocument();
35-
expect(screen.getByText("Rule description")).toBeInTheDocument();
32+
expect((window as any).vsCodeApi.postMessage).toHaveBeenCalledWith({
33+
t: "showDataFlowPaths",
34+
dataFlowPaths: {
35+
codeFlows: createMockCodeFlows(),
36+
ruleDescription: "Rule description",
37+
message: createMockAnalysisMessage(),
38+
severity: "Recommendation",
39+
},
40+
});
3641
});
3742
});

0 commit comments

Comments
 (0)