< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java

Print this page




 141     private final Source source;
 142     private final boolean allowModules;
 143 
 144     public final boolean multiModuleMode;
 145 
 146     private final String moduleOverride;
 147 
 148     private final Name java_se;
 149     private final Name java_;
 150 
 151     ModuleSymbol defaultModule;
 152 
 153     private final String addExportsOpt;
 154     private Map<ModuleSymbol, Set<ExportsDirective>> addExports;
 155     private final String addReadsOpt;
 156     private Map<ModuleSymbol, Set<RequiresDirective>> addReads;
 157     private final String addModsOpt;
 158     private final Set<String> extraAddMods = new HashSet<>();
 159     private final String limitModsOpt;
 160     private final Set<String> extraLimitMods = new HashSet<>();

 161 
 162     private final boolean lintOptions;
 163 
 164     private Set<ModuleSymbol> rootModules = null;
 165 
 166     public static Modules instance(Context context) {
 167         Modules instance = context.get(Modules.class);
 168         if (instance == null)
 169             instance = new Modules(context);
 170         return instance;
 171     }
 172 
 173     protected Modules(Context context) {
 174         context.put(Modules.class, this);
 175         log = Log.instance(context);
 176         names = Names.instance(context);
 177         syms = Symtab.instance(context);
 178         attr = Attr.instance(context);
 179         chk = Check.instance(context);
 180         deferredLintHandler = DeferredLintHandler.instance(context);


 186         allowModules = source.allowModules();
 187         Options options = Options.instance(context);
 188 
 189         lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
 190 
 191         moduleOverride = options.get(Option.XMODULE);
 192 
 193         multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH);
 194         ClassWriter classWriter = ClassWriter.instance(context);
 195         classWriter.multiModuleMode = multiModuleMode;
 196         JNIWriter jniWriter = JNIWriter.instance(context);
 197         jniWriter.multiModuleMode = multiModuleMode;
 198 
 199         java_se = names.fromString("java.se");
 200         java_ = names.fromString("java.");
 201 
 202         addExportsOpt = options.get(Option.ADD_EXPORTS);
 203         addReadsOpt = options.get(Option.ADD_READS);
 204         addModsOpt = options.get(Option.ADD_MODULES);
 205         limitModsOpt = options.get(Option.LIMIT_MODULES);

 206     }
 207 
 208     int depth = -1;
 209     private void dprintln(String msg) {
 210         for (int i = 0; i < depth; i++)
 211             System.err.print("  ");
 212         System.err.println(msg);
 213     }
 214 
 215     public void addExtraAddModules(String... extras) {
 216         extraAddMods.addAll(Arrays.asList(extras));
 217     }
 218 
 219     public void addExtraLimitModules(String... extras) {
 220         extraLimitMods.addAll(Arrays.asList(extras));
 221     }
 222 
 223     boolean inInitModules;
 224     public void initModules(List<JCCompilationUnit> trees) {
 225         Assert.check(!inInitModules);


 578             directives.add(d);
 579             requires.add(d);
 580         }
 581 
 582         RequiresDirective requiresUnnamed = new RequiresDirective(syms.unnamedModule);
 583         directives.add(requiresUnnamed);
 584         requires.add(requiresUnnamed);
 585 
 586         msym.requires = requires.toList();
 587         msym.directives = directives.toList();
 588     }
 589 
 590     private Completer getSourceCompleter(JCCompilationUnit tree) {
 591         return new Completer() {
 592             @Override
 593             public void complete(Symbol sym) throws CompletionFailure {
 594                 ModuleSymbol msym = (ModuleSymbol) sym;
 595                 msym.flags_field |= UNATTRIBUTED;
 596                 ModuleVisitor v = new ModuleVisitor();
 597                 JavaFileObject prev = log.useSource(tree.sourcefile);
 598                 try {
 599                     JCModuleDecl moduleDecl = tree.getModuleDecl();



 600                     moduleDecl.accept(v);
 601                     completeModule(msym);
 602                     checkCyclicDependencies(moduleDecl);
 603                 } finally {
 604                     log.useSource(prev);

 605                     msym.flags_field &= ~UNATTRIBUTED;
 606                 }
 607             }
 608 
 609             @Override
 610             public String toString() {
 611                 return "SourceCompleter: " + tree.sourcefile.getName();
 612             }
 613 
 614         };
 615     }
 616 
 617     class ModuleVisitor extends JCTree.Visitor {
 618         private ModuleSymbol sym;
 619         private final Set<ModuleSymbol> allRequires = new HashSet<>();
 620         private final Map<PackageSymbol,List<ExportsDirective>> allExports = new HashMap<>();
 621         private final Map<PackageSymbol,List<OpensDirective>> allOpens = new HashMap<>();
 622 
 623         @Override
 624         public void visitModuleDef(JCModuleDecl tree) {


 661 
 662         @Override
 663         public void visitExports(JCExports tree) {
 664             Name name = TreeInfo.fullName(tree.qualid);
 665             PackageSymbol packge = syms.enterPackage(sym, name);
 666             attr.setPackageSymbols(tree.qualid, packge);
 667 
 668             if (tree.hasTag(Tag.OPENS) && sym.flags.contains(ModuleFlags.OPEN)) {
 669                 log.error(tree.pos(), Errors.NoOpensUnlessStrong);
 670             }
 671             List<ExportsDirective> exportsForPackage = allExports.computeIfAbsent(packge, p -> List.nil());
 672             for (ExportsDirective d : exportsForPackage) {
 673                 reportExportsConflict(tree, packge);
 674             }
 675 
 676             List<ModuleSymbol> toModules = null;
 677             if (tree.moduleNames != null) {
 678                 Set<ModuleSymbol> to = new LinkedHashSet<>();
 679                 for (JCExpression n: tree.moduleNames) {
 680                     ModuleSymbol msym = lookupModule(n);
 681                     if (msym.kind != MDL) {
 682                         log.error(n.pos(), Errors.ModuleNotFound(msym));
 683                     } else {
 684                         for (ExportsDirective d : exportsForPackage) {
 685                             checkDuplicateExportsToModule(n, msym, d);
 686                         }
 687                         if (!to.add(msym)) {
 688                             reportExportsConflictToModule(n, msym);
 689                         }
 690                     }
 691                 }
 692                 toModules = List.from(to);
 693             }
 694 
 695             if (toModules == null || !toModules.isEmpty()) {
 696                 Set<ExportsFlag> flags = EnumSet.noneOf(ExportsFlag.class);
 697                 ExportsDirective d = new ExportsDirective(packge, toModules, flags);
 698                 sym.exports = sym.exports.prepend(d);
 699                 tree.directive = d;
 700 
 701                 allExports.put(packge, exportsForPackage.prepend(d));
 702             }
 703         }
 704 
 705         private void reportExportsConflict(JCExports tree, PackageSymbol packge) {
 706             log.error(tree.qualid.pos(), Errors.ConflictingExports(packge));
 707         }
 708 
 709         private void checkDuplicateExportsToModule(JCExpression name, ModuleSymbol msym,
 710                 ExportsDirective d) {
 711             if (d.modules != null) {


 723 
 724         @Override
 725         public void visitOpens(JCOpens tree) {
 726             Name name = TreeInfo.fullName(tree.qualid);
 727             PackageSymbol packge = syms.enterPackage(sym, name);
 728             attr.setPackageSymbols(tree.qualid, packge);
 729 
 730             if (sym.flags.contains(ModuleFlags.OPEN)) {
 731                 log.error(tree.pos(), Errors.NoOpensUnlessStrong);
 732             }
 733             List<OpensDirective> opensForPackage = allOpens.computeIfAbsent(packge, p -> List.nil());
 734             for (OpensDirective d : opensForPackage) {
 735                 reportOpensConflict(tree, packge);
 736             }
 737 
 738             List<ModuleSymbol> toModules = null;
 739             if (tree.moduleNames != null) {
 740                 Set<ModuleSymbol> to = new LinkedHashSet<>();
 741                 for (JCExpression n: tree.moduleNames) {
 742                     ModuleSymbol msym = lookupModule(n);
 743                     if (msym.kind != MDL) {
 744                         log.error(n.pos(), Errors.ModuleNotFound(msym));
 745                     } else {
 746                         for (OpensDirective d : opensForPackage) {
 747                             checkDuplicateOpensToModule(n, msym, d);
 748                         }
 749                         if (!to.add(msym)) {
 750                             reportOpensConflictToModule(n, msym);
 751                         }
 752                     }
 753                 }
 754                 toModules = List.from(to);
 755             }
 756 
 757             if (toModules == null || !toModules.isEmpty()) {
 758                 Set<OpensFlag> flags = EnumSet.noneOf(OpensFlag.class);
 759                 OpensDirective d = new OpensDirective(packge, toModules, flags);
 760                 sym.opens = sym.opens.prepend(d);
 761                 tree.directive = d;
 762 
 763                 allOpens.put(packge, opensForPackage.prepend(d));
 764             }
 765         }
 766 
 767         private void reportOpensConflict(JCOpens tree, PackageSymbol packge) {
 768             log.error(tree.qualid.pos(), Errors.ConflictingOpens(packge));
 769         }
 770 
 771         private void checkDuplicateOpensToModule(JCExpression name, ModuleSymbol msym,
 772                 OpensDirective d) {
 773             if (d.modules != null) {


1116                         break;
1117                     default:
1118                         if (!isValidName(added))
1119                             continue;
1120                         modules = Stream.of(syms.enterModule(names.fromString(added)));
1121                         break;
1122                 }
1123                 modules.forEach(sym -> {
1124                     enabledRoot.add(sym);
1125                     if (observable != null)
1126                         observable.add(sym);
1127                 });
1128             }
1129         }
1130 
1131         Set<ModuleSymbol> result = computeTransitiveClosure(enabledRoot, observable);
1132 
1133         result.add(syms.unnamedModule);
1134 
1135         allModules = result;






1136     }
1137 
1138     public boolean isInModuleGraph(ModuleSymbol msym) {
1139         return allModules == null || allModules.contains(msym);
1140     }
1141 
1142     private Set<ModuleSymbol> computeTransitiveClosure(Iterable<? extends ModuleSymbol> base, Set<ModuleSymbol> observable) {
1143         List<ModuleSymbol> todo = List.nil();
1144 
1145         for (ModuleSymbol ms : base) {
1146             todo = todo.prepend(ms);
1147         }
1148 
1149         Set<ModuleSymbol> result = new LinkedHashSet<>();
1150         result.add(syms.java_base);
1151 
1152         while (todo.nonEmpty()) {
1153             ModuleSymbol current = todo.head;
1154             todo = todo.tail;
1155             if (observable != null && !observable.contains(current))




 141     private final Source source;
 142     private final boolean allowModules;
 143 
 144     public final boolean multiModuleMode;
 145 
 146     private final String moduleOverride;
 147 
 148     private final Name java_se;
 149     private final Name java_;
 150 
 151     ModuleSymbol defaultModule;
 152 
 153     private final String addExportsOpt;
 154     private Map<ModuleSymbol, Set<ExportsDirective>> addExports;
 155     private final String addReadsOpt;
 156     private Map<ModuleSymbol, Set<RequiresDirective>> addReads;
 157     private final String addModsOpt;
 158     private final Set<String> extraAddMods = new HashSet<>();
 159     private final String limitModsOpt;
 160     private final Set<String> extraLimitMods = new HashSet<>();
 161     private final String moduleVersionOpt;
 162 
 163     private final boolean lintOptions;
 164 
 165     private Set<ModuleSymbol> rootModules = null;
 166 
 167     public static Modules instance(Context context) {
 168         Modules instance = context.get(Modules.class);
 169         if (instance == null)
 170             instance = new Modules(context);
 171         return instance;
 172     }
 173 
 174     protected Modules(Context context) {
 175         context.put(Modules.class, this);
 176         log = Log.instance(context);
 177         names = Names.instance(context);
 178         syms = Symtab.instance(context);
 179         attr = Attr.instance(context);
 180         chk = Check.instance(context);
 181         deferredLintHandler = DeferredLintHandler.instance(context);


 187         allowModules = source.allowModules();
 188         Options options = Options.instance(context);
 189 
 190         lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
 191 
 192         moduleOverride = options.get(Option.XMODULE);
 193 
 194         multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH);
 195         ClassWriter classWriter = ClassWriter.instance(context);
 196         classWriter.multiModuleMode = multiModuleMode;
 197         JNIWriter jniWriter = JNIWriter.instance(context);
 198         jniWriter.multiModuleMode = multiModuleMode;
 199 
 200         java_se = names.fromString("java.se");
 201         java_ = names.fromString("java.");
 202 
 203         addExportsOpt = options.get(Option.ADD_EXPORTS);
 204         addReadsOpt = options.get(Option.ADD_READS);
 205         addModsOpt = options.get(Option.ADD_MODULES);
 206         limitModsOpt = options.get(Option.LIMIT_MODULES);
 207         moduleVersionOpt = options.get(Option.MODULE_VERSION);
 208     }
 209 
 210     int depth = -1;
 211     private void dprintln(String msg) {
 212         for (int i = 0; i < depth; i++)
 213             System.err.print("  ");
 214         System.err.println(msg);
 215     }
 216 
 217     public void addExtraAddModules(String... extras) {
 218         extraAddMods.addAll(Arrays.asList(extras));
 219     }
 220 
 221     public void addExtraLimitModules(String... extras) {
 222         extraLimitMods.addAll(Arrays.asList(extras));
 223     }
 224 
 225     boolean inInitModules;
 226     public void initModules(List<JCCompilationUnit> trees) {
 227         Assert.check(!inInitModules);


 580             directives.add(d);
 581             requires.add(d);
 582         }
 583 
 584         RequiresDirective requiresUnnamed = new RequiresDirective(syms.unnamedModule);
 585         directives.add(requiresUnnamed);
 586         requires.add(requiresUnnamed);
 587 
 588         msym.requires = requires.toList();
 589         msym.directives = directives.toList();
 590     }
 591 
 592     private Completer getSourceCompleter(JCCompilationUnit tree) {
 593         return new Completer() {
 594             @Override
 595             public void complete(Symbol sym) throws CompletionFailure {
 596                 ModuleSymbol msym = (ModuleSymbol) sym;
 597                 msym.flags_field |= UNATTRIBUTED;
 598                 ModuleVisitor v = new ModuleVisitor();
 599                 JavaFileObject prev = log.useSource(tree.sourcefile);

 600                 JCModuleDecl moduleDecl = tree.getModuleDecl();
 601                 DiagnosticPosition prevLintPos = deferredLintHandler.setPos(moduleDecl.pos());
 602 
 603                 try {
 604                     moduleDecl.accept(v);
 605                     completeModule(msym);
 606                     checkCyclicDependencies(moduleDecl);
 607                 } finally {
 608                     log.useSource(prev);
 609                     deferredLintHandler.setPos(prevLintPos);
 610                     msym.flags_field &= ~UNATTRIBUTED;
 611                 }
 612             }
 613 
 614             @Override
 615             public String toString() {
 616                 return "SourceCompleter: " + tree.sourcefile.getName();
 617             }
 618 
 619         };
 620     }
 621 
 622     class ModuleVisitor extends JCTree.Visitor {
 623         private ModuleSymbol sym;
 624         private final Set<ModuleSymbol> allRequires = new HashSet<>();
 625         private final Map<PackageSymbol,List<ExportsDirective>> allExports = new HashMap<>();
 626         private final Map<PackageSymbol,List<OpensDirective>> allOpens = new HashMap<>();
 627 
 628         @Override
 629         public void visitModuleDef(JCModuleDecl tree) {


 666 
 667         @Override
 668         public void visitExports(JCExports tree) {
 669             Name name = TreeInfo.fullName(tree.qualid);
 670             PackageSymbol packge = syms.enterPackage(sym, name);
 671             attr.setPackageSymbols(tree.qualid, packge);
 672 
 673             if (tree.hasTag(Tag.OPENS) && sym.flags.contains(ModuleFlags.OPEN)) {
 674                 log.error(tree.pos(), Errors.NoOpensUnlessStrong);
 675             }
 676             List<ExportsDirective> exportsForPackage = allExports.computeIfAbsent(packge, p -> List.nil());
 677             for (ExportsDirective d : exportsForPackage) {
 678                 reportExportsConflict(tree, packge);
 679             }
 680 
 681             List<ModuleSymbol> toModules = null;
 682             if (tree.moduleNames != null) {
 683                 Set<ModuleSymbol> to = new LinkedHashSet<>();
 684                 for (JCExpression n: tree.moduleNames) {
 685                     ModuleSymbol msym = lookupModule(n);
 686                     chk.checkModuleExists(n.pos(), msym);


 687                     for (ExportsDirective d : exportsForPackage) {
 688                         checkDuplicateExportsToModule(n, msym, d);
 689                     }
 690                     if (!to.add(msym)) {
 691                         reportExportsConflictToModule(n, msym);
 692                     }
 693                 }

 694                 toModules = List.from(to);
 695             }
 696 
 697             if (toModules == null || !toModules.isEmpty()) {
 698                 Set<ExportsFlag> flags = EnumSet.noneOf(ExportsFlag.class);
 699                 ExportsDirective d = new ExportsDirective(packge, toModules, flags);
 700                 sym.exports = sym.exports.prepend(d);
 701                 tree.directive = d;
 702 
 703                 allExports.put(packge, exportsForPackage.prepend(d));
 704             }
 705         }
 706 
 707         private void reportExportsConflict(JCExports tree, PackageSymbol packge) {
 708             log.error(tree.qualid.pos(), Errors.ConflictingExports(packge));
 709         }
 710 
 711         private void checkDuplicateExportsToModule(JCExpression name, ModuleSymbol msym,
 712                 ExportsDirective d) {
 713             if (d.modules != null) {


 725 
 726         @Override
 727         public void visitOpens(JCOpens tree) {
 728             Name name = TreeInfo.fullName(tree.qualid);
 729             PackageSymbol packge = syms.enterPackage(sym, name);
 730             attr.setPackageSymbols(tree.qualid, packge);
 731 
 732             if (sym.flags.contains(ModuleFlags.OPEN)) {
 733                 log.error(tree.pos(), Errors.NoOpensUnlessStrong);
 734             }
 735             List<OpensDirective> opensForPackage = allOpens.computeIfAbsent(packge, p -> List.nil());
 736             for (OpensDirective d : opensForPackage) {
 737                 reportOpensConflict(tree, packge);
 738             }
 739 
 740             List<ModuleSymbol> toModules = null;
 741             if (tree.moduleNames != null) {
 742                 Set<ModuleSymbol> to = new LinkedHashSet<>();
 743                 for (JCExpression n: tree.moduleNames) {
 744                     ModuleSymbol msym = lookupModule(n);
 745                     chk.checkModuleExists(n.pos(), msym);


 746                     for (OpensDirective d : opensForPackage) {
 747                         checkDuplicateOpensToModule(n, msym, d);
 748                     }
 749                     if (!to.add(msym)) {
 750                         reportOpensConflictToModule(n, msym);
 751                     }
 752                 }

 753                 toModules = List.from(to);
 754             }
 755 
 756             if (toModules == null || !toModules.isEmpty()) {
 757                 Set<OpensFlag> flags = EnumSet.noneOf(OpensFlag.class);
 758                 OpensDirective d = new OpensDirective(packge, toModules, flags);
 759                 sym.opens = sym.opens.prepend(d);
 760                 tree.directive = d;
 761 
 762                 allOpens.put(packge, opensForPackage.prepend(d));
 763             }
 764         }
 765 
 766         private void reportOpensConflict(JCOpens tree, PackageSymbol packge) {
 767             log.error(tree.qualid.pos(), Errors.ConflictingOpens(packge));
 768         }
 769 
 770         private void checkDuplicateOpensToModule(JCExpression name, ModuleSymbol msym,
 771                 OpensDirective d) {
 772             if (d.modules != null) {


1115                         break;
1116                     default:
1117                         if (!isValidName(added))
1118                             continue;
1119                         modules = Stream.of(syms.enterModule(names.fromString(added)));
1120                         break;
1121                 }
1122                 modules.forEach(sym -> {
1123                     enabledRoot.add(sym);
1124                     if (observable != null)
1125                         observable.add(sym);
1126                 });
1127             }
1128         }
1129 
1130         Set<ModuleSymbol> result = computeTransitiveClosure(enabledRoot, observable);
1131 
1132         result.add(syms.unnamedModule);
1133 
1134         allModules = result;
1135 
1136         //add module versions from options, if any:
1137         if (moduleVersionOpt != null) {
1138             Name version = names.fromString(moduleVersionOpt);
1139             rootModules.forEach(m -> m.version = version);
1140         }
1141     }
1142 
1143     public boolean isInModuleGraph(ModuleSymbol msym) {
1144         return allModules == null || allModules.contains(msym);
1145     }
1146 
1147     private Set<ModuleSymbol> computeTransitiveClosure(Iterable<? extends ModuleSymbol> base, Set<ModuleSymbol> observable) {
1148         List<ModuleSymbol> todo = List.nil();
1149 
1150         for (ModuleSymbol ms : base) {
1151             todo = todo.prepend(ms);
1152         }
1153 
1154         Set<ModuleSymbol> result = new LinkedHashSet<>();
1155         result.add(syms.java_base);
1156 
1157         while (todo.nonEmpty()) {
1158             ModuleSymbol current = todo.head;
1159             todo = todo.tail;
1160             if (observable != null && !observable.contains(current))


< prev index next >