Chromium Code Reviews| Index: lib/src/line_scanner.dart |
| diff --git a/lib/src/line_scanner.dart b/lib/src/line_scanner.dart |
| index 54ecf7bf9e62215d7a7412a760a24fb1b5dae60d..148ad6081395cae8de857049ba55400324ca30ca 100644 |
| --- a/lib/src/line_scanner.dart |
| +++ b/lib/src/line_scanner.dart |
| @@ -4,8 +4,13 @@ |
| library string_scanner.line_scanner; |
| +import 'package:charcode/ascii.dart'; |
| + |
| import 'string_scanner.dart'; |
| +/// A regular expression matching newlines across platforms. |
| +final _newlineRegExp = new RegExp(r"\r\n?|\n"); |
| + |
| /// A subclass of [StringScanner] that tracks line and column information. |
| class LineScanner extends StringScanner { |
| /// The scanner's current (zero-based) line number. |
| @@ -24,6 +29,10 @@ class LineScanner extends StringScanner { |
| LineScannerState get state => |
| new LineScannerState._(this, position, line, column); |
| + /// Whether the current position is between a CR character and an LF |
| + /// charactet. |
| + bool get _betweenCRLF => peekChar(-1) == $cr && peekChar() == $lf; |
| + |
| set state(LineScannerState state) { |
| if (!identical(state._scanner, this)) { |
| throw new ArgumentError("The given LineScannerState was not returned by " |
| @@ -40,8 +49,10 @@ class LineScanner extends StringScanner { |
| super.position = newPosition; |
| if (newPosition > oldPosition) { |
| - var newlines = |
| - "\n".allMatches(string.substring(oldPosition, newPosition)).toList(); |
| + var newlines = _newlineRegExp |
| + .allMatches(string.substring(oldPosition, newPosition)).toList(); |
| + if (_betweenCRLF) newlines.removeLast(); |
|
Bob Nystrom
2015/09/02 00:07:24
How about hoisting this to a function:
int _newli
nweiz
2015/09/02 00:10:57
Done.
|
| + |
| _line += newlines.length; |
| if (newlines.isEmpty) { |
| _column += newPosition - oldPosition; |
| @@ -49,13 +60,16 @@ class LineScanner extends StringScanner { |
| _column = newPosition - newlines.last.end; |
| } |
| } else { |
| - var newlines = |
| - "\n".allMatches(string.substring(newPosition, oldPosition)).toList(); |
| + var newlines = _newlineRegExp |
| + .allMatches(string.substring(newPosition, oldPosition)).toList(); |
| + if (_betweenCRLF) newlines.removeLast(); |
| + |
| _line -= newlines.length; |
| if (newlines.isEmpty) { |
| _column -= oldPosition - newPosition; |
| } else { |
| - _column = newPosition - string.lastIndexOf("\n", newPosition) - 1; |
| + _column = newPosition - |
| + string.lastIndexOf(_newlineRegExp, newPosition) - 1; |
| } |
| } |
| } |
| @@ -65,7 +79,7 @@ class LineScanner extends StringScanner { |
| int readChar() { |
| var char = super.readChar(); |
| - if (char == 0xA) { |
| + if (char == $lf || (char == $cr && peekChar() != $lf)) { |
| _line += 1; |
| _column = 0; |
| } else { |
| @@ -77,7 +91,8 @@ class LineScanner extends StringScanner { |
| bool scan(Pattern pattern) { |
| if (!super.scan(pattern)) return false; |
| - var newlines = "\n".allMatches(lastMatch[0]).toList(); |
| + var newlines = _newlineRegExp.allMatches(lastMatch[0]).toList(); |
| + if (_betweenCRLF) newlines.removeLast(); |
| _line += newlines.length; |
|
Bob Nystrom
2015/09/02 00:07:24
Even here.
nweiz
2015/09/02 00:10:57
Done.
|
| if (newlines.isEmpty) { |
| _column += lastMatch[0].length; |