From 1114fada122bd9ea67b151ef6b4bf3bef30f0695 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Wed, 2 Apr 2014 20:30:09 +0000 Subject: [PATCH 001/102] Add a string_scanner package. This code has been pulled out of the Shelf package. R=kevmoo@google.com Review URL: https://codereview.chromium.org//213833013 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/string_scanner@34665 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/string_scanner/LICENSE | 26 ++ pkgs/string_scanner/README.md | 37 +++ pkgs/string_scanner/lib/string_scanner.dart | 113 ++++++++ pkgs/string_scanner/pubspec.yaml | 10 + .../test/error_format_test.dart | 110 ++++++++ .../test/string_scanner_test.dart | 267 ++++++++++++++++++ 6 files changed, 563 insertions(+) create mode 100644 pkgs/string_scanner/LICENSE create mode 100644 pkgs/string_scanner/README.md create mode 100644 pkgs/string_scanner/lib/string_scanner.dart create mode 100644 pkgs/string_scanner/pubspec.yaml create mode 100644 pkgs/string_scanner/test/error_format_test.dart create mode 100644 pkgs/string_scanner/test/string_scanner_test.dart diff --git a/pkgs/string_scanner/LICENSE b/pkgs/string_scanner/LICENSE new file mode 100644 index 000000000..5c60afea3 --- /dev/null +++ b/pkgs/string_scanner/LICENSE @@ -0,0 +1,26 @@ +Copyright 2014, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkgs/string_scanner/README.md b/pkgs/string_scanner/README.md new file mode 100644 index 000000000..90660fc8c --- /dev/null +++ b/pkgs/string_scanner/README.md @@ -0,0 +1,37 @@ +This package exposes a `StringScanner` type that makes it easy to parse a string +using a series of `Pattern`s. For example: + +```dart +import 'dart:math'; + +import 'package:string_scanner/string_scanner.dart'; + +num parseNumber(String source) { + // Scan a number ("1", "1.5", "-3"). + var scanner = new StringScanner(source); + + // [Scanner.scan] tries to consume a [Pattern] and returns whether or not it + // succeeded. It will move the scan pointer past the end of the pattern. + var negative = scanner.scan("-"); + + // [Scanner.expect] consumes a [Pattern] and throws a [FormatError] if it + // fails. Like [Scanner.scan], it will move the scan pointer forward. + scanner.expect(new RegExp(r"\d+")); + + // [Scanner.lastMatch] holds the [MatchData] for the most recent call to + // [Scanner.scan], [Scanner.expect], or [Scanner.matches]. + var number = int.parse(scanner.lastMatch[0]); + + if (scanner.scan(".")) { + scanner.expect(new RegExp(r"\d+")); + var decimal = scanner.lastMatch[0]; + number += int.parse(decimal) / math.pow(10, decimal.length); + } + + // [Scanner.expectDone] will throw a [FormatError] if there's any input that + // hasn't yet been consumed. + scanner.expectDone(); + + return (negative ? -1 : 1) * number; +} +``` diff --git a/pkgs/string_scanner/lib/string_scanner.dart b/pkgs/string_scanner/lib/string_scanner.dart new file mode 100644 index 000000000..624c090e8 --- /dev/null +++ b/pkgs/string_scanner/lib/string_scanner.dart @@ -0,0 +1,113 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// A library for parsing strings using a sequence of patterns. +library string_scanner; + +// TODO(nweiz): Add some integration between this and source maps. +/// A class that scans through a string using [Pattern]s. +class StringScanner { + /// The string being scanned through. + final String string; + + /// The current position of the scanner in the string, in characters. + int get position => _position; + set position(int position) { + if (position < 0 || position > string.length) { + throw new ArgumentError("Invalid position $position"); + } + + _position = position; + } + 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 _lastMatch; + + /// The portion of the string that hasn't yet been scanned. + String get rest => string.substring(position); + + /// Whether the scanner has completely consumed [string]. + bool get isDone => position == string.length; + + /// Creates a new [StringScanner] that starts scanning from [position]. + /// + /// [position] defaults to 0, the beginning of the string. + StringScanner(this.string, {int position}) { + if (position != null) this.position = position; + } + + /// If [pattern] matches at the current position of the string, scans forward + /// until the end of the match. + /// + /// Returns whether or not [pattern] matched. + bool scan(Pattern pattern) { + var success = matches(pattern); + if (success) _position = _lastMatch.end; + return success; + } + + /// If [pattern] matches at the current position of the string, scans forward + /// until the end of the match. + /// + /// If [pattern] did not match, throws a [FormatException] describing the + /// position of the failure. [name] is used in this error as the expected name + /// of the pattern being matched; if it's `null`, the pattern itself is used + /// instead. + void expect(Pattern pattern, {String name}) { + if (scan(pattern)) return; + + if (name == null) { + if (pattern is RegExp) { + name = "/${pattern.pattern.replaceAll("/", "\\/")}/"; + } else { + name = pattern.toString() + .replaceAll("\\", "\\\\").replaceAll('"', '\\"'); + name = '"$name"'; + } + } + _fail(name); + } + + /// If the string has not been fully consumed, this throws a + /// [FormatException]. + void expectDone() { + if (isDone) return; + _fail("no more input"); + } + + /// Returns whether or not [pattern] matches at the current position of the + /// string. + /// + /// This doesn't move the scan pointer forward. + bool matches(Pattern pattern) { + _lastMatch = pattern.matchAsPrefix(string, position); + return _lastMatch != null; + } + + // TODO(nweiz): Make this handle long lines more gracefully. + /// Throws a [FormatException] describing that [name] is expected at the + /// current position in the string. + void _fail(String name) { + var newlines = "\n".allMatches(string.substring(0, position)).toList(); + var line = newlines.length + 1; + var column; + var lastLine; + if (newlines.isEmpty) { + column = position + 1; + lastLine = string.substring(0, position); + } else { + column = position - newlines.last.end + 1; + lastLine = string.substring(newlines.last.end, position); + } + lastLine += rest.replaceFirst(new RegExp(r"\n.*"), ''); + throw new FormatException( + "Expected $name on line $line, column $column.\n" + "$lastLine\n" + "${new List.filled(column - 1, ' ').join()}^"); + } +} diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml new file mode 100644 index 000000000..3035901ea --- /dev/null +++ b/pkgs/string_scanner/pubspec.yaml @@ -0,0 +1,10 @@ +name: string_scanner +version: 0.0.1 +author: "Dart Team " +homepage: http://www.dartlang.org +description: > + A class for parsing strings using a sequence of patterns. +dev_dependencies: + unittest: ">=0.10.0 <0.11.0" +environment: + sdk: ">=1.2.0 <2.0.0" diff --git a/pkgs/string_scanner/test/error_format_test.dart b/pkgs/string_scanner/test/error_format_test.dart new file mode 100644 index 000000000..118734400 --- /dev/null +++ b/pkgs/string_scanner/test/error_format_test.dart @@ -0,0 +1,110 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.error_format_test; + +import 'package:string_scanner/string_scanner.dart'; +import 'package:unittest/unittest.dart'; + +void main() { + test('points to the first unconsumed character', () { + var scanner = new StringScanner('foo bar baz'); + scanner.expect('foo '); + expect(() => scanner.expect('foo'), throwsFormattedError(''' +Expected "foo" on line 1, column 5. +foo bar baz + ^''')); + }); + + test('prints the correct line', () { + var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + scanner.expect('foo bar baz\ndo '); + expect(() => scanner.expect('foo'), throwsFormattedError(''' +Expected "foo" on line 2, column 4. +do re mi + ^''')); + }); + + test('handles the beginning of the string correctly', () { + var scanner = new StringScanner('foo bar baz'); + expect(() => scanner.expect('zap'), throwsFormattedError(''' +Expected "zap" on line 1, column 1. +foo bar baz +^''')); + }); + + test('handles the end of the string correctly', () { + var scanner = new StringScanner('foo bar baz'); + scanner.expect('foo bar baz'); + expect(() => scanner.expect('bang'), throwsFormattedError(''' +Expected "bang" on line 1, column 12. +foo bar baz + ^''')); + }); + + test('handles an empty string correctly', () { + expect(() => new StringScanner('').expect('foo'), throwsFormattedError(''' +Expected "foo" on line 1, column 1. + +^''')); + }); + + group("expected name", () { + test("uses the provided name", () { + expect(() => new StringScanner('').expect('foo bar', name: 'zap'), + throwsFormattedError(''' +Expected zap on line 1, column 1. + +^''')); + }); + + test("escapes string quotes", () { + expect(() => new StringScanner('').expect('foo"bar'), + throwsFormattedError(''' +Expected "foo\\"bar" on line 1, column 1. + +^''')); + }); + + test("escapes string backslashes", () { + expect(() => new StringScanner('').expect('foo\\bar'), + throwsFormattedError(''' +Expected "foo\\\\bar" on line 1, column 1. + +^''')); + }); + + test("prints PERL-style regexps", () { + expect(() => new StringScanner('').expect(new RegExp(r'foo')), + throwsFormattedError(''' +Expected /foo/ on line 1, column 1. + +^''')); + }); + + test("escape regexp forward slashes", () { + expect(() => new StringScanner('').expect(new RegExp(r'foo/bar')), + throwsFormattedError(''' +Expected /foo\\/bar/ on line 1, column 1. + +^''')); + }); + + test("does not escape regexp backslashes", () { + expect(() => new StringScanner('').expect(new RegExp(r'foo\bar')), + throwsFormattedError(''' +Expected /foo\\bar/ on line 1, column 1. + +^''')); + }); + }); +} + +Matcher throwsFormattedError(String format) { + return throwsA(predicate((error) { + expect(error, isFormatException); + expect(error.message, equals(format)); + return true; + })); +} diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart new file mode 100644 index 000000000..0cab6273e --- /dev/null +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -0,0 +1,267 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.string_scanner_test; + +import 'package:string_scanner/string_scanner.dart'; +import 'package:unittest/unittest.dart'; + +void main() { + group('with an empty string', () { + var scanner; + setUp(() { + scanner = new StringScanner(''); + }); + + test('is done', () { + expect(scanner.isDone, isTrue); + expect(scanner.expectDone, isNot(throwsFormatException)); + }); + + test('rest is empty', () { + expect(scanner.rest, isEmpty); + }); + + test('lastMatch is null', () { + expect(scanner.lastMatch, isNull); + }); + + test('position is zero', () { + expect(scanner.position, equals(0)); + }); + + test("scan returns false and doesn't change the state", () { + expect(scanner.scan(new RegExp('.')), isFalse); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + + test("expect throws a FormatException and doesn't change the state", () { + expect(() => scanner.expect(new RegExp('.')), throwsFormatException); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + + test("matches returns false and doesn't change the state", () { + expect(scanner.matches(new RegExp('.')), isFalse); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + + test('setting position to 1 throws an ArgumentError', () { + expect(() { + scanner.position = 1; + }, throwsArgumentError); + }); + + test('setting position to -1 throws an ArgumentError', () { + expect(() { + scanner.position = -1; + }, throwsArgumentError); + }); + }); + + group('at the beginning of a string', () { + var scanner; + setUp(() { + scanner = new StringScanner('foo bar'); + }); + + test('is not done', () { + expect(scanner.isDone, isFalse); + expect(scanner.expectDone, throwsFormatException); + }); + + test('rest is the whole string', () { + expect(scanner.rest, equals('foo bar')); + }); + + test('lastMatch is null', () { + expect(scanner.lastMatch, isNull); + }); + + test('position is zero', () { + expect(scanner.position, equals(0)); + }); + + test("a matching scan returns true and changes the state", () { + expect(scanner.scan(new RegExp('f(..)')), isTrue); + expect(scanner.lastMatch[1], equals('oo')); + expect(scanner.position, equals(3)); + expect(scanner.rest, equals(' bar')); + }); + + test("a non-matching scan returns false and sets lastMatch to null", () { + expect(scanner.matches(new RegExp('f(..)')), isTrue); + expect(scanner.lastMatch, isNotNull); + + expect(scanner.scan(new RegExp('b(..)')), isFalse); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + expect(scanner.rest, equals('foo bar')); + }); + + test("a matching expect changes the state", () { + scanner.expect(new RegExp('f(..)')); + expect(scanner.lastMatch[1], equals('oo')); + expect(scanner.position, equals(3)); + expect(scanner.rest, equals(' bar')); + }); + + test("a non-matching expect throws a FormatException and sets lastMatch to " + "null", () { + expect(scanner.matches(new RegExp('f(..)')), isTrue); + expect(scanner.lastMatch, isNotNull); + + expect(() => scanner.expect(new RegExp('b(..)')), throwsFormatException); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + expect(scanner.rest, equals('foo bar')); + }); + + test("a matching matches returns true and only changes lastMatch", () { + expect(scanner.matches(new RegExp('f(..)')), isTrue); + expect(scanner.lastMatch[1], equals('oo')); + expect(scanner.position, equals(0)); + expect(scanner.rest, equals('foo bar')); + }); + + test("a non-matching matches returns false and doesn't change the state", + () { + expect(scanner.matches(new RegExp('b(..)')), isFalse); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + expect(scanner.rest, equals('foo bar')); + }); + + test('setting position to 1 moves the cursor forward', () { + scanner.position = 1; + expect(scanner.position, equals(1)); + expect(scanner.rest, equals('oo bar')); + + expect(scanner.scan(new RegExp('oo.')), isTrue); + expect(scanner.lastMatch[0], equals('oo ')); + expect(scanner.position, equals(4)); + expect(scanner.rest, equals('bar')); + }); + + test('setting position beyond the string throws an ArgumentError', () { + expect(() { + scanner.position = 8; + }, throwsArgumentError); + }); + + test('setting position to -1 throws an ArgumentError', () { + expect(() { + scanner.position = -1; + }, throwsArgumentError); + }); + + test('scan accepts any Pattern', () { + expect(scanner.scan('foo'), isTrue); + expect(scanner.lastMatch[0], equals('foo')); + expect(scanner.position, equals(3)); + expect(scanner.rest, equals(' bar')); + }); + + test('scans multiple times', () { + expect(scanner.scan(new RegExp('f(..)')), isTrue); + expect(scanner.lastMatch[1], equals('oo')); + expect(scanner.position, equals(3)); + expect(scanner.rest, equals(' bar')); + + expect(scanner.scan(new RegExp(' b(..)')), isTrue); + expect(scanner.lastMatch[1], equals('ar')); + expect(scanner.position, equals(7)); + expect(scanner.rest, equals('')); + expect(scanner.isDone, isTrue); + expect(scanner.expectDone, isNot(throwsFormatException)); + }); + }); + + group('at the end of a string', () { + var scanner; + setUp(() { + scanner = new StringScanner('foo bar'); + expect(scanner.scan('foo bar'), isTrue); + }); + + test('is done', () { + expect(scanner.isDone, isTrue); + expect(scanner.expectDone, isNot(throwsFormatException)); + }); + + test('rest is empty', () { + expect(scanner.rest, isEmpty); + }); + + test('position is zero', () { + expect(scanner.position, equals(7)); + }); + + test("scan returns false and sets lastMatch to null", () { + expect(scanner.scan(new RegExp('.')), isFalse); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(7)); + }); + + test("expect throws a FormatException and sets lastMatch to null", () { + expect(() => scanner.expect(new RegExp('.')), throwsFormatException); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(7)); + }); + + test("matches returns false sets lastMatch to null", () { + expect(scanner.matches(new RegExp('.')), isFalse); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(7)); + }); + + test('setting position to 1 moves the cursor backward', () { + scanner.position = 1; + expect(scanner.position, equals(1)); + expect(scanner.rest, equals('oo bar')); + + expect(scanner.scan(new RegExp('oo.')), isTrue); + expect(scanner.lastMatch[0], equals('oo ')); + expect(scanner.position, equals(4)); + expect(scanner.rest, equals('bar')); + }); + + test('setting position beyond the string throws an ArgumentError', () { + expect(() { + scanner.position = 8; + }, throwsArgumentError); + }); + + test('setting position to -1 throws an ArgumentError', () { + expect(() { + scanner.position = -1; + }, throwsArgumentError); + }); + }); + + group('a scanner constructed with a custom position', () { + test('starts scanning from that position', () { + var scanner = new StringScanner('foo bar', position: 1); + expect(scanner.position, equals(1)); + expect(scanner.rest, equals('oo bar')); + + expect(scanner.scan(new RegExp('oo.')), isTrue); + expect(scanner.lastMatch[0], equals('oo ')); + expect(scanner.position, equals(4)); + expect(scanner.rest, equals('bar')); + }); + + test('throws an ArgumentError if the position is -1', () { + expect(() => new StringScanner('foo bar', position: -1), + throwsArgumentError); + }); + + test('throws an ArgumentError if the position is beyond the string', () { + expect(() => new StringScanner('foo bar', position: 8), + throwsArgumentError); + }); + }); +} From e15bced42f232fa37b4a162ecb877761308ebc4c Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Wed, 2 Apr 2014 20:58:47 +0000 Subject: [PATCH 002/102] Convert shelf to use the string_scanner package. This also adds support for [StringScanner.error], which produces a nicely-formatted scanning error. R=kevmoo@google.com Review URL: https://codereview.chromium.org//222843003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/string_scanner@34669 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/string_scanner/lib/string_scanner.dart | 63 ++++++- pkgs/string_scanner/test/error_test.dart | 168 ++++++++++++++++++ ...ormat_test.dart => expect_error_test.dart} | 34 ++-- pkgs/string_scanner/test/utils.dart | 17 ++ 4 files changed, 255 insertions(+), 27 deletions(-) create mode 100644 pkgs/string_scanner/test/error_test.dart rename pkgs/string_scanner/test/{error_format_test.dart => expect_error_test.dart} (78%) create mode 100644 pkgs/string_scanner/test/utils.dart diff --git a/pkgs/string_scanner/lib/string_scanner.dart b/pkgs/string_scanner/lib/string_scanner.dart index 624c090e8..31ccd6266 100644 --- a/pkgs/string_scanner/lib/string_scanner.dart +++ b/pkgs/string_scanner/lib/string_scanner.dart @@ -5,6 +5,8 @@ /// A library for parsing strings using a sequence of patterns. library string_scanner; +import 'dart:math' as math; + // TODO(nweiz): Add some integration between this and source maps. /// A class that scans through a string using [Pattern]s. class StringScanner { @@ -89,10 +91,38 @@ class StringScanner { return _lastMatch != null; } - // TODO(nweiz): Make this handle long lines more gracefully. - /// Throws a [FormatException] describing that [name] is expected at the - /// current position in the string. - void _fail(String name) { + /// Throws a [FormatException] with [message] as well as a detailed + /// description of the location of the error in the string. + /// + /// [match] is the match information for the span of the string with which the + /// error is associated. This should be a match returned by this scanner's + /// [lastMatch] property. By default, the error is associated with the last + /// match. + /// + /// 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. + /// + /// 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}) { + if (match != null && (position != null || length != null)) { + throw new ArgumentError("Can't pass both match and position/length."); + } + + if (position != null && position < 0) { + throw new RangeError("position must be greater than or equal to 0."); + } + + if (length != null && length < 1) { + throw new RangeError("length must be greater than or equal to 0."); + } + + if (match == null && position == null && length == null) match = lastMatch; + if (position == null) { + position = match == null ? this.position : match.start; + } + if (length == null) length = match == null ? 1 : match.end - match.start; + var newlines = "\n".allMatches(string.substring(0, position)).toList(); var line = newlines.length + 1; var column; @@ -104,10 +134,29 @@ class StringScanner { column = position - newlines.last.end + 1; lastLine = string.substring(newlines.last.end, position); } - lastLine += rest.replaceFirst(new RegExp(r"\n.*"), ''); + + var remaining = string.substring(position); + var nextNewline = remaining.indexOf("\n"); + if (nextNewline == -1) { + lastLine += remaining; + } else { + length = math.min(length, nextNewline); + lastLine += remaining.substring(0, nextNewline); + } + + var spaces = new List.filled(column - 1, ' ').join(); + var underline = new List.filled(length, '^').join(); + throw new FormatException( - "Expected $name on line $line, column $column.\n" + "Error on line $line, column $column: $message\n" "$lastLine\n" - "${new List.filled(column - 1, ' ').join()}^"); + "$spaces$underline"); + } + + // TODO(nweiz): Make this handle long lines more gracefully. + /// Throws a [FormatException] describing that [name] is expected at the + /// current position in the string. + void _fail(String name) { + error("expected $name.", position: this.position, length: 1); } } diff --git a/pkgs/string_scanner/test/error_test.dart b/pkgs/string_scanner/test/error_test.dart new file mode 100644 index 000000000..6432197b3 --- /dev/null +++ b/pkgs/string_scanner/test/error_test.dart @@ -0,0 +1,168 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.error_test; + +import 'package:string_scanner/string_scanner.dart'; +import 'package:unittest/unittest.dart'; + +import 'utils.dart'; + +void main() { + test('defaults to the last match', () { + var scanner = new StringScanner('foo bar baz'); + scanner.expect('foo '); + scanner.expect('bar'); + expect(() => scanner.error('oh no!'), throwsFormattedError(''' +Error on line 1, column 5: oh no! +foo bar baz + ^^^''')); + }); + + group("with match", () { + test('supports an earlier match', () { + var scanner = new StringScanner('foo bar baz'); + scanner.expect('foo '); + var match = scanner.lastMatch; + scanner.expect('bar'); + expect(() => scanner.error('oh no!', match: match), + throwsFormattedError(''' +Error on line 1, column 1: oh no! +foo bar baz +^^^^''')); + }); + + test('supports a match on a previous line', () { + var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + scanner.expect('foo bar baz\ndo '); + scanner.expect('re'); + var match = scanner.lastMatch; + scanner.expect(' mi\nearth '); + expect(() => scanner.error('oh no!', match: match), + throwsFormattedError(''' +Error on line 2, column 4: oh no! +do re mi + ^^''')); + }); + + test('supports a multiline match', () { + var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + scanner.expect('foo bar '); + scanner.expect('baz\ndo'); + var match = scanner.lastMatch; + scanner.expect(' re mi'); + expect(() => scanner.error('oh no!', match: match), + throwsFormattedError(''' +Error on line 1, column 9: oh no! +foo bar baz + ^^^''')); + }); + + test('supports a match after position', () { + var scanner = new StringScanner('foo bar baz'); + scanner.expect('foo '); + scanner.expect('bar'); + var match = scanner.lastMatch; + scanner.position = 0; + expect(() => scanner.error('oh no!', match: match), + throwsFormattedError(''' +Error on line 1, column 5: oh no! +foo bar baz + ^^^''')); + }); + }); + + group("with position and/or length", () { + test('defaults to length 1', () { + var scanner = new StringScanner('foo bar baz'); + scanner.expect('foo '); + expect(() => scanner.error('oh no!', position: 1), + throwsFormattedError(''' +Error on line 1, column 2: oh no! +foo bar baz + ^''')); + }); + + test('defaults to the current position', () { + var scanner = new StringScanner('foo bar baz'); + scanner.expect('foo '); + expect(() => scanner.error('oh no!', length: 3), + throwsFormattedError(''' +Error on line 1, column 5: oh no! +foo bar baz + ^^^''')); + }); + + test('supports an earlier position', () { + var scanner = new StringScanner('foo bar baz'); + scanner.expect('foo '); + expect(() => scanner.error('oh no!', position: 1, length: 2), + throwsFormattedError(''' +Error on line 1, column 2: oh no! +foo bar baz + ^^''')); + }); + + test('supports a position on a previous line', () { + var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + scanner.expect('foo bar baz\ndo re mi\nearth'); + expect(() => scanner.error('oh no!', position: 15, length: 2), + throwsFormattedError(''' +Error on line 2, column 4: oh no! +do re mi + ^^''')); + }); + + test('supports a multiline length', () { + var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + scanner.expect('foo bar baz\ndo re mi\nearth'); + expect(() => scanner.error('oh no!', position: 8, length: 8), + throwsFormattedError(''' +Error on line 1, column 9: oh no! +foo bar baz + ^^^''')); + }); + + test('supports a position after the current one', () { + var scanner = new StringScanner('foo bar baz'); + expect(() => scanner.error('oh no!', position: 4, length: 3), + throwsFormattedError(''' +Error on line 1, column 5: oh no! +foo bar baz + ^^^''')); + }); + }); + + group("argument errors", () { + var scanner; + setUp(() { + scanner = new StringScanner('foo bar baz'); + scanner.scan('foo'); + }); + + test("if match is passed with position", () { + expect( + () => scanner.error("oh no!", match: scanner.lastMatch, position: 1), + throwsArgumentError); + }); + + test("if match is passed with length", () { + expect( + () => scanner.error("oh no!", match: scanner.lastMatch, length: 1), + throwsArgumentError); + }); + + test("if position is negative", () { + expect(() => scanner.error("oh no!", position: -1), throwsArgumentError); + }); + + test("if position is outside the string", () { + expect(() => scanner.error("oh no!", position: 100), throwsArgumentError); + }); + + test("if length is zero", () { + expect(() => scanner.error("oh no!", length: 0), throwsArgumentError); + }); + }); +} diff --git a/pkgs/string_scanner/test/error_format_test.dart b/pkgs/string_scanner/test/expect_error_test.dart similarity index 78% rename from pkgs/string_scanner/test/error_format_test.dart rename to pkgs/string_scanner/test/expect_error_test.dart index 118734400..3596e15e5 100644 --- a/pkgs/string_scanner/test/error_format_test.dart +++ b/pkgs/string_scanner/test/expect_error_test.dart @@ -2,17 +2,19 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.error_format_test; +library string_scanner.expect_error_test; import 'package:string_scanner/string_scanner.dart'; import 'package:unittest/unittest.dart'; +import 'utils.dart'; + void main() { test('points to the first unconsumed character', () { var scanner = new StringScanner('foo bar baz'); scanner.expect('foo '); expect(() => scanner.expect('foo'), throwsFormattedError(''' -Expected "foo" on line 1, column 5. +Error on line 1, column 5: expected "foo". foo bar baz ^''')); }); @@ -21,7 +23,7 @@ foo bar baz var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo '); expect(() => scanner.expect('foo'), throwsFormattedError(''' -Expected "foo" on line 2, column 4. +Error on line 2, column 4: expected "foo". do re mi ^''')); }); @@ -29,7 +31,7 @@ do re mi test('handles the beginning of the string correctly', () { var scanner = new StringScanner('foo bar baz'); expect(() => scanner.expect('zap'), throwsFormattedError(''' -Expected "zap" on line 1, column 1. +Error on line 1, column 1: expected "zap". foo bar baz ^''')); }); @@ -38,14 +40,14 @@ foo bar baz var scanner = new StringScanner('foo bar baz'); scanner.expect('foo bar baz'); expect(() => scanner.expect('bang'), throwsFormattedError(''' -Expected "bang" on line 1, column 12. +Error on line 1, column 12: expected "bang". foo bar baz ^''')); }); test('handles an empty string correctly', () { expect(() => new StringScanner('').expect('foo'), throwsFormattedError(''' -Expected "foo" on line 1, column 1. +Error on line 1, column 1: expected "foo". ^''')); }); @@ -54,7 +56,7 @@ Expected "foo" on line 1, column 1. test("uses the provided name", () { expect(() => new StringScanner('').expect('foo bar', name: 'zap'), throwsFormattedError(''' -Expected zap on line 1, column 1. +Error on line 1, column 1: expected zap. ^''')); }); @@ -62,7 +64,7 @@ Expected zap on line 1, column 1. test("escapes string quotes", () { expect(() => new StringScanner('').expect('foo"bar'), throwsFormattedError(''' -Expected "foo\\"bar" on line 1, column 1. +Error on line 1, column 1: expected "foo\\"bar". ^''')); }); @@ -70,7 +72,7 @@ Expected "foo\\"bar" on line 1, column 1. test("escapes string backslashes", () { expect(() => new StringScanner('').expect('foo\\bar'), throwsFormattedError(''' -Expected "foo\\\\bar" on line 1, column 1. +Error on line 1, column 1: expected "foo\\\\bar". ^''')); }); @@ -78,7 +80,7 @@ Expected "foo\\\\bar" on line 1, column 1. test("prints PERL-style regexps", () { expect(() => new StringScanner('').expect(new RegExp(r'foo')), throwsFormattedError(''' -Expected /foo/ on line 1, column 1. +Error on line 1, column 1: expected /foo/. ^''')); }); @@ -86,7 +88,7 @@ Expected /foo/ on line 1, column 1. test("escape regexp forward slashes", () { expect(() => new StringScanner('').expect(new RegExp(r'foo/bar')), throwsFormattedError(''' -Expected /foo\\/bar/ on line 1, column 1. +Error on line 1, column 1: expected /foo\\/bar/. ^''')); }); @@ -94,17 +96,9 @@ Expected /foo\\/bar/ on line 1, column 1. test("does not escape regexp backslashes", () { expect(() => new StringScanner('').expect(new RegExp(r'foo\bar')), throwsFormattedError(''' -Expected /foo\\bar/ on line 1, column 1. +Error on line 1, column 1: expected /foo\\bar/. ^''')); }); }); } - -Matcher throwsFormattedError(String format) { - return throwsA(predicate((error) { - expect(error, isFormatException); - expect(error.message, equals(format)); - return true; - })); -} diff --git a/pkgs/string_scanner/test/utils.dart b/pkgs/string_scanner/test/utils.dart new file mode 100644 index 000000000..eee93d89d --- /dev/null +++ b/pkgs/string_scanner/test/utils.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.test.utils; + +import 'package:unittest/unittest.dart'; + +/// Returns a matcher that asserts that a closure throws a [FormatException] +/// with the given [message]. +Matcher throwsFormattedError(String message) { + return throwsA(predicate((error) { + expect(error, isFormatException); + expect(error.message, equals(message)); + return true; + })); +} From 7117aa325aff7bc6653947e45700b887877c0c37 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Thu, 3 Apr 2014 00:27:11 +0000 Subject: [PATCH 003/102] Fix the StringScanner tests under dart2js. R=kevmoo@google.com Review URL: https://codereview.chromium.org//222613006 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/string_scanner@34677 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/string_scanner/lib/string_scanner.dart | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pkgs/string_scanner/lib/string_scanner.dart b/pkgs/string_scanner/lib/string_scanner.dart index 31ccd6266..3e3913b50 100644 --- a/pkgs/string_scanner/lib/string_scanner.dart +++ b/pkgs/string_scanner/lib/string_scanner.dart @@ -7,6 +7,11 @@ library string_scanner; import 'dart:math' as math; +/// When compiled to JS, forward slashes are always escaped in [RegExp.pattern]. +/// +/// See issue 17998. +final _slashAutoEscape = new RegExp("/").pattern == "\\/"; + // TODO(nweiz): Add some integration between this and source maps. /// A class that scans through a string using [Pattern]s. class StringScanner { @@ -65,7 +70,9 @@ class StringScanner { if (name == null) { if (pattern is RegExp) { - name = "/${pattern.pattern.replaceAll("/", "\\/")}/"; + var source = pattern.pattern; + if (!_slashAutoEscape) source = source.replaceAll("/", "\\/"); + name = "/$source/"; } else { name = pattern.toString() .replaceAll("\\", "\\\\").replaceAll('"', '\\"'); From 075137e05e28359156c44fd56706cb2685c11cf1 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Fri, 30 May 2014 00:52:40 +0000 Subject: [PATCH 004/102] Add LineScanner and SpanScanner classes to string_scanner. R=rnystrom@google.com Review URL: https://codereview.chromium.org//299973002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/string_scanner@36815 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/string_scanner/CHANGELOG.md | 19 ++ pkgs/string_scanner/lib/src/exception.dart | 37 ++++ pkgs/string_scanner/lib/src/line_scanner.dart | 108 +++++++++++ pkgs/string_scanner/lib/src/span_scanner.dart | 95 ++++++++++ .../lib/src/string_scanner.dart | 168 ++++++++++++++++++ pkgs/string_scanner/lib/src/utils.dart | 30 ++++ pkgs/string_scanner/lib/string_scanner.dart | 166 +---------------- pkgs/string_scanner/pubspec.yaml | 5 +- pkgs/string_scanner/test/error_test.dart | 70 +++----- .../test/expect_error_test.dart | 104 ----------- .../test/line_scanner_test.dart | 106 +++++++++++ .../test/span_scanner_test.dart | 60 +++++++ .../test/string_scanner_test.dart | 42 +++++ pkgs/string_scanner/test/utils.dart | 7 +- 14 files changed, 701 insertions(+), 316 deletions(-) create mode 100644 pkgs/string_scanner/CHANGELOG.md create mode 100644 pkgs/string_scanner/lib/src/exception.dart create mode 100644 pkgs/string_scanner/lib/src/line_scanner.dart create mode 100644 pkgs/string_scanner/lib/src/span_scanner.dart create mode 100644 pkgs/string_scanner/lib/src/string_scanner.dart create mode 100644 pkgs/string_scanner/lib/src/utils.dart delete mode 100644 pkgs/string_scanner/test/expect_error_test.dart create mode 100644 pkgs/string_scanner/test/line_scanner_test.dart create mode 100644 pkgs/string_scanner/test/span_scanner_test.dart diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md new file mode 100644 index 000000000..2c41c9d64 --- /dev/null +++ b/pkgs/string_scanner/CHANGELOG.md @@ -0,0 +1,19 @@ +## 0.0.2 + +* `new StringScanner()` now takes an optional `sourceUrl` argument that provides + the URL of the source file. This is used for error reporting. + +* Add `StringScanner.readChar()` and `StringScanner.peekChar()` methods for + doing character-by-character scanning. + +* Scanners now throw `StringScannerException`s which provide more detailed + access to information about the errors that were thrown and can provide + terminal-colored messages. + +* Add a `LineScanner` subclass of `StringScanner` that automatically tracks line + and column information of the text being scanned. + +* Add a `SpanScanner` subclass of `LineScanner` that exposes matched ranges as + [source map][] `Span` objects. + +[source_map]: http://pub.dartlang.org/packages/source_maps diff --git a/pkgs/string_scanner/lib/src/exception.dart b/pkgs/string_scanner/lib/src/exception.dart new file mode 100644 index 000000000..c3986871a --- /dev/null +++ b/pkgs/string_scanner/lib/src/exception.dart @@ -0,0 +1,37 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.exception; + +import 'package:source_maps/source_maps.dart'; + +/// An exception thrown by a [StringScanner] that failed to parse a string. +class StringScannerException implements FormatException { + /// The error message. + final String message; + + /// The source string being parsed. + final String string; + + /// The URL of the source file being parsed. + /// + /// This may be `null`, indicating that the source URL is unknown. + final Uri sourceUrl; + + /// The span within [string] that caused the exception. + final Span span; + + StringScannerException(this.message, this.string, this.sourceUrl, this.span); + + /// Returns a detailed description of this exception. + /// + /// If [useColors] is true, the section of the source that caused the + /// exception will be colored using ANSI color codes. By default, it's colored + /// red, but a different ANSI code may passed via [color]. + String toString({bool useColors: false, String color}) { + return "Error on " + span.getLocationMessage( + message, useColors: useColors, color: color); + } +} + diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart new file mode 100644 index 000000000..4e1217305 --- /dev/null +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -0,0 +1,108 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.line_scanner; + +import 'string_scanner.dart'; + +/// A subclass of [StringScanner] that tracks line and column information. +class LineScanner extends StringScanner { + /// The scanner's current (zero-based) line number. + int get line => _line; + int _line = 0; + + /// The scanner's current (zero-based) column number. + int get column => _column; + int _column = 0; + + /// The scanner's state, including line and column information. + /// + /// This can be used to efficiently save and restore the state of the scanner + /// when backtracking. A given [LineScannerState] is only valid for the + /// [LineScanner] that created it. + LineScannerState get state => + new LineScannerState._(this, position, line, column); + + set state(LineScannerState state) { + if (!identical(state._scanner, this)) { + throw new ArgumentError("The given LineScannerState was not returned by " + "this LineScanner."); + } + + super.position = state.position; + _line = state.line; + _column = state.column; + } + + set position(int newPosition) { + var oldPosition = position; + super.position = newPosition; + + if (newPosition > oldPosition) { + var newlines = "\n".allMatches(string.substring(oldPosition, newPosition)) + .toList(); + _line += newlines.length; + if (newlines.isEmpty) { + _column += newPosition - oldPosition; + } else { + _column = newPosition - newlines.last.end; + } + } else { + var newlines = "\n".allMatches(string.substring(newPosition, oldPosition)) + .toList(); + _line -= newlines.length; + if (newlines.isEmpty) { + _column -= oldPosition - newPosition; + } else { + _column = newPosition - string.lastIndexOf("\n", newPosition) - 1; + } + } + } + + LineScanner(String string, {sourceUrl, int position}) + : super(string, sourceUrl: sourceUrl, position: position); + + int readChar() { + var char = super.readChar(); + if (char == 0xA) { + _line += 1; + _column = 0; + } else { + _column += 1; + } + return char; + } + + bool scan(Pattern pattern) { + var oldPosition = position; + if (!super.scan(pattern)) return false; + + var newlines = "\n".allMatches(lastMatch[0]).toList(); + _line += newlines.length; + if (newlines.isEmpty) { + _column += lastMatch[0].length; + } else { + _column = lastMatch[0].length - newlines.last.end; + } + + return true; + } +} + +/// A class representing the state of a [LineScanner]. +class LineScannerState { + /// The [LineScanner] that created this. + final LineScanner _scanner; + + /// The position of the scanner in this state. + final int position; + + /// The zero-based line number of the scanner in this state. + final int line; + + /// The zero-based column number of the scanner in this state. + final int column; + + LineScannerState._(this._scanner, this.position, this.line, this.column); +} diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart new file mode 100644 index 000000000..9060e62f0 --- /dev/null +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -0,0 +1,95 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.span_scanner; + +import 'package:source_maps/source_maps.dart'; + +import 'exception.dart'; +import 'line_scanner.dart'; +import 'string_scanner.dart'; +import 'utils.dart'; + +/// A subclass of [LineScanner] that exposes matched ranges as source map +/// [Span]s. +class SpanScanner extends StringScanner implements LineScanner { + /// The source of the scanner. + /// + /// This caches line break information and is used to generate [Span]s. + final SourceFile _sourceFile; + + int get line => _sourceFile.getLine(position); + int get column => _sourceFile.getColumn(line, position); + + LineScannerState get state => new _SpanScannerState(this, position); + + set state(LineScannerState state) { + if (state is! _SpanScannerState || + !identical((state as _SpanScannerState)._scanner, this)) { + throw new ArgumentError("The given LineScannerState was not returned by " + "this LineScanner."); + } + + this.position = state.position; + } + + /// The [Span] for [lastMatch]. + /// + /// This is the span for the entire match. There's no way to get spans for + /// subgroups since [Match] exposes no information about their positions. + Span get lastSpan => _lastSpan; + Span _lastSpan; + + /// Returns an empty span at the current location. + Span get emptySpan => _sourceFile.span(position); + + /// Creates a new [SpanScanner] that starts scanning from [position]. + /// + /// [sourceUrl] is used as [Location.sourceUrl] for the returned [Span]s as + /// well as for error reporting. + SpanScanner(String string, sourceUrl, {int position}) + : _sourceFile = new SourceFile.text( + sourceUrl is Uri ? sourceUrl.toString() : sourceUrl, string), + super(string, sourceUrl: sourceUrl, position: position); + + /// Creates a [Span] representing the source range between [startState] and + /// the current position. + Span spanFrom(LineScannerState startState) => + _sourceFile.span(startState.position, position); + + bool matches(Pattern pattern) { + if (!super.matches(pattern)) { + _lastSpan = null; + return false; + } + + _lastSpan = _sourceFile.span(position, lastMatch.end); + return true; + } + + void error(String message, {Match match, int position, int length}) { + validateErrorArgs(string, match, position, length); + + if (match == null && position == null && length == null) match = lastMatch; + if (position == null) { + position = match == null ? this.position : match.start; + } + if (length == null) length = match == null ? 1 : match.end - match.start; + + var span = _sourceFile.span(position, position + length); + throw new StringScannerException(message, string, sourceUrl, span); + } +} + +/// A class representing the state of a [SpanScanner]. +class _SpanScannerState implements LineScannerState { + /// The [SpanScanner] that created this. + final SpanScanner _scanner; + + final int position; + int get line => _scanner._sourceFile.getLine(position); + int get column => _scanner._sourceFile.getColumn(line, position); + + _SpanScannerState(this._scanner, this.position); +} diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart new file mode 100644 index 000000000..c9e74594a --- /dev/null +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -0,0 +1,168 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.string_scanner; + +import 'package:source_maps/source_maps.dart'; + +import 'exception.dart'; +import 'utils.dart'; + +/// When compiled to JS, forward slashes are always escaped in [RegExp.pattern]. +/// +/// See issue 17998. +final _slashAutoEscape = new RegExp("/").pattern == "\\/"; + +/// A class that scans through a string using [Pattern]s. +class StringScanner { + /// The URL of the source of the string being scanned. + /// + /// This is used for error reporting. It may be `null`, indicating that the + /// source URL is unknown or unavailable. + final Uri sourceUrl; + + /// The string being scanned through. + final String string; + + /// The current position of the scanner in the string, in characters. + int get position => _position; + set position(int position) { + if (position < 0 || position > string.length) { + throw new ArgumentError("Invalid position $position"); + } + + _position = position; + } + 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 _lastMatch; + + /// The portion of the string that hasn't yet been scanned. + String get rest => string.substring(position); + + /// Whether the scanner has completely consumed [string]. + bool get isDone => position == string.length; + + /// Creates a new [StringScanner] that starts scanning from [position]. + /// + /// [position] defaults to 0, the beginning of the string. [sourceUrl] is the + /// URL of the source of the string being scanned, if available. It can be + /// either a [String] or a [Uri]. + StringScanner(this.string, {sourceUrl, int position}) + : sourceUrl = sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl { + if (position != null) this.position = position; + } + + /// Consumes a single character and returns its character code. + /// + /// This throws a [FormatException] if the string has been fully consumed. It + /// doesn't affect [lastMatch]. + int readChar() { + if (isDone) _fail("more input"); + return string.codeUnitAt(_position++); + } + + /// Returns the character code of the character [offset] away from [position]. + /// + /// [offset] defaults to zero, and may be negative to inspect already-consumed + /// characters. + /// + /// This returns `null` if [offset] points outside the string. It doesn't + /// affect [lastMatch]. + int peekChar([int offset]) { + if (offset == null) offset = 0; + var index = position + offset; + if (index < 0 || index >= string.length) return null; + return string.codeUnitAt(index); + } + + /// If [pattern] matches at the current position of the string, scans forward + /// until the end of the match. + /// + /// Returns whether or not [pattern] matched. + bool scan(Pattern pattern) { + var success = matches(pattern); + if (success) _position = _lastMatch.end; + return success; + } + + /// If [pattern] matches at the current position of the string, scans forward + /// until the end of the match. + /// + /// If [pattern] did not match, throws a [FormatException] describing the + /// position of the failure. [name] is used in this error as the expected name + /// of the pattern being matched; if it's `null`, the pattern itself is used + /// instead. + void expect(Pattern pattern, {String name}) { + if (scan(pattern)) return; + + if (name == null) { + if (pattern is RegExp) { + var source = pattern.pattern; + if (!_slashAutoEscape) source = source.replaceAll("/", "\\/"); + name = "/$source/"; + } else { + name = pattern.toString() + .replaceAll("\\", "\\\\").replaceAll('"', '\\"'); + name = '"$name"'; + } + } + _fail(name); + } + + /// If the string has not been fully consumed, this throws a + /// [FormatException]. + void expectDone() { + if (isDone) return; + _fail("no more input"); + } + + /// Returns whether or not [pattern] matches at the current position of the + /// string. + /// + /// This doesn't move the scan pointer forward. + bool matches(Pattern pattern) { + _lastMatch = pattern.matchAsPrefix(string, position); + return _lastMatch != null; + } + + /// Throws a [FormatException] with [message] as well as a detailed + /// description of the location of the error in the string. + /// + /// [match] is the match information for the span of the string with which the + /// error is associated. This should be a match returned by this scanner's + /// [lastMatch] property. By default, the error is associated with the last + /// match. + /// + /// 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. + /// + /// 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}) { + validateErrorArgs(string, match, position, length); + + if (match == null && position == null && length == null) match = lastMatch; + if (position == null) { + position = match == null ? this.position : match.start; + } + if (length == null) length = match == null ? 1 : match.end - match.start; + + var url = sourceUrl == null ? null : sourceUrl.toString(); + var sourceFile = new SourceFile.text(url, string); + var span = sourceFile.span(position, position + length); + throw new StringScannerException(message, string, sourceUrl, span); + } + + // TODO(nweiz): Make this handle long lines more gracefully. + /// Throws a [FormatException] describing that [name] is expected at the + /// current position in the string. + void _fail(String name) { + error("expected $name.", position: this.position, length: 0); + } +} diff --git a/pkgs/string_scanner/lib/src/utils.dart b/pkgs/string_scanner/lib/src/utils.dart new file mode 100644 index 000000000..e556236e8 --- /dev/null +++ b/pkgs/string_scanner/lib/src/utils.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.utils; + +/// Validates the arguments passed to [StringScanner.error]. +void validateErrorArgs(String string, Match match, int position, int length) { + if (match != null && (position != null || length != null)) { + throw new ArgumentError("Can't pass both match and position/length."); + } + + if (position != null) { + if (position < 0) { + throw new RangeError("position must be greater than or equal to 0."); + } else if (position > string.length) { + throw new RangeError("position must be less than or equal to the " + "string length."); + } + } + + if (length != null && length < 0) { + throw new RangeError("length must be greater than or equal to 0."); + } + + if (position != null && length != null && position + length > string.length) { + throw new RangeError("position plus length must not go beyond the end of " + "the string."); + } +} \ No newline at end of file diff --git a/pkgs/string_scanner/lib/string_scanner.dart b/pkgs/string_scanner/lib/string_scanner.dart index 3e3913b50..be294f4f6 100644 --- a/pkgs/string_scanner/lib/string_scanner.dart +++ b/pkgs/string_scanner/lib/string_scanner.dart @@ -5,165 +5,7 @@ /// A library for parsing strings using a sequence of patterns. library string_scanner; -import 'dart:math' as math; - -/// When compiled to JS, forward slashes are always escaped in [RegExp.pattern]. -/// -/// See issue 17998. -final _slashAutoEscape = new RegExp("/").pattern == "\\/"; - -// TODO(nweiz): Add some integration between this and source maps. -/// A class that scans through a string using [Pattern]s. -class StringScanner { - /// The string being scanned through. - final String string; - - /// The current position of the scanner in the string, in characters. - int get position => _position; - set position(int position) { - if (position < 0 || position > string.length) { - throw new ArgumentError("Invalid position $position"); - } - - _position = position; - } - 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 _lastMatch; - - /// The portion of the string that hasn't yet been scanned. - String get rest => string.substring(position); - - /// Whether the scanner has completely consumed [string]. - bool get isDone => position == string.length; - - /// Creates a new [StringScanner] that starts scanning from [position]. - /// - /// [position] defaults to 0, the beginning of the string. - StringScanner(this.string, {int position}) { - if (position != null) this.position = position; - } - - /// If [pattern] matches at the current position of the string, scans forward - /// until the end of the match. - /// - /// Returns whether or not [pattern] matched. - bool scan(Pattern pattern) { - var success = matches(pattern); - if (success) _position = _lastMatch.end; - return success; - } - - /// If [pattern] matches at the current position of the string, scans forward - /// until the end of the match. - /// - /// If [pattern] did not match, throws a [FormatException] describing the - /// position of the failure. [name] is used in this error as the expected name - /// of the pattern being matched; if it's `null`, the pattern itself is used - /// instead. - void expect(Pattern pattern, {String name}) { - if (scan(pattern)) return; - - if (name == null) { - if (pattern is RegExp) { - var source = pattern.pattern; - if (!_slashAutoEscape) source = source.replaceAll("/", "\\/"); - name = "/$source/"; - } else { - name = pattern.toString() - .replaceAll("\\", "\\\\").replaceAll('"', '\\"'); - name = '"$name"'; - } - } - _fail(name); - } - - /// If the string has not been fully consumed, this throws a - /// [FormatException]. - void expectDone() { - if (isDone) return; - _fail("no more input"); - } - - /// Returns whether or not [pattern] matches at the current position of the - /// string. - /// - /// This doesn't move the scan pointer forward. - bool matches(Pattern pattern) { - _lastMatch = pattern.matchAsPrefix(string, position); - return _lastMatch != null; - } - - /// Throws a [FormatException] with [message] as well as a detailed - /// description of the location of the error in the string. - /// - /// [match] is the match information for the span of the string with which the - /// error is associated. This should be a match returned by this scanner's - /// [lastMatch] property. By default, the error is associated with the last - /// match. - /// - /// 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. - /// - /// 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}) { - if (match != null && (position != null || length != null)) { - throw new ArgumentError("Can't pass both match and position/length."); - } - - if (position != null && position < 0) { - throw new RangeError("position must be greater than or equal to 0."); - } - - if (length != null && length < 1) { - throw new RangeError("length must be greater than or equal to 0."); - } - - if (match == null && position == null && length == null) match = lastMatch; - if (position == null) { - position = match == null ? this.position : match.start; - } - if (length == null) length = match == null ? 1 : match.end - match.start; - - var newlines = "\n".allMatches(string.substring(0, position)).toList(); - var line = newlines.length + 1; - var column; - var lastLine; - if (newlines.isEmpty) { - column = position + 1; - lastLine = string.substring(0, position); - } else { - column = position - newlines.last.end + 1; - lastLine = string.substring(newlines.last.end, position); - } - - var remaining = string.substring(position); - var nextNewline = remaining.indexOf("\n"); - if (nextNewline == -1) { - lastLine += remaining; - } else { - length = math.min(length, nextNewline); - lastLine += remaining.substring(0, nextNewline); - } - - var spaces = new List.filled(column - 1, ' ').join(); - var underline = new List.filled(length, '^').join(); - - throw new FormatException( - "Error on line $line, column $column: $message\n" - "$lastLine\n" - "$spaces$underline"); - } - - // TODO(nweiz): Make this handle long lines more gracefully. - /// Throws a [FormatException] describing that [name] is expected at the - /// current position in the string. - void _fail(String name) { - error("expected $name.", position: this.position, length: 1); - } -} +export 'src/exception.dart'; +export 'src/line_scanner.dart'; +export 'src/span_scanner.dart'; +export 'src/string_scanner.dart'; diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 3035901ea..86ae238a6 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,9 +1,12 @@ name: string_scanner -version: 0.0.1 +version: 0.0.2 author: "Dart Team " homepage: http://www.dartlang.org description: > A class for parsing strings using a sequence of patterns. +dependencies: + path: ">=1.2.0 <2.0.0" + source_maps: ">=0.9.0 <0.10.0" dev_dependencies: unittest: ">=0.10.0 <0.11.0" environment: diff --git a/pkgs/string_scanner/test/error_test.dart b/pkgs/string_scanner/test/error_test.dart index 6432197b3..4fe9083df 100644 --- a/pkgs/string_scanner/test/error_test.dart +++ b/pkgs/string_scanner/test/error_test.dart @@ -14,10 +14,7 @@ void main() { var scanner = new StringScanner('foo bar baz'); scanner.expect('foo '); scanner.expect('bar'); - expect(() => scanner.error('oh no!'), throwsFormattedError(''' -Error on line 1, column 5: oh no! -foo bar baz - ^^^''')); + expect(() => scanner.error('oh no!'), throwsStringScannerException('bar')); }); group("with match", () { @@ -27,10 +24,7 @@ foo bar baz var match = scanner.lastMatch; scanner.expect('bar'); expect(() => scanner.error('oh no!', match: match), - throwsFormattedError(''' -Error on line 1, column 1: oh no! -foo bar baz -^^^^''')); + throwsStringScannerException('foo ')); }); test('supports a match on a previous line', () { @@ -40,10 +34,7 @@ foo bar baz var match = scanner.lastMatch; scanner.expect(' mi\nearth '); expect(() => scanner.error('oh no!', match: match), - throwsFormattedError(''' -Error on line 2, column 4: oh no! -do re mi - ^^''')); + throwsStringScannerException('re')); }); test('supports a multiline match', () { @@ -53,10 +44,7 @@ do re mi var match = scanner.lastMatch; scanner.expect(' re mi'); expect(() => scanner.error('oh no!', match: match), - throwsFormattedError(''' -Error on line 1, column 9: oh no! -foo bar baz - ^^^''')); + throwsStringScannerException('baz\ndo')); }); test('supports a match after position', () { @@ -66,10 +54,7 @@ foo bar baz var match = scanner.lastMatch; scanner.position = 0; expect(() => scanner.error('oh no!', match: match), - throwsFormattedError(''' -Error on line 1, column 5: oh no! -foo bar baz - ^^^''')); + throwsStringScannerException('bar')); }); }); @@ -78,59 +63,47 @@ foo bar baz var scanner = new StringScanner('foo bar baz'); scanner.expect('foo '); expect(() => scanner.error('oh no!', position: 1), - throwsFormattedError(''' -Error on line 1, column 2: oh no! -foo bar baz - ^''')); + throwsStringScannerException('o')); }); test('defaults to the current position', () { var scanner = new StringScanner('foo bar baz'); scanner.expect('foo '); expect(() => scanner.error('oh no!', length: 3), - throwsFormattedError(''' -Error on line 1, column 5: oh no! -foo bar baz - ^^^''')); + throwsStringScannerException('bar')); }); test('supports an earlier position', () { var scanner = new StringScanner('foo bar baz'); scanner.expect('foo '); expect(() => scanner.error('oh no!', position: 1, length: 2), - throwsFormattedError(''' -Error on line 1, column 2: oh no! -foo bar baz - ^^''')); + throwsStringScannerException('oo')); }); test('supports a position on a previous line', () { var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo re mi\nearth'); expect(() => scanner.error('oh no!', position: 15, length: 2), - throwsFormattedError(''' -Error on line 2, column 4: oh no! -do re mi - ^^''')); + throwsStringScannerException('re')); }); test('supports a multiline length', () { var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo re mi\nearth'); expect(() => scanner.error('oh no!', position: 8, length: 8), - throwsFormattedError(''' -Error on line 1, column 9: oh no! -foo bar baz - ^^^''')); + throwsStringScannerException('baz\ndo r')); }); test('supports a position after the current one', () { var scanner = new StringScanner('foo bar baz'); expect(() => scanner.error('oh no!', position: 4, length: 3), - throwsFormattedError(''' -Error on line 1, column 5: oh no! -foo bar baz - ^^^''')); + throwsStringScannerException('bar')); + }); + + test('supports a length of zero', () { + var scanner = new StringScanner('foo bar baz'); + expect(() => scanner.error('oh no!', position: 4, length: 0), + throwsStringScannerException('')); }); }); @@ -161,8 +134,13 @@ foo bar baz expect(() => scanner.error("oh no!", position: 100), throwsArgumentError); }); - test("if length is zero", () { - expect(() => scanner.error("oh no!", length: 0), throwsArgumentError); + test("if position + length is outside the string", () { + expect(() => scanner.error("oh no!", position: 7, length: 7), + throwsArgumentError); + }); + + test("if length is negative", () { + expect(() => scanner.error("oh no!", length: -1), throwsArgumentError); }); }); } diff --git a/pkgs/string_scanner/test/expect_error_test.dart b/pkgs/string_scanner/test/expect_error_test.dart deleted file mode 100644 index 3596e15e5..000000000 --- a/pkgs/string_scanner/test/expect_error_test.dart +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -library string_scanner.expect_error_test; - -import 'package:string_scanner/string_scanner.dart'; -import 'package:unittest/unittest.dart'; - -import 'utils.dart'; - -void main() { - test('points to the first unconsumed character', () { - var scanner = new StringScanner('foo bar baz'); - scanner.expect('foo '); - expect(() => scanner.expect('foo'), throwsFormattedError(''' -Error on line 1, column 5: expected "foo". -foo bar baz - ^''')); - }); - - test('prints the correct line', () { - var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); - scanner.expect('foo bar baz\ndo '); - expect(() => scanner.expect('foo'), throwsFormattedError(''' -Error on line 2, column 4: expected "foo". -do re mi - ^''')); - }); - - test('handles the beginning of the string correctly', () { - var scanner = new StringScanner('foo bar baz'); - expect(() => scanner.expect('zap'), throwsFormattedError(''' -Error on line 1, column 1: expected "zap". -foo bar baz -^''')); - }); - - test('handles the end of the string correctly', () { - var scanner = new StringScanner('foo bar baz'); - scanner.expect('foo bar baz'); - expect(() => scanner.expect('bang'), throwsFormattedError(''' -Error on line 1, column 12: expected "bang". -foo bar baz - ^''')); - }); - - test('handles an empty string correctly', () { - expect(() => new StringScanner('').expect('foo'), throwsFormattedError(''' -Error on line 1, column 1: expected "foo". - -^''')); - }); - - group("expected name", () { - test("uses the provided name", () { - expect(() => new StringScanner('').expect('foo bar', name: 'zap'), - throwsFormattedError(''' -Error on line 1, column 1: expected zap. - -^''')); - }); - - test("escapes string quotes", () { - expect(() => new StringScanner('').expect('foo"bar'), - throwsFormattedError(''' -Error on line 1, column 1: expected "foo\\"bar". - -^''')); - }); - - test("escapes string backslashes", () { - expect(() => new StringScanner('').expect('foo\\bar'), - throwsFormattedError(''' -Error on line 1, column 1: expected "foo\\\\bar". - -^''')); - }); - - test("prints PERL-style regexps", () { - expect(() => new StringScanner('').expect(new RegExp(r'foo')), - throwsFormattedError(''' -Error on line 1, column 1: expected /foo/. - -^''')); - }); - - test("escape regexp forward slashes", () { - expect(() => new StringScanner('').expect(new RegExp(r'foo/bar')), - throwsFormattedError(''' -Error on line 1, column 1: expected /foo\\/bar/. - -^''')); - }); - - test("does not escape regexp backslashes", () { - expect(() => new StringScanner('').expect(new RegExp(r'foo\bar')), - throwsFormattedError(''' -Error on line 1, column 1: expected /foo\\bar/. - -^''')); - }); - }); -} diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart new file mode 100644 index 000000000..8cc79a65c --- /dev/null +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -0,0 +1,106 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.line_scanner_test; + +import 'package:string_scanner/string_scanner.dart'; +import 'package:unittest/unittest.dart'; + +void main() { + var scanner; + setUp(() { + scanner = new LineScanner('foo\nbar\nbaz'); + }); + + test('begins with line and column 0', () { + expect(scanner.line, equals(0)); + expect(scanner.column, equals(0)); + }); + + group("scan()", () { + test("consuming no newlines increases the column but not the line", () { + scanner.scan('foo'); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(3)); + }); + + test("consuming a newline resets the column and increases the line", () { + scanner.expect('foo\nba'); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(2)); + }); + + test("consuming multiple newlines resets the column and increases the line", + () { + scanner.expect('foo\nbar\nb'); + expect(scanner.line, equals(2)); + expect(scanner.column, equals(1)); + }); + }); + + group("readChar()", () { + test("on a non-newline character increases the column but not the line", + () { + scanner.readChar(); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(1)); + }); + + test("consuming a newline resets the column and increases the line", () { + scanner.expect('foo'); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(3)); + + scanner.readChar(); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(0)); + }); + }); + + group("position=", () { + test("forward through newlines sets the line and column", () { + scanner.position = 9; // "foo\nbar\nb" + expect(scanner.line, equals(2)); + expect(scanner.column, equals(1)); + }); + + test("forward through no newlines sets the column", () { + scanner.position = 2; // "fo" + expect(scanner.line, equals(0)); + expect(scanner.column, equals(2)); + }); + + test("backward through newlines sets the line and column", () { + scanner.scan("foo\nbar\nbaz"); + scanner.position = 2; // "fo" + expect(scanner.line, equals(0)); + expect(scanner.column, equals(2)); + }); + + test("backward through no newlines sets the column", () { + scanner.scan("foo\nbar\nbaz"); + scanner.position = 9; // "foo\nbar\nb" + expect(scanner.line, equals(2)); + expect(scanner.column, equals(1)); + }); + }); + + test("state= restores the line, column, and position", () { + scanner.scan('foo\nb'); + var state = scanner.state; + + scanner.scan('ar\nba'); + scanner.state = state; + expect(scanner.rest, equals('ar\nbaz')); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(1)); + }); + + test("state= rejects a foreign state", () { + scanner.scan('foo\nb'); + + expect(() => new LineScanner(scanner.string).state = scanner.state, + throwsArgumentError); + }); +} diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart new file mode 100644 index 000000000..93ba0b659 --- /dev/null +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -0,0 +1,60 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.span_scanner_test; + +import 'package:string_scanner/string_scanner.dart'; +import 'package:unittest/unittest.dart'; + +void main() { + var scanner; + setUp(() { + scanner = new SpanScanner('foo\nbar\nbaz', 'source'); + }); + + test("tracks the span for the last match", () { + scanner.scan('fo'); + scanner.scan('o\nba'); + + var span = scanner.lastSpan; + expect(span.start.offset, equals(2)); + expect(span.start.line, equals(0)); + expect(span.start.column, equals(2)); + expect(span.start.sourceUrl, equals('source')); + + expect(span.end.offset, equals(6)); + expect(span.end.line, equals(1)); + expect(span.end.column, equals(2)); + expect(span.start.sourceUrl, equals('source')); + + expect(span.text, equals('o\nba')); + }); + + test(".spanFrom() returns a span from a previous state", () { + scanner.scan('fo'); + var state = scanner.state; + scanner.scan('o\nba'); + scanner.scan('r\nba'); + + var span = scanner.spanFrom(state); + expect(span.text, equals('o\nbar\nba')); + }); + + test(".emptySpan returns an empty span at the current location", () { + scanner.scan('foo\nba'); + + var span = scanner.emptySpan; + expect(span.start.offset, equals(6)); + expect(span.start.line, equals(1)); + expect(span.start.column, equals(2)); + expect(span.start.sourceUrl, equals('source')); + + expect(span.end.offset, equals(6)); + expect(span.end.line, equals(1)); + expect(span.end.column, equals(2)); + expect(span.start.sourceUrl, equals('source')); + + expect(span.text, equals('')); + }); +} diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 0cab6273e..6144bf9c0 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -31,6 +31,18 @@ void main() { expect(scanner.position, equals(0)); }); + test("readChar fails and doesn't change the state", () { + expect(scanner.readChar, throwsFormatException); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + + test("peekChar returns null and doesn't change the state", () { + expect(scanner.peekChar(), isNull); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + test("scan returns false and doesn't change the state", () { expect(scanner.scan(new RegExp('.')), isFalse); expect(scanner.lastMatch, isNull); @@ -85,6 +97,24 @@ void main() { expect(scanner.position, equals(0)); }); + test('readChar returns the first character and moves forward', () { + expect(scanner.readChar(), equals(0x66)); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(1)); + }); + + test('peekChar returns the first character', () { + expect(scanner.peekChar(), equals(0x66)); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + + test('peekChar with an argument returns the nth character', () { + expect(scanner.peekChar(4), equals(0x62)); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + test("a matching scan returns true and changes the state", () { expect(scanner.scan(new RegExp('f(..)')), isTrue); expect(scanner.lastMatch[1], equals('oo')); @@ -200,6 +230,18 @@ void main() { expect(scanner.position, equals(7)); }); + test("readChar fails and doesn't change the state", () { + expect(scanner.readChar, throwsFormatException); + expect(scanner.lastMatch, isNotNull); + expect(scanner.position, equals(7)); + }); + + test("peekChar returns null and doesn't change the state", () { + expect(scanner.peekChar(), isNull); + expect(scanner.lastMatch, isNotNull); + expect(scanner.position, equals(7)); + }); + test("scan returns false and sets lastMatch to null", () { expect(scanner.scan(new RegExp('.')), isFalse); expect(scanner.lastMatch, isNull); diff --git a/pkgs/string_scanner/test/utils.dart b/pkgs/string_scanner/test/utils.dart index eee93d89d..3de601cf1 100644 --- a/pkgs/string_scanner/test/utils.dart +++ b/pkgs/string_scanner/test/utils.dart @@ -4,14 +4,15 @@ library string_scanner.test.utils; +import 'package:string_scanner/string_scanner.dart'; import 'package:unittest/unittest.dart'; /// Returns a matcher that asserts that a closure throws a [FormatException] /// with the given [message]. -Matcher throwsFormattedError(String message) { +Matcher throwsStringScannerException(String text) { return throwsA(predicate((error) { - expect(error, isFormatException); - expect(error.message, equals(message)); + expect(error, new isInstanceOf()); + expect(error.span.text, equals(text)); return true; })); } From 80a0a0304bef5834a6752c4cd734963307c4b686 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Mon, 23 Jun 2014 21:10:55 +0000 Subject: [PATCH 005/102] Make StringScannerException extend SpanFormatException. R=rnystrom@google.com BUG= Review URL: https://codereview.chromium.org//343043002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/string_scanner@37619 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/string_scanner/CHANGELOG.md | 7 +++++++ pkgs/string_scanner/lib/src/exception.dart | 22 +++------------------- pkgs/string_scanner/pubspec.yaml | 4 ++-- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 2c41c9d64..a5d551888 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.0.3 + +* Make `StringScannerException` inherit from source_map's + [`SpanFormatException`][]. + +[SpanFormatException]: (http://www.dartdocs.org/documentation/source_maps/0.9.2/index.html#source_maps/source_maps.SpanFormatException) + ## 0.0.2 * `new StringScanner()` now takes an optional `sourceUrl` argument that provides diff --git a/pkgs/string_scanner/lib/src/exception.dart b/pkgs/string_scanner/lib/src/exception.dart index c3986871a..44ec9a3e7 100644 --- a/pkgs/string_scanner/lib/src/exception.dart +++ b/pkgs/string_scanner/lib/src/exception.dart @@ -7,10 +7,7 @@ library string_scanner.exception; import 'package:source_maps/source_maps.dart'; /// An exception thrown by a [StringScanner] that failed to parse a string. -class StringScannerException implements FormatException { - /// The error message. - final String message; - +class StringScannerException extends SpanFormatException { /// The source string being parsed. final String string; @@ -19,19 +16,6 @@ class StringScannerException implements FormatException { /// This may be `null`, indicating that the source URL is unknown. final Uri sourceUrl; - /// The span within [string] that caused the exception. - final Span span; - - StringScannerException(this.message, this.string, this.sourceUrl, this.span); - - /// Returns a detailed description of this exception. - /// - /// If [useColors] is true, the section of the source that caused the - /// exception will be colored using ANSI color codes. By default, it's colored - /// red, but a different ANSI code may passed via [color]. - String toString({bool useColors: false, String color}) { - return "Error on " + span.getLocationMessage( - message, useColors: useColors, color: color); - } + StringScannerException(String message, this.string, this.sourceUrl, Span span) + : super(message, span); } - diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 86ae238a6..f6d7ab9ef 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,12 +1,12 @@ name: string_scanner -version: 0.0.2 +version: 0.0.3 author: "Dart Team " homepage: http://www.dartlang.org description: > A class for parsing strings using a sequence of patterns. dependencies: path: ">=1.2.0 <2.0.0" - source_maps: ">=0.9.0 <0.10.0" + source_maps: ">=0.9.2 <0.10.0" dev_dependencies: unittest: ">=0.10.0 <0.11.0" environment: From a3708fa9f88d21016125320ad923b4cabe3506a0 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Wed, 23 Jul 2014 23:44:09 +0000 Subject: [PATCH 006/102] Move a number of packages and some of pub over to using source_span. R=efortuna@google.com, rnystrom@google.com, sigmund@google.com BUG=19930 Review URL: https://codereview.chromium.org//401753002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/string_scanner@38526 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/string_scanner/CHANGELOG.md | 13 ++++++++ pkgs/string_scanner/lib/src/exception.dart | 13 ++++---- pkgs/string_scanner/lib/src/span_scanner.dart | 32 +++++++++---------- .../lib/src/string_scanner.dart | 9 +++--- pkgs/string_scanner/pubspec.yaml | 4 +-- .../test/span_scanner_test.dart | 10 +++--- 6 files changed, 46 insertions(+), 35 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index a5d551888..f1d876301 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.1.0 + +* Switch from `source_maps`' `Span` class to `source_span`'s `SourceSpan` class. + +* `new StringScanner()`'s `sourceUrl` parameter is now named to make it clear + that it can be safely `null`. + +* `new StringScannerException()` takes different arguments in a different order + to match `SpanFormatException`. + +* `StringScannerException.string` has been renamed to + `StringScannerException.source` to match the `FormatException` interface. + ## 0.0.3 * Make `StringScannerException` inherit from source_map's diff --git a/pkgs/string_scanner/lib/src/exception.dart b/pkgs/string_scanner/lib/src/exception.dart index 44ec9a3e7..50177d657 100644 --- a/pkgs/string_scanner/lib/src/exception.dart +++ b/pkgs/string_scanner/lib/src/exception.dart @@ -4,18 +4,17 @@ library string_scanner.exception; -import 'package:source_maps/source_maps.dart'; +import 'package:source_span/source_span.dart'; /// An exception thrown by a [StringScanner] that failed to parse a string. -class StringScannerException extends SpanFormatException { - /// The source string being parsed. - final String string; +class StringScannerException extends SourceSpanFormatException { + String get source => super.source; /// The URL of the source file being parsed. /// /// This may be `null`, indicating that the source URL is unknown. - final Uri sourceUrl; + Uri get sourceUrl => span.sourceUrl; - StringScannerException(String message, this.string, this.sourceUrl, Span span) - : super(message, span); + StringScannerException(String message, SourceSpan span, String source) + : super(message, span, source); } diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index 9060e62f0..d8dc230a8 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -4,7 +4,7 @@ library string_scanner.span_scanner; -import 'package:source_maps/source_maps.dart'; +import 'package:source_span/source_span.dart'; import 'exception.dart'; import 'line_scanner.dart'; @@ -20,7 +20,7 @@ class SpanScanner extends StringScanner implements LineScanner { final SourceFile _sourceFile; int get line => _sourceFile.getLine(position); - int get column => _sourceFile.getColumn(line, position); + int get column => _sourceFile.getColumn(position); LineScannerState get state => new _SpanScannerState(this, position); @@ -34,28 +34,28 @@ class SpanScanner extends StringScanner implements LineScanner { this.position = state.position; } - /// The [Span] for [lastMatch]. + /// The [SourceSpan] for [lastMatch]. /// /// This is the span for the entire match. There's no way to get spans for /// subgroups since [Match] exposes no information about their positions. - Span get lastSpan => _lastSpan; - Span _lastSpan; + SourceSpan get lastSpan => _lastSpan; + SourceSpan _lastSpan; /// Returns an empty span at the current location. - Span get emptySpan => _sourceFile.span(position); + SourceSpan get emptySpan => _sourceFile.location(position).pointSpan(); /// Creates a new [SpanScanner] that starts scanning from [position]. /// - /// [sourceUrl] is used as [Location.sourceUrl] for the returned [Span]s as - /// well as for error reporting. - SpanScanner(String string, sourceUrl, {int position}) - : _sourceFile = new SourceFile.text( - sourceUrl is Uri ? sourceUrl.toString() : sourceUrl, string), + /// [sourceUrl] is used as [SourceLocation.sourceUrl] for the returned + /// [SourceSpan]s as well as for error reporting. It can be a [String], a + /// [Uri], or `null`. + SpanScanner(String string, {sourceUrl, int position}) + : _sourceFile = new SourceFile(string, url: sourceUrl), super(string, sourceUrl: sourceUrl, position: position); - /// Creates a [Span] representing the source range between [startState] and - /// the current position. - Span spanFrom(LineScannerState startState) => + /// Creates a [SourceSpan] representing the source range between [startState] + /// and the current position. + SourceSpan spanFrom(LineScannerState startState) => _sourceFile.span(startState.position, position); bool matches(Pattern pattern) { @@ -78,7 +78,7 @@ class SpanScanner extends StringScanner implements LineScanner { if (length == null) length = match == null ? 1 : match.end - match.start; var span = _sourceFile.span(position, position + length); - throw new StringScannerException(message, string, sourceUrl, span); + throw new StringScannerException(message, span, string); } } @@ -89,7 +89,7 @@ class _SpanScannerState implements LineScannerState { final int position; int get line => _scanner._sourceFile.getLine(position); - int get column => _scanner._sourceFile.getColumn(line, position); + int get column => _scanner._sourceFile.getColumn(position); _SpanScannerState(this._scanner, this.position); } diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index c9e74594a..44d5d2d87 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -4,7 +4,7 @@ library string_scanner.string_scanner; -import 'package:source_maps/source_maps.dart'; +import 'package:source_span/source_span.dart'; import 'exception.dart'; import 'utils.dart'; @@ -52,7 +52,7 @@ class StringScanner { /// /// [position] defaults to 0, the beginning of the string. [sourceUrl] is the /// URL of the source of the string being scanned, if available. It can be - /// either a [String] or a [Uri]. + /// a [String], a [Uri], or `null`. StringScanner(this.string, {sourceUrl, int position}) : sourceUrl = sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl { if (position != null) this.position = position; @@ -153,10 +153,9 @@ class StringScanner { } if (length == null) length = match == null ? 1 : match.end - match.start; - var url = sourceUrl == null ? null : sourceUrl.toString(); - var sourceFile = new SourceFile.text(url, string); + var sourceFile = new SourceFile(string, url: sourceUrl); var span = sourceFile.span(position, position + length); - throw new StringScannerException(message, string, sourceUrl, span); + throw new StringScannerException(message, span, string); } // TODO(nweiz): Make this handle long lines more gracefully. diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index f6d7ab9ef..1451fc518 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,12 +1,12 @@ name: string_scanner -version: 0.0.3 +version: 0.1.0 author: "Dart Team " homepage: http://www.dartlang.org description: > A class for parsing strings using a sequence of patterns. dependencies: path: ">=1.2.0 <2.0.0" - source_maps: ">=0.9.2 <0.10.0" + source_span: ">=1.0.0 <2.0.0" dev_dependencies: unittest: ">=0.10.0 <0.11.0" environment: diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index 93ba0b659..796df2968 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -10,7 +10,7 @@ import 'package:unittest/unittest.dart'; void main() { var scanner; setUp(() { - scanner = new SpanScanner('foo\nbar\nbaz', 'source'); + scanner = new SpanScanner('foo\nbar\nbaz', sourceUrl: 'source'); }); test("tracks the span for the last match", () { @@ -21,12 +21,12 @@ void main() { expect(span.start.offset, equals(2)); expect(span.start.line, equals(0)); expect(span.start.column, equals(2)); - expect(span.start.sourceUrl, equals('source')); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); expect(span.end.offset, equals(6)); expect(span.end.line, equals(1)); expect(span.end.column, equals(2)); - expect(span.start.sourceUrl, equals('source')); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); expect(span.text, equals('o\nba')); }); @@ -48,12 +48,12 @@ void main() { expect(span.start.offset, equals(6)); expect(span.start.line, equals(1)); expect(span.start.column, equals(2)); - expect(span.start.sourceUrl, equals('source')); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); expect(span.end.offset, equals(6)); expect(span.end.line, equals(1)); expect(span.end.column, equals(2)); - expect(span.start.sourceUrl, equals('source')); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); expect(span.text, equals('')); }); From 34d0e8f51aea32285dbae09cabdd44f0887844cd Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Wed, 29 Oct 2014 00:53:21 +0000 Subject: [PATCH 007/102] Add SpanScanner.location. Also explicitly expose FileSpans and FileLocations. R=rnystrom@google.com Review URL: https://codereview.chromium.org//683323002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/string_scanner@41383 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/string_scanner/CHANGELOG.md | 9 +++++++++ pkgs/string_scanner/lib/src/span_scanner.dart | 17 ++++++++++------- pkgs/string_scanner/pubspec.yaml | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index f1d876301..d7f09f303 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.1.1 + +* Declare `SpanScanner`'s exposed `SourceSpan`s and `SourceLocation`s to be + `FileSpan`s and `FileLocation`s. They always were underneath, but callers may + now rely on it. + +* Add `SpanScanner.location`, which returns the scanner's current + `SourceLocation`. + ## 0.1.0 * Switch from `source_maps`' `Span` class to `source_span`'s `SourceSpan` class. diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index d8dc230a8..a70d5fd74 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -34,28 +34,31 @@ class SpanScanner extends StringScanner implements LineScanner { this.position = state.position; } - /// The [SourceSpan] for [lastMatch]. + /// The [FileSpan] for [lastMatch]. /// /// This is the span for the entire match. There's no way to get spans for /// subgroups since [Match] exposes no information about their positions. - SourceSpan get lastSpan => _lastSpan; - SourceSpan _lastSpan; + FileSpan get lastSpan => _lastSpan; + FileSpan _lastSpan; + + /// The current location of the scanner. + FileLocation get location => _sourceFile.location(position); /// Returns an empty span at the current location. - SourceSpan get emptySpan => _sourceFile.location(position).pointSpan(); + FileSpan get emptySpan => location.pointSpan(); /// Creates a new [SpanScanner] that starts scanning from [position]. /// /// [sourceUrl] is used as [SourceLocation.sourceUrl] for the returned - /// [SourceSpan]s as well as for error reporting. It can be a [String], a + /// [FileSpan]s as well as for error reporting. It can be a [String], a /// [Uri], or `null`. SpanScanner(String string, {sourceUrl, int position}) : _sourceFile = new SourceFile(string, url: sourceUrl), super(string, sourceUrl: sourceUrl, position: position); - /// Creates a [SourceSpan] representing the source range between [startState] + /// Creates a [FileSpan] representing the source range between [startState] /// and the current position. - SourceSpan spanFrom(LineScannerState startState) => + FileSpan spanFrom(LineScannerState startState) => _sourceFile.span(startState.position, position); bool matches(Pattern pattern) { diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 1451fc518..831dfac9a 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 0.1.0 +version: 0.1.1 author: "Dart Team " homepage: http://www.dartlang.org description: > From f82411c45085fc1a177996299601fbec9e29586e Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Wed, 5 Nov 2014 23:41:30 +0000 Subject: [PATCH 008/102] Add StringScanner.substring. R=rnystrom@google.com Review URL: https://codereview.chromium.org//701723002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/string_scanner@41536 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/string_scanner/CHANGELOG.md | 4 +++ .../lib/src/string_scanner.dart | 9 ++++++ pkgs/string_scanner/pubspec.yaml | 2 +- .../test/string_scanner_test.dart | 28 +++++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index d7f09f303..d27374809 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.2 + +* Add `StringScanner.substring`, which returns a substring of the source string. + ## 0.1.1 * Declare `SpanScanner`'s exposed `SourceSpan`s and `SourceLocation`s to be diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 44d5d2d87..bc5e1f58d 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -131,6 +131,15 @@ class StringScanner { return _lastMatch != null; } + /// Returns the substring of [string] between [start] and [end]. + /// + /// Unlike [String.substring], [end] defaults to [position] rather than the + /// end of the string. + String substring(int start, [int end]) { + if (end == null) end = position; + return string.substring(start, end); + } + /// Throws a [FormatException] with [message] as well as a detailed /// description of the location of the error in the string. /// diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 831dfac9a..d14a43e2d 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 0.1.1 +version: 0.1.2 author: "Dart Team " homepage: http://www.dartlang.org description: > diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 6144bf9c0..fcd904aba 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -61,6 +61,10 @@ void main() { expect(scanner.position, equals(0)); }); + test("substring returns the empty string", () { + expect(scanner.substring(0), isEmpty); + }); + test('setting position to 1 throws an ArgumentError', () { expect(() { scanner.position = 1; @@ -165,6 +169,18 @@ void main() { expect(scanner.rest, equals('foo bar')); }); + test("substring from the beginning returns the empty string", () { + expect(scanner.substring(0), isEmpty); + }); + + test("substring with a custom end returns the substring", () { + expect(scanner.substring(0, 3), equals('foo')); + }); + + test("substring with the string length returns the whole string", () { + expect(scanner.substring(0, 7), equals('foo bar')); + }); + test('setting position to 1 moves the cursor forward', () { scanner.position = 1; expect(scanner.position, equals(1)); @@ -260,6 +276,18 @@ void main() { expect(scanner.position, equals(7)); }); + test("substring from the beginning returns the whole string", () { + expect(scanner.substring(0), equals('foo bar')); + }); + + test("substring with a custom start returns a substring from there", () { + expect(scanner.substring(4), equals('bar')); + }); + + test("substring with a custom start and end returns that substring", () { + expect(scanner.substring(3, 5), equals(' b')); + }); + test('setting position to 1 moves the cursor backward', () { scanner.position = 1; expect(scanner.position, equals(1)); From 62e2a3c6d759adbb62eff3479caf086aae88724e Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Fri, 12 Dec 2014 01:39:22 +0000 Subject: [PATCH 009/102] Add an additional optional argument to SpanScanner.spanFrom. R=rnystrom@google.com Review URL: https://codereview.chromium.org//795343003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/string_scanner@42305 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/string_scanner/CHANGELOG.md | 4 ++++ pkgs/string_scanner/lib/src/span_scanner.dart | 6 ++++-- pkgs/string_scanner/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index d27374809..9c03874dc 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.3 + +* Add an optional `endState` argument to `SpanScanner.spanFrom`. + ## 0.1.2 * Add `StringScanner.substring`, which returns a substring of the source string. diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index a70d5fd74..2a78b5bc0 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -58,8 +58,10 @@ class SpanScanner extends StringScanner implements LineScanner { /// Creates a [FileSpan] representing the source range between [startState] /// and the current position. - FileSpan spanFrom(LineScannerState startState) => - _sourceFile.span(startState.position, position); + FileSpan spanFrom(LineScannerState startState, [LineScannerState endState]) { + var endPosition = endState == null ? position : endState.position; + return _sourceFile.span(startState.position, endPosition); + } bool matches(Pattern pattern) { if (!super.matches(pattern)) { diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index d14a43e2d..da93ead05 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 0.1.2 +version: 0.1.3 author: "Dart Team " homepage: http://www.dartlang.org description: > From e3f991b872f093959c9610b32048528927615bd2 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 17 Dec 2014 16:56:21 -0800 Subject: [PATCH 010/102] Add gitignore, status, and codereview files. --- pkgs/string_scanner/.gitignore | 14 ++++++++++++++ pkgs/string_scanner/.status | 3 +++ pkgs/string_scanner/codereview.settings | 3 +++ 3 files changed, 20 insertions(+) create mode 100644 pkgs/string_scanner/.gitignore create mode 100644 pkgs/string_scanner/.status create mode 100644 pkgs/string_scanner/codereview.settings diff --git a/pkgs/string_scanner/.gitignore b/pkgs/string_scanner/.gitignore new file mode 100644 index 000000000..388eff0ba --- /dev/null +++ b/pkgs/string_scanner/.gitignore @@ -0,0 +1,14 @@ +# Don’t commit the following directories created by pub. +.buildlog +.pub/ +build/ +packages + +# Or the files created by dart2js. +*.dart.js +*.js_ +*.js.deps +*.js.map + +# Include when developing application packages. +pubspec.lock \ No newline at end of file diff --git a/pkgs/string_scanner/.status b/pkgs/string_scanner/.status new file mode 100644 index 000000000..e9f2b0049 --- /dev/null +++ b/pkgs/string_scanner/.status @@ -0,0 +1,3 @@ +# Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. diff --git a/pkgs/string_scanner/codereview.settings b/pkgs/string_scanner/codereview.settings new file mode 100644 index 000000000..31c557fbd --- /dev/null +++ b/pkgs/string_scanner/codereview.settings @@ -0,0 +1,3 @@ +CODE_REVIEW_SERVER: http://codereview.chromium.org/ +VIEW_VC: https://github.com/dart-lang/string_scanner/commit/ +CC_LIST: reviews@dartlang.org \ No newline at end of file From a2fc7783c71f0787657332da3eedee8a2660edb2 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 17 Dec 2014 16:56:34 -0800 Subject: [PATCH 011/102] Update the pubspec's homepage link. --- pkgs/string_scanner/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index da93ead05..2a712b8cc 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,7 +1,7 @@ name: string_scanner version: 0.1.3 author: "Dart Team " -homepage: http://www.dartlang.org +homepage: http://github.com/dart-lang/string_scanner description: > A class for parsing strings using a sequence of patterns. dependencies: From 4b44fc699fbc491bec33efa44da5fe1656a3cb55 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 30 Mar 2015 15:20:46 -0700 Subject: [PATCH 012/102] code format, expanded dependency constraint on unittest, removed unused variable fixed homepage URL R=nweiz@google.com Review URL: https://codereview.chromium.org//1045533002 --- pkgs/string_scanner/CHANGELOG.md | 4 ++++ pkgs/string_scanner/lib/src/line_scanner.dart | 9 ++++----- pkgs/string_scanner/lib/src/string_scanner.dart | 4 ++-- pkgs/string_scanner/lib/src/utils.dart | 2 +- pkgs/string_scanner/pubspec.yaml | 6 +++--- pkgs/string_scanner/test/error_test.dart | 15 +++++++++------ pkgs/string_scanner/test/string_scanner_test.dart | 4 ++-- 7 files changed, 25 insertions(+), 19 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 9c03874dc..ce1e01212 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.3+1 + +* Fixed the homepage URL. + ## 0.1.3 * Add an optional `endState` argument to `SpanScanner.spanFrom`. diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 4e1217305..54ecf7bf9 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -40,8 +40,8 @@ class LineScanner extends StringScanner { super.position = newPosition; if (newPosition > oldPosition) { - var newlines = "\n".allMatches(string.substring(oldPosition, newPosition)) - .toList(); + var newlines = + "\n".allMatches(string.substring(oldPosition, newPosition)).toList(); _line += newlines.length; if (newlines.isEmpty) { _column += newPosition - oldPosition; @@ -49,8 +49,8 @@ class LineScanner extends StringScanner { _column = newPosition - newlines.last.end; } } else { - var newlines = "\n".allMatches(string.substring(newPosition, oldPosition)) - .toList(); + var newlines = + "\n".allMatches(string.substring(newPosition, oldPosition)).toList(); _line -= newlines.length; if (newlines.isEmpty) { _column -= oldPosition - newPosition; @@ -75,7 +75,6 @@ class LineScanner extends StringScanner { } bool scan(Pattern pattern) { - var oldPosition = position; if (!super.scan(pattern)) return false; var newlines = "\n".allMatches(lastMatch[0]).toList(); diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index bc5e1f58d..d9c1c2fd3 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -107,8 +107,8 @@ class StringScanner { if (!_slashAutoEscape) source = source.replaceAll("/", "\\/"); name = "/$source/"; } else { - name = pattern.toString() - .replaceAll("\\", "\\\\").replaceAll('"', '\\"'); + name = + pattern.toString().replaceAll("\\", "\\\\").replaceAll('"', '\\"'); name = '"$name"'; } } diff --git a/pkgs/string_scanner/lib/src/utils.dart b/pkgs/string_scanner/lib/src/utils.dart index e556236e8..107c4c52e 100644 --- a/pkgs/string_scanner/lib/src/utils.dart +++ b/pkgs/string_scanner/lib/src/utils.dart @@ -27,4 +27,4 @@ void validateErrorArgs(String string, Match match, int position, int length) { throw new RangeError("position plus length must not go beyond the end of " "the string."); } -} \ No newline at end of file +} diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 2a712b8cc..ffd4ccc2a 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,13 +1,13 @@ name: string_scanner -version: 0.1.3 +version: 0.1.3+1 author: "Dart Team " -homepage: http://github.com/dart-lang/string_scanner +homepage: https://github.com/dart-lang/string_scanner description: > A class for parsing strings using a sequence of patterns. dependencies: path: ">=1.2.0 <2.0.0" source_span: ">=1.0.0 <2.0.0" dev_dependencies: - unittest: ">=0.10.0 <0.11.0" + unittest: ">=0.10.0 <0.12.0" environment: sdk: ">=1.2.0 <2.0.0" diff --git a/pkgs/string_scanner/test/error_test.dart b/pkgs/string_scanner/test/error_test.dart index 4fe9083df..d7b81e812 100644 --- a/pkgs/string_scanner/test/error_test.dart +++ b/pkgs/string_scanner/test/error_test.dart @@ -28,7 +28,8 @@ void main() { }); test('supports a match on a previous line', () { - var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + var scanner = + new StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo '); scanner.expect('re'); var match = scanner.lastMatch; @@ -38,7 +39,8 @@ void main() { }); test('supports a multiline match', () { - var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + var scanner = + new StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar '); scanner.expect('baz\ndo'); var match = scanner.lastMatch; @@ -81,14 +83,16 @@ void main() { }); test('supports a position on a previous line', () { - var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + var scanner = + new StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo re mi\nearth'); expect(() => scanner.error('oh no!', position: 15, length: 2), throwsStringScannerException('re')); }); test('supports a multiline length', () { - var scanner = new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + var scanner = + new StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo re mi\nearth'); expect(() => scanner.error('oh no!', position: 8, length: 8), throwsStringScannerException('baz\ndo r')); @@ -121,8 +125,7 @@ void main() { }); test("if match is passed with length", () { - expect( - () => scanner.error("oh no!", match: scanner.lastMatch, length: 1), + expect(() => scanner.error("oh no!", match: scanner.lastMatch, length: 1), throwsArgumentError); }); diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index fcd904aba..7b00796ce 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -330,8 +330,8 @@ void main() { }); test('throws an ArgumentError if the position is beyond the string', () { - expect(() => new StringScanner('foo bar', position: 8), - throwsArgumentError); + expect( + () => new StringScanner('foo bar', position: 8), throwsArgumentError); }); }); } From 2f43e83906900d652604b4d77d1a7a65e9f91177 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 16 Jul 2015 13:43:51 -0700 Subject: [PATCH 013/102] Upgrade to the new test runner. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1228353010 . --- pkgs/string_scanner/.gitignore | 1 + pkgs/string_scanner/.status | 3 --- pkgs/string_scanner/.test_config | 3 +++ pkgs/string_scanner/pubspec.yaml | 4 ++-- pkgs/string_scanner/test/error_test.dart | 2 +- pkgs/string_scanner/test/line_scanner_test.dart | 2 +- pkgs/string_scanner/test/span_scanner_test.dart | 2 +- pkgs/string_scanner/test/string_scanner_test.dart | 2 +- pkgs/string_scanner/test/utils.dart | 2 +- 9 files changed, 11 insertions(+), 10 deletions(-) delete mode 100644 pkgs/string_scanner/.status create mode 100644 pkgs/string_scanner/.test_config diff --git a/pkgs/string_scanner/.gitignore b/pkgs/string_scanner/.gitignore index 388eff0ba..7dbf0350d 100644 --- a/pkgs/string_scanner/.gitignore +++ b/pkgs/string_scanner/.gitignore @@ -3,6 +3,7 @@ .pub/ build/ packages +.packages # Or the files created by dart2js. *.dart.js diff --git a/pkgs/string_scanner/.status b/pkgs/string_scanner/.status deleted file mode 100644 index e9f2b0049..000000000 --- a/pkgs/string_scanner/.status +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file -# for details. All rights reserved. Use of this source code is governed by a -# BSD-style license that can be found in the LICENSE file. diff --git a/pkgs/string_scanner/.test_config b/pkgs/string_scanner/.test_config new file mode 100644 index 000000000..412fc5c5c --- /dev/null +++ b/pkgs/string_scanner/.test_config @@ -0,0 +1,3 @@ +{ + "test_package": true +} \ No newline at end of file diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index ffd4ccc2a..16477beeb 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 0.1.3+1 +version: 0.1.4-dev author: "Dart Team " homepage: https://github.com/dart-lang/string_scanner description: > @@ -8,6 +8,6 @@ dependencies: path: ">=1.2.0 <2.0.0" source_span: ">=1.0.0 <2.0.0" dev_dependencies: - unittest: ">=0.10.0 <0.12.0" + test: ">=0.12.0 <0.13.0" environment: sdk: ">=1.2.0 <2.0.0" diff --git a/pkgs/string_scanner/test/error_test.dart b/pkgs/string_scanner/test/error_test.dart index d7b81e812..9c485e559 100644 --- a/pkgs/string_scanner/test/error_test.dart +++ b/pkgs/string_scanner/test/error_test.dart @@ -5,7 +5,7 @@ library string_scanner.error_test; import 'package:string_scanner/string_scanner.dart'; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'utils.dart'; diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index 8cc79a65c..83222d6ce 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -5,7 +5,7 @@ library string_scanner.line_scanner_test; import 'package:string_scanner/string_scanner.dart'; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; void main() { var scanner; diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index 796df2968..a6249b719 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -5,7 +5,7 @@ library string_scanner.span_scanner_test; import 'package:string_scanner/string_scanner.dart'; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; void main() { var scanner; diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 7b00796ce..c8e43a5aa 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -5,7 +5,7 @@ library string_scanner.string_scanner_test; import 'package:string_scanner/string_scanner.dart'; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; void main() { group('with an empty string', () { diff --git a/pkgs/string_scanner/test/utils.dart b/pkgs/string_scanner/test/utils.dart index 3de601cf1..8df4b510f 100644 --- a/pkgs/string_scanner/test/utils.dart +++ b/pkgs/string_scanner/test/utils.dart @@ -5,7 +5,7 @@ library string_scanner.test.utils; import 'package:string_scanner/string_scanner.dart'; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; /// Returns a matcher that asserts that a closure throws a [FormatException] /// with the given [message]. From 8712d0807d6ba0f807a0c503ff7005a401529904 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 1 Sep 2015 17:11:08 -0700 Subject: [PATCH 014/102] Properly handle CR LF in LineScanner. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1327713003 . --- pkgs/string_scanner/CHANGELOG.md | 5 +++ pkgs/string_scanner/lib/src/line_scanner.dart | 32 +++++++++++--- pkgs/string_scanner/pubspec.yaml | 3 +- .../test/line_scanner_test.dart | 44 ++++++++++++++++--- 4 files changed, 69 insertions(+), 15 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index ce1e01212..ddfd54016 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.1.3+2 + +* Fix `LineScanner`'s handling of carriage returns to match that of + `SpanScanner`. + ## 0.1.3+1 * Fixed the homepage URL. diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 54ecf7bf9..6a2880b5e 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/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,7 @@ class LineScanner extends StringScanner { super.position = newPosition; if (newPosition > oldPosition) { - var newlines = - "\n".allMatches(string.substring(oldPosition, newPosition)).toList(); + var newlines = _newlinesIn(string.substring(oldPosition, newPosition)); _line += newlines.length; if (newlines.isEmpty) { _column += newPosition - oldPosition; @@ -49,13 +57,15 @@ class LineScanner extends StringScanner { _column = newPosition - newlines.last.end; } } else { - var newlines = - "\n".allMatches(string.substring(newPosition, oldPosition)).toList(); + var newlines = _newlinesIn(string.substring(newPosition, oldPosition)); + 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 +75,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 +87,7 @@ class LineScanner extends StringScanner { bool scan(Pattern pattern) { if (!super.scan(pattern)) return false; - var newlines = "\n".allMatches(lastMatch[0]).toList(); + var newlines = _newlinesIn(lastMatch[0]); _line += newlines.length; if (newlines.isEmpty) { _column += lastMatch[0].length; @@ -87,6 +97,14 @@ class LineScanner extends StringScanner { return true; } + + /// Returns a list of [Match]es describing all the newlines in [text], which + /// is assumed to end at [position]. + List _newlinesIn(String text) { + var newlines = _newlineRegExp.allMatches(text).toList(); + if (_betweenCRLF) newlines.removeLast(); + return newlines; + } } /// A class representing the state of a [LineScanner]. diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 16477beeb..efc7b0a36 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,10 +1,11 @@ name: string_scanner -version: 0.1.4-dev +version: 0.1.3+2 author: "Dart Team " homepage: https://github.com/dart-lang/string_scanner description: > A class for parsing strings using a sequence of patterns. dependencies: + charcode: "^1.1.0" path: ">=1.2.0 <2.0.0" source_span: ">=1.0.0 <2.0.0" dev_dependencies: diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index 83222d6ce..68e5c3814 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -10,7 +10,7 @@ import 'package:test/test.dart'; void main() { var scanner; setUp(() { - scanner = new LineScanner('foo\nbar\nbaz'); + scanner = new LineScanner('foo\nbar\r\nbaz'); }); test('begins with line and column 0', () { @@ -33,7 +33,17 @@ void main() { test("consuming multiple newlines resets the column and increases the line", () { - scanner.expect('foo\nbar\nb'); + scanner.expect('foo\nbar\r\nb'); + expect(scanner.line, equals(2)); + expect(scanner.column, equals(1)); + }); + + test("consuming halfway through a CR LF doesn't count as a line", () { + scanner.expect('foo\nbar\r'); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(4)); + + scanner.expect('\nb'); expect(scanner.line, equals(2)); expect(scanner.column, equals(1)); }); @@ -56,11 +66,25 @@ void main() { expect(scanner.line, equals(1)); expect(scanner.column, equals(0)); }); + + test("consuming halfway through a CR LF doesn't count as a line", () { + scanner.expect('foo\nbar'); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(3)); + + scanner.readChar(); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(4)); + + scanner.readChar(); + expect(scanner.line, equals(2)); + expect(scanner.column, equals(0)); + }); }); group("position=", () { test("forward through newlines sets the line and column", () { - scanner.position = 9; // "foo\nbar\nb" + scanner.position = 10; // "foo\nbar\r\nb" expect(scanner.line, equals(2)); expect(scanner.column, equals(1)); }); @@ -72,18 +96,24 @@ void main() { }); test("backward through newlines sets the line and column", () { - scanner.scan("foo\nbar\nbaz"); + scanner.scan("foo\nbar\r\nbaz"); scanner.position = 2; // "fo" expect(scanner.line, equals(0)); expect(scanner.column, equals(2)); }); test("backward through no newlines sets the column", () { - scanner.scan("foo\nbar\nbaz"); - scanner.position = 9; // "foo\nbar\nb" + scanner.scan("foo\nbar\r\nbaz"); + scanner.position = 10; // "foo\nbar\r\nb" expect(scanner.line, equals(2)); expect(scanner.column, equals(1)); }); + + test("forward halfway through a CR LF doesn't count as a line", () { + scanner.position = 8; // "foo\nbar\r" + expect(scanner.line, equals(1)); + expect(scanner.column, equals(4)); + }); }); test("state= restores the line, column, and position", () { @@ -92,7 +122,7 @@ void main() { scanner.scan('ar\nba'); scanner.state = state; - expect(scanner.rest, equals('ar\nbaz')); + expect(scanner.rest, equals('ar\r\nbaz')); expect(scanner.line, equals(1)); expect(scanner.column, equals(1)); }); From ab2cd25c257f8d32776f7f2d558aa978d1e7e535 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 1 Sep 2015 17:29:19 -0700 Subject: [PATCH 015/102] Increase the SDK constraint to allow ^ constraints. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1325943002 . --- pkgs/string_scanner/pubspec.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index efc7b0a36..3e71eb732 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -6,9 +6,9 @@ description: > A class for parsing strings using a sequence of patterns. dependencies: charcode: "^1.1.0" - path: ">=1.2.0 <2.0.0" - source_span: ">=1.0.0 <2.0.0" + path: "^1.2.0" + source_span: "^1.0.0" dev_dependencies: test: ">=0.12.0 <0.13.0" environment: - sdk: ">=1.2.0 <2.0.0" + sdk: ">=1.8.0 <2.0.0" From 5d9076bb8fe9abf76c0e24d4be157f919474a1ca Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 2 Sep 2015 11:45:35 -0700 Subject: [PATCH 016/102] Add new SpanScanner.eager(). This is more efficient for uses like the YAML parser, which uses the current line and especially column information frequently while parsing a file. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1318603008 . --- pkgs/string_scanner/CHANGELOG.md | 5 + .../lib/src/eager_span_scanner.dart | 115 ++++++++++++++++++ pkgs/string_scanner/lib/src/line_scanner.dart | 2 + pkgs/string_scanner/lib/src/span_scanner.dart | 15 +++ pkgs/string_scanner/pubspec.yaml | 2 +- .../test/span_scanner_test.dart | 84 +++++++------ 6 files changed, 185 insertions(+), 38 deletions(-) create mode 100644 pkgs/string_scanner/lib/src/eager_span_scanner.dart diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index ddfd54016..23f911c29 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.1.4 + +* Add `new SpanScanner.eager()` for creating a `SpanScanner` that eagerly + computes its current line and column numbers. + ## 0.1.3+2 * Fix `LineScanner`'s handling of carriage returns to match that of diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart new file mode 100644 index 000000000..3fae5cca7 --- /dev/null +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -0,0 +1,115 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library string_scanner.eager_span_scanner; + +import 'package:charcode/ascii.dart'; + +import 'line_scanner.dart'; +import 'span_scanner.dart'; + +// TODO(nweiz): Currently this duplicates code in line_scanner.dart. Once +// sdk#23770 is fully complete, we should move the shared code into a mixin. + +/// A regular expression matching newlines across platforms. +final _newlineRegExp = new RegExp(r"\r\n?|\n"); + +/// A [SpanScanner] that tracks the line and column eagerly, like [LineScanner]. +class EagerSpanScanner extends SpanScanner { + int get line => _line; + int _line = 0; + + int get column => _column; + int _column = 0; + + LineScannerState get state => + new _EagerSpanScannerState(this, position, line, column); + + bool get _betweenCRLF => peekChar(-1) == $cr && peekChar() == $lf; + + set state(LineScannerState state) { + if (state is! _EagerSpanScannerState || + !identical((state as _EagerSpanScannerState)._scanner, this)) { + throw new ArgumentError("The given LineScannerState was not returned by " + "this LineScanner."); + } + + super.position = state.position; + _line = state.line; + _column = state.column; + } + + set position(int newPosition) { + var oldPosition = position; + super.position = newPosition; + + if (newPosition > oldPosition) { + var newlines = _newlinesIn(string.substring(oldPosition, newPosition)); + _line += newlines.length; + if (newlines.isEmpty) { + _column += newPosition - oldPosition; + } else { + _column = newPosition - newlines.last.end; + } + } else { + var newlines = _newlinesIn(string.substring(newPosition, oldPosition)); + if (_betweenCRLF) newlines.removeLast(); + + _line -= newlines.length; + if (newlines.isEmpty) { + _column -= oldPosition - newPosition; + } else { + _column = newPosition - + string.lastIndexOf(_newlineRegExp, newPosition) - 1; + } + } + } + + EagerSpanScanner(String string, {sourceUrl, int position}) + : super(string, sourceUrl: sourceUrl, position: position); + + int readChar() { + var char = super.readChar(); + if (char == $lf || (char == $cr && peekChar() != $lf)) { + _line += 1; + _column = 0; + } else { + _column += 1; + } + return char; + } + + bool scan(Pattern pattern) { + if (!super.scan(pattern)) return false; + + var newlines = _newlinesIn(lastMatch[0]); + _line += newlines.length; + if (newlines.isEmpty) { + _column += lastMatch[0].length; + } else { + _column = lastMatch[0].length - newlines.last.end; + } + + return true; + } + + /// Returns a list of [Match]es describing all the newlines in [text], which + /// is assumed to end at [position]. + List _newlinesIn(String text) { + var newlines = _newlineRegExp.allMatches(text).toList(); + if (_betweenCRLF) newlines.removeLast(); + return newlines; + } +} + +/// A class representing the state of an [EagerSpanScanner]. +class _EagerSpanScannerState implements LineScannerState { + final EagerSpanScanner _scanner; + final int position; + final int line; + final int column; + + _EagerSpanScannerState(this._scanner, this.position, this.line, this.column); +} + diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 6a2880b5e..66d7575b2 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -8,6 +8,8 @@ import 'package:charcode/ascii.dart'; import 'string_scanner.dart'; +// Note that much of this code is duplicated in eager_span_scanner.dart. + /// A regular expression matching newlines across platforms. final _newlineRegExp = new RegExp(r"\r\n?|\n"); diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index 2a78b5bc0..ebe230d8a 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -6,6 +6,7 @@ library string_scanner.span_scanner; import 'package:source_span/source_span.dart'; +import 'eager_span_scanner.dart'; import 'exception.dart'; import 'line_scanner.dart'; import 'string_scanner.dart'; @@ -56,6 +57,20 @@ class SpanScanner extends StringScanner implements LineScanner { : _sourceFile = new SourceFile(string, url: sourceUrl), super(string, sourceUrl: sourceUrl, position: position); + /// Creates a new [SpanScanner] that eagerly computes line and column numbers. + /// + /// In general [new SpanScanner] will be more efficient, since it avoids extra + /// computation on every scan. However, eager scanning can be useful for + /// situations where the normal course of parsing frequently involves + /// accessing the current line and column numbers. + /// + /// Note that *only* the `line` and `column` fields on the `SpanScanner` + /// itself and its `LineScannerState` are eagerly computed. To limit their + /// memory footprint, returned spans and locations will still lazily compute + /// their line and column numbers. + factory SpanScanner.eager(String string, {sourceUrl, int position}) = + EagerSpanScanner; + /// Creates a [FileSpan] representing the source range between [startState] /// and the current position. FileSpan spanFrom(LineScannerState startState, [LineScannerState endState]) { diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 3e71eb732..35b3fe01d 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 0.1.3+2 +version: 0.1.4 author: "Dart Team " homepage: https://github.com/dart-lang/string_scanner description: > diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index a6249b719..114bff726 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -8,53 +8,63 @@ import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; void main() { - var scanner; - setUp(() { - scanner = new SpanScanner('foo\nbar\nbaz', sourceUrl: 'source'); + testForImplementation("lazy", () { + return new SpanScanner('foo\nbar\nbaz', sourceUrl: 'source'); }); - test("tracks the span for the last match", () { - scanner.scan('fo'); - scanner.scan('o\nba'); + testForImplementation("eager", () { + return new SpanScanner.eager('foo\nbar\nbaz', sourceUrl: 'source'); + }); +} - var span = scanner.lastSpan; - expect(span.start.offset, equals(2)); - expect(span.start.line, equals(0)); - expect(span.start.column, equals(2)); - expect(span.start.sourceUrl, equals(Uri.parse('source'))); +void testForImplementation(String name, SpanScanner create()) { + group("for a $name scanner", () { + var scanner; + setUp(() => scanner = create()); - expect(span.end.offset, equals(6)); - expect(span.end.line, equals(1)); - expect(span.end.column, equals(2)); - expect(span.start.sourceUrl, equals(Uri.parse('source'))); + test("tracks the span for the last match", () { + scanner.scan('fo'); + scanner.scan('o\nba'); - expect(span.text, equals('o\nba')); - }); + var span = scanner.lastSpan; + expect(span.start.offset, equals(2)); + expect(span.start.line, equals(0)); + expect(span.start.column, equals(2)); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); - test(".spanFrom() returns a span from a previous state", () { - scanner.scan('fo'); - var state = scanner.state; - scanner.scan('o\nba'); - scanner.scan('r\nba'); + expect(span.end.offset, equals(6)); + expect(span.end.line, equals(1)); + expect(span.end.column, equals(2)); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); - var span = scanner.spanFrom(state); - expect(span.text, equals('o\nbar\nba')); - }); + expect(span.text, equals('o\nba')); + }); + + test(".spanFrom() returns a span from a previous state", () { + scanner.scan('fo'); + var state = scanner.state; + scanner.scan('o\nba'); + scanner.scan('r\nba'); + + var span = scanner.spanFrom(state); + expect(span.text, equals('o\nbar\nba')); + }); - test(".emptySpan returns an empty span at the current location", () { - scanner.scan('foo\nba'); + test(".emptySpan returns an empty span at the current location", () { + scanner.scan('foo\nba'); - var span = scanner.emptySpan; - expect(span.start.offset, equals(6)); - expect(span.start.line, equals(1)); - expect(span.start.column, equals(2)); - expect(span.start.sourceUrl, equals(Uri.parse('source'))); + var span = scanner.emptySpan; + expect(span.start.offset, equals(6)); + expect(span.start.line, equals(1)); + expect(span.start.column, equals(2)); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); - expect(span.end.offset, equals(6)); - expect(span.end.line, equals(1)); - expect(span.end.column, equals(2)); - expect(span.start.sourceUrl, equals(Uri.parse('source'))); + expect(span.end.offset, equals(6)); + expect(span.end.line, equals(1)); + expect(span.end.column, equals(2)); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); - expect(span.text, equals('')); + expect(span.text, equals('')); + }); }); } From 9e8e6a46739815393bb3fcf73d1033bec47ffb3c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 12 Jan 2016 17:23:49 -0800 Subject: [PATCH 017/102] Get rid of all the library tags. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1580653005 . --- pkgs/string_scanner/lib/src/eager_span_scanner.dart | 2 -- pkgs/string_scanner/lib/src/exception.dart | 2 -- pkgs/string_scanner/lib/src/line_scanner.dart | 2 -- pkgs/string_scanner/lib/src/span_scanner.dart | 2 -- pkgs/string_scanner/lib/src/string_scanner.dart | 2 -- pkgs/string_scanner/lib/src/utils.dart | 2 -- pkgs/string_scanner/lib/string_scanner.dart | 2 -- pkgs/string_scanner/test/error_test.dart | 2 -- pkgs/string_scanner/test/line_scanner_test.dart | 2 -- pkgs/string_scanner/test/span_scanner_test.dart | 2 -- pkgs/string_scanner/test/string_scanner_test.dart | 2 -- pkgs/string_scanner/test/utils.dart | 2 -- 12 files changed, 24 deletions(-) diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index 3fae5cca7..c537b0cd6 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.eager_span_scanner; - import 'package:charcode/ascii.dart'; import 'line_scanner.dart'; diff --git a/pkgs/string_scanner/lib/src/exception.dart b/pkgs/string_scanner/lib/src/exception.dart index 50177d657..84bf5e861 100644 --- a/pkgs/string_scanner/lib/src/exception.dart +++ b/pkgs/string_scanner/lib/src/exception.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.exception; - import 'package:source_span/source_span.dart'; /// An exception thrown by a [StringScanner] that failed to parse a string. diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 66d7575b2..b4391934d 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.line_scanner; - import 'package:charcode/ascii.dart'; import 'string_scanner.dart'; diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index ebe230d8a..dd16e47cf 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.span_scanner; - import 'package:source_span/source_span.dart'; import 'eager_span_scanner.dart'; diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index d9c1c2fd3..775dd5e1c 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.string_scanner; - import 'package:source_span/source_span.dart'; import 'exception.dart'; diff --git a/pkgs/string_scanner/lib/src/utils.dart b/pkgs/string_scanner/lib/src/utils.dart index 107c4c52e..aa3e95736 100644 --- a/pkgs/string_scanner/lib/src/utils.dart +++ b/pkgs/string_scanner/lib/src/utils.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.utils; - /// Validates the arguments passed to [StringScanner.error]. void validateErrorArgs(String string, Match match, int position, int length) { if (match != null && (position != null || length != null)) { diff --git a/pkgs/string_scanner/lib/string_scanner.dart b/pkgs/string_scanner/lib/string_scanner.dart index be294f4f6..7f36eef83 100644 --- a/pkgs/string_scanner/lib/string_scanner.dart +++ b/pkgs/string_scanner/lib/string_scanner.dart @@ -3,8 +3,6 @@ // BSD-style license that can be found in the LICENSE file. /// A library for parsing strings using a sequence of patterns. -library string_scanner; - export 'src/exception.dart'; export 'src/line_scanner.dart'; export 'src/span_scanner.dart'; diff --git a/pkgs/string_scanner/test/error_test.dart b/pkgs/string_scanner/test/error_test.dart index 9c485e559..ff451940e 100644 --- a/pkgs/string_scanner/test/error_test.dart +++ b/pkgs/string_scanner/test/error_test.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.error_test; - import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index 68e5c3814..9874cb309 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.line_scanner_test; - import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index 114bff726..b078f6e1a 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.span_scanner_test; - import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index c8e43a5aa..10e622a82 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.string_scanner_test; - import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; diff --git a/pkgs/string_scanner/test/utils.dart b/pkgs/string_scanner/test/utils.dart index 8df4b510f..471b4c823 100644 --- a/pkgs/string_scanner/test/utils.dart +++ b/pkgs/string_scanner/test/utils.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library string_scanner.test.utils; - import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; From aadec1ad0401036056533506ea730b5f7b683eaf Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 14 Jan 2016 16:29:22 -0800 Subject: [PATCH 018/102] Remove the dependency on "path". We never imported this, so it's not clear why the dependency was even added. Closes dart-lang/string_scanner#2 R=rnystrom@google.com Review URL: https://codereview.chromium.org//1589013004 . --- pkgs/string_scanner/CHANGELOG.md | 4 ++++ pkgs/string_scanner/pubspec.yaml | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 23f911c29..a5650cc99 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.4+1 + +* Remove the dependency on `path`, since we don't actually import it. + ## 0.1.4 * Add `new SpanScanner.eager()` for creating a `SpanScanner` that eagerly diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 35b3fe01d..b249240c8 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,12 +1,11 @@ name: string_scanner -version: 0.1.4 +version: 0.1.4+1 author: "Dart Team " homepage: https://github.com/dart-lang/string_scanner description: > A class for parsing strings using a sequence of patterns. dependencies: charcode: "^1.1.0" - path: "^1.2.0" source_span: "^1.0.0" dev_dependencies: test: ">=0.12.0 <0.13.0" From 5a2ea3e875dcd13800c32f00c0cc17d031f53e5c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 31 Mar 2016 17:22:08 -0700 Subject: [PATCH 019/102] Declare this package strong-mode clean. R=tjblasi@google.com Review URL: https://codereview.chromium.org//1840423003 . --- pkgs/string_scanner/.analysis_options | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 pkgs/string_scanner/.analysis_options diff --git a/pkgs/string_scanner/.analysis_options b/pkgs/string_scanner/.analysis_options new file mode 100644 index 000000000..a10d4c5a0 --- /dev/null +++ b/pkgs/string_scanner/.analysis_options @@ -0,0 +1,2 @@ +analyzer: + strong-mode: true From 0ccf8a08e277a1889de14a0dadbfc20942f41d9f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 6 Jun 2016 16:22:28 -0700 Subject: [PATCH 020/102] Add SpanScanner.within(). This is useful for doing more detailed parses of sub-sections of larger text. R=rnystrom@google.com Review URL: https://codereview.chromium.org//2039163002 . --- pkgs/string_scanner/CHANGELOG.md | 4 + .../lib/src/relative_span_scanner.dart | 112 ++++++++++++++++++ pkgs/string_scanner/lib/src/span_scanner.dart | 9 ++ pkgs/string_scanner/pubspec.yaml | 2 +- .../test/span_scanner_test.dart | 88 ++++++++++++++ 5 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 pkgs/string_scanner/lib/src/relative_span_scanner.dart diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index a5650cc99..ea1268c1e 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.5 + +* Add `new SpanScanner.within()`, which scans within a existing `FileSpan`. + ## 0.1.4+1 * Remove the dependency on `path`, since we don't actually import it. diff --git a/pkgs/string_scanner/lib/src/relative_span_scanner.dart b/pkgs/string_scanner/lib/src/relative_span_scanner.dart new file mode 100644 index 000000000..fdcd03fba --- /dev/null +++ b/pkgs/string_scanner/lib/src/relative_span_scanner.dart @@ -0,0 +1,112 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:source_span/source_span.dart'; + +import 'exception.dart'; +import 'line_scanner.dart'; +import 'span_scanner.dart'; +import 'string_scanner.dart'; +import 'utils.dart'; + +/// A [SpanScanner] that scans within an existing [FileSpan]. +/// +/// This re-implements chunks of [SpanScanner] rather than using a dummy span or +/// inheritance because scanning is often a performance-critical operation, so +/// it's important to avoid adding extra overhead when relative scanning isn't +/// needed. +class RelativeSpanScanner extends StringScanner implements SpanScanner { + /// The source of the scanner. + /// + /// This caches line break information and is used to generate [Span]s. + final SourceFile _sourceFile; + + /// The start location of the span within which this scanner is scanning. + /// + /// This is used to convert between span-relative and file-relative fields. + final FileLocation _startLocation; + + int get line => _sourceFile.getLine(_startLocation.offset + position) - + _startLocation.line; + + int get column { + var line = _sourceFile.getLine(_startLocation.offset + position); + var column = _sourceFile.getColumn(_startLocation.offset + position, + line: line); + return line == _startLocation.line + ? column - _startLocation.column + : column; + } + + LineScannerState get state => new _SpanScannerState(this, position); + + set state(LineScannerState state) { + if (state is! _SpanScannerState || + !identical((state as _SpanScannerState)._scanner, this)) { + throw new ArgumentError("The given LineScannerState was not returned by " + "this LineScanner."); + } + + this.position = state.position; + } + + FileSpan get lastSpan => _lastSpan; + FileSpan _lastSpan; + + FileLocation get location => + _sourceFile.location(_startLocation.offset + position); + + FileSpan get emptySpan => location.pointSpan(); + + RelativeSpanScanner(FileSpan span) + : _sourceFile = span.file, + _startLocation = span.start, + super(span.text, sourceUrl: span.sourceUrl); + + FileSpan spanFrom(LineScannerState startState, [LineScannerState endState]) { + var endPosition = endState == null ? position : endState.position; + return _sourceFile.span( + _startLocation.offset + startState.position, + _startLocation.offset + endPosition); + } + + bool matches(Pattern pattern) { + if (!super.matches(pattern)) { + _lastSpan = null; + return false; + } + + _lastSpan = _sourceFile.span( + _startLocation.offset + position, + _startLocation.offset + lastMatch.end); + return true; + } + + void error(String message, {Match match, int position, int length}) { + validateErrorArgs(string, match, position, length); + + if (match == null && position == null && length == null) match = lastMatch; + if (position == null) { + position = match == null ? this.position : match.start; + } + if (length == null) length = match == null ? 1 : match.end - match.start; + + var span = _sourceFile.span( + _startLocation.offset + position, + _startLocation.offset + position + length); + throw new StringScannerException(message, span, string); + } +} + +/// A class representing the state of a [SpanScanner]. +class _SpanScannerState implements LineScannerState { + /// The [SpanScanner] that created this. + final RelativeSpanScanner _scanner; + + final int position; + int get line => _scanner._sourceFile.getLine(position); + int get column => _scanner._sourceFile.getColumn(position); + + _SpanScannerState(this._scanner, this.position); +} diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index dd16e47cf..dd7f0e4f2 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -7,6 +7,7 @@ import 'package:source_span/source_span.dart'; import 'eager_span_scanner.dart'; import 'exception.dart'; import 'line_scanner.dart'; +import 'relative_span_scanner.dart'; import 'string_scanner.dart'; import 'utils.dart'; @@ -69,6 +70,14 @@ class SpanScanner extends StringScanner implements LineScanner { factory SpanScanner.eager(String string, {sourceUrl, int position}) = EagerSpanScanner; + /// Creates a new [SpanScanner] that scans within [span]. + /// + /// This scans through [span.text], but emits new spans from [span.file] in + /// their appropriate relative positions. The [string] field contains only + /// [span.text], and [position], [line], and [column] are all relative to the + /// span. + factory SpanScanner.within(FileSpan span) = RelativeSpanScanner; + /// Creates a [FileSpan] representing the source range between [startState] /// and the current position. FileSpan spanFrom(LineScannerState startState, [LineScannerState endState]) { diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index b249240c8..24bd6bb12 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 0.1.4+1 +version: 0.1.5-dev author: "Dart Team " homepage: https://github.com/dart-lang/string_scanner description: > diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index b078f6e1a..84d7b94ee 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -2,9 +2,12 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:source_span/source_span.dart'; import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; +import 'utils.dart'; + void main() { testForImplementation("lazy", () { return new SpanScanner('foo\nbar\nbaz', sourceUrl: 'source'); @@ -13,6 +16,91 @@ void main() { testForImplementation("eager", () { return new SpanScanner.eager('foo\nbar\nbaz', sourceUrl: 'source'); }); + + group("within", () { + var text = 'first\nbefore: foo\nbar\nbaz :after\nlast'; + var startOffset = text.indexOf('foo'); + + var scanner; + setUp(() { + var file = new SourceFile(text, url: 'source'); + scanner = new SpanScanner.within( + file.span(startOffset, text.indexOf(' :after'))); + }); + + test("string only includes the span text", () { + expect(scanner.string, equals("foo\nbar\nbaz")); + }); + + test("line and column are span-relative", () { + expect(scanner.line, equals(0)); + expect(scanner.column, equals(0)); + + scanner.scan("foo"); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(3)); + + scanner.scan("\n"); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(0)); + }); + + test("tracks the span for the last match", () { + scanner.scan('fo'); + scanner.scan('o\nba'); + + var span = scanner.lastSpan; + expect(span.start.offset, equals(startOffset + 2)); + expect(span.start.line, equals(1)); + expect(span.start.column, equals(10)); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); + + expect(span.end.offset, equals(startOffset + 6)); + expect(span.end.line, equals(2)); + expect(span.end.column, equals(2)); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); + + expect(span.text, equals('o\nba')); + }); + + test(".spanFrom() returns a span from a previous state", () { + scanner.scan('fo'); + var state = scanner.state; + scanner.scan('o\nba'); + scanner.scan('r\nba'); + + var span = scanner.spanFrom(state); + expect(span.text, equals('o\nbar\nba')); + }); + + test(".emptySpan returns an empty span at the current location", () { + scanner.scan('foo\nba'); + + var span = scanner.emptySpan; + expect(span.start.offset, equals(startOffset + 6)); + expect(span.start.line, equals(2)); + expect(span.start.column, equals(2)); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); + + expect(span.end.offset, equals(startOffset + 6)); + expect(span.end.line, equals(2)); + expect(span.end.column, equals(2)); + expect(span.start.sourceUrl, equals(Uri.parse('source'))); + + expect(span.text, equals('')); + }); + + test(".error() uses an absolute span", () { + scanner.expect("foo"); + expect(() => scanner.error('oh no!'), + throwsStringScannerException("foo")); + }); + + test(".isDone returns true at the end of the span", () { + scanner.expect("foo\nbar\nbaz"); + expect(scanner.isDone, isTrue); + }); + }); } void testForImplementation(String name, SpanScanner create()) { From 1518a7a312dc0c63043ccef9767e38f1cf7e2e32 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 6 Jun 2016 16:52:04 -0700 Subject: [PATCH 021/102] Add StringScanner.scanChar() and .expectChar(). R=jmesserly@google.com Review URL: https://codereview.chromium.org//2041813002 . --- pkgs/string_scanner/CHANGELOG.md | 2 + .../lib/src/eager_span_scanner.dart | 17 +++++-- pkgs/string_scanner/lib/src/line_scanner.dart | 17 +++++-- .../lib/src/string_scanner.dart | 33 +++++++++++++ pkgs/string_scanner/pubspec.yaml | 2 +- .../test/line_scanner_test.dart | 34 +++++++++++++ .../test/string_scanner_test.dart | 49 +++++++++++++++++++ 7 files changed, 147 insertions(+), 7 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index ea1268c1e..db7368619 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -2,6 +2,8 @@ * Add `new SpanScanner.within()`, which scans within a existing `FileSpan`. +* Add `StringScanner.scanChar()` and `StringScanner.expectChar()`. + ## 0.1.4+1 * Remove the dependency on `path`, since we don't actually import it. diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index c537b0cd6..f80dce5c3 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -67,15 +67,26 @@ class EagerSpanScanner extends SpanScanner { EagerSpanScanner(String string, {sourceUrl, int position}) : super(string, sourceUrl: sourceUrl, position: position); + bool scanChar(int character) { + if (!super.scanChar(character)) return false; + _adjustLineAndColumn(character); + return true; + } + int readChar() { - var char = super.readChar(); - if (char == $lf || (char == $cr && peekChar() != $lf)) { + var character = super.readChar(); + _adjustLineAndColumn(character); + return character; + } + + /// Adjusts [_line] and [_column] after having consumed [character]. + void _adjustLineAndColumn(int character) { + if (character == $lf || (character == $cr && peekChar() != $lf)) { _line += 1; _column = 0; } else { _column += 1; } - return char; } bool scan(Pattern pattern) { diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index b4391934d..fe6359212 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -73,15 +73,26 @@ class LineScanner extends StringScanner { LineScanner(String string, {sourceUrl, int position}) : super(string, sourceUrl: sourceUrl, position: position); + bool scanChar(int character) { + if (!super.scanChar(character)) return false; + _adjustLineAndColumn(character); + return true; + } + int readChar() { - var char = super.readChar(); - if (char == $lf || (char == $cr && peekChar() != $lf)) { + var character = super.readChar(); + _adjustLineAndColumn(character); + return character; + } + + /// Adjusts [_line] and [_column] after having consumed [character]. + void _adjustLineAndColumn(int character) { + if (character == $lf || (character == $cr && peekChar() != $lf)) { _line += 1; _column = 0; } else { _column += 1; } - return char; } bool scan(Pattern pattern) { diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 775dd5e1c..8334ccb3e 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -2,6 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:charcode/charcode.dart'; import 'package:source_span/source_span.dart'; import 'exception.dart'; @@ -79,6 +80,38 @@ class StringScanner { return string.codeUnitAt(index); } + /// If the next character in the string is [character], consumes it. + /// + /// Returns whether or not [character] was consumed. + bool scanChar(int character) { + if (isDone) return false; + if (string.codeUnitAt(_position) != character) return false; + _position++; + return true; + } + + /// If the next character in the string is [character], consumes it. + /// + /// If [character] could not be consumed, throws a [FormatException] + /// describing the position of the failure. [name] is used in this error as + /// the expected name of the character being matched; if it's `null`, the + /// character itself is used instead. + void expectChar(int character, {String name}) { + if (scanChar(character)) return; + + if (name == null) { + if (character == $backslash) { + name = r'"\"'; + } else if (character == $double_quote) { + name = r'"\""'; + } else { + name = '"${new String.fromCharCode(character)}"'; + } + } + + _fail('Expected $name.'); + } + /// If [pattern] matches at the current position of the string, scans forward /// until the end of the match. /// diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 24bd6bb12..7f7e33a30 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 0.1.5-dev +version: 0.1.5 author: "Dart Team " homepage: https://github.com/dart-lang/string_scanner description: > diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index 9874cb309..ed04b371c 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -2,6 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:charcode/charcode.dart'; import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; @@ -80,6 +81,39 @@ void main() { }); }); + group("scanChar()", () { + test("on a non-newline character increases the column but not the line", + () { + scanner.scanChar($f); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(1)); + }); + + test("consuming a newline resets the column and increases the line", () { + scanner.expect('foo'); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(3)); + + scanner.scanChar($lf); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(0)); + }); + + test("consuming halfway through a CR LF doesn't count as a line", () { + scanner.expect('foo\nbar'); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(3)); + + scanner.scanChar($cr); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(4)); + + scanner.scanChar($lf); + expect(scanner.line, equals(2)); + expect(scanner.column, equals(0)); + }); + }); + group("position=", () { test("forward through newlines sets the line and column", () { scanner.position = 10; // "foo\nbar\r\nb" diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 10e622a82..0b4d4824f 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -2,6 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:charcode/charcode.dart'; import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; @@ -41,6 +42,18 @@ void main() { expect(scanner.position, equals(0)); }); + test("scanChar returns false and doesn't change the state", () { + expect(scanner.scanChar($f), isFalse); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + + test("expectChar fails and doesn't change the state", () { + expect(() => scanner.expectChar($f), throwsFormatException); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + test("scan returns false and doesn't change the state", () { expect(scanner.scan(new RegExp('.')), isFalse); expect(scanner.lastMatch, isNull); @@ -117,6 +130,30 @@ void main() { expect(scanner.position, equals(0)); }); + test("a matching scanChar returns true moves forward", () { + expect(scanner.scanChar($f), isTrue); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(1)); + }); + + test("a non-matching scanChar returns false and does nothing", () { + expect(scanner.scanChar($x), isFalse); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + + test("a matching expectChar moves forward", () { + scanner.expectChar($f); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(1)); + }); + + test("a non-matching expectChar fails", () { + expect(() => scanner.expectChar($x), throwsFormatException); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + test("a matching scan returns true and changes the state", () { expect(scanner.scan(new RegExp('f(..)')), isTrue); expect(scanner.lastMatch[1], equals('oo')); @@ -256,6 +293,18 @@ void main() { expect(scanner.position, equals(7)); }); + test("scanChar returns false and doesn't change the state", () { + expect(scanner.scanChar($f), isFalse); + expect(scanner.lastMatch, isNotNull); + expect(scanner.position, equals(7)); + }); + + test("expectChar fails and doesn't change the state", () { + expect(() => scanner.expectChar($f), throwsFormatException); + expect(scanner.lastMatch, isNotNull); + expect(scanner.position, equals(7)); + }); + test("scan returns false and sets lastMatch to null", () { expect(scanner.scan(new RegExp('.')), isFalse); expect(scanner.lastMatch, isNull); From 579891ad3abfa2f54797d83fcb5e855fdecc46a0 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 14 Jun 2016 16:21:23 -0700 Subject: [PATCH 022/102] Add breaking changes and release 1.0.0. This makes `.error()` default to empty spans rather than single-character ones. This better represents the semantics of failing at a particular position in the text. It also makes `lastMatch` reset whenever the scanner's position changes. This makes `.error()` behave more consistently when primarily doing character-based scanning, since it won't unexpectedly emit an error for stale match data. R=jmesserly@google.com Review URL: https://codereview.chromium.org//2056933002 . --- pkgs/string_scanner/CHANGELOG.md | 13 ++++++++ pkgs/string_scanner/lib/src/line_scanner.dart | 2 ++ pkgs/string_scanner/lib/src/span_scanner.dart | 7 ++-- .../lib/src/string_scanner.dart | 19 ++++++++--- pkgs/string_scanner/pubspec.yaml | 2 +- pkgs/string_scanner/test/error_test.dart | 4 +-- .../test/string_scanner_test.dart | 33 +++++++++++++++++++ 7 files changed, 71 insertions(+), 9 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index db7368619..910d30ebc 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,16 @@ +## 1.0.0 + +* **Breaking change**: `StringScanner.error()`'s `length` argument now defaults + to `0` rather than `1` when no match data is available. + +* **Breaking change**: `StringScanner.lastMatch` and related methods are now + reset when the scanner's position changes without producing a new match. + +**Note**: While the changes in `1.0.0` are user-visible, they're unlikely to +actually break any code in practice. Unless you know that your package is +incompatible with 0.1.x, consider using 0.1.5 as your lower bound rather +than 1.0.0. For example, `string_scanner: ">=0.1.5 <2.0.0"`. + ## 0.1.5 * Add `new SpanScanner.within()`, which scans within a existing `FileSpan`. diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index fe6359212..06f1cbc1e 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -26,6 +26,8 @@ class LineScanner extends StringScanner { /// This can be used to efficiently save and restore the state of the scanner /// when backtracking. A given [LineScannerState] is only valid for the /// [LineScanner] that created it. + /// + /// This does not include the scanner's match information. LineScannerState get state => new LineScannerState._(this, position, line, column); diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index dd7f0e4f2..043021b4d 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -38,7 +38,10 @@ class SpanScanner extends StringScanner implements LineScanner { /// /// This is the span for the entire match. There's no way to get spans for /// subgroups since [Match] exposes no information about their positions. - FileSpan get lastSpan => _lastSpan; + FileSpan get lastSpan { + if (lastMatch == null) _lastSpan = null; + return _lastSpan; + } FileSpan _lastSpan; /// The current location of the scanner. @@ -102,7 +105,7 @@ class SpanScanner extends StringScanner implements LineScanner { 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 span = _sourceFile.span(position, position + length); throw new StringScannerException(message, span, string); diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 8334ccb3e..b9714ff68 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/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); diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 7f7e33a30..48ed59dbc 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 0.1.5 +version: 1.0.0 author: "Dart Team " homepage: https://github.com/dart-lang/string_scanner description: > diff --git a/pkgs/string_scanner/test/error_test.dart b/pkgs/string_scanner/test/error_test.dart index ff451940e..166077d5e 100644 --- a/pkgs/string_scanner/test/error_test.dart +++ b/pkgs/string_scanner/test/error_test.dart @@ -59,11 +59,11 @@ void main() { }); group("with position and/or length", () { - test('defaults to length 1', () { + test('defaults to length 0', () { var scanner = new StringScanner('foo bar baz'); scanner.expect('foo '); expect(() => scanner.error('oh no!', position: 1), - throwsStringScannerException('o')); + throwsStringScannerException('')); }); test('defaults to the current position', () { diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 0b4d4824f..55ffa0a9f 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -261,6 +261,32 @@ void main() { }); }); + group('after a scan', () { + var scanner; + setUp(() { + scanner = new StringScanner('foo bar'); + expect(scanner.scan('foo'), isTrue); + }); + + test('readChar returns the first character and unsets the last match', () { + expect(scanner.readChar(), equals($space)); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(4)); + }); + + test('a matching scanChar returns true and unsets the last match', () { + expect(scanner.scanChar($space), isTrue); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(4)); + }); + + test('a matching expectChar returns true and unsets the last match', () { + scanner.expectChar($space); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(4)); + }); + }); + group('at the end of a string', () { var scanner; setUp(() { @@ -346,6 +372,13 @@ void main() { expect(scanner.rest, equals('bar')); }); + test('setting and resetting position clears lastMatch', () { + var oldPosition = scanner.position; + scanner.position = 1; + scanner.position = oldPosition; + expect(scanner.lastMatch, isNull); + }); + test('setting position beyond the string throws an ArgumentError', () { expect(() { scanner.position = 8; From 553513c30fac4d98e1e1c4619d5902e4eaeb498a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 2 Nov 2016 15:11:53 -0700 Subject: [PATCH 023/102] Fix the expectChar() error text. (dart-lang/string_scanner#3) --- pkgs/string_scanner/CHANGELOG.md | 4 ++++ pkgs/string_scanner/lib/src/string_scanner.dart | 2 +- pkgs/string_scanner/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 910d30ebc..fa4cb6e43 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.1 + +* Fix the error text emitted by `StringScanner.expectChar()`. + ## 1.0.0 * **Breaking change**: `StringScanner.error()`'s `length` argument now defaults diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index b9714ff68..5817d562f 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -116,7 +116,7 @@ class StringScanner { } } - _fail('Expected $name.'); + _fail(name); } /// If [pattern] matches at the current position of the string, scans forward diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 48ed59dbc..ac893e26d 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.0.0 +version: 1.0.1 author: "Dart Team " homepage: https://github.com/dart-lang/string_scanner description: > From d8016d4a42fd2bcde4b301f97bb2f6229c1d64bc Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 22 May 2017 12:50:06 -0700 Subject: [PATCH 024/102] Don't crash on surrogate pairs. (dart-lang/string_scanner#5) Closes dart-lang/string_scanner#4 --- pkgs/string_scanner/CHANGELOG.md | 5 +++++ pkgs/string_scanner/lib/src/span_scanner.dart | 2 +- .../lib/src/string_scanner.dart | 2 +- pkgs/string_scanner/pubspec.yaml | 4 ++-- .../test/span_scanner_test.dart | 20 ++++++++++++++----- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index fa4cb6e43..83ca15b3f 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.0.2 + +* `SpanScanner` no longer crashes when creating a span that contains a UTF-16 + surrogate pair. + ## 1.0.1 * Fix the error text emitted by `StringScanner.expectChar()`. diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index 043021b4d..f362223b2 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -56,7 +56,7 @@ class SpanScanner extends StringScanner implements LineScanner { /// [FileSpan]s as well as for error reporting. It can be a [String], a /// [Uri], or `null`. SpanScanner(String string, {sourceUrl, int position}) - : _sourceFile = new SourceFile(string, url: sourceUrl), + : _sourceFile = new SourceFile.fromString(string, url: sourceUrl), super(string, sourceUrl: sourceUrl, position: position); /// Creates a new [SpanScanner] that eagerly computes line and column numbers. diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 5817d562f..712292c60 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -204,7 +204,7 @@ class StringScanner { } if (length == null) length = match == null ? 0 : match.end - match.start; - var sourceFile = new SourceFile(string, url: sourceUrl); + var sourceFile = new SourceFile.fromString(string, url: sourceUrl); var span = sourceFile.span(position, position + length); throw new StringScannerException(message, span, string); } diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index ac893e26d..f0862eeb9 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,12 +1,12 @@ name: string_scanner -version: 1.0.1 +version: 1.0.2 author: "Dart Team " homepage: https://github.com/dart-lang/string_scanner description: > A class for parsing strings using a sequence of patterns. dependencies: charcode: "^1.1.0" - source_span: "^1.0.0" + source_span: "^1.4.0" dev_dependencies: test: ">=0.12.0 <0.13.0" environment: diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index 84d7b94ee..ab3cc8087 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -9,12 +9,13 @@ import 'package:test/test.dart'; import 'utils.dart'; void main() { - testForImplementation("lazy", () { - return new SpanScanner('foo\nbar\nbaz', sourceUrl: 'source'); + testForImplementation("lazy", ([string]) { + return new SpanScanner(string ?? 'foo\nbar\nbaz', sourceUrl: 'source'); }); - testForImplementation("eager", () { - return new SpanScanner.eager('foo\nbar\nbaz', sourceUrl: 'source'); + testForImplementation("eager", ([string]) { + return new SpanScanner.eager(string ?? 'foo\nbar\nbaz', + sourceUrl: 'source'); }); group("within", () { @@ -23,7 +24,7 @@ void main() { var scanner; setUp(() { - var file = new SourceFile(text, url: 'source'); + var file = new SourceFile.fromString(text, url: 'source'); scanner = new SpanScanner.within( file.span(startOffset, text.indexOf(' :after'))); }); @@ -136,6 +137,15 @@ void testForImplementation(String name, SpanScanner create()) { expect(span.text, equals('o\nbar\nba')); }); + test(".spanFrom() handles surrogate pairs correctly", () { + scanner = create('fo\u{12345}o'); + scanner.scan('fo'); + var state = scanner.state; + scanner.scan('\u{12345}o'); + var span = scanner.spanFrom(state); + expect(span.text, equals('\u{12345}o')); + }); + test(".emptySpan returns an empty span at the current location", () { scanner.scan('foo\nba'); From e036c2eccec772079ad111b16a571a0648341162 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 1 Mar 2018 15:29:14 -0800 Subject: [PATCH 025/102] Enable Travis-CI (dart-lang/string_scanner#7) Fixes dart-lang/string_scanner#6 --- pkgs/string_scanner/.travis.yml | 24 +++++++++++++++++++ ...analysis_options => analysis_options.yaml} | 0 .../lib/src/eager_span_scanner.dart | 5 ++-- pkgs/string_scanner/lib/src/line_scanner.dart | 4 ++-- .../lib/src/relative_span_scanner.dart | 16 ++++++------- pkgs/string_scanner/lib/src/span_scanner.dart | 1 + .../lib/src/string_scanner.dart | 2 ++ .../test/span_scanner_test.dart | 10 ++++---- .../test/string_scanner_test.dart | 3 ++- 9 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 pkgs/string_scanner/.travis.yml rename pkgs/string_scanner/{.analysis_options => analysis_options.yaml} (100%) diff --git a/pkgs/string_scanner/.travis.yml b/pkgs/string_scanner/.travis.yml new file mode 100644 index 000000000..4496f3a4e --- /dev/null +++ b/pkgs/string_scanner/.travis.yml @@ -0,0 +1,24 @@ +language: dart + +dart: + - dev + - stable + +dart_task: + - test: --platform vm,chrome + +matrix: + include: + # Only validate formatting using the dev release + - dart: dev + dart_task: dartfmt + - dart: dev + dart_task: analyzer + +# Only building master means that we don't run two builds for each pull request. +branches: + only: [master] + +cache: + directories: + - $HOME/.pub-cache diff --git a/pkgs/string_scanner/.analysis_options b/pkgs/string_scanner/analysis_options.yaml similarity index 100% rename from pkgs/string_scanner/.analysis_options rename to pkgs/string_scanner/analysis_options.yaml diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index f80dce5c3..96c7362e0 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -58,8 +58,8 @@ class EagerSpanScanner extends SpanScanner { if (newlines.isEmpty) { _column -= oldPosition - newPosition; } else { - _column = newPosition - - string.lastIndexOf(_newlineRegExp, newPosition) - 1; + _column = + newPosition - string.lastIndexOf(_newlineRegExp, newPosition) - 1; } } } @@ -121,4 +121,3 @@ class _EagerSpanScannerState implements LineScannerState { _EagerSpanScannerState(this._scanner, this.position, this.line, this.column); } - diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 06f1cbc1e..518203530 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -66,8 +66,8 @@ class LineScanner extends StringScanner { if (newlines.isEmpty) { _column -= oldPosition - newPosition; } else { - _column = newPosition - - string.lastIndexOf(_newlineRegExp, newPosition) - 1; + _column = + newPosition - string.lastIndexOf(_newlineRegExp, newPosition) - 1; } } } diff --git a/pkgs/string_scanner/lib/src/relative_span_scanner.dart b/pkgs/string_scanner/lib/src/relative_span_scanner.dart index fdcd03fba..088ff481f 100644 --- a/pkgs/string_scanner/lib/src/relative_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/relative_span_scanner.dart @@ -27,13 +27,14 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { /// This is used to convert between span-relative and file-relative fields. final FileLocation _startLocation; - int get line => _sourceFile.getLine(_startLocation.offset + position) - + int get line => + _sourceFile.getLine(_startLocation.offset + position) - _startLocation.line; int get column { var line = _sourceFile.getLine(_startLocation.offset + position); - var column = _sourceFile.getColumn(_startLocation.offset + position, - line: line); + var column = + _sourceFile.getColumn(_startLocation.offset + position, line: line); return line == _startLocation.line ? column - _startLocation.column : column; @@ -66,8 +67,7 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { FileSpan spanFrom(LineScannerState startState, [LineScannerState endState]) { var endPosition = endState == null ? position : endState.position; - return _sourceFile.span( - _startLocation.offset + startState.position, + return _sourceFile.span(_startLocation.offset + startState.position, _startLocation.offset + endPosition); } @@ -77,8 +77,7 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { return false; } - _lastSpan = _sourceFile.span( - _startLocation.offset + position, + _lastSpan = _sourceFile.span(_startLocation.offset + position, _startLocation.offset + lastMatch.end); return true; } @@ -92,8 +91,7 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { } if (length == null) length = match == null ? 1 : match.end - match.start; - var span = _sourceFile.span( - _startLocation.offset + position, + var span = _sourceFile.span(_startLocation.offset + position, _startLocation.offset + position + length); throw new StringScannerException(message, span, string); } diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index f362223b2..a629f1327 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -42,6 +42,7 @@ class SpanScanner extends StringScanner implements LineScanner { if (lastMatch == null) _lastSpan = null; return _lastSpan; } + FileSpan _lastSpan; /// The current location of the scanner. diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 712292c60..ea3d6d60e 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -34,6 +34,7 @@ class StringScanner { _position = position; _lastMatch = null; } + int _position = 0; /// The data about the previous match made by the scanner. @@ -45,6 +46,7 @@ class StringScanner { if (_position != _lastMatchPosition) _lastMatch = null; return _lastMatch; } + Match _lastMatch; int _lastMatchPosition; diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index ab3cc8087..37a01e025 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -9,11 +9,11 @@ import 'package:test/test.dart'; import 'utils.dart'; void main() { - testForImplementation("lazy", ([string]) { + testForImplementation("lazy", ([String string]) { return new SpanScanner(string ?? 'foo\nbar\nbaz', sourceUrl: 'source'); }); - testForImplementation("eager", ([string]) { + testForImplementation("eager", ([String string]) { return new SpanScanner.eager(string ?? 'foo\nbar\nbaz', sourceUrl: 'source'); }); @@ -93,8 +93,8 @@ void main() { test(".error() uses an absolute span", () { scanner.expect("foo"); - expect(() => scanner.error('oh no!'), - throwsStringScannerException("foo")); + expect( + () => scanner.error('oh no!'), throwsStringScannerException("foo")); }); test(".isDone returns true at the end of the span", () { @@ -104,7 +104,7 @@ void main() { }); } -void testForImplementation(String name, SpanScanner create()) { +void testForImplementation(String name, SpanScanner create([String string])) { group("for a $name scanner", () { var scanner; setUp(() => scanner = create()); diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 55ffa0a9f..30711f5ae 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -178,7 +178,8 @@ void main() { expect(scanner.rest, equals(' bar')); }); - test("a non-matching expect throws a FormatException and sets lastMatch to " + test( + "a non-matching expect throws a FormatException and sets lastMatch to " "null", () { expect(scanner.matches(new RegExp('f(..)')), isTrue); expect(scanner.lastMatch, isNotNull); From c464dd53c907e288a7c11d725c5ccb2d46afaafd Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 18 Jul 2018 15:31:10 -0400 Subject: [PATCH 026/102] chore: set max SDK version to <3.0.0 (dart-lang/string_scanner#10) --- pkgs/string_scanner/CHANGELOG.md | 4 ++++ pkgs/string_scanner/analysis_options.yaml | 2 -- pkgs/string_scanner/pubspec.yaml | 22 +++++++++++++--------- pkgs/string_scanner/test/utils.dart | 1 + 4 files changed, 18 insertions(+), 11 deletions(-) delete mode 100644 pkgs/string_scanner/analysis_options.yaml diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 83ca15b3f..2909bea83 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.3 + +* Set max SDK version to `<3.0.0`, and adjust other dependencies. + ## 1.0.2 * `SpanScanner` no longer crashes when creating a span that contains a UTF-16 diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml deleted file mode 100644 index a10d4c5a0..000000000 --- a/pkgs/string_scanner/analysis_options.yaml +++ /dev/null @@ -1,2 +0,0 @@ -analyzer: - strong-mode: true diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index f0862eeb9..7c87a0d0a 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,13 +1,17 @@ name: string_scanner -version: 1.0.2 -author: "Dart Team " +version: 1.0.3 + +description: A class for parsing strings using a sequence of patterns. +author: Dart Team homepage: https://github.com/dart-lang/string_scanner -description: > - A class for parsing strings using a sequence of patterns. + +environment: + sdk: '>=1.8.0 <3.0.0' + dependencies: - charcode: "^1.1.0" - source_span: "^1.4.0" + charcode: ^1.1.0 + source_span: ^1.4.0 + dev_dependencies: - test: ">=0.12.0 <0.13.0" -environment: - sdk: ">=1.8.0 <2.0.0" + test: '>=0.12.0 <2.0.0' + diff --git a/pkgs/string_scanner/test/utils.dart b/pkgs/string_scanner/test/utils.dart index 471b4c823..7767fbc88 100644 --- a/pkgs/string_scanner/test/utils.dart +++ b/pkgs/string_scanner/test/utils.dart @@ -9,6 +9,7 @@ import 'package:test/test.dart'; /// with the given [message]. Matcher throwsStringScannerException(String text) { return throwsA(predicate((error) { + // ignore: deprecated_member_use expect(error, new isInstanceOf()); expect(error.span.text, equals(text)); return true; From aca34f65a3cd0623db9882251aff99f1e9653d03 Mon Sep 17 00:00:00 2001 From: Keerti Parthasarathy Date: Fri, 3 Aug 2018 13:56:30 -0700 Subject: [PATCH 027/102] Annotate method error with alwaysThrows annotation. (dart-lang/string_scanner#11) --- pkgs/string_scanner/CHANGELOG.md | 4 ++++ pkgs/string_scanner/lib/src/string_scanner.dart | 2 ++ pkgs/string_scanner/pubspec.yaml | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 2909bea83..3602fb326 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0 + +* Add @alwaysThrows annotation to error method. + ## 1.0.3 * Set max SDK version to `<3.0.0`, and adjust other dependencies. diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index ea3d6d60e..d32dc38ad 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:charcode/charcode.dart'; +import 'package:meta/meta.dart'; import 'package:source_span/source_span.dart'; import 'exception.dart'; @@ -197,6 +198,7 @@ class StringScanner { /// 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]. + @alwaysThrows void error(String message, {Match match, int position, int length}) { validateErrorArgs(string, match, position, length); diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 7c87a0d0a..769199054 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.0.3 +version: 1.0.4 description: A class for parsing strings using a sequence of patterns. author: Dart Team @@ -10,6 +10,7 @@ environment: dependencies: charcode: ^1.1.0 + meta: ^1.1.0 source_span: ^1.4.0 dev_dependencies: From bcf5a0aee713052206e0362d4742d2102c3c30e2 Mon Sep 17 00:00:00 2001 From: BC Ko Date: Mon, 13 Aug 2018 12:14:41 -0700 Subject: [PATCH 028/102] Update .gitignore to new `dart_tool` pub cache (dart-lang/string_scanner#8) RE dart-lang/sdkdart-lang/string_scanner#32030 --- pkgs/string_scanner/.gitignore | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/pkgs/string_scanner/.gitignore b/pkgs/string_scanner/.gitignore index 7dbf0350d..fb97bdebd 100644 --- a/pkgs/string_scanner/.gitignore +++ b/pkgs/string_scanner/.gitignore @@ -1,15 +1,5 @@ # Don’t commit the following directories created by pub. -.buildlog +.dart_tool/ .pub/ -build/ -packages .packages - -# Or the files created by dart2js. -*.dart.js -*.js_ -*.js.deps -*.js.map - -# Include when developing application packages. -pubspec.lock \ No newline at end of file +pubspec.lock From 15977bbbf14222f8263d7e3228e414d1f0799c07 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 13 Aug 2018 12:34:32 -0700 Subject: [PATCH 029/102] Fix changelog for release (dart-lang/string_scanner#13) Fixes https://github.com/dart-lang/string_scanner/issues/12 --- pkgs/string_scanner/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 3602fb326..43b94535a 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.1.0 +## 1.0.4 * Add @alwaysThrows annotation to error method. From af64d42ca8cd764c49dadc8c97e69a9750ec5a7f Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 6 May 2019 09:51:30 -0700 Subject: [PATCH 030/102] Enable and fix a number of lints, test on oldest supported SDK (dart-lang/string_scanner#15) Bump min SDK to Dart 2.0 --- pkgs/string_scanner/.travis.yml | 8 +- pkgs/string_scanner/CHANGELOG.md | 4 + pkgs/string_scanner/analysis_options.yaml | 93 +++++++++++++++++++ .../lib/src/eager_span_scanner.dart | 6 +- pkgs/string_scanner/lib/src/exception.dart | 2 + pkgs/string_scanner/lib/src/line_scanner.dart | 6 +- .../lib/src/relative_span_scanner.dart | 16 ++-- pkgs/string_scanner/lib/src/span_scanner.dart | 24 +++-- .../lib/src/string_scanner.dart | 22 ++--- pkgs/string_scanner/lib/src/utils.dart | 12 ++- pkgs/string_scanner/pubspec.yaml | 6 +- pkgs/string_scanner/test/error_test.dart | 32 +++---- .../test/line_scanner_test.dart | 6 +- .../test/span_scanner_test.dart | 18 ++-- .../test/string_scanner_test.dart | 62 ++++++------- pkgs/string_scanner/test/utils.dart | 15 +-- 16 files changed, 210 insertions(+), 122 deletions(-) create mode 100644 pkgs/string_scanner/analysis_options.yaml diff --git a/pkgs/string_scanner/.travis.yml b/pkgs/string_scanner/.travis.yml index 4496f3a4e..48e46ca18 100644 --- a/pkgs/string_scanner/.travis.yml +++ b/pkgs/string_scanner/.travis.yml @@ -2,7 +2,7 @@ language: dart dart: - dev - - stable + - 2.0.0 dart_task: - test: --platform vm,chrome @@ -13,7 +13,11 @@ matrix: - dart: dev dart_task: dartfmt - dart: dev - dart_task: analyzer + dart_task: + dartanalyzer: --fatal-warnings --fatal-hints . + - dart: 2.0.0 + dart_task: + dartanalyzer: --fatal-warnings . # Only building master means that we don't run two builds for each pull request. branches: diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 43b94535a..1fba528d3 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.5 + +- Update Dart SDK constraint to `>=2.0.0 <3.0.0`. + ## 1.0.4 * Add @alwaysThrows annotation to error method. diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml new file mode 100644 index 000000000..d5d521374 --- /dev/null +++ b/pkgs/string_scanner/analysis_options.yaml @@ -0,0 +1,93 @@ +include: package:pedantic/analysis_options.yaml +analyzer: +# strong-mode: +# implicit-casts: false +linter: + rules: + - always_declare_return_types + #- annotate_overrides + - avoid_bool_literals_in_conditional_expressions + - avoid_classes_with_only_static_members + - avoid_empty_else + - avoid_function_literals_in_foreach_calls + - avoid_init_to_null + - avoid_null_checks_in_equality_operators + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + #- avoid_returning_null + - avoid_returning_null_for_future + - avoid_returning_null_for_void + - avoid_returning_this + - avoid_shadowing_type_parameters + - avoid_single_cascade_in_expression_statements + - avoid_types_as_parameter_names + - avoid_unused_constructor_parameters + - await_only_futures + - camel_case_types + - cancel_subscriptions + #- cascade_invocations + - comment_references + - constant_identifier_names + - control_flow_in_finally + - directives_ordering + - empty_catches + - empty_constructor_bodies + - empty_statements + - file_names + - hash_and_equals + - implementation_imports + - invariant_booleans + - iterable_contains_unrelated_type + - join_return_with_assignment + - library_names + - library_prefixes + - list_remove_unrelated_type + - literal_only_boolean_expressions + - no_adjacent_strings_in_list + - no_duplicate_case_values + - non_constant_identifier_names + - null_closures + - omit_local_variable_types + - only_throw_errors + - overridden_fields + - package_api_docs + - package_names + - package_prefixed_library_names + - prefer_adjacent_string_concatenation + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_contains + - prefer_equal_for_default_values + - prefer_final_fields + #- prefer_final_locals + - prefer_generic_function_type_aliases + - prefer_initializing_formals + - prefer_interpolation_to_compose_strings + - prefer_is_empty + - prefer_is_not_empty + - prefer_null_aware_operators + #- prefer_single_quotes + - prefer_typing_uninitialized_variables + - recursive_getters + - slash_for_doc_comments + - test_types_in_equals + - throw_in_finally + - type_init_formals + - unawaited_futures + - unnecessary_await_in_return + - unnecessary_brace_in_string_interps + - unnecessary_const + - unnecessary_getters_setters + - unnecessary_lambdas + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_parenthesis + - unnecessary_statements + - unnecessary_this + - unrelated_type_equality_checks + - use_function_type_syntax_for_parameters + - use_rethrow_when_possible + - valid_regexps + - void_checks diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index 96c7362e0..a2df0f880 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -11,7 +11,7 @@ import 'span_scanner.dart'; // sdk#23770 is fully complete, we should move the shared code into a mixin. /// A regular expression matching newlines across platforms. -final _newlineRegExp = new RegExp(r"\r\n?|\n"); +final _newlineRegExp = RegExp(r"\r\n?|\n"); /// A [SpanScanner] that tracks the line and column eagerly, like [LineScanner]. class EagerSpanScanner extends SpanScanner { @@ -22,14 +22,14 @@ class EagerSpanScanner extends SpanScanner { int _column = 0; LineScannerState get state => - new _EagerSpanScannerState(this, position, line, column); + _EagerSpanScannerState(this, position, line, column); bool get _betweenCRLF => peekChar(-1) == $cr && peekChar() == $lf; set state(LineScannerState state) { if (state is! _EagerSpanScannerState || !identical((state as _EagerSpanScannerState)._scanner, this)) { - throw new ArgumentError("The given LineScannerState was not returned by " + throw ArgumentError("The given LineScannerState was not returned by " "this LineScanner."); } diff --git a/pkgs/string_scanner/lib/src/exception.dart b/pkgs/string_scanner/lib/src/exception.dart index 84bf5e861..3710ae814 100644 --- a/pkgs/string_scanner/lib/src/exception.dart +++ b/pkgs/string_scanner/lib/src/exception.dart @@ -4,6 +4,8 @@ import 'package:source_span/source_span.dart'; +import 'string_scanner.dart'; + /// An exception thrown by a [StringScanner] that failed to parse a string. class StringScannerException extends SourceSpanFormatException { String get source => super.source; diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 518203530..e16302a06 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -9,7 +9,7 @@ import 'string_scanner.dart'; // Note that much of this code is duplicated in eager_span_scanner.dart. /// A regular expression matching newlines across platforms. -final _newlineRegExp = new RegExp(r"\r\n?|\n"); +final _newlineRegExp = RegExp(r"\r\n?|\n"); /// A subclass of [StringScanner] that tracks line and column information. class LineScanner extends StringScanner { @@ -29,7 +29,7 @@ class LineScanner extends StringScanner { /// /// This does not include the scanner's match information. LineScannerState get state => - new LineScannerState._(this, position, line, column); + LineScannerState._(this, position, line, column); /// Whether the current position is between a CR character and an LF /// charactet. @@ -37,7 +37,7 @@ class LineScanner extends StringScanner { set state(LineScannerState state) { if (!identical(state._scanner, this)) { - throw new ArgumentError("The given LineScannerState was not returned by " + throw ArgumentError("The given LineScannerState was not returned by " "this LineScanner."); } diff --git a/pkgs/string_scanner/lib/src/relative_span_scanner.dart b/pkgs/string_scanner/lib/src/relative_span_scanner.dart index 088ff481f..1a992e41b 100644 --- a/pkgs/string_scanner/lib/src/relative_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/relative_span_scanner.dart @@ -19,7 +19,7 @@ import 'utils.dart'; class RelativeSpanScanner extends StringScanner implements SpanScanner { /// The source of the scanner. /// - /// This caches line break information and is used to generate [Span]s. + /// This caches line break information and is used to generate [SourceSpan]s. final SourceFile _sourceFile; /// The start location of the span within which this scanner is scanning. @@ -40,16 +40,16 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { : column; } - LineScannerState get state => new _SpanScannerState(this, position); + LineScannerState get state => _SpanScannerState(this, position); set state(LineScannerState state) { if (state is! _SpanScannerState || !identical((state as _SpanScannerState)._scanner, this)) { - throw new ArgumentError("The given LineScannerState was not returned by " + throw ArgumentError("The given LineScannerState was not returned by " "this LineScanner."); } - this.position = state.position; + position = state.position; } FileSpan get lastSpan => _lastSpan; @@ -86,14 +86,12 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { validateErrorArgs(string, match, position, length); if (match == null && position == null && length == null) match = lastMatch; - if (position == null) { - position = match == null ? this.position : match.start; - } - if (length == null) length = match == null ? 1 : match.end - match.start; + position ??= match == null ? this.position : match.start; + length ??= match == null ? 1 : match.end - match.start; var span = _sourceFile.span(_startLocation.offset + position, _startLocation.offset + position + length); - throw new StringScannerException(message, span, string); + throw StringScannerException(message, span, string); } } diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index a629f1327..d33221626 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -12,26 +12,26 @@ import 'string_scanner.dart'; import 'utils.dart'; /// A subclass of [LineScanner] that exposes matched ranges as source map -/// [Span]s. +/// [FileSpan]s. class SpanScanner extends StringScanner implements LineScanner { /// The source of the scanner. /// - /// This caches line break information and is used to generate [Span]s. + /// This caches line break information and is used to generate [FileSpan]s. final SourceFile _sourceFile; int get line => _sourceFile.getLine(position); int get column => _sourceFile.getColumn(position); - LineScannerState get state => new _SpanScannerState(this, position); + LineScannerState get state => _SpanScannerState(this, position); set state(LineScannerState state) { if (state is! _SpanScannerState || !identical((state as _SpanScannerState)._scanner, this)) { - throw new ArgumentError("The given LineScannerState was not returned by " + throw ArgumentError("The given LineScannerState was not returned by " "this LineScanner."); } - this.position = state.position; + position = state.position; } /// The [FileSpan] for [lastMatch]. @@ -57,7 +57,7 @@ class SpanScanner extends StringScanner implements LineScanner { /// [FileSpan]s as well as for error reporting. It can be a [String], a /// [Uri], or `null`. SpanScanner(String string, {sourceUrl, int position}) - : _sourceFile = new SourceFile.fromString(string, url: sourceUrl), + : _sourceFile = SourceFile.fromString(string, url: sourceUrl), super(string, sourceUrl: sourceUrl, position: position); /// Creates a new [SpanScanner] that eagerly computes line and column numbers. @@ -76,9 +76,9 @@ class SpanScanner extends StringScanner implements LineScanner { /// Creates a new [SpanScanner] that scans within [span]. /// - /// This scans through [span.text], but emits new spans from [span.file] in + /// This scans through [span]`.text, but emits new spans from [span]`.file` in /// their appropriate relative positions. The [string] field contains only - /// [span.text], and [position], [line], and [column] are all relative to the + /// [span]`.text`, and [position], [line], and [column] are all relative to the /// span. factory SpanScanner.within(FileSpan span) = RelativeSpanScanner; @@ -103,13 +103,11 @@ class SpanScanner extends StringScanner implements LineScanner { validateErrorArgs(string, match, position, length); if (match == null && position == null && length == null) match = lastMatch; - if (position == null) { - position = match == null ? this.position : match.start; - } - if (length == null) length = match == null ? 0 : match.end - match.start; + position ??= match == null ? this.position : match.start; + length ??= match == null ? 0 : match.end - match.start; var span = _sourceFile.span(position, position + length); - throw new StringScannerException(message, span, string); + throw StringScannerException(message, span, string); } } diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index d32dc38ad..4506355d2 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -12,7 +12,7 @@ import 'utils.dart'; /// When compiled to JS, forward slashes are always escaped in [RegExp.pattern]. /// /// See issue 17998. -final _slashAutoEscape = new RegExp("/").pattern == "\\/"; +final _slashAutoEscape = RegExp("/").pattern == "\\/"; /// A class that scans through a string using [Pattern]s. class StringScanner { @@ -29,7 +29,7 @@ class StringScanner { int get position => _position; set position(int position) { if (position < 0 || position > string.length) { - throw new ArgumentError("Invalid position $position"); + throw ArgumentError("Invalid position $position"); } _position = position; @@ -84,7 +84,7 @@ class StringScanner { /// This returns `null` if [offset] points outside the string. It doesn't /// affect [lastMatch]. int peekChar([int offset]) { - if (offset == null) offset = 0; + offset ??= 0; var index = position + offset; if (index < 0 || index >= string.length) return null; return string.codeUnitAt(index); @@ -115,7 +115,7 @@ class StringScanner { } else if (character == $double_quote) { name = r'"\""'; } else { - name = '"${new String.fromCharCode(character)}"'; + name = '"${String.fromCharCode(character)}"'; } } @@ -181,7 +181,7 @@ class StringScanner { /// Unlike [String.substring], [end] defaults to [position] rather than the /// end of the string. String substring(int start, [int end]) { - if (end == null) end = position; + end ??= position; return string.substring(start, end); } @@ -203,20 +203,18 @@ class StringScanner { validateErrorArgs(string, match, position, length); if (match == null && position == null && length == null) match = lastMatch; - if (position == null) { - position = match == null ? this.position : match.start; - } - if (length == null) length = match == null ? 0 : match.end - match.start; + position ??= match == null ? this.position : match.start; + length ??= match == null ? 0 : match.end - match.start; - var sourceFile = new SourceFile.fromString(string, url: sourceUrl); + var sourceFile = SourceFile.fromString(string, url: sourceUrl); var span = sourceFile.span(position, position + length); - throw new StringScannerException(message, span, string); + throw StringScannerException(message, span, string); } // TODO(nweiz): Make this handle long lines more gracefully. /// Throws a [FormatException] describing that [name] is expected at the /// current position in the string. void _fail(String name) { - error("expected $name.", position: this.position, length: 0); + error("expected $name.", position: position, length: 0); } } diff --git a/pkgs/string_scanner/lib/src/utils.dart b/pkgs/string_scanner/lib/src/utils.dart index aa3e95736..df29ba21b 100644 --- a/pkgs/string_scanner/lib/src/utils.dart +++ b/pkgs/string_scanner/lib/src/utils.dart @@ -2,27 +2,29 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'string_scanner.dart'; + /// Validates the arguments passed to [StringScanner.error]. void validateErrorArgs(String string, Match match, int position, int length) { if (match != null && (position != null || length != null)) { - throw new ArgumentError("Can't pass both match and position/length."); + throw ArgumentError("Can't pass both match and position/length."); } if (position != null) { if (position < 0) { - throw new RangeError("position must be greater than or equal to 0."); + throw RangeError("position must be greater than or equal to 0."); } else if (position > string.length) { - throw new RangeError("position must be less than or equal to the " + throw RangeError("position must be less than or equal to the " "string length."); } } if (length != null && length < 0) { - throw new RangeError("length must be greater than or equal to 0."); + throw RangeError("length must be greater than or equal to 0."); } if (position != null && length != null && position + length > string.length) { - throw new RangeError("position plus length must not go beyond the end of " + throw RangeError("position plus length must not go beyond the end of " "the string."); } } diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 769199054..2bc50d6e4 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,12 +1,12 @@ name: string_scanner -version: 1.0.4 +version: 1.0.5-dev description: A class for parsing strings using a sequence of patterns. author: Dart Team homepage: https://github.com/dart-lang/string_scanner environment: - sdk: '>=1.8.0 <3.0.0' + sdk: '>=2.0.0 <3.0.0' dependencies: charcode: ^1.1.0 @@ -14,5 +14,5 @@ dependencies: source_span: ^1.4.0 dev_dependencies: - test: '>=0.12.0 <2.0.0' + test: ^1.0.0 diff --git a/pkgs/string_scanner/test/error_test.dart b/pkgs/string_scanner/test/error_test.dart index 166077d5e..b966b1bca 100644 --- a/pkgs/string_scanner/test/error_test.dart +++ b/pkgs/string_scanner/test/error_test.dart @@ -9,7 +9,7 @@ import 'utils.dart'; void main() { test('defaults to the last match', () { - var scanner = new StringScanner('foo bar baz'); + var scanner = StringScanner('foo bar baz'); scanner.expect('foo '); scanner.expect('bar'); expect(() => scanner.error('oh no!'), throwsStringScannerException('bar')); @@ -17,7 +17,7 @@ void main() { group("with match", () { test('supports an earlier match', () { - var scanner = new StringScanner('foo bar baz'); + var scanner = StringScanner('foo bar baz'); scanner.expect('foo '); var match = scanner.lastMatch; scanner.expect('bar'); @@ -26,8 +26,7 @@ void main() { }); test('supports a match on a previous line', () { - var scanner = - new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + var scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo '); scanner.expect('re'); var match = scanner.lastMatch; @@ -37,8 +36,7 @@ void main() { }); test('supports a multiline match', () { - var scanner = - new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + var scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar '); scanner.expect('baz\ndo'); var match = scanner.lastMatch; @@ -48,7 +46,7 @@ void main() { }); test('supports a match after position', () { - var scanner = new StringScanner('foo bar baz'); + var scanner = StringScanner('foo bar baz'); scanner.expect('foo '); scanner.expect('bar'); var match = scanner.lastMatch; @@ -60,59 +58,57 @@ void main() { group("with position and/or length", () { test('defaults to length 0', () { - var scanner = new StringScanner('foo bar baz'); + var scanner = StringScanner('foo bar baz'); scanner.expect('foo '); expect(() => scanner.error('oh no!', position: 1), throwsStringScannerException('')); }); test('defaults to the current position', () { - var scanner = new StringScanner('foo bar baz'); + var scanner = StringScanner('foo bar baz'); scanner.expect('foo '); expect(() => scanner.error('oh no!', length: 3), throwsStringScannerException('bar')); }); test('supports an earlier position', () { - var scanner = new StringScanner('foo bar baz'); + var scanner = StringScanner('foo bar baz'); scanner.expect('foo '); expect(() => scanner.error('oh no!', position: 1, length: 2), throwsStringScannerException('oo')); }); test('supports a position on a previous line', () { - var scanner = - new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + var scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo re mi\nearth'); expect(() => scanner.error('oh no!', position: 15, length: 2), throwsStringScannerException('re')); }); test('supports a multiline length', () { - var scanner = - new StringScanner('foo bar baz\ndo re mi\nearth fire water'); + var scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo re mi\nearth'); expect(() => scanner.error('oh no!', position: 8, length: 8), throwsStringScannerException('baz\ndo r')); }); test('supports a position after the current one', () { - var scanner = new StringScanner('foo bar baz'); + var scanner = StringScanner('foo bar baz'); expect(() => scanner.error('oh no!', position: 4, length: 3), throwsStringScannerException('bar')); }); test('supports a length of zero', () { - var scanner = new StringScanner('foo bar baz'); + var scanner = StringScanner('foo bar baz'); expect(() => scanner.error('oh no!', position: 4, length: 0), throwsStringScannerException('')); }); }); group("argument errors", () { - var scanner; + StringScanner scanner; setUp(() { - scanner = new StringScanner('foo bar baz'); + scanner = StringScanner('foo bar baz'); scanner.scan('foo'); }); diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index ed04b371c..876714271 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -7,9 +7,9 @@ import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; void main() { - var scanner; + LineScanner scanner; setUp(() { - scanner = new LineScanner('foo\nbar\r\nbaz'); + scanner = LineScanner('foo\nbar\r\nbaz'); }); test('begins with line and column 0', () { @@ -162,7 +162,7 @@ void main() { test("state= rejects a foreign state", () { scanner.scan('foo\nb'); - expect(() => new LineScanner(scanner.string).state = scanner.state, + expect(() => LineScanner(scanner.string).state = scanner.state, throwsArgumentError); }); } diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index 37a01e025..65694eaac 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -10,23 +10,22 @@ import 'utils.dart'; void main() { testForImplementation("lazy", ([String string]) { - return new SpanScanner(string ?? 'foo\nbar\nbaz', sourceUrl: 'source'); + return SpanScanner(string ?? 'foo\nbar\nbaz', sourceUrl: 'source'); }); testForImplementation("eager", ([String string]) { - return new SpanScanner.eager(string ?? 'foo\nbar\nbaz', - sourceUrl: 'source'); + return SpanScanner.eager(string ?? 'foo\nbar\nbaz', sourceUrl: 'source'); }); group("within", () { var text = 'first\nbefore: foo\nbar\nbaz :after\nlast'; var startOffset = text.indexOf('foo'); - var scanner; + SpanScanner scanner; setUp(() { - var file = new SourceFile.fromString(text, url: 'source'); - scanner = new SpanScanner.within( - file.span(startOffset, text.indexOf(' :after'))); + var file = SourceFile.fromString(text, url: 'source'); + scanner = + SpanScanner.within(file.span(startOffset, text.indexOf(' :after'))); }); test("string only includes the span text", () { @@ -104,9 +103,10 @@ void main() { }); } -void testForImplementation(String name, SpanScanner create([String string])) { +void testForImplementation( + String name, SpanScanner Function([String string]) create) { group("for a $name scanner", () { - var scanner; + SpanScanner scanner; setUp(() => scanner = create()); test("tracks the span for the last match", () { diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 30711f5ae..9d6d6b860 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -8,9 +8,9 @@ import 'package:test/test.dart'; void main() { group('with an empty string', () { - var scanner; + StringScanner scanner; setUp(() { - scanner = new StringScanner(''); + scanner = StringScanner(''); }); test('is done', () { @@ -55,19 +55,19 @@ void main() { }); test("scan returns false and doesn't change the state", () { - expect(scanner.scan(new RegExp('.')), isFalse); + expect(scanner.scan(RegExp('.')), isFalse); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(0)); }); test("expect throws a FormatException and doesn't change the state", () { - expect(() => scanner.expect(new RegExp('.')), throwsFormatException); + expect(() => scanner.expect(RegExp('.')), throwsFormatException); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(0)); }); test("matches returns false and doesn't change the state", () { - expect(scanner.matches(new RegExp('.')), isFalse); + expect(scanner.matches(RegExp('.')), isFalse); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(0)); }); @@ -90,9 +90,9 @@ void main() { }); group('at the beginning of a string', () { - var scanner; + StringScanner scanner; setUp(() { - scanner = new StringScanner('foo bar'); + scanner = StringScanner('foo bar'); }); test('is not done', () { @@ -155,24 +155,24 @@ void main() { }); test("a matching scan returns true and changes the state", () { - expect(scanner.scan(new RegExp('f(..)')), isTrue); + expect(scanner.scan(RegExp('f(..)')), isTrue); expect(scanner.lastMatch[1], equals('oo')); expect(scanner.position, equals(3)); expect(scanner.rest, equals(' bar')); }); test("a non-matching scan returns false and sets lastMatch to null", () { - expect(scanner.matches(new RegExp('f(..)')), isTrue); + expect(scanner.matches(RegExp('f(..)')), isTrue); expect(scanner.lastMatch, isNotNull); - expect(scanner.scan(new RegExp('b(..)')), isFalse); + expect(scanner.scan(RegExp('b(..)')), isFalse); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(0)); expect(scanner.rest, equals('foo bar')); }); test("a matching expect changes the state", () { - scanner.expect(new RegExp('f(..)')); + scanner.expect(RegExp('f(..)')); expect(scanner.lastMatch[1], equals('oo')); expect(scanner.position, equals(3)); expect(scanner.rest, equals(' bar')); @@ -181,17 +181,17 @@ void main() { test( "a non-matching expect throws a FormatException and sets lastMatch to " "null", () { - expect(scanner.matches(new RegExp('f(..)')), isTrue); + expect(scanner.matches(RegExp('f(..)')), isTrue); expect(scanner.lastMatch, isNotNull); - expect(() => scanner.expect(new RegExp('b(..)')), throwsFormatException); + expect(() => scanner.expect(RegExp('b(..)')), throwsFormatException); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(0)); expect(scanner.rest, equals('foo bar')); }); test("a matching matches returns true and only changes lastMatch", () { - expect(scanner.matches(new RegExp('f(..)')), isTrue); + expect(scanner.matches(RegExp('f(..)')), isTrue); expect(scanner.lastMatch[1], equals('oo')); expect(scanner.position, equals(0)); expect(scanner.rest, equals('foo bar')); @@ -199,7 +199,7 @@ void main() { test("a non-matching matches returns false and doesn't change the state", () { - expect(scanner.matches(new RegExp('b(..)')), isFalse); + expect(scanner.matches(RegExp('b(..)')), isFalse); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(0)); expect(scanner.rest, equals('foo bar')); @@ -222,7 +222,7 @@ void main() { expect(scanner.position, equals(1)); expect(scanner.rest, equals('oo bar')); - expect(scanner.scan(new RegExp('oo.')), isTrue); + expect(scanner.scan(RegExp('oo.')), isTrue); expect(scanner.lastMatch[0], equals('oo ')); expect(scanner.position, equals(4)); expect(scanner.rest, equals('bar')); @@ -248,12 +248,12 @@ void main() { }); test('scans multiple times', () { - expect(scanner.scan(new RegExp('f(..)')), isTrue); + expect(scanner.scan(RegExp('f(..)')), isTrue); expect(scanner.lastMatch[1], equals('oo')); expect(scanner.position, equals(3)); expect(scanner.rest, equals(' bar')); - expect(scanner.scan(new RegExp(' b(..)')), isTrue); + expect(scanner.scan(RegExp(' b(..)')), isTrue); expect(scanner.lastMatch[1], equals('ar')); expect(scanner.position, equals(7)); expect(scanner.rest, equals('')); @@ -263,9 +263,9 @@ void main() { }); group('after a scan', () { - var scanner; + StringScanner scanner; setUp(() { - scanner = new StringScanner('foo bar'); + scanner = StringScanner('foo bar'); expect(scanner.scan('foo'), isTrue); }); @@ -289,9 +289,9 @@ void main() { }); group('at the end of a string', () { - var scanner; + StringScanner scanner; setUp(() { - scanner = new StringScanner('foo bar'); + scanner = StringScanner('foo bar'); expect(scanner.scan('foo bar'), isTrue); }); @@ -333,19 +333,19 @@ void main() { }); test("scan returns false and sets lastMatch to null", () { - expect(scanner.scan(new RegExp('.')), isFalse); + expect(scanner.scan(RegExp('.')), isFalse); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(7)); }); test("expect throws a FormatException and sets lastMatch to null", () { - expect(() => scanner.expect(new RegExp('.')), throwsFormatException); + expect(() => scanner.expect(RegExp('.')), throwsFormatException); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(7)); }); test("matches returns false sets lastMatch to null", () { - expect(scanner.matches(new RegExp('.')), isFalse); + expect(scanner.matches(RegExp('.')), isFalse); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(7)); }); @@ -367,7 +367,7 @@ void main() { expect(scanner.position, equals(1)); expect(scanner.rest, equals('oo bar')); - expect(scanner.scan(new RegExp('oo.')), isTrue); + expect(scanner.scan(RegExp('oo.')), isTrue); expect(scanner.lastMatch[0], equals('oo ')); expect(scanner.position, equals(4)); expect(scanner.rest, equals('bar')); @@ -395,24 +395,22 @@ void main() { group('a scanner constructed with a custom position', () { test('starts scanning from that position', () { - var scanner = new StringScanner('foo bar', position: 1); + var scanner = StringScanner('foo bar', position: 1); expect(scanner.position, equals(1)); expect(scanner.rest, equals('oo bar')); - expect(scanner.scan(new RegExp('oo.')), isTrue); + expect(scanner.scan(RegExp('oo.')), isTrue); expect(scanner.lastMatch[0], equals('oo ')); expect(scanner.position, equals(4)); expect(scanner.rest, equals('bar')); }); test('throws an ArgumentError if the position is -1', () { - expect(() => new StringScanner('foo bar', position: -1), - throwsArgumentError); + expect(() => StringScanner('foo bar', position: -1), throwsArgumentError); }); test('throws an ArgumentError if the position is beyond the string', () { - expect( - () => new StringScanner('foo bar', position: 8), throwsArgumentError); + expect(() => StringScanner('foo bar', position: 8), throwsArgumentError); }); }); } diff --git a/pkgs/string_scanner/test/utils.dart b/pkgs/string_scanner/test/utils.dart index 7767fbc88..676b69555 100644 --- a/pkgs/string_scanner/test/utils.dart +++ b/pkgs/string_scanner/test/utils.dart @@ -5,13 +5,8 @@ import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; -/// Returns a matcher that asserts that a closure throws a [FormatException] -/// with the given [message]. -Matcher throwsStringScannerException(String text) { - return throwsA(predicate((error) { - // ignore: deprecated_member_use - expect(error, new isInstanceOf()); - expect(error.span.text, equals(text)); - return true; - })); -} +/// Returns a matcher that asserts that a closure throws a +/// [StringScannerException] with the given [text]. +Matcher throwsStringScannerException(String text) => + throwsA(const TypeMatcher() + .having((e) => e.span.text, 'span.text', text)); From 24174b888bad8e74f3a480389f75bc4b031a205a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 31 Jul 2019 12:57:24 -0700 Subject: [PATCH 031/102] Remove unneeded codereview.settings --- pkgs/string_scanner/codereview.settings | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/string_scanner/codereview.settings diff --git a/pkgs/string_scanner/codereview.settings b/pkgs/string_scanner/codereview.settings deleted file mode 100644 index 31c557fbd..000000000 --- a/pkgs/string_scanner/codereview.settings +++ /dev/null @@ -1,3 +0,0 @@ -CODE_REVIEW_SERVER: http://codereview.chromium.org/ -VIEW_VC: https://github.com/dart-lang/string_scanner/commit/ -CC_LIST: reviews@dartlang.org \ No newline at end of file From 3ce0df0bf54fbabcfc50348dc64d5fc7a66881ad Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 31 Jul 2019 12:57:54 -0700 Subject: [PATCH 032/102] Remove very old work-around Fixes https://github.com/dart-lang/string_scanner/issues/1 --- pkgs/string_scanner/lib/src/string_scanner.dart | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 4506355d2..f6243aa1b 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -9,11 +9,6 @@ import 'package:source_span/source_span.dart'; import 'exception.dart'; import 'utils.dart'; -/// When compiled to JS, forward slashes are always escaped in [RegExp.pattern]. -/// -/// See issue 17998. -final _slashAutoEscape = RegExp("/").pattern == "\\/"; - /// A class that scans through a string using [Pattern]s. class StringScanner { /// The URL of the source of the string being scanned. @@ -148,7 +143,6 @@ class StringScanner { if (name == null) { if (pattern is RegExp) { var source = pattern.pattern; - if (!_slashAutoEscape) source = source.replaceAll("/", "\\/"); name = "/$source/"; } else { name = From 20a000b1be08899037efb6103f4d69b4cabc9876 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 31 Jul 2019 13:02:31 -0700 Subject: [PATCH 033/102] Remove and fix dead links in changelog --- pkgs/string_scanner/CHANGELOG.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 1fba528d3..afef24087 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -88,10 +88,7 @@ than 1.0.0. For example, `string_scanner: ">=0.1.5 <2.0.0"`. ## 0.0.3 -* Make `StringScannerException` inherit from source_map's - [`SpanFormatException`][]. - -[SpanFormatException]: (http://www.dartdocs.org/documentation/source_maps/0.9.2/index.html#source_maps/source_maps.SpanFormatException) +* Make `StringScannerException` inherit from source_map's `SpanFormatException`. ## 0.0.2 @@ -111,4 +108,4 @@ than 1.0.0. For example, `string_scanner: ">=0.1.5 <2.0.0"`. * Add a `SpanScanner` subclass of `LineScanner` that exposes matched ranges as [source map][] `Span` objects. -[source_map]: http://pub.dartlang.org/packages/source_maps +[source_map]: https://pub.dev/packages/source_maps From f0cc5da720a156eafdb2597716573809f8a81bd0 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 31 Jul 2019 13:09:28 -0700 Subject: [PATCH 034/102] Added example/example.dart, update README to working, valid code Fixes https://github.com/dart-lang/string_scanner/issues/9 --- pkgs/string_scanner/README.md | 8 ++--- pkgs/string_scanner/example/example.dart | 40 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 pkgs/string_scanner/example/example.dart diff --git a/pkgs/string_scanner/README.md b/pkgs/string_scanner/README.md index 90660fc8c..15aa24261 100644 --- a/pkgs/string_scanner/README.md +++ b/pkgs/string_scanner/README.md @@ -8,7 +8,7 @@ import 'package:string_scanner/string_scanner.dart'; num parseNumber(String source) { // Scan a number ("1", "1.5", "-3"). - var scanner = new StringScanner(source); + var scanner = StringScanner(source); // [Scanner.scan] tries to consume a [Pattern] and returns whether or not it // succeeded. It will move the scan pointer past the end of the pattern. @@ -16,14 +16,14 @@ num parseNumber(String source) { // [Scanner.expect] consumes a [Pattern] and throws a [FormatError] if it // fails. Like [Scanner.scan], it will move the scan pointer forward. - scanner.expect(new RegExp(r"\d+")); + scanner.expect(RegExp(r"\d+")); // [Scanner.lastMatch] holds the [MatchData] for the most recent call to // [Scanner.scan], [Scanner.expect], or [Scanner.matches]. - var number = int.parse(scanner.lastMatch[0]); + var number = num.parse(scanner.lastMatch[0]); if (scanner.scan(".")) { - scanner.expect(new RegExp(r"\d+")); + scanner.expect(RegExp(r"\d+")); var decimal = scanner.lastMatch[0]; number += int.parse(decimal) / math.pow(10, decimal.length); } diff --git a/pkgs/string_scanner/example/example.dart b/pkgs/string_scanner/example/example.dart new file mode 100644 index 000000000..ddd9d3ead --- /dev/null +++ b/pkgs/string_scanner/example/example.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:math' as math; + +import 'package:string_scanner/string_scanner.dart'; + +void main(List args) { + print(parseNumber(args.single)); +} + +num parseNumber(String source) { + // Scan a number ("1", "1.5", "-3"). + var scanner = StringScanner(source); + + // [Scanner.scan] tries to consume a [Pattern] and returns whether or not it + // succeeded. It will move the scan pointer past the end of the pattern. + var negative = scanner.scan("-"); + + // [Scanner.expect] consumes a [Pattern] and throws a [FormatError] if it + // fails. Like [Scanner.scan], it will move the scan pointer forward. + scanner.expect(RegExp(r"\d+")); + + // [Scanner.lastMatch] holds the [MatchData] for the most recent call to + // [Scanner.scan], [Scanner.expect], or [Scanner.matches]. + var number = num.parse(scanner.lastMatch[0]); + + if (scanner.scan(".")) { + scanner.expect(RegExp(r"\d+")); + var decimal = scanner.lastMatch[0]; + number += int.parse(decimal) / math.pow(10, decimal.length); + } + + // [Scanner.expectDone] will throw a [FormatError] if there's any input that + // hasn't yet been consumed. + scanner.expectDone(); + + return (negative ? -1 : 1) * number; +} From f4b2fb681bc96f91de0c1b9ed3687f3c87b25a7b Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 31 Jul 2019 13:14:28 -0700 Subject: [PATCH 035/102] analysis_options: disallow implicit casts --- pkgs/string_scanner/analysis_options.yaml | 4 ++-- pkgs/string_scanner/lib/src/exception.dart | 2 +- pkgs/string_scanner/lib/src/string_scanner.dart | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index d5d521374..6e8826ba9 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -1,7 +1,7 @@ include: package:pedantic/analysis_options.yaml analyzer: -# strong-mode: -# implicit-casts: false + strong-mode: + implicit-casts: false linter: rules: - always_declare_return_types diff --git a/pkgs/string_scanner/lib/src/exception.dart b/pkgs/string_scanner/lib/src/exception.dart index 3710ae814..bad08f6e2 100644 --- a/pkgs/string_scanner/lib/src/exception.dart +++ b/pkgs/string_scanner/lib/src/exception.dart @@ -8,7 +8,7 @@ import 'string_scanner.dart'; /// An exception thrown by a [StringScanner] that failed to parse a string. class StringScannerException extends SourceSpanFormatException { - String get source => super.source; + String get source => super.source as String; /// The URL of the source file being parsed. /// diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index f6243aa1b..4a1d10c0c 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -58,7 +58,8 @@ class StringScanner { /// URL of the source of the string being scanned, if available. It can be /// a [String], a [Uri], or `null`. StringScanner(this.string, {sourceUrl, int position}) - : sourceUrl = sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl { + : sourceUrl = + sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl as Uri { if (position != null) this.position = position; } From 3b93ffe9a99974ebcb38972a91a57a3d096294b3 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 31 Jul 2019 13:12:46 -0700 Subject: [PATCH 036/102] prepare for release --- pkgs/string_scanner/CHANGELOG.md | 2 ++ pkgs/string_scanner/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index afef24087..fb7f74dd1 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,5 +1,7 @@ ## 1.0.5 +- Added an example. + - Update Dart SDK constraint to `>=2.0.0 <3.0.0`. ## 1.0.4 diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 2bc50d6e4..6cba21e76 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.0.5-dev +version: 1.0.5 description: A class for parsing strings using a sequence of patterns. author: Dart Team From 43c11d2b5385becc8773f811084d4fe33c64b503 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 5 Dec 2019 14:32:41 -0800 Subject: [PATCH 037/102] Fix latest pedantic lints, remove deprecated author field in pubspec (dart-lang/string_scanner#17) --- pkgs/string_scanner/analysis_options.yaml | 2 - pkgs/string_scanner/example/example.dart | 8 ++-- .../lib/src/eager_span_scanner.dart | 17 ++++++-- pkgs/string_scanner/lib/src/exception.dart | 1 + pkgs/string_scanner/lib/src/line_scanner.dart | 10 +++-- .../lib/src/relative_span_scanner.dart | 17 +++++++- pkgs/string_scanner/lib/src/span_scanner.dart | 13 +++++- .../lib/src/string_scanner.dart | 12 +++--- pkgs/string_scanner/lib/src/utils.dart | 12 +++--- pkgs/string_scanner/pubspec.yaml | 1 - pkgs/string_scanner/test/error_test.dart | 30 ++++++------- .../test/line_scanner_test.dart | 38 ++++++++--------- .../test/span_scanner_test.dart | 42 +++++++++---------- .../test/string_scanner_test.dart | 40 +++++++++--------- 14 files changed, 139 insertions(+), 104 deletions(-) diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index 6e8826ba9..c9899f2e2 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -5,7 +5,6 @@ analyzer: linter: rules: - always_declare_return_types - #- annotate_overrides - avoid_bool_literals_in_conditional_expressions - avoid_classes_with_only_static_members - avoid_empty_else @@ -68,7 +67,6 @@ linter: - prefer_is_empty - prefer_is_not_empty - prefer_null_aware_operators - #- prefer_single_quotes - prefer_typing_uninitialized_variables - recursive_getters - slash_for_doc_comments diff --git a/pkgs/string_scanner/example/example.dart b/pkgs/string_scanner/example/example.dart index ddd9d3ead..0358967e4 100644 --- a/pkgs/string_scanner/example/example.dart +++ b/pkgs/string_scanner/example/example.dart @@ -16,18 +16,18 @@ num parseNumber(String source) { // [Scanner.scan] tries to consume a [Pattern] and returns whether or not it // succeeded. It will move the scan pointer past the end of the pattern. - var negative = scanner.scan("-"); + var negative = scanner.scan('-'); // [Scanner.expect] consumes a [Pattern] and throws a [FormatError] if it // fails. Like [Scanner.scan], it will move the scan pointer forward. - scanner.expect(RegExp(r"\d+")); + scanner.expect(RegExp(r'\d+')); // [Scanner.lastMatch] holds the [MatchData] for the most recent call to // [Scanner.scan], [Scanner.expect], or [Scanner.matches]. var number = num.parse(scanner.lastMatch[0]); - if (scanner.scan(".")) { - scanner.expect(RegExp(r"\d+")); + if (scanner.scan('.')) { + scanner.expect(RegExp(r'\d+')); var decimal = scanner.lastMatch[0]; number += int.parse(decimal) / math.pow(10, decimal.length); } diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index a2df0f880..d34e4f7c3 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -11,26 +11,30 @@ import 'span_scanner.dart'; // sdk#23770 is fully complete, we should move the shared code into a mixin. /// A regular expression matching newlines across platforms. -final _newlineRegExp = RegExp(r"\r\n?|\n"); +final _newlineRegExp = RegExp(r'\r\n?|\n'); /// A [SpanScanner] that tracks the line and column eagerly, like [LineScanner]. class EagerSpanScanner extends SpanScanner { + @override int get line => _line; int _line = 0; + @override int get column => _column; int _column = 0; + @override LineScannerState get state => _EagerSpanScannerState(this, position, line, column); bool get _betweenCRLF => peekChar(-1) == $cr && peekChar() == $lf; + @override set state(LineScannerState state) { if (state is! _EagerSpanScannerState || !identical((state as _EagerSpanScannerState)._scanner, this)) { - throw ArgumentError("The given LineScannerState was not returned by " - "this LineScanner."); + throw ArgumentError('The given LineScannerState was not returned by ' + 'this LineScanner.'); } super.position = state.position; @@ -38,6 +42,7 @@ class EagerSpanScanner extends SpanScanner { _column = state.column; } + @override set position(int newPosition) { var oldPosition = position; super.position = newPosition; @@ -67,12 +72,14 @@ class EagerSpanScanner extends SpanScanner { EagerSpanScanner(String string, {sourceUrl, int position}) : super(string, sourceUrl: sourceUrl, position: position); + @override bool scanChar(int character) { if (!super.scanChar(character)) return false; _adjustLineAndColumn(character); return true; } + @override int readChar() { var character = super.readChar(); _adjustLineAndColumn(character); @@ -89,6 +96,7 @@ class EagerSpanScanner extends SpanScanner { } } + @override bool scan(Pattern pattern) { if (!super.scan(pattern)) return false; @@ -115,8 +123,11 @@ class EagerSpanScanner extends SpanScanner { /// A class representing the state of an [EagerSpanScanner]. class _EagerSpanScannerState implements LineScannerState { final EagerSpanScanner _scanner; + @override final int position; + @override final int line; + @override final int column; _EagerSpanScannerState(this._scanner, this.position, this.line, this.column); diff --git a/pkgs/string_scanner/lib/src/exception.dart b/pkgs/string_scanner/lib/src/exception.dart index bad08f6e2..8c994b5ae 100644 --- a/pkgs/string_scanner/lib/src/exception.dart +++ b/pkgs/string_scanner/lib/src/exception.dart @@ -8,6 +8,7 @@ import 'string_scanner.dart'; /// An exception thrown by a [StringScanner] that failed to parse a string. class StringScannerException extends SourceSpanFormatException { + @override String get source => super.source as String; /// The URL of the source file being parsed. diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index e16302a06..180d9239b 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -9,7 +9,7 @@ import 'string_scanner.dart'; // Note that much of this code is duplicated in eager_span_scanner.dart. /// A regular expression matching newlines across platforms. -final _newlineRegExp = RegExp(r"\r\n?|\n"); +final _newlineRegExp = RegExp(r'\r\n?|\n'); /// A subclass of [StringScanner] that tracks line and column information. class LineScanner extends StringScanner { @@ -37,8 +37,8 @@ class LineScanner extends StringScanner { set state(LineScannerState state) { if (!identical(state._scanner, this)) { - throw ArgumentError("The given LineScannerState was not returned by " - "this LineScanner."); + throw ArgumentError('The given LineScannerState was not returned by ' + 'this LineScanner.'); } super.position = state.position; @@ -46,6 +46,7 @@ class LineScanner extends StringScanner { _column = state.column; } + @override set position(int newPosition) { var oldPosition = position; super.position = newPosition; @@ -75,12 +76,14 @@ class LineScanner extends StringScanner { LineScanner(String string, {sourceUrl, int position}) : super(string, sourceUrl: sourceUrl, position: position); + @override bool scanChar(int character) { if (!super.scanChar(character)) return false; _adjustLineAndColumn(character); return true; } + @override int readChar() { var character = super.readChar(); _adjustLineAndColumn(character); @@ -97,6 +100,7 @@ class LineScanner extends StringScanner { } } + @override bool scan(Pattern pattern) { if (!super.scan(pattern)) return false; diff --git a/pkgs/string_scanner/lib/src/relative_span_scanner.dart b/pkgs/string_scanner/lib/src/relative_span_scanner.dart index 1a992e41b..096bee3ad 100644 --- a/pkgs/string_scanner/lib/src/relative_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/relative_span_scanner.dart @@ -27,10 +27,12 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { /// This is used to convert between span-relative and file-relative fields. final FileLocation _startLocation; + @override int get line => _sourceFile.getLine(_startLocation.offset + position) - _startLocation.line; + @override int get column { var line = _sourceFile.getLine(_startLocation.offset + position); var column = @@ -40,24 +42,29 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { : column; } + @override LineScannerState get state => _SpanScannerState(this, position); + @override set state(LineScannerState state) { if (state is! _SpanScannerState || !identical((state as _SpanScannerState)._scanner, this)) { - throw ArgumentError("The given LineScannerState was not returned by " - "this LineScanner."); + throw ArgumentError('The given LineScannerState was not returned by ' + 'this LineScanner.'); } position = state.position; } + @override FileSpan get lastSpan => _lastSpan; FileSpan _lastSpan; + @override FileLocation get location => _sourceFile.location(_startLocation.offset + position); + @override FileSpan get emptySpan => location.pointSpan(); RelativeSpanScanner(FileSpan span) @@ -65,12 +72,14 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { _startLocation = span.start, super(span.text, sourceUrl: span.sourceUrl); + @override FileSpan spanFrom(LineScannerState startState, [LineScannerState endState]) { var endPosition = endState == null ? position : endState.position; return _sourceFile.span(_startLocation.offset + startState.position, _startLocation.offset + endPosition); } + @override bool matches(Pattern pattern) { if (!super.matches(pattern)) { _lastSpan = null; @@ -82,6 +91,7 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { return true; } + @override void error(String message, {Match match, int position, int length}) { validateErrorArgs(string, match, position, length); @@ -100,8 +110,11 @@ class _SpanScannerState implements LineScannerState { /// The [SpanScanner] that created this. final RelativeSpanScanner _scanner; + @override final int position; + @override int get line => _scanner._sourceFile.getLine(position); + @override int get column => _scanner._sourceFile.getColumn(position); _SpanScannerState(this._scanner, this.position); diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index d33221626..732a76f18 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -19,16 +19,20 @@ class SpanScanner extends StringScanner implements LineScanner { /// This caches line break information and is used to generate [FileSpan]s. final SourceFile _sourceFile; + @override int get line => _sourceFile.getLine(position); + @override int get column => _sourceFile.getColumn(position); + @override LineScannerState get state => _SpanScannerState(this, position); + @override set state(LineScannerState state) { if (state is! _SpanScannerState || !identical((state as _SpanScannerState)._scanner, this)) { - throw ArgumentError("The given LineScannerState was not returned by " - "this LineScanner."); + throw ArgumentError('The given LineScannerState was not returned by ' + 'this LineScanner.'); } position = state.position; @@ -89,6 +93,7 @@ class SpanScanner extends StringScanner implements LineScanner { return _sourceFile.span(startState.position, endPosition); } + @override bool matches(Pattern pattern) { if (!super.matches(pattern)) { _lastSpan = null; @@ -99,6 +104,7 @@ class SpanScanner extends StringScanner implements LineScanner { return true; } + @override void error(String message, {Match match, int position, int length}) { validateErrorArgs(string, match, position, length); @@ -116,8 +122,11 @@ class _SpanScannerState implements LineScannerState { /// The [SpanScanner] that created this. final SpanScanner _scanner; + @override final int position; + @override int get line => _scanner._sourceFile.getLine(position); + @override int get column => _scanner._sourceFile.getColumn(position); _SpanScannerState(this._scanner, this.position); diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 4a1d10c0c..1739a7cd4 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -24,7 +24,7 @@ class StringScanner { int get position => _position; set position(int position) { if (position < 0 || position > string.length) { - throw ArgumentError("Invalid position $position"); + throw ArgumentError('Invalid position $position'); } _position = position; @@ -68,7 +68,7 @@ class StringScanner { /// This throws a [FormatException] if the string has been fully consumed. It /// doesn't affect [lastMatch]. int readChar() { - if (isDone) _fail("more input"); + if (isDone) _fail('more input'); return string.codeUnitAt(_position++); } @@ -144,10 +144,10 @@ class StringScanner { if (name == null) { if (pattern is RegExp) { var source = pattern.pattern; - name = "/$source/"; + name = '/$source/'; } else { name = - pattern.toString().replaceAll("\\", "\\\\").replaceAll('"', '\\"'); + pattern.toString().replaceAll('\\', '\\\\').replaceAll('"', '\\"'); name = '"$name"'; } } @@ -158,7 +158,7 @@ class StringScanner { /// [FormatException]. void expectDone() { if (isDone) return; - _fail("no more input"); + _fail('no more input'); } /// Returns whether or not [pattern] matches at the current position of the @@ -210,6 +210,6 @@ class StringScanner { /// Throws a [FormatException] describing that [name] is expected at the /// current position in the string. void _fail(String name) { - error("expected $name.", position: position, length: 0); + error('expected $name.', position: position, length: 0); } } diff --git a/pkgs/string_scanner/lib/src/utils.dart b/pkgs/string_scanner/lib/src/utils.dart index df29ba21b..7fe3d5241 100644 --- a/pkgs/string_scanner/lib/src/utils.dart +++ b/pkgs/string_scanner/lib/src/utils.dart @@ -12,19 +12,19 @@ void validateErrorArgs(String string, Match match, int position, int length) { if (position != null) { if (position < 0) { - throw RangeError("position must be greater than or equal to 0."); + throw RangeError('position must be greater than or equal to 0.'); } else if (position > string.length) { - throw RangeError("position must be less than or equal to the " - "string length."); + throw RangeError('position must be less than or equal to the ' + 'string length.'); } } if (length != null && length < 0) { - throw RangeError("length must be greater than or equal to 0."); + throw RangeError('length must be greater than or equal to 0.'); } if (position != null && length != null && position + length > string.length) { - throw RangeError("position plus length must not go beyond the end of " - "the string."); + throw RangeError('position plus length must not go beyond the end of ' + 'the string.'); } } diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 6cba21e76..d5cefceda 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -2,7 +2,6 @@ name: string_scanner version: 1.0.5 description: A class for parsing strings using a sequence of patterns. -author: Dart Team homepage: https://github.com/dart-lang/string_scanner environment: diff --git a/pkgs/string_scanner/test/error_test.dart b/pkgs/string_scanner/test/error_test.dart index b966b1bca..dfa71755c 100644 --- a/pkgs/string_scanner/test/error_test.dart +++ b/pkgs/string_scanner/test/error_test.dart @@ -15,7 +15,7 @@ void main() { expect(() => scanner.error('oh no!'), throwsStringScannerException('bar')); }); - group("with match", () { + group('with match', () { test('supports an earlier match', () { var scanner = StringScanner('foo bar baz'); scanner.expect('foo '); @@ -56,7 +56,7 @@ void main() { }); }); - group("with position and/or length", () { + group('with position and/or length', () { test('defaults to length 0', () { var scanner = StringScanner('foo bar baz'); scanner.expect('foo '); @@ -105,39 +105,39 @@ void main() { }); }); - group("argument errors", () { + group('argument errors', () { StringScanner scanner; setUp(() { scanner = StringScanner('foo bar baz'); scanner.scan('foo'); }); - test("if match is passed with position", () { + test('if match is passed with position', () { expect( - () => scanner.error("oh no!", match: scanner.lastMatch, position: 1), + () => scanner.error('oh no!', match: scanner.lastMatch, position: 1), throwsArgumentError); }); - test("if match is passed with length", () { - expect(() => scanner.error("oh no!", match: scanner.lastMatch, length: 1), + test('if match is passed with length', () { + expect(() => scanner.error('oh no!', match: scanner.lastMatch, length: 1), throwsArgumentError); }); - test("if position is negative", () { - expect(() => scanner.error("oh no!", position: -1), throwsArgumentError); + test('if position is negative', () { + expect(() => scanner.error('oh no!', position: -1), throwsArgumentError); }); - test("if position is outside the string", () { - expect(() => scanner.error("oh no!", position: 100), throwsArgumentError); + test('if position is outside the string', () { + expect(() => scanner.error('oh no!', position: 100), throwsArgumentError); }); - test("if position + length is outside the string", () { - expect(() => scanner.error("oh no!", position: 7, length: 7), + test('if position + length is outside the string', () { + expect(() => scanner.error('oh no!', position: 7, length: 7), throwsArgumentError); }); - test("if length is negative", () { - expect(() => scanner.error("oh no!", length: -1), throwsArgumentError); + test('if length is negative', () { + expect(() => scanner.error('oh no!', length: -1), throwsArgumentError); }); }); } diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index 876714271..dc9b8cfd1 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -17,20 +17,20 @@ void main() { expect(scanner.column, equals(0)); }); - group("scan()", () { - test("consuming no newlines increases the column but not the line", () { + group('scan()', () { + test('consuming no newlines increases the column but not the line', () { scanner.scan('foo'); expect(scanner.line, equals(0)); expect(scanner.column, equals(3)); }); - test("consuming a newline resets the column and increases the line", () { + test('consuming a newline resets the column and increases the line', () { scanner.expect('foo\nba'); expect(scanner.line, equals(1)); expect(scanner.column, equals(2)); }); - test("consuming multiple newlines resets the column and increases the line", + test('consuming multiple newlines resets the column and increases the line', () { scanner.expect('foo\nbar\r\nb'); expect(scanner.line, equals(2)); @@ -48,15 +48,15 @@ void main() { }); }); - group("readChar()", () { - test("on a non-newline character increases the column but not the line", + group('readChar()', () { + test('on a non-newline character increases the column but not the line', () { scanner.readChar(); expect(scanner.line, equals(0)); expect(scanner.column, equals(1)); }); - test("consuming a newline resets the column and increases the line", () { + test('consuming a newline resets the column and increases the line', () { scanner.expect('foo'); expect(scanner.line, equals(0)); expect(scanner.column, equals(3)); @@ -81,15 +81,15 @@ void main() { }); }); - group("scanChar()", () { - test("on a non-newline character increases the column but not the line", + group('scanChar()', () { + test('on a non-newline character increases the column but not the line', () { scanner.scanChar($f); expect(scanner.line, equals(0)); expect(scanner.column, equals(1)); }); - test("consuming a newline resets the column and increases the line", () { + test('consuming a newline resets the column and increases the line', () { scanner.expect('foo'); expect(scanner.line, equals(0)); expect(scanner.column, equals(3)); @@ -114,28 +114,28 @@ void main() { }); }); - group("position=", () { - test("forward through newlines sets the line and column", () { + group('position=', () { + test('forward through newlines sets the line and column', () { scanner.position = 10; // "foo\nbar\r\nb" expect(scanner.line, equals(2)); expect(scanner.column, equals(1)); }); - test("forward through no newlines sets the column", () { + test('forward through no newlines sets the column', () { scanner.position = 2; // "fo" expect(scanner.line, equals(0)); expect(scanner.column, equals(2)); }); - test("backward through newlines sets the line and column", () { - scanner.scan("foo\nbar\r\nbaz"); + test('backward through newlines sets the line and column', () { + scanner.scan('foo\nbar\r\nbaz'); scanner.position = 2; // "fo" expect(scanner.line, equals(0)); expect(scanner.column, equals(2)); }); - test("backward through no newlines sets the column", () { - scanner.scan("foo\nbar\r\nbaz"); + test('backward through no newlines sets the column', () { + scanner.scan('foo\nbar\r\nbaz'); scanner.position = 10; // "foo\nbar\r\nb" expect(scanner.line, equals(2)); expect(scanner.column, equals(1)); @@ -148,7 +148,7 @@ void main() { }); }); - test("state= restores the line, column, and position", () { + test('state= restores the line, column, and position', () { scanner.scan('foo\nb'); var state = scanner.state; @@ -159,7 +159,7 @@ void main() { expect(scanner.column, equals(1)); }); - test("state= rejects a foreign state", () { + test('state= rejects a foreign state', () { scanner.scan('foo\nb'); expect(() => LineScanner(scanner.string).state = scanner.state, diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index 65694eaac..e2570aeff 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -9,15 +9,15 @@ import 'package:test/test.dart'; import 'utils.dart'; void main() { - testForImplementation("lazy", ([String string]) { + testForImplementation('lazy', ([String string]) { return SpanScanner(string ?? 'foo\nbar\nbaz', sourceUrl: 'source'); }); - testForImplementation("eager", ([String string]) { + testForImplementation('eager', ([String string]) { return SpanScanner.eager(string ?? 'foo\nbar\nbaz', sourceUrl: 'source'); }); - group("within", () { + group('within', () { var text = 'first\nbefore: foo\nbar\nbaz :after\nlast'; var startOffset = text.indexOf('foo'); @@ -28,24 +28,24 @@ void main() { SpanScanner.within(file.span(startOffset, text.indexOf(' :after'))); }); - test("string only includes the span text", () { - expect(scanner.string, equals("foo\nbar\nbaz")); + test('string only includes the span text', () { + expect(scanner.string, equals('foo\nbar\nbaz')); }); - test("line and column are span-relative", () { + test('line and column are span-relative', () { expect(scanner.line, equals(0)); expect(scanner.column, equals(0)); - scanner.scan("foo"); + scanner.scan('foo'); expect(scanner.line, equals(0)); expect(scanner.column, equals(3)); - scanner.scan("\n"); + scanner.scan('\n'); expect(scanner.line, equals(1)); expect(scanner.column, equals(0)); }); - test("tracks the span for the last match", () { + test('tracks the span for the last match', () { scanner.scan('fo'); scanner.scan('o\nba'); @@ -63,7 +63,7 @@ void main() { expect(span.text, equals('o\nba')); }); - test(".spanFrom() returns a span from a previous state", () { + test('.spanFrom() returns a span from a previous state', () { scanner.scan('fo'); var state = scanner.state; scanner.scan('o\nba'); @@ -73,7 +73,7 @@ void main() { expect(span.text, equals('o\nbar\nba')); }); - test(".emptySpan returns an empty span at the current location", () { + test('.emptySpan returns an empty span at the current location', () { scanner.scan('foo\nba'); var span = scanner.emptySpan; @@ -90,14 +90,14 @@ void main() { expect(span.text, equals('')); }); - test(".error() uses an absolute span", () { - scanner.expect("foo"); + test('.error() uses an absolute span', () { + scanner.expect('foo'); expect( - () => scanner.error('oh no!'), throwsStringScannerException("foo")); + () => scanner.error('oh no!'), throwsStringScannerException('foo')); }); - test(".isDone returns true at the end of the span", () { - scanner.expect("foo\nbar\nbaz"); + test('.isDone returns true at the end of the span', () { + scanner.expect('foo\nbar\nbaz'); expect(scanner.isDone, isTrue); }); }); @@ -105,11 +105,11 @@ void main() { void testForImplementation( String name, SpanScanner Function([String string]) create) { - group("for a $name scanner", () { + group('for a $name scanner', () { SpanScanner scanner; setUp(() => scanner = create()); - test("tracks the span for the last match", () { + test('tracks the span for the last match', () { scanner.scan('fo'); scanner.scan('o\nba'); @@ -127,7 +127,7 @@ void testForImplementation( expect(span.text, equals('o\nba')); }); - test(".spanFrom() returns a span from a previous state", () { + test('.spanFrom() returns a span from a previous state', () { scanner.scan('fo'); var state = scanner.state; scanner.scan('o\nba'); @@ -137,7 +137,7 @@ void testForImplementation( expect(span.text, equals('o\nbar\nba')); }); - test(".spanFrom() handles surrogate pairs correctly", () { + test('.spanFrom() handles surrogate pairs correctly', () { scanner = create('fo\u{12345}o'); scanner.scan('fo'); var state = scanner.state; @@ -146,7 +146,7 @@ void testForImplementation( expect(span.text, equals('\u{12345}o')); }); - test(".emptySpan returns an empty span at the current location", () { + test('.emptySpan returns an empty span at the current location', () { scanner.scan('foo\nba'); var span = scanner.emptySpan; diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 9d6d6b860..e1e5b4eb8 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -72,7 +72,7 @@ void main() { expect(scanner.position, equals(0)); }); - test("substring returns the empty string", () { + test('substring returns the empty string', () { expect(scanner.substring(0), isEmpty); }); @@ -130,38 +130,38 @@ void main() { expect(scanner.position, equals(0)); }); - test("a matching scanChar returns true moves forward", () { + test('a matching scanChar returns true moves forward', () { expect(scanner.scanChar($f), isTrue); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(1)); }); - test("a non-matching scanChar returns false and does nothing", () { + test('a non-matching scanChar returns false and does nothing', () { expect(scanner.scanChar($x), isFalse); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(0)); }); - test("a matching expectChar moves forward", () { + test('a matching expectChar moves forward', () { scanner.expectChar($f); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(1)); }); - test("a non-matching expectChar fails", () { + test('a non-matching expectChar fails', () { expect(() => scanner.expectChar($x), throwsFormatException); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(0)); }); - test("a matching scan returns true and changes the state", () { + test('a matching scan returns true and changes the state', () { expect(scanner.scan(RegExp('f(..)')), isTrue); expect(scanner.lastMatch[1], equals('oo')); expect(scanner.position, equals(3)); expect(scanner.rest, equals(' bar')); }); - test("a non-matching scan returns false and sets lastMatch to null", () { + test('a non-matching scan returns false and sets lastMatch to null', () { expect(scanner.matches(RegExp('f(..)')), isTrue); expect(scanner.lastMatch, isNotNull); @@ -171,7 +171,7 @@ void main() { expect(scanner.rest, equals('foo bar')); }); - test("a matching expect changes the state", () { + test('a matching expect changes the state', () { scanner.expect(RegExp('f(..)')); expect(scanner.lastMatch[1], equals('oo')); expect(scanner.position, equals(3)); @@ -179,8 +179,8 @@ void main() { }); test( - "a non-matching expect throws a FormatException and sets lastMatch to " - "null", () { + 'a non-matching expect throws a FormatException and sets lastMatch to ' + 'null', () { expect(scanner.matches(RegExp('f(..)')), isTrue); expect(scanner.lastMatch, isNotNull); @@ -190,7 +190,7 @@ void main() { expect(scanner.rest, equals('foo bar')); }); - test("a matching matches returns true and only changes lastMatch", () { + test('a matching matches returns true and only changes lastMatch', () { expect(scanner.matches(RegExp('f(..)')), isTrue); expect(scanner.lastMatch[1], equals('oo')); expect(scanner.position, equals(0)); @@ -205,15 +205,15 @@ void main() { expect(scanner.rest, equals('foo bar')); }); - test("substring from the beginning returns the empty string", () { + test('substring from the beginning returns the empty string', () { expect(scanner.substring(0), isEmpty); }); - test("substring with a custom end returns the substring", () { + test('substring with a custom end returns the substring', () { expect(scanner.substring(0, 3), equals('foo')); }); - test("substring with the string length returns the whole string", () { + test('substring with the string length returns the whole string', () { expect(scanner.substring(0, 7), equals('foo bar')); }); @@ -332,33 +332,33 @@ void main() { expect(scanner.position, equals(7)); }); - test("scan returns false and sets lastMatch to null", () { + test('scan returns false and sets lastMatch to null', () { expect(scanner.scan(RegExp('.')), isFalse); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(7)); }); - test("expect throws a FormatException and sets lastMatch to null", () { + test('expect throws a FormatException and sets lastMatch to null', () { expect(() => scanner.expect(RegExp('.')), throwsFormatException); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(7)); }); - test("matches returns false sets lastMatch to null", () { + test('matches returns false sets lastMatch to null', () { expect(scanner.matches(RegExp('.')), isFalse); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(7)); }); - test("substring from the beginning returns the whole string", () { + test('substring from the beginning returns the whole string', () { expect(scanner.substring(0), equals('foo bar')); }); - test("substring with a custom start returns a substring from there", () { + test('substring with a custom start returns a substring from there', () { expect(scanner.substring(4), equals('bar')); }); - test("substring with a custom start and end returns that substring", () { + test('substring with a custom start and end returns that substring', () { expect(scanner.substring(3, 5), equals(' b')); }); From c9b3111a830ecdab4cd7018bbcc7f982db1ac342 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 9 Mar 2020 12:21:41 -0700 Subject: [PATCH 038/102] Remove lints duplicated in pkg:pedantic --- pkgs/string_scanner/analysis_options.yaml | 37 ++--------------------- 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index c9899f2e2..7684be711 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -1,26 +1,20 @@ include: package:pedantic/analysis_options.yaml + analyzer: strong-mode: implicit-casts: false + linter: rules: - - always_declare_return_types - avoid_bool_literals_in_conditional_expressions - avoid_classes_with_only_static_members - - avoid_empty_else - avoid_function_literals_in_foreach_calls - - avoid_init_to_null - - avoid_null_checks_in_equality_operators - - avoid_relative_lib_imports - avoid_renaming_method_parameters - - avoid_return_types_on_setters #- avoid_returning_null - avoid_returning_null_for_future - avoid_returning_null_for_void - avoid_returning_this - - avoid_shadowing_type_parameters - avoid_single_cascade_in_expression_statements - - avoid_types_as_parameter_names - avoid_unused_constructor_parameters - await_only_futures - camel_case_types @@ -30,8 +24,6 @@ linter: - constant_identifier_names - control_flow_in_finally - directives_ordering - - empty_catches - - empty_constructor_bodies - empty_statements - file_names - hash_and_equals @@ -39,53 +31,28 @@ linter: - invariant_booleans - iterable_contains_unrelated_type - join_return_with_assignment - - library_names - - library_prefixes - list_remove_unrelated_type - literal_only_boolean_expressions - no_adjacent_strings_in_list - - no_duplicate_case_values - non_constant_identifier_names - - null_closures - - omit_local_variable_types - only_throw_errors - overridden_fields - package_api_docs - package_names - package_prefixed_library_names - - prefer_adjacent_string_concatenation - - prefer_collection_literals - - prefer_conditional_assignment - prefer_const_constructors - - prefer_contains - - prefer_equal_for_default_values - - prefer_final_fields #- prefer_final_locals - - prefer_generic_function_type_aliases - prefer_initializing_formals - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - prefer_null_aware_operators - prefer_typing_uninitialized_variables - - recursive_getters - - slash_for_doc_comments - test_types_in_equals - throw_in_finally - - type_init_formals - - unawaited_futures - unnecessary_await_in_return - unnecessary_brace_in_string_interps - - unnecessary_const - unnecessary_getters_setters - unnecessary_lambdas - - unnecessary_new - unnecessary_null_aware_assignments - unnecessary_parenthesis - unnecessary_statements - - unnecessary_this - - unrelated_type_equality_checks - - use_function_type_syntax_for_parameters - - use_rethrow_when_possible - - valid_regexps - void_checks From 2f624e5d4687dd8b29033d1cccad4d25a950072b Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 9 Mar 2020 12:28:05 -0700 Subject: [PATCH 039/102] Enable and fix a number of lints --- pkgs/string_scanner/analysis_options.yaml | 24 +++++++++-- pkgs/string_scanner/example/example.dart | 6 +-- .../lib/src/eager_span_scanner.dart | 12 +++--- pkgs/string_scanner/lib/src/line_scanner.dart | 12 +++--- .../lib/src/relative_span_scanner.dart | 8 ++-- pkgs/string_scanner/lib/src/span_scanner.dart | 8 ++-- .../lib/src/string_scanner.dart | 10 ++--- pkgs/string_scanner/test/error_test.dart | 32 +++++++-------- .../test/line_scanner_test.dart | 2 +- .../test/span_scanner_test.dart | 40 ++++++++++--------- .../test/string_scanner_test.dart | 4 +- 11 files changed, 89 insertions(+), 69 deletions(-) diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index 7684be711..60abe63e6 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -7,19 +7,21 @@ analyzer: linter: rules: - avoid_bool_literals_in_conditional_expressions + - avoid_catching_errors - avoid_classes_with_only_static_members - avoid_function_literals_in_foreach_calls + - avoid_private_typedef_functions + - avoid_redundant_argument_values - avoid_renaming_method_parameters - #- avoid_returning_null - avoid_returning_null_for_future - avoid_returning_null_for_void - avoid_returning_this - avoid_single_cascade_in_expression_statements - avoid_unused_constructor_parameters + - avoid_void_async - await_only_futures - camel_case_types - cancel_subscriptions - #- cascade_invocations - comment_references - constant_identifier_names - control_flow_in_finally @@ -31,21 +33,34 @@ linter: - invariant_booleans - iterable_contains_unrelated_type - join_return_with_assignment + - lines_longer_than_80_chars - list_remove_unrelated_type - literal_only_boolean_expressions + - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list + - no_runtimeType_toString - non_constant_identifier_names - only_throw_errors - overridden_fields - package_api_docs - package_names - package_prefixed_library_names + - prefer_asserts_in_initializer_lists - prefer_const_constructors - #- prefer_final_locals + - prefer_const_declarations + - prefer_expression_function_bodies + - prefer_final_locals + - prefer_function_declarations_over_variables - prefer_initializing_formals + - prefer_inlined_adds - prefer_interpolation_to_compose_strings + - prefer_is_not_operator - prefer_null_aware_operators + - prefer_relative_imports - prefer_typing_uninitialized_variables + - prefer_void_to_null + - provide_deprecation_message + - sort_pub_dependencies - test_types_in_equals - throw_in_finally - unnecessary_await_in_return @@ -53,6 +68,9 @@ linter: - unnecessary_getters_setters - unnecessary_lambdas - unnecessary_null_aware_assignments + - unnecessary_overrides - unnecessary_parenthesis - unnecessary_statements + - unnecessary_string_interpolations + - use_string_buffers - void_checks diff --git a/pkgs/string_scanner/example/example.dart b/pkgs/string_scanner/example/example.dart index 0358967e4..e92677f1c 100644 --- a/pkgs/string_scanner/example/example.dart +++ b/pkgs/string_scanner/example/example.dart @@ -12,11 +12,11 @@ void main(List args) { num parseNumber(String source) { // Scan a number ("1", "1.5", "-3"). - var scanner = StringScanner(source); + final scanner = StringScanner(source); // [Scanner.scan] tries to consume a [Pattern] and returns whether or not it // succeeded. It will move the scan pointer past the end of the pattern. - var negative = scanner.scan('-'); + final negative = scanner.scan('-'); // [Scanner.expect] consumes a [Pattern] and throws a [FormatError] if it // fails. Like [Scanner.scan], it will move the scan pointer forward. @@ -28,7 +28,7 @@ num parseNumber(String source) { if (scanner.scan('.')) { scanner.expect(RegExp(r'\d+')); - var decimal = scanner.lastMatch[0]; + final decimal = scanner.lastMatch[0]; number += int.parse(decimal) / math.pow(10, decimal.length); } diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index d34e4f7c3..848cb72c4 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -44,11 +44,11 @@ class EagerSpanScanner extends SpanScanner { @override set position(int newPosition) { - var oldPosition = position; + final oldPosition = position; super.position = newPosition; if (newPosition > oldPosition) { - var newlines = _newlinesIn(string.substring(oldPosition, newPosition)); + final newlines = _newlinesIn(string.substring(oldPosition, newPosition)); _line += newlines.length; if (newlines.isEmpty) { _column += newPosition - oldPosition; @@ -56,7 +56,7 @@ class EagerSpanScanner extends SpanScanner { _column = newPosition - newlines.last.end; } } else { - var newlines = _newlinesIn(string.substring(newPosition, oldPosition)); + final newlines = _newlinesIn(string.substring(newPosition, oldPosition)); if (_betweenCRLF) newlines.removeLast(); _line -= newlines.length; @@ -81,7 +81,7 @@ class EagerSpanScanner extends SpanScanner { @override int readChar() { - var character = super.readChar(); + final character = super.readChar(); _adjustLineAndColumn(character); return character; } @@ -100,7 +100,7 @@ class EagerSpanScanner extends SpanScanner { bool scan(Pattern pattern) { if (!super.scan(pattern)) return false; - var newlines = _newlinesIn(lastMatch[0]); + final newlines = _newlinesIn(lastMatch[0]); _line += newlines.length; if (newlines.isEmpty) { _column += lastMatch[0].length; @@ -114,7 +114,7 @@ class EagerSpanScanner extends SpanScanner { /// Returns a list of [Match]es describing all the newlines in [text], which /// is assumed to end at [position]. List _newlinesIn(String text) { - var newlines = _newlineRegExp.allMatches(text).toList(); + final newlines = _newlineRegExp.allMatches(text).toList(); if (_betweenCRLF) newlines.removeLast(); return newlines; } diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 180d9239b..9e7d918fa 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -48,11 +48,11 @@ class LineScanner extends StringScanner { @override set position(int newPosition) { - var oldPosition = position; + final oldPosition = position; super.position = newPosition; if (newPosition > oldPosition) { - var newlines = _newlinesIn(string.substring(oldPosition, newPosition)); + final newlines = _newlinesIn(string.substring(oldPosition, newPosition)); _line += newlines.length; if (newlines.isEmpty) { _column += newPosition - oldPosition; @@ -60,7 +60,7 @@ class LineScanner extends StringScanner { _column = newPosition - newlines.last.end; } } else { - var newlines = _newlinesIn(string.substring(newPosition, oldPosition)); + final newlines = _newlinesIn(string.substring(newPosition, oldPosition)); if (_betweenCRLF) newlines.removeLast(); _line -= newlines.length; @@ -85,7 +85,7 @@ class LineScanner extends StringScanner { @override int readChar() { - var character = super.readChar(); + final character = super.readChar(); _adjustLineAndColumn(character); return character; } @@ -104,7 +104,7 @@ class LineScanner extends StringScanner { bool scan(Pattern pattern) { if (!super.scan(pattern)) return false; - var newlines = _newlinesIn(lastMatch[0]); + final newlines = _newlinesIn(lastMatch[0]); _line += newlines.length; if (newlines.isEmpty) { _column += lastMatch[0].length; @@ -118,7 +118,7 @@ class LineScanner extends StringScanner { /// Returns a list of [Match]es describing all the newlines in [text], which /// is assumed to end at [position]. List _newlinesIn(String text) { - var newlines = _newlineRegExp.allMatches(text).toList(); + final newlines = _newlineRegExp.allMatches(text).toList(); if (_betweenCRLF) newlines.removeLast(); return newlines; } diff --git a/pkgs/string_scanner/lib/src/relative_span_scanner.dart b/pkgs/string_scanner/lib/src/relative_span_scanner.dart index 096bee3ad..a7a035abb 100644 --- a/pkgs/string_scanner/lib/src/relative_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/relative_span_scanner.dart @@ -34,8 +34,8 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { @override int get column { - var line = _sourceFile.getLine(_startLocation.offset + position); - var column = + final line = _sourceFile.getLine(_startLocation.offset + position); + final column = _sourceFile.getColumn(_startLocation.offset + position, line: line); return line == _startLocation.line ? column - _startLocation.column @@ -74,7 +74,7 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { @override FileSpan spanFrom(LineScannerState startState, [LineScannerState endState]) { - var endPosition = endState == null ? position : endState.position; + final endPosition = endState == null ? position : endState.position; return _sourceFile.span(_startLocation.offset + startState.position, _startLocation.offset + endPosition); } @@ -99,7 +99,7 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { position ??= match == null ? this.position : match.start; length ??= match == null ? 1 : match.end - match.start; - var span = _sourceFile.span(_startLocation.offset + position, + final span = _sourceFile.span(_startLocation.offset + position, _startLocation.offset + position + length); throw StringScannerException(message, span, string); } diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index 732a76f18..1a8ca2ade 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -82,14 +82,14 @@ class SpanScanner extends StringScanner implements LineScanner { /// /// This scans through [span]`.text, but emits new spans from [span]`.file` in /// their appropriate relative positions. The [string] field contains only - /// [span]`.text`, and [position], [line], and [column] are all relative to the - /// span. + /// [span]`.text`, and [position], [line], and [column] are all relative to + /// the span. factory SpanScanner.within(FileSpan span) = RelativeSpanScanner; /// Creates a [FileSpan] representing the source range between [startState] /// and the current position. FileSpan spanFrom(LineScannerState startState, [LineScannerState endState]) { - var endPosition = endState == null ? position : endState.position; + final endPosition = endState == null ? position : endState.position; return _sourceFile.span(startState.position, endPosition); } @@ -112,7 +112,7 @@ class SpanScanner extends StringScanner implements LineScanner { position ??= match == null ? this.position : match.start; length ??= match == null ? 0 : match.end - match.start; - var span = _sourceFile.span(position, position + length); + final span = _sourceFile.span(position, position + length); throw StringScannerException(message, span, string); } } diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 1739a7cd4..55ff17d3a 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -81,7 +81,7 @@ class StringScanner { /// affect [lastMatch]. int peekChar([int offset]) { offset ??= 0; - var index = position + offset; + final index = position + offset; if (index < 0 || index >= string.length) return null; return string.codeUnitAt(index); } @@ -123,7 +123,7 @@ class StringScanner { /// /// Returns whether or not [pattern] matched. bool scan(Pattern pattern) { - var success = matches(pattern); + final success = matches(pattern); if (success) { _position = _lastMatch.end; _lastMatchPosition = _position; @@ -143,7 +143,7 @@ class StringScanner { if (name == null) { if (pattern is RegExp) { - var source = pattern.pattern; + final source = pattern.pattern; name = '/$source/'; } else { name = @@ -201,8 +201,8 @@ class StringScanner { position ??= match == null ? this.position : match.start; length ??= match == null ? 0 : match.end - match.start; - var sourceFile = SourceFile.fromString(string, url: sourceUrl); - var span = sourceFile.span(position, position + length); + final sourceFile = SourceFile.fromString(string, url: sourceUrl); + final span = sourceFile.span(position, position + length); throw StringScannerException(message, span, string); } diff --git a/pkgs/string_scanner/test/error_test.dart b/pkgs/string_scanner/test/error_test.dart index dfa71755c..617304070 100644 --- a/pkgs/string_scanner/test/error_test.dart +++ b/pkgs/string_scanner/test/error_test.dart @@ -9,7 +9,7 @@ import 'utils.dart'; void main() { test('defaults to the last match', () { - var scanner = StringScanner('foo bar baz'); + final scanner = StringScanner('foo bar baz'); scanner.expect('foo '); scanner.expect('bar'); expect(() => scanner.error('oh no!'), throwsStringScannerException('bar')); @@ -17,39 +17,39 @@ void main() { group('with match', () { test('supports an earlier match', () { - var scanner = StringScanner('foo bar baz'); + final scanner = StringScanner('foo bar baz'); scanner.expect('foo '); - var match = scanner.lastMatch; + final match = scanner.lastMatch; scanner.expect('bar'); expect(() => scanner.error('oh no!', match: match), throwsStringScannerException('foo ')); }); test('supports a match on a previous line', () { - var scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); + final scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo '); scanner.expect('re'); - var match = scanner.lastMatch; + final match = scanner.lastMatch; scanner.expect(' mi\nearth '); expect(() => scanner.error('oh no!', match: match), throwsStringScannerException('re')); }); test('supports a multiline match', () { - var scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); + final scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar '); scanner.expect('baz\ndo'); - var match = scanner.lastMatch; + final match = scanner.lastMatch; scanner.expect(' re mi'); expect(() => scanner.error('oh no!', match: match), throwsStringScannerException('baz\ndo')); }); test('supports a match after position', () { - var scanner = StringScanner('foo bar baz'); + final scanner = StringScanner('foo bar baz'); scanner.expect('foo '); scanner.expect('bar'); - var match = scanner.lastMatch; + final match = scanner.lastMatch; scanner.position = 0; expect(() => scanner.error('oh no!', match: match), throwsStringScannerException('bar')); @@ -58,48 +58,48 @@ void main() { group('with position and/or length', () { test('defaults to length 0', () { - var scanner = StringScanner('foo bar baz'); + final scanner = StringScanner('foo bar baz'); scanner.expect('foo '); expect(() => scanner.error('oh no!', position: 1), throwsStringScannerException('')); }); test('defaults to the current position', () { - var scanner = StringScanner('foo bar baz'); + final scanner = StringScanner('foo bar baz'); scanner.expect('foo '); expect(() => scanner.error('oh no!', length: 3), throwsStringScannerException('bar')); }); test('supports an earlier position', () { - var scanner = StringScanner('foo bar baz'); + final scanner = StringScanner('foo bar baz'); scanner.expect('foo '); expect(() => scanner.error('oh no!', position: 1, length: 2), throwsStringScannerException('oo')); }); test('supports a position on a previous line', () { - var scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); + final scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo re mi\nearth'); expect(() => scanner.error('oh no!', position: 15, length: 2), throwsStringScannerException('re')); }); test('supports a multiline length', () { - var scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); + final scanner = StringScanner('foo bar baz\ndo re mi\nearth fire water'); scanner.expect('foo bar baz\ndo re mi\nearth'); expect(() => scanner.error('oh no!', position: 8, length: 8), throwsStringScannerException('baz\ndo r')); }); test('supports a position after the current one', () { - var scanner = StringScanner('foo bar baz'); + final scanner = StringScanner('foo bar baz'); expect(() => scanner.error('oh no!', position: 4, length: 3), throwsStringScannerException('bar')); }); test('supports a length of zero', () { - var scanner = StringScanner('foo bar baz'); + final scanner = StringScanner('foo bar baz'); expect(() => scanner.error('oh no!', position: 4, length: 0), throwsStringScannerException('')); }); diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index dc9b8cfd1..aafc74a07 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -150,7 +150,7 @@ void main() { test('state= restores the line, column, and position', () { scanner.scan('foo\nb'); - var state = scanner.state; + final state = scanner.state; scanner.scan('ar\nba'); scanner.state = state; diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index e2570aeff..2034d0a8d 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -9,21 +9,23 @@ import 'package:test/test.dart'; import 'utils.dart'; void main() { - testForImplementation('lazy', ([String string]) { - return SpanScanner(string ?? 'foo\nbar\nbaz', sourceUrl: 'source'); - }); + testForImplementation( + 'lazy', + ([String string]) => + SpanScanner(string ?? 'foo\nbar\nbaz', sourceUrl: 'source')); - testForImplementation('eager', ([String string]) { - return SpanScanner.eager(string ?? 'foo\nbar\nbaz', sourceUrl: 'source'); - }); + testForImplementation( + 'eager', + ([String string]) => + SpanScanner.eager(string ?? 'foo\nbar\nbaz', sourceUrl: 'source')); group('within', () { - var text = 'first\nbefore: foo\nbar\nbaz :after\nlast'; - var startOffset = text.indexOf('foo'); + const text = 'first\nbefore: foo\nbar\nbaz :after\nlast'; + final startOffset = text.indexOf('foo'); SpanScanner scanner; setUp(() { - var file = SourceFile.fromString(text, url: 'source'); + final file = SourceFile.fromString(text, url: 'source'); scanner = SpanScanner.within(file.span(startOffset, text.indexOf(' :after'))); }); @@ -49,7 +51,7 @@ void main() { scanner.scan('fo'); scanner.scan('o\nba'); - var span = scanner.lastSpan; + final span = scanner.lastSpan; expect(span.start.offset, equals(startOffset + 2)); expect(span.start.line, equals(1)); expect(span.start.column, equals(10)); @@ -65,18 +67,18 @@ void main() { test('.spanFrom() returns a span from a previous state', () { scanner.scan('fo'); - var state = scanner.state; + final state = scanner.state; scanner.scan('o\nba'); scanner.scan('r\nba'); - var span = scanner.spanFrom(state); + final span = scanner.spanFrom(state); expect(span.text, equals('o\nbar\nba')); }); test('.emptySpan returns an empty span at the current location', () { scanner.scan('foo\nba'); - var span = scanner.emptySpan; + final span = scanner.emptySpan; expect(span.start.offset, equals(startOffset + 6)); expect(span.start.line, equals(2)); expect(span.start.column, equals(2)); @@ -113,7 +115,7 @@ void testForImplementation( scanner.scan('fo'); scanner.scan('o\nba'); - var span = scanner.lastSpan; + final span = scanner.lastSpan; expect(span.start.offset, equals(2)); expect(span.start.line, equals(0)); expect(span.start.column, equals(2)); @@ -129,27 +131,27 @@ void testForImplementation( test('.spanFrom() returns a span from a previous state', () { scanner.scan('fo'); - var state = scanner.state; + final state = scanner.state; scanner.scan('o\nba'); scanner.scan('r\nba'); - var span = scanner.spanFrom(state); + final span = scanner.spanFrom(state); expect(span.text, equals('o\nbar\nba')); }); test('.spanFrom() handles surrogate pairs correctly', () { scanner = create('fo\u{12345}o'); scanner.scan('fo'); - var state = scanner.state; + final state = scanner.state; scanner.scan('\u{12345}o'); - var span = scanner.spanFrom(state); + final span = scanner.spanFrom(state); expect(span.text, equals('\u{12345}o')); }); test('.emptySpan returns an empty span at the current location', () { scanner.scan('foo\nba'); - var span = scanner.emptySpan; + final span = scanner.emptySpan; expect(span.start.offset, equals(6)); expect(span.start.line, equals(1)); expect(span.start.column, equals(2)); diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index e1e5b4eb8..9dee9d123 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -374,7 +374,7 @@ void main() { }); test('setting and resetting position clears lastMatch', () { - var oldPosition = scanner.position; + final oldPosition = scanner.position; scanner.position = 1; scanner.position = oldPosition; expect(scanner.lastMatch, isNull); @@ -395,7 +395,7 @@ void main() { group('a scanner constructed with a custom position', () { test('starts scanning from that position', () { - var scanner = StringScanner('foo bar', position: 1); + final scanner = StringScanner('foo bar', position: 1); expect(scanner.position, equals(1)); expect(scanner.rest, equals('oo bar')); From cf713fe332b2508eb6bde464a54ba0747448bf24 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 9 Mar 2020 12:28:23 -0700 Subject: [PATCH 040/102] Fix readme Align with example/example.dart --- pkgs/string_scanner/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkgs/string_scanner/README.md b/pkgs/string_scanner/README.md index 15aa24261..6427218c2 100644 --- a/pkgs/string_scanner/README.md +++ b/pkgs/string_scanner/README.md @@ -2,29 +2,29 @@ This package exposes a `StringScanner` type that makes it easy to parse a string using a series of `Pattern`s. For example: ```dart -import 'dart:math'; +import 'dart:math' as math; import 'package:string_scanner/string_scanner.dart'; num parseNumber(String source) { // Scan a number ("1", "1.5", "-3"). - var scanner = StringScanner(source); + final scanner = StringScanner(source); // [Scanner.scan] tries to consume a [Pattern] and returns whether or not it // succeeded. It will move the scan pointer past the end of the pattern. - var negative = scanner.scan("-"); + final negative = scanner.scan('-'); // [Scanner.expect] consumes a [Pattern] and throws a [FormatError] if it // fails. Like [Scanner.scan], it will move the scan pointer forward. - scanner.expect(RegExp(r"\d+")); + scanner.expect(RegExp(r'\d+')); // [Scanner.lastMatch] holds the [MatchData] for the most recent call to // [Scanner.scan], [Scanner.expect], or [Scanner.matches]. var number = num.parse(scanner.lastMatch[0]); - if (scanner.scan(".")) { - scanner.expect(RegExp(r"\d+")); - var decimal = scanner.lastMatch[0]; + if (scanner.scan('.')) { + scanner.expect(RegExp(r'\d+')); + final decimal = scanner.lastMatch[0]; number += int.parse(decimal) / math.pow(10, decimal.length); } From 7bd4cda7a955554fd7a4c0b646d4e400b3987a3f Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Wed, 15 Jul 2020 18:58:16 -0700 Subject: [PATCH 041/102] Merge the null_safety branch into master (dart-lang/string_scanner#22) --- pkgs/string_scanner/.travis.yml | 6 +- pkgs/string_scanner/CHANGELOG.md | 4 + pkgs/string_scanner/analysis_options.yaml | 3 + pkgs/string_scanner/example/example.dart | 4 +- .../lib/src/eager_span_scanner.dart | 12 +-- pkgs/string_scanner/lib/src/exception.dart | 2 +- pkgs/string_scanner/lib/src/line_scanner.dart | 8 +- .../lib/src/relative_span_scanner.dart | 13 ++- pkgs/string_scanner/lib/src/span_scanner.dart | 17 ++-- .../lib/src/string_scanner.dart | 31 ++++--- pkgs/string_scanner/lib/src/utils.dart | 3 +- pkgs/string_scanner/pubspec.yaml | 85 +++++++++++++++++-- pkgs/string_scanner/test/error_test.dart | 2 +- .../test/line_scanner_test.dart | 2 +- .../test/span_scanner_test.dart | 12 +-- .../test/string_scanner_test.dart | 26 +++--- pkgs/string_scanner/test/utils.dart | 2 +- 17 files changed, 153 insertions(+), 79 deletions(-) diff --git a/pkgs/string_scanner/.travis.yml b/pkgs/string_scanner/.travis.yml index 48e46ca18..dd4f4372d 100644 --- a/pkgs/string_scanner/.travis.yml +++ b/pkgs/string_scanner/.travis.yml @@ -2,7 +2,6 @@ language: dart dart: - dev - - 2.0.0 dart_task: - test: --platform vm,chrome @@ -15,13 +14,10 @@ matrix: - dart: dev dart_task: dartanalyzer: --fatal-warnings --fatal-hints . - - dart: 2.0.0 - dart_task: - dartanalyzer: --fatal-warnings . # Only building master means that we don't run two builds for each pull request. branches: - only: [master] + only: [master, null_safety] cache: directories: diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index fb7f74dd1..abe488c8d 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0-nullsafety + +- Migrate to null safety. + ## 1.0.5 - Added an example. diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index 60abe63e6..2407da620 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -4,6 +4,9 @@ analyzer: strong-mode: implicit-casts: false + enable-experiment: + - non-nullable + linter: rules: - avoid_bool_literals_in_conditional_expressions diff --git a/pkgs/string_scanner/example/example.dart b/pkgs/string_scanner/example/example.dart index e92677f1c..fd36a73c1 100644 --- a/pkgs/string_scanner/example/example.dart +++ b/pkgs/string_scanner/example/example.dart @@ -24,11 +24,11 @@ num parseNumber(String source) { // [Scanner.lastMatch] holds the [MatchData] for the most recent call to // [Scanner.scan], [Scanner.expect], or [Scanner.matches]. - var number = num.parse(scanner.lastMatch[0]); + var number = num.parse((scanner.lastMatch![0])!); if (scanner.scan('.')) { scanner.expect(RegExp(r'\d+')); - final decimal = scanner.lastMatch[0]; + final decimal = scanner.lastMatch![0]!; number += int.parse(decimal) / math.pow(10, decimal.length); } diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index 848cb72c4..415b9f32c 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -31,8 +31,7 @@ class EagerSpanScanner extends SpanScanner { @override set state(LineScannerState state) { - if (state is! _EagerSpanScannerState || - !identical((state as _EagerSpanScannerState)._scanner, this)) { + if (state is! _EagerSpanScannerState || !identical(state._scanner, this)) { throw ArgumentError('The given LineScannerState was not returned by ' 'this LineScanner.'); } @@ -69,7 +68,7 @@ class EagerSpanScanner extends SpanScanner { } } - EagerSpanScanner(String string, {sourceUrl, int position}) + EagerSpanScanner(String string, {sourceUrl, int? position}) : super(string, sourceUrl: sourceUrl, position: position); @override @@ -99,13 +98,14 @@ class EagerSpanScanner extends SpanScanner { @override bool scan(Pattern pattern) { if (!super.scan(pattern)) return false; + final firstMatch = (lastMatch![0])!; - final newlines = _newlinesIn(lastMatch[0]); + final newlines = _newlinesIn(firstMatch); _line += newlines.length; if (newlines.isEmpty) { - _column += lastMatch[0].length; + _column += firstMatch.length; } else { - _column = lastMatch[0].length - newlines.last.end; + _column = firstMatch.length - newlines.last.end; } return true; diff --git a/pkgs/string_scanner/lib/src/exception.dart b/pkgs/string_scanner/lib/src/exception.dart index 8c994b5ae..8aa7aabea 100644 --- a/pkgs/string_scanner/lib/src/exception.dart +++ b/pkgs/string_scanner/lib/src/exception.dart @@ -14,7 +14,7 @@ class StringScannerException extends SourceSpanFormatException { /// The URL of the source file being parsed. /// /// This may be `null`, indicating that the source URL is unknown. - Uri get sourceUrl => span.sourceUrl; + Uri? get sourceUrl => span?.sourceUrl; StringScannerException(String message, SourceSpan span, String source) : super(message, span, source); diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 9e7d918fa..358d4c1cb 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -73,7 +73,7 @@ class LineScanner extends StringScanner { } } - LineScanner(String string, {sourceUrl, int position}) + LineScanner(String string, {sourceUrl, int? position}) : super(string, sourceUrl: sourceUrl, position: position); @override @@ -104,12 +104,12 @@ class LineScanner extends StringScanner { bool scan(Pattern pattern) { if (!super.scan(pattern)) return false; - final newlines = _newlinesIn(lastMatch[0]); + final newlines = _newlinesIn(lastMatch![0]!); _line += newlines.length; if (newlines.isEmpty) { - _column += lastMatch[0].length; + _column += (lastMatch![0])!.length; } else { - _column = lastMatch[0].length - newlines.last.end; + _column = (lastMatch![0])!.length - newlines.last.end; } return true; diff --git a/pkgs/string_scanner/lib/src/relative_span_scanner.dart b/pkgs/string_scanner/lib/src/relative_span_scanner.dart index a7a035abb..150d5071e 100644 --- a/pkgs/string_scanner/lib/src/relative_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/relative_span_scanner.dart @@ -47,8 +47,7 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { @override set state(LineScannerState state) { - if (state is! _SpanScannerState || - !identical((state as _SpanScannerState)._scanner, this)) { + if (state is! _SpanScannerState || !identical(state._scanner, this)) { throw ArgumentError('The given LineScannerState was not returned by ' 'this LineScanner.'); } @@ -57,8 +56,8 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { } @override - FileSpan get lastSpan => _lastSpan; - FileSpan _lastSpan; + FileSpan? get lastSpan => _lastSpan; + FileSpan? _lastSpan; @override FileLocation get location => @@ -73,7 +72,7 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { super(span.text, sourceUrl: span.sourceUrl); @override - FileSpan spanFrom(LineScannerState startState, [LineScannerState endState]) { + FileSpan spanFrom(LineScannerState startState, [LineScannerState? endState]) { final endPosition = endState == null ? position : endState.position; return _sourceFile.span(_startLocation.offset + startState.position, _startLocation.offset + endPosition); @@ -87,12 +86,12 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { } _lastSpan = _sourceFile.span(_startLocation.offset + position, - _startLocation.offset + lastMatch.end); + _startLocation.offset + lastMatch!.end); return true; } @override - void error(String message, {Match match, int position, int length}) { + Never error(String message, {Match? match, int? position, int? length}) { validateErrorArgs(string, match, position, length); if (match == null && position == null && length == null) match = lastMatch; diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index 1a8ca2ade..806a8f8ea 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -29,8 +29,7 @@ class SpanScanner extends StringScanner implements LineScanner { @override set state(LineScannerState state) { - if (state is! _SpanScannerState || - !identical((state as _SpanScannerState)._scanner, this)) { + if (state is! _SpanScannerState || !identical(state._scanner, this)) { throw ArgumentError('The given LineScannerState was not returned by ' 'this LineScanner.'); } @@ -42,12 +41,12 @@ class SpanScanner extends StringScanner implements LineScanner { /// /// This is the span for the entire match. There's no way to get spans for /// subgroups since [Match] exposes no information about their positions. - FileSpan get lastSpan { + FileSpan? get lastSpan { if (lastMatch == null) _lastSpan = null; return _lastSpan; } - FileSpan _lastSpan; + FileSpan? _lastSpan; /// The current location of the scanner. FileLocation get location => _sourceFile.location(position); @@ -60,7 +59,7 @@ class SpanScanner extends StringScanner implements LineScanner { /// [sourceUrl] is used as [SourceLocation.sourceUrl] for the returned /// [FileSpan]s as well as for error reporting. It can be a [String], a /// [Uri], or `null`. - SpanScanner(String string, {sourceUrl, int position}) + SpanScanner(String string, {sourceUrl, int? position}) : _sourceFile = SourceFile.fromString(string, url: sourceUrl), super(string, sourceUrl: sourceUrl, position: position); @@ -75,7 +74,7 @@ class SpanScanner extends StringScanner implements LineScanner { /// itself and its `LineScannerState` are eagerly computed. To limit their /// memory footprint, returned spans and locations will still lazily compute /// their line and column numbers. - factory SpanScanner.eager(String string, {sourceUrl, int position}) = + factory SpanScanner.eager(String string, {sourceUrl, int? position}) = EagerSpanScanner; /// Creates a new [SpanScanner] that scans within [span]. @@ -88,7 +87,7 @@ class SpanScanner extends StringScanner implements LineScanner { /// Creates a [FileSpan] representing the source range between [startState] /// and the current position. - FileSpan spanFrom(LineScannerState startState, [LineScannerState endState]) { + FileSpan spanFrom(LineScannerState startState, [LineScannerState? endState]) { final endPosition = endState == null ? position : endState.position; return _sourceFile.span(startState.position, endPosition); } @@ -100,12 +99,12 @@ class SpanScanner extends StringScanner implements LineScanner { return false; } - _lastSpan = _sourceFile.span(position, lastMatch.end); + _lastSpan = _sourceFile.span(position, lastMatch!.end); return true; } @override - void error(String message, {Match match, int position, int length}) { + Never error(String message, {Match? match, int? position, int? length}) { validateErrorArgs(string, match, position, length); if (match == null && position == null && length == null) match = lastMatch; diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 55ff17d3a..f29bc3ac6 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:charcode/charcode.dart'; -import 'package:meta/meta.dart'; import 'package:source_span/source_span.dart'; import 'exception.dart'; @@ -15,7 +14,7 @@ class StringScanner { /// /// This is used for error reporting. It may be `null`, indicating that the /// source URL is unknown or unavailable. - final Uri sourceUrl; + final Uri? sourceUrl; /// The string being scanned through. final String string; @@ -36,15 +35,15 @@ class StringScanner { /// The data about the previous match made by the scanner. /// /// If the last match failed, this will be `null`. - Match get 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; + Match? _lastMatch; + int? _lastMatchPosition; /// The portion of the string that hasn't yet been scanned. String get rest => string.substring(position); @@ -57,9 +56,10 @@ class StringScanner { /// [position] defaults to 0, the beginning of the string. [sourceUrl] is the /// URL of the source of the string being scanned, if available. It can be /// a [String], a [Uri], or `null`. - StringScanner(this.string, {sourceUrl, int position}) - : sourceUrl = - sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl as Uri { + StringScanner(this.string, {sourceUrl, int? position}) + : sourceUrl = sourceUrl == null + ? null + : sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl as Uri { if (position != null) this.position = position; } @@ -79,7 +79,7 @@ class StringScanner { /// /// This returns `null` if [offset] points outside the string. It doesn't /// affect [lastMatch]. - int peekChar([int offset]) { + int? peekChar([int? offset]) { offset ??= 0; final index = position + offset; if (index < 0 || index >= string.length) return null; @@ -102,7 +102,7 @@ class StringScanner { /// describing the position of the failure. [name] is used in this error as /// the expected name of the character being matched; if it's `null`, the /// character itself is used instead. - void expectChar(int character, {String name}) { + void expectChar(int character, {String? name}) { if (scanChar(character)) return; if (name == null) { @@ -125,7 +125,7 @@ class StringScanner { bool scan(Pattern pattern) { final success = matches(pattern); if (success) { - _position = _lastMatch.end; + _position = _lastMatch!.end; _lastMatchPosition = _position; } return success; @@ -138,7 +138,7 @@ class StringScanner { /// position of the failure. [name] is used in this error as the expected name /// of the pattern being matched; if it's `null`, the pattern itself is used /// instead. - void expect(Pattern pattern, {String name}) { + void expect(Pattern pattern, {String? name}) { if (scan(pattern)) return; if (name == null) { @@ -175,7 +175,7 @@ class StringScanner { /// /// Unlike [String.substring], [end] defaults to [position] rather than the /// end of the string. - String substring(int start, [int end]) { + String substring(int start, [int? end]) { end ??= position; return string.substring(start, end); } @@ -193,8 +193,7 @@ class StringScanner { /// 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]. - @alwaysThrows - void error(String message, {Match match, int position, int length}) { + Never error(String message, {Match? match, int? position, int? length}) { validateErrorArgs(string, match, position, length); if (match == null && position == null && length == null) match = lastMatch; @@ -209,7 +208,7 @@ class StringScanner { // TODO(nweiz): Make this handle long lines more gracefully. /// Throws a [FormatException] describing that [name] is expected at the /// current position in the string. - void _fail(String name) { + Never _fail(String name) { error('expected $name.', position: position, length: 0); } } diff --git a/pkgs/string_scanner/lib/src/utils.dart b/pkgs/string_scanner/lib/src/utils.dart index 7fe3d5241..52dfb6360 100644 --- a/pkgs/string_scanner/lib/src/utils.dart +++ b/pkgs/string_scanner/lib/src/utils.dart @@ -5,7 +5,8 @@ import 'string_scanner.dart'; /// Validates the arguments passed to [StringScanner.error]. -void validateErrorArgs(String string, Match match, int position, int length) { +void validateErrorArgs( + String string, Match? match, int? position, int? length) { if (match != null && (position != null || length != null)) { throw ArgumentError("Can't pass both match and position/length."); } diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index d5cefceda..7a9826d6c 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,17 +1,90 @@ name: string_scanner -version: 1.0.5 +version: 1.1.0-nullsafety description: A class for parsing strings using a sequence of patterns. homepage: https://github.com/dart-lang/string_scanner environment: - sdk: '>=2.0.0 <3.0.0' + sdk: '>=2.9.0-18.0 <2.9.0' dependencies: - charcode: ^1.1.0 - meta: ^1.1.0 - source_span: ^1.4.0 + charcode: '>=1.2.0-nullsafety <1.2.0' + source_span: '>=1.8.0-nullsafety <1.8.0' dev_dependencies: - test: ^1.0.0 + test: '>=1.16.0-nullsafety <1.16.0' +dependency_overrides: + async: + git: + url: git://github.com/dart-lang/async.git + ref: null_safety + boolean_selector: + git: + url: git://github.com/dart-lang/boolean_selector.git + ref: null_safety + charcode: + git: + url: git://github.com/dart-lang/charcode.git + ref: null_safety + collection: 1.15.0-nullsafety + js: + git: + url: git://github.com/dart-lang/sdk.git + path: pkg/js + matcher: + git: + url: git://github.com/dart-lang/matcher.git + ref: null_safety + meta: 1.3.0-nullsafety + path: + git: + url: git://github.com/dart-lang/path.git + ref: null_safety + pedantic: + git: + url: git://github.com/dart-lang/pedantic.git + ref: null_safety + pool: + git: + url: git://github.com/dart-lang/pool.git + ref: null_safety + source_maps: + git: + url: git://github.com/dart-lang/source_maps.git + ref: null_safety + source_map_stack_trace: + git: + url: git://github.com/dart-lang/source_map_stack_trace.git + ref: null_safety + source_span: + git: + url: git://github.com/dart-lang/source_span.git + ref: null_safety + stack_trace: + git: + url: git://github.com/dart-lang/stack_trace.git + ref: null_safety + stream_channel: + git: + url: git://github.com/dart-lang/stream_channel.git + ref: null_safety + term_glyph: + git: + url: git://github.com/dart-lang/term_glyph.git + ref: null_safety + test_api: + git: + url: git://github.com/dart-lang/test.git + ref: null_safety + path: pkgs/test_api + test_core: + git: + url: git://github.com/dart-lang/test.git + ref: null_safety + path: pkgs/test_core + test: + git: + url: git://github.com/dart-lang/test.git + ref: null_safety + path: pkgs/test diff --git a/pkgs/string_scanner/test/error_test.dart b/pkgs/string_scanner/test/error_test.dart index 617304070..1f98c3243 100644 --- a/pkgs/string_scanner/test/error_test.dart +++ b/pkgs/string_scanner/test/error_test.dart @@ -106,7 +106,7 @@ void main() { }); group('argument errors', () { - StringScanner scanner; + late StringScanner scanner; setUp(() { scanner = StringScanner('foo bar baz'); scanner.scan('foo'); diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index aafc74a07..0bbd499ab 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -7,7 +7,7 @@ import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; void main() { - LineScanner scanner; + late LineScanner scanner; setUp(() { scanner = LineScanner('foo\nbar\r\nbaz'); }); diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index 2034d0a8d..828745fe1 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -11,19 +11,19 @@ import 'utils.dart'; void main() { testForImplementation( 'lazy', - ([String string]) => + ([String? string]) => SpanScanner(string ?? 'foo\nbar\nbaz', sourceUrl: 'source')); testForImplementation( 'eager', - ([String string]) => + ([String? string]) => SpanScanner.eager(string ?? 'foo\nbar\nbaz', sourceUrl: 'source')); group('within', () { const text = 'first\nbefore: foo\nbar\nbaz :after\nlast'; final startOffset = text.indexOf('foo'); - SpanScanner scanner; + late SpanScanner scanner; setUp(() { final file = SourceFile.fromString(text, url: 'source'); scanner = @@ -51,7 +51,7 @@ void main() { scanner.scan('fo'); scanner.scan('o\nba'); - final span = scanner.lastSpan; + final span = scanner.lastSpan!; expect(span.start.offset, equals(startOffset + 2)); expect(span.start.line, equals(1)); expect(span.start.column, equals(10)); @@ -108,14 +108,14 @@ void main() { void testForImplementation( String name, SpanScanner Function([String string]) create) { group('for a $name scanner', () { - SpanScanner scanner; + late SpanScanner scanner; setUp(() => scanner = create()); test('tracks the span for the last match', () { scanner.scan('fo'); scanner.scan('o\nba'); - final span = scanner.lastSpan; + final span = scanner.lastSpan!; expect(span.start.offset, equals(2)); expect(span.start.line, equals(0)); expect(span.start.column, equals(2)); diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 9dee9d123..0327499c7 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -8,7 +8,7 @@ import 'package:test/test.dart'; void main() { group('with an empty string', () { - StringScanner scanner; + late StringScanner scanner; setUp(() { scanner = StringScanner(''); }); @@ -90,7 +90,7 @@ void main() { }); group('at the beginning of a string', () { - StringScanner scanner; + late StringScanner scanner; setUp(() { scanner = StringScanner('foo bar'); }); @@ -156,7 +156,7 @@ void main() { test('a matching scan returns true and changes the state', () { expect(scanner.scan(RegExp('f(..)')), isTrue); - expect(scanner.lastMatch[1], equals('oo')); + expect(scanner.lastMatch![1], equals('oo')); expect(scanner.position, equals(3)); expect(scanner.rest, equals(' bar')); }); @@ -173,7 +173,7 @@ void main() { test('a matching expect changes the state', () { scanner.expect(RegExp('f(..)')); - expect(scanner.lastMatch[1], equals('oo')); + expect(scanner.lastMatch![1], equals('oo')); expect(scanner.position, equals(3)); expect(scanner.rest, equals(' bar')); }); @@ -192,7 +192,7 @@ void main() { test('a matching matches returns true and only changes lastMatch', () { expect(scanner.matches(RegExp('f(..)')), isTrue); - expect(scanner.lastMatch[1], equals('oo')); + expect(scanner.lastMatch![1], equals('oo')); expect(scanner.position, equals(0)); expect(scanner.rest, equals('foo bar')); }); @@ -223,7 +223,7 @@ void main() { expect(scanner.rest, equals('oo bar')); expect(scanner.scan(RegExp('oo.')), isTrue); - expect(scanner.lastMatch[0], equals('oo ')); + expect(scanner.lastMatch![0], equals('oo ')); expect(scanner.position, equals(4)); expect(scanner.rest, equals('bar')); }); @@ -242,19 +242,19 @@ void main() { test('scan accepts any Pattern', () { expect(scanner.scan('foo'), isTrue); - expect(scanner.lastMatch[0], equals('foo')); + expect(scanner.lastMatch![0], equals('foo')); expect(scanner.position, equals(3)); expect(scanner.rest, equals(' bar')); }); test('scans multiple times', () { expect(scanner.scan(RegExp('f(..)')), isTrue); - expect(scanner.lastMatch[1], equals('oo')); + expect(scanner.lastMatch![1], equals('oo')); expect(scanner.position, equals(3)); expect(scanner.rest, equals(' bar')); expect(scanner.scan(RegExp(' b(..)')), isTrue); - expect(scanner.lastMatch[1], equals('ar')); + expect(scanner.lastMatch![1], equals('ar')); expect(scanner.position, equals(7)); expect(scanner.rest, equals('')); expect(scanner.isDone, isTrue); @@ -263,7 +263,7 @@ void main() { }); group('after a scan', () { - StringScanner scanner; + late StringScanner scanner; setUp(() { scanner = StringScanner('foo bar'); expect(scanner.scan('foo'), isTrue); @@ -289,7 +289,7 @@ void main() { }); group('at the end of a string', () { - StringScanner scanner; + late StringScanner scanner; setUp(() { scanner = StringScanner('foo bar'); expect(scanner.scan('foo bar'), isTrue); @@ -368,7 +368,7 @@ void main() { expect(scanner.rest, equals('oo bar')); expect(scanner.scan(RegExp('oo.')), isTrue); - expect(scanner.lastMatch[0], equals('oo ')); + expect(scanner.lastMatch![0], equals('oo ')); expect(scanner.position, equals(4)); expect(scanner.rest, equals('bar')); }); @@ -400,7 +400,7 @@ void main() { expect(scanner.rest, equals('oo bar')); expect(scanner.scan(RegExp('oo.')), isTrue); - expect(scanner.lastMatch[0], equals('oo ')); + expect(scanner.lastMatch![0], equals('oo ')); expect(scanner.position, equals(4)); expect(scanner.rest, equals('bar')); }); diff --git a/pkgs/string_scanner/test/utils.dart b/pkgs/string_scanner/test/utils.dart index 676b69555..ca03c064f 100644 --- a/pkgs/string_scanner/test/utils.dart +++ b/pkgs/string_scanner/test/utils.dart @@ -9,4 +9,4 @@ import 'package:test/test.dart'; /// [StringScannerException] with the given [text]. Matcher throwsStringScannerException(String text) => throwsA(const TypeMatcher() - .having((e) => e.span.text, 'span.text', text)); + .having((e) => e.span!.text, 'span.text', text)); From 9a6ecc8fc1bf03a37249a6c7ffcae138d27e36fa Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 21 Jul 2020 19:41:49 -0700 Subject: [PATCH 042/102] update for the 2.10 dev sdk (dart-lang/string_scanner#23) This is in preparation for the actual 2.10 dev sdk release. --- pkgs/string_scanner/.travis.yml | 10 ++--- pkgs/string_scanner/pubspec.yaml | 68 +++++++++++--------------------- 2 files changed, 29 insertions(+), 49 deletions(-) diff --git a/pkgs/string_scanner/.travis.yml b/pkgs/string_scanner/.travis.yml index dd4f4372d..16a9cd3d1 100644 --- a/pkgs/string_scanner/.travis.yml +++ b/pkgs/string_scanner/.travis.yml @@ -1,23 +1,23 @@ language: dart dart: - - dev + - preview/raw/2.10.0-0.2-dev dart_task: - test: --platform vm,chrome matrix: include: - # Only validate formatting using the dev release - - dart: dev + # Only validate formatting using the preview/raw/2.10.0-0.2-dev release + - dart: preview/raw/2.10.0-0.2-dev dart_task: dartfmt - - dart: dev + - dart: preview/raw/2.10.0-0.2-dev dart_task: dartanalyzer: --fatal-warnings --fatal-hints . # Only building master means that we don't run two builds for each pull request. branches: - only: [master, null_safety] + only: [master] cache: directories: diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 7a9826d6c..1c34a645c 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -5,7 +5,8 @@ description: A class for parsing strings using a sequence of patterns. homepage: https://github.com/dart-lang/string_scanner environment: - sdk: '>=2.9.0-18.0 <2.9.0' + # This must remain a tight constraint until nnbd is stable + sdk: '>=2.10.0-0 <2.10.0' dependencies: charcode: '>=1.2.0-nullsafety <1.2.0' @@ -16,75 +17,54 @@ dev_dependencies: dependency_overrides: async: - git: - url: git://github.com/dart-lang/async.git - ref: null_safety + git: git://github.com/dart-lang/async.git boolean_selector: - git: - url: git://github.com/dart-lang/boolean_selector.git - ref: null_safety + git: git://github.com/dart-lang/boolean_selector.git charcode: - git: - url: git://github.com/dart-lang/charcode.git - ref: null_safety - collection: 1.15.0-nullsafety + git: git://github.com/dart-lang/charcode.git + collection: + git: git://github.com/dart-lang/collection.git js: git: url: git://github.com/dart-lang/sdk.git path: pkg/js + ref: 2-10-pkgs matcher: + git: git://github.com/dart-lang/matcher.git + meta: git: - url: git://github.com/dart-lang/matcher.git - ref: null_safety - meta: 1.3.0-nullsafety + url: git://github.com/dart-lang/sdk.git + path: pkg/meta + ref: 2-10-pkgs path: - git: - url: git://github.com/dart-lang/path.git - ref: null_safety + git: git://github.com/dart-lang/path.git pedantic: - git: - url: git://github.com/dart-lang/pedantic.git - ref: null_safety + git: git://github.com/dart-lang/pedantic.git pool: - git: - url: git://github.com/dart-lang/pool.git - ref: null_safety + git: git://github.com/dart-lang/pool.git source_maps: - git: - url: git://github.com/dart-lang/source_maps.git - ref: null_safety + git: git://github.com/dart-lang/source_maps.git source_map_stack_trace: - git: - url: git://github.com/dart-lang/source_map_stack_trace.git - ref: null_safety + git: git://github.com/dart-lang/source_map_stack_trace.git source_span: - git: - url: git://github.com/dart-lang/source_span.git - ref: null_safety + git: git://github.com/dart-lang/source_span.git stack_trace: - git: - url: git://github.com/dart-lang/stack_trace.git - ref: null_safety + git: git://github.com/dart-lang/stack_trace.git stream_channel: - git: - url: git://github.com/dart-lang/stream_channel.git - ref: null_safety + git: git://github.com/dart-lang/stream_channel.git term_glyph: - git: - url: git://github.com/dart-lang/term_glyph.git - ref: null_safety + git: git://github.com/dart-lang/term_glyph.git test_api: git: url: git://github.com/dart-lang/test.git - ref: null_safety path: pkgs/test_api test_core: git: url: git://github.com/dart-lang/test.git - ref: null_safety path: pkgs/test_core test: git: url: git://github.com/dart-lang/test.git - ref: null_safety path: pkgs/test + typed_data: + git: git://github.com/dart-lang/typed_data.git From 91f74c8e6211392c6fb896b72ba520e261016381 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 28 Jul 2020 13:49:12 -0700 Subject: [PATCH 043/102] Delete .test_config No longer needed --- pkgs/string_scanner/.test_config | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/string_scanner/.test_config diff --git a/pkgs/string_scanner/.test_config b/pkgs/string_scanner/.test_config deleted file mode 100644 index 412fc5c5c..000000000 --- a/pkgs/string_scanner/.test_config +++ /dev/null @@ -1,3 +0,0 @@ -{ - "test_package": true -} \ No newline at end of file From bd748d6e5396b5632a60152ed9df7636c86dbf8e Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 28 Jul 2020 16:50:30 -0700 Subject: [PATCH 044/102] Update Travis-CI config to use dev channel (dart-lang/string_scanner#24) --- pkgs/string_scanner/.travis.yml | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/pkgs/string_scanner/.travis.yml b/pkgs/string_scanner/.travis.yml index 16a9cd3d1..481e06250 100644 --- a/pkgs/string_scanner/.travis.yml +++ b/pkgs/string_scanner/.travis.yml @@ -1,19 +1,12 @@ language: dart dart: - - preview/raw/2.10.0-0.2-dev + - dev dart_task: - test: --platform vm,chrome - -matrix: - include: - # Only validate formatting using the preview/raw/2.10.0-0.2-dev release - - dart: preview/raw/2.10.0-0.2-dev - dart_task: dartfmt - - dart: preview/raw/2.10.0-0.2-dev - dart_task: - dartanalyzer: --fatal-warnings --fatal-hints . + - dartfmt + - dartanalyzer: --fatal-warnings --fatal-hints . # Only building master means that we don't run two builds for each pull request. branches: From d880864ffcfee47e9f0611af5efdfeeab01dcab4 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 4 Sep 2020 09:03:32 -0700 Subject: [PATCH 045/102] fix formatting for latest dev SDK --- pkgs/string_scanner/lib/src/string_scanner.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index f29bc3ac6..564774c3a 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -59,7 +59,9 @@ class StringScanner { StringScanner(this.string, {sourceUrl, int? position}) : sourceUrl = sourceUrl == null ? null - : sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl as Uri { + : sourceUrl is String + ? Uri.parse(sourceUrl) + : sourceUrl as Uri { if (position != null) this.position = position; } From 5b24ebd45b4909b2ad03af2c0f95673dd896601e Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 22 Sep 2020 09:19:17 -0700 Subject: [PATCH 046/102] Prepare for the 2.11 dev SDKs (dart-lang/string_scanner#25) Bump the upper bound to allow 2.10 stable and 2.11.0 dev SDK versions. --- pkgs/string_scanner/CHANGELOG.md | 4 ++++ pkgs/string_scanner/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index abe488c8d..316655105 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0-nullsafety.1 + +- Allow 2.10 stable and 2.11.0 dev SDK versions. + ## 1.1.0-nullsafety - Migrate to null safety. diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 1c34a645c..566f482a6 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,12 +1,12 @@ name: string_scanner -version: 1.1.0-nullsafety +version: 1.1.0-nullsafety.1 description: A class for parsing strings using a sequence of patterns. homepage: https://github.com/dart-lang/string_scanner environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.10.0' + sdk: '>=2.10.0-0 <2.11.0' dependencies: charcode: '>=1.2.0-nullsafety <1.2.0' From cf1691818929bd9349fc89574d0a71e495495003 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Fri, 23 Oct 2020 13:11:02 -0700 Subject: [PATCH 047/102] allow the 2.12 prerelease sdks (dart-lang/string_scanner#26) --- pkgs/string_scanner/CHANGELOG.md | 4 ++++ pkgs/string_scanner/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 316655105..4379f83db 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0-nullsafety.2 + +* Allow prerelease versions of the 2.12 sdk. + ## 1.1.0-nullsafety.1 - Allow 2.10 stable and 2.11.0 dev SDK versions. diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 566f482a6..9684e14f1 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,12 +1,12 @@ name: string_scanner -version: 1.1.0-nullsafety.1 +version: 1.1.0-nullsafety.2 description: A class for parsing strings using a sequence of patterns. homepage: https://github.com/dart-lang/string_scanner environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.11.0' + sdk: '>=2.10.0-0 <2.12.0' dependencies: charcode: '>=1.2.0-nullsafety <1.2.0' From 1c3b95377d5fef77e90849437a74f263ec60430e Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Fri, 23 Oct 2020 14:32:23 -0700 Subject: [PATCH 048/102] remove dep overrides (dart-lang/string_scanner#27) --- pkgs/string_scanner/pubspec.yaml | 54 -------------------------------- 1 file changed, 54 deletions(-) diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 9684e14f1..3319875fa 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -14,57 +14,3 @@ dependencies: dev_dependencies: test: '>=1.16.0-nullsafety <1.16.0' - -dependency_overrides: - async: - git: git://github.com/dart-lang/async.git - boolean_selector: - git: git://github.com/dart-lang/boolean_selector.git - charcode: - git: git://github.com/dart-lang/charcode.git - collection: - git: git://github.com/dart-lang/collection.git - js: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/js - ref: 2-10-pkgs - matcher: - git: git://github.com/dart-lang/matcher.git - meta: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/meta - ref: 2-10-pkgs - path: - git: git://github.com/dart-lang/path.git - pedantic: - git: git://github.com/dart-lang/pedantic.git - pool: - git: git://github.com/dart-lang/pool.git - source_maps: - git: git://github.com/dart-lang/source_maps.git - source_map_stack_trace: - git: git://github.com/dart-lang/source_map_stack_trace.git - source_span: - git: git://github.com/dart-lang/source_span.git - stack_trace: - git: git://github.com/dart-lang/stack_trace.git - stream_channel: - git: git://github.com/dart-lang/stream_channel.git - term_glyph: - git: git://github.com/dart-lang/term_glyph.git - test_api: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_api - test_core: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_core - test: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test - typed_data: - git: git://github.com/dart-lang/typed_data.git From a9f33b096e206ec5ae7a26d3666ffbbb35d8a06a Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 3 Nov 2020 14:35:30 -0800 Subject: [PATCH 049/102] Bump SDK constraints for pub (dart-lang/string_scanner#28) Use a 2.12.0 lower bound since pub does not understand allowed experiments for earlier versions. Use a 3.0.0 upper bound to avoid a warning in pub and to give some flexibility in publishing for stable. --- pkgs/string_scanner/CHANGELOG.md | 5 +++++ pkgs/string_scanner/pubspec.yaml | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 4379f83db..c8c700800 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.1.0-nullsafety.3 + +* Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release + guidelines. + ## 1.1.0-nullsafety.2 * Allow prerelease versions of the 2.12 sdk. diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 3319875fa..6099c54e3 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,12 +1,11 @@ name: string_scanner -version: 1.1.0-nullsafety.2 +version: 1.1.0-nullsafety.3 description: A class for parsing strings using a sequence of patterns. homepage: https://github.com/dart-lang/string_scanner environment: - # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.12.0' + sdk: ">=2.12.0-0 <3.0.0" dependencies: charcode: '>=1.2.0-nullsafety <1.2.0' From d092aadc46f75be94791ba62fdf13cd64ddfa7c8 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 11 Nov 2020 11:13:21 -0800 Subject: [PATCH 050/102] remove redundant experiment (dart-lang/string_scanner#31) * remove redundant experiment * bump dev version * bump dev version --- pkgs/string_scanner/CHANGELOG.md | 2 ++ pkgs/string_scanner/analysis_options.yaml | 3 --- pkgs/string_scanner/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index c8c700800..08216dc60 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.1.0-nullsafety.4-dev + ## 1.1.0-nullsafety.3 * Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index 2407da620..60abe63e6 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -4,9 +4,6 @@ analyzer: strong-mode: implicit-casts: false - enable-experiment: - - non-nullable - linter: rules: - avoid_bool_literals_in_conditional_expressions diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 6099c54e3..0d29f2e05 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.1.0-nullsafety.3 +version: 1.1.0-nullsafety.4-dev description: A class for parsing strings using a sequence of patterns. homepage: https://github.com/dart-lang/string_scanner From d769b0e6c94945d29b83175ed06f9eaec1571cbb Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Mon, 16 Nov 2020 14:32:23 -0800 Subject: [PATCH 051/102] Remove dependency on package:charcode (dart-lang/string_scanner#29) Copy in the charcode constants that are used in this package to a private library. --- pkgs/string_scanner/lib/src/charcode.dart | 24 +++++++++++++++++++ .../lib/src/eager_span_scanner.dart | 3 +-- pkgs/string_scanner/lib/src/line_scanner.dart | 3 +-- .../lib/src/string_scanner.dart | 4 ++-- pkgs/string_scanner/pubspec.yaml | 1 - .../test/line_scanner_test.dart | 2 +- .../test/string_scanner_test.dart | 2 +- 7 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 pkgs/string_scanner/lib/src/charcode.dart diff --git a/pkgs/string_scanner/lib/src/charcode.dart b/pkgs/string_scanner/lib/src/charcode.dart new file mode 100644 index 000000000..d15774935 --- /dev/null +++ b/pkgs/string_scanner/lib/src/charcode.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// Character '\'. +const int $backslash = 0x5C; + +/// "Carriage return" control character. +const int $cr = 0x0D; + +/// Character '"'. +const int $doubleQuote = 0x22; + +/// Character 'f'. +const int $f = 0x66; + +/// "Line feed" control character. +const int $lf = 0x0A; + +/// Space character. +const int $space = 0x20; + +/// Character 'x'. +const int $x = 0x78; diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index 415b9f32c..d27a818fa 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -2,8 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:charcode/ascii.dart'; - +import 'charcode.dart'; import 'line_scanner.dart'; import 'span_scanner.dart'; diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 358d4c1cb..af6b6e705 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -2,8 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:charcode/ascii.dart'; - +import 'charcode.dart'; import 'string_scanner.dart'; // Note that much of this code is duplicated in eager_span_scanner.dart. diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 564774c3a..5d69c7565 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -2,9 +2,9 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:charcode/charcode.dart'; import 'package:source_span/source_span.dart'; +import 'charcode.dart'; import 'exception.dart'; import 'utils.dart'; @@ -110,7 +110,7 @@ class StringScanner { if (name == null) { if (character == $backslash) { name = r'"\"'; - } else if (character == $double_quote) { + } else if (character == $doubleQuote) { name = r'"\""'; } else { name = '"${String.fromCharCode(character)}"'; diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 0d29f2e05..1b2c2e5c9 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -8,7 +8,6 @@ environment: sdk: ">=2.12.0-0 <3.0.0" dependencies: - charcode: '>=1.2.0-nullsafety <1.2.0' source_span: '>=1.8.0-nullsafety <1.8.0' dev_dependencies: diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index 0bbd499ab..a3deff1b7 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:charcode/charcode.dart'; +import 'package:string_scanner/src/charcode.dart'; import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 0327499c7..34176b8a3 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:charcode/charcode.dart'; +import 'package:string_scanner/src/charcode.dart'; import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; From 85f4f74336993146894b0f8482fb40107cf4de59 Mon Sep 17 00:00:00 2001 From: Alexander Thomas Date: Wed, 20 Jan 2021 18:26:21 +0100 Subject: [PATCH 052/102] Migrate to GitHub Actions (dart-lang/string_scanner#32) * Delete .travis.yml --- .../.github/workflows/test-package.yml | 64 +++++++++++++++++++ pkgs/string_scanner/.travis.yml | 17 ----- 2 files changed, 64 insertions(+), 17 deletions(-) create mode 100644 pkgs/string_scanner/.github/workflows/test-package.yml delete mode 100644 pkgs/string_scanner/.travis.yml diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml new file mode 100644 index 000000000..0a2a87433 --- /dev/null +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -0,0 +1,64 @@ +name: Dart CI + +on: + # Run on PRs and pushes to the default branch. + push: + branches: [ master ] + pull_request: + branches: [ master ] + schedule: + - cron: "0 0 * * 0" + +env: + PUB_ENVIRONMENT: bot.github + +jobs: + # Check code formatting and static analysis on a single OS (linux) + # against Dart dev. + analyze: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Check formatting + run: dart format --output=none --set-exit-if-changed . + if: always() && steps.install.outcome == 'success' + - name: Analyze code + run: dart analyze --fatal-infos + if: always() && steps.install.outcome == 'success' + + # Run tests on a matrix consisting of two dimensions: + # 1. OS: ubuntu-latest, (macos-latest, windows-latest) + # 2. release channel: dev + test: + needs: analyze + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Add macos-latest and/or windows-latest if relevant for this package. + os: [ubuntu-latest] + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Run VM tests + run: dart test --platform vm + if: always() && steps.install.outcome == 'success' + - name: Run Chrome tests + run: dart test --platform chrome + if: always() && steps.install.outcome == 'success' diff --git a/pkgs/string_scanner/.travis.yml b/pkgs/string_scanner/.travis.yml deleted file mode 100644 index 481e06250..000000000 --- a/pkgs/string_scanner/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: dart - -dart: - - dev - -dart_task: - - test: --platform vm,chrome - - dartfmt - - dartanalyzer: --fatal-warnings --fatal-hints . - -# Only building master means that we don't run two builds for each pull request. -branches: - only: [master] - -cache: - directories: - - $HOME/.pub-cache From 4bbbff29df9d12317b1c42eb089e60571b7c3742 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Fri, 29 Jan 2021 14:47:54 -0800 Subject: [PATCH 053/102] Revert "Remove dependency on package:charcode (dart-lang/string_scanner#29)" (dart-lang/string_scanner#33) This reverts commit d769b0e6c94945d29b83175ed06f9eaec1571cbb. Since this has not been published or rolled through to the SDK or Flutter we will hold it back to reduce risk. --- pkgs/string_scanner/lib/src/charcode.dart | 24 ------------------- .../lib/src/eager_span_scanner.dart | 3 ++- pkgs/string_scanner/lib/src/line_scanner.dart | 3 ++- .../lib/src/string_scanner.dart | 4 ++-- pkgs/string_scanner/pubspec.yaml | 1 + .../test/line_scanner_test.dart | 2 +- .../test/string_scanner_test.dart | 2 +- 7 files changed, 9 insertions(+), 30 deletions(-) delete mode 100644 pkgs/string_scanner/lib/src/charcode.dart diff --git a/pkgs/string_scanner/lib/src/charcode.dart b/pkgs/string_scanner/lib/src/charcode.dart deleted file mode 100644 index d15774935..000000000 --- a/pkgs/string_scanner/lib/src/charcode.dart +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -/// Character '\'. -const int $backslash = 0x5C; - -/// "Carriage return" control character. -const int $cr = 0x0D; - -/// Character '"'. -const int $doubleQuote = 0x22; - -/// Character 'f'. -const int $f = 0x66; - -/// "Line feed" control character. -const int $lf = 0x0A; - -/// Space character. -const int $space = 0x20; - -/// Character 'x'. -const int $x = 0x78; diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index d27a818fa..415b9f32c 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -2,7 +2,8 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'charcode.dart'; +import 'package:charcode/ascii.dart'; + import 'line_scanner.dart'; import 'span_scanner.dart'; diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index af6b6e705..358d4c1cb 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -2,7 +2,8 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'charcode.dart'; +import 'package:charcode/ascii.dart'; + import 'string_scanner.dart'; // Note that much of this code is duplicated in eager_span_scanner.dart. diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 5d69c7565..564774c3a 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -2,9 +2,9 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:charcode/charcode.dart'; import 'package:source_span/source_span.dart'; -import 'charcode.dart'; import 'exception.dart'; import 'utils.dart'; @@ -110,7 +110,7 @@ class StringScanner { if (name == null) { if (character == $backslash) { name = r'"\"'; - } else if (character == $doubleQuote) { + } else if (character == $double_quote) { name = r'"\""'; } else { name = '"${String.fromCharCode(character)}"'; diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 1b2c2e5c9..0d29f2e05 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -8,6 +8,7 @@ environment: sdk: ">=2.12.0-0 <3.0.0" dependencies: + charcode: '>=1.2.0-nullsafety <1.2.0' source_span: '>=1.8.0-nullsafety <1.8.0' dev_dependencies: diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index a3deff1b7..0bbd499ab 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:string_scanner/src/charcode.dart'; +import 'package:charcode/charcode.dart'; import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 34176b8a3..0327499c7 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:string_scanner/src/charcode.dart'; +import 'package:charcode/charcode.dart'; import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; From e05804976dcfe0de678609b6f47cfa172a52d3be Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 2 Feb 2021 15:49:51 -0800 Subject: [PATCH 054/102] Prepare for stable release of null safety (dart-lang/string_scanner#34) --- pkgs/string_scanner/CHANGELOG.md | 4 +++- pkgs/string_scanner/pubspec.yaml | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 08216dc60..4465d5191 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,4 +1,6 @@ -## 1.1.0-nullsafety.4-dev +## 1.1.0 + +* Stable release for null safety. ## 1.1.0-nullsafety.3 diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 0d29f2e05..5ecd164e3 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.1.0-nullsafety.4-dev +version: 1.1.0 description: A class for parsing strings using a sequence of patterns. homepage: https://github.com/dart-lang/string_scanner @@ -8,8 +8,8 @@ environment: sdk: ">=2.12.0-0 <3.0.0" dependencies: - charcode: '>=1.2.0-nullsafety <1.2.0' - source_span: '>=1.8.0-nullsafety <1.8.0' + charcode: ^1.2.0 + source_span: ^1.8.0 dev_dependencies: - test: '>=1.16.0-nullsafety <1.16.0' + test: ^1.16.0-nullsafety From 57097299c2e45e96b572a6ca4e9780e50a730050 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 4 Feb 2021 16:17:00 -0800 Subject: [PATCH 055/102] Revert "Revert "Remove dependency on package:charcode (dart-lang/string_scanner#29)" (dart-lang/string_scanner#33)" (dart-lang/string_scanner#36) This reverts commit 4bbbff29df9d12317b1c42eb089e60571b7c3742. --- pkgs/string_scanner/CHANGELOG.md | 2 ++ pkgs/string_scanner/lib/src/charcode.dart | 24 +++++++++++++++++++ .../lib/src/eager_span_scanner.dart | 3 +-- pkgs/string_scanner/lib/src/line_scanner.dart | 3 +-- .../lib/src/string_scanner.dart | 4 ++-- pkgs/string_scanner/pubspec.yaml | 3 +-- .../test/line_scanner_test.dart | 2 +- .../test/string_scanner_test.dart | 2 +- 8 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 pkgs/string_scanner/lib/src/charcode.dart diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 4465d5191..2a76ec94d 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.1.1-dev + ## 1.1.0 * Stable release for null safety. diff --git a/pkgs/string_scanner/lib/src/charcode.dart b/pkgs/string_scanner/lib/src/charcode.dart new file mode 100644 index 000000000..d15774935 --- /dev/null +++ b/pkgs/string_scanner/lib/src/charcode.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// Character '\'. +const int $backslash = 0x5C; + +/// "Carriage return" control character. +const int $cr = 0x0D; + +/// Character '"'. +const int $doubleQuote = 0x22; + +/// Character 'f'. +const int $f = 0x66; + +/// "Line feed" control character. +const int $lf = 0x0A; + +/// Space character. +const int $space = 0x20; + +/// Character 'x'. +const int $x = 0x78; diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index 415b9f32c..d27a818fa 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -2,8 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:charcode/ascii.dart'; - +import 'charcode.dart'; import 'line_scanner.dart'; import 'span_scanner.dart'; diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 358d4c1cb..af6b6e705 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -2,8 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:charcode/ascii.dart'; - +import 'charcode.dart'; import 'string_scanner.dart'; // Note that much of this code is duplicated in eager_span_scanner.dart. diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 564774c3a..5d69c7565 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -2,9 +2,9 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:charcode/charcode.dart'; import 'package:source_span/source_span.dart'; +import 'charcode.dart'; import 'exception.dart'; import 'utils.dart'; @@ -110,7 +110,7 @@ class StringScanner { if (name == null) { if (character == $backslash) { name = r'"\"'; - } else if (character == $double_quote) { + } else if (character == $doubleQuote) { name = r'"\""'; } else { name = '"${String.fromCharCode(character)}"'; diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 5ecd164e3..9eee52bfd 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.1.0 +version: 1.1.1-dev description: A class for parsing strings using a sequence of patterns. homepage: https://github.com/dart-lang/string_scanner @@ -8,7 +8,6 @@ environment: sdk: ">=2.12.0-0 <3.0.0" dependencies: - charcode: ^1.2.0 source_span: ^1.8.0 dev_dependencies: diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index 0bbd499ab..a3deff1b7 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:charcode/charcode.dart'; +import 'package:string_scanner/src/charcode.dart'; import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 0327499c7..34176b8a3 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:charcode/charcode.dart'; +import 'package:string_scanner/src/charcode.dart'; import 'package:string_scanner/string_scanner.dart'; import 'package:test/test.dart'; From cbcb9dec78d5d4b9002792f26dbc5905d7faf87e Mon Sep 17 00:00:00 2001 From: Franklin Yow <58489007+franklinyow@users.noreply.github.com> Date: Thu, 1 Apr 2021 16:58:46 -0700 Subject: [PATCH 056/102] Update LICENSE (dart-lang/string_scanner#37) Changes to comply with internal review --- pkgs/string_scanner/LICENSE | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/LICENSE b/pkgs/string_scanner/LICENSE index 5c60afea3..000cd7bec 100644 --- a/pkgs/string_scanner/LICENSE +++ b/pkgs/string_scanner/LICENSE @@ -1,4 +1,5 @@ -Copyright 2014, the Dart project authors. All rights reserved. +Copyright 2014, the Dart project authors. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -9,7 +10,7 @@ met: copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. From ce86c26e703c3f69e41c289b8fea22eddda7d68f Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sat, 5 Jun 2021 12:55:50 -0700 Subject: [PATCH 057/102] add dependabot --- pkgs/string_scanner/.github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 pkgs/string_scanner/.github/dependabot.yml diff --git a/pkgs/string_scanner/.github/dependabot.yml b/pkgs/string_scanner/.github/dependabot.yml new file mode 100644 index 000000000..430a85e7d --- /dev/null +++ b/pkgs/string_scanner/.github/dependabot.yml @@ -0,0 +1,11 @@ +# Set update schedule for GitHub Actions +# See https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot + +version: 2 +updates: + +- package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every weekday + interval: "daily" From 74bcd128c5a00d4b220894198387e97e718f4e8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Jun 2021 13:02:14 -0700 Subject: [PATCH 058/102] Bump dart-lang/setup-dart from 0.3 to 1 (dart-lang/string_scanner#38) * Bump dart-lang/setup-dart from 0.3 to 1 Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 0.3 to 1. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/v0.3...v1) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Update test-package.yml Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kevin Moore --- pkgs/string_scanner/.github/workflows/test-package.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 0a2a87433..bd93fbed8 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} - id: install @@ -47,10 +47,10 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [dev] + sdk: [2.12.0, dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} - id: install From 3f712859c53dff4faf70edde6d54a0a6575941d9 Mon Sep 17 00:00:00 2001 From: Nikita Mishkov Date: Tue, 15 Jun 2021 01:08:50 +0300 Subject: [PATCH 059/102] changed "< 0" to ".isNegative" (dart-lang/string_scanner#39) --- pkgs/string_scanner/lib/src/string_scanner.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index 5d69c7565..d254b044b 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -22,7 +22,7 @@ class StringScanner { /// The current position of the scanner in the string, in characters. int get position => _position; set position(int position) { - if (position < 0 || position > string.length) { + if (position.isNegative || position > string.length) { throw ArgumentError('Invalid position $position'); } From 94659c477bb5f654f288e0f566118323ec995455 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sat, 2 Oct 2021 20:59:12 -0700 Subject: [PATCH 060/102] Move to pkg:lints (dart-lang/string_scanner#41) --- pkgs/string_scanner/analysis_options.yaml | 2 +- pkgs/string_scanner/pubspec.yaml | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index 60abe63e6..c6528bb46 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -1,4 +1,4 @@ -include: package:pedantic/analysis_options.yaml +include: package:lints/recommended.yaml analyzer: strong-mode: diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 9eee52bfd..02136e394 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -5,10 +5,11 @@ description: A class for parsing strings using a sequence of patterns. homepage: https://github.com/dart-lang/string_scanner environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: source_span: ^1.8.0 dev_dependencies: - test: ^1.16.0-nullsafety + lints: ^1.0.0 + test: ^1.16.0 \ No newline at end of file From 4fc12445aa811aafae0eda3157afba21ffde976a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Mar 2022 19:25:13 -0800 Subject: [PATCH 061/102] Bump actions/checkout from 2 to 3 (dart-lang/string_scanner#42) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index bd93fbed8..9bf684586 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.12.0, dev] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} From 23f9f8193076a4221b29cac148cebc77db521859 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 3 May 2022 15:16:03 -0700 Subject: [PATCH 062/102] populate the pubspec repository field (dart-lang/string_scanner#44) --- pkgs/string_scanner/CHANGELOG.md | 2 ++ pkgs/string_scanner/pubspec.yaml | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 2a76ec94d..d1a0e88e6 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,5 +1,7 @@ ## 1.1.1-dev +* Populate the pubspec `repository` field. + ## 1.1.0 * Stable release for null safety. diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 02136e394..872d47c5b 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,8 +1,7 @@ name: string_scanner version: 1.1.1-dev - description: A class for parsing strings using a sequence of patterns. -homepage: https://github.com/dart-lang/string_scanner +repository: https://github.com/dart-lang/string_scanner environment: sdk: ">=2.12.0 <3.0.0" @@ -12,4 +11,4 @@ dependencies: dev_dependencies: lints: ^1.0.0 - test: ^1.16.0 \ No newline at end of file + test: ^1.16.0 From 99e9344a0d7e22bb7db987b4cd9c5f2fba152db3 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Thu, 12 May 2022 10:09:18 -0700 Subject: [PATCH 063/102] rev to 1.1.1 in preparation for publishing (dart-lang/string_scanner#45) --- pkgs/string_scanner/CHANGELOG.md | 4 +++- pkgs/string_scanner/README.md | 4 ++++ pkgs/string_scanner/pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index d1a0e88e6..cb4d29710 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,6 +1,8 @@ -## 1.1.1-dev +## 1.1.1 * Populate the pubspec `repository` field. +* Switch to `package:lints`. +* Remove a dependency on `package:charcode`. ## 1.1.0 diff --git a/pkgs/string_scanner/README.md b/pkgs/string_scanner/README.md index 6427218c2..b7a49c363 100644 --- a/pkgs/string_scanner/README.md +++ b/pkgs/string_scanner/README.md @@ -1,3 +1,7 @@ +[![Dart CI](https://github.com/dart-lang/string_scanner/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/string_scanner/actions/workflows/test-package.yml) +[![pub package](https://img.shields.io/pub/v/string_scanner.svg)](https://pub.dev/packages/string_scanner) +[![package publisher](https://img.shields.io/pub/publisher/string_scanner.svg)](https://pub.dev/packages/string_scanner/publisher) + This package exposes a `StringScanner` type that makes it easy to parse a string using a series of `Pattern`s. For example: diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 872d47c5b..421a22739 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.1.1-dev +version: 1.1.1 description: A class for parsing strings using a sequence of patterns. repository: https://github.com/dart-lang/string_scanner From 9e63a33afb0fc9c3f9c3975297fccbbb7e4825bd Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 2 Jun 2022 15:22:54 -0700 Subject: [PATCH 064/102] Add better support for dealing with supplemental-plane code units (dart-lang/string_scanner#46) --- pkgs/string_scanner/CHANGELOG.md | 14 ++ .../lib/src/eager_span_scanner.dart | 3 +- pkgs/string_scanner/lib/src/line_scanner.dart | 3 +- .../lib/src/string_scanner.dart | 64 +++++++- pkgs/string_scanner/lib/src/utils.dart | 64 ++++++++ pkgs/string_scanner/pubspec.yaml | 2 +- .../test/line_scanner_test.dart | 86 ++++++++++ .../test/span_scanner_test.dart | 68 ++++++-- .../test/string_scanner_test.dart | 148 ++++++++++++++++++ 9 files changed, 436 insertions(+), 16 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index cb4d29710..5963ce8e0 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,17 @@ +## 1.2.0 + +* Add better support for reading code points in the Unicode supplementary plane: + + * Added `StringScanner.readCodePoint()`, which consumes an entire Unicode code + point even if it's represented by two UTF-16 code units. + + * Added `StringScanner.peekCodePoint()`, which returns an entire Unicode code + point even if it's represented by two UTF-16 code units. + + * `StringScanner.scanChar()` and `StringScanner.expectChar()` will now + properly consume two UTF-16 code units if they're passed Unicode code points + in the supplementary plane. + ## 1.1.1 * Populate the pubspec `repository` field. diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index d27a818fa..3bf5416d2 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -5,6 +5,7 @@ import 'charcode.dart'; import 'line_scanner.dart'; import 'span_scanner.dart'; +import 'utils.dart'; // TODO(nweiz): Currently this duplicates code in line_scanner.dart. Once // sdk#23770 is fully complete, we should move the shared code into a mixin. @@ -90,7 +91,7 @@ class EagerSpanScanner extends SpanScanner { _line += 1; _column = 0; } else { - _column += 1; + _column += inSupplementaryPlane(character) ? 2 : 1; } } diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index af6b6e705..4f0673c9e 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -4,6 +4,7 @@ import 'charcode.dart'; import 'string_scanner.dart'; +import 'utils.dart'; // Note that much of this code is duplicated in eager_span_scanner.dart. @@ -95,7 +96,7 @@ class LineScanner extends StringScanner { _line += 1; _column = 0; } else { - _column += 1; + _column += inSupplementaryPlane(character) ? 2 : 1; } } diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index d254b044b..de566a5b6 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -90,16 +90,35 @@ class StringScanner { /// If the next character in the string is [character], consumes it. /// + /// If [character] is a Unicode code point in a supplementary plane, this will + /// consume two code units. Dart's string representation is UTF-16, which + /// represents supplementary-plane code units as two code units. + /// /// Returns whether or not [character] was consumed. bool scanChar(int character) { - if (isDone) return false; - if (string.codeUnitAt(_position) != character) return false; - _position++; - return true; + if (inSupplementaryPlane(character)) { + if (_position + 1 >= string.length || + string.codeUnitAt(_position) != highSurrogate(character) || + string.codeUnitAt(_position + 1) != lowSurrogate(character)) { + return false; + } else { + _position += 2; + return true; + } + } else { + if (isDone) return false; + if (string.codeUnitAt(_position) != character) return false; + _position++; + return true; + } } /// If the next character in the string is [character], consumes it. /// + /// If [character] is a Unicode code point in a supplementary plane, this will + /// consume two code units. Dart's string representation is UTF-16, which + /// represents supplementary-plane code units as two code units. + /// /// If [character] could not be consumed, throws a [FormatException] /// describing the position of the failure. [name] is used in this error as /// the expected name of the character being matched; if it's `null`, the @@ -120,6 +139,43 @@ class StringScanner { _fail(name); } + /// Consumes a single Unicode code unit and returns it. + /// + /// This works like [readChar], except that it automatically handles UTF-16 + /// surrogate pairs. Specifically, if the next two code units form a surrogate + /// pair, consumes them both and returns the corresponding Unicode code point. + /// + /// If next two characters are not a surrogate pair, the next code unit is + /// returned as-is, even if it's an unpaired surrogate. + int readCodePoint() { + final first = readChar(); + if (!isHighSurrogate(first)) return first; + + final next = peekChar(); + if (next == null || !isLowSurrogate(next)) return first; + + readChar(); + return decodeSurrogatePair(first, next); + } + + /// Returns the Unicode code point immediately after [position]. + /// + /// This works like [peekChar], except that it automatically handles UTF-16 + /// surrogate pairs. Specifically, if the next two code units form a surrogate + /// pair, returns the corresponding Unicode code point. + /// + /// If next two characters are not a surrogate pair, the next code unit is + /// returned as-is, even if it's an unpaired surrogate. + int? peekCodePoint() { + final first = peekChar(); + if (first == null || !isHighSurrogate(first)) return first; + + final next = peekChar(1); + if (next == null || !isLowSurrogate(next)) return first; + + return decodeSurrogatePair(first, next); + } + /// If [pattern] matches at the current position of the string, scans forward /// until the end of the match. /// diff --git a/pkgs/string_scanner/lib/src/utils.dart b/pkgs/string_scanner/lib/src/utils.dart index 52dfb6360..39891a16a 100644 --- a/pkgs/string_scanner/lib/src/utils.dart +++ b/pkgs/string_scanner/lib/src/utils.dart @@ -29,3 +29,67 @@ void validateErrorArgs( 'the string.'); } } + +// See https://en.wikipedia.org/wiki/UTF-16#Code_points_from_U+010000_to_U+10FFFF +// for documentation on how UTF-16 encoding works and definitions of various +// related terms. + +/// The inclusive lower bound of Unicode's supplementary plane. +const _supplementaryPlaneLowerBound = 0x10000; + +/// The inclusive upper bound of Unicode's supplementary plane. +const _supplementaryPlaneUpperBound = 0x10FFFF; + +/// The inclusive lower bound of the UTF-16 high surrogate block. +const _highSurrogateLowerBound = 0xD800; + +/// The inclusive lower bound of the UTF-16 low surrogate block. +const _lowSurrogateLowerBound = 0xDC00; + +/// The number of low bits in each code unit of a surrogate pair that goes into +/// determining which code point it encodes. +const _surrogateBits = 10; + +/// A bit mask that covers the lower [_surrogateBits] of a code point, which can +/// be used to extract the value of a surrogate or the low surrogate value of a +/// code unit. +const _surrogateValueMask = (1 << _surrogateBits) - 1; + +/// Returns whether [codePoint] is in the Unicode supplementary plane, and thus +/// must be represented as a surrogate pair in UTF-16. +bool inSupplementaryPlane(int codePoint) => + codePoint >= _supplementaryPlaneLowerBound && + codePoint <= _supplementaryPlaneUpperBound; + +/// Returns whether [codeUnit] is a UTF-16 high surrogate. +bool isHighSurrogate(int codeUnit) => + (codeUnit & ~_surrogateValueMask) == _highSurrogateLowerBound; + +/// Returns whether [codeUnit] is a UTF-16 low surrogate. +bool isLowSurrogate(int codeUnit) => + (codeUnit >> _surrogateBits) == (_lowSurrogateLowerBound >> _surrogateBits); + +/// Returns the high surrogate needed to encode the supplementary-plane +/// [codePoint]. +int highSurrogate(int codePoint) { + assert(inSupplementaryPlane(codePoint)); + return ((codePoint - _supplementaryPlaneLowerBound) >> _surrogateBits) + + _highSurrogateLowerBound; +} + +/// Returns the low surrogate needed to encode the supplementary-plane +/// [codePoint]. +int lowSurrogate(int codePoint) { + assert(inSupplementaryPlane(codePoint)); + return ((codePoint - _supplementaryPlaneLowerBound) & _surrogateValueMask) + + _lowSurrogateLowerBound; +} + +/// Converts a UTF-16 surrogate pair into the Unicode code unit it represents. +int decodeSurrogatePair(int highSurrogate, int lowSurrogate) { + assert(isHighSurrogate(highSurrogate)); + assert(isLowSurrogate(lowSurrogate)); + return _supplementaryPlaneLowerBound + + (((highSurrogate & _surrogateValueMask) << _surrogateBits) | + (lowSurrogate & _surrogateValueMask)); +} diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 421a22739..c38f3bfe4 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.1.1 +version: 1.2.0 description: A class for parsing strings using a sequence of patterns. repository: https://github.com/dart-lang/string_scanner diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index a3deff1b7..d31d313a3 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -81,6 +81,39 @@ void main() { }); }); + group('readCodePoint()', () { + test('on a non-newline character increases the column but not the line', + () { + scanner.readCodePoint(); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(1)); + }); + + test('consuming a newline resets the column and increases the line', () { + scanner.expect('foo'); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(3)); + + scanner.readCodePoint(); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(0)); + }); + + test("consuming halfway through a CR LF doesn't count as a line", () { + scanner.expect('foo\nbar'); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(3)); + + scanner.readCodePoint(); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(4)); + + scanner.readCodePoint(); + expect(scanner.line, equals(2)); + expect(scanner.column, equals(0)); + }); + }); + group('scanChar()', () { test('on a non-newline character increases the column but not the line', () { @@ -114,6 +147,59 @@ void main() { }); }); + group('before a surrogate pair', () { + final codePoint = '\uD83D\uDC6D'.runes.first; + const highSurrogate = 0xD83D; + + late LineScanner scanner; + setUp(() { + scanner = LineScanner('foo: \uD83D\uDC6D'); + expect(scanner.scan('foo: '), isTrue); + }); + + test('readChar returns the high surrogate and moves into the pair', () { + expect(scanner.readChar(), equals(highSurrogate)); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(6)); + expect(scanner.position, equals(6)); + }); + + test('readCodePoint returns the code unit and moves past the pair', () { + expect(scanner.readCodePoint(), equals(codePoint)); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(7)); + expect(scanner.position, equals(7)); + }); + + test('scanChar with the high surrogate moves into the pair', () { + expect(scanner.scanChar(highSurrogate), isTrue); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(6)); + expect(scanner.position, equals(6)); + }); + + test('scanChar with the code point moves past the pair', () { + expect(scanner.scanChar(codePoint), isTrue); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(7)); + expect(scanner.position, equals(7)); + }); + + test('expectChar with the high surrogate moves into the pair', () { + scanner.expectChar(highSurrogate); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(6)); + expect(scanner.position, equals(6)); + }); + + test('expectChar with the code point moves past the pair', () { + scanner.expectChar(codePoint); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(7)); + expect(scanner.position, equals(7)); + }); + }); + group('position=', () { test('forward through newlines sets the line and column', () { scanner.position = 10; // "foo\nbar\r\nb" diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index 828745fe1..0e20c36a5 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -139,15 +139,6 @@ void testForImplementation( expect(span.text, equals('o\nbar\nba')); }); - test('.spanFrom() handles surrogate pairs correctly', () { - scanner = create('fo\u{12345}o'); - scanner.scan('fo'); - final state = scanner.state; - scanner.scan('\u{12345}o'); - final span = scanner.spanFrom(state); - expect(span.text, equals('\u{12345}o')); - }); - test('.emptySpan returns an empty span at the current location', () { scanner.scan('foo\nba'); @@ -164,5 +155,64 @@ void testForImplementation( expect(span.text, equals('')); }); + + group('before a surrogate pair', () { + final codePoint = '\uD83D\uDC6D'.runes.first; + const highSurrogate = 0xD83D; + + late SpanScanner scanner; + setUp(() { + scanner = create('foo: \uD83D\uDC6D bar'); + expect(scanner.scan('foo: '), isTrue); + }); + + test('readChar returns the high surrogate and moves into the pair', () { + expect(scanner.readChar(), equals(highSurrogate)); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(6)); + expect(scanner.position, equals(6)); + }); + + test('readCodePoint returns the code unit and moves past the pair', () { + expect(scanner.readCodePoint(), equals(codePoint)); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(7)); + expect(scanner.position, equals(7)); + }); + + test('scanChar with the high surrogate moves into the pair', () { + expect(scanner.scanChar(highSurrogate), isTrue); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(6)); + expect(scanner.position, equals(6)); + }); + + test('scanChar with the code point moves past the pair', () { + expect(scanner.scanChar(codePoint), isTrue); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(7)); + expect(scanner.position, equals(7)); + }); + + test('expectChar with the high surrogate moves into the pair', () { + scanner.expectChar(highSurrogate); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(6)); + expect(scanner.position, equals(6)); + }); + + test('expectChar with the code point moves past the pair', () { + scanner.expectChar(codePoint); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(7)); + expect(scanner.position, equals(7)); + }); + + test('spanFrom covers the surrogate pair', () { + final state = scanner.state; + scanner.scan('\uD83D\uDC6D b'); + expect(scanner.spanFrom(state).text, equals('\uD83D\uDC6D b')); + }); + }); }); } diff --git a/pkgs/string_scanner/test/string_scanner_test.dart b/pkgs/string_scanner/test/string_scanner_test.dart index 34176b8a3..36a737e36 100644 --- a/pkgs/string_scanner/test/string_scanner_test.dart +++ b/pkgs/string_scanner/test/string_scanner_test.dart @@ -36,12 +36,24 @@ void main() { expect(scanner.position, equals(0)); }); + test("readCodePoint fails and doesn't change the state", () { + expect(scanner.readCodePoint, throwsFormatException); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + test("peekChar returns null and doesn't change the state", () { expect(scanner.peekChar(), isNull); expect(scanner.lastMatch, isNull); expect(scanner.position, equals(0)); }); + test("peekCodePoint returns null and doesn't change the state", () { + expect(scanner.peekCodePoint(), isNull); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + test("scanChar returns false and doesn't change the state", () { expect(scanner.scanChar($f), isFalse); expect(scanner.lastMatch, isNull); @@ -118,6 +130,12 @@ void main() { expect(scanner.position, equals(1)); }); + test('readCodePoint returns the first character and moves forward', () { + expect(scanner.readCodePoint(), equals(0x66)); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(1)); + }); + test('peekChar returns the first character', () { expect(scanner.peekChar(), equals(0x66)); expect(scanner.lastMatch, isNull); @@ -130,6 +148,12 @@ void main() { expect(scanner.position, equals(0)); }); + test('peekCodePoint returns the first character', () { + expect(scanner.peekCodePoint(), equals(0x66)); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(0)); + }); + test('a matching scanChar returns true moves forward', () { expect(scanner.scanChar($f), isTrue); expect(scanner.lastMatch, isNull); @@ -275,6 +299,13 @@ void main() { expect(scanner.position, equals(4)); }); + test('readCodePoint returns the first character and unsets the last match', + () { + expect(scanner.readCodePoint(), equals($space)); + expect(scanner.lastMatch, isNull); + expect(scanner.position, equals(4)); + }); + test('a matching scanChar returns true and unsets the last match', () { expect(scanner.scanChar($space), isTrue); expect(scanner.lastMatch, isNull); @@ -314,12 +345,24 @@ void main() { expect(scanner.position, equals(7)); }); + test("readCodePoint fails and doesn't change the state", () { + expect(scanner.readCodePoint, throwsFormatException); + expect(scanner.lastMatch, isNotNull); + expect(scanner.position, equals(7)); + }); + test("peekChar returns null and doesn't change the state", () { expect(scanner.peekChar(), isNull); expect(scanner.lastMatch, isNotNull); expect(scanner.position, equals(7)); }); + test("peekCodePoint returns null and doesn't change the state", () { + expect(scanner.peekCodePoint(), isNull); + expect(scanner.lastMatch, isNotNull); + expect(scanner.position, equals(7)); + }); + test("scanChar returns false and doesn't change the state", () { expect(scanner.scanChar($f), isFalse); expect(scanner.lastMatch, isNotNull); @@ -393,6 +436,111 @@ void main() { }); }); + group('before a surrogate pair', () { + final codePoint = '\uD83D\uDC6D'.runes.first; + const highSurrogate = 0xD83D; + + late StringScanner scanner; + setUp(() { + scanner = StringScanner('foo: \uD83D\uDC6D'); + expect(scanner.scan('foo: '), isTrue); + }); + + test('readChar returns the high surrogate and moves into the pair', () { + expect(scanner.readChar(), equals(highSurrogate)); + expect(scanner.position, equals(6)); + }); + + test('readCodePoint returns the code unit and moves past the pair', () { + expect(scanner.readCodePoint(), equals(codePoint)); + expect(scanner.position, equals(7)); + }); + + test('peekChar returns the high surrogate', () { + expect(scanner.peekChar(), equals(highSurrogate)); + expect(scanner.position, equals(5)); + }); + + test('peekCodePoint returns the code unit', () { + expect(scanner.peekCodePoint(), equals(codePoint)); + expect(scanner.position, equals(5)); + }); + + test('scanChar with the high surrogate moves into the pair', () { + expect(scanner.scanChar(highSurrogate), isTrue); + expect(scanner.position, equals(6)); + }); + + test('scanChar with the code point moves past the pair', () { + expect(scanner.scanChar(codePoint), isTrue); + expect(scanner.position, equals(7)); + }); + + test('expectChar with the high surrogate moves into the pair', () { + scanner.expectChar(highSurrogate); + expect(scanner.position, equals(6)); + }); + + test('expectChar with the code point moves past the pair', () { + scanner.expectChar(codePoint); + expect(scanner.position, equals(7)); + }); + }); + + group('before an invalid surrogate pair', () { + // This surrogate pair is invalid because U+E000 is just outside the range + // of low surrogates. If it were interpreted as a surrogate pair anyway, the + // value would be U+110000, which is outside of the Unicode gamut. + const codePoint = 0x110000; + const highSurrogate = 0xD800; + + late StringScanner scanner; + setUp(() { + scanner = StringScanner('foo: \uD800\uE000'); + expect(scanner.scan('foo: '), isTrue); + }); + + test('readChar returns the high surrogate and moves into the pair', () { + expect(scanner.readChar(), equals(highSurrogate)); + expect(scanner.position, equals(6)); + }); + + test('readCodePoint returns the high surrogate and moves past the pair', + () { + expect(scanner.readCodePoint(), equals(highSurrogate)); + expect(scanner.position, equals(6)); + }); + + test('peekChar returns the high surrogate', () { + expect(scanner.peekChar(), equals(highSurrogate)); + expect(scanner.position, equals(5)); + }); + + test('peekCodePoint returns the high surrogate', () { + expect(scanner.peekCodePoint(), equals(highSurrogate)); + expect(scanner.position, equals(5)); + }); + + test('scanChar with the high surrogate moves into the pair', () { + expect(scanner.scanChar(highSurrogate), isTrue); + expect(scanner.position, equals(6)); + }); + + test('scanChar with the fake code point returns false', () { + expect(scanner.scanChar(codePoint), isFalse); + expect(scanner.position, equals(5)); + }); + + test('expectChar with the high surrogate moves into the pair', () { + scanner.expectChar(highSurrogate); + expect(scanner.position, equals(6)); + }); + + test('expectChar with the fake code point fails', () { + expect(() => scanner.expectChar(codePoint), throwsRangeError); + }); + }); + group('a scanner constructed with a custom position', () { test('starts scanning from that position', () { final scanner = StringScanner('foo bar', position: 1); From aa3ac4429ede421714cb91ce83edac90896056ed Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Mon, 25 Jul 2022 13:25:35 -0700 Subject: [PATCH 065/102] Remove deprecated experimental invariant_booleans lint rule (dart-lang/string_scanner#47) --- pkgs/string_scanner/analysis_options.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index c6528bb46..a4495f2e0 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -30,7 +30,6 @@ linter: - file_names - hash_and_equals - implementation_imports - - invariant_booleans - iterable_contains_unrelated_type - join_return_with_assignment - lines_longer_than_80_chars From dcbb21f24e3d21296f557848d86e7e2c73311822 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 25 Oct 2022 09:15:34 -0700 Subject: [PATCH 066/102] Update minimum SDK, latest pkg:lints, update CI actions (dart-lang/string_scanner#48) --- .../.github/workflows/test-package.yml | 10 ++-- pkgs/string_scanner/CHANGELOG.md | 2 + pkgs/string_scanner/analysis_options.yaml | 50 ++++++------------- .../lib/src/eager_span_scanner.dart | 3 +- pkgs/string_scanner/lib/src/exception.dart | 4 +- pkgs/string_scanner/lib/src/line_scanner.dart | 3 +- pkgs/string_scanner/lib/src/span_scanner.dart | 7 ++- .../lib/src/string_scanner.dart | 4 +- pkgs/string_scanner/pubspec.yaml | 4 +- 9 files changed, 33 insertions(+), 54 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 9bf684586..bc4359926 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@v3 - - uses: dart-lang/setup-dart@v1 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install @@ -47,10 +47,10 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.12.0, dev] + sdk: [2.18.0, dev] steps: - - uses: actions/checkout@v3 - - uses: dart-lang/setup-dart@v1 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 5963ce8e0..b5346b063 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,5 +1,7 @@ ## 1.2.0 +* Require Dart 2.18.0 + * Add better support for reading code points in the Unicode supplementary plane: * Added `StringScanner.readCodePoint()`, which consumes an entire Unicode code diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index a4495f2e0..b507c06db 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -1,75 +1,55 @@ +# https://dart.dev/guides/language/analysis-options include: package:lints/recommended.yaml analyzer: - strong-mode: - implicit-casts: false + language: + strict-casts: true + strict-inference: true + strict-raw-types: true linter: rules: + - always_declare_return_types - avoid_bool_literals_in_conditional_expressions - avoid_catching_errors - avoid_classes_with_only_static_members - - avoid_function_literals_in_foreach_calls + - avoid_dynamic_calls - avoid_private_typedef_functions - avoid_redundant_argument_values - - avoid_renaming_method_parameters - avoid_returning_null_for_future - - avoid_returning_null_for_void - avoid_returning_this - - avoid_single_cascade_in_expression_statements - avoid_unused_constructor_parameters - avoid_void_async - - await_only_futures - - camel_case_types - cancel_subscriptions - comment_references - - constant_identifier_names - - control_flow_in_finally - directives_ordering - - empty_statements - - file_names - - hash_and_equals - - implementation_imports - - iterable_contains_unrelated_type - join_return_with_assignment - lines_longer_than_80_chars - - list_remove_unrelated_type - literal_only_boolean_expressions - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - no_runtimeType_toString - - non_constant_identifier_names + - omit_local_variable_types - only_throw_errors - - overridden_fields - package_api_docs - - package_names - - package_prefixed_library_names - prefer_asserts_in_initializer_lists - prefer_const_constructors - prefer_const_declarations - prefer_expression_function_bodies - prefer_final_locals - - prefer_function_declarations_over_variables - - prefer_initializing_formals - - prefer_inlined_adds - - prefer_interpolation_to_compose_strings - - prefer_is_not_operator - - prefer_null_aware_operators - prefer_relative_imports - - prefer_typing_uninitialized_variables - - prefer_void_to_null - - provide_deprecation_message + - prefer_single_quotes - sort_pub_dependencies - test_types_in_equals - throw_in_finally + - type_annotate_public_apis + - unawaited_futures - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_getters_setters - unnecessary_lambdas - - unnecessary_null_aware_assignments - - unnecessary_overrides - unnecessary_parenthesis + - unnecessary_raw_strings - unnecessary_statements - - unnecessary_string_interpolations + - use_if_null_to_convert_nulls_to_bools + - use_raw_strings - use_string_buffers - - void_checks + - use_super_parameters diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index 3bf5416d2..db06127e4 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -68,8 +68,7 @@ class EagerSpanScanner extends SpanScanner { } } - EagerSpanScanner(String string, {sourceUrl, int? position}) - : super(string, sourceUrl: sourceUrl, position: position); + EagerSpanScanner(super.string, {super.sourceUrl, super.position}); @override bool scanChar(int character) { diff --git a/pkgs/string_scanner/lib/src/exception.dart b/pkgs/string_scanner/lib/src/exception.dart index 8aa7aabea..57af541ff 100644 --- a/pkgs/string_scanner/lib/src/exception.dart +++ b/pkgs/string_scanner/lib/src/exception.dart @@ -16,6 +16,6 @@ class StringScannerException extends SourceSpanFormatException { /// This may be `null`, indicating that the source URL is unknown. Uri? get sourceUrl => span?.sourceUrl; - StringScannerException(String message, SourceSpan span, String source) - : super(message, span, source); + StringScannerException( + super.message, SourceSpan super.span, String super.source); } diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 4f0673c9e..5bf701c09 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -73,8 +73,7 @@ class LineScanner extends StringScanner { } } - LineScanner(String string, {sourceUrl, int? position}) - : super(string, sourceUrl: sourceUrl, position: position); + LineScanner(super.string, {super.sourceUrl, super.position}); @override bool scanChar(int character) { diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index 806a8f8ea..413a43331 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -59,13 +59,12 @@ class SpanScanner extends StringScanner implements LineScanner { /// [sourceUrl] is used as [SourceLocation.sourceUrl] for the returned /// [FileSpan]s as well as for error reporting. It can be a [String], a /// [Uri], or `null`. - SpanScanner(String string, {sourceUrl, int? position}) - : _sourceFile = SourceFile.fromString(string, url: sourceUrl), - super(string, sourceUrl: sourceUrl, position: position); + SpanScanner(super.string, {super.sourceUrl, super.position}) + : _sourceFile = SourceFile.fromString(string, url: sourceUrl); /// Creates a new [SpanScanner] that eagerly computes line and column numbers. /// - /// In general [new SpanScanner] will be more efficient, since it avoids extra + /// In general [SpanScanner.new] will be more efficient, since it avoids extra /// computation on every scan. However, eager scanning can be useful for /// situations where the normal course of parsing frequently involves /// accessing the current line and column numbers. diff --git a/pkgs/string_scanner/lib/src/string_scanner.dart b/pkgs/string_scanner/lib/src/string_scanner.dart index de566a5b6..146694432 100644 --- a/pkgs/string_scanner/lib/src/string_scanner.dart +++ b/pkgs/string_scanner/lib/src/string_scanner.dart @@ -56,7 +56,7 @@ class StringScanner { /// [position] defaults to 0, the beginning of the string. [sourceUrl] is the /// URL of the source of the string being scanned, if available. It can be /// a [String], a [Uri], or `null`. - StringScanner(this.string, {sourceUrl, int? position}) + StringScanner(this.string, {Object? sourceUrl, int? position}) : sourceUrl = sourceUrl == null ? null : sourceUrl is String @@ -205,7 +205,7 @@ class StringScanner { name = '/$source/'; } else { name = - pattern.toString().replaceAll('\\', '\\\\').replaceAll('"', '\\"'); + pattern.toString().replaceAll(r'\', r'\\').replaceAll('"', r'\"'); name = '"$name"'; } } diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index c38f3bfe4..6f14e81c7 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -4,11 +4,11 @@ description: A class for parsing strings using a sequence of patterns. repository: https://github.com/dart-lang/string_scanner environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.18.0 <3.0.0" dependencies: source_span: ^1.8.0 dev_dependencies: - lints: ^1.0.0 + lints: ^2.0.0 test: ^1.16.0 From dfed9c2c185fb4d4fcd83b1861694bd6a15be089 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 31 Oct 2022 12:17:54 -0700 Subject: [PATCH 067/102] Make code in readme consistent with example (dart-lang/string_scanner#49) --- pkgs/string_scanner/README.md | 4 ++-- pkgs/string_scanner/example/example.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/string_scanner/README.md b/pkgs/string_scanner/README.md index b7a49c363..e06e32567 100644 --- a/pkgs/string_scanner/README.md +++ b/pkgs/string_scanner/README.md @@ -24,11 +24,11 @@ num parseNumber(String source) { // [Scanner.lastMatch] holds the [MatchData] for the most recent call to // [Scanner.scan], [Scanner.expect], or [Scanner.matches]. - var number = num.parse(scanner.lastMatch[0]); + var number = num.parse(scanner.lastMatch![0]!); if (scanner.scan('.')) { scanner.expect(RegExp(r'\d+')); - final decimal = scanner.lastMatch[0]; + final decimal = scanner.lastMatch![0]!; number += int.parse(decimal) / math.pow(10, decimal.length); } diff --git a/pkgs/string_scanner/example/example.dart b/pkgs/string_scanner/example/example.dart index fd36a73c1..ec9dd7660 100644 --- a/pkgs/string_scanner/example/example.dart +++ b/pkgs/string_scanner/example/example.dart @@ -24,7 +24,7 @@ num parseNumber(String source) { // [Scanner.lastMatch] holds the [MatchData] for the most recent call to // [Scanner.scan], [Scanner.expect], or [Scanner.matches]. - var number = num.parse((scanner.lastMatch![0])!); + var number = num.parse(scanner.lastMatch![0]!); if (scanner.scan('.')) { scanner.expect(RegExp(r'\d+')); From a42fdf8baa3acda195d5e502cfe72035c8f128a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Dec 2022 12:12:30 -0800 Subject: [PATCH 068/102] Bump actions/checkout from 3.1.0 to 3.2.0 (dart-lang/string_scanner#50) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8...755da8c3cf115ac066823e79a1e1788f8940201b) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index bc4359926..cc5abcf3c 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} From 3062f6558174635706e88fc425657ff2cb56de7f Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 28 Dec 2022 16:37:21 -0800 Subject: [PATCH 069/102] Remove unnecessary parens (dart-lang/string_scanner#51) --- pkgs/string_scanner/CHANGELOG.md | 2 ++ pkgs/string_scanner/lib/src/eager_span_scanner.dart | 2 +- pkgs/string_scanner/lib/src/line_scanner.dart | 4 ++-- pkgs/string_scanner/pubspec.yaml | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index b5346b063..57b31ba8a 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.2.1-dev + ## 1.2.0 * Require Dart 2.18.0 diff --git a/pkgs/string_scanner/lib/src/eager_span_scanner.dart b/pkgs/string_scanner/lib/src/eager_span_scanner.dart index db06127e4..1ccc746ac 100644 --- a/pkgs/string_scanner/lib/src/eager_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/eager_span_scanner.dart @@ -97,7 +97,7 @@ class EagerSpanScanner extends SpanScanner { @override bool scan(Pattern pattern) { if (!super.scan(pattern)) return false; - final firstMatch = (lastMatch![0])!; + final firstMatch = lastMatch![0]!; final newlines = _newlinesIn(firstMatch); _line += newlines.length; diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 5bf701c09..2903c4039 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -106,9 +106,9 @@ class LineScanner extends StringScanner { final newlines = _newlinesIn(lastMatch![0]!); _line += newlines.length; if (newlines.isEmpty) { - _column += (lastMatch![0])!.length; + _column += lastMatch![0]!.length; } else { - _column = (lastMatch![0])!.length - newlines.last.end; + _column = lastMatch![0]!.length - newlines.last.end; } return true; diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 6f14e81c7..b297e50d2 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.2.0 +version: 1.2.1-dev description: A class for parsing strings using a sequence of patterns. repository: https://github.com/dart-lang/string_scanner From d019da9b2f49679353aaf6d8db4366cdc777cdfa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jan 2023 09:15:48 -0800 Subject: [PATCH 070/102] Bump actions/checkout from 3.2.0 to 3.3.0 (dart-lang/string_scanner#52) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/755da8c3cf115ac066823e79a1e1788f8940201b...ac593985615ec2ede58e132d2e21d2b1cbd6127c) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index cc5abcf3c..e9d2eb965 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} From e899d5ac3692080275a388a5b6b51e4abf3fb5f3 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 17 Jan 2023 07:13:00 -0800 Subject: [PATCH 071/102] dependabot: monthly is plenty (dart-lang/string_scanner#54) --- pkgs/string_scanner/.github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/string_scanner/.github/dependabot.yml b/pkgs/string_scanner/.github/dependabot.yml index 430a85e7d..d5262beb1 100644 --- a/pkgs/string_scanner/.github/dependabot.yml +++ b/pkgs/string_scanner/.github/dependabot.yml @@ -8,4 +8,4 @@ updates: directory: "/" schedule: # Check for updates to GitHub Actions every weekday - interval: "daily" + interval: "monthly" From c0e8fe5da51c4403ae201ad2f3bcc17104c8bbfb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 08:41:57 -0800 Subject: [PATCH 072/102] Bump dart-lang/setup-dart from 1.3 to 1.4 (dart-lang/string_scanner#53) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.3 to 1.4. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/6a218f2413a3e78e9087f638a238f6b40893203d...a57a6c04cf7d4840e88432aad6281d1e125f0d46) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index e9d2eb965..5a03db3b3 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.18.0, dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install From 25b9b3a605f5148500c9162e624b6d9d1dc2f42e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Apr 2023 19:50:07 -0700 Subject: [PATCH 073/102] Bump actions/checkout from 3.3.0 to 3.5.0 (dart-lang/string_scanner#55) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.5.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/ac593985615ec2ede58e132d2e21d2b1cbd6127c...8f4b7f84864484a7bf31766abe9204da3cbe65b3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 5a03db3b3..63946acf6 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} From 3964b9748ade19fa93cb150e0d8f290cef52de09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Apr 2023 19:54:26 -0700 Subject: [PATCH 074/102] Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (dart-lang/string_scanner#56) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/a57a6c04cf7d4840e88432aad6281d1e125f0d46...d6a63dab3335f427404425de0fbfed4686d93c4f) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 63946acf6..b70103cd7 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.18.0, dev] steps: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install From 34b26161a343cf2671e765c5baa30fc350b618a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 12:34:56 -0700 Subject: [PATCH 075/102] Bump actions/checkout from 3.5.0 to 3.5.2 (dart-lang/string_scanner#57) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/8f4b7f84864484a7bf31766abe9204da3cbe65b3...8e5e7e5ab8b370d6c329ec480221332ada57f0ab) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index b70103cd7..2d36a3b10 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From 419ff8922532b20f8a90794ed4708f6d4b30400d Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Fri, 19 May 2023 09:52:39 -0700 Subject: [PATCH 076/102] blast_repo fixes (dart-lang/string_scanner#58) dependabot --- pkgs/string_scanner/.github/dependabot.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pkgs/string_scanner/.github/dependabot.yml b/pkgs/string_scanner/.github/dependabot.yml index d5262beb1..c84404dc9 100644 --- a/pkgs/string_scanner/.github/dependabot.yml +++ b/pkgs/string_scanner/.github/dependabot.yml @@ -4,8 +4,9 @@ version: 2 updates: -- package-ecosystem: "github-actions" - directory: "/" +- package-ecosystem: github-actions + directory: / schedule: - # Check for updates to GitHub Actions every weekday - interval: "monthly" + interval: monthly + labels: + - autosubmit From 453f7649112a99f0f03554d703689c2aecddf2d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 00:51:17 +0000 Subject: [PATCH 077/102] Bump actions/checkout from 3.5.2 to 3.5.3 (dart-lang/string_scanner#59) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.2 to 3.5.3.
Release notes

Sourced from actions/checkout's releases.

v3.5.3

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v3.5.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

v2.3.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.2&new-version=3.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 2d36a3b10..7e593e5ce 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From d88e5fd574205ced2ca094fc51a472ea180c2a58 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 18 Jul 2023 09:30:20 -0700 Subject: [PATCH 078/102] blast_repo fixes (dart-lang/string_scanner#60) auto-publish --- .../.github/workflows/publish.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 pkgs/string_scanner/.github/workflows/publish.yaml diff --git a/pkgs/string_scanner/.github/workflows/publish.yaml b/pkgs/string_scanner/.github/workflows/publish.yaml new file mode 100644 index 000000000..27157a046 --- /dev/null +++ b/pkgs/string_scanner/.github/workflows/publish.yaml @@ -0,0 +1,17 @@ +# A CI configuration to auto-publish pub packages. + +name: Publish + +on: + pull_request: + branches: [ master ] + push: + tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ] + +jobs: + publish: + if: ${{ github.repository_owner == 'dart-lang' }} + uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main + permissions: + id-token: write # Required for authentication using OIDC + pull-requests: write # Required for writing the pull request note From c3f751308b7e035c9d1359b9454b91bee2ec5fe5 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 18 Jul 2023 09:30:33 -0700 Subject: [PATCH 079/102] Require Dart 3, update lints (dart-lang/string_scanner#61) --- .../.github/workflows/test-package.yml | 2 +- pkgs/string_scanner/CHANGELOG.md | 4 +++- pkgs/string_scanner/analysis_options.yaml | 18 +----------------- pkgs/string_scanner/lib/string_scanner.dart | 2 ++ pkgs/string_scanner/pubspec.yaml | 6 +++--- 5 files changed, 10 insertions(+), 22 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 7e593e5ce..7ad5f74e0 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.18.0, dev] + sdk: [3.0.0, dev] steps: - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 57b31ba8a..fa7af43f3 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,4 +1,6 @@ -## 1.2.1-dev +## 1.2.1-wip + +* Require Dart 3.0.0 ## 1.2.0 diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index b507c06db..0b975913d 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -1,5 +1,5 @@ # https://dart.dev/guides/language/analysis-options -include: package:lints/recommended.yaml +include: package:dart_flutter_team_lints/analysis_options.yaml analyzer: language: @@ -9,11 +9,8 @@ analyzer: linter: rules: - - always_declare_return_types - avoid_bool_literals_in_conditional_expressions - - avoid_catching_errors - avoid_classes_with_only_static_members - - avoid_dynamic_calls - avoid_private_typedef_functions - avoid_redundant_argument_values - avoid_returning_null_for_future @@ -22,33 +19,20 @@ linter: - avoid_void_async - cancel_subscriptions - comment_references - - directives_ordering - join_return_with_assignment - - lines_longer_than_80_chars - literal_only_boolean_expressions - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - no_runtimeType_toString - - omit_local_variable_types - - only_throw_errors - package_api_docs - - prefer_asserts_in_initializer_lists - prefer_const_constructors - prefer_const_declarations - prefer_expression_function_bodies - prefer_final_locals - prefer_relative_imports - - prefer_single_quotes - - sort_pub_dependencies - test_types_in_equals - - throw_in_finally - - type_annotate_public_apis - - unawaited_futures - unnecessary_await_in_return - - unnecessary_lambdas - - unnecessary_parenthesis - unnecessary_raw_strings - - unnecessary_statements - use_if_null_to_convert_nulls_to_bools - use_raw_strings - use_string_buffers diff --git a/pkgs/string_scanner/lib/string_scanner.dart b/pkgs/string_scanner/lib/string_scanner.dart index 7f36eef83..e641ae706 100644 --- a/pkgs/string_scanner/lib/string_scanner.dart +++ b/pkgs/string_scanner/lib/string_scanner.dart @@ -3,6 +3,8 @@ // BSD-style license that can be found in the LICENSE file. /// A library for parsing strings using a sequence of patterns. +library; + export 'src/exception.dart'; export 'src/line_scanner.dart'; export 'src/span_scanner.dart'; diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index b297e50d2..40682ecb1 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,14 +1,14 @@ name: string_scanner -version: 1.2.1-dev +version: 1.2.1-wip description: A class for parsing strings using a sequence of patterns. repository: https://github.com/dart-lang/string_scanner environment: - sdk: ">=2.18.0 <3.0.0" + sdk: ^3.0.0 dependencies: source_span: ^1.8.0 dev_dependencies: - lints: ^2.0.0 + dart_flutter_team_lints: ^1.0.0 test: ^1.16.0 From e18bdfba0deb28ee344a443e2ddd4b2a7409dd1d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 00:39:56 +0000 Subject: [PATCH 080/102] Bump actions/checkout from 3.5.3 to 3.6.0 (dart-lang/string_scanner#62) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.3 to 3.6.0.
Release notes

Sourced from actions/checkout's releases.

v3.6.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3.5.3...v3.6.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.3&new-version=3.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 7ad5f74e0..24d44c9ac 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From 3583f10a7ce26a7f1d3041733b450d2f1f011017 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 00:06:20 +0000 Subject: [PATCH 081/102] Bump dart-lang/setup-dart from 1.5.0 to 1.5.1 (dart-lang/string_scanner#63) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.0 to 1.5.1.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.0&new-version=1.5.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 24d44c9ac..b187c4637 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install From de978a54ab0ba6dfe3bd296d0980d98c299208c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 07:15:40 -0700 Subject: [PATCH 082/102] Bump actions/checkout from 3.6.0 to 4.1.0 (dart-lang/string_scanner#64) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.6.0 to 4.1.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/f43a0e5ff2bd294095638e18286ca9a3d1956744...8ade135a41bc03ea155e62e844d188df1ea18608) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index b187c4637..657b236db 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} From b84c6cf7c3d362ba7e090d246a88bd0343f7a49d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 00:30:30 +0000 Subject: [PATCH 083/102] Bump dart-lang/setup-dart from 1.5.1 to 1.6.0 (dart-lang/string_scanner#66) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.1 to 1.6.0.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.1&new-version=1.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 657b236db..86a16617d 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install From ed7eaa889239376c4d5d5f69a14a868bbeb8f9e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 15:54:43 +0000 Subject: [PATCH 084/102] Bump actions/checkout from 4.1.0 to 4.1.1 (dart-lang/string_scanner#65) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.1.1.
Release notes

Sourced from actions/checkout's releases.

v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.0...v4.1.1

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.0&new-version=4.1.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 86a16617d..4cb7d3a73 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} From b30d7f7e8ee72950e0562c42a19a57cbd8ee56bc Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 4 Dec 2023 10:30:39 -0800 Subject: [PATCH 085/102] Update to latest lints and cleanup (dart-lang/string_scanner#67) --- pkgs/string_scanner/analysis_options.yaml | 6 ------ pkgs/string_scanner/pubspec.yaml | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index 0b975913d..813466b66 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -13,27 +13,21 @@ linter: - avoid_classes_with_only_static_members - avoid_private_typedef_functions - avoid_redundant_argument_values - - avoid_returning_null_for_future - avoid_returning_this - avoid_unused_constructor_parameters - avoid_void_async - cancel_subscriptions - - comment_references - join_return_with_assignment - literal_only_boolean_expressions - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - no_runtimeType_toString - package_api_docs - - prefer_const_constructors - prefer_const_declarations - prefer_expression_function_bodies - prefer_final_locals - - prefer_relative_imports - - test_types_in_equals - unnecessary_await_in_return - unnecessary_raw_strings - use_if_null_to_convert_nulls_to_bools - use_raw_strings - use_string_buffers - - use_super_parameters diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 40682ecb1..7ceb7d983 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -10,5 +10,5 @@ dependencies: source_span: ^1.8.0 dev_dependencies: - dart_flutter_team_lints: ^1.0.0 + dart_flutter_team_lints: ^2.0.0 test: ^1.16.0 From 5c80b48e619d76c1b6dee6169e21b0badd8067ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 00:36:17 +0000 Subject: [PATCH 086/102] Bump dart-lang/setup-dart from 1.6.0 to 1.6.2 (dart-lang/string_scanner#68) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.0 to 1.6.2.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.0&new-version=1.6.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 4cb7d3a73..4e4e97d8d 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install From 5d1f4fc82155c3e05c7316d991203b93692dbd71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 01:07:20 +0000 Subject: [PATCH 087/102] Bump actions/checkout from 4.1.1 to 4.1.2 (dart-lang/string_scanner#70) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.2.
Release notes

Sourced from actions/checkout's releases.

v4.1.2

We are investigating the following issue with this release and have rolled-back the v4 tag to point to v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.1...v4.1.2

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.1&new-version=4.1.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 4e4e97d8d..8f1b1a691 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} From 2b9a8caf8dbe7aa965f07f5e25eae748e07da982 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 00:45:43 +0000 Subject: [PATCH 088/102] Bump dart-lang/setup-dart from 1.6.2 to 1.6.4 (dart-lang/string_scanner#72) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.2 to 1.6.4.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.4

  • Rebuild JS code to include changes from v1.6.3

v1.6.3

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.2&new-version=1.6.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 8f1b1a691..b14a4082a 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install From c67ff10a7e3e851eb728cc2168ed409a80ceb7b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 15:21:34 +0000 Subject: [PATCH 089/102] Bump actions/checkout from 4.1.2 to 4.1.4 (dart-lang/string_scanner#71) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.2 to 4.1.4.
Release notes

Sourced from actions/checkout's releases.

v4.1.4

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.3...v4.1.4

v4.1.3

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.2...v4.1.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.2&new-version=4.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index b14a4082a..97fdf914e 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 514bba1ea9b5c1ad1ccb73185cab1c3e0bfab8b4 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 13 May 2024 10:38:31 -0700 Subject: [PATCH 090/102] blast_repo fixes (dart-lang/string_scanner#73) dependabot --- pkgs/string_scanner/.github/dependabot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/string_scanner/.github/dependabot.yml b/pkgs/string_scanner/.github/dependabot.yml index c84404dc9..a19a66adf 100644 --- a/pkgs/string_scanner/.github/dependabot.yml +++ b/pkgs/string_scanner/.github/dependabot.yml @@ -10,3 +10,7 @@ updates: interval: monthly labels: - autosubmit + groups: + github-actions: + patterns: + - "*" From ff06b0cf970a4d5b5099e4a7add076acf5cb9b8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 17:40:25 +0000 Subject: [PATCH 091/102] Bump actions/checkout from 4.1.4 to 4.1.5 in the github-actions group (dart-lang/string_scanner#74) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.4 to 4.1.5
Release notes

Sourced from actions/checkout's releases.

v4.1.5

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.4...v4.1.5

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.4&new-version=4.1.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 97fdf914e..05335028c 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From a81f3cececd1cb0d2077c939699aeefc585a75b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jun 2024 00:20:17 +0000 Subject: [PATCH 092/102] Bump actions/checkout from 4.1.5 to 4.1.6 in the github-actions group (dart-lang/string_scanner#75) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.5 to 4.1.6
Release notes

Sourced from actions/checkout's releases.

v4.1.6

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.5...v4.1.6

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.5&new-version=4.1.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 05335028c..58a2061ed 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 8664c4a5b2a58e5e2fdf36bc531ee0fc27c33af2 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 20 Jun 2024 10:45:40 -0700 Subject: [PATCH 093/102] update lints, require Dart 3.1 (dart-lang/string_scanner#76) --- pkgs/string_scanner/.github/workflows/test-package.yml | 2 +- pkgs/string_scanner/CHANGELOG.md | 2 +- pkgs/string_scanner/pubspec.yaml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 58a2061ed..b65aeefdb 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [3.0.0, dev] + sdk: [3.1, dev] steps: - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index fa7af43f3..386a55b52 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,6 +1,6 @@ ## 1.2.1-wip -* Require Dart 3.0.0 +* Require Dart 3.1.0 ## 1.2.0 diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 7ceb7d983..eea570a4f 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -4,11 +4,11 @@ description: A class for parsing strings using a sequence of patterns. repository: https://github.com/dart-lang/string_scanner environment: - sdk: ^3.0.0 + sdk: ^3.1.0 dependencies: source_span: ^1.8.0 dev_dependencies: - dart_flutter_team_lints: ^2.0.0 - test: ^1.16.0 + dart_flutter_team_lints: ^3.0.0 + test: ^1.16.6 From fa4c6940b98bc27f2a69127915e47ca3656601b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 00:54:09 +0000 Subject: [PATCH 094/102] Bump the github-actions group with 2 updates (dart-lang/string_scanner#77) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `actions/checkout` from 4.1.6 to 4.1.7
Release notes

Sourced from actions/checkout's releases.

v4.1.7

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.6...v4.1.7

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

... (truncated)

Commits

Updates `dart-lang/setup-dart` from 1.6.4 to 1.6.5
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.5

dart-lang/string_scanner#118: dart-lang/setup-dartdart-lang/string_scanner#118

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.5

dart-lang/string_scanner#118: dart-lang/setup-dartdart-lang/string_scanner#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

... (truncated)

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/string_scanner/.github/workflows/test-package.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index b65aeefdb..9fc02d97c 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install @@ -49,8 +49,8 @@ jobs: os: [ubuntu-latest] sdk: [3.1, dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install From a8412336926a28d0604eb311b41bd609852f5ea3 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 9 Jul 2024 16:35:39 -0700 Subject: [PATCH 095/102] Add a `SpanScanner.spanFromPosition()` method (dart-lang/string_scanner#78) Tracking raw ints can be more efficient than tracking `LineScannerState` objects, and allows users to do small manual manipulations on the resulting positions. --- pkgs/string_scanner/CHANGELOG.md | 5 ++++- .../lib/src/relative_span_scanner.dart | 12 +++++++++++ pkgs/string_scanner/lib/src/span_scanner.dart | 11 ++++++++++ pkgs/string_scanner/pubspec.yaml | 2 +- .../test/span_scanner_test.dart | 20 +++++++++++++++++++ 5 files changed, 48 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index 386a55b52..a4c17b6bd 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,7 +1,10 @@ -## 1.2.1-wip +## 1.3.0 * Require Dart 3.1.0 +* Add a `SpanScanner.spanFromPosition()` method which takes raw code units + rather than `SpanScanner.spanFrom()`'s `LineScannerState`s. + ## 1.2.0 * Require Dart 2.18.0 diff --git a/pkgs/string_scanner/lib/src/relative_span_scanner.dart b/pkgs/string_scanner/lib/src/relative_span_scanner.dart index 150d5071e..cd9af0e03 100644 --- a/pkgs/string_scanner/lib/src/relative_span_scanner.dart +++ b/pkgs/string_scanner/lib/src/relative_span_scanner.dart @@ -78,6 +78,18 @@ class RelativeSpanScanner extends StringScanner implements SpanScanner { _startLocation.offset + endPosition); } + @override + FileSpan spanFromPosition(int startPosition, [int? endPosition]) { + RangeError.checkValidRange( + startPosition, + endPosition, + _sourceFile.length - _startLocation.offset, + 'startPosition', + 'endPosition'); + return _sourceFile.span(_startLocation.offset + startPosition, + _startLocation.offset + (endPosition ?? position)); + } + @override bool matches(Pattern pattern) { if (!super.matches(pattern)) { diff --git a/pkgs/string_scanner/lib/src/span_scanner.dart b/pkgs/string_scanner/lib/src/span_scanner.dart index 413a43331..509cf6004 100644 --- a/pkgs/string_scanner/lib/src/span_scanner.dart +++ b/pkgs/string_scanner/lib/src/span_scanner.dart @@ -91,6 +91,17 @@ class SpanScanner extends StringScanner implements LineScanner { return _sourceFile.span(startState.position, endPosition); } + /// Creates a [FileSpan] representing the source range between [startPosition] + /// and [endPosition], or the current position if [endPosition] is null. + /// + /// Each position should be a code unit offset into the string being scanned, + /// with the same conventions as [StringScanner.position]. + /// + /// Throws a [RangeError] if [startPosition] or [endPosition] aren't within + /// this source file. + FileSpan spanFromPosition(int startPosition, [int? endPosition]) => + _sourceFile.span(startPosition, endPosition ?? position); + @override bool matches(Pattern pattern) { if (!super.matches(pattern)) { diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index eea570a4f..b8585385c 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.2.1-wip +version: 1.3.0 description: A class for parsing strings using a sequence of patterns. repository: https://github.com/dart-lang/string_scanner diff --git a/pkgs/string_scanner/test/span_scanner_test.dart b/pkgs/string_scanner/test/span_scanner_test.dart index 0e20c36a5..93d9c477c 100644 --- a/pkgs/string_scanner/test/span_scanner_test.dart +++ b/pkgs/string_scanner/test/span_scanner_test.dart @@ -75,6 +75,16 @@ void main() { expect(span.text, equals('o\nbar\nba')); }); + test('.spanFromPosition() returns a span from a previous state', () { + scanner.scan('fo'); + final start = scanner.position; + scanner.scan('o\nba'); + scanner.scan('r\nba'); + + final span = scanner.spanFromPosition(start + 2, start + 5); + expect(span.text, equals('bar')); + }); + test('.emptySpan returns an empty span at the current location', () { scanner.scan('foo\nba'); @@ -139,6 +149,16 @@ void testForImplementation( expect(span.text, equals('o\nbar\nba')); }); + test('.spanFromPosition() returns a span from a previous state', () { + scanner.scan('fo'); + final start = scanner.position; + scanner.scan('o\nba'); + scanner.scan('r\nba'); + + final span = scanner.spanFromPosition(start + 2, start + 5); + expect(span.text, equals('bar')); + }); + test('.emptySpan returns an empty span at the current location', () { scanner.scan('foo\nba'); From 0d71bece47e6a0ccfc1db28112764c38c9f5106b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 00:22:01 +0000 Subject: [PATCH 096/102] Bump actions/checkout from 4.1.7 to 4.2.0 in the github-actions group (dart-lang/string_scanner#79) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.7 to 4.2.0
Release notes

Sourced from actions/checkout's releases.

v4.2.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.7...v4.2.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.7&new-version=4.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 9fc02d97c..91f097e22 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.1, dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From 5916da269c0eaaba43064fce2c233ce57691f874 Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Wed, 9 Oct 2024 20:46:54 +0100 Subject: [PATCH 097/102] Avoid treating /r as newline on it (dart-lang/string_scanner#81) Fixes https://github.com/dart-lang/string_scanner/issues/80 This fixes an error when scanning a zero-length match when between a CR and LF. * Fix typo * comment nits * Fix some bugs when setting position if the current position is between \r\n --------- Co-authored-by: Nate Bosch --- pkgs/string_scanner/CHANGELOG.md | 8 + pkgs/string_scanner/lib/src/line_scanner.dart | 70 ++++- pkgs/string_scanner/pubspec.yaml | 2 +- .../test/line_scanner_test.dart | 243 ++++++++++++++++-- 4 files changed, 292 insertions(+), 31 deletions(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index a4c17b6bd..ee75f7338 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.4.0 + +* Fix `LineScanner`'s handling of `\r\n`'s to preventing errors scanning + zero-length matches when between CR and LF. CR is treated as a new line only + if not immediately followed by a LF. +* Fix `LineScanner`'s updating of `column` when setting `position` if the + current position is not `0`. + ## 1.3.0 * Require Dart 3.1.0 diff --git a/pkgs/string_scanner/lib/src/line_scanner.dart b/pkgs/string_scanner/lib/src/line_scanner.dart index 2903c4039..b18d61057 100644 --- a/pkgs/string_scanner/lib/src/line_scanner.dart +++ b/pkgs/string_scanner/lib/src/line_scanner.dart @@ -8,8 +8,9 @@ import 'utils.dart'; // Note that much of this code is duplicated in eager_span_scanner.dart. -/// A regular expression matching newlines across platforms. -final _newlineRegExp = RegExp(r'\r\n?|\n'); +/// A regular expression matching newlines. A newline is either a `\n`, a `\r\n` +/// or a `\r` that is not immediately followed by a `\n`. +final _newlineRegExp = RegExp(r'\n|\r\n|\r(?!\n)'); /// A subclass of [StringScanner] that tracks line and column information. class LineScanner extends StringScanner { @@ -48,27 +49,57 @@ class LineScanner extends StringScanner { @override set position(int newPosition) { + if (newPosition == position) { + return; + } + final oldPosition = position; super.position = newPosition; - if (newPosition > oldPosition) { - final newlines = _newlinesIn(string.substring(oldPosition, newPosition)); + if (newPosition == 0) { + _line = 0; + _column = 0; + } else if (newPosition > oldPosition) { + final newlines = _newlinesIn(string.substring(oldPosition, newPosition), + endPosition: newPosition); _line += newlines.length; if (newlines.isEmpty) { _column += newPosition - oldPosition; } else { - _column = newPosition - newlines.last.end; + // The regex got a substring, so we need to account for where it started + // in the string. + final offsetOfLastNewline = oldPosition + newlines.last.end; + _column = newPosition - offsetOfLastNewline; } - } else { - final newlines = _newlinesIn(string.substring(newPosition, oldPosition)); - if (_betweenCRLF) newlines.removeLast(); + } else if (newPosition < oldPosition) { + final newlines = _newlinesIn(string.substring(newPosition, oldPosition), + endPosition: oldPosition); _line -= newlines.length; if (newlines.isEmpty) { _column -= oldPosition - newPosition; } else { - _column = - newPosition - string.lastIndexOf(_newlineRegExp, newPosition) - 1; + // To compute the new column, we need to locate the last newline before + // the new position. When searching, we must exclude the CR if we're + // between a CRLF because it's not considered a newline. + final crOffset = _betweenCRLF ? -1 : 0; + // Additionally, if we use newPosition as the end of the search and the + // character at that position itself (the next character) is a newline + // we should not use it, so also offset to account for that. + const currentCharOffset = -1; + final lastNewline = string.lastIndexOf( + _newlineRegExp, newPosition + currentCharOffset + crOffset); + + // Now we need to know the offset after the newline. This is the index + // above plus the length of the newline (eg. if we found `\r\n`) we need + // to add two. However if no newline was found, that index is 0. + final offsetAfterLastNewline = lastNewline == -1 + ? 0 + : string[lastNewline] == '\r' && string[lastNewline + 1] == '\n' + ? lastNewline + 2 + : lastNewline + 1; + + _column = newPosition - offsetAfterLastNewline; } } } @@ -103,7 +134,7 @@ class LineScanner extends StringScanner { bool scan(Pattern pattern) { if (!super.scan(pattern)) return false; - final newlines = _newlinesIn(lastMatch![0]!); + final newlines = _newlinesIn(lastMatch![0]!, endPosition: position); _line += newlines.length; if (newlines.isEmpty) { _column += lastMatch![0]!.length; @@ -115,10 +146,21 @@ class LineScanner extends StringScanner { } /// Returns a list of [Match]es describing all the newlines in [text], which - /// is assumed to end at [position]. - List _newlinesIn(String text) { + /// ends at [endPosition]. + /// + /// If [text] ends with `\r`, it will only be treated as a newline if the next + /// character at [position] is not a `\n`. + List _newlinesIn(String text, {required int endPosition}) { final newlines = _newlineRegExp.allMatches(text).toList(); - if (_betweenCRLF) newlines.removeLast(); + // If the last character is a `\r` it will have been treated as a newline, + // but this is only valid if the next character is not a `\n`. + if (endPosition < string.length && + text.endsWith('\r') && + string[endPosition] == '\n') { + // newlines should never be empty here, because if `text` ends with `\r` + // it would have matched `\r(?!\n)` in the newline regex. + newlines.removeLast(); + } return newlines; } } diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index b8585385c..a8295e9c2 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.3.0 +version: 1.4.0 description: A class for parsing strings using a sequence of patterns. repository: https://github.com/dart-lang/string_scanner diff --git a/pkgs/string_scanner/test/line_scanner_test.dart b/pkgs/string_scanner/test/line_scanner_test.dart index d31d313a3..1af5c3666 100644 --- a/pkgs/string_scanner/test/line_scanner_test.dart +++ b/pkgs/string_scanner/test/line_scanner_test.dart @@ -19,25 +19,24 @@ void main() { group('scan()', () { test('consuming no newlines increases the column but not the line', () { - scanner.scan('foo'); + scanner.expect('foo'); expect(scanner.line, equals(0)); expect(scanner.column, equals(3)); }); - test('consuming a newline resets the column and increases the line', () { + test('consuming a LF resets the column and increases the line', () { scanner.expect('foo\nba'); expect(scanner.line, equals(1)); expect(scanner.column, equals(2)); }); - test('consuming multiple newlines resets the column and increases the line', - () { + test('consuming multiple LFs resets the column and increases the line', () { scanner.expect('foo\nbar\r\nb'); expect(scanner.line, equals(2)); expect(scanner.column, equals(1)); }); - test("consuming halfway through a CR LF doesn't count as a line", () { + test('consuming a CR LF increases the line only after the LF', () { scanner.expect('foo\nbar\r'); expect(scanner.line, equals(1)); expect(scanner.column, equals(4)); @@ -46,6 +45,41 @@ void main() { expect(scanner.line, equals(2)); expect(scanner.column, equals(1)); }); + + test('consuming a CR not followed by LF increases the line', () { + scanner = LineScanner('foo\nbar\rbaz'); + scanner.expect('foo\nbar\r'); + expect(scanner.line, equals(2)); + expect(scanner.column, equals(0)); + + scanner.expect('b'); + expect(scanner.line, equals(2)); + expect(scanner.column, equals(1)); + }); + + test('consuming a CR at the end increases the line', () { + scanner = LineScanner('foo\nbar\r'); + scanner.expect('foo\nbar\r'); + expect(scanner.line, equals(2)); + expect(scanner.column, equals(0)); + expect(scanner.isDone, isTrue); + }); + + test('consuming a mix of CR, LF, CR+LF increases the line', () { + scanner = LineScanner('0\n1\r2\r\n3'); + scanner.expect('0\n1\r2\r\n3'); + expect(scanner.line, equals(3)); + expect(scanner.column, equals(1)); + }); + + test('scanning a zero length match between CR LF does not fail', () { + scanner.expect('foo\nbar\r'); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(4)); + scanner.expect(RegExp('(?!x)')); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(4)); + }); }); group('readChar()', () { @@ -56,7 +90,7 @@ void main() { expect(scanner.column, equals(1)); }); - test('consuming a newline resets the column and increases the line', () { + test('consuming a LF resets the column and increases the line', () { scanner.expect('foo'); expect(scanner.line, equals(0)); expect(scanner.column, equals(3)); @@ -66,19 +100,52 @@ void main() { expect(scanner.column, equals(0)); }); - test("consuming halfway through a CR LF doesn't count as a line", () { + test('consuming a CR LF increases the line only after the LF', () { + scanner = LineScanner('foo\r\nbar'); + scanner.expect('foo'); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(3)); + + scanner.readChar(); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(4)); + + scanner.readChar(); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(0)); + }); + + test('consuming a CR not followed by a LF increases the line', () { + scanner = LineScanner('foo\nbar\rbaz'); scanner.expect('foo\nbar'); expect(scanner.line, equals(1)); expect(scanner.column, equals(3)); scanner.readChar(); + expect(scanner.line, equals(2)); + expect(scanner.column, equals(0)); + }); + + test('consuming a CR at the end increases the line', () { + scanner = LineScanner('foo\nbar\r'); + scanner.expect('foo\nbar'); expect(scanner.line, equals(1)); - expect(scanner.column, equals(4)); + expect(scanner.column, equals(3)); scanner.readChar(); expect(scanner.line, equals(2)); expect(scanner.column, equals(0)); }); + + test('consuming a mix of CR, LF, CR+LF increases the line', () { + scanner = LineScanner('0\n1\r2\r\n3'); + for (var i = 0; i < scanner.string.length; i++) { + scanner.readChar(); + } + + expect(scanner.line, equals(3)); + expect(scanner.column, equals(1)); + }); }); group('readCodePoint()', () { @@ -122,7 +189,7 @@ void main() { expect(scanner.column, equals(1)); }); - test('consuming a newline resets the column and increases the line', () { + test('consuming a LF resets the column and increases the line', () { scanner.expect('foo'); expect(scanner.line, equals(0)); expect(scanner.column, equals(3)); @@ -132,7 +199,7 @@ void main() { expect(scanner.column, equals(0)); }); - test("consuming halfway through a CR LF doesn't count as a line", () { + test('consuming a CR LF increases the line only after the LF', () { scanner.expect('foo\nbar'); expect(scanner.line, equals(1)); expect(scanner.column, equals(3)); @@ -145,6 +212,38 @@ void main() { expect(scanner.line, equals(2)); expect(scanner.column, equals(0)); }); + + test('consuming a CR not followed by LF increases the line', () { + scanner = LineScanner('foo\rbar'); + scanner.expect('foo'); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(3)); + + scanner.scanChar($cr); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(0)); + }); + + test('consuming a CR at the end increases the line', () { + scanner = LineScanner('foo\r'); + scanner.expect('foo'); + expect(scanner.line, equals(0)); + expect(scanner.column, equals(3)); + + scanner.scanChar($cr); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(0)); + }); + + test('consuming a mix of CR, LF, CR+LF increases the line', () { + scanner = LineScanner('0\n1\r2\r\n3'); + for (var i = 0; i < scanner.string.length; i++) { + scanner.scanChar(scanner.string[i].codeUnits.single); + } + + expect(scanner.line, equals(3)); + expect(scanner.column, equals(1)); + }); }); group('before a surrogate pair', () { @@ -201,27 +300,102 @@ void main() { }); group('position=', () { - test('forward through newlines sets the line and column', () { - scanner.position = 10; // "foo\nbar\r\nb" + test('forward through LFs sets the line and column', () { + scanner = LineScanner('foo\nbar\nbaz'); + scanner.position = 9; // "foo\nbar\nb" + expect(scanner.line, equals(2)); + expect(scanner.column, equals(1)); + }); + + test('forward from non-zero character through LFs sets the line and column', + () { + scanner = LineScanner('foo\nbar\nbaz'); + scanner.expect('fo'); + scanner.position = 9; // "foo\nbar\nb" expect(scanner.line, equals(2)); expect(scanner.column, equals(1)); }); + test('forward through CR LFs sets the line and column', () { + scanner = LineScanner('foo\r\nbar\r\nbaz'); + scanner.position = 11; // "foo\r\nbar\r\nb" + expect(scanner.line, equals(2)); + expect(scanner.column, equals(1)); + }); + + test('forward through CR not followed by LFs sets the line and column', () { + scanner = LineScanner('foo\rbar\rbaz'); + scanner.position = 9; // "foo\rbar\rb" + expect(scanner.line, equals(2)); + expect(scanner.column, equals(1)); + }); + + test('forward through CR at end sets the line and column', () { + scanner = LineScanner('foo\rbar\r'); + scanner.position = 8; // "foo\rbar\r" + expect(scanner.line, equals(2)); + expect(scanner.column, equals(0)); + }); + + test('forward through a mix of CR, LF, CR+LF sets the line and column', () { + scanner = LineScanner('0\n1\r2\r\n3'); + scanner.position = scanner.string.length; + + expect(scanner.line, equals(3)); + expect(scanner.column, equals(1)); + }); + test('forward through no newlines sets the column', () { scanner.position = 2; // "fo" expect(scanner.line, equals(0)); expect(scanner.column, equals(2)); }); - test('backward through newlines sets the line and column', () { - scanner.scan('foo\nbar\r\nbaz'); + test('backward through LFs sets the line and column', () { + scanner = LineScanner('foo\nbar\nbaz'); + scanner.expect('foo\nbar\nbaz'); + scanner.position = 2; // "fo" + expect(scanner.line, equals(0)); + expect(scanner.column, equals(2)); + }); + + test('backward through CR LFs sets the line and column', () { + scanner = LineScanner('foo\r\nbar\r\nbaz'); + scanner.expect('foo\r\nbar\r\nbaz'); scanner.position = 2; // "fo" expect(scanner.line, equals(0)); expect(scanner.column, equals(2)); }); + test('backward through CR not followed by LFs sets the line and column', + () { + scanner = LineScanner('foo\rbar\rbaz'); + scanner.expect('foo\rbar\rbaz'); + scanner.position = 2; // "fo" + expect(scanner.line, equals(0)); + expect(scanner.column, equals(2)); + }); + + test('backward through CR at end sets the line and column', () { + scanner = LineScanner('foo\rbar\r'); + scanner.expect('foo\rbar\r'); + scanner.position = 2; // "fo" + expect(scanner.line, equals(0)); + expect(scanner.column, equals(2)); + }); + + test('backward through a mix of CR, LF, CR+LF sets the line and column', + () { + scanner = LineScanner('0\n1\r2\r\n3'); + scanner.expect(scanner.string); + + scanner.position = 1; + expect(scanner.line, equals(0)); + expect(scanner.column, equals(1)); + }); + test('backward through no newlines sets the column', () { - scanner.scan('foo\nbar\r\nbaz'); + scanner.expect('foo\nbar\r\nbaz'); scanner.position = 10; // "foo\nbar\r\nb" expect(scanner.line, equals(2)); expect(scanner.column, equals(1)); @@ -232,10 +406,47 @@ void main() { expect(scanner.line, equals(1)); expect(scanner.column, equals(4)); }); + + test('forward from halfway through a CR LF counts as a line', () { + scanner.expect('foo\nbar\r'); + scanner.position = 11; // "foo\nbar\r\nba" + expect(scanner.line, equals(2)); + expect(scanner.column, equals(2)); + }); + + test('backward to between CR LF', () { + scanner.expect('foo\nbar\r\nbaz'); + scanner.position = 8; // "foo\nbar\r" + expect(scanner.line, equals(1)); + expect(scanner.column, equals(4)); + }); + + test('backward from between CR LF', () { + scanner.expect('foo\nbar\r'); + expect(scanner.line, equals(1)); + expect(scanner.column, equals(4)); + scanner.position = 5; // "foo\nb" + expect(scanner.line, equals(1)); + expect(scanner.column, equals(1)); + }); + + test('backward to after CR LF', () { + scanner.expect('foo\nbar\r\nbaz'); + scanner.position = 9; // "foo\nbar\r\n" + expect(scanner.line, equals(2)); + expect(scanner.column, equals(0)); + }); + + test('backward to before CR LF', () { + scanner.expect('foo\nbar\r\nbaz'); + scanner.position = 7; // "foo\nbar" + expect(scanner.line, equals(1)); + expect(scanner.column, equals(3)); + }); }); test('state= restores the line, column, and position', () { - scanner.scan('foo\nb'); + scanner.expect('foo\nb'); final state = scanner.state; scanner.scan('ar\nba'); From f876f9de3273080a639a0dbfc2bdab2f7a74dbde Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 28 Oct 2024 19:07:20 -0700 Subject: [PATCH 098/102] blast_repo fixes (dart-lang/string_scanner#83) drop-lint --- pkgs/string_scanner/analysis_options.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/string_scanner/analysis_options.yaml b/pkgs/string_scanner/analysis_options.yaml index 813466b66..59f763a4d 100644 --- a/pkgs/string_scanner/analysis_options.yaml +++ b/pkgs/string_scanner/analysis_options.yaml @@ -22,7 +22,6 @@ linter: - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - no_runtimeType_toString - - package_api_docs - prefer_const_declarations - prefer_expression_function_bodies - prefer_final_locals From 8c0f5652e576489d1521f824ccd9393e46fd5773 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 00:27:17 +0000 Subject: [PATCH 099/102] Bump actions/checkout from 4.2.0 to 4.2.2 in the github-actions group (dart-lang/string_scanner#84) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.2.0 to 4.2.2
Release notes

Sourced from actions/checkout's releases.

v4.2.2

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.2.1...v4.2.2

v4.2.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.2.0...v4.2.1

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.2

v4.2.1

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.2.0&new-version=4.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index 91f097e22..a5149a239 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.1, dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From b47d77a4aad6d79346a57cc1dab9bd52792a0fd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 00:11:17 +0000 Subject: [PATCH 100/102] Bump dart-lang/setup-dart in the github-actions group (dart-lang/string_scanner#85) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `dart-lang/setup-dart` from 1.6.5 to 1.7.0
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.7.0

What's Changed

  • Install a Flutter SDK in the publish workflow allowing for publication of flutter packages.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.7.0

v1.6.5

dart-lang/string_scanner#118: dart-lang/setup-dartdart-lang/string_scanner#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.5&new-version=1.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/string_scanner/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/string_scanner/.github/workflows/test-package.yml b/pkgs/string_scanner/.github/workflows/test-package.yml index a5149a239..c60f71070 100644 --- a/pkgs/string_scanner/.github/workflows/test-package.yml +++ b/pkgs/string_scanner/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.1, dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install From 696b3f2dc4963097e40a0e95042d0f4394e04167 Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 11 Dec 2024 14:08:00 +0100 Subject: [PATCH 101/102] Add issue template and other fixes --- .github/ISSUE_TEMPLATE/string_scanner.md | 5 +++++ pkgs/string_scanner/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/string_scanner.md diff --git a/.github/ISSUE_TEMPLATE/string_scanner.md b/.github/ISSUE_TEMPLATE/string_scanner.md new file mode 100644 index 000000000..ad89f1b5b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/string_scanner.md @@ -0,0 +1,5 @@ +--- +name: "package:string_scanner" +about: "Create a bug or file a feature request against package:string_scanner." +labels: "package:string_scanner" +--- \ No newline at end of file diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index a8295e9c2..0930cda49 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,7 +1,7 @@ name: string_scanner version: 1.4.0 description: A class for parsing strings using a sequence of patterns. -repository: https://github.com/dart-lang/string_scanner +repository: https://github.com/dart-lang/tools/tree/main/pkgs/string_scanner environment: sdk: ^3.1.0 From c72a0aeb6a20809ae7adc7aede25dba556846f1a Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 17 Dec 2024 10:57:32 +0100 Subject: [PATCH 102/102] Add changelog --- pkgs/string_scanner/CHANGELOG.md | 4 ++++ pkgs/string_scanner/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkgs/string_scanner/CHANGELOG.md b/pkgs/string_scanner/CHANGELOG.md index ee75f7338..082e9f201 100644 --- a/pkgs/string_scanner/CHANGELOG.md +++ b/pkgs/string_scanner/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.4.1 + +* Move to `dart-lang/tools` monorepo. + ## 1.4.0 * Fix `LineScanner`'s handling of `\r\n`'s to preventing errors scanning diff --git a/pkgs/string_scanner/pubspec.yaml b/pkgs/string_scanner/pubspec.yaml index 0930cda49..9b259cf7b 100644 --- a/pkgs/string_scanner/pubspec.yaml +++ b/pkgs/string_scanner/pubspec.yaml @@ -1,5 +1,5 @@ name: string_scanner -version: 1.4.0 +version: 1.4.1 description: A class for parsing strings using a sequence of patterns. repository: https://github.com/dart-lang/tools/tree/main/pkgs/string_scanner