JavadocMemberEnter.java revision 3827:44bdefe64114
1219019Sgabor/* 2219019Sgabor * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 3219019Sgabor * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4219019Sgabor * 5219019Sgabor * This code is free software; you can redistribute it and/or modify it 6219019Sgabor * under the terms of the GNU General Public License version 2 only, as 7219019Sgabor * published by the Free Software Foundation. Oracle designates this 8219019Sgabor * particular file as subject to the "Classpath" exception as provided 9219019Sgabor * by Oracle in the LICENSE file that accompanied this code. 10219019Sgabor * 11219019Sgabor * This code is distributed in the hope that it will be useful, but WITHOUT 12219019Sgabor * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13219019Sgabor * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14219019Sgabor * version 2 for more details (a copy is included in the LICENSE file that 15219019Sgabor * accompanied this code). 16219019Sgabor * 17219019Sgabor * You should have received a copy of the GNU General Public License version 18219019Sgabor * 2 along with this work; if not, write to the Free Software Foundation, 19219019Sgabor * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20219019Sgabor * 21219019Sgabor * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22219019Sgabor * or visit www.oracle.com if you need additional information or have any 23219019Sgabor * questions. 24219019Sgabor */ 25219019Sgabor 26219019Sgaborpackage com.sun.tools.javadoc.main; 27219019Sgabor 28219019Sgaborimport com.sun.source.util.TreePath; 29219019Sgaborimport com.sun.tools.javac.code.Flags; 30219019Sgaborimport com.sun.tools.javac.code.Symbol.*; 31219019Sgaborimport com.sun.tools.javac.comp.MemberEnter; 32219019Sgaborimport com.sun.tools.javac.tree.JCTree; 33219019Sgaborimport com.sun.tools.javac.tree.JCTree.*; 34219019Sgaborimport com.sun.tools.javac.util.Context; 35219019Sgabor 36219019Sgaborimport static com.sun.tools.javac.code.Flags.*; 37219019Sgaborimport static com.sun.tools.javac.code.Kinds.Kind.*; 38219019Sgabor 39219019Sgabor/** 40219019Sgabor * Javadoc's own memberEnter phase does a few things above and beyond that 41219019Sgabor * done by javac. 42219019Sgabor * 43219019Sgabor * <p><b>This is NOT part of any supported API. 44219019Sgabor * If you write code that depends on this, you do so at your own risk. 45219019Sgabor * This code and its internal interfaces are subject to change or 46219019Sgabor * deletion without notice.</b> 47219019Sgabor * 48219019Sgabor * @author Neal Gafter 49219019Sgabor */ 50219019Sgabor@Deprecated 51219019Sgaborpublic class JavadocMemberEnter extends MemberEnter { 52219019Sgabor public static JavadocMemberEnter instance0(Context context) { 53219019Sgabor MemberEnter instance = context.get(memberEnterKey); 54219019Sgabor if (instance == null) 55252547Speter instance = new JavadocMemberEnter(context); 56219019Sgabor return (JavadocMemberEnter)instance; 57219019Sgabor } 58219019Sgabor 59219019Sgabor public static void preRegister(Context context) { 60219019Sgabor context.put(memberEnterKey, (Context.Factory<MemberEnter>)JavadocMemberEnter::new); 61219019Sgabor } 62219019Sgabor 63219019Sgabor final DocEnv docenv; 64219019Sgabor 65 protected JavadocMemberEnter(Context context) { 66 super(context); 67 docenv = DocEnv.instance(context); 68 } 69 70 @Override 71 public void visitMethodDef(JCMethodDecl tree) { 72 super.visitMethodDef(tree); 73 MethodSymbol meth = tree.sym; 74 if (meth == null || meth.kind != MTH) return; 75 TreePath treePath = docenv.getTreePath(env.toplevel, env.enclClass, tree); 76 if (meth.isConstructor()) 77 docenv.makeConstructorDoc(meth, treePath); 78 else if (isAnnotationTypeElement(meth)) 79 docenv.makeAnnotationTypeElementDoc(meth, treePath); 80 else 81 docenv.makeMethodDoc(meth, treePath); 82 83 // release resources 84 tree.body = null; 85 } 86 87 @Override 88 public void visitVarDef(JCVariableDecl tree) { 89 if (tree.init != null) { 90 boolean isFinal = (tree.mods.flags & FINAL) != 0 91 || (env.enclClass.mods.flags & INTERFACE) != 0; 92 if (!isFinal || containsNonConstantExpression(tree.init)) { 93 // Avoid unnecessary analysis and release resources. 94 // In particular, remove non-constant expressions 95 // which may trigger Attr.attribClass, since 96 // method bodies are also removed, in visitMethodDef. 97 tree.init = null; 98 } 99 } 100 super.visitVarDef(tree); 101 if (tree.sym != null && 102 tree.sym.kind == VAR && 103 !isParameter(tree.sym)) { 104 docenv.makeFieldDoc(tree.sym, docenv.getTreePath(env.toplevel, env.enclClass, tree)); 105 } 106 } 107 108 private static boolean isAnnotationTypeElement(MethodSymbol meth) { 109 return ClassDocImpl.isAnnotationType(meth.enclClass()); 110 } 111 112 private static boolean isParameter(VarSymbol var) { 113 return (var.flags() & Flags.PARAMETER) != 0; 114 } 115 116 /** 117 * Simple analysis of an expression tree to see if it contains tree nodes 118 * for any non-constant expression. This does not include checking references 119 * to other fields which may or may not be constant. 120 */ 121 private static boolean containsNonConstantExpression(JCExpression tree) { 122 return new MaybeConstantExpressionScanner().containsNonConstantExpression(tree); 123 } 124 125 /** 126 * See JLS 15.18, Constant Expression 127 */ 128 private static class MaybeConstantExpressionScanner extends JCTree.Visitor { 129 boolean maybeConstantExpr = true; 130 131 public boolean containsNonConstantExpression(JCExpression tree) { 132 scan(tree); 133 return !maybeConstantExpr; 134 } 135 136 public void scan(JCTree tree) { 137 // short circuit scan when end result is definitely false 138 if (maybeConstantExpr && tree != null) 139 tree.accept(this); 140 } 141 142 @Override 143 /** default for any non-overridden visit method. */ 144 public void visitTree(JCTree tree) { 145 maybeConstantExpr = false; 146 } 147 148 @Override 149 public void visitBinary(JCBinary tree) { 150 switch (tree.getTag()) { 151 case MUL: case DIV: case MOD: 152 case PLUS: case MINUS: 153 case SL: case SR: case USR: 154 case LT: case LE: case GT: case GE: 155 case EQ: case NE: 156 case BITAND: case BITXOR: case BITOR: 157 case AND: case OR: 158 break; 159 default: 160 maybeConstantExpr = false; 161 } 162 } 163 164 @Override 165 public void visitConditional(JCConditional tree) { 166 scan(tree.cond); 167 scan(tree.truepart); 168 scan(tree.falsepart); 169 } 170 171 @Override 172 public void visitIdent(JCIdent tree) { } 173 174 @Override 175 public void visitLiteral(JCLiteral tree) { } 176 177 @Override 178 public void visitParens(JCParens tree) { 179 scan(tree.expr); 180 } 181 182 @Override 183 public void visitSelect(JCTree.JCFieldAccess tree) { 184 scan(tree.selected); 185 } 186 187 @Override 188 public void visitTypeCast(JCTypeCast tree) { 189 scan(tree.clazz); 190 scan(tree.expr); 191 } 192 193 @Override 194 public void visitTypeIdent(JCPrimitiveTypeTree tree) { } 195 196 @Override 197 public void visitUnary(JCUnary tree) { 198 switch (tree.getTag()) { 199 case POS: case NEG: case COMPL: case NOT: 200 break; 201 default: 202 maybeConstantExpr = false; 203 } 204 } 205 } 206} 207