OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library source_writer; | |
6 | |
7 | |
8 class Line { | |
9 | |
10 final int lineLength; | |
11 final tokens = <LineToken>[]; | |
12 final bool useTabs; | |
13 final int spacesPerIndent; | |
14 | |
15 Line({indent: 0, this.lineLength: 80, this.useTabs: false, | |
16 this.spacesPerIndent: 2}) { | |
17 if (indent > 0) { | |
18 _indent(indent); | |
19 } | |
20 } | |
21 | |
22 void addSpace() { | |
23 addSpaces(1); | |
24 } | |
25 | |
26 void addSpaces(int n) { | |
27 if (n > 0) { | |
28 tokens.add(new SpaceToken(n)); | |
29 } | |
30 } | |
31 | |
32 void addToken(LineToken token) { | |
33 tokens.add(token); | |
34 } | |
35 | |
36 bool isWhitespace() => tokens.every((tok) => tok is SpaceToken); | |
37 | |
38 void _indent(int n) { | |
39 tokens.add(useTabs ? new TabToken(n) : new SpaceToken(n * spacesPerIndent)); | |
40 } | |
41 | |
42 String toString() { | |
43 var buffer = new StringBuffer(); | |
44 tokens.forEach((tok) => buffer.write(tok.toString())); | |
45 return buffer.toString(); | |
46 } | |
47 | |
48 } | |
49 | |
50 | |
51 class LineToken { | |
52 | |
53 final String value; | |
54 | |
55 LineToken(this.value); | |
56 | |
57 String toString() => value; | |
58 } | |
59 | |
60 class SpaceToken extends LineToken { | |
61 | |
62 SpaceToken(int n) : super(getSpaces(n)); | |
63 } | |
64 | |
65 class TabToken extends LineToken { | |
66 | |
67 TabToken(int n) : super(getTabs(n)); | |
68 } | |
69 | |
70 | |
71 class NewlineToken extends LineToken { | |
72 | |
73 NewlineToken(String value) : super(value); | |
74 } | |
75 | |
76 | |
77 | |
78 class SourceWriter { | |
79 | |
80 final StringBuffer buffer = new StringBuffer(); | |
81 Line currentLine; | |
82 | |
83 final String lineSeparator; | |
84 int indentCount = 0; | |
85 | |
86 LineToken _lastToken; | |
87 | |
88 SourceWriter({this.indentCount: 0, this.lineSeparator: NEW_LINE}) { | |
89 currentLine = new Line(indent: indentCount); | |
90 } | |
91 | |
92 LineToken get lastToken => _lastToken; | |
93 | |
94 _addToken(LineToken token) { | |
95 _lastToken = token; | |
96 currentLine.addToken(token); | |
97 } | |
98 | |
99 void indent() { | |
100 ++indentCount; | |
101 } | |
102 | |
103 void newline() { | |
104 if (currentLine.isWhitespace()) { | |
105 currentLine.tokens.clear(); | |
106 } | |
107 _addToken(new NewlineToken(this.lineSeparator)); | |
108 buffer.write(currentLine.toString()); | |
109 currentLine = new Line(indent: indentCount); | |
110 } | |
111 | |
112 void newlines(int num) { | |
113 while (num-- > 0) { | |
114 newline(); | |
115 } | |
116 } | |
117 | |
118 void print(x) { | |
119 _addToken(new LineToken(x)); | |
120 } | |
121 | |
122 void println(String s) { | |
123 print(s); | |
124 newline(); | |
125 } | |
126 | |
127 void space() { | |
128 spaces(1); | |
129 } | |
130 | |
131 void spaces(n) { | |
132 currentLine.addSpaces(n); | |
133 } | |
134 | |
135 void unindent() { | |
136 --indentCount; | |
137 } | |
138 | |
139 String toString() { | |
140 var source = new StringBuffer(buffer.toString()); | |
141 if (!currentLine.isWhitespace()) { | |
142 source.write(currentLine); | |
143 } | |
144 return source.toString(); | |
145 } | |
146 | |
147 } | |
148 | |
149 const NEW_LINE = '\n'; | |
150 const SPACE = ' '; | |
151 const SPACES = const [ | |
152 '', | |
153 ' ', | |
154 ' ', | |
155 ' ', | |
156 ' ', | |
157 ' ', | |
158 ' ', | |
159 ' ', | |
160 ' ', | |
161 ' ', | |
162 ' ', | |
163 ' ', | |
164 ' ', | |
165 ' ', | |
166 ' ', | |
167 ' ', | |
168 ' ', | |
169 ]; | |
170 const TABS = const [ | |
171 '', | |
172 '\t', | |
173 '\t\t', | |
174 '\t\t\t', | |
175 '\t\t\t\t', | |
176 '\t\t\t\t\t', | |
177 '\t\t\t\t\t\t', | |
178 '\t\t\t\t\t\t\t', | |
179 '\t\t\t\t\t\t\t\t', | |
180 '\t\t\t\t\t\t\t\t\t', | |
181 '\t\t\t\t\t\t\t\t\t\t', | |
182 '\t\t\t\t\t\t\t\t\t\t\t', | |
183 '\t\t\t\t\t\t\t\t\t\t\t\t', | |
184 '\t\t\t\t\t\t\t\t\t\t\t\t\t', | |
185 '\t\t\t\t\t\t\t\t\t\t\t\t\t\t', | |
186 ]; | |
187 | |
188 | |
189 String getIndentString(int indentWidth, {bool useTabs: false}) => | |
190 useTabs ? getTabs(indentWidth) : getSpaces(indentWidth); | |
191 | |
192 String getSpaces(int n) => n < SPACES.length ? SPACES[n] : repeat(' ', n); | |
193 | |
194 String getTabs(int n) => n < TABS.length ? TABS[n] : repeat('\t', n); | |
195 | |
196 String repeat(String ch, int times) { | |
197 var sb = new StringBuffer(); | |
198 for (var i = 0; i < times; ++i) { | |
199 sb.write(ch); | |
200 } | |
201 return sb.toString(); | |
202 } | |
OLD | NEW |