< 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.HashMap;
  35 import java.util.HashSet;
  36 import java.util.LinkedHashMap;
  37 import java.util.LinkedHashSet;
  38 import java.util.Map;
  39 import java.util.MissingResourceException;

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

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

  68 import com.sun.tools.javac.platform.PlatformDescription;
  69 import com.sun.tools.javac.processing.*;
  70 import com.sun.tools.javac.tree.*;
  71 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
  72 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
  73 import com.sun.tools.javac.tree.JCTree.JCExpression;
  74 import com.sun.tools.javac.tree.JCTree.JCLambda;
  75 import com.sun.tools.javac.tree.JCTree.JCMemberReference;
  76 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
  77 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
  78 import com.sun.tools.javac.util.*;
  79 import com.sun.tools.javac.util.Context.Key;
  80 import com.sun.tools.javac.util.DefinedBy.Api;
  81 import com.sun.tools.javac.util.JCDiagnostic.Factory;
  82 import com.sun.tools.javac.util.Log.DiagnosticHandler;
  83 import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
  84 import com.sun.tools.javac.util.Log.WriterKind;
  85 
  86 import static com.sun.tools.javac.code.Kinds.Kind.*;
  87 
  88 import com.sun.tools.javac.code.Lint;
  89 import com.sun.tools.javac.code.Lint.LintCategory;
  90 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
  91 
  92 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  93 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  94 import com.sun.tools.javac.resources.CompilerProperties.Notes;
  95 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  96 
  97 import static com.sun.tools.javac.code.TypeTag.CLASS;
  98 import static com.sun.tools.javac.main.Option.*;
  99 import com.sun.tools.javac.tree.JCTree.JCBindingPattern;
 100 import com.sun.tools.javac.tree.JCTree.JCInstanceOf;
 101 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
 102 
 103 import static javax.tools.StandardLocation.CLASS_OUTPUT;
 104 import static javax.tools.StandardLocation.ANNOTATION_PROCESSOR_PATH;
 105 
 106 import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
 107 import com.sun.tools.javac.tree.JCTree.JCRecordPattern;
 108 import com.sun.tools.javac.tree.JCTree.JCSwitch;
 109 import com.sun.tools.javac.tree.JCTree.JCSwitchExpression;

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


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

1028         Set<JavaFileObject> filesSoFar = new HashSet<>();
1029         for (JavaFileObject fileObject : fileObjects) {
1030             if (!filesSoFar.contains(fileObject)) {
1031                 filesSoFar.add(fileObject);
1032                 trees.append(parse(fileObject));
1033             }
1034         }
1035         return trees.toList();
1036     }
1037 
1038    /**
1039     * Returns true iff the compilation will continue after annotation processing
1040     * is done.
1041     */
1042     public boolean continueAfterProcessAnnotations() {
1043         return !shouldStop(CompileState.ATTR);
1044     }
1045 
1046     public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
1047         modules.initModules(roots);









1048         if (roots.isEmpty()) {
1049             enterDone();
1050         }
1051         return roots;
1052     }
1053 
1054     /**
1055      * Enter the symbols found in a list of parse trees.
1056      * As a side-effect, this puts elements on the "todo" list.
1057      * Also stores a list of all top level classes in rootClasses.
1058      */
1059     public List<JCCompilationUnit> enterTrees(List<JCCompilationUnit> roots) {
1060         //enter symbols for all files
1061         if (!taskListener.isEmpty()) {
1062             for (JCCompilationUnit unit: roots) {
1063                 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
1064                 taskListener.started(e);
1065             }
1066         }
1067 

1641 
1642             make.at(Position.FIRSTPOS);
1643             TreeMaker localMake = make.forToplevel(env.toplevel);
1644 
1645             if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF) || env.tree.hasTag(JCTree.Tag.MODULEDEF)) {
1646                 if (!(sourceOutput)) {
1647                     if (shouldStop(CompileState.LOWER))
1648                         return;
1649                     List<JCTree> def = lower.translateTopLevelClass(env, env.tree, localMake);
1650                     if (def.head != null) {
1651                         Assert.check(def.tail.isEmpty());
1652                         results.add(new Pair<>(env, (JCClassDecl)def.head));
1653                     }
1654                 }
1655                 return;
1656             }
1657 
1658             if (shouldStop(CompileState.TRANSTYPES))
1659                 return;
1660 







