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

Mon, 18 Jul 2016 23:53:12 +0300

author
aefimov
date
Mon, 18 Jul 2016 23:53:12 +0300
changeset 3315
6f0746b6de9f
parent 1490
fc4cb1577ad6
child 3446
e468915bad3a
permissions
-rw-r--r--

8138725: Add options for Javadoc generation
Reviewed-by: jjg

duke@1 1 /*
aefimov@3315 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. 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
ohair@554 7 * published by the Free Software Foundation. Oracle designates this
duke@1 8 * particular file as subject to the "Classpath" exception as provided
ohair@554 9 * by Oracle 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 *
ohair@554 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554 22 * or visit www.oracle.com if you need additional information or have any
ohair@554 23 * questions.
duke@1 24 */
duke@1 25
duke@1 26 package com.sun.tools.javadoc;
duke@1 27
jjg@911 28 import java.io.DataInputStream;
jjg@1357 29 import java.io.IOException;
duke@1 30 import java.io.InputStream;
duke@1 31 import java.text.CollationKey;
jjg@1357 32 import java.util.regex.Matcher;
jjg@1357 33 import java.util.regex.Pattern;
jjg@1357 34
jjg@197 35 import javax.tools.FileObject;
jjg@197 36
jjg@197 37 import com.sun.javadoc.*;
jjg@1443 38 import com.sun.source.util.TreePath;
aefimov@3315 39 import com.sun.tools.doclets.internal.toolkit.util.FatalError;
jjg@1443 40 import com.sun.tools.javac.tree.JCTree;
jjg@1443 41 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
duke@1 42 import com.sun.tools.javac.util.Position;
duke@1 43
duke@1 44 /**
duke@1 45 * abstract base class of all Doc classes. Doc item's are representations
duke@1 46 * of java language constructs (class, package, method,...) which have
duke@1 47 * comments and have been processed by this run of javadoc. All Doc items
duke@1 48 * are unique, that is, they are == comparable.
duke@1 49 *
jjg@1359 50 * <p><b>This is NOT part of any supported API.
jjg@1359 51 * If you write code that depends on this, you do so at your own risk.
jjg@1359 52 * This code and its internal interfaces are subject to change or
jjg@1359 53 * deletion without notice.</b>
jjg@1359 54 *
duke@1 55 * @since 1.2
duke@1 56 * @author Robert Field
duke@1 57 * @author Atul M Dambalkar
duke@1 58 * @author Neal Gafter (rewrite)
duke@1 59 */
jjg@197 60 public abstract class DocImpl implements Doc, Comparable<Object> {
duke@1 61
duke@1 62 /**
duke@1 63 * Doc environment
duke@1 64 */
duke@1 65 protected final DocEnv env; //### Rename this everywhere to 'docenv' ?
duke@1 66
duke@1 67 /**
jjg@1443 68 * Back pointer to the tree node for this doc item.
jjg@1443 69 * May be null if there is no associated tree.
jjg@1443 70 */
jjg@1443 71 protected TreePath treePath;
jjg@1443 72
jjg@1443 73 /**
duke@1 74 * The complex comment object, lazily initialized.
duke@1 75 */
duke@1 76 private Comment comment;
duke@1 77
duke@1 78 /**
duke@1 79 * The cached sort key, to take care of Natural Language Text sorting.
duke@1 80 */
duke@1 81 private CollationKey collationkey = null;
duke@1 82
duke@1 83 /**
duke@1 84 * Raw documentation string.
duke@1 85 */
duke@1 86 protected String documentation; // Accessed in PackageDocImpl, RootDocImpl
duke@1 87
duke@1 88 /**
duke@1 89 * Cached first sentence.
duke@1 90 */
duke@1 91 private Tag[] firstSentence;
duke@1 92
duke@1 93 /**
duke@1 94 * Cached inline tags.
duke@1 95 */
duke@1 96 private Tag[] inlineTags;
duke@1 97
duke@1 98 /**
duke@1 99 * Constructor.
duke@1 100 */
jjg@1443 101 DocImpl(DocEnv env, TreePath treePath) {
jjg@1443 102 this.treePath = treePath;
jjg@1443 103 this.documentation = getCommentText(treePath);
duke@1 104 this.env = env;
duke@1 105 }
duke@1 106
jjg@1443 107 private static String getCommentText(TreePath p) {
jjg@1443 108 if (p == null)
jjg@1443 109 return null;
jjg@1443 110
jjg@1443 111 JCCompilationUnit topLevel = (JCCompilationUnit) p.getCompilationUnit();
jjg@1443 112 JCTree tree = (JCTree) p.getLeaf();
jjg@1443 113 return topLevel.docComments.getCommentText(tree);
jjg@1443 114 }
jjg@1443 115
duke@1 116 /**
duke@1 117 * So subclasses have the option to do lazy initialization of
duke@1 118 * "documentation" string.
duke@1 119 */
ksrini@1051 120 protected String documentation() {
duke@1 121 if (documentation == null) documentation = "";
duke@1 122 return documentation;
duke@1 123 }
duke@1 124
duke@1 125 /**
duke@1 126 * For lazy initialization of comment.
duke@1 127 */
duke@1 128 Comment comment() {
duke@1 129 if (comment == null) {
jjg@1490 130 String d = documentation();
aefimov@3315 131 if (env.javaScriptScanner != null) {
aefimov@3315 132 env.javaScriptScanner.parse(d, new JavaScriptScanner.Reporter() {
aefimov@3315 133 @Override
aefimov@3315 134 public void report() {
aefimov@3315 135 env.error(DocImpl.this, "javadoc.JavaScript_in_comment");
aefimov@3315 136 throw new FatalError();
aefimov@3315 137 }
aefimov@3315 138 });
aefimov@3315 139 }
jjg@1490 140 if (env.doclint != null
jjg@1490 141 && treePath != null
jjg@1490 142 && d.equals(getCommentText(treePath))) {
jjg@1490 143 env.doclint.scan(treePath);
jjg@1490 144 }
jjg@1490 145 comment = new Comment(this, d);
duke@1 146 }
duke@1 147 return comment;
duke@1 148 }
duke@1 149
duke@1 150 /**
duke@1 151 * Return the text of the comment for this doc item.
duke@1 152 * TagImpls have been removed.
duke@1 153 */
duke@1 154 public String commentText() {
duke@1 155 return comment().commentText();
duke@1 156 }
duke@1 157
duke@1 158 /**
duke@1 159 * Return all tags in this Doc item.
duke@1 160 *
duke@1 161 * @return an array of TagImpl containing all tags on this Doc item.
duke@1 162 */
duke@1 163 public Tag[] tags() {
duke@1 164 return comment().tags();
duke@1 165 }
duke@1 166
duke@1 167 /**
duke@1 168 * Return tags of the specified kind in this Doc item.
duke@1 169 *
duke@1 170 * @param tagname name of the tag kind to search for.
duke@1 171 * @return an array of TagImpl containing all tags whose 'kind()'
duke@1 172 * matches 'tagname'.
duke@1 173 */
duke@1 174 public Tag[] tags(String tagname) {
duke@1 175 return comment().tags(tagname);
duke@1 176 }
duke@1 177
duke@1 178 /**
duke@1 179 * Return the see also tags in this Doc item.
duke@1 180 *
jjg@1326 181 * @return an array of SeeTag containing all &#64;see tags.
duke@1 182 */
duke@1 183 public SeeTag[] seeTags() {
duke@1 184 return comment().seeTags();
duke@1 185 }
duke@1 186
duke@1 187 public Tag[] inlineTags() {
duke@1 188 if (inlineTags == null) {
duke@1 189 inlineTags = Comment.getInlineTags(this, commentText());
duke@1 190 }
duke@1 191 return inlineTags;
duke@1 192 }
duke@1 193
duke@1 194 public Tag[] firstSentenceTags() {
duke@1 195 if (firstSentence == null) {
duke@1 196 //Parse all sentences first to avoid duplicate warnings.
duke@1 197 inlineTags();
duke@1 198 try {
duke@1 199 env.setSilent(true);
duke@1 200 firstSentence = Comment.firstSentenceTags(this, commentText());
duke@1 201 } finally {
duke@1 202 env.setSilent(false);
duke@1 203 }
duke@1 204 }
duke@1 205 return firstSentence;
duke@1 206 }
duke@1 207
duke@1 208 /**
duke@1 209 * Utility for subclasses which read HTML documentation files.
duke@1 210 */
jjg@197 211 String readHTMLDocumentation(InputStream input, FileObject filename) throws IOException {
jjg@911 212 byte[] filecontents = new byte[input.available()];
jjg@911 213 try {
jjg@911 214 DataInputStream dataIn = new DataInputStream(input);
jjg@911 215 dataIn.readFully(filecontents);
jjg@911 216 } finally {
jjg@911 217 input.close();
jjg@911 218 }
duke@1 219 String encoding = env.getEncoding();
duke@1 220 String rawDoc = (encoding!=null)
duke@1 221 ? new String(filecontents, encoding)
duke@1 222 : new String(filecontents);
jjg@911 223 Pattern bodyPat = Pattern.compile("(?is).*<body\\b[^>]*>(.*)</body\\b.*");
jjg@911 224 Matcher m = bodyPat.matcher(rawDoc);
jjg@911 225 if (m.matches()) {
jjg@911 226 return m.group(1);
jjg@911 227 } else {
jjg@911 228 String key = rawDoc.matches("(?is).*<body\\b.*")
jjg@911 229 ? "javadoc.End_body_missing_from_html_file"
jjg@911 230 : "javadoc.Body_missing_from_html_file";
jjg@911 231 env.error(SourcePositionImpl.make(filename, Position.NOPOS, null), key);
duke@1 232 return "";
duke@1 233 }
duke@1 234 }
duke@1 235
duke@1 236 /**
duke@1 237 * Return the full unprocessed text of the comment. Tags
duke@1 238 * are included as text. Used mainly for store and retrieve
duke@1 239 * operations like internalization.
duke@1 240 */
duke@1 241 public String getRawCommentText() {
duke@1 242 return documentation();
duke@1 243 }
duke@1 244
duke@1 245 /**
duke@1 246 * Set the full unprocessed text of the comment. Tags
duke@1 247 * are included as text. Used mainly for store and retrieve
duke@1 248 * operations like internalization.
duke@1 249 */
duke@1 250 public void setRawCommentText(String rawDocumentation) {
jjg@1443 251 treePath = null;
duke@1 252 documentation = rawDocumentation;
duke@1 253 comment = null;
duke@1 254 }
duke@1 255
duke@1 256 /**
jjg@1443 257 * Set the full unprocessed text of the comment and tree path.
jjg@1443 258 */
jjg@1443 259 void setTreePath(TreePath treePath) {
jjg@1443 260 this.treePath = treePath;
jjg@1443 261 documentation = getCommentText(treePath);
jjg@1443 262 comment = null;
jjg@1443 263 }
jjg@1443 264
jjg@1443 265 /**
duke@1 266 * return a key for sorting.
duke@1 267 */
duke@1 268 CollationKey key() {
duke@1 269 if (collationkey == null) {
duke@1 270 collationkey = generateKey();
duke@1 271 }
duke@1 272 return collationkey;
duke@1 273 }
duke@1 274
duke@1 275 /**
duke@1 276 * Generate a key for sorting.
duke@1 277 * <p>
duke@1 278 * Default is name().
duke@1 279 */
duke@1 280 CollationKey generateKey() {
duke@1 281 String k = name();
duke@1 282 // System.out.println("COLLATION KEY FOR " + this + " is \"" + k + "\"");
duke@1 283 return env.doclocale.collator.getCollationKey(k);
duke@1 284 }
duke@1 285
duke@1 286 /**
duke@1 287 * Returns a string representation of this Doc item.
duke@1 288 */
jjg@911 289 @Override
duke@1 290 public String toString() {
duke@1 291 return qualifiedName();
duke@1 292 }
duke@1 293
duke@1 294 /**
duke@1 295 * Returns the name of this Doc item.
duke@1 296 *
duke@1 297 * @return the name
duke@1 298 */
duke@1 299 public abstract String name();
duke@1 300
duke@1 301 /**
duke@1 302 * Returns the qualified name of this Doc item.
duke@1 303 *
duke@1 304 * @return the name
duke@1 305 */
duke@1 306 public abstract String qualifiedName();
duke@1 307
duke@1 308 /**
duke@1 309 * Compares this Object with the specified Object for order. Returns a
duke@1 310 * negative integer, zero, or a positive integer as this Object is less
duke@1 311 * than, equal to, or greater than the given Object.
duke@1 312 * <p>
duke@1 313 * Included so that Doc item are java.lang.Comparable.
duke@1 314 *
jjg@1358 315 * @param obj the {@code Object} to be compared.
duke@1 316 * @return a negative integer, zero, or a positive integer as this Object
duke@1 317 * is less than, equal to, or greater than the given Object.
duke@1 318 * @exception ClassCastException the specified Object's type prevents it
duke@1 319 * from being compared to this Object.
duke@1 320 */
duke@1 321 public int compareTo(Object obj) {
duke@1 322 // System.out.println("COMPARE \"" + this + "\" to \"" + obj + "\" = " + key().compareTo(((DocImpl)obj).key()));
duke@1 323 return key().compareTo(((DocImpl)obj).key());
duke@1 324 }
duke@1 325
duke@1 326 /**
duke@1 327 * Is this Doc item a field? False until overridden.
duke@1 328 *
duke@1 329 * @return true if it represents a field
duke@1 330 */
duke@1 331 public boolean isField() {
duke@1 332 return false;
duke@1 333 }
duke@1 334
duke@1 335 /**
duke@1 336 * Is this Doc item an enum constant? False until overridden.
duke@1 337 *
duke@1 338 * @return true if it represents an enum constant
duke@1 339 */
duke@1 340 public boolean isEnumConstant() {
duke@1 341 return false;
duke@1 342 }
duke@1 343
duke@1 344 /**
duke@1 345 * Is this Doc item a constructor? False until overridden.
duke@1 346 *
duke@1 347 * @return true if it represents a constructor
duke@1 348 */
duke@1 349 public boolean isConstructor() {
duke@1 350 return false;
duke@1 351 }
duke@1 352
duke@1 353 /**
duke@1 354 * Is this Doc item a method (but not a constructor or annotation
duke@1 355 * type element)?
duke@1 356 * False until overridden.
duke@1 357 *
duke@1 358 * @return true if it represents a method
duke@1 359 */
duke@1 360 public boolean isMethod() {
duke@1 361 return false;
duke@1 362 }
duke@1 363
duke@1 364 /**
duke@1 365 * Is this Doc item an annotation type element?
duke@1 366 * False until overridden.
duke@1 367 *
duke@1 368 * @return true if it represents an annotation type element
duke@1 369 */
duke@1 370 public boolean isAnnotationTypeElement() {
duke@1 371 return false;
duke@1 372 }
duke@1 373
duke@1 374 /**
duke@1 375 * Is this Doc item a interface (but not an annotation type)?
duke@1 376 * False until overridden.
duke@1 377 *
duke@1 378 * @return true if it represents a interface
duke@1 379 */
duke@1 380 public boolean isInterface() {
duke@1 381 return false;
duke@1 382 }
duke@1 383
duke@1 384 /**
duke@1 385 * Is this Doc item a exception class? False until overridden.
duke@1 386 *
duke@1 387 * @return true if it represents a exception
duke@1 388 */
duke@1 389 public boolean isException() {
duke@1 390 return false;
duke@1 391 }
duke@1 392
duke@1 393 /**
duke@1 394 * Is this Doc item a error class? False until overridden.
duke@1 395 *
duke@1 396 * @return true if it represents a error
duke@1 397 */
duke@1 398 public boolean isError() {
duke@1 399 return false;
duke@1 400 }
duke@1 401
duke@1 402 /**
duke@1 403 * Is this Doc item an enum type? False until overridden.
duke@1 404 *
duke@1 405 * @return true if it represents an enum type
duke@1 406 */
duke@1 407 public boolean isEnum() {
duke@1 408 return false;
duke@1 409 }
duke@1 410
duke@1 411 /**
duke@1 412 * Is this Doc item an annotation type? False until overridden.
duke@1 413 *
duke@1 414 * @return true if it represents an annotation type
duke@1 415 */
duke@1 416 public boolean isAnnotationType() {
duke@1 417 return false;
duke@1 418 }
duke@1 419
duke@1 420 /**
duke@1 421 * Is this Doc item an ordinary class (i.e. not an interface,
duke@1 422 * annotation type, enumeration, exception, or error)?
duke@1 423 * False until overridden.
duke@1 424 *
duke@1 425 * @return true if it represents an ordinary class
duke@1 426 */
duke@1 427 public boolean isOrdinaryClass() {
duke@1 428 return false;
duke@1 429 }
duke@1 430
duke@1 431 /**
duke@1 432 * Is this Doc item a class
duke@1 433 * (and not an interface or annotation type)?
duke@1 434 * This includes ordinary classes, enums, errors and exceptions.
duke@1 435 * False until overridden.
duke@1 436 *
duke@1 437 * @return true if it represents a class
duke@1 438 */
duke@1 439 public boolean isClass() {
duke@1 440 return false;
duke@1 441 }
duke@1 442
duke@1 443 /**
duke@1 444 * return true if this Doc is include in the active set.
duke@1 445 */
duke@1 446 public abstract boolean isIncluded();
duke@1 447
duke@1 448 /**
duke@1 449 * Return the source position of the entity, or null if
duke@1 450 * no position is available.
duke@1 451 */
duke@1 452 public SourcePosition position() { return null; }
duke@1 453 }

mercurial