001 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
002 // for details. All rights reserved. Use of this source code is governed by a
003 // BSD-style license that can be found in the LICENSE file.
004
005 package com.google.dart.compiler.util;
006
007 import java.util.Arrays;
008
009 public class TextOutputImpl implements TextOutput {
010 private final boolean compact;
011 private int identLevel = 0;
012 private final static int indentGranularity = 2;
013 private char[][] indents = new char[][] {new char[0]};
014 private boolean justNewlined;
015 private final StringBuilder out;
016 private int position = 0;
017 private int line = 0;
018 private int column = 0;
019
020 private OutListener outListener;
021
022 public TextOutputImpl() {
023 this(false);
024 }
025
026 public boolean isCompact() {
027 return compact;
028 }
029
030 public TextOutputImpl(boolean compact) {
031 this.compact = compact;
032 out = new StringBuilder();
033 }
034
035 @Override
036 public String toString() {
037 return out.toString();
038 }
039
040 @Override
041 public int getPosition() {
042 return position;
043 }
044
045 @Override
046 public int getLine() {
047 return line;
048 }
049
050 @Override
051 public int getColumn() {
052 return column;
053 }
054
055 @Override
056 public void indentIn() {
057 ++identLevel;
058 if (identLevel >= indents.length) {
059 // Cache a new level of indentation string.
060 char[] newIndentLevel = new char[identLevel * indentGranularity];
061 Arrays.fill(newIndentLevel, ' ');
062 char[][] newIndents = new char[indents.length + 1][];
063 System.arraycopy(indents, 0, newIndents, 0, indents.length);
064 newIndents[identLevel] = newIndentLevel;
065 indents = newIndents;
066 }
067 }
068
069 @Override
070 public void indentOut() {
071 --identLevel;
072 }
073
074 @Override
075 public void newline() {
076 out.append('\n');
077 position++;
078 line++;
079 column = 0;
080 justNewlined = true;
081 if (outListener != null) {
082 outListener.newLined();
083 }
084 }
085
086 @Override
087 public void print(double value) {
088 maybeIndent();
089 int oldLength = out.length();
090 out.append(value);
091 movePosition(out.length() - oldLength);
092 }
093
094 @Override
095 public void print(int value) {
096 maybeIndent();
097 int oldLength = out.length();
098 out.append(value);
099 movePosition(out.length() - oldLength);
100 }
101
102 @Override
103 public void print(char c) {
104 maybeIndent();
105 out.append(c);
106 movePosition(1);
107 }
108
109 private void movePosition(int l) {
110 position += l;
111 column += l;
112 }
113
114 @Override
115 public void print(char[] s) {
116 maybeIndent();
117 printAndCount(s);
118 }
119
120 @Override
121 public void print(CharSequence s) {
122 maybeIndent();
123 printAndCount(s);
124 }
125
126 @Override
127 public void printOpt(char c) {
128 if (!compact) {
129 print(c);
130 }
131 }
132
133 @Override
134 public void printOpt(char[] s) {
135 if (!compact) {
136 maybeIndent();
137 printAndCount(s);
138 }
139 }
140
141 @Override
142 public void printOpt(String s) {
143 if (!compact) {
144 maybeIndent();
145 printAndCount(s);
146 }
147 }
148
149 @Override
150 public void maybeIndent() {
151 if (justNewlined && !compact) {
152 printAndCount(indents[identLevel]);
153 justNewlined = false;
154 if (outListener != null) {
155 outListener.indentedAfterNewLine();
156 }
157 }
158 }
159
160 private void printAndCount(CharSequence charSequence) {
161 position += charSequence.length();
162 column += charSequence.length();
163 out.append(charSequence);
164 }
165
166 private void printAndCount(char[] chars) {
167 position += chars.length;
168 column += chars.length;
169 out.append(chars);
170 }
171
172 @Override
173 public boolean isJustNewlined() {
174 return justNewlined && !compact;
175 }
176
177 @Override
178 public void setOutListener(OutListener outListener) {
179 this.outListener = outListener;
180 }
181 }