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