1661             env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
1662             compileStates.put(env, CompileState.TRANSTYPES);
1663 
1664             if (shouldStop(CompileState.TRANSPATTERNS))
1665                 return;
1666 
1667             if (scanner.hasPatterns) {
1668                 env.tree = TransPatterns.instance(context).translateTopLevelClass(env, env.tree, localMake);

1669             }
1670 
1671             compileStates.put(env, CompileState.TRANSPATTERNS);
1672 
1673             if (shouldStop(CompileState.LOWER))
1674                 return;
1675 
1676             if (sourceOutput) {
1677                 //emit standard Java source file, only for compilation
1678                 //units enumerated explicitly on the command line
1679                 JCClassDecl cdef = (JCClassDecl)env.tree;
1680                 if (untranslated instanceof JCClassDecl classDecl &&
1681                     rootClasses.contains(classDecl)) {
1682                     results.add(new Pair<>(env, cdef));
1683                 }
1684                 return;
1685             }
1686 
1687             //translate out inner classes
1688             List<JCTree> cdefs = lower.translateTopLevelClass(env, env.tree, localMake);

1696                     return;
1697 
1698                 for (JCTree def : cdefs) {
1699                     LambdaToMethod.instance(context).translateTopLevelClass(env, def, localMake);
1700                 }
1701                 compileStates.put(env, CompileState.UNLAMBDA);
1702             }
1703 
1704             //generate code for each class
1705             for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
1706                 JCClassDecl cdef = (JCClassDecl)l.head;
1707                 results.add(new Pair<>(env, cdef));
1708             }
1709         }
1710         finally {
1711             log.useSource(prev);
1712         }
1713 
1714     }
1715 










































1716     /** Generates the source or class file for a list of classes.
1717      * The decision to generate a source file or a class file is
1718      * based upon the compiler's options.
1719      * Generation stops if an error occurs while writing files.
1720      */
1721     public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
1722         generate(queue, null);
1723     }
1724 
1725     public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue, Queue<JavaFileObject> results) {
1726         if (shouldStop(CompileState.GENERATE))
1727             return;
1728 
1729         for (Pair<Env<AttrContext>, JCClassDecl> x: queue) {
1730             Env<AttrContext> env = x.fst;
1731             JCClassDecl cdef = x.snd;
1732 
1733             if (verboseCompilePolicy) {
1734                 printNote("[generate " + (sourceOutput ? " source" : "code") + " " + cdef.sym + "]");
1735             }

1851                 log.warning(Warnings.ProcUseImplicit);
1852             else
1853                 log.warning(Warnings.ProcUseProcOrImplicit);
1854         }
1855         chk.reportDeferredDiagnostics();
1856         preview.reportDeferredDiagnostics();
1857         if (log.compressedOutput) {
1858             log.mandatoryNote(null, Notes.CompressedDiags);
1859         }
1860     }
1861 
1862     public void enterDone() {
1863         enterDone = true;
1864         annotate.enterDone();
1865     }
1866 
1867     public boolean isEnterDone() {
1868         return enterDone;
1869     }
1870 




