Skip to content

Commit ac7a37c

Browse files
authored
Add ability to set method for modeling in the modeling panel (#2767)
1 parent b5d6c4d commit ac7a37c

File tree

6 files changed

+73
-26
lines changed

6 files changed

+73
-26
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,3 +593,10 @@ export type FromModelEditorMessage =
593593
export type FromMethodModelingMessage =
594594
| TelemetryMessage
595595
| UnhandledErrorMessage;
596+
597+
interface SetMethodMessage {
598+
t: "setMethod";
599+
method: ExternalApiUsage;
600+
}
601+
602+
export type ToMethodModelingMessage = SetMethodMessage;
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
import { ExtensionContext, window } from "vscode";
22
import { DisposableObject } from "../../common/disposable-object";
33
import { MethodModelingViewProvider } from "./method-modeling-view-provider";
4+
import { ExternalApiUsage } from "../external-api-usage";
45

56
export class MethodModelingPanel extends DisposableObject {
7+
private readonly provider: MethodModelingViewProvider;
8+
69
constructor(context: ExtensionContext) {
710
super();
811

9-
const provider = new MethodModelingViewProvider(context);
12+
this.provider = new MethodModelingViewProvider(context);
1013
this.push(
1114
window.registerWebviewViewProvider(
1215
MethodModelingViewProvider.viewType,
13-
provider,
16+
this.provider,
1417
),
1518
);
1619
}
20+
21+
public async setMethod(method: ExternalApiUsage): Promise<void> {
22+
await this.provider.setMethod(method);
23+
}
1724
}

extensions/ql-vscode/src/model-editor/method-modeling/method-modeling-view-provider.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ import { telemetryListener } from "../../common/vscode/telemetry";
66
import { showAndLogExceptionWithTelemetry } from "../../common/logging/notifications";
77
import { extLogger } from "../../common/logging/vscode/loggers";
88
import { redactableError } from "../../common/errors";
9+
import { ExternalApiUsage } from "../external-api-usage";
910

1011
export class MethodModelingViewProvider implements WebviewViewProvider {
1112
public static readonly viewType = "codeQLMethodModeling";
1213

14+
private webviewView: vscode.WebviewView | undefined = undefined;
15+
1316
constructor(private readonly context: vscode.ExtensionContext) {}
1417

1518
/**
@@ -39,6 +42,17 @@ export class MethodModelingViewProvider implements WebviewViewProvider {
3942
webviewView.webview.html = html;
4043

4144
webviewView.webview.onDidReceiveMessage(async (msg) => this.onMessage(msg));
45+
46+
this.webviewView = webviewView;
47+
}
48+
49+
public async setMethod(method: ExternalApiUsage): Promise<void> {
50+
if (this.webviewView) {
51+
await this.webviewView.webview.postMessage({
52+
t: "setMethod",
53+
method,
54+
});
55+
}
4256
}
4357

4458
private async onMessage(msg: FromMethodModelingMessage): Promise<void> {

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

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { DisposableObject } from "../common/disposable-object";
1717
import { MethodsUsagePanel } from "./methods-usage/methods-usage-panel";
1818
import { Mode } from "./shared/mode";
1919
import { showResolvableLocation } from "../databases/local-databases/locations";
20-
import { Usage } from "./external-api-usage";
20+
import { ExternalApiUsage, Usage } from "./external-api-usage";
2121
import { setUpPack } from "./model-editor-queries";
2222
import { MethodModelingPanel } from "./method-modeling/method-modeling-panel";
2323

@@ -26,6 +26,7 @@ const SUPPORTED_LANGUAGES: string[] = ["java", "csharp"];
2626
export class ModelEditorModule extends DisposableObject {
2727
private readonly queryStorageDir: string;
2828
private readonly methodsUsagePanel: MethodsUsagePanel;
29+
private readonly methodModelingPanel: MethodModelingPanel;
2930

3031
private mostRecentlyActiveView: ModelEditorView | undefined = undefined;
3132

@@ -40,7 +41,7 @@ export class ModelEditorModule extends DisposableObject {
4041
super();
4142
this.queryStorageDir = join(baseQueryStorageDir, "model-editor-results");
4243
this.methodsUsagePanel = this.push(new MethodsUsagePanel(cliServer));
43-
this.push(new MethodModelingPanel(ctx));
44+
this.methodModelingPanel = this.push(new MethodModelingPanel(ctx));
4445
}
4546

4647
private handleViewBecameActive(view: ModelEditorView): void {
@@ -149,7 +150,7 @@ export class ModelEditorModule extends DisposableObject {
149150
modelFile,
150151
Mode.Application,
151152
this.methodsUsagePanel.setState.bind(this.methodsUsagePanel),
152-
this.methodsUsagePanel.revealItem.bind(this.methodsUsagePanel),
153+
this.showMethod.bind(this),
153154
this.handleViewBecameActive.bind(this),
154155
this.handleViewWasDisposed.bind(this),
155156
this.isMostRecentlyActiveView.bind(this),
@@ -173,4 +174,24 @@ export class ModelEditorModule extends DisposableObject {
173174
private async initialize(): Promise<void> {
174175
await ensureDir(this.queryStorageDir);
175176
}
177+
178+
private async showMethod(usage: Usage): Promise<void> {
179+
await this.methodsUsagePanel.revealItem(usage);
180+
181+
// For now, just construct a dummy method and show it in the method modeling panel
182+
// because the method isn't easily accessible yet.
183+
const method: ExternalApiUsage = {
184+
library: "sql2o",
185+
libraryVersion: "1.6.0",
186+
signature: "org.sql2o.Connection#createQuery(String)",
187+
packageName: "org.sql2o",
188+
typeName: "Connection",
189+
methodName: "createQuery",
190+
methodParameters: "(String)",
191+
supported: true,
192+
supportedType: "summary",
193+
usages: [],
194+
};
195+
await this.methodModelingPanel.setMethod(method);
196+
}
176197
}

extensions/ql-vscode/src/model-editor/model-editor-view.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export class ModelEditorView extends AbstractWebview<
6565
databaseItem: DatabaseItem,
6666
hideModeledApis: boolean,
6767
) => Promise<void>,
68-
private readonly revealItemInUsagePanel: (usage: Usage) => Promise<void>,
68+
private readonly showMethod: (usage: Usage) => Promise<void>,
6969
private readonly handleViewBecameActive: (view: ModelEditorView) => void,
7070
private readonly handleViewWasDisposed: (view: ModelEditorView) => void,
7171
private readonly isMostRecentlyActiveView: (
@@ -268,7 +268,7 @@ export class ModelEditorView extends AbstractWebview<
268268
}
269269

270270
protected async handleJumpToUsage(usage: Usage) {
271-
await this.revealItemInUsagePanel(usage);
271+
await this.showMethod(usage);
272272
await showResolvableLocation(usage.url, this.databaseItem, this.app.logger);
273273
}
274274

@@ -439,7 +439,7 @@ export class ModelEditorView extends AbstractWebview<
439439
modelFile,
440440
Mode.Framework,
441441
this.updateMethodsUsagePanelState,
442-
this.revealItemInUsagePanel,
442+
this.showMethod,
443443
this.handleViewBecameActive,
444444
this.handleViewWasDisposed,
445445
this.isMostRecentlyActiveView,
Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
import * as React from "react";
2-
import { useEffect } from "react";
2+
import { useEffect, useState } from "react";
33
import { MethodModeling } from "./MethodModeling";
44
import { ModelingStatus } from "../model-editor/ModelingStatusIndicator";
55
import { ExternalApiUsage } from "../../model-editor/external-api-usage";
6+
import { ToMethodModelingMessage } from "../../common/interface-types";
7+
import { assertNever } from "../../common/helpers-pure";
68

79
export function MethodModelingView(): JSX.Element {
10+
const [method, setMethod] = useState<ExternalApiUsage | undefined>(undefined);
11+
812
useEffect(() => {
913
const listener = (evt: MessageEvent) => {
1014
if (evt.origin === window.origin) {
11-
// Nothing to do yet.
15+
const msg: ToMethodModelingMessage = evt.data;
16+
if (msg.t === "setMethod") {
17+
setMethod(msg.method);
18+
} else {
19+
assertNever(msg.t);
20+
}
1221
} else {
1322
// sanitize origin
1423
const origin = evt.origin.replace(/\n|\r/g, "");
@@ -22,23 +31,12 @@ export function MethodModelingView(): JSX.Element {
2231
};
2332
}, []);
2433

34+
if (!method) {
35+
return <>Select method to model</>;
36+
}
37+
2538
const modelingStatus: ModelingStatus = "saved";
26-
const externalApiUsage: ExternalApiUsage = {
27-
library: "sql2o",
28-
libraryVersion: "1.6.0",
29-
signature: "org.sql2o.Connection#createQuery(String)",
30-
packageName: "org.sql2o",
31-
typeName: "Connection",
32-
methodName: "createQuery",
33-
methodParameters: "(String)",
34-
supported: true,
35-
supportedType: "summary",
36-
usages: [],
37-
};
3839
return (
39-
<MethodModeling
40-
modelingStatus={modelingStatus}
41-
externalApiUsage={externalApiUsage}
42-
/>
40+
<MethodModeling modelingStatus={modelingStatus} externalApiUsage={method} />
4341
);
4442
}

0 commit comments

Comments
 (0)