src/share/classes/com/sun/tools/javadoc/PackageDocImpl.java

Tue, 04 Mar 2008 15:45:20 +0000

author
mcimadamore
date
Tue, 04 Mar 2008 15:45:20 +0000
changeset 8
38bd6375f37d
parent 1
9a66ca7c79fa
child 197
1bf037016426
permissions
-rw-r--r--

6663588: Compiler goes into infinite loop for Cyclic Inheritance test case
Summary: interplay between cyclic inheritance and tvar bounds hangs javac
Reviewed-by: jjg

duke@1 1 /*
duke@1 2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
duke@1 7 * published by the Free Software Foundation. Sun designates this
duke@1 8 * particular file as subject to the "Classpath" exception as provided
duke@1 9 * by Sun in the LICENSE file that accompanied this code.
duke@1 10 *
duke@1 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 15 * accompanied this code).
duke@1 16 *
duke@1 17 * You should have received a copy of the GNU General Public License version
duke@1 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 20 *
duke@1 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@1 22 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@1 23 * have any questions.
duke@1 24 */
duke@1 25
duke@1 26 package com.sun.tools.javadoc;
duke@1 27
duke@1 28 import com.sun.javadoc.*;
duke@1 29
duke@1 30 import java.io.File;
duke@1 31 import java.io.InputStream;
duke@1 32 import java.io.FileInputStream;
duke@1 33 import java.io.IOException;
duke@1 34 import java.util.zip.ZipFile;
duke@1 35 import java.util.zip.ZipEntry;
duke@1 36
duke@1 37 import com.sun.tools.javac.code.Attribute;
duke@1 38 import com.sun.tools.javac.code.Scope;
duke@1 39 import com.sun.tools.javac.code.Symbol.ClassSymbol;
duke@1 40 import com.sun.tools.javac.code.Symbol.PackageSymbol;
duke@1 41 import com.sun.tools.javac.comp.AttrContext;
duke@1 42 import com.sun.tools.javac.comp.Env;
duke@1 43 import com.sun.tools.javac.tree.JCTree;
duke@1 44 import com.sun.tools.javac.util.List;
duke@1 45 import com.sun.tools.javac.util.ListBuffer;
duke@1 46 import com.sun.tools.javac.util.Name;
duke@1 47 import com.sun.tools.javac.util.Position;
duke@1 48
duke@1 49 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
duke@1 50
duke@1 51
duke@1 52 /**
duke@1 53 * Represents a java package. Provides access to information
duke@1 54 * about the package, the package's comment and tags, and the
duke@1 55 * classes in the package.
duke@1 56 *
duke@1 57 * @since 1.2
duke@1 58 * @author Kaiyang Liu (original)
duke@1 59 * @author Robert Field (rewrite)
duke@1 60 * @author Neal Gafter (rewrite)
duke@1 61 * @author Scott Seligman (package-info.java)
duke@1 62 */
duke@1 63
duke@1 64 public class PackageDocImpl extends DocImpl implements PackageDoc {
duke@1 65
duke@1 66 private static final String PACKAGE_HTML_FILE_NAME = "package.html";
duke@1 67
duke@1 68 protected PackageSymbol sym;
duke@1 69 private JCCompilationUnit tree = null; // for source position
duke@1 70
duke@1 71 public String docPath = null;
duke@1 72 public String zipDocPath = null;
duke@1 73 public String zipDocEntry = null;
duke@1 74 private boolean foundDoc; // found a doc comment in either
duke@1 75 // package.html or package-info.java
duke@1 76
duke@1 77 boolean isIncluded = false; // Set in RootDocImpl.
duke@1 78 public boolean setDocPath = false; //Flag to avoid setting doc path multiple times.
duke@1 79
duke@1 80 /**
duke@1 81 * Constructor
duke@1 82 */
duke@1 83 public PackageDocImpl(DocEnv env, PackageSymbol sym) {
duke@1 84 this(env, sym, null, null);
duke@1 85 }
duke@1 86
duke@1 87 /**
duke@1 88 * Constructor
duke@1 89 */
duke@1 90 public PackageDocImpl(DocEnv env, PackageSymbol sym,
duke@1 91 String documentation, JCTree tree) {
duke@1 92 super(env, documentation);
duke@1 93 this.sym = sym;
duke@1 94 this.tree = (JCCompilationUnit) tree;
duke@1 95 foundDoc = (documentation != null);
duke@1 96 }
duke@1 97
duke@1 98 void setTree(JCTree tree) {
duke@1 99 this.tree = (JCCompilationUnit) tree;
duke@1 100 }
duke@1 101
duke@1 102 public void setRawCommentText(String rawDocumentation) {
duke@1 103 super.setRawCommentText(rawDocumentation);
duke@1 104 checkDoc();
duke@1 105 }
duke@1 106
duke@1 107 /**
duke@1 108 * Do lazy initialization of "documentation" string.
duke@1 109 */
duke@1 110 String documentation() {
duke@1 111 if (documentation != null) return documentation;
duke@1 112 if (zipDocPath != null) {
duke@1 113 try {
duke@1 114 ZipFile f = new ZipFile(zipDocPath);
duke@1 115 ZipEntry entry = f.getEntry(zipDocEntry);
duke@1 116 if (entry != null) {
duke@1 117 InputStream s = f.getInputStream(entry);
duke@1 118 return (documentation = readHTMLDocumentation(s,
duke@1 119 zipDocPath + File.separatorChar + zipDocEntry));
duke@1 120 }
duke@1 121 } catch (IOException exc) {
duke@1 122 documentation = "";
duke@1 123 env.error(null, "javadoc.File_Read_Error",
duke@1 124 zipDocPath + File.separatorChar + zipDocEntry);
duke@1 125 }
duke@1 126 }
duke@1 127 if (docPath != null) {
duke@1 128 // read from file
duke@1 129 try {
duke@1 130 InputStream s = new FileInputStream(docPath);
duke@1 131 documentation = readHTMLDocumentation(s, docPath);
duke@1 132 } catch (IOException exc) {
duke@1 133 documentation = "";
duke@1 134 env.error(null, "javadoc.File_Read_Error", docPath);
duke@1 135 }
duke@1 136 } else {
duke@1 137 // no doc file to be had
duke@1 138 documentation = "";
duke@1 139 }
duke@1 140 return documentation;
duke@1 141 }
duke@1 142
duke@1 143 /**
duke@1 144 * Cache of all classes contained in this package, including
duke@1 145 * member classes of those classes, and their member classes, etc.
duke@1 146 * Includes only those classes at the specified protection level
duke@1 147 * and weaker.
duke@1 148 */
duke@1 149 private List<ClassDocImpl> allClassesFiltered = null;
duke@1 150
duke@1 151 /**
duke@1 152 * Cache of all classes contained in this package, including
duke@1 153 * member classes of those classes, and their member classes, etc.
duke@1 154 */
duke@1 155 private List<ClassDocImpl> allClasses = null;
duke@1 156
duke@1 157 /**
duke@1 158 * Return a list of all classes contained in this package, including
duke@1 159 * member classes of those classes, and their member classes, etc.
duke@1 160 */
duke@1 161 private List<ClassDocImpl> getClasses(boolean filtered) {
duke@1 162 if (allClasses != null && !filtered) {
duke@1 163 return allClasses;
duke@1 164 }
duke@1 165 if (allClassesFiltered != null && filtered) {
duke@1 166 return allClassesFiltered;
duke@1 167 }
duke@1 168 ListBuffer<ClassDocImpl> classes = new ListBuffer<ClassDocImpl>();
duke@1 169 for (Scope.Entry e = sym.members().elems; e != null; e = e.sibling) {
duke@1 170 if (e.sym != null) {
duke@1 171 ClassSymbol s = (ClassSymbol)e.sym;
duke@1 172 ClassDocImpl c = env.getClassDoc(s);
duke@1 173 if (c != null && !c.isSynthetic())
duke@1 174 c.addAllClasses(classes, filtered);
duke@1 175 }
duke@1 176 }
duke@1 177 if (filtered)
duke@1 178 return allClassesFiltered = classes.toList();
duke@1 179 else
duke@1 180 return allClasses = classes.toList();
duke@1 181 }
duke@1 182
duke@1 183 /**
duke@1 184 * Add all included classes (including Exceptions and Errors)
duke@1 185 * and interfaces.
duke@1 186 */
duke@1 187 public void addAllClassesTo(ListBuffer<ClassDocImpl> list) {
duke@1 188 list.appendList(getClasses(true));
duke@1 189 }
duke@1 190
duke@1 191 /**
duke@1 192 * Get all classes (including Exceptions and Errors)
duke@1 193 * and interfaces.
duke@1 194 * @since J2SE1.4.
duke@1 195 *
duke@1 196 * @return all classes and interfaces in this package, filtered to include
duke@1 197 * only the included classes if filter==true.
duke@1 198 */
duke@1 199 public ClassDoc[] allClasses(boolean filter) {
duke@1 200 List<ClassDocImpl> classes = getClasses(filter);
duke@1 201 return classes.toArray(new ClassDocImpl[classes.length()]);
duke@1 202 }
duke@1 203
duke@1 204 /**
duke@1 205 * Get all included classes (including Exceptions and Errors)
duke@1 206 * and interfaces. Same as allClasses(true).
duke@1 207 *
duke@1 208 * @return all included classes and interfaces in this package.
duke@1 209 */
duke@1 210 public ClassDoc[] allClasses() {
duke@1 211 return allClasses(true);
duke@1 212 }
duke@1 213
duke@1 214 /**
duke@1 215 * Get ordinary classes (that is, exclude exceptions, errors,
duke@1 216 * enums, interfaces, and annotation types) in this package.
duke@1 217 *
duke@1 218 * @return included ordinary classes in this package.
duke@1 219 */
duke@1 220 public ClassDoc[] ordinaryClasses() {
duke@1 221 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
duke@1 222 for (ClassDocImpl c : getClasses(true)) {
duke@1 223 if (c.isOrdinaryClass()) {
duke@1 224 ret.append(c);
duke@1 225 }
duke@1 226 }
duke@1 227 return ret.toArray(new ClassDocImpl[ret.length()]);
duke@1 228 }
duke@1 229
duke@1 230 /**
duke@1 231 * Get Exception classes in this package.
duke@1 232 *
duke@1 233 * @return included Exceptions in this package.
duke@1 234 */
duke@1 235 public ClassDoc[] exceptions() {
duke@1 236 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
duke@1 237 for (ClassDocImpl c : getClasses(true)) {
duke@1 238 if (c.isException()) {
duke@1 239 ret.append(c);
duke@1 240 }
duke@1 241 }
duke@1 242 return ret.toArray(new ClassDocImpl[ret.length()]);
duke@1 243 }
duke@1 244
duke@1 245 /**
duke@1 246 * Get Error classes in this package.
duke@1 247 *
duke@1 248 * @return included Errors in this package.
duke@1 249 */
duke@1 250 public ClassDoc[] errors() {
duke@1 251 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
duke@1 252 for (ClassDocImpl c : getClasses(true)) {
duke@1 253 if (c.isError()) {
duke@1 254 ret.append(c);
duke@1 255 }
duke@1 256 }
duke@1 257 return ret.toArray(new ClassDocImpl[ret.length()]);
duke@1 258 }
duke@1 259
duke@1 260 /**
duke@1 261 * Get included enum types in this package.
duke@1 262 *
duke@1 263 * @return included enum types in this package.
duke@1 264 */
duke@1 265 public ClassDoc[] enums() {
duke@1 266 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
duke@1 267 for (ClassDocImpl c : getClasses(true)) {
duke@1 268 if (c.isEnum()) {
duke@1 269 ret.append(c);
duke@1 270 }
duke@1 271 }
duke@1 272 return ret.toArray(new ClassDocImpl[ret.length()]);
duke@1 273 }
duke@1 274
duke@1 275 /**
duke@1 276 * Get included interfaces in this package, omitting annotation types.
duke@1 277 *
duke@1 278 * @return included interfaces in this package.
duke@1 279 */
duke@1 280 public ClassDoc[] interfaces() {
duke@1 281 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
duke@1 282 for (ClassDocImpl c : getClasses(true)) {
duke@1 283 if (c.isInterface()) {
duke@1 284 ret.append(c);
duke@1 285 }
duke@1 286 }
duke@1 287 return ret.toArray(new ClassDocImpl[ret.length()]);
duke@1 288 }
duke@1 289
duke@1 290 /**
duke@1 291 * Get included annotation types in this package.
duke@1 292 *
duke@1 293 * @return included annotation types in this package.
duke@1 294 */
duke@1 295 public AnnotationTypeDoc[] annotationTypes() {
duke@1 296 ListBuffer<AnnotationTypeDocImpl> ret =
duke@1 297 new ListBuffer<AnnotationTypeDocImpl>();
duke@1 298 for (ClassDocImpl c : getClasses(true)) {
duke@1 299 if (c.isAnnotationType()) {
duke@1 300 ret.append((AnnotationTypeDocImpl)c);
duke@1 301 }
duke@1 302 }
duke@1 303 return ret.toArray(new AnnotationTypeDocImpl[ret.length()]);
duke@1 304 }
duke@1 305
duke@1 306 /**
duke@1 307 * Get the annotations of this package.
duke@1 308 * Return an empty array if there are none.
duke@1 309 */
duke@1 310 public AnnotationDesc[] annotations() {
duke@1 311 AnnotationDesc res[] = new AnnotationDesc[sym.getAnnotationMirrors().length()];
duke@1 312 int i = 0;
duke@1 313 for (Attribute.Compound a : sym.getAnnotationMirrors()) {
duke@1 314 res[i++] = new AnnotationDescImpl(env, a);
duke@1 315 }
duke@1 316 return res;
duke@1 317 }
duke@1 318
duke@1 319
duke@1 320 /**
duke@1 321 * Lookup for a class within this package.
duke@1 322 *
duke@1 323 * @return ClassDocImpl of found class, or null if not found.
duke@1 324 */
duke@1 325 public ClassDoc findClass(String className) {
duke@1 326 final boolean filtered = true;
duke@1 327 for (ClassDocImpl c : getClasses(filtered)) {
duke@1 328 if (c.name().equals(className)) {
duke@1 329 return c;
duke@1 330 }
duke@1 331 }
duke@1 332 return null;
duke@1 333 }
duke@1 334
duke@1 335 /**
duke@1 336 * Return true if this package is included in the active set.
duke@1 337 */
duke@1 338 public boolean isIncluded() {
duke@1 339 return isIncluded;
duke@1 340 }
duke@1 341
duke@1 342 /**
duke@1 343 * Get package name.
duke@1 344 *
duke@1 345 * Note that we do not provide a means of obtaining the simple
duke@1 346 * name of a package -- package names are always returned in their
duke@1 347 * uniquely qualified form.
duke@1 348 */
duke@1 349 public String name() {
duke@1 350 return qualifiedName();
duke@1 351 }
duke@1 352
duke@1 353 /**
duke@1 354 * Get package name.
duke@1 355 */
duke@1 356 public String qualifiedName() {
duke@1 357 Name fullname = sym.getQualifiedName();
duke@1 358 // Some bogus tests depend on the interned "" being returned.
duke@1 359 // See 6457276.
duke@1 360 return fullname.isEmpty() ? "" : fullname.toString();
duke@1 361 }
duke@1 362
duke@1 363 /**
duke@1 364 * set doc path for an unzipped directory
duke@1 365 */
duke@1 366 public void setDocPath(String path) {
duke@1 367 setDocPath = true;
duke@1 368 if (path == null)
duke@1 369 return;
duke@1 370 String newDocPath = path + File.separatorChar + PACKAGE_HTML_FILE_NAME;
duke@1 371 if (!newDocPath.equals(docPath)) {
duke@1 372 docPath = newDocPath;
duke@1 373 checkDoc();
duke@1 374 }
duke@1 375 }
duke@1 376
duke@1 377 /**
duke@1 378 * set the doc path for zipped directory
duke@1 379 */
duke@1 380 public void setDocPath(String path, String entry) {
duke@1 381 if (!path.equals(zipDocPath)) {
duke@1 382 zipDocPath = path;
duke@1 383 zipDocEntry = entry + PACKAGE_HTML_FILE_NAME;
duke@1 384 checkDoc();
duke@1 385 }
duke@1 386 }
duke@1 387
duke@1 388 // Has checkDoc() sounded off yet?
duke@1 389 private boolean checkDocWarningEmitted = false;
duke@1 390
duke@1 391 /**
duke@1 392 * Invoked when a source of package doc comments is located.
duke@1 393 * Emits a diagnostic if this is the second one.
duke@1 394 */
duke@1 395 private void checkDoc() {
duke@1 396 if (foundDoc) {
duke@1 397 if (!checkDocWarningEmitted) {
duke@1 398 env.warning(null, "javadoc.Multiple_package_comments", name());
duke@1 399 checkDocWarningEmitted = true;
duke@1 400 }
duke@1 401 } else {
duke@1 402 foundDoc = true;
duke@1 403 }
duke@1 404 }
duke@1 405
duke@1 406 /**
duke@1 407 * Return the source position of the entity, or null if
duke@1 408 * no position is available.
duke@1 409 */
duke@1 410 public SourcePosition position() {
duke@1 411 return (tree != null)
duke@1 412 ? SourcePositionImpl.make(tree.sourcefile + "", tree.pos, tree.lineMap)
duke@1 413 : SourcePositionImpl.make(docPath, Position.NOPOS, null);
duke@1 414 }
duke@1 415 }

mercurial