Skip to content

Scopes: Add section that establishes relationship between Mappings and Scopes#245

Open
szuend wants to merge 1 commit into
tc39:proposal-scopesfrom
szuend:mappings-relationship
Open

Scopes: Add section that establishes relationship between Mappings and Scopes#245
szuend wants to merge 1 commit into
tc39:proposal-scopesfrom
szuend:mappings-relationship

Conversation

@szuend
Copy link
Copy Markdown
Collaborator

@szuend szuend commented Mar 3, 2026

Preview

This is an outline how we could spec mappings <-> scopes relationship. The current proposal is that it's fine if either mappings or scopes (or both) don't map a position. But if they do, the mapping needs to point into the scope that corresponds to the generated range.

@szuend szuend requested review from jridgewell and takikawa March 3, 2026 11:29
@hbenl
Copy link
Copy Markdown
Collaborator

hbenl commented Mar 26, 2026

I think we should require a bit more: Imagine you have nested generated ranges G1 and G2 and nested original scopes O1 and O2 with the definition of G1 being O1 and that of G2 being O2 and a mapping that points from a generated position in G1 but outside G2 to an original position in O2. This mapping would be allowed by this algorithm but it should be flagged as inconsistent in my opinion.
Note that if O2 is a block scope that was removed during transpilation (so we don't have G2), then mapping a position in G1 to one in O2 is consistent. Simply checking if the innermost original scope for the mapping equals the definition of the innermost generated range would incorrectly flag this as inconsistent.

@szuend
Copy link
Copy Markdown
Collaborator Author

szuend commented Mar 26, 2026

I can think of 2 solutions (although I'm not 100% sure if these are correct, I'd have to think about it some more):

  • We lookup the inner-most original scope but require it to be a descendent of [[Definition]].
  • We require strict equality between "inner-most scope" and "inner-most range". In your example, we could consider it a broken generator. It's a generator that emits code for an original scope, but doesn't emit a corresponding range. Even if it inlines the actual lexical scope, it should technically still emit a range G2 (similar to an inlined function range) that points to O2. If the code was transformed in a way where the generated code no longer reflects O2, then it should be either unmapped or the mapping should also point to O1.

@szuend szuend force-pushed the mappings-relationship branch from 8176c16 to e6a63eb Compare May 27, 2026 09:38
@szuend
Copy link
Copy Markdown
Collaborator Author

szuend commented May 29, 2026

Presented this PR (with slides in the TG4 meeting.

Re holgers comment: As seen in the slide we can't be that strict due to upwards code motion.

Some key points from the meeting:

  • Tentative agreement that mappings and scope/range boundaries should play well together. E.g. to ensure mapping call locations make sense
  • Some discussions around what to do about constant propagation, or the general "expression inlining case". As outlined in the slides, generators can take two approaches:
    1. Emit a generated range for any inlined expression, even literals. Then mappings can point back to the original literal ("literal mapping").
    2. Don't emit a generated range, then the mapping has to point to the location where the literal was inlined.
  • In the general "expression inlining case", 1) makes more sense. For trivial expressions like literals, 2) would make more sense from a debugger stepping behavior.
  • Both approaches are valid w.r.t. to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants