Preserve type arguments in generic typedefs. (#622)

Fix #619. Close #616 (already working, added regression test).
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d71f499..e3e9f39 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,9 @@
-# 1.0.4-dev
+# 1.0.4
 
 * Ensure formatter throws an exception instead of introducing non-whitespace
   changes. This sanity check ensures the formatter does not erase user code
   when the formatter itself contains a bug.
+* Preserve type arguments in generic typedefs (#619).
 * Preserve type arguments in function expression invocations (#621).
 
 # 1.0.3
diff --git a/bin/format.dart b/bin/format.dart
index df2b678..28dab2a 100644
--- a/bin/format.dart
+++ b/bin/format.dart
@@ -14,7 +14,7 @@
 import 'package:dart_style/src/source_code.dart';
 
 // Note: The following line of code is modified by tool/grind.dart.
-const version = "1.0.3";
+const version = "1.0.4";
 
 void main(List<String> args) {
   var parser = new ArgParser(allowTrailingOptions: true);
diff --git a/lib/src/source_visitor.dart b/lib/src/source_visitor.dart
index f78627e..0da685e 100644
--- a/lib/src/source_visitor.dart
+++ b/lib/src/source_visitor.dart
@@ -1198,12 +1198,24 @@
   visitGenericTypeAlias(GenericTypeAlias node) {
     visitNodes(node.metadata, between: newline, after: newline);
     _simpleStatement(node, () {
+      // If the typedef's type parameters split, split after the "=" too,
+      // mainly to ensure the function's type parameters and parameters get
+      // end up on successive lines with the same indentation.
+      builder.startRule();
+
       token(node.typedefKeyword);
       space();
+
       visit(node.name);
-      space();
+
+      visit(node.typeParameters);
+      split();
+
       token(node.equals);
+      builder.endRule();
+
       space();
+
       visit(node.functionType);
     });
   }
@@ -2062,7 +2074,7 @@
   /// declaration, function declaration, or generic function type.
   void _visitParameterSignature(
       TypeParameterList typeParameters, FormalParameterList parameters) {
-    // Start the nesting for the parameters here, so they wrap around the
+    // Start the nesting for the parameters here, so they indent past the
     // type parameters too, if any.
     builder.nestExpression();
 
diff --git a/pubspec.yaml b/pubspec.yaml
index 00e5bd7..ef5155b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
 name: dart_style
 # Note: See tool/grind.dart for how to bump the version.
-version: 1.0.4-dev
+version: 1.0.4
 author: Dart Team <misc@dartlang.org>
 description: Opinionated, automatic Dart source code formatter.
 homepage: https://github.com/dart-lang/dart_style
diff --git a/test/regression/0600/0616.unit b/test/regression/0600/0616.unit
new file mode 100644
index 0000000..720a71e
--- /dev/null
+++ b/test/regression/0600/0616.unit
@@ -0,0 +1,17 @@
+>>> (skip: published version of analyzer doesn't support function types yet)
+import "package:expect/expect.dart";
+int Function() x = () => 42;
+int Function(int Function()) y = (int Function() x) => x();
+List<int Function()> l = <int Function()>[()=>42, x];
+main() {
+  Expect.equals(42, y(l[1]));
+}
+<<<
+import "package:expect/expect.dart";
+
+int Function() x = () => 42;
+int Function(int Function()) y = (int Function() x) => x();
+List<int Function()> l = <int Function()>[() => 42, x];
+main() {
+  Expect.equals(42, y(l[1]));
+}
\ No newline at end of file
diff --git a/test/regression/0600/0619.unit b/test/regression/0600/0619.unit
new file mode 100644
index 0000000..09a7a37
--- /dev/null
+++ b/test/regression/0600/0619.unit
@@ -0,0 +1,4 @@
+>>> (skip: published version of analyzer doesn't support function types yet)
+typedef F<T> = void Function(T);
+<<<
+typedef F<T> = void Function(T);
\ No newline at end of file
diff --git a/test/splitting/function_types.unit b/test/splitting/function_types.unit
deleted file mode 100644
index 130b45f..0000000
--- a/test/splitting/function_types.unit
+++ /dev/null
@@ -1,22 +0,0 @@
-40 columns                              |
->>> split type parameters (skip: published version of analyzer doesn't support function types yet)
-typedef G = T Function<TypeOne, TypeTwo, TypeThree>();
-<<<
-typedef G = T Function<TypeOne, TypeTwo,
-    TypeThree>();
->>> split all type parameters (skip: published version of analyzer doesn't support function types yet)
-typedef G = T Function<TypeOne, TypeTwo, TypeThree, TypeFour, TypeFive, TypeSix>();
-<<<
-typedef G = T Function<
-    TypeOne,
-    TypeTwo,
-    TypeThree,
-    TypeFour,
-    TypeFive,
-    TypeSix>();
->>> split type and value parameters (skip: published version of analyzer doesn't support function types yet)
-typedef G = T Function<TypeOne, TypeTwo, TypeThree>(TypeOne one, TypeTwo two, TypeThree three);
-<<<
-typedef G = T Function<TypeOne, TypeTwo,
-        TypeThree>(TypeOne one,
-    TypeTwo two, TypeThree three);
\ No newline at end of file
diff --git a/test/splitting/typedef.unit b/test/splitting/typedef.unit
new file mode 100644
index 0000000..3d09123
--- /dev/null
+++ b/test/splitting/typedef.unit
@@ -0,0 +1,63 @@
+40 columns                              |
+>>> split type parameters (skip: published version of analyzer doesn't support function types yet)
+typedef G = T Function<TypeOne, TypeTwo, TypeThree>();
+<<<
+typedef G = T Function<TypeOne, TypeTwo,
+    TypeThree>();
+>>> split all type parameters (skip: published version of analyzer doesn't support function types yet)
+typedef G = T Function<TypeOne, TypeTwo, TypeThree, TypeFour, TypeFive, TypeSix>();
+<<<
+typedef G = T Function<
+    TypeOne,
+    TypeTwo,
+    TypeThree,
+    TypeFour,
+    TypeFive,
+    TypeSix>();
+>>> split type and value parameters (skip: published version of analyzer doesn't support function types yet)
+typedef G = T Function<TypeOne, TypeTwo, TypeThree>(TypeOne one, TypeTwo two, TypeThree three);
+<<<
+typedef G = T Function<TypeOne, TypeTwo,
+        TypeThree>(TypeOne one,
+    TypeTwo two, TypeThree three);
+>>> generic typedef parameters on one line (skip: published version of analyzer doesn't support function types yet)
+typedef Foo<T, S> = Function();
+<<<
+typedef Foo<T, S> = Function();
+>>> generic typedef parameters that split (skip: published version of analyzer doesn't support function types yet)
+typedef LongfunctionType<First, Second, Third, Fourth, Fifth, Sixth> = Function(First first, Second second, Third third, Fourth fourth);
+<<<
+typedef LongfunctionType<First, Second,
+        Third, Fourth, Fifth, Sixth>
+    = Function(
+        First first,
+        Second second,
+        Third third,
+        Fourth fourth);
+>>> both type parameter lists split (skip: published version of analyzer doesn't support function types yet)
+typedef LongfunctionType<First, Second, Third, Fourth, Fifth, Sixth> = Function<Seventh>(First first, Second second, Third third, Fourth fourth);
+<<<
+typedef LongfunctionType<First, Second,
+        Third, Fourth, Fifth, Sixth>
+    = Function<Seventh>(
+        First first,
+        Second second,
+        Third third,
+        Fourth fourth);
+>>> all three parameter lists split (skip: published version of analyzer doesn't support function types yet)
+typedef LongfunctionType<First, Second, Third, Fourth, Fifth, Sixth> = Function<Seventh, Eighth, Ninth, Tenth, Eleventh, Twelfth, Thirteenth>(First first, Second second, Third third, Fourth fourth);
+<<<
+typedef LongfunctionType<First, Second,
+        Third, Fourth, Fifth, Sixth>
+    = Function<
+            Seventh,
+            Eighth,
+            Ninth,
+            Tenth,
+            Eleventh,
+            Twelfth,
+            Thirteenth>(
+        First first,
+        Second second,
+        Third third,
+        Fourth fourth);
\ No newline at end of file
diff --git a/test/whitespace/function_types.unit b/test/whitespace/typedef.unit
similarity index 71%
rename from test/whitespace/function_types.unit
rename to test/whitespace/typedef.unit
index 4d92ad3..40f982d 100644
--- a/test/whitespace/function_types.unit
+++ b/test/whitespace/typedef.unit
@@ -1,4 +1,8 @@
 40 columns                              |
+>>> old generic typedef syntax
+typedef Foo  <  T  ,S  >(T t,S s);
+<<<
+typedef Foo<T, S>(T t, S s);
 >>> non-generic in typedef (skip: published version of analyzer doesn't support function types yet)
 typedef   SomeFunc=ReturnType  Function(int param,   double other);
 <<<
@@ -25,4 +29,12 @@
 >>> without param names (skip: published version of analyzer doesn't support function types yet)
 typedef F = Function(int, bool, String);
 <<<
-typedef F = Function(int, bool, String);
\ No newline at end of file
+typedef F = Function(int, bool, String);
+>>> generic (skip: published version of analyzer doesn't support function types yet)
+typedef    Foo < A ,B>=Function ( A a,   B b );
+<<<
+typedef Foo<A, B> = Function(A a, B b);
+>>> generic function (skip: published version of analyzer doesn't support function types yet)
+typedef    Foo  =Function  < A ,B  >   ( A a,B b );
+<<<
+typedef Foo = Function<A, B>(A a, B b);
\ No newline at end of file