-
Notifications
You must be signed in to change notification settings - Fork 191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add query items immediately #1094
Conversation
This is a large commit and includes all the changes to add query history items immediately. This also includes some smaller related changes that were hit while cleaning this area up. The major part of this change is a refactoring of what we store in the query history list. Previously, the `CompletedQuery` was stored. Previously, objects of this type include all information about a query that was run including: - Its source file and text range (if a quick eval) - Its database - Its label - The query results itself - Metrics about the query run - Metadata about the query itself Now, the item stored is called a `FullQueryInfo`, which has two properties: - InitialQueryInfo: all the data about the query that we know _before_ the query completes, eg- its source file and text range, database, and label - CompletedQueryInfo: all the data about the query that we can only learn _after_ the query completes. This is an optional property. There is also a `failureReason` property, which is an optional string describing why the query failed. There is also a `FullCompletedQueryInfo` type, which only exists to help with stronger typing. It is a `FullQueryInfo` with a non-optional `CompletedQueryInfo`. Most of the changes are around changing how the query history accesses its history list. There are some other smaller changes included here: - New icon for completed query (previously, completed queries had no icons). - New spinning icon for in progress queries. - Better error handling in the logger to handle log messages when the extension is shutting down. This mostly helps clean up the output during tests. - Add more disposables to subscriptions to be disposed of when the extension shuts down.
16c3e66
to
43f5c37
Compare
43f5c37
to
a69dbd7
Compare
if (!finalSingleItem.completedQuery) { | ||
throw new Error('Select a completed query.'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be annoying. Do we want to silently fail in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, better to fail silently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll keep the explicit error in findOtherQueryToCompare
since that may be confusing therwise.
) { | ||
if (!this.assertSingleQuery(multiSelect)) { | ||
return; | ||
} | ||
|
||
if (singleItem.logFileLocation) { | ||
await this.tryOpenExternalFile(singleItem.logFileLocation); | ||
if (!singleItem.completedQuery) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think.
if (!singleItem.completedQuery) { | |
if (!singleItem.isCompleted()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No...that won't work. If I do this, then this causes a compile error later on.
return queryHistoryItem.options.queryText; | ||
} else if (queryHistoryItem.query.quickEvalPosition) { | ||
async getQueryText(queryHistoryItem: FullQueryInfo): Promise<string> { | ||
if (queryHistoryItem.initialInfo.queryText) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait...why would this ever be falsy??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. It can't. Removing.
} | ||
|
||
if (!queryHistoryItem.completedQuery) { | ||
return '<No label>'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be somethng different. (If we can even get here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
*/ | ||
export interface InitialQueryInfo { | ||
userSpecifiedLabel?: string; // if missing, use a default label | ||
readonly queryText?: string; // text of the selected file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why will this ever be falsy???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No...but need to fix up some other types.
} | ||
|
||
get time() { | ||
return this.initialInfo.start.toLocaleString(env.language); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that "time" is now the start time, not the end time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted.
* If there is a completed query, then check if didRunSuccessfully. | ||
* If true, then this query has completed successfully, otherwise it has failed. | ||
*/ | ||
get status(): QueryStatus { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure that query cancelling works as expected. Should have a red X (ie- should be considered a failure).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works.
// interpolate | ||
// time | ||
// label | ||
// getShortLabel | ||
// getQueryFileName | ||
// getQueryName | ||
|
||
// status |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete
Same with "Open query that produced these results". In order to do this, needed to move the query id generation into the InitialQueryInfo.
All comments addressed. I love having conversations with myself. There are some things this PR does not do, but we should probably implement later:
I'll create issues for these. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR (and for walking me through the changes ✨)
Looks great overall - I've just left a few comments where there's some unexpected behaviour!
id: queryId++, | ||
start: new Date(), | ||
... (isQuickEval ? { | ||
queryText: quickEvalText!, // if this query is quick eval, it must have quick eval text |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that "Show Query Text" in the Query History doesn't work for quick evals. As in, the quickEvalText
seems to be an empty string. Possibly a bug in determineSelectedQuery
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm...I'm not able to reproduce. There's probably some case I'm not handling. Can you show me an example query and selection that isn't working?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been testing with quick-evaling https://github.com/github/codeql/blob/lgtm.com/javascript/ql/lib/semmle/javascript/BasicBlocks.qll#L13 on a github/vscode-codeql
database:
With the current version of the extension, I get:
Let me know if you still can't reproduce!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return element ? [] : this.history.sort((h1, h2) => { | ||
const q1 = h1.completedQuery; | ||
const q2 = h2.completedQuery; | ||
|
||
switch (this.sortOrder) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure where in the code to put this comment, but sorting is a bit funny at the moment 🤔 I see the following:
- Run a query. The query is at the bottom of the query history list
- Once the query finishes, it jumps to the top of the list
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes...I see that too. Thanks for pointing this out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing!
This commit fixes two related issues with the history view. 1. Sort order was changing after a query item completed. The fix is a change in how we fire off the `onDidChangeTreeData` event. When the event is fired with a single item, that item is pushed to the top of the list. I'm not exactly sure why this wasn't happening before, but I suspect it was because we were refreshing the list at the same time as we were inserting the new item. The solution here is to always refresh the entire list, instead of single items. This is fine since re building the list is a trivial operation. See the `refreshTreeView()` method. With this change, the sort order is now stable. 2. Originally reported here: #1093 The problem is that the internal treeView selection was not being updated when a new item was being added. Due to some oddities with the way selection works in the tree view (ie- the visible selection does not always match the internal selection). The solution is to use the current item from the `treeDataProvider` in `determineSelection`. Also, this change makes the sorting more precise and fixes some typos.
All comments addressed and problems fixed. Could you take another look, @shati-patel? |
Actually, there's still the issue with the quick eval. Let's chat about that tomorrow. |
3b62f0f
to
dd0a21a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes! 🎉✨
Looks good, just left an example of the quick eval query text bug 😅
id: queryId++, | ||
start: new Date(), | ||
... (isQuickEval ? { | ||
queryText: quickEvalText!, // if this query is quick eval, it must have quick eval text |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been testing with quick-evaling https://github.com/github/codeql/blob/lgtm.com/javascript/ql/lib/semmle/javascript/BasicBlocks.qll#L13 on a github/vscode-codeql
database:
With the current version of the extension, I get:
Let me know if you still can't reproduce!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation now. I think I see the problem.
As far as I can tell, the only difference between the way quick eval text is displayed before and after this PR is that when the quick eval selection is not a selection, but just a single caret location, the entire line is shown as part of the quick eval text. Both before and after, if the quick eval selection is a block of text, exactly that text is shown. This is not ideal, but since it is the same as the old behaviour, I don't think we should change. We could consider being more intelligent about grabbing surrounding text in a future change. |
And looking at how this was implemented in the past, I don't really think this is correct. The logic is that if there is no text saved with the query when it was created, then look at the quick eval location. Expand the location to capture all selected lines. This will be incorrect if the query file has changed after the query has run. I consider this a bug. We should be capturing the query text at the time the query was run. |
Fixes a bug where quick eval was showing empty query text. Previously, `getQueryText` was looking up the query text when it was called if the specified text was empty. This was removed with the recent changes to query history. It was also a bug since the query file could have changed after the query was run. This change ensures that if the quick eval position is empty, the entire line is returned as the quick eval location.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! ✨
Agree that there seems to be some general weirdness around quick eval, but that's out of scope for this PR 😅
This is a large commit and includes all the changes to add query
history items immediately. This also includes some smaller related
changes that were hit while cleaning this area up.
The major part of this change is a refactoring of what we store in
the query history list. Previously, the
CompletedQuery
was stored.Previously, objects of this type include all information about a query that was run
including:
Now, the item stored is called a
FullQueryInfo
, which has twoproperties:
the query completes, eg- its source file and text range, database, and
label
learn after the query completes. This is an optional property.
There is also a
failureReason
property, which is an optional stringdescribing why the query failed.
There is also a
FullCompletedQueryInfo
type, which only exists tohelp with stronger typing. It is a
FullQueryInfo
with a non-optionalCompletedQueryInfo
.Most of the changes are around changing how the query history accesses
its history list.
There are some other smaller changes included here:
icons).
extension is shutting down. This mostly helps clean up the output
during tests.
extension shuts down.
Checklist
ready-for-doc-review
label there.