| 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.suggestion.builder; | 5 library services.completion.suggestion.builder; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/protocol_server.dart' as protocol; | 9 import 'package:analysis_server/src/protocol_server.dart' as protocol; |
| 10 import 'package:analysis_server/src/protocol_server.dart' hide Element, | 10 import 'package:analysis_server/src/protocol_server.dart' hide Element, |
| 11 ElementKind; | 11 ElementKind; |
| 12 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; | 12 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; |
| 13 import 'package:analyzer/src/generated/ast.dart'; | 13 import 'package:analyzer/src/generated/ast.dart'; |
| 14 import 'package:analyzer/src/generated/element.dart'; | 14 import 'package:analyzer/src/generated/element.dart'; |
| 15 import 'package:analyzer/src/generated/utilities_dart.dart'; | 15 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 16 | 16 |
| 17 final DYNAMIC = 'dynamic'; | 17 const String DYNAMIC = 'dynamic'; |
| 18 final DartType NO_RETURN_TYPE = new _NoReturnType(); | |
| 19 | 18 |
| 20 /** | 19 /** |
| 21 * Return a suggestion based upon the given element | 20 * Return a suggestion based upon the given element |
| 22 * or `null` if a suggestion is not appropriate for the given element. | 21 * or `null` if a suggestion is not appropriate for the given element. |
| 23 */ | 22 */ |
| 24 CompletionSuggestion createSuggestion(Element element, | 23 CompletionSuggestion createSuggestion(Element element, |
| 25 {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, | 24 {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION, |
| 26 int relevance: COMPLETION_RELEVANCE_DEFAULT}) { | 25 int relevance: COMPLETION_RELEVANCE_DEFAULT}) { |
| 27 DartType type; | 26 |
| 27 String nameForType(DartType type) { |
| 28 if (type == null) { |
| 29 return DYNAMIC; |
| 30 } |
| 31 String name = type.displayName; |
| 32 if (name == null || name.length <= 0) { |
| 33 return DYNAMIC; |
| 34 } |
| 35 //TODO (danrubel) include type arguments ?? |
| 36 return name; |
| 37 } |
| 38 |
| 39 String returnType = null; |
| 28 if (element is ExecutableElement) { | 40 if (element is ExecutableElement) { |
| 29 if (element.isOperator) { | 41 if (element.isOperator) { |
| 42 // Do not include operators in suggestions |
| 30 return null; | 43 return null; |
| 31 } | 44 } |
| 32 if (element is PropertyAccessorElement && element.isSetter) { | 45 if (element is PropertyAccessorElement && element.isSetter) { |
| 33 type = NO_RETURN_TYPE; | 46 // no return type |
| 34 } else { | 47 } else { |
| 35 type = element.returnType; | 48 returnType = nameForType(element.returnType); |
| 36 } | 49 } |
| 37 } else if (element is VariableElement) { | 50 } else if (element is VariableElement) { |
| 38 type = element.type; | 51 returnType = nameForType(element.type); |
| 39 } else if (element is FunctionTypeAliasElement) { | 52 } else if (element is FunctionTypeAliasElement) { |
| 40 type = element.returnType; | 53 returnType = nameForType(element.returnType); |
| 41 } else { | |
| 42 type = NO_RETURN_TYPE; | |
| 43 } | 54 } |
| 55 |
| 44 String completion = element.displayName; | 56 String completion = element.displayName; |
| 45 bool isDeprecated = element.isDeprecated; | 57 bool isDeprecated = element.isDeprecated; |
| 46 CompletionSuggestion suggestion = new CompletionSuggestion( | 58 CompletionSuggestion suggestion = new CompletionSuggestion( |
| 47 kind, | 59 kind, |
| 48 isDeprecated ? COMPLETION_RELEVANCE_LOW : relevance, | 60 isDeprecated ? COMPLETION_RELEVANCE_LOW : relevance, |
| 49 completion, | 61 completion, |
| 50 completion.length, | 62 completion.length, |
| 51 0, | 63 0, |
| 52 isDeprecated, | 64 isDeprecated, |
| 53 false); | 65 false); |
| 54 suggestion.element = protocol.newElement_fromEngine(element); | 66 suggestion.element = protocol.newElement_fromEngine(element); |
| 55 if (element is ClassMemberElement) { | 67 if (element is ClassMemberElement) { |
| 56 ClassElement enclosingElement = element.enclosingElement; | 68 ClassElement enclosingElement = element.enclosingElement; |
| 57 if (enclosingElement != null) { | 69 if (enclosingElement != null) { |
| 58 suggestion.declaringType = enclosingElement.displayName; | 70 suggestion.declaringType = enclosingElement.displayName; |
| 59 } | 71 } |
| 60 } | 72 } |
| 61 suggestion.returnType = _nameForType(type); | 73 suggestion.returnType = returnType; |
| 62 if (element is ExecutableElement && element is! PropertyAccessorElement) { | 74 if (element is ExecutableElement && element is! PropertyAccessorElement) { |
| 63 suggestion.parameterNames = element.parameters.map( | 75 suggestion.parameterNames = element.parameters.map( |
| 64 (ParameterElement parameter) => parameter.name).toList(); | 76 (ParameterElement parameter) => parameter.name).toList(); |
| 65 suggestion.parameterTypes = element.parameters.map( | 77 suggestion.parameterTypes = element.parameters.map( |
| 66 (ParameterElement parameter) => parameter.type.displayName).toList(); | 78 (ParameterElement parameter) => parameter.type.displayName).toList(); |
| 67 suggestion.requiredParameterCount = element.parameters.where( | 79 suggestion.requiredParameterCount = element.parameters.where( |
| 68 (ParameterElement parameter) => | 80 (ParameterElement parameter) => |
| 69 parameter.parameterKind == ParameterKind.REQUIRED).length; | 81 parameter.parameterKind == ParameterKind.REQUIRED).length; |
| 70 suggestion.hasNamedParameters = element.parameters.any( | 82 suggestion.hasNamedParameters = element.parameters.any( |
| 71 (ParameterElement parameter) => parameter.parameterKind == ParameterKind
.NAMED); | 83 (ParameterElement parameter) => parameter.parameterKind == ParameterKind
.NAMED); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 todo.add(classNode); | 158 todo.add(classNode); |
| 147 } else { | 159 } else { |
| 148 imported(name); | 160 imported(name); |
| 149 } | 161 } |
| 150 } | 162 } |
| 151 }); | 163 }); |
| 152 } | 164 } |
| 153 } | 165 } |
| 154 | 166 |
| 155 /** | 167 /** |
| 156 * Return the name for the given type. | |
| 157 */ | |
| 158 String _nameForType(DartType type) { | |
| 159 if (type == NO_RETURN_TYPE) { | |
| 160 return null; | |
| 161 } | |
| 162 if (type == null) { | |
| 163 return DYNAMIC; | |
| 164 } | |
| 165 String name = type.displayName; | |
| 166 if (name == null || name.length <= 0) { | |
| 167 return DYNAMIC; | |
| 168 } | |
| 169 //TODO (danrubel) include type arguments ?? | |
| 170 return name; | |
| 171 } | |
| 172 | |
| 173 /** | |
| 174 * This class visits elements in a class and provides suggestions based upon | 168 * This class visits elements in a class and provides suggestions based upon |
| 175 * the visible members in that class. Clients should call | 169 * the visible members in that class. Clients should call |
| 176 * [ClassElementSuggestionBuilder.suggestionsFor]. | 170 * [ClassElementSuggestionBuilder.suggestionsFor]. |
| 177 */ | 171 */ |
| 178 class ClassElementSuggestionBuilder extends GeneralizingElementVisitor with | 172 class ClassElementSuggestionBuilder extends GeneralizingElementVisitor with |
| 179 ElementSuggestionBuilder { | 173 ElementSuggestionBuilder { |
| 180 final bool staticOnly; | 174 final bool staticOnly; |
| 181 final DartCompletionRequest request; | 175 final DartCompletionRequest request; |
| 182 | 176 |
| 183 ClassElementSuggestionBuilder(this.request, bool staticOnly) | 177 ClassElementSuggestionBuilder(this.request, bool staticOnly) |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 * or `false` if [computeFull] should be called. | 400 * or `false` if [computeFull] should be called. |
| 407 */ | 401 */ |
| 408 bool computeFast(AstNode node); | 402 bool computeFast(AstNode node); |
| 409 | 403 |
| 410 /** | 404 /** |
| 411 * Return a future that computes the suggestions given a fully resolved AST. | 405 * Return a future that computes the suggestions given a fully resolved AST. |
| 412 * The future returns `true` if suggestions were added, else `false`. | 406 * The future returns `true` if suggestions were added, else `false`. |
| 413 */ | 407 */ |
| 414 Future<bool> computeFull(AstNode node); | 408 Future<bool> computeFull(AstNode node); |
| 415 } | 409 } |
| 416 | |
| 417 class _NoReturnType extends DartType { | |
| 418 | |
| 419 @override | |
| 420 String get displayName => name; | |
| 421 | |
| 422 @override | |
| 423 Element get element => null; | |
| 424 | |
| 425 @override | |
| 426 bool get isBottom => false; | |
| 427 | |
| 428 @override | |
| 429 bool get isDartCoreFunction => false; | |
| 430 | |
| 431 @override | |
| 432 bool get isDynamic => false; | |
| 433 | |
| 434 @override | |
| 435 bool get isObject => false; | |
| 436 | |
| 437 @override | |
| 438 bool get isUndefined => false; | |
| 439 | |
| 440 @override | |
| 441 bool get isVoid => false; | |
| 442 | |
| 443 @override | |
| 444 String get name => 'NoReturnType'; | |
| 445 | |
| 446 @override | |
| 447 DartType getLeastUpperBound(DartType type) => this; | |
| 448 | |
| 449 @override | |
| 450 bool isAssignableTo(DartType type) => type is _NoReturnType; | |
| 451 | |
| 452 @override | |
| 453 bool isMoreSpecificThan(DartType type) => false; | |
| 454 | |
| 455 @override | |
| 456 bool isSubtypeOf(DartType type) => false; | |
| 457 | |
| 458 @override | |
| 459 bool isSupertypeOf(DartType type) => false; | |
| 460 | |
| 461 @override | |
| 462 DartType substitute2(List<DartType> argumentTypes, | |
| 463 List<DartType> parameterTypes) => | |
| 464 this; | |
| 465 } | |
| OLD | NEW |