| 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 @patch |    5 @patch class RegExp { | 
|    6 class RegExp { |    6   @patch factory RegExp(String source, | 
|    7   @patch |    7                               {bool multiLine: false, | 
|    8   factory RegExp(String source, |    8                                bool caseSensitive: true}) { | 
|    9       {bool multiLine: false, bool caseSensitive: true}) { |    9     _RegExpHashKey key = new _RegExpHashKey( | 
|   10     _RegExpHashKey key = new _RegExpHashKey(source, multiLine, caseSensitive); |   10         source, multiLine, caseSensitive); | 
|   11     _RegExpHashValue value = _cache[key]; |   11     _RegExpHashValue value = _cache[key]; | 
|   12  |   12  | 
|   13     if (value == null) { |   13     if (value == null) { | 
|   14       if (_cache.length > _MAX_CACHE_SIZE) { |   14       if (_cache.length > _MAX_CACHE_SIZE) { | 
|   15         _RegExpHashKey lastKey = _recentlyUsed.last; |   15         _RegExpHashKey lastKey = _recentlyUsed.last; | 
|   16         lastKey.unlink(); |   16         lastKey.unlink(); | 
|   17         _cache.remove(lastKey); |   17         _cache.remove(lastKey); | 
|   18       } |   18       } | 
|   19  |   19  | 
|   20       value = new _RegExpHashValue( |   20       value = new _RegExpHashValue( | 
|   21           new _RegExp(source, |   21           new _RegExp(source, | 
|   22               multiLine: multiLine, caseSensitive: caseSensitive), |   22                               multiLine: multiLine, | 
 |   23                               caseSensitive: caseSensitive), | 
|   23           key); |   24           key); | 
|   24       _cache[key] = value; |   25       _cache[key] = value; | 
|   25     } else { |   26     } else { | 
|   26       value.key.unlink(); |   27       value.key.unlink(); | 
|   27     } |   28     } | 
|   28  |   29  | 
|   29     assert(value != null); |   30     assert(value != null); | 
|   30  |   31  | 
|   31     _recentlyUsed.addFirst(value.key); |   32     _recentlyUsed.addFirst(value.key); | 
|   32     assert(_recentlyUsed.length == _cache.length); |   33     assert(_recentlyUsed.length == _cache.length); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|   43   // may not be removed from the cache. |   44   // may not be removed from the cache. | 
|   44   // TODO(zerny): Use self-sizing cache similar to _AccessorCache in |   45   // TODO(zerny): Use self-sizing cache similar to _AccessorCache in | 
|   45   // mirrors_impl.dart. |   46   // mirrors_impl.dart. | 
|   46   static const int _MAX_CACHE_SIZE = 256; |   47   static const int _MAX_CACHE_SIZE = 256; | 
|   47   static final Map<_RegExpHashKey, _RegExpHashValue> _cache = |   48   static final Map<_RegExpHashKey, _RegExpHashValue> _cache = | 
|   48       new HashMap<_RegExpHashKey, _RegExpHashValue>(); |   49       new HashMap<_RegExpHashKey, _RegExpHashValue>(); | 
|   49   static final LinkedList<_RegExpHashKey> _recentlyUsed = |   50   static final LinkedList<_RegExpHashKey> _recentlyUsed = | 
|   50       new LinkedList<_RegExpHashKey>(); |   51       new LinkedList<_RegExpHashKey>(); | 
|   51 } |   52 } | 
|   52  |   53  | 
 |   54  | 
|   53 // Represents both a key in the regular expression cache as well as its |   55 // Represents both a key in the regular expression cache as well as its | 
|   54 // corresponding entry in the LRU list. |   56 // corresponding entry in the LRU list. | 
|   55 class _RegExpHashKey extends LinkedListEntry<_RegExpHashKey> { |   57 class _RegExpHashKey extends LinkedListEntry<_RegExpHashKey> { | 
|   56   final String pattern; |   58   final String pattern; | 
|   57   final bool multiLine; |   59   final bool multiLine; | 
|   58   final bool caseSensitive; |   60   final bool caseSensitive; | 
|   59  |   61  | 
|   60   _RegExpHashKey(this.pattern, this.multiLine, this.caseSensitive); |   62   _RegExpHashKey(this.pattern, this.multiLine, this.caseSensitive); | 
|   61  |   63  | 
|   62   int get hashCode => pattern.hashCode; |   64   int get hashCode => pattern.hashCode; | 
|   63   bool operator ==(_RegExpHashKey that) { |   65   bool operator==(_RegExpHashKey that) { | 
|   64     return (this.pattern == that.pattern) && |   66     return (this.pattern == that.pattern) && | 
|   65         (this.multiLine == that.multiLine) && |   67            (this.multiLine == that.multiLine) && | 
|   66         (this.caseSensitive == that.caseSensitive); |   68            (this.caseSensitive == that.caseSensitive); | 
|   67   } |   69   } | 
|   68 } |   70 } | 
|   69  |   71  | 
 |   72  | 
|   70 // Represents a value in the regular expression cache. Contains a pointer |   73 // Represents a value in the regular expression cache. Contains a pointer | 
|   71 // back to the key in order to access the corresponding LRU entry. |   74 // back to the key in order to access the corresponding LRU entry. | 
|   72 class _RegExpHashValue { |   75 class _RegExpHashValue { | 
|   73   final _RegExp regexp; |   76   final _RegExp regexp; | 
|   74   final _RegExpHashKey key; |   77   final _RegExpHashKey key; | 
|   75  |   78  | 
|   76   _RegExpHashValue(this.regexp, this.key); |   79   _RegExpHashValue(this.regexp, this.key); | 
|   77 } |   80 } | 
|   78  |   81  | 
 |   82  | 
|   79 class _RegExpMatch implements Match { |   83 class _RegExpMatch implements Match { | 
|   80   _RegExpMatch(this._regexp, this.input, this._match); |   84   _RegExpMatch(this._regexp, this.input, this._match); | 
|   81  |   85  | 
|   82   int get start => _start(0); |   86   int get start => _start(0); | 
|   83   int get end => _end(0); |   87   int get end => _end(0); | 
|   84  |   88  | 
|   85   int _start(int groupIdx) { |   89   int _start(int groupIdx) { | 
|   86     return _match[(groupIdx * _MATCH_PAIR)]; |   90     return _match[(groupIdx * _MATCH_PAIR)]; | 
|   87   } |   91   } | 
|   88  |   92  | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
|  118   int get groupCount => _regexp._groupCount; |  122   int get groupCount => _regexp._groupCount; | 
|  119  |  123  | 
|  120   Pattern get pattern => _regexp; |  124   Pattern get pattern => _regexp; | 
|  121  |  125  | 
|  122   final RegExp _regexp; |  126   final RegExp _regexp; | 
|  123   final String input; |  127   final String input; | 
|  124   final List<int> _match; |  128   final List<int> _match; | 
|  125   static const int _MATCH_PAIR = 2; |  129   static const int _MATCH_PAIR = 2; | 
|  126 } |  130 } | 
|  127  |  131  | 
 |  132  | 
|  128 class _RegExp implements RegExp { |  133 class _RegExp implements RegExp { | 
|  129   factory _RegExp(String pattern, |  134   factory _RegExp( | 
 |  135       String pattern, | 
|  130       {bool multiLine: false, |  136       {bool multiLine: false, | 
|  131       bool caseSensitive: true}) native "RegExp_factory"; |  137        bool caseSensitive: true}) native "RegExp_factory"; | 
|  132  |  138  | 
|  133   Match firstMatch(String str) { |  139   Match firstMatch(String str) { | 
|  134     if (str is! String) throw new ArgumentError(str); |  140     if (str is! String) throw new ArgumentError(str); | 
|  135     List match = _ExecuteMatch(str, 0); |  141     List match = _ExecuteMatch(str, 0); | 
|  136     if (match == null) { |  142     if (match == null) { | 
|  137       return null; |  143       return null; | 
|  138     } |  144     } | 
|  139     return new _RegExpMatch(this, str, match); |  145     return new _RegExpMatch(this, str, match); | 
|  140   } |  146   } | 
|  141  |  147  | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  186   // character (digit, letter or underscore) and 0x00 otherwise. |  192   // character (digit, letter or underscore) and 0x00 otherwise. | 
|  187   // Used by generated RegExp code. |  193   // Used by generated RegExp code. | 
|  188   static const List<int> _wordCharacterMap = const <int>[ |  194   static const List<int> _wordCharacterMap = const <int>[ | 
|  189     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  195     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  190     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  196     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  191     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  197     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  192     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  198     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  193  |  199  | 
|  194     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  200     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  195     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  201     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  196     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // '0' - '7' |  202     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // '0' - '7' | 
|  197     0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // '8' - '9' |  203     0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // '8' - '9' | 
|  198  |  204  | 
|  199     0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'A' - 'G' |  205     0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // 'A' - 'G' | 
|  200     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'H' - 'O' |  206     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // 'H' - 'O' | 
|  201     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'P' - 'W' |  207     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // 'P' - 'W' | 
|  202     0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, // 'X' - 'Z', '_' |  208     0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,  // 'X' - 'Z', '_' | 
|  203  |  209  | 
|  204     0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'a' - 'g' |  210     0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // 'a' - 'g' | 
|  205     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'h' - 'o' |  211     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // 'h' - 'o' | 
|  206     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'p' - 'w' |  212     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // 'p' - 'w' | 
|  207     0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, // 'x' - 'z' |  213     0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,  // 'x' - 'z' | 
|  208     // Latin-1 range |  214     // Latin-1 range | 
|  209     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  215     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  210     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  216     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  211     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  217     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  212     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  218     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  213  |  219  | 
|  214     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  220     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  215     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  221     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  216     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  222     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  217     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  223     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  218  |  224  | 
|  219     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  225     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  220     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  226     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  221     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  227     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  222     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  228     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  223  |  229  | 
|  224     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  230     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  225     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  231     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  226     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  232     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  227     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |  233     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 
|  228   ]; |  234   ]; | 
|  229  |  235  | 
|  230   List _ExecuteMatch(String str, int start_index) native "RegExp_ExecuteMatch"; |  236   List _ExecuteMatch(String str, int start_index) | 
 |  237       native "RegExp_ExecuteMatch"; | 
|  231  |  238  | 
|  232   List _ExecuteMatchSticky(String str, int start_index) |  239   List _ExecuteMatchSticky(String str, int start_index) | 
|  233       native "RegExp_ExecuteMatchSticky"; |  240       native "RegExp_ExecuteMatchSticky"; | 
|  234 } |  241 } | 
|  235  |  242  | 
|  236 class _AllMatchesIterable extends IterableBase<Match> { |  243 class _AllMatchesIterable extends IterableBase<Match> { | 
|  237   final _RegExp _re; |  244   final _RegExp _re; | 
|  238   final String _str; |  245   final String _str; | 
|  239   final int _start; |  246   final int _start; | 
|  240  |  247  | 
|  241   _AllMatchesIterable(this._re, this._str, this._start); |  248   _AllMatchesIterable(this._re, this._str, this._start); | 
|  242  |  249  | 
|  243   Iterator<Match> get iterator => new _AllMatchesIterator(_re, _str, _start); |  250   Iterator<Match> get iterator => new _AllMatchesIterator(_re, _str, _start); | 
|  244 } |  251 } | 
|  245  |  252  | 
|  246 class _AllMatchesIterator implements Iterator<Match> { |  253 class _AllMatchesIterator implements Iterator<Match> { | 
|  247   final String _str; |  254   final String _str; | 
|  248   int _nextIndex; |  255   int _nextIndex; | 
|  249   _RegExp _re; |  256   _RegExp _re; | 
|  250   Match _current; |  257   Match _current; | 
|  251  |  258  | 
|  252   _AllMatchesIterator(this._re, this._str, this._nextIndex); |  259   _AllMatchesIterator(this._re, this._str, this._nextIndex); | 
|  253  |  260  | 
|  254   Match get current => _current; |  261   Match get current => _current; | 
|  255  |  262  | 
|  256   bool moveNext() { |  263   bool moveNext() { | 
|  257     if (_re == null) return false; // Cleared after a failed match. |  264     if (_re == null) return false;  // Cleared after a failed match. | 
|  258     if (_nextIndex <= _str.length) { |  265     if (_nextIndex <= _str.length) { | 
|  259       var match = _re._ExecuteMatch(_str, _nextIndex); |  266       var match = _re._ExecuteMatch(_str, _nextIndex); | 
|  260       if (match != null) { |  267       if (match != null) { | 
|  261         _current = new _RegExpMatch(_re, _str, match); |  268         _current = new _RegExpMatch(_re, _str, match); | 
|  262         _nextIndex = _current.end; |  269         _nextIndex = _current.end; | 
|  263         if (_nextIndex == _current.start) { |  270         if (_nextIndex == _current.start) { | 
|  264           // Zero-width match. Advance by one more. |  271           // Zero-width match. Advance by one more. | 
|  265           _nextIndex++; |  272           _nextIndex++; | 
|  266         } |  273         } | 
|  267         return true; |  274         return true; | 
|  268       } |  275       } | 
|  269     } |  276     } | 
|  270     _current = null; |  277     _current = null; | 
|  271     _re = null; |  278     _re = null; | 
|  272     return false; |  279     return false; | 
|  273   } |  280   } | 
|  274 } |  281 } | 
| OLD | NEW |