001: /* TabbedPrintWriter Copyright (C) 1998-2002 Jochen Hoenicke.
002: *
003: * This program is free software; you can redistribute it and/or modify
004: * it under the terms of the GNU Lesser General Public License as published by
005: * the Free Software Foundation; either version 2, or (at your option)
006: * any later version.
007: *
008: * This program is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
011: * GNU General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public License
014: * along with this program; see the file COPYING.LESSER. If not, write to
015: * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
016: *
017: * $Id: TabbedPrintWriter.java,v 4.20.2.4 2002/05/28 17:34:03 hoenicke Exp $
018: */
019:
020: package jode.decompiler;
021:
022: import java.io.*;
023: import java.util.Stack;
024: import java.util.Vector;
025: import java.util.Enumeration;
026: import jode.AssertError;
027: import jode.GlobalOptions;
028: import jode.bytecode.ClassInfo;
029: import jode.bytecode.InnerClassInfo;
030: import jode.type.*;
031:
032: public class TabbedPrintWriter {
033: /* The indentation size. */
034: private int indentsize;
035: /* The size of a tab, MAXINT if we shouldn't use tabs at all. */
036: private int tabWidth;
037: private int lineWidth;
038: private int currentIndent = 0;
039: private String indentStr = "";
040: private PrintWriter pw;
041: private ImportHandler imports;
042: private Stack scopes = new Stack();
043:
044: private StringBuffer currentLine;
045: private BreakPoint currentBP;
046: public final static int EXPL_PAREN = 0;
047: public final static int NO_PAREN = 1;
048: public final static int IMPL_PAREN = 2;
049: public final static int DONT_BREAK = 3;
050:
051: /**
052: * Convert the numeric indentation to a string.
053: */
054: protected String makeIndentStr(int indent) {
055: String tabSpaceString = /* (tab x 20) . (space x 20) */
056: "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ";
057: if (indent < 0)
058: return "NEGATIVEINDENT" + indent;
059:
060: int tabs = indent / tabWidth;
061: indent -= tabs * tabWidth;
062: if (tabs <= 20 && indent <= 20) {
063: /* The fast way. */
064: return tabSpaceString.substring(20 - tabs, 20 + indent);
065: } else {
066: /* the not so fast way */
067: StringBuffer sb = new StringBuffer(tabs + indent);
068: while (tabs > 20) {
069: sb.append(tabSpaceString.substring(0, 20));
070: tabs -= 20;
071: }
072: sb.append(tabSpaceString.substring(0, tabs));
073: while (indent > 20) {
074: sb.append(tabSpaceString.substring(20));
075: indent -= 20;
076: }
077: sb.append(tabSpaceString.substring(40 - indent));
078: return sb.toString();
079: }
080: }
081:
082: class BreakPoint {
083: int options;
084: int breakPenalty;
085: int breakPos;
086: int startPos;
087: BreakPoint parentBP;
088: Vector childBPs;
089: int nesting = 0;
090: int endPos;
091: int whatBreak = 0;
092:
093: public BreakPoint(BreakPoint parent, int position) {
094: this .breakPos = position;
095: this .parentBP = parent;
096: this .options = DONT_BREAK;
097: this .breakPenalty = 0;
098: this .startPos = -1;
099: this .endPos = -1;
100: this .whatBreak = 0;
101: this .childBPs = null;
102: }
103:
104: public void startOp(int opts, int penalty, int pos) {
105: if (startPos != -1)
106: throw new InternalError("missing breakOp");
107: startPos = pos;
108: options = opts;
109: breakPenalty = penalty;
110: childBPs = new Vector();
111: breakOp(pos);
112: }
113:
114: public void breakOp(int pos) {
115: childBPs.addElement(new BreakPoint(this , pos));
116: }
117:
118: public void endOp(int pos) {
119: endPos = pos;
120: if (childBPs.size() == 1) {
121: /* There is no breakpoint in this op, replace this with
122: * our child, if possible.
123: */
124: BreakPoint child = (BreakPoint) childBPs.elementAt(0);
125: options = Math.min(options, child.options);
126: startPos = child.startPos;
127: endPos = child.endPos;
128: breakPenalty = child.breakPenalty;
129: childBPs = child.childBPs;
130: }
131: }
132:
133: public void dump(String line) {
134: if (startPos == -1) {
135: pw.print(line);
136: } else {
137: pw.print(line.substring(0, startPos));
138: dumpRegion(line);
139: pw.print(line.substring(endPos));
140: }
141: }
142:
143: public void dumpRegion(String line) {
144: String parens = "{\010{}\010}<\010<>\010>[\010[]\010]`\010`'\010'"
145: .substring(options*6, options*6+6);
146: pw.print(parens.substring(0,3));
147: Enumeration enum = childBPs.elements();
148: int cur = startPos;
149: BreakPoint child = (BreakPoint) enum.nextElement();
150: if (child.startPos >= 0) {
151: pw.print(line.substring(cur, child.startPos));
152: child.dumpRegion(line);
153: cur = child.endPos;
154: }
155: while (enum.hasMoreElements()) {
156: child = (BreakPoint) enum.nextElement();
157: pw.print(line.substring(cur, child.breakPos));
158: pw.print("!\010!"+breakPenalty);
159: cur = child.breakPos;
160: if (child.startPos >= 0) {
161: pw.print(line.substring(child.breakPos, child.startPos));
162: child.dumpRegion(line);
163: cur = child.endPos;
164: }
165: }
166: pw.print(line.substring(cur, endPos));
167: pw.print(parens.substring(3));
168: }
169:
170: public void printLines(int indent, String line) {
171: if (startPos == -1) {
172: pw.print(line);
173: } else {
174: pw.print(line.substring(0, startPos));
175: printRegion(indent + startPos, line);
176: pw.print(line.substring(endPos));
177: }
178: }
179:
180: public void printRegion(int indent, String line) {
181: if (options == IMPL_PAREN) {
182: pw.print("(");
183: indent++;
184: }
185:
186: Enumeration enum = childBPs.elements();
187: int cur = startPos;
188: BreakPoint child = (BreakPoint) enum.nextElement();
189: if (child.startPos >= 0) {
190: pw.print(line.substring(cur, child.startPos));
191: child.printRegion(indent + child.startPos - cur, line);
192: cur = child.endPos;
193: }
194: if (options == NO_PAREN)
195: indent += indentsize;
196: String indentStr = makeIndentStr(indent);
197: while (enum.hasMoreElements()) {
198: child = (BreakPoint) enum.nextElement();
199: pw.print(line.substring(cur, child.breakPos));
200: pw.println();
201: pw.print(indentStr);
202: cur = child.breakPos;
203: if (cur < endPos && line.charAt(cur) == ' ')
204: cur++;
205: if (child.startPos >= 0) {
206: pw.print(line.substring(cur, child.startPos));
207: child.printRegion(indent + child.startPos - cur, line);
208: cur = child.endPos;
209: }
210: }
211: pw.print(line.substring(cur, endPos));
212: if (options == IMPL_PAREN)
213: pw.print(")");
214: }
215:
216: public BreakPoint commitMinPenalty(int space, int lastSpace,
217: int minPenalty) {
218: if (startPos == -1
219: || lastSpace > endPos - startPos
220: || minPenalty == 10 * (endPos - startPos - lastSpace)) {
221: /* We don't have to break anything */
222: startPos = -1;
223: childBPs = null;
224: return this ;
225: }
226:
227: int size = childBPs.size();
228: if (size > 1 && options != DONT_BREAK) {
229: /* penalty if we are breaking the line here. */
230: int breakPen = getBreakPenalty(space, lastSpace,
231: minPenalty + 1);
232: // pw.print("commit[bp="+breakPen+";"+minPenalty+";"
233: // +space+","+lastSpace+"]");
234: if (minPenalty == breakPen) {
235: commitBreakPenalty(space, lastSpace, breakPen);
236: return this ;
237: }
238: }
239:
240: /* penalty if we are breaking only one child */
241: for (int i = 0; i < size; i++) {
242: BreakPoint child = (BreakPoint) childBPs.elementAt(i);
243: int front = child.startPos - startPos;
244: int tail = endPos - child.endPos;
245: int needPenalty = minPenalty - (i < size - 1 ? 1 : 0);
246: if (needPenalty == child.getMinPenalty(space - front,
247: lastSpace - front - tail, needPenalty + 1)) {
248: child = child.commitMinPenalty(space - front,
249: lastSpace - front - tail, needPenalty);
250: child.breakPos = breakPos;
251: return child;
252: }
253: }
254: pw.println("XXXXXXXXXXX CAN'T COMMIT");
255: startPos = -1;
256: childBPs = null;
257: return this ;
258: }
259:
260: public int getMinPenalty(int space, int lastSpace,
261: int minPenalty) {
262: // pw.print("getMinPenalty["+startPos+","+endPos+"]("+space+","+lastSpace+","+minPenalty+") ");
263: if (10 * -lastSpace >= minPenalty) {
264: // pw.println("= minPenalty");
265: return minPenalty;
266: }
267:
268: if (startPos == -1)
269: return 10 * -lastSpace;
270:
271: if (lastSpace > endPos - startPos) {
272: // pw.println("= NULL");
273: return 0;
274: }
275:
276: if (minPenalty <= 1) {
277: // pw.println("= ONE");
278: return minPenalty;
279: }
280:
281: if (minPenalty > 10 * (endPos - startPos - lastSpace))
282: minPenalty = 10 * (endPos - startPos - lastSpace);
283:
284: // pw.print("[mp="+minPenalty+"]");
285:
286: int size = childBPs.size();
287: if (size == 0)
288: return minPenalty;
289:
290: if (size > 1 && options != DONT_BREAK) {
291: /* penalty if we are breaking at this level. */
292: minPenalty = getBreakPenalty(space, lastSpace,
293: minPenalty);
294: // pw.print("[bp="+minPenalty+"]");
295: }
296:
297: /* penalty if we are breaking only one child */
298: for (int i = 0; i < size; i++) {
299: BreakPoint child = (BreakPoint) childBPs.elementAt(i);
300: int front = child.startPos - startPos;
301: int tail = endPos - child.endPos;
302: int penalty = (i < size - 1 ? 1 : 0);
303: minPenalty = penalty
304: + child.getMinPenalty(space - front, lastSpace
305: - front - tail, minPenalty - penalty);
306: }
307: // pw.println("= "+minPenalty);
308: return minPenalty;
309: }
310:
311: public void commitBreakPenalty(int space, int lastSpace,
312: int minPenalty) {
313:// pw.println("commitBreakPenalty: "+startPos+","+endPos+";"
314:// +space+","+lastSpace+";"+minPenalty);
315:
316: if (options == IMPL_PAREN) {
317: space--;
318: lastSpace -= 2;
319: }
320:
321: Enumeration enum = childBPs.elements();
322: childBPs = new Vector();
323: int currInd = 0;
324: BreakPoint lastChild, nextChild;
325: boolean indentNext = options == NO_PAREN;
326: for (lastChild = (BreakPoint) enum.nextElement();
327: enum.hasMoreElements(); lastChild = nextChild) {
328: nextChild = (BreakPoint) enum.nextElement();
329: int childStart = lastChild.breakPos;
330: int childEnd = nextChild.breakPos;
331:
332: if (currInd > 0) {
333: currInd += childEnd - childStart;
334: if (currInd <= space)
335: continue;
336: }
337: if (childStart < endPos
338: && currentLine.charAt(childStart) == ' ')
339: childStart++;
340:
341: if (childEnd - childStart > space) {
342: int front = lastChild.startPos - childStart;
343: int tail = childEnd - lastChild.endPos;
344: int childPenalty = lastChild.getMinPenalty
345: (space - front, space - front - tail, minPenalty);
346: currInd = 0;
347: childBPs.addElement
348: (lastChild.commitMinPenalty
349: (space - front, space - front - tail, childPenalty));
350: } else {
351: lastChild.startPos = -1;
352: lastChild.childBPs = null;
353: childBPs.addElement(lastChild);
354: currInd = childEnd - childStart;
355: }
356:
357: if (indentNext) {
358: space -= indentsize;
359: lastSpace -= indentsize;
360: indentNext = false;
361: }
362: }
363: int childStart = lastChild.breakPos;
364: if (currInd > 0 && currInd + endPos - childStart <= lastSpace)
365: return;
366:
367: if (childStart < endPos
368: && currentLine.charAt(childStart) == ' ')
369: childStart++;
370: if (endPos - childStart > lastSpace) {
371: int front = lastChild.startPos - childStart;
372: int tail = endPos - lastChild.endPos;
373: int childPenalty = lastChild.getMinPenalty
374: (space - front, lastSpace - front - tail, minPenalty + 1);
375: childBPs.addElement
376: (lastChild.commitMinPenalty
377: (space - front, lastSpace - front - tail, childPenalty));
378: } else {
379: lastChild.startPos = -1;
380: lastChild.childBPs = null;
381: childBPs.addElement(lastChild);
382: }
383: }
384:
385: public int getBreakPenalty(int space, int lastSpace, int minPenalty) {
386: int penalty = breakPenalty;
387: int currInd = 0;
388: if (options == IMPL_PAREN) {
389: space--;
390: lastSpace -= 2;
391: }
392: if (space < 0)
393: return minPenalty;
394: Enumeration enum = childBPs.elements();
395: BreakPoint lastChild, nextChild;
396: boolean indentNext = options == NO_PAREN;
397: for (lastChild = (BreakPoint) enum.nextElement();
398: enum.hasMoreElements(); lastChild = nextChild) {
399: nextChild = (BreakPoint) enum.nextElement();
400: int childStart = lastChild.breakPos;
401: int childEnd = nextChild.breakPos;
402:
403: if (currInd > 0) {
404: currInd += childEnd - childStart;
405: if (currInd <= space)
406: continue;
407:
408: penalty++;
409: if (indentNext) {
410: space -= indentsize;
411: lastSpace -= indentsize;
412: indentNext = false;
413: }
414: }
415:
416: if (childStart < endPos
417: && currentLine.charAt(childStart) == ' ')
418: childStart++;
419:
420: if (childEnd - childStart > space) {
421: int front = lastChild.startPos - childStart;
422: int tail = childEnd - lastChild.endPos;
423: penalty += 1 + lastChild.getMinPenalty
424: (space - front, space - front - tail,
425: minPenalty - penalty - 1);
426:
427: if (indentNext) {
428: space -= indentsize;
429: lastSpace -= indentsize;
430: indentNext = false;
431: }
432: currInd = 0;
433: } else
434: currInd = childEnd - childStart;
435:
436: if (penalty >= minPenalty)
437: return minPenalty;
438: }
439: int childStart = lastChild.breakPos;
440: if (currInd > 0) {
441: if (currInd + endPos - childStart <= lastSpace)
442: return penalty;
443:
444: penalty++;
445: if (indentNext) {
446: space -= indentsize;
447: lastSpace -= indentsize;
448: indentNext = false;
449: }
450: }
451: if (childStart < endPos
452: && currentLine.charAt(childStart) == ' ')
453: childStart++;
454: if (endPos - childStart > lastSpace) {
455: int front = lastChild.startPos - childStart;
456: int tail = endPos - lastChild.endPos;
457: penalty += lastChild.getMinPenalty
458: (space - front, lastSpace - front - tail,
459: minPenalty - penalty);
460: }
461: if (penalty < minPenalty)
462: return penalty;
463: return minPenalty;
464: }
465: }
466:
467: public TabbedPrintWriter(OutputStream os, ImportHandler imports,
468: boolean autoFlush) {
469: pw = new PrintWriter(os, autoFlush);
470: this .imports = imports;
471: init();
472: }
473:
474: public TabbedPrintWriter(Writer os, ImportHandler imports,
475: boolean autoFlush) {
476: pw = new PrintWriter(os, autoFlush);
477: this .imports = imports;
478: init();
479: }
480:
481: public TabbedPrintWriter(OutputStream os, ImportHandler imports) {
482: this (os, imports, true);
483: }
484:
485: public TabbedPrintWriter(Writer os, ImportHandler imports) {
486: this (os, imports, true);
487: }
488:
489: public TabbedPrintWriter(OutputStream os) {
490: this (os, null);
491: }
492:
493: public TabbedPrintWriter(Writer os) {
494: this (os, null);
495: }
496:
497: public void init() {
498: this .indentsize = (Options.outputStyle & Options.TAB_SIZE_MASK);
499: this .tabWidth = 8;
500: this .lineWidth = 79;
501: currentLine = new StringBuffer();
502: currentBP = new BreakPoint(null, 0);
503: currentBP.startOp(DONT_BREAK, 1, 0);
504: }
505:
506: public void tab() {
507: currentIndent += indentsize;
508: indentStr = makeIndentStr(currentIndent);
509: }
510:
511: public void untab() {
512: currentIndent -= indentsize;
513: indentStr = makeIndentStr(currentIndent);
514: }
515:
516: public void startOp(int options, int penalty) {
517: currentBP = (BreakPoint) currentBP.childBPs.lastElement();
518: currentBP.startOp(options, penalty, currentLine.length());
519: }
520:
521: public void breakOp() {
522: int pos = currentLine.length();
523: if (pos > currentBP.startPos
524: && currentLine.charAt(pos - 1) == ' ')
525: pos--;
526: currentBP.breakOp(pos);
527: }
528:
529: public void endOp() {
530: currentBP.endOp(currentLine.length());
531: currentBP = currentBP.parentBP;
532: if (currentBP == null)
533: throw new NullPointerException();
534: }
535:
536: public Object saveOps() {
537: Stack state = new Stack();
538: int pos = currentLine.length();
539: while (currentBP.parentBP != null) {
540: state.push(new Integer(currentBP.breakPenalty));
541: /* We don't want parentheses or unconventional line breaking */
542: currentBP.options = DONT_BREAK;
543: currentBP.endPos = pos;
544: currentBP = currentBP.parentBP;
545: }
546: return state;
547: }
548:
549: public void restoreOps(Object s) {
550: Stack state = (Stack) s;
551: while (!state.isEmpty()) {
552: int penalty = ((Integer) state.pop()).intValue();
553: startOp(DONT_BREAK, penalty);
554: }
555: }
556:
557: public void println(String str) {
558: print(str);
559: println();
560: }
561:
562: public void println() {
563: currentBP.endPos = currentLine.length();
564:
565: // pw.print(indentStr);
566: // currentBP.dump(currentLine.toString());
567: // pw.println();
568:
569: int lw = lineWidth - currentIndent;
570: int minPenalty = currentBP.getMinPenalty(lw, lw,
571: Integer.MAX_VALUE / 2);
572: currentBP = currentBP.commitMinPenalty(lw, lw, minPenalty);
573:
574: // pw.print(indentStr);
575: // currentBP.dump(currentLine.toString());
576: // pw.println();
577: pw.print(indentStr);
578: currentBP.printLines(currentIndent, currentLine.toString());
579: pw.println();
580:
581: currentLine.setLength(0);
582: currentBP = new BreakPoint(null, 0);
583: currentBP.startOp(DONT_BREAK, 1, 0);
584: }
585:
586: public void print(String str) {
587: currentLine.append(str);
588: }
589:
590: public void printType(Type type) {
591: print(getTypeString(type));
592: }
593:
594: public void pushScope(Scope scope) {
595: scopes.push(scope);
596: }
597:
598: public void popScope() {
599: scopes.pop();
600: }
601:
602: /**
603: * Checks if the name in inScope conflicts with an identifier in a
604: * higher scope.
605: */
606: public boolean conflicts(String name, Scope inScope, int context) {
607: int dot = name.indexOf('.');
608: if (dot >= 0)
609: name = name.substring(0, dot);
610: int count = scopes.size();
611: for (int ptr = count; ptr-- > 0;) {
612: Scope scope = (Scope) scopes.elementAt(ptr);
613: if (scope == inScope)
614: return false;
615: if (scope.conflicts(name, context)) {
616: return true;
617: }
618: }
619: return false;
620: }
621:
622: public Scope getScope(Object obj, int scopeType) {
623: int count = scopes.size();
624: for (int ptr = count; ptr-- > 0;) {
625: Scope scope = (Scope) scopes.elementAt(ptr);
626: if (scope.isScopeOf(obj, scopeType))
627: return scope;
628: }
629: return null;
630: }
631:
632: public String getInnerClassString(ClassInfo info, int scopeType) {
633: InnerClassInfo[] outers = info.getOuterClasses();
634: if (outers == null)
635: return null;
636: for (int i = 0; i < outers.length; i++) {
637: if (outers[i].name == null || outers[i].outer == null)
638: return null;
639: Scope scope = getScope(ClassInfo.forName(outers[i].outer),
640: Scope.CLASSSCOPE);
641: if (scope != null
642: && !conflicts(outers[i].name, scope, scopeType)) {
643: StringBuffer sb = new StringBuffer(outers[i].name);
644: for (int j = i; j-- > 0;) {
645: sb.append('.').append(outers[j].name);
646: }
647: return sb.toString();
648: }
649: }
650: String name = getClassString(ClassInfo
651: .forName(outers[outers.length - 1].outer), scopeType);
652: StringBuffer sb = new StringBuffer(name);
653: for (int j = outers.length; j-- > 0;)
654: sb.append('.').append(outers[j].name);
655: return sb.toString();
656: }
657:
658: public String getAnonymousClassString(ClassInfo info, int scopeType) {
659: InnerClassInfo[] outers = info.getOuterClasses();
660: if (outers == null)
661: return null;
662: for (int i = 0; i < outers.length; i++) {
663: if (outers[i].name == null)
664: return "ANONYMOUS CLASS " + info.getName();
665: Scope scope = getScope(info, Scope.METHODSCOPE);
666: if (scope != null
667: && !conflicts(outers[i].name, scope, scopeType)) {
668: StringBuffer sb = new StringBuffer(outers[i].name);
669: for (int j = i; j-- > 0;) {
670: sb.append('.').append(outers[j].name);
671: }
672: return sb.toString();
673: } else if (outers[i].outer == null) {
674: StringBuffer sb;
675: if (scope != null)
676: sb = new StringBuffer("NAME CONFLICT ");
677: else
678: sb = new StringBuffer("UNREACHABLE ");
679:
680: sb.append(outers[i].name);
681: for (int j = i; j-- > 0;) {
682: sb.append('.').append(outers[j].name);
683: }
684: return sb.toString();
685: }
686: }
687: String name = getClassString(ClassInfo
688: .forName(outers[outers.length - 1].outer), scopeType);
689: StringBuffer sb = new StringBuffer(name);
690: for (int j = outers.length; j-- > 0;)
691: sb.append('.').append(outers[j].name);
692: return sb.toString();
693: }
694:
695: public String getClassString(ClassInfo clazz, int scopeType) {
696: String name = clazz.getName();
697: if (name.indexOf('$') >= 0) {
698: if ((Options.options & Options.OPTION_INNER) != 0) {
699: String innerClassName = getInnerClassString(clazz,
700: scopeType);
701: if (innerClassName != null)
702: return innerClassName;
703: }
704: if ((Options.options & Options.OPTION_ANON) != 0) {
705: String innerClassName = getAnonymousClassString(clazz,
706: scopeType);
707: if (innerClassName != null)
708: return innerClassName;
709: }
710: }
711: if (imports != null) {
712: String importedName = imports.getClassString(clazz);
713: if (!conflicts(importedName, null, scopeType))
714: return importedName;
715: }
716: if (conflicts(name, null, Scope.AMBIGUOUSNAME))
717: return "PKGNAMECONFLICT " + name;
718: return name;
719: }
720:
721: public String getTypeString(Type type) {
722: if (type instanceof ArrayType)
723: return getTypeString(((ArrayType) type).getElementType())
724: + "[]";
725: else if (type instanceof ClassInterfacesType) {
726: ClassInfo clazz = ((ClassInterfacesType) type)
727: .getClassInfo();
728: return getClassString(clazz, Scope.CLASSNAME);
729: } else if (type instanceof NullType)
730: return "Object";
731: else
732: return type.toString();
733: }
734:
735: /**
736: * Print a opening brace with the current indentation style.
737: * Called at the end of the line of the instance that opens the
738: * brace. It doesn't do a tab stop after opening the brace.
739: */
740: public void openBrace() {
741: if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0) {
742: print(currentLine.length() > 0 ? " {" : "{");
743: println();
744: } else {
745: if (currentLine.length() > 0)
746: println();
747: if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
748: && currentIndent > 0)
749: tab();
750: println("{");
751: }
752: }
753:
754: public void openBraceClass() {
755: if (currentLine.length() > 0) {
756: if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0)
757: print(" ");
758: else
759: println();
760: }
761: println("{");
762: }
763:
764: /**
765: * Print a opening brace with the current indentation style.
766: * Called at the end the line of a method declaration.
767: */
768: public void openBraceNoIndent() {
769: if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0) {
770: print(currentLine.length() > 0 ? " {" : "{");
771: println();
772: } else {
773: if (currentLine.length() > 0)
774: println();
775: println("{");
776: }
777: }
778:
779: /**
780: * Print a opening brace with the current indentation style.
781: * Called at the end of the line of the instance that opens the
782: * brace. It doesn't do a tab stop after opening the brace.
783: */
784: public void openBraceNoSpace() {
785: if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0)
786: println("{");
787: else {
788: if (currentLine.length() > 0)
789: println();
790: if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
791: && currentIndent > 0)
792: tab();
793: println("{");
794: }
795: }
796:
797: public void closeBraceContinue() {
798: if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0)
799: print("} ");
800: else {
801: println("}");
802: if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
803: && currentIndent > 0)
804: untab();
805: }
806: }
807:
808: public void closeBraceClass() {
809: print("}");
810: }
811:
812: public void closeBrace() {
813: if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0)
814: println("}");
815: else {
816: println("}");
817: if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
818: && currentIndent > 0)
819: untab();
820: }
821: }
822:
823: public void closeBraceNoIndent() {
824: println("}");
825: }
826:
827: public void flush() {
828: pw.flush();
829: }
830:
831: public void close() {
832: pw.close();
833: }
834: }
|