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 List regExpExec(JSSyntaxRegExp regExp, String str) { | 7 List regExpExec(JSSyntaxRegExp regExp, String str) { |
8 var nativeRegExp = regExpGetNative(regExp); | 8 var nativeRegExp = regExpGetNative(regExp); |
9 var result = JS('=List', r'#.exec(#)', nativeRegExp, str); | 9 var result = JS('=List', r'#.exec(#)', nativeRegExp, str); |
10 if (JS('bool', r'# == null', result)) return null; | 10 if (JS('bool', r'# == null', result)) return null; |
(...skipping 12 matching lines...) Expand all Loading... |
23 } | 23 } |
24 return r; | 24 return r; |
25 } | 25 } |
26 | 26 |
27 regExpAttachGlobalNative(JSSyntaxRegExp regExp) { | 27 regExpAttachGlobalNative(JSSyntaxRegExp regExp) { |
28 JS('void', r'#._re = #', regExp, regExpMakeNative(regExp, global: true)); | 28 JS('void', r'#._re = #', regExp, regExpMakeNative(regExp, global: true)); |
29 } | 29 } |
30 | 30 |
31 regExpMakeNative(JSSyntaxRegExp regExp, {bool global: false}) { | 31 regExpMakeNative(JSSyntaxRegExp regExp, {bool global: false}) { |
32 String pattern = regExp.pattern; | 32 String pattern = regExp.pattern; |
33 bool multiLine = regExp.multiLine; | 33 bool isMultiLine = regExp.isMultiLine; |
34 bool ignoreCase = regExp.ignoreCase; | 34 bool isCaseSensitive = regExp.isCaseSensitive; |
35 checkString(pattern); | 35 checkString(pattern); |
36 StringBuffer sb = new StringBuffer(); | 36 StringBuffer sb = new StringBuffer(); |
37 if (multiLine) sb.add('m'); | 37 if (isMultiLine) sb.add('m'); |
38 if (ignoreCase) sb.add('i'); | 38 if (!isCaseSensitive) sb.add('i'); |
39 if (global) sb.add('g'); | 39 if (global) sb.add('g'); |
40 try { | 40 try { |
41 return JS('var', r'new RegExp(#, #)', pattern, sb.toString()); | 41 return JS('var', r'new RegExp(#, #)', pattern, sb.toString()); |
42 } catch (e) { | 42 } catch (e) { |
43 throw new IllegalJSRegExpException(pattern, | 43 throw new IllegalJSRegExpException(pattern, |
44 JS('String', r'String(#)', e)); | 44 JS('String', r'String(#)', e)); |
45 } | 45 } |
46 } | 46 } |
47 | 47 |
48 int regExpMatchStart(m) => JS('int', r'#.index', m); | 48 int regExpMatchStart(m) => JS('int', r'#.index', m); |
49 | 49 |
50 class JSSyntaxRegExp implements RegExp { | 50 class JSSyntaxRegExp implements RegExp { |
51 final String _pattern; | 51 final String _pattern; |
52 final bool _multiLine; | 52 final bool _isMultiLine; |
53 final bool _ignoreCase; | 53 final bool _isCaseSensitive; |
54 | 54 |
55 const JSSyntaxRegExp(String pattern, | 55 const JSSyntaxRegExp(String pattern, |
56 {bool multiLine: false, | 56 {bool multiLine: false, |
57 bool ignoreCase: false}) | 57 bool caseSensitive: true}) |
58 : _pattern = pattern, | 58 : _pattern = pattern, |
59 _multiLine = multiLine, | 59 _isMultiLine = multiLine, |
60 _ignoreCase = ignoreCase; | 60 _isCaseSensitive = caseSensitive; |
61 | 61 |
62 Match firstMatch(String str) { | 62 Match firstMatch(String str) { |
63 List<String> m = regExpExec(this, checkString(str)); | 63 List<String> m = regExpExec(this, checkString(str)); |
64 if (m == null) return null; | 64 if (m == null) return null; |
65 var matchStart = regExpMatchStart(m); | 65 var matchStart = regExpMatchStart(m); |
66 // m.lastIndex only works with flag 'g'. | 66 // m.lastIndex only works with flag 'g'. |
67 var matchEnd = matchStart + m[0].length; | 67 var matchEnd = matchStart + m[0].length; |
68 return new _MatchImplementation(pattern, str, matchStart, matchEnd, m); | 68 return new _MatchImplementation(pattern, str, matchStart, matchEnd, m); |
69 } | 69 } |
70 | 70 |
71 bool hasMatch(String str) => regExpTest(this, checkString(str)); | 71 bool hasMatch(String str) => regExpTest(this, checkString(str)); |
72 | 72 |
73 String stringMatch(String str) { | 73 String stringMatch(String str) { |
74 var match = firstMatch(str); | 74 var match = firstMatch(str); |
75 return match == null ? null : match.group(0); | 75 return match == null ? null : match.group(0); |
76 } | 76 } |
77 | 77 |
78 Iterable<Match> allMatches(String str) { | 78 Iterable<Match> allMatches(String str) { |
79 checkString(str); | 79 checkString(str); |
80 return new _AllMatchesIterable(this, str); | 80 return new _AllMatchesIterable(this, str); |
81 } | 81 } |
82 | 82 |
83 String get pattern => _pattern; | 83 String get pattern => _pattern; |
84 bool get multiLine => _multiLine; | 84 bool get isMultiLine => _isMultiLine; |
85 bool get ignoreCase => _ignoreCase; | 85 bool get isCaseSensitive => _isCaseSensitive; |
86 | 86 |
87 static JSSyntaxRegExp _globalVersionOf(JSSyntaxRegExp other) { | 87 static JSSyntaxRegExp _globalVersionOf(JSSyntaxRegExp other) { |
88 JSSyntaxRegExp re = new JSSyntaxRegExp(other.pattern, | 88 JSSyntaxRegExp re = |
89 multiLine: other.multiLine, | 89 new JSSyntaxRegExp(other.pattern, |
90 ignoreCase: other.ignoreCase); | 90 multiLine: other.isMultiLine, |
| 91 caseSensitive: other.isCaseSensitive); |
91 regExpAttachGlobalNative(re); | 92 regExpAttachGlobalNative(re); |
92 return re; | 93 return re; |
93 } | 94 } |
94 | 95 |
95 _getNative() => regExpGetNative(this); | 96 _getNative() => regExpGetNative(this); |
96 } | 97 } |
97 | 98 |
98 class _MatchImplementation implements Match { | 99 class _MatchImplementation implements Match { |
99 final String pattern; | 100 final String pattern; |
100 final String str; | 101 final String str; |
(...skipping 14 matching lines...) Expand all Loading... |
115 | 116 |
116 List<String> groups(List<int> groups) { | 117 List<String> groups(List<int> groups) { |
117 List<String> out = []; | 118 List<String> out = []; |
118 for (int i in groups) { | 119 for (int i in groups) { |
119 out.add(group(i)); | 120 out.add(group(i)); |
120 } | 121 } |
121 return out; | 122 return out; |
122 } | 123 } |
123 } | 124 } |
124 | 125 |
125 class _AllMatchesIterable implements Iterable<Match> { | 126 class _AllMatchesIterable extends Iterable<Match> { |
126 final JSSyntaxRegExp _re; | 127 final JSSyntaxRegExp _re; |
127 final String _str; | 128 final String _str; |
128 | 129 |
129 const _AllMatchesIterable(this._re, this._str); | 130 const _AllMatchesIterable(this._re, this._str); |
130 | 131 |
131 Iterator<Match> iterator() => new _AllMatchesIterator(_re, _str); | 132 Iterator<Match> get iterator => new _AllMatchesIterator(_re, _str); |
132 } | 133 } |
133 | 134 |
134 class _AllMatchesIterator implements Iterator<Match> { | 135 class _AllMatchesIterator implements Iterator<Match> { |
135 final RegExp _re; | 136 final RegExp _re; |
136 final String _str; | 137 final String _str; |
137 Match _next; | 138 Match _current; |
138 bool _done; | |
139 | 139 |
140 _AllMatchesIterator(JSSyntaxRegExp re, String this._str) | 140 _AllMatchesIterator(JSSyntaxRegExp re, String this._str) |
141 : _done = false, _re = JSSyntaxRegExp._globalVersionOf(re); | 141 : _re = JSSyntaxRegExp._globalVersionOf(re); |
142 | 142 |
143 Match next() { | 143 Match get current => _current; |
144 if (!hasNext) { | |
145 throw new StateError("No more elements"); | |
146 } | |
147 | 144 |
148 // _next is set by [hasNext]. | 145 bool moveNext() { |
149 var next = _next; | |
150 _next = null; | |
151 return next; | |
152 } | |
153 | |
154 bool get hasNext { | |
155 if (_done) { | |
156 return false; | |
157 } else if (_next != null) { | |
158 return true; | |
159 } | |
160 | |
161 // firstMatch actually acts as nextMatch because of | 146 // firstMatch actually acts as nextMatch because of |
162 // hidden global flag. | 147 // hidden global flag. |
163 _next = _re.firstMatch(_str); | 148 _current = _re.firstMatch(_str); |
164 if (_next == null) { | 149 return _current != null; |
165 _done = true; | |
166 return false; | |
167 } else { | |
168 return true; | |
169 } | |
170 } | 150 } |
171 } | 151 } |
OLD | NEW |