1871     private Name readModuleName(JavaFileObject fo) {
1872         return parseAndGetName(fo, t -> {
1873             JCModuleDecl md = t.getModuleDecl();
1874 
1875             return md != null ? TreeInfo.fullName(md.getName()) : null;
1876         });
1877     }
1878 
1879     private Name findPackageInFile(JavaFileObject fo) {
1880         return parseAndGetName(fo, t -> t.getPackage() != null ?
1881                                         TreeInfo.fullName(t.getPackage().getPackageName()) : null);
1882     }
1883 
1884     private Name parseAndGetName(JavaFileObject fo,
1885                                  Function<JCTree.JCCompilationUnit, Name> tree2Name) {
1886         DiagnosticHandler dh = log.new DiscardDiagnosticHandler();
1887         JavaFileObject prevSource = log.useSource(fo);
1888         try {
1889             JCTree.JCCompilationUnit t = parse(fo, fo.getCharContent(false), true);
1890             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.HashMap;
  37 import java.util.HashSet;
  38 import java.util.LinkedHashMap;
  39 import java.util.LinkedHashSet;
  40 import java.util.Map;
  41 import java.util.MissingResourceException;
  42 import java.util.Optional;
  43 import java.util.Queue;
  44 import java.util.ResourceBundle;
  45 import java.util.ServiceLoader;
  46 import java.util.Set;
  47 import java.util.function.Function;
  48 import java.util.function.ToIntFunction;
  49 
  50 import javax.annotation.processing.Processor;
  51 import javax.lang.model.SourceVersion;
  52 import javax.lang.model.element.ElementVisitor;
  53 import javax.tools.DiagnosticListener;
  54 import javax.tools.JavaFileManager;
  55 import javax.tools.JavaFileObject;
  56 import javax.tools.JavaFileObject.Kind;
  57 import javax.tools.StandardLocation;
  58 
  59 import com.sun.source.util.TaskEvent;
  60 import com.sun.tools.javac.api.MultiTaskListener;
  61 import com.sun.tools.javac.code.*;
  62 import com.sun.tools.javac.code.Lint.LintCategory;
  63 import com.sun.tools.javac.code.Source.Feature;
  64 import com.sun.tools.javac.code.Symbol.ClassSymbol;
  65 import com.sun.tools.javac.code.Symbol.CompletionFailure;

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


  92 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
  93 
  94 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  95 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  96 import com.sun.tools.javac.resources.CompilerProperties.Notes;
  97 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  98 
  99 import static com.sun.tools.javac.code.TypeTag.CLASS;
 100 import static com.sun.tools.javac.main.Option.*;
 101 import com.sun.tools.javac.tree.JCTree.JCBindingPattern;
 102 import com.sun.tools.javac.tree.JCTree.JCInstanceOf;
 103 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
 104 
 105 import static javax.tools.StandardLocation.CLASS_OUTPUT;
 106 import static javax.tools.StandardLocation.ANNOTATION_PROCESSOR_PATH;
 107 
 108 import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
 109 import com.sun.tools.javac.tree.JCTree.JCRecordPattern;
 110 import com.sun.tools.javac.tree.JCTree.JCSwitch;
 111 import com.sun.tools.javac.tree.JCTree.JCSwitchExpression;

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

1032         Set<JavaFileObject> filesSoFar = new HashSet<>();
1033         for (JavaFileObject fileObject : fileObjects) {
1034             if (!filesSoFar.contains(fileObject)) {
1035                 filesSoFar.add(fileObject);
1036                 trees.append(parse(fileObject));
1037             }
1038         }
1039         return trees.toList();
1040     }
1041 
1042    /**
1043     * Returns true iff the compilation will continue after annotation processing
1044     * is done.
1045     */
1046     public boolean continueAfterProcessAnnotations() {
1047         return !shouldStop(CompileState.ATTR);
1048     }
1049 
1050     public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
1051         modules.initModules(roots);
1052 
1053         if (modules.modulesInitialized()) {
1054             // This has to happen precisely here. At this point, we have all we need to
1055             // determine whether jdk.incubator.module is part of the module graph
1056             // but we have yet to trigger an ENTER event. This gives the code reflection plugin
1057             // a window to check whether code reflection should be enabled for this compilation unit.
1058             hasCodeReflectionModule = modules.getObservableModule(names.jdk_incubator_code) != null;
1059         }
1060 
1061         if (roots.isEmpty()) {
1062             enterDone();
1063         }
1064         return roots;
1065     }
1066 
1067     /**
1068      * Enter the symbols found in a list of parse trees.
1069      * As a side-effect, this puts elements on the "todo" list.
1070      * Also stores a list of all top level classes in rootClasses.
1071      */
1072     public List<JCCompilationUnit> enterTrees(List<JCCompilationUnit> roots) {
1073         //enter symbols for all files
1074         if (!taskListener.isEmpty()) {
1075             for (JCCompilationUnit unit: roots) {
1076                 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
1077                 taskListener.started(e);
1078             }
1079         }
1080 

1654 
1655             make.at(Position.FIRSTPOS);
1656             TreeMaker localMake = make.forToplevel(env.toplevel);
1657 
1658             if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF) || env.tree.hasTag(JCTree.Tag.MODULEDEF)) {
1659                 if (!(sourceOutput)) {
1660                     if (shouldStop(CompileState.LOWER))
1661                         return;
1662                     List<JCTree> def = lower.translateTopLevelClass(env, env.tree, localMake);
1663                     if (def.head != null) {
1664                         Assert.check(def.tail.isEmpty());
1665                         results.add(new Pair<>(env, (JCClassDecl)def.head));
1666                     }
1667                 }
1668                 return;
1669             }
1670 
1671             if (shouldStop(CompileState.TRANSTYPES))
1672                 return;
1673 
1674             if (Feature.REFLECT_METHODS.allowedInSource(source)) {
1675                 Optional<CodeReflectionTransformer> reflectMethods = reflectMethods();
1676                 if (reflectMethods.isPresent()) {
1677                     env.tree = reflectMethods.get().translateTopLevelClass(context, env.tree, localMake);
1678                 }
1679             }
1680 
1681             env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
1682             compileStates.put(env, CompileState.TRANSTYPES);
1683 
1684             if (shouldStop(CompileState.TRANSPATTERNS))
1685                 return;
1686 
1687             if (scanner.hasPatterns) {
1688                 env.tree = TransPatterns.instance(context)
1689                         .translateTopLevelClass(env, env.tree, localMake);
1690             }
1691 
1692             compileStates.put(env, CompileState.TRANSPATTERNS);
1693 
1694             if (shouldStop(CompileState.LOWER))
1695                 return;
1696 
1697             if (sourceOutput) {
1698                 //emit standard Java source file, only for compilation
1699                 //units enumerated explicitly on the command line
1700                 JCClassDecl cdef = (JCClassDecl)env.tree;
1701                 if (untranslated instanceof JCClassDecl classDecl &&
1702                     rootClasses.contains(classDecl)) {
1703                     results.add(new Pair<>(env, cdef));
1704                 }
1705                 return;
1706             }
1707 
1708             //translate out inner classes
1709             List<JCTree> cdefs = lower.translateTopLevelClass(env, env.tree, localMake);

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

