Skip to content

Commit daf389a

Browse files
Merge pull request #2678 from github/robert-nora/model-details-data
Populate details panel with external API usages
2 parents 0aae739 + 29916be commit daf389a

File tree

5 files changed

+100
-3
lines changed

5 files changed

+100
-3
lines changed

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@ import { redactableError } from "../common/errors";
2020
import { extLogger } from "../common/logging/vscode";
2121
import { isQueryLanguage } from "../common/query-language";
2222
import { setUpPack } from "./external-api-usage-query";
23+
import { DisposableObject } from "../common/disposable-object";
24+
import { ModelDetailsPanel } from "./model-details/model-details-panel";
25+
import { Mode } from "./shared/mode";
2326

2427
const SUPPORTED_LANGUAGES: string[] = ["java", "csharp"];
2528

26-
export class DataExtensionsEditorModule {
29+
export class DataExtensionsEditorModule extends DisposableObject {
2730
private readonly queryStorageDir: string;
31+
private readonly modelDetailsPanel: ModelDetailsPanel;
2832

2933
private constructor(
3034
private readonly ctx: ExtensionContext,
@@ -34,10 +38,12 @@ export class DataExtensionsEditorModule {
3438
private readonly queryRunner: QueryRunner,
3539
baseQueryStorageDir: string,
3640
) {
41+
super();
3742
this.queryStorageDir = join(
3843
baseQueryStorageDir,
3944
"data-extensions-editor-results",
4045
);
46+
this.modelDetailsPanel = this.push(new ModelDetailsPanel());
4147
}
4248

4349
public static async initialize(
@@ -138,6 +144,8 @@ export class DataExtensionsEditorModule {
138144
queryDir,
139145
db,
140146
modelFile,
147+
Mode.Application,
148+
(usages) => this.modelDetailsPanel.setExternalApiUsages(usages),
141149
);
142150
await view.openView();
143151
},

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,10 @@ export class DataExtensionsEditorView extends AbstractWebview<
7676
private readonly queryDir: string,
7777
private readonly databaseItem: DatabaseItem,
7878
private readonly extensionPack: ExtensionPack,
79-
private mode: Mode = Mode.Application,
79+
private mode: Mode,
80+
private readonly onExternalApiUsagesChanged: (
81+
externalApiUsages: ExternalApiUsage[],
82+
) => void,
8083
) {
8184
super(ctx);
8285
}
@@ -307,6 +310,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
307310
t: "setExternalApiUsages",
308311
externalApiUsages,
309312
});
313+
this.onExternalApiUsagesChanged(externalApiUsages);
310314
} catch (err) {
311315
void showAndLogExceptionWithTelemetry(
312316
this.app.logger,
@@ -588,6 +592,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
588592
addedDatabase,
589593
modelFile,
590594
Mode.Framework,
595+
this.onExternalApiUsagesChanged,
591596
);
592597
await view.openView();
593598
});

extensions/ql-vscode/src/data-extensions-editor/external-api-usage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export enum CallClassification {
1313
Generated = "generated",
1414
}
1515

16-
type Usage = Call & {
16+
export type Usage = Call & {
1717
classification: CallClassification;
1818
};
1919

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import {
2+
Event,
3+
EventEmitter,
4+
TreeDataProvider,
5+
TreeItem,
6+
TreeItemCollapsibleState,
7+
} from "vscode";
8+
import { DisposableObject } from "../../common/disposable-object";
9+
import { ExternalApiUsage, Usage } from "../external-api-usage";
10+
11+
export class ModelDetailsDataProvider
12+
extends DisposableObject
13+
implements TreeDataProvider<ModelDetailsTreeViewItem>
14+
{
15+
private externalApiUsages: ExternalApiUsage[] = [];
16+
17+
private readonly onDidChangeTreeDataEmitter = this.push(
18+
new EventEmitter<void>(),
19+
);
20+
21+
public get onDidChangeTreeData(): Event<void> {
22+
return this.onDidChangeTreeDataEmitter.event;
23+
}
24+
25+
public setExternalApiUsages(externalApiUsages: ExternalApiUsage[]): void {
26+
this.externalApiUsages = externalApiUsages;
27+
this.onDidChangeTreeDataEmitter.fire();
28+
}
29+
30+
getTreeItem(item: ModelDetailsTreeViewItem): TreeItem {
31+
if (isExternalApiUsage(item)) {
32+
return {
33+
label: item.signature,
34+
collapsibleState: TreeItemCollapsibleState.Collapsed,
35+
};
36+
} else {
37+
return {
38+
label: item.label,
39+
collapsibleState: TreeItemCollapsibleState.None,
40+
};
41+
}
42+
}
43+
44+
getChildren(item?: ModelDetailsTreeViewItem): ModelDetailsTreeViewItem[] {
45+
if (item === undefined) {
46+
return this.externalApiUsages;
47+
} else if (isExternalApiUsage(item)) {
48+
return item.usages;
49+
} else {
50+
return [];
51+
}
52+
}
53+
}
54+
55+
type ModelDetailsTreeViewItem = ExternalApiUsage | Usage;
56+
57+
function isExternalApiUsage(
58+
item: ModelDetailsTreeViewItem,
59+
): item is ExternalApiUsage {
60+
return (item as any).usages !== undefined;
61+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { window } from "vscode";
2+
import { DisposableObject } from "../../common/disposable-object";
3+
import { ModelDetailsDataProvider } from "./model-details-data-provider";
4+
import { ExternalApiUsage } from "../external-api-usage";
5+
6+
export class ModelDetailsPanel extends DisposableObject {
7+
private readonly dataProvider: ModelDetailsDataProvider;
8+
9+
public constructor() {
10+
super();
11+
12+
this.dataProvider = new ModelDetailsDataProvider();
13+
14+
const treeView = window.createTreeView("codeQLModelDetails", {
15+
treeDataProvider: this.dataProvider,
16+
});
17+
this.push(treeView);
18+
}
19+
20+
public setExternalApiUsages(externalApiUsages: ExternalApiUsage[]): void {
21+
this.dataProvider.setExternalApiUsages(externalApiUsages);
22+
}
23+
}

0 commit comments

Comments
 (0)