Enable and fix a number of lints
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 7684be7..60abe63 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -7,19 +7,21 @@
 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 @@
     - 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 @@
     - 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/example/example.dart b/example/example.dart
index 0358967..e92677f 100644
--- a/example/example.dart
+++ b/example/example.dart
@@ -12,11 +12,11 @@
 
 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 @@
 
   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/lib/src/eager_span_scanner.dart b/lib/src/eager_span_scanner.dart
index d34e4f7..848cb72 100644
--- a/lib/src/eager_span_scanner.dart
+++ b/lib/src/eager_span_scanner.dart
@@ -44,11 +44,11 @@
 
   @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 @@
         _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 @@
 
   @override
   int readChar() {
-    var character = super.readChar();
+    final character = super.readChar();
     _adjustLineAndColumn(character);
     return character;
   }
@@ -100,7 +100,7 @@
   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 @@
   /// Returns a list of [Match]es describing all the newlines in [text], which
   /// is assumed to end at [position].
   List<Match> _newlinesIn(String text) {
-    var newlines = _newlineRegExp.allMatches(text).toList();
+    final newlines = _newlineRegExp.allMatches(text).toList();
     if (_betweenCRLF) newlines.removeLast();
     return newlines;
   }
diff --git a/lib/src/line_scanner.dart b/lib/src/line_scanner.dart
index 180d923..9e7d918 100644
--- a/lib/src/line_scanner.dart
+++ b/lib/src/line_scanner.dart
@@ -48,11 +48,11 @@
 
   @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 @@
         _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 @@
 
   @override
   int readChar() {
-    var character = super.readChar();
+    final character = super.readChar();
     _adjustLineAndColumn(character);
     return character;
   }
@@ -104,7 +104,7 @@
   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 @@
   /// Returns a list of [Match]es describing all the newlines in [text], which
   /// is assumed to end at [position].
   List<Match> _newlinesIn(String text) {
-    var newlines = _newlineRegExp.allMatches(text).toList();
+    final newlines = _newlineRegExp.allMatches(text).toList();
     if (_betweenCRLF) newlines.removeLast();
     return newlines;
   }
diff --git a/lib/src/relative_span_scanner.dart b/lib/src/relative_span_scanner.dart
index 096bee3..a7a035a 100644
--- a/lib/src/relative_span_scanner.dart
+++ b/lib/src/relative_span_scanner.dart
@@ -34,8 +34,8 @@
 
   @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 @@
 
   @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 @@
     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/lib/src/span_scanner.dart b/lib/src/span_scanner.dart
index 732a76f..1a8ca2a 100644
--- a/lib/src/span_scanner.dart
+++ b/lib/src/span_scanner.dart
@@ -82,14 +82,14 @@
   ///
   /// 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 @@
     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/lib/src/string_scanner.dart b/lib/src/string_scanner.dart
index 1739a7c..55ff17d 100644
--- a/lib/src/string_scanner.dart
+++ b/lib/src/string_scanner.dart
@@ -81,7 +81,7 @@
   /// 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 @@
   ///
   /// 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 @@
 
     if (name == null) {
       if (pattern is RegExp) {
-        var source = pattern.pattern;
+        final source = pattern.pattern;
         name = '/$source/';
       } else {
         name =
@@ -201,8 +201,8 @@
     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/test/error_test.dart b/test/error_test.dart
index dfa7175..6173040 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 = 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 @@
 
   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 @@
 
   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/test/line_scanner_test.dart b/test/line_scanner_test.dart
index dc9b8cf..aafc74a 100644
--- a/test/line_scanner_test.dart
+++ b/test/line_scanner_test.dart
@@ -150,7 +150,7 @@
 
   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/test/span_scanner_test.dart b/test/span_scanner_test.dart
index e2570ae..2034d0a 100644
--- a/test/span_scanner_test.dart
+++ b/test/span_scanner_test.dart
@@ -9,21 +9,23 @@
 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 @@
       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 @@
 
     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 @@
       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 @@
 
     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/test/string_scanner_test.dart b/test/string_scanner_test.dart
index e1e5b4e..9dee9d1 100644
--- a/test/string_scanner_test.dart
+++ b/test/string_scanner_test.dart
@@ -374,7 +374,7 @@
     });
 
     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 @@
 
   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'));