Support for generic annotations. (#994)

This change provides enough support to avoid a crash, ensure that
generic annotations are preserved by the formatter, and format them nicely.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd2d4cf..fcc6c1d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 1.3.14
+
+* Add support for generic annotations.
+
 # 1.3.13
 
 - Allow the latest version of `package:analyzer`.
diff --git a/lib/src/dart_formatter.dart b/lib/src/dart_formatter.dart
index aed309a..e842bb2 100644
--- a/lib/src/dart_formatter.dart
+++ b/lib/src/dart_formatter.dart
@@ -91,7 +91,8 @@
     // TODO(paulberry): consider plumbing in experiment enable flags from the
     // command line.
     var featureSet = FeatureSet.fromEnableFlags2(
-        sdkLanguageVersion: Version(2, 10, 0), flags: ['non-nullable']);
+        sdkLanguageVersion: Version(2, 10, 0),
+        flags: ['non-nullable', 'generic-metadata']);
 
     var inputOffset = 0;
     var text = source.text;
diff --git a/lib/src/source_visitor.dart b/lib/src/source_visitor.dart
index 64be1a5..ebbae38 100644
--- a/lib/src/source_visitor.dart
+++ b/lib/src/source_visitor.dart
@@ -297,13 +297,20 @@
   void visitAnnotation(Annotation node) {
     token(node.atSign);
     visit(node.name);
+
+    builder.nestExpression();
+    visit(node.typeArguments);
     token(node.period);
     visit(node.constructorName);
 
-    // Metadata annotations are always const contexts.
-    _constNesting++;
-    visit(node.arguments);
-    _constNesting--;
+    if (node.arguments != null) {
+      // Metadata annotations are always const contexts.
+      _constNesting++;
+      visitArgumentList(node.arguments, nestExpression: false);
+      _constNesting--;
+    }
+
+    builder.unnest();
   }
 
   /// Visits an argument list.
diff --git a/pubspec.yaml b/pubspec.yaml
index 177e313..5118209 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.3.13
+version: 1.3.14-dev
 description: >-
   Opinionated, automatic Dart source code formatter.
   Provides an API and a CLI tool.
diff --git a/test/splitting/annotations.unit b/test/splitting/annotations.unit
new file mode 100644
index 0000000..da72c4c
--- /dev/null
+++ b/test/splitting/annotations.unit
@@ -0,0 +1,95 @@
+40 columns                              |
+>>> complex annotation that all fits on one line
+@a.B<C,D>(e,f,g) int i = 0;
+<<<
+@a.B<C, D>(e, f, g)
+int i = 0;
+>>> prefer to split between args even when they all fit on next line
+@BigLongClassName<First, Second, Third>() int i = 0;
+<<<
+@BigLongClassName<First, Second,
+    Third>()
+int i = 0;
+>>> split before first if needed
+@BigLongClassName<FirstTypeArgumentIsLong, Second>() int i = 0;
+<<<
+@BigLongClassName<
+    FirstTypeArgumentIsLong, Second>()
+int i = 0;
+>>> split in middle if fit in two lines
+@BigLongClassName<First, Second, Third, Fourth, Fifth, Sixth, Seventh>() int i = 0;
+<<<
+@BigLongClassName<First, Second, Third,
+    Fourth, Fifth, Sixth, Seventh>()
+int i = 0;
+>>> split one per line if they don't fit in two lines
+@BigLongClassName<First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth>() int i = 0;
+<<<
+@BigLongClassName<
+    First,
+    Second,
+    Third,
+    Fourth,
+    Fifth,
+    Sixth,
+    Seventh,
+    Eighth>()
+int i = 0;
+>>> prefers to not split at type arguments
+@SomeBigClass<
+    TypeArgument>(valueArgument)
+int i = 0;
+<<<
+@SomeBigClass<TypeArgument>(
+    valueArgument)
+int i = 0;
+>>> split both type and value arguments
+@SomeBigClass<First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth>(first, second, third, fourth, fifth, sixth, seventh, eighth) int i = 0;
+<<<
+@SomeBigClass<
+        First,
+        Second,
+        Third,
+        Fourth,
+        Fifth,
+        Sixth,
+        Seventh,
+        Eighth>(
+    first,
+    second,
+    third,
+    fourth,
+    fifth,
+    sixth,
+    seventh,
+    eighth)
+int i = 0;
+>>> prefer to split at arguments rather than prefix
+@veryLongPrefix.VeryLongClassName<VeryLongTypeArgument,OtherVeryLongTypeArgument>(veryLongArgument,otherVeryLongArgument,thirdVeryLongArgument) int i = 0;
+<<<
+@veryLongPrefix.VeryLongClassName<
+        VeryLongTypeArgument,
+        OtherVeryLongTypeArgument>(
+    veryLongArgument,
+    otherVeryLongArgument,
+    thirdVeryLongArgument)
+int i = 0;
+>>> nested type arguments, no splitting required
+@A<B<C,D>,E<F,G>>() int i = 0;
+<<<
+@A<B<C, D>, E<F, G>>()
+int i = 0;
+>>> nested type arguments, split at outer level when possible
+@Aaaa<Bbbb<Cccc,Dddd>,Eeee<Ffff,Gggg>>() int i = 0;
+<<<
+@Aaaa<Bbbb<Cccc, Dddd>,
+    Eeee<Ffff, Gggg>>()
+int i = 0;
+>>> nested type arguments, split at inner level when necessary
+@Aaaaaaaaa<Bbbbbbbbbbb<Ccccccccccc,Ddddddddddd>,Eeeeeeeee<Fffffffff,Ggggggggg>>() int i = 0;
+<<<
+@Aaaaaaaaa<
+    Bbbbbbbbbbb<Ccccccccccc,
+        Ddddddddddd>,
+    Eeeeeeeee<Fffffffff, Ggggggggg>>()
+int i = 0;
diff --git a/test/whitespace/metadata.unit b/test/whitespace/metadata.unit
index c25e98f..87ed0b7 100644
--- a/test/whitespace/metadata.unit
+++ b/test/whitespace/metadata.unit
@@ -380,4 +380,24 @@
 class C {
   @meta
   abstract var x;
-}
\ No newline at end of file
+}
+>>> annotation with type arguments
+@A<int,String>()int x;
+<<<
+@A<int, String>()
+int x;
+>>>
+@prefix.A<int,String>()int x;
+<<<
+@prefix.A<int, String>()
+int x;
+>>>
+@A<int,String>.constructor()int x;
+<<<
+@A<int, String>.constructor()
+int x;
+>>>
+@prefix.A<int,String>.constructor()int x;
+<<<
+@prefix.A<int, String>.constructor()
+int x;