-
Notifications
You must be signed in to change notification settings - Fork 77
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
improvement: add reference from definition of inner class variable to outer one #120
base: master
Are you sure you want to change the base?
Conversation
It uses an old version of require.dir, which is broken in node 8
@sokra Classes actually do create two bindings: one in the surrounding scope and one in the inner scope. This is because the outer binding is mutable, but the inner binding is not. So a reference to a class name from one of its methods will always refer to that class, while a reference to a class name from outside of the class may be changed by anything else that closes over it. class C { constructor() { console.log(C === alwaysC); } }
const alwaysC = C;
new alwaysC; // true
C = null;
new alwaysC; // still true
C === alwaysC; // false But I'd be happy to accept your other commits! |
@sokra As @michaelficarra says, there are indeed two variables. You can compare against shift-scope, for example, by pasting his snippet here, or read the spec: the outer binding is created as step 7 of BindingClassDeclarationEvaluation, and the inner as step 4a of ClassDefinitionEvaluation. |
@bakkot That demo actually supports shareable links. |
The same is true for FunctionDeclarations and here escope also creates a single variable. function Foo() {
Foo // 1
}
Foo // 2
ClassDeclaration currently class Foo {
constructor() {
Foo // 1
}
}
Foo // 2
I wanted to align the behavior. If the intended behavior is that two variables are created, this should be changed for FunctionDeclarations too. In this case I would propose to add a cross referencing property to the variables to be able to find the inner scope variable from the outer scope variable. This is important for the renaming operation. |
or am I wrong about the FunctionDeclaration? ... need to check the spec here. |
ok I was wrong here. FunctionDeclaration behaves different. |
I will update to PR to keep the behavior and include a cross-reference instead. |
@sokra Can you rebase? |
As it looks like master was merged in, is this ready for merging now? |
I'm not really convinced that this is useful. The two bindings aren't related, other than that they're declared by the same node. And if you want to look for any variables declared by the same node, you already have that ability. A similar quirk occurs with references in catch blocks. What's the problem this is trying to solve? |
The first 3 commits bring this repo up-to-date:
({a}) = b
is incorrect syntax ->({a} = b)
insteadThe last commit is the important one.
Before a ClassDeclaration creates two variables, one in the outer scope and one in the inner scope. This results in weird behavior when the class is referenced from inside the class. i. e. when renaming a variable.
After the change only a single variable is created and all references are attached to this one.
Note: that a comment on one test assumes it's the correct behavior to create to two variables. I'm not this opinion. FunctionDeclarations are similar and also create only a single variable.
fixes webpack/webpack#5000