< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java

Print this page

   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.nio.file.FileSystemNotFoundException;
  30 import java.nio.file.InvalidPathException;
  31 import java.nio.file.ReadOnlyFileSystemException;
  32 import java.util.Collection;
  33 import java.util.Comparator;
  34 import java.util.EnumSet;
  35 import java.util.HashMap;
  36 import java.util.HashSet;
  37 import java.util.LinkedHashMap;
  38 import java.util.LinkedHashSet;
  39 import java.util.Map;
  40 import java.util.MissingResourceException;

  41 import java.util.Queue;
  42 import java.util.ResourceBundle;

  43 import java.util.Set;
  44 import java.util.function.Function;
  45 import java.util.function.ToIntFunction;
  46 
  47 import javax.annotation.processing.Processor;
  48 import javax.lang.model.SourceVersion;
  49 import javax.lang.model.element.ElementVisitor;
  50 import javax.tools.DiagnosticListener;
  51 import javax.tools.JavaFileManager;
  52 import javax.tools.JavaFileObject;
  53 import javax.tools.JavaFileObject.Kind;
  54 import javax.tools.StandardLocation;
  55 
  56 import com.sun.source.util.TaskEvent;
  57 import com.sun.tools.javac.api.MultiTaskListener;
  58 import com.sun.tools.javac.code.*;
  59 import com.sun.tools.javac.code.Lint.LintCategory;
  60 import com.sun.tools.javac.code.Source.Feature;
  61 import com.sun.tools.javac.code.Symbol.ClassSymbol;
  62 import com.sun.tools.javac.code.Symbol.CompletionFailure;

  70 import com.sun.tools.javac.platform.PlatformDescription;
  71 import com.sun.tools.javac.processing.*;
  72 import com.sun.tools.javac.tree.*;
  73 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
  74 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
  75 import com.sun.tools.javac.tree.JCTree.JCExpression;
  76 import com.sun.tools.javac.tree.JCTree.JCLambda;
  77 import com.sun.tools.javac.tree.JCTree.JCMemberReference;
  78 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
  79 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
  80 import com.sun.tools.javac.util.*;
  81 import com.sun.tools.javac.util.Context.Key;
  82 import com.sun.tools.javac.util.DefinedBy.Api;
  83 import com.sun.tools.javac.util.JCDiagnostic.Factory;
  84 import com.sun.tools.javac.util.Log.DiagnosticHandler;
  85 import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
  86 import com.sun.tools.javac.util.Log.WriterKind;
  87 
  88 import static com.sun.tools.javac.code.Kinds.Kind.*;
  89 


  90 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  91 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  92 import com.sun.tools.javac.resources.CompilerProperties.Notes;
  93 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  94 
  95 import static com.sun.tools.javac.code.TypeTag.CLASS;
  96 import static com.sun.tools.javac.main.Option.*;
  97 import com.sun.tools.javac.tree.JCTree.JCBindingPattern;
  98 import com.sun.tools.javac.tree.JCTree.JCInstanceOf;
  99 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
 100 
 101 import static javax.tools.StandardLocation.CLASS_OUTPUT;
 102 import static javax.tools.StandardLocation.ANNOTATION_PROCESSOR_PATH;
 103 
 104 import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
 105 import com.sun.tools.javac.tree.JCTree.JCRecordPattern;
 106 import com.sun.tools.javac.tree.JCTree.JCSwitch;
 107 import com.sun.tools.javac.tree.JCTree.JCSwitchExpression;
 108 
 109 /** This class could be the main entry point for GJC when GJC is used as a

 360      * Command line options.
 361      */
 362     protected Options options;
 363 
 364     protected Context context;
 365 
 366     /**
 367      * Flag set if any annotation processing occurred.
 368      **/
 369     protected boolean annotationProcessingOccurred;
 370 
 371     /**
 372      * Flag set if any implicit source files read.
 373      **/
 374     protected boolean implicitSourceFilesRead;
 375 
 376     private boolean enterDone;
 377 
 378     protected CompileStates compileStates;
 379 


 380     /** Construct a new compiler using a shared context.
 381      */
 382     @SuppressWarnings("this-escape")
 383     public JavaCompiler(Context context) {
 384         this.context = context;
 385         context.put(compilerKey, this);
 386 
 387         // if fileManager not already set, register the JavacFileManager to be used
 388         if (context.get(JavaFileManager.class) == null)
 389             JavacFileManager.preRegister(context);
 390 
 391         names = Names.instance(context);
 392         log = Log.instance(context);
 393         lintMapper = LintMapper.instance(context);
 394         diagFactory = JCDiagnostic.Factory.instance(context);
 395         finder = ClassFinder.instance(context);
 396         reader = ClassReader.instance(context);
 397         make = TreeMaker.instance(context);
 398         writer = ClassWriter.instance(context);
 399         jniWriter = JNIWriter.instance(context);

 760                 tree = (tree == null) ? make.Ident(names.fromString(s))
 761                                       : make.Select(tree, names.fromString(s));
 762             }
 763             JCCompilationUnit toplevel =
 764                 make.TopLevel(List.nil());
 765             toplevel.modle = msym;
 766             toplevel.packge = msym.unnamedPackage;
 767             return attr.attribIdent(tree, toplevel);
 768         } finally {
 769             log.useSource(prev);
 770         }
 771     }
 772 
 773     /** Generate code and emit a class file for a given class
 774      *  @param env    The attribution environment of the outermost class
 775      *                containing this class.
 776      *  @param cdef   The class definition from which code is generated.
 777      */
 778     JavaFileObject genCode(Env<AttrContext> env, JCClassDecl cdef) throws IOException {
 779         try {







 780             if (gen.genClass(env, cdef) && (errorCount() == 0))
 781                 return writer.writeClass(cdef.sym);
 782         } catch (ClassWriter.PoolOverflow ex) {
 783             log.error(cdef.pos(), Errors.LimitPool);
 784         } catch (ClassWriter.StringOverflow ex) {
 785             log.error(cdef.pos(),
 786                       Errors.LimitStringOverflow(ex.value.substring(0, 20)));
 787         } catch (CompletionFailure ex) {
 788             chk.completionError(cdef.pos(), ex);
 789         }
 790         return null;
 791     }
 792 
 793     /** Emit plain Java source for a class.
 794      *  @param env    The attribution environment of the outermost class
 795      *                containing this class.
 796      *  @param cdef   The class definition to be printed.
 797      */
 798     JavaFileObject printSource(Env<AttrContext> env, JCClassDecl cdef) throws IOException {
 799         JavaFileObject outFile

1042         Set<JavaFileObject> filesSoFar = new HashSet<>();
1043         for (JavaFileObject fileObject : fileObjects) {
1044             if (!filesSoFar.contains(fileObject)) {
1045                 filesSoFar.add(fileObject);
1046                 trees.append(parse(fileObject));
1047             }
1048         }
1049         return trees.toList();
1050     }
1051 
1052    /**
1053     * Returns true iff the compilation will continue after annotation processing
1054     * is done.
1055     */
1056     public boolean continueAfterProcessAnnotations() {
1057         return !shouldStop(CompileState.ATTR);
1058     }
1059 
1060     public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
1061         modules.initModules(roots);









