Use Object in place of dynamic (#134)

Replace fields and Map keys with `Object` where they were previously
`dynamic`.
diff --git a/lib/dom.dart b/lib/dom.dart
index fbd2c90..c3d2e5d 100644
--- a/lib/dom.dart
+++ b/lib/dom.dart
@@ -55,7 +55,7 @@
   }
 
   @override
-  int compareTo(dynamic other) {
+  int compareTo(Object other) {
     // Not sure about this sort order
     if (other is! AttributeName) return 1;
     final otherAttributeName = other as AttributeName;
@@ -152,7 +152,7 @@
   ///
   /// Note that attribute order needs to be stable for serialization, so we use
   /// a LinkedHashMap. Each key is a [String] or [AttributeName].
-  LinkedHashMap<dynamic, String> attributes = LinkedHashMap();
+  LinkedHashMap<Object, String> attributes = LinkedHashMap();
 
   /// A list of child nodes of the current node. This must
   /// include all elements but not necessarily other node types.
@@ -166,8 +166,8 @@
   FileSpan sourceSpan;
 
   /// The attribute spans if requested. Otherwise null.
-  LinkedHashMap<dynamic, FileSpan> _attributeSpans;
-  LinkedHashMap<dynamic, FileSpan> _attributeValueSpans;
+  LinkedHashMap<Object, FileSpan> _attributeSpans;
+  LinkedHashMap<Object, FileSpan> _attributeValueSpans;
 
   Node._() {
     nodes._parent = this;
@@ -177,7 +177,7 @@
   /// The span of an attribute is the entire attribute, including the name and
   /// quotes (if any). For example, the span of "attr" in `<a attr="value">`
   /// would be the text `attr="value"`.
-  LinkedHashMap<dynamic, FileSpan> get attributeSpans {
+  LinkedHashMap<Object, FileSpan> get attributeSpans {
     _ensureAttributeSpans();
     return _attributeSpans;
   }
@@ -186,7 +186,7 @@
   /// value. Unlike [attributeSpans], this span will inlcude only the value.
   /// For example, the value span of "attr" in `<a attr="value">` would be the
   /// text `value`.
-  LinkedHashMap<dynamic, FileSpan> get attributeValueSpans {
+  LinkedHashMap<Object, FileSpan> get attributeValueSpans {
     _ensureAttributeSpans();
     return _attributeValueSpans;
   }
@@ -279,8 +279,8 @@
   void _ensureAttributeSpans() {
     if (_attributeSpans != null) return;
 
-    _attributeSpans = LinkedHashMap<dynamic, FileSpan>();
-    _attributeValueSpans = LinkedHashMap<dynamic, FileSpan>();
+    _attributeSpans = LinkedHashMap<Object, FileSpan>();
+    _attributeValueSpans = LinkedHashMap<Object, FileSpan>();
 
     if (sourceSpan == null) return;
 
@@ -421,7 +421,7 @@
   /// The text node's data, stored as either a String or StringBuffer.
   /// We support storing a StringBuffer here to support fast [appendData].
   /// It will flatten back to a String on read.
-  dynamic _data;
+  Object _data;
 
   Text(String data)
       : _data = data ?? '',
diff --git a/lib/parser.dart b/lib/parser.dart
index ac3d304..940753c 100644
--- a/lib/parser.dart
+++ b/lib/parser.dart
@@ -826,7 +826,7 @@
   // helper methods
   void insertHtmlElement() {
     tree.insertRoot(
-        StartTagToken('html', data: LinkedHashMap<dynamic, String>()));
+        StartTagToken('html', data: LinkedHashMap<Object, String>()));
     parser.phase = parser._beforeHeadPhase;
   }
 
@@ -913,7 +913,7 @@
 
   @override
   bool processEOF() {
-    startTagHead(StartTagToken('head', data: LinkedHashMap<dynamic, String>()));
+    startTagHead(StartTagToken('head', data: LinkedHashMap<Object, String>()));
     return true;
   }
 
@@ -924,7 +924,7 @@
 
   @override
   Token processCharacters(CharactersToken token) {
-    startTagHead(StartTagToken('head', data: LinkedHashMap<dynamic, String>()));
+    startTagHead(StartTagToken('head', data: LinkedHashMap<Object, String>()));
     return token;
   }
 
@@ -940,12 +940,12 @@
   }
 
   Token startTagOther(StartTagToken token) {
-    startTagHead(StartTagToken('head', data: LinkedHashMap<dynamic, String>()));
+    startTagHead(StartTagToken('head', data: LinkedHashMap<Object, String>()));
     return token;
   }
 
   Token endTagImplyHead(EndTagToken token) {
-    startTagHead(StartTagToken('head', data: LinkedHashMap<dynamic, String>()));
+    startTagHead(StartTagToken('head', data: LinkedHashMap<Object, String>()));
     return token;
   }
 
@@ -1209,7 +1209,7 @@
 
   void anythingElse() {
     tree.insertElement(
-        StartTagToken('body', data: LinkedHashMap<dynamic, String>()));
+        StartTagToken('body', data: LinkedHashMap<Object, String>()));
     parser.phase = parser._inBodyPhase;
     parser.framesetOK = true;
   }
@@ -1813,29 +1813,27 @@
     if (tree.formPointer != null) {
       return;
     }
-    final formAttrs = LinkedHashMap<dynamic, String>();
+    final formAttrs = LinkedHashMap<Object, String>();
     final dataAction = token.data['action'];
     if (dataAction != null) {
       formAttrs['action'] = dataAction;
     }
     processStartTag(StartTagToken('form', data: formAttrs));
+    processStartTag(StartTagToken('hr', data: LinkedHashMap<Object, String>()));
     processStartTag(
-        StartTagToken('hr', data: LinkedHashMap<dynamic, String>()));
-    processStartTag(
-        StartTagToken('label', data: LinkedHashMap<dynamic, String>()));
+        StartTagToken('label', data: LinkedHashMap<Object, String>()));
     // XXX Localization ...
     var prompt = token.data['prompt'];
     prompt ??= 'This is a searchable index. Enter search keywords: ';
     processCharacters(CharactersToken(prompt));
-    final attributes = LinkedHashMap<dynamic, String>.from(token.data);
+    final attributes = LinkedHashMap<Object, String>.from(token.data);
     attributes.remove('action');
     attributes.remove('prompt');
     attributes['name'] = 'isindex';
     processStartTag(StartTagToken('input',
         data: attributes, selfClosing: token.selfClosing));
     processEndTag(EndTagToken('label'));
-    processStartTag(
-        StartTagToken('hr', data: LinkedHashMap<dynamic, String>()));
+    processStartTag(StartTagToken('hr', data: LinkedHashMap<Object, String>()));
     processEndTag(EndTagToken('form'));
   }
 
@@ -1938,8 +1936,7 @@
 
   void endTagP(EndTagToken token) {
     if (!tree.elementInScope('p', variant: 'button')) {
-      startTagCloseP(
-          StartTagToken('p', data: LinkedHashMap<dynamic, String>()));
+      startTagCloseP(StartTagToken('p', data: LinkedHashMap<Object, String>()));
       parser.parseError(token.span, 'unexpected-end-tag', {'name': 'p'});
       endTagP(EndTagToken('p'));
     } else {
@@ -2238,7 +2235,7 @@
         {'originalName': 'br', 'newName': 'br element'});
     tree.reconstructActiveFormattingElements();
     tree.insertElement(
-        StartTagToken('br', data: LinkedHashMap<dynamic, String>()));
+        StartTagToken('br', data: LinkedHashMap<Object, String>()));
     tree.openElements.removeLast();
   }
 
