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 11 matching lines...) Expand all Loading... |
22 import 'package:analyzer/src/generated/engine.dart'; | 22 import 'package:analyzer/src/generated/engine.dart'; |
23 import 'package:analyzer/src/generated/java_core.dart'; | 23 import 'package:analyzer/src/generated/java_core.dart'; |
24 import 'package:analyzer/src/generated/source.dart'; | 24 import 'package:analyzer/src/generated/source.dart'; |
25 | 25 |
26 /** | 26 /** |
27 * An enumeration of possible statement completion kinds. | 27 * An enumeration of possible statement completion kinds. |
28 */ | 28 */ |
29 class DartStatementCompletion { | 29 class DartStatementCompletion { |
30 static const NO_COMPLETION = | 30 static const NO_COMPLETION = |
31 const StatementCompletionKind('No_COMPLETION', 'No completion available'); | 31 const StatementCompletionKind('No_COMPLETION', 'No completion available'); |
32 static const PLAIN_OLE_ENTER = const StatementCompletionKind( | 32 static const SIMPLE_ENTER = const StatementCompletionKind( |
33 'PLAIN_OLE_ENTER', "Insert a newline at the end of the current line"); | 33 'SIMPLE_ENTER', "Insert a newline at the end of the current line"); |
34 static const SIMPLE_SEMICOLON = const StatementCompletionKind( | 34 static const SIMPLE_SEMICOLON = const StatementCompletionKind( |
35 'SIMPLE_SEMICOLON', "Add a semicolon and newline"); | 35 'SIMPLE_SEMICOLON', "Add a semicolon and newline"); |
36 static const COMPLETE_IF_STMT = const StatementCompletionKind( | 36 static const COMPLETE_IF_STMT = const StatementCompletionKind( |
37 'COMPLETE_IF_STMT', "Complete if-statement"); | 37 'COMPLETE_IF_STMT', "Complete if-statement"); |
38 static const COMPLETE_WHILE_STMT = const StatementCompletionKind( | 38 static const COMPLETE_WHILE_STMT = const StatementCompletionKind( |
39 'COMPLETE_WHILE_STMT', "Complete while-statement"); | 39 'COMPLETE_WHILE_STMT', "Complete while-statement"); |
40 } | 40 } |
41 | 41 |
42 /** | 42 /** |
43 * A description of a statement completion. | 43 * A description of a statement completion. |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 node = node.getAncestor((n) => n is Statement); | 164 node = node.getAncestor((n) => n is Statement); |
165 for (engine.AnalysisError error in statementContext.errors) { | 165 for (engine.AnalysisError error in statementContext.errors) { |
166 if (error.offset >= node.offset && | 166 if (error.offset >= node.offset && |
167 error.offset <= node.offset + node.length) { | 167 error.offset <= node.offset + node.length) { |
168 if (error.errorCode is! HintCode) { | 168 if (error.errorCode is! HintCode) { |
169 errors.add(error); | 169 errors.add(error); |
170 } | 170 } |
171 } | 171 } |
172 } | 172 } |
173 | 173 |
| 174 // TODO(messick) Consider changing (some of) this to a visitor. |
174 if (_complete_ifStatement() || | 175 if (_complete_ifStatement() || |
175 _complete_whileStatement() || | 176 _complete_whileStatement() || |
176 _complete_simpleSemicolon() || | 177 _complete_simpleSemicolon() || |
177 _complete_plainOleEnter()) { | 178 _complete_simpleEnter()) { |
178 return completion; | 179 return completion; |
179 } | 180 } |
180 return NO_COMPLETION; | 181 return NO_COMPLETION; |
181 } | 182 } |
182 | 183 |
183 void _addIndentEdit(SourceRange range, String oldIndent, String newIndent) { | 184 void _addIndentEdit(SourceRange range, String oldIndent, String newIndent) { |
184 SourceEdit edit = utils.createIndentEdit(range, oldIndent, newIndent); | 185 SourceEdit edit = utils.createIndentEdit(range, oldIndent, newIndent); |
185 doSourceChange_addElementEdit(change, unitElement, edit); | 186 doSourceChange_addElementEdit(change, unitElement, edit); |
186 } | 187 } |
187 | 188 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 return false; | 270 return false; |
270 } | 271 } |
271 var stmt = new _IfWhileStructure(ifNode.ifKeyword, ifNode.leftParenthesis, | 272 var stmt = new _IfWhileStructure(ifNode.ifKeyword, ifNode.leftParenthesis, |
272 ifNode.condition, ifNode.rightParenthesis, ifNode.thenStatement); | 273 ifNode.condition, ifNode.rightParenthesis, ifNode.thenStatement); |
273 return _complete_ifOrWhileStatement( | 274 return _complete_ifOrWhileStatement( |
274 stmt, DartStatementCompletion.COMPLETE_IF_STMT); | 275 stmt, DartStatementCompletion.COMPLETE_IF_STMT); |
275 } | 276 } |
276 return false; | 277 return false; |
277 } | 278 } |
278 | 279 |
279 bool _complete_plainOleEnter() { | 280 bool _complete_simpleEnter() { |
280 int offset; | 281 int offset; |
281 if (!errors.isEmpty) { | 282 if (!errors.isEmpty) { |
282 offset = selectionOffset; | 283 offset = selectionOffset; |
283 } else { | 284 } else { |
284 String indent = utils.getLinePrefix(selectionOffset); | 285 String indent = utils.getLinePrefix(selectionOffset); |
285 int loc = utils.getLineNext(selectionOffset); | 286 int loc = utils.getLineNext(selectionOffset); |
286 _addInsertEdit(loc, indent + eol); | 287 _addInsertEdit(loc, indent + eol); |
287 offset = loc + indent.length + eol.length; | 288 offset = loc + indent.length + eol.length; |
288 } | 289 } |
289 _setCompletionAt(DartStatementCompletion.PLAIN_OLE_ENTER, offset); | 290 _setCompletionAt(DartStatementCompletion.SIMPLE_ENTER, offset); |
290 return true; | 291 return true; |
291 } | 292 } |
292 | 293 |
293 bool _complete_simpleSemicolon() { | 294 bool _complete_simpleSemicolon() { |
294 if (errors.length != 1) { | 295 if (errors.length != 1) { |
295 return false; | 296 return false; |
296 } | 297 } |
297 var error = _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); | 298 var error = _findError(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "';'"); |
298 if (error != null) { | 299 if (error != null) { |
299 int insertOffset = error.offset + error.length; | 300 int insertOffset = error.offset + error.length; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 final Token keyword; | 402 final Token keyword; |
402 final Token leftParenthesis, rightParenthesis; | 403 final Token leftParenthesis, rightParenthesis; |
403 final Expression condition; | 404 final Expression condition; |
404 final Statement block; | 405 final Statement block; |
405 | 406 |
406 _IfWhileStructure(this.keyword, this.leftParenthesis, this.condition, | 407 _IfWhileStructure(this.keyword, this.leftParenthesis, this.condition, |
407 this.rightParenthesis, this.block); | 408 this.rightParenthesis, this.block); |
408 | 409 |
409 int get offset => keyword.offset; | 410 int get offset => keyword.offset; |
410 } | 411 } |
OLD | NEW |