1062         if (roots.isEmpty()) {
1063             enterDone();
1064         }
1065         return roots;
1066     }
1067 
1068     /**
1069      * Enter the symbols found in a list of parse trees.
1070      * As a side-effect, this puts elements on the "todo" list.
1071      * Also stores a list of all top level classes in rootClasses.
1072      */
1073     public List<JCCompilationUnit> enterTrees(List<JCCompilationUnit> roots) {
1074         //enter symbols for all files
1075         if (!taskListener.isEmpty()) {
1076             for (JCCompilationUnit unit: roots) {
1077                 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
1078                 taskListener.started(e);
1079             }
1080         }
1081 

1655 
1656             make.at(Position.FIRSTPOS);
1657             TreeMaker localMake = make.forToplevel(env.toplevel);
1658 
1659             if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF) || env.tree.hasTag(JCTree.Tag.MODULEDEF)) {
1660                 if (!(sourceOutput)) {
1661                     if (shouldStop(CompileState.LOWER))
1662                         return;
1663                     List<JCTree> def = lower.translateTopLevelClass(env, env.tree, localMake);
1664                     if (def.head != null) {
1665                         Assert.check(def.tail.isEmpty());
1666                         results.add(new Pair<>(env, (JCClassDecl)def.head));
1667                     }
1668                 }
1669                 return;
1670             }
1671 
1672             if (shouldStop(CompileState.TRANSTYPES))
1673                 return;
1674 







