-
Notifications
You must be signed in to change notification settings - Fork 3
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
Convenience API for dealing with variable scopes #13
base: master
Are you sure you want to change the base?
Conversation
7cf389a
to
c50dfbe
Compare
c50dfbe
to
84e3a67
Compare
4e7921c
to
5e1eacb
Compare
As a next step, I plan to do some dogfooding with my ES module bundler. That, however, uses the core package only and will implement a custom scope tree data structure. In other words, this won't do any dogfooding to So it would be great if you can provide feedback on how satisfied you are with the API of |
5e1eacb
to
5b842c3
Compare
If you need to link any given node to a scope, you can do I know it's not the most streamlined dev. experience, however it seems we can't really do any better if we want to stick to the performance-oriented design guidelines outlined in the PR description.
Sure, now that the basics are more or less figured out, we can move on to polishing DX. My only request is to avoid adding features too specific to your use case. I'd like to keep this lib general, that is, only include features that most of the use cases are expected to benefit from. |
e0d83c9
to
b8ca906
Compare
Public API's taking shape nicely, plus I did some tweaks and could even improve the max. recursion depth. Seems like we're also ok performance-wise: Acornima.Benchmark.FileParsingBenchmark
|
Uh-oh... we have a problem. Let's consider we have a simple function declaration with default parameters: function f(a = y) { var y = 2 } For this script, acorn reports the following scope info:
The problem here is that variable This happens because acorn doesn't create separate scopes for the function parameter list and the function body but merges the declarations in the two into one scope. This makes the feature in its current form pretty useless for consumers (e.g. for my ES module bundler). It would only be useful if it produced this:
I'll take a look to find out whether we could tweak the parser logic to output the correct scope info without major changes and a significant performance penalty. But there is a chance that this whole effort goes down the drain in the end... |
671bc9c
to
0be0672
Compare
Good news, looks like the PR is saved as I could figure out an unobtrusive way to tackle the issues described in my previous comment.
Thanks to this extra info, it became possible to build a scope tree with separate scopes for function/catch clause parameter lists and function/catch clause bodies. For
I also made some further improvements: The name of a function declaration or function expressions is available in the function's scope. E.g. an expression like
Similarly, the name of a class declaration or named class expressions is available in the class's scope. (Which means that my statement "Classes don't create variable scopes as you can't directly declare variables in the body of a class, just properties and methods." wasn't entirely true. The class name is a special variable in the class's scope.) E.g. an expression like
This was problematic though because the parser didn't create scopes for classes to do variable redeclaration detection as they're not needed for that purpose. So, I decided to bite the bullet and changed the parser to create scopes for classes too. (Hopefully won't affect perf. much but I'll need to do some benchmarks w.r.t. this.) After making these changes, I also updated my bundler project to use the scope info from the parser to build its scope tree. I could make it work, what's more, this simplified the related logic pretty much. 🎉 So the feature seems to turn out useful in the end. So I plan to include the core functionality (the changes to the parser and |
0be0672
to
e1004c6
Compare
…dealing with variable scopes
e1004c6
to
6910e38
Compare
The core functionality (exposing the raw scope info via So from now on, this PR is about the convenience features living in the Extras package ( The starting point is already there, including the logic that does the heavy-lifting. I'm aware of one thing that's still missing from it: in non-strict mode function declarations are also hoisted. Probably I'll implement this (will be tricky though), but apart from this, I don't have plans with this PR for now. I'd leave it up to the community to shape the implementation to their needs. So, @Divulcan, if you're still interested, please go for it. |
This PR is kind of an experiment to find out if exposing the variable scopes tracked by the parser for checking variable redeclarations makes sense in the first place, and if so, how it can be technically achieved and what the public API of such a feature should look like.
My goal with this is to provide a starting point to help us understand the problem better, explore our options so we can discuss them and shape the implementation and API accordingly.
The main requirement regarding the implementation is that it must not degrade the performance of the primary consumer (Jint execution engine) significantly. This applies to both execution time and memory allocation + the memory footprint of the resulting AST. Big changes to the parser's logic are not allowed either, as it should stay a close translation of acornjs.
Beyond that, the main goal, of course, is to come up with the most convenient API possible for the consumers. However, I don't intend to implement and maintain an "all batteries included" solution but a general one that provides access to the scope information (and maybe some convenience features in the Extras package) for consumers who want to deal with variable scopes. That is, a limited feature set is preferred, which leaves the possibility open for consumers to work with variable scopes in a way that is optimized to their specific use cases (I mean primarily the freedom to choose the data structure to store the scope tree.)
All ideas and feedback are welcome!