Migrate to null safety (#110)

- *Breaking* The `Font.merge` and `BoxEdge.merge` factory constructors
  are now static methods since a factory constructor can't return null,
  but that was the entire point of these constructors.
- Add nullable return types on methods that have a branch returning
  `null`.
- Add a lot of `?` on parameters that can't provably be non-null.
- Add a lot of `!`.
- Add overrides of `TreeNode.clone` to tighten the return type in a few
  places and allow some skipped explicit casts.
- Remove some dead code on conditional branches that never would have
  been followed, even before the migration, but weren't obvious
  statically.
- Add explicit casts.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a43bf56..c4c3b8b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,14 @@
-## 0.16.3-dev
+## 0.17.0-nullsafety-dev
+
+- `Font.merge` and `BoxEdge.merge` are now static methods instead of factory
+  constructors.
 
 ## 0.16.2
 
 - Added support for escape codes in identifiers.
 
 ## 0.16.1
-	
+
 - Fixed a crash caused by parsing certain calc() expressions and variables names that contain numbers.
 
 ## 0.16.0
diff --git a/example/call_parser.dart b/example/call_parser.dart
index 60adf61..1f4efe8 100644
--- a/example/call_parser.dart
+++ b/example/call_parser.dart
@@ -14,7 +14,7 @@
 /// CSS will allow any property/value pairs regardless of validity; all of our
 /// tests (by default) will ensure that the CSS is really valid.
 StyleSheet parseCss(String cssInput,
-    {List<css.Message> errors, css.PreprocessorOptions opts}) {
+    {List<css.Message>? errors, css.PreprocessorOptions? opts}) {
   return css.parse(cssInput, errors: errors, options: opts ?? _default);
 }
 
diff --git a/lib/parser.dart b/lib/parser.dart
index 099240d..5b3164d 100644
--- a/lib/parser.dart
+++ b/lib/parser.dart
@@ -30,14 +30,14 @@
 /// Used for parser lookup ahead (used for nested selectors Less support).
 class ParserState extends TokenizerState {
   final Token peekToken;
-  final Token previousToken;
+  final Token? previousToken;
 
   ParserState(this.peekToken, this.previousToken, Tokenizer tokenizer)
       : super(tokenizer);
 }
 
 // TODO(jmesserly): this should not be global
-void _createMessages({List<Message> errors, PreprocessorOptions options}) {
+void _createMessages({List<Message>? errors, PreprocessorOptions? options}) {
   errors ??= [];
 
   options ??= PreprocessorOptions(useColors: false, inputFile: 'memory');
@@ -51,11 +51,11 @@
 // TODO(terry): Remove nested name parameter.
 /// Parse and analyze the CSS file.
 StyleSheet compile(input,
-    {List<Message> errors,
-    PreprocessorOptions options,
+    {List<Message>? errors,
+    PreprocessorOptions? options,
     bool nested = true,
     bool polyfill = false,
-    List<StyleSheet> includes}) {
+    List<StyleSheet>? includes}) {
   includes ??= [];
 
   var source = _inputAsString(input);
@@ -78,7 +78,7 @@
 
 /// Analyze the CSS file.
 void analyze(List<StyleSheet> styleSheets,
-    {List<Message> errors, PreprocessorOptions options}) {
+    {List<Message>? errors, PreprocessorOptions? options}) {
   _createMessages(errors: errors, options: options);
   Analyzer(styleSheets, messages).run();
 }
@@ -86,7 +86,7 @@
 /// Parse the [input] CSS stylesheet into a tree. The [input] can be a [String],
 /// or [List<int>] of bytes and returns a [StyleSheet] AST.  The optional
 /// [errors] list will contain each error/warning as a [Message].
-StyleSheet parse(input, {List<Message> errors, PreprocessorOptions options}) {
+StyleSheet parse(input, {List<Message>? errors, PreprocessorOptions? options}) {
   var source = _inputAsString(input);
 
   _createMessages(errors: errors, options: options);
@@ -99,7 +99,7 @@
 /// or [List<int>] of bytes and returns a [StyleSheet] AST.  The optional
 /// [errors] list will contain each error/warning as a [Message].
 // TODO(jmesserly): should rename "parseSelector" and return Selector
-StyleSheet selector(input, {List<Message> errors}) {
+StyleSheet selector(input, {List<Message>? errors}) {
   var source = _inputAsString(input);
 
   _createMessages(errors: errors);
@@ -108,7 +108,7 @@
   return (_Parser(file, source)..tokenizer.inSelector = true).parseSelector();
 }
 
-SelectorGroup parseSelectorGroup(input, {List<Message> errors}) {
+SelectorGroup? parseSelectorGroup(input, {List<Message>? errors}) {
   var source = _inputAsString(input);
 
   _createMessages(errors: errors);
@@ -161,7 +161,7 @@
 
   // TODO(jmesserly): having file and text is redundant.
   // TODO(rnystrom): baseUrl isn't used. Remove from API.
-  Parser(SourceFile file, String text, {int start = 0, String baseUrl})
+  Parser(SourceFile file, String text, {int start = 0, String? baseUrl})
       : _parser = _Parser(file, text, start: start);
 
   StyleSheet parse() => _parser.parse();
@@ -183,8 +183,8 @@
   /// source-span locations.
   final SourceFile file;
 
-  Token _previousToken;
-  Token _peekToken;
+  Token? _previousToken;
+  late Token _peekToken;
 
   _Parser(this.file, String text, {int start = 0})
       : tokenizer = Tokenizer(file, text, true, start) {
@@ -259,9 +259,9 @@
   }
 
   Token _next({bool unicodeRange = false}) {
-    _previousToken = _peekToken;
+    final next = _previousToken = _peekToken;
     _peekToken = tokenizer.next(unicodeRange: unicodeRange);
-    return _previousToken;
+    return next;
   }
 
   bool _peekKind(int kind) {
@@ -310,12 +310,12 @@
     _error(message, tok.span);
   }
 
-  void _error(String message, SourceSpan location) {
+  void _error(String message, SourceSpan? location) {
     location ??= _peekToken.span;
     messages.error(message, location);
   }
 
-  void _warning(String message, SourceSpan location) {
+  void _warning(String message, SourceSpan? location) {
     location ??= _peekToken.span;
     messages.warning(message, location);
   }
@@ -324,10 +324,10 @@
     // TODO(terry): there are places where we are creating spans before we eat
     // the tokens, so using _previousToken is not always valid.
     // TODO(nweiz): use < rather than compareTo when SourceSpan supports it.
-    if (_previousToken == null || _previousToken.span.compareTo(start) < 0) {
+    if (_previousToken == null || _previousToken!.span.compareTo(start) < 0) {
       return start;
     }
-    return start.expand(_previousToken.span);
+    return start.expand(_previousToken!.span);
   }
 
   ///////////////////////////////////////////////////////////////////
@@ -363,7 +363,7 @@
     return mediaQueries;
   }
 
-  MediaQuery processMediaQuery() {
+  MediaQuery? processMediaQuery() {
     // Grammar: [ONLY | NOT]? S* media_type S*
     //          [ AND S* MediaExpr ]* | MediaExpr [ AND S* MediaExpr ]*
 
@@ -385,7 +385,7 @@
       start = _peekToken.span;
     }
 
-    Identifier type;
+    Identifier? type;
     // Get the media type.
     if (_peekIdentifier()) type = identifier();
 
@@ -416,7 +416,7 @@
     return null;
   }
 
-  MediaExpression processMediaExpression([bool andOperator = false]) {
+  MediaExpression? processMediaExpression([bool andOperator = false]) {
     var start = _peekToken.span;
 
     // Grammar: '(' S* media_feature S* [ ':' S* expr ]? ')' S*
@@ -460,7 +460,7 @@
   ///                           declarations
   ///                         '}'
   ///     supports:           '@supports' supports_condition group_rule_body
-  Directive processDirective() {
+  Directive? processDirective() {
     var start = _peekToken.span;
 
     var tokId = processVariableOrDirective();
@@ -471,7 +471,7 @@
 
         // @import "uri_string" or @import url("uri_string") are identical; only
         // a url can follow an @import.
-        String importStr;
+        String? importStr;
         if (_peekIdentifier()) {
           var func = processFunction(identifier());
           if (func is UriTerm) {
@@ -488,7 +488,7 @@
           _error('missing import string', _peekToken.span);
         }
 
-        return ImportDirective(importStr.trim(), medias, _makeSpan(start));
+        return ImportDirective(importStr!.trim(), medias, _makeSpan(start));
 
       case TokenKind.DIRECTIVE_MEDIA:
         _next();
@@ -549,13 +549,13 @@
         _next();
 
         // Page name
-        Identifier name;
+        Identifier? name;
         if (_peekIdentifier()) {
           name = identifier();
         }
 
         // Any pseudo page?
-        Identifier pseudoPage;
+        Identifier? pseudoPage;
         if (_maybeEat(TokenKind.COLON)) {
           if (_peekIdentifier()) {
             pseudoPage = identifier();
@@ -581,11 +581,6 @@
         _next();
 
         var charEncoding = processQuotedString(false);
-        if (isChecked && charEncoding == null) {
-          // Missing character encoding.
-          _warning('missing character encoding string', _makeSpan(start));
-        }
-
         return CharsetDirective(charEncoding, _makeSpan(start));
 
       // TODO(terry): Workaround Dart2js bug continue not implemented in switch
@@ -628,7 +623,7 @@
         //       ['from'|'to'|PERCENTAGE] [',' ['from'|'to'|PERCENTAGE] ]* ;
         _next();
 
-        Identifier name;
+        Identifier? name;
         if (_peekIdentifier()) {
           name = identifier();
         }
@@ -695,14 +690,14 @@
         // namespace_prefix : IDENT
         _next();
 
-        Identifier prefix;
+        Identifier? prefix;
         if (_peekIdentifier()) {
           prefix = identifier();
         }
 
         // The namespace URI can be either a quoted string url("uri_string")
         // are identical.
-        String namespaceUri;
+        String? namespaceUri;
         if (_peekIdentifier()) {
           var func = processFunction(identifier());
           if (func is UriTerm) {
@@ -722,7 +717,7 @@
         }
 
         return NamespaceDirective(
-            prefix != null ? prefix.name : '', namespaceUri, _makeSpan(start));
+            prefix?.name ?? '', namespaceUri, _makeSpan(start));
 
       case TokenKind.DIRECTIVE_MIXIN:
         return processMixin();
@@ -752,7 +747,7 @@
   ///     @mixin IDENT [(args,...)] '{'
   ///       [ruleset | property | directive]*
   ///     '}'
-  MixinDefinition processMixin() {
+  MixinDefinition? processMixin() {
     _next();
 
     var name = identifier();
@@ -781,7 +776,7 @@
     _eat(TokenKind.LBRACE);
 
     var productions = <TreeNode>[];
-    MixinDefinition mixinDirective;
+    MixinDefinition? mixinDirective;
 
     var start = _peekToken.span;
     while (!_maybeEat(TokenKind.END_OF_FILE)) {
@@ -803,7 +798,7 @@
             newDecls.add(IncludeMixinAtDeclaration(include, include.span));
           } else {
             _warning('Error mixing of top-level vs declarations mixins',
-                _makeSpan(include.span));
+                _makeSpan(include.span as FileSpan));
           }
         });
         declGroup.declarations.insertAll(0, newDecls);
@@ -876,12 +871,12 @@
           // Less compatibility:
           //    @name: value;      =>    var-name: value;       (VarDefinition)
           //    property: @name;   =>    property: var(name);   (VarUsage)
-          Identifier name;
+          Identifier? name;
           if (_peekIdentifier()) {
             name = identifier();
           }
 
-          Expressions exprs;
+          Expressions? exprs;
           if (mixinParameter && _maybeEat(TokenKind.COLON)) {
             exprs = processExpr();
           } else if (!mixinParameter) {
@@ -897,10 +892,10 @@
       }
     } else if (mixinParameter && _peekToken.kind == TokenKind.VAR_DEFINITION) {
       _next();
-      Identifier definedName;
+      Identifier? definedName;
       if (_peekIdentifier()) definedName = identifier();
 
-      Expressions exprs;
+      Expressions? exprs;
       if (_maybeEat(TokenKind.COLON)) {
         exprs = processExpr();
       }
@@ -917,7 +912,7 @@
     //     @include IDENT [(args,...)];
     _next();
 
-    Identifier name;
+    Identifier? name;
     if (_peekIdentifier()) {
       name = identifier();
     }
@@ -952,7 +947,7 @@
       _eat(TokenKind.SEMICOLON);
     }
 
-    return IncludeDirective(name.name, params, span);
+    return IncludeDirective(name!.name, params, span);
   }
 
   DocumentDirective processDocumentDirective() {
@@ -982,12 +977,12 @@
 
         _eat(TokenKind.RPAREN);
 
-        var arguments = Expressions(_makeSpan(argumentSpan))
+        var arguments = Expressions(_makeSpan(argumentSpan as FileSpan))
           ..add(LiteralTerm(argument, argument, argumentSpan));
-        function = FunctionTerm(
-            ident.name, ident.name, arguments, _makeSpan(ident.span));
+        function = FunctionTerm(ident.name, ident.name, arguments,
+            _makeSpan(ident.span as FileSpan));
       } else {
-        function = processFunction(ident);
+        function = processFunction(ident) as LiteralTerm;
       }
 
       functions.add(function);
@@ -1009,7 +1004,7 @@
     return SupportsDirective(condition, groupRuleBody, _makeSpan(start));
   }
 
-  SupportsCondition processSupportsCondition() {
+  SupportsCondition? processSupportsCondition() {
     if (_peekKind(TokenKind.IDENTIFIER)) {
       return processSupportsNegation();
     }
@@ -1052,7 +1047,7 @@
     }
   }
 
-  SupportsNegation processSupportsNegation() {
+  SupportsNegation? processSupportsNegation() {
     var start = _peekToken.span;
     var text = _peekToken.text.toLowerCase();
     if (text != 'not') return null;
@@ -1083,7 +1078,7 @@
     return ViewportDirective(name, declarations, _makeSpan(start));
   }
 
-  TreeNode processRule([SelectorGroup selectorGroup]) {
+  TreeNode? processRule([SelectorGroup? selectorGroup]) {
     if (selectorGroup == null) {
       final directive = processDirective();
       if (directive != null) {
@@ -1133,7 +1128,7 @@
   ///
   /// Return [:null:] if no selector or [SelectorGroup] if a selector was
   /// parsed.
-  SelectorGroup _nestedSelector() {
+  SelectorGroup? _nestedSelector() {
     var oldMessages = messages;
     _createMessages();
 
@@ -1172,7 +1167,7 @@
       var selectorGroup = _nestedSelector();
       while (selectorGroup != null) {
         // Nested selector so process as a ruleset.
-        var ruleset = processRule(selectorGroup);
+        var ruleset = processRule(selectorGroup)!;
         decls.add(ruleset);
         selectorGroup = _nestedSelector();
       }
@@ -1180,7 +1175,7 @@
       var decl = processDeclaration(dartStyles);
       if (decl != null) {
         if (decl.hasDartStyle) {
-          var newDartStyle = decl.dartStyle;
+          var newDartStyle = decl.dartStyle!;
 
           // Replace or add latest Dart style.
           var replaced = false;
@@ -1255,16 +1250,14 @@
           _next();
 
           var declGroup = processDeclarations();
-          if (declGroup != null) {
-            groups.add(MarginGroup(
-                marginSym, declGroup.declarations, _makeSpan(start)));
-          }
+          groups.add(
+              MarginGroup(marginSym, declGroup.declarations, _makeSpan(start)));
           break;
         default:
           var decl = processDeclaration(dartStyles);
           if (decl != null) {
             if (decl.hasDartStyle) {
-              var newDartStyle = decl.dartStyle;
+              var newDartStyle = decl.dartStyle!;
 
               // Replace or add latest Dart style.
               var replaced = false;
@@ -1303,7 +1296,7 @@
     return groups;
   }
 
-  SelectorGroup processSelectorGroup() {
+  SelectorGroup? processSelectorGroup() {
     var selectors = <Selector>[];
     var start = _peekToken.span;
 
@@ -1323,7 +1316,7 @@
   }
 
   /// Return list of selectors
-  Selector processSelector() {
+  Selector? processSelector() {
     var simpleSequences = <SimpleSelectorSequence>[];
     var start = _peekToken.span;
     while (true) {
@@ -1346,7 +1339,7 @@
   /// This is a quick fix for parsing <compound-selectors> until the parser
   /// supports Selector Level 4 grammar:
   /// https://drafts.csswg.org/selectors-4/#typedef-compound-selector
-  Selector processCompoundSelector() {
+  Selector? processCompoundSelector() {
     var selector = processSelector();
     if (selector != null) {
       for (var sequence in selector.simpleSelectorSequences) {
@@ -1358,7 +1351,7 @@
     return selector;
   }
 
-  SimpleSelectorSequence simpleSelectorSequence(bool forceCombinatorNone) {
+  SimpleSelectorSequence? simpleSelectorSequence(bool forceCombinatorNone) {
     var start = _peekToken.span;
     var combinatorType = TokenKind.COMBINATOR_NONE;
     var thisOperator = false;
@@ -1384,7 +1377,7 @@
 
     // Check if WHITESPACE existed between tokens if so we're descendent.
     if (combinatorType == TokenKind.COMBINATOR_NONE && !forceCombinatorNone) {
-      if (_previousToken != null && _previousToken.end != _peekToken.start) {
+      if (_previousToken != null && _previousToken!.end != _peekToken.start) {
         combinatorType = TokenKind.COMBINATOR_DESCENDANT;
       }
     }
@@ -1427,7 +1420,7 @@
   ///        : [ namespace_prefix ]? '*'
   ///     class
   ///        : '.' IDENT
-  SimpleSelector simpleSelector() {
+  SimpleSelector? simpleSelector() {
     // TODO(terry): Natalie makes a good point parsing of namespace and element
     //              are essentially the same (asterisk or identifier) other
     //              than the error message for element.  Should consolidate the
@@ -1457,7 +1450,7 @@
     }
 
     if (_maybeEat(TokenKind.NAMESPACE)) {
-      TreeNode element;
+      TreeNode? element;
       switch (_peek()) {
         case TokenKind.ASTERISK:
           // Mark as universal element
@@ -1474,7 +1467,7 @@
       }
 
       return NamespaceSelector(
-          first, ElementSelector(element, element.span), _makeSpan(start));
+          first, ElementSelector(element, element!.span!), _makeSpan(start));
     } else if (first != null) {
       return ElementSelector(first, _makeSpan(start));
     } else {
@@ -1484,19 +1477,17 @@
   }
 
   bool _anyWhiteSpaceBeforePeekToken(int kind) {
-    if (_previousToken != null &&
-        _peekToken != null &&
-        _previousToken.kind == kind) {
+    if (_previousToken != null && _previousToken!.kind == kind) {
       // If end of previous token isn't same as the start of peek token then
       // there's something between these tokens probably whitespace.
-      return _previousToken.end != _peekToken.start;
+      return _previousToken!.end != _peekToken.start;
     }
 
     return false;
   }
 
   /// type_selector | universal | HASH | class | attrib | pseudo
-  SimpleSelector simpleSelectorTail() {
+  SimpleSelector? simpleSelectorTail() {
     // Check for HASH | class | attrib | pseudo | negation
     var start = _peekToken.span;
     switch (_peek()) {
@@ -1531,7 +1522,7 @@
     return null;
   }
 
-  SimpleSelector processPseudoSelector(FileSpan start) {
+  SimpleSelector? processPseudoSelector(FileSpan start) {
     // :pseudo-class ::pseudo-element
     // TODO(terry): '::' should be token.
     _eat(TokenKind.COLON);
@@ -1618,7 +1609,7 @@
 
     var expressions = <Expression>[];
 
-    Token termToken;
+    Token? termToken;
     dynamic value;
 
     var keepParsing = true;
@@ -1685,7 +1676,7 @@
   //     SUFFIXMATCH:      '$='
   //
   //     SUBSTRMATCH:      '*='
-  AttributeSelector processAttribute() {
+  AttributeSelector? processAttribute() {
     var start = _peekToken.span;
 
     if (_maybeEat(TokenKind.LBRACK)) {
@@ -1739,8 +1730,8 @@
   //   property: expr prio? \9; - IE8 and below property, /9 before semi-colon
   //   *IDENT                   - IE7 or below
   //   _IDENT                   - IE6 property (automatically a valid ident)
-  Declaration processDeclaration(List<DartStyleExpression> dartStyles) {
-    Declaration decl;
+  Declaration? processDeclaration(List<DartStyleExpression> dartStyles) {
+    Declaration? decl;
 
     var start = _peekToken.span;
 
@@ -1769,7 +1760,7 @@
           important: importantPriority, ie7: ie7);
     } else if (_peekToken.kind == TokenKind.VAR_DEFINITION) {
       _next();
-      Identifier definedName;
+      Identifier? definedName;
       if (_peekIdentifier()) definedName = identifier();
 
       _eat(TokenKind.COLON);
@@ -1797,7 +1788,7 @@
         var pseudoSelector = processPseudoSelector(_peekToken.span);
         if (pseudoSelector is PseudoElementSelector ||
             pseudoSelector is PseudoClassSelector) {
-          simpleSequences.add(pseudoSelector);
+          simpleSequences.add(pseudoSelector!);
         } else {
           _warning('not a valid selector', span);
         }
@@ -1876,9 +1867,9 @@
     'normal': FontWeight.normal
   };
 
-  static int _findStyle(String styleName) => _stylesToDart[styleName];
+  static int? _findStyle(String styleName) => _stylesToDart[styleName];
 
-  DartStyleExpression _styleForDart(Identifier property, Expressions exprs,
+  DartStyleExpression? _styleForDart(Identifier property, Expressions exprs,
       List<DartStyleExpression> dartStyles) {
     var styleType = _findStyle(property.name.toLowerCase());
     if (styleType != null) {
@@ -1892,14 +1883,14 @@
     // Merge all font styles for this class selector.
     for (var dartStyle in dartStyles) {
       if (dartStyle.isFont) {
-        fontExpr = FontExpression.merge(dartStyle, fontExpr);
+        fontExpr = FontExpression.merge(dartStyle as FontExpression, fontExpr);
       }
     }
 
     return fontExpr;
   }
 
-  DartStyleExpression buildDartStyleNode(
+  DartStyleExpression? buildDartStyleNode(
       int styleType, Expressions exprs, List<DartStyleExpression> dartStyles) {
     switch (styleType) {
       // Properties in order:
@@ -1917,7 +1908,7 @@
         try {
           return _mergeFontStyles(processor.processFontFamily(), dartStyles);
         } catch (fontException) {
-          _error(fontException, _peekToken.span);
+          _error('$fontException', _peekToken.span);
         }
         break;
       case _fontPartSize:
@@ -2036,7 +2027,7 @@
 
   // TODO(terry): Look at handling width of thin, thick, etc. any none numbers
   //              to convert to a number.
-  DartStyleExpression processOneNumber(Expressions exprs, int part) {
+  DartStyleExpression? processOneNumber(Expressions exprs, int part) {
     var value = marginValue(exprs.expressions[0]);
     if (value != null) {
       switch (part) {
@@ -2085,11 +2076,11 @@
   /// * top/right/bottom/left      (1 parameter)
   ///
   /// The values of the margins can be a unit or unitless or auto.
-  BoxEdge processFourNums(Expressions exprs) {
-    num top;
-    num right;
-    num bottom;
-    num left;
+  BoxEdge? processFourNums(Expressions exprs) {
+    num? top;
+    num? right;
+    num? bottom;
+    num? left;
 
     var totalExprs = exprs.expressions.length;
     switch (totalExprs) {
@@ -2125,7 +2116,7 @@
   }
 
   // TODO(terry): Need to handle auto.
-  num marginValue(Expression exprTerm) {
+  num? marginValue(Expression exprTerm) {
     if (exprTerm is UnitTerm) {
       return exprTerm.value as num;
     } else if (exprTerm is NumberTerm) {
@@ -2147,7 +2138,7 @@
     var keepGoing = true;
     dynamic expr;
     while (keepGoing && (expr = processTerm(ieFilter)) != null) {
-      Expression op;
+      Expression? op;
 
       var opStart = _peekToken.span;
 
@@ -2228,7 +2219,7 @@
   dynamic /* Expression | List<Expression> | ... */ processTerm(
       [bool ieFilter = false]) {
     var start = _peekToken.span;
-    Token t; // token for term's value
+    Token? t; // token for term's value
     dynamic value; // value of term (numeric values)
 
     var unary = '';
@@ -2236,12 +2227,12 @@
       case TokenKind.HASH:
         _eat(TokenKind.HASH);
         if (!_anyWhiteSpaceBeforePeekToken(TokenKind.HASH)) {
-          String hexText;
+          String? hexText;
           if (_peekKind(TokenKind.INTEGER)) {
             var hexText1 = _peekToken.text;
             _next();
             // Append identifier only if there's no delimiting whitespace.
-            if (_peekIdentifier() && _previousToken.end == _peekToken.start) {
+            if (_peekIdentifier() && _previousToken!.end == _peekToken.start) {
               hexText = '$hexText1${identifier().name}';
             } else {
               hexText = hexText1;
@@ -2347,20 +2338,20 @@
             TokenKind.decimalToHex(TokenKind.colorValue(colorEntry), 6);
         return _parseHex(rgbColor, _makeSpan(start));
       case TokenKind.UNICODE_RANGE:
-        String first;
-        String second;
+        String? first;
+        String? second;
         int firstNumber;
         int secondNumber;
         _eat(TokenKind.UNICODE_RANGE, unicodeRange: true);
         if (_maybeEat(TokenKind.HEX_INTEGER, unicodeRange: true)) {
-          first = _previousToken.text;
+          first = _previousToken!.text;
           firstNumber = int.parse('0x$first');
           if (firstNumber > MAX_UNICODE) {
             _error('unicode range must be less than 10FFFF', _makeSpan(start));
           }
           if (_maybeEat(TokenKind.MINUS, unicodeRange: true)) {
             if (_maybeEat(TokenKind.HEX_INTEGER, unicodeRange: true)) {
-              second = _previousToken.text;
+              second = _previousToken!.text;
               secondNumber = int.parse('0x$second');
               if (secondNumber > MAX_UNICODE) {
                 _error(
@@ -2373,7 +2364,7 @@
             }
           }
         } else if (_maybeEat(TokenKind.HEX_RANGE, unicodeRange: true)) {
-          first = _previousToken.text;
+          first = _previousToken!.text;
         }
 
         return UnicodeRangeTerm(first, second, _makeSpan(start));
@@ -2399,17 +2390,17 @@
   }
 
   /// Process all dimension units.
-  LiteralTerm processDimension(Token t, var value, SourceSpan span) {
+  LiteralTerm processDimension(Token? t, Object value, SourceSpan span) {
     LiteralTerm term;
     var unitType = _peek();
 
     switch (unitType) {
       case TokenKind.UNIT_EM:
-        term = EmTerm(value, t.text, span);
+        term = EmTerm(value, t!.text, span);
         _next(); // Skip the unit
         break;
       case TokenKind.UNIT_EX:
-        term = ExTerm(value, t.text, span);
+        term = ExTerm(value, t!.text, span);
         _next(); // Skip the unit
         break;
       case TokenKind.UNIT_LENGTH_PX:
@@ -2418,62 +2409,60 @@
       case TokenKind.UNIT_LENGTH_IN:
       case TokenKind.UNIT_LENGTH_PT:
       case TokenKind.UNIT_LENGTH_PC:
-        term = LengthTerm(value, t.text, span, unitType);
+        term = LengthTerm(value, t!.text, span, unitType);
         _next(); // Skip the unit
         break;
       case TokenKind.UNIT_ANGLE_DEG:
       case TokenKind.UNIT_ANGLE_RAD:
       case TokenKind.UNIT_ANGLE_GRAD:
       case TokenKind.UNIT_ANGLE_TURN:
-        term = AngleTerm(value, t.text, span, unitType);
+        term = AngleTerm(value, t!.text, span, unitType);
         _next(); // Skip the unit
         break;
       case TokenKind.UNIT_TIME_MS:
       case TokenKind.UNIT_TIME_S:
-        term = TimeTerm(value, t.text, span, unitType);
+        term = TimeTerm(value, t!.text, span, unitType);
         _next(); // Skip the unit
         break;
       case TokenKind.UNIT_FREQ_HZ:
       case TokenKind.UNIT_FREQ_KHZ:
-        term = FreqTerm(value, t.text, span, unitType);
+        term = FreqTerm(value, t!.text, span, unitType);
         _next(); // Skip the unit
         break;
       case TokenKind.PERCENT:
-        term = PercentageTerm(value, t.text, span);
+        term = PercentageTerm(value, t!.text, span);
         _next(); // Skip the %
         break;
       case TokenKind.UNIT_FRACTION:
-        term = FractionTerm(value, t.text, span);
+        term = FractionTerm(value, t!.text, span);
         _next(); // Skip the unit
         break;
       case TokenKind.UNIT_RESOLUTION_DPI:
       case TokenKind.UNIT_RESOLUTION_DPCM:
       case TokenKind.UNIT_RESOLUTION_DPPX:
-        term = ResolutionTerm(value, t.text, span, unitType);
+        term = ResolutionTerm(value, t!.text, span, unitType);
         _next(); // Skip the unit
         break;
       case TokenKind.UNIT_CH:
-        term = ChTerm(value, t.text, span, unitType);
+        term = ChTerm(value, t!.text, span, unitType);
         _next(); // Skip the unit
         break;
       case TokenKind.UNIT_REM:
-        term = RemTerm(value, t.text, span, unitType);
+        term = RemTerm(value, t!.text, span, unitType);
         _next(); // Skip the unit
         break;
       case TokenKind.UNIT_VIEWPORT_VW:
       case TokenKind.UNIT_VIEWPORT_VH:
       case TokenKind.UNIT_VIEWPORT_VMIN:
       case TokenKind.UNIT_VIEWPORT_VMAX:
-        term = ViewportTerm(value, t.text, span, unitType);
+        term = ViewportTerm(value, t!.text, span, unitType);
         _next(); // Skip the unit
         break;
       default:
-        if (value != null) {
-          if (value is Identifier) {
-            term = LiteralTerm(value, value.name, span);
-          } else if (t != null) {
-            term = NumberTerm(value, t.text, span);
-          }
+        if (value is Identifier) {
+          term = LiteralTerm(value, value.name, span);
+        } else {
+          term = NumberTerm(value, t!.text, span);
         }
     }
 
@@ -2607,7 +2596,7 @@
     return stringValue.toString();
   }
 
-  CalcTerm processCalc(Identifier func) {
+  CalcTerm? processCalc(Identifier func) {
     var start = _peekToken.span;
 
     var name = func.name;
@@ -2765,8 +2754,8 @@
     // * ##length in px, pt, etc.
     // * ##%, percent of parent elem's font-size
     // * inherit
-    LengthTerm size;
-    LineHeight lineHt;
+    LengthTerm? size;
+    LineHeight? lineHt;
     var nextIsLineHeight = false;
     for (; _index < _exprs.expressions.length; _index++) {
       var expr = _exprs.expressions[_index];
@@ -2824,8 +2813,8 @@
 
   FontExpression processFont() {
     // Process all parts of the font expression.
-    FontExpression fontSize;
-    FontExpression fontFamily;
+    FontExpression? fontSize;
+    FontExpression? fontFamily;
     for (; _index < _exprs.expressions.length; _index++) {
       // Order is font-size font-family
       fontSize ??= processFontSize();
@@ -2837,20 +2826,20 @@
     }
 
     return FontExpression(_exprs.span,
-        size: fontSize.font.size,
+        size: fontSize!.font.size,
         lineHeight: fontSize.font.lineHeight,
-        family: fontFamily.font.family);
+        family: fontFamily!.font.family);
   }
 }
 
 /// Escapes [text] for use in a CSS string.
 /// [single] specifies single quote `'` vs double quote `"`.
 String _escapeString(String text, {bool single = false}) {
-  StringBuffer result;
+  StringBuffer? result;
 
   for (var i = 0; i < text.length; i++) {
     var code = text.codeUnitAt(i);
-    String replace;
+    String? replace;
     switch (code) {
       case 34 /*'"'*/ :
         if (!single) replace = r'\"';
diff --git a/lib/src/analyzer.dart b/lib/src/analyzer.dart
index 7ed553f..f685a2b 100644
--- a/lib/src/analyzer.dart
+++ b/lib/src/analyzer.dart
@@ -171,16 +171,16 @@
 /// expanded.
 class ExpandNestedSelectors extends Visitor {
   /// Parent [RuleSet] if a nested rule otherwise [:null:].
-  RuleSet _parentRuleSet;
+  RuleSet? _parentRuleSet;
 
   /// Top-most rule if nested rules.
-  SelectorGroup _topLevelSelectorGroup;
+  SelectorGroup? _topLevelSelectorGroup;
 
   /// SelectorGroup at each nesting level.
-  SelectorGroup _nestedSelectorGroup;
+  SelectorGroup? _nestedSelectorGroup;
 
   /// Declaration (sans the nested selectors).
-  DeclarationGroup _flatDeclarationGroup;
+  DeclarationGroup? _flatDeclarationGroup;
 
   /// Each nested selector get's a flatten RuleSet.
   List<RuleSet> _expandedRuleSets = [];
@@ -196,7 +196,7 @@
 
     if (_nestedSelectorGroup == null) {
       // Create top-level selector (may have nested rules).
-      final newSelectors = node.selectorGroup.selectors.toList();
+      final newSelectors = node.selectorGroup!.selectors.toList();
       _topLevelSelectorGroup = SelectorGroup(newSelectors, node.span);
       _nestedSelectorGroup = _topLevelSelectorGroup;
     } else {
@@ -234,8 +234,8 @@
   /// the [_nestedSelectorGroup].
   SelectorGroup _mergeToFlatten(RuleSet node) {
     // Create a new SelectorGroup for this nesting level.
-    var nestedSelectors = _nestedSelectorGroup.selectors;
-    var selectors = node.selectorGroup.selectors;
+    var nestedSelectors = _nestedSelectorGroup!.selectors;
+    var selectors = node.selectorGroup!.selectors;
 
     // Create a merged set of previous parent selectors and current selectors.
     var newSelectors = <Selector>[];
@@ -343,7 +343,7 @@
   @override
   void visitDeclaration(Declaration node) {
     if (_parentRuleSet != null) {
-      _flatDeclarationGroup.declarations.add(node);
+      _flatDeclarationGroup!.declarations.add(node);
     }
     super.visitDeclaration(node);
   }
@@ -351,7 +351,7 @@
   @override
   void visitVarDefinition(VarDefinition node) {
     if (_parentRuleSet != null) {
-      _flatDeclarationGroup.declarations.add(node);
+      _flatDeclarationGroup!.declarations.add(node);
     }
     super.visitVarDefinition(node);
   }
@@ -359,7 +359,7 @@
   @override
   void visitExtendDeclaration(ExtendDeclaration node) {
     if (_parentRuleSet != null) {
-      _flatDeclarationGroup.declarations.add(node);
+      _flatDeclarationGroup!.declarations.add(node);
     }
     super.visitExtendDeclaration(node);
   }
@@ -367,7 +367,7 @@
   @override
   void visitMarginGroup(MarginGroup node) {
     if (_parentRuleSet != null) {
-      _flatDeclarationGroup.declarations.add(node);
+      _flatDeclarationGroup!.declarations.add(node);
     }
     super.visitMarginGroup(node);
   }
@@ -421,12 +421,12 @@
 /// Expand all @include at the top-level the ruleset(s) associated with the
 /// mixin.
 class TopLevelIncludes extends Visitor {
-  StyleSheet _styleSheet;
+  StyleSheet? _styleSheet;
   final Messages _messages;
 
   /// Map of variable name key to it's definition.
   final map = <String, MixinDefinition>{};
-  MixinDefinition currDef;
+  MixinDefinition? currDef;
 
   static void expand(Messages messages, List<StyleSheet> styleSheets) {
     TopLevelIncludes(messages, styleSheets);
@@ -450,14 +450,14 @@
 
   @override
   void visitIncludeDirective(IncludeDirective node) {
+    final currDef = this.currDef;
     if (map.containsKey(node.name)) {
       var mixinDef = map[node.name];
       if (mixinDef is MixinRulesetDirective) {
         _TopLevelIncludeReplacer.replace(
-            _messages, _styleSheet, node, mixinDef.rulesets);
+            _messages, _styleSheet!, node, mixinDef.rulesets);
       } else if (currDef is MixinRulesetDirective && _anyRulesets(currDef)) {
-        // currDef is MixinRulesetDirective
-        MixinRulesetDirective mixinRuleset = currDef;
+        final mixinRuleset = currDef;
         var index = mixinRuleset.rulesets.indexOf(node);
         mixinRuleset.rulesets.removeAt(index);
         _messages.warning(
@@ -466,7 +466,7 @@
       }
     } else {
       if (currDef is MixinRulesetDirective) {
-        var rulesetDirect = currDef as MixinRulesetDirective;
+        var rulesetDirect = currDef;
         rulesetDirect.rulesets.removeWhere((entry) {
           if (entry == node) {
             _messages.warning('Undefined mixin ${node.name}', node.span);
@@ -548,8 +548,9 @@
 /// RuleSets, depending on type of mixin (ruleset or declaration).  The include
 /// can be an include in a declaration or an include directive (top-level).
 int _findInclude(List list, TreeNode node) {
-  IncludeDirective matchNode =
-      (node is IncludeMixinAtDeclaration) ? node.include : node;
+  final matchNode = (node is IncludeMixinAtDeclaration)
+      ? node.include
+      : node as IncludeDirective;
 
   var index = 0;
   for (var item in list) {
@@ -564,20 +565,20 @@
 /// parameters.
 class CallMixin extends Visitor {
   final MixinDefinition mixinDef;
-  List _definedArgs;
-  Expressions _currExpressions;
+  List? _definedArgs;
+  Expressions? _currExpressions;
   int _currIndex = -1;
 
   final varUsages = <String, Map<Expressions, Set<int>>>{};
 
   /// Only var defs with more than one expression (comma separated).
-  final Map<String, VarDefinition> varDefs;
+  final Map<String, VarDefinition>? varDefs;
 
   CallMixin(this.mixinDef, [this.varDefs]) {
     if (mixinDef is MixinRulesetDirective) {
-      visitMixinRulesetDirective(mixinDef);
+      visitMixinRulesetDirective(mixinDef as MixinRulesetDirective);
     } else {
-      visitMixinDeclarationDirective(mixinDef);
+      visitMixinDeclarationDirective(mixinDef as MixinDeclarationDirective);
     }
   }
 
@@ -586,9 +587,9 @@
   MixinDefinition transform(List<List<Expression>> callArgs) {
     // TODO(terry): Handle default arguments and varArgs.
     // Transform mixin with callArgs.
-    for (var index = 0; index < _definedArgs.length; index++) {
-      var definedArg = _definedArgs[index];
-      VarDefinition varDef;
+    for (var index = 0; index < _definedArgs!.length; index++) {
+      var definedArg = _definedArgs![index];
+      VarDefinition? varDef;
       if (definedArg is VarDefinition) {
         varDef = definedArg;
       } else if (definedArg is VarDefinitionDirective) {
@@ -606,8 +607,8 @@
         callArg = callArgs[index];
       }
 
-      var expressions = varUsages[varDef.definedName];
-      expressions.forEach((k, v) {
+      var expressions = varUsages[varDef!.definedName];
+      expressions!.forEach((k, v) {
         for (var usagesIndex in v) {
           k.expressions.replaceRange(usagesIndex, usagesIndex + 1, callArg);
         }
@@ -622,8 +623,8 @@
   List<List<Expression>> _varDefsAsCallArgs(var callArg) {
     var defArgs = <List<Expression>>[];
     if (callArg is List && callArg[0] is VarUsage) {
-      var varDef = varDefs[callArg[0].name];
-      var expressions = (varDef.expression as Expressions).expressions;
+      var varDef = varDefs![callArg[0].name];
+      var expressions = (varDef!.expression as Expressions).expressions;
       assert(expressions.length > 1);
       for (var expr in expressions) {
         if (expr is! OperatorComma) {
@@ -651,7 +652,7 @@
   void _addExpression(Map<Expressions, Set<int>> expressions) {
     var indexSet = <int>{};
     indexSet.add(_currIndex);
-    expressions[_currExpressions] = indexSet;
+    expressions[_currExpressions!] = indexSet;
   }
 
   @override
@@ -660,7 +661,7 @@
     assert(_currExpressions != null);
     if (varUsages.containsKey(node.name)) {
       var expressions = varUsages[node.name];
-      var allIndexes = expressions[_currExpressions];
+      var allIndexes = expressions![_currExpressions];
       if (allIndexes == null) {
         _addExpression(expressions);
       } else {
@@ -689,7 +690,7 @@
 
 /// Expand all @include inside of a declaration associated with a mixin.
 class DeclarationIncludes extends Visitor {
-  StyleSheet _styleSheet;
+  StyleSheet? _styleSheet;
   final Messages _messages;
 
   /// Map of variable name key to it's definition.
@@ -697,8 +698,8 @@
 
   /// Cache of mixin called with parameters.
   final Map<String, CallMixin> callMap = <String, CallMixin>{};
-  MixinDefinition currDef;
-  DeclarationGroup currDeclGroup;
+  MixinDefinition? currDef;
+  DeclarationGroup? currDeclGroup;
 
   /// Var definitions with more than 1 expression.
   final varDefs = <String, VarDefinition>{};
@@ -741,9 +742,10 @@
       // Fix up any mixin that is really a Declaration but has includes.
       if (mixinDef is MixinRulesetDirective) {
         if (!_allIncludes(mixinDef.rulesets) && currDeclGroup != null) {
-          var index = _findInclude(currDeclGroup.declarations, node);
+          var index = _findInclude(currDeclGroup!.declarations, node);
           if (index != -1) {
-            currDeclGroup.declarations.replaceRange(index, index + 1, [NoOp()]);
+            currDeclGroup!.declarations
+                .replaceRange(index, index + 1, [NoOp()]);
           }
           _messages.warning(
               'Using top-level mixin ${node.include.name} as a declaration',
@@ -758,19 +760,19 @@
               rulesets.add(IncludeMixinAtDeclaration(
                   ruleset as IncludeDirective, ruleset.span));
             });
-            _IncludeReplacer.replace(_styleSheet, node, rulesets);
+            _IncludeReplacer.replace(_styleSheet!, node, rulesets);
           }
         }
       }
 
-      if (mixinDef.definedArgs.isNotEmpty && node.include.args.isNotEmpty) {
+      if (mixinDef!.definedArgs.isNotEmpty && node.include.args.isNotEmpty) {
         var callMixin = _createCallDeclMixin(mixinDef);
         mixinDef = callMixin.transform(node.include.args);
       }
 
       if (mixinDef is MixinDeclarationDirective) {
         _IncludeReplacer.replace(
-            _styleSheet, node, mixinDef.declarations.declarations);
+            _styleSheet!, node, mixinDef.declarations.declarations);
       }
     } else {
       _messages.warning('Undefined mixin ${node.include.name}', node.span);
@@ -786,7 +788,7 @@
       if (currDef is MixinDeclarationDirective &&
           mixinDef is MixinDeclarationDirective) {
         _IncludeReplacer.replace(
-            _styleSheet, node, mixinDef.declarations.declarations);
+            _styleSheet!, node, mixinDef.declarations.declarations);
       } else if (currDef is MixinDeclarationDirective) {
         var decls =
             (currDef as MixinDeclarationDirective).declarations.declarations;
@@ -903,8 +905,8 @@
 class AllExtends extends Visitor {
   final inherits = <String, List<SelectorGroup>>{};
 
-  SelectorGroup _currSelectorGroup;
-  int _currDeclIndex;
+  SelectorGroup? _currSelectorGroup;
+  int? _currDeclIndex;
   final _extendsToRemove = <int>[];
 
   @override
@@ -924,13 +926,13 @@
       inheritName += selector.toString();
     }
     if (inherits.containsKey(inheritName)) {
-      inherits[inheritName].add(_currSelectorGroup);
+      inherits[inheritName]!.add(_currSelectorGroup!);
     } else {
-      inherits[inheritName] = [_currSelectorGroup];
+      inherits[inheritName] = [_currSelectorGroup!];
     }
 
     // Remove this @extend
-    _extendsToRemove.add(_currDeclIndex);
+    _extendsToRemove.add(_currDeclIndex!);
 
     super.visitExtendDeclaration(node);
   }
@@ -940,8 +942,10 @@
     var oldDeclIndex = _currDeclIndex;
 
     var decls = node.declarations;
-    for (_currDeclIndex = 0; _currDeclIndex < decls.length; _currDeclIndex++) {
-      decls[_currDeclIndex].visit(this);
+    for (_currDeclIndex = 0;
+        _currDeclIndex! < decls.length;
+        _currDeclIndex = _currDeclIndex! + 1) {
+      decls[_currDeclIndex!].visit(this);
     }
 
     if (_extendsToRemove.isNotEmpty) {
diff --git a/lib/src/css_printer.dart b/lib/src/css_printer.dart
index e7298dc..0f5b822 100644
--- a/lib/src/css_printer.dart
+++ b/lib/src/css_printer.dart
@@ -101,7 +101,7 @@
   @override
   void visitSupportsDirective(SupportsDirective node) {
     emit('$_newLine@supports ');
-    node.condition.visit(this);
+    node.condition!.visit(this);
     emit('$_sp{');
     for (var rule in node.groupRuleBody) {
       rule.visit(this);
@@ -112,7 +112,7 @@
   @override
   void visitSupportsConditionInParens(SupportsConditionInParens node) {
     emit('(');
-    node.condition.visit(this);
+    node.condition!.visit(this);
     emit(')');
   }
 
@@ -150,7 +150,7 @@
   @override
   void visitMediaDirective(MediaDirective node) {
     emit('$_newLine@media');
-    emitMediaQueries(node.mediaQueries);
+    emitMediaQueries(node.mediaQueries.cast<MediaQuery>());
     emit('$_sp{');
     for (var ruleset in node.rules) {
       ruleset.visit(this);
@@ -175,7 +175,7 @@
     emit('$_newLine@page');
     if (node.hasIdent || node.hasPseudoPage) {
       if (node.hasIdent) emit(' ');
-      emit(node._ident);
+      emit(node._ident!);
       emit(node.hasPseudoPage ? ':${node._pseudoPage}' : '');
     }
 
@@ -215,7 +215,7 @@
   @override
   void visitKeyFrameDirective(KeyFrameDirective node) {
     emit('$_newLine${node.keyFrameName} ');
-    node.name.visit(this);
+    node.name!.visit(this);
     emit('$_sp{$_newLine');
     for (final block in node._blocks) {
       block.visit(this);
@@ -249,7 +249,7 @@
   void visitNamespaceDirective(NamespaceDirective node) {
     bool isStartingQuote(String ch) => ('\'"'.contains(ch));
 
-    if (isStartingQuote(node._uri)) {
+    if (isStartingQuote(node._uri!)) {
       emit(' @namespace ${node.prefix}"${node._uri}"');
     } else {
       if (_isTesting) {
@@ -303,7 +303,7 @@
   @override
   void visitRuleSet(RuleSet node) {
     emit('$_newLine');
-    node.selectorGroup.visit(this);
+    node.selectorGroup!.visit(this);
     emit('$_sp{$_newLine');
     node.declarationGroup.visit(this);
     emit('}');
@@ -340,7 +340,7 @@
   @override
   void visitDeclaration(Declaration node) {
     emit('${node.property}:$_sp');
-    node.expression.visit(this);
+    node.expression!.visit(this);
     if (node.important) {
       emit('$_sp!important');
     }
@@ -349,7 +349,7 @@
   @override
   void visitVarDefinition(VarDefinition node) {
     emit('var-${node.definedName}: ');
-    node.expression.visit(this);
+    node.expression!.visit(this);
   }
 
   @override
@@ -439,7 +439,7 @@
   @override
   void visitNegationSelector(NegationSelector node) {
     emit(':not(');
-    node.negationArg.visit(this);
+    node.negationArg!.visit(this);
     emit(')');
   }
 
@@ -470,7 +470,7 @@
 
   @override
   void visitHexColorTerm(HexColorTerm node) {
-    String mappedName;
+    String? mappedName;
     if (_isTesting && (node.value is! BAD_HEX_VALUE)) {
       mappedName = TokenKind.hexToColorName(node.value);
     }
diff --git a/lib/src/messages.dart b/lib/src/messages.dart
index b93a554..0f4ff4d 100644
--- a/lib/src/messages.dart
+++ b/lib/src/messages.dart
@@ -12,7 +12,7 @@
 //              compilation state.
 
 /// The global [Messages] for tracking info/warnings/messages.
-Messages messages;
+late Messages messages;
 
 // Color constants used for generating messages.
 const _greenColor = '\u001b[32m';
@@ -38,7 +38,7 @@
 class Message {
   final MessageLevel level;
   final String message;
-  final SourceSpan span;
+  final SourceSpan? span;
   final bool useColors;
 
   Message(this.level, this.message, {this.span, this.useColors = false});
@@ -56,7 +56,7 @@
       output.write(message);
     } else {
       output.write('on ');
-      output.write(span.message(message, color: levelColor));
+      output.write(span!.message(message, color: levelColor));
     }
 
     return output.toString();
@@ -73,11 +73,11 @@
 
   final List<Message> messages = <Message>[];
 
-  Messages({PreprocessorOptions options, this.printHandler = print})
+  Messages({PreprocessorOptions? options, this.printHandler = print})
       : options = options ?? PreprocessorOptions();
 
   /// Report a compile-time CSS error.
-  void error(String message, SourceSpan span) {
+  void error(String message, SourceSpan? span) {
     var msg = Message(MessageLevel.severe, message,
         span: span, useColors: options.useColors);
 
@@ -87,7 +87,7 @@
   }
 
   /// Report a compile-time CSS warning.
-  void warning(String message, SourceSpan span) {
+  void warning(String message, SourceSpan? span) {
     if (options.warningsAsErrors) {
       error(message, span);
     } else {
diff --git a/lib/src/polyfill.dart b/lib/src/polyfill.dart
index 0c2ef04..389b89c 100644
--- a/lib/src/polyfill.dart
+++ b/lib/src/polyfill.dart
@@ -19,7 +19,7 @@
 
   /// Run the analyzer on every file that is a style sheet or any component that
   /// has a style tag.
-  void process(StyleSheet styleSheet, {List<StyleSheet> includes}) {
+  void process(StyleSheet styleSheet, {List<StyleSheet>? includes}) {
     if (includes != null) {
       processVarDefinitions(includes);
     }
@@ -85,8 +85,8 @@
   final Map<String, VarDefinition> _knownVarDefs;
   final varDefs = <String, VarDefinition>{};
 
-  VarDefinition currVarDefinition;
-  List<Expression> currentExpressions;
+  VarDefinition? currVarDefinition;
+  List<Expression>? currentExpressions;
 
   _VarDefAndUsage(this._messages, this._knownVarDefs);
 
@@ -122,14 +122,14 @@
 
   @override
   void visitVarUsage(VarUsage node) {
-    if (currVarDefinition != null && currVarDefinition.badUsage) return;
+    if (currVarDefinition != null && currVarDefinition!.badUsage) return;
 
     // Don't process other var() inside of a varUsage.  That implies that the
     // default is a var() too.  Also, don't process any var() inside of a
     // varDefinition (they're just place holders until we've resolved all real
     // usages.
     var expressions = currentExpressions;
-    var index = expressions.indexOf(node);
+    var index = expressions!.indexOf(node);
     assert(index >= 0);
     var def = _knownVarDefs[node.name];
     if (def != null) {
@@ -138,14 +138,14 @@
         expressions.removeAt(index);
         return;
       }
-      _resolveVarUsage(currentExpressions, index,
+      _resolveVarUsage(currentExpressions!, index,
           _findTerminalVarDefinition(_knownVarDefs, def));
     } else if (node.defaultValues.any((e) => e is VarUsage)) {
       // Don't have a VarDefinition need to use default values resolve all
       // default values.
       var terminalDefaults = <Expression>[];
       for (var defaultValue in node.defaultValues) {
-        terminalDefaults.addAll(resolveUsageTerminal(defaultValue));
+        terminalDefaults.addAll(resolveUsageTerminal(defaultValue as VarUsage));
       }
       expressions.replaceRange(index, index + 1, terminalDefaults);
     } else if (node.defaultValues.isNotEmpty) {
@@ -153,10 +153,10 @@
       expressions.replaceRange(index, index + 1, node.defaultValues);
     } else {
       if (currVarDefinition != null) {
-        currVarDefinition.badUsage = true;
+        currVarDefinition!.badUsage = true;
         var mainStyleSheetDef = varDefs[node.name];
         if (mainStyleSheetDef != null) {
-          varDefs.remove(currVarDefinition.property);
+          varDefs.remove(currVarDefinition!.property);
         }
       }
       // Remove var usage that points at an undefined definition.
diff --git a/lib/src/preprocessor_options.dart b/lib/src/preprocessor_options.dart
index 8df2680..2ca67dc 100644
--- a/lib/src/preprocessor_options.dart
+++ b/lib/src/preprocessor_options.dart
@@ -32,7 +32,7 @@
   final bool useColors;
 
   /// File to process by the compiler.
-  final String inputFile;
+  final String? inputFile;
 
   const PreprocessorOptions(
       {this.verbose = false,
diff --git a/lib/src/property.dart b/lib/src/property.dart
index 0fb79fb..a8c3c80 100644
--- a/lib/src/property.dart
+++ b/lib/src/property.dart
@@ -22,7 +22,7 @@
   ///
   /// then _cssExpression would return 'rgba(255,255,0)'.  See
   /// <http://www.w3.org/TR/CSS21/grammar.html>
-  String get cssExpression;
+  String? get cssExpression;
 }
 
 /// Base interface for Color, HSL and RGB.
@@ -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]) : _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
@@ -62,7 +62,7 @@
   /// '0' (completely transparent) to '1.0' (completely opaque).  It will
   /// 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])
+  Color.createRgba(int red, int green, int blue, [num? alpha])
       : _argb = Color.convertToHexString(
             Color._clamp(red, 0, 255),
             Color._clamp(green, 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) : _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
@@ -86,7 +86,7 @@
   /// '0' (completely transparent foreground) to '1.0' (completely opaque
   /// foreground).
   Color.createHsla(num hueDegree, num saturationPercent, num lightnessPercent,
-      [num alpha])
+      [num? alpha])
       : _argb = Hsla(
                 Color._clamp(hueDegree, 0, 360) / 360,
                 Color._clamp(saturationPercent, 0, 100) / 100,
@@ -107,7 +107,7 @@
   ///   [alpha]      level of translucency range of values is 0..1, zero is a
   ///                completely transparent foreground and 1 is a completely
   ///                opaque foreground.
-  Color.hslaRaw(num hue, num saturation, num lightness, [num alpha])
+  Color.hslaRaw(num hue, num saturation, num lightness, [num? alpha])
       : _argb = Hsla(
                 Color._clamp(hue, 0, 1),
                 Color._clamp(saturation, 0, 1),
@@ -143,7 +143,7 @@
 
   Rgba get rgba {
     var nextIndex = 0;
-    num a;
+    num? a;
     if (_argb.length == 8) {
       // Get alpha blending value 0..255
       var alpha = Color.hexToInt(_argb.substring(nextIndex, nextIndex + 2));
@@ -200,8 +200,8 @@
 
   // Conversion routines:
 
-  static String _rgbToArgbString(int rgba, num alpha) {
-    int a;
+  static String _rgbToArgbString(int rgba, num? alpha) {
+    num? a;
     // If alpha is defined then adjust from 0..1 to 0..255 value, if not set
     // then a is left as undefined and passed to convertToHexString.
     if (alpha != null) {
@@ -223,7 +223,7 @@
   /// Parse CSS expressions of the from #rgb, rgb(r,g,b), rgba(r,g,b,a),
   /// hsl(h,s,l), hsla(h,s,l,a) and SVG colors (e.g., darkSlateblue, etc.) and
   /// convert to argb.
-  static String _convertCssToArgb(String value) {
+  static String? _convertCssToArgb(String value) {
     // TODO(terry): Better parser/regex for converting CSS properties.
     var color = value.trim().replaceAll('\\s', '');
     if (color[0] == '#') {
@@ -257,9 +257,11 @@
       }
       switch (type) {
         case _rgbCss:
-          return Color.convertToHexString(args[0], args[1], args[2]);
+          return Color.convertToHexString(
+              args[0] as int, args[1] as int, args[2] as int);
         case _rgbaCss:
-          return Color.convertToHexString(args[0], args[1], args[2], args[3]);
+          return Color.convertToHexString(
+              args[0] as int, args[1] as int, args[2] as int, args[3]);
         case _hslCss:
           return Hsla(args[0], args[1], args[2]).toHexArgbString();
         case _hslaCss:
@@ -275,7 +277,7 @@
 
   static int hexToInt(String hex) => int.parse(hex, radix: 16);
 
-  static String convertToHexString(int r, int g, int b, [num a]) {
+  static String convertToHexString(int r, int g, int b, [num? a]) {
     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));
@@ -298,7 +300,7 @@
     return hex;
   }
 
-  static num _clamp(num value, num min, num max) =>
+  static T _clamp<T extends num>(T value, T min, T max) =>
       math.max(math.min(max, value), min);
 
   /// Change the tint (make color lighter) or shade (make color darker) of all
@@ -497,9 +499,9 @@
   final int r;
   final int g;
   final int b;
-  final num a;
+  final num? a;
 
-  Rgba(int red, int green, int blue, [num alpha])
+  Rgba(int red, int green, int blue, [num? alpha])
       : r = Color._clamp(red, 0, 255),
         g = Color._clamp(green, 0, 255),
         b = Color._clamp(blue, 0, 255),
@@ -597,7 +599,7 @@
   int get argbValue {
     var value = 0;
     if (a != null) {
-      value = (a.toInt() << 0x18);
+      value = (a!.toInt() << 0x18);
     }
     value += (r << 0x10);
     value += (g << 0x08);
@@ -623,13 +625,13 @@
   final num _h; // Value from 0..1
   final num _s; // Value from 0..1
   final num _l; // Value from 0..1
-  final num _a; // Value from 0..1
+  final num? _a; // Value from 0..1
 
   /// [hue] is a 0..1 fraction of 360 degrees (360 == 0).
   /// [saturation] is a 0..1 fraction (100% == 1).
   /// [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])
+  Hsla(num hue, num saturation, num lightness, [num? alpha])
       : _h = (hue == 1) ? 0 : Color._clamp(hue, 0, 1),
         _s = Color._clamp(saturation, 0, 1),
         _l = Color._clamp(lightness, 0, 1),
@@ -652,9 +654,7 @@
     var b = value.toInt() & 0xff;
 
     // Convert alpha to 0..1 from (0..255).
-    if (a != null) {
-      a = double.parse((a / 255).toStringAsPrecision(2));
-    }
+    a = double.parse((a / 255).toStringAsPrecision(2));
 
     return _createFromRgba(r, g, b, a);
   }
@@ -662,7 +662,7 @@
   factory Hsla.fromRgba(Rgba rgba) =>
       _createFromRgba(rgba.r, rgba.g, rgba.b, rgba.a);
 
-  static Hsla _createFromRgba(num r, num g, num b, num a) {
+  static Hsla _createFromRgba(num r, num g, num b, num? a) {
     // Convert RGB to hsl.
     // See site <http://easyrgb.com/index.php?X=MATH> for good documentation
     // and color conversion routines.
@@ -725,7 +725,7 @@
   num get lightnessPercentage => (_l * 100).round();
 
   /// Returns number as 0..1
-  num get alpha => _a;
+  num? get alpha => _a;
 
   @override
   bool operator ==(other) => Color.equal(this, other);
@@ -759,7 +759,7 @@
   const PointXY(this.x, this.y);
 
   @override
-  String get cssExpression {
+  String? get cssExpression {
     // TODO(terry): TBD
     return null;
   }
@@ -768,7 +768,7 @@
 // TODO(terry): Implement style and color.
 /// Supports border for measuring with layout.
 class Border implements _StyleProperty {
-  final int top, left, bottom, right;
+  final int? top, left, bottom, right;
 
   // TODO(terry): Just like CSS, 1-arg -> set all properties, 2-args -> top and
   //               bottom are first arg, left and right are second, 3-args, and
@@ -776,14 +776,14 @@
   const Border([this.top, this.left, this.bottom, this.right]);
 
   // TODO(terry): Consider using Size or width and height.
-  Border.uniform(num amount)
+  Border.uniform(int amount)
       : top = amount,
         left = amount,
         bottom = amount,
         right = amount;
 
-  int get width => left + right;
-  int get height => top + bottom;
+  int get width => left! + right!;
+  int get height => top! + bottom!;
 
   @override
   String get cssExpression {
@@ -967,7 +967,7 @@
   // TODO(terry): Should support the values xx-small, small, large, xx-large,
   //              etc. (mapped to a pixel sized font)?
   /// Font size in pixels.
-  final num size;
+  final num? size;
 
   // TODO(terry): _family should be an immutable list, wrapper class to do this
   //              should exist in Dart.
@@ -975,20 +975,20 @@
   /// the first known/supported font.  There are two types of font families the
   /// family-name (e.g., arial, times, courier, etc) or the generic-family
   /// (e.g., serif, sans-seric, etc.)
-  final List<String> family;
+  final List<String>? family;
 
   /// Font weight from 100, 200, 300, 400, 500, 600, 700, 800, 900
-  final int weight;
+  final int? weight;
 
   /// Style of a font normal, italic, oblique.
-  final String style;
+  final String? style;
 
   /// Font variant NORMAL (default) or SMALL_CAPS.  Different set of font glyph
   /// lower case letters designed to have to fit within the font-height and
   /// weight of the corresponding lowercase letters.
-  final String variant;
+  final String? variant;
 
-  final LineHeight lineHeight;
+  final LineHeight? lineHeight;
 
   // TODO(terry): Size and computedLineHeight are in pixels.  Need to figure out
   //              how to handle in other units (specified in other units) like
@@ -1015,7 +1015,7 @@
 
   /// Merge the two fonts and return the result. See [Style.merge] for
   /// more information.
-  factory Font.merge(Font a, Font b) {
+  static Font? merge(Font? a, Font? b) {
     if (a == null) return b;
     if (b == null) return a;
     return Font._merge(a, b);
@@ -1050,7 +1050,7 @@
   }
 
   Font scale(num ratio) => Font(
-      size: size * ratio,
+      size: size! * ratio,
       family: family,
       weight: weight,
       style: style,
@@ -1063,34 +1063,33 @@
   /// ~1.2, and CSS suggest a ration from 1 to 1.2 of the font-size when
   /// computing line-height. The Font class constructor has the computation for
   /// _lineHeight.
-  num get lineHeightInPixels {
+  num? get lineHeightInPixels {
     if (lineHeight != null) {
-      if (lineHeight.inPixels) {
-        return lineHeight.height;
+      if (lineHeight!.inPixels) {
+        return lineHeight!.height;
       } else {
-        return (size != null) ? lineHeight.height * size : null;
+        return (size != null) ? lineHeight!.height * size! : null;
       }
     } else {
-      return (size != null) ? size * 1.2 : null;
+      return (size != null) ? size! * 1.2 : null;
     }
   }
 
   @override
   int get hashCode {
     // TODO(jimhug): Lot's of potential collisions here. List of fonts, etc.
-    return size.toInt() % family[0].hashCode;
+    return size!.toInt() % family![0].hashCode;
   }
 
   @override
   bool operator ==(other) {
     if (other is! Font) return false;
-    Font o = other;
-    return o.size == size &&
-        o.family == family &&
-        o.weight == weight &&
-        o.lineHeight == lineHeight &&
-        o.style == style &&
-        o.variant == variant;
+    return other.size == size &&
+        other.family == family &&
+        other.weight == weight &&
+        other.lineHeight == lineHeight &&
+        other.style == style &&
+        other.variant == variant;
   }
 
   // TODO(terry): This is fragile should probably just iterate through the list
@@ -1113,16 +1112,16 @@
 /// [box model]: https://developer.mozilla.org/en/CSS/box_model
 class BoxEdge {
   /// The size of the left edge, or null if the style has no edge.
-  final num left;
+  final num? left;
 
   /// The size of the top edge, or null if the style has no edge.
-  final num top;
+  final num? top;
 
   /// The size of the right edge, or null if the style has no edge.
-  final num right;
+  final num? right;
 
   /// The size of the bottom edge, or null if the style has no edge.
-  final num bottom;
+  final num? bottom;
 
   /// Creates a box edge with the specified [left], [top], [right], and
   /// [bottom] width.
@@ -1145,7 +1144,7 @@
 
   /// Takes a possibly null box edge, with possibly null metrics, and fills
   /// them in with 0 instead.
-  factory BoxEdge.nonNull(BoxEdge other) {
+  factory BoxEdge.nonNull(BoxEdge? other) {
     if (other == null) return const BoxEdge(0, 0, 0, 0);
     var left = other.left;
     var top = other.top;
@@ -1173,7 +1172,7 @@
 
   /// Merge the two box edge sizes and return the result. See [Style.merge] for
   /// more information.
-  factory BoxEdge.merge(BoxEdge x, BoxEdge y) {
+  static BoxEdge? merge(BoxEdge? x, BoxEdge? y) {
     if (x == null) return y;
     if (y == null) return x;
     return BoxEdge._merge(x, y);
diff --git a/lib/src/token.dart b/lib/src/token.dart
index 444b8ee..f3a2885 100644
--- a/lib/src/token.dart
+++ b/lib/src/token.dart
@@ -47,7 +47,7 @@
 
 /// A token containing error information.
 class ErrorToken extends Token {
-  String message;
+  String? message;
   ErrorToken(int kind, FileSpan span, this.message) : super(kind, span);
 }
 
diff --git a/lib/src/token_kind.dart b/lib/src/token_kind.dart
index 492800e..32cbd69 100644
--- a/lib/src/token_kind.dart
+++ b/lib/src/token_kind.dart
@@ -518,7 +518,7 @@
     return matchList(MEDIA_OPERATORS, 'type', text, offset, length);
   }
 
-  static String idToValue(var identList, int tokenId) {
+  static String? idToValue(var identList, int tokenId) {
     for (var entry in identList) {
       if (tokenId == entry['type']) {
         return entry['value'];
@@ -546,19 +546,20 @@
 
   /// Match color name, case insensitive match and return the associated color
   /// entry from _EXTENDED_COLOR_NAMES list, return [:null:] if not found.
-  static Map matchColorName(String text) {
+  static Map? matchColorName(String text) {
     var name = text.toLowerCase();
-    return _EXTENDED_COLOR_NAMES.firstWhere((e) => e['name'] == name,
-        orElse: () => null);
+    for (var color in _EXTENDED_COLOR_NAMES) {
+      if (color['name'] == name) return color;
+    }
+    return null;
   }
 
   /// Return RGB value as [int] from a color entry in _EXTENDED_COLOR_NAMES.
   static int colorValue(Map entry) {
-    assert(entry != null);
     return entry['value'];
   }
 
-  static String hexToColorName(hexValue) {
+  static String? hexToColorName(hexValue) {
     for (final entry in _EXTENDED_COLOR_NAMES) {
       if (entry['value'] == hexValue) {
         return entry['name'];
diff --git a/lib/src/tokenizer.dart b/lib/src/tokenizer.dart
index de28cb3..07316be 100644
--- a/lib/src/tokenizer.dart
+++ b/lib/src/tokenizer.dart
@@ -176,8 +176,7 @@
         }
         return _finishToken(TokenKind.DOLLAR);
       case TokenChar.BANG:
-        var tok = finishIdentifier();
-        return (tok == null) ? _finishToken(TokenKind.BANG) : tok;
+        return finishIdentifier();
       default:
         // TODO(jmesserly): this is used for IE8 detection; I'm not sure it's
         // appropriate outside of a few specific places; certainly shouldn't
@@ -243,7 +242,7 @@
   }
 
   @override
-  Token _errorToken([String message]) {
+  Token _errorToken([String? message]) {
     return _finishToken(TokenKind.ERROR);
   }
 
diff --git a/lib/src/tokenizer_base.dart b/lib/src/tokenizer_base.dart
index 5f22112..bb44fee 100644
--- a/lib/src/tokenizer_base.dart
+++ b/lib/src/tokenizer_base.dart
@@ -111,7 +111,7 @@
     return Token(kind, _file.span(_startIndex, _index));
   }
 
-  Token _errorToken([String message]) {
+  Token _errorToken([String? message]) {
     return ErrorToken(
         TokenKind.ERROR, _file.span(_startIndex, _index), message);
   }
@@ -186,7 +186,7 @@
     }
   }
 
-  int readHex([int hexLength]) {
+  int readHex([int? hexLength]) {
     int maxIndex;
     if (hexLength == null) {
       maxIndex = _text.length - 1;
diff --git a/lib/src/tree.dart b/lib/src/tree.dart
index d1c330f..2e987ce 100644
--- a/lib/src/tree.dart
+++ b/lib/src/tree.dart
@@ -11,7 +11,7 @@
 class Identifier extends TreeNode {
   String name;
 
-  Identifier(this.name, SourceSpan span) : super(span);
+  Identifier(this.name, SourceSpan? span) : super(span);
 
   @override
   Identifier clone() => Identifier(name, span);
@@ -29,7 +29,7 @@
 }
 
 class Wildcard extends TreeNode {
-  Wildcard(SourceSpan span) : super(span);
+  Wildcard(SourceSpan? span) : super(span);
   @override
   Wildcard clone() => Wildcard(span);
   @override
@@ -39,7 +39,7 @@
 }
 
 class ThisOperator extends TreeNode {
-  ThisOperator(SourceSpan span) : super(span);
+  ThisOperator(SourceSpan? span) : super(span);
   @override
   ThisOperator clone() => ThisOperator(span);
   @override
@@ -49,7 +49,7 @@
 }
 
 class Negation extends TreeNode {
-  Negation(SourceSpan span) : super(span);
+  Negation(SourceSpan? span) : super(span);
   @override
   Negation clone() => Negation(span);
   @override
@@ -64,7 +64,7 @@
 class CalcTerm extends LiteralTerm {
   final LiteralTerm expr;
 
-  CalcTerm(var value, String t, this.expr, SourceSpan span)
+  CalcTerm(var value, String t, this.expr, SourceSpan? span)
       : super(value, t, span);
 
   @override
@@ -80,7 +80,7 @@
 class CssComment extends TreeNode {
   final String comment;
 
-  CssComment(this.comment, SourceSpan span) : super(span);
+  CssComment(this.comment, SourceSpan? span) : super(span);
   @override
   CssComment clone() => CssComment(comment, span);
   @override
@@ -89,7 +89,7 @@
 
 // CDO/CDC (Comment Definition Open <!-- and Comment Definition Close -->).
 class CommentDefinition extends CssComment {
-  CommentDefinition(String comment, SourceSpan span) : super(comment, span);
+  CommentDefinition(String comment, SourceSpan? span) : super(comment, span);
   @override
   CommentDefinition clone() => CommentDefinition(comment, span);
   @override
@@ -99,7 +99,7 @@
 class SelectorGroup extends TreeNode {
   final List<Selector> selectors;
 
-  SelectorGroup(this.selectors, SourceSpan span) : super(span);
+  SelectorGroup(this.selectors, SourceSpan? span) : super(span);
 
   @override
   SelectorGroup clone() => SelectorGroup(selectors, span);
@@ -111,7 +111,7 @@
 class Selector extends TreeNode {
   final List<SimpleSelectorSequence> simpleSelectorSequences;
 
-  Selector(this.simpleSelectorSequences, SourceSpan span) : super(span);
+  Selector(this.simpleSelectorSequences, SourceSpan? span) : super(span);
 
   void add(SimpleSelectorSequence seq) => simpleSelectorSequences.add(seq);
 
@@ -134,7 +134,7 @@
   int combinator;
   final SimpleSelector simpleSelector;
 
-  SimpleSelectorSequence(this.simpleSelector, SourceSpan span,
+  SimpleSelectorSequence(this.simpleSelector, SourceSpan? span,
       [int combinator = TokenKind.COMBINATOR_NONE])
       : combinator = combinator,
         super(span);
@@ -178,7 +178,7 @@
 abstract class SimpleSelector extends TreeNode {
   final dynamic _name; // Wildcard, ThisOperator, Identifier, Negation, others?
 
-  SimpleSelector(this._name, SourceSpan span) : super(span);
+  SimpleSelector(this._name, SourceSpan? span) : super(span);
 
   String get name => _name.name;
 
@@ -192,7 +192,7 @@
 
 // element name
 class ElementSelector extends SimpleSelector {
-  ElementSelector(name, SourceSpan span) : super(name, span);
+  ElementSelector(name, SourceSpan? span) : super(name, span);
   @override
   dynamic visit(VisitorBase visitor) => visitor.visitElementSelector(this);
 
@@ -207,7 +207,7 @@
 class NamespaceSelector extends SimpleSelector {
   final dynamic _namespace; // null, Wildcard or Identifier
 
-  NamespaceSelector(this._namespace, var name, SourceSpan span)
+  NamespaceSelector(this._namespace, var name, SourceSpan? span)
       : super(name, span);
 
   String get namespace =>
@@ -215,7 +215,7 @@
 
   bool get isNamespaceWildcard => _namespace is Wildcard;
 
-  SimpleSelector get nameAsSimpleSelector => _name;
+  SimpleSelector? get nameAsSimpleSelector => _name;
 
   @override
   NamespaceSelector clone() => NamespaceSelector(_namespace, '', span);
@@ -224,7 +224,7 @@
   dynamic visit(VisitorBase visitor) => visitor.visitNamespaceSelector(this);
 
   @override
-  String toString() => '$namespace|${nameAsSimpleSelector.name}';
+  String toString() => '$namespace|${nameAsSimpleSelector!.name}';
 }
 
 // [attr op value]
@@ -232,12 +232,12 @@
   final int _op;
   final dynamic value;
 
-  AttributeSelector(Identifier name, this._op, this.value, SourceSpan span)
+  AttributeSelector(Identifier name, this._op, this.value, SourceSpan? span)
       : super(name, span);
 
   int get operatorKind => _op;
 
-  String matchOperator() {
+  String? matchOperator() {
     switch (_op) {
       case TokenKind.EQUALS:
         return '=';
@@ -258,7 +258,7 @@
   }
 
   // Return the TokenKind for operator used by visitAttributeSelector.
-  String matchOperatorAsTokenString() {
+  String? matchOperatorAsTokenString() {
     switch (_op) {
       case TokenKind.EQUALS:
         return 'EQUALS';
@@ -300,7 +300,7 @@
 
 // #id
 class IdSelector extends SimpleSelector {
-  IdSelector(Identifier name, SourceSpan span) : super(name, span);
+  IdSelector(Identifier name, SourceSpan? span) : super(name, span);
   @override
   IdSelector clone() => IdSelector(_name, span);
   @override
@@ -312,7 +312,7 @@
 
 // .class
 class ClassSelector extends SimpleSelector {
-  ClassSelector(Identifier name, SourceSpan span) : super(name, span);
+  ClassSelector(Identifier name, SourceSpan? span) : super(name, span);
   @override
   ClassSelector clone() => ClassSelector(_name, span);
   @override
@@ -324,7 +324,7 @@
 
 // :pseudoClass
 class PseudoClassSelector extends SimpleSelector {
-  PseudoClassSelector(Identifier name, SourceSpan span) : super(name, span);
+  PseudoClassSelector(Identifier name, SourceSpan? span) : super(name, span);
   @override
   dynamic visit(VisitorBase visitor) => visitor.visitPseudoClassSelector(this);
 
@@ -340,7 +340,7 @@
   // If true, this is a CSS2.1 pseudo-element with only a single ':'.
   final bool isLegacy;
 
-  PseudoElementSelector(Identifier name, SourceSpan span,
+  PseudoElementSelector(Identifier name, SourceSpan? span,
       {this.isLegacy = false})
       : super(name, span);
   @override
@@ -358,7 +358,7 @@
 class PseudoClassFunctionSelector extends PseudoClassSelector {
   final TreeNode argument; // Selector, SelectorExpression
 
-  PseudoClassFunctionSelector(Identifier name, this.argument, SourceSpan span)
+  PseudoClassFunctionSelector(Identifier name, this.argument, SourceSpan? span)
       : super(name, span);
 
   @override
@@ -378,7 +378,7 @@
   final SelectorExpression expression;
 
   PseudoElementFunctionSelector(
-      Identifier name, this.expression, SourceSpan span)
+      Identifier name, this.expression, SourceSpan? span)
       : super(name, span);
 
   @override
@@ -393,7 +393,10 @@
 class SelectorExpression extends TreeNode {
   final List<Expression> expressions;
 
-  SelectorExpression(this.expressions, SourceSpan span) : super(span);
+  SelectorExpression(this.expressions, SourceSpan? span) : super(span);
+
+  @override
+  SourceSpan get span => super.span!;
 
   @override
   SelectorExpression clone() {
@@ -406,9 +409,9 @@
 
 // :NOT(negation_arg)
 class NegationSelector extends SimpleSelector {
-  final SimpleSelector negationArg;
+  final SimpleSelector? negationArg;
 
-  NegationSelector(this.negationArg, SourceSpan span)
+  NegationSelector(this.negationArg, SourceSpan? span)
       : super(Negation(span), span);
 
   @override
@@ -432,14 +435,17 @@
   /// Contains charset, ruleset, directives (media, page, etc.), and selectors.
   final List<TreeNode> topLevels;
 
-  StyleSheet(this.topLevels, SourceSpan span) : super(span) {
+  StyleSheet(this.topLevels, SourceSpan? span) : super(span) {
     for (final node in topLevels) {
       assert(node is TopLevelProduction || node is Directive);
     }
   }
 
   /// Selectors only in this tree.
-  StyleSheet.selector(this.topLevels, SourceSpan span) : super(span);
+  StyleSheet.selector(this.topLevels, SourceSpan? span) : super(span);
+
+  @override
+  SourceSpan get span => super.span!;
 
   @override
   StyleSheet clone() {
@@ -452,7 +458,9 @@
 }
 
 class TopLevelProduction extends TreeNode {
-  TopLevelProduction(SourceSpan span) : super(span);
+  TopLevelProduction(SourceSpan? span) : super(span);
+  @override
+  SourceSpan get span => super.span!;
   @override
   TopLevelProduction clone() => TopLevelProduction(span);
   @override
@@ -460,15 +468,15 @@
 }
 
 class RuleSet extends TopLevelProduction {
-  final SelectorGroup selectorGroup;
+  final SelectorGroup? selectorGroup;
   final DeclarationGroup declarationGroup;
 
-  RuleSet(this.selectorGroup, this.declarationGroup, SourceSpan span)
+  RuleSet(this.selectorGroup, this.declarationGroup, SourceSpan? span)
       : super(span);
 
   @override
   RuleSet clone() {
-    var cloneSelectorGroup = selectorGroup.clone();
+    var cloneSelectorGroup = selectorGroup!.clone();
     var cloneDeclarationGroup = declarationGroup.clone();
     return RuleSet(cloneSelectorGroup, cloneDeclarationGroup, span);
   }
@@ -478,12 +486,15 @@
 }
 
 class Directive extends TreeNode {
-  Directive(SourceSpan span) : super(span);
+  Directive(SourceSpan? span) : super(span);
 
   bool get isBuiltIn => true; // Known CSS directive?
   bool get isExtension => false; // SCSS extension?
 
   @override
+  SourceSpan get span => super.span!;
+
+  @override
   Directive clone() => Directive(span);
   @override
   dynamic visit(VisitorBase visitor) => visitor.visitDirective(this);
@@ -493,7 +504,7 @@
   final List<LiteralTerm> functions;
   final List<TreeNode> groupRuleBody;
 
-  DocumentDirective(this.functions, this.groupRuleBody, SourceSpan span)
+  DocumentDirective(this.functions, this.groupRuleBody, SourceSpan? span)
       : super(span);
 
   @override
@@ -514,15 +525,15 @@
 }
 
 class SupportsDirective extends Directive {
-  final SupportsCondition condition;
+  final SupportsCondition? condition;
   final List<TreeNode> groupRuleBody;
 
-  SupportsDirective(this.condition, this.groupRuleBody, SourceSpan span)
+  SupportsDirective(this.condition, this.groupRuleBody, SourceSpan? span)
       : super(span);
 
   @override
   SupportsDirective clone() {
-    var clonedCondition = condition.clone();
+    var clonedCondition = condition!.clone() as SupportsCondition;
     var clonedGroupRuleBody = <TreeNode>[];
     for (var rule in groupRuleBody) {
       clonedGroupRuleBody.add(rule.clone());
@@ -535,24 +546,27 @@
 }
 
 abstract class SupportsCondition extends TreeNode {
-  SupportsCondition(SourceSpan span) : super(span);
+  SupportsCondition(SourceSpan? span) : super(span);
+  @override
+  SourceSpan get span => super.span!;
 }
 
 class SupportsConditionInParens extends SupportsCondition {
   /// A [Declaration] or nested [SupportsCondition].
-  final TreeNode condition;
+  final TreeNode? condition;
 
-  SupportsConditionInParens(Declaration declaration, SourceSpan span)
+  SupportsConditionInParens(Declaration? declaration, SourceSpan? span)
       : condition = declaration,
         super(span);
 
-  SupportsConditionInParens.nested(SupportsCondition condition, SourceSpan span)
+  SupportsConditionInParens.nested(
+      SupportsCondition condition, SourceSpan? span)
       : condition = condition,
         super(span);
 
   @override
   SupportsConditionInParens clone() =>
-      SupportsConditionInParens(condition.clone(), span);
+      SupportsConditionInParens(condition!.clone() as Declaration, span);
 
   @override
   dynamic visit(VisitorBase visitor) =>
@@ -562,7 +576,7 @@
 class SupportsNegation extends SupportsCondition {
   final SupportsConditionInParens condition;
 
-  SupportsNegation(this.condition, SourceSpan span) : super(span);
+  SupportsNegation(this.condition, SourceSpan? span) : super(span);
 
   @override
   SupportsNegation clone() => SupportsNegation(condition.clone(), span);
@@ -574,7 +588,7 @@
 class SupportsConjunction extends SupportsCondition {
   final List<SupportsConditionInParens> conditions;
 
-  SupportsConjunction(this.conditions, SourceSpan span) : super(span);
+  SupportsConjunction(this.conditions, SourceSpan? span) : super(span);
 
   @override
   SupportsConjunction clone() {
@@ -592,7 +606,7 @@
 class SupportsDisjunction extends SupportsCondition {
   final List<SupportsConditionInParens> conditions;
 
-  SupportsDisjunction(this.conditions, SourceSpan span) : super(span);
+  SupportsDisjunction(this.conditions, SourceSpan? span) : super(span);
 
   @override
   SupportsDisjunction clone() {
@@ -611,7 +625,7 @@
   final String name;
   final DeclarationGroup declarations;
 
-  ViewportDirective(this.name, this.declarations, SourceSpan span)
+  ViewportDirective(this.name, this.declarations, SourceSpan? span)
       : super(span);
 
   @override
@@ -629,7 +643,7 @@
   /// Any media queries for this import.
   final List<MediaQuery> mediaQueries;
 
-  ImportDirective(this.import, this.mediaQueries, SourceSpan span)
+  ImportDirective(this.import, this.mediaQueries, SourceSpan? span)
       : super(span);
 
   @override
@@ -654,12 +668,15 @@
   final Expressions exprs;
 
   MediaExpression(
-      this.andOperator, this._mediaFeature, this.exprs, SourceSpan span)
+      this.andOperator, this._mediaFeature, this.exprs, SourceSpan? span)
       : super(span);
 
   String get mediaFeature => _mediaFeature.name;
 
   @override
+  SourceSpan get span => super.span!;
+
+  @override
   MediaExpression clone() {
     var clonedExprs = exprs.clone();
     return MediaExpression(andOperator, _mediaFeature, clonedExprs, span);
@@ -682,19 +699,23 @@
 class MediaQuery extends TreeNode {
   /// not, only or no operator.
   final int _mediaUnary;
-  final Identifier _mediaType;
+  final Identifier? _mediaType;
   final List<MediaExpression> expressions;
 
   MediaQuery(
-      this._mediaUnary, this._mediaType, this.expressions, SourceSpan span)
+      this._mediaUnary, this._mediaType, this.expressions, SourceSpan? span)
       : super(span);
 
   bool get hasMediaType => _mediaType != null;
-  String get mediaType => _mediaType.name;
+  String get mediaType => _mediaType!.name;
 
   bool get hasUnary => _mediaUnary != -1;
   String get unary =>
-      TokenKind.idToValue(TokenKind.MEDIA_OPERATORS, _mediaUnary).toUpperCase();
+      TokenKind.idToValue(TokenKind.MEDIA_OPERATORS, _mediaUnary)!
+          .toUpperCase();
+
+  @override
+  SourceSpan get span => super.span!;
 
   @override
   MediaQuery clone() {
@@ -713,7 +734,7 @@
   final List<MediaQuery> mediaQueries;
   final List<TreeNode> rules;
 
-  MediaDirective(this.mediaQueries, this.rules, SourceSpan span) : super(span);
+  MediaDirective(this.mediaQueries, this.rules, SourceSpan? span) : super(span);
 
   @override
   MediaDirective clone() {
@@ -735,7 +756,7 @@
 class HostDirective extends Directive {
   final List<TreeNode> rules;
 
-  HostDirective(this.rules, SourceSpan span) : super(span);
+  HostDirective(this.rules, SourceSpan? span) : super(span);
 
   @override
   HostDirective clone() {
@@ -751,12 +772,12 @@
 }
 
 class PageDirective extends Directive {
-  final String _ident;
-  final String _pseudoPage;
+  final String? _ident;
+  final String? _pseudoPage;
   final List<DeclarationGroup> _declsMargin;
 
   PageDirective(
-      this._ident, this._pseudoPage, this._declsMargin, SourceSpan span)
+      this._ident, this._pseudoPage, this._declsMargin, SourceSpan? span)
       : super(span);
 
   @override
@@ -771,14 +792,14 @@
   @override
   dynamic visit(VisitorBase visitor) => visitor.visitPageDirective(this);
 
-  bool get hasIdent => _ident != null && _ident.isNotEmpty;
-  bool get hasPseudoPage => _pseudoPage != null && _pseudoPage.isNotEmpty;
+  bool get hasIdent => _ident?.isNotEmpty ?? false;
+  bool get hasPseudoPage => _pseudoPage?.isNotEmpty ?? false;
 }
 
 class CharsetDirective extends Directive {
   final String charEncoding;
 
-  CharsetDirective(this.charEncoding, SourceSpan span) : super(span);
+  CharsetDirective(this.charEncoding, SourceSpan? span) : super(span);
   @override
   CharsetDirective clone() => CharsetDirective(charEncoding, span);
   @override
@@ -788,10 +809,10 @@
 class KeyFrameDirective extends Directive {
   // Either @keyframe or keyframe prefixed with @-webkit-, @-moz-, @-ms-, @-o-.
   final int _keyframeName;
-  final Identifier name;
+  final Identifier? name;
   final List<KeyFrameBlock> _blocks;
 
-  KeyFrameDirective(this._keyframeName, this.name, SourceSpan span)
+  KeyFrameDirective(this._keyframeName, this.name, SourceSpan? span)
       : _blocks = [],
         super(span);
 
@@ -799,7 +820,7 @@
     _blocks.add(block);
   }
 
-  String get keyFrameName {
+  String? get keyFrameName {
     switch (_keyframeName) {
       case TokenKind.DIRECTIVE_KEYFRAMES:
       case TokenKind.DIRECTIVE_MS_KEYFRAMES:
@@ -816,7 +837,7 @@
 
   @override
   KeyFrameDirective clone() {
-    var directive = KeyFrameDirective(_keyframeName, name.clone(), span);
+    var directive = KeyFrameDirective(_keyframeName, name!.clone(), span);
     for (var block in _blocks) {
       directive.add(block.clone());
     }
@@ -831,7 +852,7 @@
   final Expressions _blockSelectors;
   final DeclarationGroup _declarations;
 
-  KeyFrameBlock(this._blockSelectors, this._declarations, SourceSpan span)
+  KeyFrameBlock(this._blockSelectors, this._declarations, SourceSpan? span)
       : super(span);
 
   @override
@@ -844,7 +865,7 @@
 class FontFaceDirective extends Directive {
   final DeclarationGroup _declarations;
 
-  FontFaceDirective(this._declarations, SourceSpan span) : super(span);
+  FontFaceDirective(this._declarations, SourceSpan? span) : super(span);
 
   @override
   FontFaceDirective clone() => FontFaceDirective(_declarations.clone(), span);
@@ -856,7 +877,7 @@
   final String dartClassName;
   final List<TreeNode> rules;
 
-  StyletDirective(this.dartClassName, this.rules, SourceSpan span)
+  StyletDirective(this.dartClassName, this.rules, SourceSpan? span)
       : super(span);
 
   @override
@@ -882,9 +903,9 @@
   final String _prefix;
 
   /// URI associated with this namespace.
-  final String _uri;
+  final String? _uri;
 
-  NamespaceDirective(this._prefix, this._uri, SourceSpan span) : super(span);
+  NamespaceDirective(this._prefix, this._uri, SourceSpan? span) : super(span);
 
   @override
   NamespaceDirective clone() => NamespaceDirective(_prefix, _uri, span);
@@ -899,7 +920,7 @@
 class VarDefinitionDirective extends Directive {
   final VarDefinition def;
 
-  VarDefinitionDirective(this.def, SourceSpan span) : super(span);
+  VarDefinitionDirective(this.def, SourceSpan? span) : super(span);
 
   @override
   VarDefinitionDirective clone() => VarDefinitionDirective(def.clone(), span);
@@ -914,7 +935,7 @@
   final List<TreeNode> definedArgs;
   final bool varArgs;
 
-  MixinDefinition(this.name, this.definedArgs, this.varArgs, SourceSpan span)
+  MixinDefinition(this.name, this.definedArgs, this.varArgs, SourceSpan? span)
       : super(span);
 
   @override
@@ -935,14 +956,14 @@
   final List<TreeNode> rulesets;
 
   MixinRulesetDirective(String name, List<TreeNode> args, bool varArgs,
-      this.rulesets, SourceSpan span)
+      this.rulesets, SourceSpan? span)
       : super(name, args, varArgs, span);
 
   @override
   MixinRulesetDirective clone() {
     var clonedArgs = <VarDefinition>[];
     for (var arg in definedArgs) {
-      clonedArgs.add(arg.clone());
+      clonedArgs.add(arg.clone() as VarDefinition);
     }
     var clonedRulesets = <TreeNode>[];
     for (var ruleset in rulesets) {
@@ -961,7 +982,7 @@
   final DeclarationGroup declarations;
 
   MixinDeclarationDirective(String name, List<TreeNode> args, bool varArgs,
-      this.declarations, SourceSpan span)
+      this.declarations, SourceSpan? span)
       : super(name, args, varArgs, span);
 
   @override
@@ -984,7 +1005,7 @@
   final String name;
   final List<List<Expression>> args;
 
-  IncludeDirective(this.name, this.args, SourceSpan span) : super(span);
+  IncludeDirective(this.name, this.args, SourceSpan? span) : super(span);
 
   @override
   IncludeDirective clone() {
@@ -1001,18 +1022,18 @@
 
 /// To support Sass @content.
 class ContentDirective extends Directive {
-  ContentDirective(SourceSpan span) : super(span);
+  ContentDirective(SourceSpan? span) : super(span);
 
   @override
   dynamic visit(VisitorBase visitor) => visitor.visitContentDirective(this);
 }
 
 class Declaration extends TreeNode {
-  final Identifier _property;
-  final Expression expression;
+  final Identifier? _property;
+  final Expression? expression;
 
   /// Style exposed to Dart.
-  DartStyleExpression dartStyle;
+  DartStyleExpression? dartStyle;
   final bool important;
 
   /// IE CSS hacks that can only be read by a particular IE version.
@@ -1024,18 +1045,21 @@
   ///   since an ident can start with underscore (e.g., `_background: red;`)
   final bool isIE7;
 
-  Declaration(this._property, this.expression, this.dartStyle, SourceSpan span,
+  Declaration(this._property, this.expression, this.dartStyle, SourceSpan? span,
       {this.important = false, bool ie7 = false})
       : isIE7 = ie7,
         super(span);
 
-  String get property => isIE7 ? '*${_property.name}' : _property.name;
+  String get property => isIE7 ? '*${_property!.name}' : _property!.name;
 
   bool get hasDartStyle => dartStyle != null;
 
   @override
+  SourceSpan get span => super.span!;
+
+  @override
   Declaration clone() =>
-      Declaration(_property.clone(), expression.clone(), dartStyle, span,
+      Declaration(_property!.clone(), expression!.clone(), dartStyle, span,
           important: important);
 
   @override
@@ -1051,14 +1075,14 @@
 class VarDefinition extends Declaration {
   bool badUsage = false;
 
-  VarDefinition(Identifier definedName, Expression expr, SourceSpan span)
+  VarDefinition(Identifier? definedName, Expression? expr, SourceSpan? span)
       : super(definedName, expr, null, span);
 
-  String get definedName => _property.name;
+  String get definedName => _property!.name;
 
   @override
-  VarDefinition clone() => VarDefinition(
-      _property.clone(), expression != null ? expression.clone() : null, span);
+  VarDefinition clone() =>
+      VarDefinition(_property!.clone(), expression?.clone(), span);
 
   @override
   dynamic visit(VisitorBase visitor) => visitor.visitVarDefinition(this);
@@ -1073,7 +1097,7 @@
 class IncludeMixinAtDeclaration extends Declaration {
   final IncludeDirective include;
 
-  IncludeMixinAtDeclaration(this.include, SourceSpan span)
+  IncludeMixinAtDeclaration(this.include, SourceSpan? span)
       : super(null, null, null, span);
 
   @override
@@ -1088,7 +1112,7 @@
 class ExtendDeclaration extends Declaration {
   final List<TreeNode> selectors;
 
-  ExtendDeclaration(this.selectors, SourceSpan span)
+  ExtendDeclaration(this.selectors, SourceSpan? span)
       : super(null, null, null, span);
 
   @override
@@ -1105,7 +1129,10 @@
   /// Can be either Declaration or RuleSet (if nested selector).
   final List<TreeNode> declarations;
 
-  DeclarationGroup(this.declarations, SourceSpan span) : super(span);
+  DeclarationGroup(this.declarations, SourceSpan? span) : super(span);
+
+  @override
+  SourceSpan get span => super.span!;
 
   @override
   DeclarationGroup clone() {
@@ -1120,7 +1147,7 @@
 class MarginGroup extends DeclarationGroup {
   final int margin_sym; // TokenType for for @margin sym.
 
-  MarginGroup(this.margin_sym, List<TreeNode> decls, SourceSpan span)
+  MarginGroup(this.margin_sym, List<TreeNode> decls, SourceSpan? span)
       : super(decls, span);
   @override
   MarginGroup clone() =>
@@ -1133,7 +1160,7 @@
   final String name;
   final List<Expression> defaultValues;
 
-  VarUsage(this.name, this.defaultValues, SourceSpan span) : super(span);
+  VarUsage(this.name, this.defaultValues, SourceSpan? span) : super(span);
 
   @override
   VarUsage clone() {
@@ -1149,7 +1176,7 @@
 }
 
 class OperatorSlash extends Expression {
-  OperatorSlash(SourceSpan span) : super(span);
+  OperatorSlash(SourceSpan? span) : super(span);
   @override
   OperatorSlash clone() => OperatorSlash(span);
   @override
@@ -1157,7 +1184,7 @@
 }
 
 class OperatorComma extends Expression {
-  OperatorComma(SourceSpan span) : super(span);
+  OperatorComma(SourceSpan? span) : super(span);
   @override
   OperatorComma clone() => OperatorComma(span);
   @override
@@ -1165,7 +1192,7 @@
 }
 
 class OperatorPlus extends Expression {
-  OperatorPlus(SourceSpan span) : super(span);
+  OperatorPlus(SourceSpan? span) : super(span);
   @override
   OperatorPlus clone() => OperatorPlus(span);
   @override
@@ -1173,7 +1200,7 @@
 }
 
 class OperatorMinus extends Expression {
-  OperatorMinus(SourceSpan span) : super(span);
+  OperatorMinus(SourceSpan? span) : super(span);
   @override
   OperatorMinus clone() => OperatorMinus(span);
   @override
@@ -1181,10 +1208,10 @@
 }
 
 class UnicodeRangeTerm extends Expression {
-  final String first;
-  final String second;
+  final String? first;
+  final String? second;
 
-  UnicodeRangeTerm(this.first, this.second, SourceSpan span) : super(span);
+  UnicodeRangeTerm(this.first, this.second, SourceSpan? span) : super(span);
 
   bool get hasSecond => second != null;
 
@@ -1202,7 +1229,7 @@
   dynamic value;
   String text;
 
-  LiteralTerm(this.value, this.text, SourceSpan span) : super(span);
+  LiteralTerm(this.value, this.text, SourceSpan? span) : super(span);
 
   @override
   LiteralTerm clone() => LiteralTerm(value, text, span);
@@ -1212,7 +1239,7 @@
 }
 
 class NumberTerm extends LiteralTerm {
-  NumberTerm(value, String t, SourceSpan span) : super(value, t, span);
+  NumberTerm(value, String t, SourceSpan? span) : super(value, t, span);
   @override
   NumberTerm clone() => NumberTerm(value, text, span);
   @override
@@ -1222,7 +1249,8 @@
 class UnitTerm extends LiteralTerm {
   final int unit;
 
-  UnitTerm(value, String t, SourceSpan span, this.unit) : super(value, t, span);
+  UnitTerm(value, String t, SourceSpan? span, this.unit)
+      : super(value, t, span);
 
   @override
   UnitTerm clone() => UnitTerm(value, text, span, unit);
@@ -1237,7 +1265,7 @@
 }
 
 class LengthTerm extends UnitTerm {
-  LengthTerm(value, String t, SourceSpan span,
+  LengthTerm(value, String t, SourceSpan? span,
       [int unit = TokenKind.UNIT_LENGTH_PX])
       : super(value, t, span, unit) {
     assert(this.unit == TokenKind.UNIT_LENGTH_PX ||
@@ -1254,7 +1282,7 @@
 }
 
 class PercentageTerm extends LiteralTerm {
-  PercentageTerm(value, String t, SourceSpan span) : super(value, t, span);
+  PercentageTerm(value, String t, SourceSpan? span) : super(value, t, span);
   @override
   PercentageTerm clone() => PercentageTerm(value, text, span);
   @override
@@ -1262,7 +1290,7 @@
 }
 
 class EmTerm extends LiteralTerm {
-  EmTerm(value, String t, SourceSpan span) : super(value, t, span);
+  EmTerm(value, String t, SourceSpan? span) : super(value, t, span);
   @override
   EmTerm clone() => EmTerm(value, text, span);
   @override
@@ -1270,7 +1298,7 @@
 }
 
 class ExTerm extends LiteralTerm {
-  ExTerm(value, String t, SourceSpan span) : super(value, t, span);
+  ExTerm(value, String t, SourceSpan? span) : super(value, t, span);
   @override
   ExTerm clone() => ExTerm(value, text, span);
   @override
@@ -1278,7 +1306,7 @@
 }
 
 class AngleTerm extends UnitTerm {
-  AngleTerm(var value, String t, SourceSpan span,
+  AngleTerm(var value, String t, SourceSpan? span,
       [int unit = TokenKind.UNIT_LENGTH_PX])
       : super(value, t, span, unit) {
     assert(this.unit == TokenKind.UNIT_ANGLE_DEG ||
@@ -1294,7 +1322,7 @@
 }
 
 class TimeTerm extends UnitTerm {
-  TimeTerm(var value, String t, SourceSpan span,
+  TimeTerm(var value, String t, SourceSpan? span,
       [int unit = TokenKind.UNIT_LENGTH_PX])
       : super(value, t, span, unit) {
     assert(this.unit == TokenKind.UNIT_ANGLE_DEG ||
@@ -1309,7 +1337,7 @@
 }
 
 class FreqTerm extends UnitTerm {
-  FreqTerm(var value, String t, SourceSpan span,
+  FreqTerm(var value, String t, SourceSpan? span,
       [int unit = TokenKind.UNIT_LENGTH_PX])
       : super(value, t, span, unit) {
     assert(unit == TokenKind.UNIT_FREQ_HZ || unit == TokenKind.UNIT_FREQ_KHZ);
@@ -1322,7 +1350,7 @@
 }
 
 class FractionTerm extends LiteralTerm {
-  FractionTerm(var value, String t, SourceSpan span) : super(value, t, span);
+  FractionTerm(var value, String t, SourceSpan? span) : super(value, t, span);
 
   @override
   FractionTerm clone() => FractionTerm(value, text, span);
@@ -1331,7 +1359,7 @@
 }
 
 class UriTerm extends LiteralTerm {
-  UriTerm(String value, SourceSpan span) : super(value, value, span);
+  UriTerm(String value, SourceSpan? span) : super(value, value, span);
 
   @override
   UriTerm clone() => UriTerm(value, span);
@@ -1340,7 +1368,7 @@
 }
 
 class ResolutionTerm extends UnitTerm {
-  ResolutionTerm(var value, String t, SourceSpan span,
+  ResolutionTerm(var value, String t, SourceSpan? span,
       [int unit = TokenKind.UNIT_LENGTH_PX])
       : super(value, t, span, unit) {
     assert(unit == TokenKind.UNIT_RESOLUTION_DPI ||
@@ -1355,7 +1383,7 @@
 }
 
 class ChTerm extends UnitTerm {
-  ChTerm(var value, String t, SourceSpan span,
+  ChTerm(var value, String t, SourceSpan? span,
       [int unit = TokenKind.UNIT_LENGTH_PX])
       : super(value, t, span, unit) {
     assert(unit == TokenKind.UNIT_CH);
@@ -1368,7 +1396,7 @@
 }
 
 class RemTerm extends UnitTerm {
-  RemTerm(var value, String t, SourceSpan span,
+  RemTerm(var value, String t, SourceSpan? span,
       [int unit = TokenKind.UNIT_LENGTH_PX])
       : super(value, t, span, unit) {
     assert(unit == TokenKind.UNIT_REM);
@@ -1381,7 +1409,7 @@
 }
 
 class ViewportTerm extends UnitTerm {
-  ViewportTerm(var value, String t, SourceSpan span,
+  ViewportTerm(var value, String t, SourceSpan? span,
       [int unit = TokenKind.UNIT_LENGTH_PX])
       : super(value, t, span, unit) {
     assert(unit == TokenKind.UNIT_VIEWPORT_VW ||
@@ -1400,7 +1428,7 @@
 class BAD_HEX_VALUE {}
 
 class HexColorTerm extends LiteralTerm {
-  HexColorTerm(var value, String t, SourceSpan span) : super(value, t, span);
+  HexColorTerm(var value, String t, SourceSpan? span) : super(value, t, span);
 
   @override
   HexColorTerm clone() => HexColorTerm(value, text, span);
@@ -1411,7 +1439,7 @@
 class FunctionTerm extends LiteralTerm {
   final Expressions _params;
 
-  FunctionTerm(var value, String t, this._params, SourceSpan span)
+  FunctionTerm(var value, String t, this._params, SourceSpan? span)
       : super(value, t, span);
 
   @override
@@ -1424,7 +1452,7 @@
 /// This is an IE trick to ignore a property or value except by IE 8 and older
 /// browsers.
 class IE8Term extends LiteralTerm {
-  IE8Term(SourceSpan span) : super('\\9', '\\9', span);
+  IE8Term(SourceSpan? span) : super('\\9', '\\9', span);
   @override
   IE8Term clone() => IE8Term(span);
   @override
@@ -1434,7 +1462,7 @@
 class GroupTerm extends Expression {
   final List<LiteralTerm> _terms;
 
-  GroupTerm(SourceSpan span)
+  GroupTerm(SourceSpan? span)
       : _terms = [],
         super(span);
 
@@ -1449,7 +1477,7 @@
 }
 
 class ItemTerm extends NumberTerm {
-  ItemTerm(dynamic value, String t, SourceSpan span) : super(value, t, span);
+  ItemTerm(dynamic value, String t, SourceSpan? span) : super(value, t, span);
 
   @override
   ItemTerm clone() => ItemTerm(value, text, span);
@@ -1460,7 +1488,7 @@
 class Expressions extends Expression {
   final List<Expression> expressions = [];
 
-  Expressions(SourceSpan span) : super(span);
+  Expressions(SourceSpan? span) : super(span);
 
   void add(Expression expression) {
     expressions.add(expression);
@@ -1484,7 +1512,7 @@
   final Expression x;
   final Expression y;
 
-  BinaryExpression(this.op, this.x, this.y, SourceSpan span) : super(span);
+  BinaryExpression(this.op, this.x, this.y, SourceSpan? span) : super(span);
 
   @override
   BinaryExpression clone() => BinaryExpression(op, x.clone(), y.clone(), span);
@@ -1496,7 +1524,7 @@
   final Token op;
   final Expression self;
 
-  UnaryExpression(this.op, this.self, SourceSpan span) : super(span);
+  UnaryExpression(this.op, this.self, SourceSpan? span) : super(span);
 
   @override
   UnaryExpression clone() => UnaryExpression(op, self.clone(), span);
@@ -1513,15 +1541,15 @@
   static const int heightStyle = 5;
   static const int widthStyle = 6;
 
-  final int _styleType;
-  int priority;
+  final int? _styleType;
+  int? priority;
 
-  DartStyleExpression(this._styleType, SourceSpan span) : super(span);
+  DartStyleExpression(this._styleType, SourceSpan? span) : super(span);
 
   // Merges give 2 DartStyleExpression (or derived from DartStyleExpression,
   // e.g., FontExpression, etc.) will merge if the two expressions are of the
   // same property name (implies same exact type e.g, FontExpression).
-  DartStyleExpression merged(DartStyleExpression newDartExpr);
+  DartStyleExpression? merged(DartStyleExpression newDartExpr);
 
   bool get isUnknown => _styleType == 0 || _styleType == null;
   bool get isFont => _styleType == fontStyle;
@@ -1535,6 +1563,9 @@
   bool isSame(DartStyleExpression other) => _styleType == other._styleType;
 
   @override
+  SourceSpan get span => super.span!;
+
+  @override
   dynamic visit(VisitorBase visitor) => visitor.visitDartStyleExpression(this);
 }
 
@@ -1544,13 +1575,13 @@
   //   font-style font-variant font-weight font-size/line-height font-family
   // TODO(terry): Only px/pt for now need to handle all possible units to
   //              support calc expressions on units.
-  FontExpression(SourceSpan span,
-      {Object /* LengthTerm | num */ size,
-      List<String> family,
-      int weight,
-      String style,
-      String variant,
-      LineHeight lineHeight})
+  FontExpression(SourceSpan? span,
+      {Object? /* LengthTerm | num */ size,
+      List<String>? family,
+      int? weight,
+      String? style,
+      String? variant,
+      LineHeight? lineHeight})
       : font = Font(
             size: size is LengthTerm ? size.value : size as num,
             family: family,
@@ -1561,7 +1592,7 @@
         super(DartStyleExpression.fontStyle, span);
 
   @override
-  FontExpression merged(DartStyleExpression newFontExpr) {
+  FontExpression? merged(DartStyleExpression newFontExpr) {
     if (newFontExpr is FontExpression && isFont && newFontExpr.isFont) {
       return FontExpression.merge(this, newFontExpr);
     }
@@ -1573,8 +1604,8 @@
     return FontExpression._merge(x, y, y.span);
   }
 
-  FontExpression._merge(FontExpression x, FontExpression y, SourceSpan span)
-      : font = Font.merge(x.font, y.font),
+  FontExpression._merge(FontExpression x, FontExpression y, SourceSpan? span)
+      : font = Font.merge(x.font, y.font)!,
         super(DartStyleExpression.fontStyle, span);
 
   @override
@@ -1591,22 +1622,24 @@
 }
 
 abstract class BoxExpression extends DartStyleExpression {
-  final BoxEdge box;
+  final BoxEdge? box;
 
-  BoxExpression(int styleType, SourceSpan span, this.box)
+  BoxExpression(int? styleType, SourceSpan? span, this.box)
       : super(styleType, span);
 
   @override
   dynamic 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})';
+    if (box!.top == box!.left &&
+        box!.top == box!.bottom &&
+        box!.top == box!.right) {
+      return '.uniform(${box!.top})';
     } else {
-      var left = box.left ?? 0;
-      var top = box.top ?? 0;
-      var right = box.right ?? 0;
-      var bottom = box.bottom ?? 0;
+      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)';
     }
   }
@@ -1615,15 +1648,16 @@
 class MarginExpression extends BoxExpression {
   // TODO(terry): Does auto for margin need to be exposed to Dart UI framework?
   /// Margin expression ripped apart.
-  MarginExpression(SourceSpan span, {num top, num right, num bottom, num left})
+  MarginExpression(SourceSpan? span,
+      {num? top, num? right, num? bottom, num? left})
       : super(DartStyleExpression.marginStyle, span,
             BoxEdge(left, top, right, bottom));
 
-  MarginExpression.boxEdge(SourceSpan span, BoxEdge box)
+  MarginExpression.boxEdge(SourceSpan? span, BoxEdge? box)
       : super(DartStyleExpression.marginStyle, span, box);
 
   @override
-  MarginExpression merged(DartStyleExpression newMarginExpr) {
+  MarginExpression? merged(DartStyleExpression newMarginExpr) {
     if (newMarginExpr is MarginExpression &&
         isMargin &&
         newMarginExpr.isMargin) {
@@ -1639,12 +1673,12 @@
   }
 
   MarginExpression._merge(
-      MarginExpression x, MarginExpression y, SourceSpan span)
+      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);
+      top: box!.top, right: box!.right, bottom: box!.bottom, left: box!.left);
 
   @override
   dynamic visit(VisitorBase visitor) => visitor.visitMarginExpression(this);
@@ -1652,15 +1686,16 @@
 
 class BorderExpression extends BoxExpression {
   /// Border expression ripped apart.
-  BorderExpression(SourceSpan span, {num top, num right, num bottom, num left})
+  BorderExpression(SourceSpan? span,
+      {num? top, num? right, num? bottom, num? left})
       : super(DartStyleExpression.borderStyle, span,
             BoxEdge(left, top, right, bottom));
 
-  BorderExpression.boxEdge(SourceSpan span, BoxEdge box)
+  BorderExpression.boxEdge(SourceSpan? span, BoxEdge box)
       : super(DartStyleExpression.borderStyle, span, box);
 
   @override
-  BorderExpression merged(DartStyleExpression newBorderExpr) {
+  BorderExpression? merged(DartStyleExpression newBorderExpr) {
     if (newBorderExpr is BorderExpression &&
         isBorder &&
         newBorderExpr.isBorder) {
@@ -1676,13 +1711,13 @@
   }
 
   BorderExpression._merge(
-      BorderExpression x, BorderExpression y, SourceSpan span)
+      BorderExpression x, BorderExpression y, SourceSpan? span)
       : 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);
+      top: box!.top, right: box!.right, bottom: box!.bottom, left: box!.left);
 
   @override
   dynamic visit(VisitorBase visitor) => visitor.visitBorderExpression(this);
@@ -1691,15 +1726,15 @@
 class HeightExpression extends DartStyleExpression {
   final dynamic height;
 
-  HeightExpression(SourceSpan span, this.height)
+  HeightExpression(SourceSpan? span, this.height)
       : super(DartStyleExpression.heightStyle, span);
 
   @override
-  HeightExpression merged(DartStyleExpression newHeightExpr) {
+  HeightExpression? merged(DartStyleExpression newHeightExpr) {
     if (newHeightExpr is DartStyleExpression &&
         isHeight &&
         newHeightExpr.isHeight) {
-      return newHeightExpr;
+      return newHeightExpr as HeightExpression;
     }
 
     return null;
@@ -1714,11 +1749,11 @@
 class WidthExpression extends DartStyleExpression {
   final dynamic width;
 
-  WidthExpression(SourceSpan span, this.width)
+  WidthExpression(SourceSpan? span, this.width)
       : super(DartStyleExpression.widthStyle, span);
 
   @override
-  WidthExpression merged(DartStyleExpression newWidthExpr) {
+  WidthExpression? merged(DartStyleExpression newWidthExpr) {
     if (newWidthExpr is WidthExpression && isWidth && newWidthExpr.isWidth) {
       return newWidthExpr;
     }
@@ -1734,15 +1769,16 @@
 
 class PaddingExpression extends BoxExpression {
   /// Padding expression ripped apart.
-  PaddingExpression(SourceSpan span, {num top, num right, num bottom, num left})
+  PaddingExpression(SourceSpan? span,
+      {num? top, num? right, num? bottom, num? left})
       : super(DartStyleExpression.paddingStyle, span,
             BoxEdge(left, top, right, bottom));
 
-  PaddingExpression.boxEdge(SourceSpan span, BoxEdge box)
+  PaddingExpression.boxEdge(SourceSpan? span, BoxEdge? box)
       : super(DartStyleExpression.paddingStyle, span, box);
 
   @override
-  PaddingExpression merged(DartStyleExpression newPaddingExpr) {
+  PaddingExpression? merged(DartStyleExpression newPaddingExpr) {
     if (newPaddingExpr is PaddingExpression &&
         isPadding &&
         newPaddingExpr.isPadding) {
@@ -1758,13 +1794,13 @@
   }
 
   PaddingExpression._merge(
-      PaddingExpression x, PaddingExpression y, SourceSpan span)
+      PaddingExpression x, PaddingExpression y, SourceSpan? span)
       : 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);
+      top: box!.top, right: box!.right, bottom: box!.bottom, left: box!.left);
   @override
   dynamic visit(VisitorBase visitor) => visitor.visitPaddingExpression(this);
 }
diff --git a/lib/src/tree_base.dart b/lib/src/tree_base.dart
index eef1849..dc7aa76 100644
--- a/lib/src/tree_base.dart
+++ b/lib/src/tree_base.dart
@@ -7,7 +7,7 @@
 /// The base type for all nodes in a CSS abstract syntax tree.
 abstract class TreeNode {
   /// The source code this [TreeNode] represents.
-  final SourceSpan span;
+  final SourceSpan? span;
 
   TreeNode(this.span);
 
@@ -27,14 +27,16 @@
 
 /// The base type for expressions.
 abstract class Expression extends TreeNode {
-  Expression(SourceSpan span) : super(span);
+  Expression(SourceSpan? span) : super(span);
+  @override
+  Expression clone();
 }
 
 /// Simple class to provide a textual dump of trees for debugging.
 class TreeOutput {
   int depth = 0;
   final StringBuffer buf = StringBuffer();
-  VisitorBase printer;
+  VisitorBase? printer;
 
   void write(String s) {
     for (var i = 0; i < depth; i++) {
@@ -66,11 +68,11 @@
     }
   }
 
-  void writeNode(String label, TreeNode node) {
+  void writeNode(String label, TreeNode? node) {
     write('${label}: ');
     depth += 1;
     if (node != null) {
-      node.visit(printer);
+      node.visit(printer!);
     } else {
       writeln('null');
     }
@@ -82,16 +84,12 @@
     writeln('${label}: ${v}');
   }
 
-  void writeNodeList(String label, List<TreeNode> list) {
+  void writeNodeList(String label, List<TreeNode>? list) {
     writeln('${label} [');
     if (list != null) {
       depth += 1;
       for (var node in list) {
-        if (node != null) {
-          node.visit(printer);
-        } else {
-          writeln('null');
-        }
+        node.visit(printer!);
       }
       depth -= 1;
       writeln(']');
diff --git a/lib/src/tree_printer.dart b/lib/src/tree_printer.dart
index b53f214..72f1223 100644
--- a/lib/src/tree_printer.dart
+++ b/lib/src/tree_printer.dart
@@ -374,7 +374,7 @@
 
     super.visitNamespaceSelector(node);
 
-    visitSimpleSelector(node.nameAsSimpleSelector);
+    visitSimpleSelector(node.nameAsSimpleSelector!);
     output.depth--;
   }
 
diff --git a/lib/src/validate.dart b/lib/src/validate.dart
index 4d255e2..ec54553 100644
--- a/lib/src/validate.dart
+++ b/lib/src/validate.dart
@@ -7,7 +7,7 @@
 
 /// Can be thrown on any Css runtime problem includes source location.
 class CssSelectorException extends SourceSpanException {
-  CssSelectorException(String message, [SourceSpan span])
+  CssSelectorException(String message, [SourceSpan? span])
       : super(message, span);
 }
 
diff --git a/lib/visitor.dart b/lib/visitor.dart
index d88081b..de30efc 100644
--- a/lib/visitor.dart
+++ b/lib/visitor.dart
@@ -175,13 +175,13 @@
 
   @override
   dynamic visitSupportsDirective(SupportsDirective node) {
-    node.condition.visit(this);
+    node.condition!.visit(this);
     _visitNodeList(node.groupRuleBody);
   }
 
   @override
   dynamic visitSupportsConditionInParens(SupportsConditionInParens node) {
-    node.condition.visit(this);
+    node.condition!.visit(this);
   }
 
   @override
@@ -238,7 +238,7 @@
 
   @override
   dynamic visitKeyFrameDirective(KeyFrameDirective node) {
-    visitIdentifier(node.name);
+    visitIdentifier(node.name!);
     _visitNodeList(node._blocks);
   }
 
@@ -294,7 +294,7 @@
 
   @override
   dynamic visitRuleSet(RuleSet node) {
-    visitSelectorGroup(node.selectorGroup);
+    visitSelectorGroup(node.selectorGroup!);
     visitDeclarationGroup(node.declarationGroup);
   }
 
@@ -308,14 +308,14 @@
 
   @override
   dynamic visitDeclaration(Declaration node) {
-    visitIdentifier(node._property);
-    if (node.expression != null) node.expression.visit(this);
+    visitIdentifier(node._property!);
+    if (node.expression != null) node.expression!.visit(this);
   }
 
   @override
   dynamic visitVarDefinition(VarDefinition node) {
-    visitIdentifier(node._property);
-    if (node.expression != null) node.expression.visit(this);
+    visitIdentifier(node._property!);
+    if (node.expression != null) node.expression!.visit(this);
   }
 
   @override
@@ -350,7 +350,7 @@
   dynamic visitNamespaceSelector(NamespaceSelector node) {
     if (node._namespace != null) node._namespace.visit(this);
     if (node.nameAsSimpleSelector != null) {
-      node.nameAsSimpleSelector.visit(this);
+      node.nameAsSimpleSelector!.visit(this);
     }
   }
 
diff --git a/pubspec.yaml b/pubspec.yaml
index 62773b9..53be256 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,15 +1,19 @@
 name: csslib
-version: 0.16.3-dev
+version: 0.17.0-nullsafety-dev
 
 description: A library for parsing CSS.
 homepage: https://github.com/dart-lang/csslib
 
 environment:
-  sdk: '>=2.2.0 <3.0.0'
+  sdk: '>=2.10.0-2.0.dev <2.10.0'
 
 dependencies:
-  source_span: ^1.4.0
+  source_span: ^1.8.0-nullsafety
 
 dev_dependencies:
-  pedantic: ^1.0.0
-  test: ^1.2.0
+  pedantic: ^1.10.0-nullsafety
+  test: ^1.16.0-nullsafety.2
+
+dependency_overrides:
+  analyzer: 0.40.0
+  html: 0.14.0+3
diff --git a/test/big_1_test.dart b/test/big_1_test.dart
index 0001777..75bc910 100644
--- a/test/big_1_test.dart
+++ b/test/big_1_test.dart
@@ -11,7 +11,6 @@
 void compilePolyfillAndValidate(String input, String generated) {
   var errors = <Message>[];
   var stylesheet = polyFillCompileCss(input, errors: errors, opts: options);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
diff --git a/test/compiler_test.dart b/test/compiler_test.dart
index a692a64..a27bde1 100644
--- a/test/compiler_test.dart
+++ b/test/compiler_test.dart
@@ -16,7 +16,6 @@
   var input = '.foobar {}';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -26,10 +25,11 @@
   expect(stylesheet.topLevels[0] is RuleSet, true);
 
   var ruleset = stylesheet.topLevels[0] as RuleSet;
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  var selectorSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  var selectorSeqs =
+      ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
   expect(selectorSeqs.length, 1);
   final simpSelector = selectorSeqs[0].simpleSelector;
   expect(simpSelector is ClassSelector, true);
@@ -42,7 +42,6 @@
   var input = '.foobar .bar .no-story {}';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -51,10 +50,10 @@
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
   var ruleset = stylesheet.topLevels[0] as RuleSet;
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  var simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
   expect(simpleSeqs.length, 3);
 
   var simpSelector0 = simpleSeqs[0].simpleSelector;
@@ -78,7 +77,6 @@
   var input = '#elemId {}';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -87,10 +85,10 @@
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
   var ruleset = stylesheet.topLevels[0] as RuleSet;
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  var simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
 
   expect(simpleSeqs.length, 1);
   var simpSelector = simpleSeqs[0].simpleSelector;
@@ -104,7 +102,6 @@
   var input = 'div {}';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -113,10 +110,10 @@
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
   var ruleset = stylesheet.topLevels[0] as RuleSet;
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  var simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
 
   expect(simpleSeqs.length, 1);
 
@@ -128,7 +125,6 @@
   input = 'div div span {}';
   stylesheet = parseCss(input, errors: errors..clear());
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -136,11 +132,11 @@
   expect(stylesheet.topLevels.length, 1);
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
-  ruleset = stylesheet.topLevels[0];
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  ruleset = stylesheet.topLevels[0] as RuleSet;
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
 
   expect(simpleSeqs.length, 3);
 
@@ -165,7 +161,6 @@
   var input = 'ns1|div {}';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -174,10 +169,10 @@
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
   var ruleset = stylesheet.topLevels[0] as RuleSet;
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  var simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
 
   expect(simpleSeqs.length, 1);
   expect(simpleSeqs[0].simpleSelector is NamespaceSelector, true);
@@ -187,7 +182,7 @@
   expect(simpSelector.namespace, 'ns1');
   var elementSelector = simpSelector.nameAsSimpleSelector;
   expect(elementSelector is ElementSelector, true);
-  expect(elementSelector.isWildcard, false);
+  expect(elementSelector!.isWildcard, false);
   expect(elementSelector.name, 'div');
 }
 
@@ -196,7 +191,6 @@
   var input = 'ns1|div div ns2|span .foobar {}';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -205,10 +199,10 @@
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
   var ruleset = stylesheet.topLevels[0] as RuleSet;
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  var simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
 
   expect(simpleSeqs.length, 4);
 
@@ -218,7 +212,7 @@
   expect(simpSelector0.namespace, 'ns1');
   var elementSelector0 = simpSelector0.nameAsSimpleSelector;
   expect(elementSelector0 is ElementSelector, true);
-  expect(elementSelector0.isWildcard, false);
+  expect(elementSelector0!.isWildcard, false);
   expect(elementSelector0.name, 'div');
 
   var simpSelector1 = simpleSeqs[1].simpleSelector;
@@ -232,7 +226,7 @@
   expect(simpSelector2.namespace, 'ns2');
   var elementSelector2 = simpSelector2.nameAsSimpleSelector;
   expect(elementSelector2 is ElementSelector, true);
-  expect(elementSelector2.isWildcard, false);
+  expect(elementSelector2!.isWildcard, false);
   expect(elementSelector2.name, 'span');
 
   var simpSelector3 = simpleSeqs[3].simpleSelector;
@@ -247,7 +241,6 @@
       'div, .foobar ,#elemId, .xyzzy .test, ns1|div div #elemId .foobar {}';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -256,10 +249,10 @@
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
   var ruleset = stylesheet.topLevels[0] as RuleSet;
-  expect(ruleset.selectorGroup.selectors.length, 5);
+  expect(ruleset.selectorGroup!.selectors.length, 5);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  var groupSelector0 = ruleset.selectorGroup.selectors[0];
+  var groupSelector0 = ruleset.selectorGroup!.selectors[0];
   expect(groupSelector0.simpleSelectorSequences.length, 1);
   var selector0 = groupSelector0.simpleSelectorSequences[0];
   var simpleSelector0 = selector0.simpleSelector;
@@ -267,7 +260,7 @@
   expect(selector0.isCombinatorNone, true);
   expect(simpleSelector0.name, 'div');
 
-  var groupSelector1 = ruleset.selectorGroup.selectors[1];
+  var groupSelector1 = ruleset.selectorGroup!.selectors[1];
   expect(groupSelector1.simpleSelectorSequences.length, 1);
   var selector1 = groupSelector1.simpleSelectorSequences[0];
   var simpleSelector1 = selector1.simpleSelector;
@@ -275,7 +268,7 @@
   expect(selector1.isCombinatorNone, true);
   expect(simpleSelector1.name, 'foobar');
 
-  var groupSelector2 = ruleset.selectorGroup.selectors[2];
+  var groupSelector2 = ruleset.selectorGroup!.selectors[2];
   expect(groupSelector2.simpleSelectorSequences.length, 1);
   var selector2 = groupSelector2.simpleSelectorSequences[0];
   var simpleSelector2 = selector2.simpleSelector;
@@ -283,7 +276,7 @@
   expect(selector2.isCombinatorNone, true);
   expect(simpleSelector2.name, 'elemId');
 
-  var groupSelector3 = ruleset.selectorGroup.selectors[3];
+  var groupSelector3 = ruleset.selectorGroup!.selectors[3];
   expect(groupSelector3.simpleSelectorSequences.length, 2);
 
   var selector30 = groupSelector3.simpleSelectorSequences[0];
@@ -298,7 +291,7 @@
   expect(selector31.isCombinatorDescendant, true);
   expect(simpleSelector31.name, 'test');
 
-  var groupSelector4 = ruleset.selectorGroup.selectors[4];
+  var groupSelector4 = ruleset.selectorGroup!.selectors[4];
   expect(groupSelector4.simpleSelectorSequences.length, 4);
 
   var selector40 = groupSelector4.simpleSelectorSequences[0];
@@ -308,7 +301,7 @@
   expect(simpleSelector40.namespace, 'ns1');
   var elementSelector = simpleSelector40.nameAsSimpleSelector;
   expect(elementSelector is ElementSelector, true);
-  expect(elementSelector.isWildcard, false);
+  expect(elementSelector!.isWildcard, false);
   expect(elementSelector.name, 'div');
 
   var selector41 = groupSelector4.simpleSelectorSequences[1];
@@ -334,7 +327,6 @@
   var input = '.foobar > .bar + .no-story ~ myNs|div #elemId {}';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -343,10 +335,10 @@
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
   var ruleset = stylesheet.topLevels[0] as RuleSet;
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  var simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
 
   expect(simpleSeqs.length, 5);
 
@@ -375,7 +367,7 @@
   expect(simpleSelector3.namespace, 'myNs');
   var elementSelector = simpleSelector3.nameAsSimpleSelector;
   expect(elementSelector is ElementSelector, true);
-  expect(elementSelector.isWildcard, false);
+  expect(elementSelector!.isWildcard, false);
   expect(elementSelector.name, 'div');
 
   var selector4 = simpleSeqs[4];
@@ -390,7 +382,6 @@
   var input = '* {}';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -399,10 +390,10 @@
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
   var ruleset = stylesheet.topLevels[0] as RuleSet;
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  var simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  var simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
 
   expect(simpleSeqs.length, 1);
   var simpSelector = simpleSeqs[0].simpleSelector;
@@ -414,7 +405,6 @@
   input = '*.foobar {}';
   stylesheet = parseCss(input, errors: errors..clear());
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -422,11 +412,11 @@
   expect(stylesheet.topLevels.length, 1);
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
-  ruleset = stylesheet.topLevels[0];
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  ruleset = stylesheet.topLevels[0] as RuleSet;
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
 
   expect(simpleSeqs.length, 2);
 
@@ -448,7 +438,6 @@
   input = 'myNs|*.foobar {}';
   stylesheet = parseCss(input, errors: errors..clear());
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -456,11 +445,11 @@
   expect(stylesheet.topLevels.length, 1);
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
-  ruleset = stylesheet.topLevels[0];
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  ruleset = stylesheet.topLevels[0] as RuleSet;
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
 
   expect(simpleSeqs.length, 2);
 
@@ -472,7 +461,7 @@
     expect(simpleSelector0.isNamespaceWildcard, false);
     var elementSelector = simpleSelector0.nameAsSimpleSelector;
     expect('myNs', simpleSelector0.namespace);
-    expect(elementSelector.isWildcard, true);
+    expect(elementSelector!.isWildcard, true);
     expect('*', elementSelector.name);
   }
 
@@ -485,17 +474,16 @@
   input = '*|*.foobar {}';
   stylesheet = parseCss(input, errors: errors..clear());
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
 
   expect(stylesheet.topLevels[0] is RuleSet, true);
-  ruleset = stylesheet.topLevels[0];
-  expect(ruleset.selectorGroup.selectors.length, 1);
+  ruleset = stylesheet.topLevels[0] as RuleSet;
+  expect(ruleset.selectorGroup!.selectors.length, 1);
   expect(ruleset.declarationGroup.declarations.length, 0);
 
-  simpleSeqs = ruleset.selectorGroup.selectors[0].simpleSelectorSequences;
+  simpleSeqs = ruleset.selectorGroup!.selectors[0].simpleSelectorSequences;
 
   expect(simpleSeqs.length, 2);
 
@@ -507,7 +495,7 @@
     expect(simpleSelector0.isNamespaceWildcard, true);
     expect('*', simpleSelector0.namespace);
     var elementSelector = simpleSelector0.nameAsSimpleSelector;
-    expect(elementSelector.isWildcard, true);
+    expect(elementSelector!.isWildcard, true);
     expect('*', elementSelector.name);
   }
 
@@ -530,7 +518,6 @@
 
   var stylesheet = parse(utf8.encode(input), errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   expect(prettyPrint(stylesheet), r'''
@@ -593,7 +580,6 @@
 
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), r'''
 html:lang(fr-ca) {
@@ -663,7 +649,6 @@
       '}';
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), r'''
 @host {
@@ -688,7 +673,6 @@
   var errors = <Message>[];
   var input = r'''a { foo: '{"text" : "a\\\""}' }''';
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   expect(prettyPrint(stylesheet), r'''
@@ -708,7 +692,6 @@
       '}';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
@@ -736,7 +719,6 @@
 }''';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   walkTree(stylesheet);
diff --git a/test/declaration_test.dart b/test/declaration_test.dart
index 61f04f5..6cccc9c 100644
--- a/test/declaration_test.dart
+++ b/test/declaration_test.dart
@@ -51,7 +51,6 @@
 
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 
@@ -66,7 +65,6 @@
 
   stylesheet = parseCss(input2, errors: errors..clear());
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated2);
 
@@ -79,7 +77,7 @@
   stylesheet = parseCss(css, errors: errors..clear(), opts: simpleOptions);
   expect(errors, isNotEmpty);
   expect(errors.first.message, 'expected }, but found %');
-  expect(errors.first.span.text, '%');
+  expect(errors.first.span!.text, '%');
 }
 
 /// Declarations with comments, references with single-quotes, double-quotes,
@@ -117,7 +115,6 @@
 
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -145,7 +142,6 @@
   var stylesheet = parseCss(input, errors: errors);
 
   expect(errors.isEmpty, true, reason: errors.toString());
-  expect(stylesheet != null, true);
   expect(prettyPrint(stylesheet), generated);
 }
 
@@ -173,7 +169,6 @@
 }''';
 
   var stylesheet = parseCss(input, errors: errors);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -257,7 +252,6 @@
 
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -285,7 +279,6 @@
 
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -339,7 +332,6 @@
 
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -366,7 +358,6 @@
 }''';
 
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 
@@ -414,7 +405,6 @@
 
   stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 
@@ -431,7 +421,6 @@
 
   stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 
@@ -448,7 +437,6 @@
 
   stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 
@@ -459,7 +447,6 @@
 
   stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 
@@ -475,7 +462,7 @@
   expect(errors, isNotEmpty);
   expect(
       errors.first.message, contains('expected { after media before ruleset'));
-  expect(errors.first.span.text, '(');
+  expect(errors.first.span!.text, '(');
 
   // Test nested at-rules.
   input = '''
@@ -647,7 +634,7 @@
   expect(errors, isNotEmpty);
   expect(errors.first.message,
       "Operators can't be mixed without a layer of parentheses");
-  expect(errors.first.span.text, 'or');
+  expect(errors.first.span!.text, 'or');
 }
 
 void testViewport() {
@@ -696,7 +683,6 @@
 }''';
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 
@@ -714,7 +700,6 @@
 
   stylesheet = parseCss(input1, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated1);
 
@@ -731,7 +716,6 @@
 
   stylesheet = parseCss(input2, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated2);
 
@@ -750,7 +734,6 @@
 
   stylesheet = parseCss(input3, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated3);
 
@@ -767,7 +750,6 @@
 }''';
   stylesheet = parseCss(input4, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated4);
 }
@@ -838,7 +820,6 @@
       '}';
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -887,7 +868,6 @@
 
   var stylesheet = parseCss(input, errors: errors);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(compactOutput(stylesheet), generated);
 
@@ -897,7 +877,6 @@
 
   var stylesheet2 = parseCss(input2, errors: errors..clear());
 
-  expect(stylesheet2 != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(compactOutput(stylesheet2), generated2);
 }
@@ -987,7 +966,6 @@
 
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -1005,7 +983,6 @@
 
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 
@@ -1023,7 +1000,6 @@
 
   stylesheet = parseCss(input2, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated2);
 
@@ -1053,7 +1029,6 @@
 
   stylesheet = parseCss(input3, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated3);
 
@@ -1064,7 +1039,6 @@
 
   stylesheet = parseCss(input4, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), input4);
 }
@@ -1238,7 +1212,6 @@
 }''';
 
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -1248,31 +1221,30 @@
 
   // Bad hexvalue had caused a hang in processTerm.
   final input = r'''#a { color: #ebebeburl(0/IE8+9+); }''';
-  var stylesheet = parseCss(input, errors: errors, opts: options);
+  parseCss(input, errors: errors, opts: options);
 
-  expect(stylesheet != null, true);
   expect(errors.length, 3, reason: errors.toString());
 
   var errorMessage = errors[0];
   expect(errorMessage.message, contains('Bad hex number'));
   expect(errorMessage.span, isNotNull);
-  expect(errorMessage.span.start.line, 0);
-  expect(errorMessage.span.start.column, 12);
-  expect(errorMessage.span.text, '#ebebeburl');
+  expect(errorMessage.span!.start.line, 0);
+  expect(errorMessage.span!.start.column, 12);
+  expect(errorMessage.span!.text, '#ebebeburl');
 
   errorMessage = errors[1];
   expect(errorMessage.message, contains('expected }, but found +'));
   expect(errorMessage.span, isNotNull);
-  expect(errorMessage.span.start.line, 0);
-  expect(errorMessage.span.start.column, 30);
-  expect(errorMessage.span.text, '+');
+  expect(errorMessage.span!.start.line, 0);
+  expect(errorMessage.span!.start.column, 30);
+  expect(errorMessage.span!.text, '+');
 
   errorMessage = errors[2];
   expect(errorMessage.message, contains('premature end of file unknown CSS'));
   expect(errorMessage.span, isNotNull);
-  expect(errorMessage.span.start.line, 0);
-  expect(errorMessage.span.start.column, 31);
-  expect(errorMessage.span.text, ')');
+  expect(errorMessage.span!.start.line, 0);
+  expect(errorMessage.span!.start.column, 31);
+  expect(errorMessage.span!.text, ')');
 
   // Missing closing parenthesis for keyframes.
   final input2 = r'''@-ms-keyframes progress-bar-stripes {
@@ -1284,18 +1256,16 @@
   }
 ''';
 
-  stylesheet = parseCss(input2, errors: errors..clear(), opts: options);
-
-  expect(stylesheet != null, true);
+  parseCss(input2, errors: errors..clear(), opts: options);
 
   expect(errors.length, 1, reason: errors.toString());
 
   errorMessage = errors[0];
   expect(errorMessage.message, contains('unexpected end of file'));
   expect(errorMessage.span, isNotNull);
-  expect(errorMessage.span.start.line, 7);
-  expect(errorMessage.span.start.column, 0);
-  expect(errorMessage.span.text.trim(), '');
+  expect(errorMessage.span!.start.line, 7);
+  expect(errorMessage.span!.start.column, 0);
+  expect(errorMessage.span!.text.trim(), '');
 }
 
 void testExpressionSpans() {
@@ -1306,9 +1276,9 @@
       .declarations
       .single;
   // This passes
-  expect(decl.span.text, 'width: 50px');
+  expect(decl.span!.text, 'width: 50px');
   // This currently fails
-  expect((decl as Declaration).expression.span.text, '50px');
+  expect((decl as Declaration).expression!.span!.text, '50px');
 }
 
 void testComments() {
@@ -1328,7 +1298,7 @@
       .declarationGroup
       .declarations
       .single;
-  expect(decl.span.text, 'height: calc(100% - 55px)');
+  expect(decl.span!.text, 'height: calc(100% - 55px)');
 }
 
 void complexCalc() {
@@ -1338,7 +1308,7 @@
       .declarationGroup
       .declarations
       .single;
-  expect(decl.span.text, 'left: calc((100%/3 - 2) * 1em - 2 * 1px)');
+  expect(decl.span!.text, 'left: calc((100%/3 - 2) * 1em - 2 * 1px)');
 }
 
 void twoCalcs() {
@@ -1348,7 +1318,7 @@
       .declarationGroup
       .declarations
       .single;
-  expect(decl.span.text, 'margin: calc(1rem - 2px) calc(1rem - 1px)');
+  expect(decl.span!.text, 'margin: calc(1rem - 2px) calc(1rem - 1px)');
 }
 
 void selectorWithCalcs() {
@@ -1371,7 +1341,6 @@
 }''';
 
   var stylesheet = parseCss(input, errors: errors);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
diff --git a/test/error_test.dart b/test/error_test.dart
index 5822c4c..5b211c2 100644
--- a/test/error_test.dart
+++ b/test/error_test.dart
@@ -25,7 +25,6 @@
 1 │ .foobar { font-weight: bolder; }
   │                        ^^^^^^
   ╵''');
-  expect(stylesheet != null, true);
 
   expect(prettyPrint(stylesheet), r'''
 .foobar {
@@ -44,7 +43,6 @@
 1 │ .foobar { font-weight: lighter; }
   │                        ^^^^^^^
   ╵''');
-  expect(stylesheet != null, true);
   expect(prettyPrint(stylesheet), r'''
 .foobar {
   font-weight: lighter;
@@ -62,7 +60,6 @@
 1 │ .foobar { font-weight: inherit; }
   │                        ^^^^^^^
   ╵''');
-  expect(stylesheet != null, true);
   expect(prettyPrint(stylesheet), r'''
 .foobar {
   font-weight: inherit;
@@ -85,7 +82,6 @@
 1 │ .foobar { line-height: 120%; }
   │                        ^^^
   ╵''');
-  expect(stylesheet != null, true);
   expect(prettyPrint(stylesheet), r'''
 .foobar {
   line-height: 120%;
@@ -103,7 +99,6 @@
 1 │ .foobar { line-height: 20cm; }
   │                        ^^
   ╵''');
-  expect(stylesheet != null, true);
   expect(prettyPrint(stylesheet), r'''
 .foobar {
   line-height: 20cm;
@@ -121,7 +116,6 @@
 1 │ .foobar { line-height: inherit; }
   │                        ^^^^^^^
   ╵''');
-  expect(stylesheet != null, true);
   expect(prettyPrint(stylesheet), r'''
 .foobar {
   line-height: inherit;
@@ -172,7 +166,6 @@
 1 │ .foobar { color: #AH787; }
   │                  ^^^^^^
   ╵''');
-  expect(stylesheet != null, true);
   expect(prettyPrint(stylesheet), r'''
 .foobar {
   color: #AH787;
@@ -190,7 +183,6 @@
   │                  ^^^^^^
   ╵''');
 
-  expect(stylesheet != null, true);
   expect(prettyPrint(stylesheet), r'''
 .foobar {
   color: redder;
@@ -208,7 +200,6 @@
   │                  ^
   ╵''');
 
-  expect(stylesheet != null, true);
   expect(prettyPrint(stylesheet), r'''
 .foobar {
   color: # ffffff;
@@ -226,8 +217,6 @@
   │                  ^
   ╵''');
 
-  expect(stylesheet != null, true);
-
   // Formating is off with an extra space.  However, the entire value is bad
   // and isn't processed anyway.
   expect(prettyPrint(stylesheet), r'''
@@ -294,9 +283,9 @@
   var errorMessage = messages.messages[0];
   expect(errorMessage.message, contains('Bad hex number'));
   expect(errorMessage.span, isNotNull);
-  expect(errorMessage.span.start.line, 4);
-  expect(errorMessage.span.start.column, 11);
-  expect(errorMessage.span.text, '#ffghghgh');
+  expect(errorMessage.span!.start.line, 4);
+  expect(errorMessage.span!.start.column, 11);
+  expect(errorMessage.span!.text, '#ffghghgh');
 
   // Test for bad selector syntax.
   final input2 = '''
@@ -311,30 +300,30 @@
   errorMessage = messages.messages[0];
   expect(errorMessage.message, contains(':, but found +'));
   expect(errorMessage.span, isNotNull);
-  expect(errorMessage.span.start.line, 1);
-  expect(errorMessage.span.start.column, 7);
-  expect(errorMessage.span.text, '+');
+  expect(errorMessage.span!.start.line, 1);
+  expect(errorMessage.span!.start.column, 7);
+  expect(errorMessage.span!.text, '+');
 
   errorMessage = messages.messages[1];
   expect(errorMessage.message, contains('Unknown property value ul'));
   expect(errorMessage.span, isNotNull);
-  expect(errorMessage.span.start.line, 1);
-  expect(errorMessage.span.start.column, 9);
-  expect(errorMessage.span.text, 'ul');
+  expect(errorMessage.span!.start.line, 1);
+  expect(errorMessage.span!.start.column, 9);
+  expect(errorMessage.span!.text, 'ul');
 
   errorMessage = messages.messages[2];
   expect(errorMessage.message, contains('expected }, but found >'));
   expect(errorMessage.span, isNotNull);
-  expect(errorMessage.span.start.line, 1);
-  expect(errorMessage.span.start.column, 18);
-  expect(errorMessage.span.text, '>');
+  expect(errorMessage.span!.start.line, 1);
+  expect(errorMessage.span!.start.column, 18);
+  expect(errorMessage.span!.text, '>');
 
   errorMessage = messages.messages[3];
   expect(errorMessage.message, contains('premature end of file unknown CSS'));
   expect(errorMessage.span, isNotNull);
-  expect(errorMessage.span.start.line, 1);
-  expect(errorMessage.span.start.column, 20);
-  expect(errorMessage.span.text, '(');
+  expect(errorMessage.span!.start.line, 1);
+  expect(errorMessage.span!.start.column, 20);
+  expect(errorMessage.span!.text, '(');
 
   // Test for missing close braces and bad declaration.
   final input3 = '''
@@ -348,16 +337,16 @@
   errorMessage = messages.messages[0];
   expect(errorMessage.message, contains('Bad hex number'));
   expect(errorMessage.span, isNotNull);
-  expect(errorMessage.span.start.line, 2);
-  expect(errorMessage.span.start.column, 11);
-  expect(errorMessage.span.text, '#green');
+  expect(errorMessage.span!.start.line, 2);
+  expect(errorMessage.span!.start.column, 11);
+  expect(errorMessage.span!.text, '#green');
 
   errorMessage = messages.messages[1];
   expect(errorMessage.message, contains('expected }, but found end of file'));
   expect(errorMessage.span, isNotNull);
-  expect(errorMessage.span.start.line, 3);
-  expect(errorMessage.span.start.column, 1);
-  expect(errorMessage.span.text, '\n');
+  expect(errorMessage.span!.start.line, 3);
+  expect(errorMessage.span!.start.column, 1);
+  expect(errorMessage.span!.text, '\n');
 }
 
 void main() {
diff --git a/test/extend_test.dart b/test/extend_test.dart
index 38e0ea0..37b433a 100644
--- a/test/extend_test.dart
+++ b/test/extend_test.dart
@@ -12,7 +12,6 @@
 void compileAndValidate(String input, String generated) {
   var errors = <Message>[];
   var stylesheet = compileCss(input, errors: errors, opts: options);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
diff --git a/test/mixin_test.dart b/test/mixin_test.dart
index f562f38..0432b1c 100644
--- a/test/mixin_test.dart
+++ b/test/mixin_test.dart
@@ -12,7 +12,6 @@
 void compileAndValidate(String input, String generated) {
   var errors = <Message>[];
   var stylesheet = compileCss(input, errors: errors, opts: options);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -20,7 +19,6 @@
 void compilePolyfillAndValidate(String input, String generated) {
   var errors = <Message>[];
   var stylesheet = polyFillCompileCss(input, errors: errors, opts: options);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -442,15 +440,14 @@
 @include b;
 ''';
 
-  var stylesheet = compileCss(input, errors: errors, opts: options);
+  compileCss(input, errors: errors, opts: options);
 
-  expect(stylesheet != null, true);
   expect(errors.isNotEmpty, true);
   expect(errors.length, 1, reason: errors.toString());
   var error = errors[0];
   expect(error.message, 'Using top-level mixin a as a declaration');
-  expect(error.span.start.line, 8);
-  expect(error.span.end.offset, 105);
+  expect(error.span!.start.line, 8);
+  expect(error.span!.end.offset, 105);
 }
 
 void badTopInclude() {
@@ -470,13 +467,13 @@
 @include a;
   ''';
 
-  var stylesheet = compileCss(input, errors: errors, opts: options);
-  expect(stylesheet != null, true);
+  compileCss(input, errors: errors, opts: options);
+
   expect(errors.length, 1, reason: errors.toString());
   var error = errors[0];
   expect(error.message, 'Using declaration mixin b as top-level mixin');
-  expect(error.span.start.line, 8);
-  expect(error.span.end.offset, 90);
+  expect(error.span!.start.line, 8);
+  expect(error.span!.end.offset, 90);
 }
 
 void emptyMixin() {
@@ -500,7 +497,6 @@
 
   var stylesheet = compileCss(input, errors: errors, opts: options);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -522,15 +518,14 @@
 
   ''';
 
-  var stylesheet = compileCss(input, errors: errors, opts: options);
+  compileCss(input, errors: errors, opts: options);
 
-  expect(stylesheet != null, true);
   expect(errors.isNotEmpty, true);
   expect(errors.length, 1, reason: errors.toString());
   var error = errors[0];
   expect(error.message, 'Undefined mixin b');
-  expect(error.span.start.line, 1);
-  expect(error.span.start.offset, 14);
+  expect(error.span!.start.line, 1);
+  expect(error.span!.start.offset, 14);
 }
 
 void undefinedDeclaration() {
@@ -548,15 +543,14 @@
 }
   ''';
 
-  var stylesheet = compileCss(input, errors: errors, opts: options);
+  compileCss(input, errors: errors, opts: options);
 
-  expect(stylesheet != null, true);
   expect(errors.isNotEmpty, true);
   expect(errors.length, 1, reason: errors.toString());
   var error = errors[0];
   expect(error.message, 'Undefined mixin b');
-  expect(error.span.start.line, 1);
-  expect(error.span.start.offset, 14);
+  expect(error.span!.start.line, 1);
+  expect(error.span!.start.offset, 14);
 }
 
 void includeGrammar() {
@@ -608,36 +602,34 @@
 @include b
 ''';
 
-  var stylesheet = compileCss(input, errors: errors, opts: options);
-
-  expect(stylesheet != null, true);
+  compileCss(input, errors: errors, opts: options);
 
   expect(errors.isNotEmpty, true);
   expect(errors.length, 6, reason: errors.toString());
   var error = errors[0];
   expect(error.message, 'parsing error expected ;');
-  expect(error.span.start.line, 6);
-  expect(error.span.end.offset, 69);
+  expect(error.span!.start.line, 6);
+  expect(error.span!.end.offset, 69);
   error = errors[1];
   expect(error.message, 'expected :, but found }');
-  expect(error.span.start.line, 7);
-  expect(error.span.end.offset, 73);
+  expect(error.span!.start.line, 7);
+  expect(error.span!.end.offset, 73);
   error = errors[2];
   expect(error.message, 'parsing error expected }');
-  expect(error.span.start.line, 9);
-  expect(error.span.end.offset, 83);
+  expect(error.span!.start.line, 9);
+  expect(error.span!.end.offset, 83);
   error = errors[3];
   expect(error.message, 'expected {, but found end of file()');
-  expect(error.span.start.line, 9);
-  expect(error.span.end.offset, 86);
+  expect(error.span!.start.line, 9);
+  expect(error.span!.end.offset, 86);
   error = errors[4];
   expect(error.message, 'expected }, but found end of file()');
-  expect(error.span.start.line, 10);
-  expect(error.span.end.offset, 86);
+  expect(error.span!.start.line, 10);
+  expect(error.span!.end.offset, 86);
   error = errors[5];
   expect(error.message, 'Using top-level mixin a as a declaration');
-  expect(error.span.start.line, 5);
-  expect(error.span.end.offset, 56);
+  expect(error.span!.start.line, 5);
+  expect(error.span!.end.offset, 56);
 }
 
 void main() {
diff --git a/test/nested_test.dart b/test/nested_test.dart
index b096fc2..a594969 100644
--- a/test/nested_test.dart
+++ b/test/nested_test.dart
@@ -12,7 +12,6 @@
 void compileAndValidate(String input, String generated) {
   var errors = <Message>[];
   var stylesheet = compileCss(input, errors: errors, opts: simpleOptions);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
diff --git a/test/samples_test.dart b/test/samples_test.dart
index b906131..5a066a6 100644
--- a/test/samples_test.dart
+++ b/test/samples_test.dart
@@ -27,7 +27,7 @@
   final cssDir = Directory.fromUri(libraryUri.resolve('examples'));
   for (var element in cssDir.listSync()) {
     if (element is File && element.uri.pathSegments.last.endsWith('.css')) {
-      test(element.uri.pathSegments.last, () => testCSSFile(element));
+      test(element.uri.pathSegments.last, () => testCSSFile(element as File));
     }
   }
 }
diff --git a/test/testing.dart b/test/testing.dart
index 5c8cc55..66bd815 100644
--- a/test/testing.dart
+++ b/test/testing.dart
@@ -28,7 +28,7 @@
 /// CSS will allow any property/value pairs regardless of validity; all of our
 /// tests (by default) will ensure that the CSS is really valid.
 StyleSheet parseCss(String cssInput,
-        {List<Message> errors, PreprocessorOptions opts}) =>
+        {List<Message>? errors, PreprocessorOptions? opts}) =>
     parse(cssInput,
         errors: errors,
         options: opts ?? simpleOptionsWithCheckedAndWarningsAsErrors);
@@ -37,10 +37,10 @@
 /// CSS will allow any property/value pairs regardless of validity; all of our
 /// tests (by default) will ensure that the CSS is really valid.
 StyleSheet compileCss(String cssInput,
-        {List<Message> errors,
-        PreprocessorOptions opts,
+        {List<Message>? errors,
+        PreprocessorOptions? opts,
         bool polyfill = false,
-        List<StyleSheet> includes}) =>
+        List<StyleSheet>? includes}) =>
     compile(cssInput,
         errors: errors,
         options: opts ?? simpleOptionsWithCheckedAndWarningsAsErrors,
@@ -48,7 +48,7 @@
         includes: includes);
 
 StyleSheet polyFillCompileCss(input,
-        {List<Message> errors, PreprocessorOptions opts}) =>
+        {List<Message>? errors, PreprocessorOptions? opts}) =>
     compileCss(input, errors: errors, polyfill: true, opts: opts);
 
 /// CSS emitter walks the style sheet tree and emits readable CSS.
diff --git a/test/var_test.dart b/test/var_test.dart
index 1ebd975..923d121 100644
--- a/test/var_test.dart
+++ b/test/var_test.dart
@@ -12,7 +12,6 @@
 void compileAndValidate(String input, String generated) {
   var errors = <Message>[];
   var stylesheet = compileCss(input, errors: errors, opts: options);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -20,7 +19,6 @@
 void compilePolyfillAndValidate(String input, String generated) {
   var errors = <Message>[];
   var stylesheet = polyFillCompileCss(input, errors: errors, opts: options);
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 }
@@ -476,8 +474,6 @@
   var stylesheet =
       polyFillCompileCss(input, errors: errors..clear(), opts: options);
 
-  expect(stylesheet != null, true);
-
   expect(errors.length, errorStrings.length, reason: errors.toString());
   testBitMap = 0;
 
@@ -678,7 +674,6 @@
 
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 
@@ -704,7 +699,6 @@
 
   stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated2);
 
@@ -733,7 +727,6 @@
 
   var stylesheet = parseCss(input, errors: errors, opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated);
 
@@ -759,7 +752,6 @@
 
   stylesheet = parseCss(input, errors: errors..clear(), opts: simpleOptions);
 
-  expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet), generated2);
 
@@ -874,7 +866,6 @@
 }''';
 
   var stylesheet1 = compileCss(file1Input, errors: errors, opts: options);
-  expect(stylesheet1 != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet1), generated1);
 
@@ -891,7 +882,6 @@
 
   var stylesheet2 = compileCss(file2Input,
       includes: [stylesheet1], errors: errors..clear(), opts: options);
-  expect(stylesheet2 != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheet2), generated2);
 
@@ -908,7 +898,6 @@
 }''';
   var styleSheet1Polyfill = compileCss(file1Input,
       errors: errors..clear(), polyfill: true, opts: options);
-  expect(styleSheet1Polyfill != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(styleSheet1Polyfill), generatedPolyfill1);
 
@@ -925,7 +914,6 @@
       errors: errors..clear(),
       polyfill: true,
       opts: options);
-  expect(styleSheet2Polyfill != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(styleSheet2Polyfill), generatedPolyfill2);
 
@@ -946,7 +934,6 @@
       polyfill: true,
       opts: options);
 
-  expect(stylesheetPolyfill != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
   expect(prettyPrint(stylesheetPolyfill), generatedPolyfill);
 
diff --git a/test/visitor_test.dart b/test/visitor_test.dart
index 958db30..a5346dd 100644
--- a/test/visitor_test.dart
+++ b/test/visitor_test.dart
@@ -40,7 +40,6 @@
 
   var s = parseCss(in1, errors: errors);
 
-  expect(s != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   var clsVisits = ClassVisitor(['foobar'])..visitTree(s);
@@ -54,7 +53,6 @@
 
   s = parseCss(in1, errors: errors..clear(), opts: simpleOptions);
 
-  expect(s != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   clsVisits = ClassVisitor(['foobar1', 'xyzzy', 'foo', 'hello'])..visitTree(s);
@@ -102,7 +100,6 @@
 }''';
 
   var s = parseCss(input, errors: errors);
-  expect(s != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
 
   final emitted = polyfillPrint('myComponent', s);