J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 1 | /* |
Jan Lahoda | ec39815 | 2017-01-20 09:26:49 +0100 | [diff] [blame] | 2 | * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 4 | * |
| 5 | * This code is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License version 2 only, as |
Kelly O'Hair | bd4f4be | 2010-05-25 15:54:51 -0700 | [diff] [blame] | 7 | * published by the Free Software Foundation. Oracle designates this |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 8 | * particular file as subject to the "Classpath" exception as provided |
Kelly O'Hair | bd4f4be | 2010-05-25 15:54:51 -0700 | [diff] [blame] | 9 | * by Oracle in the LICENSE file that accompanied this code. |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 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 | * |
Kelly O'Hair | bd4f4be | 2010-05-25 15:54:51 -0700 | [diff] [blame] | 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. |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 24 | */ |
| 25 | |
Jonathan Gibbons | daca004 | 2016-05-09 16:52:15 -0700 | [diff] [blame] | 26 | package com.sun.tools.javadoc.main; |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 27 | |
Jonathan Gibbons | 981f025 | 2009-01-20 15:17:45 -0800 | [diff] [blame] | 28 | import java.io.File; |
| 29 | import java.io.IOException; |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 30 | import java.util.Collection; |
Kumar Srinivasan | 2814387 | 2016-07-20 12:49:32 -0700 | [diff] [blame] | 31 | import java.util.Collections; |
Jonathan Gibbons | 981f025 | 2009-01-20 15:17:45 -0800 | [diff] [blame] | 32 | import java.util.EnumSet; |
Kumar Srinivasan | c7480b6 | 2014-02-14 17:28:07 -0800 | [diff] [blame] | 33 | import java.util.HashSet; |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 34 | import java.util.LinkedHashMap; |
| 35 | import java.util.LinkedHashSet; |
Jonathan Gibbons | 981f025 | 2009-01-20 15:17:45 -0800 | [diff] [blame] | 36 | import java.util.Map; |
| 37 | import java.util.Set; |
Jonathan Gibbons | 31e6340 | 2014-05-18 19:59:10 -0700 | [diff] [blame] | 38 | |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 39 | import javax.tools.JavaFileManager; |
Jonathan Gibbons | 981f025 | 2009-01-20 15:17:45 -0800 | [diff] [blame] | 40 | import javax.tools.JavaFileManager.Location; |
| 41 | import javax.tools.JavaFileObject; |
| 42 | import javax.tools.StandardJavaFileManager; |
| 43 | import javax.tools.StandardLocation; |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 44 | |
Jonathan Gibbons | 31e6340 | 2014-05-18 19:59:10 -0700 | [diff] [blame] | 45 | import com.sun.tools.javac.code.ClassFinder; |
Andreas Lundblad | 4c30778 | 2015-04-28 22:25:36 +0200 | [diff] [blame] | 46 | import com.sun.tools.javac.code.Symbol.Completer; |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 47 | import com.sun.tools.javac.code.Symbol.ModuleSymbol; |
Kumar Srinivasan | 2814387 | 2016-07-20 12:49:32 -0700 | [diff] [blame] | 48 | import com.sun.tools.javac.code.Symbol.PackageSymbol; |
Jonathan Gibbons | 31e6340 | 2014-05-18 19:59:10 -0700 | [diff] [blame] | 49 | import com.sun.tools.javac.comp.Enter; |
Jonathan Gibbons | 981f025 | 2009-01-20 15:17:45 -0800 | [diff] [blame] | 50 | import com.sun.tools.javac.tree.JCTree; |
| 51 | import com.sun.tools.javac.tree.JCTree.JCClassDecl; |
| 52 | import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; |
| 53 | import com.sun.tools.javac.util.Abort; |
| 54 | import com.sun.tools.javac.util.Context; |
| 55 | import com.sun.tools.javac.util.List; |
| 56 | import com.sun.tools.javac.util.ListBuffer; |
Kumar Srinivasan | 2814387 | 2016-07-20 12:49:32 -0700 | [diff] [blame] | 57 | import com.sun.tools.javac.util.Name; |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 58 | |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 59 | |
| 60 | /** |
| 61 | * This class could be the main entry point for Javadoc when Javadoc is used as a |
| 62 | * component in a larger software system. It provides operations to |
| 63 | * construct a new javadoc processor, and to run it on a set of source |
| 64 | * files. |
Jonathan Gibbons | 680ffeb | 2012-10-10 16:48:21 -0700 | [diff] [blame] | 65 | * |
| 66 | * <p><b>This is NOT part of any supported API. |
| 67 | * If you write code that depends on this, you do so at your own risk. |
| 68 | * This code and its internal interfaces are subject to change or |
| 69 | * deletion without notice.</b> |
| 70 | * |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 71 | * @author Neal Gafter |
| 72 | */ |
Jonathan Gibbons | cfc5ca5 | 2016-05-27 13:06:58 -0700 | [diff] [blame] | 73 | @Deprecated |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 74 | public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { |
| 75 | DocEnv docenv; |
| 76 | |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 77 | final Messager messager; |
Jonathan Gibbons | 31e6340 | 2014-05-18 19:59:10 -0700 | [diff] [blame] | 78 | final ClassFinder javadocFinder; |
| 79 | final Enter javadocEnter; |
Kumar Srinivasan | 7a7a57b | 2014-04-16 18:15:48 -0700 | [diff] [blame] | 80 | final Set<JavaFileObject> uniquefiles; |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 81 | |
| 82 | /** |
| 83 | * Construct a new JavaCompiler processor, using appropriately |
| 84 | * extended phases of the underlying compiler. |
| 85 | */ |
| 86 | protected JavadocTool(Context context) { |
| 87 | super(context); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 88 | messager = Messager.instance0(context); |
Jonathan Gibbons | 31e6340 | 2014-05-18 19:59:10 -0700 | [diff] [blame] | 89 | javadocFinder = JavadocClassFinder.instance(context); |
| 90 | javadocEnter = JavadocEnter.instance(context); |
Kumar Srinivasan | 7a7a57b | 2014-04-16 18:15:48 -0700 | [diff] [blame] | 91 | uniquefiles = new HashSet<>(); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 92 | } |
| 93 | |
| 94 | /** |
| 95 | * For javadoc, the parser needs to keep comments. Overrides method from JavaCompiler. |
| 96 | */ |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 97 | @Override |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 98 | protected boolean keepComments() { |
| 99 | return true; |
| 100 | } |
| 101 | |
| 102 | /** |
| 103 | * Construct a new javadoc tool. |
| 104 | */ |
| 105 | public static JavadocTool make0(Context context) { |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 106 | // force the use of Javadoc's class finder |
| 107 | JavadocClassFinder.preRegister(context); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 108 | |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 109 | // force the use of Javadoc's own enter phase |
| 110 | JavadocEnter.preRegister(context); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 111 | |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 112 | // force the use of Javadoc's own member enter phase |
| 113 | JavadocMemberEnter.preRegister(context); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 114 | |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 115 | // force the use of Javadoc's own todo phase |
| 116 | JavadocTodo.preRegister(context); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 117 | |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 118 | // force the use of Messager as a Log |
| 119 | Messager.instance0(context); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 120 | |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 121 | return new JavadocTool(context); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 122 | } |
| 123 | |
| 124 | public RootDocImpl getRootDocImpl(String doclocale, |
| 125 | String encoding, |
| 126 | ModifierFilter filter, |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 127 | List<String> args, |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 128 | List<String[]> options, |
Jonathan Gibbons | b3a3f7c | 2012-11-15 23:07:24 -0800 | [diff] [blame] | 129 | Iterable<? extends JavaFileObject> fileObjects, |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 130 | boolean breakiterator, |
| 131 | List<String> subPackages, |
| 132 | List<String> excludedPackages, |
| 133 | boolean docClasses, |
| 134 | boolean legacyDoclet, |
| 135 | boolean quiet) throws IOException { |
| 136 | docenv = DocEnv.instance(context); |
| 137 | docenv.showAccess = filter; |
Jonathan Gibbons | 981f025 | 2009-01-20 15:17:45 -0800 | [diff] [blame] | 138 | docenv.quiet = quiet; |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 139 | docenv.breakiterator = breakiterator; |
| 140 | docenv.setLocale(doclocale); |
| 141 | docenv.setEncoding(encoding); |
| 142 | docenv.docClasses = docClasses; |
| 143 | docenv.legacyDoclet = legacyDoclet; |
Jonathan Gibbons | 31e6340 | 2014-05-18 19:59:10 -0700 | [diff] [blame] | 144 | |
Andreas Lundblad | 4c30778 | 2015-04-28 22:25:36 +0200 | [diff] [blame] | 145 | javadocFinder.sourceCompleter = docClasses ? Completer.NULL_COMPLETER : sourceCompleter; |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 146 | |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 147 | if (docClasses) { |
| 148 | // If -Xclasses is set, the args should be a series of class names |
| 149 | for (String arg: args) { |
| 150 | if (!isValidPackageName(arg)) // checks |
| 151 | docenv.error(null, "main.illegal_class_name", arg); |
| 152 | } |
| 153 | if (messager.nerrors() != 0) { |
| 154 | return null; |
| 155 | } |
| 156 | return new RootDocImpl(docenv, args, options); |
| 157 | } |
| 158 | |
Brian Goetz | 6b6b488 | 2013-12-18 16:05:18 -0500 | [diff] [blame] | 159 | ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<>(); |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 160 | Set<String> includedPackages = new LinkedHashSet<>(); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 161 | |
| 162 | try { |
Jonathan Gibbons | b3a3f7c | 2012-11-15 23:07:24 -0800 | [diff] [blame] | 163 | StandardJavaFileManager fm = docenv.fileManager instanceof StandardJavaFileManager |
| 164 | ? (StandardJavaFileManager) docenv.fileManager : null; |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 165 | Set<String> packageNames = new LinkedHashSet<>(); |
| 166 | // Normally, the args should be a series of package names or file names. |
| 167 | // Parse the files and collect the package names. |
| 168 | for (String arg: args) { |
| 169 | if (fm != null && arg.endsWith(".java") && new File(arg).exists()) { |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 170 | if (new File(arg).getName().equals("module-info.java")) { |
| 171 | docenv.warning(null, "main.file_ignored", arg); |
| 172 | } else { |
| 173 | parse(fm.getJavaFileObjects(arg), classTrees, true); |
| 174 | } |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 175 | } else if (isValidPackageName(arg)) { |
| 176 | packageNames.add(arg); |
| 177 | } else if (arg.endsWith(".java")) { |
Jonathan Gibbons | b3a3f7c | 2012-11-15 23:07:24 -0800 | [diff] [blame] | 178 | if (fm == null) |
| 179 | throw new IllegalArgumentException(); |
| 180 | else |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 181 | docenv.error(null, "main.file_not_found", arg); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 182 | } else { |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 183 | docenv.error(null, "main.illegal_package_name", arg); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 184 | } |
| 185 | } |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 186 | |
| 187 | // Parse file objects provide via the DocumentationTool API |
| 188 | parse(fileObjects, classTrees, true); |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 189 | |
Jan Lahoda | ec9ca29 | 2016-08-11 17:26:12 +0200 | [diff] [blame] | 190 | modules.initModules(classTrees.toList()); |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 191 | |
| 192 | // Build up the complete list of any packages to be documented |
Vicente Romero | 58de940 | 2016-05-27 19:45:57 -0400 | [diff] [blame] | 193 | Location location = modules.multiModuleMode ? StandardLocation.MODULE_SOURCE_PATH |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 194 | : docenv.fileManager.hasLocation(StandardLocation.SOURCE_PATH) ? StandardLocation.SOURCE_PATH |
| 195 | : StandardLocation.CLASS_PATH; |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 196 | |
| 197 | PackageTable t = new PackageTable(docenv.fileManager, location) |
| 198 | .packages(packageNames) |
| 199 | .subpackages(subPackages, excludedPackages); |
| 200 | |
| 201 | includedPackages = t.getIncludedPackages(); |
| 202 | |
| 203 | // Parse the files in the packages to be documented |
| 204 | ListBuffer<JCCompilationUnit> packageTrees = new ListBuffer<>(); |
| 205 | for (String packageName: includedPackages) { |
| 206 | List<JavaFileObject> files = t.getFiles(packageName); |
| 207 | docenv.notice("main.Loading_source_files_for_package", packageName); |
| 208 | |
| 209 | if (files.isEmpty()) |
| 210 | messager.warning(Messager.NOPOS, "main.no_source_files_for_package", packageName); |
| 211 | parse(files, packageTrees, false); |
Jonathan Gibbons | b3a3f7c | 2012-11-15 23:07:24 -0800 | [diff] [blame] | 212 | } |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 213 | modules.enter(packageTrees.toList(), null); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 214 | |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 215 | if (messager.nerrors() != 0) { |
| 216 | return null; |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 217 | } |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 218 | |
| 219 | // Enter symbols for all files |
| 220 | docenv.notice("main.Building_tree"); |
| 221 | javadocEnter.main(classTrees.toList().appendList(packageTrees.toList())); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 222 | } catch (Abort ex) {} |
| 223 | |
Jonathan Gibbons | 981f025 | 2009-01-20 15:17:45 -0800 | [diff] [blame] | 224 | if (messager.nerrors() != 0) |
| 225 | return null; |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 226 | |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 227 | return new RootDocImpl(docenv, listClasses(classTrees.toList()), List.from(includedPackages), options); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 228 | } |
| 229 | |
| 230 | /** Is the given string a valid package name? */ |
| 231 | boolean isValidPackageName(String s) { |
| 232 | int index; |
| 233 | while ((index = s.indexOf('.')) != -1) { |
| 234 | if (!isValidClassName(s.substring(0, index))) return false; |
| 235 | s = s.substring(index+1); |
| 236 | } |
| 237 | return isValidClassName(s); |
| 238 | } |
| 239 | |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 240 | private void parse(Iterable<? extends JavaFileObject> files, ListBuffer<JCCompilationUnit> trees, |
Kumar Srinivasan | 7a7a57b | 2014-04-16 18:15:48 -0700 | [diff] [blame] | 241 | boolean trace) { |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 242 | for (JavaFileObject fo: files) { |
| 243 | if (uniquefiles.add(fo)) { // ignore duplicates |
| 244 | if (trace) |
| 245 | docenv.notice("main.Loading_source_file", fo.getName()); |
| 246 | trees.append(parse(fo)); |
Jonathan Gibbons | 981f025 | 2009-01-20 15:17:45 -0800 | [diff] [blame] | 247 | } |
| 248 | } |
| 249 | } |
| 250 | |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 251 | /** Are surrogates supported? |
| 252 | */ |
| 253 | final static boolean surrogatesSupported = surrogatesSupported(); |
| 254 | private static boolean surrogatesSupported() { |
| 255 | try { |
| 256 | boolean b = Character.isHighSurrogate('a'); |
| 257 | return true; |
| 258 | } catch (NoSuchMethodError ex) { |
| 259 | return false; |
| 260 | } |
| 261 | } |
| 262 | |
| 263 | /** |
| 264 | * Return true if given file name is a valid class name |
| 265 | * (including "package-info"). |
Jonathan Gibbons | b155b54 | 2012-10-09 19:31:58 -0700 | [diff] [blame] | 266 | * @param s the name of the class to check. |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 267 | * @return true if given class name is a valid class name |
| 268 | * and false otherwise. |
| 269 | */ |
| 270 | public static boolean isValidClassName(String s) { |
| 271 | if (s.length() < 1) return false; |
| 272 | if (s.equals("package-info")) return true; |
| 273 | if (surrogatesSupported) { |
| 274 | int cp = s.codePointAt(0); |
| 275 | if (!Character.isJavaIdentifierStart(cp)) |
| 276 | return false; |
| 277 | for (int j=Character.charCount(cp); j<s.length(); j+=Character.charCount(cp)) { |
| 278 | cp = s.codePointAt(j); |
| 279 | if (!Character.isJavaIdentifierPart(cp)) |
| 280 | return false; |
| 281 | } |
| 282 | } else { |
| 283 | if (!Character.isJavaIdentifierStart(s.charAt(0))) |
| 284 | return false; |
| 285 | for (int j=1; j<s.length(); j++) |
| 286 | if (!Character.isJavaIdentifierPart(s.charAt(j))) |
| 287 | return false; |
| 288 | } |
| 289 | return true; |
| 290 | } |
| 291 | |
| 292 | /** |
| 293 | * From a list of top level trees, return the list of contained class definitions |
| 294 | */ |
| 295 | List<JCClassDecl> listClasses(List<JCCompilationUnit> trees) { |
Brian Goetz | 6b6b488 | 2013-12-18 16:05:18 -0500 | [diff] [blame] | 296 | ListBuffer<JCClassDecl> result = new ListBuffer<>(); |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 297 | for (JCCompilationUnit t : trees) { |
| 298 | for (JCTree def : t.defs) { |
Vicente Romero | 399b71b | 2011-11-08 11:51:05 -0800 | [diff] [blame] | 299 | if (def.hasTag(JCTree.Tag.CLASSDEF)) |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 300 | result.append((JCClassDecl)def); |
| 301 | } |
| 302 | } |
| 303 | return result.toList(); |
| 304 | } |
| 305 | |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 306 | /** |
| 307 | * A table to manage included and excluded packages. |
| 308 | */ |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 309 | class PackageTable { |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 310 | private final Map<String, Entry> entries = new LinkedHashMap<>(); |
| 311 | private final Set<String> includedPackages = new LinkedHashSet<>(); |
| 312 | private final JavaFileManager fm; |
| 313 | private final Location location; |
| 314 | private final Set<JavaFileObject.Kind> sourceKinds = EnumSet.of(JavaFileObject.Kind.SOURCE); |
| 315 | |
| 316 | /** |
| 317 | * Creates a table to manage included and excluded packages. |
| 318 | * @param fm The file manager used to locate source files |
| 319 | * @param locn the location used to locate source files |
| 320 | */ |
| 321 | PackageTable(JavaFileManager fm, Location locn) { |
| 322 | this.fm = fm; |
| 323 | this.location = locn; |
| 324 | getEntry("").excluded = false; |
| 325 | } |
| 326 | |
| 327 | PackageTable packages(Collection<String> packageNames) { |
| 328 | includedPackages.addAll(packageNames); |
| 329 | return this; |
| 330 | } |
| 331 | |
| 332 | PackageTable subpackages(Collection<String> packageNames, Collection<String> excludePackageNames) |
| 333 | throws IOException { |
| 334 | for (String p: excludePackageNames) { |
| 335 | getEntry(p).excluded = true; |
| 336 | } |
| 337 | |
| 338 | for (String packageName: packageNames) { |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 339 | Location packageLocn = getLocation(packageName); |
| 340 | for (JavaFileObject fo: fm.list(packageLocn, packageName, sourceKinds, true)) { |
| 341 | String binaryName = fm.inferBinaryName(packageLocn, fo); |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 342 | String pn = getPackageName(binaryName); |
| 343 | String simpleName = getSimpleName(binaryName); |
| 344 | Entry e = getEntry(pn); |
| 345 | if (!e.isExcluded() && isValidClassName(simpleName)) { |
| 346 | includedPackages.add(pn); |
| 347 | e.files = (e.files == null ? List.of(fo) : e.files.prepend(fo)); |
| 348 | } |
| 349 | } |
| 350 | } |
| 351 | return this; |
| 352 | } |
| 353 | |
| 354 | /** |
| 355 | * Returns the aggregate set of included packages. |
| 356 | * @return the aggregate set of included packages |
| 357 | */ |
| 358 | Set<String> getIncludedPackages() { |
| 359 | return includedPackages; |
| 360 | } |
| 361 | |
| 362 | /** |
| 363 | * Returns the set of source files for a package. |
| 364 | * @param packageName the specified package |
| 365 | * @return the set of file objects for the specified package |
| 366 | * @throws IOException if an error occurs while accessing the files |
| 367 | */ |
| 368 | List<JavaFileObject> getFiles(String packageName) throws IOException { |
| 369 | Entry e = getEntry(packageName); |
| 370 | // The files may have been found as a side effect of searching for subpackages |
| 371 | if (e.files != null) |
| 372 | return e.files; |
| 373 | |
| 374 | ListBuffer<JavaFileObject> lb = new ListBuffer<>(); |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 375 | Location packageLocn = getLocation(packageName); |
| 376 | for (JavaFileObject fo: fm.list(packageLocn, packageName, sourceKinds, false)) { |
| 377 | String binaryName = fm.inferBinaryName(packageLocn, fo); |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 378 | String simpleName = getSimpleName(binaryName); |
| 379 | if (isValidClassName(simpleName)) { |
| 380 | lb.append(fo); |
| 381 | } |
| 382 | } |
| 383 | |
| 384 | return lb.toList(); |
| 385 | } |
| 386 | |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 387 | private Location getLocation(String packageName) throws IOException { |
| 388 | if (location == StandardLocation.MODULE_SOURCE_PATH) { |
| 389 | // TODO: handle invalid results |
Kumar Srinivasan | 2814387 | 2016-07-20 12:49:32 -0700 | [diff] [blame] | 390 | Name pack = names.fromString(packageName); |
| 391 | |
| 392 | for (ModuleSymbol msym : modules.allModules()) { |
| 393 | PackageSymbol p = syms.getPackage(msym, pack); |
| 394 | if (p != null && !p.members().isEmpty()) { |
Jonathan Gibbons | c7374cd | 2016-11-16 12:12:02 -0800 | [diff] [blame] | 395 | return fm.getLocationForModule(location, msym.name.toString()); |
Kumar Srinivasan | 2814387 | 2016-07-20 12:49:32 -0700 | [diff] [blame] | 396 | } |
| 397 | } |
| 398 | |
| 399 | return null; |
Alan Bateman | 001ebb3 | 2016-03-17 19:04:28 +0000 | [diff] [blame] | 400 | } else { |
| 401 | return location; |
| 402 | } |
| 403 | } |
Jonathan Gibbons | 966fc67 | 2015-08-10 12:27:29 -0700 | [diff] [blame] | 404 | |
| 405 | private Entry getEntry(String name) { |
| 406 | Entry e = entries.get(name); |
| 407 | if (e == null) |
| 408 | entries.put(name, e = new Entry(name)); |
| 409 | return e; |
| 410 | } |
| 411 | |
| 412 | private String getPackageName(String name) { |
| 413 | int lastDot = name.lastIndexOf("."); |
| 414 | return (lastDot == -1 ? "" : name.substring(0, lastDot)); |
| 415 | } |
| 416 | |
| 417 | private String getSimpleName(String name) { |
| 418 | int lastDot = name.lastIndexOf("."); |
| 419 | return (lastDot == -1 ? name : name.substring(lastDot + 1)); |
| 420 | } |
| 421 | |
| 422 | class Entry { |
| 423 | final String name; |
| 424 | Boolean excluded; |
| 425 | List<JavaFileObject> files; |
| 426 | |
| 427 | Entry(String name) { |
| 428 | this.name = name; |
| 429 | } |
| 430 | |
| 431 | boolean isExcluded() { |
| 432 | if (excluded == null) |
| 433 | excluded = getEntry(getPackageName(name)).isExcluded(); |
| 434 | return excluded; |
| 435 | } |
| 436 | } |
| 437 | } |
| 438 | |
J. Duke | f57b87e | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 439 | } |