Skip to content

Commit af22a15

Browse files
authored
Add new method modeling panel (#2752)
1 parent 6a6028b commit af22a15

9 files changed

Lines changed: 136 additions & 1 deletion

File tree

extensions/ql-vscode/package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,14 @@
17651765
"name": "CodeQL Methods Usage",
17661766
"when": "config.codeQL.canary && codeql.dataExtensionsEditorOpen"
17671767
}
1768+
],
1769+
"explorer": [
1770+
{
1771+
"type": "webview",
1772+
"id": "codeQLMethodModeling",
1773+
"name": "CodeQL Method Modeling",
1774+
"when": "config.codeQL.canary && config.codeQL.modelEditor.methodModelingView && codeql.dataExtensionsEditorOpen"
1775+
}
17681776
]
17691777
},
17701778
"viewsWelcome": [

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,3 +592,7 @@ export type FromDataExtensionsEditorMessage =
592592
| StopGeneratingExternalApiFromLlmMessage
593593
| ModelDependencyMessage
594594
| HideModeledApisMessage;
595+
596+
export type FromMethodModelingMessage =
597+
| TelemetryMessage
598+
| UnhandledErrorMessage;

extensions/ql-vscode/src/common/vscode/webview-html.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ export type WebviewKind =
77
| "compare"
88
| "variant-analysis"
99
| "data-flow-paths"
10-
| "data-extensions-editor";
10+
| "data-extensions-editor"
11+
| "method-modeling";
1112

1213
export interface WebviewMessage {
1314
t: string;

extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { Mode } from "./shared/mode";
1919
import { showResolvableLocation } from "../databases/local-databases/locations";
2020
import { Usage } from "./external-api-usage";
2121
import { setUpPack } from "./data-extensions-editor-queries";
22+
import { MethodModelingPanel } from "./method-modeling/method-modeling-panel";
2223

2324
const SUPPORTED_LANGUAGES: string[] = ["java", "csharp"];
2425

@@ -43,6 +44,7 @@ export class DataExtensionsEditorModule extends DisposableObject {
4344
"data-extensions-editor-results",
4445
);
4546
this.methodsUsagePanel = this.push(new MethodsUsagePanel(cliServer));
47+
this.push(new MethodModelingPanel(ctx));
4648
}
4749

4850
private handleViewBecameActive(view: DataExtensionsEditorView): void {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { ExtensionContext, window } from "vscode";
2+
import { DisposableObject } from "../../common/disposable-object";
3+
import { MethodModelingViewProvider } from "./method-modeling-view-provider";
4+
5+
export class MethodModelingPanel extends DisposableObject {
6+
constructor(context: ExtensionContext) {
7+
super();
8+
9+
const provider = new MethodModelingViewProvider(context);
10+
this.push(
11+
window.registerWebviewViewProvider(
12+
MethodModelingViewProvider.viewType,
13+
provider,
14+
),
15+
);
16+
}
17+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import * as vscode from "vscode";
2+
import { WebviewViewProvider } from "vscode";
3+
import { getHtmlForWebview } from "../../common/vscode/webview-html";
4+
import { FromMethodModelingMessage } from "../../common/interface-types";
5+
import { telemetryListener } from "../../common/vscode/telemetry";
6+
import { showAndLogExceptionWithTelemetry } from "../../common/logging/notifications";
7+
import { extLogger } from "../../common/logging/vscode/loggers";
8+
import { redactableError } from "../../common/errors";
9+
10+
export class MethodModelingViewProvider implements WebviewViewProvider {
11+
public static readonly viewType = "codeQLMethodModeling";
12+
13+
constructor(private readonly context: vscode.ExtensionContext) {}
14+
15+
/**
16+
* This is called when a view first becomes visible. This may happen when the view is
17+
* first loaded or when the user hides and then shows a view again.
18+
*/
19+
public resolveWebviewView(
20+
webviewView: vscode.WebviewView,
21+
_context: vscode.WebviewViewResolveContext,
22+
_token: vscode.CancellationToken,
23+
) {
24+
webviewView.webview.options = {
25+
enableScripts: true,
26+
localResourceRoots: [this.context.extensionUri],
27+
};
28+
29+
const html = getHtmlForWebview(
30+
this.context,
31+
webviewView.webview,
32+
"method-modeling",
33+
{
34+
allowInlineStyles: true,
35+
allowWasmEval: false,
36+
},
37+
);
38+
39+
webviewView.webview.html = html;
40+
41+
webviewView.webview.onDidReceiveMessage(async (msg) => this.onMessage(msg));
42+
}
43+
44+
private async onMessage(msg: FromMethodModelingMessage): Promise<void> {
45+
switch (msg.t) {
46+
case "telemetry": {
47+
telemetryListener?.sendUIInteraction(msg.action);
48+
break;
49+
}
50+
case "unhandledError":
51+
void showAndLogExceptionWithTelemetry(
52+
extLogger,
53+
telemetryListener,
54+
redactableError(
55+
msg.error,
56+
)`Unhandled error in method modeling view: ${msg.error.message}`,
57+
);
58+
break;
59+
}
60+
}
61+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from "react";
2+
3+
export const MethodModeling = (): JSX.Element => {
4+
return (
5+
<>
6+
<p>Hello</p>
7+
</>
8+
);
9+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as React from "react";
2+
import { useEffect } from "react";
3+
import { MethodModeling } from "./MethodModeling";
4+
5+
export function MethodModelingView(): JSX.Element {
6+
useEffect(() => {
7+
const listener = (evt: MessageEvent) => {
8+
if (evt.origin === window.origin) {
9+
// Nothing to do yet.
10+
} else {
11+
// sanitize origin
12+
const origin = evt.origin.replace(/\n|\r/g, "");
13+
console.error(`Invalid event origin ${origin}`);
14+
}
15+
};
16+
window.addEventListener("message", listener);
17+
18+
return () => {
19+
window.removeEventListener("message", listener);
20+
};
21+
}, []);
22+
23+
return <MethodModeling />;
24+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as React from "react";
2+
import { WebviewDefinition } from "../webview-definition";
3+
import { MethodModelingView } from "./MethodModelingView";
4+
5+
const definition: WebviewDefinition = {
6+
component: <MethodModelingView />,
7+
};
8+
9+
export default definition;

0 commit comments

Comments
 (0)