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

Side by Side Diff: lib/src/source_visitor.dart

Issue 2196863002: Format parameter lists with trailing commas like argument lists. (Closed) Base URL: https://github.com/dart-lang/dart_style.git@master
Patch Set: Created 4 years, 4 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 unified diff | Download patch
« no previous file with comments | « bin/format.dart ('k') | pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart_style.src.source_visitor; 5 library dart_style.src.source_visitor;
6 6
7 import 'package:analyzer/analyzer.dart'; 7 import 'package:analyzer/analyzer.dart';
8 import 'package:analyzer/dart/ast/token.dart'; 8 import 'package:analyzer/dart/ast/token.dart';
9 import 'package:analyzer/src/generated/source.dart'; 9 import 'package:analyzer/src/generated/source.dart';
10 10
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 if (node.parameters.isEmpty) { 872 if (node.parameters.isEmpty) {
873 token(node.leftParenthesis); 873 token(node.leftParenthesis);
874 874
875 // If there is a comment, do allow splitting before it. 875 // If there is a comment, do allow splitting before it.
876 if (node.rightParenthesis.precedingComments != null) soloZeroSplit(); 876 if (node.rightParenthesis.precedingComments != null) soloZeroSplit();
877 877
878 token(node.rightParenthesis); 878 token(node.rightParenthesis);
879 return; 879 return;
880 } 880 }
881 881
882 // If the parameter list has a trailing comma, format it like a collection
883 // literal where each parameter goes on its own line, they are indented +2,
884 // and the ")" ends up on its own line.
885 if (node.parameters.last.endToken.next.type == TokenType.COMMA) {
886 _visitTrailingCommaParameterList(node);
887 return;
888 }
889
882 var requiredParams = node.parameters 890 var requiredParams = node.parameters
883 .where((param) => param is! DefaultFormalParameter) 891 .where((param) => param is! DefaultFormalParameter)
884 .toList(); 892 .toList();
885 var optionalParams = node.parameters 893 var optionalParams = node.parameters
886 .where((param) => param is DefaultFormalParameter) 894 .where((param) => param is DefaultFormalParameter)
887 .toList(); 895 .toList();
888 896
889 builder.nestExpression(); 897 builder.nestExpression();
890 token(node.leftParenthesis); 898 token(node.leftParenthesis);
891 899
(...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 // parameter) => 1855 // parameter) =>
1848 // function( 1856 // function(
1849 // argument); 1857 // argument);
1850 if (body is ExpressionFunctionBody) { 1858 if (body is ExpressionFunctionBody) {
1851 builder.nestExpression(); 1859 builder.nestExpression();
1852 1860
1853 // This rule is ended by visitExpressionFunctionBody(). 1861 // This rule is ended by visitExpressionFunctionBody().
1854 builder.startLazyRule(new Rule(Cost.arrow)); 1862 builder.startLazyRule(new Rule(Cost.arrow));
1855 } 1863 }
1856 1864
1857 if (parameters != null) { 1865 if (parameters != null) visit(parameters);
1858 builder.nestExpression();
1859 visit(parameters);
1860 builder.unnest();
1861 }
1862 1866
1863 if (beforeBody != null) beforeBody(); 1867 if (beforeBody != null) beforeBody();
1864 visit(body); 1868 visit(body);
1865 1869
1866 if (body is ExpressionFunctionBody) builder.unnest(); 1870 if (body is ExpressionFunctionBody) builder.unnest();
1867 } 1871 }
1868 1872
1869 /// Visits the body statement of a `for`, `for in`, or `while` loop. 1873 /// Visits the body statement of a `for`, `for in`, or `while` loop.
1870 void _visitLoopBody(Statement body) { 1874 void _visitLoopBody(Statement body) {
1871 if (body is EmptyStatement) { 1875 if (body is EmptyStatement) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 2017
2014 // If the collection has a trailing comma, the user must want it to split. 2018 // If the collection has a trailing comma, the user must want it to split.
2015 if (elements.isNotEmpty && 2019 if (elements.isNotEmpty &&
2016 elements.last.endToken.next.type == TokenType.COMMA) { 2020 elements.last.endToken.next.type == TokenType.COMMA) {
2017 force = true; 2021 force = true;
2018 } 2022 }
2019 2023
2020 _endLiteralBody(rightBracket, ignoredRule: rule, forceSplit: force); 2024 _endLiteralBody(rightBracket, ignoredRule: rule, forceSplit: force);
2021 } 2025 }
2022 2026
2027 /// Writes [parameters], which is assumed to have a trailing comma after the
2028 /// last parameter.
2029 ///
2030 /// Parameter lists with trailing commas are formatted differently from
2031 /// regular parameter lists. They are treated more like collection literals.
2032 ///
2033 /// We don't reuse [_visitCollectionLiteral] here because there are enough
2034 /// weird differences around optional parameters that it's easiest just to
2035 /// give them their own method.
2036 void _visitTrailingCommaParameterList(FormalParameterList parameters) {
2037 // Can't have a trailing comma if there are no parameters.
2038 assert(parameters.parameters.isNotEmpty);
jakemac 2016/07/29 21:57:05 or possibly assert(node.parameters.last.endToken.n
Bob Nystrom 2016/07/29 22:18:26 I could assert that too, but it felt a bit gratuit
2039
2040 // Always split the parameters.
2041 builder.startRule(new Rule.hard());
2042
2043 token(parameters.leftParenthesis);
2044
2045 // Find the parameter immediately preceding the optional parameters (if
2046 // there are any).
2047 FormalParameter lastRequired;
2048 for (var i = 0; i < parameters.parameters.length; i++) {
2049 if (parameters.parameters[i] is DefaultFormalParameter) {
2050 if (i > 0) lastRequired = parameters.parameters[i - 1];
2051 break;
2052 }
2053 }
2054
2055 // If all parameters are optional, put the "[" or "{" right after "(".
2056 if (parameters.parameters.first is DefaultFormalParameter) {
2057 token(parameters.leftDelimiter);
2058 }
2059
2060 // Process the parameters as a separate set of chunks.
2061 builder = builder.startBlock(null);
2062
2063 for (var parameter in parameters.parameters) {
2064 builder.nestExpression();
2065 visit(parameter);
2066
2067 // The comma after the parameter.
2068 if (parameter.endToken.next.type == TokenType.COMMA) {
2069 token(parameter.endToken.next);
2070 }
2071
2072 // If the optional parameters start after this one, put the delimiter
2073 // at the end of its line.
2074 if (parameter == lastRequired) {
2075 space();
2076 token(parameters.leftDelimiter);
2077 lastRequired = null;
2078 }
2079
2080 builder.unnest();
2081 newline();
2082 }
2083
2084 // Put comments before the closing ")", "]", or "}" inside the block.
2085 var firstDelimiter =
2086 parameters.rightDelimiter ?? parameters.rightParenthesis;
2087 writePrecedingCommentsAndNewlines(firstDelimiter);
2088 builder = builder.endBlock(null, forceSplit: true);
2089 builder.endRule();
2090
2091 // Now write the delimiter itself.
2092 _writeText(firstDelimiter.lexeme, firstDelimiter.offset);
2093 if (firstDelimiter != parameters.rightParenthesis) {
2094 token(parameters.rightParenthesis);
2095 }
2096 }
2097
2023 /// Gets the cost to split at an assignment (or `:` in the case of a named 2098 /// Gets the cost to split at an assignment (or `:` in the case of a named
2024 /// default value) with the given [rightHandSide]. 2099 /// default value) with the given [rightHandSide].
2025 /// 2100 ///
2026 /// "Block-like" expressions (collections and cascades) bind a bit tighter 2101 /// "Block-like" expressions (collections and cascades) bind a bit tighter
2027 /// because it looks better to have code like: 2102 /// because it looks better to have code like:
2028 /// 2103 ///
2029 /// var list = [ 2104 /// var list = [
2030 /// element, 2105 /// element,
2031 /// element, 2106 /// element,
2032 /// element 2107 /// element
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
2491 /// Gets the 1-based line number that the beginning of [token] lies on. 2566 /// Gets the 1-based line number that the beginning of [token] lies on.
2492 int _startLine(Token token) => _lineInfo.getLocation(token.offset).lineNumber; 2567 int _startLine(Token token) => _lineInfo.getLocation(token.offset).lineNumber;
2493 2568
2494 /// Gets the 1-based line number that the end of [token] lies on. 2569 /// Gets the 1-based line number that the end of [token] lies on.
2495 int _endLine(Token token) => _lineInfo.getLocation(token.end).lineNumber; 2570 int _endLine(Token token) => _lineInfo.getLocation(token.end).lineNumber;
2496 2571
2497 /// Gets the 1-based column number that the beginning of [token] lies on. 2572 /// Gets the 1-based column number that the beginning of [token] lies on.
2498 int _startColumn(Token token) => 2573 int _startColumn(Token token) =>
2499 _lineInfo.getLocation(token.offset).columnNumber; 2574 _lineInfo.getLocation(token.offset).columnNumber;
2500 } 2575 }
OLDNEW
« no previous file with comments | « bin/format.dart ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698