OLD | NEW |
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/src/generated/scanner.dart'; | 8 import 'package:analyzer/src/generated/scanner.dart'; |
9 import 'package:analyzer/src/generated/source.dart'; | 9 import 'package:analyzer/src/generated/source.dart'; |
10 | 10 |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 visit(node.elseExpression); | 449 visit(node.elseExpression); |
450 | 450 |
451 _writer.endMultisplit(); | 451 _writer.endMultisplit(); |
452 _writer.endSpan(); | 452 _writer.endSpan(); |
453 _writer.unnest(); | 453 _writer.unnest(); |
454 } | 454 } |
455 | 455 |
456 visitConstructorDeclaration(ConstructorDeclaration node) { | 456 visitConstructorDeclaration(ConstructorDeclaration node) { |
457 visitMemberMetadata(node.metadata); | 457 visitMemberMetadata(node.metadata); |
458 | 458 |
459 _writer.nestExpression(); | |
460 modifier(node.externalKeyword); | 459 modifier(node.externalKeyword); |
461 modifier(node.constKeyword); | 460 modifier(node.constKeyword); |
462 modifier(node.factoryKeyword); | 461 modifier(node.factoryKeyword); |
463 visit(node.returnType); | 462 visit(node.returnType); |
464 token(node.period); | 463 token(node.period); |
465 visit(node.name); | 464 visit(node.name); |
466 | 465 |
467 // Start a multisplit that spans the parameter list. We'll use this for the | 466 // Start a multisplit that spans the parameter list. We'll use this for the |
468 // split before ":" to ensure that if the parameter list doesn't fit on one | 467 // split before ":" to ensure that if the parameter list doesn't fit on one |
469 // line that the initialization list gets pushed to its own line too. | 468 // line that the initialization list gets pushed to its own line too. |
470 if (node.initializers.length == 1) _writer.startMultisplit(); | 469 if (node.initializers.length == 1) _writer.startMultisplit(); |
471 | 470 |
472 visit(node.parameters); | 471 _visitBody(node.parameters, node.body, () { |
473 | 472 // Check for redirects or initializer lists. |
474 // Check for redirects or initializer lists. | 473 if (node.redirectedConstructor != null) { |
475 if (node.redirectedConstructor != null) { | 474 _visitConstructorRedirects(node); |
476 _visitConstructorRedirects(node); | 475 } else if (node.initializers.isNotEmpty) { |
477 } else if (node.initializers.isNotEmpty) { | 476 _visitConstructorInitializers(node); |
478 _visitConstructorInitializers(node); | 477 } |
479 } | 478 }); |
480 | |
481 _writer.unnest(); | |
482 | |
483 visitBody(node.body); | |
484 } | 479 } |
485 | 480 |
486 void _visitConstructorInitializers(ConstructorDeclaration node) { | 481 void _visitConstructorInitializers(ConstructorDeclaration node) { |
487 _writer.indent(2); | 482 _writer.indent(2); |
488 | 483 |
489 if (node.initializers.length == 1) { | 484 if (node.initializers.length == 1) { |
490 // If there is only a single initializer, allow it on the first line, but | 485 // If there is only a single initializer, allow it on the first line, but |
491 // only if the parameter list also fit all one line. | 486 // only if the parameter list also fit all one line. |
492 _writer.multisplit(space: true); | 487 _writer.multisplit(space: true); |
493 _writer.endMultisplit(); | 488 _writer.endMultisplit(); |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 token(node.inKeyword); | 698 token(node.inKeyword); |
704 space(); | 699 space(); |
705 visit(node.iterator); | 700 visit(node.iterator); |
706 token(node.rightParenthesis); | 701 token(node.rightParenthesis); |
707 space(); | 702 space(); |
708 visit(node.body); | 703 visit(node.body); |
709 _writer.unnest(); | 704 _writer.unnest(); |
710 } | 705 } |
711 | 706 |
712 visitFormalParameterList(FormalParameterList node) { | 707 visitFormalParameterList(FormalParameterList node) { |
| 708 _writer.nestExpression(); |
713 token(node.leftParenthesis); | 709 token(node.leftParenthesis); |
714 | 710 |
715 // Allow splitting after the "(" in non-empty parameter lists, but not for | 711 // Allow splitting after the "(" in non-empty parameter lists, but not for |
716 // lambdas. | 712 // lambdas. |
717 if ((node.parameters.isNotEmpty || | 713 if ((node.parameters.isNotEmpty || |
718 node.rightParenthesis.precedingComments != null) && | 714 node.rightParenthesis.precedingComments != null) && |
719 !_isLambda(node)) { | 715 !_isLambda(node)) { |
720 zeroSplit(); | 716 zeroSplit(); |
721 } | 717 } |
722 | 718 |
(...skipping 24 matching lines...) Expand all Loading... |
747 inOptionalParams = true; | 743 inOptionalParams = true; |
748 } | 744 } |
749 | 745 |
750 visit(parameter); | 746 visit(parameter); |
751 } | 747 } |
752 | 748 |
753 // "]" or "}" for optional parameters. | 749 // "]" or "}" for optional parameters. |
754 token(node.rightDelimiter); | 750 token(node.rightDelimiter); |
755 | 751 |
756 token(node.rightParenthesis); | 752 token(node.rightParenthesis); |
| 753 _writer.unnest(); |
757 _writer.endSpan(); | 754 _writer.endSpan(); |
758 } | 755 } |
759 | 756 |
760 visitForStatement(ForStatement node) { | 757 visitForStatement(ForStatement node) { |
761 _writer.nestExpression(); | 758 _writer.nestExpression(); |
762 token(node.forKeyword); | 759 token(node.forKeyword); |
763 space(); | 760 space(); |
764 token(node.leftParenthesis); | 761 token(node.leftParenthesis); |
765 | 762 |
766 _writer.startMultisplit(); | 763 _writer.startMultisplit(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 visit(node.name); | 815 visit(node.name); |
819 visit(node.functionExpression); | 816 visit(node.functionExpression); |
820 _writer.unnest(); | 817 _writer.unnest(); |
821 } | 818 } |
822 | 819 |
823 visitFunctionDeclarationStatement(FunctionDeclarationStatement node) { | 820 visitFunctionDeclarationStatement(FunctionDeclarationStatement node) { |
824 visit(node.functionDeclaration); | 821 visit(node.functionDeclaration); |
825 } | 822 } |
826 | 823 |
827 visitFunctionExpression(FunctionExpression node) { | 824 visitFunctionExpression(FunctionExpression node) { |
828 visit(node.parameters); | 825 _visitBody(node.parameters, node.body); |
829 visitBody(node.body); | |
830 } | 826 } |
831 | 827 |
832 visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 828 visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
833 visit(node.function); | 829 visit(node.function); |
834 visit(node.argumentList); | 830 visit(node.argumentList); |
835 } | 831 } |
836 | 832 |
837 visitFunctionTypeAlias(FunctionTypeAlias node) { | 833 visitFunctionTypeAlias(FunctionTypeAlias node) { |
838 visitDeclarationMetadata(node.metadata); | 834 visitDeclarationMetadata(node.metadata); |
839 | 835 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 visitMapLiteralEntry(MapLiteralEntry node) { | 994 visitMapLiteralEntry(MapLiteralEntry node) { |
999 visit(node.key); | 995 visit(node.key); |
1000 token(node.separator); | 996 token(node.separator); |
1001 split(); | 997 split(); |
1002 visit(node.value); | 998 visit(node.value); |
1003 } | 999 } |
1004 | 1000 |
1005 visitMethodDeclaration(MethodDeclaration node) { | 1001 visitMethodDeclaration(MethodDeclaration node) { |
1006 visitMemberMetadata(node.metadata); | 1002 visitMemberMetadata(node.metadata); |
1007 | 1003 |
1008 _writer.nestExpression(); | |
1009 modifier(node.externalKeyword); | 1004 modifier(node.externalKeyword); |
1010 modifier(node.modifierKeyword); | 1005 modifier(node.modifierKeyword); |
1011 visit(node.returnType, after: space); | 1006 visit(node.returnType, after: space); |
1012 modifier(node.propertyKeyword); | 1007 modifier(node.propertyKeyword); |
1013 modifier(node.operatorKeyword); | 1008 modifier(node.operatorKeyword); |
1014 visit(node.name); | 1009 visit(node.name); |
1015 if (!node.isGetter) visit(node.parameters); | |
1016 | 1010 |
1017 _writer.unnest(); | 1011 _visitBody(node.parameters, node.body); |
1018 | |
1019 visitBody(node.body); | |
1020 } | 1012 } |
1021 | 1013 |
1022 visitMethodInvocation(MethodInvocation node) { | 1014 visitMethodInvocation(MethodInvocation node) { |
1023 // With a chain of method calls like `foo.bar.baz.bang`, they either all | 1015 // With a chain of method calls like `foo.bar.baz.bang`, they either all |
1024 // split or none of them do. | 1016 // split or none of them do. |
1025 var startedMultisplit = false; | 1017 var startedMultisplit = false; |
1026 | 1018 |
1027 // Try to keep the entire method chain one line. | 1019 // Try to keep the entire method chain one line. |
1028 _writer.startSpan(); | 1020 _writer.startSpan(); |
1029 _writer.nestExpression(); | 1021 _writer.nestExpression(); |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1474 } | 1466 } |
1475 | 1467 |
1476 /// Visit metadata annotations on parameters and type parameters. | 1468 /// Visit metadata annotations on parameters and type parameters. |
1477 /// | 1469 /// |
1478 /// These are always on the same line as the parameter. | 1470 /// These are always on the same line as the parameter. |
1479 void visitParameterMetadata(NodeList<Annotation> metadata) { | 1471 void visitParameterMetadata(NodeList<Annotation> metadata) { |
1480 // TODO(rnystrom): Allow splitting after annotations? | 1472 // TODO(rnystrom): Allow splitting after annotations? |
1481 visitNodes(metadata, between: space, after: space); | 1473 visitNodes(metadata, between: space, after: space); |
1482 } | 1474 } |
1483 | 1475 |
1484 /// Visit the given function [body], printing a space before it if it's not | 1476 /// Visit the given function [parameters] followed by its [body], printing a |
1485 /// empty. | 1477 /// space before it if it's not empty. |
1486 void visitBody(FunctionBody body) { | 1478 /// |
| 1479 /// If [afterParameters] is provided, it is invoked between the parameters |
| 1480 /// and body. (It's used for constructor initialization lists.) |
| 1481 void _visitBody(FormalParameterList parameters, FunctionBody body, |
| 1482 [afterParameters()]) { |
| 1483 if (parameters != null) { |
| 1484 // If the body is "=>", add an extra level of indentation around the |
| 1485 // parameters. This ensures that if they wrap, they wrap more deeply than |
| 1486 // the "=>" does, as in: |
| 1487 // |
| 1488 // someFunction(parameter, |
| 1489 // parameter, parameter) => |
| 1490 // "the body"; |
| 1491 if (body is ExpressionFunctionBody) _writer.nestExpression(); |
| 1492 |
| 1493 visit(parameters); |
| 1494 if (afterParameters != null) afterParameters(); |
| 1495 |
| 1496 if (body is ExpressionFunctionBody) _writer.unnest(); |
| 1497 } |
| 1498 |
1487 if (body is! EmptyFunctionBody) space(); | 1499 if (body is! EmptyFunctionBody) space(); |
1488 visit(body); | 1500 visit(body); |
1489 } | 1501 } |
1490 | 1502 |
1491 /// Visit a list of [nodes] if not null, optionally separated and/or preceded | 1503 /// Visit a list of [nodes] if not null, optionally separated and/or preceded |
1492 /// and followed by the given functions. | 1504 /// and followed by the given functions. |
1493 void visitNodes(Iterable<AstNode> nodes, {before(), between(), after()}) { | 1505 void visitNodes(Iterable<AstNode> nodes, {before(), between(), after()}) { |
1494 if (nodes == null || nodes.isEmpty) return; | 1506 if (nodes == null || nodes.isEmpty) return; |
1495 | 1507 |
1496 if (before != null) before(); | 1508 if (before != null) before(); |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1905 /// Gets the 1-based line number that the beginning of [token] lies on. | 1917 /// Gets the 1-based line number that the beginning of [token] lies on. |
1906 int _startLine(Token token) => _lineInfo.getLocation(token.offset).lineNumber; | 1918 int _startLine(Token token) => _lineInfo.getLocation(token.offset).lineNumber; |
1907 | 1919 |
1908 /// Gets the 1-based line number that the end of [token] lies on. | 1920 /// Gets the 1-based line number that the end of [token] lies on. |
1909 int _endLine(Token token) => _lineInfo.getLocation(token.end).lineNumber; | 1921 int _endLine(Token token) => _lineInfo.getLocation(token.end).lineNumber; |
1910 | 1922 |
1911 /// Gets the 1-based column number that the beginning of [token] lies on. | 1923 /// Gets the 1-based column number that the beginning of [token] lies on. |
1912 int _startColumn(Token token) => | 1924 int _startColumn(Token token) => |
1913 _lineInfo.getLocation(token.offset).columnNumber; | 1925 _lineInfo.getLocation(token.offset).columnNumber; |
1914 } | 1926 } |
OLD | NEW |