1675             env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
1676             compileStates.put(env, CompileState.TRANSTYPES);
1677 
1678             if (shouldStop(CompileState.TRANSPATTERNS))
1679                 return;
1680 
1681             if (scanner.hasPatterns) {
1682                 env.tree = TransPatterns.instance(context).translateTopLevelClass(env, env.tree, localMake);
1683             }
1684 
1685             compileStates.put(env, CompileState.TRANSPATTERNS);
1686 
1687             if (shouldStop(CompileState.LOWER))
1688                 return;
1689 
1690             if (sourceOutput) {
1691                 //emit standard Java source file, only for compilation
1692                 //units enumerated explicitly on the command line
1693                 JCClassDecl cdef = (JCClassDecl)env.tree;
1694                 if (untranslated instanceof JCClassDecl classDecl &&

1710                     return;
1711 
1712                 for (JCTree def : cdefs) {
1713                     LambdaToMethod.instance(context).translateTopLevelClass(env, def, localMake);
1714                 }
1715                 compileStates.put(env, CompileState.UNLAMBDA);
1716             }
1717 
1718             //generate code for each class
1719             for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
1720                 JCClassDecl cdef = (JCClassDecl)l.head;
1721                 results.add(new Pair<>(env, cdef));
1722             }
1723         }
1724         finally {
1725             log.useSource(prev);
1726         }
1727 
1728     }
1729 










































1730     /** Generates the source or class file for a list of classes.
1731      * The decision to generate a source file or a class file is
1732      * based upon the compiler's options.
1733      * Generation stops if an error occurs while writing files.
1734      */
1735     public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
1736         generate(queue, null);
1737     }
1738 
1739     public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue, Queue<JavaFileObject> results) {
1740         if (shouldStop(CompileState.GENERATE))
1741             return;
1742 
1743         for (Pair<Env<AttrContext>, JCClassDecl> x: queue) {
1744             Env<AttrContext> env = x.fst;
1745             JCClassDecl cdef = x.snd;
1746 
1747             if (verboseCompilePolicy) {
1748                 printNote("[generate " + (sourceOutput ? " source" : "code") + " " + cdef.sym + "]");
1749             }

1865                 log.warning(Warnings.ProcUseImplicit);
1866             else
1867                 log.warning(Warnings.ProcUseProcOrImplicit);
1868         }
1869         log.reportOutstandingWarnings();
1870         log.reportOutstandingNotes();
1871         if (log.compressedOutput) {
1872             log.note(Notes.CompressedDiags);
1873         }
1874     }
1875 
1876     public void enterDone() {
1877         enterDone = true;
1878         annotate.enterDone();
1879     }
1880 
1881     public boolean isEnterDone() {
1882         return enterDone;
1883     }
1884 




