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 services.completion.contributor.dart.keyword; | 5 library services.completion.contributor.dart.keyword; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:analysis_server/src/protocol.dart'; | 9 import 'package:analysis_server/src/protocol.dart'; |
10 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; | 10 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 } | 150 } |
151 | 151 |
152 @override | 152 @override |
153 visitForEachStatement(ForEachStatement node) { | 153 visitForEachStatement(ForEachStatement node) { |
154 if (entity == node.inKeyword) { | 154 if (entity == node.inKeyword) { |
155 Token previous = node.inKeyword.previous; | 155 Token previous = node.inKeyword.previous; |
156 if (previous is SyntheticStringToken && previous.lexeme == 'in') { | 156 if (previous is SyntheticStringToken && previous.lexeme == 'in') { |
157 previous = previous.previous; | 157 previous = previous.previous; |
158 } | 158 } |
159 if (previous != null && previous.type == TokenType.EQ) { | 159 if (previous != null && previous.type == TokenType.EQ) { |
160 _addSuggestions( | 160 _addSuggestions([ |
161 [Keyword.FALSE, Keyword.NEW, Keyword.NULL, Keyword.TRUE]); | 161 Keyword.CONST, |
| 162 Keyword.FALSE, |
| 163 Keyword.NEW, |
| 164 Keyword.NULL, |
| 165 Keyword.TRUE |
| 166 ]); |
162 } else { | 167 } else { |
163 _addSuggestion(Keyword.IN, DART_RELEVANCE_HIGH); | 168 _addSuggestion(Keyword.IN, DART_RELEVANCE_HIGH); |
164 } | 169 } |
165 } | 170 } |
166 } | 171 } |
167 | 172 |
168 @override | 173 @override |
169 visitFormalParameterList(FormalParameterList node) { | 174 visitFormalParameterList(FormalParameterList node) { |
170 AstNode constructorDecl = | 175 AstNode constructorDecl = |
171 node.getAncestor((p) => p is ConstructorDeclaration); | 176 node.getAncestor((p) => p is ConstructorDeclaration); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 @override | 230 @override |
226 visitInstanceCreationExpression(InstanceCreationExpression node) { | 231 visitInstanceCreationExpression(InstanceCreationExpression node) { |
227 if (entity == node.constructorName) { | 232 if (entity == node.constructorName) { |
228 // no keywords in 'new ^' expression | 233 // no keywords in 'new ^' expression |
229 } else { | 234 } else { |
230 super.visitInstanceCreationExpression(node); | 235 super.visitInstanceCreationExpression(node); |
231 } | 236 } |
232 } | 237 } |
233 | 238 |
234 @override | 239 @override |
| 240 visitIsExpression(IsExpression node) { |
| 241 if (entity == node.isOperator) { |
| 242 _addSuggestion(Keyword.IS, DART_RELEVANCE_HIGH); |
| 243 } else { |
| 244 _addExpressionKeywords(node); |
| 245 } |
| 246 } |
| 247 |
| 248 @override |
235 visitLibraryIdentifier(LibraryIdentifier node) { | 249 visitLibraryIdentifier(LibraryIdentifier node) { |
236 // no suggestions | 250 // no suggestions |
237 } | 251 } |
238 | 252 |
239 @override | 253 @override |
240 visitMethodDeclaration(MethodDeclaration node) { | 254 visitMethodDeclaration(MethodDeclaration node) { |
241 if (entity == node.body) { | 255 if (entity == node.body) { |
242 if (node.body is EmptyFunctionBody) { | 256 if (node.body is EmptyFunctionBody) { |
243 _addClassBodyKeywords(); | 257 _addClassBodyKeywords(); |
244 _addSuggestion2(ASYNC); | 258 _addSuggestion2(ASYNC); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 Keyword.CONST, | 374 Keyword.CONST, |
361 Keyword.DYNAMIC, | 375 Keyword.DYNAMIC, |
362 Keyword.FINAL, | 376 Keyword.FINAL, |
363 Keyword.TYPEDEF, | 377 Keyword.TYPEDEF, |
364 Keyword.VAR, | 378 Keyword.VAR, |
365 Keyword.VOID | 379 Keyword.VOID |
366 ], DART_RELEVANCE_HIGH); | 380 ], DART_RELEVANCE_HIGH); |
367 } | 381 } |
368 | 382 |
369 void _addExpressionKeywords(AstNode node) { | 383 void _addExpressionKeywords(AstNode node) { |
370 _addSuggestions([Keyword.FALSE, Keyword.NEW, Keyword.NULL, Keyword.TRUE,]); | 384 _addSuggestions([ |
| 385 Keyword.CONST, |
| 386 Keyword.FALSE, |
| 387 Keyword.NEW, |
| 388 Keyword.NULL, |
| 389 Keyword.TRUE, |
| 390 ]); |
371 if (_inClassMemberBody(node)) { | 391 if (_inClassMemberBody(node)) { |
372 _addSuggestions([Keyword.SUPER, Keyword.THIS,]); | 392 _addSuggestions([Keyword.SUPER, Keyword.THIS,]); |
373 } | 393 } |
374 if (_inAsyncMethodOrFunction(node)) { | 394 if (_inAsyncMethodOrFunction(node)) { |
375 _addSuggestion2(AWAIT); | 395 _addSuggestion2(AWAIT); |
376 } | 396 } |
377 } | 397 } |
378 | 398 |
379 void _addImportDirectiveKeywords(ImportDirective node) { | 399 void _addImportDirectiveKeywords(ImportDirective node) { |
380 bool hasDeferredKeyword = node.deferredKeyword != null; | 400 bool hasDeferredKeyword = node.deferredKeyword != null; |
(...skipping 16 matching lines...) Expand all Loading... |
397 } | 417 } |
398 } | 418 } |
399 | 419 |
400 void _addStatementKeywords(AstNode node) { | 420 void _addStatementKeywords(AstNode node) { |
401 if (_inClassMemberBody(node)) { | 421 if (_inClassMemberBody(node)) { |
402 _addSuggestions([Keyword.SUPER, Keyword.THIS,]); | 422 _addSuggestions([Keyword.SUPER, Keyword.THIS,]); |
403 } | 423 } |
404 if (_inAsyncMethodOrFunction(node)) { | 424 if (_inAsyncMethodOrFunction(node)) { |
405 _addSuggestion2(AWAIT); | 425 _addSuggestion2(AWAIT); |
406 } | 426 } |
| 427 if (_inLoop(node)) { |
| 428 _addSuggestions([Keyword.BREAK, Keyword.CONTINUE]); |
| 429 } |
| 430 if (_inSwitch(node)) { |
| 431 _addSuggestions([Keyword.BREAK]); |
| 432 } |
407 _addSuggestions([ | 433 _addSuggestions([ |
408 Keyword.ASSERT, | 434 Keyword.ASSERT, |
409 Keyword.CONTINUE, | 435 Keyword.CONST, |
410 Keyword.DO, | 436 Keyword.DO, |
411 Keyword.FINAL, | 437 Keyword.FINAL, |
412 Keyword.FOR, | 438 Keyword.FOR, |
413 Keyword.IF, | 439 Keyword.IF, |
414 Keyword.NEW, | 440 Keyword.NEW, |
415 Keyword.RETURN, | 441 Keyword.RETURN, |
416 Keyword.SWITCH, | 442 Keyword.SWITCH, |
417 Keyword.THROW, | 443 Keyword.THROW, |
418 Keyword.TRY, | 444 Keyword.TRY, |
419 Keyword.VAR, | 445 Keyword.VAR, |
420 Keyword.VOID, | 446 Keyword.VOID, |
421 Keyword.WHILE | 447 Keyword.WHILE |
422 ]); | 448 ]); |
423 _addSuggestion(Keyword.RETHROW, DART_RELEVANCE_KEYWORD - 1); | 449 _addSuggestion(Keyword.RETHROW, DART_RELEVANCE_KEYWORD - 1); |
424 } | 450 } |
425 | 451 |
426 void _addSuggestion(Keyword keyword, | 452 void _addSuggestion(Keyword keyword, |
427 [int relevance = DART_RELEVANCE_KEYWORD]) { | 453 [int relevance = DART_RELEVANCE_KEYWORD]) { |
428 _addSuggestion2(keyword.syntax, relevance: relevance); | 454 _addSuggestion2(keyword.syntax, relevance: relevance); |
429 } | 455 } |
430 | 456 |
431 void _addSuggestion2(String completion, | 457 void _addSuggestion2(String completion, |
432 {int offset, int relevance: DART_RELEVANCE_KEYWORD}) { | 458 {int offset, int relevance: DART_RELEVANCE_KEYWORD}) { |
433 if (offset == null) { | 459 if (offset == null) { |
434 offset = completion.length; | 460 offset = completion.length; |
435 } | 461 } |
436 request.addSuggestion(new CompletionSuggestion( | 462 request.addSuggestion(new CompletionSuggestion( |
437 CompletionSuggestionKind.KEYWORD, relevance, completion, offset, 0, | 463 CompletionSuggestionKind.KEYWORD, |
438 false, false)); | 464 relevance, |
| 465 completion, |
| 466 offset, |
| 467 0, |
| 468 false, |
| 469 false)); |
439 } | 470 } |
440 | 471 |
441 void _addSuggestions(List<Keyword> keywords, | 472 void _addSuggestions(List<Keyword> keywords, |
442 [int relevance = DART_RELEVANCE_KEYWORD]) { | 473 [int relevance = DART_RELEVANCE_KEYWORD]) { |
443 keywords.forEach((Keyword keyword) { | 474 keywords.forEach((Keyword keyword) { |
444 _addSuggestion(keyword, relevance); | 475 _addSuggestion(keyword, relevance); |
445 }); | 476 }); |
446 } | 477 } |
447 | 478 |
448 bool _inAsyncMethodOrFunction(AstNode node) { | 479 bool _inAsyncMethodOrFunction(AstNode node) { |
449 FunctionBody body = node.getAncestor((n) => n is FunctionBody); | 480 FunctionBody body = node.getAncestor((n) => n is FunctionBody); |
450 return body != null && body.isAsynchronous; | 481 return body != null && body.isAsynchronous; |
451 } | 482 } |
452 | 483 |
453 bool _inClassMemberBody(AstNode node) { | 484 bool _inClassMemberBody(AstNode node) { |
454 while (true) { | 485 while (true) { |
455 AstNode body = node.getAncestor((n) => n is FunctionBody); | 486 AstNode body = node.getAncestor((n) => n is FunctionBody); |
456 if (body == null) { | 487 if (body == null) { |
457 return false; | 488 return false; |
458 } | 489 } |
459 AstNode parent = body.parent; | 490 AstNode parent = body.parent; |
460 if (parent is ConstructorDeclaration || parent is MethodDeclaration) { | 491 if (parent is ConstructorDeclaration || parent is MethodDeclaration) { |
461 return true; | 492 return true; |
462 } | 493 } |
463 node = parent; | 494 node = parent; |
464 } | 495 } |
465 } | 496 } |
| 497 |
| 498 bool _inDoLoop(AstNode node) => |
| 499 node.getAncestor((p) => p is DoStatement) != null; |
| 500 |
| 501 bool _inForLoop(AstNode node) => |
| 502 node.getAncestor((p) => p is ForStatement || p is ForEachStatement) != |
| 503 null; |
| 504 |
| 505 bool _inLoop(AstNode node) => |
| 506 _inDoLoop(node) || _inForLoop(node) || _inWhileLoop(node); |
| 507 |
| 508 bool _inSwitch(AstNode node) => |
| 509 node.getAncestor((p) => p is SwitchStatement) != null; |
| 510 |
| 511 bool _inWhileLoop(AstNode node) => |
| 512 node.getAncestor((p) => p is WhileStatement) != null; |
466 } | 513 } |
OLD | NEW |