builder.rs |
Data collection.
`ScopeBuilder` is the entry point of this module.
Each AST node that will hold bindings (global, block, function, etc.) has a
corresponding scope builder type defined in this module:
* `GlobalScopeBuilder`
* `BlockScopeBuilder`
* `FunctionExpressionScopeBuilder`
* `FunctionParametersScopeBuilder`
* `FunctionBodyScopeBuilder`
They follow the pattern:
* They are created and pushed to the `ScopeBuilderStack` when the
algorithm enters a scope.
* They collect the information necessary to build a `ScopeData` object
(which will eventually become a `js::ScopeCreationData` on the
C++ side).
* They stay on the scope builder stack until the algorithm leaves that
scope.
* Then they are converted by `into_scope_data()`.
Fields in the builder types mostly correspond to local variables in spec
algorithms. For example, `GlobalScopeBuilder` has fields named
`functions_to_initialize`, `declared_function_names`, and
`declared_var_names` which correspond to the
[GlobalDeclarationInstantiation][1] algorithm's local variables
*functionsToInitialize*, *declaredFunctionNames*, and *declaredVarNames*.
This module performs some steps of those algorithms -- the parts that can
be done at compile time. The results are passed along to the emitter and
ultimately the JS runtime.
# Syntax-only mode
When doing syntax-only parsing, we collect minimal information, that does
not include `ScopeData`, but `ScriptStencil` for functions.
[1]: https://tc39.es/ecma262/#sec-globaldeclarationinstantiation |
128839 |
data.rs |
Data generated by scope analysis, and consumed only by emitter |
1539 |
free_name_tracker.rs |
Code to track free names in scopes, to compute which bindings are closed
over.
A binding is closed-over if it is defined in a scope in one `JSScript` and
can be used in another `JSScript` (a nested function or direct eval).
In our single pass over the AST, we compute which bindings are closed-over
using a `FreeNameTracker` for each scope. |
4904 |
lib.rs |
Collect information about scopes and bindings, used by the emitter.
Scope analysis happens in a separate pass after the AST is built:
1. Parse the script, check for early errors, and build an AST.
2. Traverse the AST and do scope analysis (this crate).
3. Traverse the AST and emit bytecode.
The output of this analysis is a `ScopeDataMapAndFunctionMap`
describing each scope, binding, and function in the AST. |
1140 |
pass.rs |
Code to traverse the AST and drive the rest of scope analysis.
This module is responsible for walking the AST. Other modules do the actual
analysis.
Scope analysis is currently a second pass, after parsing, using the AST,
but the goal is to do this analysis as part of the parse phase, even when
no AST is built. So we try to keep AST use separate from the analysis code. |
13023 |