KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > source > pretty > WidthEstimator


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

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 /** Estimate the printed width of a tree
32  */

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 JavaDoc 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++; // '@'
168
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 JavaDoc)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