Add ability to set method for modeling in the modeling panel (#2767)
This commit is contained in:
@@ -593,3 +593,10 @@ export type FromModelEditorMessage =
|
|||||||
export type FromMethodModelingMessage =
|
export type FromMethodModelingMessage =
|
||||||
| TelemetryMessage
|
| TelemetryMessage
|
||||||
| UnhandledErrorMessage;
|
| UnhandledErrorMessage;
|
||||||
|
|
||||||
|
interface SetMethodMessage {
|
||||||
|
t: "setMethod";
|
||||||
|
method: ExternalApiUsage;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ToMethodModelingMessage = SetMethodMessage;
|
||||||
|
|||||||
@@ -1,17 +1,24 @@
|
|||||||
import { ExtensionContext, window } from "vscode";
|
import { ExtensionContext, window } from "vscode";
|
||||||
import { DisposableObject } from "../../common/disposable-object";
|
import { DisposableObject } from "../../common/disposable-object";
|
||||||
import { MethodModelingViewProvider } from "./method-modeling-view-provider";
|
import { MethodModelingViewProvider } from "./method-modeling-view-provider";
|
||||||
|
import { ExternalApiUsage } from "../external-api-usage";
|
||||||
|
|
||||||
export class MethodModelingPanel extends DisposableObject {
|
export class MethodModelingPanel extends DisposableObject {
|
||||||
|
private readonly provider: MethodModelingViewProvider;
|
||||||
|
|
||||||
constructor(context: ExtensionContext) {
|
constructor(context: ExtensionContext) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
const provider = new MethodModelingViewProvider(context);
|
this.provider = new MethodModelingViewProvider(context);
|
||||||
this.push(
|
this.push(
|
||||||
window.registerWebviewViewProvider(
|
window.registerWebviewViewProvider(
|
||||||
MethodModelingViewProvider.viewType,
|
MethodModelingViewProvider.viewType,
|
||||||
provider,
|
this.provider,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async setMethod(method: ExternalApiUsage): Promise<void> {
|
||||||
|
await this.provider.setMethod(method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,13 @@ import { telemetryListener } from "../../common/vscode/telemetry";
|
|||||||
import { showAndLogExceptionWithTelemetry } from "../../common/logging/notifications";
|
import { showAndLogExceptionWithTelemetry } from "../../common/logging/notifications";
|
||||||
import { extLogger } from "../../common/logging/vscode/loggers";
|
import { extLogger } from "../../common/logging/vscode/loggers";
|
||||||
import { redactableError } from "../../common/errors";
|
import { redactableError } from "../../common/errors";
|
||||||
|
import { ExternalApiUsage } from "../external-api-usage";
|
||||||
|
|
||||||
export class MethodModelingViewProvider implements WebviewViewProvider {
|
export class MethodModelingViewProvider implements WebviewViewProvider {
|
||||||
public static readonly viewType = "codeQLMethodModeling";
|
public static readonly viewType = "codeQLMethodModeling";
|
||||||
|
|
||||||
|
private webviewView: vscode.WebviewView | undefined = undefined;
|
||||||
|
|
||||||
constructor(private readonly context: vscode.ExtensionContext) {}
|
constructor(private readonly context: vscode.ExtensionContext) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,6 +42,17 @@ export class MethodModelingViewProvider implements WebviewViewProvider {
|
|||||||
webviewView.webview.html = html;
|
webviewView.webview.html = html;
|
||||||
|
|
||||||
webviewView.webview.onDidReceiveMessage(async (msg) => this.onMessage(msg));
|
webviewView.webview.onDidReceiveMessage(async (msg) => this.onMessage(msg));
|
||||||
|
|
||||||
|
this.webviewView = webviewView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async setMethod(method: ExternalApiUsage): Promise<void> {
|
||||||
|
if (this.webviewView) {
|
||||||
|
await this.webviewView.webview.postMessage({
|
||||||
|
t: "setMethod",
|
||||||
|
method,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async onMessage(msg: FromMethodModelingMessage): Promise<void> {
|
private async onMessage(msg: FromMethodModelingMessage): Promise<void> {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { DisposableObject } from "../common/disposable-object";
|
|||||||
import { MethodsUsagePanel } from "./methods-usage/methods-usage-panel";
|
import { MethodsUsagePanel } from "./methods-usage/methods-usage-panel";
|
||||||
import { Mode } from "./shared/mode";
|
import { Mode } from "./shared/mode";
|
||||||
import { showResolvableLocation } from "../databases/local-databases/locations";
|
import { showResolvableLocation } from "../databases/local-databases/locations";
|
||||||
import { Usage } from "./external-api-usage";
|
import { ExternalApiUsage, Usage } from "./external-api-usage";
|
||||||
import { setUpPack } from "./model-editor-queries";
|
import { setUpPack } from "./model-editor-queries";
|
||||||
import { MethodModelingPanel } from "./method-modeling/method-modeling-panel";
|
import { MethodModelingPanel } from "./method-modeling/method-modeling-panel";
|
||||||
|
|
||||||
@@ -26,6 +26,7 @@ const SUPPORTED_LANGUAGES: string[] = ["java", "csharp"];
|
|||||||
export class ModelEditorModule extends DisposableObject {
|
export class ModelEditorModule extends DisposableObject {
|
||||||
private readonly queryStorageDir: string;
|
private readonly queryStorageDir: string;
|
||||||
private readonly methodsUsagePanel: MethodsUsagePanel;
|
private readonly methodsUsagePanel: MethodsUsagePanel;
|
||||||
|
private readonly methodModelingPanel: MethodModelingPanel;
|
||||||
|
|
||||||
private mostRecentlyActiveView: ModelEditorView | undefined = undefined;
|
private mostRecentlyActiveView: ModelEditorView | undefined = undefined;
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ export class ModelEditorModule extends DisposableObject {
|
|||||||
super();
|
super();
|
||||||
this.queryStorageDir = join(baseQueryStorageDir, "model-editor-results");
|
this.queryStorageDir = join(baseQueryStorageDir, "model-editor-results");
|
||||||
this.methodsUsagePanel = this.push(new MethodsUsagePanel(cliServer));
|
this.methodsUsagePanel = this.push(new MethodsUsagePanel(cliServer));
|
||||||
this.push(new MethodModelingPanel(ctx));
|
this.methodModelingPanel = this.push(new MethodModelingPanel(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleViewBecameActive(view: ModelEditorView): void {
|
private handleViewBecameActive(view: ModelEditorView): void {
|
||||||
@@ -149,7 +150,7 @@ export class ModelEditorModule extends DisposableObject {
|
|||||||
modelFile,
|
modelFile,
|
||||||
Mode.Application,
|
Mode.Application,
|
||||||
this.methodsUsagePanel.setState.bind(this.methodsUsagePanel),
|
this.methodsUsagePanel.setState.bind(this.methodsUsagePanel),
|
||||||
this.methodsUsagePanel.revealItem.bind(this.methodsUsagePanel),
|
this.showMethod.bind(this),
|
||||||
this.handleViewBecameActive.bind(this),
|
this.handleViewBecameActive.bind(this),
|
||||||
this.handleViewWasDisposed.bind(this),
|
this.handleViewWasDisposed.bind(this),
|
||||||
this.isMostRecentlyActiveView.bind(this),
|
this.isMostRecentlyActiveView.bind(this),
|
||||||
@@ -173,4 +174,24 @@ export class ModelEditorModule extends DisposableObject {
|
|||||||
private async initialize(): Promise<void> {
|
private async initialize(): Promise<void> {
|
||||||
await ensureDir(this.queryStorageDir);
|
await ensureDir(this.queryStorageDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async showMethod(usage: Usage): Promise<void> {
|
||||||
|
await this.methodsUsagePanel.revealItem(usage);
|
||||||
|
|
||||||
|
// For now, just construct a dummy method and show it in the method modeling panel
|
||||||
|
// because the method isn't easily accessible yet.
|
||||||
|
const method: ExternalApiUsage = {
|
||||||
|
library: "sql2o",
|
||||||
|
libraryVersion: "1.6.0",
|
||||||
|
signature: "org.sql2o.Connection#createQuery(String)",
|
||||||
|
packageName: "org.sql2o",
|
||||||
|
typeName: "Connection",
|
||||||
|
methodName: "createQuery",
|
||||||
|
methodParameters: "(String)",
|
||||||
|
supported: true,
|
||||||
|
supportedType: "summary",
|
||||||
|
usages: [],
|
||||||
|
};
|
||||||
|
await this.methodModelingPanel.setMethod(method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export class ModelEditorView extends AbstractWebview<
|
|||||||
databaseItem: DatabaseItem,
|
databaseItem: DatabaseItem,
|
||||||
hideModeledApis: boolean,
|
hideModeledApis: boolean,
|
||||||
) => Promise<void>,
|
) => Promise<void>,
|
||||||
private readonly revealItemInUsagePanel: (usage: Usage) => Promise<void>,
|
private readonly showMethod: (usage: Usage) => Promise<void>,
|
||||||
private readonly handleViewBecameActive: (view: ModelEditorView) => void,
|
private readonly handleViewBecameActive: (view: ModelEditorView) => void,
|
||||||
private readonly handleViewWasDisposed: (view: ModelEditorView) => void,
|
private readonly handleViewWasDisposed: (view: ModelEditorView) => void,
|
||||||
private readonly isMostRecentlyActiveView: (
|
private readonly isMostRecentlyActiveView: (
|
||||||
@@ -268,7 +268,7 @@ export class ModelEditorView extends AbstractWebview<
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async handleJumpToUsage(usage: Usage) {
|
protected async handleJumpToUsage(usage: Usage) {
|
||||||
await this.revealItemInUsagePanel(usage);
|
await this.showMethod(usage);
|
||||||
await showResolvableLocation(usage.url, this.databaseItem, this.app.logger);
|
await showResolvableLocation(usage.url, this.databaseItem, this.app.logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,7 +439,7 @@ export class ModelEditorView extends AbstractWebview<
|
|||||||
modelFile,
|
modelFile,
|
||||||
Mode.Framework,
|
Mode.Framework,
|
||||||
this.updateMethodsUsagePanelState,
|
this.updateMethodsUsagePanelState,
|
||||||
this.revealItemInUsagePanel,
|
this.showMethod,
|
||||||
this.handleViewBecameActive,
|
this.handleViewBecameActive,
|
||||||
this.handleViewWasDisposed,
|
this.handleViewWasDisposed,
|
||||||
this.isMostRecentlyActiveView,
|
this.isMostRecentlyActiveView,
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { useEffect } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { MethodModeling } from "./MethodModeling";
|
import { MethodModeling } from "./MethodModeling";
|
||||||
import { ModelingStatus } from "../model-editor/ModelingStatusIndicator";
|
import { ModelingStatus } from "../model-editor/ModelingStatusIndicator";
|
||||||
import { ExternalApiUsage } from "../../model-editor/external-api-usage";
|
import { ExternalApiUsage } from "../../model-editor/external-api-usage";
|
||||||
|
import { ToMethodModelingMessage } from "../../common/interface-types";
|
||||||
|
import { assertNever } from "../../common/helpers-pure";
|
||||||
|
|
||||||
export function MethodModelingView(): JSX.Element {
|
export function MethodModelingView(): JSX.Element {
|
||||||
|
const [method, setMethod] = useState<ExternalApiUsage | undefined>(undefined);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const listener = (evt: MessageEvent) => {
|
const listener = (evt: MessageEvent) => {
|
||||||
if (evt.origin === window.origin) {
|
if (evt.origin === window.origin) {
|
||||||
// Nothing to do yet.
|
const msg: ToMethodModelingMessage = evt.data;
|
||||||
|
if (msg.t === "setMethod") {
|
||||||
|
setMethod(msg.method);
|
||||||
|
} else {
|
||||||
|
assertNever(msg.t);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// sanitize origin
|
// sanitize origin
|
||||||
const origin = evt.origin.replace(/\n|\r/g, "");
|
const origin = evt.origin.replace(/\n|\r/g, "");
|
||||||
@@ -22,23 +31,12 @@ export function MethodModelingView(): JSX.Element {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
if (!method) {
|
||||||
|
return <>Select method to model</>;
|
||||||
|
}
|
||||||
|
|
||||||
const modelingStatus: ModelingStatus = "saved";
|
const modelingStatus: ModelingStatus = "saved";
|
||||||
const externalApiUsage: ExternalApiUsage = {
|
|
||||||
library: "sql2o",
|
|
||||||
libraryVersion: "1.6.0",
|
|
||||||
signature: "org.sql2o.Connection#createQuery(String)",
|
|
||||||
packageName: "org.sql2o",
|
|
||||||
typeName: "Connection",
|
|
||||||
methodName: "createQuery",
|
|
||||||
methodParameters: "(String)",
|
|
||||||
supported: true,
|
|
||||||
supportedType: "summary",
|
|
||||||
usages: [],
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<MethodModeling
|
<MethodModeling modelingStatus={modelingStatus} externalApiUsage={method} />
|
||||||
modelingStatus={modelingStatus}
|
|
||||||
externalApiUsage={externalApiUsage}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user