Skip to content

Commit bd6a7b2

Browse files
Merge pull request #2679 from github/robertbrignull/data-details-jump
Implementing jumping to location when clicking on a usage in the details panel
2 parents 6791ddb + 1139790 commit bd6a7b2

File tree

7 files changed

+56
-36
lines changed

7 files changed

+56
-36
lines changed

extensions/ql-vscode/src/common/commands.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
} from "../variant-analysis/shared/variant-analysis";
1313
import type { QLDebugConfiguration } from "../debugger/debug-configuration";
1414
import type { QueryTreeViewItem } from "../queries-panel/query-tree-view-item";
15+
import type { Usage } from "../data-extensions-editor/external-api-usage";
1516

1617
// A command function matching the signature that VS Code calls when
1718
// a command is invoked from a context menu on a TreeView with
@@ -304,6 +305,10 @@ export type PackagingCommands = {
304305

305306
export type DataExtensionsEditorCommands = {
306307
"codeQL.openDataExtensionsEditor": () => Promise<void>;
308+
"codeQLDataExtensionsEditor.jumpToUsageLocation": (
309+
usage: Usage,
310+
databaseItem: DatabaseItem,
311+
) => Promise<void>;
307312
};
308313

309314
export type EvalLogViewerCommands = {

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { DataExtensionsEditorView } from "./data-extensions-editor-view";
33
import { DataExtensionsEditorCommands } from "../common/commands";
44
import { CliVersionConstraint, CodeQLCliServer } from "../codeql-cli/cli";
55
import { QueryRunner } from "../query-server";
6-
import { DatabaseManager } from "../databases/local-databases";
6+
import { DatabaseItem, DatabaseManager } from "../databases/local-databases";
77
import { ensureDir } from "fs-extra";
88
import { join } from "path";
99
import { App } from "../common/app";
@@ -23,6 +23,8 @@ import { setUpPack } from "./external-api-usage-query";
2323
import { DisposableObject } from "../common/disposable-object";
2424
import { ModelDetailsPanel } from "./model-details/model-details-panel";
2525
import { Mode } from "./shared/mode";
26+
import { showResolvableLocation } from "../databases/local-databases/locations";
27+
import { Usage } from "./external-api-usage";
2628

2729
const SUPPORTED_LANGUAGES: string[] = ["java", "csharp"];
2830

@@ -145,7 +147,7 @@ export class DataExtensionsEditorModule extends DisposableObject {
145147
db,
146148
modelFile,
147149
Mode.Application,
148-
(usages) => this.modelDetailsPanel.setExternalApiUsages(usages),
150+
this.modelDetailsPanel.setState.bind(this.modelDetailsPanel),
149151
);
150152
await view.openView();
151153
},
@@ -154,6 +156,12 @@ export class DataExtensionsEditorModule extends DisposableObject {
154156
},
155157
);
156158
},
159+
"codeQLDataExtensionsEditor.jumpToUsageLocation": async (
160+
usage: Usage,
161+
databaseItem: DatabaseItem,
162+
) => {
163+
await showResolvableLocation(usage.url, databaseItem, this.app.logger);
164+
},
157165
};
158166
}
159167

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

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ export class DataExtensionsEditorView extends AbstractWebview<
7070
private readonly databaseItem: DatabaseItem,
7171
private readonly extensionPack: ExtensionPack,
7272
private mode: Mode,
73-
private readonly onExternalApiUsagesChanged: (
73+
private readonly updateModelDetailsPanelState: (
7474
externalApiUsages: ExternalApiUsage[],
75+
databaseItem: DatabaseItem,
7576
) => void,
7677
) {
7778
super(ctx);
@@ -235,21 +236,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
235236
protected async jumpToUsage(
236237
location: ResolvableLocationValue,
237238
): Promise<void> {
238-
try {
239-
await showResolvableLocation(location, this.databaseItem);
240-
} catch (e) {
241-
if (e instanceof Error) {
242-
if (e.message.match(/File not found/)) {
243-
void window.showErrorMessage(
244-
"Original file of this result is not in the database's source archive.",
245-
);
246-
} else {
247-
void this.app.logger.log(`Unable to handleMsgFromView: ${e.message}`);
248-
}
249-
} else {
250-
void this.app.logger.log(`Unable to handleMsgFromView: ${e}`);
251-
}
252-
}
239+
await showResolvableLocation(location, this.databaseItem, this.app.logger);
253240
}
254241

255242
protected async loadExistingModeledMethods(): Promise<void> {
@@ -315,7 +302,10 @@ export class DataExtensionsEditorView extends AbstractWebview<
315302
t: "setExternalApiUsages",
316303
externalApiUsages,
317304
});
318-
this.onExternalApiUsagesChanged(externalApiUsages);
305+
this.updateModelDetailsPanelState(
306+
externalApiUsages,
307+
this.databaseItem,
308+
);
319309
} catch (err) {
320310
void showAndLogExceptionWithTelemetry(
321311
this.app.logger,
@@ -503,7 +493,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
503493
addedDatabase,
504494
modelFile,
505495
Mode.Framework,
506-
this.onExternalApiUsagesChanged,
496+
this.updateModelDetailsPanelState,
507497
);
508498
await view.openView();
509499
});

