/** * Finds set of all defs in function given (defSites). Adds parameters of function to this set: * defSites. Finds all variables that are referenced in the function given (alf.names). * windowProps are all global properties available. Closures = alf.names - defSites - windowProps * * @param n root node of the function who's closures are to be found * @return set of closure names */ private Set<String> findClosures(Node n) { Set<String> closureVars = null; SimpleDefinitionFinder defFinder = new SimpleDefinitionFinder(compiler); defFinder.process(externs, n.getLastChild()); Collection<DefinitionSite> defSites = defFinder.getDefinitionSites(); Set<String> localDefs = new HashSet<String>(); for (DefinitionSite site : defSites) { if (site.node.getType() == Token.GETPROP) continue; String def = site.node.getString(); if (def.length() > 0) { localDefs.add(def); } } // adding params to function as defs Node origParamNode = n.getChildAtIndex(1); for (int i = 0; i < origParamNode.getChildCount(); i++) { String temp = origParamNode.getChildAtIndex(i).getString(); localDefs.add(temp); } // System.out.println("\nPrinting LOCAL def sites:" + defs); /*SimpleDefinitionFinder defFinder1 = new SimpleDefinitionFinder(compiler); defFinder1.process(externs, root); Collection<DefinitionSite> defSites1 = defFinder1.getDefinitionSites(); Set<String> defs1 = new HashSet<String>(); for(DefinitionSite site1: defSites1){ if (site1.node.getType() == Token.GETPROP) continue; String def = site1.node.getString(); if (def.length() > 0){ defs1.add(def); } } System.out.println("\nPrinting Global def sites:" + defs1);*/ AllNamesFinder alf = new AllNamesFinder(compiler); NodeTraversal.traverse(compiler, n.getLastChild(), alf); // System.out.println("all names: " + alf.names); closureVars = alf.names; closureVars.removeAll(localDefs); closureVars.removeAll(Props.windowProps); closureVars.remove( "this"); // since 'this' is later modified to $$_self we don't need to consider this as // closure return closureVars; }
@Override public void process(Node externs, Node root) { if (!passes.isEmpty()) { SimpleDefinitionFinder defFinder = new SimpleDefinitionFinder(compiler); compiler.setSimpleDefinitionFinder(defFinder); defFinder.process(externs, root); for (CallGraphCompilerPass pass : passes) { pass.process(externs, root, defFinder); } } }
/** * Traverses the root, removing all unused variables. Multiple traversals may occur to ensure all * unused variables are removed. */ public void process(Node externs, Node root) { Preconditions.checkState(compiler.getLifeCycleStage().isNormalized()); SimpleDefinitionFinder defFinder = null; if (modifyCallSites) { // For testing, allow the SimpleDefinitionFinder to be build now. defFinder = new SimpleDefinitionFinder(compiler); defFinder.process(externs, root); } process(externs, root, defFinder); }