Skip to content

Conversation

@sandersn
Copy link
Member

Fixes #48498

Unchecked JS files gather identifier-based completions. Currently, this search happens instead of getCompletionEntriesFromSymbols for TS/checked JS files. However, identifier-based completions are much lower quality and can be ignored by some editors.

Identifier-based completions should be gathered last, after gathering other completions. That's what this PR does.

Fixes #48498

Unchecked JS files gather identifier-based completions. Currently, this search
happens instead of `getCompletionEntriesFromSymbols` for TS/checked JS
files. However, identifier-based completions are much lower quality and
can be ignored by some editors.

Identifier-based completions should be gathered last, after gathering
other completions. That's what this PR does.
@typescript-bot typescript-bot added Author: Team For Milestone Bug PRs that fix a bug with a specific milestone labels Jun 28, 2022
@andrewbranch
Copy link
Member

Ah, I think your code is basically right but your description is off a bit. There’s a big chunk of completions that already does run first and doesn’t discriminate much between checked and unchecked files: getCompletionData which gathers relevant symbols. getCompletionEntriesFromSymbols runs both for checked and unchecked files too, converting those symbols to actual completion entries. The part you shifted forwards is just about keywords. Those were indeed getting shadowed by the identifiers in the file. It sounded like you were saying that unchecked JS files don’t get any symbol-based / semantic completions whatsoever, which would have been extremely surprising, but thankfully turns out not to be the case.

}

if (!isChecked) {
const uniqueNames = getCompletionEntriesFromSymbols(
Copy link
Member

Choose a reason for hiding this comment

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

So this actually changes the order for unchecked files from

  1. symbols
  2. identifiers
  3. keywords

to

  1. keywords
  2. symbols
  3. identifiers

and I think we still want symbols first.

The (pre-existing) two huge calls to getCompletionEntriesFromSymbols are identical—can we lift and deduplicate that from the if/else? Then, let’s maintain uniqueNames from the result of that throughout the rest of this function so we don’t have to repeatedly regenerate it from entries.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, that makes sense. When I was moving the code around, I missed that entries was side-effected by getCompletionEntriesFromSymbols, and I assumed that the two calls were different since there would be no good reason to duplicate calls like that.

The code is much more elegant now, although reading it raises more questions than before. But those were questions that were hidden by the previous structure, in my opinion.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, the important work is done by mutation and the return value is bonus info... not the best

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, the important work is done by mutation and the return value is bonus info... not the best

@sandersn
Copy link
Member Author

@typescript-bot run dt

(Trying to fix the on-demand DT run)

@sandersn sandersn closed this Jun 29, 2022
@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 29, 2022

Heya @sandersn, I've started to run the parallelized Definitely Typed test suite on this PR at 8d06692. You can monitor the build here.

@sandersn sandersn reopened this Jun 29, 2022
@sandersn
Copy link
Member Author

@typescript-bot run dt

trying again

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 29, 2022

Heya @sandersn, I've started to run the parallelized Definitely Typed test suite on this PR at cd0556d. You can monitor the build here.

uniqueNames: UniqueNameSet,
target: ScriptTarget,
entries: SortedArray<CompletionEntry>): void {
const entryNames = new Set(entries.map(e => e.name));
Copy link
Member

Choose a reason for hiding this comment

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

GitHub isn’t showing me where this function gets called, but is this one redundant with uniqueNames too?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep! I forgot to update that one, but it's the JS identifier-based completion path that I moved to the end of the function.
(So technically it's not required to add items to uniqueNames, but I'm going to, in order to avoid future surprises.)

@sandersn sandersn merged commit cba184f into main Jun 29, 2022
@sandersn sandersn deleted the demote-js-completions-priority branch June 29, 2022 18:05
@microsoft microsoft locked as resolved and limited conversation to collaborators Oct 22, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Author: Team For Milestone Bug PRs that fix a bug with a specific milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IntelliSense in JavaScript is broken when documenting a context for a function in argument (this replaced by globalThis)

4 participants