Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mark static block as FunctionParent #13832

Merged
merged 5 commits into from Oct 11, 2021

Conversation

JLHwung
Copy link
Contributor

@JLHwung JLHwung commented Oct 8, 2021

Q                       A
Fixed Issues? Babel does not register var bindings to the StaticBlock
Patch: Bug Fix? Y
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT

In this PR we mark StaticBlock as a FunctionParent, it was overlooked in #12079. We also enumerated tests for BlockParent and FunctionParent.

@JLHwung JLHwung added PR: Bug Fix 🐛 A type of pull request used for our changelog categories Spec: Class Static Block labels Oct 8, 2021
@codesandbox-ci
Copy link

codesandbox-ci bot commented Oct 8, 2021

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit c3a7fd9:

Sandbox Source
babel-repl-custom-plugin Configuration
babel-plugin-multi-config Configuration

expect(switchStatement.scope.hasOwnBinding("foo")).toBe(true);
});
});
//todo: decide whether these statements should be scopeable and blockParent
Copy link
Contributor Author

@JLHwung JLHwung Oct 8, 2021

Choose a reason for hiding this comment

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

I don't think WhileStatement and DoWhileStatement should be marked as Scopeable and BlockParent: The expression in while ( ) can not introduce variable declarations.

We can remove them in Babel 8.

Ahh TIL

do
  var x = 1
while (x);

is valid. I will add more tests.

Copy link
Member

Choose a reason for hiding this comment

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

The bindings should be registered in the block inside the loop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah we already register let bindings in the block statements. since

do
  let x;
while (0)

is not allowed. I still think we can remove WhileStatement and DoWhileStatement from Scopeable and BlockParent.

Copy link
Member

Choose a reason for hiding this comment

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

It should match whatever if, for-in, for-of and with are.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah. We don't mark IfStatement as Scopeable and BlockParent because all the introduced let declarations are from its underneath BlockStatement. But we do mark ForIn/ForOf because they can introduce let declarations other than from the BlockStatement.

const staticBlock = getPath("(class { static { var foo; } })", {
plugins: ["classStaticBlock"],
}).get("body.0.expression.body.body.0");
expect(staticBlock.scope.hasOwnBinding("foo")).toBe(true);
Copy link
Member

Choose a reason for hiding this comment

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

The old behavior was that var foo was registered as an own binding of the program scope? If so, we might want to also test that it's not registered in the global scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the old behavior is to register in upper functionParent scope / program scope.

we might want to also test that it's not registered in the global scope.

Well we can add a general test that the same binding should not be registered twice in different scope, is that true?

Copy link
Member

Choose a reason for hiding this comment

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

Oh right, testing that a binding is in one scope is effectively already testing that it's not in the other one.

@JLHwung JLHwung force-pushed the mark-static-block-as-function-parent branch from 32e4d81 to f6b5fae Compare October 8, 2021 21:06
@@ -206,7 +206,7 @@ const aliasDescriptions = {
ForXStatement:
"A cover of [ForInStatements and ForOfStatements](https://tc39.es/ecma262/#sec-for-in-and-for-of-statements).",
Function:
"A cover of functions and [method](#method)s, the must have `body` and `params`. Note: `Function` is different to `FunctionParent`.",
"A cover of functions and [method](#method)s, the must have `body` and `params`. Note: `Function` is different to `FunctionParent`. For example, a `StaticBlock` is a `FunctionParent` but not `Function`.",
FunctionParent:
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should rename FunctionParent to VarHoistScope?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am good with renaming and adding alias for backward compatibility. The FunctionParent is named v.s. BlockParent. If we pick VarHoistScope for FunctionParent, then we should also pick one for BlockParent: Maybe LexicalScope?

We also have Scope#getFunctionParent and Scope#getBlockParent which returns the scope's path's someParent's scope. They will also have to be renamed.

Related: By definition I would like to add Program to FunctionParent too. The Program is a FunctionParent in Babel 6 but we mark it as BlockParent since Babel 7: An AST node could be both BlockParent and FunctionParent, though: Precisely FunctionParent is a subset of BlockParent.

@babel-bot
Copy link
Collaborator

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/49135/

@JLHwung JLHwung merged commit 49a0d65 into babel:main Oct 11, 2021
@JLHwung JLHwung deleted the mark-static-block-as-function-parent branch October 11, 2021 00:22
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Jan 10, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: Bug Fix 🐛 A type of pull request used for our changelog categories Spec: Class Static Block
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants