jjg@1455: /*
jjg@1668: * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
jjg@1455: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jjg@1455: *
jjg@1455: * This code is free software; you can redistribute it and/or modify it
jjg@1455: * under the terms of the GNU General Public License version 2 only, as
jjg@1455: * published by the Free Software Foundation. Oracle designates this
jjg@1455: * particular file as subject to the "Classpath" exception as provided
jjg@1455: * by Oracle in the LICENSE file that accompanied this code.
jjg@1455: *
jjg@1455: * This code is distributed in the hope that it will be useful, but WITHOUT
jjg@1455: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jjg@1455: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jjg@1455: * version 2 for more details (a copy is included in the LICENSE file that
jjg@1455: * accompanied this code).
jjg@1455: *
jjg@1455: * You should have received a copy of the GNU General Public License version
jjg@1455: * 2 along with this work; if not, write to the Free Software Foundation,
jjg@1455: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jjg@1455: *
jjg@1455: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jjg@1455: * or visit www.oracle.com if you need additional information or have any
jjg@1455: * questions.
jjg@1455: */
jjg@1455:
jjg@1455: package com.sun.tools.doclint;
jjg@1455:
jjg@1455:
jjg@1455: import java.util.Set;
bpatel@2169: import java.util.LinkedHashSet;
jjg@1455:
jjg@1455: import javax.lang.model.element.Element;
jlahoda@1734: import javax.lang.model.element.ElementKind;
jjg@1455: import javax.lang.model.element.ExecutableElement;
jjg@1455: import javax.lang.model.element.Modifier;
jjg@1455: import javax.lang.model.type.TypeMirror;
jjg@1455: import javax.lang.model.util.Elements;
jjg@1455: import javax.lang.model.util.Types;
jjg@1455:
jjg@1455: import com.sun.source.doctree.DocCommentTree;
jjg@1455: import com.sun.source.util.DocTrees;
jjg@1455: import com.sun.source.util.JavacTask;
jjg@1455: import com.sun.source.util.SourcePositions;
jjg@1455: import com.sun.source.util.TreePath;
jjg@1455: import com.sun.tools.javac.model.JavacTypes;
jjg@1455: import com.sun.tools.javac.tree.JCTree;
jjg@1455:
jjg@1455: /**
jjg@1455: * Utility container for current execution environment,
jjg@1455: * providing the current declaration and its doc comment.
jjg@1455: *
jjg@1455: *
This is NOT part of any supported API.
jjg@1455: * If you write code that depends on this, you do so at your own
jjg@1455: * risk. This code and its internal interfaces are subject to change
jjg@1455: * or deletion without notice.
jjg@1455: */
jjg@1455: public class Env {
jjg@1455: /**
jjg@1455: * Access kinds for declarations.
jjg@1455: */
jjg@1455: public enum AccessKind {
jjg@1455: PRIVATE,
jjg@1455: PACKAGE,
jjg@1455: PROTECTED,
jjg@1455: PUBLIC;
jjg@1455:
jjg@1455: static boolean accepts(String opt) {
jjg@1455: for (AccessKind g: values())
jjg@1455: if (opt.equals(g.name().toLowerCase())) return true;
jjg@1455: return false;
jjg@1455: }
jjg@1455:
jjg@1455: static AccessKind of(Set mods) {
jjg@1455: if (mods.contains(Modifier.PUBLIC))
jjg@1455: return AccessKind.PUBLIC;
jjg@1455: else if (mods.contains(Modifier.PROTECTED))
jjg@1455: return AccessKind.PROTECTED;
jjg@1455: else if (mods.contains(Modifier.PRIVATE))
jjg@1455: return AccessKind.PRIVATE;
jjg@1455: else
jjg@1455: return AccessKind.PACKAGE;
jjg@1455: }
jjg@1455: };
jjg@1455:
jjg@1455: /** Message handler. */
jjg@1455: final Messages messages;
jjg@1455:
jjg@1668: int implicitHeaderLevel = 0;
jjg@1668:
bpatel@2169: Set customTags;
bpatel@2169:
jjg@1455: // Utility classes
jjg@1455: DocTrees trees;
jjg@1455: Elements elements;
jjg@1455: Types types;
jjg@1455:
jjg@1455: // Types used when analysing doc comments.
jjg@1455: TypeMirror java_lang_Error;
jjg@1455: TypeMirror java_lang_RuntimeException;
jjg@1455: TypeMirror java_lang_Throwable;
jjg@1455: TypeMirror java_lang_Void;
jjg@1455:
jjg@1455: /** The path for the declaration containing the comment currently being analyzed. */
jjg@1455: TreePath currPath;
jjg@1455: /** The element for the declaration containing the comment currently being analyzed. */
jjg@1455: Element currElement;
jjg@1455: /** The comment current being analyzed. */
jjg@1455: DocCommentTree currDocComment;
jjg@1455: /**
jjg@1455: * The access kind of the declaration containing the comment currently being analyzed.
jjg@1668: * This is the minimum (most restrictive) access kind of the declaration itself
jjg@1455: * and that of its containers. For example, a public method in a private class is
jjg@1455: * noted as private.
jjg@1455: */
jjg@1455: AccessKind currAccess;
jjg@1455: /** The set of methods, if any, that the current declaration overrides. */
jjg@1455: Set extends ExecutableElement> currOverriddenMethods;
jjg@1455:
jjg@1455: Env() {
jjg@1455: messages = new Messages(this);
jjg@1455: }
jjg@1455:
jjg@1455: void init(JavacTask task) {
jjg@1455: init(DocTrees.instance(task), task.getElements(), task.getTypes());
jjg@1455: }
jjg@1455:
jjg@1455: void init(DocTrees trees, Elements elements, Types types) {
jjg@1455: this.trees = trees;
jjg@1455: this.elements = elements;
jjg@1455: this.types = types;
jjg@1455: java_lang_Error = elements.getTypeElement("java.lang.Error").asType();
jjg@1455: java_lang_RuntimeException = elements.getTypeElement("java.lang.RuntimeException").asType();
jjg@1455: java_lang_Throwable = elements.getTypeElement("java.lang.Throwable").asType();
jjg@1455: java_lang_Void = elements.getTypeElement("java.lang.Void").asType();
jjg@1455: }
jjg@1455:
jjg@1668: void setImplicitHeaders(int n) {
jjg@1668: implicitHeaderLevel = n;
jjg@1668: }
jjg@1668:
bpatel@2169: void setCustomTags(String cTags) {
bpatel@2169: customTags = new LinkedHashSet();
bpatel@2169: for (String s : cTags.split(DocLint.TAGS_SEPARATOR)) {
bpatel@2169: if (!s.isEmpty())
bpatel@2169: customTags.add(s);
bpatel@2169: }
bpatel@2169: }
bpatel@2169:
jjg@1455: /** Set the current declaration and its doc comment. */
jjg@1455: void setCurrent(TreePath path, DocCommentTree comment) {
jjg@1455: currPath = path;
jjg@1455: currDocComment = comment;
jjg@1455: currElement = trees.getElement(currPath);
jjg@1455: currOverriddenMethods = ((JavacTypes) types).getOverriddenMethods(currElement);
jjg@1455:
jjg@1895: AccessKind ak = AccessKind.PUBLIC;
jjg@1455: for (TreePath p = path; p != null; p = p.getParentPath()) {
jjg@1455: Element e = trees.getElement(p);
jlahoda@1734: if (e != null && e.getKind() != ElementKind.PACKAGE) {
jjg@1455: ak = min(ak, AccessKind.of(e.getModifiers()));
jjg@1455: }
jjg@1455: }
jjg@1455: currAccess = ak;
jjg@1455: }
jjg@1455:
jjg@1455: AccessKind getAccessKind() {
jjg@1455: return currAccess;
jjg@1455: }
jjg@1455:
jjg@1455: long getPos(TreePath p) {
jjg@1455: return ((JCTree) p.getLeaf()).pos;
jjg@1455: }
jjg@1455:
jjg@1455: long getStartPos(TreePath p) {
jjg@1455: SourcePositions sp = trees.getSourcePositions();
jjg@1455: return sp.getStartPosition(p.getCompilationUnit(), p.getLeaf());
jjg@1455: }
jjg@1455:
jjg@1455: private > T min(T item1, T item2) {
jjg@1455: return (item1 == null) ? item2
jjg@1455: : (item2 == null) ? item1
jjg@1455: : item1.compareTo(item2) <= 0 ? item1 : item2;
jjg@1455: }
jjg@1455: }