class RemoveUnusedVars extends java.lang.Object implements CompilerPass, OptimizeCalls.CallGraphCompilerPass
SmartNameRemoval
.
SmartNameRemoval
maintains an explicit graph of dependencies
between global symbols. However, SmartNameRemoval
cannot handle
non-trivial edges in the reference graph ("A is referenced iff both B and C
are referenced"), or local variables. SmartNameRemoval
is also
substantially more complicated because it tries to handle namespaces
(which is largely unnecessary in the presence of CollapseProperties
.
This pass also uses a more complex analysis of assignments, where
an assignment to a variable or a property of that variable does not
necessarily count as a reference to that variable, unless we can prove
that it modifies external state. This is similar to
FlowSensitiveInlineVariables
, except that it works for variables
used across scopes.Modifier and Type | Class and Description |
---|---|
private static class |
RemoveUnusedVars.Assign |
private static class |
RemoveUnusedVars.CallSiteOptimizer |
private class |
RemoveUnusedVars.Continuation
Our progress in a traversal can be expressed completely as the
current node and scope.
|
Modifier and Type | Field and Description |
---|---|
private java.util.List<Scope> |
allFunctionScopes
Keep track of scopes that we've traversed.
|
private java.util.Map<Node,RemoveUnusedVars.Assign> |
assignsByNode
The assigns, indexed by the NAME node that they assign to.
|
private com.google.common.collect.Multimap<Var,RemoveUnusedVars.Assign> |
assignsByVar
Keep track of assigns to variables that we haven't referenced.
|
private RemoveUnusedVars.CallSiteOptimizer |
callSiteOptimizer |
private com.google.common.collect.Multimap<Var,Node> |
classDefiningCalls
Subclass name -> class-defining call EXPR node.
|
private CodingConvention |
codingConvention |
private AbstractCompiler |
compiler |
private com.google.common.collect.Multimap<Var,RemoveUnusedVars.Continuation> |
continuations
Keep track of continuations that are finished iff the variable they're
indexed by is referenced.
|
private java.util.List<Var> |
maybeUnreferenced
Keep track of variables that might be unreferenced.
|
private boolean |
modifyCallSites |
private boolean |
mustResetModifyCallSites |
private boolean |
preserveFunctionExpressionNames |
private java.util.Set<Var> |
referenced
Keep track of variables that we've referenced.
|
private boolean |
removeGlobals |
Constructor and Description |
---|
RemoveUnusedVars(AbstractCompiler compiler,
boolean removeGlobals,
boolean preserveFunctionExpressionNames,
boolean modifyCallSites) |
Modifier and Type | Method and Description |
---|---|
private void |
collectMaybeUnreferencedVars(Scope scope)
For each variable in this scope that we haven't found a reference
for yet, add it to the list of variables to check later.
|
private static Node |
getFunctionArgList(Node function) |
private void |
interpretAssigns()
Look at all the property assigns to all variables.
|
private boolean |
isRemovableVar(Var var) |
private boolean |
markReferencedVar(Var var)
Marks a var as referenced, recursing into any values of this var
that we skipped.
|
void |
process(Node externs,
Node root)
Traverses the root, removing all unused variables.
|
void |
process(Node externs,
Node root,
SimpleDefinitionFinder defFinder) |
private void |
removeAllAssigns(Var var)
Remove all assigns to a var.
|
private void |
removeUnreferencedFunctionArgs(Scope fnScope)
Removes unreferenced arguments from a function declaration and when
possible the function's callSites.
|
private void |
removeUnreferencedVars()
Removes any vars in the scope that were not referenced.
|
private void |
traverseAndRemoveUnusedReferences(Node root)
Traverses a node recursively.
|
private void |
traverseFunction(Node n,
Scope parentScope)
Traverses a function, which creates a new scope in JavaScript.
|
private void |
traverseNode(Node n,
Node parent,
Scope scope)
Traverses everything in the current scope and marks variables that
are referenced.
|
private final AbstractCompiler compiler
private final CodingConvention codingConvention
private final boolean removeGlobals
private boolean preserveFunctionExpressionNames
private final java.util.Set<Var> referenced
private final java.util.List<Var> maybeUnreferenced
private final java.util.List<Scope> allFunctionScopes
private final com.google.common.collect.Multimap<Var,RemoveUnusedVars.Assign> assignsByVar
private final java.util.Map<Node,RemoveUnusedVars.Assign> assignsByNode
private final com.google.common.collect.Multimap<Var,Node> classDefiningCalls
private final com.google.common.collect.Multimap<Var,RemoveUnusedVars.Continuation> continuations
private boolean modifyCallSites
private boolean mustResetModifyCallSites
private RemoveUnusedVars.CallSiteOptimizer callSiteOptimizer
RemoveUnusedVars(AbstractCompiler compiler, boolean removeGlobals, boolean preserveFunctionExpressionNames, boolean modifyCallSites)
public void process(Node externs, Node root)
process
in interface CompilerPass
externs
- Top of external JS treeroot
- Top of JS treepublic void process(Node externs, Node root, SimpleDefinitionFinder defFinder)
process
in interface OptimizeCalls.CallGraphCompilerPass
private void traverseAndRemoveUnusedReferences(Node root)
private void traverseNode(Node n, Node parent, Scope scope)
private boolean isRemovableVar(Var var)
private void traverseFunction(Node n, Scope parentScope)
private void collectMaybeUnreferencedVars(Scope scope)
private void removeUnreferencedFunctionArgs(Scope fnScope)
fnScope
- The scope inside the functionprivate static Node getFunctionArgList(Node function)
private void interpretAssigns()
var x = {};
x.foo = 3; // not a reference.
var y = foo();
y.foo = 3; // is a reference.
Interpreting assignments could mark a variable as referenced that
wasn't referenced before, in order to keep it alive. Because we find
references by lazily traversing subtrees, marking a variable as
referenced could trigger new traversals of new subtrees, which could
find new references.
Therefore, this interpretation needs to be run to a fixed point.private void removeAllAssigns(Var var)
private boolean markReferencedVar(Var var)
private void removeUnreferencedVars()