| Index: lib/src/chunk_builder.dart
|
| diff --git a/lib/src/chunk_builder.dart b/lib/src/chunk_builder.dart
|
| index 2109991399cdd565c8a830489d7bdb857d087947..54695cfaccb1cdcc76cf67391d608a1c0414795e 100644
|
| --- a/lib/src/chunk_builder.dart
|
| +++ b/lib/src/chunk_builder.dart
|
| @@ -14,6 +14,9 @@ import 'rule/rule.dart';
|
| import 'source_code.dart';
|
| import 'whitespace.dart';
|
|
|
| +/// Matches if the last character of a string is an identifier character.
|
| +final _trailingIdentifierChar = new RegExp(r"[a-zA-Z0-9_]$");
|
| +
|
| /// Takes the incremental serialized output of [SourceVisitor]--the source text
|
| /// along with any comments and preserved whitespace--and produces a coherent
|
| /// tree of [Chunk]s which can then be split into physical lines.
|
| @@ -240,9 +243,7 @@ class ChunkBuilder {
|
|
|
| // The comment follows other text, so we need to decide if it gets a
|
| // space before it or not.
|
| - if (_needsSpaceBeforeComment(isLineComment: comment.isLineComment)) {
|
| - _writeText(" ");
|
| - }
|
| + if (_needsSpaceBeforeComment(comment)) _writeText(" ");
|
| } else {
|
| // The comment starts a line, so make sure it stays on its own line.
|
| _writeHardSplit(
|
| @@ -614,6 +615,15 @@ class ChunkBuilder {
|
| return !text.endsWith("(") && !text.endsWith("[") && !text.endsWith("{");
|
| }
|
|
|
| + /// Returns `true` if [comment] appears to be a magic generic method comment.
|
| + ///
|
| + /// Those get spaced a little differently to look more like real syntax:
|
| + ///
|
| + /// int f/*<S, T>*/(int x) => 3;
|
| + bool _isGenericMethodComment(SourceComment comment) {
|
| + return comment.text.startsWith("/*<") || comment.text.startsWith("/*=");
|
| + }
|
| +
|
| /// Returns `true` if a space should be output between the end of the current
|
| /// output and the subsequent comment which is about to be written.
|
| ///
|
| @@ -626,7 +636,7 @@ class ChunkBuilder {
|
| /// * The comment is a block comment immediately following a grouping
|
| /// character (`(`, `[`, or `{`). This is to allow `foo(/* comment */)`,
|
| /// et. al.
|
| - bool _needsSpaceBeforeComment({bool isLineComment}) {
|
| + bool _needsSpaceBeforeComment(SourceComment comment) {
|
| // Not at the start of the file.
|
| if (_chunks.isEmpty) return false;
|
|
|
| @@ -637,7 +647,13 @@ class ChunkBuilder {
|
| if (text.endsWith("\n")) return false;
|
|
|
| // Always put a space before line comments.
|
| - if (isLineComment) return true;
|
| + if (comment.isLineComment) return true;
|
| +
|
| + // Magic generic method comments like "Foo/*<T>*/" don't get spaces.
|
| + if (_isGenericMethodComment(comment) &&
|
| + _trailingIdentifierChar.hasMatch(text)) {
|
| + return false;
|
| + }
|
|
|
| // Block comments do not get a space if following a grouping character.
|
| return !text.endsWith("(") && !text.endsWith("[") && !text.endsWith("{");
|
| @@ -652,6 +668,11 @@ class ChunkBuilder {
|
| // Not at the beginning of a line.
|
| if (!_chunks.last.canAddText) return false;
|
|
|
| + // Magic generic method comments like "Foo/*<T>*/" don't get spaces.
|
| + if (_isGenericMethodComment(comments.last) && token == "(") {
|
| + return false;
|
| + }
|
| +
|
| // Otherwise, it gets a space if the following token is not a delimiter or
|
| // the empty string, for EOF.
|
| return token != ")" &&
|
|
|