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

Sat, 07 Nov 2020 10:30:02 +0800

author
aoqi
date
Sat, 07 Nov 2020 10:30:02 +0800
changeset 3938
93012e2a5d1d
parent 3446
e468915bad3a
permissions
-rw-r--r--

Added tag mips-jdk8u275-b01 for changeset eb6ee6a5f2fe

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

mercurial