Java Code Examples for com.google.javascript.jscomp.NodeTraversal#reportCodeChange()

The following examples show how to use com.google.javascript.jscomp.NodeTraversal#reportCodeChange() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: NodeModulePass.java    From js-dossier with Apache License 2.0 6 votes vote down vote up
@Override
public void visit(NodeTraversal t, final Node n, final Node parent) {
  if (NodeUtil.isNameDeclaration(n)) {
    RequireDetector detector = new RequireDetector();
    traverse(t.getCompiler(), n, detector);

    if (detector.foundRequire) {
      Node addAfter = n;
      for (Node last = n.getLastChild();
          last != null && last != n.getFirstChild();
          last = n.getLastChild()) {
        n.removeChild(last);

        Node newDecl = declaration(last, n.getToken()).srcrefTree(last);
        parent.addChildAfter(newDecl, addAfter);
        addAfter = newDecl;
        t.reportCodeChange();
      }
    }
  }
}
 
Example 2
Source File: NodeModulePass.java    From js-dossier with Apache License 2.0 5 votes vote down vote up
private void visitScript(NodeTraversal t, Node script) {
  if (currentModule == null) {
    return;
  }

  // Remove any 'use strict' directives. The compiler adds these by default to
  // closure modules and will generate a warning if specified directly.
  // TODO: remove when https://github.com/google/closure-compiler/issues/1263 is fixed.
  Set<String> directives = script.getDirectives();
  if (directives != null && directives.contains("use strict")) {
    // Directives is likely an immutable collection, so we need to make a copy.
    Set<String> newDirectives = new HashSet<>(directives);
    newDirectives.remove("use strict");
    script.setDirectives(newDirectives);
  }

  processModuleExportRefs(t);

  Node moduleBody = createModuleBody();
  moduleBody.srcrefTree(script);
  if (script.getChildCount() > 0) {
    moduleBody.addChildrenToBack(script.removeChildren());
  }
  script.addChildToBack(moduleBody);
  script.putBooleanProp(Node.GOOG_MODULE, true);

  t.getInput().addProvide(currentModule);

  traverse(t.getCompiler(), script, new TypeCleanup());

  googRequireExpr.clear();
  currentModule = null;

  t.reportCodeChange();
}
 
Example 3
Source File: NodeModulePass.java    From js-dossier with Apache License 2.0 4 votes vote down vote up
private void visitRequireCall(NodeTraversal t, Node require, Node parent) {
  Path currentFile = inputFs.getPath(t.getSourceName());

  String modulePath = require.getSecondChild().getString();

  if (modulePath.isEmpty()) {
    t.report(require, REQUIRE_INVALID_MODULE_ID);
    return;
  }

  String moduleId = null;

  if (modulePath.startsWith(".") || modulePath.startsWith("/")) {
    Path moduleFile = currentFile.getParent().resolve(modulePath).normalize();
    if (modulePath.endsWith("/")
        || (isDirectory(moduleFile)
            && !modulePath.endsWith(".js")
            && !Files.exists(moduleFile.resolveSibling(moduleFile.getFileName() + ".js")))) {
      moduleFile = moduleFile.resolve("index.js");
    }
    moduleId = NODE.newId(moduleFile).getOriginalName();

  } else if (nodeLibrary.canRequireId(modulePath)) {
    moduleId = nodeLibrary.normalizeRequireId(modulePath);
  }

  if (moduleId != null) {
    // Only register the require statement on this module if it occurs at the global
    // scope. Assume other require statements are not declared at the global scope to
    // avoid create a circular dependency. While node can handle these, by returning
    // a partial definition of the required module, the cycle would be an error for
    // the compiler. For more information on how Node handles cycles, see:
    //     http://www.nodejs.org/api/modules.html#modules_cycles
    if (t.getScope().isGlobal()) {
      Node googRequire = call(getprop(name("goog"), string("require")), string(moduleId));

      // ClosureCheckModule enforces that goog.require statements are at the top level. To
      // compensate, if we have a require statement that is not at the top level, we introduce
      // a hidden variable at the top level that does the actual require. The compiler should
      // always inline the require making this effectively a no-op.
      //
      // Example:
      //    var Foo = require('./foo').Foo;
      //
      // Becomes:
      //    var _some_hidden_name = require('./foo');
      //    var Foo = _some_hidden_name.Foo;
      if (!parent.isName()) {
        String hiddenName = Types.toInternalVar(moduleId);

        JSDocInfoBuilder infoBuilder = new JSDocInfoBuilder(false);
        infoBuilder.recordConstancy();

        googRequireExpr.put(
            hiddenName, var(name(hiddenName).setJSDocInfo(infoBuilder.build()), googRequire));
        googRequire = name(hiddenName);
      }

      parent.replaceChild(require, googRequire.srcrefTree(require));
      t.getInput().addRequire(DependencyInfo.Require.googRequireSymbol(moduleId));

    } else {
      // For goog.module('foo'), ClosureRewriteModule produces module$exports$foo = {};, so
      // we use the transformed name in the direct reference.
      parent.replaceChild(require, name("module$exports$" + moduleId).srcrefTree(require));
    }

    t.reportCodeChange();
  }

  // Else we have an unrecognized module ID. Do nothing, leaving it to the
  // type-checking gods.
}