1 19 package org.netbeans.modules.java.source.pretty; 20 21 import com.sun.tools.javac.util.*; 22 import com.sun.tools.javac.code.*; 23 import com.sun.tools.javac.code.Symbol.*; 24 import com.sun.tools.javac.tree.JCTree; 25 import com.sun.tools.javac.tree.JCTree.*; 26 import com.sun.tools.javac.tree.TreeInfo; 27 28 import static com.sun.tools.javac.code.Flags.*; 29 import static com.sun.tools.javac.code.TypeTags.*; 30 31 33 public class WidthEstimator extends Visitor { 34 private int width; 35 private int prec; 36 private int maxwidth; 37 private final Symtab symbols; 38 private final TreeInfo treeinfo; 39 40 public WidthEstimator(Context context) { 41 symbols = Symtab.instance(context); 42 treeinfo = TreeInfo.instance(context); 43 } 44 45 public int estimateWidth(JCTree t, int maxwidth) { 46 width = 0; 47 this.maxwidth = maxwidth; 48 t.accept(this); 49 return width; 50 } 51 public int estimateWidth(JCTree t) { 52 return estimateWidth(t,100); 53 } 54 private void open(int contextPrec, int ownPrec) { 55 if (ownPrec < contextPrec) 56 width += 2; 57 } 58 private void width(Name n) { width += n.len; } 59 private void width(String n) { width += n.length(); } 60 private void width(JCTree n) { if(width<maxwidth) n.accept(this); } 61 private void width(JCTree n, Type t) { if(t==null) width(n); else width(t); } 62 private ImportAnalysis imports; 63 public void setImports(ImportAnalysis i) { 64 imports = i; 65 } 66 public ImportAnalysis getImports() { return imports; } 67 private void width(Type ty) { 68 while(ty instanceof Type.ArrayType) { 69 ty = ((Type.ArrayType)ty).elemtype; 70 width+=2; 71 } 72 widthQ(ty.tsym); 73 if (ty instanceof Type.ClassType) { 74 List < Type > typarams = ((Type.ClassType) ty).typarams_field; 75 if (typarams != null && typarams.nonEmpty()) { 76 width++; 77 for (; typarams.nonEmpty(); typarams = typarams.tail) { 78 width++; 79 width(typarams.head); 80 } 81 } 82 } 83 } 84 public void widthQ(Symbol t) { 85 if (t.owner != null && t.owner != symbols.rootPackage && t.owner != symbols.unnamedPackage 86 && !(t.type instanceof Type.TypeVar) 87 && (imports == null || !imports.imported(t)) && !(t.owner instanceof MethodSymbol)) { 88 width++; 89 widthQ(t.owner); 90 } 91 width(t.name); 92 } 93 private void width(List<? extends JCTree> n, int pad) { 94 int nadd = 0; 95 while(!n.isEmpty() && width<maxwidth) { 96 width(n.head); 97 n = n.tail; 98 nadd++; 99 } 100 if(nadd>1) width += pad*nadd; 101 } 102 private void width(List<? extends JCTree> n) { 103 width(n, 2); 104 } 105 private void width(JCTree tree, int prec) { 106 if (tree != null) { 107 int prevPrec = this.prec; 108 this.prec = prec; 109 tree.accept(this); 110 this.prec = prevPrec; 111 } 112 } 113 public void visitTree(JCTree tree) { 114 System.err.println("Need width calc for "+tree); 115 width = maxwidth; 116 } 117 public void visitParens(JCParens tree) { 118 width+=2; 119 width(tree.expr); 120 } 121 public void visitApply(JCMethodInvocation tree) { 122 width+=2; 123 width(tree.meth, TreeInfo.postfixPrec); 124 width(tree.args); 125 } 126 public void visitNewClass(JCNewClass tree) { 127 if (tree.encl != null) { 128 width(tree.encl); 129 width++; 130 } 131 width+=4; 132 if (tree.encl == null) 133 width(tree.clazz, tree.clazz.type); 134 else if (tree.clazz.type != null) 135 width(tree.clazz.type.tsym.name); 136 else 137 width(tree.clazz); 138 width+=2; 139 width(tree.args, 2); 140 if (tree.def != null) { 141 width+=4; 142 width(((JCClassDecl) tree.def).defs, 2); 143 } 144 } 145 public void visitNewArray(JCNewArray tree) { 146 if (tree.elemtype != null) { 147 width+=4; 148 JCTree elemtype = tree.elemtype; 149 while (elemtype.tag == JCTree.TYPEARRAY) { 150 width+=2; 151 elemtype = ((JCArrayTypeTree) elemtype).elemtype; 152 } 153 width(elemtype); 154 for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) { 155 width+=2; 156 width(l.head); 157 } 158 } 159 if (tree.elems != null) { 160 width+=4; 161 width(tree.elems); 162 } 163 } 164 private void widthAnnotations(List<JCAnnotation> anns) { 165 int nadd = 0; 166 while(!anns.isEmpty() && width<maxwidth) { 167 width++; width(anns.head); 169 anns = anns.tail; 170 nadd++; 171 } 172 if(nadd>1) width += nadd; 173 174 } 175 private void widthFlags(long flags) { 176 if ((flags & SYNTHETIC) != 0) 177 width+=14; 178 width+=treeinfo.flagNames(flags).length(); 179 if ((flags & StandardFlags) != 0) 180 width++; 181 } 182 public void visitVarDef(JCVariableDecl tree) { 183 widthAnnotations(tree.mods.annotations); 184 widthFlags(tree.mods.flags); 185 width(tree.vartype, tree.type); 186 width++; 187 width(tree.name); 188 if (tree.init != null) { 189 width+=3; 190 width(tree.init); 191 } 192 } 193 public void visitConditional(JCConditional tree) { 194 open(prec, TreeInfo.condPrec); 195 width+=6; 196 width(tree.cond, TreeInfo.condPrec-1); 197 width(tree.truepart, TreeInfo.condPrec); 198 width(tree.falsepart, TreeInfo.condPrec); 199 } 200 201 public void visitAssignop(JCAssignOp tree) { 202 open(prec, TreeInfo.assignopPrec); 203 width+=3; 204 width(treeinfo.operatorName(tree.tag - JCTree.ASGOffset)); 205 width(tree.lhs, TreeInfo.assignopPrec + 1); 206 width(tree.rhs, TreeInfo.assignopPrec); 207 } 208 public void visitAssign(JCAssign tree) { 209 open(prec, TreeInfo.assignPrec); 210 width+=3; 211 width(tree.lhs, TreeInfo.assignPrec + 1); 212 width(tree.rhs, TreeInfo.assignPrec); 213 } 214 public void visitUnary(JCUnary tree) { 215 int ownprec = treeinfo.opPrec(tree.tag); 216 Name opname = treeinfo.operatorName(tree.tag); 217 open(prec, ownprec); 218 width(opname); 219 width(tree.arg, ownprec); 220 } 221 public void visitBinary(JCBinary tree) { 222 int ownprec = treeinfo.opPrec(tree.tag); 223 Name opname = treeinfo.operatorName(tree.tag); 224 open(prec, ownprec); 225 width(opname); 226 width+=2; 227 width(tree.lhs, ownprec); 228 width(tree.rhs, ownprec + 1); 229 } 230 public void visitTypeCast(JCTypeCast tree) { 231 width+=2; 232 open(prec, TreeInfo.prefixPrec); 233 width(tree.clazz, tree.clazz.type); 234 width(tree.expr, TreeInfo.prefixPrec); 235 } 236 237 public void visitTypeTest(JCInstanceOf tree) { 238 open(prec, TreeInfo.ordPrec); 239 width += 12; 240 width(tree.expr, TreeInfo.ordPrec); 241 width(tree.clazz, tree.clazz.type); 242 } 243 244 public void visitIndexed(JCArrayAccess tree) { 245 width+=2; 246 width(tree.indexed, TreeInfo.postfixPrec); 247 width(tree.index); 248 } 249 250 public void visitSelect(JCFieldAccess tree) { 251 if (tree.sym instanceof Symbol.ClassSymbol && tree.type != null) { 252 width(tree.type); 253 } else { 254 width+=1; 255 width(tree.selected, TreeInfo.postfixPrec); 256 width(tree.name); 257 } 258 } 259 260 public void visitIdent(JCIdent tree) { 261 if (tree.sym instanceof Symbol.ClassSymbol) 262 width(tree.type); 263 else width(tree.name); 264 } 265 266 public void visitLiteral(JCLiteral tree) { 267 switch (tree.typetag) { 268 case LONG: 269 case FLOAT: 270 width++; 271 width(tree.value.toString()); 272 break; 273 case CHAR: 274 width += 3; 275 break; 276 case CLASS: 277 width+=2; 278 width(tree.value.toString()); 279 break; 280 case BOOLEAN: 281 width(((Number )tree.value).intValue() == 1 ? "true" : "false"); 282 break; 283 case BOT: 284 width("null"); 285 break; 286 default: 287 width(tree.value.toString()); 288 } 289 } 290 291 public void visitTypeIdent(JCPrimitiveTypeTree tree) { 292 width(symbols.typeOfTag[tree.typetag].tsym.name); 293 } 294 295 public void visitTypeArray(JCArrayTypeTree tree) { 296 width(tree.elemtype); 297 width+=2; 298 } 299 300 } 301 | Popular Tags |