1 /* 2 * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. 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 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 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 * 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. 24 */ 25 26 package com.sun.tools.javadoc.main; 27 28 import java.lang.reflect.Modifier; 29 import java.util.*; 30 31 import javax.tools.JavaFileManager; 32 33 import com.sun.javadoc.*; 34 import com.sun.source.tree.CompilationUnitTree; 35 import com.sun.source.util.JavacTask; 36 import com.sun.source.util.TreePath; 37 import com.sun.tools.doclint.DocLint; 38 import com.sun.tools.javac.api.BasicJavacTask; 39 import com.sun.tools.javac.code.*; 40 import com.sun.tools.javac.code.Symbol.*; 41 import com.sun.tools.javac.code.Symbol.ClassSymbol; 42 import com.sun.tools.javac.code.Symbol.CompletionFailure; 43 import com.sun.tools.javac.code.Symbol.MethodSymbol; 44 import com.sun.tools.javac.code.Symbol.PackageSymbol; 45 import com.sun.tools.javac.code.Symbol.VarSymbol; 46 import com.sun.tools.javac.code.Type.ClassType; 47 import com.sun.tools.javac.comp.Check; 48 import com.sun.tools.javac.comp.Enter; 49 import com.sun.tools.javac.file.JavacFileManager; 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.tree.JCTree.JCPackageDecl; 54 import com.sun.tools.javac.util.Context; 55 import com.sun.tools.javac.util.Convert; 56 import com.sun.tools.javac.util.Name; 57 import com.sun.tools.javac.util.Names; 58 59 /** 60 * Holds the environment for a run of javadoc. 61 * Holds only the information needed throughout the 62 * run and not the compiler info that could be GC'ed 63 * or ported. 64 * 65 * <p><b>This is NOT part of any supported API. 66 * If you write code that depends on this, you do so at your own risk. 67 * This code and its internal interfaces are subject to change or 68 * deletion without notice.</b> 69 * 70 * @since 1.4 71 * @author Robert Field 72 * @author Neal Gafter (rewrite) 73 * @author Scott Seligman (generics) 74 */ 75 @Deprecated(since="9", forRemoval=true) 76 @SuppressWarnings("removal") 77 public class DocEnv { 78 protected static final Context.Key<DocEnv> docEnvKey = new Context.Key<>(); 79 instance(Context context)80 public static DocEnv instance(Context context) { 81 DocEnv instance = context.get(docEnvKey); 82 if (instance == null) 83 instance = new DocEnv(context); 84 return instance; 85 } 86 87 DocLocale doclocale; 88 89 private final Messager messager; 90 91 /** Predefined symbols known to the compiler. */ 92 final Symtab syms; 93 94 /** Referenced directly in RootDocImpl. */ 95 private final ClassFinder finder; 96 97 /** Javadoc's own version of the compiler's enter phase. */ 98 final Enter enter; 99 100 /** The name table. */ 101 private final Names names; 102 103 /** The encoding name. */ 104 private String encoding; 105 106 final Symbol externalizableSym; 107 108 /** Access filter (public, protected, ...). */ 109 protected ModifierFilter showAccess; 110 111 /** True if we are using a sentence BreakIterator. */ 112 boolean breakiterator; 113 114 /** 115 * True if we do not want to print any notifications at all. 116 */ 117 boolean quiet = false; 118 119 Check chk; 120 Types types; 121 JavaFileManager fileManager; 122 Context context; 123 DocLint doclint; 124 JavaScriptScanner javaScriptScanner; 125 126 WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>(); 127 128 /** Allow documenting from class files? */ 129 boolean docClasses = false; 130 131 /** Does the doclet only expect pre-1.5 doclet API? */ 132 protected boolean legacyDoclet = true; 133 134 /** 135 * Set this to true if you would like to not emit any errors, warnings and 136 * notices. 137 */ 138 private boolean silent = false; 139 140 /** 141 * The source language version. 142 */ 143 protected Source source; 144 145 /** 146 * Constructor 147 * 148 * @param context Context for this javadoc instance. 149 */ DocEnv(Context context)150 protected DocEnv(Context context) { 151 context.put(docEnvKey, this); 152 this.context = context; 153 154 messager = Messager.instance0(context); 155 syms = Symtab.instance(context); 156 finder = JavadocClassFinder.instance(context); 157 enter = JavadocEnter.instance(context); 158 names = Names.instance(context); 159 externalizableSym = syms.enterClass(syms.java_base, names.fromString("java.io.Externalizable")); 160 chk = Check.instance(context); 161 types = Types.instance(context); 162 fileManager = context.get(JavaFileManager.class); 163 if (fileManager instanceof JavacFileManager) { 164 ((JavacFileManager)fileManager).setSymbolFileEnabled(false); 165 } 166 167 // Default. Should normally be reset with setLocale. 168 this.doclocale = new DocLocale(this, "", breakiterator); 169 source = Source.instance(context); 170 } 171 setSilent(boolean silent)172 public void setSilent(boolean silent) { 173 this.silent = silent; 174 } 175 176 /** 177 * Look up ClassDoc by qualified name. 178 */ lookupClass(String name)179 public ClassDocImpl lookupClass(String name) { 180 ClassSymbol c = getClassSymbol(name); 181 if (c != null) { 182 return getClassDoc(c); 183 } else { 184 return null; 185 } 186 } 187 188 /** 189 * Load ClassDoc by qualified name. 190 */ loadClass(String name)191 public ClassDocImpl loadClass(String name) { 192 try { 193 Name nameImpl = names.fromString(name); 194 ModuleSymbol mod = syms.inferModule(Convert.packagePart(nameImpl)); 195 ClassSymbol c = finder.loadClass(mod != null ? mod : syms.errModule, nameImpl); 196 return getClassDoc(c); 197 } catch (CompletionFailure ex) { 198 chk.completionError(null, ex); 199 return null; 200 } 201 } 202 203 /** 204 * Look up PackageDoc by qualified name. 205 */ lookupPackage(String name)206 public PackageDocImpl lookupPackage(String name) { 207 //### Jing alleges that class check is needed 208 //### to avoid a compiler bug. Most likely 209 //### instead a dummy created for error recovery. 210 //### Should investigate this. 211 Name nameImpl = names.fromString(name); 212 ModuleSymbol mod = syms.inferModule(nameImpl); 213 PackageSymbol p = mod != null ? syms.getPackage(mod, nameImpl) : null; 214 ClassSymbol c = getClassSymbol(name); 215 if (p != null && c == null) { 216 return getPackageDoc(p); 217 } else { 218 return null; 219 } 220 } 221 // where 222 /** Retrieve class symbol by fully-qualified name. 223 */ getClassSymbol(String name)224 ClassSymbol getClassSymbol(String name) { 225 // Name may contain nested class qualification. 226 // Generate candidate flatnames with successively shorter 227 // package qualifiers and longer nested class qualifiers. 228 int nameLen = name.length(); 229 char[] nameChars = name.toCharArray(); 230 int idx = name.length(); 231 for (;;) { 232 Name nameImpl = names.fromChars(nameChars, 0, nameLen); 233 ModuleSymbol mod = syms.inferModule(Convert.packagePart(nameImpl)); 234 ClassSymbol s = mod != null ? syms.getClass(mod, nameImpl) : null; 235 if (s != null) 236 return s; // found it! 237 idx = name.substring(0, idx).lastIndexOf('.'); 238 if (idx < 0) break; 239 nameChars[idx] = '$'; 240 } 241 return null; 242 } 243 244 /** 245 * Set the locale. 246 */ setLocale(String localeName)247 public void setLocale(String localeName) { 248 // create locale specifics 249 doclocale = new DocLocale(this, localeName, breakiterator); 250 // update Messager if locale has changed. 251 messager.setLocale(doclocale.locale); 252 } 253 254 /** Check whether this member should be documented. */ shouldDocument(VarSymbol sym)255 public boolean shouldDocument(VarSymbol sym) { 256 long mod = sym.flags(); 257 258 if ((mod & Flags.SYNTHETIC) != 0) { 259 return false; 260 } 261 262 return showAccess.checkModifier(translateModifiers(mod)); 263 } 264 265 /** Check whether this member should be documented. */ shouldDocument(MethodSymbol sym)266 public boolean shouldDocument(MethodSymbol sym) { 267 long mod = sym.flags(); 268 269 if ((mod & Flags.SYNTHETIC) != 0) { 270 return false; 271 } 272 273 return showAccess.checkModifier(translateModifiers(mod)); 274 } 275 276 /** check whether this class should be documented. */ shouldDocument(ClassSymbol sym)277 public boolean shouldDocument(ClassSymbol sym) { 278 return 279 (sym.flags_field&Flags.SYNTHETIC) == 0 && // no synthetics 280 (docClasses || getClassDoc(sym).tree != null) && 281 isVisible(sym); 282 } 283 284 //### Comment below is inaccurate wrt modifier filter testing 285 /** 286 * Check the visibility if this is an nested class. 287 * if this is not a nested class, return true. 288 * if this is an static visible nested class, 289 * return true. 290 * if this is an visible nested class 291 * if the outer class is visible return true. 292 * else return false. 293 * IMPORTANT: This also allows, static nested classes 294 * to be defined inside an nested class, which is not 295 * allowed by the compiler. So such an test case will 296 * not reach upto this method itself, but if compiler 297 * allows it, then that will go through. 298 */ isVisible(ClassSymbol sym)299 protected boolean isVisible(ClassSymbol sym) { 300 long mod = sym.flags_field; 301 if (!showAccess.checkModifier(translateModifiers(mod))) { 302 return false; 303 } 304 ClassSymbol encl = sym.owner.enclClass(); 305 return (encl == null || (mod & Flags.STATIC) != 0 || isVisible(encl)); 306 } 307 308 //---------------- print forwarders ----------------// 309 310 /** 311 * Print error message, increment error count. 312 * 313 * @param msg message to print. 314 */ printError(String msg)315 public void printError(String msg) { 316 if (silent) 317 return; 318 messager.printError(msg); 319 } 320 321 /** 322 * Print error message, increment error count. 323 * 324 * @param key selects message from resource 325 */ error(DocImpl doc, String key)326 public void error(DocImpl doc, String key) { 327 if (silent) 328 return; 329 messager.error(doc==null ? null : doc.position(), key); 330 } 331 332 /** 333 * Print error message, increment error count. 334 * 335 * @param key selects message from resource 336 */ error(SourcePosition pos, String key)337 public void error(SourcePosition pos, String key) { 338 if (silent) 339 return; 340 messager.error(pos, key); 341 } 342 343 /** 344 * Print error message, increment error count. 345 * 346 * @param msg message to print. 347 */ printError(SourcePosition pos, String msg)348 public void printError(SourcePosition pos, String msg) { 349 if (silent) 350 return; 351 messager.printError(pos, msg); 352 } 353 354 /** 355 * Print error message, increment error count. 356 * 357 * @param key selects message from resource 358 * @param a1 first argument 359 */ error(DocImpl doc, String key, String a1)360 public void error(DocImpl doc, String key, String a1) { 361 if (silent) 362 return; 363 messager.error(doc==null ? null : doc.position(), key, a1); 364 } 365 366 /** 367 * Print error message, increment error count. 368 * 369 * @param key selects message from resource 370 * @param a1 first argument 371 * @param a2 second argument 372 */ error(DocImpl doc, String key, String a1, String a2)373 public void error(DocImpl doc, String key, String a1, String a2) { 374 if (silent) 375 return; 376 messager.error(doc==null ? null : doc.position(), key, a1, a2); 377 } 378 379 /** 380 * Print error message, increment error count. 381 * 382 * @param key selects message from resource 383 * @param a1 first argument 384 * @param a2 second argument 385 * @param a3 third argument 386 */ error(DocImpl doc, String key, String a1, String a2, String a3)387 public void error(DocImpl doc, String key, String a1, String a2, String a3) { 388 if (silent) 389 return; 390 messager.error(doc==null ? null : doc.position(), key, a1, a2, a3); 391 } 392 393 /** 394 * Print warning message, increment warning count. 395 * 396 * @param msg message to print. 397 */ printWarning(String msg)398 public void printWarning(String msg) { 399 if (silent) 400 return; 401 messager.printWarning(msg); 402 } 403 404 /** 405 * Print warning message, increment warning count. 406 * 407 * @param key selects message from resource 408 */ warning(DocImpl doc, String key)409 public void warning(DocImpl doc, String key) { 410 if (silent) 411 return; 412 messager.warning(doc==null ? null : doc.position(), key); 413 } 414 415 /** 416 * Print warning message, increment warning count. 417 * 418 * @param msg message to print. 419 */ printWarning(SourcePosition pos, String msg)420 public void printWarning(SourcePosition pos, String msg) { 421 if (silent) 422 return; 423 messager.printWarning(pos, msg); 424 } 425 426 /** 427 * Print warning message, increment warning count. 428 * 429 * @param key selects message from resource 430 * @param a1 first argument 431 */ warning(DocImpl doc, String key, String a1)432 public void warning(DocImpl doc, String key, String a1) { 433 if (silent) 434 return; 435 // suppress messages that have (probably) been covered by doclint 436 if (doclint != null && doc != null && key.startsWith("tag")) 437 return; 438 messager.warning(doc==null ? null : doc.position(), key, a1); 439 } 440 441 /** 442 * Print warning message, increment warning count. 443 * 444 * @param key selects message from resource 445 * @param a1 first argument 446 * @param a2 second argument 447 */ warning(DocImpl doc, String key, String a1, String a2)448 public void warning(DocImpl doc, String key, String a1, String a2) { 449 if (silent) 450 return; 451 messager.warning(doc==null ? null : doc.position(), key, a1, a2); 452 } 453 454 /** 455 * Print warning message, increment warning count. 456 * 457 * @param key selects message from resource 458 * @param a1 first argument 459 * @param a2 second argument 460 * @param a3 third argument 461 */ warning(DocImpl doc, String key, String a1, String a2, String a3)462 public void warning(DocImpl doc, String key, String a1, String a2, String a3) { 463 if (silent) 464 return; 465 messager.warning(doc==null ? null : doc.position(), key, a1, a2, a3); 466 } 467 468 /** 469 * Print warning message, increment warning count. 470 * 471 * @param key selects message from resource 472 * @param a1 first argument 473 * @param a2 second argument 474 * @param a3 third argument 475 */ warning(DocImpl doc, String key, String a1, String a2, String a3, String a4)476 public void warning(DocImpl doc, String key, String a1, String a2, String a3, 477 String a4) { 478 if (silent) 479 return; 480 messager.warning(doc==null ? null : doc.position(), key, a1, a2, a3, a4); 481 } 482 483 /** 484 * Print a message. 485 * 486 * @param msg message to print. 487 */ printNotice(String msg)488 public void printNotice(String msg) { 489 if (silent || quiet) 490 return; 491 messager.printNotice(msg); 492 } 493 494 495 /** 496 * Print a message. 497 * 498 * @param key selects message from resource 499 */ notice(String key)500 public void notice(String key) { 501 if (silent || quiet) 502 return; 503 messager.notice(key); 504 } 505 506 /** 507 * Print a message. 508 * 509 * @param msg message to print. 510 */ printNotice(SourcePosition pos, String msg)511 public void printNotice(SourcePosition pos, String msg) { 512 if (silent || quiet) 513 return; 514 messager.printNotice(pos, msg); 515 } 516 517 /** 518 * Print a message. 519 * 520 * @param key selects message from resource 521 * @param a1 first argument 522 */ notice(String key, String a1)523 public void notice(String key, String a1) { 524 if (silent || quiet) 525 return; 526 messager.notice(key, a1); 527 } 528 529 /** 530 * Print a message. 531 * 532 * @param key selects message from resource 533 * @param a1 first argument 534 * @param a2 second argument 535 */ notice(String key, String a1, String a2)536 public void notice(String key, String a1, String a2) { 537 if (silent || quiet) 538 return; 539 messager.notice(key, a1, a2); 540 } 541 542 /** 543 * Print a message. 544 * 545 * @param key selects message from resource 546 * @param a1 first argument 547 * @param a2 second argument 548 * @param a3 third argument 549 */ notice(String key, String a1, String a2, String a3)550 public void notice(String key, String a1, String a2, String a3) { 551 if (silent || quiet) 552 return; 553 messager.notice(key, a1, a2, a3); 554 } 555 556 /** 557 * Exit, reporting errors and warnings. 558 */ exit()559 public void exit() { 560 // Messager should be replaced by a more general 561 // compilation environment. This can probably 562 // subsume DocEnv as well. 563 messager.exit(); 564 } 565 566 protected Map<PackageSymbol, PackageDocImpl> packageMap = new HashMap<>(); 567 /** 568 * Return the PackageDoc of this package symbol. 569 */ getPackageDoc(PackageSymbol pack)570 public PackageDocImpl getPackageDoc(PackageSymbol pack) { 571 PackageDocImpl result = packageMap.get(pack); 572 if (result != null) return result; 573 result = new PackageDocImpl(this, pack); 574 packageMap.put(pack, result); 575 return result; 576 } 577 578 /** 579 * Create the PackageDoc (or a subtype) for a package symbol. 580 */ makePackageDoc(PackageSymbol pack, TreePath treePath)581 void makePackageDoc(PackageSymbol pack, TreePath treePath) { 582 PackageDocImpl result = packageMap.get(pack); 583 if (result != null) { 584 if (treePath != null) result.setTreePath(treePath); 585 } else { 586 result = new PackageDocImpl(this, pack, treePath); 587 packageMap.put(pack, result); 588 } 589 } 590 591 592 protected Map<ClassSymbol, ClassDocImpl> classMap = new HashMap<>(); 593 /** 594 * Return the ClassDoc (or a subtype) of this class symbol. 595 */ getClassDoc(ClassSymbol clazz)596 public ClassDocImpl getClassDoc(ClassSymbol clazz) { 597 ClassDocImpl result = classMap.get(clazz); 598 if (result != null) return result; 599 if (isAnnotationType(clazz)) { 600 result = new AnnotationTypeDocImpl(this, clazz); 601 } else { 602 result = new ClassDocImpl(this, clazz); 603 } 604 classMap.put(clazz, result); 605 return result; 606 } 607 608 /** 609 * Create the ClassDoc (or a subtype) for a class symbol. 610 */ makeClassDoc(ClassSymbol clazz, TreePath treePath)611 protected void makeClassDoc(ClassSymbol clazz, TreePath treePath) { 612 ClassDocImpl result = classMap.get(clazz); 613 if (result != null) { 614 if (treePath != null) result.setTreePath(treePath); 615 return; 616 } 617 if (isAnnotationType((JCClassDecl) treePath.getLeaf())) { // flags of clazz may not yet be set 618 result = new AnnotationTypeDocImpl(this, clazz, treePath); 619 } else { 620 result = new ClassDocImpl(this, clazz, treePath); 621 } 622 classMap.put(clazz, result); 623 } 624 isAnnotationType(ClassSymbol clazz)625 protected static boolean isAnnotationType(ClassSymbol clazz) { 626 return ClassDocImpl.isAnnotationType(clazz); 627 } 628 isAnnotationType(JCClassDecl tree)629 protected static boolean isAnnotationType(JCClassDecl tree) { 630 return (tree.mods.flags & Flags.ANNOTATION) != 0; 631 } 632 633 protected Map<VarSymbol, FieldDocImpl> fieldMap = new HashMap<>(); 634 /** 635 * Return the FieldDoc of this var symbol. 636 */ getFieldDoc(VarSymbol var)637 public FieldDocImpl getFieldDoc(VarSymbol var) { 638 FieldDocImpl result = fieldMap.get(var); 639 if (result != null) return result; 640 result = new FieldDocImpl(this, var); 641 fieldMap.put(var, result); 642 return result; 643 } 644 /** 645 * Create a FieldDoc for a var symbol. 646 */ makeFieldDoc(VarSymbol var, TreePath treePath)647 protected void makeFieldDoc(VarSymbol var, TreePath treePath) { 648 FieldDocImpl result = fieldMap.get(var); 649 if (result != null) { 650 if (treePath != null) result.setTreePath(treePath); 651 } else { 652 result = new FieldDocImpl(this, var, treePath); 653 fieldMap.put(var, result); 654 } 655 } 656 657 protected Map<MethodSymbol, ExecutableMemberDocImpl> methodMap = new HashMap<>(); 658 /** 659 * Create a MethodDoc for this MethodSymbol. 660 * Should be called only on symbols representing methods. 661 */ makeMethodDoc(MethodSymbol meth, TreePath treePath)662 protected void makeMethodDoc(MethodSymbol meth, TreePath treePath) { 663 MethodDocImpl result = (MethodDocImpl)methodMap.get(meth); 664 if (result != null) { 665 if (treePath != null) result.setTreePath(treePath); 666 } else { 667 result = new MethodDocImpl(this, meth, treePath); 668 methodMap.put(meth, result); 669 } 670 } 671 672 /** 673 * Return the MethodDoc for a MethodSymbol. 674 * Should be called only on symbols representing methods. 675 */ getMethodDoc(MethodSymbol meth)676 public MethodDocImpl getMethodDoc(MethodSymbol meth) { 677 assert !meth.isConstructor() : "not expecting a constructor symbol"; 678 MethodDocImpl result = (MethodDocImpl)methodMap.get(meth); 679 if (result != null) return result; 680 result = new MethodDocImpl(this, meth); 681 methodMap.put(meth, result); 682 return result; 683 } 684 685 /** 686 * Create the ConstructorDoc for a MethodSymbol. 687 * Should be called only on symbols representing constructors. 688 */ makeConstructorDoc(MethodSymbol meth, TreePath treePath)689 protected void makeConstructorDoc(MethodSymbol meth, TreePath treePath) { 690 ConstructorDocImpl result = (ConstructorDocImpl)methodMap.get(meth); 691 if (result != null) { 692 if (treePath != null) result.setTreePath(treePath); 693 } else { 694 result = new ConstructorDocImpl(this, meth, treePath); 695 methodMap.put(meth, result); 696 } 697 } 698 699 /** 700 * Return the ConstructorDoc for a MethodSymbol. 701 * Should be called only on symbols representing constructors. 702 */ getConstructorDoc(MethodSymbol meth)703 public ConstructorDocImpl getConstructorDoc(MethodSymbol meth) { 704 assert meth.isConstructor() : "expecting a constructor symbol"; 705 ConstructorDocImpl result = (ConstructorDocImpl)methodMap.get(meth); 706 if (result != null) return result; 707 result = new ConstructorDocImpl(this, meth); 708 methodMap.put(meth, result); 709 return result; 710 } 711 712 /** 713 * Create the AnnotationTypeElementDoc for a MethodSymbol. 714 * Should be called only on symbols representing annotation type elements. 715 */ makeAnnotationTypeElementDoc(MethodSymbol meth, TreePath treePath)716 protected void makeAnnotationTypeElementDoc(MethodSymbol meth, TreePath treePath) { 717 AnnotationTypeElementDocImpl result = 718 (AnnotationTypeElementDocImpl)methodMap.get(meth); 719 if (result != null) { 720 if (treePath != null) result.setTreePath(treePath); 721 } else { 722 result = 723 new AnnotationTypeElementDocImpl(this, meth, treePath); 724 methodMap.put(meth, result); 725 } 726 } 727 728 /** 729 * Return the AnnotationTypeElementDoc for a MethodSymbol. 730 * Should be called only on symbols representing annotation type elements. 731 */ getAnnotationTypeElementDoc( MethodSymbol meth)732 public AnnotationTypeElementDocImpl getAnnotationTypeElementDoc( 733 MethodSymbol meth) { 734 735 AnnotationTypeElementDocImpl result = 736 (AnnotationTypeElementDocImpl)methodMap.get(meth); 737 if (result != null) return result; 738 result = new AnnotationTypeElementDocImpl(this, meth); 739 methodMap.put(meth, result); 740 return result; 741 } 742 743 // private Map<ClassType, ParameterizedTypeImpl> parameterizedTypeMap = 744 // new HashMap<ClassType, ParameterizedTypeImpl>(); 745 /** 746 * Return the ParameterizedType of this instantiation. 747 // * ### Could use Type.sameTypeAs() instead of equality matching in hashmap 748 // * ### to avoid some duplication. 749 */ getParameterizedType(ClassType t)750 ParameterizedTypeImpl getParameterizedType(ClassType t) { 751 return new ParameterizedTypeImpl(this, t); 752 // ParameterizedTypeImpl result = parameterizedTypeMap.get(t); 753 // if (result != null) return result; 754 // result = new ParameterizedTypeImpl(this, t); 755 // parameterizedTypeMap.put(t, result); 756 // return result; 757 } 758 getTreePath(JCCompilationUnit tree)759 TreePath getTreePath(JCCompilationUnit tree) { 760 TreePath p = treePaths.get(tree); 761 if (p == null) 762 treePaths.put(tree, p = new TreePath(tree)); 763 return p; 764 } 765 getTreePath(JCCompilationUnit toplevel, JCPackageDecl tree)766 TreePath getTreePath(JCCompilationUnit toplevel, JCPackageDecl tree) { 767 TreePath p = treePaths.get(tree); 768 if (p == null) 769 treePaths.put(tree, p = new TreePath(getTreePath(toplevel), tree)); 770 return p; 771 } 772 getTreePath(JCCompilationUnit toplevel, JCClassDecl tree)773 TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl tree) { 774 TreePath p = treePaths.get(tree); 775 if (p == null) 776 treePaths.put(tree, p = new TreePath(getTreePath(toplevel), tree)); 777 return p; 778 } 779 getTreePath(JCCompilationUnit toplevel, JCClassDecl cdecl, JCTree tree)780 TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl cdecl, JCTree tree) { 781 return new TreePath(getTreePath(toplevel, cdecl), tree); 782 } 783 784 /** 785 * Set the encoding. 786 */ setEncoding(String encoding)787 public void setEncoding(String encoding) { 788 this.encoding = encoding; 789 } 790 791 /** 792 * Get the encoding. 793 */ getEncoding()794 public String getEncoding() { 795 return encoding; 796 } 797 798 /** 799 * Convert modifier bits from private coding used by 800 * the compiler to that of java.lang.reflect.Modifier. 801 */ translateModifiers(long flags)802 static int translateModifiers(long flags) { 803 int result = 0; 804 if ((flags & Flags.ABSTRACT) != 0) 805 result |= Modifier.ABSTRACT; 806 if ((flags & Flags.FINAL) != 0) 807 result |= Modifier.FINAL; 808 if ((flags & Flags.INTERFACE) != 0) 809 result |= Modifier.INTERFACE; 810 if ((flags & Flags.NATIVE) != 0) 811 result |= Modifier.NATIVE; 812 if ((flags & Flags.PRIVATE) != 0) 813 result |= Modifier.PRIVATE; 814 if ((flags & Flags.PROTECTED) != 0) 815 result |= Modifier.PROTECTED; 816 if ((flags & Flags.PUBLIC) != 0) 817 result |= Modifier.PUBLIC; 818 if ((flags & Flags.STATIC) != 0) 819 result |= Modifier.STATIC; 820 if ((flags & Flags.SYNCHRONIZED) != 0) 821 result |= Modifier.SYNCHRONIZED; 822 if ((flags & Flags.TRANSIENT) != 0) 823 result |= Modifier.TRANSIENT; 824 if ((flags & Flags.VOLATILE) != 0) 825 result |= Modifier.VOLATILE; 826 return result; 827 } 828 initDoclint(Collection<String> opts, Collection<String> customTagNames, String htmlVersion)829 void initDoclint(Collection<String> opts, Collection<String> customTagNames, String htmlVersion) { 830 ArrayList<String> doclintOpts = new ArrayList<>(); 831 boolean msgOptionSeen = false; 832 833 for (String opt : opts) { 834 if (opt.startsWith(DocLint.XMSGS_OPTION)) { 835 if (opt.equals(DocLint.XMSGS_CUSTOM_PREFIX + "none")) 836 return; 837 msgOptionSeen = true; 838 } 839 doclintOpts.add(opt); 840 } 841 842 if (!msgOptionSeen) { 843 doclintOpts.add(DocLint.XMSGS_OPTION); 844 } 845 846 String sep = ""; 847 StringBuilder customTags = new StringBuilder(); 848 for (String customTag : customTagNames) { 849 customTags.append(sep); 850 customTags.append(customTag); 851 sep = DocLint.SEPARATOR; 852 } 853 doclintOpts.add(DocLint.XCUSTOM_TAGS_PREFIX + customTags.toString()); 854 doclintOpts.add(DocLint.XHTML_VERSION_PREFIX + htmlVersion); 855 856 JavacTask t = BasicJavacTask.instance(context); 857 doclint = new DocLint(); 858 // standard doclet normally generates H1, H2 859 doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2"); 860 doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false); 861 } 862 initJavaScriptScanner(boolean allowScriptInComments)863 JavaScriptScanner initJavaScriptScanner(boolean allowScriptInComments) { 864 if (allowScriptInComments) { 865 javaScriptScanner = null; 866 } else { 867 javaScriptScanner = new JavaScriptScanner(); 868 } 869 return javaScriptScanner; 870 } 871 showTagMessages()872 boolean showTagMessages() { 873 return (doclint == null); 874 } 875 876 Map<CompilationUnitTree, Boolean> shouldCheck = new HashMap<>(); 877 shouldCheck(CompilationUnitTree unit)878 boolean shouldCheck(CompilationUnitTree unit) { 879 return shouldCheck.computeIfAbsent(unit, doclint :: shouldCheck); 880 } 881 } 882