37 import java.util.ResourceBundle; |
37 import java.util.ResourceBundle; |
38 import java.util.Set; |
38 import java.util.Set; |
39 |
39 |
40 import javax.annotation.processing.Processor; |
40 import javax.annotation.processing.Processor; |
41 import javax.lang.model.SourceVersion; |
41 import javax.lang.model.SourceVersion; |
|
42 import javax.lang.model.element.ElementVisitor; |
42 import javax.tools.DiagnosticListener; |
43 import javax.tools.DiagnosticListener; |
43 import javax.tools.JavaFileManager; |
44 import javax.tools.JavaFileManager; |
44 import javax.tools.JavaFileObject; |
45 import javax.tools.JavaFileObject; |
45 import javax.tools.StandardLocation; |
46 import javax.tools.StandardLocation; |
46 |
47 |
65 import com.sun.tools.javac.tree.JCTree.JCLambda; |
66 import com.sun.tools.javac.tree.JCTree.JCLambda; |
66 import com.sun.tools.javac.tree.JCTree.JCMemberReference; |
67 import com.sun.tools.javac.tree.JCTree.JCMemberReference; |
67 import com.sun.tools.javac.tree.JCTree.JCMethodDecl; |
68 import com.sun.tools.javac.tree.JCTree.JCMethodDecl; |
68 import com.sun.tools.javac.tree.JCTree.JCVariableDecl; |
69 import com.sun.tools.javac.tree.JCTree.JCVariableDecl; |
69 import com.sun.tools.javac.util.*; |
70 import com.sun.tools.javac.util.*; |
|
71 import com.sun.tools.javac.util.DefinedBy.Api; |
|
72 import com.sun.tools.javac.util.JCDiagnostic.Factory; |
70 import com.sun.tools.javac.util.Log.WriterKind; |
73 import com.sun.tools.javac.util.Log.WriterKind; |
71 |
74 |
72 import static com.sun.tools.javac.code.Kinds.Kind.*; |
75 import static com.sun.tools.javac.code.Kinds.Kind.*; |
|
76 |
|
77 import com.sun.tools.javac.code.Symbol.ModuleSymbol; |
|
78 import com.sun.tools.javac.resources.CompilerProperties.Errors; |
|
79 import com.sun.tools.javac.resources.CompilerProperties.Warnings; |
|
80 |
73 import static com.sun.tools.javac.code.TypeTag.CLASS; |
81 import static com.sun.tools.javac.code.TypeTag.CLASS; |
74 import static com.sun.tools.javac.main.Option.*; |
82 import static com.sun.tools.javac.main.Option.*; |
75 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; |
83 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; |
|
84 |
76 import static javax.tools.StandardLocation.CLASS_OUTPUT; |
85 import static javax.tools.StandardLocation.CLASS_OUTPUT; |
77 |
86 |
78 /** This class could be the main entry point for GJC when GJC is used as a |
87 /** This class could be the main entry point for GJC when GJC is used as a |
79 * component in a larger software system. It provides operations to |
88 * component in a larger software system. It provides operations to |
80 * construct a new compiler, and to run a new compiler on a set of source |
89 * construct a new compiler, and to run a new compiler on a set of source |
274 |
283 |
275 /** The flow analyzer. |
284 /** The flow analyzer. |
276 */ |
285 */ |
277 protected Flow flow; |
286 protected Flow flow; |
278 |
287 |
|
288 /** The modules visitor |
|
289 */ |
|
290 protected Modules modules; |
|
291 |
|
292 /** The module finder |
|
293 */ |
|
294 protected ModuleFinder moduleFinder; |
|
295 |
|
296 /** The diagnostics factory |
|
297 */ |
|
298 protected JCDiagnostic.Factory diags; |
|
299 |
279 /** The type eraser. |
300 /** The type eraser. |
280 */ |
301 */ |
281 protected TransTypes transTypes; |
302 protected TransTypes transTypes; |
282 |
303 |
283 /** The syntactic sugar desweetener. |
304 /** The syntactic sugar desweetener. |
380 transTypes = TransTypes.instance(context); |
403 transTypes = TransTypes.instance(context); |
381 lower = Lower.instance(context); |
404 lower = Lower.instance(context); |
382 annotate = Annotate.instance(context); |
405 annotate = Annotate.instance(context); |
383 types = Types.instance(context); |
406 types = Types.instance(context); |
384 taskListener = MultiTaskListener.instance(context); |
407 taskListener = MultiTaskListener.instance(context); |
|
408 modules = Modules.instance(context); |
|
409 moduleFinder = ModuleFinder.instance(context); |
|
410 diags = Factory.instance(context); |
385 |
411 |
386 finder.sourceCompleter = sourceCompleter; |
412 finder.sourceCompleter = sourceCompleter; |
387 |
413 |
388 options = Options.instance(context); |
414 options = Options.instance(context); |
389 |
415 |
428 |
454 |
429 PlatformDescription platformProvider = context.get(PlatformDescription.class); |
455 PlatformDescription platformProvider = context.get(PlatformDescription.class); |
430 |
456 |
431 if (platformProvider != null) |
457 if (platformProvider != null) |
432 closeables = closeables.prepend(platformProvider); |
458 closeables = closeables.prepend(platformProvider); |
|
459 |
|
460 silentFail = new Symbol(ABSENT_TYP, 0, names.empty, Type.noType, syms.rootPackage) { |
|
461 @DefinedBy(Api.LANGUAGE_MODEL) |
|
462 public <R, P> R accept(ElementVisitor<R, P> v, P p) { |
|
463 return v.visitUnknown(this, p); |
|
464 } |
|
465 @Override |
|
466 public boolean exists() { |
|
467 return false; |
|
468 } |
|
469 }; |
|
470 |
433 } |
471 } |
434 |
472 |
435 /* Switches: |
473 /* Switches: |
436 */ |
474 */ |
437 |
475 |
509 /** The set of currently compiled inputfiles, needed to ensure |
547 /** The set of currently compiled inputfiles, needed to ensure |
510 * we don't accidentally overwrite an input file when -s is set. |
548 * we don't accidentally overwrite an input file when -s is set. |
511 * initialized by `compile'. |
549 * initialized by `compile'. |
512 */ |
550 */ |
513 protected Set<JavaFileObject> inputFiles = new HashSet<>(); |
551 protected Set<JavaFileObject> inputFiles = new HashSet<>(); |
|
552 |
|
553 /** Used by the resolveBinaryNameOrIdent to say that the given type cannot be found, and that |
|
554 * an error has already been produced about that. |
|
555 */ |
|
556 private final Symbol silentFail; |
514 |
557 |
515 protected boolean shouldStop(CompileState cs) { |
558 protected boolean shouldStop(CompileState cs) { |
516 CompileState shouldStopPolicy = (errorCount() > 0 || unrecoverableError()) |
559 CompileState shouldStopPolicy = (errorCount() > 0 || unrecoverableError()) |
517 ? shouldStopPolicyIfError |
560 ? shouldStopPolicyIfError |
518 : shouldStopPolicyIfNoError; |
561 : shouldStopPolicyIfNoError; |
623 /** Resolve an identifier which may be the binary name of a class or |
666 /** Resolve an identifier which may be the binary name of a class or |
624 * the Java name of a class or package. |
667 * the Java name of a class or package. |
625 * @param name The name to resolve |
668 * @param name The name to resolve |
626 */ |
669 */ |
627 public Symbol resolveBinaryNameOrIdent(String name) { |
670 public Symbol resolveBinaryNameOrIdent(String name) { |
|
671 ModuleSymbol msym; |
|
672 String typeName; |
|
673 int sep = name.indexOf('/'); |
|
674 if (sep == -1) { |
|
675 msym = modules.getDefaultModule(); |
|
676 typeName = name; |
|
677 } else if (source.allowModules() && !options.isSet("noModules")) { |
|
678 Name modName = names.fromString(name.substring(0, sep)); |
|
679 |
|
680 msym = moduleFinder.findModule(modName); |
|
681 typeName = name.substring(sep + 1); |
|
682 } else { |
|
683 log.error(Errors.InvalidModuleSpecifier(name)); |
|
684 return silentFail; |
|
685 } |
|
686 |
|
687 return resolveBinaryNameOrIdent(msym, typeName); |
|
688 } |
|
689 |
|
690 /** Resolve an identifier which may be the binary name of a class or |
|
691 * the Java name of a class or package. |
|
692 * @param msym The module in which the search should be performed |
|
693 * @param name The name to resolve |
|
694 */ |
|
695 public Symbol resolveBinaryNameOrIdent(ModuleSymbol msym, String name) { |
628 try { |
696 try { |
629 Name flatname = names.fromString(name.replace("/", ".")); |
697 Name flatname = names.fromString(name.replace("/", ".")); |
630 return finder.loadClass(flatname); |
698 return finder.loadClass(msym, flatname); |
631 } catch (CompletionFailure ignore) { |
699 } catch (CompletionFailure ignore) { |
632 return resolveIdent(name); |
700 return resolveIdent(msym, name); |
633 } |
701 } |
634 } |
702 } |
635 |
703 |
636 /** Resolve an identifier. |
704 /** Resolve an identifier. |
|
705 * @param msym The module in which the search should be performed |
637 * @param name The identifier to resolve |
706 * @param name The identifier to resolve |
638 */ |
707 */ |
639 public Symbol resolveIdent(String name) { |
708 public Symbol resolveIdent(ModuleSymbol msym, String name) { |
640 if (name.equals("")) |
709 if (name.equals("")) |
641 return syms.errSymbol; |
710 return syms.errSymbol; |
642 JavaFileObject prev = log.useSource(null); |
711 JavaFileObject prev = log.useSource(null); |
643 try { |
712 try { |
644 JCExpression tree = null; |
713 JCExpression tree = null; |
648 tree = (tree == null) ? make.Ident(names.fromString(s)) |
717 tree = (tree == null) ? make.Ident(names.fromString(s)) |
649 : make.Select(tree, names.fromString(s)); |
718 : make.Select(tree, names.fromString(s)); |
650 } |
719 } |
651 JCCompilationUnit toplevel = |
720 JCCompilationUnit toplevel = |
652 make.TopLevel(List.<JCTree>nil()); |
721 make.TopLevel(List.<JCTree>nil()); |
653 toplevel.packge = syms.unnamedPackage; |
722 toplevel.modle = msym; |
|
723 toplevel.packge = msym.unnamedPackage; |
654 return attr.attribIdent(tree, toplevel); |
724 return attr.attribIdent(tree, toplevel); |
655 } finally { |
725 } finally { |
656 log.useSource(prev); |
726 log.useSource(prev); |
657 } |
727 } |
658 } |
728 } |
735 if (!taskListener.isEmpty()) { |
805 if (!taskListener.isEmpty()) { |
736 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree); |
806 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree); |
737 taskListener.started(e); |
807 taskListener.started(e); |
738 } |
808 } |
739 |
809 |
|
810 // Process module declarations. |
|
811 // If module resolution fails, ignore trees, and if trying to |
|
812 // complete a specific symbol, throw CompletionFailure. |
|
813 // Note that if module resolution failed, we may not even |
|
814 // have enough modules available to access java.lang, and |
|
815 // so risk getting FatalError("no.java.lang") from MemberEnter. |
|
816 if (!modules.enter(List.of(tree), c)) { |
|
817 throw new CompletionFailure(c, diags.fragment("cant.resolve.modules")); |
|
818 } |
|
819 |
740 enter.complete(List.of(tree), c); |
820 enter.complete(List.of(tree), c); |
741 |
821 |
742 if (!taskListener.isEmpty()) { |
822 if (!taskListener.isEmpty()) { |
743 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree); |
823 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree); |
744 taskListener.finished(e); |
824 taskListener.finished(e); |
746 |
826 |
747 if (enter.getEnv(c) == null) { |
827 if (enter.getEnv(c) == null) { |
748 boolean isPkgInfo = |
828 boolean isPkgInfo = |
749 tree.sourcefile.isNameCompatible("package-info", |
829 tree.sourcefile.isNameCompatible("package-info", |
750 JavaFileObject.Kind.SOURCE); |
830 JavaFileObject.Kind.SOURCE); |
751 if (isPkgInfo) { |
831 boolean isModuleInfo = |
|
832 tree.sourcefile.isNameCompatible("module-info", |
|
833 JavaFileObject.Kind.SOURCE); |
|
834 if (isModuleInfo) { |
|
835 if (enter.getEnv(tree.modle) == null) { |
|
836 JCDiagnostic diag = |
|
837 diagFactory.fragment("file.does.not.contain.module"); |
|
838 throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory); |
|
839 } |
|
840 } else if (isPkgInfo) { |
752 if (enter.getEnv(tree.packge) == null) { |
841 if (enter.getEnv(tree.packge) == null) { |
753 JCDiagnostic diag = |
842 JCDiagnostic diag = |
754 diagFactory.fragment("file.does.not.contain.package", |
843 diagFactory.fragment("file.does.not.contain.package", |
755 c.location()); |
844 c.location()); |
756 throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory); |
845 throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory); |
810 try { |
899 try { |
811 initProcessAnnotations(processors); |
900 initProcessAnnotations(processors); |
812 |
901 |
813 // These method calls must be chained to avoid memory leaks |
902 // These method calls must be chained to avoid memory leaks |
814 processAnnotations( |
903 processAnnotations( |
815 enterTrees(stopIfError(CompileState.PARSE, parseFiles(sourceFileObjects))), |
904 enterTrees( |
816 classnames); |
905 stopIfError(CompileState.PARSE, |
|
906 initModules(stopIfError(CompileState.PARSE, parseFiles(sourceFileObjects)))) |
|
907 ), |
|
908 classnames |
|
909 ); |
817 |
910 |
818 // If it's safe to do so, skip attr / flow / gen for implicit classes |
911 // If it's safe to do so, skip attr / flow / gen for implicit classes |
819 if (taskListener.isEmpty() && |
912 if (taskListener.isEmpty() && |
820 implicitSourcePolicy == ImplicitSourcePolicy.NONE) { |
913 implicitSourcePolicy == ImplicitSourcePolicy.NONE) { |
821 todo.retainFiles(inputFiles); |
914 todo.retainFiles(inputFiles); |
910 * Also stores a list of all top level classes in rootClasses. |
1003 * Also stores a list of all top level classes in rootClasses. |
911 */ |
1004 */ |
912 public List<JCCompilationUnit> enterTreesIfNeeded(List<JCCompilationUnit> roots) { |
1005 public List<JCCompilationUnit> enterTreesIfNeeded(List<JCCompilationUnit> roots) { |
913 if (shouldStop(CompileState.ATTR)) |
1006 if (shouldStop(CompileState.ATTR)) |
914 return List.nil(); |
1007 return List.nil(); |
915 return enterTrees(roots); |
1008 return enterTrees(initModules(roots)); |
|
1009 } |
|
1010 |
|
1011 public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) { |
|
1012 List<JCCompilationUnit> result = initModules(roots, null); |
|
1013 if (roots.isEmpty()) { |
|
1014 enterDone = true; |
|
1015 } |
|
1016 return result; |
|
1017 } |
|
1018 |
|
1019 List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots, ClassSymbol c) { |
|
1020 modules.enter(roots, c); |
|
1021 return roots; |
916 } |
1022 } |
917 |
1023 |
918 /** |
1024 /** |
919 * Enter the symbols found in a list of parse trees. |
1025 * Enter the symbols found in a list of parse trees. |
920 * As a side-effect, this puts elements on the "todo" list. |
1026 * As a side-effect, this puts elements on the "todo" list. |
928 taskListener.started(e); |
1034 taskListener.started(e); |
929 } |
1035 } |
930 } |
1036 } |
931 |
1037 |
932 enter.main(roots); |
1038 enter.main(roots); |
|
1039 |
|
1040 enterDone = true; |
933 |
1041 |
934 if (!taskListener.isEmpty()) { |
1042 if (!taskListener.isEmpty()) { |
935 for (JCCompilationUnit unit: roots) { |
1043 for (JCCompilationUnit unit: roots) { |
936 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit); |
1044 TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit); |
937 taskListener.finished(e); |
1045 taskListener.finished(e); |
1083 for (String nameStr : classnames) { |
1191 for (String nameStr : classnames) { |
1084 Symbol sym = resolveBinaryNameOrIdent(nameStr); |
1192 Symbol sym = resolveBinaryNameOrIdent(nameStr); |
1085 if (sym == null || |
1193 if (sym == null || |
1086 (sym.kind == PCK && !processPcks) || |
1194 (sym.kind == PCK && !processPcks) || |
1087 sym.kind == ABSENT_TYP) { |
1195 sym.kind == ABSENT_TYP) { |
1088 log.error("proc.cant.find.class", nameStr); |
1196 if (sym != silentFail) |
|
1197 log.error(Errors.ProcCantFindClass(nameStr)); |
1089 errors = true; |
1198 errors = true; |
1090 continue; |
1199 continue; |
1091 } |
1200 } |
1092 try { |
1201 try { |
1093 if (sym.kind == PCK) |
1202 if (sym.kind == PCK) |
1098 else |
1207 else |
1099 classSymbols = classSymbols.prepend((ClassSymbol)sym); |
1208 classSymbols = classSymbols.prepend((ClassSymbol)sym); |
1100 continue; |
1209 continue; |
1101 } |
1210 } |
1102 Assert.check(sym.kind == PCK); |
1211 Assert.check(sym.kind == PCK); |
1103 log.warning("proc.package.does.not.exist", nameStr); |
1212 log.warning(Warnings.ProcPackageDoesNotExist(nameStr)); |
1104 pckSymbols = pckSymbols.prepend((PackageSymbol)sym); |
1213 pckSymbols = pckSymbols.prepend((PackageSymbol)sym); |
1105 } catch (CompletionFailure e) { |
1214 } catch (CompletionFailure e) { |
1106 log.error("proc.cant.find.class", nameStr); |
1215 log.error(Errors.ProcCantFindClass(nameStr)); |
1107 errors = true; |
1216 errors = true; |
1108 continue; |
1217 continue; |
1109 } |
1218 } |
1110 } |
1219 } |
1111 if (errors) { |
1220 if (errors) { |
1152 |
1261 |
1153 static boolean explicitAnnotationProcessingRequested(Options options) { |
1262 static boolean explicitAnnotationProcessingRequested(Options options) { |
1154 return |
1263 return |
1155 options.isSet(PROCESSOR) || |
1264 options.isSet(PROCESSOR) || |
1156 options.isSet(PROCESSORPATH) || |
1265 options.isSet(PROCESSORPATH) || |
|
1266 options.isSet(PROCESSORMODULEPATH) || |
1157 options.isSet(PROC, "only") || |
1267 options.isSet(PROC, "only") || |
1158 options.isSet(XPRINT); |
1268 options.isSet(XPRINT); |
1159 } |
1269 } |
1160 |
1270 |
1161 public void setDeferredDiagnosticHandler(Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { |
1271 public void setDeferredDiagnosticHandler(Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { |
1386 JCTree untranslated = env.tree; |
1496 JCTree untranslated = env.tree; |
1387 |
1497 |
1388 make.at(Position.FIRSTPOS); |
1498 make.at(Position.FIRSTPOS); |
1389 TreeMaker localMake = make.forToplevel(env.toplevel); |
1499 TreeMaker localMake = make.forToplevel(env.toplevel); |
1390 |
1500 |
1391 if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF)) { |
1501 if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF) || env.tree.hasTag(JCTree.Tag.MODULEDEF)) { |
1392 if (!(sourceOutput)) { |
1502 if (!(sourceOutput)) { |
1393 if (shouldStop(CompileState.LOWER)) |
1503 if (shouldStop(CompileState.LOWER)) |
1394 return; |
1504 return; |
1395 List<JCTree> pdef = lower.translateTopLevelClass(env, env.tree, localMake); |
1505 List<JCTree> def = lower.translateTopLevelClass(env, env.tree, localMake); |
1396 if (pdef.head != null) { |
1506 if (def.head != null) { |
1397 Assert.check(pdef.tail.isEmpty()); |
1507 Assert.check(def.tail.isEmpty()); |
1398 results.add(new Pair<>(env, (JCClassDecl)pdef.head)); |
1508 results.add(new Pair<>(env, (JCClassDecl)def.head)); |
1399 } |
1509 } |
1400 } |
1510 } |
1401 return; |
1511 return; |
1402 } |
1512 } |
1403 |
1513 |
1587 if (log.compressedOutput) { |
1697 if (log.compressedOutput) { |
1588 log.mandatoryNote(null, "compressed.diags"); |
1698 log.mandatoryNote(null, "compressed.diags"); |
1589 } |
1699 } |
1590 } |
1700 } |
1591 |
1701 |
|
1702 public boolean isEnterDone() { |
|
1703 return enterDone; |
|
1704 } |
|
1705 |
1592 /** Close the compiler, flushing the logs |
1706 /** Close the compiler, flushing the logs |
1593 */ |
1707 */ |
1594 public void close() { |
1708 public void close() { |
1595 rootClasses = null; |
1709 rootClasses = null; |
1596 finder = null; |
1710 finder = null; |