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.
This may be annoying. Do we want to silently fail in this case?
There was a problem hiding this comment.
Yes, better to fail silently.
There was a problem hiding this comment.
I'll keep the explicit error in findOtherQueryToCompare since that may be confusing therwise.
|
|
||
| if (singleItem.logFileLocation) { | ||
| await this.tryOpenExternalFile(singleItem.logFileLocation); | ||
| if (!singleItem.completedQuery) { |
There was a problem hiding this comment.
I think.
| if (!singleItem.completedQuery) { | |
| if (!singleItem.isCompleted()) { |
There was a problem hiding this comment.
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.
Wait...why would this ever be falsy??
There was a problem hiding this comment.
No. It can't. Removing.
| } | ||
|
|
||
| if (!queryHistoryItem.completedQuery) { | ||
| return '<No label>'; |
There was a problem hiding this comment.
I think this should be somethng different. (If we can even get here)
| */ | ||
| 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.
Why will this ever be falsy???
There was a problem hiding this comment.
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.
Note that "time" is now the start time, not the end time.
| * 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.
Make sure that query cancelling works as expected. Should have a red X (ie- should be considered a failure).
| // interpolate | ||
| // time | ||
| // label | ||
| // getShortLabel | ||
| // getQueryFileName | ||
| // getQueryName | ||
|
|
||
| // status |
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. |
shati-patel
left a comment
There was a problem hiding this comment.
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.
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.
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.
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!
| const q1 = h1.completedQuery; | ||
| const q2 = h2.completedQuery; | ||
|
|
||
| switch (this.sortOrder) { |
There was a problem hiding this comment.
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.
Yes...I see that too. Thanks for pointing this out.
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
shati-patel
left a comment
There was a problem hiding this comment.
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.
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!
aeisenberg
left a comment
There was a problem hiding this comment.
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.
shati-patel
left a comment
There was a problem hiding this comment.
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
CompletedQuerywas 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
failureReasonproperty, which is an optional stringdescribing why the query failed.
There is also a
FullCompletedQueryInfotype, which only exists tohelp with stronger typing. It is a
FullQueryInfowith 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-reviewlabel there.