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