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/argument_list_visitor.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/dist/dart-style.d.ts ('k') | packages/dart_style/lib/src/call_chain_visitor.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: packages/dart_style/lib/src/argument_list_visitor.dart
diff --git a/packages/dart_style/lib/src/argument_list_visitor.dart b/packages/dart_style/lib/src/argument_list_visitor.dart
index b07198722b2ffd86b87e2ab8c10496de29ccee75..38bc6eb04476037866aa374796e38a657a7885a7 100644
--- a/packages/dart_style/lib/src/argument_list_visitor.dart
+++ b/packages/dart_style/lib/src/argument_list_visitor.dart
@@ -7,7 +7,7 @@ library dart_style.src.argument_list_visitor;
import 'dart:math' as math;
import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/dart/ast/token.dart';
import 'chunk.dart';
import 'rule/argument.dart';
@@ -20,7 +20,15 @@ import 'source_visitor.dart';
class ArgumentListVisitor {
final SourceVisitor _visitor;
- final ArgumentList _node;
+ /// The "(" before the argument list.
+ final Token _leftParenthesis;
+
+ /// The ")" after the argument list.
+ final Token _rightParenthesis;
+
+ /// All of the arguments, positional, named, and functions, in the argument
+ /// list.
+ final List<Expression> _allArguments;
/// The normal arguments preceding any block function arguments.
final ArgumentSublist _arguments;
@@ -37,7 +45,7 @@ class ArgumentListVisitor {
/// Returns `true` if there is only a single positional argument.
bool get _isSingle =>
- _node.arguments.length == 1 && _node.arguments.single is! NamedExpression;
+ _allArguments.length == 1 && _allArguments.single is! NamedExpression;
/// Whether this argument list has any collection or block function arguments.
// TODO(rnystrom): Returning true based on collections is non-optimal. It
@@ -48,12 +56,21 @@ class ArgumentListVisitor {
_arguments._collections.isNotEmpty || _functions != null;
factory ArgumentListVisitor(SourceVisitor visitor, ArgumentList node) {
+ return new ArgumentListVisitor.forArguments(
+ visitor, node.leftParenthesis, node.rightParenthesis, node.arguments);
+ }
+
+ factory ArgumentListVisitor.forArguments(
+ SourceVisitor visitor,
+ Token leftParenthesis,
+ Token rightParenthesis,
+ List<Expression> arguments) {
// Look for a single contiguous range of block function arguments.
var functionsStart;
var functionsEnd;
- for (var i = 0; i < node.arguments.length; i++) {
- var argument = node.arguments[i];
+ for (var i = 0; i < arguments.length; i++) {
+ var argument = arguments[i];
if (_isBlockFunction(argument)) {
if (functionsStart == null) functionsStart = i;
@@ -68,40 +85,76 @@ class ArgumentListVisitor {
}
}
+ // Edge case: If all of the arguments are named, but they aren't all
+ // functions, then don't handle the functions specially. A function with a
+ // bunch of named arguments tends to look best when they are all lined up,
+ // even the function ones (unless they are all functions).
+ //
+ // Prefers:
+ //
+ // function(
+ // named: () {
+ // something();
+ // },
+ // another: argument);
+ //
+ // Over:
+ //
+ // function(named: () {
+ // something();
+ // }
+ // another: argument);
+ if (functionsStart != null &&
+ arguments[0] is NamedExpression &&
+ (functionsStart > 0 || functionsEnd < arguments.length)) {
+ functionsStart = null;
+ }
+
if (functionsStart == null) {
// No functions, so there is just a single argument list.
- return new ArgumentListVisitor._(visitor, node,
- new ArgumentSublist(node.arguments, node.arguments), null, null);
+ return new ArgumentListVisitor._(
+ visitor,
+ leftParenthesis,
+ rightParenthesis,
+ arguments,
+ new ArgumentSublist(arguments, arguments),
+ null,
+ null);
}
// Split the arguments into two independent argument lists with the
// functions in the middle.
- var argumentsBefore = node.arguments.take(functionsStart).toList();
- var functions = node.arguments.sublist(functionsStart, functionsEnd);
- var argumentsAfter = node.arguments.skip(functionsEnd).toList();
+ var argumentsBefore = arguments.take(functionsStart).toList();
+ var functions = arguments.sublist(functionsStart, functionsEnd);
+ var argumentsAfter = arguments.skip(functionsEnd).toList();
return new ArgumentListVisitor._(
visitor,
- node,
- new ArgumentSublist(node.arguments, argumentsBefore),
+ leftParenthesis,
+ rightParenthesis,
+ arguments,
+ new ArgumentSublist(arguments, argumentsBefore),
functions,
- new ArgumentSublist(node.arguments, argumentsAfter));
+ new ArgumentSublist(arguments, argumentsAfter));
}
- ArgumentListVisitor._(this._visitor, this._node, this._arguments,
- this._functions, this._argumentsAfterFunctions);
+ ArgumentListVisitor._(
+ this._visitor,
+ this._leftParenthesis,
+ this._rightParenthesis,
+ this._allArguments,
+ this._arguments,
+ this._functions,
+ this._argumentsAfterFunctions);
- /// Builds chunks for the call chain.
+ /// Builds chunks for the argument list.
void visit() {
// If there is just one positional argument, it tends to look weird to
// split before it, so try not to.
if (_isSingle) _visitor.builder.startSpan();
- // Nest around the parentheses in case there are comments before or after
- // them.
- _visitor.builder.nestExpression();
_visitor.builder.startSpan();
- _visitor.token(_node.leftParenthesis);
+ _visitor.token(_leftParenthesis);
_arguments.visit(_visitor);
@@ -113,7 +166,7 @@ class ArgumentListVisitor {
// instead of just having this little solo split here. That would try to
// keep the parameter list with other arguments when possible, and, I
// think, generally look nicer.
- if (_functions.first == _node.arguments.first) {
+ if (_functions.first == _allArguments.first) {
_visitor.soloZeroSplit();
} else {
_visitor.soloSplit();
@@ -124,8 +177,8 @@ class ArgumentListVisitor {
_visitor.visit(argument);
- // Write the trailing comma.
- if (argument != _node.arguments.last) {
+ // Write the following comma.
+ if (argument.endToken.next.type == TokenType.COMMA) {
_visitor.token(argument.endToken.next);
}
}
@@ -135,9 +188,7 @@ class ArgumentListVisitor {
_visitor.builder.endSpan();
}
- _visitor.token(_node.rightParenthesis);
-
- _visitor.builder.unnest();
+ _visitor.token(_rightParenthesis);
if (_isSingle) _visitor.builder.endSpan();
}
@@ -232,8 +283,6 @@ class ArgumentSublist {
Chunk get previousSplit => _previousSplit;
Chunk _previousSplit;
- bool get _hasMultipleArguments => _positional.length + _named.length > 1;
-
factory ArgumentSublist(
List<Expression> allArguments, List<Expression> arguments) {
// Assumes named arguments follow all positional ones.
@@ -241,7 +290,7 @@ class ArgumentSublist {
arguments.takeWhile((arg) => arg is! NamedExpression).toList();
var named = arguments.skip(positional.length).toList();
- var collections = {};
+ var collections = <Expression, Token>{};
for (var argument in arguments) {
var bracket = _getCollectionBracket(argument);
if (bracket != null) collections[argument] = bracket;
@@ -294,22 +343,13 @@ class ArgumentSublist {
if (_positional.isEmpty) return null;
// Allow splitting after "(".
- var rule;
- if (_positional.length == 1) {
- rule = new SinglePositionalRule(_collectionRule,
- splitsOnInnerRules: _allArguments.length > 1 &&
- !_collections.containsKey(_positional.first));
- } else {
- // Only count the collections in the positional rule.
- var leadingCollections =
- math.min(_leadingCollections, _positional.length);
- var trailingCollections =
- math.max(_trailingCollections - _named.length, 0);
- rule = new MultiplePositionalRule(
- _collectionRule, leadingCollections, trailingCollections);
- }
-
+ // Only count the collections in the positional rule.
+ var leadingCollections = math.min(_leadingCollections, _positional.length);
+ var trailingCollections = math.max(_trailingCollections - _named.length, 0);
+ var rule = new PositionalRule(
+ _collectionRule, leadingCollections, trailingCollections);
_visitArguments(visitor, _positional, rule);
+
return rule;
}
@@ -338,7 +378,7 @@ class ArgumentSublist {
// Split before the first argument.
_previousSplit =
- visitor.builder.split(space: !_isFirstArgument(arguments.first));
+ visitor.builder.split(space: arguments.first != _allArguments.first);
rule.beforeArgument(_previousSplit);
// Try to not split the positional arguments.
@@ -365,38 +405,47 @@ class ArgumentSublist {
SourceVisitor visitor, ArgumentRule rule, Expression argument) {
// If we're about to write a collection argument, handle it specially.
if (_collections.containsKey(argument)) {
- if (rule != null) rule.beforeCollection();
+ rule.disableSplitOnInnerRules();
// Tell it to use the rule we've already created.
visitor.beforeCollection(_collections[argument], this);
- } else if (_hasMultipleArguments) {
- // Edge case: If there is just a single argument, don't bump the nesting.
- // This lets us avoid spurious indentation in cases like:
+ } else if (_allArguments.length > 1) {
+ // Edge case: Only bump the nesting if there are multiple arguments. This
+ // lets us avoid spurious indentation in cases like:
//
// function(function(() {
// body;
// }));
visitor.builder.startBlockArgumentNesting();
+ } else if (argument is! NamedExpression) {
+ // Edge case: Likewise, don't force the argument to split if there is
+ // only a single positional one, like:
+ //
+ // outer(inner(
+ // longArgument));
+ rule.disableSplitOnInnerRules();
}
- visitor.visit(argument);
+ if (argument is NamedExpression) {
+ visitor.visitNamedArgument(argument, rule as NamedRule);
+ } else {
+ visitor.visit(argument);
+ }
if (_collections.containsKey(argument)) {
- if (rule != null) rule.afterCollection();
- } else if (_hasMultipleArguments) {
+ rule.enableSplitOnInnerRules();
+ } else if (_allArguments.length > 1) {
visitor.builder.endBlockArgumentNesting();
+ } else if (argument is! NamedExpression) {
+ rule.enableSplitOnInnerRules();
}
- // Write the trailing comma.
- if (!_isLastArgument(argument)) {
+ // Write the following comma.
+ if (argument.endToken.next.type == TokenType.COMMA) {
visitor.token(argument.endToken.next);
}
}
- bool _isFirstArgument(Expression argument) => argument == _allArguments.first;
-
- bool _isLastArgument(Expression argument) => argument == _allArguments.last;
-
/// Returns the token for the left bracket if [expression] denotes a
/// collection literal argument.
///
« no previous file with comments | « packages/dart_style/dist/dart-style.d.ts ('k') | packages/dart_style/lib/src/call_chain_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698