Ensure that Identifier source mappings explicitly start and stop on the generated range #8380
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.
Babel's current source map generation logic is a little handwavy in how it generates mappings. Essentially what it does is:
This has served us for a while, but it has some downsides:
In a perfect world, the printers would assign exact locations, or make explicit best-effort attempts to pick a good location, but currently that isn't what we do. While I'm totally for exploring that, it'd be a massive change and it's always hard to tell what other things would break in tooling that consumes Babel's output maps.
This PR attempts to address one specific case where having exact location information is a big improvement:
Identifier
nodes. Consider a simple case like this:With the algorithm I described above, we get:
0
as position0
as positionWhat this means is that there is only a single mapping for this whole line. That is a pain point for any tooling that wants to perform further transformations on the output that Babel produces. Prime examples of this are Rollup and Webpack (and other bundlers I'm sure), which may want to replace
foo
withns.foo
if the code hadimport foo from "foo";
for instance.As mentioned, it would be great to have a better "unified theory of map generation", but this PR aims to address this one specific case.
This PR adds two special cases:
()
in the screenshot below map better.These can be seen in this comparison, with the right being the old mappings, and the left being the new ones:
You can see that the various identifiers are now accurately mapped with their own specific range.
On the off chance you're wondering why we don't do this for all nodes, the main issue is that using the "end" location of a node in general isn't super effective once you have to take generic transformation into account. If an identifier gets moved, there's technically no guarantee that the end of the original location actually maps what's actually getting referenced in the original code. Consider
getting transformed into
then this patch will make the
;
in1
map to the(
in0
. It's not great, but on the other hand we don't really get something useful either way.I've essentially decided to special-case
Identifier
to reduce the risk of breaking things, while still accomplishing useful improvements.Edit
Also, once this lands, I'd like to backport it to
6.x
.