diff --git a/CHANGELOG.md b/CHANGELOG.md index 28c4d4c4..4c0caf22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.0.2 + +* Support new generic function typedef syntax (#563). + # 1.0.1 * Ensure space between `-` and `--` (#170). diff --git a/lib/src/source_visitor.dart b/lib/src/source_visitor.dart index faab9e88..60f56204 100644 --- a/lib/src/source_visitor.dart +++ b/lib/src/source_visitor.dart @@ -1181,6 +1181,25 @@ class SourceVisitor extends ThrowingAstVisitor { }); } + visitGenericFunctionType(GenericFunctionType node) { + visit(node.returnType, after: space); + token(node.functionKeyword); + _visitParameterSignature(node.typeParameters, node.parameters); + } + + visitGenericTypeAlias(GenericTypeAlias node) { + visitNodes(node.metadata, between: newline, after: newline); + _simpleStatement(node, () { + token(node.typedefKeyword); + space(); + visit(node.name); + space(); + token(node.equals); + space(); + visit(node.functionType); + }); + } + visitHideCombinator(HideCombinator node) { _visitCombinator(node.keyword, node.hiddenNames); } @@ -1555,7 +1574,14 @@ class SourceVisitor extends ThrowingAstVisitor { builder.nestExpression(); modifier(node.covariantKeyword); modifier(node.keyword); - visit(node.type, after: split); + + visit(node.type); + + // In function declarations and the old typedef syntax, you can have a + // parameter name without a type. In the new syntax, you can have a type + // without a name. Handle both cases. + if (node.type != null && node.identifier != null) split(); + visit(node.identifier); builder.unnest(); builder.endRule(); @@ -2016,6 +2042,18 @@ class SourceVisitor extends ThrowingAstVisitor { builder.startLazyRule(new Rule(Cost.arrow)); } + _visitParameterSignature(typeParameters, parameters); + + if (beforeBody != null) beforeBody(); + visit(body); + + if (body is ExpressionFunctionBody) builder.unnest(); + } + + /// Visits the type parameters (if any) and formal parameters of a method + /// 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 // type parameters too, if any. builder.nestExpression(); @@ -2026,11 +2064,6 @@ class SourceVisitor extends ThrowingAstVisitor { } builder.unnest(); - - if (beforeBody != null) beforeBody(); - visit(body); - - if (body is ExpressionFunctionBody) builder.unnest(); } /// Visits the body statement of a `for`, `for in`, or `while` loop. diff --git a/pubspec.lock b/pubspec.lock index 2a59357d..5ff28ee2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -6,7 +6,7 @@ packages: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.29.8" + version: "0.29.9" ansicolor: description: name: ansicolor diff --git a/pubspec.yaml b/pubspec.yaml index b6d7c02a..c48ef27c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,13 +1,13 @@ name: dart_style # Note: See tool/grind.dart for how to bump the version. -version: 1.0.1 +version: 1.0.2-dev author: Dart Team description: Opinionated, automatic Dart source code formatter. homepage: https://github.com/dart-lang/dart_style environment: sdk: ">=1.8.0 <2.0.0" dependencies: - analyzer: '^0.29.5' + analyzer: '^0.29.9' args: '>=0.12.1 <0.14.0' path: '>=1.0.0 <2.0.0' source_span: '>=1.1.1 <2.0.0' diff --git a/test/splitting/function_types.unit b/test/splitting/function_types.unit new file mode 100644 index 00000000..130b45fa --- /dev/null +++ b/test/splitting/function_types.unit @@ -0,0 +1,22 @@ +40 columns | +>>> split type parameters (skip: published version of analyzer doesn't support function types yet) +typedef G = T Function(); +<<< +typedef G = T Function(); +>>> split all type parameters (skip: published version of analyzer doesn't support function types yet) +typedef G = T Function(); +<<< +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 one, TypeTwo two, TypeThree three); +<<< +typedef G = T Function(TypeOne one, + TypeTwo two, TypeThree three); \ No newline at end of file diff --git a/test/whitespace/function_types.unit b/test/whitespace/function_types.unit new file mode 100644 index 00000000..4d92ad39 --- /dev/null +++ b/test/whitespace/function_types.unit @@ -0,0 +1,28 @@ +40 columns | +>>> non-generic in typedef (skip: published version of analyzer doesn't support function types yet) +typedef SomeFunc=ReturnType Function(int param, double other); +<<< +typedef SomeFunc = ReturnType Function( + int param, double other); +>>> generic in typedef (skip: published version of analyzer doesn't support function types yet) +typedef Generic = T Function(T param, double other); +<<< +typedef Generic = T Function( + T param, double other); +>>> no return type (skip: published version of analyzer doesn't support function types yet) +typedef SomeFunc = Function(); +<<< +typedef SomeFunc = Function(); +>>> nested (skip: published version of analyzer doesn't support function types yet) +typedef SomeFunc = Function(int first, Function(int first, bool second, String third) second, String third); +<<< +typedef SomeFunc = Function( + int first, + Function(int first, bool second, + String third) + second, + String third); +>>> 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 diff --git a/test/whitespace/metadata.unit b/test/whitespace/metadata.unit index 7f70cf7d..ce92c11a 100644 --- a/test/whitespace/metadata.unit +++ b/test/whitespace/metadata.unit @@ -253,4 +253,9 @@ function(@Annotation @VeryLongMetadataAnnotation covariant longParameter) {} function( @Annotation @VeryLongMetadataAnnotation - covariant longParameter) {} \ No newline at end of file + covariant longParameter) {} +>>> metadata on function typedef (skip: published version of analyzer doesn't support function types yet) +@foo typedef Fn = Function(); +<<< +@foo +typedef Fn = Function(); \ No newline at end of file