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