6794582: javadoc should read files using a FileManager
Reviewed-by: darcy, bpatel
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java
index 30c4c74..2cb3ab3 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java
@@ -25,17 +25,29 @@
package com.sun.tools.javadoc;
-import java.io.*;
-
+import java.io.File;
+import java.io.IOException;
import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
-import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.comp.*;
-import com.sun.tools.javac.file.Paths;
+import com.sun.tools.javac.code.Symbol.CompletionFailure;
+import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.parser.DocCommentScanner;
-import com.sun.tools.javac.tree.*;
-import com.sun.tools.javac.tree.JCTree.*;
-import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.util.Abort;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Position;
/**
@@ -53,7 +65,6 @@
final JavadocClassReader reader;
final JavadocEnter enter;
final Annotate annotate;
- private final Paths paths;
/**
* Construct a new JavaCompiler processor, using appropriately
@@ -66,7 +77,6 @@
reader = JavadocClassReader.instance0(context);
enter = JavadocEnter.instance0(context);
annotate = Annotate.instance(context);
- paths = Paths.instance(context);
}
/**
@@ -120,7 +130,7 @@
boolean quiet) throws IOException {
docenv = DocEnv.instance(context);
docenv.showAccess = filter;
- docenv.quiet = quiet;
+ docenv.quiet = quiet;
docenv.breakiterator = breakiterator;
docenv.setLocale(doclocale);
docenv.setEncoding(encoding);
@@ -133,12 +143,14 @@
ListBuffer<JCCompilationUnit> packTrees = new ListBuffer<JCCompilationUnit>();
try {
+ StandardJavaFileManager fm = (StandardJavaFileManager) docenv.fileManager;
for (List<String> it = javaNames; it.nonEmpty(); it = it.tail) {
String name = it.head;
if (!docClasses && name.endsWith(".java") && new File(name).exists()) {
+ JavaFileObject fo = fm.getJavaFileObjects(name).iterator().next();
docenv.notice("main.Loading_source_file", name);
- JCCompilationUnit tree = parse(name);
- classTrees.append(tree);
+ JCCompilationUnit tree = parse(fo);
+ classTrees.append(tree);
} else if (isValidPackageName(name)) {
names = names.append(name);
} else if (name.endsWith(".java")) {
@@ -151,12 +163,14 @@
if (!docClasses) {
// Recursively search given subpackages. If any packages
//are found, add them to the list.
- searchSubPackages(subPackages, names, excludedPackages);
+ Map<String,List<JavaFileObject>> packageFiles =
+ searchSubPackages(subPackages, names, excludedPackages);
// Parse the packages
for (List<String> packs = names.toList(); packs.nonEmpty(); packs = packs.tail) {
// Parse sources ostensibly belonging to package.
- parsePackageClasses(packs.head, packTrees, excludedPackages);
+ String packageName = packs.head;
+ parsePackageClasses(packageName, packageFiles.get(packageName), packTrees, excludedPackages);
}
if (messager.nerrors() != 0) return null;
@@ -167,7 +181,8 @@
}
} catch (Abort ex) {}
- if (messager.nerrors() != 0) return null;
+ if (messager.nerrors() != 0)
+ return null;
if (docClasses)
return new RootDocImpl(docenv, javaNames, options);
@@ -185,66 +200,129 @@
return isValidClassName(s);
}
-
- private final static char pathSep = File.pathSeparatorChar;
-
/**
* search all directories in path for subdirectory name. Add all
* .java files found in such a directory to args.
*/
private void parsePackageClasses(String name,
- ListBuffer<JCCompilationUnit> trees,
- List<String> excludedPackages)
- throws IOException {
+ Iterable<JavaFileObject> files,
+ ListBuffer<JCCompilationUnit> trees,
+ List<String> excludedPackages)
+ throws IOException {
if (excludedPackages.contains(name)) {
return;
}
+
boolean hasFiles = false;
docenv.notice("main.Loading_source_files_for_package", name);
- name = name.replace('.', File.separatorChar);
- for (File pathname : paths.sourceSearchPath()) {
- File f = new File(pathname, name);
- String names[] = f.list();
- // if names not null, then found directory with source files
- if (names != null) {
- String dir = f.getAbsolutePath();
- if (!dir.endsWith(File.separator))
- dir = dir + File.separator;
- for (int j = 0; j < names.length; j++) {
- if (isValidJavaSourceFile(names[j])) {
- String fn = dir + names[j];
- // messager.notice("main.Loading_source_file", fn);
- trees.append(parse(fn));
- hasFiles = true;
- }
+
+ if (files == null) {
+ Location location = docenv.fileManager.hasLocation(StandardLocation.SOURCE_PATH)
+ ? StandardLocation.SOURCE_PATH : StandardLocation.CLASS_PATH;
+ ListBuffer<JavaFileObject> lb = new ListBuffer<JavaFileObject>();
+ for (JavaFileObject fo: docenv.fileManager.list(
+ location, name, EnumSet.of(JavaFileObject.Kind.SOURCE), false)) {
+ String binaryName = docenv.fileManager.inferBinaryName(location, fo);
+ String simpleName = getSimpleName(binaryName);
+ if (isValidClassName(simpleName)) {
+ lb.append(fo);
}
}
+ files = lb.toList();
}
- if (!hasFiles)
+
+ for (JavaFileObject fo : files) {
+ // messager.notice("main.Loading_source_file", fn);
+ trees.append(parse(fo));
+ hasFiles = true;
+ }
+
+ if (!hasFiles) {
messager.warning(null, "main.no_source_files_for_package",
- name.replace(File.separatorChar, '.'));
+ name.replace(File.separatorChar, '.'));
+ }
}
/**
* Recursively search all directories in path for subdirectory name.
* Add all packages found in such a directory to packages list.
*/
- private void searchSubPackages(List<String> subPackages,
- ListBuffer<String> packages,
- List<String> excludedPackages) {
- // FIXME: This search path is bogus.
- // Only the effective source path should be searched for sources.
- // Only the effective class path should be searched for classes.
- // Should the bootclasspath/extdirs also be searched for classes?
- java.util.List<File> pathnames = new java.util.ArrayList<File>();
- if (paths.sourcePath() != null)
- for (File elt : paths.sourcePath())
- pathnames.add(elt);
- for (File elt : paths.userClassPath())
- pathnames.add(elt);
+ private Map<String,List<JavaFileObject>> searchSubPackages(
+ List<String> subPackages,
+ ListBuffer<String> packages,
+ List<String> excludedPackages)
+ throws IOException {
+ Map<String,List<JavaFileObject>> packageFiles =
+ new HashMap<String,List<JavaFileObject>>();
- for (String subPackage : subPackages)
- searchSubPackage(subPackage, packages, excludedPackages, pathnames);
+ Map<String,Boolean> includedPackages = new HashMap<String,Boolean>();
+ includedPackages.put("", true);
+ for (String p: excludedPackages)
+ includedPackages.put(p, false);
+
+ if (docenv.fileManager.hasLocation(StandardLocation.SOURCE_PATH)) {
+ searchSubPackages(subPackages,
+ includedPackages,
+ packages, packageFiles,
+ StandardLocation.SOURCE_PATH,
+ EnumSet.of(JavaFileObject.Kind.SOURCE));
+ searchSubPackages(subPackages,
+ includedPackages,
+ packages, packageFiles,
+ StandardLocation.CLASS_PATH,
+ EnumSet.of(JavaFileObject.Kind.CLASS));
+ } else {
+ searchSubPackages(subPackages,
+ includedPackages,
+ packages, packageFiles,
+ StandardLocation.CLASS_PATH,
+ EnumSet.of(JavaFileObject.Kind.SOURCE, JavaFileObject.Kind.CLASS));
+ }
+ return packageFiles;
+ }
+
+ private void searchSubPackages(List<String> subPackages,
+ Map<String,Boolean> includedPackages,
+ ListBuffer<String> packages,
+ Map<String, List<JavaFileObject>> packageFiles,
+ StandardLocation location, Set<JavaFileObject.Kind> kinds)
+ throws IOException {
+ for (String subPackage: subPackages) {
+ if (!isIncluded(subPackage, includedPackages))
+ continue;
+
+ for (JavaFileObject fo: docenv.fileManager.list(location, subPackage, kinds, true)) {
+ String binaryName = docenv.fileManager.inferBinaryName(location, fo);
+ String packageName = getPackageName(binaryName);
+ String simpleName = getSimpleName(binaryName);
+ if (isIncluded(packageName, includedPackages) && isValidClassName(simpleName)) {
+ List<JavaFileObject> list = packageFiles.get(packageName);
+ list = (list == null ? List.of(fo) : list.prepend(fo));
+ packageFiles.put(packageName, list);
+ if (!packages.contains(packageName))
+ packages.add(packageName);
+ }
+ }
+ }
+ }
+
+ private String getPackageName(String name) {
+ int lastDot = name.lastIndexOf(".");
+ return (lastDot == -1 ? "" : name.substring(0, lastDot));
+ }
+
+ private String getSimpleName(String name) {
+ int lastDot = name.lastIndexOf(".");
+ return (lastDot == -1 ? name : name.substring(lastDot + 1));
+ }
+
+ private boolean isIncluded(String packageName, Map<String,Boolean> includedPackages) {
+ Boolean b = includedPackages.get(packageName);
+ if (b == null) {
+ b = isIncluded(getPackageName(packageName), includedPackages);
+ includedPackages.put(packageName, b);
+ }
+ return b;
}
/**