comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java @ 7844:4cbe062678ba

Implemented line wrapping for code writer.
author Christian Humer <christian.humer@gmail.com>
date Mon, 18 Feb 2013 20:35:54 +0100
parents 5f3cba05c2fa
children 85891f9c2197
comparison
equal deleted inserted replaced
7843:4969921f57b7 7844:4cbe062678ba
34 import com.oracle.truffle.codegen.processor.*; 34 import com.oracle.truffle.codegen.processor.*;
35 import com.oracle.truffle.codegen.processor.ast.*; 35 import com.oracle.truffle.codegen.processor.ast.*;
36 36
37 public abstract class AbstractCodeWriter extends CodeElementScanner<Void, Void> { 37 public abstract class AbstractCodeWriter extends CodeElementScanner<Void, Void> {
38 38
39 private static final int LINE_LENGTH = 200;
40 private static final int LINE_WRAP_INDENTS = 3;
41 private static final String IDENT_STRING = " ";
42 private static final String LN = "\n"; /* unix style */
43
39 protected Writer writer; 44 protected Writer writer;
40 private int indent; 45 private int indent;
41 private boolean newLine; 46 private boolean newLine;
47 private int lineLength;
48 private boolean lineWrapping = false;
42 49
43 private OrganizedImports imports; 50 private OrganizedImports imports;
44 51
45 public void visitCompilationUnit(CodeCompilationUnit e) { 52 public void visitCompilationUnit(CodeCompilationUnit e) {
46 for (TypeElement clazz : e.getEnclosedElements()) { 53 for (TypeElement clazz : e.getEnclosedElements()) {
54 public Void visitType(CodeTypeElement e, Void p) { 61 public Void visitType(CodeTypeElement e, Void p) {
55 if (e.isTopLevelClass()) { 62 if (e.isTopLevelClass()) {
56 Writer w = null; 63 Writer w = null;
57 try { 64 try {
58 imports = OrganizedImports.organize(e); 65 imports = OrganizedImports.organize(e);
59 66 w = new TrimTrailingSpaceWriter(createWriter(e));
60 w = createWriter(e);
61 writer = w; 67 writer = w;
62 writeRootClass(e); 68 writeRootClass(e);
63 } catch (IOException ex) { 69 } catch (IOException ex) {
64 throw new RuntimeException(ex); 70 throw new RuntimeException(ex);
65 } finally { 71 } finally {
143 } 149 }
144 } 150 }
145 151
146 write(" {").writeLn(); 152 write(" {").writeLn();
147 writeEmptyLn(); 153 writeEmptyLn();
148 indent(); 154 indent(1);
149 155
150 List<VariableElement> staticFields = getStaticFields(e); 156 List<VariableElement> staticFields = getStaticFields(e);
151 List<VariableElement> instanceFields = getInstanceFields(e); 157 List<VariableElement> instanceFields = getInstanceFields(e);
152 158
153 for (int i = 0; i < staticFields.size(); i++) { 159 for (int i = 0; i < staticFields.size(); i++) {
189 195
190 for (TypeElement clazz : e.getInnerClasses()) { 196 for (TypeElement clazz : e.getInnerClasses()) {
191 clazz.accept(this, null); 197 clazz.accept(this, null);
192 } 198 }
193 199
194 dedent(); 200 dedent(1);
195 write("}"); 201 write("}");
196 writeEmptyLn(); 202 writeEmptyLn();
197 } 203 }
198 204
199 private static List<VariableElement> getStaticFields(CodeTypeElement clazz) { 205 private static List<VariableElement> getStaticFields(CodeTypeElement clazz) {
472 478
473 if (e.getModifiers().contains(Modifier.ABSTRACT)) { 479 if (e.getModifiers().contains(Modifier.ABSTRACT)) {
474 writeLn(";"); 480 writeLn(";");
475 } else if (e.getBodyTree() != null) { 481 } else if (e.getBodyTree() != null) {
476 writeLn(" {"); 482 writeLn(" {");
477 indent(); 483 indent(1);
478 e.getBodyTree().acceptCodeElementScanner(this, p); 484 e.getBodyTree().acceptCodeElementScanner(this, p);
479 dedent(); 485 dedent(1);
480 writeLn("}"); 486 writeLn("}");
481 } else if (e.getBody() != null) { 487 } else if (e.getBody() != null) {
482 write(" {"); 488 write(" {");
483 write(e.getBody()); 489 write(e.getBody());
484 writeLn("}"); 490 writeLn("}");
507 for (CodeTree tree : e.getEnclosedElements()) { 513 for (CodeTree tree : e.getEnclosedElements()) {
508 tree.acceptCodeElementScanner(this, p); 514 tree.acceptCodeElementScanner(this, p);
509 } 515 }
510 break; 516 break;
511 case INDENT: 517 case INDENT:
512 indent(); 518 indent(1);
513 for (CodeTree tree : e.getEnclosedElements()) { 519 for (CodeTree tree : e.getEnclosedElements()) {
514 tree.acceptCodeElementScanner(this, p); 520 tree.acceptCodeElementScanner(this, p);
515 } 521 }
516 dedent(); 522 dedent(1);
517 break; 523 break;
518 case NEW_LINE: 524 case NEW_LINE:
519 writeLn(); 525 writeLn();
520 break; 526 break;
521 case STRING: 527 case STRING:
563 write(" "); 569 write(" ");
564 } 570 }
565 } 571 }
566 } 572 }
567 573
568 private static final String LN = "\n"; 574 protected void indent(int count) {
569 575 indent += count;
570 protected void indent() { 576 }
571 indent++; 577
572 } 578 protected void dedent(int count) {
573 579 indent -= count;
574 protected void dedent() {
575 indent--;
576 } 580 }
577 581
578 protected void writeLn() { 582 protected void writeLn() {
579 write(LN); 583 writeLn("");
580 newLine = true;
581 } 584 }
582 585
583 protected void writeLn(String text) { 586 protected void writeLn(String text) {
584 write(text); 587 write(text);
585 write(LN); 588 write(LN);
589 lineLength = 0;
586 newLine = true; 590 newLine = true;
591 if (lineWrapping) {
592 dedent(LINE_WRAP_INDENTS);
593 lineWrapping = false;
594 }
595 lineWrapping = false;
587 } 596 }
588 597
589 protected void writeEmptyLn() { 598 protected void writeEmptyLn() {
590 writeLn(); 599 writeLn();
591 } 600 }
594 return write(name.toString()); 603 return write(name.toString());
595 } 604 }
596 605
597 private AbstractCodeWriter write(String m) { 606 private AbstractCodeWriter write(String m) {
598 try { 607 try {
608 lineLength += m.length();
599 if (newLine && m != LN) { 609 if (newLine && m != LN) {
600 writeIndent(); 610 writeIndent();
601 newLine = false; 611 newLine = false;
602 } 612 }
613 if (lineLength > LINE_LENGTH && m.length() > 0) {
614 char firstChar = m.charAt(0);
615 if (Character.isAlphabetic(firstChar)) {
616 if (!lineWrapping) {
617 indent(LINE_WRAP_INDENTS);
618 }
619 lineWrapping = true;
620 lineLength = 0;
621 write(LN);
622 writeIndent();
623 }
624 }
603 writer.write(m); 625 writer.write(m);
604 } catch (IOException e) { 626 } catch (IOException e) {
605 throw new RuntimeException(e); 627 throw new RuntimeException(e);
606 } 628 }
607 return this; 629 return this;
608 } 630 }
609 631
610 private void writeIndent() throws IOException { 632 private void writeIndent() throws IOException {
611 for (int i = 0; i < indent; i++) { 633 for (int i = 0; i < indent; i++) {
612 writer.write(" "); 634 lineLength += IDENT_STRING.length();
613 } 635 writer.write(IDENT_STRING);
614 } 636 }
637 }
638
639 private static class TrimTrailingSpaceWriter extends Writer {
640
641 private final Writer delegate;
642 private final StringBuilder buffer = new StringBuilder();
643
644 public TrimTrailingSpaceWriter(Writer delegate) {
645 this.delegate = delegate;
646 }
647
648 @Override
649 public void close() throws IOException {
650 this.delegate.close();
651 }
652
653 @Override
654 public void flush() throws IOException {
655 this.delegate.flush();
656 }
657
658 @Override
659 public void write(char[] cbuf, int off, int len) throws IOException {
660 buffer.append(cbuf, off, len);
661 int newLinePoint = buffer.indexOf(LN);
662
663 if (newLinePoint != -1) {
664 String lhs = trimTrailing(buffer.substring(0, newLinePoint));
665 delegate.write(lhs);
666 delegate.write(LN);
667 buffer.delete(0, newLinePoint + 1);
668 }
669 }
670
671 private static String trimTrailing(String s) {
672 int cut = 0;
673 for (int i = s.length() - 1; i >= 0; i--) {
674 if (Character.isWhitespace(s.charAt(i))) {
675 cut++;
676 } else {
677 break;
678 }
679 }
680 if (cut > 0) {
681 return s.substring(0, s.length() - cut);
682 }
683 return s;
684 }
685 }
686
615 } 687 }