tc39 / source-map

Source map specification, RFCs and new proposals.

Home Page:https://tc39.es/source-map/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Scopes: support default parameter initializers

hbenl opened this issue · comments

From MDN:

The default parameter initializers live in their own scope, which is a parent of the scope created for the function body.

To support this we need to add some information for function scopes:

  • which of the scope's variables are parameters
  • the location range for the special scope for default parameter initializers (i.e. the location range of the function's parameter declarations)

I think this could be supported with the current proposal by encoding two sibling scopes for each function: one containing only the parameters and with the location range of the parameter declarations and one containing parameters and local variables with the location range of the function's body.
Note that this is only necessary if the function declaration contains default parameter initializers and some of the initializers reference other parameters. Otherwise the initializers are effectively evaluated in the parent scope and no special scope for the initializers needs to be added to the sourcemap.

I'm not sure about sibling scopes, but we could handle it similar to how JS engines do this. (See this comment):

  • The function scope starts at the opening paren of the function declaration. It contains the parameters.
  • If default initializers are used, emit a child block scope that starts at the opening brace, but contains the full function body.

I'm not sure about sibling scopes, but we could handle it similar to how JS engines do this.

Right, and actually the documentation at MDN also suggests this (because it says the extra scope should be the parent of the function body's scope) and this is also more efficient (because we don't need to repeat the function parameters).

If default initializers are used, emit a child block scope that starts at the opening brace, but contains the full function body.

Actually I found that the extra scope is only created when it's absolutely necessary: when default initializers are used and one of the initializers references a variable that is redeclared in the function's body.
This is important because we need to match the scopes we get from the debugger to the GeneratedRanges described in the sourcemap in order to compute the original scopes.

I found that the extra scope is only created when it's absolutely necessary: when default initializers are used and one of the initializers references a variable that is redeclared in the function's body.

I was wrong about this - it seems the extra scope is created when default initializers are used and there is a variable declaration in the body. Generally JS engines seem to omit scopes without bindings.

I've added examples showing how this can be done using the current proposal.