| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 /// A library for parsing strings using a sequence of patterns. | 5 /// A library for parsing strings using a sequence of patterns. |
| 6 library string_scanner; | 6 library string_scanner; |
| 7 | 7 |
| 8 import 'dart:math' as math; | 8 import 'dart:math' as math; |
| 9 | 9 |
| 10 /// When compiled to JS, forward slashes are always escaped in [RegExp.pattern]. |
| 11 /// |
| 12 /// See issue 17998. |
| 13 final _slashAutoEscape = new RegExp("/").pattern == "\\/"; |
| 14 |
| 10 // TODO(nweiz): Add some integration between this and source maps. | 15 // TODO(nweiz): Add some integration between this and source maps. |
| 11 /// A class that scans through a string using [Pattern]s. | 16 /// A class that scans through a string using [Pattern]s. |
| 12 class StringScanner { | 17 class StringScanner { |
| 13 /// The string being scanned through. | 18 /// The string being scanned through. |
| 14 final String string; | 19 final String string; |
| 15 | 20 |
| 16 /// The current position of the scanner in the string, in characters. | 21 /// The current position of the scanner in the string, in characters. |
| 17 int get position => _position; | 22 int get position => _position; |
| 18 set position(int position) { | 23 set position(int position) { |
| 19 if (position < 0 || position > string.length) { | 24 if (position < 0 || position > string.length) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 /// | 63 /// |
| 59 /// If [pattern] did not match, throws a [FormatException] describing the | 64 /// If [pattern] did not match, throws a [FormatException] describing the |
| 60 /// position of the failure. [name] is used in this error as the expected name | 65 /// position of the failure. [name] is used in this error as the expected name |
| 61 /// of the pattern being matched; if it's `null`, the pattern itself is used | 66 /// of the pattern being matched; if it's `null`, the pattern itself is used |
| 62 /// instead. | 67 /// instead. |
| 63 void expect(Pattern pattern, {String name}) { | 68 void expect(Pattern pattern, {String name}) { |
| 64 if (scan(pattern)) return; | 69 if (scan(pattern)) return; |
| 65 | 70 |
| 66 if (name == null) { | 71 if (name == null) { |
| 67 if (pattern is RegExp) { | 72 if (pattern is RegExp) { |
| 68 name = "/${pattern.pattern.replaceAll("/", "\\/")}/"; | 73 var source = pattern.pattern; |
| 74 if (!_slashAutoEscape) source = source.replaceAll("/", "\\/"); |
| 75 name = "/$source/"; |
| 69 } else { | 76 } else { |
| 70 name = pattern.toString() | 77 name = pattern.toString() |
| 71 .replaceAll("\\", "\\\\").replaceAll('"', '\\"'); | 78 .replaceAll("\\", "\\\\").replaceAll('"', '\\"'); |
| 72 name = '"$name"'; | 79 name = '"$name"'; |
| 73 } | 80 } |
| 74 } | 81 } |
| 75 _fail(name); | 82 _fail(name); |
| 76 } | 83 } |
| 77 | 84 |
| 78 /// If the string has not been fully consumed, this throws a | 85 /// If the string has not been fully consumed, this throws a |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 "$spaces$underline"); | 160 "$spaces$underline"); |
| 154 } | 161 } |
| 155 | 162 |
| 156 // TODO(nweiz): Make this handle long lines more gracefully. | 163 // TODO(nweiz): Make this handle long lines more gracefully. |
| 157 /// Throws a [FormatException] describing that [name] is expected at the | 164 /// Throws a [FormatException] describing that [name] is expected at the |
| 158 /// current position in the string. | 165 /// current position in the string. |
| 159 void _fail(String name) { | 166 void _fail(String name) { |
| 160 error("expected $name.", position: this.position, length: 1); | 167 error("expected $name.", position: this.position, length: 1); |
| 161 } | 168 } |
| 162 } | 169 } |
| OLD | NEW |