Make `accept` a generic method (#21)

Stop throwing away types from the `Visitor` which already has a generic.

Use generic for RecursiveVisitor instead of allowing an implicit `dynamic`.
diff --git a/lib/src/ast.dart b/lib/src/ast.dart
index 1408ffd..d16098a 100644
--- a/lib/src/ast.dart
+++ b/lib/src/ast.dart
@@ -21,7 +21,7 @@
   Iterable<String> get variables;
 
   /// Calls the appropriate [Visitor] method on [this] and returns the result.
-  dynamic accept(Visitor visitor);
+  T accept<T>(Visitor<T> visitor);
 }
 
 /// A single variable.
@@ -38,7 +38,7 @@
   VariableNode(this.name, [this.span]);
 
   @override
-  dynamic accept(Visitor visitor) => visitor.visitVariable(this);
+  T accept<T>(Visitor<T> visitor) => visitor.visitVariable(this);
 
   @override
   String toString() => name;
@@ -64,7 +64,7 @@
   NotNode(this.child, [this.span]);
 
   @override
-  dynamic accept(Visitor visitor) => visitor.visitNot(this);
+  T accept<T>(Visitor<T> visitor) => visitor.visitNot(this);
 
   @override
   String toString() =>
@@ -97,7 +97,7 @@
   OrNode(this.left, this.right);
 
   @override
-  dynamic accept(Visitor visitor) => visitor.visitOr(this);
+  T accept<T>(Visitor<T> visitor) => visitor.visitOr(this);
 
   @override
   String toString() {
@@ -136,7 +136,7 @@
   AndNode(this.left, this.right);
 
   @override
-  dynamic accept(Visitor visitor) => visitor.visitAnd(this);
+  T accept<T>(Visitor<T> visitor) => visitor.visitAnd(this);
 
   @override
   String toString() {
@@ -179,7 +179,7 @@
   ConditionalNode(this.condition, this.whenTrue, this.whenFalse);
 
   @override
-  dynamic accept(Visitor visitor) => visitor.visitConditional(this);
+  T accept<T>(Visitor<T> visitor) => visitor.visitConditional(this);
 
   @override
   String toString() {
diff --git a/lib/src/visitor.dart b/lib/src/visitor.dart
index d0efe72..c6808c2 100644
--- a/lib/src/visitor.dart
+++ b/lib/src/visitor.dart
@@ -17,7 +17,7 @@
 ///
 /// The default implementations of this visitor's methods just traverse the AST
 /// and do nothing with it.
-abstract class RecursiveVisitor implements Visitor {
+abstract class RecursiveVisitor implements Visitor<void> {
   const RecursiveVisitor();
 
   @override