These pages are old. They apply to UglifyJS v2. Version 3 has evolved a lot in the mean time to support most of ES6. Please check the documentation in the official repository for up-to-date information. Big thanks to all contributors, especially to Alex Lam S.L., who has maintained this project for years!
UglifyJS — scope analyzer
UglifyJS contains a scope analyzer which figures out variable/function definitions, references etc. You need to call it manually before compression or mangling:
toplevel.figure_out_scope();
The figure_out_scope method is defined only on the AST_Toplevel node.
Methods
Several methods do meaningful things after a call to figure_out_scope:
- AST_Scope::find_variable(name) — looks up the variable by name and if found it returns the associated SymbolDef.
- AST_Scope::references(def) — returns non-null if this scope references the given SymbolDef.
- AST_Symbol::unmangleable() — returns
true
if this symbol cannot be renamed (it's either global, undeclared, or defined in scope whereeval
orwith
are in use. - AST_Symbol::unreferenced() — returns
true
if this symbol is not referenced. - AST_Symbol::undeclared() — returns
true
if this symbol is undeclared. - AST_Symbol::global() — returns
true
if this symbol is defined in the global (toplevel) scope. - AST_Symbol::definition() — returns the associated SymbolDef for this symbol.
Internals
figure_out_scope will supplement nodes with additional information:
In AST_Scope nodes
- directives — an array of directives that appear in this scope.
- variables — a mapping from name to SymbolDef object for all definitions in this scope, including functions.
- functions — a like variables but only for function declarations.
- uses_with — becomes
true
if thewith
statement is used in this scope or any subscopes. - uses_eval — becomes
true
if a direct call to the globaleval
is seen in this scope or any subscope. - parent_scope — a pointer to the parent scope, or null of this is the toplevel scope.
- enclosed — a list of SymbolDef-s defined in this or in the outer scopes which are used from this or from inner scopes.
In AST_Symbol nodes
- scope — pointer to the current scope.
- thedef — pointer to the SymbolDef associated with this symbol
In AST_LabelRef nodes
- scope — pointer to the current scope.
- thedef — pointer to the AST_Label declaration that this symbol refers to
Symbol definitions
After parsing you'll want to call toplevel.figure_out_scope() in order to supply additional information in the AST. This function will create an unique definition for each symbol. Think of code like this, for example:
function f(x) {
if (something) {
var x = 10;
}
var x = 20;
}
Are the x-es the same variable? Well, they should be, although in the AST they are different AST_SymbolDeclaration nodes. The scope analyzer will create a single definition and point each of them to the same definition. This definition is a SymbolDef object and it has the following properties:
name — the original symbol name
orig — an array of AST_SymbolDeclaration-s where this variable is defined; for the case above it would contain all 3 x-es.
scope — points to the AST_Scope where this is defined.
references — an array of AST_SymbolRef nodes that were determined to point to this definition.
global — boolean, tells us if this is a global definition.
undeclared — boolean, tells us if this is an undeclared definition (more below about undeclared names).
constant — boolean, true if this is a constant definition (occurring in
const
).mangled_name — the mangled name for this node, created by toplevel.mangle_names(). If present, the code generator will use this name when printing symbols.
When it sees an undeclared symbol such as the Q below:
function f(x) {
return Q + Q + x;
}
UglifyJS will still create a SymbolDef, but mark it "undeclared". This is for consistency, so that every symbol's definition() method returns something usable. It also might be useful for various applications to track access to undeclared globals, which can be found in the SymbolDef's references property.
UglifyJS
JS compressor of world fame.
Open demo- Home
- Parser
- Code generator
- Compressor
- Mangler
- The AST structure
- SpiderMonkey AST
- Scope analysis
- AST walker
- AST transformer
- UglifyJS on Github
Latest blog entries tagged "uglifyjs"
- Using UglifyJS for code refactoring
- Should you switch to UglifyJS2?
- UglifyJS online demo
- UglifyJS — why not switching to SpiderMonkey AST
/** May the source-map be with you! **/