1914                 log.warning(Warnings.ProcUseImplicit);
1915             else
1916                 log.warning(Warnings.ProcUseProcOrImplicit);
1917         }
1918         chk.reportDeferredDiagnostics();
1919         preview.reportDeferredDiagnostics();
1920         if (log.compressedOutput) {
1921             log.mandatoryNote(null, Notes.CompressedDiags);
1922         }
1923     }
1924 
1925     public void enterDone() {
1926         enterDone = true;
1927         annotate.enterDone();
1928     }
1929 
1930     public boolean isEnterDone() {
1931         return enterDone;
1932     }
1933 
1934     public boolean hasCodeReflectionModule() {
1935         return hasCodeReflectionModule;
1936     }
1937 
1938     private Name readModuleName(JavaFileObject fo) {
1939         return parseAndGetName(fo, t -> {
1940             JCModuleDecl md = t.getModuleDecl();
1941 
1942             return md != null ? TreeInfo.fullName(md.getName()) : null;
1943         });
1944     }
1945 
1946     private Name findPackageInFile(JavaFileObject fo) {
1947         return parseAndGetName(fo, t -> t.getPackage() != null ?
1948                                         TreeInfo.fullName(t.getPackage().getPackageName()) : null);
1949     }
1950 
1951     private Name parseAndGetName(JavaFileObject fo,
1952                                  Function<JCTree.JCCompilationUnit, Name> tree2Name) {
1953         DiagnosticHandler dh = log.new DiscardDiagnosticHandler();
1954         JavaFileObject prevSource = log.useSource(fo);
1955         try {
1956             JCTree.JCCompilationUnit t = parse(fo, fo.getCharContent(false), true);
1957             return tree2Name.apply(t);
< prev index next >