Merge pull request #2977 from github/robertbrignull/fix_jump_to_usage

Revert changes to codeQLModelEditor.jumpToMethod to allow jumping to usages other than the first usage
This commit is contained in:
Robert
2023-10-16 11:21:18 +01:00
committed by GitHub
5 changed files with 39 additions and 15 deletions

View File

@@ -13,6 +13,7 @@ import type {
import type { QLDebugConfiguration } from "../debugger/debug-configuration";
import type { QueryTreeViewItem } from "../queries-panel/query-tree-view-item";
import type { LanguageSelectionTreeViewItem } from "../language-selection-panel/language-selection-data-provider";
import type { Method, Usage } from "../model-editor/method";
// A command function matching the signature that VS Code calls when
// a command is invoked from a context menu on a TreeView with
@@ -333,7 +334,8 @@ export type ModelEditorCommands = {
"codeQL.openModelEditor": () => Promise<void>;
"codeQL.openModelEditorFromModelingPanel": () => Promise<void>;
"codeQLModelEditor.jumpToMethod": (
methodSignature: string,
method: Method,
usage: Usage,
databaseItem: DatabaseItem,
) => Promise<void>;
};

View File

@@ -106,7 +106,7 @@ export class MethodsUsageDataProvider
command: {
title: "Show usage",
command: "codeQLModelEditor.jumpToMethod",
arguments: [method.signature, this.databaseItem],
arguments: [method, item, this.databaseItem],
},
};
}

View File

@@ -77,10 +77,11 @@ export class ModelEditorModule extends DisposableObject {
"codeQL.openModelEditorFromModelingPanel":
this.openModelEditor.bind(this),
"codeQLModelEditor.jumpToMethod": async (
methodSignature: string,
method: Method,
usage: Usage,
databaseItem: DatabaseItem,
) => {
this.modelingStore.setSelectedMethod(databaseItem, methodSignature);
this.modelingStore.setSelectedMethod(databaseItem, method, usage);
},
};
}

View File

@@ -374,7 +374,17 @@ export class ModelEditorView extends AbstractWebview<
}
protected async handleJumpToMethod(methodSignature: string) {
this.modelingStore.setSelectedMethod(this.databaseItem, methodSignature);
const method = this.modelingStore.getMethod(
this.databaseItem,
methodSignature,
);
if (method) {
this.modelingStore.setSelectedMethod(
this.databaseItem,
method,
method.usages[0],
);
}
}
protected async loadExistingModeledMethods(): Promise<void> {

View File

@@ -230,6 +230,19 @@ export class ModelingStore extends DisposableObject {
return this.state.size > 0;
}
/**
* Returns the method for the given database item and method signature.
* Returns undefined if no method exists with that signature.
*/
public getMethod(
dbItem: DatabaseItem,
methodSignature: string,
): Method | undefined {
return this.getState(dbItem).methods.find(
(m) => m.signature === methodSignature,
);
}
/**
* Returns the methods for the given database item and method signatures.
* If the `methodSignatures` argument is not provided or is undefined, returns all methods.
@@ -388,18 +401,16 @@ export class ModelingStore extends DisposableObject {
});
}
public setSelectedMethod(dbItem: DatabaseItem, methodSignature: string) {
/**
* Sets which method is considered to be selected. This method will be shown in the method modeling panel.
*
* The `Method` and `Usage` objects must have been retrieved from the modeling store, and not from
* a webview. This is because we rely on object referential identity so it must be the same object
* that is held internally by the modeling store.
*/
public setSelectedMethod(dbItem: DatabaseItem, method: Method, usage: Usage) {
const dbState = this.getState(dbItem);
const method = dbState.methods.find((m) => m.signature === methodSignature);
if (method === undefined) {
throw new Error(
`No method with signature "${methodSignature}" found in modeling store`,
);
}
const usage = method.usages[0];
dbState.selectedMethod = method;
dbState.selectedUsage = usage;