1 /* 2 * Copyright (c) 2012, 2020, 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.doclint; 27 28 29 import java.util.Arrays; 30 import java.util.HashSet; 31 import java.util.LinkedHashSet; 32 import java.util.List; 33 import java.util.Set; 34 import java.util.regex.Pattern; 35 36 import javax.lang.model.element.Element; 37 import javax.lang.model.element.ElementKind; 38 import javax.lang.model.element.ExecutableElement; 39 import javax.lang.model.element.Modifier; 40 import javax.lang.model.type.TypeMirror; 41 import javax.lang.model.util.Elements; 42 import javax.lang.model.util.Types; 43 import javax.tools.Diagnostic.Kind; 44 45 import com.sun.source.doctree.DocCommentTree; 46 import com.sun.source.tree.CompilationUnitTree; 47 import com.sun.source.util.DocTrees; 48 import com.sun.source.util.JavacTask; 49 import com.sun.source.util.SourcePositions; 50 import com.sun.source.util.TreePath; 51 import com.sun.tools.javac.model.JavacTypes; 52 import com.sun.tools.javac.tree.JCTree; 53 import com.sun.tools.javac.util.MatchingUtils; 54 import com.sun.tools.javac.util.StringUtils; 55 56 /** 57 * Utility container for current execution environment, 58 * providing the current declaration and its doc comment. 59 * 60 * <p><b>This is NOT part of any supported API. 61 * If you write code that depends on this, you do so at your own 62 * risk. This code and its internal interfaces are subject to change 63 * or deletion without notice.</b></p> 64 */ 65 public class Env { 66 /** 67 * Access kinds for declarations. 68 */ 69 public enum AccessKind { 70 PRIVATE, 71 PACKAGE, 72 PROTECTED, 73 PUBLIC; 74 accepts(String opt)75 static boolean accepts(String opt) { 76 for (AccessKind g: values()) 77 if (opt.equals(StringUtils.toLowerCase(g.name()))) return true; 78 return false; 79 } 80 of(Set<Modifier> mods)81 static AccessKind of(Set<Modifier> mods) { 82 if (mods.contains(Modifier.PUBLIC)) 83 return AccessKind.PUBLIC; 84 else if (mods.contains(Modifier.PROTECTED)) 85 return AccessKind.PROTECTED; 86 else if (mods.contains(Modifier.PRIVATE)) 87 return AccessKind.PRIVATE; 88 else 89 return AccessKind.PACKAGE; 90 } 91 } 92 93 /** Message handler. */ 94 final Messages messages; 95 96 Set<String> customTags; 97 98 Set<Pattern> includePackages; 99 Set<Pattern> excludePackages; 100 101 // Utility classes 102 DocTrees trees; 103 Elements elements; 104 Types types; 105 106 // Types used when analysing doc comments. 107 TypeMirror java_lang_Error; 108 TypeMirror java_lang_RuntimeException; 109 TypeMirror java_lang_Throwable; 110 TypeMirror java_lang_Void; 111 112 /** The path for the declaration containing the comment currently being analyzed. */ 113 TreePath currPath; 114 /** The element for the declaration containing the comment currently being analyzed. */ 115 Element currElement; 116 /** The comment current being analyzed. */ 117 DocCommentTree currDocComment; 118 /** 119 * The access kind of the declaration containing the comment currently being analyzed. 120 * This is the minimum (most restrictive) access kind of the declaration itself 121 * and that of its containers. For example, a public method in a private class is 122 * noted as private. 123 */ 124 AccessKind currAccess; 125 /** The set of methods, if any, that the current declaration overrides. */ 126 Set<? extends ExecutableElement> currOverriddenMethods; 127 Env()128 Env() { 129 messages = new Messages(this); 130 } 131 init(JavacTask task)132 void init(JavacTask task) { 133 init(DocTrees.instance(task), task.getElements(), task.getTypes()); 134 } 135 init(DocTrees trees, Elements elements, Types types)136 void init(DocTrees trees, Elements elements, Types types) { 137 this.trees = trees; 138 this.elements = elements; 139 this.types = types; 140 } 141 initTypes()142 void initTypes() { 143 if (java_lang_Error != null) 144 return ; 145 146 java_lang_Error = elements.getTypeElement("java.lang.Error").asType(); 147 java_lang_RuntimeException = elements.getTypeElement("java.lang.RuntimeException").asType(); 148 java_lang_Throwable = elements.getTypeElement("java.lang.Throwable").asType(); 149 java_lang_Void = elements.getTypeElement("java.lang.Void").asType(); 150 } 151 setCustomTags(String cTags)152 void setCustomTags(String cTags) { 153 customTags = new LinkedHashSet<>(); 154 for (String s : cTags.split(DocLint.SEPARATOR)) { 155 if (!s.isEmpty()) 156 customTags.add(s); 157 } 158 } 159 setCheckPackages(String packages)160 void setCheckPackages(String packages) { 161 includePackages = new HashSet<>(); 162 excludePackages = new HashSet<>(); 163 for (String pack : packages.split(DocLint.SEPARATOR)) { 164 boolean excluded = false; 165 if (pack.startsWith("-")) { 166 pack = pack.substring(1); 167 excluded = true; 168 } 169 if (pack.isEmpty()) 170 continue; 171 Pattern pattern = MatchingUtils.validImportStringToPattern(pack); 172 if (excluded) { 173 excludePackages.add(pattern); 174 } else { 175 includePackages.add(pattern); 176 } 177 } 178 } 179 validatePackages(String packages)180 static boolean validatePackages(String packages) { 181 for (String pack : packages.split(DocLint.SEPARATOR)) { 182 if (pack.startsWith("-")) { 183 pack = pack.substring(1); 184 } 185 if (!pack.isEmpty() && !MatchingUtils.isValidImportString(pack)) 186 return false; 187 } 188 return true; 189 } 190 191 /** Set the current declaration and its doc comment. */ setCurrent(TreePath path, DocCommentTree comment)192 void setCurrent(TreePath path, DocCommentTree comment) { 193 currPath = path; 194 currDocComment = comment; 195 currElement = trees.getElement(currPath); 196 currOverriddenMethods = ((JavacTypes) types).getOverriddenMethods(currElement); 197 198 AccessKind ak = AccessKind.PUBLIC; 199 for (TreePath p = path; p != null; p = p.getParentPath()) { 200 Element e = trees.getElement(p); 201 if (e != null && e.getKind() != ElementKind.PACKAGE && e.getKind() != ElementKind.MODULE) { 202 ak = min(ak, AccessKind.of(e.getModifiers())); 203 } 204 } 205 currAccess = ak; 206 } 207 getAccessKind()208 AccessKind getAccessKind() { 209 return currAccess; 210 } 211 getPos(TreePath p)212 long getPos(TreePath p) { 213 return ((JCTree) p.getLeaf()).pos; 214 } 215 getStartPos(TreePath p)216 long getStartPos(TreePath p) { 217 SourcePositions sp = trees.getSourcePositions(); 218 return sp.getStartPosition(p.getCompilationUnit(), p.getLeaf()); 219 } 220 shouldCheck(CompilationUnitTree unit)221 boolean shouldCheck(CompilationUnitTree unit) { 222 if (includePackages == null) 223 return true; 224 225 String packageName = unit.getPackageName() != null 226 ? unit.getPackageName().toString() 227 : ""; 228 229 if (!includePackages.isEmpty()) { 230 boolean included = false; 231 for (Pattern pack : includePackages) { 232 if (pack.matcher(packageName).matches()) { 233 included = true; 234 break; 235 } 236 } 237 if (!included) 238 return false; 239 } 240 241 for (Pattern pack : excludePackages) { 242 if (pack.matcher(packageName).matches()) { 243 return false; 244 } 245 } 246 247 return true; 248 } 249 min(T item1, T item2)250 private <T extends Comparable<T>> T min(T item1, T item2) { 251 return (item1 == null) ? item2 252 : (item2 == null) ? item1 253 : item1.compareTo(item2) <= 0 ? item1 : item2; 254 } 255 } 256