comparison truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeBuilder.java @ 21951:9c8c0937da41

Moving all sources into truffle subdirectory
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 17 Jun 2015 10:58:08 +0200
parents graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeBuilder.java@476374f3fe9a
children dc83cc1f94f2
comparison
equal deleted inserted replaced
21950:2a5011c7e641 21951:9c8c0937da41
1 /*
2 * Copyright (c) 2012, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.oracle.truffle.dsl.processor.java.model;
24
25 import static com.oracle.truffle.dsl.processor.java.model.CodeTreeKind.*;
26
27 import java.util.*;
28
29 import javax.lang.model.element.*;
30 import javax.lang.model.type.*;
31
32 import com.oracle.truffle.dsl.processor.java.*;
33
34 public class CodeTreeBuilder {
35
36 private BuilderCodeTree currentElement;
37 private final BuilderCodeTree root;
38
39 private int treeCount;
40 private Element enclosingElement;
41
42 public CodeTreeBuilder(CodeTreeBuilder parent) {
43 this.root = new BuilderCodeTree(null, GROUP, null, null);
44 this.currentElement = root;
45 if (parent != null) {
46 this.enclosingElement = parent.enclosingElement;
47 }
48 }
49
50 public void setEnclosingElement(Element enclosingElement) {
51 this.enclosingElement = enclosingElement;
52 }
53
54 @Override
55 public String toString() {
56 return root.toString();
57 }
58
59 public int getTreeCount() {
60 return treeCount;
61 }
62
63 public boolean isEmpty() {
64 return treeCount == 0;
65 }
66
67 public CodeTreeBuilder statement(String statement) {
68 return startStatement().string(statement).end();
69 }
70
71 public CodeTreeBuilder statement(CodeTree statement) {
72 return startStatement().tree(statement).end();
73 }
74
75 public static CodeTreeBuilder createBuilder() {
76 return new CodeTreeBuilder(null);
77 }
78
79 public static CodeTree singleString(String s) {
80 return createBuilder().string(s).build();
81 }
82
83 public static CodeTree singleType(TypeMirror s) {
84 return createBuilder().type(s).build();
85 }
86
87 private CodeTreeBuilder push(CodeTreeKind kind) {
88 return push(new BuilderCodeTree(currentElement, kind, null, null), kind == NEW_LINE);
89 }
90
91 private CodeTreeBuilder push(String string) {
92 return push(new BuilderCodeTree(currentElement, CodeTreeKind.STRING, null, string), false);
93 }
94
95 private CodeTreeBuilder push(TypeMirror type) {
96 return push(new BuilderCodeTree(currentElement, CodeTreeKind.TYPE, type, null), false);
97 }
98
99 private CodeTreeBuilder push(CodeTreeKind kind, TypeMirror type, String string) {
100 return push(new BuilderCodeTree(currentElement, kind, type, string), kind == NEW_LINE);
101 }
102
103 private CodeTreeBuilder push(BuilderCodeTree tree, boolean removeLast) {
104 if (currentElement != null) {
105 if (removeLast && !removeLastIfEnqueued(tree)) {
106 return this;
107 }
108 currentElement.add(tree);
109 }
110 switch (tree.getCodeKind()) {
111 case COMMA_GROUP:
112 case GROUP:
113 case INDENT:
114 currentElement = tree;
115 break;
116 }
117 treeCount++;
118 return this;
119 }
120
121 private boolean removeLastIfEnqueued(BuilderCodeTree tree) {
122 if (tree.getCodeKind() == REMOVE_LAST) {
123 return !clearLastRec(tree.removeLast, currentElement.getEnclosedElements());
124 }
125 List<CodeTree> childTree = tree.getEnclosedElements();
126 if (childTree != null && !childTree.isEmpty()) {
127 CodeTree last = childTree.get(0);
128 if (last instanceof BuilderCodeTree) {
129 if (!removeLastIfEnqueued((BuilderCodeTree) last)) {
130 childTree.remove(0);
131 }
132 }
133 }
134 return true;
135 }
136
137 private void clearLast(CodeTreeKind kind) {
138 if (clearLastRec(kind, currentElement.getEnclosedElements())) {
139 treeCount--;
140 } else {
141 // delay clearing the last
142 BuilderCodeTree tree = new BuilderCodeTree(currentElement, REMOVE_LAST, null, null);
143 tree.removeLast = kind;
144 push(tree, false);
145 }
146 }
147
148 public CodeTreeBuilder startStatement() {
149 startGroup();
150 registerCallBack(new EndCallback() {
151
152 @Override
153 public void beforeEnd() {
154 string(";").newLine();
155 }
156
157 @Override
158 public void afterEnd() {
159 }
160 });
161 return this;
162 }
163
164 public CodeTreeBuilder startGroup() {
165 return push(CodeTreeKind.GROUP);
166 }
167
168 public CodeTreeBuilder startCommaGroup() {
169 return push(CodeTreeKind.COMMA_GROUP);
170 }
171
172 public CodeTreeBuilder startCall(String callSite) {
173 return startCall((CodeTree) null, callSite);
174 }
175
176 public CodeTreeBuilder startCall(String receiver, String callSite) {
177 if (receiver != null) {
178 return startCall(singleString(receiver), callSite);
179 } else {
180 return startCall(callSite);
181 }
182 }
183
184 public CodeTreeBuilder startCall(CodeTree receiver, String callSite) {
185 if (receiver == null) {
186 return startGroup().string(callSite).startParanthesesCommaGroup().endAfter();
187 } else {
188 return startGroup().tree(receiver).string(".").string(callSite).startParanthesesCommaGroup().endAfter();
189 }
190 }
191
192 public CodeTreeBuilder startStaticCall(TypeMirror type, String methodName) {
193 return startGroup().push(CodeTreeKind.STATIC_METHOD_REFERENCE, type, methodName).startParanthesesCommaGroup().endAfter();
194 }
195
196 public CodeTreeBuilder startStaticCall(ExecutableElement method) {
197 return startStaticCall(ElementUtils.findNearestEnclosingType(method).asType(), method.getSimpleName().toString());
198 }
199
200 public CodeTreeBuilder staticReference(TypeMirror type, String fieldName) {
201 return push(CodeTreeKind.STATIC_FIELD_REFERENCE, type, fieldName);
202 }
203
204 private CodeTreeBuilder endAndWhitespaceAfter() {
205 registerCallBack(new EndCallback() {
206
207 @Override
208 public void beforeEnd() {
209 }
210
211 @Override
212 public void afterEnd() {
213 string(" ");
214 end();
215 }
216 });
217 return this;
218 }
219
220 private CodeTreeBuilder endAfter() {
221 registerCallBack(new EndCallback() {
222
223 @Override
224 public void beforeEnd() {
225 }
226
227 @Override
228 public void afterEnd() {
229 end();
230 }
231 });
232 return this;
233 }
234
235 private CodeTreeBuilder startParanthesesCommaGroup() {
236 startGroup();
237 string("(").startCommaGroup();
238 registerCallBack(new EndCallback() {
239
240 @Override
241 public void beforeEnd() {
242 }
243
244 @Override
245 public void afterEnd() {
246 string(")");
247 }
248 });
249 endAfter();
250 return this;
251 }
252
253 private CodeTreeBuilder startCurlyBracesCommaGroup() {
254 startGroup();
255 string("{").startCommaGroup();
256 registerCallBack(new EndCallback() {
257
258 @Override
259 public void beforeEnd() {
260 }
261
262 @Override
263 public void afterEnd() {
264 string("}");
265 }
266 });
267 endAfter();
268 return this;
269 }
270
271 public CodeTreeBuilder startParantheses() {
272 startGroup();
273 string("(").startGroup();
274 registerCallBack(new EndCallback() {
275
276 @Override
277 public void beforeEnd() {
278 }
279
280 @Override
281 public void afterEnd() {
282 string(")");
283 }
284 });
285 endAfter();
286 return this;
287 }
288
289 public CodeTreeBuilder doubleQuote(String s) {
290 return startGroup().string("\"" + s + "\"").end();
291 }
292
293 public CodeTreeBuilder string(String chunk1) {
294 return push(chunk1);
295 }
296
297 public CodeTreeBuilder string(String chunk1, String chunk2) {
298 return push(GROUP).string(chunk1).string(chunk2).end();
299 }
300
301 public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3) {
302 return push(GROUP).string(chunk1).string(chunk2).string(chunk3).end();
303 }
304
305 public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3, String chunk4) {
306 return push(GROUP).string(chunk1).string(chunk2).string(chunk3).string(chunk4).end();
307 }
308
309 public CodeTreeBuilder tree(CodeTree treeToAdd) {
310 if (treeToAdd instanceof BuilderCodeTree) {
311 return push((BuilderCodeTree) treeToAdd, true).end();
312 } else {
313 BuilderCodeTree tree = new BuilderCodeTree(currentElement, GROUP, null, null);
314 currentElement.add(treeToAdd);
315 return push(tree, true).end();
316 }
317 }
318
319 public CodeTreeBuilder trees(CodeTree... trees) {
320 for (CodeTree tree : trees) {
321 tree(tree);
322 }
323 return this;
324 }
325
326 public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3, String chunk4, String... chunks) {
327 push(GROUP).string(chunk1).string(chunk2).string(chunk3).string(chunk4);
328 for (int i = 0; i < chunks.length; i++) {
329 string(chunks[i]);
330 }
331 return end();
332 }
333
334 public CodeTreeBuilder newLine() {
335 return push(NEW_LINE);
336 }
337
338 public CodeTreeBuilder startWhile() {
339 return startGroup().string("while ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter();
340 }
341
342 public CodeTreeBuilder startDoBlock() {
343 return startGroup().string("do ").startBlock();
344 }
345
346 public CodeTreeBuilder startDoWhile() {
347 clearLast(CodeTreeKind.NEW_LINE);
348 return startStatement().string(" while ").startParanthesesCommaGroup().endAfter().startGroup().endAfter();
349 }
350
351 public CodeTreeBuilder startIf() {
352 return startGroup().string("if ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter();
353 }
354
355 public CodeTreeBuilder startFor() {
356 return startGroup().string("for ").startParantheses().endAndWhitespaceAfter().startGroup().endAfter();
357 }
358
359 public boolean startIf(boolean elseIf) {
360 if (elseIf) {
361 startElseIf();
362 } else {
363 startIf();
364 }
365 return true;
366 }
367
368 public CodeTreeBuilder startElseIf() {
369 clearLast(CodeTreeKind.NEW_LINE);
370 return startGroup().string(" else if ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter();
371 }
372
373 public CodeTreeBuilder startElseBlock() {
374 clearLast(CodeTreeKind.NEW_LINE);
375 return startGroup().string(" else ").startBlock().endAfter();
376 }
377
378 private boolean clearLastRec(CodeTreeKind kind, List<CodeTree> children) {
379 if (children == null) {
380 return false;
381 }
382 for (int i = children.size() - 1; i >= 0; i--) {
383 CodeTree child = children.get(i);
384 if (child.getCodeKind() == kind) {
385 children.remove(children.get(i));
386 return true;
387 } else {
388 if (clearLastRec(kind, child.getEnclosedElements())) {
389 return true;
390 }
391 }
392 }
393 return false;
394 }
395
396 public CodeTreeBuilder startCase() {
397 startGroup().string("case ");
398 registerCallBack(new EndCallback() {
399
400 @Override
401 public void beforeEnd() {
402 string(" :").newLine();
403 }
404
405 @Override
406 public void afterEnd() {
407 }
408 });
409 return this;
410 }
411
412 public CodeTreeBuilder caseDefault() {
413 return startGroup().string("default :").newLine().end();
414 }
415
416 public CodeTreeBuilder startSwitch() {
417 return startGroup().string("switch ").startParanthesesCommaGroup().endAndWhitespaceAfter();
418 }
419
420 public CodeTreeBuilder startReturn() {
421 ExecutableElement method = findMethod();
422 if (method != null && ElementUtils.isVoid(method.getReturnType())) {
423 startGroup();
424 registerCallBack(new EndCallback() {
425
426 @Override
427 public void beforeEnd() {
428 string(";").newLine(); // complete statement to execute
429 }
430
431 @Override
432 public void afterEnd() {
433 string("return").string(";").newLine(); // emit a return;
434 }
435 });
436 return this;
437 } else {
438 return startStatement().string("return ");
439 }
440 }
441
442 public CodeTreeBuilder startAssert() {
443 return startStatement().string("assert ");
444 }
445
446 public CodeTreeBuilder startNewArray(ArrayType arrayType, CodeTree size) {
447 startGroup().string("new ").type(arrayType.getComponentType()).string("[");
448 if (size != null) {
449 tree(size);
450 }
451 string("]");
452 if (size == null) {
453 string(" ");
454 startCurlyBracesCommaGroup().endAfter();
455 }
456 return this;
457 }
458
459 public CodeTreeBuilder startNew(TypeMirror uninializedNodeClass) {
460 return startGroup().string("new ").type(uninializedNodeClass).startParanthesesCommaGroup().endAfter();
461 }
462
463 public CodeTreeBuilder startNew(String typeName) {
464 return startGroup().string("new ").string(typeName).startParanthesesCommaGroup().endAfter();
465 }
466
467 public CodeTreeBuilder startIndention() {
468 return push(CodeTreeKind.INDENT);
469 }
470
471 public CodeTreeBuilder end(int times) {
472 for (int i = 0; i < times; i++) {
473 end();
474 }
475 return this;
476 }
477
478 public CodeTreeBuilder end() {
479 BuilderCodeTree tree = currentElement;
480 EndCallback callback = tree.getAtEndListener();
481 if (callback != null) {
482 callback.beforeEnd();
483 toParent();
484 callback.afterEnd();
485 } else {
486 toParent();
487 }
488 return this;
489 }
490
491 private void toParent() {
492 CodeTree parentElement = currentElement.getParent();
493 if (currentElement != root) {
494 this.currentElement = (BuilderCodeTree) parentElement;
495 } else {
496 this.currentElement = root;
497 }
498 }
499
500 public CodeTreeBuilder startBlock() {
501 startGroup();
502 string("{").newLine().startIndention();
503 registerCallBack(new EndCallback() {
504
505 @Override
506 public void beforeEnd() {
507 }
508
509 @Override
510 public void afterEnd() {
511 string("}").newLine();
512 }
513 });
514 endAfter();
515 return this;
516 }
517
518 private void registerCallBack(EndCallback callback) {
519 currentElement.registerAtEnd(callback);
520 }
521
522 public CodeTreeBuilder defaultDeclaration(TypeMirror type, String name) {
523 if (!ElementUtils.isVoid(type)) {
524 startStatement();
525 type(type);
526 string(" ");
527 string(name);
528 string(" = ");
529 defaultValue(type);
530 end(); // statement
531 }
532 return this;
533 }
534
535 public CodeTreeBuilder declaration(TypeMirror type, String name, String init) {
536 return declaration(type, name, singleString(init));
537 }
538
539 public CodeTreeBuilder declaration(String type, String name, CodeTree init) {
540 startStatement();
541 string(type);
542 string(" ");
543 string(name);
544 if (init != null) {
545 string(" = ");
546 tree(init);
547 }
548 end(); // statement
549 return this;
550 }
551
552 public CodeTreeBuilder declaration(String type, String name, String init) {
553 return declaration(type, name, singleString(init));
554 }
555
556 public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTree init) {
557 if (ElementUtils.isVoid(type)) {
558 startStatement();
559 tree(init);
560 end();
561 } else {
562 startStatement();
563 type(type);
564 string(" ");
565 string(name);
566 if (init != null) {
567 string(" = ");
568 tree(init);
569 }
570 end(); // statement
571 }
572 return this;
573 }
574
575 public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTreeBuilder init) {
576 if (init == this) {
577 throw new IllegalArgumentException("Recursive builder usage.");
578 }
579 return declaration(type, name, init.getTree());
580 }
581
582 public CodeTreeBuilder create() {
583 return new CodeTreeBuilder(this);
584 }
585
586 public CodeTreeBuilder type(TypeMirror type) {
587 return push(type);
588 }
589
590 public CodeTreeBuilder typeLiteral(TypeMirror type) {
591 return startGroup().type(ElementUtils.eraseGenericTypes(type)).string(".class").end();
592 }
593
594 private void assertRoot() {
595 if (currentElement != root) {
596 throw new IllegalStateException("CodeTreeBuilder was not ended properly.");
597 }
598 }
599
600 public CodeTreeBuilder startCaseBlock() {
601 return startIndention();
602 }
603
604 public CodeTreeBuilder startThrow() {
605 return startStatement().string("throw ");
606 }
607
608 public CodeTree getTree() {
609 assertRoot();
610 return root;
611 }
612
613 public CodeTree build() {
614 return root;
615 }
616
617 public CodeTreeBuilder cast(TypeMirror type) {
618 string("(").type(type).string(") ");
619 return this;
620 }
621
622 public CodeTreeBuilder cast(TypeMirror type, CodeTree content) {
623 if (ElementUtils.isVoid(type)) {
624 tree(content);
625 return this;
626 } else if (type.getKind() == TypeKind.DECLARED && ElementUtils.getQualifiedName(type).equals("java.lang.Object")) {
627 tree(content);
628 return this;
629 } else {
630 return startGroup().string("(").type(type).string(")").string(" ").tree(content).end();
631 }
632 }
633
634 public CodeTreeBuilder startSuperCall() {
635 return string("super").startParanthesesCommaGroup();
636 }
637
638 public CodeTreeBuilder returnFalse() {
639 return startReturn().string("false").end();
640 }
641
642 public CodeTreeBuilder returnStatement() {
643 return statement("return");
644 }
645
646 public ExecutableElement findMethod() {
647 if (enclosingElement != null && (enclosingElement.getKind() == ElementKind.METHOD || enclosingElement.getKind() == ElementKind.CONSTRUCTOR)) {
648 return (ExecutableElement) enclosingElement;
649 }
650 return null;
651 }
652
653 public CodeTreeBuilder returnNull() {
654 return startReturn().string("null").end();
655 }
656
657 public CodeTreeBuilder returnTrue() {
658 return startReturn().string("true").end();
659 }
660
661 public CodeTreeBuilder instanceOf(CodeTree var, TypeMirror type) {
662 return tree(var).string(" instanceof ").type(type);
663 }
664
665 public CodeTreeBuilder defaultValue(TypeMirror mirror) {
666 switch (mirror.getKind()) {
667 case VOID:
668 return string("");
669 case ARRAY:
670 case DECLARED:
671 case PACKAGE:
672 case NULL:
673 return string("null");
674 case BOOLEAN:
675 return string("false");
676 case BYTE:
677 return string("(byte) 0");
678 case CHAR:
679 return string("(char) 0");
680 case DOUBLE:
681 return string("0.0D");
682 case LONG:
683 return string("0L");
684 case INT:
685 return string("0");
686 case FLOAT:
687 return string("0.0F");
688 case SHORT:
689 return string("(short) 0");
690 default:
691 throw new AssertionError();
692 }
693 }
694
695 public CodeTreeBuilder startTryBlock() {
696 return string("try ").startBlock();
697 }
698
699 public CodeTreeBuilder startCatchBlock(TypeMirror exceptionType, String localVarName) {
700 clearLast(CodeTreeKind.NEW_LINE);
701 string(" catch (").type(exceptionType).string(" ").string(localVarName).string(") ");
702 return startBlock();
703 }
704
705 public CodeTreeBuilder startCatchBlock(TypeMirror[] exceptionTypes, String localVarName) {
706 clearLast(CodeTreeKind.NEW_LINE);
707 string(" catch (");
708
709 for (int i = 0; i < exceptionTypes.length; i++) {
710 if (i != 0) {
711 string(" | ");
712 }
713 type(exceptionTypes[i]);
714 }
715
716 string(" ").string(localVarName).string(") ");
717 return startBlock();
718 }
719
720 public CodeTreeBuilder startFinallyBlock() {
721 clearLast(CodeTreeKind.NEW_LINE);
722 string(" finally ");
723 return startBlock();
724 }
725
726 public CodeTreeBuilder nullLiteral() {
727 return string("null");
728 }
729
730 private static class BuilderCodeTree extends CodeTree {
731
732 private EndCallback atEndListener;
733 private CodeTreeKind removeLast;
734
735 public BuilderCodeTree(CodeTree parent, CodeTreeKind kind, TypeMirror type, String string) {
736 super(parent, kind, type, string);
737 }
738
739 public void registerAtEnd(EndCallback atEnd) {
740 if (this.atEndListener != null) {
741 this.atEndListener = new CompoundCallback(this.atEndListener, atEnd);
742 } else {
743 this.atEndListener = atEnd;
744 }
745 }
746
747 public EndCallback getAtEndListener() {
748 return atEndListener;
749 }
750
751 @Override
752 public String toString() {
753 final StringBuilder b = new StringBuilder();
754 new Printer(b).visitTree(this, null, null);
755 return b.toString();
756 }
757
758 private static class CompoundCallback implements EndCallback {
759
760 private final EndCallback callback1;
761 private final EndCallback callback2;
762
763 public CompoundCallback(EndCallback callback1, EndCallback callback2) {
764 this.callback1 = callback1;
765 this.callback2 = callback2;
766 }
767
768 @Override
769 public void afterEnd() {
770 callback1.afterEnd();
771 callback2.afterEnd();
772 }
773
774 @Override
775 public void beforeEnd() {
776 callback1.beforeEnd();
777 callback1.beforeEnd();
778 }
779 }
780
781 }
782
783 private interface EndCallback {
784
785 void beforeEnd();
786
787 void afterEnd();
788 }
789
790 private static class Printer extends CodeElementScanner<Void, Void> {
791
792 private int indent;
793 private boolean newLine;
794 private final String ln = "\n";
795
796 private final StringBuilder b;
797
798 Printer(StringBuilder b) {
799 this.b = b;
800 }
801
802 @Override
803 public void visitTree(CodeTree e, Void p, Element enclosingElement) {
804 switch (e.getCodeKind()) {
805 case COMMA_GROUP:
806 List<CodeTree> children = e.getEnclosedElements();
807 if (children != null) {
808 for (int i = 0; i < children.size(); i++) {
809 visitTree(children.get(i), p, enclosingElement);
810 if (i < e.getEnclosedElements().size() - 1) {
811 b.append(", ");
812 }
813 }
814 }
815 break;
816 case GROUP:
817 super.visitTree(e, p, enclosingElement);
818 break;
819 case INDENT:
820 indent();
821 super.visitTree(e, p, enclosingElement);
822 dedent();
823 break;
824 case NEW_LINE:
825 writeLn();
826 break;
827 case STRING:
828 if (e.getString() != null) {
829 write(e.getString());
830 } else {
831 write("null");
832 }
833 break;
834 case TYPE:
835 write(ElementUtils.getSimpleName(e.getType()));
836 break;
837 default:
838 assert false;
839 return;
840 }
841 }
842
843 private void indent() {
844 indent++;
845 }
846
847 private void dedent() {
848 indent--;
849 }
850
851 private void writeLn() {
852 write(ln);
853 newLine = true;
854 }
855
856 private void write(String m) {
857 if (newLine && m != ln) {
858 writeIndent();
859 newLine = false;
860 }
861 b.append(m);
862 }
863
864 private void writeIndent() {
865 for (int i = 0; i < indent; i++) {
866 b.append(" ");
867 }
868 }
869 }
870
871 public CodeTreeBuilder returnDefault() {
872 ExecutableElement method = findMethod();
873 if (ElementUtils.isVoid(method.getReturnType())) {
874 returnStatement();
875 } else {
876 startReturn().defaultValue(method.getReturnType()).end();
877 }
878 return this;
879
880 }
881
882 }