Skip to content

Introduce helpers for commands that operate on selections#2287

Merged
robertbrignull merged 30 commits intomainfrom
robertbrignull/selection
Apr 27, 2023
Merged

Introduce helpers for commands that operate on selections#2287
robertbrignull merged 30 commits intomainfrom
robertbrignull/selection

Conversation

@robertbrignull
Copy link
Copy Markdown
Contributor

@robertbrignull robertbrignull commented Apr 6, 2023

This PR aims to improve our commands that work on selections of items from the UI. These commands all follow a pattern but currently there's nothing enforcing the arguments the commands take or how they process them. I've added new helper functions and converted all of the commands to use the helpers.

This should hopefully help in the following ways:

  • Enforces the number and types of arguments accepted by the command, and it is not duplicated on each command.
  • The command implementation accepts only the arguments it needs (either single item or array).
  • Consistent error handling for when a command is called in a situation it isn't designed for.

I'm still open for suggestions of how to make this even better. We could definitely reduce duplication even more, or make things more streamlined or safer.

Checklist

  • CHANGELOG.md has been updated to incorporate all user visible changes made by this pull request.
  • Issues have been created for any UI or other user-facing changes made by this pull request.
  • [Maintainers only] If this pull request makes user-facing changes that require documentation changes, open a corresponding docs pull request in the github/codeql repo and add the ready-for-doc-review label there.

@robertbrignull robertbrignull force-pushed the robertbrignull/selection branch from 429ce43 to 14952cf Compare April 24, 2023 15:09
@robertbrignull robertbrignull requested a review from a team April 24, 2023 15:12
@robertbrignull robertbrignull marked this pull request as ready for review April 24, 2023 15:12
@robertbrignull robertbrignull requested a review from a team as a code owner April 24, 2023 15:12
Copy link
Copy Markdown
Contributor

@aeisenberg aeisenberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like this solution.

// A hack to match types that are not an array, which is useful to help avoid
// misusing createSingleSelectionCommand, e.g. where T accidentally gets instantiated
// as DatabaseItem[] instead of DatabaseItem.
type NotArray = object & { length?: never };
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice.

Comment on lines +20 to +25
type SelectionCommand<T extends NotArray> = CreateSupertypeOf<
TreeViewContextMultiSelectionCommandFunction<T> &
TreeViewContextSingleSelectionCommandFunction<T> &
ExplorerSelectionCommandFunction<T>,
(singleItem: T, multiSelect?: T[] | undefined) => Promise<void>
>;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is some great typescript-fu.

if (multiSelect !== undefined && multiSelect.length > 0) {
return f(multiSelect);
} else {
return f([singleItem]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I correct in understanding that if singleItem is undefined, we will be returning f([undefined]) here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the types and my experimentation, singleItem cannot be undefined. If you can find a way to trigger one of our commands and get singleItem to be undefined I'd be very interested to hear. Otherwise I'd prefer to keep our types and code simple.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing those out. The commands around upgrading databases are a little complicated because we kinda have two notions of being "selected". You can click to highlight entries in the list (i.e. the vscode tree view), and this state gets passed through to the codeQLDatabases.upgradeDatabase command if you select to upgrade the databases from the context menu. You can also click "make selected" on a database and this state is managed internally, and this is what is used for the codeQL.upgradeCurrentDatabase or codeQL.runQuery (a.k.a. "Run Query on Selected Database") commands.

Looking at each bit of code:

queryHistoryManager.treeDataProvider.getCurrent(),
).toBeUndefined();
});
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has the behaviour changed or is there a different reason for removing this test?

I can see we've removed some of the tests that were checking for multiple items being passed, when the function should only receive a single item. I think for those cases, it makes sense for the tests to become redundant.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm deleting this test because it was covering the case of having multiple items selected. I don't quite understand why it's named "double click", but in practice it's calling handleItemClicked as if two items in the query history are selected, and then asserting it ignores it and does nothing. It's now no longer possible to pass two items to handleItemClicked, so we don't need this test anymore.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's now no longer possible to pass two items to handleItemClicked, so we don't need this test anymore.

Ah, I see. Thanks for explaining!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the reason we added the test in the first place was because double clicking was causing problems and we fixed the issue. We wanted to make sure we account for the behaviour. It was kind of a superfluous test if we were already testing this in other places. Perhaps it was me not having a proper overview of the existing tests when this was introduced. Anyway, I agree we don't need this.

Conflicts:
	extensions/ql-vscode/src/databases/local-databases-ui.ts
	extensions/ql-vscode/src/query-history/query-history-manager.ts
@robertbrignull robertbrignull merged commit 29d0483 into main Apr 27, 2023
@robertbrignull robertbrignull deleted the robertbrignull/selection branch April 27, 2023 10:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants