Skip to content

Conversation

@andrewbranch
Copy link
Member

Fixes #37091
Fixes #37651

#37091 is interesting, because it exposes that the symbols for, say, console and window.console are completely different symbols that just happen to have the same type. There’s really no way to know generally that a member on a given this type is actually the same thing as a symbol that’s declared globally. And as far as I can tell, there’s nothing special in the type system about symbols like window, self, or global, so there’s no mechanism to determine that a given type is the global object type.

So, I’ve introduced a special case heuristic to reject this. completions when the this type is the type of a global by the name self, global, or globalThis. It’s possible to construct a strange environment for yourself where this is wrong, but the stakes are fairly low—you won’t get this.-inserting completions in methods on that type.

I also discovered and fixed #37651 along the way.

Copy link
Member

@amcasey amcasey left a comment

Choose a reason for hiding this comment

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

I was expecting two entries here. Did I misunderstand?

image

}
});
if (!compilationOptions.noLib) {
this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName,
Copy link

Choose a reason for hiding this comment

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

The below code is identical to the front, is there any possibilities to reuse it?

@andrewbranch
Copy link
Member Author

I was expecting two entries here. Did I misunderstand?

@amcasey for the purposes of this PR, at least, forget about the conversation I started in Teams. I didn’t really sense that any of us were in agreement about the best behavior, so I left the sorting and the shadowing as it’s always been. There is a rule baked into the architecture of getCompletionEntriesFromSymbols that locals shadow everything else.

This PR does only two things, despite being related to the other ideas we talked about:

  1. It special-cases methods where the type of this is the type of self, global, or globalThis to prevent offering completions like parseInt -> this.parseInt, since every member symbol is probably available as a global, and preferable to access globally.
  2. In the case where there’s a foo -> this.foo completion and a global foo, fix the details request (Completion details are wrong for 'this.' member when a global exists by the same name #37651).

*/
export enum CompletionSource {
/** Completions that require `this.` insertion text */
ThisProperty = "ThisProperty/"
Copy link
Member

Choose a reason for hiding this comment

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

is "/" intentional at the end?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, it’s explained in the comment—we need these values to be impossible values for an auto-import specifier. If someone had a folder named ThisProperty and a baseUrl set, we could conceivably generate an auto-import suggestion whose source is ThisProperty.

@andrewbranch andrewbranch merged commit 23b500c into microsoft:master Mar 31, 2020
@andrewbranch andrewbranch deleted the bug/37091 branch March 31, 2020 19:41
@microsoft microsoft locked as resolved and limited conversation to collaborators Oct 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

7 participants