Provide completions for template globals #61
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I'm working on generating types for the built-in Ember intrinsics (which is the last remaining thing before "write a Getting Started and then publish"!) when I realized we weren't providing completion suggestions for global values. This includes intrinsics and, in the case of
environment-ember-loose
, everything user-defined as well.The fundamental issue was a small bug in the template rewriting logic, but fixing that unearthed a thornier issue, which is that given the way the system works today, we can't simultaneously provide completions for both in-scope identifiers and global items.
Today when we see a mustache like
{{foo}}
, that might ultimately be emitted asfoo
(iffoo
is an in-scope identifier) or asGlobals['foo']
if it's not. The transformation process takes a list of known static identifiers as input, which is how we know which version to emit, but if as a user I've only typedfo
so far, we can't a priori know whether emittingfo
orGlobals['fo']
is going to yield the completion results we want.The solution here gets the immediate issue unblocked and provide what's hopefully good-enough support for both loose-mode and strict-mode templates. When emitting an identifier, if it's a prefix of a something we statically know is in scope, we emit the prefix directly; otherwise we assume it's a global lookup.
For loose-mode, this should work fine as essentially nothing is ever statically in scope. For strict-mode, this means that you won't get e.g. a completion for
each
when you typeea
ifearlyRiser
is in scope somewhere. That seems like an ok tradeoff to me, but we can always revisit down the line if it turns out to be a problem.