diff --git a/lib/src/front_end/piece_factory.dart b/lib/src/front_end/piece_factory.dart index 0fa9f4fb..a3ff6489 100644 --- a/lib/src/front_end/piece_factory.dart +++ b/lib/src/front_end/piece_factory.dart @@ -616,6 +616,19 @@ mixin PieceFactory { return; } + // Hoist any comments before the function so they don't force a split + // between the return type and function. In most cases, this doesn't matter + // because the [SequenceBuilder] for the surrounding code will separate out + // the leading comment. But if there is a metadata annotation followed by + // a comment, then the function, then the comment doesn't get captured by + // the [SequenceBuilder], as in: + // + // @meta + // // Weird place for comment. + // int f() {} + var leadingComments = + pieces.takeCommentsBefore(returnType.firstNonCommentToken); + var returnTypePiece = pieces.build(() { for (var keyword in modifiers) { pieces.modifier(keyword); @@ -628,7 +641,8 @@ mixin PieceFactory { writeFunction(); }); - pieces.add(VariablePiece(returnTypePiece, [signature], hasType: true)); + pieces.add(prependLeadingComments(leadingComments, + VariablePiece(returnTypePiece, [signature], hasType: true))); } /// If [parameter] has a [defaultValue] then writes a piece for the parameter diff --git a/test/tall/function/comment.unit b/test/tall/function/comment.unit index 5d12641c..c31030fa 100644 --- a/test/tall/function/comment.unit +++ b/test/tall/function/comment.unit @@ -21,4 +21,12 @@ main() { // nested } } +} +>>> Don't split return type if comment before. +// Comment. +int f() {;} +<<< +// Comment. +int f() { + ; } \ No newline at end of file diff --git a/test/tall/function/metadata.unit b/test/tall/function/metadata.unit index 8c4ded94..22d091cb 100644 --- a/test/tall/function/metadata.unit +++ b/test/tall/function/metadata.unit @@ -95,4 +95,14 @@ f([ @metadata @another(argument, argument) callback() = constantFunction, -]) {} \ No newline at end of file +]) {} +>>> Don't split return type if comment after metadata. +@meta +// Comment. +int f() {;} +<<< +@meta +// Comment. +int f() { + ; +} \ No newline at end of file diff --git a/test/tall/regression/other/dart.unit b/test/tall/regression/other/dart.unit index 2821123a..f0c6c8df 100644 --- a/test/tall/regression/other/dart.unit +++ b/test/tall/regression/other/dart.unit @@ -39,4 +39,19 @@ main() { .transform(utf8.decoder) .transform(const LineSplitter()) .asBroadcastStream(); +} +>>> Don't split return type if comment after metadata annotation. +class Benchmark { + @override + // A rate of one run per 2s, with a millisecond of noise. Some variation is + // needed for Golem's noise-based filtering and regression detection. + double + measure() => (2000 + Random().nextDouble() - 0.5) * 1000; +} +<<< +class Benchmark { + @override + // A rate of one run per 2s, with a millisecond of noise. Some variation is + // needed for Golem's noise-based filtering and regression detection. + double measure() => (2000 + Random().nextDouble() - 0.5) * 1000; } \ No newline at end of file