| 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 |