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);
}
}
}
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;
}
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);
}
Aggregations