extensions/ql-vscode/src/data-extensions-editor/model-details/model-details-data-provider.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ import {
77
} from "vscode";
88
import { DisposableObject } from "../../common/disposable-object";
99
import { ExternalApiUsage, Usage } from "../external-api-usage";
10+
import { DatabaseItem } from "../../databases/local-databases";
1011

1112
export class ModelDetailsDataProvider
1213
extends DisposableObject
1314
implements TreeDataProvider<ModelDetailsTreeViewItem>
1415
{
1516
private externalApiUsages: ExternalApiUsage[] = [];
17+
private databaseItem: DatabaseItem | undefined = undefined;
1618

1719
private readonly onDidChangeTreeDataEmitter = this.push(
1820
new EventEmitter<void>(),
@@ -22,8 +24,12 @@ export class ModelDetailsDataProvider
2224
return this.onDidChangeTreeDataEmitter.event;
2325
}
2426

25-
public setExternalApiUsages(externalApiUsages: ExternalApiUsage[]): void {
27+
public setState(
28+
externalApiUsages: ExternalApiUsage[],
29+
databaseItem: DatabaseItem,
30+
): void {
2631
this.externalApiUsages = externalApiUsages;
32+
this.databaseItem = databaseItem;
2733
this.onDidChangeTreeDataEmitter.fire();
2834
}
2935

@@ -37,6 +43,11 @@ export class ModelDetailsDataProvider
3743
return {
3844
label: item.label,
3945
collapsibleState: TreeItemCollapsibleState.None,
46+
command: {
47+
title: "Show usage",
48+
command: "codeQLDataExtensionsEditor.jumpToUsageLocation",
49+
arguments: [item, this.databaseItem],
50+
},
4051
};
4152
}
4253
}

extensions/ql-vscode/src/data-extensions-editor/model-details/model-details-panel.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { window } from "vscode";
22
import { DisposableObject } from "../../common/disposable-object";
33
import { ModelDetailsDataProvider } from "./model-details-data-provider";
44
import { ExternalApiUsage } from "../external-api-usage";
5+
import { DatabaseItem } from "../../databases/local-databases";
56

67
export class ModelDetailsPanel extends DisposableObject {
78
private readonly dataProvider: ModelDetailsDataProvider;
@@ -17,7 +18,10 @@ export class ModelDetailsPanel extends DisposableObject {
1718
this.push(treeView);
1819
}
1920

20-
public setExternalApiUsages(externalApiUsages: ExternalApiUsage[]): void {
21-
this.dataProvider.setExternalApiUsages(externalApiUsages);
21+
public setState(
22+
externalApiUsages: ExternalApiUsage[],
23+
databaseItem: DatabaseItem,
24+
): void {
25+
this.dataProvider.setState(externalApiUsages, databaseItem);
2226
}
2327
}

extensions/ql-vscode/src/databases/local-databases/locations.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,19 @@ export function tryResolveLocation(
9797
export async function showResolvableLocation(
9898
loc: ResolvableLocationValue,
9999
databaseItem: DatabaseItem,
100+
logger: Logger,
100101
): Promise<void> {
101-
await showLocation(tryResolveLocation(loc, databaseItem));
102+
try {
103+
await showLocation(tryResolveLocation(loc, databaseItem));
104+
} catch (e) {
105+
if (e instanceof Error && e.message.match(/File not found/)) {
106+
void Window.showErrorMessage(
107+
"Original file of this result is not in the database's source archive.",
108+
);
109+
} else {
110+
void logger.log(`Unable to jump to location: ${getErrorMessage(e)}`);
111+
}
112+
}
102113
}
103114

104115
export async function showLocation(location?: Location) {
@@ -146,16 +157,6 @@ export async function jumpToLocation(
146157
) {
147158
const databaseItem = databaseManager.findDatabaseItem(Uri.parse(databaseUri));
148159
if (databaseItem !== undefined) {
149-
try {
150-
await showResolvableLocation(loc, databaseItem);
151-
} catch (e) {
152-
if (e instanceof Error && e.message.match(/File not found/)) {
153-
void Window.showErrorMessage(
154-
"Original file of this result is not in the database's source archive.",
155-
);
156-
} else {
157-
void logger.log(`Unable to jump to location: ${getErrorMessage(e)}`);
158-
}
159-
}
160+
await showResolvableLocation(loc, databaseItem, logger);
160161
}
161162
}

extensions/ql-vscode/test/unit-tests/command-lint.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ describe("commands declared in package.json", () => {
4444
command.match(/^codeQLQueryHistory\./) ||
4545
command.match(/^codeQLAstViewer\./) ||
4646
command.match(/^codeQLEvalLogViewer\./) ||
47-
command.match(/^codeQLTests\./)
47+
command.match(/^codeQLTests\./) ||
48+
command.match(/^codeQLDataExtensionsEditor\./)
4849
) {
4950
scopedCmds.add(command);
5051
expect(title).toBeDefined();

0 commit comments

Comments
 (0)