Skip to content

Commit 9e92c6c

Browse files
authored
Merge pull request #2857 from github/charisk/initial-modeling-store
Introduce modeling store and move some state there
2 parents 3be7eb9 + c77a300 commit 9e92c6c

File tree

7 files changed

+262
-81
lines changed

7 files changed

+262
-81
lines changed

extensions/ql-vscode/src/model-editor/methods-usage/methods-usage-panel.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@ import {
77
import { Method, Usage } from "../method";
88
import { DatabaseItem } from "../../databases/local-databases";
99
import { CodeQLCliServer } from "../../codeql-cli/cli";
10+
import { ModelingStore } from "../modeling-store";
1011

1112
export class MethodsUsagePanel extends DisposableObject {
1213
private readonly dataProvider: MethodsUsageDataProvider;
1314
private readonly treeView: TreeView<MethodsUsageTreeViewItem>;
1415

15-
public constructor(cliServer: CodeQLCliServer) {
16+
public constructor(
17+
private readonly modelingStore: ModelingStore,
18+
cliServer: CodeQLCliServer,
19+
) {
1620
super();
1721

1822
this.dataProvider = new MethodsUsageDataProvider(cliServer);
@@ -21,6 +25,8 @@ export class MethodsUsagePanel extends DisposableObject {
2125
treeDataProvider: this.dataProvider,
2226
});
2327
this.push(this.treeView);
28+
29+
this.registerToModelingStoreEvents();
2430
}
2531

2632
public async setState(
@@ -44,4 +50,39 @@ export class MethodsUsagePanel extends DisposableObject {
4450
await this.treeView.reveal(canonicalUsage);
4551
}
4652
}
53+
54+
private registerToModelingStoreEvents(): void {
55+
this.push(
56+
this.modelingStore.onActiveDbChanged(async () => {
57+
await this.handleStateChangeEvent();
58+
}),
59+
);
60+
61+
this.push(
62+
this.modelingStore.onMethodsChanged(async (event) => {
63+
if (event.isActiveDb) {
64+
await this.handleStateChangeEvent();
65+
}
66+
}),
67+
);
68+
69+
this.push(
70+
this.modelingStore.onHideModeledMethodsChanged(async (event) => {
71+
if (event.isActiveDb) {
72+
await this.handleStateChangeEvent();
73+
}
74+
}),
75+
);
76+
}
77+
78+
private async handleStateChangeEvent(): Promise<void> {
79+
const activeState = this.modelingStore.getStateForActiveDb();
80+
if (activeState !== undefined) {
81+
await this.setState(
82+
activeState.methods,
83+
activeState.databaseItem,
84+
activeState.hideModeledMethods,
85+
);
86+
}
87+
}
4788
}

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

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ import { showResolvableLocation } from "../databases/local-databases/locations";
1919
import { Method, Usage } from "./method";
2020
import { setUpPack } from "./model-editor-queries";
2121
import { MethodModelingPanel } from "./method-modeling/method-modeling-panel";
22+
import { ModelingStore } from "./modeling-store";
2223

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

2526
export class ModelEditorModule extends DisposableObject {
2627
private readonly queryStorageDir: string;
28+
private readonly modelingStore: ModelingStore;
2729
private readonly methodsUsagePanel: MethodsUsagePanel;
2830
private readonly methodModelingPanel: MethodModelingPanel;
2931

30-
private mostRecentlyActiveView: ModelEditorView | undefined = undefined;
31-
3232
private constructor(
3333
private readonly app: App,
3434
private readonly databaseManager: DatabaseManager,
@@ -38,24 +38,13 @@ export class ModelEditorModule extends DisposableObject {
3838
) {
3939
super();
4040
this.queryStorageDir = join(baseQueryStorageDir, "model-editor-results");
41-
this.methodsUsagePanel = this.push(new MethodsUsagePanel(cliServer));
41+
this.modelingStore = new ModelingStore(app);
42+
this.methodsUsagePanel = this.push(
43+
new MethodsUsagePanel(this.modelingStore, cliServer),
44+
);
4245
this.methodModelingPanel = this.push(new MethodModelingPanel(app));
4346
}
4447

45-
private handleViewBecameActive(view: ModelEditorView): void {
46-
this.mostRecentlyActiveView = view;
47-
}
48-
49-
private handleViewWasDisposed(view: ModelEditorView): void {
50-
if (this.mostRecentlyActiveView === view) {
51-
this.mostRecentlyActiveView = undefined;
52-
}
53-
}
54-
55-
private isMostRecentlyActiveView(view: ModelEditorView): boolean {
56-
return this.mostRecentlyActiveView === view;
57-
}
58-
5948
public static async initialize(
6049
app: App,
6150
databaseManager: DatabaseManager,
@@ -153,6 +142,7 @@ export class ModelEditorModule extends DisposableObject {
153142

154143
const view = new ModelEditorView(
155144
this.app,
145+
this.modelingStore,
156146
this.databaseManager,
157147
this.cliServer,
158148
this.queryRunner,
@@ -161,16 +151,15 @@ export class ModelEditorModule extends DisposableObject {
161151
db,
162152
modelFile,
163153
Mode.Application,
164-
this.methodsUsagePanel.setState.bind(this.methodsUsagePanel),
165154
this.showMethod.bind(this),
166-
this.handleViewBecameActive.bind(this),
167-
(view) => {
168-
this.handleViewWasDisposed(view);
169-
void cleanupQueryDir();
170-
},
171-
this.isMostRecentlyActiveView.bind(this),
172155
);
173156

157+
this.modelingStore.onDbClosed(async (dbUri) => {
158+
if (dbUri === db.databaseUri.toString()) {
159+
await cleanupQueryDir();
160+
}
161+
});
162+
174163
this.push(view);
175164
this.push({
176165
dispose(): void {

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

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,18 @@ import { loadModeledMethods, saveModeledMethods } from "./modeled-method-fs";
4141
import { pickExtensionPack } from "./extension-pack-picker";
4242
import { getLanguageDisplayName } from "../common/query-language";
4343
import { AutoModeler } from "./auto-modeler";
44-
import { INITIAL_HIDE_MODELED_METHODS_VALUE } from "./shared/hide-modeled-methods";
4544
import { telemetryListener } from "../common/vscode/telemetry";
45+
import { ModelingStore } from "./modeling-store";
4646

4747
export class ModelEditorView extends AbstractWebview<
4848
ToModelEditorMessage,
4949
FromModelEditorMessage
5050
> {
5151
private readonly autoModeler: AutoModeler;
5252

53-
private methods: Method[];
54-
private hideModeledMethods: boolean;
55-
5653
public constructor(
5754
protected readonly app: App,
55+
private readonly modelingStore: ModelingStore,
5856
private readonly databaseManager: DatabaseManager,
5957
private readonly cliServer: CodeQLCliServer,
6058
private readonly queryRunner: QueryRunner,
@@ -63,23 +61,16 @@ export class ModelEditorView extends AbstractWebview<
6361
private readonly databaseItem: DatabaseItem,
6462
private readonly extensionPack: ExtensionPack,
6563
private mode: Mode,
66-
private readonly updateMethodsUsagePanelState: (
67-
methods: Method[],
68-
databaseItem: DatabaseItem,
69-
hideModeledMethods: boolean,
70-
) => Promise<void>,
7164
private readonly showMethod: (
7265
method: Method,
7366
usage: Usage,
7467
) => Promise<void>,
75-
private readonly handleViewBecameActive: (view: ModelEditorView) => void,
76-
private readonly handleViewWasDisposed: (view: ModelEditorView) => void,
77-
private readonly isMostRecentlyActiveView: (
78-
view: ModelEditorView,
79-
) => boolean,
8068
) {
8169
super(app);
8270

71+
this.modelingStore.initializeStateForDb(databaseItem);
72+
this.registerToModelingStoreEvents();
73+
8374
this.autoModeler = new AutoModeler(
8475
app,
8576
cliServer,
@@ -97,8 +88,6 @@ export class ModelEditorView extends AbstractWebview<
9788
await this.postMessage({ t: "addModeledMethods", modeledMethods });
9889
},
9990
);
100-
this.methods = [];
101-
this.hideModeledMethods = INITIAL_HIDE_MODELED_METHODS_VALUE;
10291
}
10392

10493
public async openView() {
@@ -107,20 +96,15 @@ export class ModelEditorView extends AbstractWebview<
10796

10897
panel.onDidChangeViewState(async () => {
10998
if (panel.active) {
110-
this.handleViewBecameActive(this);
111-
await this.updateMethodsUsagePanelState(
112-
this.methods,
113-
this.databaseItem,
114-
this.hideModeledMethods,
115-
);
99+
this.modelingStore.setActiveDb(this.databaseItem);
116100
await this.markModelEditorAsActive();
117101
} else {
118102
await this.updateModelEditorActiveContext();
119103
}
120104
});
121105

122106
panel.onDidDispose(() => {
123-
this.handleViewWasDisposed(this);
107+
this.modelingStore.removeDb(this.databaseItem);
124108
// onDidDispose is called after the tab has been closed,
125109
// so we want to check if there are any others still open.
126110
void this.app.commands.execute(
@@ -309,11 +293,11 @@ export class ModelEditorView extends AbstractWebview<
309293
break;
310294
case "switchMode":
311295
this.mode = msg.mode;
312-
this.methods = [];
296+
this.modelingStore.setMethods(this.databaseItem, []);
313297
await Promise.all([
314298
this.postMessage({
315299
t: "setMethods",
316-
methods: this.methods,
300+
methods: [],
317301
}),
318302
this.setViewState(),
319303
withProgress((progress) => this.loadMethods(progress), {
@@ -324,11 +308,9 @@ export class ModelEditorView extends AbstractWebview<
324308

325309
break;
326310
case "hideModeledMethods":
327-
this.hideModeledMethods = msg.hideModeledMethods;
328-
await this.updateMethodsUsagePanelState(
329-
this.methods,
311+
this.modelingStore.setHideModeledMethods(
330312
this.databaseItem,
331-
this.hideModeledMethods,
313+
msg.hideModeledMethods,
332314
);
333315
void telemetryListener?.sendUIInteraction(
334316
"model-editor-hide-modeled-methods",
@@ -409,19 +391,8 @@ export class ModelEditorView extends AbstractWebview<
409391
if (!queryResult) {
410392
return;
411393
}
412-
this.methods = queryResult;
413394

414-
await this.postMessage({
415-
t: "setMethods",
416-
methods: this.methods,
417-
});
418-
if (this.isMostRecentlyActiveView(this)) {
419-
await this.updateMethodsUsagePanelState(
420-
this.methods,
421-
this.databaseItem,
422-
this.hideModeledMethods,
423-
);
424-
}
395+
this.modelingStore.setMethods(this.databaseItem, queryResult);
425396
} catch (err) {
426397
void showAndLogExceptionWithTelemetry(
427398
this.app.logger,
@@ -527,6 +498,7 @@ export class ModelEditorView extends AbstractWebview<
527498

528499
const view = new ModelEditorView(
529500
this.app,
501+
this.modelingStore,
530502
this.databaseManager,
531503
this.cliServer,
532504
this.queryRunner,
@@ -535,11 +507,7 @@ export class ModelEditorView extends AbstractWebview<
535507
addedDatabase,
536508
modelFile,
537509
Mode.Framework,
538-
this.updateMethodsUsagePanelState,
539510
this.showMethod,
540-
this.handleViewBecameActive,
541-
this.handleViewWasDisposed,
542-
this.isMostRecentlyActiveView,
543511
);
544512
await view.openView();
545513
});
@@ -617,4 +585,17 @@ export class ModelEditorView extends AbstractWebview<
617585

618586
return addedDatabase;
619587
}
588+
589+
private registerToModelingStoreEvents() {
590+
this.push(
591+
this.modelingStore.onMethodsChanged(async (event) => {
592+
if (event.dbUri === this.databaseItem.databaseUri.toString()) {
593+
await this.postMessage({
594+
t: "setMethods",
595+
methods: event.methods,
596+
});
597+
}
598+
}),
599+
);
600+
}
620601
}

0 commit comments

Comments
 (0)