Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(776)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/tree/dartstring.dart

Issue 11783009: Big merge from experimental to bleeding edge. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of tree; 5 part of tree;
6 6
7 /** 7 /**
8 * The [DartString] type represents a Dart string value as a sequence of Unicode 8 * The [DartString] type represents a Dart string value as a sequence of Unicode
9 * Scalar Values. 9 * Scalar Values.
10 * After parsing, any valid [LiteralString] will contain a [DartString] 10 * After parsing, any valid [LiteralString] will contain a [DartString]
11 * representing its content after removing quotes and resolving escapes in 11 * representing its content after removing quotes and resolving escapes in
12 * its source. 12 * its source.
13 */ 13 */
14 abstract class DartString implements Iterable<int> { 14 abstract class DartString extends Iterable<int> {
15 factory DartString.empty() => const LiteralDartString(""); 15 factory DartString.empty() => const LiteralDartString("");
16 // This is a convenience constructor. If you need a const literal DartString, 16 // This is a convenience constructor. If you need a const literal DartString,
17 // use [const LiteralDartString(string)] directly. 17 // use [const LiteralDartString(string)] directly.
18 factory DartString.literal(String string) => new LiteralDartString(string); 18 factory DartString.literal(String string) => new LiteralDartString(string);
19 factory DartString.rawString(SourceString source, int length) => 19 factory DartString.rawString(SourceString source, int length) =>
20 new RawSourceDartString(source, length); 20 new RawSourceDartString(source, length);
21 factory DartString.escapedString(SourceString source, int length) => 21 factory DartString.escapedString(SourceString source, int length) =>
22 new EscapedSourceDartString(source, length); 22 new EscapedSourceDartString(source, length);
23 factory DartString.concat(DartString first, DartString second) { 23 factory DartString.concat(DartString first, DartString second) {
24 if (first.isEmpty) return second; 24 if (first.isEmpty) return second;
25 if (second.isEmpty) return first; 25 if (second.isEmpty) return first;
26 return new ConsDartString(first, second); 26 return new ConsDartString(first, second);
27 } 27 }
28 const DartString(); 28 const DartString();
29 int get length; 29 int get length;
30 bool get isEmpty => length == 0; 30 bool get isEmpty => length == 0;
31 Iterator<int> iterator(); 31 Iterator<int> get iterator;
32 String slowToString(); 32 String slowToString();
33 33
34 bool operator ==(var other) { 34 bool operator ==(var other) {
35 if (other is !DartString) return false; 35 if (other is !DartString) return false;
36 DartString otherString = other; 36 DartString otherString = other;
37 if (length != otherString.length) return false; 37 if (length != otherString.length) return false;
38 Iterator it1 = iterator(); 38 Iterator it1 = iterator;
39 Iterator it2 = otherString.iterator(); 39 Iterator it2 = otherString.iterator;
40 while (it1.hasNext) { 40 while (it1.moveNext()) {
41 if (it1.next() != it2.next()) return false; 41 if (!it2.moveNext()) return false;
42 if (it1.current != it2.current) return false;
42 } 43 }
43 return true; 44 return true;
44 } 45 }
45 String toString() => "DartString#${length}:${slowToString()}"; 46 String toString() => "DartString#${length}:${slowToString()}";
46 SourceString get source; 47 SourceString get source;
47 } 48 }
48 49
49 50
50 /** 51 /**
51 * A [DartString] where the content is represented by an actual [String]. 52 * A [DartString] where the content is represented by an actual [String].
52 */ 53 */
53 class LiteralDartString extends DartString { 54 class LiteralDartString extends DartString {
54 final String string; 55 final String string;
55 const LiteralDartString(this.string); 56 const LiteralDartString(this.string);
56 int get length => string.length; 57 int get length => string.length;
57 Iterator<int> iterator() => new StringCodeIterator(string); 58 Iterator<int> get iterator => new StringCodeIterator(string);
58 String slowToString() => string; 59 String slowToString() => string;
59 SourceString get source => new StringWrapper(string); 60 SourceString get source => new StringWrapper(string);
60 } 61 }
61 62
62 /** 63 /**
63 * A [DartString] where the content comes from a slice of the program source. 64 * A [DartString] where the content comes from a slice of the program source.
64 */ 65 */
65 abstract class SourceBasedDartString extends DartString { 66 abstract class SourceBasedDartString extends DartString {
66 String toStringCache = null; 67 String toStringCache = null;
67 final SourceString source; 68 final SourceString source;
68 final int length; 69 final int length;
69 SourceBasedDartString(this.source, this.length); 70 SourceBasedDartString(this.source, this.length);
70 Iterator<int> iterator(); 71 Iterator<int> get iterator;
71 } 72 }
72 73
73 /** 74 /**
74 * Special case of a [SourceBasedDartString] where we know the source doesn't 75 * Special case of a [SourceBasedDartString] where we know the source doesn't
75 * contain any escapes. 76 * contain any escapes.
76 */ 77 */
77 class RawSourceDartString extends SourceBasedDartString { 78 class RawSourceDartString extends SourceBasedDartString {
78 RawSourceDartString(source, length) : super(source, length); 79 RawSourceDartString(source, length) : super(source, length);
79 Iterator<int> iterator() => source.iterator(); 80 Iterator<int> get iterator => source.iterator;
80 String slowToString() { 81 String slowToString() {
81 if (toStringCache != null) return toStringCache; 82 if (toStringCache != null) return toStringCache;
82 toStringCache = source.slowToString(); 83 toStringCache = source.slowToString();
83 return toStringCache; 84 return toStringCache;
84 } 85 }
85 } 86 }
86 87
87 /** 88 /**
88 * General case of a [SourceBasedDartString] where the source might contain 89 * General case of a [SourceBasedDartString] where the source might contain
89 * escapes. 90 * escapes.
90 */ 91 */
91 class EscapedSourceDartString extends SourceBasedDartString { 92 class EscapedSourceDartString extends SourceBasedDartString {
92 EscapedSourceDartString(source, length) : super(source, length); 93 EscapedSourceDartString(source, length) : super(source, length);
93 Iterator<int> iterator() { 94 Iterator<int> get iterator {
94 if (toStringCache != null) return new StringCodeIterator(toStringCache); 95 if (toStringCache != null) return new StringCodeIterator(toStringCache);
95 return new StringEscapeIterator(source); 96 return new StringEscapeIterator(source);
96 } 97 }
97 String slowToString() { 98 String slowToString() {
98 if (toStringCache != null) return toStringCache; 99 if (toStringCache != null) return toStringCache;
99 StringBuffer buffer = new StringBuffer(); 100 StringBuffer buffer = new StringBuffer();
100 StringEscapeIterator it = new StringEscapeIterator(source); 101 StringEscapeIterator it = new StringEscapeIterator(source);
101 while (it.hasNext) { 102 while (it.moveNext()) {
102 buffer.addCharCode(it.next()); 103 buffer.addCharCode(it.current);
103 } 104 }
104 toStringCache = buffer.toString(); 105 toStringCache = buffer.toString();
105 return toStringCache; 106 return toStringCache;
106 } 107 }
107 } 108 }
108 109
109 /** 110 /**
110 * The concatenation of two [DartString]s. 111 * The concatenation of two [DartString]s.
111 */ 112 */
112 class ConsDartString extends DartString { 113 class ConsDartString extends DartString {
113 final DartString left; 114 final DartString left;
114 final DartString right; 115 final DartString right;
115 final int length; 116 final int length;
116 String toStringCache; 117 String toStringCache;
117 ConsDartString(DartString left, DartString right) 118 ConsDartString(DartString left, DartString right)
118 : this.left = left, 119 : this.left = left,
119 this.right = right, 120 this.right = right,
120 length = left.length + right.length; 121 length = left.length + right.length;
121 122
122 Iterator<int> iterator() => new ConsDartStringIterator(this); 123 Iterator<int> get iterator => new ConsDartStringIterator(this);
123 124
124 String slowToString() { 125 String slowToString() {
125 if (toStringCache != null) return toStringCache; 126 if (toStringCache != null) return toStringCache;
126 toStringCache = left.slowToString().concat(right.slowToString()); 127 toStringCache = left.slowToString().concat(right.slowToString());
127 return toStringCache; 128 return toStringCache;
128 } 129 }
129 SourceString get source => new StringWrapper(slowToString()); 130 SourceString get source => new StringWrapper(slowToString());
130 } 131 }
131 132
132 class ConsDartStringIterator implements Iterator<int> { 133 class ConsDartStringIterator implements Iterator<int> {
133 Iterator<int> current; 134 HasNextIterator<int> currentIterator;
134 DartString right; 135 DartString right;
135 bool hasNextLookAhead; 136 bool hasNextLookAhead;
137 int _current = null;
138
136 ConsDartStringIterator(ConsDartString cons) 139 ConsDartStringIterator(ConsDartString cons)
137 : current = cons.left.iterator(), 140 : currentIterator = new HasNextIterator<int>(cons.left.iterator),
138 right = cons.right { 141 right = cons.right {
139 hasNextLookAhead = current.hasNext; 142 hasNextLookAhead = currentIterator.hasNext;
140 if (!hasNextLookAhead) { 143 if (!hasNextLookAhead) {
141 nextPart(); 144 nextPart();
142 } 145 }
143 } 146 }
144 bool get hasNext { 147
145 return hasNextLookAhead; 148 int get current => _current;
146 } 149
147 int next() { 150 bool moveNext() {
148 assert(hasNextLookAhead); 151 if (!hasNextLookAhead) {
149 int result = current.next(); 152 _current = null;
150 hasNextLookAhead = current.hasNext; 153 return false;
154 }
155 _current = currentIterator.next();
156 hasNextLookAhead = currentIterator.hasNext;
151 if (!hasNextLookAhead) { 157 if (!hasNextLookAhead) {
152 nextPart(); 158 nextPart();
153 } 159 }
154 return result; 160 return true;
155 } 161 }
156 void nextPart() { 162 void nextPart() {
157 if (right != null) { 163 if (right != null) {
158 current = right.iterator(); 164 currentIterator = new HasNextIterator<int>(right.iterator);
159 right = null; 165 right = null;
160 hasNextLookAhead = current.hasNext; 166 hasNextLookAhead = currentIterator.hasNext;
161 } 167 }
162 } 168 }
163 } 169 }
164 170
165 /** 171 /**
166 *Iterator that returns the actual string contents of a string with escapes. 172 *Iterator that returns the actual string contents of a string with escapes.
167 */ 173 */
168 class StringEscapeIterator implements Iterator<int>{ 174 class StringEscapeIterator implements Iterator<int>{
169 final Iterator<int> source; 175 final Iterator<int> source;
170 StringEscapeIterator(SourceString source) : this.source = source.iterator(); 176 int _current = null;
171 bool get hasNext => source.hasNext; 177
172 int next() { 178 StringEscapeIterator(SourceString source) : this.source = source.iterator;
173 int code = source.next(); 179
174 if (!identical(code, $BACKSLASH)) { 180 int get current => _current;
175 return code; 181
182 bool moveNext() {
183 if (!source.moveNext()) {
184 _current = null;
185 return false;
176 } 186 }
177 code = source.next(); 187 int code = source.current;
178 if (identical(code, $n)) return $LF; 188 if (code != $BACKSLASH) {
179 if (identical(code, $r)) return $CR; 189 _current = code;
180 if (identical(code, $t)) return $TAB; 190 return true;
181 if (identical(code, $b)) return $BS;
182 if (identical(code, $f)) return $FF;
183 if (identical(code, $v)) return $VTAB;
184 if (identical(code, $x)) {
185 int value = hexDigitValue(source.next());
186 value = value * 16 + hexDigitValue(source.next());
187 return value;
188 } 191 }
189 if (identical(code, $u)) { 192 source.moveNext();
190 int value = 0; 193 code = source.current;
191 code = source.next(); 194 switch (code) {
192 if (identical(code, $OPEN_CURLY_BRACKET)) { 195 case $n: _current = $LF; break;
193 for (code = source.next(); 196 case $r: _current = $CR; break;
194 code != $CLOSE_CURLY_BRACKET; 197 case $t: _current = $TAB; break;
195 code = source.next()) { 198 case $b: _current = $BS; break;
196 value = value * 16 + hexDigitValue(code); 199 case $f: _current = $FF; break;
200 case $v: _current = $VTAB; break;
201 case $x:
202 source.moveNext();
203 int value = hexDigitValue(source.current);
204 source.moveNext();
205 value = value * 16 + hexDigitValue(source.current);
206 _current = value;
207 break;
208 case $u:
209 int value = 0;
210 source.moveNext();
211 code = source.current;
212 if (code == $OPEN_CURLY_BRACKET) {
213 source.moveNext();
214 while (source.current != $CLOSE_CURLY_BRACKET) {
215 value = value * 16 + hexDigitValue(source.current);
216 source.moveNext();
217 }
218 _current = value;
219 break;
197 } 220 }
198 return value; 221 // Four digit hex value.
199 } 222 value = hexDigitValue(code);
200 // Four digit hex value. 223 for (int i = 0; i < 3; i++) {
201 value = hexDigitValue(code); 224 source.moveNext();
202 for (int i = 0; i < 3; i++) { 225 value = value * 16 + hexDigitValue(source.current);
203 code = source.next(); 226 }
204 value = value * 16 + hexDigitValue(code); 227 _current = value;
205 } 228 break;
206 return value; 229 default:
230 _current = code;
207 } 231 }
208 return code; 232 return true;
209 } 233 }
210 } 234 }
211 235
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698