Enable and fix a number of lints, test on oldest supported SDK (#15)

Bump min SDK to Dart 2.0
diff --git a/.travis.yml b/.travis.yml
index 4496f3a..48e46ca 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@
 
 dart:
   - dev
-  - stable
+  - 2.0.0
 
 dart_task:
   - test: --platform vm,chrome
@@ -13,7 +13,11 @@
     - 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/CHANGELOG.md b/CHANGELOG.md
index 43b9453..1fba528 100644
--- a/CHANGELOG.md
+++ b/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/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 0000000..d5d5213
--- /dev/null
+++ b/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/lib/src/eager_span_scanner.dart b/lib/src/eager_span_scanner.dart
index 96c7362..a2df0f8 100644
--- a/lib/src/eager_span_scanner.dart
+++ b/lib/src/eager_span_scanner.dart
@@ -11,7 +11,7 @@
 // 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 @@
   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/lib/src/exception.dart b/lib/src/exception.dart
index 84bf5e8..3710ae8 100644
--- a/lib/src/exception.dart
+++ b/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/lib/src/line_scanner.dart b/lib/src/line_scanner.dart
index 5182035..e16302a 100644
--- a/lib/src/line_scanner.dart
+++ b/lib/src/line_scanner.dart
@@ -9,7 +9,7 @@
 // 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 @@
   ///
   /// 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 @@
 
   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/lib/src/relative_span_scanner.dart b/lib/src/relative_span_scanner.dart
index 088ff48..1a992e4 100644
--- a/lib/src/relative_span_scanner.dart
+++ b/lib/src/relative_span_scanner.dart
@@ -19,7 +19,7 @@
 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 @@
         : 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 @@
     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/lib/src/span_scanner.dart b/lib/src/span_scanner.dart
index a629f13..d332216 100644
--- a/lib/src/span_scanner.dart
+++ b/lib/src/span_scanner.dart
@@ -12,26 +12,26 @@
 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 @@
   /// [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 @@
 
   /// 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 @@
     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/lib/src/string_scanner.dart b/lib/src/string_scanner.dart
index d32dc38..4506355 100644
--- a/lib/src/string_scanner.dart
+++ b/lib/src/string_scanner.dart
@@ -12,7 +12,7 @@
 /// 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 @@
   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 @@
   /// 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 @@
       } else if (character == $double_quote) {
         name = r'"\""';
       } else {
-        name = '"${new String.fromCharCode(character)}"';
+        name = '"${String.fromCharCode(character)}"';
       }
     }
 
@@ -181,7 +181,7 @@
   /// 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 @@
     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/lib/src/utils.dart b/lib/src/utils.dart
index aa3e957..df29ba2 100644
--- a/lib/src/utils.dart
+++ b/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/pubspec.yaml b/pubspec.yaml
index 7691990..2bc50d6 100644
--- a/pubspec.yaml
+++ b/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 <misc@dartlang.org>
 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 @@
   source_span: ^1.4.0
 
 dev_dependencies:
-  test: '>=0.12.0 <2.0.0'
+  test: ^1.0.0
 
diff --git a/test/error_test.dart b/test/error_test.dart
index 166077d..b966b1b 100644
--- a/test/error_test.dart
+++ b/test/error_test.dart
@@ -9,7 +9,7 @@
 
 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 @@
 
   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 @@
     });
 
     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 @@
     });
 
     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 @@
     });
 
     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 @@
 
   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/test/line_scanner_test.dart b/test/line_scanner_test.dart
index ed04b37..8767142 100644
--- a/test/line_scanner_test.dart
+++ b/test/line_scanner_test.dart
@@ -7,9 +7,9 @@
 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 @@
   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/test/span_scanner_test.dart b/test/span_scanner_test.dart
index 37a01e0..65694ea 100644
--- a/test/span_scanner_test.dart
+++ b/test/span_scanner_test.dart
@@ -10,23 +10,22 @@
 
 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 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/test/string_scanner_test.dart b/test/string_scanner_test.dart
index 30711f5..9d6d6b8 100644
--- a/test/string_scanner_test.dart
+++ b/test/string_scanner_test.dart
@@ -8,9 +8,9 @@
 
 void main() {
   group('with an empty string', () {
-    var scanner;
+    StringScanner scanner;
     setUp(() {
-      scanner = new StringScanner('');
+      scanner = StringScanner('');
     });
 
     test('is done', () {
@@ -55,19 +55,19 @@
     });
 
     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 @@
   });
 
   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 @@
     });
 
     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 @@
     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 @@
 
     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 @@
       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 @@
     });
 
     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 @@
   });
 
   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 @@
   });
 
   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 @@
     });
 
     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 @@
       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 @@
 
   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/test/utils.dart b/test/utils.dart
index 7767fbc..676b695 100644
--- a/test/utils.dart
+++ b/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<StringScannerException>());
-    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<StringScannerException>()
+        .having((e) => e.span.text, 'span.text', text));