langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java
changeset 44301 2f97c71f06f4
parent 43265 4ec472ee5135
child 44389 a745e6ff79a5
equal deleted inserted replaced
44300:4bd6416db3de 44301:2f97c71f06f4
    51 import javax.tools.JavaFileManager.Location;
    51 import javax.tools.JavaFileManager.Location;
    52 import javax.tools.JavaFileObject;
    52 import javax.tools.JavaFileObject;
    53 import javax.tools.StandardLocation;
    53 import javax.tools.StandardLocation;
    54 
    54 
    55 import com.sun.tools.javac.code.Kinds.Kind;
    55 import com.sun.tools.javac.code.Kinds.Kind;
       
    56 import com.sun.tools.javac.code.Source;
    56 import com.sun.tools.javac.code.Symbol;
    57 import com.sun.tools.javac.code.Symbol;
    57 import com.sun.tools.javac.code.Symbol.ClassSymbol;
    58 import com.sun.tools.javac.code.Symbol.ClassSymbol;
    58 import com.sun.tools.javac.code.Symbol.CompletionFailure;
    59 import com.sun.tools.javac.code.Symbol.CompletionFailure;
    59 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
    60 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
    60 import com.sun.tools.javac.code.Symbol.PackageSymbol;
    61 import com.sun.tools.javac.code.Symbol.PackageSymbol;
    61 import com.sun.tools.javac.code.Symtab;
    62 import com.sun.tools.javac.code.Symtab;
    62 import com.sun.tools.javac.comp.Modules;
    63 import com.sun.tools.javac.comp.Modules;
       
    64 import com.sun.tools.javac.main.JavaCompiler;
    63 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
    65 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
    64 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
    66 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
       
    67 import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
       
    68 import com.sun.tools.javac.tree.TreeInfo;
    65 import com.sun.tools.javac.util.Context;
    69 import com.sun.tools.javac.util.Context;
    66 import com.sun.tools.javac.util.ListBuffer;
    70 import com.sun.tools.javac.util.ListBuffer;
    67 import com.sun.tools.javac.util.Name;
    71 import com.sun.tools.javac.util.Name;
    68 import com.sun.tools.javac.util.Names;
    72 import com.sun.tools.javac.util.Names;
    69 import jdk.javadoc.doclet.DocletEnvironment;
    73 import jdk.javadoc.doclet.DocletEnvironment;
    70 import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
    74 import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
    71 
    75 
    72 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
    76 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
       
    77 
    73 import static javax.tools.JavaFileObject.Kind.*;
    78 import static javax.tools.JavaFileObject.Kind.*;
       
    79 
    74 import static jdk.javadoc.internal.tool.Main.Result.*;
    80 import static jdk.javadoc.internal.tool.Main.Result.*;
    75 import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
    81 import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
    76 
    82 
    77 
    83 
    78 /**
    84 /**
   151 
   157 
   152     private final ToolEnvironment toolEnv;
   158     private final ToolEnvironment toolEnv;
   153     private final Symtab syms;
   159     private final Symtab syms;
   154     private final Names names;
   160     private final Names names;
   155     private final JavaFileManager fm;
   161     private final JavaFileManager fm;
   156     private final Location location;
   162     private final List<Location> locations;
   157     private final Modules modules;
   163     private final Modules modules;
   158     private final Map<ToolOption, Object> opts;
   164     private final Map<ToolOption, Object> opts;
   159     private final Messager messager;
   165     private final Messager messager;
       
   166     private final JavaCompiler compiler;
   160 
   167 
   161     private final Map<String, Entry> entries = new LinkedHashMap<>();
   168     private final Map<String, Entry> entries = new LinkedHashMap<>();
   162 
   169 
   163     // specified elements
   170     // specified elements
   164     private Set<ModuleElement> specifiedModuleElements = new LinkedHashSet<>();
   171     private Set<ModuleElement> specifiedModuleElements = new LinkedHashSet<>();
   199         this.names = Names.instance(context);
   206         this.names = Names.instance(context);
   200         this.fm = toolEnv.fileManager;
   207         this.fm = toolEnv.fileManager;
   201         this.modules = Modules.instance(context);
   208         this.modules = Modules.instance(context);
   202         this.opts = opts;
   209         this.opts = opts;
   203         this.messager = Messager.instance0(context);
   210         this.messager = Messager.instance0(context);
   204 
   211         this.compiler = JavaCompiler.instance(context);
   205         this.location = modules.multiModuleMode
   212         Source source = Source.instance(context);
   206                 ? StandardLocation.MODULE_SOURCE_PATH
   213 
   207                 : toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH)
   214         List<Location> locs = new ArrayList<>();
   208                     ? StandardLocation.SOURCE_PATH
   215         if (modules.multiModuleMode) {
   209                     : StandardLocation.CLASS_PATH;
   216             locs.add(StandardLocation.MODULE_SOURCE_PATH);
       
   217         } else {
       
   218             if (toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH))
       
   219                 locs.add(StandardLocation.SOURCE_PATH);
       
   220             else
       
   221                 locs.add(StandardLocation.CLASS_PATH);
       
   222         }
       
   223         if (source.allowModules() && toolEnv.fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH))
       
   224             locs.add(StandardLocation.PATCH_MODULE_PATH);
       
   225         this.locations = Collections.unmodifiableList(locs);
       
   226 
   210         getEntry("").excluded = false;
   227         getEntry("").excluded = false;
   211 
   228 
   212         accessFilter = new ModifierFilter(opts);
   229         accessFilter = new ModifierFilter(opts);
   213         xclasses = (boolean)opts.getOrDefault(ToolOption.XCLASSES, false);
   230         xclasses = (boolean)opts.getOrDefault(ToolOption.XCLASSES, false);
   214         expandRequires = (AccessKind)opts.get(ToolOption.EXPAND_REQUIRES);
   231         expandRequires = (AccessKind)opts.get(ToolOption.EXPAND_REQUIRES);
   339     ElementsTable classTrees(com.sun.tools.javac.util.List<JCCompilationUnit> classTrees) {
   356     ElementsTable classTrees(com.sun.tools.javac.util.List<JCCompilationUnit> classTrees) {
   340         this.classTreeList = classTrees;
   357         this.classTreeList = classTrees;
   341         return this;
   358         return this;
   342     }
   359     }
   343 
   360 
       
   361     /*
       
   362      * This method sanity checks the following cases:
       
   363      * a. a source-path containing a single module and many modules specified with --module
       
   364      * b. no modules on source-path
       
   365      * c. mismatched source-path and many modules specified with --module
       
   366      */
       
   367     void sanityCheckSourcePathModules(List<String> moduleNames) throws ToolException {
       
   368         if (!haveSourceLocationWithModule)
       
   369             return;
       
   370 
       
   371         if (moduleNames.size() > 1) {
       
   372             String text = messager.getText("main.cannot_use_sourcepath_for_modules",
       
   373                     String.join(", ", moduleNames));
       
   374             throw new ToolException(CMDERR, text);
       
   375         }
       
   376 
       
   377         String foundModule = getModuleName(StandardLocation.SOURCE_PATH);
       
   378         if (foundModule == null) {
       
   379             String text = messager.getText("main.module_not_found_on_sourcepath", moduleNames.get(0));
       
   380             throw new ToolException(CMDERR, text);
       
   381         }
       
   382 
       
   383         if (!moduleNames.get(0).equals(foundModule)) {
       
   384             String text = messager.getText("main.sourcepath_does_not_contain_module", moduleNames.get(0));
       
   385             throw new ToolException(CMDERR, text);
       
   386         }
       
   387     }
       
   388 
       
   389     private String getModuleName(Location location) throws ToolException {
       
   390         try {
       
   391             JavaFileObject jfo = fm.getJavaFileForInput(location,
       
   392                     "module-info", JavaFileObject.Kind.SOURCE);
       
   393             if (jfo != null) {
       
   394                 JCCompilationUnit jcu = compiler.parse(jfo);
       
   395                 JCModuleDecl module = TreeInfo.getModule(jcu);
       
   396                 if (module != null) {
       
   397                     return module.getName().toString();
       
   398                 }
       
   399             }
       
   400         } catch (IOException ioe) {
       
   401             String text = messager.getText("main.file.manager.list", location);
       
   402             throw new ToolException(SYSERR, text, ioe);
       
   403         }
       
   404         return null;
       
   405     }
       
   406 
   344     @SuppressWarnings("unchecked")
   407     @SuppressWarnings("unchecked")
   345     ElementsTable scanSpecifiedItems() throws ToolException {
   408     ElementsTable scanSpecifiedItems() throws ToolException {
   346 
   409 
   347         // scan modules specified on the command line
   410         // scan modules specified on the command line
   348         List<String> moduleNames = (List<String>) opts.computeIfAbsent(ToolOption.MODULE,
   411         List<String> moduleNames = (List<String>) opts.computeIfAbsent(ToolOption.MODULE,
   349                 s -> Collections.EMPTY_LIST);
   412                 s -> Collections.EMPTY_LIST);
   350         List<String> mlist = new ArrayList<>();
   413         List<String> mlist = new ArrayList<>();
   351         for (String m : moduleNames) {
   414         for (String m : moduleNames) {
   352             Location moduleLoc = getModuleLocation(location, m);
   415             List<Location> moduleLocations = getModuleLocation(locations, m);
   353             if (moduleLoc == null) {
   416             if (moduleLocations.isEmpty()) {
   354                 String text = messager.getText("main.module_not_found", m);
   417                 String text = messager.getText("main.module_not_found", m);
   355                 throw new ToolException(CMDERR, text);
   418                 throw new ToolException(CMDERR, text);
   356             } else {
   419             }
   357                 mlist.add(m);
   420             if (moduleLocations.contains(StandardLocation.SOURCE_PATH)) {
   358                 ModuleSymbol msym = syms.enterModule(names.fromString(m));
   421                 sanityCheckSourcePathModules(moduleNames);
   359                 specifiedModuleElements.add((ModuleElement) msym);
   422             }
   360             }
   423             mlist.add(m);
       
   424             ModuleSymbol msym = syms.enterModule(names.fromString(m));
       
   425             specifiedModuleElements.add((ModuleElement) msym);
   361         }
   426         }
   362 
   427 
   363         // scan for modules with qualified packages
   428         // scan for modules with qualified packages
   364         cmdLinePackages.stream()
   429         cmdLinePackages.stream()
   365                 .filter((mpkg) -> (mpkg.hasModule()))
   430                 .filter((mpkg) -> (mpkg.hasModule()))
   446         excludePackages.forEach((p) -> {
   511         excludePackages.forEach((p) -> {
   447             getEntry(p).excluded = true;
   512             getEntry(p).excluded = true;
   448         });
   513         });
   449 
   514 
   450         for (ModulePackage modpkg : subPackages) {
   515         for (ModulePackage modpkg : subPackages) {
   451             Location packageLocn = getLocation(modpkg);
   516             List<Location> locs = getLocation(modpkg);
   452             Iterable<JavaFileObject> list = null;
   517             for (Location loc : locs) {
   453             try {
   518                 addPackagesFromLocations(loc, modpkg);
   454                 list = fm.list(packageLocn, modpkg.packageName, sourceKinds, true);
   519             }
   455             } catch (IOException ioe) {
   520         }
   456                 String text = messager.getText("main.file.manager.list", modpkg.packageName);
   521     }
   457                 throw new ToolException(SYSERR, text, ioe);
   522 
   458             }
   523     private void addPackagesFromLocations(Location packageLocn, ModulePackage modpkg) throws ToolException {
   459             for (JavaFileObject fo : list) {
   524         Iterable<JavaFileObject> list = null;
   460                 String binaryName = fm.inferBinaryName(packageLocn, fo);
   525         try {
   461                 String pn = getPackageName(binaryName);
   526             list = fm.list(packageLocn, modpkg.packageName, sourceKinds, true);
   462                 String simpleName = getSimpleName(binaryName);
   527         } catch (IOException ioe) {
   463                 Entry e = getEntry(pn);
   528             String text = messager.getText("main.file.manager.list", modpkg.packageName);
   464                 if (!e.isExcluded() && isValidClassName(simpleName)) {
   529             throw new ToolException(SYSERR, text, ioe);
   465                     ModuleSymbol msym = (modpkg.hasModule())
   530         }
   466                             ? syms.getModule(names.fromString(modpkg.moduleName))
   531         for (JavaFileObject fo : list) {
   467                             : findModuleOfPackageName(modpkg.packageName);
   532             String binaryName = fm.inferBinaryName(packageLocn, fo);
   468 
   533             String pn = getPackageName(binaryName);
   469                     if (msym != null && !msym.isUnnamed()) {
   534             String simpleName = getSimpleName(binaryName);
   470                         syms.enterPackage(msym, names.fromString(pn));
   535             Entry e = getEntry(pn);
   471                         ModulePackage npkg = new ModulePackage(msym.toString(), pn);
   536             if (!e.isExcluded() && isValidClassName(simpleName)) {
   472                         cmdLinePackages.add(npkg);
   537                 ModuleSymbol msym = (modpkg.hasModule())
   473                     } else {
   538                         ? syms.getModule(names.fromString(modpkg.moduleName))
   474                         cmdLinePackages.add(e.modpkg);
   539                         : findModuleOfPackageName(modpkg.packageName);
   475                     }
   540 
   476                     e.files = (e.files == null
   541                 if (msym != null && !msym.isUnnamed()) {
   477                             ? com.sun.tools.javac.util.List.of(fo)
   542                     syms.enterPackage(msym, names.fromString(pn));
   478                             : e.files.prepend(fo));
   543                     ModulePackage npkg = new ModulePackage(msym.toString(), pn);
   479                 }
   544                     cmdLinePackages.add(npkg);
       
   545                 } else {
       
   546                     cmdLinePackages.add(e.modpkg);
       
   547                 }
       
   548                 e.files = (e.files == null
       
   549                         ? com.sun.tools.javac.util.List.of(fo)
       
   550                         : e.files.prepend(fo));
   480             }
   551             }
   481         }
   552         }
   482     }
   553     }
   483 
   554 
   484     /**
   555     /**
   542     }
   613     }
   543 
   614 
   544     private Set<PackageElement> getAllModulePackages(ModuleElement mdle) throws ToolException {
   615     private Set<PackageElement> getAllModulePackages(ModuleElement mdle) throws ToolException {
   545         Set<PackageElement> result = new HashSet<>();
   616         Set<PackageElement> result = new HashSet<>();
   546         ModuleSymbol msym = (ModuleSymbol) mdle;
   617         ModuleSymbol msym = (ModuleSymbol) mdle;
   547         Location msymloc = getModuleLocation(location, msym.name.toString());
   618         List<Location> msymlocs = getModuleLocation(locations, msym.name.toString());
   548         try {
   619         for (Location msymloc : msymlocs) {
   549             for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
   620             try {
   550                 if (fo.getName().endsWith("module-info.java"))
   621                 for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
   551                     continue;
   622                     if (fo.getName().endsWith("module-info.java")) {
   552                 String binaryName = fm.inferBinaryName(msymloc, fo);
   623                         continue;
   553                 String pn = getPackageName(binaryName);
   624                     }
   554                 PackageSymbol psym = syms.enterPackage(msym, names.fromString(pn));
   625                     String binaryName = fm.inferBinaryName(msymloc, fo);
   555                 result.add((PackageElement) psym);
   626                     String pn = getPackageName(binaryName);
   556             }
   627                     PackageSymbol psym = syms.enterPackage(msym, names.fromString(pn));
   557 
   628                     result.add((PackageElement) psym);
   558         } catch (IOException ioe) {
   629                 }
   559             String text = messager.getText("main.file.manager.list", msymloc.getName());
   630 
   560             throw new ToolException(SYSERR, text, ioe);
   631             } catch (IOException ioe) {
       
   632                 String text = messager.getText("main.file.manager.list", msymloc.getName());
       
   633                 throw new ToolException(SYSERR, text, ioe);
       
   634             }
   561         }
   635         }
   562         return result;
   636         return result;
   563     }
   637     }
   564 
   638 
   565     private Set<PackageElement> computeModulePackages() throws ToolException {
   639     private Set<PackageElement> computeModulePackages() throws ToolException {
   739         if (e.files != null) {
   813         if (e.files != null) {
   740             return e.files;
   814             return e.files;
   741         }
   815         }
   742 
   816 
   743         ListBuffer<JavaFileObject> lb = new ListBuffer<>();
   817         ListBuffer<JavaFileObject> lb = new ListBuffer<>();
   744         Location packageLocn = getLocation(modpkg);
   818         List<Location> locs = getLocation(modpkg);
   745         if (packageLocn == null) {
   819         if (locs.isEmpty()) {
   746             return Collections.emptyList();
   820             return Collections.emptyList();
   747         }
   821         }
   748         String pname = modpkg.packageName;
   822         String pname = modpkg.packageName;
   749 
   823         for (Location packageLocn : locs) {
   750         try {
   824             try {
   751             for (JavaFileObject fo : fm.list(packageLocn, pname, sourceKinds, recurse)) {
   825                 for (JavaFileObject fo : fm.list(packageLocn, pname, sourceKinds, recurse)) {
   752                 String binaryName = fm.inferBinaryName(packageLocn, fo);
   826                     String binaryName = fm.inferBinaryName(packageLocn, fo);
   753                 String simpleName = getSimpleName(binaryName);
   827                     String simpleName = getSimpleName(binaryName);
   754                 if (isValidClassName(simpleName)) {
   828                     if (isValidClassName(simpleName)) {
   755                     lb.append(fo);
   829                         lb.append(fo);
   756                 }
   830                     }
   757             }
   831                 }
   758         } catch (IOException ioe) {
   832             } catch (IOException ioe) {
   759             String text = messager.getText("main.file.manager.list", pname);
   833                 String text = messager.getText("main.file.manager.list", pname);
   760             throw new ToolException(SYSERR, text, ioe);
   834                 throw new ToolException(SYSERR, text, ioe);
   761         }
   835             }
   762 
   836         }
   763         return lb.toList();
   837         return lb.toList();
   764     }
   838     }
   765 
   839 
   766     private ModuleSymbol findModuleOfPackageName(String packageName) {
   840     private ModuleSymbol findModuleOfPackageName(String packageName) {
   767             Name pack = names.fromString(packageName);
   841             Name pack = names.fromString(packageName);
   772                 }
   846                 }
   773             }
   847             }
   774             return null;
   848             return null;
   775     }
   849     }
   776 
   850 
   777     private Location getLocation(ModulePackage modpkg) throws ToolException {
   851     private List<Location> getLocation(ModulePackage modpkg) throws ToolException {
   778         if (location != StandardLocation.MODULE_SOURCE_PATH) {
   852         if (locations.size() == 1 && !locations.contains(StandardLocation.MODULE_SOURCE_PATH)) {
   779             return location;
   853             return Collections.singletonList(locations.get(0));
   780         }
   854         }
   781 
   855 
   782         if (modpkg.hasModule()) {
   856         if (modpkg.hasModule()) {
   783             return getModuleLocation(location, modpkg.moduleName);
   857             return getModuleLocation(locations, modpkg.moduleName);
   784         }
   858         }
   785         // TODO: handle invalid results better.
   859         // TODO: handle invalid results better.
   786         ModuleSymbol msym = findModuleOfPackageName(modpkg.packageName);
   860         ModuleSymbol msym = findModuleOfPackageName(modpkg.packageName);
   787         if (msym == null) {
   861         if (msym == null) {
   788             return null;
   862             return Collections.emptyList();
   789         }
   863         }
   790         return getModuleLocation(location, msym.name.toString());
   864         return getModuleLocation(locations, msym.name.toString());
   791     }
   865     }
   792 
   866 
   793     private Location getModuleLocation(Location location, String msymName)
   867     boolean haveSourceLocationWithModule = false;
   794             throws ToolException {
   868 
       
   869     private List<Location> getModuleLocation(List<Location> locations, String msymName) throws ToolException {
       
   870         List<Location> out = new ArrayList<>();
       
   871         // search in the patch module first, this overrides others
       
   872         if (locations.contains(StandardLocation.PATCH_MODULE_PATH)) {
       
   873             Location loc = getModuleLocation(StandardLocation.PATCH_MODULE_PATH, msymName);
       
   874             if (loc != null)
       
   875                 out.add(loc);
       
   876         }
       
   877         for (Location location : locations) {
       
   878             // skip patch module, already done
       
   879             if (location == StandardLocation.PATCH_MODULE_PATH) {
       
   880                 continue;
       
   881             } else if (location == StandardLocation.MODULE_SOURCE_PATH) {
       
   882                 Location loc = getModuleLocation(location, msymName);
       
   883                 if (loc != null)
       
   884                     out.add(loc);
       
   885             } else if (location == StandardLocation.SOURCE_PATH) {
       
   886                 haveSourceLocationWithModule = true;
       
   887                 out.add(StandardLocation.SOURCE_PATH);
       
   888             }
       
   889         }
       
   890         return out;
       
   891     }
       
   892 
       
   893     private Location getModuleLocation(Location location, String msymName) throws ToolException {
   795         try {
   894         try {
   796             return fm.getLocationForModule(location, msymName);
   895             return fm.getLocationForModule(location, msymName);
   797         } catch (IOException ioe) {
   896         } catch (IOException ioe) {
   798             String text = messager.getText("main.doclet_could_not_get_location", msymName);
   897             String text = messager.getText("main.doclet_could_not_get_location", msymName);
   799             throw new ToolException(ERROR, text, ioe);
   898             throw new ToolException(ERROR, text, ioe);