code: public List<JCCompilationUnit> enterTrees(List<JCCompilationUnit> roots) {
          //enter symbols for all files
          if (!taskListener.isEmpty()) {
              for (JCCompilationUnit unit: roots) {
                  TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
                  taskListener.started(e);
              }
          }
  
          enter.main(roots);
  
          if (!taskListener.isEmpty()) {
              for (JCCompilationUnit unit: roots) {
                  TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
                  taskListener.finished(e);
              }
          }
  
          // If generating source, or if tracking public apis,
          // then remember the classes declared in
          // the original compilation units listed on the command line.
          if (needRootClasses || sourceOutput || stubOutput) {
              ListBuffer<JCClassDecl> cdefs = new ListBuffer<>();
              for (JCCompilationUnit unit : roots) {
                  for (List<JCTree> defs = unit.defs;
                       defs.nonEmpty();
                       defs = defs.tail) {
                      if (defs.head instanceof JCClassDecl)
                          cdefs.append((JCClassDecl)defs.head);
                  }
              }
              rootClasses = cdefs.toList();
          }
  
          // Ensure the input files have been recorded. Although this is normally
          // done by readSource, it may not have been done if the trees were read
          // in a prior round of annotation processing, and the trees have been
          // cleaned and are being reused.
          for (JCCompilationUnit unit : roots) {
              inputFiles.add(unit.sourcefile);
          }
  
          return roots;
      }
docs: Enter the symbols found in a list of parse trees.
  As a side-effect, this puts elements on the "todo" list.
  Also stores a list of all top level classes in rootClasses.