1 /* 2 * Copyright (c) 2003, 2018, 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 com.sun.tools.javadoc.main; 27 28 import com.sun.source.util.TreePath; 29 import com.sun.tools.javac.code.Flags; 30 import com.sun.tools.javac.code.Symbol.*; 31 import com.sun.tools.javac.comp.MemberEnter; 32 import com.sun.tools.javac.tree.JCTree; 33 import com.sun.tools.javac.tree.JCTree.*; 34 import com.sun.tools.javac.util.Context; 35 36 import static com.sun.tools.javac.code.Flags.*; 37 import static com.sun.tools.javac.code.Kinds.Kind.*; 38 39 /** 40 * Javadoc's own memberEnter phase does a few things above and beyond that 41 * done by javac. 42 * 43 * <p><b>This is NOT part of any supported API. 44 * If you write code that depends on this, you do so at your own risk. 45 * This code and its internal interfaces are subject to change or 46 * deletion without notice.</b> 47 * 48 * @author Neal Gafter 49 */ 50 @Deprecated(since="9", forRemoval=true) 51 @SuppressWarnings("removal") 52 public class JavadocMemberEnter extends MemberEnter { instance0(Context context)53 public static JavadocMemberEnter instance0(Context context) { 54 MemberEnter instance = context.get(memberEnterKey); 55 if (instance == null) 56 instance = new JavadocMemberEnter(context); 57 return (JavadocMemberEnter)instance; 58 } 59 preRegister(Context context)60 public static void preRegister(Context context) { 61 context.put(memberEnterKey, (Context.Factory<MemberEnter>)JavadocMemberEnter::new); 62 } 63 64 final DocEnv docenv; 65 JavadocMemberEnter(Context context)66 protected JavadocMemberEnter(Context context) { 67 super(context); 68 docenv = DocEnv.instance(context); 69 } 70 71 @Override visitMethodDef(JCMethodDecl tree)72 public void visitMethodDef(JCMethodDecl tree) { 73 super.visitMethodDef(tree); 74 MethodSymbol meth = tree.sym; 75 if (meth == null || meth.kind != MTH) return; 76 TreePath treePath = docenv.getTreePath(env.toplevel, env.enclClass, tree); 77 if (meth.isConstructor()) 78 docenv.makeConstructorDoc(meth, treePath); 79 else if (isAnnotationTypeElement(meth)) 80 docenv.makeAnnotationTypeElementDoc(meth, treePath); 81 else 82 docenv.makeMethodDoc(meth, treePath); 83 84 // release resources 85 tree.body = null; 86 } 87 88 @Override visitVarDef(JCVariableDecl tree)89 public void visitVarDef(JCVariableDecl tree) { 90 if (tree.init != null) { 91 boolean isFinal = (tree.mods.flags & FINAL) != 0 92 || (env.enclClass.mods.flags & INTERFACE) != 0; 93 if (!isFinal || containsNonConstantExpression(tree.init)) { 94 // Avoid unnecessary analysis and release resources. 95 // In particular, remove non-constant expressions 96 // which may trigger Attr.attribClass, since 97 // method bodies are also removed, in visitMethodDef. 98 tree.init = null; 99 } 100 } 101 super.visitVarDef(tree); 102 if (tree.sym != null && 103 tree.sym.kind == VAR && 104 !isParameter(tree.sym)) { 105 docenv.makeFieldDoc(tree.sym, docenv.getTreePath(env.toplevel, env.enclClass, tree)); 106 } 107 } 108 isAnnotationTypeElement(MethodSymbol meth)109 private static boolean isAnnotationTypeElement(MethodSymbol meth) { 110 return ClassDocImpl.isAnnotationType(meth.enclClass()); 111 } 112 isParameter(VarSymbol var)113 private static boolean isParameter(VarSymbol var) { 114 return (var.flags() & Flags.PARAMETER) != 0; 115 } 116 117 /** 118 * Simple analysis of an expression tree to see if it contains tree nodes 119 * for any non-constant expression. This does not include checking references 120 * to other fields which may or may not be constant. 121 */ containsNonConstantExpression(JCExpression tree)122 private static boolean containsNonConstantExpression(JCExpression tree) { 123 return new MaybeConstantExpressionScanner().containsNonConstantExpression(tree); 124 } 125 126 /** 127 * See JLS 15.18, Constant Expression 128 */ 129 private static class MaybeConstantExpressionScanner extends JCTree.Visitor { 130 boolean maybeConstantExpr = true; 131 containsNonConstantExpression(JCExpression tree)132 public boolean containsNonConstantExpression(JCExpression tree) { 133 scan(tree); 134 return !maybeConstantExpr; 135 } 136 scan(JCTree tree)137 public void scan(JCTree tree) { 138 // short circuit scan when end result is definitely false 139 if (maybeConstantExpr && tree != null) 140 tree.accept(this); 141 } 142 143 @Override 144 /** default for any non-overridden visit method. */ visitTree(JCTree tree)145 public void visitTree(JCTree tree) { 146 maybeConstantExpr = false; 147 } 148 149 @Override visitBinary(JCBinary tree)150 public void visitBinary(JCBinary tree) { 151 switch (tree.getTag()) { 152 case MUL: case DIV: case MOD: 153 case PLUS: case MINUS: 154 case SL: case SR: case USR: 155 case LT: case LE: case GT: case GE: 156 case EQ: case NE: 157 case BITAND: case BITXOR: case BITOR: 158 case AND: case OR: 159 break; 160 default: 161 maybeConstantExpr = false; 162 } 163 } 164 165 @Override visitConditional(JCConditional tree)166 public void visitConditional(JCConditional tree) { 167 scan(tree.cond); 168 scan(tree.truepart); 169 scan(tree.falsepart); 170 } 171 172 @Override visitIdent(JCIdent tree)173 public void visitIdent(JCIdent tree) { } 174 175 @Override visitLiteral(JCLiteral tree)176 public void visitLiteral(JCLiteral tree) { } 177 178 @Override visitParens(JCParens tree)179 public void visitParens(JCParens tree) { 180 scan(tree.expr); 181 } 182 183 @Override visitSelect(JCTree.JCFieldAccess tree)184 public void visitSelect(JCTree.JCFieldAccess tree) { 185 scan(tree.selected); 186 } 187 188 @Override visitTypeCast(JCTypeCast tree)189 public void visitTypeCast(JCTypeCast tree) { 190 scan(tree.clazz); 191 scan(tree.expr); 192 } 193 194 @Override visitTypeIdent(JCPrimitiveTypeTree tree)195 public void visitTypeIdent(JCPrimitiveTypeTree tree) { } 196 197 @Override visitUnary(JCUnary tree)198 public void visitUnary(JCUnary tree) { 199 switch (tree.getTag()) { 200 case POS: case NEG: case COMPL: case NOT: 201 break; 202 default: 203 maybeConstantExpr = false; 204 } 205 } 206 } 207 } 208