| Index: runtime/lib/string_patch.dart
|
| diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
|
| index 11db8fe066a8f4e74ede1e9d314ac6427f612edf..f14a54da3c0e0550411c0e1a61262eaf43ae95b5 100644
|
| --- a/runtime/lib/string_patch.dart
|
| +++ b/runtime/lib/string_patch.dart
|
| @@ -312,7 +312,7 @@ class _StringBase {
|
|
|
| int indexOf(Pattern pattern, [int start = 0]) {
|
| if ((start < 0) || (start > this.length)) {
|
| - throw new RangeError.range(start, 0, this.length);
|
| + throw new RangeError.range(start, 0, this.length, "start");
|
| }
|
| if (pattern is String) {
|
| String other = pattern;
|
| @@ -844,26 +844,10 @@ class _StringBase {
|
| }
|
|
|
| Iterable<Match> allMatches(String string, [int start = 0]) {
|
| - List<Match> result = new List<Match>();
|
| - int length = string.length;
|
| - int patternLength = this.length;
|
| - int startIndex = start;
|
| - while (true) {
|
| - int position = string.indexOf(this, startIndex);
|
| - if (position == -1) {
|
| - break;
|
| - }
|
| - result.add(new _StringMatch(position, string, this));
|
| - int endIndex = position + patternLength;
|
| - if (endIndex == length) {
|
| - break;
|
| - } else if (position == endIndex) {
|
| - ++startIndex; // empty match, advance and restart
|
| - } else {
|
| - startIndex = endIndex;
|
| - }
|
| + if (start < 0 || start > string.length) {
|
| + throw new RangeError.range(start, 0, string.length, "start");
|
| }
|
| - return result;
|
| + return new _StringAllMatchesIterable(string, this, start);
|
| }
|
|
|
| Match matchAsPrefix(String string, [int start = 0]) {
|
| @@ -1321,3 +1305,53 @@ class _StringMatch implements Match {
|
| final String input;
|
| final String pattern;
|
| }
|
| +
|
| +
|
| +class _StringAllMatchesIterable extends Iterable<Match> {
|
| + final String _input;
|
| + final String _pattern;
|
| + final int _index;
|
| +
|
| + _StringAllMatchesIterable(this._input, this._pattern, this._index);
|
| +
|
| + Iterator<Match> get iterator =>
|
| + new _StringAllMatchesIterator(_input, _pattern, _index);
|
| +
|
| + Match get first {
|
| + int index = _input.indexOf(_pattern, _index);
|
| + if (index >= 0) {
|
| + return new _StringMatch(index, _input, _pattern);
|
| + }
|
| + throw IterableElementError.noElement();
|
| + }
|
| +}
|
| +
|
| +class _StringAllMatchesIterator implements Iterator<Match> {
|
| + final String _input;
|
| + final String _pattern;
|
| + int _index;
|
| + Match _current;
|
| +
|
| + _StringAllMatchesIterator(this._input, this._pattern, this._index);
|
| +
|
| + bool moveNext() {
|
| + if (_index + _pattern.length > _input.length) {
|
| + _current = null;
|
| + return false;
|
| + }
|
| + var index = _input.indexOf(_pattern, _index);
|
| + if (index < 0) {
|
| + _index = _input.length + 1;
|
| + _current = null;
|
| + return false;
|
| + }
|
| + int end = index + _pattern.length;
|
| + _current = new _StringMatch(index, _input, _pattern);
|
| + // Empty match, don't start at same location again.
|
| + if (end == _index) end++;
|
| + _index = end;
|
| + return true;
|
| + }
|
| +
|
| + Match get current => _current;
|
| +}
|
|
|