Fix a number of lints, disable a couple of lints that cannot be easily fixed (#97)

diff --git a/.travis.yml b/.travis.yml
index f6e2d7b..df7d186 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,7 @@
 language: dart
 
 dart:
-  - 2.1.0
+  - 2.2.0
   - dev
 
 dart_task:
@@ -12,7 +12,7 @@
   include:
     - dart: dev
       dartanalyzer: --fatal-infos --fatal-warnings .
-    - dart: 2.1.0
+    - dart: 2.2.0
       dartanalyzer: --fatal-warnings .
     - dart: dev
       dart_task: dartfmt
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 9d14291..b8036fa 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,5 +1,10 @@
 include: package:pedantic/analysis_options.yaml
 
+analyzer:
+  errors:
+    always_declare_return_types: ignore # 318
+    omit_local_variable_types: ignore # 48
+
 linter:
   rules:
   - prefer_equal_for_default_values
diff --git a/example/call_parser.dart b/example/call_parser.dart
index fc299d9..60adf61 100644
--- a/example/call_parser.dart
+++ b/example/call_parser.dart
@@ -15,8 +15,7 @@
 /// tests (by default) will ensure that the CSS is really valid.
 StyleSheet parseCss(String cssInput,
     {List<css.Message> errors, css.PreprocessorOptions opts}) {
-  return css.parse(cssInput,
-      errors: errors, options: opts == null ? _default : opts);
+  return css.parse(cssInput, errors: errors, options: opts ?? _default);
 }
 
 // Pretty printer for CSS.
@@ -24,7 +23,7 @@
 String prettyPrint(StyleSheet ss) =>
     (emitCss..visitTree(ss, pretty: true)).toString();
 
-main() {
+void main() {
   var errors = <css.Message>[];
 
   // Parse a simple stylesheet.
@@ -42,7 +41,7 @@
       errors: errors);
 
   if (errors.isNotEmpty) {
-    print("Got ${errors.length} errors.\n");
+    print('Got ${errors.length} errors.\n');
     for (var error in errors) {
       print(error);
     }
@@ -60,7 +59,7 @@
       errors: errors);
 
   if (errors.isNotEmpty) {
-    print("Got ${errors.length} errors.\n");
+    print('Got ${errors.length} errors.\n');
     for (var error in errors) {
       print(error);
     }
@@ -74,7 +73,7 @@
   stylesheetError = parseCss('# div1 { color: red; }', errors: errors);
 
   if (errors.isNotEmpty) {
-    print("Detected ${errors.length} problem in checked mode.\n");
+    print('Detected ${errors.length} problem in checked mode.\n');
     for (var error in errors) {
       print(error);
     }
@@ -87,7 +86,7 @@
   print('   ======================');
   var selectorAst = css.selector('#div .foo', errors: errors);
   if (errors.isNotEmpty) {
-    print("Got ${errors.length} errors.\n");
+    print('Got ${errors.length} errors.\n');
     for (var error in errors) {
       print(error);
     }
diff --git a/lib/parser.dart b/lib/parser.dart
index d8ba671..e9402ab 100644
--- a/lib/parser.dart
+++ b/lib/parser.dart
@@ -38,11 +38,9 @@
 
 // TODO(jmesserly): this should not be global
 void _createMessages({List<Message> errors, PreprocessorOptions options}) {
-  if (errors == null) errors = [];
+  errors ??= [];
 
-  if (options == null) {
-    options = PreprocessorOptions(useColors: false, inputFile: 'memory');
-  }
+  options ??= PreprocessorOptions(useColors: false, inputFile: 'memory');
 
   messages = Messages(options: options, printHandler: errors.add);
 }
@@ -58,9 +56,7 @@
     bool nested = true,
     bool polyfill = false,
     List<StyleSheet> includes}) {
-  if (includes == null) {
-    includes = [];
-  }
+  includes ??= [];
 
   var source = _inputAsString(input);
 
@@ -150,8 +146,8 @@
   } else {
     // TODO(terry): Support RandomAccessFile using console.
     throw ArgumentError("'source' must be a String or "
-        "List<int> (of bytes). RandomAccessFile not supported from this "
-        "simple interface");
+        'List<int> (of bytes). RandomAccessFile not supported from this '
+        'simple interface');
   }
 
   return source;
@@ -172,12 +168,12 @@
 }
 
 // CSS2.1 pseudo-elements which were defined with a single ':'.
-final _legacyPseudoElements = Set<String>.from(const [
+const _legacyPseudoElements = <String>{
   'after',
   'before',
   'first-letter',
   'first-line',
-]);
+};
 
 /// A simple recursive descent parser for CSS.
 class _Parser {
@@ -190,15 +186,14 @@
   Token _previousToken;
   Token _peekToken;
 
-  _Parser(SourceFile file, String text, {int start = 0})
-      : this.file = file,
-        tokenizer = Tokenizer(file, text, true, start) {
+  _Parser(this.file, String text, {int start = 0})
+      : tokenizer = Tokenizer(file, text, true, start) {
     _peekToken = tokenizer.next();
   }
 
   /// Main entry point for parsing an entire CSS file.
   StyleSheet parse() {
-    List<TreeNode> productions = [];
+    var productions = <TreeNode>[];
 
     var start = _peekToken.span;
     while (!_maybeEat(TokenKind.END_OF_FILE) && !_peekKind(TokenKind.RBRACE)) {
@@ -218,7 +213,7 @@
 
   /// Main entry point for parsing a simple selector sequence.
   StyleSheet parseSelector() {
-    List<TreeNode> productions = [];
+    var productions = <TreeNode>[];
 
     var start = _peekToken.span;
     while (!_maybeEat(TokenKind.END_OF_FILE) && !_peekKind(TokenKind.RBRACE)) {
@@ -316,16 +311,12 @@
   }
 
   void _error(String message, SourceSpan location) {
-    if (location == null) {
-      location = _peekToken.span;
-    }
+    location ??= _peekToken.span;
     messages.error(message, location);
   }
 
   void _warning(String message, SourceSpan location) {
-    if (location == null) {
-      location = _peekToken.span;
-    }
+    location ??= _peekToken.span;
     messages.warning(message, location);
   }
 
@@ -386,7 +377,7 @@
       if (isChecked) {
         if (unaryOp != TokenKind.MEDIA_OP_NOT ||
             unaryOp != TokenKind.MEDIA_OP_ONLY) {
-          _warning("Only the unary operators NOT and ONLY allowed",
+          _warning('Only the unary operators NOT and ONLY allowed',
               _makeSpan(start));
         }
       }
@@ -439,11 +430,11 @@
           return MediaExpression(andOperator, feature, exprs, _makeSpan(start));
         } else if (isChecked) {
           _warning(
-              "Missing parenthesis around media expression", _makeSpan(start));
+              'Missing parenthesis around media expression', _makeSpan(start));
           return null;
         }
       } else if (isChecked) {
-        _warning("Missing media feature in media expression", _makeSpan(start));
+        _warning('Missing media feature in media expression', _makeSpan(start));
       }
     }
     return null;
@@ -505,7 +496,7 @@
         // Any medias?
         var media = processMediaQueryList();
 
-        List<TreeNode> rules = [];
+        var rules = <TreeNode>[];
         if (_maybeEat(TokenKind.LBRACE)) {
           while (!_maybeEat(TokenKind.END_OF_FILE)) {
             final rule = processRule();
@@ -524,7 +515,7 @@
       case TokenKind.DIRECTIVE_HOST:
         _next();
 
-        List<TreeNode> rules = [];
+        var rules = <TreeNode>[];
         if (_maybeEat(TokenKind.LBRACE)) {
           while (!_maybeEat(TokenKind.END_OF_FILE)) {
             final rule = processRule();
@@ -574,14 +565,14 @@
                     pseudoPage.name == 'right' ||
                     pseudoPage.name == 'first')) {
               _warning(
-                  "Pseudo page must be left, top or first", pseudoPage.span);
+                  'Pseudo page must be left, top or first', pseudoPage.span);
               return null;
             }
           }
         }
 
-        String pseudoName = pseudoPage is Identifier ? pseudoPage.name : '';
-        String ident = name is Identifier ? name.name : '';
+        var pseudoName = pseudoPage is Identifier ? pseudoPage.name : '';
+        var ident = name is Identifier ? name.name : '';
         return PageDirective(
             ident, pseudoName, processMarginsDeclarations(), _makeSpan(start));
 
@@ -647,7 +638,7 @@
         var keyframe = KeyFrameDirective(tokId, name, _makeSpan(start));
 
         do {
-          Expressions selectors = Expressions(_makeSpan(start));
+          var selectors = Expressions(_makeSpan(start));
 
           do {
             var term = processTerm();
@@ -682,7 +673,7 @@
 
         _eat(TokenKind.LBRACE);
 
-        List<TreeNode> productions = [];
+        var productions = <TreeNode>[];
 
         start = _peekToken.span;
         while (!_maybeEat(TokenKind.END_OF_FILE)) {
@@ -740,7 +731,7 @@
         return processInclude(_makeSpan(start));
       case TokenKind.DIRECTIVE_CONTENT:
         // TODO(terry): TBD
-        _warning("@content not implemented.", _makeSpan(start));
+        _warning('@content not implemented.', _makeSpan(start));
         return null;
       case TokenKind.DIRECTIVE_MOZ_DOCUMENT:
         return processDocumentDirective();
@@ -776,7 +767,7 @@
         if (varDef is VarDefinitionDirective || varDef is VarDefinition) {
           params.add(varDef);
         } else if (mustHaveParam) {
-          _warning("Expecting parameter", _makeSpan(_peekToken.span));
+          _warning('Expecting parameter', _makeSpan(_peekToken.span));
           keepGoing = false;
         }
         if (_maybeEat(TokenKind.COMMA)) {
@@ -811,7 +802,7 @@
           if (include is IncludeDirective) {
             newDecls.add(IncludeMixinAtDeclaration(include, include.span));
           } else {
-            _warning("Error mixing of top-level vs declarations mixins",
+            _warning('Error mixing of top-level vs declarations mixins',
                 _makeSpan(include.span));
           }
         });
@@ -1143,13 +1134,13 @@
   /// Return [:null:] if no selector or [SelectorGroup] if a selector was
   /// parsed.
   SelectorGroup _nestedSelector() {
-    Messages oldMessages = messages;
+    var oldMessages = messages;
     _createMessages();
 
     var markedData = _mark;
 
     // Look a head do we have a nested selector instead of a declaration?
-    SelectorGroup selGroup = processSelectorGroup();
+    var selGroup = processSelectorGroup();
 
     var nestedSelector = selGroup != null &&
         _peekKind(TokenKind.LBRACE) &&
@@ -1186,13 +1177,13 @@
         selectorGroup = _nestedSelector();
       }
 
-      Declaration decl = processDeclaration(dartStyles);
+      var decl = processDeclaration(dartStyles);
       if (decl != null) {
         if (decl.hasDartStyle) {
           var newDartStyle = decl.dartStyle;
 
           // Replace or add latest Dart style.
-          bool replaced = false;
+          var replaced = false;
           for (var i = 0; i < dartStyles.length; i++) {
             var dartStyle = dartStyles[i];
             if (dartStyle.isSame(newDartStyle)) {
@@ -1270,13 +1261,13 @@
           }
           break;
         default:
-          Declaration decl = processDeclaration(dartStyles);
+          var decl = processDeclaration(dartStyles);
           if (decl != null) {
             if (decl.hasDartStyle) {
               var newDartStyle = decl.dartStyle;
 
               // Replace or add latest Dart style.
-              bool replaced = false;
+              var replaced = false;
               for (var i = 0; i < dartStyles.length; i++) {
                 var dartStyle = dartStyles[i];
                 if (dartStyle.isSame(newDartStyle)) {
@@ -1313,11 +1304,11 @@
   }
 
   SelectorGroup processSelectorGroup() {
-    List<Selector> selectors = [];
+    var selectors = <Selector>[];
     var start = _peekToken.span;
 
     do {
-      Selector selector = processSelector();
+      var selector = processSelector();
       if (selector != null) {
         selectors.add(selector);
       }
@@ -1391,8 +1382,7 @@
 
     // Check if WHITESPACE existed between tokens if so we're descendent.
     if (combinatorType == TokenKind.COMBINATOR_NONE && !forceCombinatorNone) {
-      if (this._previousToken != null &&
-          this._previousToken.end != this._peekToken.start) {
+      if (_previousToken != null && _previousToken.end != _peekToken.start) {
         combinatorType = TokenKind.COMBINATOR_DESCENDANT;
       }
     }
@@ -1411,7 +1401,7 @@
       //    .foo&:hover     combinator before & is NONE
       //    .foo &          combinator before & is DESCDENDANT
       //    .foo > &        combinator before & is GREATER
-      simpleSel = ElementSelector(Identifier("", span), span);
+      simpleSel = ElementSelector(Identifier('', span), span);
     }
     if (simpleSel != null) {
       return SimpleSelectorSequence(simpleSel, span, combinatorType);
@@ -1513,14 +1503,14 @@
 
         var hasWhiteSpace = false;
         if (_anyWhiteSpaceBeforePeekToken(TokenKind.HASH)) {
-          _warning("Not a valid ID selector expected #id", _makeSpan(start));
+          _warning('Not a valid ID selector expected #id', _makeSpan(start));
           hasWhiteSpace = true;
         }
         if (_peekIdentifier()) {
           var id = identifier();
           if (hasWhiteSpace) {
             // Generate bad selector id (normalized).
-            id.name = " ${id.name}";
+            id.name = ' ${id.name}';
           }
           return IdSelector(id, _makeSpan(start));
         }
@@ -1528,16 +1518,16 @@
       case TokenKind.DOT:
         _eat(TokenKind.DOT);
 
-        bool hasWhiteSpace = false;
+        var hasWhiteSpace = false;
         if (_anyWhiteSpaceBeforePeekToken(TokenKind.DOT)) {
-          _warning("Not a valid class selector expected .className",
+          _warning('Not a valid class selector expected .className',
               _makeSpan(start));
           hasWhiteSpace = true;
         }
         var id = identifier();
         if (hasWhiteSpace) {
           // Generate bad selector class (normalized).
-          id.name = " ${id.name}";
+          id.name = ' ${id.name}';
         }
         return ClassSelector(id, _makeSpan(start));
       case TokenKind.COLON:
@@ -1614,7 +1604,7 @@
               ? PseudoElementFunctionSelector(pseudoName, expr, span)
               : PseudoClassFunctionSelector(pseudoName, expr, span);
         } else {
-          _errorExpected("CSS expression");
+          _errorExpected('CSS expression');
           return null;
         }
       }
@@ -1681,8 +1671,7 @@
       }
 
       if (keepParsing && value != null) {
-        LiteralTerm unitTerm =
-            processDimension(termToken, value, _makeSpan(start));
+        var unitTerm = processDimension(termToken, value, _makeSpan(start));
         expressions.add(unitTerm);
 
         value = null;
@@ -1782,7 +1771,7 @@
 
       _eat(TokenKind.COLON);
 
-      Expressions exprs = processExpr(ieFilterProperty);
+      var exprs = processExpr(ieFilterProperty);
 
       var dartComposite = _styleForDart(propertyIdent, exprs, dartStyles);
 
@@ -1798,7 +1787,7 @@
 
       _eat(TokenKind.COLON);
 
-      Expressions exprs = processExpr();
+      var exprs = processExpr();
 
       decl = VarDefinition(definedName, exprs, _makeSpan(start));
     } else if (_peekToken.kind == TokenKind.DIRECTIVE_INCLUDE) {
@@ -1813,7 +1802,7 @@
       var span = _makeSpan(start);
       var selector = simpleSelector();
       if (selector == null) {
-        _warning("@extends expecting simple selector name", span);
+        _warning('@extends expecting simple selector name', span);
       } else {
         simpleSequences.add(selector);
       }
@@ -1823,7 +1812,7 @@
             pseudoSelector is PseudoClassSelector) {
           simpleSequences.add(pseudoSelector);
         } else {
-          _warning("not a valid selector", span);
+          _warning('not a valid selector', span);
         }
       }
       decl = ExtendDeclaration(simpleSequences, span);
@@ -1981,7 +1970,7 @@
           var fontExpr = FontExpression(expr.span, weight: expr.value);
           return _mergeFontStyles(fontExpr, dartStyles);
         } else if (expr is LiteralTerm) {
-          int weight = _nameToFontWeight[expr.value.toString()];
+          var weight = _nameToFontWeight[expr.value.toString()];
           if (weight != null) {
             var fontExpr = FontExpression(expr.span, weight: weight);
             return _mergeFontStyles(fontExpr, dartStyles);
@@ -1992,7 +1981,7 @@
         if (exprs.expressions.length == 1) {
           var expr = exprs.expressions[0];
           if (expr is UnitTerm) {
-            UnitTerm unitTerm = expr;
+            var unitTerm = expr;
             // TODO(terry): Need to handle other units and LiteralTerm normal
             //              See https://github.com/dart-lang/csslib/issues/2.
             if (unitTerm.unit == TokenKind.UNIT_LENGTH_PX ||
@@ -2001,14 +1990,14 @@
                   lineHeight: LineHeight(expr.value, inPixels: true));
               return _mergeFontStyles(fontExpr, dartStyles);
             } else if (isChecked) {
-              _warning("Unexpected unit for line-height", expr.span);
+              _warning('Unexpected unit for line-height', expr.span);
             }
           } else if (expr is NumberTerm) {
             var fontExpr = FontExpression(expr.span,
                 lineHeight: LineHeight(expr.value, inPixels: false));
             return _mergeFontStyles(fontExpr, dartStyles);
           } else if (isChecked) {
-            _warning("Unexpected value for line-height", expr.span);
+            _warning('Unexpected value for line-height', expr.span);
           }
         }
         break;
@@ -2115,7 +2104,7 @@
     num bottom;
     num left;
 
-    int totalExprs = exprs.expressions.length;
+    var totalExprs = exprs.expressions.length;
     switch (totalExprs) {
       case 1:
         top = marginValue(exprs.expressions[0]);
@@ -2195,7 +2184,7 @@
               op = IE8Term(_makeSpan(ie8Start));
             } else if (isChecked) {
               _warning(
-                  "\$value is not valid in an expression", _makeSpan(start));
+                  '\$value is not valid in an expression', _makeSpan(start));
             }
           }
           break;
@@ -2255,14 +2244,14 @@
     Token t; // token for term's value
     var value; // value of term (numeric values)
 
-    var unary = "";
+    var unary = '';
     switch (_peek()) {
       case TokenKind.HASH:
-        this._eat(TokenKind.HASH);
+        _eat(TokenKind.HASH);
         if (!_anyWhiteSpaceBeforePeekToken(TokenKind.HASH)) {
           String hexText;
           if (_peekKind(TokenKind.INTEGER)) {
-            String hexText1 = _peekToken.text;
+            var hexText1 = _peekToken.text;
             _next();
             // Append identifier only if there's no delimiting whitespace.
             if (_peekIdentifier() && _previousToken.end == _peekToken.start) {
@@ -2279,17 +2268,17 @@
         }
 
         if (isChecked) {
-          _warning("Expected hex number", _makeSpan(start));
+          _warning('Expected hex number', _makeSpan(start));
         }
         // Construct the bad hex value with a #<space>number.
-        return _parseHex(" ${processTerm().text}", _makeSpan(start));
+        return _parseHex(' ${processTerm().text}', _makeSpan(start));
       case TokenKind.INTEGER:
         t = _next();
-        value = int.parse("${unary}${t.text}");
+        value = int.parse('${unary}${t.text}');
         break;
       case TokenKind.DOUBLE:
         t = _next();
-        value = double.parse("${unary}${t.text}");
+        value = double.parse('${unary}${t.text}');
         break;
       case TokenKind.SINGLE_QUOTE:
         value = processQuotedString(false);
@@ -2302,7 +2291,7 @@
       case TokenKind.LPAREN:
         _next();
 
-        GroupTerm group = GroupTerm(_makeSpan(start));
+        var group = GroupTerm(_makeSpan(start));
 
         dynamic /* Expression | List<Expression> | ... */ term;
         do {
@@ -2359,8 +2348,8 @@
           if (isChecked) {
             var propName = nameValue.name;
             var errMsg = TokenKind.isPredefinedName(propName)
-                ? "Improper use of property value ${propName}"
-                : "Unknown property value ${propName}";
+                ? 'Improper use of property value ${propName}'
+                : 'Unknown property value ${propName}';
             _warning(errMsg, _makeSpan(start));
           }
           return LiteralTerm(nameValue, nameValue.name, _makeSpan(start));
@@ -2380,7 +2369,7 @@
           first = _previousToken.text;
           firstNumber = int.parse('0x$first');
           if (firstNumber > MAX_UNICODE) {
-            _error("unicode range must be less than 10FFFF", _makeSpan(start));
+            _error('unicode range must be less than 10FFFF', _makeSpan(start));
           }
           if (_maybeEat(TokenKind.MINUS, unicodeRange: true)) {
             if (_maybeEat(TokenKind.HEX_INTEGER, unicodeRange: true)) {
@@ -2388,10 +2377,10 @@
               secondNumber = int.parse('0x$second');
               if (secondNumber > MAX_UNICODE) {
                 _error(
-                    "unicode range must be less than 10FFFF", _makeSpan(start));
+                    'unicode range must be less than 10FFFF', _makeSpan(start));
               }
               if (firstNumber > secondNumber) {
-                _error("unicode first range can not be greater than last",
+                _error('unicode first range can not be greater than last',
                     _makeSpan(start));
               }
             }
@@ -2407,7 +2396,7 @@
 
           var expr = processExpr();
           if (isChecked && expr.expressions.length > 1) {
-            _error("only @name for Less syntax", _peekToken.span);
+            _error('only @name for Less syntax', _peekToken.span);
           }
 
           var param = expr.expressions[0];
@@ -2425,7 +2414,7 @@
   /// Process all dimension units.
   LiteralTerm processDimension(Token t, var value, SourceSpan span) {
     LiteralTerm term;
-    var unitType = this._peek();
+    var unitType = _peek();
 
     switch (unitType) {
       case TokenKind.UNIT_EM:
@@ -2614,16 +2603,16 @@
     var matchingParens = false;
     while (_peek() != TokenKind.END_OF_FILE && !matchingParens) {
       var token = _peek();
-      if (token == TokenKind.LPAREN)
+      if (token == TokenKind.LPAREN) {
         left++;
-      else if (token == TokenKind.RPAREN) left--;
+      } else if (token == TokenKind.RPAREN) left--;
 
       matchingParens = left == 0;
       if (!matchingParens) stringValue.write(_next().text);
     }
 
     if (!matchingParens) {
-      _error("problem parsing function expected ), ", _peekToken.span);
+      _error('problem parsing function expected ), ', _peekToken.span);
     }
 
     tokenizer._inString = inString;
@@ -2637,11 +2626,11 @@
     var name = func.name;
     if (name == 'calc' || name == '-webkit-calc' || name == '-moz-calc') {
       // TODO(terry): Implement expression parsing properly.
-      String expression = processCalcExpression();
+      var expression = processCalcExpression();
       var calcExpr = LiteralTerm(expression, expression, _makeSpan(start));
 
       if (!_maybeEat(TokenKind.RPAREN)) {
-        _error("problem parsing function expected ), ", _peekToken.span);
+        _error('problem parsing function expected ), ', _peekToken.span);
       }
 
       return CalcTerm(name, name, calcExpr, _makeSpan(start));
@@ -2666,7 +2655,7 @@
 
         // TODO(terry): Better error message and checking for mismatched quotes.
         if (_peek() == TokenKind.END_OF_FILE) {
-          _error("problem parsing URI", _peekToken.span);
+          _error('problem parsing URI', _peekToken.span);
         }
 
         if (_peek() == TokenKind.RPAREN) {
@@ -2685,11 +2674,11 @@
         //      (GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
         var expr = processExpr();
         if (!_maybeEat(TokenKind.RPAREN)) {
-          _error("problem parsing var expected ), ", _peekToken.span);
+          _error('problem parsing var expected ), ', _peekToken.span);
         }
         if (isChecked &&
-            expr.expressions.where((e) => e is OperatorComma).length > 1) {
-          _error("too many parameters to var()", _peekToken.span);
+            expr.expressions.whereType<OperatorComma>().length > 1) {
+          _error('too many parameters to var()', _peekToken.span);
         }
 
         var paramName = (expr.expressions[0] as LiteralTerm).text;
@@ -2702,7 +2691,7 @@
       default:
         var expr = processExpr();
         if (!_maybeEat(TokenKind.RPAREN)) {
-          _error("problem parsing function expected ), ", _peekToken.span);
+          _error('problem parsing function expected ), ', _peekToken.span);
         }
 
         return FunctionTerm(name, name, expr, _makeSpan(start));
@@ -2717,7 +2706,7 @@
       if (isChecked) {
         _warning('expected identifier, but found $tok', tok.span);
       }
-      return Identifier("", _makeSpan(tok.span));
+      return Identifier('', _makeSpan(tok.span));
     }
 
     return Identifier(tok.text, _makeSpan(tok.span));
@@ -2827,7 +2816,7 @@
     var moreFamilies = false;
 
     for (; _index < _exprs.expressions.length; _index++) {
-      Expression expr = _exprs.expressions[_index];
+      var expr = _exprs.expressions[_index];
       if (expr is LiteralTerm) {
         if (family.isEmpty || moreFamilies) {
           // It's font-family now.
@@ -2852,12 +2841,8 @@
     FontExpression fontFamily;
     for (; _index < _exprs.expressions.length; _index++) {
       // Order is font-size font-family
-      if (fontSize == null) {
-        fontSize = processFontSize();
-      }
-      if (fontFamily == null) {
-        fontFamily = processFontFamily();
-      }
+      fontSize ??= processFontSize();
+      fontFamily ??= processFontFamily();
       //TODO(terry): Handle font-weight, font-style, and font-variant. See
       //               https://github.com/dart-lang/csslib/issues/3
       //               https://github.com/dart-lang/csslib/issues/4
@@ -2876,7 +2861,7 @@
 String _escapeString(String text, {bool single = false}) {
   StringBuffer result;
 
-  for (int i = 0; i < text.length; i++) {
+  for (var i = 0; i < text.length; i++) {
     var code = text.codeUnitAt(i);
     String replace;
     switch (code) {
@@ -2892,7 +2877,7 @@
       result = StringBuffer(text.substring(0, i));
     }
 
-    if (result != null) result.write(replace != null ? replace : text[i]);
+    if (result != null) result.write(replace ?? text[i]);
   }
 
   return result == null ? text : result.toString();
diff --git a/lib/src/analyzer.dart b/lib/src/analyzer.dart
index 5f34da5..0b121ad 100644
--- a/lib/src/analyzer.dart
+++ b/lib/src/analyzer.dart
@@ -186,8 +186,9 @@
   List<RuleSet> _expandedRuleSets = [];
 
   /// Maping of a nested rule set to the fully expanded list of RuleSet(s).
-  final Map<RuleSet, List<RuleSet>> _expansions = Map();
+  final _expansions = <RuleSet, List<RuleSet>>{};
 
+  @override
   void visitRuleSet(RuleSet node) {
     final oldParent = _parentRuleSet;
 
@@ -238,8 +239,8 @@
 
     // Create a merged set of previous parent selectors and current selectors.
     var newSelectors = <Selector>[];
-    for (Selector selector in selectors) {
-      for (Selector nestedSelector in nestedSelectors) {
+    for (var selector in selectors) {
+      for (var nestedSelector in nestedSelectors) {
         var seq = _mergeNestedSelector(nestedSelector.simpleSelectorSequences,
             selector.simpleSelectorSequences);
         newSelectors.add(Selector(seq, node.span));
@@ -300,6 +301,7 @@
     return newSequences;
   }
 
+  @override
   void visitDeclarationGroup(DeclarationGroup node) {
     var span = node.span;
 
@@ -338,6 +340,7 @@
   // Record all declarations in a nested selector (Declaration, VarDefinition
   // and MarginGroup) but not the nested rule in the Declaration.
 
+  @override
   void visitDeclaration(Declaration node) {
     if (_parentRuleSet != null) {
       _flatDeclarationGroup.declarations.add(node);
@@ -345,6 +348,7 @@
     super.visitDeclaration(node);
   }
 
+  @override
   void visitVarDefinition(VarDefinition node) {
     if (_parentRuleSet != null) {
       _flatDeclarationGroup.declarations.add(node);
@@ -352,6 +356,7 @@
     super.visitVarDefinition(node);
   }
 
+  @override
   void visitExtendDeclaration(ExtendDeclaration node) {
     if (_parentRuleSet != null) {
       _flatDeclarationGroup.declarations.add(node);
@@ -359,6 +364,7 @@
     super.visitExtendDeclaration(node);
   }
 
+  @override
   void visitMarginGroup(MarginGroup node) {
     if (_parentRuleSet != null) {
       _flatDeclarationGroup.declarations.add(node);
@@ -386,8 +392,8 @@
 }
 
 class _MediaRulesReplacer extends Visitor {
-  RuleSet _ruleSet;
-  List<RuleSet> _newRules;
+  final RuleSet _ruleSet;
+  final List<RuleSet> _newRules;
   bool _foundAndReplaced = false;
 
   /// Look for the [ruleSet] inside of an @media directive; if found then
@@ -402,6 +408,7 @@
 
   _MediaRulesReplacer(this._ruleSet, this._newRules);
 
+  @override
   visitMediaDirective(MediaDirective node) {
     var index = node.rules.indexOf(_ruleSet);
     if (index != -1) {
@@ -418,7 +425,7 @@
   final Messages _messages;
 
   /// Map of variable name key to it's definition.
-  final Map<String, MixinDefinition> map = Map<String, MixinDefinition>();
+  final map = <String, MixinDefinition>{};
   MixinDefinition currDef;
 
   static void expand(Messages messages, List<StyleSheet> styleSheets) {
@@ -434,12 +441,14 @@
     }
   }
 
+  @override
   void visitStyleSheet(StyleSheet ss) {
     _styleSheet = ss;
     super.visitStyleSheet(ss);
     _styleSheet = null;
   }
 
+  @override
   void visitIncludeDirective(IncludeDirective node) {
     if (map.containsKey(node.name)) {
       var mixinDef = map[node.name];
@@ -449,7 +458,7 @@
       } else if (currDef is MixinRulesetDirective && _anyRulesets(currDef)) {
         // currDef is MixinRulesetDirective
         MixinRulesetDirective mixinRuleset = currDef;
-        int index = mixinRuleset.rulesets.indexOf(node);
+        var index = mixinRuleset.rulesets.indexOf(node);
         mixinRuleset.rulesets.removeAt(index);
         _messages.warning(
             'Using declaration mixin ${node.name} as top-level mixin',
@@ -457,7 +466,7 @@
       }
     } else {
       if (currDef is MixinRulesetDirective) {
-        MixinRulesetDirective rulesetDirect = currDef as MixinRulesetDirective;
+        var rulesetDirect = currDef as MixinRulesetDirective;
         rulesetDirect.rulesets.removeWhere((entry) {
           if (entry == node) {
             _messages.warning('Undefined mixin ${node.name}', node.span);
@@ -470,6 +479,7 @@
     super.visitIncludeDirective(node);
   }
 
+  @override
   void visitMixinRulesetDirective(MixinRulesetDirective node) {
     currDef = node;
 
@@ -480,6 +490,7 @@
     currDef = null;
   }
 
+  @override
   void visitMixinDeclarationDirective(MixinDeclarationDirective node) {
     currDef = node;
 
@@ -493,7 +504,6 @@
 
 /// @include as a top-level with ruleset(s).
 class _TopLevelIncludeReplacer extends Visitor {
-  final Messages _messages;
   final IncludeDirective _include;
   final List<TreeNode> _newRules;
   bool _foundAndReplaced = false;
@@ -503,13 +513,14 @@
   /// true.
   static bool replace(Messages messages, StyleSheet styleSheet,
       IncludeDirective include, List<TreeNode> newRules) {
-    var visitor = _TopLevelIncludeReplacer(messages, include, newRules);
+    var visitor = _TopLevelIncludeReplacer(include, newRules);
     visitor.visitStyleSheet(styleSheet);
     return visitor._foundAndReplaced;
   }
 
-  _TopLevelIncludeReplacer(this._messages, this._include, this._newRules);
+  _TopLevelIncludeReplacer(this._include, this._newRules);
 
+  @override
   visitStyleSheet(StyleSheet node) {
     var index = node.topLevels.indexOf(_include);
     if (index != -1) {
@@ -520,6 +531,7 @@
     super.visitStyleSheet(node);
   }
 
+  @override
   void visitMixinRulesetDirective(MixinRulesetDirective node) {
     var index = node.rulesets.indexOf(_include as dynamic);
     if (index != -1) {
@@ -556,7 +568,7 @@
   Expressions _currExpressions;
   int _currIndex = -1;
 
-  final varUsages = Map<String, Map<Expressions, Set<int>>>();
+  final varUsages = <String, Map<Expressions, Set<int>>>{};
 
   /// Only var defs with more than one expression (comma separated).
   final Map<String, VarDefinition> varDefs;
@@ -580,7 +592,7 @@
       if (definedArg is VarDefinition) {
         varDef = definedArg;
       } else if (definedArg is VarDefinitionDirective) {
-        VarDefinitionDirective varDirective = definedArg;
+        var varDirective = definedArg;
         varDef = varDirective.def;
       }
       var callArg = callArgs[index];
@@ -622,6 +634,7 @@
     return defArgs;
   }
 
+  @override
   void visitExpressions(Expressions node) {
     var oldExpressions = _currExpressions;
     var oldIndex = _currIndex;
@@ -636,35 +649,38 @@
   }
 
   void _addExpression(Map<Expressions, Set<int>> expressions) {
-    var indexSet = Set<int>();
+    var indexSet = <int>{};
     indexSet.add(_currIndex);
     expressions[_currExpressions] = indexSet;
   }
 
+  @override
   void visitVarUsage(VarUsage node) {
     assert(_currIndex != -1);
     assert(_currExpressions != null);
     if (varUsages.containsKey(node.name)) {
-      Map<Expressions, Set<int>> expressions = varUsages[node.name];
-      Set<int> allIndexes = expressions[_currExpressions];
+      var expressions = varUsages[node.name];
+      var allIndexes = expressions[_currExpressions];
       if (allIndexes == null) {
         _addExpression(expressions);
       } else {
         allIndexes.add(_currIndex);
       }
     } else {
-      var newExpressions = Map<Expressions, Set<int>>();
+      var newExpressions = <Expressions, Set<int>>{};
       _addExpression(newExpressions);
       varUsages[node.name] = newExpressions;
     }
     super.visitVarUsage(node);
   }
 
+  @override
   void visitMixinDeclarationDirective(MixinDeclarationDirective node) {
     _definedArgs = node.definedArgs;
     super.visitMixinDeclarationDirective(node);
   }
 
+  @override
   void visitMixinRulesetDirective(MixinRulesetDirective node) {
     _definedArgs = node.definedArgs;
     super.visitMixinRulesetDirective(node);
@@ -677,15 +693,15 @@
   final Messages _messages;
 
   /// Map of variable name key to it's definition.
-  final Map<String, MixinDefinition> map = Map<String, MixinDefinition>();
+  final Map<String, MixinDefinition> map = <String, MixinDefinition>{};
 
   /// Cache of mixin called with parameters.
-  final Map<String, CallMixin> callMap = Map<String, CallMixin>();
+  final Map<String, CallMixin> callMap = <String, CallMixin>{};
   MixinDefinition currDef;
   DeclarationGroup currDeclGroup;
 
   /// Var definitions with more than 1 expression.
-  final Map<String, VarDefinition> varDefs = Map<String, VarDefinition>();
+  final varDefs = <String, VarDefinition>{};
 
   static void expand(Messages messages, List<StyleSheet> styleSheets) {
     DeclarationIncludes(messages, styleSheets);
@@ -706,18 +722,21 @@
     return callMap[mixinDef.name];
   }
 
+  @override
   void visitStyleSheet(StyleSheet ss) {
     _styleSheet = ss;
     super.visitStyleSheet(ss);
     _styleSheet = null;
   }
 
+  @override
   void visitDeclarationGroup(DeclarationGroup node) {
     currDeclGroup = node;
     super.visitDeclarationGroup(node);
     currDeclGroup = null;
   }
 
+  @override
   void visitIncludeMixinAtDeclaration(IncludeMixinAtDeclaration node) {
     if (map.containsKey(node.include.name)) {
       var mixinDef = map[node.include.name];
@@ -730,7 +749,7 @@
             currDeclGroup.declarations.replaceRange(index, index + 1, [NoOp()]);
           }
           _messages.warning(
-              "Using top-level mixin ${node.include.name} as a declaration",
+              'Using top-level mixin ${node.include.name} as a declaration',
               node.span);
         } else {
           // We're a list of @include(s) inside of a mixin ruleset - convert
@@ -757,12 +776,13 @@
             _styleSheet, node, mixinDef.declarations.declarations);
       }
     } else {
-      _messages.warning("Undefined mixin ${node.include.name}", node.span);
+      _messages.warning('Undefined mixin ${node.include.name}', node.span);
     }
 
     super.visitIncludeMixinAtDeclaration(node);
   }
 
+  @override
   void visitIncludeDirective(IncludeDirective node) {
     if (map.containsKey(node.name)) {
       var mixinDef = map[node.name];
@@ -783,6 +803,7 @@
     super.visitIncludeDirective(node);
   }
 
+  @override
   void visitMixinRulesetDirective(MixinRulesetDirective node) {
     currDef = node;
 
@@ -793,6 +814,7 @@
     currDef = null;
   }
 
+  @override
   void visitMixinDeclarationDirective(MixinDeclarationDirective node) {
     currDef = node;
 
@@ -803,6 +825,7 @@
     currDef = null;
   }
 
+  @override
   void visitVarDefinition(VarDefinition node) {
     // Only record var definitions that have multiple expressions (comma
     // separated for mixin parameter substitution.
@@ -813,6 +836,7 @@
     super.visitVarDefinition(node);
   }
 
+  @override
   void visitVarDefinitionDirective(VarDefinitionDirective node) {
     visitVarDefinition(node.def);
   }
@@ -822,7 +846,6 @@
 class _IncludeReplacer extends Visitor {
   final _include;
   final List<TreeNode> _newDeclarations;
-  bool _foundAndReplaced = false;
 
   /// Look for the [ruleSet] inside of a @media directive; if found then replace
   /// with the [newRules].
@@ -834,13 +857,13 @@
 
   _IncludeReplacer(this._include, this._newDeclarations);
 
+  @override
   void visitDeclarationGroup(DeclarationGroup node) {
     var index = _findInclude(node.declarations, _include);
     if (index != -1) {
       node.declarations.insertAll(index + 1, _newDeclarations);
       // Change @include to NoOp so it's processed only once.
       node.declarations.replaceRange(index, index + 1, [NoOp()]);
-      _foundAndReplaced = true;
     }
     super.visitDeclarationGroup(node);
   }
@@ -856,6 +879,7 @@
   bool _nodesToRemove(node) =>
       node is IncludeDirective || node is MixinDefinition || node is NoOp;
 
+  @override
   void visitStyleSheet(StyleSheet ss) {
     var index = ss.topLevels.length;
     while (--index >= 0) {
@@ -866,6 +890,7 @@
     super.visitStyleSheet(ss);
   }
 
+  @override
   void visitDeclarationGroup(DeclarationGroup node) {
     var index = node.declarations.length;
     while (--index >= 0) {
@@ -879,13 +904,13 @@
 
 /// Find all @extend to create inheritance.
 class AllExtends extends Visitor {
-  final Map<String, List<SelectorGroup>> inherits =
-      Map<String, List<SelectorGroup>>();
+  final inherits = <String, List<SelectorGroup>>{};
 
   SelectorGroup _currSelectorGroup;
   int _currDeclIndex;
-  final List<int> _extendsToRemove = [];
+  final _extendsToRemove = <int>[];
 
+  @override
   void visitRuleSet(RuleSet node) {
     var oldSelectorGroup = _currSelectorGroup;
     _currSelectorGroup = node.selectorGroup;
@@ -895,8 +920,9 @@
     _currSelectorGroup = oldSelectorGroup;
   }
 
+  @override
   void visitExtendDeclaration(ExtendDeclaration node) {
-    var inheritName = "";
+    var inheritName = '';
     for (var selector in node.selectors) {
       inheritName += selector.toString();
     }
@@ -912,6 +938,7 @@
     super.visitExtendDeclaration(node);
   }
 
+  @override
   void visitDeclarationGroup(DeclarationGroup node) {
     var oldDeclIndex = _currDeclIndex;
 
@@ -937,25 +964,25 @@
 // TODO(terry): Need to handle !optional glag.
 /// Changes any selector that matches @extend.
 class InheritExtends extends Visitor {
-  final Messages _messages;
   final AllExtends _allExtends;
 
-  InheritExtends(this._messages, this._allExtends);
+  InheritExtends(Messages messages, this._allExtends);
 
+  @override
   void visitSelectorGroup(SelectorGroup node) {
     for (var selectorsIndex = 0;
         selectorsIndex < node.selectors.length;
         selectorsIndex++) {
       var selectors = node.selectors[selectorsIndex];
       var isLastNone = false;
-      var selectorName = "";
+      var selectorName = '';
       for (var index = 0;
           index < selectors.simpleSelectorSequences.length;
           index++) {
         var simpleSeq = selectors.simpleSelectorSequences[index];
         var namePart = simpleSeq.simpleSelector.toString();
         selectorName = (isLastNone) ? (selectorName + namePart) : namePart;
-        List<SelectorGroup> matches = _allExtends.inherits[selectorName];
+        var matches = _allExtends.inherits[selectorName];
         if (matches != null) {
           for (var match in matches) {
             // Create a new group.
diff --git a/lib/src/css_printer.dart b/lib/src/css_printer.dart
index a95fa34..0399296 100644
--- a/lib/src/css_printer.dart
+++ b/lib/src/css_printer.dart
@@ -11,6 +11,7 @@
 
   /// Walk the [tree] Stylesheet. [pretty] if true emits line breaks, extra
   /// spaces, friendly property values, etc., if false emits compacted output.
+  @override
   void visitTree(StyleSheet tree, {bool pretty = false}) {
     prettyPrint = pretty;
     _buff = StringBuffer();
@@ -23,6 +24,7 @@
   }
 
   /// Returns the output buffer.
+  @override
   String toString() => _buff.toString().trim();
 
   String get _newLine => prettyPrint ? '\n' : '';
@@ -34,20 +36,24 @@
   //              flag for obfuscation.
   bool get _isTesting => !prettyPrint;
 
+  @override
   void visitCalcTerm(CalcTerm node) {
     emit('${node.text}(');
     node.expr.visit(this);
     emit(')');
   }
 
+  @override
   void visitCssComment(CssComment node) {
     emit('/* ${node.comment} */');
   }
 
+  @override
   void visitCommentDefinition(CommentDefinition node) {
     emit('<!-- ${node.comment} -->');
   }
 
+  @override
   void visitMediaExpression(MediaExpression node) {
     emit(node.andOperator ? ' AND ' : ' ');
     emit('(${node.mediaFeature}');
@@ -58,6 +64,7 @@
     emit(')');
   }
 
+  @override
   void visitMediaQuery(MediaQuery query) {
     var unary = query.hasUnary ? ' ${query.unary}' : '';
     var mediaType = query.hasMediaType ? ' ${query.mediaType}' : '';
@@ -76,6 +83,7 @@
     }
   }
 
+  @override
   void visitDocumentDirective(DocumentDirective node) {
     emit('$_newLine@-moz-document ');
     node.functions.first.visit(this);
@@ -90,6 +98,7 @@
     emit('$_newLine}');
   }
 
+  @override
   void visitSupportsDirective(SupportsDirective node) {
     emit('$_newLine@supports ');
     node.condition.visit(this);
@@ -100,17 +109,20 @@
     emit('$_newLine}');
   }
 
+  @override
   void visitSupportsConditionInParens(SupportsConditionInParens node) {
     emit('(');
     node.condition.visit(this);
     emit(')');
   }
 
+  @override
   void visitSupportsNegation(SupportsNegation node) {
     emit('not$_sp');
     node.condition.visit(this);
   }
 
+  @override
   void visitSupportsConjunction(SupportsConjunction node) {
     node.conditions.first.visit(this);
     for (var condition in node.conditions.skip(1)) {
@@ -119,6 +131,7 @@
     }
   }
 
+  @override
   void visitSupportsDisjunction(SupportsDisjunction node) {
     node.conditions.first.visit(this);
     for (var condition in node.conditions.skip(1)) {
@@ -127,12 +140,14 @@
     }
   }
 
+  @override
   void visitViewportDirective(ViewportDirective node) {
     emit('@${node.name}$_sp{$_newLine');
     node.declarations.visit(this);
     emit('}');
   }
 
+  @override
   void visitMediaDirective(MediaDirective node) {
     emit('$_newLine@media');
     emitMediaQueries(node.mediaQueries);
@@ -143,6 +158,7 @@
     emit('$_newLine}');
   }
 
+  @override
   void visitHostDirective(HostDirective node) {
     emit('$_newLine@host$_sp{');
     for (var ruleset in node.rules) {
@@ -154,6 +170,7 @@
   ///  @page : pseudoPage {
   ///    decls
   ///  }
+  @override
   void visitPageDirective(PageDirective node) {
     emit('$_newLine@page');
     if (node.hasIdent || node.hasPseudoPage) {
@@ -172,10 +189,12 @@
   }
 
   /// @charset "charset encoding"
+  @override
   void visitCharsetDirective(CharsetDirective node) {
     emit('$_newLine@charset "${node.charEncoding}";');
   }
 
+  @override
   void visitImportDirective(ImportDirective node) {
     bool isStartingQuote(String ch) => ('\'"'.contains(ch[0]));
 
@@ -193,6 +212,7 @@
     emit(';');
   }
 
+  @override
   void visitKeyFrameDirective(KeyFrameDirective node) {
     emit('$_newLine${node.keyFrameName} ');
     node.name.visit(this);
@@ -203,6 +223,7 @@
     emit('}');
   }
 
+  @override
   void visitFontFaceDirective(FontFaceDirective node) {
     emit('$_newLine@font-face ');
     emit('$_sp{$_newLine');
@@ -210,6 +231,7 @@
     emit('}');
   }
 
+  @override
   void visitKeyFrameBlock(KeyFrameBlock node) {
     emit('$_sp$_sp');
     node._blockSelectors.visit(this);
@@ -218,10 +240,12 @@
     emit('$_sp$_sp}$_newLine');
   }
 
+  @override
   void visitStyletDirective(StyletDirective node) {
     emit('/* @stylet export as ${node.dartClassName} */\n');
   }
 
+  @override
   void visitNamespaceDirective(NamespaceDirective node) {
     bool isStartingQuote(String ch) => ('\'"'.contains(ch));
 
@@ -240,11 +264,13 @@
     emit(';');
   }
 
+  @override
   void visitVarDefinitionDirective(VarDefinitionDirective node) {
     visitVarDefinition(node.def);
     emit(';$_newLine');
   }
 
+  @override
   void visitMixinRulesetDirective(MixinRulesetDirective node) {
     emit('@mixin ${node.name} {');
     for (var ruleset in node.rulesets) {
@@ -253,6 +279,7 @@
     emit('}');
   }
 
+  @override
   void visitMixinDeclarationDirective(MixinDeclarationDirective node) {
     emit('@mixin ${node.name} {\n');
     visitDeclarationGroup(node.declarations);
@@ -261,30 +288,34 @@
 
   /// Added optional newLine for handling @include at top-level vs/ inside of
   /// a declaration group.
+  @override
   void visitIncludeDirective(IncludeDirective node, [bool topLevel = true]) {
     if (topLevel) emit(_newLine);
     emit('@include ${node.name}');
     emit(';');
   }
 
+  @override
   void visitContentDirective(ContentDirective node) {
     // TODO(terry): TBD
   }
 
+  @override
   void visitRuleSet(RuleSet node) {
-    emit("$_newLine");
+    emit('$_newLine');
     node._selectorGroup.visit(this);
-    emit("$_sp{$_newLine");
+    emit('$_sp{$_newLine');
     node._declarationGroup.visit(this);
-    emit("}");
+    emit('}');
   }
 
+  @override
   void visitDeclarationGroup(DeclarationGroup node) {
     var declarations = node.declarations;
     var declarationsLength = declarations.length;
     for (var i = 0; i < declarationsLength; i++) {
       if (i > 0) emit(_newLine);
-      emit("$_sp$_sp");
+      emit('$_sp$_sp');
       declarations[i].visit(this);
       // Don't emit the last semicolon in compact mode.
       if (prettyPrint || i < declarationsLength - 1) {
@@ -294,17 +325,19 @@
     if (declarationsLength > 0) emit(_newLine);
   }
 
+  @override
   void visitMarginGroup(MarginGroup node) {
     var margin_sym_name =
         TokenKind.idToValue(TokenKind.MARGIN_DIRECTIVES, node.margin_sym);
 
-    emit("@$margin_sym_name$_sp{$_newLine");
+    emit('@$margin_sym_name$_sp{$_newLine');
 
     visitDeclarationGroup(node);
 
-    emit("}$_newLine");
+    emit('}$_newLine');
   }
 
+  @override
   void visitDeclaration(Declaration node) {
     emit('${node.property}:$_sp');
     node._expression.visit(this);
@@ -313,23 +346,27 @@
     }
   }
 
+  @override
   void visitVarDefinition(VarDefinition node) {
-    emit("var-${node.definedName}: ");
+    emit('var-${node.definedName}: ');
     node._expression.visit(this);
   }
 
+  @override
   void visitIncludeMixinAtDeclaration(IncludeMixinAtDeclaration node) {
     // Don't emit a new line we're inside of a declaration group.
     visitIncludeDirective(node.include, false);
   }
 
+  @override
   void visitExtendDeclaration(ExtendDeclaration node) {
-    emit("@extend ");
+    emit('@extend ');
     for (var selector in node.selectors) {
       selector.visit(this);
     }
   }
 
+  @override
   void visitSelectorGroup(SelectorGroup node) {
     var selectors = node.selectors;
     var selectorsLength = selectors.length;
@@ -339,61 +376,74 @@
     }
   }
 
+  @override
   void visitSimpleSelectorSequence(SimpleSelectorSequence node) {
     emit('${node._combinatorToString}');
     node.simpleSelector.visit(this);
   }
 
+  @override
   void visitSimpleSelector(SimpleSelector node) {
     emit(node.name);
   }
 
+  @override
   void visitNamespaceSelector(NamespaceSelector node) {
     emit(node.toString());
   }
 
+  @override
   void visitElementSelector(ElementSelector node) {
     emit(node.toString());
   }
 
+  @override
   void visitAttributeSelector(AttributeSelector node) {
     emit(node.toString());
   }
 
+  @override
   void visitIdSelector(IdSelector node) {
     emit(node.toString());
   }
 
+  @override
   void visitClassSelector(ClassSelector node) {
     emit(node.toString());
   }
 
+  @override
   void visitPseudoClassSelector(PseudoClassSelector node) {
     emit(node.toString());
   }
 
+  @override
   void visitPseudoElementSelector(PseudoElementSelector node) {
     emit(node.toString());
   }
 
+  @override
   void visitPseudoClassFunctionSelector(PseudoClassFunctionSelector node) {
-    emit(":${node.name}(");
+    emit(':${node.name}(');
     node.argument.visit(this);
     emit(')');
   }
 
+  @override
   void visitPseudoElementFunctionSelector(PseudoElementFunctionSelector node) {
-    emit("::${node.name}(");
+    emit('::${node.name}(');
     node.expression.visit(this);
     emit(')');
   }
 
+  @override
   void visitNegationSelector(NegationSelector node) {
     emit(':not(');
     node.negationArg.visit(this);
     emit(')');
   }
 
+  @override
   void visitSelectorExpression(SelectorExpression node) {
     var expressions = node.expressions;
     var expressionsLength = expressions.length;
@@ -404,82 +454,97 @@
     }
   }
 
+  @override
   void visitUnicodeRangeTerm(UnicodeRangeTerm node) {
     if (node.hasSecond) {
-      emit("U+${node.first}-${node.second}");
+      emit('U+${node.first}-${node.second}');
     } else {
-      emit("U+${node.first}");
+      emit('U+${node.first}');
     }
   }
 
+  @override
   void visitLiteralTerm(LiteralTerm node) {
     emit(node.text);
   }
 
+  @override
   void visitHexColorTerm(HexColorTerm node) {
     String mappedName;
     if (_isTesting && (node.value is! BAD_HEX_VALUE)) {
       mappedName = TokenKind.hexToColorName(node.value);
     }
-    if (mappedName == null) {
-      mappedName = '#${node.text}';
-    }
+    mappedName ??= '#${node.text}';
 
     emit(mappedName);
   }
 
+  @override
   void visitNumberTerm(NumberTerm node) {
     visitLiteralTerm(node);
   }
 
+  @override
   void visitUnitTerm(UnitTerm node) {
     emit(node.toString());
   }
 
+  @override
   void visitLengthTerm(LengthTerm node) {
     emit(node.toString());
   }
 
+  @override
   void visitPercentageTerm(PercentageTerm node) {
     emit('${node.text}%');
   }
 
+  @override
   void visitEmTerm(EmTerm node) {
     emit('${node.text}em');
   }
 
+  @override
   void visitExTerm(ExTerm node) {
     emit('${node.text}ex');
   }
 
+  @override
   void visitAngleTerm(AngleTerm node) {
     emit(node.toString());
   }
 
+  @override
   void visitTimeTerm(TimeTerm node) {
     emit(node.toString());
   }
 
+  @override
   void visitFreqTerm(FreqTerm node) {
     emit(node.toString());
   }
 
+  @override
   void visitFractionTerm(FractionTerm node) {
     emit('${node.text}fr');
   }
 
+  @override
   void visitUriTerm(UriTerm node) {
     emit('url("${node.text}")');
   }
 
+  @override
   void visitResolutionTerm(ResolutionTerm node) {
     emit(node.toString());
   }
 
+  @override
   void visitViewportTerm(ViewportTerm node) {
     emit(node.toString());
   }
 
+  @override
   void visitFunctionTerm(FunctionTerm node) {
     // TODO(terry): Optimize rgb to a hexcolor.
     emit('${node.text}(');
@@ -487,6 +552,7 @@
     emit(')');
   }
 
+  @override
   void visitGroupTerm(GroupTerm node) {
     emit('(');
     var terms = node._terms;
@@ -498,30 +564,37 @@
     emit(')');
   }
 
+  @override
   void visitItemTerm(ItemTerm node) {
     emit('[${node.text}]');
   }
 
+  @override
   void visitIE8Term(IE8Term node) {
     visitLiteralTerm(node);
   }
 
+  @override
   void visitOperatorSlash(OperatorSlash node) {
     emit('/');
   }
 
+  @override
   void visitOperatorComma(OperatorComma node) {
     emit(',');
   }
 
+  @override
   void visitOperatorPlus(OperatorPlus node) {
     emit('+');
   }
 
+  @override
   void visitOperatorMinus(OperatorMinus node) {
     emit('-');
   }
 
+  @override
   void visitVarUsage(VarUsage node) {
     emit('var(${node.name}');
     if (node.defaultValues.isNotEmpty) {
@@ -534,6 +607,7 @@
     emit(')');
   }
 
+  @override
   void visitExpressions(Expressions node) {
     var expressions = node.expressions;
     var expressionsLength = expressions.length;
@@ -558,24 +632,29 @@
     }
   }
 
+  @override
   void visitBinaryExpression(BinaryExpression node) {
     // TODO(terry): TBD
     throw UnimplementedError;
   }
 
+  @override
   void visitUnaryExpression(UnaryExpression node) {
     // TODO(terry): TBD
     throw UnimplementedError;
   }
 
+  @override
   void visitIdentifier(Identifier node) {
     emit(node.name);
   }
 
+  @override
   void visitWildcard(Wildcard node) {
     emit('*');
   }
 
+  @override
   void visitDartStyleExpression(DartStyleExpression node) {
     // TODO(terry): TBD
     throw UnimplementedError;
diff --git a/lib/src/messages.dart b/lib/src/messages.dart
index edc72d8..b93a554 100644
--- a/lib/src/messages.dart
+++ b/lib/src/messages.dart
@@ -41,13 +41,12 @@
   final SourceSpan span;
   final bool useColors;
 
-  Message(this.level, this.message, {SourceSpan span, bool useColors = false})
-      : this.span = span,
-        this.useColors = useColors;
+  Message(this.level, this.message, {this.span, this.useColors = false});
 
+  @override
   String toString() {
     var output = StringBuffer();
-    bool colors = useColors && _errorColors.containsKey(level);
+    var colors = useColors && _errorColors.containsKey(level);
     var levelColor = colors ? _errorColors[level] : null;
     if (colors) output.write(levelColor);
     output..write(_errorLabel[level])..write(' ');
@@ -75,7 +74,7 @@
   final List<Message> messages = <Message>[];
 
   Messages({PreprocessorOptions options, this.printHandler = print})
-      : options = options != null ? options : PreprocessorOptions();
+      : options = options ?? PreprocessorOptions();
 
   /// Report a compile-time CSS error.
   void error(String message, SourceSpan span) {
diff --git a/lib/src/polyfill.dart b/lib/src/polyfill.dart
index d9c1b73..fa1a22a 100644
--- a/lib/src/polyfill.dart
+++ b/lib/src/polyfill.dart
@@ -8,9 +8,9 @@
 /// understand (var, calc, etc.).
 class PolyFill {
   final Messages _messages;
-  Map<String, VarDefinition> _allVarDefinitions = Map<String, VarDefinition>();
+  Map<String, VarDefinition> _allVarDefinitions = <String, VarDefinition>{};
 
-  Set<StyleSheet> allStyleSheets = Set<StyleSheet>();
+  Set<StyleSheet> allStyleSheets = <StyleSheet>{};
 
   /// [_pseudoElements] list of known pseudo attributes found in HTML, any
   /// CSS pseudo-elements 'name::custom-element' is mapped to the manged name
@@ -40,10 +40,9 @@
 
   void processVars(StyleSheet styleSheet) {
     // Build list of all var definitions.
-    var mainStyleSheetVarDefs =
-        (_VarDefAndUsage(this._messages, _allVarDefinitions)
-              ..visitTree(styleSheet))
-            .varDefs;
+    var mainStyleSheetVarDefs = (_VarDefAndUsage(_messages, _allVarDefinitions)
+          ..visitTree(styleSheet))
+        .varDefs;
 
     // Resolve all definitions to a non-VarUsage (terminal expression).
     mainStyleSheetVarDefs.forEach((key, value) {
@@ -61,16 +60,19 @@
 
   _VarDefinitionsIncludes(this.varDefs);
 
+  @override
   void visitTree(StyleSheet tree) {
     visitStyleSheet(tree);
   }
 
+  @override
   visitVarDefinition(VarDefinition node) {
     // Replace with latest variable definition.
     varDefs[node.definedName] = node;
     super.visitVarDefinition(node);
   }
 
+  @override
   void visitVarDefinitionDirective(VarDefinitionDirective node) {
     visitVarDefinition(node.def);
   }
@@ -81,17 +83,19 @@
 class _VarDefAndUsage extends Visitor {
   final Messages _messages;
   final Map<String, VarDefinition> _knownVarDefs;
-  final Map<String, VarDefinition> varDefs = Map<String, VarDefinition>();
+  final varDefs = <String, VarDefinition>{};
 
   VarDefinition currVarDefinition;
   List<Expression> currentExpressions;
 
   _VarDefAndUsage(this._messages, this._knownVarDefs);
 
+  @override
   void visitTree(StyleSheet tree) {
     visitStyleSheet(tree);
   }
 
+  @override
   visitVarDefinition(VarDefinition node) {
     // Replace with latest variable definition.
     currVarDefinition = node;
@@ -104,16 +108,19 @@
     currVarDefinition = null;
   }
 
+  @override
   void visitVarDefinitionDirective(VarDefinitionDirective node) {
     visitVarDefinition(node.def);
   }
 
+  @override
   void visitExpressions(Expressions node) {
     currentExpressions = node.expressions;
     super.visitExpressions(node);
     currentExpressions = null;
   }
 
+  @override
   void visitVarUsage(VarUsage node) {
     if (currVarDefinition != null && currVarDefinition.badUsage) return;
 
@@ -154,7 +161,7 @@
       }
       // Remove var usage that points at an undefined definition.
       expressions.removeAt(index);
-      _messages.warning("Variable is not defined.", node.span);
+      _messages.warning('Variable is not defined.', node.span);
     }
 
     var oldExpressions = currentExpressions;
@@ -199,15 +206,18 @@
 
 /// Remove all var definitions.
 class _RemoveVarDefinitions extends Visitor {
+  @override
   void visitTree(StyleSheet tree) {
     visitStyleSheet(tree);
   }
 
+  @override
   void visitStyleSheet(StyleSheet ss) {
     ss.topLevels.removeWhere((e) => e is VarDefinitionDirective);
     super.visitStyleSheet(ss);
   }
 
+  @override
   void visitDeclarationGroup(DeclarationGroup node) {
     node.declarations.removeWhere((e) => e is VarDefinition);
     super.visitDeclarationGroup(node);
diff --git a/lib/src/property.dart b/lib/src/property.dart
index 01fc96b..0fb79fb 100644
--- a/lib/src/property.dart
+++ b/lib/src/property.dart
@@ -52,7 +52,7 @@
   /// The [rgb] value of 0xffd700 would map to #ffd700 or the constant
   /// Color.gold, where ff is red intensity, d7 is green intensity, and 00 is
   /// blue intensity.
-  Color(int rgb, [num alpha]) : this._argb = Color._rgbToArgbString(rgb, alpha);
+  Color(int rgb, [num alpha]) : _argb = Color._rgbToArgbString(rgb, alpha);
 
   /// RGB takes three values. The [red], [green], and [blue] parameters are
   /// the intensity of those components where '0' is the least and '256' is the
@@ -63,7 +63,7 @@
   /// internally be mapped to an int between '0' and '255' like the other color
   /// components.
   Color.createRgba(int red, int green, int blue, [num alpha])
-      : this._argb = Color.convertToHexString(
+      : _argb = Color.convertToHexString(
             Color._clamp(red, 0, 255),
             Color._clamp(green, 0, 255),
             Color._clamp(blue, 0, 255),
@@ -71,7 +71,7 @@
 
   /// Creates a new color from a CSS color string. For more information, see
   /// <https://developer.mozilla.org/en/CSS/color>.
-  Color.css(String color) : this._argb = Color._convertCssToArgb(color);
+  Color.css(String color) : _argb = Color._convertCssToArgb(color);
 
   // TODO(jmesserly): I found the use of percents a bit suprising.
   /// HSL takes three values.  The [hueDegree] degree on the color wheel; '0' is
@@ -87,7 +87,7 @@
   /// foreground).
   Color.createHsla(num hueDegree, num saturationPercent, num lightnessPercent,
       [num alpha])
-      : this._argb = Hsla(
+      : _argb = Hsla(
                 Color._clamp(hueDegree, 0, 360) / 360,
                 Color._clamp(saturationPercent, 0, 100) / 100,
                 Color._clamp(lightnessPercent, 0, 100) / 100,
@@ -108,7 +108,7 @@
   ///                completely transparent foreground and 1 is a completely
   ///                opaque foreground.
   Color.hslaRaw(num hue, num saturation, num lightness, [num alpha])
-      : this._argb = Hsla(
+      : _argb = Hsla(
                 Color._clamp(hue, 0, 1),
                 Color._clamp(saturation, 0, 1),
                 Color._clamp(lightness, 0, 1),
@@ -119,6 +119,7 @@
   const Color.hex(this._argb);
 
   // TODO(jmesserly): this is needed by the example so leave it exposed for now.
+  @override
   String toString() => cssExpression;
 
   // TODO(terry): Regardless of how color is set (rgb, num, css or hsl) we'll
@@ -126,70 +127,75 @@
   //              CSS if user uses hsl and would like to edit as hsl, etc.  If
   //              this is an issue we should keep the original value and not re-
   //              create the CSS from the normalized value.
+  @override
   String get cssExpression {
     if (_argb.length == 6) {
-      return "#$_argb"; // RGB only, no alpha blending.
+      return '#$_argb'; // RGB only, no alpha blending.
     } else {
       num alpha = Color.hexToInt(_argb.substring(0, 2));
-      String a = (alpha / 255).toStringAsPrecision(2);
-      int r = Color.hexToInt(_argb.substring(2, 4));
-      int g = Color.hexToInt(_argb.substring(4, 6));
-      int b = Color.hexToInt(_argb.substring(6, 8));
-      return "rgba($r,$g,$b,$a)";
+      var a = (alpha / 255).toStringAsPrecision(2);
+      var r = Color.hexToInt(_argb.substring(2, 4));
+      var g = Color.hexToInt(_argb.substring(4, 6));
+      var b = Color.hexToInt(_argb.substring(6, 8));
+      return 'rgba($r,$g,$b,$a)';
     }
   }
 
   Rgba get rgba {
-    int nextIndex = 0;
+    var nextIndex = 0;
     num a;
     if (_argb.length == 8) {
       // Get alpha blending value 0..255
-      int alpha = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
+      var alpha = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
       // Convert to value from 0..1
       a = double.parse((alpha / 255).toStringAsPrecision(2));
       nextIndex += 2;
     }
-    int r = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
+    var r = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
     nextIndex += 2;
-    int g = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
+    var g = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
     nextIndex += 2;
-    int b = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
+    var b = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
     return Rgba(r, g, b, a);
   }
 
   Hsla get hsla => Hsla.fromRgba(rgba);
 
+  @override
   int get argbValue => Color.hexToInt(_argb);
 
+  @override
   bool operator ==(other) => Color.equal(this, other);
 
+  @override
   String toHexArgbString() => _argb;
 
   Color darker(num amount) {
-    Rgba newRgba = Color._createNewTintShadeFromRgba(rgba, -amount);
-    return Color.hex("${newRgba.toHexArgbString()}");
+    var newRgba = Color._createNewTintShadeFromRgba(rgba, -amount);
+    return Color.hex('${newRgba.toHexArgbString()}');
   }
 
   Color lighter(num amount) {
-    Rgba newRgba = Color._createNewTintShadeFromRgba(rgba, amount);
-    return Color.hex("${newRgba.toHexArgbString()}");
+    var newRgba = Color._createNewTintShadeFromRgba(rgba, amount);
+    return Color.hex('${newRgba.toHexArgbString()}');
   }
 
   static bool equal(ColorBase curr, other) {
     if (other is Color) {
-      Color o = other;
+      var o = other;
       return o.toHexArgbString() == curr.toHexArgbString();
     } else if (other is Rgba) {
-      Rgba rgb = other;
+      var rgb = other;
       return rgb.toHexArgbString() == curr.toHexArgbString();
     } else if (other is Hsla) {
-      Hsla hsla = other;
+      var hsla = other;
       return hsla.toHexArgbString() == curr.toHexArgbString();
     } else {
       return false;
     }
   }
 
+  @override
   int get hashCode => _argb.hashCode;
 
   // Conversion routines:
@@ -202,9 +208,9 @@
       a = (Color._clamp(alpha, 0, 1) * 255).round();
     }
 
-    int r = (rgba & 0xff0000) >> 0x10;
-    int g = (rgba & 0xff00) >> 8;
-    int b = rgba & 0xff;
+    var r = (rgba & 0xff0000) >> 0x10;
+    var g = (rgba & 0xff00) >> 8;
+    var b = rgba & 0xff;
 
     return Color.convertToHexString(r, g, b, a);
   }
@@ -219,23 +225,23 @@
   /// convert to argb.
   static String _convertCssToArgb(String value) {
     // TODO(terry): Better parser/regex for converting CSS properties.
-    String color = value.trim().replaceAll("\\s", "");
+    var color = value.trim().replaceAll('\\s', '');
     if (color[0] == '#') {
-      String v = color.substring(1);
+      var v = color.substring(1);
       Color.hexToInt(v); // Valid hexadecimal, throws if not.
       return v;
     } else if (color.isNotEmpty && color[color.length - 1] == ')') {
       int type;
-      if (color.indexOf("rgb(") == 0 || color.indexOf("RGB(") == 0) {
+      if (color.indexOf('rgb(') == 0 || color.indexOf('RGB(') == 0) {
         color = color.substring(4);
         type = _rgbCss;
-      } else if (color.indexOf("rgba(") == 0 || color.indexOf("RGBA(") == 0) {
+      } else if (color.indexOf('rgba(') == 0 || color.indexOf('RGBA(') == 0) {
         type = _rgbaCss;
         color = color.substring(5);
-      } else if (color.indexOf("hsl(") == 0 || color.indexOf("HSL(") == 0) {
+      } else if (color.indexOf('hsl(') == 0 || color.indexOf('HSL(') == 0) {
         type = _hslCss;
         color = color.substring(4);
-      } else if (color.indexOf("hsla(") == 0 || color.indexOf("HSLA(") == 0) {
+      } else if (color.indexOf('hsla(') == 0 || color.indexOf('HSLA(') == 0) {
         type = _hslaCss;
         color = color.substring(5);
       } else {
@@ -245,8 +251,8 @@
       color = color.substring(0, color.length - 1); // Strip close paren.
 
       var args = <num>[];
-      List<String> params = color.split(",");
-      for (String param in params) {
+      var params = color.split(',');
+      for (var param in params) {
         args.add(double.parse(param));
       }
       switch (type) {
@@ -270,24 +276,24 @@
   static int hexToInt(String hex) => int.parse(hex, radix: 16);
 
   static String convertToHexString(int r, int g, int b, [num a]) {
-    String rHex = Color._numAs2DigitHex(Color._clamp(r, 0, 255));
-    String gHex = Color._numAs2DigitHex(Color._clamp(g, 0, 255));
-    String bHex = Color._numAs2DigitHex(Color._clamp(b, 0, 255));
-    String aHex = (a != null)
+    var rHex = Color._numAs2DigitHex(Color._clamp(r, 0, 255));
+    var gHex = Color._numAs2DigitHex(Color._clamp(g, 0, 255));
+    var bHex = Color._numAs2DigitHex(Color._clamp(b, 0, 255));
+    var aHex = (a != null)
         ? Color._numAs2DigitHex((Color._clamp(a, 0, 1) * 255).round())
-        : "";
+        : '';
 
     // TODO(terry) 15.toRadixString(16) return 'F' on Dartium not f as in JS.
     //             bug: <http://code.google.com/p/dart/issues/detail?id=2670>
-    return "$aHex$rHex$gHex$bHex".toLowerCase();
+    return '$aHex$rHex$gHex$bHex'.toLowerCase();
   }
 
   static String _numAs2DigitHex(num v) {
     // TODO(terry): v.toInt().toRadixString instead of v.toRadixString
     //              Bug <http://code.google.com/p/dart/issues/detail?id=2671>.
-    String hex = v.toInt().toRadixString(16);
+    var hex = v.toInt().toRadixString(16);
     if (hex.length == 1) {
-      hex = "0${hex}";
+      hex = '0${hex}';
     }
     return hex;
   }
@@ -306,7 +312,7 @@
   /// the color #ffffff (white).
   static Rgba _createNewTintShadeFromRgba(Rgba rgba, num amount) {
     int r, g, b;
-    num tintShade = Color._clamp(amount, -1, 1);
+    var tintShade = Color._clamp(amount, -1, 1);
     if (amount < 0 && rgba.r == 255 && rgba.g == 255 && rgba.b == 255) {
       // TODO(terry): See TODO in _changeTintShadeColor; eliminate this test
       //              by converting to HSL and adjust lightness although this
@@ -334,154 +340,154 @@
       Color._clamp(((1 - delta) * v + (delta * 255)).round(), 0, 255);
 
   // Predefined CSS colors see <http://www.w3.org/TR/css3-color/>
-  static final Color transparent = const Color.hex("00ffffff"); // Alpha 0.0
-  static final Color aliceBlue = const Color.hex("0f08ff");
-  static final Color antiqueWhite = const Color.hex("0faebd7");
-  static final Color aqua = const Color.hex("00ffff");
-  static final Color aquaMarine = const Color.hex("7fffd4");
-  static final Color azure = const Color.hex("f0ffff");
-  static final Color beige = const Color.hex("f5f5dc");
-  static final Color bisque = const Color.hex("ffe4c4");
-  static final Color black = const Color.hex("000000");
-  static final Color blanchedAlmond = const Color.hex("ffebcd");
-  static final Color blue = const Color.hex("0000ff");
-  static final Color blueViolet = const Color.hex("8a2be2");
-  static final Color brown = const Color.hex("a52a2a");
-  static final Color burlyWood = const Color.hex("deb887");
-  static final Color cadetBlue = const Color.hex("5f9ea0");
-  static final Color chartreuse = const Color.hex("7fff00");
-  static final Color chocolate = const Color.hex("d2691e");
-  static final Color coral = const Color.hex("ff7f50");
-  static final Color cornFlowerBlue = const Color.hex("6495ed");
-  static final Color cornSilk = const Color.hex("fff8dc");
-  static final Color crimson = const Color.hex("dc143c");
-  static final Color cyan = const Color.hex("00ffff");
-  static final Color darkBlue = const Color.hex("00008b");
-  static final Color darkCyan = const Color.hex("008b8b");
-  static final Color darkGoldenRod = const Color.hex("b8860b");
-  static final Color darkGray = const Color.hex("a9a9a9");
-  static final Color darkGreen = const Color.hex("006400");
-  static final Color darkGrey = const Color.hex("a9a9a9");
-  static final Color darkKhaki = const Color.hex("bdb76b");
-  static final Color darkMagenta = const Color.hex("8b008b");
-  static final Color darkOliveGreen = const Color.hex("556b2f");
-  static final Color darkOrange = const Color.hex("ff8c00");
-  static final Color darkOrchid = const Color.hex("9932cc");
-  static final Color darkRed = const Color.hex("8b0000");
-  static final Color darkSalmon = const Color.hex("e9967a");
-  static final Color darkSeaGreen = const Color.hex("8fbc8f");
-  static final Color darkSlateBlue = const Color.hex("483d8b");
-  static final Color darkSlateGray = const Color.hex("2f4f4f");
-  static final Color darkSlateGrey = const Color.hex("2f4f4f");
-  static final Color darkTurquoise = const Color.hex("00ced1");
-  static final Color darkViolet = const Color.hex("9400d3");
-  static final Color deepPink = const Color.hex("ff1493");
-  static final Color deepSkyBlue = const Color.hex("00bfff");
-  static final Color dimGray = const Color.hex("696969");
-  static final Color dimGrey = const Color.hex("696969");
-  static final Color dodgerBlue = const Color.hex("1e90ff");
-  static final Color fireBrick = const Color.hex("b22222");
-  static final Color floralWhite = const Color.hex("fffaf0");
-  static final Color forestGreen = const Color.hex("228b22");
-  static final Color fuchsia = const Color.hex("ff00ff");
-  static final Color gainsboro = const Color.hex("dcdcdc");
-  static final Color ghostWhite = const Color.hex("f8f8ff");
-  static final Color gold = const Color.hex("ffd700");
-  static final Color goldenRod = const Color.hex("daa520");
-  static final Color gray = const Color.hex("808080");
-  static final Color green = const Color.hex("008000");
-  static final Color greenYellow = const Color.hex("adff2f");
-  static final Color grey = const Color.hex("808080");
-  static final Color honeydew = const Color.hex("f0fff0");
-  static final Color hotPink = const Color.hex("ff69b4");
-  static final Color indianRed = const Color.hex("cd5c5c");
-  static final Color indigo = const Color.hex("4b0082");
-  static final Color ivory = const Color.hex("fffff0");
-  static final Color khaki = const Color.hex("f0e68c");
-  static final Color lavender = const Color.hex("e6e6fa");
-  static final Color lavenderBlush = const Color.hex("fff0f5");
-  static final Color lawnGreen = const Color.hex("7cfc00");
-  static final Color lemonChiffon = const Color.hex("fffacd");
-  static final Color lightBlue = const Color.hex("add8e6");
-  static final Color lightCoral = const Color.hex("f08080");
-  static final Color lightCyan = const Color.hex("e0ffff");
-  static final Color lightGoldenRodYellow = const Color.hex("fafad2");
-  static final Color lightGray = const Color.hex("d3d3d3");
-  static final Color lightGreen = const Color.hex("90ee90");
-  static final Color lightGrey = const Color.hex("d3d3d3");
-  static final Color lightPink = const Color.hex("ffb6c1");
-  static final Color lightSalmon = const Color.hex("ffa07a");
-  static final Color lightSeaGreen = const Color.hex("20b2aa");
-  static final Color lightSkyBlue = const Color.hex("87cefa");
-  static final Color lightSlateGray = const Color.hex("778899");
-  static final Color lightSlateGrey = const Color.hex("778899");
-  static final Color lightSteelBlue = const Color.hex("b0c4de");
-  static final Color lightYellow = const Color.hex("ffffe0");
-  static final Color lime = const Color.hex("00ff00");
-  static final Color limeGreen = const Color.hex("32cd32");
-  static final Color linen = const Color.hex("faf0e6");
-  static final Color magenta = const Color.hex("ff00ff");
-  static final Color maroon = const Color.hex("800000");
-  static final Color mediumAquaMarine = const Color.hex("66cdaa");
-  static final Color mediumBlue = const Color.hex("0000cd");
-  static final Color mediumOrchid = const Color.hex("ba55d3");
-  static final Color mediumPurple = const Color.hex("9370db");
-  static final Color mediumSeaGreen = const Color.hex("3cb371");
-  static final Color mediumSlateBlue = const Color.hex("7b68ee");
-  static final Color mediumSpringGreen = const Color.hex("00fa9a");
-  static final Color mediumTurquoise = const Color.hex("48d1cc");
-  static final Color mediumVioletRed = const Color.hex("c71585");
-  static final Color midnightBlue = const Color.hex("191970");
-  static final Color mintCream = const Color.hex("f5fffa");
-  static final Color mistyRose = const Color.hex("ffe4e1");
-  static final Color moccasin = const Color.hex("ffe4b5");
-  static final Color navajoWhite = const Color.hex("ffdead");
-  static final Color navy = const Color.hex("000080");
-  static final Color oldLace = const Color.hex("fdf5e6");
-  static final Color olive = const Color.hex("808000");
-  static final Color oliveDrab = const Color.hex("6b8e23");
-  static final Color orange = const Color.hex("ffa500");
-  static final Color orangeRed = const Color.hex("ff4500");
-  static final Color orchid = const Color.hex("da70d6");
-  static final Color paleGoldenRod = const Color.hex("eee8aa");
-  static final Color paleGreen = const Color.hex("98fb98");
-  static final Color paleTurquoise = const Color.hex("afeeee");
-  static final Color paleVioletRed = const Color.hex("db7093");
-  static final Color papayaWhip = const Color.hex("ffefd5");
-  static final Color peachPuff = const Color.hex("ffdab9");
-  static final Color peru = const Color.hex("cd85ef");
-  static final Color pink = const Color.hex("ffc0cb");
-  static final Color plum = const Color.hex("dda0dd");
-  static final Color powderBlue = const Color.hex("b0e0e6");
-  static final Color purple = const Color.hex("800080");
-  static final Color red = const Color.hex("ff0000");
-  static final Color rosyBrown = const Color.hex("bc8f8f");
-  static final Color royalBlue = const Color.hex("4169e1");
-  static final Color saddleBrown = const Color.hex("8b4513");
-  static final Color salmon = const Color.hex("fa8072");
-  static final Color sandyBrown = const Color.hex("f4a460");
-  static final Color seaGreen = const Color.hex("2e8b57");
-  static final Color seashell = const Color.hex("fff5ee");
-  static final Color sienna = const Color.hex("a0522d");
-  static final Color silver = const Color.hex("c0c0c0");
-  static final Color skyBlue = const Color.hex("87ceeb");
-  static final Color slateBlue = const Color.hex("6a5acd");
-  static final Color slateGray = const Color.hex("708090");
-  static final Color slateGrey = const Color.hex("708090");
-  static final Color snow = const Color.hex("fffafa");
-  static final Color springGreen = const Color.hex("00ff7f");
-  static final Color steelBlue = const Color.hex("4682b4");
-  static final Color tan = const Color.hex("d2b48c");
-  static final Color teal = const Color.hex("008080");
-  static final Color thistle = const Color.hex("d8bfd8");
-  static final Color tomato = const Color.hex("ff6347");
-  static final Color turquoise = const Color.hex("40e0d0");
-  static final Color violet = const Color.hex("ee82ee");
-  static final Color wheat = const Color.hex("f5deb3");
-  static final Color white = const Color.hex("ffffff");
-  static final Color whiteSmoke = const Color.hex("f5f5f5");
-  static final Color yellow = const Color.hex("ffff00");
-  static final Color yellowGreen = const Color.hex("9acd32");
+  static final Color transparent = const Color.hex('00ffffff'); // Alpha 0.0
+  static final Color aliceBlue = const Color.hex('0f08ff');
+  static final Color antiqueWhite = const Color.hex('0faebd7');
+  static final Color aqua = const Color.hex('00ffff');
+  static final Color aquaMarine = const Color.hex('7fffd4');
+  static final Color azure = const Color.hex('f0ffff');
+  static final Color beige = const Color.hex('f5f5dc');
+  static final Color bisque = const Color.hex('ffe4c4');
+  static final Color black = const Color.hex('000000');
+  static final Color blanchedAlmond = const Color.hex('ffebcd');
+  static final Color blue = const Color.hex('0000ff');
+  static final Color blueViolet = const Color.hex('8a2be2');
+  static final Color brown = const Color.hex('a52a2a');
+  static final Color burlyWood = const Color.hex('deb887');
+  static final Color cadetBlue = const Color.hex('5f9ea0');
+  static final Color chartreuse = const Color.hex('7fff00');
+  static final Color chocolate = const Color.hex('d2691e');
+  static final Color coral = const Color.hex('ff7f50');
+  static final Color cornFlowerBlue = const Color.hex('6495ed');
+  static final Color cornSilk = const Color.hex('fff8dc');
+  static final Color crimson = const Color.hex('dc143c');
+  static final Color cyan = const Color.hex('00ffff');
+  static final Color darkBlue = const Color.hex('00008b');
+  static final Color darkCyan = const Color.hex('008b8b');
+  static final Color darkGoldenRod = const Color.hex('b8860b');
+  static final Color darkGray = const Color.hex('a9a9a9');
+  static final Color darkGreen = const Color.hex('006400');
+  static final Color darkGrey = const Color.hex('a9a9a9');
+  static final Color darkKhaki = const Color.hex('bdb76b');
+  static final Color darkMagenta = const Color.hex('8b008b');
+  static final Color darkOliveGreen = const Color.hex('556b2f');
+  static final Color darkOrange = const Color.hex('ff8c00');
+  static final Color darkOrchid = const Color.hex('9932cc');
+  static final Color darkRed = const Color.hex('8b0000');
+  static final Color darkSalmon = const Color.hex('e9967a');
+  static final Color darkSeaGreen = const Color.hex('8fbc8f');
+  static final Color darkSlateBlue = const Color.hex('483d8b');
+  static final Color darkSlateGray = const Color.hex('2f4f4f');
+  static final Color darkSlateGrey = const Color.hex('2f4f4f');
+  static final Color darkTurquoise = const Color.hex('00ced1');
+  static final Color darkViolet = const Color.hex('9400d3');
+  static final Color deepPink = const Color.hex('ff1493');
+  static final Color deepSkyBlue = const Color.hex('00bfff');
+  static final Color dimGray = const Color.hex('696969');
+  static final Color dimGrey = const Color.hex('696969');
+  static final Color dodgerBlue = const Color.hex('1e90ff');
+  static final Color fireBrick = const Color.hex('b22222');
+  static final Color floralWhite = const Color.hex('fffaf0');
+  static final Color forestGreen = const Color.hex('228b22');
+  static final Color fuchsia = const Color.hex('ff00ff');
+  static final Color gainsboro = const Color.hex('dcdcdc');
+  static final Color ghostWhite = const Color.hex('f8f8ff');
+  static final Color gold = const Color.hex('ffd700');
+  static final Color goldenRod = const Color.hex('daa520');
+  static final Color gray = const Color.hex('808080');
+  static final Color green = const Color.hex('008000');
+  static final Color greenYellow = const Color.hex('adff2f');
+  static final Color grey = const Color.hex('808080');
+  static final Color honeydew = const Color.hex('f0fff0');
+  static final Color hotPink = const Color.hex('ff69b4');
+  static final Color indianRed = const Color.hex('cd5c5c');
+  static final Color indigo = const Color.hex('4b0082');
+  static final Color ivory = const Color.hex('fffff0');
+  static final Color khaki = const Color.hex('f0e68c');
+  static final Color lavender = const Color.hex('e6e6fa');
+  static final Color lavenderBlush = const Color.hex('fff0f5');
+  static final Color lawnGreen = const Color.hex('7cfc00');
+  static final Color lemonChiffon = const Color.hex('fffacd');
+  static final Color lightBlue = const Color.hex('add8e6');
+  static final Color lightCoral = const Color.hex('f08080');
+  static final Color lightCyan = const Color.hex('e0ffff');
+  static final Color lightGoldenRodYellow = const Color.hex('fafad2');
+  static final Color lightGray = const Color.hex('d3d3d3');
+  static final Color lightGreen = const Color.hex('90ee90');
+  static final Color lightGrey = const Color.hex('d3d3d3');
+  static final Color lightPink = const Color.hex('ffb6c1');
+  static final Color lightSalmon = const Color.hex('ffa07a');
+  static final Color lightSeaGreen = const Color.hex('20b2aa');
+  static final Color lightSkyBlue = const Color.hex('87cefa');
+  static final Color lightSlateGray = const Color.hex('778899');
+  static final Color lightSlateGrey = const Color.hex('778899');
+  static final Color lightSteelBlue = const Color.hex('b0c4de');
+  static final Color lightYellow = const Color.hex('ffffe0');
+  static final Color lime = const Color.hex('00ff00');
+  static final Color limeGreen = const Color.hex('32cd32');
+  static final Color linen = const Color.hex('faf0e6');
+  static final Color magenta = const Color.hex('ff00ff');
+  static final Color maroon = const Color.hex('800000');
+  static final Color mediumAquaMarine = const Color.hex('66cdaa');
+  static final Color mediumBlue = const Color.hex('0000cd');
+  static final Color mediumOrchid = const Color.hex('ba55d3');
+  static final Color mediumPurple = const Color.hex('9370db');
+  static final Color mediumSeaGreen = const Color.hex('3cb371');
+  static final Color mediumSlateBlue = const Color.hex('7b68ee');
+  static final Color mediumSpringGreen = const Color.hex('00fa9a');
+  static final Color mediumTurquoise = const Color.hex('48d1cc');
+  static final Color mediumVioletRed = const Color.hex('c71585');
+  static final Color midnightBlue = const Color.hex('191970');
+  static final Color mintCream = const Color.hex('f5fffa');
+  static final Color mistyRose = const Color.hex('ffe4e1');
+  static final Color moccasin = const Color.hex('ffe4b5');
+  static final Color navajoWhite = const Color.hex('ffdead');
+  static final Color navy = const Color.hex('000080');
+  static final Color oldLace = const Color.hex('fdf5e6');
+  static final Color olive = const Color.hex('808000');
+  static final Color oliveDrab = const Color.hex('6b8e23');
+  static final Color orange = const Color.hex('ffa500');
+  static final Color orangeRed = const Color.hex('ff4500');
+  static final Color orchid = const Color.hex('da70d6');
+  static final Color paleGoldenRod = const Color.hex('eee8aa');
+  static final Color paleGreen = const Color.hex('98fb98');
+  static final Color paleTurquoise = const Color.hex('afeeee');
+  static final Color paleVioletRed = const Color.hex('db7093');
+  static final Color papayaWhip = const Color.hex('ffefd5');
+  static final Color peachPuff = const Color.hex('ffdab9');
+  static final Color peru = const Color.hex('cd85ef');
+  static final Color pink = const Color.hex('ffc0cb');
+  static final Color plum = const Color.hex('dda0dd');
+  static final Color powderBlue = const Color.hex('b0e0e6');
+  static final Color purple = const Color.hex('800080');
+  static final Color red = const Color.hex('ff0000');
+  static final Color rosyBrown = const Color.hex('bc8f8f');
+  static final Color royalBlue = const Color.hex('4169e1');
+  static final Color saddleBrown = const Color.hex('8b4513');
+  static final Color salmon = const Color.hex('fa8072');
+  static final Color sandyBrown = const Color.hex('f4a460');
+  static final Color seaGreen = const Color.hex('2e8b57');
+  static final Color seashell = const Color.hex('fff5ee');
+  static final Color sienna = const Color.hex('a0522d');
+  static final Color silver = const Color.hex('c0c0c0');
+  static final Color skyBlue = const Color.hex('87ceeb');
+  static final Color slateBlue = const Color.hex('6a5acd');
+  static final Color slateGray = const Color.hex('708090');
+  static final Color slateGrey = const Color.hex('708090');
+  static final Color snow = const Color.hex('fffafa');
+  static final Color springGreen = const Color.hex('00ff7f');
+  static final Color steelBlue = const Color.hex('4682b4');
+  static final Color tan = const Color.hex('d2b48c');
+  static final Color teal = const Color.hex('008080');
+  static final Color thistle = const Color.hex('d8bfd8');
+  static final Color tomato = const Color.hex('ff6347');
+  static final Color turquoise = const Color.hex('40e0d0');
+  static final Color violet = const Color.hex('ee82ee');
+  static final Color wheat = const Color.hex('f5deb3');
+  static final Color white = const Color.hex('ffffff');
+  static final Color whiteSmoke = const Color.hex('f5f5f5');
+  static final Color yellow = const Color.hex('ffff00');
+  static final Color yellowGreen = const Color.hex('9acd32');
 }
 
 /// Rgba class for users that want to interact with a color as a RGBA value.
@@ -494,13 +500,13 @@
   final num a;
 
   Rgba(int red, int green, int blue, [num alpha])
-      : this.r = Color._clamp(red, 0, 255),
-        this.g = Color._clamp(green, 0, 255),
-        this.b = Color._clamp(blue, 0, 255),
-        this.a = (alpha != null) ? Color._clamp(alpha, 0, 1) : alpha;
+      : r = Color._clamp(red, 0, 255),
+        g = Color._clamp(green, 0, 255),
+        b = Color._clamp(blue, 0, 255),
+        a = (alpha != null) ? Color._clamp(alpha, 0, 1) : alpha;
 
   factory Rgba.fromString(String hexValue) =>
-      Color.css("#${Color._convertCssToArgb(hexValue)}").rgba;
+      Color.css('#${Color._convertCssToArgb(hexValue)}').rgba;
 
   factory Rgba.fromColor(Color color) => color.rgba;
 
@@ -517,10 +523,10 @@
     // See site <http://easyrgb.com/index.php?X=MATH> for good documentation
     // and color conversion routines.
 
-    num h = hsla.hue;
-    num s = hsla.saturation;
-    num l = hsla.lightness;
-    num a = hsla.alpha;
+    var h = hsla.hue;
+    var s = hsla.saturation;
+    var l = hsla.lightness;
+    var a = hsla.alpha;
 
     int r;
     int g;
@@ -538,7 +544,7 @@
       } else {
         var2 = (l + s) - (s * l);
       }
-      num var1 = 2 * l - var2;
+      var var1 = 2 * l - var2;
 
       r = (255 * Rgba._hueToRGB(var1, var2, h + (1 / 3))).round().toInt();
       g = (255 * Rgba._hueToRGB(var1, var2, h)).round().toInt();
@@ -572,20 +578,24 @@
     return v1;
   }
 
+  @override
   bool operator ==(other) => Color.equal(this, other);
 
+  @override
   String get cssExpression {
     if (a == null) {
-      return "#${Color.convertToHexString(r, g, b)}";
+      return '#${Color.convertToHexString(r, g, b)}';
     } else {
-      return "rgba($r,$g,$b,$a)";
+      return 'rgba($r,$g,$b,$a)';
     }
   }
 
+  @override
   String toHexArgbString() => Color.convertToHexString(r, g, b, a);
 
+  @override
   int get argbValue {
-    int value = 0;
+    var value = 0;
     if (a != null) {
       value = (a.toInt() << 0x18);
     }
@@ -601,6 +611,7 @@
   Rgba darker(num amount) => Color._createNewTintShadeFromRgba(this, -amount);
   Rgba lighter(num amount) => Color._createNewTintShadeFromRgba(this, amount);
 
+  @override
   int get hashCode => toHexArgbString().hashCode;
 }
 
@@ -619,26 +630,26 @@
   /// [lightness] is a 0..1 fraction (100% == 1).
   /// [alpha] is a 0..1 fraction, alpha blending between 0..1, 1 == 100% opaque.
   Hsla(num hue, num saturation, num lightness, [num alpha])
-      : this._h = (hue == 1) ? 0 : Color._clamp(hue, 0, 1),
-        this._s = Color._clamp(saturation, 0, 1),
-        this._l = Color._clamp(lightness, 0, 1),
-        this._a = (alpha != null) ? Color._clamp(alpha, 0, 1) : alpha;
+      : _h = (hue == 1) ? 0 : Color._clamp(hue, 0, 1),
+        _s = Color._clamp(saturation, 0, 1),
+        _l = Color._clamp(lightness, 0, 1),
+        _a = (alpha != null) ? Color._clamp(alpha, 0, 1) : alpha;
 
   factory Hsla.fromString(String hexValue) {
-    Rgba rgba = Color.css("#${Color._convertCssToArgb(hexValue)}").rgba;
+    var rgba = Color.css('#${Color._convertCssToArgb(hexValue)}').rgba;
     return _createFromRgba(rgba.r, rgba.g, rgba.b, rgba.a);
   }
 
   factory Hsla.fromColor(Color color) {
-    Rgba rgba = color.rgba;
+    var rgba = color.rgba;
     return _createFromRgba(rgba.r, rgba.g, rgba.b, rgba.a);
   }
 
   factory Hsla.fromArgbValue(num value) {
     num a = (value.toInt() & 0xff000000) >> 0x18;
-    int r = (value.toInt() & 0xff0000) >> 0x10;
-    int g = (value.toInt() & 0xff00) >> 8;
-    int b = value.toInt() & 0xff;
+    var r = (value.toInt() & 0xff0000) >> 0x10;
+    var g = (value.toInt() & 0xff00) >> 8;
+    var b = value.toInt() & 0xff;
 
     // Convert alpha to 0..1 from (0..255).
     if (a != null) {
@@ -664,14 +675,14 @@
     num s;
     num l;
 
-    num minRgb = math.min(r, math.min(g, b));
-    num maxRgb = math.max(r, math.max(g, b));
+    var minRgb = math.min(r, math.min(g, b));
+    var maxRgb = math.max(r, math.max(g, b));
     l = (maxRgb + minRgb) / 2;
     if (l <= 0) {
       return Hsla(0, 0, l); // Black;
     }
 
-    num vm = maxRgb - minRgb;
+    var vm = maxRgb - minRgb;
     s = vm;
     if (s > 0) {
       s /= (l < 0.5) ? (maxRgb + minRgb) : (2 - maxRgb - minRgb);
@@ -716,15 +727,19 @@
   /// Returns number as 0..1
   num get alpha => _a;
 
+  @override
   bool operator ==(other) => Color.equal(this, other);
 
+  @override
   String get cssExpression => (_a == null)
-      ? "hsl($hueDegrees,$saturationPercentage,$lightnessPercentage)"
-      : "hsla($hueDegrees,$saturationPercentage,$lightnessPercentage,$_a)";
+      ? 'hsl($hueDegrees,$saturationPercentage,$lightnessPercentage)'
+      : 'hsla($hueDegrees,$saturationPercentage,$lightnessPercentage,$_a)';
 
+  @override
   String toHexArgbString() => Rgba.fromHsla(this).toHexArgbString();
 
-  int get argbValue => Color.hexToInt(this.toHexArgbString());
+  @override
+  int get argbValue => Color.hexToInt(toHexArgbString());
 
   Color get color => Color.createHsla(_h, _s, _l, _a);
   Rgba get rgba => Rgba.fromHsla(this);
@@ -734,6 +749,7 @@
   Hsla lighter(num amount) =>
       Hsla.fromRgba(Rgba.fromHsla(this).lighter(amount));
 
+  @override
   int get hashCode => toHexArgbString().hashCode;
 }
 
@@ -742,6 +758,7 @@
   final num x, y;
   const PointXY(this.x, this.y);
 
+  @override
   String get cssExpression {
     // TODO(terry): TBD
     return null;
@@ -768,9 +785,10 @@
   int get width => left + right;
   int get height => top + bottom;
 
+  @override
   String get cssExpression {
     return (top == left && bottom == right && top == right)
-        ? "${left}px"
+        ? '${left}px'
         : "${top != null ? '$top' : '0'}px "
             "${right != null ? '$right' : '0'}px "
             "${bottom != null ? '$bottom' : '0'}px "
@@ -781,24 +799,24 @@
 /// Font style constants.
 class FontStyle {
   /// Font style [normal] default.
-  static const String normal = "normal";
+  static const String normal = 'normal';
 
   /// Font style [italic] use explicity crafted italic font otherwise inclined
   /// on the fly like oblique.
-  static const String italic = "italic";
+  static const String italic = 'italic';
 
   /// Font style [oblique] is rarely used. The normal style of a font is
   /// inclined on the fly to the right by 8-12 degrees.
-  static const String oblique = "oblique";
+  static const String oblique = 'oblique';
 }
 
 /// Font variant constants.
 class FontVariant {
   /// Font style [normal] default.
-  static const String normal = "normal";
+  static const String normal = 'normal';
 
   /// Font variant [smallCaps].
-  static const String smallCaps = "small-caps";
+  static const String smallCaps = 'small-caps';
 }
 
 /// Font weight constants values 100, 200, 300, 400, 500, 600, 700, 800, 900.
@@ -823,19 +841,19 @@
 /// Generic font family names.
 class FontGeneric {
   /// Generic family sans-serif font (w/o serifs).
-  static const String sansSerif = "sans-serif";
+  static const String sansSerif = 'sans-serif';
 
   /// Generic family serif font.
-  static const String serif = "serif";
+  static const String serif = 'serif';
 
   /// Generic family fixed-width font.
-  static const monospace = "monospace";
+  static const monospace = 'monospace';
 
   /// Generic family emulate handwriting font.
-  static const String cursive = "cursive";
+  static const String cursive = 'cursive';
 
   /// Generic family decorative font.
-  static const String fantasy = "fantasy";
+  static const String fantasy = 'fantasy';
 }
 
 /// List of most common font families across different platforms.  Use the
@@ -846,55 +864,55 @@
 /// description of fonts available between platforms and browsers.
 class FontFamily {
   /// Sans-Serif font for Windows similar to Helvetica on Mac bold/italic.
-  static const String arial = "arial";
+  static const String arial = 'arial';
 
   /// Sans-Serif font for Windows less common already bolded.
-  static const String arialBlack = "arial black";
+  static const String arialBlack = 'arial black';
 
   /// Sans-Serif font for Mac since 1984, similar to Arial/Helvetica.
-  static const String geneva = "geneva";
+  static const String geneva = 'geneva';
 
   /// Sans-Serif font for Windows most readable sans-serif font for displays.
-  static const String verdana = "verdana";
+  static const String verdana = 'verdana';
 
   /// Sans-Serif font for Mac since 1984 is identical to Arial.
-  static const String helvetica = "helvetica";
+  static const String helvetica = 'helvetica';
 
   /// Serif font for Windows traditional font with “old-style” numerals.
-  static const String georgia = "georgia";
+  static const String georgia = 'georgia';
 
   /// Serif font for Mac. PCs may have the non-scalable Times use Times New
   /// Roman instead.  Times is more compact than Times New Roman.
-  static const String times = "times";
+  static const String times = 'times';
 
   /// Serif font for Windows most common serif font and default serif font for
   /// most browsers.
-  static const String timesNewRoman = "times new roman";
+  static const String timesNewRoman = 'times new roman';
 
   /// Monospace font for Mac/Windows most common. Scalable on Mac not scalable
   /// on Windows.
-  static const String courier = "courier";
+  static const String courier = 'courier';
 
   /// Monospace font for Mac/Windows scalable on both platforms.
-  static const String courierNew = "courier new";
+  static const String courierNew = 'courier new';
 
   /// Cursive font for Windows and default cursive font for IE.
-  static const String comicSansMs = "comic sans ms";
+  static const String comicSansMs = 'comic sans ms';
 
   /// Cursive font for Mac on Macs 2000 and newer.
-  static const String textile = "textile";
+  static const String textile = 'textile';
 
   /// Cursive font for older Macs.
-  static const String appleChancery = "apple chancery";
+  static const String appleChancery = 'apple chancery';
 
   /// Cursive font for some PCs.
-  static const String zaphChancery = "zaph chancery";
+  static const String zaphChancery = 'zaph chancery';
 
   /// Fantasy font on most Mac/Windows/Linux platforms.
-  static const String impact = "impact";
+  static const String impact = 'impact';
 
   /// Fantasy font for Windows.
-  static const String webdings = "webdings";
+  static const String webdings = 'webdings';
 }
 
 class LineHeight {
@@ -1017,12 +1035,13 @@
   ///
   /// The font-size and font-family values are required. If any of the other
   /// values are missing the default value is used.
+  @override
   String get cssExpression {
     // TODO(jimhug): include variant, style, other options
     if (weight != null) {
       // TODO(jacobr): is this really correct for lineHeight?
       if (lineHeight != null) {
-        return "$weight ${size}px/$lineHeightInPixels $_fontsAsString";
+        return '$weight ${size}px/$lineHeightInPixels $_fontsAsString';
       }
       return '$weight ${size}px $_fontsAsString';
     }
@@ -1056,11 +1075,13 @@
     }
   }
 
+  @override
   int get hashCode {
     // TODO(jimhug): Lot's of potential collisions here. List of fonts, etc.
     return size.toInt() % family[0].hashCode;
   }
 
+  @override
   bool operator ==(other) {
     if (other is! Font) return false;
     Font o = other;
@@ -1076,8 +1097,8 @@
   //              of fonts construction the font-family string.
   /// Return fonts as a comma seperated list sans the square brackets.
   String get _fontsAsString {
-    String fonts = family.toString();
-    return fonts.length > 2 ? fonts.substring(1, fonts.length - 1) : "";
+    var fonts = family.toString();
+    return fonts.length > 2 ? fonts.substring(1, fonts.length - 1) : '';
   }
 }
 
@@ -1126,11 +1147,11 @@
   /// them in with 0 instead.
   factory BoxEdge.nonNull(BoxEdge other) {
     if (other == null) return const BoxEdge(0, 0, 0, 0);
-    num left = other.left;
-    num top = other.top;
-    num right = other.right;
-    num bottom = other.bottom;
-    bool make = false;
+    var left = other.left;
+    var top = other.top;
+    var right = other.right;
+    var bottom = other.bottom;
+    var make = false;
     if (left == null) {
       make = true;
       left = 0;
@@ -1166,11 +1187,11 @@
 
   /// The total size of the horizontal edges. Equal to [left] + [right], where
   /// null is interpreted as 0px.
-  num get width => (left != null ? left : 0) + (right != null ? right : 0);
+  num get width => (left ?? 0) + (right ?? 0);
 
   /// The total size of the vertical edges. Equal to [top] + [bottom], where
   /// null is interpreted as 0px.
-  num get height => (top != null ? top : 0) + (bottom != null ? bottom : 0);
+  num get height => (top ?? 0) + (bottom ?? 0);
 }
 
-T _mergeVal<T>(T x, T y) => y != null ? y : x;
+T _mergeVal<T>(T x, T y) => y ?? x;
diff --git a/lib/src/token.dart b/lib/src/token.dart
index f29850f..7c5ef65 100644
--- a/lib/src/token.dart
+++ b/lib/src/token.dart
@@ -24,6 +24,7 @@
   Token(this.kind, this.span);
 
   /// Returns a pretty representation of this token for error messages.
+  @override
   String toString() {
     var kindText = TokenKind.kindToString(kind);
     var actualText = text.trim();
@@ -55,6 +56,7 @@
 /// See <http://dev.w3.org/csswg/css-syntax/#typedef-ident-token> and
 /// <http://dev.w3.org/csswg/css-syntax/#ident-token-diagram>.
 class IdentifierToken extends Token {
+  @override
   final String text;
 
   IdentifierToken(this.text, int kind, FileSpan span) : super(kind, span);
diff --git a/lib/src/token_kind.dart b/lib/src/token_kind.dart
index f9e6da0..b0b60eb 100644
--- a/lib/src/token_kind.dart
+++ b/lib/src/token_kind.dart
@@ -473,11 +473,11 @@
       String ident = entry['value'];
 
       if (length == ident.length) {
-        int idx = offset;
-        bool match = true;
-        for (int i = 0; i < ident.length; i++) {
-          int identChar = ident.codeUnitAt(i);
-          int char = text.codeUnitAt(idx++);
+        var idx = offset;
+        var match = true;
+        for (var i = 0; i < ident.length; i++) {
+          var identChar = ident.codeUnitAt(i);
+          var char = text.codeUnitAt(idx++);
           // Compare lowercase to lowercase then check if char is uppercase.
           match = match &&
               (char == identChar ||
@@ -571,10 +571,10 @@
   static String decimalToHex(int number, [int minDigits = 1]) {
     final String _HEX_DIGITS = '0123456789abcdef';
 
-    List<String> result = List<String>();
+    var result = <String>[];
 
-    int dividend = number >> 4;
-    int remain = number % 16;
+    var dividend = number >> 4;
+    var remain = number % 16;
     result.add(_HEX_DIGITS[remain]);
     while (dividend != 0) {
       remain = dividend % 16;
@@ -582,12 +582,12 @@
       result.add(_HEX_DIGITS[remain]);
     }
 
-    StringBuffer invertResult = StringBuffer();
-    int paddings = minDigits - result.length;
+    var invertResult = StringBuffer();
+    var paddings = minDigits - result.length;
     while (paddings-- > 0) {
       invertResult.write('0');
     }
-    for (int i = result.length - 1; i >= 0; i--) {
+    for (var i = result.length - 1; i >= 0; i--) {
       invertResult.write(result[i]);
     }
 
@@ -597,61 +597,61 @@
   static String kindToString(int kind) {
     switch (kind) {
       case TokenKind.UNUSED:
-        return "ERROR";
+        return 'ERROR';
       case TokenKind.END_OF_FILE:
-        return "end of file";
+        return 'end of file';
       case TokenKind.LPAREN:
-        return "(";
+        return '(';
       case TokenKind.RPAREN:
-        return ")";
+        return ')';
       case TokenKind.LBRACK:
-        return "[";
+        return '[';
       case TokenKind.RBRACK:
-        return "]";
+        return ']';
       case TokenKind.LBRACE:
-        return "{";
+        return '{';
       case TokenKind.RBRACE:
-        return "}";
+        return '}';
       case TokenKind.DOT:
-        return ".";
+        return '.';
       case TokenKind.SEMICOLON:
-        return ";";
+        return ';';
       case TokenKind.AT:
-        return "@";
+        return '@';
       case TokenKind.HASH:
-        return "#";
+        return '#';
       case TokenKind.PLUS:
-        return "+";
+        return '+';
       case TokenKind.GREATER:
-        return ">";
+        return '>';
       case TokenKind.TILDE:
-        return "~";
+        return '~';
       case TokenKind.ASTERISK:
-        return "*";
+        return '*';
       case TokenKind.NAMESPACE:
-        return "|";
+        return '|';
       case TokenKind.COLON:
-        return ":";
+        return ':';
       case TokenKind.PRIVATE_NAME:
-        return "_";
+        return '_';
       case TokenKind.COMMA:
-        return ",";
+        return ',';
       case TokenKind.SPACE:
-        return " ";
+        return ' ';
       case TokenKind.TAB:
-        return "\t";
+        return '\t';
       case TokenKind.NEWLINE:
-        return "\n";
+        return '\n';
       case TokenKind.RETURN:
-        return "\r";
+        return '\r';
       case TokenKind.PERCENT:
-        return "%";
+        return '%';
       case TokenKind.SINGLE_QUOTE:
         return "'";
       case TokenKind.DOUBLE_QUOTE:
-        return "\"";
+        return '\"';
       case TokenKind.SLASH:
-        return "/";
+        return '/';
       case TokenKind.EQUALS:
         return '=';
       case TokenKind.CARET:
@@ -667,7 +667,7 @@
       case TokenKind.BACKSLASH:
         return '\\';
       default:
-        throw "Unknown TOKEN";
+        throw 'Unknown TOKEN';
     }
   }
 
diff --git a/lib/src/tokenizer.dart b/lib/src/tokenizer.dart
index 724f5b7..de28cb3 100644
--- a/lib/src/tokenizer.dart
+++ b/lib/src/tokenizer.dart
@@ -18,6 +18,7 @@
   Tokenizer(SourceFile file, String text, bool skipWhitespace, [int index = 0])
       : super(file, text, skipWhitespace, index);
 
+  @override
   Token next({bool unicodeRange = false}) {
     // keep track of our starting position
     _startIndex = _index;
@@ -33,7 +34,7 @@
       case TokenChar.END_OF_FILE:
         return _finishToken(TokenKind.END_OF_FILE);
       case TokenChar.AT:
-        int peekCh = _peekChar();
+        var peekCh = _peekChar();
         if (TokenizerHelpers.isIdentifierStart(peekCh)) {
           var oldIndex = _index;
           var oldStartIndex = _startIndex;
@@ -43,7 +44,7 @@
           finishIdentifier();
 
           // Is it a directive?
-          int tokId = TokenKind.matchDirectives(
+          var tokId = TokenKind.matchDirectives(
               _text, _startIndex, _index - _startIndex);
           if (tokId == -1) {
             // No, is it a margin directive?
@@ -62,10 +63,10 @@
         }
         return _finishToken(TokenKind.AT);
       case TokenChar.DOT:
-        int start = _startIndex; // Start where the dot started.
+        var start = _startIndex; // Start where the dot started.
         if (maybeEatDigit()) {
           // looks like a number dot followed by digit(s).
-          Token number = finishNumber();
+          var number = finishNumber();
           if (number.kind == TokenKind.INTEGER) {
             // It's a number but it's preceeded by a dot, so make it a double.
             _startIndex = start;
@@ -175,7 +176,7 @@
         }
         return _finishToken(TokenKind.DOLLAR);
       case TokenChar.BANG:
-        Token tok = finishIdentifier();
+        var tok = finishIdentifier();
         return (tok == null) ? _finishToken(TokenKind.BANG) : tok;
       default:
         // TODO(jmesserly): this is used for IE8 detection; I'm not sure it's
@@ -241,13 +242,15 @@
         (_peekChar() == '-'.codeUnitAt(0));
   }
 
+  @override
   Token _errorToken([String message]) {
     return _finishToken(TokenKind.ERROR);
   }
 
+  @override
   int getIdentifierKind() {
     // Is the identifier a unit type?
-    int tokId = -1;
+    var tokId = -1;
 
     // Don't match units in selectors or selector expressions.
     if (!inSelectorExpression && !inSelector) {
@@ -268,10 +271,10 @@
     var chars = <int>[];
 
     // backup so we can start with the first character
-    int validateFrom = _index;
+    var validateFrom = _index;
     _index = _startIndex;
     while (_index < _text.length) {
-      int ch = _text.codeUnitAt(_index);
+      var ch = _text.codeUnitAt(_index);
 
       // If the previous character was "\" we need to escape. T
       // http://www.w3.org/TR/CSS21/syndata.html#characters
@@ -279,7 +282,7 @@
       // otherwise, include the character in the identifier and don't treat it
       // specially.
       if (ch == 92 /*\*/ && _inString) {
-        int startHex = ++_index;
+        var startHex = ++_index;
         eatHexDigits(startHex + 6);
         if (_index != startHex) {
           // Parse the hex digits and add that character.
@@ -319,6 +322,7 @@
     return IdentifierToken(text, getIdentifierKind(), span);
   }
 
+  @override
   Token finishNumber() {
     eatDigits();
 
@@ -395,7 +399,7 @@
 
   Token finishHtmlComment() {
     while (true) {
-      int ch = _nextChar();
+      var ch = _nextChar();
       if (ch == 0) {
         return _finishToken(TokenKind.INCOMPLETE_COMMENT);
       } else if (ch == TokenChar.MINUS) {
@@ -413,9 +417,10 @@
     }
   }
 
+  @override
   Token finishMultiLineComment() {
     while (true) {
-      int ch = _nextChar();
+      var ch = _nextChar();
       if (ch == 0) {
         return _finishToken(TokenKind.INCOMPLETE_COMMENT);
       } else if (ch == 42 /*'*'*/) {
diff --git a/lib/src/tokenizer_base.dart b/lib/src/tokenizer_base.dart
index a12471d..a648e62 100644
--- a/lib/src/tokenizer_base.dart
+++ b/lib/src/tokenizer_base.dart
@@ -25,6 +25,8 @@
   final SourceFile _file;
   final String _text;
 
+  // TODO: this seems like a bug – this field *is* used
+  // ignore: prefer_final_fields
   bool _inString;
 
   /// Changes tokenization when in a pseudo function expression.  If true then
@@ -139,9 +141,9 @@
   }
 
   Token finishMultiLineComment() {
-    int nesting = 1;
+    var nesting = 1;
     do {
-      int ch = _nextChar();
+      var ch = _nextChar();
       if (ch == 0) {
         return _errorToken();
       } else if (ch == TokenChar.ASTERISK) {
@@ -241,7 +243,7 @@
     }
     if (_peekChar() != 0 && TokenizerHelpers.isIdentifierStart(_peekChar())) {
       _nextChar();
-      return _errorToken("illegal character in number");
+      return _errorToken('illegal character in number');
     }
 
     return _finishToken(kind);
@@ -262,7 +264,7 @@
     var s;
     if (isMultiline) {
       // Skip initial newline in multiline strings
-      int start = _startIndex + 4;
+      var start = _startIndex + 4;
       if (_text[start] == '\n') start++;
       s = _text.substring(start, _index - 3);
     } else {
@@ -274,7 +276,7 @@
   Token finishMultilineString(int quote) {
     var buf = <int>[];
     while (true) {
-      int ch = _nextChar();
+      var ch = _nextChar();
       if (ch == 0) {
         return _errorToken();
       } else if (ch == quote) {
@@ -288,7 +290,7 @@
       } else if (ch == TokenChar.BACKSLASH) {
         var escapeVal = readEscapeSequence();
         if (escapeVal == -1) {
-          return _errorToken("invalid hex escape sequence");
+          return _errorToken('invalid hex escape sequence');
         } else {
           buf.add(escapeVal);
         }
@@ -305,7 +307,7 @@
         _maybeEatChar(TokenChar.NEWLINE);
         return finishMultilineString(quote);
       } else {
-        return _makeStringToken(List<int>(), false);
+        return _makeStringToken(<int>[], false);
       }
     }
     return finishStringBody(quote);
@@ -320,7 +322,7 @@
       }
     }
     while (true) {
-      int ch = _nextChar();
+      var ch = _nextChar();
       if (ch == quote) {
         return _makeRawStringToken(false);
       } else if (ch == 0) {
@@ -331,7 +333,7 @@
 
   Token finishMultilineRawString(int quote) {
     while (true) {
-      int ch = _nextChar();
+      var ch = _nextChar();
       if (ch == 0) {
         return _errorToken();
       } else if (ch == quote && _maybeEatChar(quote) && _maybeEatChar(quote)) {
@@ -341,9 +343,9 @@
   }
 
   Token finishStringBody(int quote) {
-    var buf = List<int>();
+    var buf = <int>[];
     while (true) {
-      int ch = _nextChar();
+      var ch = _nextChar();
       if (ch == quote) {
         return _makeStringToken(buf, false);
       } else if (ch == 0) {
@@ -351,7 +353,7 @@
       } else if (ch == TokenChar.BACKSLASH) {
         var escapeVal = readEscapeSequence();
         if (escapeVal == -1) {
-          return _errorToken("invalid hex escape sequence");
+          return _errorToken('invalid hex escape sequence');
         } else {
           buf.add(escapeVal);
         }
diff --git a/lib/src/tree.dart b/lib/src/tree.dart
index 9c2e385..4aca2c9 100644
--- a/lib/src/tree.dart
+++ b/lib/src/tree.dart
@@ -13,16 +13,21 @@
 
   Identifier(this.name, SourceSpan span) : super(span);
 
+  @override
   Identifier clone() => Identifier(name, span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitIdentifier(this);
 
+  @override
   String toString() => name;
 }
 
 class Wildcard extends TreeNode {
   Wildcard(SourceSpan span) : super(span);
+  @override
   Wildcard clone() => Wildcard(span);
+  @override
   visit(VisitorBase visitor) => visitor.visitWildcard(this);
 
   String get name => '*';
@@ -30,7 +35,9 @@
 
 class ThisOperator extends TreeNode {
   ThisOperator(SourceSpan span) : super(span);
+  @override
   ThisOperator clone() => ThisOperator(span);
+  @override
   visit(VisitorBase visitor) => visitor.visitThisOperator(this);
 
   String get name => '&';
@@ -38,7 +45,9 @@
 
 class Negation extends TreeNode {
   Negation(SourceSpan span) : super(span);
+  @override
   Negation clone() => Negation(span);
+  @override
   visit(VisitorBase visitor) => visitor.visitNegation(this);
 
   String get name => 'not';
@@ -53,10 +62,13 @@
   CalcTerm(var value, String t, this.expr, SourceSpan span)
       : super(value, t, span);
 
+  @override
   CalcTerm clone() => CalcTerm(value, text, expr.clone(), span);
+  @override
   visit(VisitorBase visitor) => visitor.visitCalcTerm(this);
 
-  String toString() => "$text($expr)";
+  @override
+  String toString() => '$text($expr)';
 }
 
 // /*  ....   */
@@ -64,14 +76,18 @@
   final String comment;
 
   CssComment(this.comment, SourceSpan span) : super(span);
+  @override
   CssComment clone() => CssComment(comment, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitCssComment(this);
 }
 
 // CDO/CDC (Comment Definition Open <!-- and Comment Definition Close -->).
 class CommentDefinition extends CssComment {
   CommentDefinition(String comment, SourceSpan span) : super(comment, span);
+  @override
   CommentDefinition clone() => CommentDefinition(comment, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitCommentDefinition(this);
 }
 
@@ -80,8 +96,10 @@
 
   SelectorGroup(this.selectors, SourceSpan span) : super(span);
 
+  @override
   SelectorGroup clone() => SelectorGroup(selectors, span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitSelectorGroup(this);
 }
 
@@ -94,6 +112,7 @@
 
   int get length => simpleSelectorSequences.length;
 
+  @override
   Selector clone() {
     var simpleSequences =
         simpleSelectorSequences.map((ss) => ss.clone()).toList();
@@ -101,6 +120,7 @@
     return Selector(simpleSequences, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitSelector(this);
 }
 
@@ -136,11 +156,14 @@
     }
   }
 
+  @override
   SimpleSelectorSequence clone() =>
       SimpleSelectorSequence(simpleSelector, span, combinator);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitSimpleSelectorSequence(this);
 
+  @override
   String toString() => simpleSelector.name;
 }
 
@@ -157,16 +180,20 @@
 
   bool get isThis => _name is ThisOperator;
 
+  @override
   visit(VisitorBase visitor) => visitor.visitSimpleSelector(this);
 }
 
 // element name
 class ElementSelector extends SimpleSelector {
   ElementSelector(name, SourceSpan span) : super(name, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitElementSelector(this);
 
+  @override
   ElementSelector clone() => ElementSelector(_name, span);
 
+  @override
   String toString() => name;
 }
 
@@ -184,11 +211,14 @@
 
   SimpleSelector get nameAsSimpleSelector => _name;
 
-  NamespaceSelector clone() => NamespaceSelector(_namespace, "", span);
+  @override
+  NamespaceSelector clone() => NamespaceSelector(_namespace, '', span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitNamespaceSelector(this);
 
-  String toString() => "$namespace|${nameAsSimpleSelector.name}";
+  @override
+  String toString() => '$namespace|${nameAsSimpleSelector.name}';
 }
 
 // [attr op value]
@@ -254,39 +284,51 @@
     }
   }
 
+  @override
   AttributeSelector clone() => AttributeSelector(_name, _op, _value, span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitAttributeSelector(this);
 
-  String toString() => "[$name${matchOperator()}${valueToString()}]";
+  @override
+  String toString() => '[$name${matchOperator()}${valueToString()}]';
 }
 
 // #id
 class IdSelector extends SimpleSelector {
   IdSelector(Identifier name, SourceSpan span) : super(name, span);
+  @override
   IdSelector clone() => IdSelector(_name, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitIdSelector(this);
 
-  String toString() => "#$_name";
+  @override
+  String toString() => '#$_name';
 }
 
 // .class
 class ClassSelector extends SimpleSelector {
   ClassSelector(Identifier name, SourceSpan span) : super(name, span);
+  @override
   ClassSelector clone() => ClassSelector(_name, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitClassSelector(this);
 
-  String toString() => ".$_name";
+  @override
+  String toString() => '.$_name';
 }
 
 // :pseudoClass
 class PseudoClassSelector extends SimpleSelector {
   PseudoClassSelector(Identifier name, SourceSpan span) : super(name, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitPseudoClassSelector(this);
 
+  @override
   PseudoClassSelector clone() => PseudoClassSelector(_name, span);
 
-  String toString() => ":$name";
+  @override
+  String toString() => ':$name';
 }
 
 // ::pseudoElement
@@ -297,10 +339,13 @@
   PseudoElementSelector(Identifier name, SourceSpan span,
       {this.isLegacy = false})
       : super(name, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitPseudoElementSelector(this);
 
+  @override
   PseudoElementSelector clone() => PseudoElementSelector(_name, span);
 
+  @override
   String toString() => "${isLegacy ? ':' : '::'}$name";
 }
 
@@ -311,6 +356,7 @@
   PseudoClassFunctionSelector(Identifier name, this._argument, SourceSpan span)
       : super(name, span);
 
+  @override
   PseudoClassFunctionSelector clone() =>
       PseudoClassFunctionSelector(_name, _argument, span);
 
@@ -318,6 +364,7 @@
   Selector get selector => _argument as Selector;
   SelectorExpression get expression => _argument as SelectorExpression;
 
+  @override
   visit(VisitorBase visitor) => visitor.visitPseudoClassFunctionSelector(this);
 }
 
@@ -329,9 +376,11 @@
       Identifier name, this.expression, SourceSpan span)
       : super(name, span);
 
+  @override
   PseudoElementFunctionSelector clone() =>
       PseudoElementFunctionSelector(_name, expression, span);
 
+  @override
   visit(VisitorBase visitor) =>
       visitor.visitPseudoElementFunctionSelector(this);
 }
@@ -341,10 +390,12 @@
 
   SelectorExpression(this.expressions, SourceSpan span) : super(span);
 
+  @override
   SelectorExpression clone() {
     return SelectorExpression(expressions.map((e) => e.clone()).toList(), span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitSelectorExpression(this);
 }
 
@@ -355,16 +406,20 @@
   NegationSelector(this.negationArg, SourceSpan span)
       : super(Negation(span), span);
 
+  @override
   NegationSelector clone() => NegationSelector(negationArg, span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitNegationSelector(this);
 }
 
 class NoOp extends TreeNode {
   NoOp() : super(null);
 
+  @override
   NoOp clone() => NoOp();
 
+  @override
   visit(VisitorBase visitor) => visitor.visitNoOp(this);
 }
 
@@ -381,17 +436,21 @@
   /// Selectors only in this tree.
   StyleSheet.selector(this.topLevels, SourceSpan span) : super(span);
 
+  @override
   StyleSheet clone() {
     var clonedTopLevels = topLevels.map((e) => e.clone()).toList();
     return StyleSheet(clonedTopLevels, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitStyleSheet(this);
 }
 
 class TopLevelProduction extends TreeNode {
   TopLevelProduction(SourceSpan span) : super(span);
+  @override
   TopLevelProduction clone() => TopLevelProduction(span);
+  @override
   visit(VisitorBase visitor) => visitor.visitTopLevelProduction(this);
 }
 
@@ -405,12 +464,14 @@
   SelectorGroup get selectorGroup => _selectorGroup;
   DeclarationGroup get declarationGroup => _declarationGroup;
 
+  @override
   RuleSet clone() {
     var cloneSelectorGroup = _selectorGroup.clone();
     var cloneDeclarationGroup = _declarationGroup.clone();
     return RuleSet(cloneSelectorGroup, cloneDeclarationGroup, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitRuleSet(this);
 }
 
@@ -420,7 +481,9 @@
   bool get isBuiltIn => true; // Known CSS directive?
   bool get isExtension => false; // SCSS extension?
 
+  @override
   Directive clone() => Directive(span);
+  @override
   visit(VisitorBase visitor) => visitor.visitDirective(this);
 }
 
@@ -431,6 +494,7 @@
   DocumentDirective(this.functions, this.groupRuleBody, SourceSpan span)
       : super(span);
 
+  @override
   DocumentDirective clone() {
     var clonedFunctions = <LiteralTerm>[];
     for (var function in functions) {
@@ -443,6 +507,7 @@
     return DocumentDirective(clonedFunctions, clonedGroupRuleBody, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitDocumentDirective(this);
 }
 
@@ -453,6 +518,7 @@
   SupportsDirective(this.condition, this.groupRuleBody, SourceSpan span)
       : super(span);
 
+  @override
   SupportsDirective clone() {
     var clonedCondition = condition.clone();
     var clonedGroupRuleBody = <TreeNode>[];
@@ -462,6 +528,7 @@
     return SupportsDirective(clonedCondition, clonedGroupRuleBody, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitSupportsDirective(this);
 }
 
@@ -481,9 +548,11 @@
       : condition = condition,
         super(span);
 
+  @override
   SupportsConditionInParens clone() =>
       SupportsConditionInParens(condition.clone(), span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitSupportsConditionInParens(this);
 }
 
@@ -492,8 +561,10 @@
 
   SupportsNegation(this.condition, SourceSpan span) : super(span);
 
+  @override
   SupportsNegation clone() => SupportsNegation(condition.clone(), span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitSupportsNegation(this);
 }
 
@@ -502,6 +573,7 @@
 
   SupportsConjunction(this.conditions, SourceSpan span) : super(span);
 
+  @override
   SupportsConjunction clone() {
     var clonedConditions = <SupportsConditionInParens>[];
     for (var condition in conditions) {
@@ -510,6 +582,7 @@
     return SupportsConjunction(clonedConditions, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitSupportsConjunction(this);
 }
 
@@ -518,6 +591,7 @@
 
   SupportsDisjunction(this.conditions, SourceSpan span) : super(span);
 
+  @override
   SupportsDisjunction clone() {
     var clonedConditions = <SupportsConditionInParens>[];
     for (var condition in conditions) {
@@ -526,6 +600,7 @@
     return SupportsDisjunction(clonedConditions, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitSupportsDisjunction(this);
 }
 
@@ -536,9 +611,11 @@
   ViewportDirective(this.name, this.declarations, SourceSpan span)
       : super(span);
 
+  @override
   ViewportDirective clone() =>
       ViewportDirective(name, declarations.clone(), span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitViewportDirective(this);
 }
 
@@ -552,6 +629,7 @@
   ImportDirective(this.import, this.mediaQueries, SourceSpan span)
       : super(span);
 
+  @override
   ImportDirective clone() {
     var cloneMediaQueries = <MediaQuery>[];
     for (var mediaQuery in mediaQueries) {
@@ -560,6 +638,7 @@
     return ImportDirective(import, cloneMediaQueries, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitImportDirective(this);
 }
 
@@ -577,11 +656,13 @@
 
   String get mediaFeature => _mediaFeature.name;
 
+  @override
   MediaExpression clone() {
     var clonedExprs = exprs.clone();
     return MediaExpression(andOperator, _mediaFeature, clonedExprs, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitMediaExpression(this);
 }
 
@@ -612,6 +693,7 @@
   String get unary =>
       TokenKind.idToValue(TokenKind.MEDIA_OPERATORS, _mediaUnary).toUpperCase();
 
+  @override
   MediaQuery clone() {
     var cloneExpressions = <MediaExpression>[];
     for (var expr in expressions) {
@@ -620,6 +702,7 @@
     return MediaQuery(_mediaUnary, _mediaType, cloneExpressions, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitMediaQuery(this);
 }
 
@@ -629,6 +712,7 @@
 
   MediaDirective(this.mediaQueries, this.rules, SourceSpan span) : super(span);
 
+  @override
   MediaDirective clone() {
     var cloneQueries = <MediaQuery>[];
     for (var mediaQuery in mediaQueries) {
@@ -641,6 +725,7 @@
     return MediaDirective(cloneQueries, cloneRules, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitMediaDirective(this);
 }
 
@@ -649,6 +734,7 @@
 
   HostDirective(this.rules, SourceSpan span) : super(span);
 
+  @override
   HostDirective clone() {
     var cloneRules = <TreeNode>[];
     for (var rule in rules) {
@@ -657,6 +743,7 @@
     return HostDirective(cloneRules, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitHostDirective(this);
 }
 
@@ -669,6 +756,7 @@
       this._ident, this._pseudoPage, this._declsMargin, SourceSpan span)
       : super(span);
 
+  @override
   PageDirective clone() {
     var cloneDeclsMargin = <DeclarationGroup>[];
     for (var declMargin in _declsMargin) {
@@ -677,6 +765,7 @@
     return PageDirective(_ident, _pseudoPage, cloneDeclsMargin, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitPageDirective(this);
 
   bool get hasIdent => _ident != null && _ident.isNotEmpty;
@@ -687,7 +776,9 @@
   final String charEncoding;
 
   CharsetDirective(this.charEncoding, SourceSpan span) : super(span);
+  @override
   CharsetDirective clone() => CharsetDirective(charEncoding, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitCharsetDirective(this);
 }
 
@@ -720,6 +811,7 @@
     return null;
   }
 
+  @override
   KeyFrameDirective clone() {
     var directive = KeyFrameDirective(_keyframeName, name.clone(), span);
     for (var block in _blocks) {
@@ -728,6 +820,7 @@
     return directive;
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitKeyFrameDirective(this);
 }
 
@@ -738,8 +831,10 @@
   KeyFrameBlock(this._blockSelectors, this._declarations, SourceSpan span)
       : super(span);
 
+  @override
   KeyFrameBlock clone() =>
       KeyFrameBlock(_blockSelectors.clone(), _declarations.clone(), span);
+  @override
   visit(VisitorBase visitor) => visitor.visitKeyFrameBlock(this);
 }
 
@@ -748,7 +843,9 @@
 
   FontFaceDirective(this._declarations, SourceSpan span) : super(span);
 
+  @override
   FontFaceDirective clone() => FontFaceDirective(_declarations.clone(), span);
+  @override
   visit(VisitorBase visitor) => visitor.visitFontFaceDirective(this);
 }
 
@@ -759,9 +856,12 @@
   StyletDirective(this.dartClassName, this.rules, SourceSpan span)
       : super(span);
 
+  @override
   bool get isBuiltIn => false;
+  @override
   bool get isExtension => true;
 
+  @override
   StyletDirective clone() {
     var cloneRules = <TreeNode>[];
     for (var rule in rules) {
@@ -770,6 +870,7 @@
     return StyletDirective(dartClassName, cloneRules, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitStyletDirective(this);
 }
 
@@ -782,8 +883,10 @@
 
   NamespaceDirective(this._prefix, this._uri, SourceSpan span) : super(span);
 
+  @override
   NamespaceDirective clone() => NamespaceDirective(_prefix, _uri, span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitNamespaceDirective(this);
 
   String get prefix => _prefix.isNotEmpty ? '$_prefix ' : '';
@@ -795,8 +898,10 @@
 
   VarDefinitionDirective(this.def, SourceSpan span) : super(span);
 
+  @override
   VarDefinitionDirective clone() => VarDefinitionDirective(def.clone(), span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitVarDefinitionDirective(this);
 }
 
@@ -808,6 +913,7 @@
   MixinDefinition(this.name, this.definedArgs, this.varArgs, SourceSpan span)
       : super(span);
 
+  @override
   MixinDefinition clone() {
     var cloneDefinedArgs = <TreeNode>[];
     for (var definedArg in definedArgs) {
@@ -816,6 +922,7 @@
     return MixinDefinition(name, cloneDefinedArgs, varArgs, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitMixinDefinition(this);
 }
 
@@ -827,6 +934,7 @@
       this.rulesets, SourceSpan span)
       : super(name, args, varArgs, span);
 
+  @override
   MixinRulesetDirective clone() {
     var clonedArgs = <VarDefinition>[];
     for (var arg in definedArgs) {
@@ -840,6 +948,7 @@
         name, clonedArgs, varArgs, clonedRulesets, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitMixinRulesetDirective(this);
 }
 
@@ -850,6 +959,7 @@
       this.declarations, SourceSpan span)
       : super(name, args, varArgs, span);
 
+  @override
   MixinDeclarationDirective clone() {
     var clonedArgs = <TreeNode>[];
     for (var arg in definedArgs) {
@@ -859,6 +969,7 @@
         name, clonedArgs, varArgs, declarations.clone(), span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitMixinDeclarationDirective(this);
 }
 
@@ -869,6 +980,7 @@
 
   IncludeDirective(this.name, this.args, SourceSpan span) : super(span);
 
+  @override
   IncludeDirective clone() {
     var cloneArgs = <List<Expression>>[];
     for (var arg in args) {
@@ -877,6 +989,7 @@
     return IncludeDirective(name, cloneArgs, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitIncludeDirective(this);
 }
 
@@ -884,6 +997,7 @@
 class ContentDirective extends Directive {
   ContentDirective(SourceSpan span) : super(span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitContentDirective(this);
 }
 
@@ -905,9 +1019,8 @@
   final bool isIE7;
 
   Declaration(this._property, this._expression, this.dartStyle, SourceSpan span,
-      {bool important = false, bool ie7 = false})
-      : this.important = important,
-        this.isIE7 = ie7,
+      {this.important = false, bool ie7 = false})
+      : isIE7 = ie7,
         super(span);
 
   String get property => isIE7 ? '*${_property.name}' : _property.name;
@@ -915,10 +1028,12 @@
 
   bool get hasDartStyle => dartStyle != null;
 
+  @override
   Declaration clone() =>
       Declaration(_property.clone(), _expression.clone(), dartStyle, span,
           important: important);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitDeclaration(this);
 }
 
@@ -936,9 +1051,11 @@
 
   String get definedName => _property.name;
 
+  @override
   VarDefinition clone() => VarDefinition(
       _property.clone(), expression != null ? expression.clone() : null, span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitVarDefinition(this);
 }
 
@@ -954,9 +1071,11 @@
   IncludeMixinAtDeclaration(this.include, SourceSpan span)
       : super(null, null, null, span);
 
+  @override
   IncludeMixinAtDeclaration clone() =>
       IncludeMixinAtDeclaration(include.clone(), span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitIncludeMixinAtDeclaration(this);
 }
 
@@ -966,11 +1085,13 @@
   ExtendDeclaration(this.selectors, SourceSpan span)
       : super(null, null, null, span);
 
+  @override
   ExtendDeclaration clone() {
     var newSelector = selectors.map((s) => s.clone()).toList();
     return ExtendDeclaration(newSelector, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitExtendDeclaration(this);
 }
 
@@ -980,11 +1101,13 @@
 
   DeclarationGroup(this.declarations, SourceSpan span) : super(span);
 
+  @override
   DeclarationGroup clone() {
     var clonedDecls = declarations.map((d) => d.clone()).toList();
     return DeclarationGroup(clonedDecls, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitDeclarationGroup(this);
 }
 
@@ -993,8 +1116,10 @@
 
   MarginGroup(this.margin_sym, List<TreeNode> decls, SourceSpan span)
       : super(decls, span);
+  @override
   MarginGroup clone() =>
       MarginGroup(margin_sym, super.clone().declarations, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitMarginGroup(this);
 }
 
@@ -1004,6 +1129,7 @@
 
   VarUsage(this.name, this.defaultValues, SourceSpan span) : super(span);
 
+  @override
   VarUsage clone() {
     var clonedValues = <Expression>[];
     for (var expr in defaultValues) {
@@ -1012,30 +1138,39 @@
     return VarUsage(name, clonedValues, span);
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitVarUsage(this);
 }
 
 class OperatorSlash extends Expression {
   OperatorSlash(SourceSpan span) : super(span);
+  @override
   OperatorSlash clone() => OperatorSlash(span);
+  @override
   visit(VisitorBase visitor) => visitor.visitOperatorSlash(this);
 }
 
 class OperatorComma extends Expression {
   OperatorComma(SourceSpan span) : super(span);
+  @override
   OperatorComma clone() => OperatorComma(span);
+  @override
   visit(VisitorBase visitor) => visitor.visitOperatorComma(this);
 }
 
 class OperatorPlus extends Expression {
   OperatorPlus(SourceSpan span) : super(span);
+  @override
   OperatorPlus clone() => OperatorPlus(span);
+  @override
   visit(VisitorBase visitor) => visitor.visitOperatorPlus(this);
 }
 
 class OperatorMinus extends Expression {
   OperatorMinus(SourceSpan span) : super(span);
+  @override
   OperatorMinus clone() => OperatorMinus(span);
+  @override
   visit(VisitorBase visitor) => visitor.visitOperatorMinus(this);
 }
 
@@ -1047,8 +1182,10 @@
 
   bool get hasSecond => second != null;
 
+  @override
   UnicodeRangeTerm clone() => UnicodeRangeTerm(first, second, span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitUnicodeRangeTerm(this);
 }
 
@@ -1061,14 +1198,18 @@
 
   LiteralTerm(this.value, this.text, SourceSpan span) : super(span);
 
+  @override
   LiteralTerm clone() => LiteralTerm(value, text, span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitLiteralTerm(this);
 }
 
 class NumberTerm extends LiteralTerm {
   NumberTerm(value, String t, SourceSpan span) : super(value, t, span);
+  @override
   NumberTerm clone() => NumberTerm(value, text, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitNumberTerm(this);
 }
 
@@ -1077,12 +1218,15 @@
 
   UnitTerm(value, String t, SourceSpan span, this.unit) : super(value, t, span);
 
+  @override
   UnitTerm clone() => UnitTerm(value, text, span, unit);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitUnitTerm(this);
 
   String unitToString() => TokenKind.unitToString(unit);
 
+  @override
   String toString() => '$text${unitToString()}';
 }
 
@@ -1097,25 +1241,33 @@
         this.unit == TokenKind.UNIT_LENGTH_PT ||
         this.unit == TokenKind.UNIT_LENGTH_PC);
   }
+  @override
   LengthTerm clone() => LengthTerm(value, text, span, unit);
+  @override
   visit(VisitorBase visitor) => visitor.visitLengthTerm(this);
 }
 
 class PercentageTerm extends LiteralTerm {
   PercentageTerm(value, String t, SourceSpan span) : super(value, t, span);
+  @override
   PercentageTerm clone() => PercentageTerm(value, text, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitPercentageTerm(this);
 }
 
 class EmTerm extends LiteralTerm {
   EmTerm(value, String t, SourceSpan span) : super(value, t, span);
+  @override
   EmTerm clone() => EmTerm(value, text, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitEmTerm(this);
 }
 
 class ExTerm extends LiteralTerm {
   ExTerm(value, String t, SourceSpan span) : super(value, t, span);
+  @override
   ExTerm clone() => ExTerm(value, text, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitExTerm(this);
 }
 
@@ -1129,7 +1281,9 @@
         this.unit == TokenKind.UNIT_ANGLE_TURN);
   }
 
+  @override
   AngleTerm clone() => AngleTerm(value, text, span, unit);
+  @override
   visit(VisitorBase visitor) => visitor.visitAngleTerm(this);
 }
 
@@ -1142,7 +1296,9 @@
         this.unit == TokenKind.UNIT_TIME_S);
   }
 
+  @override
   TimeTerm clone() => TimeTerm(value, text, span, unit);
+  @override
   visit(VisitorBase visitor) => visitor.visitTimeTerm(this);
 }
 
@@ -1153,21 +1309,27 @@
     assert(unit == TokenKind.UNIT_FREQ_HZ || unit == TokenKind.UNIT_FREQ_KHZ);
   }
 
+  @override
   FreqTerm clone() => FreqTerm(value, text, span, unit);
+  @override
   visit(VisitorBase visitor) => visitor.visitFreqTerm(this);
 }
 
 class FractionTerm extends LiteralTerm {
   FractionTerm(var value, String t, SourceSpan span) : super(value, t, span);
 
+  @override
   FractionTerm clone() => FractionTerm(value, text, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitFractionTerm(this);
 }
 
 class UriTerm extends LiteralTerm {
   UriTerm(String value, SourceSpan span) : super(value, value, span);
 
+  @override
   UriTerm clone() => UriTerm(value, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitUriTerm(this);
 }
 
@@ -1180,7 +1342,9 @@
         unit == TokenKind.UNIT_RESOLUTION_DPPX);
   }
 
+  @override
   ResolutionTerm clone() => ResolutionTerm(value, text, span, unit);
+  @override
   visit(VisitorBase visitor) => visitor.visitResolutionTerm(this);
 }
 
@@ -1191,7 +1355,9 @@
     assert(unit == TokenKind.UNIT_CH);
   }
 
+  @override
   ChTerm clone() => ChTerm(value, text, span, unit);
+  @override
   visit(VisitorBase visitor) => visitor.visitChTerm(this);
 }
 
@@ -1202,7 +1368,9 @@
     assert(unit == TokenKind.UNIT_REM);
   }
 
+  @override
   RemTerm clone() => RemTerm(value, text, span, unit);
+  @override
   visit(VisitorBase visitor) => visitor.visitRemTerm(this);
 }
 
@@ -1216,7 +1384,9 @@
         unit == TokenKind.UNIT_VIEWPORT_VMAX);
   }
 
+  @override
   ViewportTerm clone() => ViewportTerm(value, text, span, unit);
+  @override
   visit(VisitorBase visitor) => visitor.visitViewportTerm(this);
 }
 
@@ -1226,7 +1396,9 @@
 class HexColorTerm extends LiteralTerm {
   HexColorTerm(var value, String t, SourceSpan span) : super(value, t, span);
 
+  @override
   HexColorTerm clone() => HexColorTerm(value, text, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitHexColorTerm(this);
 }
 
@@ -1236,7 +1408,9 @@
   FunctionTerm(var value, String t, this._params, SourceSpan span)
       : super(value, t, span);
 
+  @override
   FunctionTerm clone() => FunctionTerm(value, text, _params.clone(), span);
+  @override
   visit(VisitorBase visitor) => visitor.visitFunctionTerm(this);
 }
 
@@ -1245,7 +1419,9 @@
 /// browsers.
 class IE8Term extends LiteralTerm {
   IE8Term(SourceSpan span) : super('\\9', '\\9', span);
+  @override
   IE8Term clone() => IE8Term(span);
+  @override
   visit(VisitorBase visitor) => visitor.visitIE8Term(this);
 }
 
@@ -1260,14 +1436,18 @@
     _terms.add(term);
   }
 
+  @override
   GroupTerm clone() => GroupTerm(span);
+  @override
   visit(VisitorBase visitor) => visitor.visitGroupTerm(this);
 }
 
 class ItemTerm extends NumberTerm {
   ItemTerm(dynamic value, String t, SourceSpan span) : super(value, t, span);
 
+  @override
   ItemTerm clone() => ItemTerm(value, text, span);
+  @override
   visit(VisitorBase visitor) => visitor.visitItemTerm(this);
 }
 
@@ -1280,6 +1460,7 @@
     expressions.add(expression);
   }
 
+  @override
   Expressions clone() {
     var clonedExprs = Expressions(span);
     for (var expr in expressions) {
@@ -1288,6 +1469,7 @@
     return clonedExprs;
   }
 
+  @override
   visit(VisitorBase visitor) => visitor.visitExpressions(this);
 }
 
@@ -1298,7 +1480,9 @@
 
   BinaryExpression(this.op, this.x, this.y, SourceSpan span) : super(span);
 
+  @override
   BinaryExpression clone() => BinaryExpression(op, x.clone(), y.clone(), span);
+  @override
   visit(VisitorBase visitor) => visitor.visitBinaryExpression(this);
 }
 
@@ -1308,7 +1492,9 @@
 
   UnaryExpression(this.op, this.self, SourceSpan span) : super(span);
 
+  @override
   UnaryExpression clone() => UnaryExpression(op, self.clone(), span);
+  @override
   visit(VisitorBase visitor) => visitor.visitUnaryExpression(this);
 }
 
@@ -1340,8 +1526,9 @@
   bool get isWidth => _styleType == widthStyle;
   bool get isBoxExpression => isMargin || isBorder || isPadding;
 
-  bool isSame(DartStyleExpression other) => this._styleType == other._styleType;
+  bool isSame(DartStyleExpression other) => _styleType == other._styleType;
 
+  @override
   visit(VisitorBase visitor) => visitor.visitDartStyleExpression(this);
 }
 
@@ -1367,8 +1554,9 @@
             lineHeight: lineHeight),
         super(DartStyleExpression.fontStyle, span);
 
+  @override
   FontExpression merged(DartStyleExpression newFontExpr) {
-    if (newFontExpr is FontExpression && this.isFont && newFontExpr.isFont) {
+    if (newFontExpr is FontExpression && isFont && newFontExpr.isFont) {
       return FontExpression.merge(this, newFontExpr);
     }
     return null;
@@ -1383,6 +1571,7 @@
       : font = Font.merge(x.font, y.font),
         super(DartStyleExpression.fontStyle, span);
 
+  @override
   FontExpression clone() => FontExpression(span,
       size: font.size,
       family: font.family,
@@ -1391,6 +1580,7 @@
       variant: font.variant,
       lineHeight: font.lineHeight);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitFontExpression(this);
 }
 
@@ -1400,16 +1590,17 @@
   BoxExpression(int styleType, SourceSpan span, this.box)
       : super(styleType, span);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitBoxExpression(this);
 
   String get formattedBoxEdge {
     if (box.top == box.left && box.top == box.bottom && box.top == box.right) {
       return '.uniform(${box.top})';
     } else {
-      var left = box.left == null ? 0 : box.left;
-      var top = box.top == null ? 0 : box.top;
-      var right = box.right == null ? 0 : box.right;
-      var bottom = box.bottom == null ? 0 : box.bottom;
+      var left = box.left ?? 0;
+      var top = box.top ?? 0;
+      var right = box.right ?? 0;
+      var bottom = box.bottom ?? 0;
       return '.clockwiseFromTop($top,$right,$bottom,$left)';
     }
   }
@@ -1425,9 +1616,10 @@
   MarginExpression.boxEdge(SourceSpan span, BoxEdge box)
       : super(DartStyleExpression.marginStyle, span, box);
 
+  @override
   merged(DartStyleExpression newMarginExpr) {
     if (newMarginExpr is MarginExpression &&
-        this.isMargin &&
+        isMargin &&
         newMarginExpr.isMargin) {
       return MarginExpression.merge(this, newMarginExpr);
     }
@@ -1444,9 +1636,11 @@
       MarginExpression x, MarginExpression y, SourceSpan span)
       : super(x._styleType, span, BoxEdge.merge(x.box, y.box));
 
+  @override
   MarginExpression clone() => MarginExpression(span,
       top: box.top, right: box.right, bottom: box.bottom, left: box.left);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitMarginExpression(this);
 }
 
@@ -1459,9 +1653,10 @@
   BorderExpression.boxEdge(SourceSpan span, BoxEdge box)
       : super(DartStyleExpression.borderStyle, span, box);
 
+  @override
   merged(DartStyleExpression newBorderExpr) {
     if (newBorderExpr is BorderExpression &&
-        this.isBorder &&
+        isBorder &&
         newBorderExpr.isBorder) {
       return BorderExpression.merge(this, newBorderExpr);
     }
@@ -1479,9 +1674,11 @@
       : super(
             DartStyleExpression.borderStyle, span, BoxEdge.merge(x.box, y.box));
 
+  @override
   BorderExpression clone() => BorderExpression(span,
       top: box.top, right: box.right, bottom: box.bottom, left: box.left);
 
+  @override
   visit(VisitorBase visitor) => visitor.visitBorderExpression(this);
 }
 
@@ -1491,9 +1688,10 @@
   HeightExpression(SourceSpan span, this.height)
       : super(DartStyleExpression.heightStyle, span);
 
+  @override
   merged(DartStyleExpression newHeightExpr) {
     if (newHeightExpr is DartStyleExpression &&
-        this.isHeight &&
+        isHeight &&
         newHeightExpr.isHeight) {
       return newHeightExpr;
     }
@@ -1501,7 +1699,9 @@
     return null;
   }
 
+  @override
   HeightExpression clone() => HeightExpression(span, height);
+  @override
   visit(VisitorBase visitor) => visitor.visitHeightExpression(this);
 }
 
@@ -1511,17 +1711,18 @@
   WidthExpression(SourceSpan span, this.width)
       : super(DartStyleExpression.widthStyle, span);
 
+  @override
   merged(DartStyleExpression newWidthExpr) {
-    if (newWidthExpr is WidthExpression &&
-        this.isWidth &&
-        newWidthExpr.isWidth) {
+    if (newWidthExpr is WidthExpression && isWidth && newWidthExpr.isWidth) {
       return newWidthExpr;
     }
 
     return null;
   }
 
+  @override
   WidthExpression clone() => WidthExpression(span, width);
+  @override
   visit(VisitorBase visitor) => visitor.visitWidthExpression(this);
 }
 
@@ -1534,9 +1735,10 @@
   PaddingExpression.boxEdge(SourceSpan span, BoxEdge box)
       : super(DartStyleExpression.paddingStyle, span, box);
 
+  @override
   merged(DartStyleExpression newPaddingExpr) {
     if (newPaddingExpr is PaddingExpression &&
-        this.isPadding &&
+        isPadding &&
         newPaddingExpr.isPadding) {
       return PaddingExpression.merge(this, newPaddingExpr);
     }
@@ -1554,7 +1756,9 @@
       : super(DartStyleExpression.paddingStyle, span,
             BoxEdge.merge(x.box, y.box));
 
+  @override
   PaddingExpression clone() => PaddingExpression(span,
       top: box.top, right: box.right, bottom: box.bottom, left: box.left);
+  @override
   visit(VisitorBase visitor) => visitor.visitPaddingExpression(this);
 }
diff --git a/lib/src/tree_base.dart b/lib/src/tree_base.dart
index 5011f3d..ef157cd 100644
--- a/lib/src/tree_base.dart
+++ b/lib/src/tree_base.dart
@@ -20,7 +20,7 @@
   String toDebugString() {
     var to = TreeOutput();
     var tp = _TreePrinter(to, true);
-    this.visit(tp);
+    visit(tp);
     return to.buf.toString();
   }
 }
@@ -37,7 +37,7 @@
   VisitorBase printer;
 
   void write(String s) {
-    for (int i = 0; i < depth; i++) {
+    for (var i = 0; i < depth; i++) {
       buf.write(' ');
     }
     buf.write(s);
@@ -98,5 +98,6 @@
     }
   }
 
+  @override
   String toString() => buf.toString();
 }
diff --git a/lib/src/tree_printer.dart b/lib/src/tree_printer.dart
index d8d4962..8aa5852 100644
--- a/lib/src/tree_printer.dart
+++ b/lib/src/tree_printer.dart
@@ -21,6 +21,7 @@
     output.printer = this;
   }
 
+  @override
   void visitTree(StyleSheet tree) => visitStylesheet(tree);
 
   void heading(String heading, node) {
@@ -38,14 +39,17 @@
     output.depth--;
   }
 
+  @override
   void visitTopLevelProduction(TopLevelProduction node) {
     heading('TopLevelProduction', node);
   }
 
+  @override
   void visitDirective(Directive node) {
     heading('Directive', node);
   }
 
+  @override
   void visitCalcTerm(CalcTerm node) {
     heading('CalcTerm', node);
     output.depth++;
@@ -53,6 +57,7 @@
     output.depth--;
   }
 
+  @override
   void visitCssComment(CssComment node) {
     heading('Comment', node);
     output.depth++;
@@ -60,6 +65,7 @@
     output.depth--;
   }
 
+  @override
   void visitCommentDefinition(CommentDefinition node) {
     heading('CommentDefinition (CDO/CDC)', node);
     output.depth++;
@@ -67,6 +73,7 @@
     output.depth--;
   }
 
+  @override
   void visitMediaExpression(MediaExpression node) {
     heading('MediaExpression', node);
     output.writeValue('feature', node.mediaFeature);
@@ -81,6 +88,7 @@
     output.writeNodeList('media expressions', query.expressions);
   }
 
+  @override
   void visitMediaDirective(MediaDirective node) {
     heading('MediaDirective', node);
     output.depth++;
@@ -90,6 +98,7 @@
     output.depth--;
   }
 
+  @override
   void visitDocumentDirective(DocumentDirective node) {
     heading('DocumentDirective', node);
     output.depth++;
@@ -98,6 +107,7 @@
     output.depth--;
   }
 
+  @override
   void visitSupportsDirective(SupportsDirective node) {
     heading('SupportsDirective', node);
     output.depth++;
@@ -106,6 +116,7 @@
     output.depth--;
   }
 
+  @override
   void visitSupportsConditionInParens(SupportsConditionInParens node) {
     heading('SupportsConditionInParens', node);
     output.depth++;
@@ -113,6 +124,7 @@
     output.depth--;
   }
 
+  @override
   void visitSupportsNegation(SupportsNegation node) {
     heading('SupportsNegation', node);
     output.depth++;
@@ -120,6 +132,7 @@
     output.depth--;
   }
 
+  @override
   void visitSupportsConjunction(SupportsConjunction node) {
     heading('SupportsConjunction', node);
     output.depth++;
@@ -127,6 +140,7 @@
     output.depth--;
   }
 
+  @override
   void visitSupportsDisjunction(SupportsDisjunction node) {
     heading('SupportsDisjunction', node);
     output.depth++;
@@ -134,6 +148,7 @@
     output.depth--;
   }
 
+  @override
   void visitViewportDirective(ViewportDirective node) {
     heading('ViewportDirective', node);
     output.depth++;
@@ -141,6 +156,7 @@
     output.depth--;
   }
 
+  @override
   void visitPageDirective(PageDirective node) {
     heading('PageDirective', node);
     output.depth++;
@@ -149,11 +165,13 @@
     output.depth;
   }
 
+  @override
   void visitCharsetDirective(CharsetDirective node) {
     heading('Charset Directive', node);
     output.writeValue('charset encoding', node.charEncoding);
   }
 
+  @override
   void visitImportDirective(ImportDirective node) {
     heading('ImportDirective', node);
     output.depth++;
@@ -163,10 +181,12 @@
     output.depth--;
   }
 
+  @override
   void visitContentDirective(ContentDirective node) {
-    print("ContentDirective not implemented");
+    print('ContentDirective not implemented');
   }
 
+  @override
   void visitKeyFrameDirective(KeyFrameDirective node) {
     heading('KeyFrameDirective', node);
     output.depth++;
@@ -176,6 +196,7 @@
     output.depth--;
   }
 
+  @override
   void visitKeyFrameBlock(KeyFrameBlock node) {
     heading('KeyFrameBlock', node);
     output.depth++;
@@ -183,10 +204,12 @@
     output.depth--;
   }
 
+  @override
   void visitFontFaceDirective(FontFaceDirective node) {
     // TODO(terry): To Be Implemented
   }
 
+  @override
   void visitStyletDirective(StyletDirective node) {
     heading('StyletDirective', node);
     output.writeValue('dartClassName', node.dartClassName);
@@ -195,6 +218,7 @@
     output.depth--;
   }
 
+  @override
   void visitNamespaceDirective(NamespaceDirective node) {
     heading('NamespaceDirective', node);
     output.depth++;
@@ -203,6 +227,7 @@
     output.depth--;
   }
 
+  @override
   void visitVarDefinitionDirective(VarDefinitionDirective node) {
     heading('Less variable definition', node);
     output.depth++;
@@ -210,6 +235,7 @@
     output.depth--;
   }
 
+  @override
   void visitMixinRulesetDirective(MixinRulesetDirective node) {
     heading('Mixin top-level ${node.name}', node);
     output.writeNodeList('parameters', node.definedArgs);
@@ -218,6 +244,7 @@
     output.depth--;
   }
 
+  @override
   void visitMixinDeclarationDirective(MixinDeclarationDirective node) {
     heading('Mixin declaration ${node.name}', node);
     output.writeNodeList('parameters', node.definedArgs);
@@ -228,12 +255,14 @@
 
   /// Added optional newLine for handling @include at top-level vs/ inside of
   /// a declaration group.
+  @override
   void visitIncludeDirective(IncludeDirective node) {
     heading('IncludeDirective ${node.name}', node);
     var flattened = node.args.expand((e) => e).toList();
     output.writeNodeList('parameters', flattened);
   }
 
+  @override
   void visitIncludeMixinAtDeclaration(IncludeMixinAtDeclaration node) {
     heading('IncludeMixinAtDeclaration ${node.include.name}', node);
     output.depth++;
@@ -241,6 +270,7 @@
     output.depth--;
   }
 
+  @override
   void visitExtendDeclaration(ExtendDeclaration node) {
     heading('ExtendDeclaration', node);
     output.depth++;
@@ -248,6 +278,7 @@
     output.depth--;
   }
 
+  @override
   void visitRuleSet(RuleSet node) {
     heading('Ruleset', node);
     output.depth++;
@@ -255,6 +286,7 @@
     output.depth--;
   }
 
+  @override
   void visitDeclarationGroup(DeclarationGroup node) {
     heading('DeclarationGroup', node);
     output.depth++;
@@ -262,6 +294,7 @@
     output.depth--;
   }
 
+  @override
   void visitMarginGroup(MarginGroup node) {
     heading('MarginGroup', node);
     output.depth++;
@@ -270,6 +303,7 @@
     output.depth--;
   }
 
+  @override
   void visitDeclaration(Declaration node) {
     heading('Declaration', node);
     output.depth++;
@@ -283,6 +317,7 @@
     output.depth--;
   }
 
+  @override
   void visitVarDefinition(VarDefinition node) {
     heading('Var', node);
     output.depth++;
@@ -292,6 +327,7 @@
     output.depth--;
   }
 
+  @override
   void visitSelectorGroup(SelectorGroup node) {
     heading('Selector Group', node);
     output.depth++;
@@ -299,6 +335,7 @@
     output.depth--;
   }
 
+  @override
   void visitSelector(Selector node) {
     heading('Selector', node);
     output.depth++;
@@ -307,21 +344,22 @@
     output.depth--;
   }
 
+  @override
   void visitSimpleSelectorSequence(SimpleSelectorSequence node) {
     heading('SimpleSelectorSequence', node);
     output.depth++;
     if (node.isCombinatorNone) {
-      output.writeValue('combinator', "NONE");
+      output.writeValue('combinator', 'NONE');
     } else if (node.isCombinatorDescendant) {
-      output.writeValue('combinator', "descendant");
+      output.writeValue('combinator', 'descendant');
     } else if (node.isCombinatorPlus) {
-      output.writeValue('combinator', "+");
+      output.writeValue('combinator', '+');
     } else if (node.isCombinatorGreater) {
-      output.writeValue('combinator', ">");
+      output.writeValue('combinator', '>');
     } else if (node.isCombinatorTilde) {
-      output.writeValue('combinator', "~");
+      output.writeValue('combinator', '~');
     } else {
-      output.writeValue('combinator', "ERROR UNKNOWN");
+      output.writeValue('combinator', 'ERROR UNKNOWN');
     }
 
     super.visitSimpleSelectorSequence(node);
@@ -329,6 +367,7 @@
     output.depth--;
   }
 
+  @override
   void visitNamespaceSelector(NamespaceSelector node) {
     heading('Namespace Selector', node);
     output.depth++;
@@ -339,6 +378,7 @@
     output.depth--;
   }
 
+  @override
   void visitElementSelector(ElementSelector node) {
     heading('Element Selector', node);
     output.depth++;
@@ -346,16 +386,18 @@
     output.depth--;
   }
 
+  @override
   void visitAttributeSelector(AttributeSelector node) {
     heading('AttributeSelector', node);
     output.depth++;
     super.visitAttributeSelector(node);
-    String tokenStr = node.matchOperatorAsTokenString();
+    var tokenStr = node.matchOperatorAsTokenString();
     output.writeValue('operator', '${node.matchOperator()} (${tokenStr})');
     output.writeValue('value', node.valueToString());
     output.depth--;
   }
 
+  @override
   void visitIdSelector(IdSelector node) {
     heading('Id Selector', node);
     output.depth++;
@@ -363,6 +405,7 @@
     output.depth--;
   }
 
+  @override
   void visitClassSelector(ClassSelector node) {
     heading('Class Selector', node);
     output.depth++;
@@ -370,6 +413,7 @@
     output.depth--;
   }
 
+  @override
   void visitPseudoClassSelector(PseudoClassSelector node) {
     heading('Pseudo Class Selector', node);
     output.depth++;
@@ -377,6 +421,7 @@
     output.depth--;
   }
 
+  @override
   void visitPseudoElementSelector(PseudoElementSelector node) {
     heading('Pseudo Element Selector', node);
     output.depth++;
@@ -384,6 +429,7 @@
     output.depth--;
   }
 
+  @override
   void visitPseudoClassFunctionSelector(PseudoClassFunctionSelector node) {
     heading('Pseudo Class Function Selector', node);
     output.depth++;
@@ -392,6 +438,7 @@
     output.depth--;
   }
 
+  @override
   void visitPseudoElementFunctionSelector(PseudoElementFunctionSelector node) {
     heading('Pseudo Element Function Selector', node);
     output.depth++;
@@ -400,6 +447,7 @@
     output.depth--;
   }
 
+  @override
   void visitSelectorExpression(SelectorExpression node) {
     heading('Selector Expression', node);
     output.depth++;
@@ -407,6 +455,7 @@
     output.depth--;
   }
 
+  @override
   void visitNegationSelector(NegationSelector node) {
     super.visitNegationSelector(node);
     output.depth++;
@@ -415,6 +464,7 @@
     output.depth--;
   }
 
+  @override
   void visitUnicodeRangeTerm(UnicodeRangeTerm node) {
     heading('UnicodeRangeTerm', node);
     output.depth++;
@@ -423,6 +473,7 @@
     output.depth--;
   }
 
+  @override
   void visitLiteralTerm(LiteralTerm node) {
     heading('LiteralTerm', node);
     output.depth++;
@@ -430,6 +481,7 @@
     output.depth--;
   }
 
+  @override
   void visitHexColorTerm(HexColorTerm node) {
     heading('HexColorTerm', node);
     output.depth++;
@@ -438,6 +490,7 @@
     output.depth--;
   }
 
+  @override
   void visitNumberTerm(NumberTerm node) {
     heading('NumberTerm', node);
     output.depth++;
@@ -445,6 +498,7 @@
     output.depth--;
   }
 
+  @override
   void visitUnitTerm(UnitTerm node) {
     output.depth++;
     output.writeValue('value', node.text);
@@ -452,11 +506,13 @@
     output.depth--;
   }
 
+  @override
   void visitLengthTerm(LengthTerm node) {
     heading('LengthTerm', node);
     super.visitLengthTerm(node);
   }
 
+  @override
   void visitPercentageTerm(PercentageTerm node) {
     heading('PercentageTerm', node);
     output.depth++;
@@ -464,6 +520,7 @@
     output.depth--;
   }
 
+  @override
   void visitEmTerm(EmTerm node) {
     heading('EmTerm', node);
     output.depth++;
@@ -471,6 +528,7 @@
     output.depth--;
   }
 
+  @override
   void visitExTerm(ExTerm node) {
     heading('ExTerm', node);
     output.depth++;
@@ -478,21 +536,25 @@
     output.depth--;
   }
 
+  @override
   void visitAngleTerm(AngleTerm node) {
     heading('AngleTerm', node);
     super.visitAngleTerm(node);
   }
 
+  @override
   void visitTimeTerm(TimeTerm node) {
     heading('TimeTerm', node);
     super.visitTimeTerm(node);
   }
 
+  @override
   void visitFreqTerm(FreqTerm node) {
     heading('FreqTerm', node);
     super.visitFreqTerm(node);
   }
 
+  @override
   void visitFractionTerm(FractionTerm node) {
     heading('FractionTerm', node);
     output.depth++;
@@ -500,6 +562,7 @@
     output.depth--;
   }
 
+  @override
   void visitUriTerm(UriTerm node) {
     heading('UriTerm', node);
     output.depth++;
@@ -507,6 +570,7 @@
     output.depth--;
   }
 
+  @override
   void visitFunctionTerm(FunctionTerm node) {
     heading('FunctionTerm', node);
     output.depth++;
@@ -514,6 +578,7 @@
     output.depth--;
   }
 
+  @override
   void visitGroupTerm(GroupTerm node) {
     heading('GroupTerm', node);
     output.depth++;
@@ -521,32 +586,39 @@
     output.depth--;
   }
 
+  @override
   void visitItemTerm(ItemTerm node) {
     heading('ItemTerm', node);
     super.visitItemTerm(node);
   }
 
+  @override
   void visitIE8Term(IE8Term node) {
     heading('IE8Term', node);
     visitLiteralTerm(node);
   }
 
+  @override
   void visitOperatorSlash(OperatorSlash node) {
     heading('OperatorSlash', node);
   }
 
+  @override
   void visitOperatorComma(OperatorComma node) {
     heading('OperatorComma', node);
   }
 
+  @override
   void visitOperatorPlus(OperatorPlus node) {
     heading('OperatorPlus', node);
   }
 
+  @override
   void visitOperatorMinus(OperatorMinus node) {
     heading('OperatorMinus', node);
   }
 
+  @override
   void visitVarUsage(VarUsage node) {
     heading('Var', node);
     output.depth++;
@@ -555,6 +627,7 @@
     output.depth--;
   }
 
+  @override
   void visitExpressions(Expressions node) {
     heading('Expressions', node);
     output.depth++;
@@ -562,52 +635,64 @@
     output.depth--;
   }
 
+  @override
   void visitBinaryExpression(BinaryExpression node) {
     heading('BinaryExpression', node);
     // TODO(terry): TBD
   }
 
+  @override
   void visitUnaryExpression(UnaryExpression node) {
     heading('UnaryExpression', node);
     // TODO(terry): TBD
   }
 
+  @override
   void visitIdentifier(Identifier node) {
     heading('Identifier(${output.toValue(node.name)})', node);
   }
 
+  @override
   void visitWildcard(Wildcard node) {
     heading('Wildcard(*)', node);
   }
 
+  @override
   void visitDartStyleExpression(DartStyleExpression node) {
     heading('DartStyleExpression', node);
   }
 
+  @override
   void visitFontExpression(FontExpression node) {
     heading('Dart Style FontExpression', node);
   }
 
+  @override
   void visitBoxExpression(BoxExpression node) {
     heading('Dart Style BoxExpression', node);
   }
 
+  @override
   void visitMarginExpression(MarginExpression node) {
     heading('Dart Style MarginExpression', node);
   }
 
+  @override
   void visitBorderExpression(BorderExpression node) {
     heading('Dart Style BorderExpression', node);
   }
 
+  @override
   void visitHeightExpression(HeightExpression node) {
     heading('Dart Style HeightExpression', node);
   }
 
+  @override
   void visitPaddingExpression(PaddingExpression node) {
     heading('Dart Style PaddingExpression', node);
   }
 
+  @override
   void visitWidthExpression(WidthExpression node) {
     heading('Dart Style WidthExpression', node);
   }
diff --git a/lib/src/validate.dart b/lib/src/validate.dart
index e6d66f2..fe18e05 100644
--- a/lib/src/validate.dart
+++ b/lib/src/validate.dart
@@ -19,7 +19,7 @@
     if (selector.isCombinatorDescendant ||
         (selector.isCombinatorNone && matches == 0)) {
       if (matches < 0) {
-        String tooMany = selector.simpleSelector.toString();
+        var tooMany = selector.simpleSelector.toString();
         throw CssSelectorException(
             'Can not mix Id selector with class selector(s). Id '
             'selector must be singleton too many starting at $tooMany');
@@ -27,7 +27,7 @@
 
       return matches + 1;
     } else {
-      String error = selector.toString();
+      var error = selector.toString();
       throw CssSelectorException(
           'Selectors can not have combinators (>, +, or ~) before $error');
     }
@@ -38,11 +38,11 @@
       // Perfect just one element id returns matches of -1.
       return -1;
     } else if (selector.isCombinatorDescendant) {
-      String tooMany = selector.simpleSelector.toString();
+      var tooMany = selector.simpleSelector.toString();
       throw CssSelectorException(
           'Use of Id selector must be singleton starting at $tooMany');
     } else {
-      String error = selector.simpleSelector.toString();
+      var error = selector.simpleSelector.toString();
       throw CssSelectorException(
           'Selectors can not have combinators (>, +, or ~) before $error');
     }
@@ -51,8 +51,8 @@
   // Validate the @{css expression} only .class and #elementId are valid inside
   // of @{...}.
   static template(List<Selector> selectors) {
-    bool found = false; // signal if a selector is matched.
-    int matches = 0; // < 0 IdSelectors, > 0 ClassSelector
+    var found = false; // signal if a selector is matched.
+    var matches = 0; // < 0 IdSelectors, > 0 ClassSelector
 
     // At most one selector group (any number of simple selector sequences).
     assert(selectors.length <= 1);
@@ -102,19 +102,19 @@
             found = true; // #_id are always okay
           }
         } else {
-          String badSelector = simpleSelector.toString();
+          var badSelector = simpleSelector.toString();
           throw CssSelectorException('Invalid template selector $badSelector');
         }
 
         if (!found) {
-          String unknownName = simpleSelector.toString();
+          var unknownName = simpleSelector.toString();
           throw CssSelectorException('Unknown selector name $unknownName');
         }
       }
     }
 
     // Every selector must match.
-    Selector selector = selectors[0];
+    var selector = selectors[0];
     assert((matches >= 0 ? matches : -matches) ==
         selector.simpleSelectorSequences.length);
   }
diff --git a/lib/visitor.dart b/lib/visitor.dart
index e21cff7..2ccd8ff 100644
--- a/lib/visitor.dart
+++ b/lib/visitor.dart
@@ -128,74 +128,93 @@
 
   visitTree(StyleSheet tree) => visitStyleSheet(tree);
 
+  @override
   visitStyleSheet(StyleSheet ss) {
     _visitNodeList(ss.topLevels);
   }
 
+  @override
   visitNoOp(NoOp node) {}
 
+  @override
   visitTopLevelProduction(TopLevelProduction node) {}
 
+  @override
   visitDirective(Directive node) {}
 
+  @override
   visitCalcTerm(CalcTerm node) {
     visitLiteralTerm(node);
     visitLiteralTerm(node.expr);
   }
 
+  @override
   visitCssComment(CssComment node) {}
 
+  @override
   visitCommentDefinition(CommentDefinition node) {}
 
+  @override
   visitMediaExpression(MediaExpression node) {
     visitExpressions(node.exprs);
   }
 
+  @override
   visitMediaQuery(MediaQuery node) {
     for (var mediaExpr in node.expressions) {
       visitMediaExpression(mediaExpr);
     }
   }
 
+  @override
   visitDocumentDirective(DocumentDirective node) {
     _visitNodeList(node.functions);
     _visitNodeList(node.groupRuleBody);
   }
 
+  @override
   visitSupportsDirective(SupportsDirective node) {
     node.condition.visit(this);
     _visitNodeList(node.groupRuleBody);
   }
 
+  @override
   visitSupportsConditionInParens(SupportsConditionInParens node) {
     node.condition.visit(this);
   }
 
+  @override
   visitSupportsNegation(SupportsNegation node) {
     node.condition.visit(this);
   }
 
+  @override
   visitSupportsConjunction(SupportsConjunction node) {
     _visitNodeList(node.conditions);
   }
 
+  @override
   visitSupportsDisjunction(SupportsDisjunction node) {
     _visitNodeList(node.conditions);
   }
 
+  @override
   visitViewportDirective(ViewportDirective node) {
     node.declarations.visit(this);
   }
 
+  @override
   visitMediaDirective(MediaDirective node) {
     _visitNodeList(node.mediaQueries);
     _visitNodeList(node.rules);
   }
 
+  @override
   visitHostDirective(HostDirective node) {
     _visitNodeList(node.rules);
   }
 
+  @override
   visitPageDirective(PageDirective node) {
     for (var declGroup in node._declsMargin) {
       if (declGroup is MarginGroup) {
@@ -206,48 +225,60 @@
     }
   }
 
+  @override
   visitCharsetDirective(CharsetDirective node) {}
 
+  @override
   visitImportDirective(ImportDirective node) {
     for (var mediaQuery in node.mediaQueries) {
       visitMediaQuery(mediaQuery);
     }
   }
 
+  @override
   visitKeyFrameDirective(KeyFrameDirective node) {
     visitIdentifier(node.name);
     _visitNodeList(node._blocks);
   }
 
+  @override
   visitKeyFrameBlock(KeyFrameBlock node) {
     visitExpressions(node._blockSelectors);
     visitDeclarationGroup(node._declarations);
   }
 
+  @override
   visitFontFaceDirective(FontFaceDirective node) {
     visitDeclarationGroup(node._declarations);
   }
 
+  @override
   visitStyletDirective(StyletDirective node) {
     _visitNodeList(node.rules);
   }
 
+  @override
   visitNamespaceDirective(NamespaceDirective node) {}
 
+  @override
   visitVarDefinitionDirective(VarDefinitionDirective node) {
     visitVarDefinition(node.def);
   }
 
+  @override
   visitMixinRulesetDirective(MixinRulesetDirective node) {
     _visitNodeList(node.rulesets);
   }
 
+  @override
   visitMixinDefinition(MixinDefinition node) {}
 
+  @override
   visitMixinDeclarationDirective(MixinDeclarationDirective node) {
     visitDeclarationGroup(node.declarations);
   }
 
+  @override
   visitIncludeDirective(IncludeDirective node) {
     for (var index = 0; index < node.args.length; index++) {
       var param = node.args[index];
@@ -255,53 +286,66 @@
     }
   }
 
+  @override
   visitContentDirective(ContentDirective node) {
     // TODO(terry): TBD
   }
 
+  @override
   visitRuleSet(RuleSet node) {
     visitSelectorGroup(node._selectorGroup);
     visitDeclarationGroup(node._declarationGroup);
   }
 
+  @override
   visitDeclarationGroup(DeclarationGroup node) {
     _visitNodeList(node.declarations);
   }
 
+  @override
   visitMarginGroup(MarginGroup node) => visitDeclarationGroup(node);
 
+  @override
   visitDeclaration(Declaration node) {
     visitIdentifier(node._property);
     if (node._expression != null) node._expression.visit(this);
   }
 
+  @override
   visitVarDefinition(VarDefinition node) {
     visitIdentifier(node._property);
     if (node._expression != null) node._expression.visit(this);
   }
 
+  @override
   visitIncludeMixinAtDeclaration(IncludeMixinAtDeclaration node) {
     visitIncludeDirective(node.include);
   }
 
+  @override
   visitExtendDeclaration(ExtendDeclaration node) {
     _visitNodeList(node.selectors);
   }
 
+  @override
   visitSelectorGroup(SelectorGroup node) {
     _visitNodeList(node.selectors);
   }
 
+  @override
   visitSelector(Selector node) {
     _visitNodeList(node.simpleSelectorSequences);
   }
 
+  @override
   visitSimpleSelectorSequence(SimpleSelectorSequence node) {
     node.simpleSelector.visit(this);
   }
 
+  @override
   visitSimpleSelector(SimpleSelector node) => node._name.visit(this);
 
+  @override
   visitNamespaceSelector(NamespaceSelector node) {
     if (node._namespace != null) node._namespace.visit(this);
     if (node.nameAsSimpleSelector != null) {
@@ -309,179 +353,231 @@
     }
   }
 
+  @override
   visitElementSelector(ElementSelector node) => visitSimpleSelector(node);
 
+  @override
   visitAttributeSelector(AttributeSelector node) {
     visitSimpleSelector(node);
   }
 
+  @override
   visitIdSelector(IdSelector node) => visitSimpleSelector(node);
 
+  @override
   visitClassSelector(ClassSelector node) => visitSimpleSelector(node);
 
+  @override
   visitPseudoClassSelector(PseudoClassSelector node) =>
       visitSimpleSelector(node);
 
+  @override
   visitPseudoElementSelector(PseudoElementSelector node) =>
       visitSimpleSelector(node);
 
+  @override
   visitPseudoClassFunctionSelector(PseudoClassFunctionSelector node) =>
       visitSimpleSelector(node);
 
+  @override
   visitPseudoElementFunctionSelector(PseudoElementFunctionSelector node) =>
       visitSimpleSelector(node);
 
+  @override
   visitNegationSelector(NegationSelector node) => visitSimpleSelector(node);
 
+  @override
   visitSelectorExpression(SelectorExpression node) {
     _visitNodeList(node.expressions);
   }
 
+  @override
   visitUnicodeRangeTerm(UnicodeRangeTerm node) {}
 
+  @override
   visitLiteralTerm(LiteralTerm node) {}
 
+  @override
   visitHexColorTerm(HexColorTerm node) {}
 
+  @override
   visitNumberTerm(NumberTerm node) {}
 
+  @override
   visitUnitTerm(UnitTerm node) {}
 
+  @override
   visitLengthTerm(LengthTerm node) {
     visitUnitTerm(node);
   }
 
+  @override
   visitPercentageTerm(PercentageTerm node) {
     visitLiteralTerm(node);
   }
 
+  @override
   visitEmTerm(EmTerm node) {
     visitLiteralTerm(node);
   }
 
+  @override
   visitExTerm(ExTerm node) {
     visitLiteralTerm(node);
   }
 
+  @override
   visitAngleTerm(AngleTerm node) {
     visitUnitTerm(node);
   }
 
+  @override
   visitTimeTerm(TimeTerm node) {
     visitUnitTerm(node);
   }
 
+  @override
   visitFreqTerm(FreqTerm node) {
     visitUnitTerm(node);
   }
 
+  @override
   visitFractionTerm(FractionTerm node) {
     visitLiteralTerm(node);
   }
 
+  @override
   visitUriTerm(UriTerm node) {
     visitLiteralTerm(node);
   }
 
+  @override
   visitResolutionTerm(ResolutionTerm node) {
     visitUnitTerm(node);
   }
 
+  @override
   visitChTerm(ChTerm node) {
     visitUnitTerm(node);
   }
 
+  @override
   visitRemTerm(RemTerm node) {
     visitUnitTerm(node);
   }
 
+  @override
   visitViewportTerm(ViewportTerm node) {
     visitUnitTerm(node);
   }
 
+  @override
   visitFunctionTerm(FunctionTerm node) {
     visitLiteralTerm(node);
     visitExpressions(node._params);
   }
 
+  @override
   visitGroupTerm(GroupTerm node) {
     for (var term in node._terms) {
       term.visit(this);
     }
   }
 
+  @override
   visitItemTerm(ItemTerm node) {
     visitNumberTerm(node);
   }
 
+  @override
   visitIE8Term(IE8Term node) {}
 
+  @override
   visitOperatorSlash(OperatorSlash node) {}
 
+  @override
   visitOperatorComma(OperatorComma node) {}
 
+  @override
   visitOperatorPlus(OperatorPlus node) {}
 
+  @override
   visitOperatorMinus(OperatorMinus node) {}
 
+  @override
   visitVarUsage(VarUsage node) {
     _visitNodeList(node.defaultValues);
   }
 
+  @override
   visitExpressions(Expressions node) {
     _visitNodeList(node.expressions);
   }
 
+  @override
   visitBinaryExpression(BinaryExpression node) {
     // TODO(terry): TBD
     throw UnimplementedError();
   }
 
+  @override
   visitUnaryExpression(UnaryExpression node) {
     // TODO(terry): TBD
     throw UnimplementedError();
   }
 
+  @override
   visitIdentifier(Identifier node) {}
 
+  @override
   visitWildcard(Wildcard node) {}
 
+  @override
   visitThisOperator(ThisOperator node) {}
 
+  @override
   visitNegation(Negation node) {}
 
+  @override
   visitDartStyleExpression(DartStyleExpression node) {}
 
+  @override
   visitFontExpression(FontExpression node) {
     // TODO(terry): TBD
     throw UnimplementedError();
   }
 
+  @override
   visitBoxExpression(BoxExpression node) {
     // TODO(terry): TBD
     throw UnimplementedError();
   }
 
+  @override
   visitMarginExpression(MarginExpression node) {
     // TODO(terry): TBD
     throw UnimplementedError();
   }
 
+  @override
   visitBorderExpression(BorderExpression node) {
     // TODO(terry): TBD
     throw UnimplementedError();
   }
 
+  @override
   visitHeightExpression(HeightExpression node) {
     // TODO(terry): TB
     throw UnimplementedError();
   }
 
+  @override
   visitPaddingExpression(PaddingExpression node) {
     // TODO(terry): TBD
     throw UnimplementedError();
   }
 
+  @override
   visitWidthExpression(WidthExpression node) {
     // TODO(terry): TBD
     throw UnimplementedError();
diff --git a/pubspec.yaml b/pubspec.yaml
index f4c6d83..ae2288d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -6,7 +6,7 @@
 homepage: https://github.com/dart-lang/csslib
 
 environment:
-  sdk: '>=2.1.0 <3.0.0'
+  sdk: '>=2.2.0 <3.0.0'
 
 dependencies:
   source_span: ^1.4.0
diff --git a/test/big_1_test.dart b/test/big_1_test.dart
index 9a6a584..5df5b45 100644
--- a/test/big_1_test.dart
+++ b/test/big_1_test.dart
@@ -1162,6 +1162,6 @@
   compilePolyfillAndValidate(input, generated);
 }
 
-main() {
+void main() {
   test('big #1', big_test);
 }
diff --git a/test/compiler_test.dart b/test/compiler_test.dart
index c9e8375..a692a64 100644
--- a/test/compiler_test.dart
+++ b/test/compiler_test.dart
@@ -13,7 +13,7 @@
 
 void testClass() {
   var errors = <Message>[];
-  var input = ".foobar {}";
+  var input = '.foobar {}';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(stylesheet != null, true);
@@ -34,12 +34,12 @@
   final simpSelector = selectorSeqs[0].simpleSelector;
   expect(simpSelector is ClassSelector, true);
   expect(selectorSeqs[0].isCombinatorNone, true);
-  expect(simpSelector.name, "foobar");
+  expect(simpSelector.name, 'foobar');
 }
 
 void testClass2() {
   var errors = <Message>[];
-  var input = ".foobar .bar .no-story {}";
+  var input = '.foobar .bar .no-story {}';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(stylesheet != null, true);
@@ -60,22 +60,22 @@
   var simpSelector0 = simpleSeqs[0].simpleSelector;
   expect(simpSelector0 is ClassSelector, true);
   expect(simpleSeqs[0].isCombinatorNone, true);
-  expect(simpSelector0.name, "foobar");
+  expect(simpSelector0.name, 'foobar');
 
   var simpSelector1 = simpleSeqs[1].simpleSelector;
   expect(simpSelector1 is ClassSelector, true);
   expect(simpleSeqs[1].isCombinatorDescendant, true);
-  expect(simpSelector1.name, "bar");
+  expect(simpSelector1.name, 'bar');
 
   var simpSelector2 = simpleSeqs[2].simpleSelector;
   expect(simpSelector2 is ClassSelector, true);
   expect(simpleSeqs[2].isCombinatorDescendant, true);
-  expect(simpSelector2.name, "no-story");
+  expect(simpSelector2.name, 'no-story');
 }
 
 void testId() {
   var errors = <Message>[];
-  var input = "#elemId {}";
+  var input = '#elemId {}';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(stylesheet != null, true);
@@ -96,12 +96,12 @@
   var simpSelector = simpleSeqs[0].simpleSelector;
   expect(simpSelector is IdSelector, true);
   expect(simpleSeqs[0].isCombinatorNone, true);
-  expect(simpSelector.name, "elemId");
+  expect(simpSelector.name, 'elemId');
 }
 
 void testElement() {
   var errors = <Message>[];
-  var input = "div {}";
+  var input = 'div {}';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(stylesheet != null, true);
@@ -123,9 +123,9 @@
   final simpSelector = simpleSeqs[0].simpleSelector;
   expect(simpSelector is ElementSelector, true);
   expect(simpleSeqs[0].isCombinatorNone, true);
-  expect(simpSelector.name, "div");
+  expect(simpSelector.name, 'div');
 
-  input = "div div span {}";
+  input = 'div div span {}';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(stylesheet != null, true);
@@ -147,22 +147,22 @@
   var simpSelector0 = simpleSeqs[0].simpleSelector;
   expect(simpSelector0 is ElementSelector, true);
   expect(simpleSeqs[0].isCombinatorNone, true);
-  expect(simpSelector0.name, "div");
+  expect(simpSelector0.name, 'div');
 
   var simpSelector1 = simpleSeqs[1].simpleSelector;
   expect(simpSelector1 is ElementSelector, true);
   expect(simpleSeqs[1].isCombinatorDescendant, true);
-  expect(simpSelector1.name, "div");
+  expect(simpSelector1.name, 'div');
 
   var simpSelector2 = simpleSeqs[2].simpleSelector;
   expect(simpSelector2 is ElementSelector, true);
   expect(simpleSeqs[2].isCombinatorDescendant, true);
-  expect(simpSelector2.name, "span");
+  expect(simpSelector2.name, 'span');
 }
 
 void testNamespace() {
   var errors = <Message>[];
-  var input = "ns1|div {}";
+  var input = 'ns1|div {}';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(stylesheet != null, true);
@@ -184,16 +184,16 @@
   var simpSelector = simpleSeqs[0].simpleSelector as NamespaceSelector;
   expect(simpleSeqs[0].isCombinatorNone, true);
   expect(simpSelector.isNamespaceWildcard, false);
-  expect(simpSelector.namespace, "ns1");
+  expect(simpSelector.namespace, 'ns1');
   var elementSelector = simpSelector.nameAsSimpleSelector;
   expect(elementSelector is ElementSelector, true);
   expect(elementSelector.isWildcard, false);
-  expect(elementSelector.name, "div");
+  expect(elementSelector.name, 'div');
 }
 
 void testNamespace2() {
   var errors = <Message>[];
-  var input = "ns1|div div ns2|span .foobar {}";
+  var input = 'ns1|div div ns2|span .foobar {}';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(stylesheet != null, true);
@@ -215,36 +215,36 @@
   expect(simpleSeqs[0].simpleSelector is NamespaceSelector, true);
   var simpSelector0 = simpleSeqs[0].simpleSelector as NamespaceSelector;
   expect(simpleSeqs[0].isCombinatorNone, true);
-  expect(simpSelector0.namespace, "ns1");
+  expect(simpSelector0.namespace, 'ns1');
   var elementSelector0 = simpSelector0.nameAsSimpleSelector;
   expect(elementSelector0 is ElementSelector, true);
   expect(elementSelector0.isWildcard, false);
-  expect(elementSelector0.name, "div");
+  expect(elementSelector0.name, 'div');
 
   var simpSelector1 = simpleSeqs[1].simpleSelector;
   expect(simpSelector1 is ElementSelector, true);
   expect(simpleSeqs[1].isCombinatorDescendant, true);
-  expect(simpSelector1.name, "div");
+  expect(simpSelector1.name, 'div');
 
   expect(simpleSeqs[2].simpleSelector is NamespaceSelector, true);
   var simpSelector2 = simpleSeqs[2].simpleSelector as NamespaceSelector;
   expect(simpleSeqs[2].isCombinatorDescendant, true);
-  expect(simpSelector2.namespace, "ns2");
+  expect(simpSelector2.namespace, 'ns2');
   var elementSelector2 = simpSelector2.nameAsSimpleSelector;
   expect(elementSelector2 is ElementSelector, true);
   expect(elementSelector2.isWildcard, false);
-  expect(elementSelector2.name, "span");
+  expect(elementSelector2.name, 'span');
 
   var simpSelector3 = simpleSeqs[3].simpleSelector;
   expect(simpSelector3 is ClassSelector, true);
   expect(simpleSeqs[3].isCombinatorDescendant, true);
-  expect(simpSelector3.name, "foobar");
+  expect(simpSelector3.name, 'foobar');
 }
 
 void testSelectorGroups() {
   var errors = <Message>[];
   var input =
-      "div, .foobar ,#elemId, .xyzzy .test, ns1|div div #elemId .foobar {}";
+      'div, .foobar ,#elemId, .xyzzy .test, ns1|div div #elemId .foobar {}';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(stylesheet != null, true);
@@ -265,7 +265,7 @@
   var simpleSelector0 = selector0.simpleSelector;
   expect(simpleSelector0 is ElementSelector, true);
   expect(selector0.isCombinatorNone, true);
-  expect(simpleSelector0.name, "div");
+  expect(simpleSelector0.name, 'div');
 
   var groupSelector1 = ruleset.selectorGroup.selectors[1];
   expect(groupSelector1.simpleSelectorSequences.length, 1);
@@ -273,7 +273,7 @@
   var simpleSelector1 = selector1.simpleSelector;
   expect(simpleSelector1 is ClassSelector, true);
   expect(selector1.isCombinatorNone, true);
-  expect(simpleSelector1.name, "foobar");
+  expect(simpleSelector1.name, 'foobar');
 
   var groupSelector2 = ruleset.selectorGroup.selectors[2];
   expect(groupSelector2.simpleSelectorSequences.length, 1);
@@ -281,7 +281,7 @@
   var simpleSelector2 = selector2.simpleSelector;
   expect(simpleSelector2 is IdSelector, true);
   expect(selector2.isCombinatorNone, true);
-  expect(simpleSelector2.name, "elemId");
+  expect(simpleSelector2.name, 'elemId');
 
   var groupSelector3 = ruleset.selectorGroup.selectors[3];
   expect(groupSelector3.simpleSelectorSequences.length, 2);
@@ -290,13 +290,13 @@
   var simpleSelector30 = selector30.simpleSelector;
   expect(simpleSelector30 is ClassSelector, true);
   expect(selector30.isCombinatorNone, true);
-  expect(simpleSelector30.name, "xyzzy");
+  expect(simpleSelector30.name, 'xyzzy');
 
   var selector31 = groupSelector3.simpleSelectorSequences[1];
   var simpleSelector31 = selector31.simpleSelector;
   expect(simpleSelector31 is ClassSelector, true);
   expect(selector31.isCombinatorDescendant, true);
-  expect(simpleSelector31.name, "test");
+  expect(simpleSelector31.name, 'test');
 
   var groupSelector4 = ruleset.selectorGroup.selectors[4];
   expect(groupSelector4.simpleSelectorSequences.length, 4);
@@ -305,33 +305,33 @@
   expect(selector40.simpleSelector is NamespaceSelector, true);
   var simpleSelector40 = selector40.simpleSelector as NamespaceSelector;
   expect(selector40.isCombinatorNone, true);
-  expect(simpleSelector40.namespace, "ns1");
+  expect(simpleSelector40.namespace, 'ns1');
   var elementSelector = simpleSelector40.nameAsSimpleSelector;
   expect(elementSelector is ElementSelector, true);
   expect(elementSelector.isWildcard, false);
-  expect(elementSelector.name, "div");
+  expect(elementSelector.name, 'div');
 
   var selector41 = groupSelector4.simpleSelectorSequences[1];
   var simpleSelector41 = selector41.simpleSelector;
   expect(simpleSelector41 is ElementSelector, true);
   expect(selector41.isCombinatorDescendant, true);
-  expect(simpleSelector41.name, "div");
+  expect(simpleSelector41.name, 'div');
 
   var selector42 = groupSelector4.simpleSelectorSequences[2];
   var simpleSelector42 = selector42.simpleSelector;
   expect(simpleSelector42 is IdSelector, true);
   expect(selector42.isCombinatorDescendant, true);
-  expect(simpleSelector42.name, "elemId");
+  expect(simpleSelector42.name, 'elemId');
 
   var selector43 = groupSelector4.simpleSelectorSequences[3];
   var simpleSelector43 = selector43.simpleSelector;
   expect(selector43.isCombinatorDescendant, true);
-  expect(simpleSelector43.name, "foobar");
+  expect(simpleSelector43.name, 'foobar');
 }
 
 void testCombinator() {
   var errors = <Message>[];
-  var input = ".foobar > .bar + .no-story ~ myNs|div #elemId {}";
+  var input = '.foobar > .bar + .no-story ~ myNs|div #elemId {}';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(stylesheet != null, true);
@@ -354,40 +354,40 @@
   var simpleSelector0 = selector0.simpleSelector;
   expect(simpleSelector0 is ClassSelector, true);
   expect(selector0.isCombinatorNone, true);
-  expect(simpleSelector0.name, "foobar");
+  expect(simpleSelector0.name, 'foobar');
 
   var selector1 = simpleSeqs[1];
   var simpleSelector1 = selector1.simpleSelector;
   expect(simpleSelector1 is ClassSelector, true);
   expect(selector1.isCombinatorGreater, true);
-  expect(simpleSelector1.name, "bar");
+  expect(simpleSelector1.name, 'bar');
 
   var selector2 = simpleSeqs[2];
   var simpleSelector2 = selector2.simpleSelector;
   expect(simpleSelector2 is ClassSelector, true);
   expect(selector2.isCombinatorPlus, true);
-  expect(simpleSelector2.name, "no-story");
+  expect(simpleSelector2.name, 'no-story');
 
   var selector3 = simpleSeqs[3];
   expect(selector3.simpleSelector is NamespaceSelector, true);
   var simpleSelector3 = selector3.simpleSelector as NamespaceSelector;
   expect(selector3.isCombinatorTilde, true);
-  expect(simpleSelector3.namespace, "myNs");
+  expect(simpleSelector3.namespace, 'myNs');
   var elementSelector = simpleSelector3.nameAsSimpleSelector;
   expect(elementSelector is ElementSelector, true);
   expect(elementSelector.isWildcard, false);
-  expect(elementSelector.name, "div");
+  expect(elementSelector.name, 'div');
 
   var selector4 = simpleSeqs[4];
   var simpleSelector4 = selector4.simpleSelector;
   expect(simpleSelector4 is IdSelector, true);
   expect(selector4.isCombinatorDescendant, true);
-  expect(simpleSelector4.name, "elemId");
+  expect(simpleSelector4.name, 'elemId');
 }
 
 void testWildcard() {
   var errors = <Message>[];
-  var input = "* {}";
+  var input = '* {}';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(stylesheet != null, true);
@@ -409,9 +409,9 @@
   expect(simpSelector is ElementSelector, true);
   expect(simpleSeqs[0].isCombinatorNone, true);
   expect(simpSelector.isWildcard, true);
-  expect(simpSelector.name, "*");
+  expect(simpSelector.name, '*');
 
-  input = "*.foobar {}";
+  input = '*.foobar {}';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(stylesheet != null, true);
@@ -436,16 +436,16 @@
     expect(simpleSelector0 is ElementSelector, true);
     expect(selector0.isCombinatorNone, true);
     expect(simpleSelector0.isWildcard, true);
-    expect(simpleSelector0.name, "*");
+    expect(simpleSelector0.name, '*');
   }
 
   var selector1 = simpleSeqs[1];
   var simpleSelector1 = selector1.simpleSelector;
   expect(simpleSelector1 is ClassSelector, true);
   expect(selector1.isCombinatorNone, true);
-  expect(simpleSelector1.name, "foobar");
+  expect(simpleSelector1.name, 'foobar');
 
-  input = "myNs|*.foobar {}";
+  input = 'myNs|*.foobar {}';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(stylesheet != null, true);
@@ -471,18 +471,18 @@
     expect(selector0.isCombinatorNone, true);
     expect(simpleSelector0.isNamespaceWildcard, false);
     var elementSelector = simpleSelector0.nameAsSimpleSelector;
-    expect("myNs", simpleSelector0.namespace);
+    expect('myNs', simpleSelector0.namespace);
     expect(elementSelector.isWildcard, true);
-    expect("*", elementSelector.name);
+    expect('*', elementSelector.name);
   }
 
   selector1 = simpleSeqs[1];
   simpleSelector1 = selector1.simpleSelector;
   expect(simpleSelector1 is ClassSelector, true);
   expect(selector1.isCombinatorNone, true);
-  expect("foobar", simpleSelector1.name);
+  expect('foobar', simpleSelector1.name);
 
-  input = "*|*.foobar {}";
+  input = '*|*.foobar {}';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(stylesheet != null, true);
@@ -505,17 +505,17 @@
     var simpleSelector0 = selector0.simpleSelector as NamespaceSelector;
     expect(selector0.isCombinatorNone, true);
     expect(simpleSelector0.isNamespaceWildcard, true);
-    expect("*", simpleSelector0.namespace);
+    expect('*', simpleSelector0.namespace);
     var elementSelector = simpleSelector0.nameAsSimpleSelector;
     expect(elementSelector.isWildcard, true);
-    expect("*", elementSelector.name);
+    expect('*', elementSelector.name);
   }
 
   selector1 = simpleSeqs[1];
   simpleSelector1 = selector1.simpleSelector;
   expect(simpleSelector1 is ClassSelector, true);
   expect(selector1.isCombinatorNone, true);
-  expect("foobar", simpleSelector1.name);
+  expect('foobar', simpleSelector1.name);
 }
 
 /// Test List<int> as input to parser.
@@ -748,7 +748,7 @@
 }''');
 }
 
-main() {
+void main() {
   test('Classes', testClass);
   test('Classes 2', testClass2);
   test('Ids', testId);
diff --git a/test/debug_test.dart b/test/debug_test.dart
index 94898eb..6f1cee2 100644
--- a/test/debug_test.dart
+++ b/test/debug_test.dart
@@ -4,7 +4,7 @@
 import 'testing.dart';
 
 void main() {
-  test("excercise debug", () {
+  test('excercise debug', () {
     var style = parseCss(_input);
 
     var debugValue = style.toDebugString();
diff --git a/test/declaration_test.dart b/test/declaration_test.dart
index 1cbceb9..d943b08 100644
--- a/test/declaration_test.dart
+++ b/test/declaration_test.dart
@@ -346,7 +346,7 @@
 
 void testMediaQueries() {
   var errors = <Message>[];
-  String input = '''
+  var input = '''
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   .todo-item .toggle {
     background: none;
@@ -355,7 +355,7 @@
     height: 40px;
   }
 }''';
-  String generated = '''
+  var generated = '''
 @media screen AND (-webkit-min-device-pixel-ratio:0) {
 .todo-item .toggle {
   background: none;
@@ -556,15 +556,15 @@
   expect(prettyPrint(styleSheet), expected);
 
   // Test all document functions combined.
-  css = '@-moz-document ' +
-      'url(http://www.w3.org/), ' +
-      "url-prefix('http://www.w3.org/Style/'), " +
-      'domain("google.com"), ' +
+  css = '@-moz-document '
+      'url(http://www.w3.org/), '
+      "url-prefix('http://www.w3.org/Style/'), "
+      'domain("google.com"), '
       'regexp("https:.*") { div { color: #000; } }';
-  expected = '@-moz-document ' +
-      'url("http://www.w3.org/"), ' +
-      'url-prefix("http://www.w3.org/Style/"), ' +
-      'domain("google.com"), ' +
+  expected = '@-moz-document '
+      'url("http://www.w3.org/"), '
+      'url-prefix("http://www.w3.org/Style/"), '
+      'domain("google.com"), '
       'regexp("https:.*") {\ndiv {\n  color: #000;\n}\n}';
   styleSheet = parseCss(css, errors: errors);
   expect(styleSheet, isNotNull);
@@ -609,13 +609,13 @@
     box-shadow: 0 0 2px black inset;
   }
 }''';
-  expected = '@supports (box-shadow: 0 0 2px #000 inset) or ' +
-      '(-moz-box-shadow: 0 0 2px #000 inset) or ' +
-      '(-webkit-box-shadow: 0 0 2px #000 inset) or ' +
-      '(-o-box-shadow: 0 0 2px #000 inset) {\n' +
-      '.box {\n' +
-      '  box-shadow: 0 0 2px #000 inset;\n' +
-      '}\n' +
+  expected = '@supports (box-shadow: 0 0 2px #000 inset) or '
+      '(-moz-box-shadow: 0 0 2px #000 inset) or '
+      '(-webkit-box-shadow: 0 0 2px #000 inset) or '
+      '(-o-box-shadow: 0 0 2px #000 inset) {\n'
+      '.box {\n'
+      '  box-shadow: 0 0 2px #000 inset;\n'
+      '}\n'
       '}';
   expectCss(css, expected);
 
@@ -629,13 +629,13 @@
   }
 }''';
 
-  expected = '@supports ' +
-      '((transition-property: color) or (animation-name: foo)) and ' +
-      '(transform: rotate(10deg)) {\n' +
-      'div {\n' +
-      '  transition-property: color;\n' +
-      '  transform: rotate(10deg);\n' +
-      '}\n' +
+  expected = '@supports '
+      '((transition-property: color) or (animation-name: foo)) and '
+      '(transform: rotate(10deg)) {\n'
+      'div {\n'
+      '  transition-property: color;\n'
+      '  transform: rotate(10deg);\n'
+      '}\n'
       '}';
   expectCss(css, expected);
 
@@ -893,8 +893,8 @@
   expect(compactOuptut(stylesheet), generated);
 
   // Check namespace directive compactly emitted.
-  final String input2 = "@namespace a url(http://www.example.org/a);";
-  final String generated2 = "@namespace a url(http://www.example.org/a);";
+  final String input2 = '@namespace a url(http://www.example.org/a);';
+  final String generated2 = '@namespace a url(http://www.example.org/a);';
 
   var stylesheet2 = parseCss(input2, errors: errors..clear());
 
@@ -995,14 +995,14 @@
 
 void testIE() {
   var errors = <Message>[];
-  final String input = ".test {\n"
-      "  filter: progid:DXImageTransform.Microsoft.gradient"
+  final String input = '.test {\n'
+      '  filter: progid:DXImageTransform.Microsoft.gradient'
       "(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');\n"
-      "}";
-  final String generated = ".test {\n"
-      "  filter: progid:DXImageTransform.Microsoft.gradient"
+      '}';
+  final String generated = '.test {\n'
+      '  filter: progid:DXImageTransform.Microsoft.gradient'
       "(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');\n"
-      "}";
+      '}';
 
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
 
@@ -1010,17 +1010,17 @@
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 
-  final String input2 = ".test {\n"
-      "  filter: progid:DXImageTransform.Microsoft.gradient"
+  final String input2 = '.test {\n'
+      '  filter: progid:DXImageTransform.Microsoft.gradient'
       "(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670')\n"
-      "        progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n"
-      "}";
+      '        progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n'
+      '}';
 
-  final String generated2 = ".test {\n"
-      "  filter: progid:DXImageTransform.Microsoft.gradient"
+  final String generated2 = '.test {\n'
+      '  filter: progid:DXImageTransform.Microsoft.gradient'
       "(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670')\n"
-      "         progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n"
-      "}";
+      '         progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n'
+      '}';
 
   stylesheet = parseCss(input2, errors: errors..clear(), opts: simpleOptions);
 
@@ -1391,7 +1391,7 @@
   expectCss(css, css);
 }
 
-main() {
+void main() {
   test('Simple Terms', testSimpleTerms);
   test('Declarations', testDeclarations);
   test('Identifiers', testIdentifiers);
diff --git a/test/error_test.dart b/test/error_test.dart
index 67af07e..f4ec960 100644
--- a/test/error_test.dart
+++ b/test/error_test.dart
@@ -15,7 +15,7 @@
 
   // TODO(terry): Need to support bolder.
   // font-weight value bolder.
-  var input = ".foobar { font-weight: bolder; }";
+  var input = '.foobar { font-weight: bolder; }';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(errors.isEmpty, false);
@@ -34,7 +34,7 @@
 
   // TODO(terry): Need to support lighter.
   // font-weight value lighter.
-  input = ".foobar { font-weight: lighter; }";
+  input = '.foobar { font-weight: lighter; }';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(errors.isEmpty, false);
@@ -52,7 +52,7 @@
 
   // TODO(terry): Need to support inherit.
   // font-weight value inherit.
-  input = ".foobar { font-weight: inherit; }";
+  input = '.foobar { font-weight: inherit; }';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(errors.isEmpty, false);
@@ -75,7 +75,7 @@
   var errors = <Message>[];
 
   // line-height value in percentge unit.
-  var input = ".foobar { line-height: 120%; }";
+  var input = '.foobar { line-height: 120%; }';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(errors.isEmpty, false);
@@ -93,7 +93,7 @@
 
   // TODO(terry): Need to support all units.
   // line-height value in cm unit.
-  input = ".foobar { line-height: 20cm; }";
+  input = '.foobar { line-height: 20cm; }';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(errors.isEmpty, false);
@@ -111,7 +111,7 @@
 
   // TODO(terry): Need to support inherit.
   // line-height value inherit.
-  input = ".foobar { line-height: inherit; }";
+  input = '.foobar { line-height: inherit; }';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(errors.isEmpty, false);
@@ -133,7 +133,7 @@
   var errors = <Message>[];
 
   // Invalid id selector.
-  var input = "# foo { color: #ff00ff; }";
+  var input = '# foo { color: #ff00ff; }';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(errors.isEmpty, false);
@@ -150,7 +150,7 @@
 }''');
 
   // Invalid class selector.
-  input = ". foo { color: #ff00ff; }";
+  input = '. foo { color: #ff00ff; }';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(errors.isEmpty, false);
@@ -172,7 +172,7 @@
   var errors = <Message>[];
 
   // Invalid hex value.
-  var input = ".foobar { color: #AH787; }";
+  var input = '.foobar { color: #AH787; }';
   var stylesheet = parseCss(input, errors: errors);
 
   expect(errors.isEmpty, false);
@@ -189,7 +189,7 @@
 }''');
 
   // Bad color constant.
-  input = ".foobar { color: redder; }";
+  input = '.foobar { color: redder; }';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(errors.isEmpty, false);
@@ -207,7 +207,7 @@
 }''');
 
   // Bad hex color #<space>ffffff.
-  input = ".foobar { color: # ffffff; }";
+  input = '.foobar { color: # ffffff; }';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(errors.isEmpty, false);
@@ -225,7 +225,7 @@
 }''');
 
   // Bad hex color #<space>123fff.
-  input = ".foobar { color: # 123fff; }";
+  input = '.foobar { color: # 123fff; }';
   stylesheet = parseCss(input, errors: errors..clear());
 
   expect(errors.isEmpty, false);
@@ -370,7 +370,7 @@
   expect(errorMessage.span.text, '\n');
 }
 
-main() {
+void main() {
   test('font-weight value errors', testUnsupportedFontWeights);
   test('line-height value errors', testUnsupportedLineHeights);
   test('bad selectors', testBadSelectors);
diff --git a/test/extend_test.dart b/test/extend_test.dart
index 78c2994..ed5904f 100644
--- a/test/extend_test.dart
+++ b/test/extend_test.dart
@@ -235,12 +235,12 @@
           '  color: #00f;\n}');
 }
 
-main() {
-  test("Simple Extend", simpleExtend);
-  test("complex", complexSelectors);
-  test("multiple", multipleExtends);
-  test("chaining", chaining);
-  test("nested selectors", nestedSelectors);
-  test("nested many selector sequences", nestedMulty);
-  test("N-way extends", nWayExtends);
+void main() {
+  test('Simple Extend', simpleExtend);
+  test('complex', complexSelectors);
+  test('multiple', multipleExtends);
+  test('chaining', chaining);
+  test('nested selectors', nestedSelectors);
+  test('nested many selector sequences', nestedMulty);
+  test('N-way extends', nWayExtends);
 }
diff --git a/test/mixin_test.dart b/test/mixin_test.dart
index e5d3ae7..dec6651 100644
--- a/test/mixin_test.dart
+++ b/test/mixin_test.dart
@@ -640,7 +640,7 @@
   expect(error.span.end.offset, 56);
 }
 
-main() {
+void main() {
   group('Basic mixin', () {
     test('include grammar', includeGrammar);
     test('empty mixin content', emptyMixin);
diff --git a/test/nested_test.dart b/test/nested_test.dart
index a5cadab..b8ef9eb 100644
--- a/test/nested_test.dart
+++ b/test/nested_test.dart
@@ -620,13 +620,13 @@
   compileAndValidate(input, generated);
 }
 
-main() {
+void main() {
   test('Selector and Nested Variations', selectorVariations);
   test('Simple nesting', simpleNest);
   test('Complex nesting', complexNest);
   test('@media nesting', mediaNesting);
   test('Simple &', simpleThis);
-  test("Variations &", variationsThis);
+  test('Variations &', variationsThis);
   test('Complex &', complexThis);
   test('& with + selector', thisCombinator);
 }
diff --git a/test/samples_test.dart b/test/samples_test.dart
index afba147..b906131 100644
--- a/test/samples_test.dart
+++ b/test/samples_test.dart
@@ -22,7 +22,7 @@
   expect(errors, isEmpty, reason: errors.toString());
 }
 
-main() {
+void main() {
   final libraryUri = currentMirrorSystem().findLibrary(#samples_test).uri;
   final cssDir = Directory.fromUri(libraryUri.resolve('examples'));
   for (var element in cssDir.listSync()) {
diff --git a/test/selector_test.dart b/test/selector_test.dart
index a64b8d4..df52be6 100644
--- a/test/selector_test.dart
+++ b/test/selector_test.dart
@@ -87,7 +87,7 @@
       '  ╵');
 }
 
-main() {
+void main() {
   test('Valid Selectors', testSelectorSuccesses);
   test('Invalid Selectors', testSelectorFailures);
 }
diff --git a/test/testing.dart b/test/testing.dart
index 345e5b6..471697e 100644
--- a/test/testing.dart
+++ b/test/testing.dart
@@ -31,8 +31,7 @@
         {List<Message> errors, PreprocessorOptions opts}) =>
     parse(cssInput,
         errors: errors,
-        options:
-            opts == null ? simpleOptionsWithCheckedAndWarningsAsErrors : opts);
+        options: opts ?? simpleOptionsWithCheckedAndWarningsAsErrors);
 
 /// Spin-up CSS parser in checked mode to detect any problematic CSS.  Normally,
 /// CSS will allow any property/value pairs regardless of validity; all of our
@@ -44,8 +43,7 @@
         List<StyleSheet> includes}) =>
     compile(cssInput,
         errors: errors,
-        options:
-            opts == null ? simpleOptionsWithCheckedAndWarningsAsErrors : opts,
+        options: opts ?? simpleOptionsWithCheckedAndWarningsAsErrors,
         polyfill: polyfill,
         includes: includes);
 
diff --git a/test/var_test.dart b/test/var_test.dart
index d1e689e..db03b25 100644
--- a/test/var_test.dart
+++ b/test/var_test.dart
@@ -469,7 +469,7 @@
   color: var(one);
   background: var(six);
 }''';
-  int testBitMap = 0;
+  var testBitMap = 0;
 
   compileAndValidate(input, generated);
 
@@ -484,13 +484,13 @@
   outer:
   for (var error in errors) {
     var errorString = error.toString();
-    for (int i = 0; i < errorStrings.length; i++) {
+    for (var i = 0; i < errorStrings.length; i++) {
       if (errorString == errorStrings[i]) {
         testBitMap |= 1 << i;
         continue outer;
       }
     }
-    fail("Unexpected error string: $errorString");
+    fail('Unexpected error string: $errorString');
   }
   expect(testBitMap, equals((1 << errorStrings.length) - 1));
   expect(prettyPrint(stylesheet), generatedPolyfill);
@@ -955,7 +955,7 @@
   expect(prettyPrint(stylesheet2), generated2);
 }
 
-main() {
+void main() {
   test('Simple var', simpleVar);
   test('Expressions var', expressionsVar);
   test('Default value in var()', defaultVar);
diff --git a/test/visitor_test.dart b/test/visitor_test.dart
index b82ac6b..958db30 100644
--- a/test/visitor_test.dart
+++ b/test/visitor_test.dart
@@ -12,16 +12,17 @@
 
 class ClassVisitor extends Visitor {
   final List expectedClasses;
-  final Set<String> foundClasses = Set();
+  final foundClasses = <String>{};
 
   ClassVisitor(this.expectedClasses);
 
+  @override
   void visitClassSelector(ClassSelector node) {
     foundClasses.add(node.name);
   }
 
   bool get matches {
-    bool match = true;
+    var match = true;
     foundClasses.forEach((value) {
       match = match && expectedClasses.contains(value);
     });
@@ -75,6 +76,7 @@
 
   PolyfillEmitter(this._prefix);
 
+  @override
   void visitClassSelector(ClassSelector node) {
     emit('.${_prefix}_${node.name}');
   }
@@ -107,7 +109,7 @@
   expect(emitted, generated);
 }
 
-main() {
+void main() {
   test('Class Visitors', testClassVisitors);
   test('Polyfill', testPolyFill);
 }