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

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

Issue 1303233008: improve keyword suggestions - fixes #24016 (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: merge Created 5 years, 3 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/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) 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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/test/completion_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698