| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file |  | 
| 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. |  | 
| 4 |  | 
| 5 library string_scanner.eager_span_scanner; |  | 
| 6 |  | 
| 7 import 'package:charcode/ascii.dart'; |  | 
| 8 |  | 
| 9 import 'line_scanner.dart'; |  | 
| 10 import 'span_scanner.dart'; |  | 
| 11 |  | 
| 12 // TODO(nweiz): Currently this duplicates code in line_scanner.dart. Once |  | 
| 13 // sdk#23770 is fully complete, we should move the shared code into a mixin. |  | 
| 14 |  | 
| 15 /// A regular expression matching newlines across platforms. |  | 
| 16 final _newlineRegExp = new RegExp(r"\r\n?|\n"); |  | 
| 17 |  | 
| 18 /// A [SpanScanner] that tracks the line and column eagerly, like [LineScanner]. |  | 
| 19 class EagerSpanScanner extends SpanScanner { |  | 
| 20   int get line => _line; |  | 
| 21   int _line = 0; |  | 
| 22 |  | 
| 23   int get column => _column; |  | 
| 24   int _column = 0; |  | 
| 25 |  | 
| 26   LineScannerState get state => |  | 
| 27       new _EagerSpanScannerState(this, position, line, column); |  | 
| 28 |  | 
| 29   bool get _betweenCRLF => peekChar(-1) == $cr && peekChar() == $lf; |  | 
| 30 |  | 
| 31   set state(LineScannerState state) { |  | 
| 32     if (state is! _EagerSpanScannerState || |  | 
| 33         !identical((state as _EagerSpanScannerState)._scanner, this)) { |  | 
| 34       throw new ArgumentError("The given LineScannerState was not returned by " |  | 
| 35           "this LineScanner."); |  | 
| 36     } |  | 
| 37 |  | 
| 38     super.position = state.position; |  | 
| 39     _line = state.line; |  | 
| 40     _column = state.column; |  | 
| 41   } |  | 
| 42 |  | 
| 43   set position(int newPosition) { |  | 
| 44     var oldPosition = position; |  | 
| 45     super.position = newPosition; |  | 
| 46 |  | 
| 47     if (newPosition > oldPosition) { |  | 
| 48       var newlines = _newlinesIn(string.substring(oldPosition, newPosition)); |  | 
| 49       _line += newlines.length; |  | 
| 50       if (newlines.isEmpty) { |  | 
| 51         _column += newPosition - oldPosition; |  | 
| 52       } else { |  | 
| 53         _column = newPosition - newlines.last.end; |  | 
| 54       } |  | 
| 55     } else { |  | 
| 56       var newlines = _newlinesIn(string.substring(newPosition, oldPosition)); |  | 
| 57       if (_betweenCRLF) newlines.removeLast(); |  | 
| 58 |  | 
| 59       _line -= newlines.length; |  | 
| 60       if (newlines.isEmpty) { |  | 
| 61         _column -= oldPosition - newPosition; |  | 
| 62       } else { |  | 
| 63         _column = newPosition - |  | 
| 64             string.lastIndexOf(_newlineRegExp, newPosition) - 1; |  | 
| 65       } |  | 
| 66     } |  | 
| 67   } |  | 
| 68 |  | 
| 69   EagerSpanScanner(String string, {sourceUrl, int position}) |  | 
| 70       : super(string, sourceUrl: sourceUrl, position: position); |  | 
| 71 |  | 
| 72   int readChar() { |  | 
| 73     var char = super.readChar(); |  | 
| 74     if (char == $lf || (char == $cr && peekChar() != $lf)) { |  | 
| 75       _line += 1; |  | 
| 76       _column = 0; |  | 
| 77     } else { |  | 
| 78       _column += 1; |  | 
| 79     } |  | 
| 80     return char; |  | 
| 81   } |  | 
| 82 |  | 
| 83   bool scan(Pattern pattern) { |  | 
| 84     if (!super.scan(pattern)) return false; |  | 
| 85 |  | 
| 86     var newlines = _newlinesIn(lastMatch[0]); |  | 
| 87     _line += newlines.length; |  | 
| 88     if (newlines.isEmpty) { |  | 
| 89       _column += lastMatch[0].length; |  | 
| 90     } else { |  | 
| 91       _column = lastMatch[0].length - newlines.last.end; |  | 
| 92     } |  | 
| 93 |  | 
| 94     return true; |  | 
| 95   } |  | 
| 96 |  | 
| 97   /// Returns a list of [Match]es describing all the newlines in [text], which |  | 
| 98   /// is assumed to end at [position]. |  | 
| 99   List<Match> _newlinesIn(String text) { |  | 
| 100     var newlines = _newlineRegExp.allMatches(text).toList(); |  | 
| 101     if (_betweenCRLF) newlines.removeLast(); |  | 
| 102     return newlines; |  | 
| 103   } |  | 
| 104 } |  | 
| 105 |  | 
| 106 /// A class representing the state of an [EagerSpanScanner]. |  | 
| 107 class _EagerSpanScannerState implements LineScannerState { |  | 
| 108   final EagerSpanScanner _scanner; |  | 
| 109   final int position; |  | 
| 110   final int line; |  | 
| 111   final int column; |  | 
| 112 |  | 
| 113   _EagerSpanScannerState(this._scanner, this.position, this.line, this.column); |  | 
| 114 } |  | 
| 115 |  | 
| OLD | NEW | 
|---|