langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/DocEnv.java
changeset 39368 59320a0754e7
parent 39360 f3c3b4447c63
parent 39367 3a9d6e8c6fde
child 39369 0469f052203d
child 39597 72fcee36846d
equal deleted inserted replaced
39360:f3c3b4447c63 39368:59320a0754e7
     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 
       
    26 package jdk.javadoc.internal.tool;
       
    27 
       
    28 
       
    29 import java.lang.reflect.Modifier;
       
    30 import java.util.*;
       
    31 
       
    32 import javax.lang.model.element.Element;
       
    33 import javax.lang.model.element.ExecutableElement;
       
    34 import javax.lang.model.element.PackageElement;
       
    35 import javax.lang.model.element.TypeElement;
       
    36 import javax.lang.model.element.VariableElement;
       
    37 import javax.lang.model.util.Elements;
       
    38 import javax.lang.model.util.SimpleElementVisitor9;
       
    39 import javax.tools.JavaFileManager;
       
    40 import javax.tools.JavaFileObject;
       
    41 
       
    42 import com.sun.source.util.DocTrees;
       
    43 import com.sun.source.util.TreePath;
       
    44 import com.sun.tools.javac.api.JavacTrees;
       
    45 import com.sun.tools.javac.code.ClassFinder;
       
    46 import com.sun.tools.javac.code.Flags;
       
    47 import com.sun.tools.javac.code.Kinds.Kind;
       
    48 import com.sun.tools.javac.code.Source;
       
    49 import com.sun.tools.javac.code.Symbol;
       
    50 import com.sun.tools.javac.code.Symbol.ClassSymbol;
       
    51 import com.sun.tools.javac.code.Symbol.CompletionFailure;
       
    52 import com.sun.tools.javac.code.Symbol.MethodSymbol;
       
    53 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
       
    54 import com.sun.tools.javac.code.Symbol.PackageSymbol;
       
    55 import com.sun.tools.javac.code.Symbol.VarSymbol;
       
    56 import com.sun.tools.javac.code.Symtab;
       
    57 import com.sun.tools.javac.comp.AttrContext;
       
    58 import com.sun.tools.javac.comp.Check;
       
    59 import com.sun.tools.javac.comp.Enter;
       
    60 import com.sun.tools.javac.comp.Env;
       
    61 import com.sun.tools.javac.file.JavacFileManager;
       
    62 import com.sun.tools.javac.model.JavacElements;
       
    63 import com.sun.tools.javac.model.JavacTypes;
       
    64 import com.sun.tools.javac.tree.JCTree;
       
    65 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
       
    66 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
       
    67 import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
       
    68 import com.sun.tools.javac.util.Context;
       
    69 import com.sun.tools.javac.util.Convert;
       
    70 import com.sun.tools.javac.util.DefinedBy;
       
    71 import com.sun.tools.javac.util.DefinedBy.Api;
       
    72 import com.sun.tools.javac.util.Name;
       
    73 import com.sun.tools.javac.util.Names;
       
    74 
       
    75 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
       
    76 
       
    77 /**
       
    78  * Holds the environment for a run of javadoc.
       
    79  * Holds only the information needed throughout the
       
    80  * run and not the compiler info that could be GC'ed
       
    81  * or ported.
       
    82  *
       
    83  *  <p><b>This is NOT part of any supported API.
       
    84  *  If you write code that depends on this, you do so at your own risk.
       
    85  *  This code and its internal interfaces are subject to change or
       
    86  *  deletion without notice.</b>
       
    87  *
       
    88  * @author Robert Field
       
    89  * @author Neal Gafter (rewrite)
       
    90  * @author Scott Seligman (generics)
       
    91  */
       
    92 public class DocEnv {
       
    93     protected static final Context.Key<DocEnv> docEnvKey = new Context.Key<>();
       
    94 
       
    95     public static DocEnv instance(Context context) {
       
    96         DocEnv instance = context.get(docEnvKey);
       
    97         if (instance == null)
       
    98             instance = new DocEnv(context);
       
    99         return instance;
       
   100     }
       
   101 
       
   102     private final Messager messager;
       
   103 
       
   104     /** Predefined symbols known to the compiler. */
       
   105     public final Symtab syms;
       
   106 
       
   107     /** Referenced directly in RootDocImpl. */
       
   108     private final ClassFinder finder;
       
   109 
       
   110     /** Javadoc's own version of the compiler's enter phase. */
       
   111     final Enter enter;
       
   112 
       
   113     /** The name table. */
       
   114     private Names names;
       
   115 
       
   116     /** The encoding name. */
       
   117     private String encoding;
       
   118 
       
   119     final Symbol externalizableSym;
       
   120 
       
   121     /** Access filter (public, protected, ...).  */
       
   122     protected ModifierFilter filter;
       
   123 
       
   124     /**
       
   125      * True if we do not want to print any notifications at all.
       
   126      */
       
   127     boolean quiet = false;
       
   128 
       
   129     Check chk;
       
   130     com.sun.tools.javac.code.Types types;
       
   131     JavaFileManager fileManager;
       
   132     public final Context context;
       
   133 
       
   134     WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>();
       
   135 
       
   136     public final HashMap<PackageElement, JavaFileObject> pkgToJavaFOMap = new HashMap<>();
       
   137 
       
   138     /** Allow documenting from class files? */
       
   139     boolean docClasses = false;
       
   140 
       
   141     /**
       
   142      * The source language version.
       
   143      */
       
   144     public final Source source;
       
   145 
       
   146     public final Elements elements;
       
   147 
       
   148     public final JavacTypes typeutils;
       
   149 
       
   150     protected RootDocImpl root;
       
   151 
       
   152     public final DocTrees docTrees;
       
   153 
       
   154     public final Map<Element, TreePath> elementToTreePath;
       
   155 
       
   156     /**
       
   157      * Constructor
       
   158      *
       
   159      * @param context      Context for this javadoc instance.
       
   160      */
       
   161     protected DocEnv(Context context) {
       
   162         context.put(docEnvKey, this);
       
   163         this.context = context;
       
   164 
       
   165         messager = Messager.instance0(context);
       
   166         syms = Symtab.instance(context);
       
   167         finder = JavadocClassFinder.instance(context);
       
   168         enter = JavadocEnter.instance(context);
       
   169         names = Names.instance(context);
       
   170         externalizableSym = syms.enterClass(syms.java_base, names.fromString("java.io.Externalizable"));
       
   171         chk = Check.instance(context);
       
   172         types = com.sun.tools.javac.code.Types.instance(context);
       
   173         fileManager = context.get(JavaFileManager.class);
       
   174         if (fileManager instanceof JavacFileManager) {
       
   175             ((JavacFileManager)fileManager).setSymbolFileEnabled(false);
       
   176         }
       
   177         docTrees = JavacTrees.instance(context);
       
   178         source = Source.instance(context);
       
   179         elements =  JavacElements.instance(context);
       
   180         typeutils = JavacTypes.instance(context);
       
   181         elementToTreePath = new HashMap<>();
       
   182     }
       
   183 
       
   184     public void intialize(String encoding,
       
   185             String showAccess,
       
   186             String overviewpath,
       
   187             List<String> javaNames,
       
   188             Iterable<? extends JavaFileObject> fileObjects,
       
   189             List<String> subPackages,
       
   190             List<String> excludedPackages,
       
   191             boolean docClasses,
       
   192             boolean quiet) {
       
   193         this.filter = ModifierFilter.getModifierFilter(showAccess);
       
   194         this.quiet = quiet;
       
   195 
       
   196         this.setEncoding(encoding);
       
   197         this.docClasses = docClasses;
       
   198     }
       
   199 
       
   200     /**
       
   201      * Load a class by qualified name.
       
   202      */
       
   203     public TypeElement loadClass(String name) {
       
   204         try {
       
   205             Name nameImpl = names.fromString(name);
       
   206             ModuleSymbol mod = syms.inferModule(Convert.packagePart(nameImpl));
       
   207             ClassSymbol c = finder.loadClass(mod != null ? mod : syms.errModule, nameImpl);
       
   208             return c;
       
   209         } catch (CompletionFailure ex) {
       
   210             chk.completionError(null, ex);
       
   211             return null;
       
   212         }
       
   213     }
       
   214 
       
   215     private boolean isSynthetic(long flags) {
       
   216         return (flags & Flags.SYNTHETIC) != 0;
       
   217     }
       
   218 
       
   219     private boolean isSynthetic(Symbol sym) {
       
   220         return isSynthetic(sym.flags_field);
       
   221     }
       
   222 
       
   223     SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null;
       
   224     public boolean shouldDocument(Element e) {
       
   225         if (shouldDocumentVisitor == null) {
       
   226             shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() {
       
   227 
       
   228             @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   229             public Boolean visitType(TypeElement e, Void p) {
       
   230                 return shouldDocument((ClassSymbol)e);
       
   231             }
       
   232 
       
   233             @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   234             public Boolean visitVariable(VariableElement e, Void p) {
       
   235                 return shouldDocument((VarSymbol)e);
       
   236             }
       
   237 
       
   238             @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   239             public Boolean visitExecutable(ExecutableElement e, Void p) {
       
   240                 return shouldDocument((MethodSymbol)e);
       
   241             }
       
   242         };
       
   243         }
       
   244         return shouldDocumentVisitor.visit(e);
       
   245     }
       
   246 
       
   247     /** Check whether this member should be documented. */
       
   248     public boolean shouldDocument(VarSymbol sym) {
       
   249         long mod = sym.flags();
       
   250         if (isSynthetic(mod)) {
       
   251             return false;
       
   252         }
       
   253         return filter.checkModifier(translateModifiers(mod));
       
   254     }
       
   255 
       
   256     /** Check whether this member should be documented. */
       
   257     public boolean shouldDocument(MethodSymbol sym) {
       
   258         long mod = sym.flags();
       
   259         if (isSynthetic(mod)) {
       
   260             return false;
       
   261         }
       
   262         return filter.checkModifier(translateModifiers(mod));
       
   263     }
       
   264 
       
   265     void setElementToTreePath(Element e, TreePath tree) {
       
   266         if (e == null || tree == null)
       
   267             return;
       
   268         elementToTreePath.put(e, tree);
       
   269     }
       
   270 
       
   271     private boolean hasLeaf(ClassSymbol sym) {
       
   272         TreePath path = elementToTreePath.get(sym);
       
   273         if (path == null)
       
   274             return false;
       
   275         return path.getLeaf() != null;
       
   276     }
       
   277 
       
   278     /** check whether this class should be documented. */
       
   279     public boolean shouldDocument(ClassSymbol sym) {
       
   280         return
       
   281             !isSynthetic(sym.flags_field) && // no synthetics
       
   282             (docClasses || hasLeaf(sym)) &&
       
   283             isVisible(sym);
       
   284     }
       
   285 
       
   286     //### Comment below is inaccurate wrt modifier filter testing
       
   287     /**
       
   288      * Check the visibility if this is an nested class.
       
   289      * if this is not a nested class, return true.
       
   290      * if this is an static visible nested class,
       
   291      *    return true.
       
   292      * if this is an visible nested class
       
   293      *    if the outer class is visible return true.
       
   294      *    else return false.
       
   295      * IMPORTANT: This also allows, static nested classes
       
   296      * to be defined inside an nested class, which is not
       
   297      * allowed by the compiler. So such an test case will
       
   298      * not reach upto this method itself, but if compiler
       
   299      * allows it, then that will go through.
       
   300      */
       
   301     public boolean isVisible(ClassSymbol sym) {
       
   302         long mod = sym.flags_field;
       
   303         if (!filter.checkModifier(translateModifiers(mod))) {
       
   304             return false;
       
   305         }
       
   306         ClassSymbol encl = sym.owner.enclClass();
       
   307         return (encl == null || (mod & Flags.STATIC) != 0 || isVisible(encl));
       
   308     }
       
   309 
       
   310     //---------------- print forwarders ----------------//
       
   311 
       
   312     // ERRORS
       
   313     /**
       
   314      * Print error message, increment error count.
       
   315      *
       
   316      * @param msg message to print.
       
   317      */
       
   318     public void printError(String msg) {
       
   319         messager.printError(msg);
       
   320     }
       
   321 
       
   322 //    /**
       
   323 //     * Print error message, increment error count.
       
   324 //     *
       
   325 //     * @param key selects message from resource
       
   326 //     */
       
   327 //    public void error(Element element, String key) {
       
   328 //        if (element == null)
       
   329 //            messager.error(key);
       
   330 //        else
       
   331 //            messager.error(element, key);
       
   332 //    }
       
   333 //
       
   334 //    public void error(String prefix, String key) {
       
   335 //        printError(prefix + ":" + messager.getText(key));
       
   336 //    }
       
   337 //
       
   338 //    /**
       
   339 //     * Print error message, increment error count.
       
   340 //     *
       
   341 //     * @param path the path to the source
       
   342 //     * @param key selects message from resource
       
   343 //     */
       
   344 //    public void error(DocTreePath path, String key) {
       
   345 //        messager.error(path, key);
       
   346 //    }
       
   347 //
       
   348 //    /**
       
   349 //     * Print error message, increment error count.
       
   350 //     *
       
   351 //     * @param path the path to the source
       
   352 //     * @param msg message to print.
       
   353 //     */
       
   354 //    public void printError(DocTreePath path, String msg) {
       
   355 //        messager.printError(path, msg);
       
   356 //    }
       
   357 //
       
   358 //    /**
       
   359 //     * Print error message, increment error count.
       
   360 //     * @param e the target element
       
   361 //     * @param msg message to print.
       
   362 //     */
       
   363 //    public void printError(Element e, String msg) {
       
   364 //        messager.printError(e, msg);
       
   365 //    }
       
   366 
       
   367     /**
       
   368      * Print error message, increment error count.
       
   369      *
       
   370      * @param element the source element
       
   371      * @param key selects message from resource
       
   372      * @param args replacement arguments
       
   373      */
       
   374     public void error(Element element, String key, String... args) {
       
   375         if (element == null)
       
   376             messager.error(key, (Object[]) args);
       
   377         else
       
   378             messager.error(element, key, (Object[]) args);
       
   379     }
       
   380 
       
   381     // WARNINGS
       
   382 
       
   383 //    /**
       
   384 //     * Print warning message, increment warning count.
       
   385 //     *
       
   386 //     * @param msg message to print.
       
   387 //     */
       
   388 //    public void printWarning(String msg) {
       
   389 //        messager.printWarning(msg);
       
   390 //    }
       
   391 //
       
   392 //    public void warning(String key) {
       
   393 //        warning((Element)null, key);
       
   394 //    }
       
   395 
       
   396     public void warning(String key, String... args) {
       
   397         warning((Element)null, key, args);
       
   398     }
       
   399 
       
   400 //    /**
       
   401 //     * Print warning message, increment warning count.
       
   402 //     *
       
   403 //     * @param element the source element
       
   404 //     * @param key selects message from resource
       
   405 //     */
       
   406 //    public void warning(Element element, String key) {
       
   407 //        if (element == null)
       
   408 //            messager.warning(key);
       
   409 //        else
       
   410 //            messager.warning(element, key);
       
   411 //    }
       
   412 //
       
   413 //    /**
       
   414 //     * Print warning message, increment warning count.
       
   415 //     *
       
   416 //     * @param path the path to the source
       
   417 //     * @param msg message to print.
       
   418 //     */
       
   419 //    public void printWarning(DocTreePath path, String msg) {
       
   420 //        messager.printWarning(path, msg);
       
   421 //    }
       
   422 //
       
   423 //    /**
       
   424 //     * Print warning message, increment warning count.
       
   425 //     *
       
   426 //     * @param e  the source element
       
   427 //     * @param msg message to print.
       
   428 //     */
       
   429 //    public void printWarning(Element e, String msg) {
       
   430 //        messager.printWarning(e, msg);
       
   431 //    }
       
   432 
       
   433     /**
       
   434      * Print warning message, increment warning count.
       
   435      *
       
   436      * @param e    the source element
       
   437      * @param key  selects message from resource
       
   438      * @param args the replace arguments
       
   439      */
       
   440     public void warning(Element e, String key, String... args) {
       
   441         if (e == null)
       
   442             messager.warning(key, (Object[]) args);
       
   443         else
       
   444             messager.warning(e, key, (Object[]) args);
       
   445     }
       
   446 
       
   447 //    Note: no longer required
       
   448 //    /**
       
   449 //     * Print a message.
       
   450 //     *
       
   451 //     * @param msg message to print.
       
   452 //     */
       
   453 //    public void printNotice(String msg) {
       
   454 //        if (quiet) {
       
   455 //            return;
       
   456 //        }
       
   457 //        messager.printNotice(msg);
       
   458 //    }
       
   459 
       
   460 //  Note: no longer required
       
   461 //    /**
       
   462 //     * Print a message.
       
   463 //     *
       
   464 //     * @param e the source element
       
   465 //     * @param msg message to print.
       
   466 //     */
       
   467 //    public void printNotice(Element e, String msg) {
       
   468 //        if (quiet) {
       
   469 //            return;
       
   470 //        }
       
   471 //        messager.printNotice(e, msg);
       
   472 //    }
       
   473 
       
   474     //  NOTICES
       
   475     /**
       
   476      * Print a message.
       
   477      *
       
   478      * @param key selects message from resource
       
   479      */
       
   480     public void notice(String key) {
       
   481         if (quiet) {
       
   482             return;
       
   483         }
       
   484         messager.notice(key);
       
   485     }
       
   486 
       
   487 //    Note: not used anymore
       
   488 //    /**
       
   489 //     * Print a message.
       
   490 //     *
       
   491 //     * @param path the path to the source
       
   492 //     * @param msg message to print.
       
   493 //     */
       
   494 //    public void printNotice(DocTreePath path, String msg) {
       
   495 //        if (quiet) {
       
   496 //            return;
       
   497 //        }
       
   498 //        messager.printNotice(path, msg);
       
   499 //    }
       
   500 
       
   501     /**
       
   502      * Print a message.
       
   503      *
       
   504      * @param key selects message from resource
       
   505      * @param a1 first argument
       
   506      */
       
   507     public void notice(String key, String a1) {
       
   508         if (quiet) {
       
   509             return;
       
   510         }
       
   511         messager.notice(key, a1);
       
   512     }
       
   513 
       
   514 //    Note: not used anymore
       
   515 //    /**
       
   516 //     * Print a message.
       
   517 //     *
       
   518 //     * @param key selects message from resource
       
   519 //     * @param a1 first argument
       
   520 //     * @param a2 second argument
       
   521 //     */
       
   522 //    public void notice(String key, String a1, String a2) {
       
   523 //        if (quiet) {
       
   524 //            return;
       
   525 //        }
       
   526 //        messager.notice(key, a1, a2);
       
   527 //    }
       
   528 //
       
   529 
       
   530 //    Note: not used anymore
       
   531 //    /**
       
   532 //     * Print a message.
       
   533 //     *
       
   534 //     * @param key selects message from resource
       
   535 //     * @param a1 first argument
       
   536 //     * @param a2 second argument
       
   537 //     * @param a3 third argument
       
   538 //     */
       
   539 //    public void notice(String key, String a1, String a2, String a3) {
       
   540 //        if (quiet) {
       
   541 //            return;
       
   542 //        }
       
   543 //        messager.notice(key, a1, a2, a3);
       
   544 //    }
       
   545 
       
   546     /**
       
   547      * Exit, reporting errors and warnings.
       
   548      */
       
   549     public void exit() {
       
   550         // Messager should be replaced by a more general
       
   551         // compilation environment.  This can probably
       
   552         // subsume DocEnv as well.
       
   553         throw new Messager.ExitJavadoc();
       
   554     }
       
   555 
       
   556     /**
       
   557      * Adds all inner classes of this class, and their inner classes recursively, to the list
       
   558      */
       
   559     void addAllClasses(Collection<TypeElement> list, TypeElement typeElement, boolean filtered) {
       
   560         ClassSymbol klass = (ClassSymbol)typeElement;
       
   561         try {
       
   562             if (isSynthetic(klass.flags())) return;
       
   563             // sometimes synthetic classes are not marked synthetic
       
   564             if (!JavadocTool.isValidClassName(klass.name.toString())) return;
       
   565             if (filtered && !shouldDocument(klass)) return;
       
   566             if (list.contains(klass)) return;
       
   567             list.add(klass);
       
   568             for (Symbol sym : klass.members().getSymbols(NON_RECURSIVE)) {
       
   569                 if (sym != null && sym.kind == Kind.TYP) {
       
   570                     ClassSymbol s = (ClassSymbol)sym;
       
   571                     if (!isSynthetic(s.flags())) {
       
   572                         addAllClasses(list, s, filtered);
       
   573                     }
       
   574                 }
       
   575             }
       
   576         } catch (CompletionFailure e) {
       
   577             // quietly ignore completion failures
       
   578         }
       
   579     }
       
   580 
       
   581     /**
       
   582      * Return a list of all classes contained in this package, including
       
   583      * member classes of those classes, and their member classes, etc.
       
   584      */
       
   585     void addAllClasses(Collection<TypeElement> list, PackageElement pkg) {
       
   586         boolean filtered = true;
       
   587         PackageSymbol sym = (PackageSymbol)pkg;
       
   588         for (Symbol isym : sym.members().getSymbols(NON_RECURSIVE)) {
       
   589             if (isym != null) {
       
   590                 ClassSymbol s = (ClassSymbol)isym;
       
   591                 if (!isSynthetic(s)) {
       
   592                     addAllClasses(list, s, filtered);
       
   593                 }
       
   594             }
       
   595         }
       
   596     }
       
   597 
       
   598     TreePath getTreePath(JCCompilationUnit tree) {
       
   599         TreePath p = treePaths.get(tree);
       
   600         if (p == null)
       
   601             treePaths.put(tree, p = new TreePath(tree));
       
   602         return p;
       
   603     }
       
   604 
       
   605     TreePath getTreePath(JCCompilationUnit toplevel, JCPackageDecl tree) {
       
   606         TreePath p = treePaths.get(tree);
       
   607         if (p == null)
       
   608             treePaths.put(tree, p = new TreePath(getTreePath(toplevel), tree));
       
   609         return p;
       
   610     }
       
   611 
       
   612     TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl tree) {
       
   613         TreePath p = treePaths.get(tree);
       
   614         if (p == null)
       
   615             treePaths.put(tree, p = new TreePath(getTreePath(toplevel), tree));
       
   616         return p;
       
   617     }
       
   618 
       
   619     TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl cdecl, JCTree tree) {
       
   620         return new TreePath(getTreePath(toplevel, cdecl), tree);
       
   621     }
       
   622 
       
   623     public com.sun.tools.javac.code.Types getTypes() {
       
   624         return types;
       
   625     }
       
   626 
       
   627     /**
       
   628      * Set the encoding.
       
   629      */
       
   630     public void setEncoding(String encoding) {
       
   631         this.encoding = encoding;
       
   632     }
       
   633 
       
   634     public Env<AttrContext> getEnv(ClassSymbol tsym) {
       
   635         return enter.getEnv(tsym);
       
   636     }
       
   637 
       
   638     /**
       
   639      * Get the encoding.
       
   640      */
       
   641     public String getEncoding() {
       
   642         return encoding;
       
   643     }
       
   644 
       
   645     /**
       
   646      * Convert modifier bits from private coding used by
       
   647      * the compiler to that of java.lang.reflect.Modifier.
       
   648      */
       
   649     static int translateModifiers(long flags) {
       
   650         int result = 0;
       
   651         if ((flags & Flags.ABSTRACT) != 0)
       
   652             result |= Modifier.ABSTRACT;
       
   653         if ((flags & Flags.FINAL) != 0)
       
   654             result |= Modifier.FINAL;
       
   655         if ((flags & Flags.INTERFACE) != 0)
       
   656             result |= Modifier.INTERFACE;
       
   657         if ((flags & Flags.NATIVE) != 0)
       
   658             result |= Modifier.NATIVE;
       
   659         if ((flags & Flags.PRIVATE) != 0)
       
   660             result |= Modifier.PRIVATE;
       
   661         if ((flags & Flags.PROTECTED) != 0)
       
   662             result |= Modifier.PROTECTED;
       
   663         if ((flags & Flags.PUBLIC) != 0)
       
   664             result |= Modifier.PUBLIC;
       
   665         if ((flags & Flags.STATIC) != 0)
       
   666             result |= Modifier.STATIC;
       
   667         if ((flags & Flags.SYNCHRONIZED) != 0)
       
   668             result |= Modifier.SYNCHRONIZED;
       
   669         if ((flags & Flags.TRANSIENT) != 0)
       
   670             result |= Modifier.TRANSIENT;
       
   671         if ((flags & Flags.VOLATILE) != 0)
       
   672             result |= Modifier.VOLATILE;
       
   673         return result;
       
   674     }
       
   675 
       
   676     private final Set<Element> includedSet = new HashSet<>();
       
   677 
       
   678     public void setIncluded(Element element) {
       
   679         includedSet.add(element);
       
   680     }
       
   681 
       
   682     private SimpleElementVisitor9<Boolean, Void> includedVisitor = null;
       
   683 
       
   684     public boolean isIncluded(Element e) {
       
   685         if (e == null) {
       
   686             return false;
       
   687         }
       
   688         if (includedVisitor == null) {
       
   689             includedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
       
   690                 @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   691                 public Boolean visitType(TypeElement e, Void p) {
       
   692                     if (includedSet.contains(e)) {
       
   693                         return true;
       
   694                     }
       
   695                     if (shouldDocument(e)) {
       
   696                         // Class is nameable from top-level and
       
   697                         // the class and all enclosing classes
       
   698                         // pass the modifier filter.
       
   699                         PackageElement pkg = elements.getPackageOf(e);
       
   700                         if (includedSet.contains(pkg)) {
       
   701                             setIncluded(e);
       
   702                             return true;
       
   703                         }
       
   704                         Element enclosing = e.getEnclosingElement();
       
   705                         if (enclosing != null && includedSet.contains(enclosing)) {
       
   706                             setIncluded(e);
       
   707                             return true;
       
   708                         }
       
   709                     }
       
   710                     return false;
       
   711                 }
       
   712 
       
   713                 @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   714                 public Boolean visitPackage(PackageElement e, Void p) {
       
   715                     return includedSet.contains(e);
       
   716                 }
       
   717 
       
   718                 @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   719                 public Boolean visitUnknown(Element e, Void p) {
       
   720                     throw new AssertionError("unknown element: " + e);
       
   721                 }
       
   722 
       
   723                 @Override @DefinedBy(Api.LANGUAGE_MODEL)
       
   724                 public Boolean defaultAction(Element e, Void p) {
       
   725                     return visit(e.getEnclosingElement()) && shouldDocument(e);
       
   726                 }
       
   727             };
       
   728         }
       
   729         return includedVisitor.visit(e);
       
   730     }
       
   731 
       
   732     public boolean isQuiet() {
       
   733         return quiet;
       
   734     }
       
   735 
       
   736     /**
       
   737      * A class which filters the access flags on classes, fields, methods, etc.
       
   738      *
       
   739      * <p>
       
   740      * <b>This is NOT part of any supported API. If you write code that depends on this, you do so
       
   741      * at your own risk. This code and its internal interfaces are subject to change or deletion
       
   742      * without notice.</b>
       
   743      *
       
   744      * @see javax.lang.model.element.Modifier
       
   745      * @author Robert Field
       
   746      */
       
   747 
       
   748     private static class ModifierFilter {
       
   749 
       
   750         static enum FilterFlag {
       
   751             PACKAGE,
       
   752             PRIVATE,
       
   753             PROTECTED,
       
   754             PUBLIC
       
   755         }
       
   756 
       
   757         private Set<FilterFlag> oneOf;
       
   758 
       
   759         /**
       
   760          * Constructor - Specify a filter.
       
   761          *
       
   762          * @param oneOf a set containing desired flags to be matched.
       
   763          */
       
   764         ModifierFilter(Set<FilterFlag> oneOf) {
       
   765             this.oneOf = oneOf;
       
   766         }
       
   767 
       
   768         /**
       
   769          * Constructor - Specify a filter.
       
   770          *
       
   771          * @param oneOf an array containing desired flags to be matched.
       
   772          */
       
   773         ModifierFilter(FilterFlag... oneOf) {
       
   774             this.oneOf = new HashSet<>();
       
   775             this.oneOf.addAll(Arrays.asList(oneOf));
       
   776         }
       
   777 
       
   778         static ModifierFilter getModifierFilter(String showAccess) {
       
   779             switch (showAccess) {
       
   780                 case "public":
       
   781                     return new ModifierFilter(FilterFlag.PUBLIC);
       
   782                 case "package":
       
   783                     return new ModifierFilter(FilterFlag.PUBLIC, FilterFlag.PROTECTED,
       
   784                                               FilterFlag.PACKAGE);
       
   785                 case "private":
       
   786                     return new ModifierFilter(FilterFlag.PRIVATE);
       
   787                 default:
       
   788                     return new ModifierFilter(FilterFlag.PUBLIC, FilterFlag.PROTECTED);
       
   789             }
       
   790         }
       
   791 
       
   792         private boolean hasFlag(long flag, long modifierBits) {
       
   793             return (flag & modifierBits) != 0;
       
   794         }
       
   795 
       
   796         private List<FilterFlag> flagsToModifiers(long modifierBits) {
       
   797             List<FilterFlag> list = new ArrayList<>();
       
   798             boolean isPackage = true;
       
   799             if (hasFlag(com.sun.tools.javac.code.Flags.PRIVATE, modifierBits)) {
       
   800                 list.add(FilterFlag.PRIVATE);
       
   801                 isPackage = false;
       
   802             }
       
   803             if (hasFlag(com.sun.tools.javac.code.Flags.PROTECTED, modifierBits)) {
       
   804                 list.add(FilterFlag.PROTECTED);
       
   805                 isPackage = false;
       
   806             }
       
   807             if (hasFlag(com.sun.tools.javac.code.Flags.PUBLIC, modifierBits)) {
       
   808                 list.add(FilterFlag.PUBLIC);
       
   809                 isPackage = false;
       
   810             }
       
   811             if (isPackage) {
       
   812                 list.add(FilterFlag.PACKAGE);
       
   813             }
       
   814             return list;
       
   815         }
       
   816 
       
   817         /**
       
   818          * Filter on modifier bits.
       
   819          *
       
   820          * @param modifierBits Bits as specified in the Modifier class
       
   821          *
       
   822          * @return Whether the modifierBits pass this filter.
       
   823          */
       
   824         public boolean checkModifier(int modifierBits) {
       
   825             return checkModifier(flagsToModifiers(modifierBits));
       
   826         }
       
   827 
       
   828         /**
       
   829          * Filter on Filter flags
       
   830          *
       
   831          * @param modifiers Flags as specified in the FilterFlags enumeration.
       
   832          *
       
   833          * @return if the modifier is contained.
       
   834          */
       
   835         public boolean checkModifier(List<FilterFlag> modifiers) {
       
   836             if (oneOf.contains(FilterFlag.PRIVATE)) {
       
   837                 return true;
       
   838             }
       
   839             for (FilterFlag mod : modifiers) {
       
   840                 if (oneOf.contains(mod)) {
       
   841                     return true;
       
   842                 }
       
   843             }
       
   844             return false;
       
   845         }
       
   846 
       
   847     } // end ModifierFilter
       
   848 }