Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Unified Diff: packages/dart_style/lib/src/chunk_builder.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « packages/dart_style/lib/src/chunk.dart ('k') | packages/dart_style/lib/src/dart_formatter.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: packages/dart_style/lib/src/chunk_builder.dart
diff --git a/packages/dart_style/lib/src/chunk_builder.dart b/packages/dart_style/lib/src/chunk_builder.dart
index 3aa95a5caf60adbf4b0aabede74e244216916081..d141cbc44125743427463232475949d6fc1c11c6 100644
--- a/packages/dart_style/lib/src/chunk_builder.dart
+++ b/packages/dart_style/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.
@@ -98,7 +101,6 @@ class ChunkBuilder {
/// token pair.
bool get needsToPreserveNewlines =>
_pendingWhitespace == Whitespace.oneOrTwoNewlines ||
- _pendingWhitespace == Whitespace.spaceOrNewline ||
_pendingWhitespace == Whitespace.splitOrNewline;
/// The number of characters of code that can fit in a single line.
@@ -171,7 +173,7 @@ class ChunkBuilder {
/// previous token if there are no comments) and the next token.
void writeComments(
List<SourceComment> comments, int linesBeforeToken, String token) {
- // Corner case: if we require a blank line, but there exists one between
+ // Edge case: if we require a blank line, but there exists one between
// some of the comments, or after the last one, then we don't need to
// enforce one before the first comment. Example:
//
@@ -197,8 +199,8 @@ class ChunkBuilder {
}
}
- // Corner case: if the comments are completely inline (i.e. just a series
- // of block comments with no newlines before, after, or between them), then
+ // Edge case: if the comments are completely inline (i.e. just a series of
+ // block comments with no newlines before, after, or between them), then
// they will eat any pending newlines. Make sure that doesn't happen by
// putting the pending whitespace before the first comment and moving them
// to their own line. Turns this:
@@ -241,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(
@@ -300,14 +300,6 @@ class ChunkBuilder {
// If we didn't know how many newlines the user authored between the last
// token and this one, now we do.
switch (_pendingWhitespace) {
- case Whitespace.spaceOrNewline:
- if (numLines > 0) {
- _pendingWhitespace = Whitespace.nestedNewline;
- } else {
- _pendingWhitespace = Whitespace.space;
- }
- break;
-
case Whitespace.splitOrNewline:
if (numLines > 0) {
_pendingWhitespace = Whitespace.nestedNewline;
@@ -369,15 +361,18 @@ class ChunkBuilder {
if (rule == null) rule = new Rule();
// See if any of the rules that contain this one care if it splits.
- _rules.forEach((outer) => outer.contain(rule));
+ _rules.forEach((outer) {
+ if (!outer.splitsOnInnerRules) return;
+ rule.imply(outer);
+ });
_rules.add(rule);
}
/// Starts a new [Rule] that comes into play *after* the next whitespace
/// (including comments) is written.
///
- /// This is used for binary operators who want to start a rule before the
- /// first operand but not get forced to split if a comment appears before the
+ /// This is used for operators who want to start a rule before the first
+ /// operand but not get forced to split if a comment appears before the
/// entire expression.
///
/// If [rule] is omitted, defaults to a new [Rule].
@@ -389,7 +384,11 @@ class ChunkBuilder {
/// Ends the innermost rule.
void endRule() {
- _rules.removeLast();
+ if (_lazyRules.isNotEmpty) {
+ _lazyRules.removeLast();
+ } else {
+ _rules.removeLast();
+ }
}
/// Pre-emptively forces all of the current rules to become hard splits.
@@ -595,7 +594,6 @@ class ChunkBuilder {
_writeHardSplit(isDouble: true);
break;
- case Whitespace.spaceOrNewline:
case Whitespace.splitOrNewline:
case Whitespace.oneOrTwoNewlines:
// We should have pinned these down before getting here.
@@ -615,12 +613,25 @@ class ChunkBuilder {
// Multi-line comments are always pushed to the next line.
if (comment.contains("\n")) return false;
- // If the text before the split is an open grouping character, we don't
- // want to adhere the comment to that.
var text = _chunks.last.text;
+
+ // A block comment following a comma probably refers to the following item.
+ if (text.endsWith(",") && comment.startsWith("/*")) return false;
+
+ // If the text before the split is an open grouping character, it looks
+ // better to keep it with the elements than with the bracket itself.
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.
///
@@ -633,7 +644,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;
@@ -644,7 +655,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("{");
@@ -659,6 +676,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 != ")" &&
« no previous file with comments | « packages/dart_style/lib/src/chunk.dart ('k') | packages/dart_style/lib/src/dart_formatter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698