Fix newly enforced package:pedantic lints (#279)

- annotate_overrides
- prefer_adjacent_string_concatenation
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_single_quotes
- unnecessary_this
- use_function_type_syntax_for_parameters

Bump min SDK to 2.2.0 to allow for Set literals.
diff --git a/.travis.yml b/.travis.yml
index 6bb8e4d..a5026d9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,7 @@
 language: dart
 
 dart:
-  - 2.1.1
+  - 2.2.0
   - dev
 
 dart_task:
diff --git a/benchmark/benchmark.dart b/benchmark/benchmark.dart
index 3090799..bd70a8f 100644
--- a/benchmark/benchmark.dart
+++ b/benchmark/benchmark.dart
@@ -11,8 +11,8 @@
 const numTrials = 100;
 const runsPerTrial = 50;
 
-final source = loadFile("input.md");
-final expected = loadFile("output.html");
+final source = loadFile('input.md');
+final expected = loadFile('output.html');
 
 void main(List<String> args) {
   var best = double.infinity;
@@ -38,7 +38,7 @@
     // Sanity check to make sure the output is what we expect and to make sure
     // the VM doesn't optimize "dead" code away.
     if (result != expected) {
-      print("Incorrect output:\n$result");
+      print('Incorrect output:\n$result');
       exit(1);
     }
 
@@ -48,7 +48,7 @@
     printResult("Run ${padLeft('#$i', 3)}", elapsed);
   }
 
-  printResult("Best   ", best);
+  printResult('Best   ', best);
 }
 
 String loadFile(String name) {
@@ -57,14 +57,14 @@
 }
 
 void printResult(String label, double time) {
-  print("$label: ${padLeft(time.toStringAsFixed(2), 4)}ms "
+  print('$label: ${padLeft(time.toStringAsFixed(2), 4)}ms '
       "${'=' * ((time * 20).toInt())}");
 }
 
 String padLeft(input, int length) {
   var result = input.toString();
   if (result.length < length) {
-    result = " " * (length - result.length) + result;
+    result = ' ' * (length - result.length) + result;
   }
 
   return result;
diff --git a/example/app.dart b/example/app.dart
index 7e7cf91..9d11bf7 100644
--- a/example/app.dart
+++ b/example/app.dart
@@ -119,5 +119,6 @@
 }
 
 class NullTreeSanitizer implements NodeTreeSanitizer {
+  @override
   void sanitizeTree(Node node) {}
 }
diff --git a/example/highlight.dart b/example/highlight.dart
index 4460b6e..b46b8bb 100644
--- a/example/highlight.dart
+++ b/example/highlight.dart
@@ -5,7 +5,7 @@
 @JS('hljs')
 library hljs;
 
-import "package:js/js.dart";
+import 'package:js/js.dart';
 
 @JS()
 external void highlightBlock(block);
diff --git a/lib/src/ast.dart b/lib/src/ast.dart
index dd672c1..5755226 100644
--- a/lib/src/ast.dart
+++ b/lib/src/ast.dart
@@ -41,6 +41,7 @@
   /// Whether this element is self-closing.
   bool get isEmpty => children == null;
 
+  @override
   void accept(NodeVisitor visitor) {
     if (visitor.visitElementBefore(this)) {
       if (children != null) {
@@ -52,6 +53,7 @@
     }
   }
 
+  @override
   String get textContent {
     return (children ?? []).map((Node child) => child.textContent).join('');
   }
@@ -63,8 +65,10 @@
 
   Text(this.text);
 
+  @override
   void accept(NodeVisitor visitor) => visitor.visitText(this);
 
+  @override
   String get textContent => text;
 }
 
@@ -75,10 +79,12 @@
 /// of a document are still being parsed, in order to gather all reference link
 /// definitions.
 class UnparsedContent implements Node {
+  @override
   final String textContent;
 
   UnparsedContent(this.textContent);
 
+  @override
   void accept(NodeVisitor visitor) => null;
 }
 
diff --git a/lib/src/block_parser.dart b/lib/src/block_parser.dart
index 56faaab..151624d 100644
--- a/lib/src/block_parser.dart
+++ b/lib/src/block_parser.dart
@@ -205,10 +205,12 @@
 }
 
 class EmptyBlockSyntax extends BlockSyntax {
+  @override
   RegExp get pattern => _emptyPattern;
 
   const EmptyBlockSyntax();
 
+  @override
   Node parse(BlockParser parser) {
     parser.encounteredBlankLine = true;
     parser.advance();
@@ -222,6 +224,7 @@
 class SetextHeaderSyntax extends BlockSyntax {
   const SetextHeaderSyntax();
 
+  @override
   bool canParse(BlockParser parser) {
     if (!_interperableAsParagraph(parser.current)) return false;
     var i = 1;
@@ -242,6 +245,7 @@
     }
   }
 
+  @override
   Node parse(BlockParser parser) {
     var lines = <String>[];
     String tag;
@@ -281,6 +285,7 @@
 class SetextHeaderWithIdSyntax extends SetextHeaderSyntax {
   const SetextHeaderWithIdSyntax();
 
+  @override
   Node parse(BlockParser parser) {
     var element = super.parse(parser) as Element;
     element.generatedId = BlockSyntax.generateAnchorHash(element);
@@ -290,10 +295,12 @@
 
 /// Parses atx-style headers: `## Header ##`.
 class HeaderSyntax extends BlockSyntax {
+  @override
   RegExp get pattern => _headerPattern;
 
   const HeaderSyntax();
 
+  @override
   Node parse(BlockParser parser) {
     var match = pattern.firstMatch(parser.current);
     parser.advance();
@@ -307,6 +314,7 @@
 class HeaderWithIdSyntax extends HeaderSyntax {
   const HeaderWithIdSyntax();
 
+  @override
   Node parse(BlockParser parser) {
     var element = super.parse(parser) as Element;
     element.generatedId = BlockSyntax.generateAnchorHash(element);
@@ -316,10 +324,12 @@
 
 /// Parses email-style blockquotes: `> quote`.
 class BlockquoteSyntax extends BlockSyntax {
+  @override
   RegExp get pattern => _blockquotePattern;
 
   const BlockquoteSyntax();
 
+  @override
   List<String> parseChildLines(BlockParser parser) {
     // Grab all of the lines that form the blockquote, stripping off the ">".
     var childLines = <String>[];
@@ -347,6 +357,7 @@
     return childLines;
   }
 
+  @override
   Node parse(BlockParser parser) {
     var childLines = parseChildLines(parser);
 
@@ -359,12 +370,15 @@
 
 /// Parses preformatted code blocks that are indented four spaces.
 class CodeBlockSyntax extends BlockSyntax {
+  @override
   RegExp get pattern => _indentPattern;
 
+  @override
   bool get canEndBlock => false;
 
   const CodeBlockSyntax();
 
+  @override
   List<String> parseChildLines(BlockParser parser) {
     var childLines = <String>[];
 
@@ -391,6 +405,7 @@
     return childLines;
   }
 
+  @override
   Node parse(BlockParser parser) {
     var childLines = parseChildLines(parser);
 
@@ -410,10 +425,12 @@
 ///
 /// See the CommonMark spec: https://spec.commonmark.org/0.29/#fenced-code-blocks
 class FencedCodeBlockSyntax extends BlockSyntax {
+  @override
   RegExp get pattern => _codeFencePattern;
 
   const FencedCodeBlockSyntax();
 
+  @override
   bool canParse(BlockParser parser) {
     final match = pattern.firstMatch(parser.current);
     if (match == null) return false;
@@ -427,8 +444,9 @@
         !infoString.codeUnits.contains($backquote));
   }
 
+  @override
   List<String> parseChildLines(BlockParser parser, [String endBlock]) {
-    if (endBlock == null) endBlock = '';
+    endBlock ??= '';
 
     var childLines = <String>[];
     parser.advance();
@@ -447,6 +465,7 @@
     return childLines;
   }
 
+  @override
   Node parse(BlockParser parser) {
     // Get the syntax identifier, if there is one.
     var match = pattern.firstMatch(parser.current);
@@ -477,7 +496,7 @@
       if (parser.document.encodeHtml) {
         infoString = escapeHtmlAttribute(infoString);
       }
-      code.attributes['class'] = "language-$infoString";
+      code.attributes['class'] = 'language-$infoString';
     }
 
     var element = Element('pre', [code]);
@@ -488,10 +507,12 @@
 
 /// Parses horizontal rules like `---`, `_ _ _`, `*  *  *`, etc.
 class HorizontalRuleSyntax extends BlockSyntax {
+  @override
   RegExp get pattern => _hrPattern;
 
   const HorizontalRuleSyntax();
 
+  @override
   Node parse(BlockParser parser) {
     parser.advance();
     return Element.empty('hr');
@@ -505,6 +526,7 @@
 /// 2.  Essentially no HTML parsing or validation is done. We're a Markdown
 ///     parser, not an HTML parser!
 abstract class BlockHtmlSyntax extends BlockSyntax {
+  @override
   bool get canEndBlock => true;
 
   const BlockHtmlSyntax();
@@ -526,6 +548,7 @@
   /// tag, which occur very rarely in typical Markdown.
   static final _openBracketPattern = RegExp(r'^ {0,3}<');
 
+  @override
   RegExp get pattern => _pattern;
 
   const BlockTagBlockHtmlSyntax();
@@ -536,6 +559,7 @@
     return super.canParse(parser);
   }
 
+  @override
   Node parse(BlockParser parser) {
     var childLines = <String>[];
 
@@ -550,6 +574,7 @@
 }
 
 class OtherTagBlockHtmlSyntax extends BlockTagBlockHtmlSyntax {
+  @override
   bool get canEndBlock => false;
 
   // Really hacky way to detect "other" HTML. This matches:
@@ -561,6 +586,7 @@
   //   * a close bracket, or
   //   * whitespace followed by not-brackets followed by a close bracket
   // * possible whitespace and the end of the line.
+  @override
   RegExp get pattern => RegExp(r'^ {0,3}</?\w+(?:>|\s+[^>]*>)\s*$');
 
   const OtherTagBlockHtmlSyntax();
@@ -571,6 +597,7 @@
 /// In practice this means that the syntax dominates; it is allowed to eat
 /// many lines, including blank lines, before matching its `endPattern`.
 class LongBlockHtmlSyntax extends BlockHtmlSyntax {
+  @override
   final RegExp pattern;
   final RegExp _endPattern;
 
@@ -578,6 +605,7 @@
       : pattern = RegExp(pattern),
         _endPattern = RegExp(endPattern);
 
+  @override
   Node parse(BlockParser parser) {
     var childLines = <String>[];
     // Eat until we hit [endPattern].
@@ -601,6 +629,7 @@
 
 /// Base class for both ordered and unordered lists.
 abstract class ListSyntax extends BlockSyntax {
+  @override
   bool get canEndBlock => true;
 
   String get listTag;
@@ -619,6 +648,7 @@
 
   static final _whitespaceRe = RegExp('[ \t]*');
 
+  @override
   Node parse(BlockParser parser) {
     var items = <ListItem>[];
     var childLines = <String>[];
@@ -792,8 +822,10 @@
 
 /// Parses unordered lists.
 class UnorderedListSyntax extends ListSyntax {
+  @override
   RegExp get pattern => _ulPattern;
 
+  @override
   String get listTag => 'ul';
 
   const UnorderedListSyntax();
@@ -801,8 +833,10 @@
 
 /// Parses ordered lists.
 class OrderedListSyntax extends ListSyntax {
+  @override
   RegExp get pattern => _olPattern;
 
+  @override
   String get listTag => 'ol';
 
   const OrderedListSyntax();
@@ -814,10 +848,12 @@
   static final _openingPipe = RegExp(r'^\|\s*');
   static final _closingPipe = RegExp(r'\s*\|$');
 
+  @override
   bool get canEndBlock => false;
 
   const TableSyntax();
 
+  @override
   bool canParse(BlockParser parser) {
     // Note: matches *next* line, not the current one. We're looking for the
     // bar separating the head row from the body rows.
@@ -829,6 +865,7 @@
   /// * a head row of head cells (`<th>` cells)
   /// * a divider of hyphens and pipes (not rendered)
   /// * many body rows of body cells (`<td>` cells)
+  @override
   Node parse(BlockParser parser) {
     var alignments = parseAlignments(parser.next);
     var columnCount = alignments.length;
@@ -912,12 +949,15 @@
 
   static final _whitespacePattern = RegExp(r'^\s*$');
 
+  @override
   bool get canEndBlock => false;
 
   const ParagraphSyntax();
 
+  @override
   bool canParse(BlockParser parser) => true;
 
+  @override
   Node parse(BlockParser parser) {
     var childLines = <String>[];
 
diff --git a/lib/src/document.dart b/lib/src/document.dart
index 5f510e0..2d57a46 100644
--- a/lib/src/document.dart
+++ b/lib/src/document.dart
@@ -14,8 +14,8 @@
   final Resolver linkResolver;
   final Resolver imageLinkResolver;
   final bool encodeHtml;
-  final _blockSyntaxes = Set<BlockSyntax>();
-  final _inlineSyntaxes = Set<InlineSyntax>();
+  final _blockSyntaxes = <BlockSyntax>{};
+  final _inlineSyntaxes = <InlineSyntax>{};
 
   Iterable<BlockSyntax> get blockSyntaxes => _blockSyntaxes;
 
@@ -28,11 +28,11 @@
     this.linkResolver,
     this.imageLinkResolver,
     this.encodeHtml = true,
-  }) : this.extensionSet = extensionSet ?? ExtensionSet.commonMark {
-    this._blockSyntaxes
+  }) : extensionSet = extensionSet ?? ExtensionSet.commonMark {
+    _blockSyntaxes
       ..addAll(blockSyntaxes ?? [])
       ..addAll(this.extensionSet.blockSyntaxes);
-    this._inlineSyntaxes
+    _inlineSyntaxes
       ..addAll(inlineSyntaxes ?? [])
       ..addAll(this.extensionSet.inlineSyntaxes);
   }
diff --git a/lib/src/html_renderer.dart b/lib/src/html_renderer.dart
index 2ffc21d..b7ec306 100644
--- a/lib/src/html_renderer.dart
+++ b/lib/src/html_renderer.dart
@@ -2,7 +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.
 
-import 'dart:collection';
 import 'dart:convert';
 
 import 'ast.dart';
@@ -68,7 +67,7 @@
 
   String render(List<Node> nodes) {
     buffer = StringBuffer();
-    uniqueIds = LinkedHashSet<String>();
+    uniqueIds = <String>{};
 
     for (final node in nodes) {
       node.accept(this);
@@ -77,6 +76,7 @@
     return buffer.toString();
   }
 
+  @override
   void visitText(Text text) {
     var content = text.text;
     if (const ['p', 'li'].contains(_lastVisitedTag)) {
@@ -93,6 +93,7 @@
     _lastVisitedTag = null;
   }
 
+  @override
   bool visitElementBefore(Element element) {
     // Hackish. Separate block-level elements with newlines.
     if (buffer.isNotEmpty && _blockTags.contains(element.tag)) {
@@ -128,6 +129,7 @@
     }
   }
 
+  @override
   void visitElementAfter(Element element) {
     assert(identical(_elementStack.last, element));
 
diff --git a/lib/src/inline_parser.dart b/lib/src/inline_parser.dart
index e17a3ba..bb0d650 100644
--- a/lib/src/inline_parser.dart
+++ b/lib/src/inline_parser.dart
@@ -84,7 +84,7 @@
 
     syntaxes.addAll(_defaultSyntaxes);
 
-    if (this.document.encodeHtml) {
+    if (document.encodeHtml) {
       syntaxes.addAll(_htmlSyntaxes);
     }
 
@@ -181,7 +181,7 @@
   /// The parser's position can be overriden with [startMatchPos].
   /// Returns whether or not the pattern successfully matched.
   bool tryMatch(InlineParser parser, [int startMatchPos]) {
-    if (startMatchPos == null) startMatchPos = parser.pos;
+    startMatchPos ??= parser.pos;
 
     // Before matching with the regular expression [pattern], which can be
     // expensive on some platforms, check if even the first character matches
@@ -213,6 +213,7 @@
   LineBreakSyntax() : super(r'(?:\\|  +)\n');
 
   /// Create a void <br> element.
+  @override
   bool onMatch(InlineParser parser, Match match) {
     parser.addNode(Element.empty('br'));
     return true;
@@ -237,6 +238,7 @@
   ///
   /// Otherwise, the parser is advanced by the length of [match] and `false` is
   /// returned.
+  @override
   bool onMatch(InlineParser parser, Match match) {
     if (substitute == null ||
         (match.start > 0 &&
@@ -256,6 +258,7 @@
 class EscapeSyntax extends InlineSyntax {
   EscapeSyntax() : super(r'''\\[!"#$%&'()*+,\-./:;<=>?@\[\\\]^_`{|}~]''');
 
+  @override
   bool onMatch(InlineParser parser, Match match) {
     final char = match[0].codeUnitAt(1);
     // Insert the substitution. Why these three charactes are replaced with
@@ -300,6 +303,7 @@
 
   EmailAutolinkSyntax() : super('<($_email)>', startCharacter: $lt);
 
+  @override
   bool onMatch(InlineParser parser, Match match) {
     var url = match[1];
     var text = parser.document.encodeHtml ? escapeHtml(url) : url;
@@ -315,6 +319,7 @@
 class AutolinkSyntax extends InlineSyntax {
   AutolinkSyntax() : super(r'<(([a-zA-Z][a-zA-Z\-\+\.]+):(?://)?[^\s>]*)>');
 
+  @override
   bool onMatch(InlineParser parser, Match match) {
     var url = match[1];
     var text = parser.document.encodeHtml ? escapeHtml(url) : url;
@@ -352,8 +357,7 @@
   // be considered part of the autolink
   static const truncatingPunctuationPositive = r'[?!.,:*_~]';
 
-  static final regExpTrailingPunc =
-      RegExp('$truncatingPunctuationPositive*' + r'$');
+  static final regExpTrailingPunc = RegExp('$truncatingPunctuationPositive*\$');
   static final regExpEndsWithColon = RegExp(r'\&[a-zA-Z0-9]+;$');
   static final regExpWhiteSpace = RegExp(r'\s');
 
@@ -560,6 +564,7 @@
     );
   }
 
+  @override
   String toString() =>
       '<char: $char, length: $length, isLeftFlanking: $isLeftFlanking, '
       'isRightFlanking: $isRightFlanking>';
@@ -598,6 +603,7 @@
       : endPattern = RegExp((end != null) ? end : pattern, multiLine: true),
         super(pattern, startCharacter: startCharacter);
 
+  @override
   bool onMatch(InlineParser parser, Match match) {
     var runLength = match.group(0).length;
     var matchStart = parser.pos;
@@ -685,7 +691,7 @@
       {Resolver linkResolver,
       String pattern = r'\[',
       int startCharacter = $lbracket})
-      : this.linkResolver = (linkResolver ?? (String _, [String __]) => null),
+      : linkResolver = (linkResolver ?? (String _, [String __]) => null),
         super(pattern, end: r'\]', startCharacter: startCharacter);
 
   // The pending [TagState]s, all together, are "active" or "inactive" based on
@@ -702,6 +708,7 @@
   // the one, in this case).
   var _pendingStatesAreActive = true;
 
+  @override
   bool onMatch(InlineParser parser, Match match) {
     var matched = super.onMatch(parser, match);
     if (!matched) return false;
@@ -711,6 +718,7 @@
     return true;
   }
 
+  @override
   bool onMatchEnd(InlineParser parser, Match match, TagState state) {
     if (!_pendingStatesAreActive) return false;
 
@@ -1107,6 +1115,7 @@
             pattern: r'!\[',
             startCharacter: $exclamation);
 
+  @override
   Node _createNode(TagState state, String destination, String title) {
     var element = Element.empty('img');
     element.attributes['src'] = destination;
@@ -1124,6 +1133,7 @@
   // Otherwise, it is treated as an inline image.
   //
   // Returns whether the image was added successfully.
+  @override
   bool _tryAddReferenceLink(InlineParser parser, TagState state, String label) {
     var element =
         _resolveReferenceLink(label, state, parser.document.linkReferences);
@@ -1152,6 +1162,7 @@
 
   CodeSyntax() : super(_pattern);
 
+  @override
   bool tryMatch(InlineParser parser, [int startMatchPos]) {
     if (parser.pos > 0 && parser.charAt(parser.pos - 1) == $backquote) {
       // Not really a match! We can't just sneak past one backtick to try the
@@ -1171,6 +1182,7 @@
     return true;
   }
 
+  @override
   bool onMatch(InlineParser parser, Match match) {
     var code = match[2].trim().replaceAll('\n', ' ');
     if (parser.document.encodeHtml) code = escapeHtml(code);
@@ -1190,6 +1202,7 @@
   // underscores, but GitHub also supports `:+1:` and `:-1:`.
   EmojiSyntax() : super(':([a-z0-9_+-]+):');
 
+  @override
   bool onMatch(InlineParser parser, Match match) {
     var alias = match[1];
     var emoji = emojis[alias];
diff --git a/lib/src/version.dart b/lib/src/version.dart
index d09e279..eb2b080 100644
--- a/lib/src/version.dart
+++ b/lib/src/version.dart
@@ -1,2 +1,2 @@
 // Generated code. Do not modify.
-const packageVersion = '2.1.3';
+const packageVersion = '2.1.4-dev';
diff --git a/pubspec.yaml b/pubspec.yaml
index aa021fe..2d53c0e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: markdown
-version: 2.1.3
+version: 2.1.4-dev
 
 description: A library for converting markdown to HTML.
 author: Dart Team <misc@dartlang.org>
@@ -9,7 +9,7 @@
   markdown:
 
 environment:
-  sdk: '>=2.1.1 <3.0.0'
+  sdk: '>=2.2.0 <3.0.0'
 
 dependencies:
   args: ^1.0.0
diff --git a/test/document_test.dart b/test/document_test.dart
index 2dbcafc..8c11b7d 100644
--- a/test/document_test.dart
+++ b/test/document_test.dart
@@ -23,26 +23,26 @@
       var document = Document(encodeHtml: true);
 
       test('encodes HTML in an inline code snippet', () {
-        var result = document.parseInline("``<p>Hello <em>Markdown</em></p>``");
+        var result = document.parseInline('``<p>Hello <em>Markdown</em></p>``');
         var codeSnippet = result.single as Element;
         expect(codeSnippet.textContent,
-            equals("&lt;p&gt;Hello &lt;em&gt;Markdown&lt;/em&gt;&lt;/p&gt;"));
+            equals('&lt;p&gt;Hello &lt;em&gt;Markdown&lt;/em&gt;&lt;/p&gt;'));
       });
 
       test('encodes HTML in a fenced code block', () {
-        var lines = "```\n<p>Hello <em>Markdown</em></p>\n```\n".split('\n');
+        var lines = '```\n<p>Hello <em>Markdown</em></p>\n```\n'.split('\n');
         var result = document.parseLines(lines);
         var codeBlock = result.single as Element;
         expect(codeBlock.textContent,
-            equals("&lt;p&gt;Hello &lt;em&gt;Markdown&lt;/em&gt;&lt;/p&gt;\n"));
+            equals('&lt;p&gt;Hello &lt;em&gt;Markdown&lt;/em&gt;&lt;/p&gt;\n'));
       });
 
       test('encodes HTML in an indented code block', () {
-        var lines = "    <p>Hello <em>Markdown</em></p>\n".split('\n');
+        var lines = '    <p>Hello <em>Markdown</em></p>\n'.split('\n');
         var result = document.parseLines(lines);
         var codeBlock = result.single as Element;
         expect(codeBlock.textContent,
-            equals("&lt;p&gt;Hello &lt;em&gt;Markdown&lt;/em&gt;&lt;/p&gt;\n"));
+            equals('&lt;p&gt;Hello &lt;em&gt;Markdown&lt;/em&gt;&lt;/p&gt;\n'));
       });
 
       test('encodeHtml spaces are preserved in text', () {
@@ -61,26 +61,26 @@
 
       test('leaves HTML alone, in a code snippet', () {
         var result =
-            document.parseInline("```<p>Hello <em>Markdown</em></p>```");
+            document.parseInline('```<p>Hello <em>Markdown</em></p>```');
         var codeSnippet = result.single as Element;
         expect(
-            codeSnippet.textContent, equals("<p>Hello <em>Markdown</em></p>"));
+            codeSnippet.textContent, equals('<p>Hello <em>Markdown</em></p>'));
       });
 
       test('leaves HTML alone, in a fenced code block', () {
-        var lines = "```\n<p>Hello <em>Markdown</em></p>\n```\n".split('\n');
+        var lines = '```\n<p>Hello <em>Markdown</em></p>\n```\n'.split('\n');
         var result = document.parseLines(lines);
         var codeBlock = result.single as Element;
         expect(
-            codeBlock.textContent, equals("<p>Hello <em>Markdown</em></p>\n"));
+            codeBlock.textContent, equals('<p>Hello <em>Markdown</em></p>\n'));
       });
 
       test('leaves HTML alone, in an indented code block', () {
-        var lines = "    <p>Hello <em>Markdown</em></p>\n".split('\n');
+        var lines = '    <p>Hello <em>Markdown</em></p>\n'.split('\n');
         var result = document.parseLines(lines);
         var codeBlock = result.single as Element;
         expect(
-            codeBlock.textContent, equals("<p>Hello <em>Markdown</em></p>\n"));
+            codeBlock.textContent, equals('<p>Hello <em>Markdown</em></p>\n'));
       });
     });
   });
diff --git a/tool/dartdoc-compare.dart b/tool/dartdoc-compare.dart
index 9a06b45..93857e6 100644
--- a/tool/dartdoc-compare.dart
+++ b/tool/dartdoc-compare.dart
@@ -13,14 +13,14 @@
 
 void main(List<String> arguments) {
   final parser = ArgParser()
-    ..addSeparator("Usage: dartdoc-compare.dart [OPTIONS] <dart-package>")
-    ..addOption(_dartdocDir, help: "Directory of the dartdoc package")
+    ..addSeparator('Usage: dartdoc-compare.dart [OPTIONS] <dart-package>')
+    ..addOption(_dartdocDir, help: 'Directory of the dartdoc package')
     ..addOption(_markdownBefore, help: "Markdown package 'before' ref")
     ..addOption(_markdownAfter,
-        defaultsTo: "HEAD", help: "Markdown package 'after' ref (or 'local')")
+        defaultsTo: 'HEAD', help: "Markdown package 'after' ref (or 'local')")
     ..addFlag(_sdk,
-        defaultsTo: false, negatable: false, help: "Is the package the SDK?")
-    ..addFlag(_help, abbr: "h", hide: true);
+        defaultsTo: false, negatable: false, help: 'Is the package the SDK?')
+    ..addFlag(_help, abbr: 'h', hide: true);
 
   var options = parser.parse(arguments);
   if (options[_help] as bool) {
@@ -30,7 +30,7 @@
   }
   if (options[_dartdocDir] == null || options[_markdownBefore] == null) {
     print(
-        "Invalid arguments: Options --$_dartdocDir and --$_markdownBefore must be specified");
+        'Invalid arguments: Options --$_dartdocDir and --$_markdownBefore must be specified');
     print(parser.usage);
     exitCode = 1;
     return;
@@ -39,8 +39,8 @@
       options[_dartdocDir] as String,
       options[_markdownBefore] as String,
       options[_markdownAfter] as String,
-      absolute(options[_dartdocDir] as String, "bin/dartdoc.dart"),
-      absolute(options[_dartdocDir] as String, "pubspec.yaml"),
+      absolute(options[_dartdocDir] as String, 'bin/dartdoc.dart'),
+      absolute(options[_dartdocDir] as String, 'pubspec.yaml'),
       options[_sdk] as bool);
 
   String path;
@@ -79,18 +79,18 @@
     var outAfter = _runDartdoc(markdownAfter, package);
 
     // Compare outputs
-    var diffOptions = ["-r", "-B", outBefore, outAfter];
-    var result = Process.runSync("diff", diffOptions, runInShell: true);
-    var nlines = "\n".allMatches(result.stdout as String).length;
-    print("Diff lines: $nlines");
-    print("diff ${diffOptions.join(" ")}");
+    var diffOptions = ['-r', '-B', outBefore, outAfter];
+    var result = Process.runSync('diff', diffOptions, runInShell: true);
+    var nlines = '\n'.allMatches(result.stdout as String).length;
+    print('Diff lines: $nlines');
+    print('diff ${diffOptions.join(" ")}');
     return result.exitCode == 0;
   }
 
   String _runDartdoc(String markdownRef, String path) {
-    print("==========================================================");
-    print("Running dartdoc for $markdownRef...");
-    print("==========================================================");
+    print('==========================================================');
+    print('Running dartdoc for $markdownRef...');
+    print('==========================================================');
     _doInPath(dartdocDir, () {
       var returnCode = _updateDartdocPubspec(markdownRef);
       if (returnCode != 0) {
@@ -102,9 +102,9 @@
         _system('pub', ['upgrade']);
       }
       var out = Directory.systemTemp
-          .createTempSync("dartdoc-compare-${markdownRef}__");
-      var cmd = "dart";
-      var args = ["$dartdocBin", "--output=${out.path}"];
+          .createTempSync('dartdoc-compare-${markdownRef}__');
+      var cmd = 'dart';
+      var args = ['$dartdocBin', '--output=${out.path}'];
 
       if (sdk) {
         args.add('--sdk-docs');
@@ -153,7 +153,7 @@
   return result.exitCode;
 }
 
-T _doInPath<T>(String path, T f()) {
+T _doInPath<T>(String path, T Function() f) {
   if (path == null) {
     return f();
   }
diff --git a/tool/stats.dart b/tool/stats.dart
index 55ba001..39e4aac 100644
--- a/tool/stats.dart
+++ b/tool/stats.dart
@@ -162,7 +162,7 @@
       case CompareLevel.loose:
         return 'loose';
       default:
-        throw ArgumentError("`$obj` is unknown.");
+        throw ArgumentError('`$obj` is unknown.');
     }
   }
   if (obj is Map) {
diff --git a/tool/stats_lib.dart b/tool/stats_lib.dart
index 4d5d68b..53fb0b9 100644
--- a/tool/stats_lib.dart
+++ b/tool/stats_lib.dart
@@ -32,7 +32,7 @@
 
   var testArray = jsonDecode(testsJson) as List;
 
-  var sections = Map<String, List<CommonMarkTestCase>>();
+  var sections = <String, List<CommonMarkTestCase>>{};
 
   for (var exampleMap in testArray) {
     var exampleTest =