Search in sources :

Example 6 with AbstractPostOrderCallback

use of com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback in project closure-compiler by google.

the class DataFlowAnalysis method computeEscaped.

/**
 * Compute set of escaped variables. When a variable is escaped in a dataflow analysis, it can be
 * referenced outside of the code that we are analyzing. A variable is escaped if any of the
 * following is true:
 *
 *   1. Exported variables as they can be needed after the script terminates.
 *   2. Names of named functions because in JavaScript, function foo(){} does not kill
 *       foo in the dataflow.
 *
 * @param jsScope Must be a function scope
 */
static void computeEscaped(final Scope jsScope, final Set<Var> escaped, AbstractCompiler compiler, Es6SyntacticScopeCreator scopeCreator) {
    checkArgument(jsScope.isFunctionScope());
    AbstractPostOrderCallback finder = new AbstractPostOrderCallback() {

        @Override
        public void visit(NodeTraversal t, Node n, Node parent) {
            Node enclosingBlock = NodeUtil.getEnclosingFunction(n);
            if (jsScope.getRootNode() == enclosingBlock || !n.isName() || parent.isFunction()) {
                return;
            }
            String name = n.getString();
            Var var = t.getScope().getVar(name);
            if (var != null) {
                Node enclosingScopeNode = NodeUtil.getEnclosingFunction(var.getNode());
                if (enclosingScopeNode == jsScope.getRootNode()) {
                    escaped.add(var);
                }
            }
        }
    };
    Map<String, Var> allVarsInFn = new HashMap<>();
    List<Var> orderedVars = new ArrayList<>();
    NodeUtil.getAllVarsDeclaredInFunction(allVarsInFn, orderedVars, compiler, scopeCreator, jsScope);
    NodeTraversal t = new NodeTraversal(compiler, finder, scopeCreator);
    t.traverseAtScope(jsScope);
    // the catch check is causing breakages however
    for (Var var : allVarsInFn.values()) {
        if (var.getParentNode().isCatch() || compiler.getCodingConvention().isExported(var.getName())) {
            escaped.add(var);
        }
    }
}
Also used : HashMap(java.util.HashMap) DiGraphNode(com.google.javascript.jscomp.graph.DiGraph.DiGraphNode) Node(com.google.javascript.rhino.Node) AbstractPostOrderCallback(com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback) ArrayList(java.util.ArrayList)

Example 7 with AbstractPostOrderCallback

use of com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback in project closure-compiler by google.

the class J2clClinitPrunerPass method collectClinitReferences.

private Multimap<String, Node> collectClinitReferences(Node root) {
    final Multimap<String, Node> clinitReferences = HashMultimap.create();
    NodeTraversal.traverse(compiler, root, new AbstractPostOrderCallback() {

        @Override
        public void visit(NodeTraversal t, Node node, Node parent) {
            String clinitName = getClinitMethodName(node);
            if (clinitName != null) {
                clinitReferences.put(clinitName, node);
            }
        }
    });
    return clinitReferences;
}
Also used : Node(com.google.javascript.rhino.Node) AbstractPostOrderCallback(com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback)

Example 8 with AbstractPostOrderCallback

use of com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback in project closure-compiler by google.

the class SymbolTable method fillGoogProvideModuleRequires.

/**
 * Connects goog.module/goog.provide calls with goog.require/goog.requireType. For each
 * goog.module/goog.provide call creates a symbol and all goog.require/goog.requireType added as
 * references.
 */
void fillGoogProvideModuleRequires(Node externs, Node root) {
    // small optimization to keep symbols created within this function for fast access instead of
    // going through SymbolTable.getSymbolForName() every time.
    Map<String, Symbol> declaredNamespaces = new HashMap<>();
    // Map containind goog.module names to Scope object representing them. For goog.provide
    // namespaces there is no scope as elements of goog.provide are global.
    Map<String, SymbolScope> moduleScopes = new HashMap<>();
    Predicate<Node> looksLikeGoogCall = (Node n) -> {
        if (!n.isCall()) {
            return false;
        }
        Node left = n.getFirstChild();
        Node arg = n.getSecondChild();
        // We want only nodes of type `goog.xyz('somestring')`.
        if (!(left.isGetProp() && left.getFirstChild().isName() && left.getFirstChild().getString().equals("goog")) || arg == null || !arg.isStringLit()) {
            return false;
        }
        return true;
    };
    NodeTraversal.Callback collectModuleScopes = new AbstractPostOrderCallback() {

        @Override
        public void visit(NodeTraversal t, Node n, Node parent) {
            if (!looksLikeGoogCall.test(n)) {
                return;
            }
            Node arg = n.getSecondChild();
            String namespaceName = "ns$" + arg.getString();
            switch(n.getFirstChild().getString()) {
                case "module":
                case "provide":
                    Symbol ns = declareSymbol(namespaceName, /* type= */
                    null, /* inferred= */
                    false, getGlobalScope(), arg, /* info= */
                    null);
                    declaredNamespaces.put(namespaceName, ns);
                    if (n.getGrandparent().isModuleBody()) {
                        moduleScopes.put(arg.getString(), scopes.get(n.getGrandparent()));
                    }
                    break;
                default:
            }
        }
    };
    NodeTraversal.Callback processRequireStatements = new AbstractPostOrderCallback() {

        @Override
        public void visit(NodeTraversal t, Node n, Node parent) {
            if (!looksLikeGoogCall.test(n)) {
                return;
            }
            Node arg = n.getSecondChild();
            String namespaceName = "ns$" + arg.getString();
            switch(n.getFirstChild().getString()) {
                case "require":
                case "requireType":
                case "forwardDeclare":
                    addRefsInGoogRequireStatement(n.getParent(), moduleScopes);
                    Symbol symbol = declaredNamespaces.get(namespaceName);
                    // code it might be missing. In which case just skip it.
                    if (symbol != null) {
                        symbol.defineReferenceAt(arg);
                    }
                    break;
                default:
            }
        }
    };
    NodeTraversal.traverseRoots(compiler, collectModuleScopes, externs, root);
    NodeTraversal.traverseRoots(compiler, processRequireStatements, externs, root);
}
Also used : IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Node(com.google.javascript.rhino.Node) AbstractPostOrderCallback(com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback)

Aggregations

AbstractPostOrderCallback (com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback)8 Node (com.google.javascript.rhino.Node)8 DiGraphNode (com.google.javascript.jscomp.graph.DiGraph.DiGraphNode)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 ArrayList (java.util.ArrayList)1 IdentityHashMap (java.util.IdentityHashMap)1 LinkedHashMap (java.util.LinkedHashMap)1