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

Side by Side Diff: sdk/lib/_internal/compiler/js_lib/string_helper.dart

Issue 1212513002: sdk files reorganization to make dart2js a proper package (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: renamed Created 5 years, 5 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of _js_helper;
6
7 stringIndexOfStringUnchecked(receiver, other, startIndex) {
8 return JS('int', '#.indexOf(#, #)', receiver, other, startIndex);
9 }
10
11 substring1Unchecked(receiver, startIndex) {
12 return JS('String', '#.substring(#)', receiver, startIndex);
13 }
14
15 substring2Unchecked(receiver, startIndex, endIndex) {
16 return JS('String', '#.substring(#, #)', receiver, startIndex, endIndex);
17 }
18
19 stringContainsStringUnchecked(receiver, other, startIndex) {
20 return stringIndexOfStringUnchecked(receiver, other, startIndex) >= 0;
21 }
22
23 class StringMatch implements Match {
24 const StringMatch(int this.start,
25 String this.input,
26 String this.pattern);
27
28 int get end => start + pattern.length;
29 String operator[](int g) => group(g);
30 int get groupCount => 0;
31
32 String group(int group_) {
33 if (group_ != 0) {
34 throw new RangeError.value(group_);
35 }
36 return pattern;
37 }
38
39 List<String> groups(List<int> groups_) {
40 List<String> result = new List<String>();
41 for (int g in groups_) {
42 result.add(group(g));
43 }
44 return result;
45 }
46
47 final int start;
48 final String input;
49 final String pattern;
50 }
51
52 List<Match> allMatchesInStringUnchecked(String pattern, String string,
53 int startIndex) {
54 // Copied from StringBase.allMatches in
55 // /runtime/lib/string_base.dart
56 List<Match> result = new List<Match>();
57 int length = string.length;
58 int patternLength = pattern.length;
59 while (true) {
60 int position = stringIndexOfStringUnchecked(string, pattern, startIndex);
61 if (position == -1) {
62 break;
63 }
64 result.add(new StringMatch(position, string, pattern));
65 int endIndex = position + patternLength;
66 if (endIndex == length) {
67 break;
68 } else if (position == endIndex) {
69 ++startIndex; // empty match, advance and restart
70 } else {
71 startIndex = endIndex;
72 }
73 }
74 return result;
75 }
76
77 stringContainsUnchecked(receiver, other, startIndex) {
78 if (other is String) {
79 return stringContainsStringUnchecked(receiver, other, startIndex);
80 } else if (other is JSSyntaxRegExp) {
81 return other.hasMatch(receiver.substring(startIndex));
82 } else {
83 var substr = receiver.substring(startIndex);
84 return other.allMatches(substr).isNotEmpty;
85 }
86 }
87
88 stringReplaceJS(receiver, replacer, replacement) {
89 // The JavaScript String.replace method recognizes replacement
90 // patterns in the replacement string. Dart does not have that
91 // behavior.
92 replacement = JS('String', r'#.replace(/\$/g, "$$$$")', replacement);
93 return JS('String', r'#.replace(#, #)', receiver, replacer, replacement);
94 }
95
96 stringReplaceFirstRE(receiver, regexp, replacement, startIndex) {
97 var match = regexp._execGlobal(receiver, startIndex);
98 if (match == null) return receiver;
99 var start = match.start;
100 var end = match.end;
101 return stringReplaceRangeUnchecked(receiver, start, end, replacement);
102 }
103
104 const String ESCAPE_REGEXP = r'[[\]{}()*+?.\\^$|]';
105
106 stringReplaceAllUnchecked(receiver, pattern, replacement) {
107 checkString(replacement);
108 if (pattern is String) {
109 if (pattern == "") {
110 if (receiver == "") {
111 return replacement;
112 } else {
113 StringBuffer result = new StringBuffer();
114 int length = receiver.length;
115 result.write(replacement);
116 for (int i = 0; i < length; i++) {
117 result.write(receiver[i]);
118 result.write(replacement);
119 }
120 return result.toString();
121 }
122 } else {
123 var quoter = JS('', "new RegExp(#, 'g')", ESCAPE_REGEXP);
124 var quoted = JS('String', r'#.replace(#, "\\$&")', pattern, quoter);
125 var replacer = JS('', "new RegExp(#, 'g')", quoted);
126 return stringReplaceJS(receiver, replacer, replacement);
127 }
128 } else if (pattern is JSSyntaxRegExp) {
129 var re = regExpGetGlobalNative(pattern);
130 return stringReplaceJS(receiver, re, replacement);
131 } else {
132 checkNull(pattern);
133 // TODO(floitsch): implement generic String.replace (with patterns).
134 throw "String.replaceAll(Pattern) UNIMPLEMENTED";
135 }
136 }
137
138 String _matchString(Match match) => match[0];
139 String _stringIdentity(String string) => string;
140
141 stringReplaceAllFuncUnchecked(receiver, pattern, onMatch, onNonMatch) {
142 if (onMatch == null) onMatch = _matchString;
143 if (onNonMatch == null) onNonMatch = _stringIdentity;
144 if (pattern is String) {
145 return stringReplaceAllStringFuncUnchecked(receiver, pattern,
146 onMatch, onNonMatch);
147 }
148 // Placing the Pattern test here is indistingishable from placing it at the
149 // top of the method but it saves an extra check on the `pattern is String`
150 // path.
151 if (pattern is! Pattern) {
152 throw new ArgumentError.value(pattern, 'pattern', 'is not a Pattern');
153 }
154 StringBuffer buffer = new StringBuffer();
155 int startIndex = 0;
156 for (Match match in pattern.allMatches(receiver)) {
157 buffer.write(onNonMatch(receiver.substring(startIndex, match.start)));
158 buffer.write(onMatch(match));
159 startIndex = match.end;
160 }
161 buffer.write(onNonMatch(receiver.substring(startIndex)));
162 return buffer.toString();
163 }
164
165 stringReplaceAllEmptyFuncUnchecked(receiver, onMatch, onNonMatch) {
166 // Pattern is the empty string.
167 StringBuffer buffer = new StringBuffer();
168 int length = receiver.length;
169 int i = 0;
170 buffer.write(onNonMatch(""));
171 while (i < length) {
172 buffer.write(onMatch(new StringMatch(i, receiver, "")));
173 // Special case to avoid splitting a surrogate pair.
174 int code = receiver.codeUnitAt(i);
175 if ((code & ~0x3FF) == 0xD800 && length > i + 1) {
176 // Leading surrogate;
177 code = receiver.codeUnitAt(i + 1);
178 if ((code & ~0x3FF) == 0xDC00) {
179 // Matching trailing surrogate.
180 buffer.write(onNonMatch(receiver.substring(i, i + 2)));
181 i += 2;
182 continue;
183 }
184 }
185 buffer.write(onNonMatch(receiver[i]));
186 i++;
187 }
188 buffer.write(onMatch(new StringMatch(i, receiver, "")));
189 buffer.write(onNonMatch(""));
190 return buffer.toString();
191 }
192
193 stringReplaceAllStringFuncUnchecked(receiver, pattern, onMatch, onNonMatch) {
194 int patternLength = pattern.length;
195 if (patternLength == 0) {
196 return stringReplaceAllEmptyFuncUnchecked(receiver, onMatch, onNonMatch);
197 }
198 int length = receiver.length;
199 StringBuffer buffer = new StringBuffer();
200 int startIndex = 0;
201 while (startIndex < length) {
202 int position = stringIndexOfStringUnchecked(receiver, pattern, startIndex);
203 if (position == -1) {
204 break;
205 }
206 buffer.write(onNonMatch(receiver.substring(startIndex, position)));
207 buffer.write(onMatch(new StringMatch(position, receiver, pattern)));
208 startIndex = position + patternLength;
209 }
210 buffer.write(onNonMatch(receiver.substring(startIndex)));
211 return buffer.toString();
212 }
213
214
215 stringReplaceFirstUnchecked(receiver, pattern, replacement, int startIndex) {
216 if (pattern is String) {
217 int index = stringIndexOfStringUnchecked(receiver, pattern, startIndex);
218 if (index < 0) return receiver;
219 int end = index + pattern.length;
220 return stringReplaceRangeUnchecked(receiver, index, end, replacement);
221 }
222 if (pattern is JSSyntaxRegExp) {
223 return startIndex == 0
224 ? stringReplaceJS(receiver, regExpGetNative(pattern), replacement)
225 : stringReplaceFirstRE(receiver, pattern, replacement, startIndex);
226 }
227 checkNull(pattern);
228 Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator;
229 if (!matches.moveNext()) return receiver;
230 Match match = matches.current;
231 return receiver.replaceRange(match.start, match.end, replacement);
232 }
233
234 stringReplaceFirstMappedUnchecked(receiver, pattern, replace,
235 int startIndex) {
236 Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator;
237 if (!matches.moveNext()) return receiver;
238 Match match = matches.current;
239 String replacement = "${replace(match)}";
240 return receiver.replaceRange(match.start, match.end, replacement);
241 }
242
243 stringJoinUnchecked(array, separator) {
244 return JS('String', r'#.join(#)', array, separator);
245 }
246
247 String stringReplaceRangeUnchecked(String receiver,
248 int start, int end, String replacement) {
249 var prefix = JS('String', '#.substring(0, #)', receiver, start);
250 var suffix = JS('String', '#.substring(#)', receiver, end);
251 return "$prefix$replacement$suffix";
252 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698