1 package net.sourceforge.jenesis4java.impl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 import java.util.ArrayList;
40 import java.util.Comparator;
41 import java.util.LinkedList;
42 import java.util.List;
43
44 import net.sourceforge.jenesis4java.*;
45 import net.sourceforge.jenesis4java.impl.util.*;
46
47
48
49
50 abstract class MStatement extends MVM.MCodeable implements Statement {
51
52
53
54
55 static class BlockStatement extends MStatement implements Block {
56
57 List<Statement> vs;
58
59 BlockStatement(MVM vm) {
60 super(vm);
61 vs = new ArrayList<>();
62 }
63
64 @Override
65 public List<Statement> getStatements() {
66 return ListTypeSelector.select(vs);
67 }
68
69 @Override
70 public Statement insertStatement(int index, Expression expression) {
71 ExpressionStatement expressionStatement = new MStatement.MExpressionStatement((MVM) vm(), expression);
72 vs.add(index, expressionStatement);
73 return expressionStatement;
74 }
75
76 @Override
77 public void insertStatement(int index, Statement statement) {
78 vs.add(index, statement);
79 }
80
81 @Override
82 public boolean isBlockWithAbruptCompletion() {
83 return BlockUtil.isBlockWithAbruptCompletion(getStatements());
84 }
85
86 @Override
87 public Break newBreak() {
88 Break x = new MBreak(vm);
89 vs.add(x);
90 return x;
91 }
92
93 @Override
94 public Continue newContinue() {
95 Continue x = new MContinue(vm);
96 vs.add(x);
97 return x;
98 }
99
100 @Override
101 public Let newDeclarationLet(Type type) {
102 Let x = new MStatement.MLet(vm, type);
103 int index = 0;
104 while (index < vs.size() && vs.get(index) instanceof Let) {
105 index++;
106 }
107 vs.add(index, x);
108 return x;
109 }
110
111 @Override
112 public DoWhile newDoWhile(Expression predicate) {
113 DoWhile x = new MDoWhile(vm, predicate);
114 vs.add(x);
115 return x;
116 }
117
118 @Override
119 public Empty newEmpty() {
120 Empty x = new MEmpty(vm);
121 vs.add(x);
122 return x;
123 }
124
125 @Override
126 public For newFor() {
127 For x = new MFor(vm);
128 vs.add(x);
129 return x;
130 }
131
132 @Override
133 public If newIf(Expression predicate) {
134 If x = new MIf(vm, predicate);
135 vs.add(x);
136 return x;
137 }
138
139 @Override
140 public Let newLet(Type type) {
141 Let x = new MLet(vm, type);
142 vs.add(x);
143 return x;
144 }
145
146 @Override
147 public LocalBlock newLocalBlock() {
148 LocalBlock x = new MLocalBlock(vm);
149 vs.add(x);
150 return x;
151 }
152
153 @Override
154 public LocalClass newLocalClass(String name) {
155 return newLocalClass(name, new MemberComparator());
156 }
157
158 @Override
159 public LocalClass newLocalClass(String name, Comparator comparator) {
160 LocalClass x = new MDeclaration.MLocalClass(vm, name, comparator);
161 vs.add(x);
162 return x;
163 }
164
165 @Override
166 public Return newReturn() {
167 Return x = new MReturn(vm);
168 vs.add(x);
169 return x;
170 }
171
172 @Override
173 public ExpressionStatement newStmt(Expression expr) {
174 ExpressionStatement x = new MExpressionStatement(vm, expr);
175 vs.add(x);
176 return x;
177 }
178
179 @Override
180 public Switch newSwitch(Expression integer) {
181 Switch x = new MSwitch(vm, integer);
182 vs.add(x);
183 return x;
184 }
185
186 @Override
187 public Synchronized newSynchronized(Expression mutex) {
188 Synchronized x = new MSynchronized(vm, mutex);
189 vs.add(x);
190 return x;
191 }
192
193 @Override
194 public Throw newThrow(Expression throwable) {
195 Throw x = new MThrow(vm, throwable);
196 vs.add(x);
197 return x;
198 }
199
200 @Override
201 public Try newTry() {
202 Try x = new MTry(vm);
203 vs.add(x);
204 return x;
205 }
206
207 @Override
208 public While newWhile(Expression predicate) {
209 While x = new MWhile(vm, predicate);
210 vs.add(x);
211 return x;
212 }
213
214 @Override
215 public void removeStmt(Statement statement) {
216 if (vs != null) {
217 vs.remove(statement);
218 }
219 }
220
221 @Override
222 public void visit(ReplacingVisitor visitor) {
223 super.visit(visitor);
224 VisitorUtils.visit(vs, this, visitor);
225 }
226
227 void writeBlock(CodeWriter out, BlockStyle style) {
228
229 style.toCode(out, getStatements(), comment);
230 }
231 }
232
233
234
235
236 abstract static class GotoStatement extends MStatement {
237
238 final String kwd;
239
240 String target;
241
242 GotoStatement(MVM vm, String kwd) {
243 super(vm);
244 this.kwd = kwd;
245 }
246
247 public String getGoto() {
248 return target;
249 }
250
251 public GotoStatement setGoto(String target) {
252 this.target = target;
253 return this;
254 }
255
256 @Override
257 public CodeWriter toCode(CodeWriter out) {
258 super.toCode(out);
259
260 out.write(kwd);
261
262 if (target != null) {
263 out.space().write(target);
264 }
265
266 out.write(';');
267 appendTrailingComment(out);
268 return out;
269 }
270 }
271
272
273
274
275 static class MBreak extends GotoStatement implements Break {
276
277 MBreak(MVM vm) {
278 super(vm, "break");
279 }
280
281 @Override
282 public MBreak setGoto(String target) {
283 super.setGoto(target);
284 return this;
285 }
286 }
287
288
289
290
291 static class MCase extends MConditionalStatement implements Case {
292
293 MCase(MVM vm, Expression expr) {
294 super(vm);
295 setPredicate(expr);
296 }
297
298 @Override
299 public Expression getConstant() {
300 return getPredicate();
301 }
302
303 @Override
304 public MCase setConstant(Expression expr) {
305 setPredicate(expr);
306 return this;
307 }
308
309 @Override
310 public CodeWriter toCode(CodeWriter out) {
311 super.toCode(out);
312 out.write("case ").write(e).write(':');
313 appendTrailingComment(out);
314
315 out.indentLine();
316 out.write(getStatements());
317 out.dedentLine();
318 return out;
319 }
320 }
321
322
323
324
325 abstract static class MConditionalStatement extends BlockStatement implements ConditionalStatement {
326
327 Expression e;
328
329 public MConditionalStatement(MVM vm) {
330 super(vm);
331 }
332
333 public MConditionalStatement(MVM vm, Expression e) {
334 super(vm);
335 this.e = e;
336 }
337
338 @Override
339 public Expression getPredicate() {
340 return e;
341 }
342
343 @Override
344 public MConditionalStatement setPredicate(Expression e) {
345 this.e = e;
346 return this;
347 }
348
349 @Override
350 public void visit(ReplacingVisitor visitor) {
351 super.visit(visitor);
352 e = VisitorUtils.visit(e, this, visitor);
353 }
354 }
355
356
357
358
359 static class MContinue extends GotoStatement implements Continue {
360
361 MContinue(MVM vm) {
362 super(vm, "continue");
363 }
364
365 @Override
366 public MContinue setGoto(String target) {
367 super.setGoto(target);
368 return this;
369 }
370 }
371
372
373
374
375 static class MDefault extends BlockStatement implements Default {
376
377 MDefault(MVM vm) {
378 super(vm);
379 }
380
381 @Override
382 public CodeWriter toCode(CodeWriter out) {
383 super.toCode(out);
384 out.write("default:");
385 writeBlock(out, vm.getStyle("default"));
386 return out;
387 }
388 }
389
390
391
392
393 static class MDoWhile extends MConditionalStatement implements DoWhile {
394
395 public MDoWhile(MVM vm, Expression e) {
396 super(vm, e);
397 }
398
399 @Override
400 public CodeWriter toCode(CodeWriter out) {
401 super.toCode(out);
402 out.write("do");
403 writeBlock(out, vm.getStyle("do"));
404 out.write("while (").write(e).write(");");
405 return out;
406 }
407 }
408
409
410
411
412 static class MElse extends BlockStatement implements Else {
413
414 MElse(MVM vm) {
415 super(vm);
416 }
417
418 @Override
419 public CodeWriter toCode(CodeWriter out) {
420 appendCommentsAndLabel(out);
421 if (!out.isLineNew()) {
422 out.space();
423 }
424 out.write("else");
425 writeBlock(out, vm.getStyle("else"));
426 return out;
427 }
428 }
429
430
431
432
433 static class MElseIf extends MConditionalStatement implements ElseIf {
434
435 MElseIf(MVM vm, Expression e) {
436 super(vm, e);
437 }
438
439 @Override
440 public CodeWriter toCode(CodeWriter out) {
441 appendCommentsAndLabel(out);
442 if (!out.isLineNew()) {
443 out.space();
444 }
445 out.write("else if (").write(e).write(')');
446 writeBlock(out, vm.getStyle("else-if"));
447 return out;
448 }
449 }
450
451
452
453
454 static class MEmpty extends MStatement implements Empty {
455
456 MEmpty(MVM vm) {
457 super(vm);
458 }
459
460 @Override
461 public CodeWriter toCode(CodeWriter out) {
462 super.toCode(out);
463 out.write(';');
464 appendTrailingComment(out);
465 return out;
466 }
467 }
468
469
470
471
472 abstract static class MExpressionableStatement extends MStatement {
473
474 Expression e;
475
476 MExpressionableStatement(MVM vm) {
477 super(vm);
478 }
479
480 public Expression getExpression() {
481 return e;
482 }
483
484 public MExpressionableStatement setExpression(Expression e) {
485 this.e = e;
486 return this;
487 }
488
489 @Override
490 public void visit(ReplacingVisitor visitor) {
491 super.visit(visitor);
492 e = VisitorUtils.visit(e, this, visitor);
493 }
494 }
495
496
497
498
499 static class MExpressionStatement extends MExpressionableStatement implements ExpressionStatement {
500
501 MExpressionStatement(MVM vm, Expression e) {
502 super(vm);
503 setExpression(e);
504 }
505
506 @Override
507 public MExpressionStatement setExpression(Expression e) {
508 super.setExpression(e);
509 return this;
510 }
511
512 @Override
513 public CodeWriter toCode(CodeWriter out) {
514 super.toCode(out);
515 out.write(getExpression()).write(';');
516 appendTrailingComment(out);
517 return out;
518 }
519 }
520
521
522
523
524 static class MFinally extends BlockStatement implements Finally {
525
526 MFinally(MVM vm) {
527 super(vm);
528 }
529
530 @Override
531 public CodeWriter toCode(CodeWriter out) {
532 appendCommentsAndLabel(out);
533 if (!out.isLineNew()) {
534 out.space();
535 }
536 out.write("finally");
537 writeBlock(out, vm.getStyle("finally"));
538 return out;
539 }
540 }
541
542
543
544
545 static class MFor extends MConditionalStatement implements For {
546
547 List<Codeable> initExpressions = new ArrayList<>();
548
549 List<Codeable> vu = new ArrayList<>();
550
551 MFor(MVM vm) {
552 super(vm);
553 }
554
555 @Override
556 public MFor addInit(Expression e) {
557 initExpressions.add(e);
558 return this;
559 }
560
561 @Override
562 public MFor addUpdate(Expression e) {
563 vu.add(e);
564 return this;
565 }
566
567 @Override
568 public List<Codeable> getInits() {
569 return ListTypeSelector.select(initExpressions);
570 }
571
572 @Override
573 public List<Codeable> getUpdates() {
574 return ListTypeSelector.select(vu);
575 }
576
577 @Override
578 public Let setInit(Type type) {
579 Let let = new MForInitLet(vm, type);
580 initExpressions.add(let);
581 return let;
582 }
583
584 @Override
585 public CodeWriter toCode(CodeWriter out) {
586 super.toCode(out);
587 out.write("for (");
588 write(initExpressions, out);
589 out.write(';');
590 if (e != null) {
591 out.space().write(e);
592 }
593 out.write(';');
594 if (!vu.isEmpty()) {
595 out.space();
596 write(vu, out);
597 }
598 out.write(')');
599 writeBlock(out, vm.getStyle("for"));
600 return out;
601 }
602
603 @Override
604 public void visit(ReplacingVisitor visitor) {
605 super.visit(visitor);
606 VisitorUtils.visit(initExpressions, this, visitor);
607 VisitorUtils.visit(vu, this, visitor);
608 }
609
610 private void write(List<Codeable> v, CodeWriter out) {
611 for (int i = 0; i < v.size(); i++) {
612 if (i > 0) {
613 out.write(", ");
614 }
615 out.write(v.get(i));
616 }
617 }
618 }
619
620
621
622
623 static class MForInitLet extends MLet {
624
625 MForInitLet(MVM vm, Type type) {
626 super(vm, type);
627 }
628
629 @Override
630 public CodeWriter toCode(CodeWriter out) {
631
632 out.queue(comment);
633
634 if (isFinal) {
635 out.write("final").space();
636 }
637
638 out.write(type).space();
639
640 for (int i = 0; i < v.size(); i++) {
641 if (i > 0) {
642 out.write(',').space();
643 }
644 out.write(v.get(i));
645 }
646
647 return out;
648 }
649 }
650
651
652
653
654 static class MIf extends MConditionalStatement implements If {
655
656 List<ElseIf> elseIfs = new ArrayList<>();
657
658 Else _else;
659
660 MIf(MVM vm, Expression e) {
661 super(vm, e);
662 }
663
664 @Override
665 public Else getElse() {
666 if (_else == null) {
667 _else = new MElse(vm);
668 }
669 return _else;
670 }
671
672 @Override
673 public List<ElseIf> getElseIfs() {
674 return ListTypeSelector.select(elseIfs);
675 }
676
677 @Override
678 public ElseIf newElseIf(Expression e) {
679 ElseIf ei = new MElseIf(vm, e);
680 elseIfs.add(ei);
681 return ei;
682 }
683
684 @Override
685 public CodeWriter toCode(CodeWriter out) {
686 super.toCode(out);
687 out.write("if (").write(e).write(')');
688 writeBlock(out, vm.getStyle("if"));
689 for (ElseIf elseIf : elseIfs) {
690 out.write(elseIf);
691 }
692 if (_else != null && !_else.getStatements().isEmpty()) {
693 out.write(_else);
694 }
695 return out;
696 }
697
698 @Override
699 public void visit(ReplacingVisitor visitor) {
700 super.visit(visitor);
701 VisitorUtils.visit(elseIfs, this, visitor);
702 _else = VisitorUtils.visit(_else, this, visitor);
703 }
704 }
705
706
707
708
709 static class MLet extends MExpressionableStatement implements Let {
710
711 Type type;
712
713 boolean isFinal;
714
715 List<Assign> v = new ArrayList<>();
716
717 MLet(MVM vm, Type type) {
718 super(vm);
719 this.type = type;
720 }
721
722 @Override
723 public MLet addAssign(Assign assign) {
724 v.add(assign);
725 return this;
726 }
727
728 @Override
729 public MLet addAssign(String name, Expression expr) {
730 v.add(new MExpression.MAssign(vm, Assign.S, new MExpression.MVariable(vm, name), expr));
731 return this;
732 }
733
734 @Override
735 public List<Assign> getAssigns() {
736 return ListTypeSelector.select(v);
737 }
738
739 @Override
740 public Type getType() {
741 return type;
742 }
743
744 @Override
745 public boolean isFinal() {
746 return isFinal;
747 }
748
749 @Override
750 public MLet isFinal(boolean value) {
751 isFinal = value;
752 return this;
753 }
754
755 @Override
756 public MLet setType(Type type) {
757 this.type = type;
758 return this;
759 }
760
761 @Override
762 public CodeWriter toCode(CodeWriter out) {
763 super.toCode(out);
764
765 if (isFinal) {
766 out.write("final").space();
767 }
768
769 out.write(type).space();
770
771 for (int i = 0; i < v.size(); i++) {
772 if (i > 0) {
773 out.write(',').space();
774 }
775 out.write(v.get(i));
776 }
777
778 out.write(';');
779
780 appendTrailingComment(out);
781
782 return out;
783 }
784
785 @Override
786 public void visit(ReplacingVisitor visitor) {
787 super.visit(visitor);
788 type = VisitorUtils.visit(type, this, visitor);
789 VisitorUtils.visit(v, this, visitor);
790 }
791 }
792
793
794
795
796 static class MLocalBlock extends BlockStatement implements LocalBlock {
797
798 public MLocalBlock(MVM vm) {
799 super(vm);
800 }
801
802 @Override
803 public CodeWriter toCode(CodeWriter out) {
804 super.toCode(out);
805 writeBlock(out, vm.getStyle("local-class"));
806 return out;
807 }
808 }
809
810
811
812
813 static class MReturn extends MExpressionableStatement implements Return {
814
815 MReturn(MVM vm) {
816 super(vm);
817 }
818
819 @Override
820 public MReturn setExpression(Expression e) {
821 super.setExpression(e);
822 return this;
823 }
824
825 @Override
826 public CodeWriter toCode(CodeWriter out) {
827 super.toCode(out);
828
829 out.write("return");
830
831 if (e != null) {
832 out.space().write(e);
833 }
834
835 out.write(';');
836
837 appendTrailingComment(out);
838
839 return out;
840 }
841 }
842
843
844
845
846 static class MSwitch extends MConditionalStatement implements Switch {
847
848 boolean triggered;
849
850 Default d;
851
852 MSwitch(MVM vm, Expression e) {
853 super(vm, e);
854 }
855
856 @Override
857 public List<Case> getCases() {
858 return ListTypeSelector.select(vs, Case.class);
859 }
860
861 @Override
862 public Default getDefault() {
863 if (d == null) {
864 d = new MDefault(vm);
865 }
866 return d;
867 }
868
869 @Override
870 public Case newCase(Expression constant) {
871 Case c = new MCase(vm, constant);
872 vs.add(c);
873 return c;
874 }
875
876 @Override
877 public CodeWriter toCode(CodeWriter out) {
878 if (!triggered) {
879
880 if (d != null) {
881 vs.add(d);
882 }
883 triggered = true;
884 }
885
886 super.toCode(out);
887 out.write("switch (").write(e).write(')');
888 writeBlock(out, vm.getStyle("switch"));
889 return out;
890 }
891
892 @Override
893 public void visit(ReplacingVisitor visitor) {
894 super.visit(visitor);
895 d = VisitorUtils.visit(d, this, visitor);
896 }
897 }
898
899
900
901
902 static class MSynchronized extends BlockStatement implements Synchronized {
903
904 Expression mutex;
905
906 MSynchronized(MVM vm, Expression mutex) {
907 super(vm);
908 this.mutex = mutex;
909 }
910
911 @Override
912 public Expression getMutex() {
913 return mutex;
914 }
915
916 @Override
917 public MSynchronized setMutex(Expression mutex) {
918 this.mutex = mutex;
919 return this;
920 }
921
922 @Override
923 public CodeWriter toCode(CodeWriter out) {
924 super.toCode(out);
925 out.write("synchronized ").write('(').write(mutex).write(')');
926 writeBlock(out, vm.getStyle("synchronized"));
927 return out;
928 }
929
930 @Override
931 public void visit(ReplacingVisitor visitor) {
932 super.visit(visitor);
933 mutex = VisitorUtils.visit(mutex, this, visitor);
934 }
935 }
936
937 static class MConstructorForwarding extends MStatement implements ConstructorForwarding {
938
939 private final Constructor.ForwardingTarget target;
940
941 private final List<Expression> arguments = new ArrayList<>();
942
943 private String qualifier;
944
945 MConstructorForwarding(MVM vm, Constructor.ForwardingTarget target) {
946 super(vm);
947 this.target = target;
948 }
949
950 @Override
951 public CodeWriter toCode(CodeWriter out) {
952 super.toCode(out);
953
954 if (qualifier != null) {
955 out.write(qualifier).write('.');
956 }
957
958 if (target == Constructor.ForwardingTarget.THIS) {
959 out.write("this(");
960 } else if (target == Constructor.ForwardingTarget.SUPER){
961 out.write("super(");
962 }
963
964 String separator = "";
965 for (Expression argument : arguments) {
966 out.write(separator);
967 out.write(argument);
968 separator = ", ";
969 }
970
971 out.write(");");
972 appendTrailingComment(out);
973 return out;
974 }
975
976 @Override
977 public ConstructorForwarding addArg(boolean value) {
978 return addArg(value ? vm.newTrue() : vm.newFalse());
979 }
980
981 @Override
982 public ConstructorForwarding addArg(double value) {
983 return addArg(vm.newDouble(value));
984 }
985
986 @Override
987 public ConstructorForwarding addArg(Expression arg) {
988 arguments.add(arg);
989 return this;
990 }
991
992 @Override
993 public ConstructorForwarding addArg(float value) {
994 return addArg(vm.newFloat(value));
995 }
996
997 @Override
998 public ConstructorForwarding addArg(int value) {
999 return addArg(vm.newInt(value));
1000 }
1001
1002 @Override
1003 public ConstructorForwarding addArg(long value) {
1004 return addArg(vm.newLong(value));
1005 }
1006
1007 @Override
1008 public ConstructorForwarding addArg(String value) {
1009 return addArg(vm.newString(value));
1010 }
1011
1012 @Override
1013 public ConstructorForwarding addVariableArg(String variableName) {
1014 return addArg(vm.newVar(variableName));
1015 }
1016
1017 @Override
1018 public List<Expression> getArgs() {
1019 return ListTypeSelector.select(arguments, Expression.class);
1020 }
1021
1022 @Override
1023 public void removeArg(int index) {
1024 if (index < 0 || index >= arguments.size()) {
1025 throw new IllegalArgumentException("Cannot remove argument with index " + index);
1026 }
1027
1028 arguments.remove(index);
1029 }
1030
1031 @Override
1032 public void visit(ReplacingVisitor visitor) {
1033 super.visit(visitor);
1034 VisitorUtils.visit(arguments, this, visitor);
1035 }
1036
1037 @Override
1038 public Constructor.ForwardingTarget getTarget() {
1039 return target;
1040 }
1041
1042 @Override
1043 public void setQualifier(String qualifier) {
1044 this.qualifier = qualifier;
1045 }
1046
1047 @Override
1048 public Expression getQualifier() {
1049 if (qualifier != null) {
1050 return vm.newClassLiteral(qualifier);
1051 } else {
1052 return null;
1053 }
1054 }
1055 }
1056
1057
1058
1059
1060 static class MThrow extends MStatement implements Throw {
1061
1062 Expression e;
1063
1064 MThrow(MVM vm, Expression e) {
1065 super(vm);
1066 this.e = e;
1067 }
1068
1069 @Override
1070 public Expression getThrowable() {
1071 return e;
1072 }
1073
1074 @Override
1075 public MThrow setThrowable(Expression e) {
1076 this.e = e;
1077 return this;
1078 }
1079
1080 @Override
1081 public CodeWriter toCode(CodeWriter out) {
1082 super.toCode(out);
1083
1084 out.write("throw ").write(e).write(';');
1085 appendTrailingComment(out);
1086
1087 return out;
1088 }
1089
1090 @Override
1091 public void visit(ReplacingVisitor visitor) {
1092 super.visit(visitor);
1093 e = VisitorUtils.visit(e, this, visitor);
1094 }
1095 }
1096
1097
1098
1099
1100 static class MWhile extends MConditionalStatement implements While {
1101
1102 public MWhile(MVM vm, Expression e) {
1103 super(vm, e);
1104 }
1105
1106 @Override
1107 public CodeWriter toCode(CodeWriter out) {
1108 super.toCode(out);
1109 out.write("while (").write(e).write(')');
1110 writeBlock(out, vm.getStyle("while"));
1111 return out;
1112 }
1113 }
1114
1115 private String label;
1116
1117 MStatement(MVM vm) {
1118 super(vm);
1119 }
1120
1121 @Override
1122 public Comment comment(String text) {
1123 comment = new MComment.MSingleLineComment(vm, text);
1124 return comment;
1125 }
1126
1127 @Override
1128 public String getLabel() {
1129 return label;
1130 }
1131
1132 @Override
1133 public boolean isAbruptCompletionStatement() {
1134 return this instanceof Return ||
1135 this instanceof Break ||
1136 this instanceof Throw ||
1137 this instanceof Continue;
1138 }
1139
1140 @Override
1141 public MStatement setLabel(String label) {
1142 this.label = label;
1143 return this;
1144 }
1145
1146 private List<Comment> collectComments() {
1147 final List<Comment> collectedComments = new LinkedList<>();
1148
1149 visit(new ConditionalVisitor() {
1150
1151 @Override
1152 public boolean visit(Codeable current, Codeable parent) {
1153 if (current instanceof Expression) {
1154 Expression expression = (Expression) current;
1155 if (expression.getComment() != null) {
1156 collectedComments.add(expression.getComment());
1157 }
1158 return true;
1159
1160 } else if (current instanceof MForInitLet) {
1161
1162 MExpressionableStatement expression = (MExpressionableStatement) current;
1163 if (expression.getComment() != null) {
1164 collectedComments.add(expression.getComment());
1165 }
1166 return true;
1167
1168 } else {
1169 return false;
1170 }
1171 }
1172 });
1173
1174 return collectedComments;
1175 }
1176
1177 @Override
1178 public CodeWriter toCode(CodeWriter out) {
1179
1180 out.ensureNewLine();
1181
1182 appendCommentsAndLabel(out);
1183 return out;
1184 }
1185
1186 void appendCommentsAndLabel(CodeWriter out) {
1187
1188 if (comment != null && comment.getType() != Comment.TRAILING) {
1189 out.write(comment);
1190 out.ensureNewLine();
1191 }
1192
1193
1194 List<Comment> commentsFromInnerExpressions = collectComments();
1195 for (Comment expressionComment : commentsFromInnerExpressions) {
1196 if (expressionComment.getType() != Comment.TRAILING) {
1197 out.write(expressionComment);
1198
1199 out.ensureNewLine();
1200 }
1201 }
1202
1203
1204 if (label != null) {
1205 out.ensureNewLine();
1206 out.write(label).write(':').space();
1207 }
1208 }
1209
1210 CodeWriter appendTrailingComment(CodeWriter out) {
1211 if (comment != null && comment.getType() == Comment.TRAILING) {
1212 out.write(comment);
1213 }
1214
1215 List<Comment> commentsFromInnerExpressions = collectComments();
1216 for (Comment expressionComment : commentsFromInnerExpressions) {
1217 if (expressionComment.getType() == Comment.TRAILING) {
1218 out.write(expressionComment);
1219 }
1220 }
1221
1222 return out;
1223 }
1224 }