[repo] improve the analysis of the tools/ directory

Change-Id: I4185e3bdc1f0f6f8464ebc2a043254200e3df486
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/233502
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Devon Carew <devoncarew@google.com>
diff --git a/tools/addlatexhash.dart b/tools/addlatexhash.dart
index a3b2230..d1cc30f 100755
--- a/tools/addlatexhash.dart
+++ b/tools/addlatexhash.dart
@@ -22,6 +22,10 @@
 // NB: This utility assumes UN*X style line endings, \n, in the LaTeX
 // source file received as input; it will not work with other styles.
 
+// @dart = 2.9
+
+// ignore_for_file: constant_identifier_names
+
 import 'dart:convert';
 import 'dart:io';
 
@@ -32,15 +36,15 @@
 // Normalization of the text: removal or normalization of parts that
 // do not affect the output from latex, such as white space.
 
-final commentRE = new RegExp(r"[^\\]%.*"); // NB: . does not match \n.
-final whitespaceAllRE = new RegExp(r"^\s+$");
-final whitespaceRE = new RegExp(r"(?:(?=\s).){2,}"); // \s except end-of-line
+final commentRE = RegExp(r"[^\\]%.*"); // NB: . does not match \n.
+final whitespaceAllRE = RegExp(r"^\s+$");
+final whitespaceRE = RegExp(r"(?:(?=\s).){2,}"); // \s except end-of-line
 
 /// Removes [match]ing part of [line], adjusting that part with the
 /// given [startOffset] and [endOffset], bounded to be valid indices
 /// into the string if needed, then inserts [glue] where text was
 /// removed.  If there is no match then [line] is returned.
