Merge pull request #149 from dart-lang/dynamic-calls

Avoid dynamic calls
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 1df858d..6bafdbe 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -5,6 +5,7 @@
 
 linter:
   rules:
+  - avoid_dynamic_calls
   - prefer_equal_for_default_values
   - prefer_generic_function_type_aliases
   - prefer_typing_uninitialized_variables
diff --git a/lib/parser.dart b/lib/parser.dart
index d80dc00..f6623da 100644
--- a/lib/parser.dart
+++ b/lib/parser.dart
@@ -2255,7 +2255,8 @@
           _warning('Expected hex number', _makeSpan(start));
         }
         // Construct the bad hex value with a #<space>number.
-        return _parseHex(' ${processTerm().text}', _makeSpan(start));
+        return _parseHex(
+            ' ${(processTerm() as LiteralTerm).text}', _makeSpan(start));
       case TokenKind.INTEGER:
         t = _next();
         value = int.parse('$unary${t.text}');
@@ -2292,13 +2293,14 @@
         _next();
 
         var term = processTerm();
-        if (!(term is NumberTerm)) {
+        if (term is! NumberTerm) {
           _error('Expecting a positive number', _makeSpan(start));
+          throw StateError('Expecting a positive number');
         }
 
         _eat(TokenKind.RBRACK);
 
-        return ItemTerm(term.value, term.text as String, _makeSpan(start));
+        return ItemTerm(term.value, term.text, _makeSpan(start));
       case TokenKind.IDENTIFIER:
         var nameValue = identifier(); // Snarf up the ident we'll remap, maybe.
 
diff --git a/lib/src/analyzer.dart b/lib/src/analyzer.dart
index 6d33e25..7cea7e8 100644
--- a/lib/src/analyzer.dart
+++ b/lib/src/analyzer.dart
@@ -622,13 +622,16 @@
   /// Rip apart var def with multiple parameters.
   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;
-      assert(expressions.length > 1);
-      for (var expr in expressions) {
-        if (expr is! OperatorComma) {
-          defArgs.add([expr]);
+    if (callArg is List) {
+      var firstCallArg = callArg[0];
+      if (firstCallArg is VarUsage) {
+        var varDef = varDefs![firstCallArg.name];
+        var expressions = (varDef!.expression as Expressions).expressions;
+        assert(expressions.length > 1);
+        for (var expr in expressions) {
+          if (expr is! OperatorComma) {
+            defArgs.add([expr]);
+          }
         }
       }
     }
diff --git a/lib/src/token_kind.dart b/lib/src/token_kind.dart
index 148a835..9018e2e 100644
--- a/lib/src/token_kind.dart
+++ b/lib/src/token_kind.dart
@@ -518,8 +518,9 @@
     return matchList(MEDIA_OPERATORS, 'type', text, offset, length);
   }
 
-  static String? idToValue(var identList, int tokenId) {
+  static String? idToValue(Iterable<Object?> identList, int tokenId) {
     for (var entry in identList) {
+      entry as Map<String, Object?>;
       if (tokenId == entry['type']) {
         return entry['value'] as String?;
       }
diff --git a/lib/src/tree.dart b/lib/src/tree.dart
index 3af71dc..7155192 100644
--- a/lib/src/tree.dart
+++ b/lib/src/tree.dart
@@ -180,6 +180,8 @@
 
   SimpleSelector(this._name, SourceSpan? span) : super(span);
 
+  // TOOD(srawlins): Figure this one out.
+  // ignore: avoid_dynamic_calls
   String get name => _name.name as String;
 
   bool get isWildcard => _name is Wildcard;
@@ -214,7 +216,7 @@
       ? '*'
       : _namespace == null
           ? ''
-          : _namespace.name as String;
+          : (_namespace as Identifier).name;
 
   bool get isNamespaceWildcard => _namespace is Wildcard;
 
diff --git a/lib/src/tree_base.dart b/lib/src/tree_base.dart
index db3a56c..e8243f0 100644
--- a/lib/src/tree_base.dart
+++ b/lib/src/tree_base.dart
@@ -50,7 +50,7 @@
     buf.write('\n');
   }
 
-  void heading(String name, [span]) {
+  void heading(String name, [SourceSpan? span]) {
     write(name);
     if (span != null) {
       buf.write('  (${span.message('')})');
diff --git a/lib/src/tree_printer.dart b/lib/src/tree_printer.dart
index 0d18400..338b7e0 100644
--- a/lib/src/tree_printer.dart
+++ b/lib/src/tree_printer.dart
@@ -24,7 +24,7 @@
   @override
   void visitTree(StyleSheet tree) => visitStylesheet(tree);
 
-  void heading(String heading, node) {
+  void heading(String heading, TreeNode node) {
     if (useSpan) {
       output.heading(heading, node.span);
     } else {
diff --git a/lib/visitor.dart b/lib/visitor.dart
index de30efc..0b7356d 100644
--- a/lib/visitor.dart
+++ b/lib/visitor.dart
@@ -344,11 +344,12 @@
   }
 
   @override
-  dynamic visitSimpleSelector(SimpleSelector node) => node._name.visit(this);
+  dynamic visitSimpleSelector(SimpleSelector node) =>
+      (node._name as TreeNode).visit(this);
 
   @override
   dynamic visitNamespaceSelector(NamespaceSelector node) {
-    if (node._namespace != null) node._namespace.visit(this);
+    if (node._namespace != null) (node._namespace as TreeNode).visit(this);
     if (node.nameAsSimpleSelector != null) {
       node.nameAsSimpleSelector!.visit(this);
     }