@@ -2450,7 +2447,7 @@
 
   Token startTagCol(StartTagToken token) {
     startTagColgroup(
-        StartTagToken('colgroup', data: LinkedHashMap<dynamic, String>()));
+        StartTagToken('colgroup', data: LinkedHashMap<Object, String>()));
     return token;
   }
 
@@ -2462,7 +2459,7 @@
 
   Token startTagImplyTbody(StartTagToken token) {
     startTagRowGroup(
-        StartTagToken('tbody', data: LinkedHashMap<dynamic, String>()));
+        StartTagToken('tbody', data: LinkedHashMap<Object, String>()));
     return token;
   }
 
@@ -2918,7 +2915,7 @@
   Token startTagTableCell(StartTagToken token) {
     parser.parseError(
         token.span, 'unexpected-cell-in-table-body', {'name': token.name});
-    startTagTr(StartTagToken('tr', data: LinkedHashMap<dynamic, String>()));
+    startTagTr(StartTagToken('tr', data: LinkedHashMap<Object, String>()));
     return token;
   }
 
diff --git a/lib/src/token.dart b/lib/src/token.dart
index 24c531e..05fe58d 100644
--- a/lib/src/token.dart
+++ b/lib/src/token.dart
@@ -22,7 +22,7 @@
 class StartTagToken extends TagToken {
   /// The tag's attributes. A map from the name to the value, where the name
   /// can be a [String] or [AttributeName].
-  LinkedHashMap<dynamic, String> data;
+  LinkedHashMap<Object, String> data;
 
   /// The attribute spans if requested. Otherwise null.
   List<TagAttribute> attributeSpans;
diff --git a/test/parser_feature_test.dart b/test/parser_feature_test.dart
index f59df1b..0237172 100644
--- a/test/parser_feature_test.dart
+++ b/test/parser_feature_test.dart
@@ -231,10 +231,13 @@
       ''');
       final n = doc.querySelector('desc');
       final keys = n.attributes.keys.toList();
-      expect(keys[0], const TypeMatcher<AttributeName>());
-      expect(keys[0].prefix, 'xlink');
-      expect(keys[0].namespace, 'http://www.w3.org/1999/xlink');
-      expect(keys[0].name, 'type');
+      expect(
+          keys.first,
+          isA<AttributeName>()
+              .having((n) => n.prefix, 'prefix', 'xlink')
+              .having((n) => n.namespace, 'namespace',
+                  'http://www.w3.org/1999/xlink')
+              .having((n) => n.name, 'name', 'type'));
 
       expect(
           n.outerHtml,