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 }