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

Side by Side Diff: pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart

Issue 2842523002: Fix detection of bad catch-clauses and try-statements (Closed)
Patch Set: Created 3 years, 8 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 | « no previous file | pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart » ('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) 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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 // If the source was changed between the constructor and running 166 // If the source was changed between the constructor and running
167 // this asynchronous method, it is not safe to use the unit. 167 // this asynchronous method, it is not safe to use the unit.
168 if (analysisContext.getModificationStamp(source) != fileStamp) { 168 if (analysisContext.getModificationStamp(source) != fileStamp) {
169 return NO_COMPLETION; 169 return NO_COMPLETION;
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 node = node.getAncestor((n) => n is Statement); 176 AstNode newNode = node.getAncestor((n) => n is Statement);
177 if (newNode is Block) {
178 Block blockNode = newNode;
179 if (blockNode.statements.isNotEmpty) {
180 node = blockNode.statements[blockNode.statements.length - 1];
scheglov 2017/04/24 18:52:33 blockNode.statements.last
181 } else {
182 newNode = node.getAncestor((n) => n is CatchClause);
183 if (newNode != null) {
184 node = newNode.parent;
185 } else {
186 node = node.getAncestor((n) => n is Statement).parent;
187 }
188 }
189 } else {
190 node = newNode;
191 }
177 if (_isEmptyStatement(node)) { 192 if (_isEmptyStatement(node)) {
178 node = node.parent; 193 node = node.parent;
179 } 194 }
180 for (engine.AnalysisError error in statementContext.errors) { 195 for (engine.AnalysisError error in statementContext.errors) {
181 if (error.offset >= node.offset && 196 if (error.offset >= node.offset &&
182 error.offset <= node.offset + node.length) { 197 error.offset <= node.offset + node.length) {
183 if (error.errorCode is! HintCode) { 198 if (error.errorCode is! HintCode) {
184 errors.add(error); 199 errors.add(error);
185 } 200 }
186 } 201 }
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 // keywordSpace 670 // keywordSpace
656 sb = new SourceBuilder(file, tryNode.tryKeyword.end + 1); 671 sb = new SourceBuilder(file, tryNode.tryKeyword.end + 1);
657 } else { 672 } else {
658 // keywordOnly 673 // keywordOnly
659 sb = new SourceBuilder(file, tryNode.tryKeyword.end); 674 sb = new SourceBuilder(file, tryNode.tryKeyword.end);
660 sb.append(' '); 675 sb.append(' ');
661 } 676 }
662 _appendEmptyBraces(sb, true); 677 _appendEmptyBraces(sb, true);
663 _insertBuilder(sb); 678 _insertBuilder(sb);
664 sb = null; 679 sb = null;
665 } else if ((catchNode = _firstInvalidCatch(tryNode.catchClauses)) != null) { 680 } else if ((catchNode = _findInvalidCatch(tryNode.catchClauses)) != null) {
666 if (catchNode.onKeyword != null) { 681 if (catchNode.onKeyword != null) {
667 if (catchNode.exceptionType.length == 0) { 682 if (catchNode.exceptionType.length == 0) {
668 String src = utils.getNodeText(catchNode); 683 String src = utils.getNodeText(catchNode);
669 if (src.startsWith(new RegExp(r'on[ \t]+'))) { 684 if (src.startsWith(new RegExp(r'on[ \t]+'))) {
670 if (src.startsWith(new RegExp(r'on[ \t][ \t]+'))) { 685 if (src.startsWith(new RegExp(r'on[ \t][ \t]+'))) {
671 // onSpaces 686 // onSpaces
672 exitPosition = new Position(file, catchNode.onKeyword.end + 1); 687 exitPosition = new Position(file, catchNode.onKeyword.end + 1);
673 sb = new SourceBuilder(file, catchNode.onKeyword.end + 2); 688 sb = new SourceBuilder(file, catchNode.onKeyword.end + 2);
674 addSpace = false; 689 addSpace = false;
675 } else { 690 } else {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 errors.firstWhere((err) => err.errorCode == code, orElse: () => null); 764 errors.firstWhere((err) => err.errorCode == code, orElse: () => null);
750 if (error != null) { 765 if (error != null) {
751 if (partialMatch != null) { 766 if (partialMatch != null) {
752 return error.message.contains(partialMatch) ? error : null; 767 return error.message.contains(partialMatch) ? error : null;
753 } 768 }
754 return error; 769 return error;
755 } 770 }
756 return null; 771 return null;
757 } 772 }
758 773
759 CatchClause _firstInvalidCatch(NodeList<CatchClause> list) { 774 CatchClause _findInvalidCatch(NodeList<CatchClause> list) {
760 return list.firstWhere((e) { 775 return list.firstWhere(
761 bool found = false; 776 (catchClause) =>
762 for (var error in errors) { 777 selectionOffset >= catchClause.offset &&
763 if (error.offset >= e.offset && error.offset <= e.end) { 778 selectionOffset <= catchClause.end,
764 if (error.errorCode is! HintCode) { 779 orElse: () => null);
765 found = true;
766 break;
767 }
768 }
769 }
770 return found;
771 }, orElse: () => null);
772 } 780 }
773 781
774 LinkedEditGroup _getLinkedPosition(String groupId) { 782 LinkedEditGroup _getLinkedPosition(String groupId) {
775 LinkedEditGroup group = linkedPositionGroups[groupId]; 783 LinkedEditGroup group = linkedPositionGroups[groupId];
776 if (group == null) { 784 if (group == null) {
777 group = new LinkedEditGroup.empty(); 785 group = new LinkedEditGroup.empty();
778 linkedPositionGroups[groupId] = group; 786 linkedPositionGroups[groupId] = group;
779 } 787 }
780 return group; 788 return group;
781 } 789 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 final Token keyword; 864 final Token keyword;
857 final Token leftParenthesis, rightParenthesis; 865 final Token leftParenthesis, rightParenthesis;
858 final Expression condition; 866 final Expression condition;
859 final Statement block; 867 final Statement block;
860 868
861 _KeywordConditionBlockStructure(this.keyword, this.leftParenthesis, 869 _KeywordConditionBlockStructure(this.keyword, this.leftParenthesis,
862 this.condition, this.rightParenthesis, this.block); 870 this.condition, this.rightParenthesis, this.block);
863 871
864 int get offset => keyword.offset; 872 int get offset => keyword.offset;
865 } 873 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698