Code with Finding: |
class GenerateExports { @Override public void process(Node externs, Node root) { FindExportableNodes findExportableNodes = new FindExportableNodes(compiler); NodeTraversal.traverse(compiler, root, findExportableNodes); Map<String, GenerateNodeContext> exports = findExportableNodes .getExports();
for (Map.Entry<String, GenerateNodeContext> entry : exports.entrySet()) { String export = entry.getKey(); GenerateNodeContext context = entry.getValue();
// Emit the proper CALL expression. // This is an optimization to avoid exporting everything as a symbol // because exporting a property is significantly simpler/faster. // Only export the property if the parent is being exported or // if the parent is "prototype" and the grandparent is being exported. String parent = null; String grandparent = null;
Node node = context.getNode().getFirstChild(); if (node.getType() == Token.GETPROP) { parent = node.getFirstChild().getQualifiedName(); if (node.getFirstChild().getType() == Token.GETPROP && getPropertyName(node.getFirstChild()).equals(PROTOTYPE_PROPERTY)) { grandparent = node.getFirstChild().getFirstChild().getQualifiedName(); } }
boolean useExportSymbol = true; if (grandparent != null && exports.containsKey(grandparent)) { useExportSymbol = false; } else if (parent != null && exports.containsKey(parent)) { useExportSymbol = false; }
Node call; if (useExportSymbol) { // exportSymbol(publicPath, object); call = new Node(Token.CALL, NodeUtil.newQualifiedNameNode( compiler.getCodingConvention(), exportSymbolFunction, context.getNode(), export)); call.addChildToBack(Node.newString(export)); call.addChildToBack(NodeUtil.newQualifiedNameNode( compiler.getCodingConvention(), export, context.getNode(), export)); } else { // exportProperty(object, publicName, symbol); String property = getPropertyName(node); call = new Node(Token.CALL, new Node[] { NodeUtil.newQualifiedNameNode( compiler.getCodingConvention(), exportPropertyFunction, context.getNode(), exportPropertyFunction), NodeUtil.newQualifiedNameNode( compiler.getCodingConvention(), parent, context.getNode(), exportPropertyFunction), Node.newString(property), NodeUtil.newQualifiedNameNode( compiler.getCodingConvention(), export, context.getNode(), exportPropertyFunction) }); }
Node expression = new Node(Token.EXPR_RESULT, call); annotate(expression);
// It's important that any class-building calls (goog.inherits) // come right after the class definition, so move the export after that. Node insertionPoint = context.getContextNode().getNext(); CodingConvention convention = compiler.getCodingConvention(); while (insertionPoint != null && NodeUtil.isExprCall(insertionPoint) && convention.getClassesDefinedByCall( insertionPoint.getFirstChild()) != null) { insertionPoint = insertionPoint.getNext(); }
if (insertionPoint == null) { context.getScriptNode().addChildToBack(expression); } else { context.getScriptNode().addChildBefore(expression, insertionPoint); } compiler.reportCodeChange(); } }
}
|