code: public static void traverseChangedFunctions(
        final AbstractCompiler compiler, final ChangeScopeRootCallback callback) {
      final Node jsRoot = compiler.getJsRoot();
      NodeTraversal.traverse(compiler, jsRoot,
          new AbstractPreOrderCallback() {
            @Override
            public final boolean shouldTraverse(NodeTraversal t, Node n, Node parent) {
              if (NodeUtil.isChangeScopeRoot(n) && compiler.hasScopeChanged(n)) {
                callback.enterChangeScopeRoot(compiler, n);
              }
              return true;
            }
          });
    }
docs: Traversal for passes that work only on changed functions.
  Suppose a loopable pass P1 uses this traversal.
  Then, if a function doesn't change between two runs of P1, it won't look at
  the function the second time.
  (We're assuming that P1 runs to a fixpoint, o/w we may miss optimizations.)
  
  <p>Most changes are reported with calls to Compiler.reportCodeChange(), which
  doesn't know which scope changed. We keep track of the current scope by
  calling Compiler.setScope inside pushScope and popScope.
  The automatic tracking can be wrong in rare cases when a pass changes scope
  w/out causing a call to pushScope or popScope.
  
  Passes that do cross-scope modifications call
  Compiler.reportChangeToEnclosingScope(Node n).