-cutMatch(line, match, {startOffset: 0, endOffset: 0, glue: ""}) {
+cutMatch(line, match, {startOffset = 0, endOffset = 0, glue = ""}) {
   if (match == null) return line;
   var start = match.start + startOffset;
   var end = match.end + endOffset;
@@ -50,7 +54,7 @@
   return line.substring(0, start) + glue + line.substring(end);
 }
 
-cutRegexp(line, re, {startOffset: 0, endOffset: 0, glue: ""}) {
+cutRegexp(line, re, {startOffset = 0, endOffset = 0, glue = ""}) {
   return cutMatch(line, re.firstMatch(line),
       startOffset: startOffset, endOffset: endOffset, glue: glue);
 }
@@ -58,12 +62,12 @@
 /// Removes the rest of [line] starting from the beginning of the
 /// given [match], and adjusting with the given [offset].  If there
 /// is no match then [line] is returned.
-cutFromMatch(line, match, {offset: 0, glue: ""}) {
+cutFromMatch(line, match, {offset = 0, glue = ""}) {
   if (match == null) return line;
   return line.substring(0, match.start + offset) + glue;
 }
 
-cutFromRegexp(line, re, {offset: 0, glue: ""}) {
+cutFromRegexp(line, re, {offset = 0, glue = ""}) {
   return cutFromMatch(line, re.firstMatch(line), offset: offset, glue: glue);
 }
 
@@ -175,8 +179,8 @@
 
 // Managing fragments with significant spacing.
 
-final dartCodeBeginRE = new RegExp(r"^\s*\\begin\s*\{dartCode\}");
-final dartCodeEndRE = new RegExp(r"^\s*\\end\s*\{dartCode\}");
+final dartCodeBeginRE = RegExp(r"^\s*\\begin\s*\{dartCode\}");
+final dartCodeEndRE = RegExp(r"^\s*\\end\s*\{dartCode\}");
 
 /// Recognizes beginning of dartCode block.
 sispIsDartBegin(line) => line.contains(dartCodeBeginRE);
@@ -204,11 +208,10 @@
 /// Returns RegExp text for recognizing a command occupying a line
 /// of its own, given the part of the RegExp that recognizes the
 /// command name, [cmdNameRE]
-lineCommandRE(cmdNameRE) =>
-    new RegExp(r"^\s*\\" + cmdNameRE + r"\s*\{.*\}%?\s*$");
+lineCommandRE(cmdNameRE) => RegExp(r"^\s*\\" + cmdNameRE + r"\s*\{.*\}%?\s*$");
 
-final hashLabelStartRE = new RegExp(r"^\s*\\LMLabel\s*\{");
-final hashLabelEndRE = new RegExp(r"\}\s*$");
+final hashLabelStartRE = RegExp(r"^\s*\\LMLabel\s*\{");
+final hashLabelEndRE = RegExp(r"\}\s*$");
 
 final hashMarkRE = lineCommandRE("LMHash");
 final hashLabelRE = lineCommandRE("LMLabel");
@@ -259,19 +262,19 @@
   /// The endLineNumber specifies the end of the block of lines
   /// associated with a given event, for event types concerned with
   /// blocks of lines rather than single lines.
-  setEndLineNumber(n) {}
+  setEndLineNumber(int n) {}
 
   /// Returns null except for \LMHash{} events, where it returns
   /// the startLineNumber.  This serves to specify a boundary because
   /// the preceding \LMHash{} block should stop before the line of
   /// this \LMHash{} command.  Note that hash blocks may stop earlier,
   /// because they cannot contain sectioning commands.
-  getStartLineNumber() => null;
+  int getStartLineNumber() => null;
 }
 
 class HashMarkerEvent extends HashEvent {
   // Line number of first line in block that gets hashed.
-  var startLineNumber;
+  int startLineNumber;
 
   // Highest possible number of first line after block that gets
   // hashed (where the next \LMHash{} occurs).  Note that this value
@@ -279,19 +282,21 @@
   // reached), so [endLineNumber] will be initialized in a separate
   // scan.  Also note that the block may end earlier, because a block
   // ends if it would otherwise include a sectioning command.
-  var endLineNumber;
+  int endLineNumber;
 
   HashMarkerEvent(this.startLineNumber);
 
-  setEndLineNumber(n) {
+  @override
+  setEndLineNumber(int n) {
     endLineNumber = n;
   }
 
-  getStartLineNumber() => startLineNumber;
+  @override
+  int getStartLineNumber() => startLineNumber;
 }
 
 class HashLabelEvent extends HashEvent {
-  var labelText;
+  String labelText;
   HashLabelEvent(this.labelText);
 }
 
@@ -337,10 +342,8 @@
         return "subsec:";
       case PENDING_IS_SUBSUBSECTION:
         return "subsubsec:";
-      case PENDING_IS_PARAGRAPH:
-        return "par:";
       case PENDING_IS_NONE:
-        throw "\\LMHash{..} should only be used after a sectioning command " +
+        throw "\\LMHash{..} should only be used after a sectioning command "
             "(\\section, \\subsection, \\subsubsection, \\paragraph)";
       default:
         // set of PENDING_IS_.. was extended, but updates here omitted
@@ -351,10 +354,10 @@
   analyze(line) {
     var currentLineNumber = lineNumber++;
     if (isHashMarker(line)) {
-      return new HashMarkerEvent(currentLineNumber);
+      return HashMarkerEvent(currentLineNumber);
     } else if (isHashLabel(line)) {
       var labelText = sectioningPrefix() + extractHashLabel(line);
-      return new HashLabelEvent(labelText);
+      return HashLabelEvent(labelText);
     } else {
       // No events to emit, but we may need to note state changes
       if (isSectionCommand(line)) {
@@ -375,7 +378,7 @@
 
 findHashEvents(lines) {
   // Create the list of events, omitting endLineNumbers.
-  var events = findEvents(lines, new HashAnalyzer());
+  var events = findEvents(lines, HashAnalyzer());
   // Set the endLineNumbers.
   var currentEndLineNumber = lines.length;
   for (var event in events.reversed) {
@@ -444,8 +447,8 @@
   throw "Unmatched braces";
 }
 
-final commentaryRE = new RegExp(r"\\commentary\s*\{");
-final rationaleRE = new RegExp(r"\\rationale\s*\{");
+final commentaryRE = RegExp(r"\\commentary\s*\{");
+final rationaleRE = RegExp(r"\\rationale\s*\{");
 
 /// Removes {}-balanced '\commentary{..}' commands from [line].
 removeCommentary(line) {
@@ -473,7 +476,7 @@
 // ----------------------------------------------------------------------
 // Recognition of line blocks, insertion of block hash into \LMHash{}.
 
-final latexArgumentRE = new RegExp(r"\{.*\}");
+final latexArgumentRE = RegExp(r"\{.*\}");
 
 cleanupLine(line) => cutRegexp(line, commentRE, startOffset: 1).trimRight();
 
@@ -530,15 +533,15 @@
   }
 
   // Get LaTeX source.
-  var inputFile = new File(args[0]);
+  var inputFile = File(args[0]);
   assert(inputFile.existsSync());
   var lines = inputFile.readAsLinesSync();
 
   // Will hold LaTeX source with normalized spacing etc., plus hash values.
-  var outputFile = new File(args[1]);
+  var outputFile = File(args[1]);
 
   // Will hold hierarchical list of hash values.
-  var listFile = new File(args[2]);
+  var listFile = File(args[2]);
   var listSink = listFile.openWrite();
 
   // Perform single-line normalization.
diff --git a/tools/analysis_options.yaml b/tools/analysis_options.yaml
new file mode 100644
index 0000000..204e7c6
--- /dev/null
+++ b/tools/analysis_options.yaml
@@ -0,0 +1,17 @@
+include: package:lints/recommended.yaml
+
+analyzer:
+  exclude:
+    # This directory isn't intended to be analyzed.
+    - sdks/**
+    # There are a fair number of issues in here.
+    - dart2js/**
+    - dom/**
+    - test_generators/**
+
+linter:
+  rules:
+    # TODO: Enable this once other issues are addressed.
+    # - avoid_dynamic_calls
+    - depend_on_referenced_packages
+    - directives_ordering
diff --git a/tools/bots/compare_results.dart b/tools/bots/compare_results.dart
index bcf9abe52..1e2bad3 100755
--- a/tools/bots/compare_results.dart
+++ b/tools/bots/compare_results.dart
@@ -9,8 +9,8 @@
 
 // @dart = 2.9
 
-import '../../pkg/test_runner/bin/compare_results.dart' as compareResults;
+import '../../pkg/test_runner/bin/compare_results.dart' as compare_results;
 
 main(List<String> args) {
-  compareResults.main(args);
+  compare_results.main(args);
 }
diff --git a/tools/bots/extend_results.dart b/tools/bots/extend_results.dart
index 4ab1d2c..6b03623 100644
--- a/tools/bots/extend_results.dart
+++ b/tools/bots/extend_results.dart
@@ -63,7 +63,7 @@
       result['changed'] = true;
     }
   }
-  final sink = new File(newResultsPath).openWrite();
+  final sink = File(newResultsPath).openWrite();
   final sorted = results.keys.toList()..sort();
   for (final key in sorted) {
     sink.writeln(jsonEncode(results[key]));
diff --git a/tools/bots/find_base_commit.dart b/tools/bots/find_base_commit.dart
index 4a68e261..595871d 100755
--- a/tools/bots/find_base_commit.dart
+++ b/tools/bots/find_base_commit.dart
@@ -14,7 +14,7 @@
 import 'package:glob/glob.dart';
 
 void main(List<String> args) async {
-  final parser = new ArgParser();
+  final parser = ArgParser();
   parser.addMultiOption("builder",
       abbr: "b",
       help: "Select the builders matching the glob [option is repeatable]",
@@ -40,15 +40,15 @@
   }
 
   int count = int.parse(options["count"]);
-  final globs = new List<Glob>.from(
-      options["builder"].map((String pattern) => new Glob(pattern)));
+  final globs = List<Glob>.from(
+      options["builder"].map((String pattern) => Glob(pattern)));
 
   // Download the most recent builds from buildbucket.
   const maxBuilds = 1000;
   final url = Uri.parse("https://cr-buildbucket.appspot.com"
       "/prpc/buildbucket.v2.Builds/SearchBuilds");
   const maxRetries = 3;
-  const timeout = const Duration(seconds: 30);
+  const timeout = Duration(seconds: 30);
   final query = jsonEncode({
     "predicate": {
       "builder": {"project": "dart", "bucket": "ci.sandbox"},
@@ -60,7 +60,7 @@
   late Map<String, dynamic> searchResult;
   for (int i = 1; i <= maxRetries; i++) {
     try {
-      final client = new HttpClient();
+      final client = HttpClient();
       final request = await client.postUrl(url).timeout(timeout)
         ..headers.contentType = ContentType.json
         ..headers.add(HttpHeaders.acceptHeader, ContentType.json)
@@ -74,10 +74,10 @@
       const prefix = ")]}'";
       searchResult = await (response
           .cast<List<int>>()
-          .transform(new Utf8Decoder())
+          .transform(Utf8Decoder())
           .map((event) =>
               event.startsWith(prefix) ? event.substring(prefix.length) : event)
-          .transform(new JsonDecoder())
+          .transform(JsonDecoder())
           .cast<Map<String, dynamic>>()
           .first
           .timeout(timeout));
@@ -132,7 +132,7 @@
     }
     final commit = input["id"] as String;
     final buildersForCommit =
-        buildersForCommits.putIfAbsent(commit, () => new Set<String>());
+        buildersForCommits.putIfAbsent(commit, () => <String>{});
     buildersForCommit.add(builder);
   }
 
diff --git a/tools/bots/lib/src/firestore.dart b/tools/bots/lib/src/firestore.dart
index c1d602a..aed2175 100644
--- a/tools/bots/lib/src/firestore.dart
+++ b/tools/bots/lib/src/firestore.dart
@@ -74,7 +74,7 @@
         path: '$collectionName/$documentName',
         query: _currentTransaction == null
             ? null
-            : 'transaction=${_escapedCurrentTransaction}'));
+            : 'transaction=$_escapedCurrentTransaction'));
     var response = await _client.get(url, headers: _headers);
     if (response.statusCode == HttpStatus.ok) {
       var document = jsonDecode(response.body);
@@ -123,7 +123,7 @@
     }
     var body = jsonEncode({
       "writes": writes.map((write) => write.data).toList(),
-      "transaction": "$_currentTransaction"
+      "transaction": _currentTransaction
     });
     var response =
         await _client.post(_commitUrl, headers: _headers, body: body);
@@ -140,7 +140,7 @@
     return true;
   }
 
-  Exception _error(http.Response response, {String message: 'Error'}) {
+  Exception _error(http.Response response, {String message = 'Error'}) {
     throw Exception('$message: ${response.statusCode}: '
         '${response.reasonPhrase}:\n${response.body}');
   }
@@ -154,6 +154,7 @@
 }
 
 class Update implements Write {
+  @override
   final Map data;
   Update(List<String> updateMask, Map document, {String updateTime})
       : data = {
@@ -188,7 +189,7 @@
           'fieldFilter': {
             'field': {'fieldPath': field},
             'op': op,
-            'value': {'$type': value},
+            'value': {type: value},
           }
         });
 }
diff --git a/tools/bots/update_blamelists.dart b/tools/bots/update_blamelists.dart
index af8d525..5488856 100644
--- a/tools/bots/update_blamelists.dart
+++ b/tools/bots/update_blamelists.dart
@@ -11,9 +11,9 @@
 import 'dart:io';
 
 import 'package:args/args.dart';
+import 'package:test_runner/bot_results.dart';
 
 import 'lib/src/firestore.dart';
-import 'package:test_runner/bot_results.dart';
 
 const newTest = 'new test';
 const skippedTest = 'skipped';
@@ -23,7 +23,7 @@
 FirestoreDatabase database;
 
 class ResultRecord {
-  final data;
+  final Map data;
 
   ResultRecord(this.data);
 
@@ -33,7 +33,7 @@
     return int.parse(field('blamelist_start_index')['integerValue']);
   }
 
-  void set blamelistStartIndex(int index) {
+  set blamelistStartIndex(int index) {
     field('blamelist_start_index')['integerValue'] = '$index';
   }
 
@@ -109,7 +109,7 @@
         .where((result) => result['document'] != null)
         .map((result) => result['document']['name']);
     for (var documentPath in documents) {
-      await database.beginTransaction();
+      database.beginTransaction();
       var documentName = documentPath.split('/').last;
       var result =
           ResultRecord(await database.getDocument('results', documentName));
@@ -181,6 +181,6 @@
   var project = options['staging'] ? 'dart-ci-staging' : 'dart-ci';
   database = FirestoreDatabase(
       project, await readGcloudAuthToken(options['auth-token']));
-  await updateBlameLists(configuration, commit, results);
+  updateBlameLists(configuration, commit, results);
   database.closeClient();
 }
diff --git a/tools/diff_results.dart b/tools/diff_results.dart
index 427534f..e00f65b 100644
--- a/tools/diff_results.dart
+++ b/tools/diff_results.dart
@@ -6,8 +6,8 @@
 // @dart = 2.9
 
 import 'dart:async';
-import 'dart:io';
 import 'dart:convert';
+import 'dart:io';
 
 import 'package:args/args.dart';
 import 'package:glob/glob.dart';
@@ -213,7 +213,7 @@
   int h = 0;
   while (h < diffs.length) {
     final d = diffs[h++];
-    final builders = Set<String>()..add(d.builder);
+    final builders = <String>{}..add(d.builder);
     final gropupDiffs = <Diff>[d];
 
     while (h < diffs.length) {
@@ -294,6 +294,7 @@
   Result(this.commit, this.builderName, this.buildNumber, this.name,
       this.expected, this.result);
 
+  @override
   String toString() => '(expected: $expected, actual: $result)';
 
   bool sameResult(Result other) {
@@ -310,7 +311,14 @@
     return false;
   }
 
+  @override
   int get hashCode => name.hashCode ^ builderName.hashCode;
+
+  @override
+  bool operator ==(Object other) {
+    // TODO: implement ==
+    return super == other;
+  }
 }
 
 String currentDate() {
@@ -322,7 +330,7 @@
   final contents = File('tools/bots/test_matrix.json').readAsStringSync();
   final testMatrix = json.decode(contents);
 
-  final vmBuilders = Set<String>();
+  final vmBuilders = <String>{};
   for (final config in testMatrix['builder_configurations']) {
     for (final builder in config['builders']) {
       if (builder.startsWith('vm-') || builder.startsWith('app-')) {
@@ -334,7 +342,7 @@
   // This one is in the test_matrix.json but we don't run it on CI.
   vmBuilders.remove('vm-kernel-asan-linux-release-ia32');
 
-  if (!globs.isEmpty) {
+  if (globs.isNotEmpty) {
     vmBuilders.removeWhere((String builder) {
       return !globs.any((Glob glob) => glob.matches(builder));
     });
diff --git a/tools/generate_experimental_flags.dart b/tools/generate_experimental_flags.dart
index bdb089e..3ae2858 100644
--- a/tools/generate_experimental_flags.dart
+++ b/tools/generate_experimental_flags.dart
@@ -8,12 +8,11 @@
 import 'package:yaml/yaml.dart' show YamlMap, loadYaml;
 
 void main() {
-  YamlMap yaml =
-      loadYaml(new File.fromUri(computeYamlFile()).readAsStringSync());
+  YamlMap yaml = loadYaml(File.fromUri(computeYamlFile()).readAsStringSync());
   final currentVersion = getAsVersionNumber(yaml['current-version']);
-  final enumNames = new StringBuffer();
-  final featureValues = new StringBuffer();
-  final featureNames = new StringBuffer();
+  final enumNames = StringBuffer();
+  final featureValues = StringBuffer();
+  final featureNames = StringBuffer();
 
   YamlMap features = yaml['features'];
   for (var entry in features.entries) {
@@ -112,7 +111,9 @@
 List<num> getAsVersionNumber(dynamic value) {
   if (value == null) return null;
   final version = List.of("$value".split(".").map(int.parse));
-  while (version.length < 3) version.add(0);
+  while (version.length < 3) {
+    version.add(0);
+  }
   return version;
 }
 
diff --git a/tools/line_doc_comments.dart b/tools/line_doc_comments.dart
index cedd1b8..e31109d 100755
--- a/tools/line_doc_comments.dart
+++ b/tools/line_doc_comments.dart
@@ -9,10 +9,10 @@
 
 import 'package:path/path.dart' as path;
 
-final oneLineBlock = new RegExp(r'^(\s*)/\*\*\s?(.*)\*/\s*$');
-final startBlock = new RegExp(r'^(\s*)/\*\*(.*)$');
-final blockLine = new RegExp(r'^\s*\*\s?(.*)$');
-final endBlock = new RegExp(r'^\s*\*/\s*$');
+final oneLineBlock = RegExp(r'^(\s*)/\*\*\s?(.*)\*/\s*$');
+final startBlock = RegExp(r'^(\s*)/\*\*(.*)$');
+final blockLine = RegExp(r'^\s*\*\s?(.*)$');
+final endBlock = RegExp(r'^\s*\*/\s*$');
 
 main(List<String> args) {
   if (args.length != 1) {
@@ -23,7 +23,7 @@
     return;
   }
 
-  var dir = new Directory(args[0]);
+  var dir = Directory(args[0]);
   dir.list(recursive: true, followLinks: false).listen((entity) {
     if (entity is File) {
       var file = entity.path;
@@ -34,19 +34,19 @@
 }
 
 void fixFile(String path) {
-  var file = new File(path);
+  var file = File(path);
   file.readAsLines().then((lines) => fixContents(lines, path)).then((fixed) {
-    return new File(path).writeAsString(fixed);
+    return File(path).writeAsString(fixed);
   }).then((file) {
     print(file.path);
   });
 }
 
 String fixContents(List<String> lines, String path) {
-  var buffer = new StringBuffer();
+  var buffer = StringBuffer();
   var linesOut = 0;
   var inBlock = false;
-  var indent;
+  String indent;
 
   for (var line in lines) {
     var oldLine = line;
@@ -104,11 +104,11 @@
 
       // Warn about lines that crossed 80 columns as a result of the change.
       if (line.length > 80 && oldLine.length <= 80) {
-        const _PURPLE = '\u001b[35m';
-        const _RED = '\u001b[31m';
-        const _NO_COLOR = '\u001b[0m';
+        const purple = '\u001b[35m';
+        const red = '\u001b[31m';
+        const reset = '\u001b[0m';
 
-        print('$_PURPLE$path$_NO_COLOR:$_RED$linesOut$_NO_COLOR: '
+        print('$purple$path$reset:$red$linesOut$reset: '
             'line exceeds 80 cols:\n    $line');
       }
 
diff --git a/tools/manage_deps.dart b/tools/manage_deps.dart
index 9c8e1c6..f954327 100755
--- a/tools/manage_deps.dart
+++ b/tools/manage_deps.dart
@@ -19,8 +19,8 @@
 library bump;
 
 import 'dart:io';
-import 'package:args/command_runner.dart';
 
+import 'package:args/command_runner.dart';
 import 'package:path/path.dart' as p;
 
 class BumpCommand extends Command<int> {
@@ -36,6 +36,7 @@
 4. Prompt to create a CL
 ''';
 
+  @override
   String get invocation =>
       './tools/manage_deps.dart bump <path/to/dependency> <options>';
 
diff --git a/tools/opt_out_files.dart b/tools/opt_out_files.dart
index 6932604..10ec4dd 100644
--- a/tools/opt_out_files.dart
+++ b/tools/opt_out_files.dart
@@ -10,7 +10,7 @@
 final languageMarker = RegExp(r"^\s*//\s*@dart\s*=");
 
 void main(List<String> args) {
-  if (args.length < 1) {
+  if (args.isEmpty) {
     print('Mark files passed on the command line or under a directory');
     print(' passed on the command line as opted out of null safety.  Does');
     print(' not mark files under directories containing a pubspec.yaml file');
diff --git a/tools/package_deps/bin/package_deps.dart b/tools/package_deps/bin/package_deps.dart
index 1bf3598..5fee3c1 100644
--- a/tools/package_deps/bin/package_deps.dart
+++ b/tools/package_deps/bin/package_deps.dart
@@ -101,6 +101,7 @@
   late final String _packageName;
   late final Set<String> _declaredDependencies;
   late final Set<String> _declaredDevDependencies;
+  // ignore: unused_field
   late final Set<String> _declaredOverrideDependencies;
   late final bool _publishToNone;
 
@@ -208,9 +209,9 @@
     //   print('  dev deps: ${devdeps}');
     // }
 
-    var out = (String message) {
+    void out(String message) {
       logger.stdout(logger.ansi.emphasized(message));
-    };
+    }
 
     var undeclaredRegularUses = Set<String>.from(deps)
       ..removeAll(_declaredDependencies);
@@ -439,6 +440,7 @@
 
   PubDep(this.name);
 
+  @override
   String toString() => name;
 
   static PubDep parse(String name, Object dep) {
@@ -461,6 +463,7 @@
 
   SemverPubDep(String name, this.value) : super(name);
 
+  @override
   String toString() => '$name: $value';
 }
 
@@ -469,6 +472,7 @@
 
   PathPubDep(String name, this.path) : super(name);
 
+  @override
   String toString() => '$name: $path';
 }
 
diff --git a/tools/spec_parser/spec_parse.dart b/tools/spec_parser/spec_parse.dart
index d94ce95..d680f6d 100755
--- a/tools/spec_parser/spec_parse.dart
+++ b/tools/spec_parser/spec_parse.dart
@@ -5,9 +5,9 @@
 
 import 'dart:io';
 
-const String ClassPath = '.:/usr/share/java/antlr3-runtime.jar';
-const String MainClass = 'SpecParser';
-const String JavaExecutable = 'java';
+const String classPath = '.:/usr/share/java/antlr3-runtime.jar';
+const String mainClass = 'SpecParser';
+const String javaExecutable = 'java';
 
 main([arguments]) {
   for (String arg in arguments) {
@@ -18,7 +18,7 @@
       print(result.stdout);
     }
 
-    List<String> javaArguments = <String>['-cp', ClassPath, MainClass, arg];
-    Process.run(JavaExecutable, javaArguments).then(handleResult);
+    List<String> javaArguments = <String>['-cp', classPath, mainClass, arg];
+    Process.run(javaExecutable, javaArguments).then(handleResult);
   }
 }
diff --git a/tools/validate_test_matrix.dart b/tools/validate_test_matrix.dart
index 9006b54..ce4e1f1 100644
--- a/tools/validate_test_matrix.dart
+++ b/tools/validate_test_matrix.dart
@@ -8,11 +8,12 @@
 
 import 'dart:convert' show jsonDecode;
 import 'dart:io' show File, Platform;
+
 import 'package:smith/smith.dart' show TestMatrix;
 
 main() {
   var path = Platform.script.resolve("bots/test_matrix.json").toFilePath();
-  var json;
+  Map<String, dynamic> json;
   try {
     json = jsonDecode(File(path).readAsStringSync());
   } catch (e) {
diff --git a/tools/verify_docs/bin/verify_docs.dart b/tools/verify_docs/bin/verify_docs.dart
index ebe1ce7..85bcdf7 100755
--- a/tools/verify_docs/bin/verify_docs.dart
+++ b/tools/verify_docs/bin/verify_docs.dart
@@ -297,7 +297,7 @@
         ..writeAllLines(lines)
         ..writeln('}');
     } else if (template == 'expression') {
-      assert(lines.length >= 1);
+      assert(lines.isNotEmpty);
       buffer
         ..writeln('void main() async =>')
         ..writeAllLines(lines.take(lines.length - 1))
@@ -375,7 +375,7 @@
         print('');
       }
     } else {
-      throw 'unexpected result type: ${result}';
+      throw 'unexpected result type: $result';
     }
 
     return;
@@ -520,7 +520,7 @@
   /// Write every line, right-trimmed, of [lines] with a newline after.
   void writeAllLines(Iterable<String> lines) {
     for (var line in lines) {
-      this.writeln(line.trimRight());
+      writeln(line.trimRight());
     }
   }
 }
diff --git a/tools/yaml2json.dart b/tools/yaml2json.dart
index ef9fcdd..b8936fe 100644
--- a/tools/yaml2json.dart
+++ b/tools/yaml2json.dart
@@ -2,16 +2,14 @@
 // 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:io' show File, exit, stderr;
-
-import 'dart:isolate' show RawReceivePort;
-
 import 'dart:convert' show JsonEncoder;
+import 'dart:io' show File, exit, stderr;
+import 'dart:isolate' show RawReceivePort;
 
 import 'package:yaml/yaml.dart' show loadYaml;
 
 main(List<String> rawArguments) {
-  var port = new RawReceivePort();
+  var port = RawReceivePort();
   bool check = false;
   String? relative;
   List<String> arguments = [];
@@ -28,12 +26,12 @@
     stderr.writeln("Usage: yaml2json.dart input.yaml output.json [--check]");
     exit(1);
   }
-  Uri input = new File(arguments[0]).absolute.uri;
-  Uri output = new File(arguments[1]).absolute.uri;
+  Uri input = File(arguments[0]).absolute.uri;
+  Uri output = File(arguments[1]).absolute.uri;
   String inputString = arguments[0];
   String outputString = arguments[1];
   if (relative != null) {
-    String relativeTo = new File(relative).absolute.uri.toString();
+    String relativeTo = File(relative).absolute.uri.toString();
     if (input.toString().startsWith(relativeTo)) {
       inputString = input.toString().substring(relativeTo.length);
     }
@@ -41,15 +39,15 @@
       outputString = output.toString().substring(relativeTo.length);
     }
   }
-  Map yaml = loadYaml(new File.fromUri(input).readAsStringSync());
-  Map<String, dynamic> result = new Map<String, dynamic>();
+  Map yaml = loadYaml(File.fromUri(input).readAsStringSync());
+  Map<String, dynamic> result = <String, dynamic>{};
   result["comment:0"] = "NOTE: THIS FILE IS GENERATED. DO NOT EDIT.";
   result["comment:1"] =
       "Instead modify '$inputString' and follow the instructions therein.";
   for (String key in yaml.keys) {
     result[key] = yaml[key];
   }
-  File file = new File.fromUri(output);
+  File file = File.fromUri(output);
   String text = const JsonEncoder.withIndent("  ").convert(result);
   if (check) {
     bool needsUpdate = true;