Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 services.src.completion.statement; | 5 library services.src.completion.statement; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/plugin/protocol/protocol.dart'; | 9 import 'package:analysis_server/plugin/protocol/protocol.dart'; |
| 10 import 'package:analysis_server/src/protocol_server.dart' hide Element; | 10 import 'package:analysis_server/src/protocol_server.dart' hide Element; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 } | 170 } |
| 171 node = new NodeLocator(selectionOffset).searchWithin(unit); | 171 node = new NodeLocator(selectionOffset).searchWithin(unit); |
| 172 if (node == null) { | 172 if (node == null) { |
| 173 return NO_COMPLETION; | 173 return NO_COMPLETION; |
| 174 } | 174 } |
| 175 // TODO(messick): This needs to work for declarations. | 175 // TODO(messick): This needs to work for declarations. |
| 176 AstNode newNode = node.getAncestor((n) => n is Statement); | 176 AstNode newNode = node.getAncestor((n) => n is Statement); |
| 177 if (newNode is Block) { | 177 if (newNode is Block) { |
| 178 Block blockNode = newNode; | 178 Block blockNode = newNode; |
| 179 if (blockNode.statements.isNotEmpty) { | 179 if (blockNode.statements.isNotEmpty) { |
| 180 node = blockNode.statements[blockNode.statements.length - 1]; | 180 node = blockNode.statements.last; |
| 181 } else { | 181 } else { |
| 182 newNode = node.getAncestor((n) => n is CatchClause); | 182 node = newNode; |
| 183 if (newNode != null) { | |
| 184 node = newNode.parent; | |
| 185 } else { | |
| 186 node = node.getAncestor((n) => n is Statement).parent; | |
| 187 } | |
| 188 } | 183 } |
| 189 } else { | 184 } else { |
| 190 node = newNode; | 185 node = newNode; |
|
Brian Wilkerson
2017/04/24 21:07:40
Given that 'node' is set to 'newNode' in two third
messick
2017/04/25 18:13:23
Acknowledged.
| |
| 191 } | 186 } |
| 192 if (_isEmptyStatement(node)) { | 187 if (_isEmptyStatement(node)) { |
| 193 node = node.parent; | 188 node = node.parent; |
| 194 } | 189 } |
| 195 for (engine.AnalysisError error in statementContext.errors) { | 190 for (engine.AnalysisError error in statementContext.errors) { |
| 196 if (error.offset >= node.offset && | 191 if (error.offset >= node.offset && |
| 197 error.offset <= node.offset + node.length) { | 192 error.offset <= node.offset + node.length) { |
| 198 if (error.errorCode is! HintCode) { | 193 if (error.errorCode is! HintCode) { |
| 199 errors.add(error); | 194 errors.add(error); |
| 200 } | 195 } |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 641 if (_isSyntheticExpression(switchNode.expression)) { | 636 if (_isSyntheticExpression(switchNode.expression)) { |
| 642 exitPosition = | 637 exitPosition = |
| 643 new Position(file, switchNode.leftParenthesis.offset + 1); | 638 new Position(file, switchNode.leftParenthesis.offset + 1); |
| 644 } | 639 } |
| 645 } | 640 } |
| 646 if (switchNode | 641 if (switchNode |
| 647 .leftBracket.isSynthetic /*&& switchNode.rightBracket.isSynthetic*/) { | 642 .leftBracket.isSynthetic /*&& switchNode.rightBracket.isSynthetic*/) { |
| 648 // See https://github.com/dart-lang/sdk/issues/29391 | 643 // See https://github.com/dart-lang/sdk/issues/29391 |
| 649 sb.append(' '); | 644 sb.append(' '); |
| 650 _appendEmptyBraces(sb, exitPosition == null); | 645 _appendEmptyBraces(sb, exitPosition == null); |
| 646 } else { | |
| 647 SwitchMember member = _findInvalidElement(switchNode.members); | |
| 648 if (member != null) { | |
| 649 if (member.colon.isSynthetic) { | |
| 650 int loc = | |
| 651 member is SwitchCase ? member.expression.end : member.keyword.end; | |
| 652 sb = new SourceBuilder(file, loc); | |
| 653 sb.append(': '); | |
| 654 exitPosition = new Position(file, loc + 2); | |
| 655 } | |
| 656 } | |
| 651 } | 657 } |
| 652 _insertBuilder(sb); | 658 _insertBuilder(sb); |
| 653 _setCompletion(DartStatementCompletion.COMPLETE_SWITCH_STMT); | 659 _setCompletion(DartStatementCompletion.COMPLETE_SWITCH_STMT); |
| 654 return true; | 660 return true; |
| 655 } | 661 } |
| 656 | 662 |
| 657 bool _complete_tryStatement() { | 663 bool _complete_tryStatement() { |
| 658 if (node is! TryStatement) { | 664 if (node is! TryStatement) { |
| 659 return false; | 665 return false; |
| 660 } | 666 } |
| 661 TryStatement tryNode = node; | 667 TryStatement tryNode = node; |
| 662 SourceBuilder sb; | 668 SourceBuilder sb; |
| 663 CatchClause catchNode; | 669 CatchClause catchNode; |
| 664 bool addSpace = true; | 670 bool addSpace = true; |
| 665 if (tryNode.body.leftBracket.isSynthetic) { | 671 if (tryNode.body.leftBracket.isSynthetic) { |
| 666 String src = utils.getNodeText(tryNode); | 672 String src = utils.getNodeText(tryNode); |
| 667 if (src | 673 if (src |
| 668 .substring(tryNode.tryKeyword.end - tryNode.offset) | 674 .substring(tryNode.tryKeyword.end - tryNode.offset) |
| 669 .startsWith(new RegExp(r'[ \t]+'))) { | 675 .startsWith(new RegExp(r'[ \t]+'))) { |
| 670 // keywordSpace | 676 // keywordSpace |
| 671 sb = new SourceBuilder(file, tryNode.tryKeyword.end + 1); | 677 sb = new SourceBuilder(file, tryNode.tryKeyword.end + 1); |
| 672 } else { | 678 } else { |
| 673 // keywordOnly | 679 // keywordOnly |
| 674 sb = new SourceBuilder(file, tryNode.tryKeyword.end); | 680 sb = new SourceBuilder(file, tryNode.tryKeyword.end); |
| 675 sb.append(' '); | 681 sb.append(' '); |
| 676 } | 682 } |
| 677 _appendEmptyBraces(sb, true); | 683 _appendEmptyBraces(sb, true); |
| 678 _insertBuilder(sb); | 684 _insertBuilder(sb); |
| 679 sb = null; | 685 sb = null; |
| 680 } else if ((catchNode = _findInvalidCatch(tryNode.catchClauses)) != null) { | 686 } else if ((catchNode = _findInvalidElement(tryNode.catchClauses)) != |
| 687 null) { | |
| 681 if (catchNode.onKeyword != null) { | 688 if (catchNode.onKeyword != null) { |
| 682 if (catchNode.exceptionType.length == 0) { | 689 if (catchNode.exceptionType.length == 0) { |
| 683 String src = utils.getNodeText(catchNode); | 690 String src = utils.getNodeText(catchNode); |
| 684 if (src.startsWith(new RegExp(r'on[ \t]+'))) { | 691 if (src.startsWith(new RegExp(r'on[ \t]+'))) { |
| 685 if (src.startsWith(new RegExp(r'on[ \t][ \t]+'))) { | 692 if (src.startsWith(new RegExp(r'on[ \t][ \t]+'))) { |
| 686 // onSpaces | 693 // onSpaces |
| 687 exitPosition = new Position(file, catchNode.onKeyword.end + 1); | 694 exitPosition = new Position(file, catchNode.onKeyword.end + 1); |
| 688 sb = new SourceBuilder(file, catchNode.onKeyword.end + 2); | 695 sb = new SourceBuilder(file, catchNode.onKeyword.end + 2); |
| 689 addSpace = false; | 696 addSpace = false; |
| 690 } else { | 697 } else { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 764 errors.firstWhere((err) => err.errorCode == code, orElse: () => null); | 771 errors.firstWhere((err) => err.errorCode == code, orElse: () => null); |
| 765 if (error != null) { | 772 if (error != null) { |
| 766 if (partialMatch != null) { | 773 if (partialMatch != null) { |
| 767 return error.message.contains(partialMatch) ? error : null; | 774 return error.message.contains(partialMatch) ? error : null; |
| 768 } | 775 } |
| 769 return error; | 776 return error; |
| 770 } | 777 } |
| 771 return null; | 778 return null; |
| 772 } | 779 } |
| 773 | 780 |
| 774 CatchClause _findInvalidCatch(NodeList<CatchClause> list) { | 781 T _findInvalidElement<T extends AstNode>(NodeList<T> list) { |
| 775 return list.firstWhere( | 782 return list.firstWhere( |
| 776 (catchClause) => | 783 (catchClause) => |
|
Brian Wilkerson
2017/04/24 21:07:40
Given that the method has been generalized, perhap
messick
2017/04/25 18:13:23
Acknowledged.
| |
| 777 selectionOffset >= catchClause.offset && | 784 selectionOffset >= catchClause.offset && |
| 778 selectionOffset <= catchClause.end, | 785 selectionOffset <= catchClause.end, |
| 779 orElse: () => null); | 786 orElse: () => null); |
| 780 } | 787 } |
| 781 | 788 |
| 782 LinkedEditGroup _getLinkedPosition(String groupId) { | 789 LinkedEditGroup _getLinkedPosition(String groupId) { |
| 783 LinkedEditGroup group = linkedPositionGroups[groupId]; | 790 LinkedEditGroup group = linkedPositionGroups[groupId]; |
| 784 if (group == null) { | 791 if (group == null) { |
| 785 group = new LinkedEditGroup.empty(); | 792 group = new LinkedEditGroup.empty(); |
| 786 linkedPositionGroups[groupId] = group; | 793 linkedPositionGroups[groupId] = group; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 864 final Token keyword; | 871 final Token keyword; |
| 865 final Token leftParenthesis, rightParenthesis; | 872 final Token leftParenthesis, rightParenthesis; |
| 866 final Expression condition; | 873 final Expression condition; |
| 867 final Statement block; | 874 final Statement block; |
| 868 | 875 |
| 869 _KeywordConditionBlockStructure(this.keyword, this.leftParenthesis, | 876 _KeywordConditionBlockStructure(this.keyword, this.leftParenthesis, |
| 870 this.condition, this.rightParenthesis, this.block); | 877 this.condition, this.rightParenthesis, this.block); |
| 871 | 878 |
| 872 int get offset => keyword.offset; | 879 int get offset => keyword.offset; |
| 873 } | 880 } |
| OLD | NEW |