| Index: lib/src/string_scanner.dart
|
| diff --git a/lib/src/string_scanner.dart b/lib/src/string_scanner.dart
|
| index 8334ccb3e62c92389f5730d55a02176748508221..b9714ff68e6a444505e94804f40bcaf37aec3df7 100644
|
| --- a/lib/src/string_scanner.dart
|
| +++ b/lib/src/string_scanner.dart
|
| @@ -32,14 +32,21 @@ class StringScanner {
|
| }
|
|
|
| _position = position;
|
| + _lastMatch = null;
|
| }
|
| int _position = 0;
|
|
|
| /// The data about the previous match made by the scanner.
|
| ///
|
| /// If the last match failed, this will be `null`.
|
| - Match get lastMatch => _lastMatch;
|
| + Match get lastMatch {
|
| + // Lazily unset [_lastMatch] so that we avoid extra assignments in
|
| + // character-by-character methods that are used in core loops.
|
| + if (_position != _lastMatchPosition) _lastMatch = null;
|
| + return _lastMatch;
|
| + }
|
| Match _lastMatch;
|
| + int _lastMatchPosition;
|
|
|
| /// The portion of the string that hasn't yet been scanned.
|
| String get rest => string.substring(position);
|
| @@ -118,7 +125,10 @@ class StringScanner {
|
| /// Returns whether or not [pattern] matched.
|
| bool scan(Pattern pattern) {
|
| var success = matches(pattern);
|
| - if (success) _position = _lastMatch.end;
|
| + if (success) {
|
| + _position = _lastMatch.end;
|
| + _lastMatchPosition = _position;
|
| + }
|
| return success;
|
| }
|
|
|
| @@ -159,6 +169,7 @@ class StringScanner {
|
| /// This doesn't move the scan pointer forward.
|
| bool matches(Pattern pattern) {
|
| _lastMatch = pattern.matchAsPrefix(string, position);
|
| + _lastMatchPosition = _position;
|
| return _lastMatch != null;
|
| }
|
|
|
| @@ -181,7 +192,7 @@ class StringScanner {
|
| ///
|
| /// If [position] and/or [length] are passed, they are used as the error span
|
| /// instead. If only [length] is passed, [position] defaults to the current
|
| - /// position; if only [position] is passed, [length] defaults to 1.
|
| + /// position; if only [position] is passed, [length] defaults to 0.
|
| ///
|
| /// It's an error to pass [match] at the same time as [position] or [length].
|
| void error(String message, {Match match, int position, int length}) {
|
| @@ -191,7 +202,7 @@ class StringScanner {
|
| if (position == null) {
|
| position = match == null ? this.position : match.start;
|
| }
|
| - if (length == null) length = match == null ? 1 : match.end - match.start;
|
| + if (length == null) length = match == null ? 0 : match.end - match.start;
|
|
|
| var sourceFile = new SourceFile(string, url: sourceUrl);
|
| var span = sourceFile.span(position, position + length);
|
|
|