src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java
author Dusan Balek <dbalek@netbeans.org>
Mon, 31 Jul 2017 11:07:41 +0200
changeset 5955 f54cccaf6e6c
parent 5862 cf7168447ec6
child 5959 28bebf0841dd
permissions -rw-r--r--
Mergin jlahoda's fix of #8182450: javac aborts when generating ct.sym intermittently - Initialize the module system model even in presence of missing/broken module-infos; BadClassFiles should not immediatelly abort compilation anymore, but should be handled as if the classfile did not exist.
     1 /*
     2  * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 package com.sun.tools.javac.main;
    27 
    28 import java.io.*;
    29 import java.util.Collection;
    30 import java.util.Collections;
    31 import java.util.HashMap;
    32 import java.util.HashSet;
    33 import java.util.LinkedHashMap;
    34 import java.util.LinkedHashSet;
    35 import java.util.Map;
    36 import java.util.MissingResourceException;
    37 import java.util.Queue;
    38 import java.util.ResourceBundle;
    39 import java.util.Set;
    40 import java.util.function.Function;
    41 
    42 import javax.annotation.processing.Processor;
    43 import javax.lang.model.SourceVersion;
    44 import javax.lang.model.element.ElementVisitor;
    45 import javax.tools.DiagnosticListener;
    46 import javax.tools.JavaFileManager;
    47 import javax.tools.JavaFileObject;
    48 import javax.tools.JavaFileObject.Kind;
    49 import javax.tools.StandardLocation;
    50 
    51 import com.sun.source.util.TaskEvent;
    52 import com.sun.tools.javac.api.DuplicateClassChecker;
    53 import com.sun.tools.javac.api.MultiTaskListener;
    54 import com.sun.tools.javac.code.*;
    55 import com.sun.tools.javac.code.Lint.LintCategory;
    56 import com.sun.tools.javac.code.Symbol.ClassSymbol;
    57 import com.sun.tools.javac.code.Symbol.CompletionFailure;
    58 import com.sun.tools.javac.code.Symbol.PackageSymbol;
    59 import com.sun.tools.javac.comp.*;
    60 import com.sun.tools.javac.comp.CompileStates.CompileState;
    61 import com.sun.tools.javac.file.JavacFileManager;
    62 import com.sun.tools.javac.jvm.*;
    63 import com.sun.tools.javac.parser.*;
    64 import com.sun.tools.javac.platform.PlatformDescription;
    65 import com.sun.tools.javac.processing.*;
    66 import com.sun.tools.javac.tree.*;
    67 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
    68 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
    69 import com.sun.tools.javac.tree.JCTree.JCExpression;
    70 import com.sun.tools.javac.tree.JCTree.JCLambda;
    71 import com.sun.tools.javac.tree.JCTree.JCMemberReference;
    72 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
    73 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
    74 import com.sun.tools.javac.util.*;
    75 import com.sun.tools.javac.util.DefinedBy.Api;
    76 import com.sun.tools.javac.util.JCDiagnostic.Factory;
    77 import com.sun.tools.javac.util.Log.DiagnosticHandler;
    78 import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
    79 import com.sun.tools.javac.util.Log.WriterKind;
    80 
    81 import static com.sun.tools.javac.code.Kinds.Kind.*;
    82 
    83 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
    84 import com.sun.tools.javac.resources.CompilerProperties.Errors;
    85 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
    86 
    87 import static com.sun.tools.javac.code.TypeTag.CLASS;
    88 import static com.sun.tools.javac.main.Option.*;
    89 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
    90 import java.util.Iterator;
    91 
    92 import static javax.tools.StandardLocation.CLASS_OUTPUT;
    93 
    94 import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
    95 
    96 /** This class could be the main entry point for GJC when GJC is used as a
    97  *  component in a larger software system. It provides operations to
    98  *  construct a new compiler, and to run a new compiler on a set of source
    99  *  files.
   100  *
   101  *  <p><b>This is NOT part of any supported API.
   102  *  If you write code that depends on this, you do so at your own risk.
   103  *  This code and its internal interfaces are subject to change or
   104  *  deletion without notice.</b>
   105  */
   106 public class JavaCompiler {
   107     /** The context key for the compiler. */
   108     public static final Context.Key<JavaCompiler> compilerKey = new Context.Key<>();
   109 
   110     /** Get the JavaCompiler instance for this context. */
   111     public static JavaCompiler instance(Context context) {
   112         JavaCompiler instance = context.get(compilerKey);
   113         if (instance == null)
   114             instance = new JavaCompiler(context);
   115         return instance;
   116     }
   117 
   118     /** The current version number as a string.
   119      */
   120     public static String version() {
   121         return version("release");  // mm.nn.oo[-milestone]
   122     }
   123 
   124     /** The current full version number as a string.
   125      */
   126     public static String fullVersion() {
   127         return version("full"); // mm.mm.oo[-milestone]-build
   128     }
   129 
   130     private static final String versionRBName = "com.sun.tools.javac.resources.version";
   131     private static ResourceBundle versionRB;
   132 
   133     private static String version(String key) {
   134         if (versionRB == null) {
   135             try {
   136                 versionRB = ResourceBundle.getBundle(versionRBName);
   137             } catch (MissingResourceException e) {
   138                 return Log.getLocalizedString("version.not.available");
   139             }
   140         }
   141         try {
   142             return versionRB.getString(key);
   143         }
   144         catch (MissingResourceException e) {
   145             return Log.getLocalizedString("version.not.available");
   146         }
   147     }
   148 
   149     /**
   150      * Control how the compiler's latter phases (attr, flow, desugar, generate)
   151      * are connected. Each individual file is processed by each phase in turn,
   152      * but with different compile policies, you can control the order in which
   153      * each class is processed through its next phase.
   154      *
   155      * <p>Generally speaking, the compiler will "fail fast" in the face of
   156      * errors, although not aggressively so. flow, desugar, etc become no-ops
   157      * once any errors have occurred. No attempt is currently made to determine
   158      * if it might be safe to process a class through its next phase because
   159      * it does not depend on any unrelated errors that might have occurred.
   160      */
   161     protected static enum CompilePolicy {
   162         /**
   163          * Just attribute the parse trees.
   164          */
   165         ATTR_ONLY,
   166 
   167         /**
   168          * Just attribute and do flow analysis on the parse trees.
   169          * This should catch most user errors.
   170          */
   171         CHECK_ONLY,
   172 
   173         /**
   174          * Attribute everything, then do flow analysis for everything,
   175          * then desugar everything, and only then generate output.
   176          * This means no output will be generated if there are any
   177          * errors in any classes.
   178          */
   179         SIMPLE,
   180 
   181         /**
   182          * Groups the classes for each source file together, then process
   183          * each group in a manner equivalent to the {@code SIMPLE} policy.
   184          * This means no output will be generated if there are any
   185          * errors in any of the classes in a source file.
   186          */
   187         BY_FILE,
   188 
   189         /**
   190          * Completely process each entry on the todo list in turn.
   191          * -- this is the same for 1.5.
   192          * Means output might be generated for some classes in a compilation unit
   193          * and not others.
   194          */
   195         BY_TODO;
   196 
   197         static CompilePolicy decode(String option) {
   198             if (option == null)
   199                 return DEFAULT_COMPILE_POLICY;
   200             else if (option.equals("attr"))
   201                 return ATTR_ONLY;
   202             else if (option.equals("check"))
   203                 return CHECK_ONLY;
   204             else if (option.equals("simple"))
   205                 return SIMPLE;
   206             else if (option.equals("byfile"))
   207                 return BY_FILE;
   208             else if (option.equals("bytodo"))
   209                 return BY_TODO;
   210             else
   211                 return DEFAULT_COMPILE_POLICY;
   212         }
   213     }
   214 
   215     private static final CompilePolicy DEFAULT_COMPILE_POLICY = CompilePolicy.BY_TODO;
   216 
   217     protected static enum ImplicitSourcePolicy {
   218         /** Don't generate or process implicitly read source files. */
   219         NONE,
   220         /** Generate classes for implicitly read source files. */
   221         CLASS,
   222         /** Like CLASS, but generate warnings if annotation processing occurs */
   223         UNSET;
   224 
   225         static ImplicitSourcePolicy decode(String option) {
   226             if (option == null)
   227                 return UNSET;
   228             else if (option.equals("none"))
   229                 return NONE;
   230             else if (option.equals("class"))
   231                 return CLASS;
   232             else
   233                 return UNSET;
   234         }
   235     }
   236 
   237     /** The log to be used for error reporting.
   238      */
   239     public Log log;
   240 
   241     /** Factory for creating diagnostic objects
   242      */
   243     JCDiagnostic.Factory diagFactory;
   244 
   245     /** The tree factory module.
   246      */
   247     protected TreeMaker make;
   248 
   249     /** The class finder.
   250      */
   251     protected ClassFinder finder;
   252 
   253     /** The class reader.
   254      */
   255     protected ClassReader reader;
   256 
   257     /** The class writer.
   258      */
   259     protected ClassWriter writer;
   260 
   261     /** The native header writer.
   262      */
   263     protected JNIWriter jniWriter;
   264 
   265     /** The module for the symbol table entry phases.
   266      */
   267     protected Enter enter;
   268 
   269     /** The symbol table.
   270      */
   271     protected Symtab syms;
   272 
   273     /** The language version.
   274      */
   275     protected Source source;
   276 
   277     /** The module for code generation.
   278      */
   279     protected Gen gen;
   280 
   281     /** The name table.
   282      */
   283     protected Names names;
   284 
   285     /** The attributor.
   286      */
   287     protected Attr attr;
   288 
   289     /** The attributor.
   290      */
   291     protected Check chk;
   292 
   293     /** The flow analyzer.
   294      */
   295     protected Flow flow;
   296 
   297     /** The modules visitor
   298      */
   299     protected Modules modules;
   300 
   301     /** The module finder
   302      */
   303     protected ModuleFinder moduleFinder;
   304 
   305     /** The diagnostics factory
   306      */
   307     protected JCDiagnostic.Factory diags;
   308 
   309     
   310     /** The error repairer.
   311      */
   312     public Repair repair;
   313     
   314     /** The type eraser.
   315      */
   316     protected TransTypes transTypes;
   317 
   318     /** The syntactic sugar desweetener.
   319      */
   320     protected Lower lower;
   321 
   322     /** The annotation annotator.
   323      */
   324     protected Annotate annotate;
   325 
   326     /** Force a completion failure on this name
   327      */
   328     protected final Name completionFailureName;
   329 
   330     /** Type utilities.
   331      */
   332     protected Types types;
   333 
   334     /** Access to file objects.
   335      */
   336     protected JavaFileManager fileManager;
   337 
   338     /** Factory for parsers.
   339      */
   340     protected ParserFactory parserFactory;
   341 
   342     /** Broadcasting listener for progress events
   343      */
   344     protected MultiTaskListener taskListener;
   345 
   346     /**
   347      * SourceCompleter that delegates to the readSourceFile method of this class.
   348      */
   349     protected final Symbol.Completer sourceCompleter =
   350             sym -> readSourceFile((ClassSymbol) sym);
   351 
   352     /**
   353      * Command line options.
   354      */
   355     protected Options options;
   356 
   357     protected Context context;
   358 
   359     /**
   360      * Flag set if any annotation processing occurred.
   361      **/
   362     protected boolean annotationProcessingOccurred;
   363 
   364     /**
   365      * Flag set if any implicit source files read.
   366      **/
   367     protected boolean implicitSourceFilesRead;
   368 
   369     private boolean enterDone;
   370 
   371     protected CompileStates compileStates;
   372 
   373     protected Map<JavaFileObject, JCCompilationUnit> notYetEntered;
   374 
   375     public boolean skipAnnotationProcessing = false;
   376 
   377     private final DuplicateClassChecker duplicateClassChecker;
   378     public List<JCCompilationUnit> toProcessAnnotations = List.nil();
   379 
   380     /** Construct a new compiler using a shared context.
   381      */
   382     public JavaCompiler(Context context) {
   383         this.context = context;
   384         context.put(compilerKey, this);
   385 
   386         // if fileManager not already set, register the JavacFileManager to be used
   387         if (context.get(JavaFileManager.class) == null)
   388             JavacFileManager.preRegister(context);
   389 
   390         names = Names.instance(context);
   391         log = Log.instance(context);
   392         diagFactory = JCDiagnostic.Factory.instance(context);
   393         finder = ClassFinder.instance(context);
   394         reader = ClassReader.instance(context);
   395         make = TreeMaker.instance(context);
   396         writer = ClassWriter.instance(context);
   397         jniWriter = JNIWriter.instance(context);
   398         enter = Enter.instance(context);
   399         todo = Todo.instance(context);
   400 
   401         fileManager = context.get(JavaFileManager.class);
   402         parserFactory = ParserFactory.instance(context);
   403         compileStates = CompileStates.instance(context);
   404 
   405         try {
   406             // catch completion problems with predefineds
   407             syms = Symtab.instance(context);
   408         } catch (CompletionFailure ex) {
   409             // inlined Check.completionError as it is not initialized yet
   410             log.error("cant.access", ex.sym, ex.getDetailValue());
   411         }
   412         source = Source.instance(context);
   413         attr = Attr.instance(context);
   414         chk = Check.instance(context);
   415         gen = Gen.instance(context);
   416         flow = Flow.instance(context);
   417         repair = Repair.instance(context);
   418         transTypes = TransTypes.instance(context);
   419         lower = Lower.instance(context);
   420         annotate = Annotate.instance(context);
   421         types = Types.instance(context);
   422         taskListener = MultiTaskListener.instance(context);
   423         modules = Modules.instance(context);
   424         moduleFinder = ModuleFinder.instance(context);
   425         diags = Factory.instance(context);
   426         duplicateClassChecker = context.get(DuplicateClassChecker.class);
   427 
   428         finder.sourceCompleter = sourceCompleter;
   429         modules.findPackageInFile = this::findPackageInFile;
   430         moduleFinder.moduleNameFromSourceReader = this::readModuleName;
   431 
   432         options = Options.instance(context);
   433 
   434         verbose       = options.isSet(VERBOSE);
   435         sourceOutput  = options.isSet(PRINTSOURCE); // used to be -s
   436         lineDebugInfo = options.isUnset(G_CUSTOM) ||
   437                         options.isSet(G_CUSTOM, "lines");
   438         genEndPos     = options.isSet(XJCOV) ||
   439                         (context.get(DiagnosticListener.class) != null && options.get("backgroundCompilation") == null);
   440         devVerbose    = options.isSet("dev");
   441         processPcks   = options.isSet("process.packages");
   442         werror        = options.isSet(WERROR);
   443         keepComments  = options.getBoolean("keepComments");
   444 
   445         verboseCompilePolicy = options.isSet("verboseCompilePolicy");
   446 
   447         if (options.isSet("should-stop.at") &&
   448             CompileState.valueOf(options.get("should-stop.at")) == CompileState.ATTR)
   449             compilePolicy = CompilePolicy.ATTR_ONLY;
   450         else
   451             compilePolicy = CompilePolicy.decode(options.get("compilePolicy"));
   452 
   453         implicitSourcePolicy = ImplicitSourcePolicy.decode(options.get("-implicit"));
   454 
   455         completionFailureName =
   456             options.isSet("failcomplete")
   457             ? names.fromString(options.get("failcomplete"))
   458             : null;
   459 
   460         shouldStopPolicyIfError =
   461             options.isSet("should-stop.at") // backwards compatible
   462             ? CompileState.valueOf(options.get("should-stop.at"))
   463             : options.isSet("should-stop.ifError")
   464             ? CompileState.valueOf(options.get("should-stop.ifError"))
   465             : CompileState.INIT;
   466         shouldStopPolicyIfNoError =
   467             options.isSet("should-stop.ifNoError")
   468             ? CompileState.valueOf(options.get("should-stop.ifNoError"))
   469             : CompileState.GENERATE;
   470 
   471         if (options.isUnset("diags.legacy"))
   472             log.setDiagnosticFormatter(RichDiagnosticFormatter.instance(context));
   473 
   474         PlatformDescription platformProvider = context.get(PlatformDescription.class);
   475 
   476         if (platformProvider != null)
   477             closeables = closeables.prepend(platformProvider);
   478 
   479         silentFail = new Symbol(ABSENT_TYP, 0, names.empty, Type.noType, syms.rootPackage) {
   480             @DefinedBy(Api.LANGUAGE_MODEL)
   481             public <R, P> R accept(ElementVisitor<R, P> v, P p) {
   482                 return v.visitUnknown(this, p);
   483             }
   484             @Override
   485             public boolean exists() {
   486                 return false;
   487             }
   488         };
   489 
   490     }
   491 
   492     /* Switches:
   493      */
   494 
   495     /** Verbose output.
   496      */
   497     public boolean verbose;
   498 
   499     /** Emit plain Java source files rather than class files.
   500      */
   501     public boolean sourceOutput;
   502 
   503 
   504     /** Generate code with the LineNumberTable attribute for debugging
   505      */
   506     public boolean lineDebugInfo;
   507 
   508     /** Switch: should we store the ending positions?
   509      */
   510     public boolean genEndPos;
   511 
   512     /** Switch: should we debug ignored exceptions
   513      */
   514     protected boolean devVerbose;
   515 
   516     /** Switch: should we (annotation) process packages as well
   517      */
   518     protected boolean processPcks;
   519 
   520     /** Switch: treat warnings as errors
   521      */
   522     protected boolean werror;
   523 
   524     /** Switch: is annotation processing requested explicitly via
   525      * CompilationTask.setProcessors?
   526      */
   527     protected boolean explicitAnnotationProcessingRequested = false;
   528 
   529     /**
   530      * The policy for the order in which to perform the compilation
   531      */
   532     protected CompilePolicy compilePolicy;
   533 
   534     /**
   535      * The policy for what to do with implicitly read source files
   536      */
   537     protected ImplicitSourcePolicy implicitSourcePolicy;
   538 
   539     /**
   540      * Report activity related to compilePolicy
   541      */
   542     public boolean verboseCompilePolicy;
   543 
   544     /**
   545      * Policy of how far to continue compilation after errors have occurred.
   546      * Set this to minimum CompileState (INIT) to stop as soon as possible
   547      * after errors.
   548      */
   549     public CompileState shouldStopPolicyIfError;
   550 
   551     /**
   552      * Policy of how far to continue compilation when no errors have occurred.
   553      * Set this to maximum CompileState (GENERATE) to perform full compilation.
   554      * Set this lower to perform partial compilation, such as -proc:only.
   555      */
   556     public CompileState shouldStopPolicyIfNoError;
   557 
   558     /** A queue of all as yet unattributed classes.
   559      */
   560     public Todo todo;
   561 
   562     /** A list of items to be closed when the compilation is complete.
   563      */
   564     public List<Closeable> closeables = List.nil();
   565 
   566     /** The set of currently compiled inputfiles, needed to ensure
   567      *  we don't accidentally overwrite an input file when -s is set.
   568      *  initialized by `compile'.
   569      */
   570     protected Set<JavaFileObject> inputFiles = new HashSet<>();
   571 
   572     /** Used by the resolveBinaryNameOrIdent to say that the given type cannot be found, and that
   573      *  an error has already been produced about that.
   574      */
   575     private final Symbol silentFail;
   576 
   577     protected boolean shouldStop(CompileState cs) {
   578         CompileState shouldStopPolicy = (errorCount() > 0 || unrecoverableError())
   579             ? shouldStopPolicyIfError
   580             : shouldStopPolicyIfNoError;
   581         return cs.isAfter(shouldStopPolicy);
   582     }
   583 
   584     /** The number of errors reported so far.
   585      */
   586     public int errorCount() {
   587         if (werror && log.nerrors == 0 && log.nwarnings > 0) {
   588             log.error("warnings.and.werror");
   589         }
   590         return log.nerrors;
   591     }
   592 
   593     protected final <T> Queue<T> stopIfError(CompileState cs, Queue<T> queue) {
   594         return shouldStop(cs) ? new ListBuffer<T>() : queue;
   595     }
   596 
   597     protected final <T> List<T> stopIfError(CompileState cs, List<T> list) {
   598         return shouldStop(cs) ? List.nil() : list;
   599     }
   600 
   601     /** The number of warnings reported so far.
   602      */
   603     public int warningCount() {
   604         return log.nwarnings;
   605     }
   606 
   607     /** Try to open input stream with given name.
   608      *  Report an error if this fails.
   609      *  @param filename   The file name of the input stream to be opened.
   610      */
   611     public CharSequence readSource(JavaFileObject filename) {
   612         try {
   613             inputFiles.add(filename);
   614             return filename.getCharContent(false);
   615         } catch (IOException e) {
   616             log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
   617             return null;
   618         }
   619     }
   620 
   621     /** Parse contents of input stream.
   622      *  @param filename     The name of the file from which input stream comes.
   623      *  @param content      The characters to be parsed.
   624      */
   625     protected JCCompilationUnit parse(JavaFileObject filename, CharSequence content) {
   626         long msec = now();
   627         JCCompilationUnit tree = make.TopLevel(List.nil());
   628         if (content != null) {
   629             if (verbose) {
   630                 log.printVerbose("parsing.started", filename);
   631             }
   632             if (!taskListener.isEmpty()) {
   633                 TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, filename);
   634                 taskListener.started(e);
   635                 keepComments = true;
   636                 genEndPos = true;
   637             }
   638             Parser parser = parserFactory.newParser(content, keepComments(), genEndPos,
   639                                 lineDebugInfo, filename != null && filename.isNameCompatible("module-info", Kind.SOURCE));
   640             tree = parser.parseCompilationUnit();
   641             if (verbose) {
   642                 log.printVerbose("parsing.done", Long.toString(elapsed(msec)));
   643             }
   644         }
   645 
   646         tree.sourcefile = filename;
   647 
   648         if (content != null && !taskListener.isEmpty()) {
   649             TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, tree);
   650             taskListener.finished(e);
   651         }
   652 
   653         return tree;
   654     }
   655     // where
   656         public boolean keepComments = false;
   657         protected boolean keepComments() {
   658             return keepComments || sourceOutput;
   659         }
   660 
   661 
   662     /** Parse contents of file.
   663      *  @param filename     The name of the file to be parsed.
   664      */
   665     @Deprecated
   666     public JCTree.JCCompilationUnit parse(String filename) {
   667         JavacFileManager fm = (JavacFileManager)fileManager;
   668         return parse(fm.getJavaFileObjectsFromStrings(List.of(filename)).iterator().next());
   669     }
   670 
   671     /** Parse contents of file.
   672      *  @param filename     The name of the file to be parsed.
   673      */
   674     public JCTree.JCCompilationUnit parse(JavaFileObject filename) {
   675         JavaFileObject prev = log.useSource(filename);
   676         try {
   677             JCTree.JCCompilationUnit t = parse(filename, readSource(filename));
   678             if (t.endPositions != null)
   679                 log.setEndPosTable(filename, t.endPositions);
   680             return t;
   681         } finally {
   682             log.useSource(prev);
   683         }
   684     }
   685 
   686     /** Resolve an identifier which may be the binary name of a class or
   687      * the Java name of a class or package.
   688      * @param name      The name to resolve
   689      */
   690     public Symbol resolveBinaryNameOrIdent(String name) {
   691         ModuleSymbol msym;
   692         String typeName;
   693         int sep = name.indexOf('/');
   694         if (sep == -1) {
   695             msym = modules.getDefaultModule();
   696             typeName = name;
   697         } else if (source.allowModules()) {
   698             Name modName = names.fromString(name.substring(0, sep));
   699 
   700             msym = moduleFinder.findModule(modName);
   701             typeName = name.substring(sep + 1);
   702         } else {
   703             log.error(Errors.InvalidModuleSpecifier(name));
   704             return silentFail;
   705         }
   706 
   707         return resolveBinaryNameOrIdent(msym, typeName);
   708     }
   709 
   710     /** Resolve an identifier which may be the binary name of a class or
   711      * the Java name of a class or package.
   712      * @param msym      The module in which the search should be performed
   713      * @param name      The name to resolve
   714      */
   715     public Symbol resolveBinaryNameOrIdent(ModuleSymbol msym, String name) {
   716         try {
   717             Name flatname = names.fromString(name.replace("/", "."));
   718             return finder.loadClass(msym, flatname);
   719         } catch (CompletionFailure ignore) {
   720             return resolveIdent(msym, name);
   721         }
   722     }
   723 
   724     /** Resolve an identifier.
   725      * @param msym      The module in which the search should be performed
   726      * @param name      The identifier to resolve
   727      */
   728     public Symbol resolveIdent(ModuleSymbol msym, String name) {
   729         if (name.equals(""))
   730             return syms.errSymbol;
   731         JavaFileObject prev = log.useSource(null);
   732         Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(log);
   733         Log.DeferredDiagnosticHandler deferredHandler = deferredDiagnosticHandler;
   734         deferredDiagnosticHandler = null;
   735         try {
   736             JCExpression tree = null;
   737             for (String s : name.split("\\.", -1)) {
   738                 if (!SourceVersion.isIdentifier(s)) // TODO: check for keywords
   739                     return syms.errSymbol;
   740                 tree = (tree == null) ? make.Ident(names.fromString(s))
   741                                       : make.Select(tree, names.fromString(s));
   742             }
   743             JCCompilationUnit toplevel =
   744                 make.TopLevel(List.nil());
   745             toplevel.modle = msym;
   746             toplevel.packge = msym.unnamedPackage;
   747             Symbol ret = attr.attribIdent(tree, toplevel);
   748             if (!skipAnnotationProcessing && deferredDiagnosticHandler != null && toProcessAnnotations.nonEmpty())
   749                 processAnnotations(List.<JCCompilationUnit>nil());
   750             return ret;
   751         } finally {
   752             deferredDiagnosticHandler = deferredHandler;
   753             log.popDiagnosticHandler(discardHandler);
   754             log.useSource(prev);
   755         }
   756     }
   757 
   758     /** Generate code and emit a class file for a given class
   759      *  @param env    The attribution environment of the outermost class
   760      *                containing this class.
   761      *  @param cdef   The class definition from which code is generated.
   762      */
   763     JavaFileObject genCode(Env<AttrContext> env, JCClassDecl cdef) throws IOException {
   764         try {
   765             if (gen.genClass(env, cdef))
   766                 return writer.writeClass(cdef.sym);
   767         } catch (ClassWriter.PoolOverflow ex) {
   768             log.error(cdef.pos(), "limit.pool");
   769         } catch (ClassWriter.StringOverflow ex) {
   770             log.error(cdef.pos(), "limit.string.overflow",
   771                       ex.value.substring(0, 20));
   772         } catch (CompletionFailure ex) {
   773             chk.completionError(cdef.pos(), ex);
   774         }
   775         return null;
   776     }
   777 
   778     /** Emit plain Java source for a class.
   779      *  @param env    The attribution environment of the outermost class
   780      *                containing this class.
   781      *  @param cdef   The class definition to be printed.
   782      */
   783     JavaFileObject printSource(Env<AttrContext> env, JCClassDecl cdef) throws IOException {
   784         JavaFileObject outFile
   785            = fileManager.getJavaFileForOutput(CLASS_OUTPUT,
   786                                                cdef.sym.flatname.toString(),
   787                                                JavaFileObject.Kind.SOURCE,
   788                                                null);
   789         if (inputFiles.contains(outFile)) {
   790             log.error(cdef.pos(), "source.cant.overwrite.input.file", outFile);
   791             return null;
   792         } else {
   793             try (BufferedWriter out = new BufferedWriter(outFile.openWriter())) {
   794                 new Pretty(out, true).printUnit(env.toplevel, cdef);
   795                 if (verbose)
   796                     log.printVerbose("wrote.file", outFile);
   797             }
   798             return outFile;
   799         }
   800     }
   801 
   802     /** Compile a source file that has been accessed by the class finder.
   803      *  @param c          The class the source file of which needs to be compiled.
   804      */
   805     private void readSourceFile(ClassSymbol c) throws CompletionFailure {
   806         readSourceFile(null, c);
   807     }
   808 
   809     /** Compile a ClassSymbol from source, optionally using the given compilation unit as
   810      *  the source tree.
   811      *  @param tree the compilation unit in which the given ClassSymbol resides,
   812      *              or null if should be parsed from source
   813      *  @param c    the ClassSymbol to complete
   814      */
   815     public void readSourceFile(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure {
   816         if (completionFailureName == c.fullname) {
   817             throw new CompletionFailure(c, "user-selected completion failure by class name");
   818         }
   819         JavaFileObject filename = c.classfile;
   820 
   821         if (tree == null && notYetEntered != null) {
   822             tree = notYetEntered.remove(filename);
   823         }
   824         if (tree == null) {
   825             JavaFileObject prev = log.useSource(filename);
   826             try {
   827                 tree = parse(filename, filename.getCharContent(false));
   828             } catch (IOException e) {
   829                 log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
   830                 tree = make.TopLevel(List.<JCTree>nil());
   831             } finally {
   832                 log.useSource(prev);
   833             }
   834         }
   835 
   836         if (!taskListener.isEmpty()) {
   837             TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
   838             taskListener.started(e);
   839         }
   840 
   841         Log.DeferredDiagnosticHandler h = null;
   842         if (!skipAnnotationProcessing && processAnnotations && deferredDiagnosticHandler == null)
   843             deferredDiagnosticHandler = h = new Log.DeferredDiagnosticHandler(log);
   844             
   845 
   846         // Process module declarations.
   847         // If module resolution fails, ignore trees, and if trying to
   848         // complete a specific symbol, throw CompletionFailure.
   849         // Note that if module resolution failed, we may not even
   850         // have enough modules available to access java.lang, and
   851         // so risk getting FatalError("no.java.lang") from MemberEnter.
   852         if (!modules.enter(List.of(tree), c)) {
   853             throw new CompletionFailure(c, diags.fragment("cant.resolve.modules"));
   854         }
   855 
   856         enter.complete(List.of(tree), c);
   857 
   858         if (!taskListener.isEmpty()) {
   859             TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
   860             taskListener.finished(e);
   861         }
   862 
   863         if (enter.getEnv(c) == null) {
   864             boolean isPkgInfo =
   865                 tree.sourcefile.isNameCompatible("package-info",
   866                                                  JavaFileObject.Kind.SOURCE);
   867             boolean isModuleInfo =
   868                 tree.sourcefile.isNameCompatible("module-info",
   869                                                  JavaFileObject.Kind.SOURCE);
   870             if (isModuleInfo) {
   871                 if (enter.getEnv(tree.modle) == null) {
   872                     if (h != null) {
   873                         log.popDiagnosticHandler(h);
   874                         deferredDiagnosticHandler = null;
   875                     }
   876                     JCDiagnostic diag =
   877                         diagFactory.fragment("file.does.not.contain.module");
   878                     throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
   879                 }
   880             } else if (isPkgInfo) {
   881                 if (enter.getEnv(tree.packge) == null) {
   882                     if (h != null) {
   883                         log.popDiagnosticHandler(h);
   884                         deferredDiagnosticHandler = null;
   885                     }
   886                     JCDiagnostic diag =
   887                         diagFactory.fragment("file.does.not.contain.package",
   888                                                  c.location());
   889                     throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
   890                 }
   891             } else {
   892                 if (h != null) {
   893                     log.popDiagnosticHandler(h);
   894                     deferredDiagnosticHandler = null;
   895                 }
   896                 JCDiagnostic diag =
   897                         diagFactory.fragment("file.doesnt.contain.class",
   898                                             c.getQualifiedName());
   899                 throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
   900             }
   901         }
   902 
   903         if (!skipAnnotationProcessing && processAnnotations && checkEntered(tree)) {
   904             JCCompilationUnit t = tree;
   905             finder.ap = () -> {
   906                 if (annotate.annotationsBlocked() || annotate.isFlushing()) {
   907                     toProcessAnnotations = toProcessAnnotations.prepend(t);
   908                 } else {
   909                     skipAnnotationProcessing = true;
   910                     try {
   911                         processAnnotations(List.of(t));
   912                     } finally {
   913                         skipAnnotationProcessing = false;
   914                     }
   915                 }
   916             };
   917         }
   918 
   919         implicitSourceFilesRead = true;
   920     }
   921     
   922     private boolean checkEntered(JCCompilationUnit unit) {
   923         for (JCTree node : unit.defs) {
   924             if (node.hasTag(JCTree.Tag.CLASSDEF)) {
   925                 if (((JCClassDecl) node).sym == null) {
   926                     return false;
   927                 }
   928             }
   929         }
   930         return true;
   931     }
   932 
   933     /** Track when the JavaCompiler has been used to compile something. */
   934     private boolean hasBeenUsed = false;
   935     private long start_msec = 0;
   936     public long elapsed_msec = 0;
   937 
   938     public void compile(List<JavaFileObject> sourceFileObject)
   939         throws Throwable {
   940         compile(sourceFileObject, List.nil(), null, List.nil());
   941     }
   942 
   943     /**
   944      * Main method: compile a list of files, return all compiled classes
   945      *
   946      * @param sourceFileObjects file objects to be compiled
   947      * @param classnames class names to process for annotations
   948      * @param processors user provided annotation processors to bypass
   949      * discovery, {@code null} means that no processors were provided
   950      * @param addModules additional root modules to be used during
   951      * module resolution.
   952      */
   953     public void compile(Collection<JavaFileObject> sourceFileObjects,
   954                         Collection<String> classnames,
   955                         Iterable<? extends Processor> processors,
   956                         Collection<String> addModules)
   957     {
   958         if (!taskListener.isEmpty()) {
   959             taskListener.started(new TaskEvent(TaskEvent.Kind.COMPILATION));
   960         }
   961 
   962         if (processors != null && processors.iterator().hasNext())
   963             explicitAnnotationProcessingRequested = true;
   964         // as a JavaCompiler can only be used once, throw an exception if
   965         // it has been used before.
   966         if (hasBeenUsed)
   967             checkReusable();
   968         hasBeenUsed = true;
   969 
   970         // forcibly set the equivalent of -Xlint:-options, so that no further
   971         // warnings about command line options are generated from this point on
   972         options.put(XLINT_CUSTOM.primaryName + "-" + LintCategory.OPTIONS.option, "true");
   973         options.remove(XLINT_CUSTOM.primaryName + LintCategory.OPTIONS.option);
   974 
   975         start_msec = now();
   976 
   977         try {
   978             initProcessAnnotations(processors, sourceFileObjects, classnames);
   979 
   980             for (String className : classnames) {
   981                 int sep = className.indexOf('/');
   982                 if (sep != -1) {
   983                     modules.addExtraAddModules(className.substring(0, sep));
   984                 }
   985             }
   986 
   987             for (String moduleName : addModules) {
   988                 modules.addExtraAddModules(moduleName);
   989             }
   990 
   991             // These method calls must be chained to avoid memory leaks
   992             processAnnotations(
   993                 enterTrees(
   994                         stopIfError(CompileState.PARSE,
   995                                 initModules(stopIfError(CompileState.PARSE, parseFiles(sourceFileObjects))))
   996                 ),
   997                 classnames
   998             );
   999 
  1000             // If it's safe to do so, skip attr / flow / gen for implicit classes
  1001             if (taskListener.isEmpty() &&
  1002                     implicitSourcePolicy == ImplicitSourcePolicy.NONE) {
  1003                 todo.retainFiles(inputFiles);
  1004             }
  1005 
  1006             switch (compilePolicy) {
  1007             case ATTR_ONLY:
  1008                 attribute(todo);
  1009                 break;
  1010 
  1011             case CHECK_ONLY:
  1012                 flow(attribute(todo));
  1013                 break;
  1014 
  1015             case SIMPLE:
  1016                 generate(desugar(flow(attribute(todo))));
  1017                 break;
  1018 
  1019             case BY_FILE: {
  1020                     Queue<Queue<Env<AttrContext>>> q = todo.groupByFile();
  1021                     while (!q.isEmpty() && !shouldStop(CompileState.ATTR)) {
  1022                         generate(desugar(flow(attribute(q.remove()))));
  1023                     }
  1024                 }
  1025                 break;
  1026 
  1027             case BY_TODO:
  1028                 while (!todo.isEmpty())
  1029                     generate(desugar(flow(attribute(todo.remove()))));
  1030                 break;
  1031 
  1032             default:
  1033                 Assert.error("unknown compile policy");
  1034             }
  1035         } catch (Abort ex) {
  1036             if (devVerbose)
  1037                 ex.printStackTrace(System.err);
  1038         } finally {
  1039             if (verbose) {
  1040                 elapsed_msec = elapsed(start_msec);
  1041                 log.printVerbose("total", Long.toString(elapsed_msec));
  1042             }
  1043 
  1044             reportDeferredDiagnostics();
  1045 
  1046             if (!log.hasDiagnosticListener()) {
  1047                 printCount("error", errorCount());
  1048                 printCount("warn", warningCount());
  1049             }
  1050             if (!taskListener.isEmpty()) {
  1051                 taskListener.finished(new TaskEvent(TaskEvent.Kind.COMPILATION));
  1052             }
  1053             close();
  1054             if (procEnvImpl != null)
  1055                 procEnvImpl.close();
  1056         }
  1057     }
  1058 
  1059     protected void checkReusable() {
  1060         throw new AssertionError("attempt to reuse JavaCompiler");
  1061     }
  1062 
  1063     /**
  1064      * The list of classes explicitly supplied on the command line for compilation.
  1065      * Not always populated.
  1066      */
  1067     private List<JCClassDecl> rootClasses;
  1068 
  1069     /**
  1070      * Parses a list of files.
  1071      */
  1072    public List<JCCompilationUnit> parseFiles(Iterable<JavaFileObject> fileObjects) {
  1073        if (shouldStop(CompileState.PARSE))
  1074            return List.nil();
  1075 
  1076         //parse all files
  1077         ListBuffer<JCCompilationUnit> trees = new ListBuffer<>();
  1078         Set<JavaFileObject> filesSoFar = new HashSet<>();
  1079         for (JavaFileObject fileObject : fileObjects) {
  1080             if (!filesSoFar.contains(fileObject)) {
  1081                 filesSoFar.add(fileObject);
  1082                 trees.append(parse(fileObject));
  1083             }
  1084         }
  1085         return trees.toList();
  1086     }
  1087 
  1088     /**
  1089      * Enter the symbols found in a list of parse trees if the compilation
  1090      * is expected to proceed beyond anno processing into attr.
  1091      * As a side-effect, this puts elements on the "todo" list.
  1092      * Also stores a list of all top level classes in rootClasses.
  1093      */
  1094     public List<JCCompilationUnit> enterTreesIfNeeded(List<JCCompilationUnit> roots) {
  1095        if (shouldStop(CompileState.ATTR))
  1096            return List.nil();
  1097         return enterTrees(initModules(roots));
  1098     }
  1099 
  1100     public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
  1101         modules.initModules(roots);
  1102         if (roots.isEmpty()) {
  1103             enterDone();
  1104         }
  1105         return roots;
  1106     }
  1107 
  1108     /**
  1109      * Enter the symbols found in a list of parse trees.
  1110      * As a side-effect, this puts elements on the "todo" list.
  1111      * Also stores a list of all top level classes in rootClasses.
  1112      */
  1113     public List<JCCompilationUnit> enterTrees(List<JCCompilationUnit> roots) {
  1114         //enter symbols for all files
  1115         if (!taskListener.isEmpty()) {
  1116             for (JCCompilationUnit unit: roots) {
  1117                 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
  1118                 taskListener.started(e);
  1119             }
  1120         }
  1121 
  1122         enter.main(roots);
  1123 
  1124         enterDone();
  1125 
  1126         if (!taskListener.isEmpty()) {
  1127             for (JCCompilationUnit unit: roots) {
  1128                 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
  1129                 taskListener.finished(e);
  1130             }
  1131         }
  1132 
  1133         // If generating source, or if tracking public apis,
  1134         // then remember the classes declared in
  1135         // the original compilation units listed on the command line.
  1136         if (sourceOutput) {
  1137             ListBuffer<JCClassDecl> cdefs = new ListBuffer<>();
  1138             for (JCCompilationUnit unit : roots) {
  1139                 for (List<JCTree> defs = unit.defs;
  1140                         defs.nonEmpty();
  1141                         defs = defs.tail) {
  1142                     if (defs.head instanceof JCClassDecl) {
  1143                         cdefs.append((JCClassDecl) defs.head);
  1144                     }
  1145                 }
  1146             }
  1147             rootClasses = cdefs.toList();
  1148         }
  1149 
  1150         // Ensure the input files have been recorded. Although this is normally
  1151         // done by readSource, it may not have been done if the trees were read
  1152         // in a prior round of annotation processing, and the trees have been
  1153         // cleaned and are being reused.
  1154         for (JCCompilationUnit unit : roots) {
  1155             inputFiles.add(unit.sourcefile);
  1156         }
  1157 
  1158         return roots;
  1159     }
  1160 
  1161     public void initNotYetEntered(Map<JavaFileObject, JCCompilationUnit> notYetEntered) {
  1162         this.notYetEntered = notYetEntered;
  1163     }
  1164 
  1165     /**
  1166      * Set to true to enable skeleton annotation processing code.
  1167      * Currently, we assume this variable will be replaced more
  1168      * advanced logic to figure out if annotation processing is
  1169      * needed.
  1170      */
  1171     public boolean processAnnotations = false;
  1172 
  1173     public Log.DeferredDiagnosticHandler deferredDiagnosticHandler;
  1174 
  1175     /**
  1176      * Object to handle annotation processing.
  1177      */
  1178     private JavacProcessingEnvironment procEnvImpl = null;
  1179 
  1180     /**
  1181      * Check if we should process annotations.
  1182      * If so, and if no scanner is yet registered, then set up the DocCommentScanner
  1183      * to catch doc comments, and set keepComments so the parser records them in
  1184      * the compilation unit.
  1185      *
  1186      * @param processors user provided annotation processors to bypass
  1187      * discovery, {@code null} means that no processors were provided
  1188      */
  1189     public void initProcessAnnotations(Iterable<? extends Processor> processors,
  1190                                        Collection<? extends JavaFileObject> initialFiles,
  1191                                        Collection<String> initialClassNames) {
  1192         // Process annotations if processing is not disabled and there
  1193         // is at least one Processor available.
  1194         if (options.isSet(PROC, "none")) {
  1195             processAnnotations = false;
  1196         } else if (procEnvImpl == null) {
  1197             procEnvImpl = JavacProcessingEnvironment.instance(context);
  1198             procEnvImpl.setProcessors(processors);
  1199             processAnnotations = procEnvImpl.atLeastOneProcessor();
  1200 
  1201             if (processAnnotations) {
  1202                 options.put("parameters", "parameters");
  1203                 reader.saveParameterNames = true;
  1204                 keepComments = true;
  1205                 genEndPos = true;
  1206                 if (!taskListener.isEmpty())
  1207                     taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
  1208                 deferredDiagnosticHandler = new Log.DeferredDiagnosticHandler(log);
  1209                 procEnvImpl.getFiler().setInitialState(initialFiles, initialClassNames);
  1210             } else { // free resources
  1211                 procEnvImpl.close();
  1212             }
  1213         }
  1214     }
  1215 
  1216     // TODO: called by JavacTaskImpl
  1217     public void processAnnotations(List<JCCompilationUnit> roots) {
  1218         processAnnotations(roots, List.nil());
  1219     }
  1220 
  1221     /**
  1222      * Process any annotations found in the specified compilation units.
  1223      * @param roots a list of compilation units
  1224      */
  1225     // Implementation note: when this method is called, log.deferredDiagnostics
  1226     // will have been set true by initProcessAnnotations, meaning that any diagnostics
  1227     // that are reported will go into the log.deferredDiagnostics queue.
  1228     // By the time this method exits, log.deferDiagnostics must be set back to false,
  1229     // and all deferredDiagnostics must have been handled: i.e. either reported
  1230     // or determined to be transient, and therefore suppressed.
  1231     public void processAnnotations(List<JCCompilationUnit> roots,
  1232                                    Collection<String> classnames) {
  1233         List<JCCompilationUnit> currentRoots = toProcessAnnotations.prependList(roots);
  1234         toProcessAnnotations = List.nil();
  1235         if (shouldStop(CompileState.PROCESS)) {
  1236             // Errors were encountered.
  1237             // Unless all the errors are resolve errors, the errors were parse errors
  1238             // or other errors during enter which cannot be fixed by running
  1239             // any annotation processors.
  1240             if (unrecoverableError()) {
  1241                 deferredDiagnosticHandler.reportDeferredDiagnostics();
  1242                 log.popDiagnosticHandler(deferredDiagnosticHandler);
  1243                 deferredDiagnosticHandler = null;
  1244                 return ;
  1245             }
  1246         }
  1247 
  1248         // ASSERT: processAnnotations and procEnvImpl should have been set up by
  1249         // by initProcessAnnotations
  1250 
  1251         // NOTE: The !classnames.isEmpty() checks should be refactored to Main.
  1252 
  1253         if (!processAnnotations) {
  1254             // If there are no annotation processors present, and
  1255             // annotation processing is to occur with compilation,
  1256             // emit a warning.
  1257             if (options.isSet(PROC, "only")) {
  1258                 log.warning("proc.proc-only.requested.no.procs");
  1259                 todo.clear();
  1260             }
  1261             // If not processing annotations, classnames must be empty
  1262             if (!classnames.isEmpty()) {
  1263                 log.error("proc.no.explicit.annotation.processing.requested",
  1264                           classnames);
  1265             }
  1266             Assert.checkNull(deferredDiagnosticHandler);
  1267             return ; // continue regular compilation
  1268         }
  1269 
  1270         Assert.checkNonNull(deferredDiagnosticHandler);
  1271 
  1272         try {
  1273             List<ClassSymbol> classSymbols = List.nil();
  1274             List<PackageSymbol> pckSymbols = List.nil();
  1275             if (!classnames.isEmpty()) {
  1276                  // Check for explicit request for annotation
  1277                  // processing
  1278                 if (!explicitAnnotationProcessingRequested()) {
  1279                     log.error("proc.no.explicit.annotation.processing.requested",
  1280                               classnames);
  1281                     deferredDiagnosticHandler.reportDeferredDiagnostics();
  1282                     log.popDiagnosticHandler(deferredDiagnosticHandler);
  1283                     deferredDiagnosticHandler = null;
  1284                     return ; // TODO: Will this halt compilation?
  1285                 } else {
  1286                     boolean errors = false;
  1287                     for (String nameStr : classnames) {
  1288                         Symbol sym = resolveBinaryNameOrIdent(nameStr);
  1289                         if (sym == null ||
  1290                             (sym.kind == PCK && !processPcks) ||
  1291                             sym.kind == ABSENT_TYP) {
  1292                             if (sym != silentFail)
  1293                                 log.error(Errors.ProcCantFindClass(nameStr));
  1294                             errors = true;
  1295                             continue;
  1296                         }
  1297                         try {
  1298                             if (sym.kind == PCK)
  1299                                 sym.complete();
  1300                             if (sym.exists()) {
  1301                                 if (sym.kind == PCK)
  1302                                     pckSymbols = pckSymbols.prepend((PackageSymbol)sym);
  1303                                 else
  1304                                     classSymbols = classSymbols.prepend((ClassSymbol)sym);
  1305                                 continue;
  1306                             }
  1307                             Assert.check(sym.kind == PCK);
  1308                             log.warning(Warnings.ProcPackageDoesNotExist(nameStr));
  1309                             pckSymbols = pckSymbols.prepend((PackageSymbol)sym);
  1310                         } catch (CompletionFailure e) {
  1311                             log.error(Errors.ProcCantFindClass(nameStr));
  1312                             errors = true;
  1313                             continue;
  1314                         }
  1315                     }
  1316                     if (errors) {
  1317                         deferredDiagnosticHandler.reportDeferredDiagnostics();
  1318                         log.popDiagnosticHandler(deferredDiagnosticHandler);
  1319                         deferredDiagnosticHandler = null;
  1320                         return ;
  1321                     }
  1322                 }
  1323             }
  1324             final boolean hasOrigin = currentRoots.nonEmpty();
  1325             if (hasOrigin) {
  1326                 fileManager.handleOption("apt-origin", Collections.singleton(currentRoots.head.getSourceFile().toUri().toString()).iterator());    //NOI18N
  1327             }
  1328             try {
  1329                 annotationProcessingOccurred =
  1330                         procEnvImpl.doProcessing(currentRoots,
  1331                                                  classSymbols,
  1332                                                  pckSymbols,
  1333                                                  deferredDiagnosticHandler);
  1334                 // doProcessing will have handled deferred diagnostics
  1335             } finally {
  1336                 if (hasOrigin) {
  1337                     fileManager.handleOption("apt-origin", Collections.singletonList("").iterator());   //NOI18N
  1338                 }
  1339             }
  1340         } catch (CompletionFailure ex) {
  1341             log.error("cant.access", ex.sym, ex.getDetailValue());
  1342             if (deferredDiagnosticHandler != null) {
  1343                 deferredDiagnosticHandler.reportDeferredDiagnostics();
  1344                 log.popDiagnosticHandler(deferredDiagnosticHandler);
  1345                 deferredDiagnosticHandler = null;
  1346             }
  1347         }
  1348     }
  1349 
  1350     private boolean unrecoverableError() {
  1351         if (deferredDiagnosticHandler != null) {
  1352             for (JCDiagnostic d: deferredDiagnosticHandler.getDiagnostics()) {
  1353                 if (d.getKind() == JCDiagnostic.Kind.ERROR && !d.isFlagSet(RECOVERABLE))
  1354                     return true;
  1355             }
  1356         }
  1357         return false;
  1358     }
  1359 
  1360     boolean explicitAnnotationProcessingRequested() {
  1361         return
  1362             explicitAnnotationProcessingRequested ||
  1363             explicitAnnotationProcessingRequested(options);
  1364     }
  1365 
  1366     static boolean explicitAnnotationProcessingRequested(Options options) {
  1367         return
  1368             options.isSet(PROCESSOR) ||
  1369             options.isSet(PROCESSOR_PATH) ||
  1370             options.isSet(PROCESSOR_MODULE_PATH) ||
  1371             options.isSet(PROC, "only") ||
  1372             options.isSet(XPRINT);
  1373     }
  1374 
  1375     public void setDeferredDiagnosticHandler(Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
  1376         this.deferredDiagnosticHandler = deferredDiagnosticHandler;
  1377     }
  1378 
  1379     /**
  1380      * Attribute a list of parse trees, such as found on the "todo" list.
  1381      * Note that attributing classes may cause additional files to be
  1382      * parsed and entered via the SourceCompleter.
  1383      * Attribution of the entries in the list does not stop if any errors occur.
  1384      * @return a list of environments for attribute classes.
  1385      */
  1386     public Queue<Env<AttrContext>> attribute(Queue<Env<AttrContext>> envs) {
  1387         ListBuffer<Env<AttrContext>> results = new ListBuffer<>();
  1388         while (!envs.isEmpty())
  1389             results.append(attribute(envs.remove()));
  1390         return stopIfError(CompileState.ATTR, results);
  1391     }
  1392 
  1393     /**
  1394      * Attribute a parse tree.
  1395      * @return the attributed parse tree
  1396      */
  1397     public Env<AttrContext> attribute(Env<AttrContext> env) {
  1398         if (compileStates.isDone(env, CompileState.ATTR))
  1399             return env;
  1400 
  1401         if (verboseCompilePolicy)
  1402             printNote("[attribute " + env.enclClass.sym + "]");
  1403         if (verbose)
  1404             log.printVerbose("checking.attribution", env.enclClass.sym);
  1405 
  1406         if (!taskListener.isEmpty()) {
  1407             TaskEvent e = new TaskEvent(TaskEvent.Kind.ANALYZE, env.toplevel, env.enclClass.sym);
  1408             taskListener.started(e);
  1409         }
  1410 
  1411         JavaFileObject prev = log.useSource(
  1412                                   env.enclClass.sym.sourcefile != null ?
  1413                                   env.enclClass.sym.sourcefile :
  1414                                   env.toplevel.sourcefile);
  1415         try {
  1416             attr.attrib(env);
  1417             if (!shouldStop(CompileState.ATTR)) {
  1418                 //if in fail-over mode, ensure that AST expression nodes
  1419                 //are correctly initialized (e.g. they have a type/symbol)
  1420                 attr.postAttr(env.tree);
  1421             }
  1422             compileStates.put(env, CompileState.ATTR);
  1423         }
  1424         finally {
  1425             log.useSource(prev);
  1426         }
  1427 
  1428         return env;
  1429     }
  1430 
  1431     /**
  1432      * Perform dataflow checks on attributed parse trees.
  1433      * These include checks for definite assignment and unreachable statements.
  1434      * If any errors occur, an empty list will be returned.
  1435      * @return the list of attributed parse trees
  1436      */
  1437     public Queue<Env<AttrContext>> flow(Queue<Env<AttrContext>> envs) {
  1438         ListBuffer<Env<AttrContext>> results = new ListBuffer<>();
  1439         for (Env<AttrContext> env: envs) {
  1440             flow(env, results);
  1441         }
  1442         return stopIfError(CompileState.FLOW, results);
  1443     }
  1444 
  1445     /**
  1446      * Perform dataflow checks on an attributed parse tree.
  1447      */
  1448     public Queue<Env<AttrContext>> flow(Env<AttrContext> env) {
  1449         ListBuffer<Env<AttrContext>> results = new ListBuffer<>();
  1450         flow(env, results);
  1451         return stopIfError(CompileState.FLOW, results);
  1452     }
  1453 
  1454     /**
  1455      * Perform dataflow checks on an attributed parse tree.
  1456      */
  1457     protected void flow(Env<AttrContext> env, Queue<Env<AttrContext>> results) {
  1458         if (compileStates.isDone(env, CompileState.FLOW)) {
  1459             results.add(env);
  1460             return;
  1461         }
  1462 
  1463         try {
  1464             if (shouldStop(CompileState.FLOW))
  1465                 return;
  1466 
  1467             if (verboseCompilePolicy)
  1468                 printNote("[flow " + env.enclClass.sym + "]");
  1469             JavaFileObject prev = log.useSource(
  1470                                                 env.enclClass.sym.sourcefile != null ?
  1471                                                 env.enclClass.sym.sourcefile :
  1472                                                 env.toplevel.sourcefile);
  1473             try {
  1474                 make.at(Position.FIRSTPOS);
  1475                 TreeMaker localMake = make.forToplevel(env.toplevel);
  1476                 flow.analyzeTree(env, localMake);
  1477                 compileStates.put(env, CompileState.FLOW);
  1478 
  1479                 if (shouldStop(CompileState.FLOW))
  1480                     return;
  1481 
  1482                 results.add(env);
  1483             }
  1484             finally {
  1485                 log.useSource(prev);
  1486             }
  1487         }
  1488         finally {
  1489             if (!taskListener.isEmpty()) {
  1490                 TaskEvent e = new TaskEvent(TaskEvent.Kind.ANALYZE, env.toplevel, env.enclClass.sym);
  1491                 taskListener.finished(e);
  1492             }
  1493         }
  1494     }
  1495 
  1496     public boolean doRepair = true; // Allows for switching off repair. For test purposes only.
  1497 
  1498     /**
  1499      * Prepare attributed parse trees, in conjunction with their attribution contexts,
  1500      * for source or code generation.
  1501      * If any errors occur, an empty list will be returned.
  1502      * @return a list containing the classes to be generated
  1503      */
  1504     public Queue<Pair<Env<AttrContext>, JCClassDecl>> desugar(Queue<Env<AttrContext>> envs) {
  1505         ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results = new ListBuffer<>();
  1506         for (Env<AttrContext> env: envs)
  1507             desugar(env, results);
  1508         return stopIfError(CompileState.FLOW, results);
  1509     }
  1510 
  1511     HashMap<Env<AttrContext>, Queue<Pair<Env<AttrContext>, JCClassDecl>>> desugaredEnvs = new HashMap<>();
  1512 
  1513     /**
  1514      * Prepare attributed parse trees, in conjunction with their attribution contexts,
  1515      * for source or code generation. If the file was not listed on the command line,
  1516      * the current implicitSourcePolicy is taken into account.
  1517      * The preparation stops as soon as an error is found.
  1518      */
  1519     protected void desugar(final Env<AttrContext> env, Queue<Pair<Env<AttrContext>, JCClassDecl>> results) {
  1520         if (shouldStop(CompileState.TRANSTYPES))
  1521             return;
  1522 
  1523         if (implicitSourcePolicy == ImplicitSourcePolicy.NONE
  1524                 && !inputFiles.contains(env.toplevel.sourcefile)) {
  1525             return;
  1526         }
  1527 
  1528         if (!modules.multiModuleMode && env.toplevel.modle != modules.getDefaultModule()) {
  1529             //can only generate classfiles for a single module:
  1530             return;
  1531         }
  1532 
  1533         if (duplicateClassChecker != null && env.tree.hasTag(JCTree.Tag.CLASSDEF) && duplicateClassChecker.check(((JCClassDecl)env.tree).sym.fullname,
  1534                 env.enclClass.sym.sourcefile != null
  1535                 ? env.enclClass.sym.sourcefile
  1536                 : env.toplevel.sourcefile)) {
  1537             return;
  1538         }
  1539 
  1540         if (compileStates.isDone(env, CompileState.LOWER)) {
  1541             results.addAll(desugaredEnvs.get(env));
  1542             return;
  1543         }
  1544 
  1545         /**
  1546          * Ensure that superclasses of C are desugared before C itself. This is
  1547          * required for two reasons: (i) as erasure (TransTypes) destroys
  1548          * information needed in flow analysis and (ii) as some checks carried
  1549          * out during lowering require that all synthetic fields/methods have
  1550          * already been added to C and its superclasses.
  1551          */
  1552         class ScanNested extends TreeScanner {
  1553             Set<Env<AttrContext>> dependencies = new LinkedHashSet<>();
  1554             protected boolean hasLambdas;
  1555             @Override
  1556             public void visitClassDef(JCClassDecl node) {
  1557                 if (node.sym != null) {
  1558                     Type st = types.supertype(node.sym.type);
  1559                     boolean envForSuperTypeFound = false;
  1560                     while (!envForSuperTypeFound && st != null && st.hasTag(CLASS)) {
  1561                         ClassSymbol c = st.tsym.outermostClass();
  1562                         Env<AttrContext> stEnv = enter.getEnv(c);
  1563                         if (stEnv != null && env != stEnv) {
  1564                             if (dependencies.add(stEnv)) {
  1565                                 boolean prevHasLambdas = hasLambdas;
  1566                                 try {
  1567                                     scan(stEnv.tree);
  1568                                 } finally {
  1569                                     /*
  1570                                      * ignore any updates to hasLambdas made during
  1571                                      * the nested scan, this ensures an initalized
  1572                                      * LambdaToMethod is available only to those
  1573                                      * classes that contain lambdas
  1574                                      */
  1575                                     hasLambdas = prevHasLambdas;
  1576                                 }
  1577                             }
  1578                             envForSuperTypeFound = true;
  1579                         }
  1580                         st = types.supertype(st);
  1581                     }
  1582                 }
  1583                 super.visitClassDef(node);
  1584             }
  1585             @Override
  1586             public void visitLambda(JCLambda tree) {
  1587                 hasLambdas = true;
  1588                 super.visitLambda(tree);
  1589             }
  1590             @Override
  1591             public void visitReference(JCMemberReference tree) {
  1592                 hasLambdas = true;
  1593                 super.visitReference(tree);
  1594             }
  1595         }
  1596         ScanNested scanner = new ScanNested();
  1597         scanner.scan(env.tree);
  1598         for (Env<AttrContext> dep: scanner.dependencies) {
  1599         if (!compileStates.isDone(dep, CompileState.FLOW))
  1600             desugaredEnvs.put(dep, desugar(flow(attribute(dep))));
  1601         }
  1602 
  1603         //We need to check for error another time as more classes might
  1604         //have been attributed and analyzed at this stage
  1605         if (shouldStop(CompileState.TRANSTYPES))
  1606             return;
  1607 
  1608         if (verboseCompilePolicy)
  1609             printNote("[desugar " + env.enclClass.sym + "]");
  1610 
  1611         JavaFileObject prev = log.useSource(env.enclClass.sym.sourcefile != null ?
  1612                                   env.enclClass.sym.sourcefile :
  1613                                   env.toplevel.sourcefile);
  1614         try {
  1615             //save tree prior to rewriting
  1616             JCTree untranslated = env.tree;
  1617 
  1618             make.at(Position.FIRSTPOS);
  1619             TreeMaker localMake = make.forToplevel(env.toplevel);
  1620 
  1621             if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF) || env.tree.hasTag(JCTree.Tag.MODULEDEF)) {
  1622                 if (!(sourceOutput)) {
  1623                     if (shouldStop(CompileState.LOWER))
  1624                         return;
  1625                     List<JCTree> def = lower.translateTopLevelClass(env, env.tree, localMake);
  1626                     if (def.head != null) {
  1627                         Assert.check(def.tail.isEmpty());
  1628                         results.add(new Pair<>(env, (JCClassDecl)def.head));
  1629                     }
  1630                 }
  1631                 return;
  1632             }
  1633 
  1634             if (doRepair)
  1635                 env.tree = repair.translateTopLevelClass(env, env.tree, localMake);
  1636 
  1637             if (shouldStop(CompileState.TRANSTYPES))
  1638                 return;
  1639 
  1640             env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
  1641             compileStates.put(env, CompileState.TRANSTYPES);
  1642 
  1643             if (source.allowLambda() && scanner.hasLambdas) {
  1644                 if (shouldStop(CompileState.UNLAMBDA))
  1645                     return;
  1646 
  1647                 env.tree = LambdaToMethod.instance(context).translateTopLevelClass(env, env.tree, localMake);
  1648                 compileStates.put(env, CompileState.UNLAMBDA);
  1649             }
  1650 
  1651             if (shouldStop(CompileState.LOWER))
  1652                 return;
  1653 
  1654             if (sourceOutput) {
  1655                 //emit standard Java source file, only for compilation
  1656                 //units enumerated explicitly on the command line
  1657                 JCClassDecl cdef = (JCClassDecl)env.tree;
  1658                 if (untranslated instanceof JCClassDecl &&
  1659                     rootClasses.contains((JCClassDecl)untranslated)) {
  1660                     results.add(new Pair<>(env, cdef));
  1661                 }
  1662                 return;
  1663             }
  1664 
  1665             //translate out inner classes
  1666             List<JCTree> cdefs = lower.translateTopLevelClass(env, env.tree, localMake);
  1667             compileStates.put(env, CompileState.LOWER);
  1668 
  1669             if (shouldStop(CompileState.LOWER))
  1670                 return;
  1671 
  1672             //generate code for each class
  1673             for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
  1674                 JCClassDecl cdef = (JCClassDecl)l.head;
  1675                 results.add(new Pair<>(env, cdef));
  1676             }
  1677         }
  1678         finally {
  1679             log.useSource(prev);
  1680         }
  1681 
  1682     }
  1683 
  1684     /** Generates the source or class file for a list of classes.
  1685      * The decision to generate a source file or a class file is
  1686      * based upon the compiler's options.
  1687      * Generation stops if an error occurs while writing files.
  1688      */
  1689     public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
  1690         generate(queue, null);
  1691     }
  1692 
  1693     public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue, Queue<JavaFileObject> results) {
  1694         if (shouldStop(CompileState.GENERATE))
  1695             return;
  1696 
  1697         for (Pair<Env<AttrContext>, JCClassDecl> x: queue) {
  1698             Env<AttrContext> env = x.fst;
  1699             JCClassDecl cdef = x.snd;
  1700 
  1701             if (verboseCompilePolicy) {
  1702                 printNote("[generate " + (sourceOutput ? " source" : "code") + " " + cdef.sym + "]");
  1703             }
  1704 
  1705             if (!taskListener.isEmpty()) {
  1706                 TaskEvent e = new TaskEvent(TaskEvent.Kind.GENERATE, env.toplevel, cdef.sym);
  1707                 taskListener.started(e);
  1708             }
  1709 
  1710             JavaFileObject prev = log.useSource(env.enclClass.sym.sourcefile != null ?
  1711                                       env.enclClass.sym.sourcefile :
  1712                                       env.toplevel.sourcefile);
  1713             try {
  1714                 JavaFileObject file = null;
  1715                 if (sourceOutput) {
  1716                     file = printSource(env, cdef);
  1717                 } else {
  1718                     try {
  1719                         writeHeader(cdef);
  1720                     } catch (LinkageError ex) {
  1721                         log.error(cdef.pos(), "class.cant.write",
  1722                                   cdef.sym, ex.getMessage());
  1723                     }
  1724                     file = genCode(env, cdef);
  1725                 }
  1726                 if (results != null && file != null)
  1727                     results.add(file);
  1728             } catch (IOException ex) {
  1729                 log.error(cdef.pos(), "class.cant.write",
  1730                           cdef.sym, ex.getMessage());
  1731                 return;
  1732             } finally {
  1733                 log.useSource(prev);
  1734             }
  1735 
  1736             if (!taskListener.isEmpty()) {
  1737                 TaskEvent e = new TaskEvent(TaskEvent.Kind.GENERATE, env.toplevel, cdef.sym);
  1738                 taskListener.finished(e);
  1739             }
  1740         }
  1741     }
  1742     
  1743     private void writeHeader(JCClassDecl cdef) throws IOException {
  1744         if (fileManager.hasLocation(StandardLocation.NATIVE_HEADER_OUTPUT)
  1745                 && jniWriter.needsHeader(cdef.sym)) {
  1746             jniWriter.write(cdef.sym);
  1747         }
  1748     }
  1749 
  1750         // where
  1751         Map<JCCompilationUnit, Queue<Env<AttrContext>>> groupByFile(Queue<Env<AttrContext>> envs) {
  1752             // use a LinkedHashMap to preserve the order of the original list as much as possible
  1753             Map<JCCompilationUnit, Queue<Env<AttrContext>>> map = new LinkedHashMap<>();
  1754             for (Env<AttrContext> env: envs) {
  1755                 Queue<Env<AttrContext>> sublist = map.get(env.toplevel);
  1756                 if (sublist == null) {
  1757                     sublist = new ListBuffer<>();
  1758                     map.put(env.toplevel, sublist);
  1759                 }
  1760                 sublist.add(env);
  1761             }
  1762             return map;
  1763         }
  1764 
  1765         JCClassDecl removeMethodBodies(JCClassDecl cdef) {
  1766             final boolean isInterface = (cdef.mods.flags & Flags.INTERFACE) != 0;
  1767             class MethodBodyRemover extends TreeTranslator {
  1768                 @Override
  1769                 public void visitMethodDef(JCMethodDecl tree) {
  1770                     tree.mods.flags &= ~Flags.SYNCHRONIZED;
  1771                     for (JCVariableDecl vd : tree.params)
  1772                         vd.mods.flags &= ~Flags.FINAL;
  1773                     tree.body = null;
  1774                     super.visitMethodDef(tree);
  1775                 }
  1776                 @Override
  1777                 public void visitVarDef(JCVariableDecl tree) {
  1778                     if (tree.init != null && tree.init.type.constValue() == null)
  1779                         tree.init = null;
  1780                     super.visitVarDef(tree);
  1781                 }
  1782                 @Override
  1783                 public void visitClassDef(JCClassDecl tree) {
  1784                     ListBuffer<JCTree> newdefs = new ListBuffer<>();
  1785                     for (List<JCTree> it = tree.defs; it.tail != null; it = it.tail) {
  1786                         JCTree t = it.head;
  1787                         switch (t.getTag()) {
  1788                         case CLASSDEF:
  1789                             if (isInterface ||
  1790                                 (((JCClassDecl) t).mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 ||
  1791                                 (((JCClassDecl) t).mods.flags & (Flags.PRIVATE)) == 0 && ((JCClassDecl) t).sym.packge().getQualifiedName() == names.java_lang)
  1792                                 newdefs.append(t);
  1793                             break;
  1794                         case METHODDEF:
  1795                             if (isInterface ||
  1796                                 (((JCMethodDecl) t).mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 ||
  1797                                 ((JCMethodDecl) t).sym.name == names.init ||
  1798                                 (((JCMethodDecl) t).mods.flags & (Flags.PRIVATE)) == 0 && ((JCMethodDecl) t).sym.packge().getQualifiedName() == names.java_lang)
  1799                                 newdefs.append(t);
  1800                             break;
  1801                         case VARDEF:
  1802                             if (isInterface || (((JCVariableDecl) t).mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 ||
  1803                                 (((JCVariableDecl) t).mods.flags & (Flags.PRIVATE)) == 0 && ((JCVariableDecl) t).sym.packge().getQualifiedName() == names.java_lang)
  1804                                 newdefs.append(t);
  1805                             break;
  1806                         default:
  1807                             break;
  1808                         }
  1809                     }
  1810                     tree.defs = newdefs.toList();
  1811                     super.visitClassDef(tree);
  1812                 }
  1813             }
  1814             MethodBodyRemover r = new MethodBodyRemover();
  1815             return r.translate(cdef);
  1816         }
  1817 
  1818     public void reportDeferredDiagnostics() {
  1819         if (errorCount() == 0
  1820                 && annotationProcessingOccurred
  1821                 && implicitSourceFilesRead
  1822                 && implicitSourcePolicy == ImplicitSourcePolicy.UNSET) {
  1823             if (explicitAnnotationProcessingRequested())
  1824                 log.warning("proc.use.implicit");
  1825             else
  1826                 log.warning("proc.use.proc.or.implicit");
  1827         }
  1828         chk.reportDeferredDiagnostics();
  1829         if (log.compressedOutput) {
  1830             log.mandatoryNote(null, "compressed.diags");
  1831         }
  1832     }
  1833 
  1834     public void enterDone() {
  1835         enterDone = true;
  1836         annotate.enterDone();
  1837     }
  1838 
  1839     public boolean isEnterDone() {
  1840         return enterDone;
  1841     }
  1842 
  1843     private Name readModuleName(JavaFileObject fo) {
  1844         return parseAndGetName(fo, t -> {
  1845             JCModuleDecl md = t.getModuleDecl();
  1846 
  1847             return md != null ? TreeInfo.fullName(md.getName()) : null;
  1848         });
  1849     }
  1850 
  1851     private Name findPackageInFile(JavaFileObject fo) {
  1852         return parseAndGetName(fo, t -> t.getPackage() != null ?
  1853                                         TreeInfo.fullName(t.getPackage().getPackageName()) : null);
  1854     }
  1855 
  1856     private Name parseAndGetName(JavaFileObject fo,
  1857                                  Function<JCTree.JCCompilationUnit, Name> tree2Name) {
  1858         DiagnosticHandler dh = new DiscardDiagnosticHandler(log);
  1859         try {
  1860             JCTree.JCCompilationUnit t = parse(fo, fo.getCharContent(false));
  1861             return tree2Name.apply(t);
  1862         } catch (IOException e) {
  1863             return null;
  1864         } finally {
  1865             log.popDiagnosticHandler(dh);
  1866         }
  1867     }
  1868 
  1869     public void resetEnterDone() {
  1870         enterDone = false;
  1871     }
  1872 
  1873     /** Close the compiler, flushing the logs
  1874      */
  1875     public void close() {
  1876         rootClasses = null;
  1877         finder = null;
  1878         reader = null;
  1879         make = null;
  1880         writer = null;
  1881         enter = null;
  1882         if (todo != null)
  1883             todo.clear();
  1884         todo = null;
  1885         parserFactory = null;
  1886         syms = null;
  1887         source = null;
  1888         attr = null;
  1889         chk = null;
  1890         gen = null;
  1891         flow = null;
  1892         transTypes = null;
  1893         lower = null;
  1894         annotate = null;
  1895         types = null;
  1896 
  1897         log.flush();
  1898         try {
  1899             fileManager.flush();
  1900             if (procEnvImpl != null)
  1901                 procEnvImpl.close();
  1902             procEnvImpl = null;
  1903         } catch (IOException e) {
  1904             throw new Abort(e);
  1905         } finally {
  1906             if (names != null)
  1907                 names.dispose();
  1908             names = null;
  1909 
  1910             for (Closeable c: closeables) {
  1911                 try {
  1912                     c.close();
  1913                 } catch (IOException e) {
  1914                     // When javac uses JDK 7 as a baseline, this code would be
  1915                     // better written to set any/all exceptions from all the
  1916                     // Closeables as suppressed exceptions on the FatalError
  1917                     // that is thrown.
  1918                     JCDiagnostic msg = diagFactory.fragment("fatal.err.cant.close");
  1919                     throw new FatalError(msg, e);
  1920                 }
  1921             }
  1922             closeables = List.nil();
  1923         }
  1924     }
  1925 
  1926     protected void printNote(String lines) {
  1927         log.printRawLines(Log.WriterKind.NOTICE, lines);
  1928     }
  1929 
  1930     /** Print numbers of errors and warnings.
  1931      */
  1932     public void printCount(String kind, int count) {
  1933         if (count != 0) {
  1934             String key;
  1935             if (count == 1)
  1936                 key = "count." + kind;
  1937             else
  1938                 key = "count." + kind + ".plural";
  1939             log.printLines(WriterKind.ERROR, key, String.valueOf(count));
  1940             log.flush(Log.WriterKind.ERROR);
  1941         }
  1942     }
  1943 
  1944     private static long now() {
  1945         return System.currentTimeMillis();
  1946     }
  1947 
  1948     private static long elapsed(long then) {
  1949         return now() - then;
  1950     }
  1951 
  1952     public void newRound(final Set<? extends JCCompilationUnit> treesToClean) {
  1953         for (JCCompilationUnit treeToClean : treesToClean) {
  1954             if (treeToClean.sourcefile != null) {
  1955                 inputFiles.remove(treeToClean.sourcefile);
  1956             }
  1957         }
  1958         for (Iterator<Env<AttrContext>> it = todo.iterator(); it.hasNext();) {
  1959             final Env<AttrContext> env = it.next();
  1960             if (treesToClean.contains(env.toplevel)) {
  1961                 it.remove();
  1962             }
  1963         }
  1964     }
  1965 }