OLD | NEW |
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 _js_helper; | 5 part of _js_helper; |
6 | 6 |
7 stringIndexOfStringUnchecked(receiver, other, startIndex) { | 7 stringIndexOfStringUnchecked(receiver, other, startIndex) { |
8 return JS('int', '#.indexOf(#, #)', receiver, other, startIndex); | 8 return JS('int', '#.indexOf(#, #)', receiver, other, startIndex); |
9 } | 9 } |
10 | 10 |
11 substring1Unchecked(receiver, startIndex) { | 11 substring1Unchecked(receiver, startIndex) { |
12 return JS('String', '#.substring(#)', receiver, startIndex); | 12 return JS('String', '#.substring(#)', receiver, startIndex); |
13 } | 13 } |
14 | 14 |
15 substring2Unchecked(receiver, startIndex, endIndex) { | 15 substring2Unchecked(receiver, startIndex, endIndex) { |
16 return JS('String', '#.substring(#, #)', receiver, startIndex, endIndex); | 16 return JS('String', '#.substring(#, #)', receiver, startIndex, endIndex); |
17 } | 17 } |
18 | 18 |
19 stringContainsStringUnchecked(receiver, other, startIndex) { | 19 stringContainsStringUnchecked(receiver, other, startIndex) { |
20 return stringIndexOfStringUnchecked(receiver, other, startIndex) >= 0; | 20 return stringIndexOfStringUnchecked(receiver, other, startIndex) >= 0; |
21 } | 21 } |
22 | 22 |
23 class StringMatch implements Match { | 23 class StringMatch implements Match { |
24 const StringMatch(int this.start, | 24 const StringMatch(int this.start, String this.input, String this.pattern); |
25 String this.input, | |
26 String this.pattern); | |
27 | 25 |
28 int get end => start + pattern.length; | 26 int get end => start + pattern.length; |
29 String operator[](int g) => group(g); | 27 String operator [](int g) => group(g); |
30 int get groupCount => 0; | 28 int get groupCount => 0; |
31 | 29 |
32 String group(int group_) { | 30 String group(int group_) { |
33 if (group_ != 0) { | 31 if (group_ != 0) { |
34 throw new RangeError.value(group_); | 32 throw new RangeError.value(group_); |
35 } | 33 } |
36 return pattern; | 34 return pattern; |
37 } | 35 } |
38 | 36 |
39 List<String> groups(List<int> groups_) { | 37 List<String> groups(List<int> groups_) { |
40 List<String> result = new List<String>(); | 38 List<String> result = new List<String>(); |
41 for (int g in groups_) { | 39 for (int g in groups_) { |
42 result.add(group(g)); | 40 result.add(group(g)); |
43 } | 41 } |
44 return result; | 42 return result; |
45 } | 43 } |
46 | 44 |
47 final int start; | 45 final int start; |
48 final String input; | 46 final String input; |
49 final String pattern; | 47 final String pattern; |
50 } | 48 } |
51 | 49 |
52 Iterable<Match> allMatchesInStringUnchecked(String pattern, String string, | 50 Iterable<Match> allMatchesInStringUnchecked( |
53 int startIndex) { | 51 String pattern, String string, int startIndex) { |
54 return new _StringAllMatchesIterable(string, pattern, startIndex); | 52 return new _StringAllMatchesIterable(string, pattern, startIndex); |
55 } | 53 } |
56 | 54 |
57 class _StringAllMatchesIterable extends Iterable<Match> { | 55 class _StringAllMatchesIterable extends Iterable<Match> { |
58 final String _input; | 56 final String _input; |
59 final String _pattern; | 57 final String _pattern; |
60 final int _index; | 58 final int _index; |
61 | 59 |
62 _StringAllMatchesIterable(this._input, this._pattern, this._index); | 60 _StringAllMatchesIterable(this._input, this._pattern, this._index); |
63 | 61 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 } | 121 } |
124 | 122 |
125 stringReplaceFirstRE(receiver, regexp, replacement, startIndex) { | 123 stringReplaceFirstRE(receiver, regexp, replacement, startIndex) { |
126 var match = regexp._execGlobal(receiver, startIndex); | 124 var match = regexp._execGlobal(receiver, startIndex); |
127 if (match == null) return receiver; | 125 if (match == null) return receiver; |
128 var start = match.start; | 126 var start = match.start; |
129 var end = match.end; | 127 var end = match.end; |
130 return stringReplaceRangeUnchecked(receiver, start, end, replacement); | 128 return stringReplaceRangeUnchecked(receiver, start, end, replacement); |
131 } | 129 } |
132 | 130 |
133 | |
134 /// Returns a string for a RegExp pattern that matches [string]. This is done by | 131 /// Returns a string for a RegExp pattern that matches [string]. This is done by |
135 /// escaping all RegExp metacharacters. | 132 /// escaping all RegExp metacharacters. |
136 quoteStringForRegExp(string) { | 133 quoteStringForRegExp(string) { |
137 return JS('String', r'#.replace(/[[\]{}()*+?.\\^$|]/g, "\\$&")', string); | 134 return JS('String', r'#.replace(/[[\]{}()*+?.\\^$|]/g, "\\$&")', string); |
138 } | 135 } |
139 | 136 |
140 stringReplaceAllUnchecked(receiver, pattern, replacement) { | 137 stringReplaceAllUnchecked(receiver, pattern, replacement) { |
141 checkString(replacement); | 138 checkString(replacement); |
142 if (pattern is String) { | 139 if (pattern is String) { |
143 if (pattern == "") { | 140 if (pattern == "") { |
(...skipping 24 matching lines...) Expand all Loading... |
168 } | 165 } |
169 } | 166 } |
170 | 167 |
171 String _matchString(Match match) => match[0]; | 168 String _matchString(Match match) => match[0]; |
172 String _stringIdentity(String string) => string; | 169 String _stringIdentity(String string) => string; |
173 | 170 |
174 stringReplaceAllFuncUnchecked(receiver, pattern, onMatch, onNonMatch) { | 171 stringReplaceAllFuncUnchecked(receiver, pattern, onMatch, onNonMatch) { |
175 if (onMatch == null) onMatch = _matchString; | 172 if (onMatch == null) onMatch = _matchString; |
176 if (onNonMatch == null) onNonMatch = _stringIdentity; | 173 if (onNonMatch == null) onNonMatch = _stringIdentity; |
177 if (pattern is String) { | 174 if (pattern is String) { |
178 return stringReplaceAllStringFuncUnchecked(receiver, pattern, | 175 return stringReplaceAllStringFuncUnchecked( |
179 onMatch, onNonMatch); | 176 receiver, pattern, onMatch, onNonMatch); |
180 } | 177 } |
181 // Placing the Pattern test here is indistingishable from placing it at the | 178 // Placing the Pattern test here is indistingishable from placing it at the |
182 // top of the method but it saves an extra check on the `pattern is String` | 179 // top of the method but it saves an extra check on the `pattern is String` |
183 // path. | 180 // path. |
184 if (pattern is! Pattern) { | 181 if (pattern is! Pattern) { |
185 throw new ArgumentError.value(pattern, 'pattern', 'is not a Pattern'); | 182 throw new ArgumentError.value(pattern, 'pattern', 'is not a Pattern'); |
186 } | 183 } |
187 StringBuffer buffer = new StringBuffer(''); | 184 StringBuffer buffer = new StringBuffer(''); |
188 int startIndex = 0; | 185 int startIndex = 0; |
189 for (Match match in pattern.allMatches(receiver)) { | 186 for (Match match in pattern.allMatches(receiver)) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 break; | 234 break; |
238 } | 235 } |
239 buffer.write(onNonMatch(receiver.substring(startIndex, position))); | 236 buffer.write(onNonMatch(receiver.substring(startIndex, position))); |
240 buffer.write(onMatch(new StringMatch(position, receiver, pattern))); | 237 buffer.write(onMatch(new StringMatch(position, receiver, pattern))); |
241 startIndex = position + patternLength; | 238 startIndex = position + patternLength; |
242 } | 239 } |
243 buffer.write(onNonMatch(receiver.substring(startIndex))); | 240 buffer.write(onNonMatch(receiver.substring(startIndex))); |
244 return buffer.toString(); | 241 return buffer.toString(); |
245 } | 242 } |
246 | 243 |
247 | |
248 stringReplaceFirstUnchecked(receiver, pattern, replacement, int startIndex) { | 244 stringReplaceFirstUnchecked(receiver, pattern, replacement, int startIndex) { |
249 if (pattern is String) { | 245 if (pattern is String) { |
250 int index = stringIndexOfStringUnchecked(receiver, pattern, startIndex); | 246 int index = stringIndexOfStringUnchecked(receiver, pattern, startIndex); |
251 if (index < 0) return receiver; | 247 if (index < 0) return receiver; |
252 int end = index + pattern.length; | 248 int end = index + pattern.length; |
253 return stringReplaceRangeUnchecked(receiver, index, end, replacement); | 249 return stringReplaceRangeUnchecked(receiver, index, end, replacement); |
254 } | 250 } |
255 if (pattern is JSSyntaxRegExp) { | 251 if (pattern is JSSyntaxRegExp) { |
256 return startIndex == 0 | 252 return startIndex == 0 |
257 ? stringReplaceJS(receiver, regExpGetNative(pattern), replacement) | 253 ? stringReplaceJS(receiver, regExpGetNative(pattern), replacement) |
258 : stringReplaceFirstRE(receiver, pattern, replacement, startIndex); | 254 : stringReplaceFirstRE(receiver, pattern, replacement, startIndex); |
259 } | 255 } |
260 checkNull(pattern); | 256 checkNull(pattern); |
261 Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator; | 257 Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator; |
262 if (!matches.moveNext()) return receiver; | 258 if (!matches.moveNext()) return receiver; |
263 Match match = matches.current; | 259 Match match = matches.current; |
264 return receiver.replaceRange(match.start, match.end, replacement); | 260 return receiver.replaceRange(match.start, match.end, replacement); |
265 } | 261 } |
266 | 262 |
267 stringReplaceFirstMappedUnchecked(receiver, pattern, replace, | 263 stringReplaceFirstMappedUnchecked(receiver, pattern, replace, int startIndex) { |
268 int startIndex) { | |
269 Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator; | 264 Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator; |
270 if (!matches.moveNext()) return receiver; | 265 if (!matches.moveNext()) return receiver; |
271 Match match = matches.current; | 266 Match match = matches.current; |
272 String replacement = "${replace(match)}"; | 267 String replacement = "${replace(match)}"; |
273 return receiver.replaceRange(match.start, match.end, replacement); | 268 return receiver.replaceRange(match.start, match.end, replacement); |
274 } | 269 } |
275 | 270 |
276 stringJoinUnchecked(array, separator) { | 271 stringJoinUnchecked(array, separator) { |
277 return JS('String', r'#.join(#)', array, separator); | 272 return JS('String', r'#.join(#)', array, separator); |
278 } | 273 } |
279 | 274 |
280 String stringReplaceRangeUnchecked(String receiver, | 275 String stringReplaceRangeUnchecked( |
281 int start, int end, String replacement) { | 276 String receiver, int start, int end, String replacement) { |
282 var prefix = JS('String', '#.substring(0, #)', receiver, start); | 277 var prefix = JS('String', '#.substring(0, #)', receiver, start); |
283 var suffix = JS('String', '#.substring(#)', receiver, end); | 278 var suffix = JS('String', '#.substring(#)', receiver, end); |
284 return "$prefix$replacement$suffix"; | 279 return "$prefix$replacement$suffix"; |
285 } | 280 } |
OLD | NEW |