Merge pull request #2989 from github/koesie10/usage-panel-tree-items-reference

Keep reference to original items in usage data provider
This commit is contained in:
Koen Vlaswinkel
2023-10-18 09:23:30 +02:00
committed by GitHub
3 changed files with 33 additions and 23 deletions

View File

@@ -89,26 +89,26 @@ export class MethodsUsageDataProvider
getTreeItem(item: MethodsUsageTreeViewItem): TreeItem {
if (isMethodTreeViewItem(item)) {
const { method } = item;
return {
label: `${item.packageName}.${item.typeName}.${item.methodName}${item.methodParameters}`,
label: `${method.packageName}.${method.typeName}.${method.methodName}${method.methodParameters}`,
collapsibleState: TreeItemCollapsibleState.Collapsed,
iconPath: this.getModelingStatusIcon(item),
iconPath: this.getModelingStatusIcon(method),
};
} else {
const method = this.getParent(item);
if (!method || !isMethodTreeViewItem(method)) {
throw new Error("Parent not found for tree item");
}
const { method, usage } = item;
return {
label: item.label,
description: `${this.relativePathWithinDatabase(item.url.uri)} [${
item.url.startLine
}, ${item.url.endLine}]`,
label: usage.label,
description: `${this.relativePathWithinDatabase(usage.url.uri)} [${
usage.url.startLine
}, ${usage.url.endLine}]`,
collapsibleState: TreeItemCollapsibleState.None,
command: {
title: "Show usage",
command: "codeQLModelEditor.jumpToMethod",
arguments: [method, item, this.databaseItem],
arguments: [method, usage, this.databaseItem],
},
};
}
@@ -146,7 +146,7 @@ export class MethodsUsageDataProvider
getChildren(item?: MethodsUsageTreeViewItem): MethodsUsageTreeViewItem[] {
if (item === undefined) {
if (this.hideModeledMethods) {
return this.sortedTreeItems.filter((api) => !api.supported);
return this.sortedTreeItems.filter((api) => !api.method.supported);
} else {
return [...this.sortedTreeItems];
}
@@ -172,21 +172,24 @@ export class MethodsUsageDataProvider
usage: Usage,
): UsageTreeViewItem | undefined {
const method = this.sortedTreeItems.find(
(m) => m.signature === methodSignature,
(m) => m.method.signature === methodSignature,
);
if (!method) {
return undefined;
}
return method.children.find((u) => usagesAreEqual(u, usage));
return method.children.find((u) => usagesAreEqual(u.usage, usage));
}
}
type MethodTreeViewItem = Method & {
type MethodTreeViewItem = {
method: Method;
children: UsageTreeViewItem[];
};
type UsageTreeViewItem = Usage & {
type UsageTreeViewItem = {
method: Method;
usage: Usage;
parent: MethodTreeViewItem;
};
@@ -195,7 +198,7 @@ export type MethodsUsageTreeViewItem = MethodTreeViewItem | UsageTreeViewItem;
function isMethodTreeViewItem(
item: MethodsUsageTreeViewItem,
): item is MethodTreeViewItem {
return "children" in item && "usages" in item;
return "children" in item && "method" in item;
}
function usagesAreEqual(u1: Usage, u2: Usage): boolean {
@@ -225,12 +228,13 @@ function sortMethodsInGroups(methods: readonly Method[], mode: Mode): Method[] {
function createTreeItems(methods: readonly Method[]): MethodTreeViewItem[] {
return methods.map((method) => {
const newMethod: MethodTreeViewItem = {
...method,
method,
children: [],
};
newMethod.children = method.usages.map((usage) => ({
...usage,
method,
usage,
// This needs to be a reference to the parent method, not a copy of it.
parent: newMethod,
}));

View File

@@ -246,12 +246,13 @@ describe("MethodsUsageDataProvider", () => {
const usage = createUsage({});
const methodTreeItem: MethodsUsageTreeViewItem = {
...supportedMethod,
method: supportedMethod,
children: [],
};
const usageTreeItem: MethodsUsageTreeViewItem = {
...usage,
method: supportedMethod,
usage,
parent: methodTreeItem,
};
methodTreeItem.children = [usageTreeItem];
@@ -383,7 +384,9 @@ describe("MethodsUsageDataProvider", () => {
expect(
dataProvider
.getChildren()
.map((item) => (item as Method).signature),
.map(
(item) => (item as MethodsUsageTreeViewItem).method.signature,
),
).toEqual(["b.a.C.d()", "b.a.C.b()", "b.a.C.a()", "a.b.C.d()"]);
// reasoning for sort order:
// b.a.C.d() has more usages than b.a.C.b()

View File

@@ -86,7 +86,10 @@ describe("MethodsUsagePanel", () => {
await panel.revealItem(method.signature, usage);
expect(mockTreeView.reveal).toHaveBeenCalledWith(
expect.objectContaining(usage),
expect.objectContaining({
method,
usage,
}),
);
});