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

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

Issue 2526633002: Support generic methods. Fix #556. (Closed)
Patch Set: Merge branch 'master' into generic-methods Created 4 years 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 | « lib/src/dart_formatter.dart ('k') | pubspec.lock » ('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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 /// 126 ///
127 /// This is a bit complex to handle the rules for formatting positional and 127 /// This is a bit complex to handle the rules for formatting positional and
128 /// named arguments. The goals, in rough order of descending priority are: 128 /// named arguments. The goals, in rough order of descending priority are:
129 /// 129 ///
130 /// 1. Keep everything on the first line. 130 /// 1. Keep everything on the first line.
131 /// 2. Keep the named arguments together on the next line. 131 /// 2. Keep the named arguments together on the next line.
132 /// 3. Keep everything together on the second line. 132 /// 3. Keep everything together on the second line.
133 /// 4. Split between one or more positional arguments, trying to keep as many 133 /// 4. Split between one or more positional arguments, trying to keep as many
134 /// on earlier lines as possible. 134 /// on earlier lines as possible.
135 /// 5. Split the named arguments each onto their own line. 135 /// 5. Split the named arguments each onto their own line.
136 visitArgumentList(ArgumentList node) { 136 visitArgumentList(ArgumentList node, {bool nestExpression: true}) {
137 // Corner case: handle empty argument lists. 137 // Corner case: handle empty argument lists.
138 if (node.arguments.isEmpty) { 138 if (node.arguments.isEmpty) {
139 token(node.leftParenthesis); 139 token(node.leftParenthesis);
140 140
141 // If there is a comment inside the parens, do allow splitting before it. 141 // If there is a comment inside the parens, do allow splitting before it.
142 if (node.rightParenthesis.precedingComments != null) soloZeroSplit(); 142 if (node.rightParenthesis.precedingComments != null) soloZeroSplit();
143 143
144 token(node.rightParenthesis); 144 token(node.rightParenthesis);
145 return; 145 return;
146 } 146 }
147 147
148 // If the argument list has a trailing comma, format it like a collection 148 // If the argument list has a trailing comma, format it like a collection
149 // literal where each argument goes on its own line, they are indented +2, 149 // literal where each argument goes on its own line, they are indented +2,
150 // and the ")" ends up on its own line. 150 // and the ")" ends up on its own line.
151 if (node.arguments.last.endToken.next.type == TokenType.COMMA) { 151 if (node.arguments.last.endToken.next.type == TokenType.COMMA) {
152 _visitCollectionLiteral( 152 _visitCollectionLiteral(
153 null, node.leftParenthesis, node.arguments, node.rightParenthesis); 153 null, node.leftParenthesis, node.arguments, node.rightParenthesis);
154 return; 154 return;
155 } 155 }
156 156
157 if (nestExpression) builder.nestExpression();
157 new ArgumentListVisitor(this, node).visit(); 158 new ArgumentListVisitor(this, node).visit();
159 if (nestExpression) builder.unnest();
158 } 160 }
159 161
160 visitAsExpression(AsExpression node) { 162 visitAsExpression(AsExpression node) {
161 builder.startSpan(); 163 builder.startSpan();
162 builder.nestExpression(); 164 builder.nestExpression();
163 visit(node.expression); 165 visit(node.expression);
164 soloSplit(); 166 soloSplit();
165 token(node.asOperator); 167 token(node.asOperator);
166 space(); 168 space();
167 visit(node.type); 169 visit(node.type);
168 builder.unnest(); 170 builder.unnest();
169 builder.endSpan(); 171 builder.endSpan();
170 } 172 }
171 173
172 // TODO(rnystrom): Type annotate once analyzer publishes a version with the 174 // TODO(rnystrom): Type annotate once analyzer publishes a version with the
173 // new AST type. 175 // new AST type.
174 // TODO(rnystrom): Test. 176 // TODO(rnystrom): Test.
175 visitAssertInitializer(node) { 177 visitAssertInitializer(node) {
176 _simpleStatement(node, () { 178 _simpleStatement(node, () {
177 token(node.assertKeyword); 179 token(node.assertKeyword);
178 180
179 var arguments = <Expression>[node.condition]; 181 var arguments = <Expression>[node.condition];
180 if (node.message != null) arguments.add(node.message); 182 if (node.message != null) arguments.add(node.message);
181 183
184 builder.nestExpression();
182 var visitor = new ArgumentListVisitor.forArguments( 185 var visitor = new ArgumentListVisitor.forArguments(
183 this, node.leftParenthesis, node.rightParenthesis, arguments); 186 this, node.leftParenthesis, node.rightParenthesis, arguments);
184 visitor.visit(); 187 visitor.visit();
188 builder.unnest();
185 }); 189 });
186 } 190 }
187 191
188 visitAssertStatement(AssertStatement node) { 192 visitAssertStatement(AssertStatement node) {
189 _simpleStatement(node, () { 193 _simpleStatement(node, () {
190 token(node.assertKeyword); 194 token(node.assertKeyword);
191 195
192 var arguments = [node.condition]; 196 var arguments = [node.condition];
193 if (node.message != null) arguments.add(node.message); 197 if (node.message != null) arguments.add(node.message);
194 198
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 visit(node.index); 1217 visit(node.index);
1214 token(node.rightBracket); 1218 token(node.rightBracket);
1215 builder.endSpan(); 1219 builder.endSpan();
1216 } 1220 }
1217 1221
1218 visitInstanceCreationExpression(InstanceCreationExpression node) { 1222 visitInstanceCreationExpression(InstanceCreationExpression node) {
1219 builder.startSpan(); 1223 builder.startSpan();
1220 token(node.keyword); 1224 token(node.keyword);
1221 space(); 1225 space();
1222 builder.startSpan(Cost.constructorName); 1226 builder.startSpan(Cost.constructorName);
1227
1228 // Start the expression nesting for the argument list here, in case this
1229 // is a generic constructor with type arguments. If it is, we need the type
1230 // arguments to be nested too so they get indented past the arguments.
1231 builder.nestExpression();
1223 visit(node.constructorName); 1232 visit(node.constructorName);
1233
1224 builder.endSpan(); 1234 builder.endSpan();
1225 visit(node.argumentList); 1235 visitArgumentList(node.argumentList, nestExpression: false);
1226 builder.endSpan(); 1236 builder.endSpan();
1237
1238 builder.unnest();
1227 } 1239 }
1228 1240
1229 visitIntegerLiteral(IntegerLiteral node) { 1241 visitIntegerLiteral(IntegerLiteral node) {
1230 token(node.literal); 1242 token(node.literal);
1231 } 1243 }
1232 1244
1233 visitInterpolationExpression(InterpolationExpression node) { 1245 visitInterpolationExpression(InterpolationExpression node) {
1234 token(node.leftBracket); 1246 token(node.leftBracket);
1235 visit(node.expression); 1247 visit(node.expression);
1236 token(node.rightBracket); 1248 token(node.rightBracket);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 visitMethodInvocation(MethodInvocation node) { 1320 visitMethodInvocation(MethodInvocation node) {
1309 // If there's no target, this is a "bare" function call like "foo(1, 2)", 1321 // If there's no target, this is a "bare" function call like "foo(1, 2)",
1310 // or a section in a cascade. Handle this case specially. 1322 // or a section in a cascade. Handle this case specially.
1311 if (node.target == null) { 1323 if (node.target == null) {
1312 // Try to keep the entire method invocation one line. 1324 // Try to keep the entire method invocation one line.
1313 builder.startSpan(); 1325 builder.startSpan();
1314 builder.nestExpression(); 1326 builder.nestExpression();
1315 1327
1316 // This will be non-null for cascade sections. 1328 // This will be non-null for cascade sections.
1317 token(node.operator); 1329 token(node.operator);
1318 token(node.methodName.token); 1330 visit(node.methodName);
1319 visit(node.argumentList); 1331
1332 // TODO(rnystrom): Currently, there are no constraints between a generic
1333 // method's type arguments and arguments. That can lead to some funny
1334 // splitting like:
1335 //
1336 // method<VeryLongType,
1337 // AnotherTypeArgument>(argument,
1338 // argument, argument, argument);
1339 //
1340 // The indentation is fine, but splitting in the middle of each argument
1341 // list looks kind of strange. If this ends up happening in real world
1342 // code, consider putting a constraint between them.
1343
1344 visit(node.typeArguments);
1345 visitArgumentList(node.argumentList, nestExpression: false);
1320 1346
1321 builder.unnest(); 1347 builder.unnest();
1322 builder.endSpan(); 1348 builder.endSpan();
1323 return; 1349 return;
1324 } 1350 }
1325 1351
1326 new CallChainVisitor(this, node).visit(); 1352 new CallChainVisitor(this, node).visit();
1327 } 1353 }
1328 1354
1329 visitNamedExpression(NamedExpression node) { 1355 visitNamedExpression(NamedExpression node) {
(...skipping 1264 matching lines...) Expand 10 before | Expand all | Expand 10 after
2594 /// Gets the 1-based line number that the beginning of [token] lies on. 2620 /// Gets the 1-based line number that the beginning of [token] lies on.
2595 int _startLine(Token token) => _lineInfo.getLocation(token.offset).lineNumber; 2621 int _startLine(Token token) => _lineInfo.getLocation(token.offset).lineNumber;
2596 2622
2597 /// Gets the 1-based line number that the end of [token] lies on. 2623 /// Gets the 1-based line number that the end of [token] lies on.
2598 int _endLine(Token token) => _lineInfo.getLocation(token.end).lineNumber; 2624 int _endLine(Token token) => _lineInfo.getLocation(token.end).lineNumber;
2599 2625
2600 /// Gets the 1-based column number that the beginning of [token] lies on. 2626 /// Gets the 1-based column number that the beginning of [token] lies on.
2601 int _startColumn(Token token) => 2627 int _startColumn(Token token) =>
2602 _lineInfo.getLocation(token.offset).columnNumber; 2628 _lineInfo.getLocation(token.offset).columnNumber;
2603 } 2629 }
OLDNEW
« no previous file with comments | « lib/src/dart_formatter.dart ('k') | pubspec.lock » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698