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