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);
750 tree = (tree == null) ? make.Ident(names.fromString(s))
751 : make.Select(tree, names.fromString(s));
752 }
753 JCCompilationUnit toplevel =
754 make.TopLevel(List.nil());
755 toplevel.modle = msym;
756 toplevel.packge = msym.unnamedPackage;
757 return attr.attribIdent(tree, toplevel);
758 } finally {
759 log.useSource(prev);
760 }
761 }
762
763 /** Generate code and emit a class file for a given class
764 * @param env The attribution environment of the outermost class
765 * containing this class.
766 * @param cdef The class definition from which code is generated.
767 */
768 JavaFileObject genCode(Env<AttrContext> env, JCClassDecl cdef) throws IOException {
769 try {
770 if (gen.genClass(env, cdef) && (errorCount() == 0))
771 return writer.writeClass(cdef.sym);
772 } catch (ClassWriter.PoolOverflow ex) {
773 log.error(cdef.pos(), Errors.LimitPool);
774 } catch (ClassWriter.StringOverflow ex) {
775 log.error(cdef.pos(),
776 Errors.LimitStringOverflow(ex.value.substring(0, 20)));
777 } catch (CompletionFailure ex) {
778 chk.completionError(cdef.pos(), ex);
779 }
780 return null;
781 }
782
783 /** Emit plain Java source for a class.
784 * @param env The attribution environment of the outermost class
785 * containing this class.
786 * @param cdef The class definition to be printed.
787 */
788 JavaFileObject printSource(Env<AttrContext> env, JCClassDecl cdef) throws IOException {
789 JavaFileObject outFile
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 if (roots.isEmpty()) {
1053 enterDone();
1054 }
1055 return roots;
1056 }
1057
1058 /**
1059 * Enter the symbols found in a list of parse trees.
1060 * As a side-effect, this puts elements on the "todo" list.
1061 * Also stores a list of all top level classes in rootClasses.
1062 */
1063 public List<JCCompilationUnit> enterTrees(List<JCCompilationUnit> roots) {
1064 //enter symbols for all files
1065 if (!taskListener.isEmpty()) {
1066 for (JCCompilationUnit unit: roots) {
1067 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
1068 taskListener.started(e);
1069 }
1070 }
1071
1644
1645 make.at(Position.FIRSTPOS);
1646 TreeMaker localMake = make.forToplevel(env.toplevel);
1647
1648 if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF) || env.tree.hasTag(JCTree.Tag.MODULEDEF)) {
1649 if (!(sourceOutput)) {
1650 if (shouldStop(CompileState.LOWER))
1651 return;
1652 List<JCTree> def = lower.translateTopLevelClass(env, env.tree, localMake);
1653 if (def.head != null) {
1654 Assert.check(def.tail.isEmpty());
1655 results.add(new Pair<>(env, (JCClassDecl)def.head));
1656 }
1657 }
1658 return;
1659 }
1660
1661 if (shouldStop(CompileState.TRANSTYPES))
1662 return;
1663
1664 env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
1665 compileStates.put(env, CompileState.TRANSTYPES);
1666
1667 if (shouldStop(CompileState.TRANSPATTERNS))
1668 return;
1669
1670 if (scanner.hasPatterns) {
1671 env.tree = TransPatterns.instance(context).translateTopLevelClass(env, env.tree, localMake);
1672 }
1673
1674 compileStates.put(env, CompileState.TRANSPATTERNS);
1675
1676 if (shouldStop(CompileState.LOWER))
1677 return;
1678
1679 if (sourceOutput) {
1680 //emit standard Java source file, only for compilation
1681 //units enumerated explicitly on the command line
1682 JCClassDecl cdef = (JCClassDecl)env.tree;
1683 if (untranslated instanceof JCClassDecl classDecl &&
1699 return;
1700
1701 for (JCTree def : cdefs) {
1702 LambdaToMethod.instance(context).translateTopLevelClass(env, def, localMake);
1703 }
1704 compileStates.put(env, CompileState.UNLAMBDA);
1705 }
1706
1707 //generate code for each class
1708 for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
1709 JCClassDecl cdef = (JCClassDecl)l.head;
1710 results.add(new Pair<>(env, cdef));
1711 }
1712 }
1713 finally {
1714 log.useSource(prev);
1715 }
1716
1717 }
1718
1719 /** Generates the source or class file for a list of classes.
1720 * The decision to generate a source file or a class file is
1721 * based upon the compiler's options.
1722 * Generation stops if an error occurs while writing files.
1723 */
1724 public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
1725 generate(queue, null);
1726 }
1727
1728 public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue, Queue<JavaFileObject> results) {
1729 if (shouldStop(CompileState.GENERATE))
1730 return;
1731
1732 for (Pair<Env<AttrContext>, JCClassDecl> x: queue) {
1733 Env<AttrContext> env = x.fst;
1734 JCClassDecl cdef = x.snd;
1735
1736 if (verboseCompilePolicy) {
1737 printNote("[generate " + (sourceOutput ? " source" : "code") + " " + cdef.sym + "]");
1738 }
1854 log.warning(Warnings.ProcUseImplicit);
1855 else
1856 log.warning(Warnings.ProcUseProcOrImplicit);
1857 }
1858 log.reportOutstandingWarnings();
1859 log.reportOutstandingNotes();
1860 if (log.compressedOutput) {
1861 log.note(Notes.CompressedDiags);
1862 }
1863 }
1864
1865 public void enterDone() {
1866 enterDone = true;
1867 annotate.enterDone();
1868 }
1869
1870 public boolean isEnterDone() {
1871 return enterDone;
1872 }
1873
1874 private Name readModuleName(JavaFileObject fo) {
1875 return parseAndGetName(fo, t -> {
1876 JCModuleDecl md = t.getModuleDecl();
1877
1878 return md != null ? TreeInfo.fullName(md.getName()) : null;
1879 });
1880 }
1881
1882 private Name findPackageInFile(JavaFileObject fo) {
1883 return parseAndGetName(fo, t -> t.getPackage() != null ?
1884 TreeInfo.fullName(t.getPackage().getPackageName()) : null);
1885 }
1886
1887 private Name parseAndGetName(JavaFileObject fo,
1888 Function<JCTree.JCCompilationUnit, Name> tree2Name) {
1889 DiagnosticHandler dh = log.new DiscardDiagnosticHandler();
1890 JavaFileObject prevSource = log.useSource(fo);
1891 try {
1892 JCTree.JCCompilationUnit t = parse(fo, fo.getCharContent(false), true);
1893 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);
758 tree = (tree == null) ? make.Ident(names.fromString(s))
759 : make.Select(tree, names.fromString(s));
760 }
761 JCCompilationUnit toplevel =
762 make.TopLevel(List.nil());
763 toplevel.modle = msym;
764 toplevel.packge = msym.unnamedPackage;
765 return attr.attribIdent(tree, toplevel);
766 } finally {
767 log.useSource(prev);
768 }
769 }
770
771 /** Generate code and emit a class file for a given class
772 * @param env The attribution environment of the outermost class
773 * containing this class.
774 * @param cdef The class definition from which code is generated.
775 */
776 JavaFileObject genCode(Env<AttrContext> env, JCClassDecl cdef) throws IOException {
777 try {
778 if (Feature.REFLECT_METHODS.allowedInSource(source)) {
779 Optional<CodeReflectionTransformer> reflectMethods = reflectMethods();
780 if (reflectMethods.isPresent()) {
781 reflectMethods.get().genCode(context, cdef);
782 }
783 }
784
785 if (gen.genClass(env, cdef) && (errorCount() == 0))
786 return writer.writeClass(cdef.sym);
787 } catch (ClassWriter.PoolOverflow ex) {
788 log.error(cdef.pos(), Errors.LimitPool);
789 } catch (ClassWriter.StringOverflow ex) {
790 log.error(cdef.pos(),
791 Errors.LimitStringOverflow(ex.value.substring(0, 20)));
792 } catch (CompletionFailure ex) {
793 chk.completionError(cdef.pos(), ex);
794 }
795 return null;
796 }
797
798 /** Emit plain Java source for a class.
799 * @param env The attribution environment of the outermost class
800 * containing this class.
801 * @param cdef The class definition to be printed.
802 */
803 JavaFileObject printSource(Env<AttrContext> env, JCClassDecl cdef) throws IOException {
804 JavaFileObject outFile
1047 Set<JavaFileObject> filesSoFar = new HashSet<>();
1048 for (JavaFileObject fileObject : fileObjects) {
1049 if (!filesSoFar.contains(fileObject)) {
1050 filesSoFar.add(fileObject);
1051 trees.append(parse(fileObject));
1052 }
1053 }
1054 return trees.toList();
1055 }
1056
1057 /**
1058 * Returns true iff the compilation will continue after annotation processing
1059 * is done.
1060 */
1061 public boolean continueAfterProcessAnnotations() {
1062 return !shouldStop(CompileState.ATTR);
1063 }
1064
1065 public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
1066 modules.initModules(roots);
1067
1068 if (modules.modulesInitialized()) {
1069 // This has to happen precisely here. At this point, we have all we need to
1070 // determine whether jdk.incubator.module is part of the module graph
1071 // but we have yet to trigger an ENTER event. This gives the code reflection plugin
1072 // a window to check whether code reflection should be enabled for this compilation unit.
1073 hasCodeReflectionModule = modules.getObservableModule(names.jdk_incubator_code) != null;
1074 }
1075
1076 if (roots.isEmpty()) {
1077 enterDone();
1078 }
1079 return roots;
1080 }
1081
1082 /**
1083 * Enter the symbols found in a list of parse trees.
1084 * As a side-effect, this puts elements on the "todo" list.
1085 * Also stores a list of all top level classes in rootClasses.
1086 */
1087 public List<JCCompilationUnit> enterTrees(List<JCCompilationUnit> roots) {
1088 //enter symbols for all files
1089 if (!taskListener.isEmpty()) {
1090 for (JCCompilationUnit unit: roots) {
1091 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
1092 taskListener.started(e);
1093 }
1094 }
1095
1668
1669 make.at(Position.FIRSTPOS);
1670 TreeMaker localMake = make.forToplevel(env.toplevel);
1671
1672 if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF) || env.tree.hasTag(JCTree.Tag.MODULEDEF)) {
1673 if (!(sourceOutput)) {
1674 if (shouldStop(CompileState.LOWER))
1675 return;
1676 List<JCTree> def = lower.translateTopLevelClass(env, env.tree, localMake);
1677 if (def.head != null) {
1678 Assert.check(def.tail.isEmpty());
1679 results.add(new Pair<>(env, (JCClassDecl)def.head));
1680 }
1681 }
1682 return;
1683 }
1684
1685 if (shouldStop(CompileState.TRANSTYPES))
1686 return;
1687
1688 if (Feature.REFLECT_METHODS.allowedInSource(source)) {
1689 Optional<CodeReflectionTransformer> reflectMethods = reflectMethods();
1690 if (reflectMethods.isPresent()) {
1691 env.tree = reflectMethods.get().translateTopLevelClass(context, env.tree, localMake);
1692 }
1693 }
1694
1695 env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
1696 compileStates.put(env, CompileState.TRANSTYPES);
1697
1698 if (shouldStop(CompileState.TRANSPATTERNS))
1699 return;
1700
1701 if (scanner.hasPatterns) {
1702 env.tree = TransPatterns.instance(context).translateTopLevelClass(env, env.tree, localMake);
1703 }
1704
1705 compileStates.put(env, CompileState.TRANSPATTERNS);
1706
1707 if (shouldStop(CompileState.LOWER))
1708 return;
1709
1710 if (sourceOutput) {
1711 //emit standard Java source file, only for compilation
1712 //units enumerated explicitly on the command line
1713 JCClassDecl cdef = (JCClassDecl)env.tree;
1714 if (untranslated instanceof JCClassDecl classDecl &&
1730 return;
1731
1732 for (JCTree def : cdefs) {
1733 LambdaToMethod.instance(context).translateTopLevelClass(env, def, localMake);
1734 }
1735 compileStates.put(env, CompileState.UNLAMBDA);
1736 }
1737
1738 //generate code for each class
1739 for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
1740 JCClassDecl cdef = (JCClassDecl)l.head;
1741 results.add(new Pair<>(env, cdef));
1742 }
1743 }
1744 finally {
1745 log.useSource(prev);
1746 }
1747
1748 }
1749
1750 Optional<CodeReflectionTransformer> reflectMethods() {
1751 return CodeReflectionSupport.CODE_LAYER != null ?
1752 ServiceLoader.load(CodeReflectionSupport.CODE_LAYER, CodeReflectionTransformer.class).findFirst() :
1753 Optional.empty();
1754 }
1755
1756 public static class CodeReflectionSupport {
1757 public static final ModuleLayer CODE_LAYER;
1758
1759 static {
1760 if (ModuleLayer.boot().findModule("jdk.incubator.code").isPresent()) {
1761 // we are in an exploded build, so just use the boot layer
1762 CODE_LAYER = ModuleLayer.boot();
1763 } else if (java.lang.module.ModuleFinder.ofSystem().find("jdk.incubator.code").isPresent()) {
1764 // the code module is installed, but not in the boot layer, create a new layer which contains it
1765 ModuleLayer parent = ModuleLayer.boot();
1766 Configuration cf = parent.configuration()
1767 .resolve(java.lang.module.ModuleFinder.of(), java.lang.module.ModuleFinder.ofSystem(), Set.of("jdk.incubator.code"));
1768 ClassLoader scl = ClassLoader.getSystemClassLoader();
1769 CODE_LAYER = parent.defineModulesWithOneLoader(cf, scl);
1770 Module codeReflectionModule = CODE_LAYER.findModule("jdk.incubator.code").get();
1771 Module jdkCompilerModule = JavaCompiler.class.getModule();
1772 // We need to add exports all jdk.compiler packages so that the plugin can use them
1773 for (String packageName : jdkCompilerModule.getPackages()) {
1774 jdkCompilerModule.addExports(packageName, codeReflectionModule);
1775 }
1776 // We also need to add exports all java.base packages so that the plugin can use them
1777 // But we need to do so by calling a method in java.base reflectively
1778 try {
1779 Class<?> codeModuleLayerInit = Class.forName("jdk.internal.access.code.CodeModuleLayerInit");
1780 Method initLayerMethod = codeModuleLayerInit.getDeclaredMethod("initCodeModuleLayer", ModuleLayer.class);
1781 initLayerMethod.invoke(null, CODE_LAYER);
1782 } catch (ReflectiveOperationException ex) {
1783 throw new AssertionError(ex);
1784 }
1785 } else {
1786 // if we run in bootstrap mode, there might be no jdk.incubator.code
1787 CODE_LAYER = null;
1788 }
1789 }
1790 }
1791
1792 /** Generates the source or class file for a list of classes.
1793 * The decision to generate a source file or a class file is
1794 * based upon the compiler's options.
1795 * Generation stops if an error occurs while writing files.
1796 */
1797 public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
1798 generate(queue, null);
1799 }
1800
1801 public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue, Queue<JavaFileObject> results) {
1802 if (shouldStop(CompileState.GENERATE))
1803 return;
1804
1805 for (Pair<Env<AttrContext>, JCClassDecl> x: queue) {
1806 Env<AttrContext> env = x.fst;
1807 JCClassDecl cdef = x.snd;
1808
1809 if (verboseCompilePolicy) {
1810 printNote("[generate " + (sourceOutput ? " source" : "code") + " " + cdef.sym + "]");
1811 }
1927 log.warning(Warnings.ProcUseImplicit);
1928 else
1929 log.warning(Warnings.ProcUseProcOrImplicit);
1930 }
1931 log.reportOutstandingWarnings();
1932 log.reportOutstandingNotes();
1933 if (log.compressedOutput) {
1934 log.note(Notes.CompressedDiags);
1935 }
1936 }
1937
1938 public void enterDone() {
1939 enterDone = true;
1940 annotate.enterDone();
1941 }
1942
1943 public boolean isEnterDone() {
1944 return enterDone;
1945 }
1946
1947 public boolean hasCodeReflectionModule() {
1948 return hasCodeReflectionModule;
1949 }
1950
1951 private Name readModuleName(JavaFileObject fo) {
1952 return parseAndGetName(fo, t -> {
1953 JCModuleDecl md = t.getModuleDecl();
1954
1955 return md != null ? TreeInfo.fullName(md.getName()) : null;
1956 });
1957 }
1958
1959 private Name findPackageInFile(JavaFileObject fo) {
1960 return parseAndGetName(fo, t -> t.getPackage() != null ?
1961 TreeInfo.fullName(t.getPackage().getPackageName()) : null);
1962 }
1963
1964 private Name parseAndGetName(JavaFileObject fo,
1965 Function<JCTree.JCCompilationUnit, Name> tree2Name) {
1966 DiagnosticHandler dh = log.new DiscardDiagnosticHandler();
1967 JavaFileObject prevSource = log.useSource(fo);
1968 try {
1969 JCTree.JCCompilationUnit t = parse(fo, fo.getCharContent(false), true);
1970 return tree2Name.apply(t);
|