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

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

Issue 1291283002: suggest prefixed constructors - fixes #23210 (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: merge Created 5 years, 4 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
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.suggestion.builder; 5 library services.completion.suggestion.builder;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analysis_server/src/protocol_server.dart' as protocol; 10 import 'package:analysis_server/src/protocol_server.dart' as protocol;
11 import 'package:analysis_server/src/protocol_server.dart' 11 import 'package:analysis_server/src/protocol_server.dart'
12 hide Element, ElementKind; 12 hide Element, ElementKind;
13 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart'; 13 import 'package:analysis_server/src/services/completion/dart_completion_manager. dart';
14 import 'package:analyzer/src/generated/ast.dart'; 14 import 'package:analyzer/src/generated/ast.dart';
15 import 'package:analyzer/src/generated/element.dart'; 15 import 'package:analyzer/src/generated/element.dart';
16 import 'package:analyzer/src/generated/utilities_dart.dart'; 16 import 'package:analyzer/src/generated/utilities_dart.dart';
17 import 'package:analyzer/src/generated/source.dart'; 17 import 'package:analyzer/src/generated/source.dart';
18 import 'package:path/path.dart' as path; 18 import 'package:path/path.dart' as path;
19 19
20 const String DYNAMIC = 'dynamic'; 20 const String DYNAMIC = 'dynamic';
21 21
22 /** 22 /**
23 * Return a suggestion based upon the given element 23 * Return a suggestion based upon the given element
24 * or `null` if a suggestion is not appropriate for the given element. 24 * or `null` if a suggestion is not appropriate for the given element.
25 * If the suggestion is not currently in scope, then specify 25 * If the suggestion is not currently in scope, then specify
26 * importForSource as the source to which an import should be added. 26 * importForSource as the source to which an import should be added.
27 */ 27 */
28 CompletionSuggestion createSuggestion(Element element, 28 CompletionSuggestion createSuggestion(Element element, {String completion,
29 {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, 29 CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
30 int relevance: DART_RELEVANCE_DEFAULT, Source importForSource}) { 30 int relevance: DART_RELEVANCE_DEFAULT, Source importForSource}) {
31 if (element is ExecutableElement && element.isOperator) { 31 if (element is ExecutableElement && element.isOperator) {
32 // Do not include operators in suggestions 32 // Do not include operators in suggestions
33 return null; 33 return null;
34 } 34 }
35 String completion = element.displayName; 35 if (completion == null) {
36 completion = element.displayName;
37 }
36 bool isDeprecated = element.isDeprecated; 38 bool isDeprecated = element.isDeprecated;
37 CompletionSuggestion suggestion = new CompletionSuggestion(kind, 39 CompletionSuggestion suggestion = new CompletionSuggestion(kind,
38 isDeprecated ? DART_RELEVANCE_LOW : relevance, completion, 40 isDeprecated ? DART_RELEVANCE_LOW : relevance, completion,
39 completion.length, 0, isDeprecated, false); 41 completion.length, 0, isDeprecated, false);
40 suggestion.element = protocol.newElement_fromEngine(element); 42 suggestion.element = protocol.newElement_fromEngine(element);
41 Element enclosingElement = element.enclosingElement; 43 Element enclosingElement = element.enclosingElement;
42 if (enclosingElement is ClassElement) { 44 if (enclosingElement is ClassElement) {
43 suggestion.declaringType = enclosingElement.displayName; 45 suggestion.declaringType = enclosingElement.displayName;
44 } 46 }
45 suggestion.returnType = getReturnTypeString(element); 47 suggestion.returnType = getReturnTypeString(element);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 CompletionSuggestionKind get kind; 184 CompletionSuggestionKind get kind;
183 185
184 /** 186 /**
185 * Return the request on which the builder is operating. 187 * Return the request on which the builder is operating.
186 */ 188 */
187 DartCompletionRequest get request; 189 DartCompletionRequest get request;
188 190
189 /** 191 /**
190 * Add a suggestion based upon the given element. 192 * Add a suggestion based upon the given element.
191 */ 193 */
192 void addSuggestion(Element element, {int relevance: DART_RELEVANCE_DEFAULT}) { 194 void addSuggestion(Element element,
195 {String prefix, int relevance: DART_RELEVANCE_DEFAULT}) {
193 if (element.isPrivate) { 196 if (element.isPrivate) {
194 LibraryElement elementLibrary = element.library; 197 LibraryElement elementLibrary = element.library;
195 CompilationUnitElement unitElem = request.unit.element; 198 CompilationUnitElement unitElem = request.unit.element;
196 if (unitElem == null) { 199 if (unitElem == null) {
197 return; 200 return;
198 } 201 }
199 LibraryElement unitLibrary = unitElem.library; 202 LibraryElement unitLibrary = unitElem.library;
200 if (elementLibrary != unitLibrary) { 203 if (elementLibrary != unitLibrary) {
201 return; 204 return;
202 } 205 }
203 } 206 }
204 if (element.isSynthetic) { 207 if (prefix == null && element.isSynthetic) {
205 if ((element is PropertyAccessorElement) || 208 if ((element is PropertyAccessorElement) ||
206 element is FieldElement && !_isSpecialEnumField(element)) { 209 element is FieldElement && !_isSpecialEnumField(element)) {
207 return; 210 return;
208 } 211 }
209 } 212 }
210 String completion = element.displayName; 213 String completion = element.displayName;
214 if (prefix != null && prefix.length > 0) {
215 if (completion == null || completion.length <= 0) {
216 completion = prefix;
217 } else {
218 completion = '$prefix.$completion';
219 }
220 }
211 if (completion == null || completion.length <= 0) { 221 if (completion == null || completion.length <= 0) {
212 return; 222 return;
213 } 223 }
214 CompletionSuggestion suggestion = 224 CompletionSuggestion suggestion = createSuggestion(element,
215 createSuggestion(element, kind: kind, relevance: relevance); 225 completion: completion, kind: kind, relevance: relevance);
216 if (suggestion != null) { 226 if (suggestion != null) {
217 request.addSuggestion(suggestion); 227 request.addSuggestion(suggestion);
218 } 228 }
219 } 229 }
220 230
221 /** 231 /**
222 * Determine if the given element is one of the synthetic enum accessors 232 * Determine if the given element is one of the synthetic enum accessors
223 * for which we should generate a suggestion. 233 * for which we should generate a suggestion.
224 */ 234 */
225 bool _isSpecialEnumField(FieldElement element) { 235 bool _isSpecialEnumField(FieldElement element) {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 /** 443 /**
434 * This class visits elements in a library and provides suggestions based upon 444 * This class visits elements in a library and provides suggestions based upon
435 * the visible members in that library. Clients should call 445 * the visible members in that library. Clients should call
436 * [LibraryElementSuggestionBuilder.suggestionsFor]. 446 * [LibraryElementSuggestionBuilder.suggestionsFor].
437 */ 447 */
438 class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor 448 class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
439 with ElementSuggestionBuilder { 449 with ElementSuggestionBuilder {
440 final DartCompletionRequest request; 450 final DartCompletionRequest request;
441 final CompletionSuggestionKind kind; 451 final CompletionSuggestionKind kind;
442 final bool typesOnly; 452 final bool typesOnly;
453 final bool instCreation;
443 454
444 LibraryElementSuggestionBuilder(this.request, this.kind, this.typesOnly); 455 LibraryElementSuggestionBuilder(
456 this.request, this.kind, this.typesOnly, this.instCreation);
445 457
446 @override 458 @override
447 visitClassElement(ClassElement element) { 459 visitClassElement(ClassElement element) {
448 addSuggestion(element); 460 if (instCreation) {
461 element.visitChildren(this);
462 } else {
463 addSuggestion(element);
464 }
449 } 465 }
450 466
451 @override 467 @override
452 visitCompilationUnitElement(CompilationUnitElement element) { 468 visitCompilationUnitElement(CompilationUnitElement element) {
453 element.visitChildren(this); 469 element.visitChildren(this);
454 LibraryElement containingLibrary = element.library; 470 LibraryElement containingLibrary = element.library;
455 if (containingLibrary != null) { 471 if (containingLibrary != null) {
456 for (var lib in containingLibrary.exportedLibraries) { 472 for (var lib in containingLibrary.exportedLibraries) {
457 lib.visitChildren(this); 473 lib.visitChildren(this);
458 } 474 }
459 } 475 }
460 } 476 }
461 477
462 @override 478 @override
479 visitConstructorElement(ConstructorElement element) {
480 if (instCreation) {
481 ClassElement classElem = element.enclosingElement;
482 if (classElem != null) {
483 String prefix = classElem.name;
484 if (prefix != null && prefix.length > 0) {
485 addSuggestion(element, prefix: prefix);
486 }
487 }
488 }
489 }
490
491 @override
463 visitElement(Element element) { 492 visitElement(Element element) {
464 // ignored 493 // ignored
465 } 494 }
466 495
467 @override 496 @override
468 visitFunctionElement(FunctionElement element) { 497 visitFunctionElement(FunctionElement element) {
469 if (!typesOnly) { 498 if (!typesOnly) {
470 addSuggestion(element); 499 addSuggestion(element);
471 } 500 }
472 } 501 }
473 502
474 @override 503 @override
475 visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { 504 visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
476 addSuggestion(element); 505 if (!instCreation) {
506 addSuggestion(element);
507 }
477 } 508 }
478 509
479 @override 510 @override
480 visitTopLevelVariableElement(TopLevelVariableElement element) { 511 visitTopLevelVariableElement(TopLevelVariableElement element) {
481 if (!typesOnly) { 512 if (!typesOnly) {
482 addSuggestion(element); 513 addSuggestion(element);
483 } 514 }
484 } 515 }
485 516
486 /** 517 /**
487 * Add suggestions for the visible members in the given library 518 * Add suggestions for the visible members in the given library
488 */ 519 */
489 static void suggestionsFor(DartCompletionRequest request, 520 static void suggestionsFor(DartCompletionRequest request,
490 CompletionSuggestionKind kind, LibraryElement library, bool typesOnly) { 521 CompletionSuggestionKind kind, LibraryElement library, bool typesOnly,
522 bool instCreation) {
491 if (library != null) { 523 if (library != null) {
492 library.visitChildren( 524 library.visitChildren(new LibraryElementSuggestionBuilder(
493 new LibraryElementSuggestionBuilder(request, kind, typesOnly)); 525 request, kind, typesOnly, instCreation));
494 } 526 }
495 } 527 }
496 } 528 }
497 529
498 /** 530 /**
499 * This class visits elements in a class and provides suggestions based upon 531 * This class visits elements in a class and provides suggestions based upon
500 * the visible named constructors in that class. 532 * the visible named constructors in that class.
501 */ 533 */
502 class NamedConstructorSuggestionBuilder extends GeneralizingElementVisitor 534 class NamedConstructorSuggestionBuilder extends GeneralizingElementVisitor
503 with ElementSuggestionBuilder implements SuggestionBuilder { 535 with ElementSuggestionBuilder implements SuggestionBuilder {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 * or `false` if [computeFull] should be called. 657 * or `false` if [computeFull] should be called.
626 */ 658 */
627 bool computeFast(AstNode node); 659 bool computeFast(AstNode node);
628 660
629 /** 661 /**
630 * Return a future that computes the suggestions given a fully resolved AST. 662 * Return a future that computes the suggestions given a fully resolved AST.
631 * The future returns `true` if suggestions were added, else `false`. 663 * The future returns `true` if suggestions were added, else `false`.
632 */ 664 */
633 Future<bool> computeFull(AstNode node); 665 Future<bool> computeFull(AstNode node);
634 } 666 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698