1885     private Name readModuleName(JavaFileObject fo) {
1886         return parseAndGetName(fo, t -> {
1887             JCModuleDecl md = t.getModuleDecl();
1888 
1889             return md != null ? TreeInfo.fullName(md.getName()) : null;
1890         });
1891     }
1892 
1893     private Name findPackageInFile(JavaFileObject fo) {
1894         return parseAndGetName(fo, t -> t.getPackage() != null ?
1895                                         TreeInfo.fullName(t.getPackage().getPackageName()) : null);
1896     }
1897 
1898     private Name parseAndGetName(JavaFileObject fo,
1899                                  Function<JCTree.JCCompilationUnit, Name> tree2Name) {
1900         DiagnosticHandler dh = log.new DiscardDiagnosticHandler();
1901         JavaFileObject prevSource = log.useSource(fo);
1902         try {
1903             JCTree.JCCompilationUnit t = parse(fo, fo.getCharContent(false), true);
1904             return tree2Name.apply(t);

   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.lang.module.Configuration;
  30 import java.lang.reflect.Method;
  31 import java.nio.file.FileSystemNotFoundException;
  32 import java.nio.file.InvalidPathException;
  33 import java.nio.file.ReadOnlyFileSystemException;
  34 import java.util.Collection;
  35 import java.util.Comparator;
  36 import java.util.EnumSet;
  37 import java.util.HashMap;
  38 import java.util.HashSet;
  39 import java.util.LinkedHashMap;
  40 import java.util.LinkedHashSet;
  41 import java.util.Map;
  42 import java.util.MissingResourceException;
  43 import java.util.Optional;
  44 import java.util.Queue;
  45 import java.util.ResourceBundle;
  46 import java.util.ServiceLoader;
  47 import java.util.Set;
  48 import java.util.function.Function;
  49 import java.util.function.ToIntFunction;
  50 
  51 import javax.annotation.processing.Processor;
  52 import javax.lang.model.SourceVersion;
  53 import javax.lang.model.element.ElementVisitor;
  54 import javax.tools.DiagnosticListener;
  55 import javax.tools.JavaFileManager;
  56 import javax.tools.JavaFileObject;
  57 import javax.tools.JavaFileObject.Kind;
  58 import javax.tools.StandardLocation;
  59 
  60 import com.sun.source.util.TaskEvent;
  61 import com.sun.tools.javac.api.MultiTaskListener;
  62 import com.sun.tools.javac.code.*;
  63 import com.sun.tools.javac.code.Lint.LintCategory;
  64 import com.sun.tools.javac.code.Source.Feature;
  65 import com.sun.tools.javac.code.Symbol.ClassSymbol;
  66 import com.sun.tools.javac.code.Symbol.CompletionFailure;

  74 import com.sun.tools.javac.platform.PlatformDescription;
  75 import com.sun.tools.javac.processing.*;
  76 import com.sun.tools.javac.tree.*;
  77 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
  78 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
  79 import com.sun.tools.javac.tree.JCTree.JCExpression;
  80 import com.sun.tools.javac.tree.JCTree.JCLambda;
  81 import com.sun.tools.javac.tree.JCTree.JCMemberReference;
  82 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
  83 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
  84 import com.sun.tools.javac.util.*;
  85 import com.sun.tools.javac.util.Context.Key;
  86 import com.sun.tools.javac.util.DefinedBy.Api;
  87 import com.sun.tools.javac.util.JCDiagnostic.Factory;
  88 import com.sun.tools.javac.util.Log.DiagnosticHandler;
  89 import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
  90 import com.sun.tools.javac.util.Log.WriterKind;
  91 
  92 import static com.sun.tools.javac.code.Kinds.Kind.*;
  93 
  94 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
  95 
  96 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  97 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  98 import com.sun.tools.javac.resources.CompilerProperties.Notes;
  99 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
 100 
 101 import static com.sun.tools.javac.code.TypeTag.CLASS;
 102 import static com.sun.tools.javac.main.Option.*;
 103 import com.sun.tools.javac.tree.JCTree.JCBindingPattern;
 104 import com.sun.tools.javac.tree.JCTree.JCInstanceOf;
 105 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
 106 
 107 import static javax.tools.StandardLocation.CLASS_OUTPUT;
 108 import static javax.tools.StandardLocation.ANNOTATION_PROCESSOR_PATH;
 109 
 110 import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
 111 import com.sun.tools.javac.tree.JCTree.JCRecordPattern;
 112 import com.sun.tools.javac.tree.JCTree.JCSwitch;
 113 import com.sun.tools.javac.tree.JCTree.JCSwitchExpression;
 114 
 115 /** This class could be the main entry point for GJC when GJC is used as a

 366      * Command line options.
 367      */
 368     protected Options options;
 369 
 370     protected Context context;
 371 
 372     /**
 373      * Flag set if any annotation processing occurred.
 374      **/
 375     protected boolean annotationProcessingOccurred;
 376 
 377     /**
 378      * Flag set if any implicit source files read.
 379      **/
 380     protected boolean implicitSourceFilesRead;
 381 
 382     private boolean enterDone;
 383 
 384     protected CompileStates compileStates;
 385 
 386     private boolean hasCodeReflectionModule;
 387 
 388     /** Construct a new compiler using a shared context.
 389      */
 390     @SuppressWarnings("this-escape")
 391     public JavaCompiler(Context context) {
 392         this.context = context;
 393         context.put(compilerKey, this);
 394 
 395         // if fileManager not already set, register the JavacFileManager to be used
 396         if (context.get(JavaFileManager.class) == null)
 397             JavacFileManager.preRegister(context);
 398 
 399         names = Names.instance(context);
 400         log = Log.instance(context);
 401         lintMapper = LintMapper.instance(context);
 402         diagFactory = JCDiagnostic.Factory.instance(context);
 403         finder = ClassFinder.instance(context);
 404         reader = ClassReader.instance(context);
 405         make = TreeMaker.instance(context);
 406         writer = ClassWriter.instance(context);
 407         jniWriter = JNIWriter.instance(context);

 768                 tree = (tree == null) ? make.Ident(names.fromString(s))
 769                                       : make.Select(tree, names.fromString(s));
 770             }
 771             JCCompilationUnit toplevel =
 772                 make.TopLevel(List.nil());
 773             toplevel.modle = msym;
 774             toplevel.packge = msym.unnamedPackage;
 775             return attr.attribIdent(tree, toplevel);
 776         } finally {
 777             log.useSource(prev);
 778         }
 779     }
 780 
 781     /** Generate code and emit a class file for a given class
 782      *  @param env    The attribution environment of the outermost class
 783      *                containing this class.
 784      *  @param cdef   The class definition from which code is generated.
 785      */
 786     JavaFileObject genCode(Env<AttrContext> env, JCClassDecl cdef) throws IOException {
 787         try {
 788             if (Feature.REFLECT_METHODS.allowedInSource(source)) {
 789                 Optional<CodeReflectionTransformer> reflectMethods = reflectMethods();
 790                 if (reflectMethods.isPresent()) {
 791                     reflectMethods.get().genCode(context, cdef);
 792                 }
 793             }
 794 
 795             if (gen.genClass(env, cdef) && (errorCount() == 0))
 796                 return writer.writeClass(cdef.sym);
 797         } catch (ClassWriter.PoolOverflow ex) {
 798             log.error(cdef.pos(), Errors.LimitPool);
 799         } catch (ClassWriter.StringOverflow ex) {
 800             log.error(cdef.pos(),
 801                       Errors.LimitStringOverflow(ex.value.substring(0, 20)));
 802         } catch (CompletionFailure ex) {
 803             chk.completionError(cdef.pos(), ex);
 804         }
 805         return null;
 806     }
 807 
 808     /** Emit plain Java source for a class.
 809      *  @param env    The attribution environment of the outermost class
 810      *                containing this class.
 811      *  @param cdef   The class definition to be printed.
 812      */
 813     JavaFileObject printSource(Env<AttrContext> env, JCClassDecl cdef) throws IOException {
 814         JavaFileObject outFile

1057         Set<JavaFileObject> filesSoFar = new HashSet<>();
1058         for (JavaFileObject fileObject : fileObjects) {
1059             if (!filesSoFar.contains(fileObject)) {
1060                 filesSoFar.add(fileObject);
1061                 trees.append(parse(fileObject));
1062             }
1063         }
1064         return trees.toList();
1065     }
1066 
1067    /**
1068     * Returns true iff the compilation will continue after annotation processing
1069     * is done.
1070     */
1071     public boolean continueAfterProcessAnnotations() {
1072         return !shouldStop(CompileState.ATTR);
1073     }
1074 
1075     public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
1076         modules.initModules(roots);
1077 
1078         if (modules.modulesInitialized()) {
1079             // This has to happen precisely here. At this point, we have all we need to
1080             // determine whether jdk.incubator.module is part of the module graph
1081             // but we have yet to trigger an ENTER event. This gives the code reflection plugin
1082             // a window to check whether code reflection should be enabled for this compilation unit.
1083             hasCodeReflectionModule = modules.getObservableModule(names.jdk_incubator_code) != null;
1084         }
1085 
1086         if (roots.isEmpty()) {
1087             enterDone();
1088         }
1089         return roots;
1090     }
1091 
1092     /**
1093      * Enter the symbols found in a list of parse trees.
1094      * As a side-effect, this puts elements on the "todo" list.
1095      * Also stores a list of all top level classes in rootClasses.
1096      */
1097     public List<JCCompilationUnit> enterTrees(List<JCCompilationUnit> roots) {
1098         //enter symbols for all files
1099         if (!taskListener.isEmpty()) {
1100             for (JCCompilationUnit unit: roots) {
1101                 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
1102                 taskListener.started(e);
1103             }
1104         }
1105 

1679 
1680             make.at(Position.FIRSTPOS);
1681             TreeMaker localMake = make.forToplevel(env.toplevel);
1682 
1683             if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF) || env.tree.hasTag(JCTree.Tag.MODULEDEF)) {
1684                 if (!(sourceOutput)) {
1685                     if (shouldStop(CompileState.LOWER))
1686                         return;
1687                     List<JCTree> def = lower.translateTopLevelClass(env, env.tree, localMake);
1688                     if (def.head != null) {
1689                         Assert.check(def.tail.isEmpty());
1690                         results.add(new Pair<>(env, (JCClassDecl)def.head));
1691                     }
1692                 }
1693                 return;
1694             }
1695 
1696             if (shouldStop(CompileState.TRANSTYPES))
1697                 return;
1698 
1699             if (Feature.REFLECT_METHODS.allowedInSource(source)) {
1700                 Optional<CodeReflectionTransformer> reflectMethods = reflectMethods();
1701                 if (reflectMethods.isPresent()) {
1702                     env.tree = reflectMethods.get().translateTopLevelClass(context, env.tree, localMake);
1703                 }
1704             }
1705 
1706             env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
1707             compileStates.put(env, CompileState.TRANSTYPES);
1708 
1709             if (shouldStop(CompileState.TRANSPATTERNS))
1710                 return;
1711 
1712             if (scanner.hasPatterns) {
1713                 env.tree = TransPatterns.instance(context).translateTopLevelClass(env, env.tree, localMake);
1714             }
1715 
1716             compileStates.put(env, CompileState.TRANSPATTERNS);
1717 
1718             if (shouldStop(CompileState.LOWER))
1719                 return;
1720 
1721             if (sourceOutput) {
1722                 //emit standard Java source file, only for compilation
1723                 //units enumerated explicitly on the command line
1724                 JCClassDecl cdef = (JCClassDecl)env.tree;
1725                 if (untranslated instanceof JCClassDecl classDecl &&

1741                     return;
1742 
1743                 for (JCTree def : cdefs) {
1744                     LambdaToMethod.instance(context).translateTopLevelClass(env, def, localMake);
1745                 }
1746                 compileStates.put(env, CompileState.UNLAMBDA);
1747             }
1748 
1749             //generate code for each class
1750             for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
1751                 JCClassDecl cdef = (JCClassDecl)l.head;
1752                 results.add(new Pair<>(env, cdef));
1753             }
1754         }
1755         finally {
1756             log.useSource(prev);
1757         }
1758 
1759     }
1760 
1761     Optional<CodeReflectionTransformer> reflectMethods() {
1762         return CodeReflectionSupport.CODE_LAYER != null ?
1763                 ServiceLoader.load(CodeReflectionSupport.CODE_LAYER, CodeReflectionTransformer.class).findFirst() :
1764                 Optional.empty();
1765     }
1766 
1767     public static class CodeReflectionSupport {
1768         public static final ModuleLayer CODE_LAYER;
1769 
1770         static {
1771             if (ModuleLayer.boot().findModule("jdk.incubator.code").isPresent()) {
1772                 // we are in an exploded build, so just use the boot layer
1773                 CODE_LAYER = ModuleLayer.boot();
1774             } else if (java.lang.module.ModuleFinder.ofSystem().find("jdk.incubator.code").isPresent()) {
1775                 // the code module is installed, but not in the boot layer, create a new layer which contains it
1776                 ModuleLayer parent = ModuleLayer.boot();
1777                 Configuration cf = parent.configuration()
1778                         .resolve(java.lang.module.ModuleFinder.of(), java.lang.module.ModuleFinder.ofSystem(), Set.of("jdk.incubator.code"));
1779                 ClassLoader scl = ClassLoader.getSystemClassLoader();
1780                 CODE_LAYER = parent.defineModulesWithOneLoader(cf, scl);
1781                 Module codeReflectionModule = CODE_LAYER.findModule("jdk.incubator.code").get();
1782                 Module jdkCompilerModule = JavaCompiler.class.getModule();
1783                 // We need to add exports all jdk.compiler packages so that the plugin can use them
1784                 for (String packageName : jdkCompilerModule.getPackages()) {
1785                     jdkCompilerModule.addExports(packageName, codeReflectionModule);
1786                 }
1787                 // We also need to add exports all java.base packages so that the plugin can use them
1788                 // But we need to do so by calling a method in java.base reflectively
1789                 try {
1790                     Class<?> codeModuleLayerInit = Class.forName("jdk.internal.access.code.CodeModuleLayerInit");
1791                     Method initLayerMethod = codeModuleLayerInit.getDeclaredMethod("initCodeModuleLayer", ModuleLayer.class);
1792                     initLayerMethod.invoke(null, CODE_LAYER);
1793                 } catch (ReflectiveOperationException ex) {
1794                     throw new AssertionError(ex);
1795                 }
1796             } else {
1797                 // if we run in bootstrap mode, there might be no jdk.incubator.code
1798                 CODE_LAYER = null;
1799             }
1800         }
1801     }
1802 
1803     /** Generates the source or class file for a list of classes.
1804      * The decision to generate a source file or a class file is
1805      * based upon the compiler's options.
1806      * Generation stops if an error occurs while writing files.
1807      */
1808     public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
1809         generate(queue, null);
1810     }
1811 
1812     public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue, Queue<JavaFileObject> results) {
1813         if (shouldStop(CompileState.GENERATE))
1814             return;
1815 
1816         for (Pair<Env<AttrContext>, JCClassDecl> x: queue) {
1817             Env<AttrContext> env = x.fst;
1818             JCClassDecl cdef = x.snd;
1819 
1820             if (verboseCompilePolicy) {
1821                 printNote("[generate " + (sourceOutput ? " source" : "code") + " " + cdef.sym + "]");
1822             }

1938                 log.warning(Warnings.ProcUseImplicit);
1939             else
1940                 log.warning(Warnings.ProcUseProcOrImplicit);
1941         }
1942         log.reportOutstandingWarnings();
1943         log.reportOutstandingNotes();
1944         if (log.compressedOutput) {
1945             log.note(Notes.CompressedDiags);
1946         }
1947     }
1948 
1949     public void enterDone() {
1950         enterDone = true;
1951         annotate.enterDone();
1952     }
1953 
1954     public boolean isEnterDone() {
1955         return enterDone;
1956     }
1957 
1958     public boolean hasCodeReflectionModule() {
1959         return hasCodeReflectionModule;
1960     }
1961 
1962     private Name readModuleName(JavaFileObject fo) {
1963         return parseAndGetName(fo, t -> {
1964             JCModuleDecl md = t.getModuleDecl();
1965 
1966             return md != null ? TreeInfo.fullName(md.getName()) : null;
1967         });
1968     }
1969 
1970     private Name findPackageInFile(JavaFileObject fo) {
1971         return parseAndGetName(fo, t -> t.getPackage() != null ?
1972                                         TreeInfo.fullName(t.getPackage().getPackageName()) : null);
1973     }
1974 
1975     private Name parseAndGetName(JavaFileObject fo,
1976                                  Function<JCTree.JCCompilationUnit, Name> tree2Name) {
1977         DiagnosticHandler dh = log.new DiscardDiagnosticHandler();
1978         JavaFileObject prevSource = log.useSource(fo);
1979         try {
1980             JCTree.JCCompilationUnit t = parse(fo, fo.getCharContent(false), true);
1981             return tree2Name.apply(t);
< prev index next >