| 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.computer.dart.local; | 5 library services.completion.computer.dart.local; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/protocol.dart' as protocol | 9 import 'package:analysis_server/src/protocol.dart' as protocol |
| 10 show Element, ElementKind; | 10 show Element, ElementKind; |
| 11 import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind; | 11 import 'package:analysis_server/src/protocol.dart' hide Element, 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:analysis_server/src/services/completion/local_declaration_visito
r.dart'; | 13 import 'package:analysis_server/src/services/completion/local_declaration_visito
r.dart'; |
| 14 import 'package:analysis_server/src/services/completion/optype.dart'; | 14 import 'package:analysis_server/src/services/completion/optype.dart'; |
| 15 import 'package:analyzer/src/generated/ast.dart'; | 15 import 'package:analyzer/src/generated/ast.dart'; |
| 16 import 'package:analyzer/src/generated/scanner.dart'; | 16 import 'package:analyzer/src/generated/scanner.dart'; |
| 17 import 'package:analyzer/src/generated/utilities_dart.dart'; | 17 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 18 | 18 |
| 19 const _DYNAMIC = 'dynamic'; |
| 20 |
| 21 final TypeName _NO_RETURN_TYPE = new TypeName( |
| 22 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), null); |
| 23 |
| 24 /** |
| 25 * Create a new protocol Element for inclusion in a completion suggestion. |
| 26 */ |
| 27 protocol.Element _createElement(protocol.ElementKind kind, SimpleIdentifier id, |
| 28 {String parameters, TypeName returnType, bool isAbstract: false, |
| 29 bool isDeprecated: false}) { |
| 30 String name = id != null ? id.name : ''; |
| 31 int flags = protocol.Element.makeFlags( |
| 32 isAbstract: isAbstract, |
| 33 isDeprecated: isDeprecated, |
| 34 isPrivate: Identifier.isPrivateName(name)); |
| 35 return new protocol.Element(kind, name, flags, |
| 36 parameters: parameters, returnType: _nameForType(returnType)); |
| 37 } |
| 38 |
| 39 /** |
| 40 * Return `true` if the @deprecated annotation is present |
| 41 */ |
| 42 bool _isDeprecated(AnnotatedNode node) { |
| 43 if (node != null) { |
| 44 NodeList<Annotation> metadata = node.metadata; |
| 45 if (metadata != null) { |
| 46 return metadata.any((Annotation a) { |
| 47 return a.name is SimpleIdentifier && a.name.name == 'deprecated'; |
| 48 }); |
| 49 } |
| 50 } |
| 51 return false; |
| 52 } |
| 53 |
| 54 /** |
| 55 * Return the name for the given type. |
| 56 */ |
| 57 String _nameForType(TypeName type) { |
| 58 if (type == _NO_RETURN_TYPE) { |
| 59 return null; |
| 60 } |
| 61 if (type == null) { |
| 62 return _DYNAMIC; |
| 63 } |
| 64 Identifier id = type.name; |
| 65 if (id == null) { |
| 66 return _DYNAMIC; |
| 67 } |
| 68 String name = id.name; |
| 69 if (name == null || name.length <= 0) { |
| 70 return _DYNAMIC; |
| 71 } |
| 72 TypeArgumentList typeArgs = type.typeArguments; |
| 73 if (typeArgs != null) { |
| 74 //TODO (danrubel) include type arguments |
| 75 } |
| 76 return name; |
| 77 } |
| 78 |
| 19 /** | 79 /** |
| 20 * A computer for calculating `completion.getSuggestions` request results | 80 * A computer for calculating `completion.getSuggestions` request results |
| 21 * for the local library in which the completion is requested. | 81 * for the local library in which the completion is requested. |
| 22 */ | 82 */ |
| 23 class LocalComputer extends DartCompletionComputer { | 83 class LocalComputer extends DartCompletionComputer { |
| 24 @override | 84 @override |
| 25 bool computeFast(DartCompletionRequest request) { | 85 bool computeFast(DartCompletionRequest request) { |
| 26 OpType optype = request.optype; | 86 OpType optype = request.optype; |
| 87 |
| 88 // Collect suggestions from the specific child [AstNode] that contains |
| 89 // the completion offset and all of its parents recursively. |
| 27 if (optype.includeTopLevelSuggestions) { | 90 if (optype.includeTopLevelSuggestions) { |
| 28 _LocalVisitor localVisitor = new _LocalVisitor(request, request.offset, | 91 _LocalVisitor localVisitor = new _LocalVisitor(request, request.offset, |
| 29 optype.includeOnlyTypeNameSuggestions, | 92 optype.includeOnlyTypeNameSuggestions, |
| 30 !optype.includeVoidReturnSuggestions); | 93 !optype.includeVoidReturnSuggestions); |
| 31 | |
| 32 // Collect suggestions from the specific child [AstNode] that contains | |
| 33 // the completion offset and all of its parents recursively. | |
| 34 localVisitor.visit(request.node); | 94 localVisitor.visit(request.node); |
| 35 } | 95 } |
| 36 if (optype.includeStatementLabelSuggestions || | 96 if (optype.includeStatementLabelSuggestions || |
| 37 optype.includeCaseLabelSuggestions) { | 97 optype.includeCaseLabelSuggestions) { |
| 38 _LabelVisitor labelVisitor = new _LabelVisitor(request, | 98 _LabelVisitor labelVisitor = new _LabelVisitor(request, |
| 39 optype.includeStatementLabelSuggestions, | 99 optype.includeStatementLabelSuggestions, |
| 40 optype.includeCaseLabelSuggestions); | 100 optype.includeCaseLabelSuggestions); |
| 41 labelVisitor.visit(request.node); | 101 labelVisitor.visit(request.node); |
| 42 } | 102 } |
| 103 if (optype.includeConstructorSuggestions) { |
| 104 new _ConstructorVisitor(request).visit(request.node); |
| 105 } |
| 43 | 106 |
| 44 // If the unit is not a part and does not reference any parts | 107 // If the unit is not a part and does not reference any parts |
| 45 // then work is complete | 108 // then work is complete |
| 46 return !request.unit.directives.any((Directive directive) => | 109 return !request.unit.directives.any((Directive directive) => |
| 47 directive is PartOfDirective || directive is PartDirective); | 110 directive is PartOfDirective || directive is PartDirective); |
| 48 } | 111 } |
| 49 | 112 |
| 50 @override | 113 @override |
| 51 Future<bool> computeFull(DartCompletionRequest request) { | 114 Future<bool> computeFull(DartCompletionRequest request) { |
| 52 // TODO: implement computeFull | 115 // TODO: implement computeFull |
| 53 // include results from part files that are included in the library | 116 // include results from part files that are included in the library |
| 54 return new Future.value(false); | 117 return new Future.value(false); |
| 55 } | 118 } |
| 56 } | 119 } |
| 57 | 120 |
| 58 /** | 121 /** |
| 122 * A visitor for collecting constructor suggestions. |
| 123 */ |
| 124 class _ConstructorVisitor extends LocalDeclarationVisitor { |
| 125 final DartCompletionRequest request; |
| 126 |
| 127 _ConstructorVisitor(DartCompletionRequest request) |
| 128 : super(request.offset), |
| 129 request = request; |
| 130 |
| 131 @override |
| 132 void declaredClass(ClassDeclaration declaration) { |
| 133 bool found = false; |
| 134 for (ClassMember member in declaration.members) { |
| 135 if (member is ConstructorDeclaration) { |
| 136 found = true; |
| 137 _addSuggestion(declaration, member); |
| 138 } |
| 139 } |
| 140 if (!found) { |
| 141 _addSuggestion(declaration, null); |
| 142 } |
| 143 } |
| 144 |
| 145 @override |
| 146 void declaredClassTypeAlias(ClassTypeAlias declaration) { |
| 147 // TODO: implement declaredClassTypeAlias |
| 148 } |
| 149 |
| 150 @override |
| 151 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) { |
| 152 // TODO: implement declaredField |
| 153 } |
| 154 |
| 155 @override |
| 156 void declaredFunction(FunctionDeclaration declaration) { |
| 157 // TODO: implement declaredFunction |
| 158 } |
| 159 |
| 160 @override |
| 161 void declaredFunctionTypeAlias(FunctionTypeAlias declaration) { |
| 162 // TODO: implement declaredFunctionTypeAlias |
| 163 } |
| 164 |
| 165 @override |
| 166 void declaredLabel(Label label, bool isCaseLabel) { |
| 167 // TODO: implement declaredLabel |
| 168 } |
| 169 |
| 170 @override |
| 171 void declaredLocalVar(SimpleIdentifier name, TypeName type) { |
| 172 // TODO: implement declaredLocalVar |
| 173 } |
| 174 |
| 175 @override |
| 176 void declaredMethod(MethodDeclaration declaration) { |
| 177 // TODO: implement declaredMethod |
| 178 } |
| 179 |
| 180 @override |
| 181 void declaredParam(SimpleIdentifier name, TypeName type) { |
| 182 // TODO: implement declaredParam |
| 183 } |
| 184 |
| 185 @override |
| 186 void declaredTopLevelVar( |
| 187 VariableDeclarationList varList, VariableDeclaration varDecl) { |
| 188 // TODO: implement declaredTopLevelVar |
| 189 } |
| 190 |
| 191 /** |
| 192 * For the given class and constructor, |
| 193 * add a suggestion of the form B(...) or B.name(...). |
| 194 * If the given constructor is `null` |
| 195 * then add a default constructor suggestion. |
| 196 */ |
| 197 CompletionSuggestion _addSuggestion( |
| 198 ClassDeclaration classDecl, ConstructorDeclaration constructorDecl) { |
| 199 String completion = classDecl.name.name; |
| 200 if (constructorDecl != null) { |
| 201 SimpleIdentifier elemId = constructorDecl.name; |
| 202 if (elemId != null) { |
| 203 String name = elemId.name; |
| 204 if (name != null && name.length > 0) { |
| 205 completion = '$completion.$name'; |
| 206 } |
| 207 } |
| 208 } |
| 209 bool isDeprecated = |
| 210 constructorDecl != null && _isDeprecated(constructorDecl); |
| 211 List<String> parameterNames = new List<String>(); |
| 212 List<String> parameterTypes = new List<String>(); |
| 213 int requiredParameterCount = 0; |
| 214 bool hasNamedParameters = false; |
| 215 StringBuffer paramBuf = new StringBuffer(); |
| 216 paramBuf.write('('); |
| 217 int paramCount = 0; |
| 218 if (constructorDecl != null) { |
| 219 for (FormalParameter param in constructorDecl.parameters.parameters) { |
| 220 if (paramCount > 0) { |
| 221 paramBuf.write(', '); |
| 222 } |
| 223 String paramName; |
| 224 String typeName; |
| 225 if (param is NormalFormalParameter) { |
| 226 paramName = param.identifier.name; |
| 227 typeName = _nameForParamType(param); |
| 228 ++requiredParameterCount; |
| 229 } else if (param is DefaultFormalParameter) { |
| 230 NormalFormalParameter childParam = param.parameter; |
| 231 paramName = childParam.identifier.name; |
| 232 typeName = _nameForParamType(childParam); |
| 233 if (param.kind == ParameterKind.NAMED) { |
| 234 hasNamedParameters = true; |
| 235 } |
| 236 if (paramCount == requiredParameterCount) { |
| 237 paramBuf.write(hasNamedParameters ? '{' : '['); |
| 238 } |
| 239 } |
| 240 parameterNames.add(paramName); |
| 241 parameterTypes.add(typeName); |
| 242 paramBuf.write(typeName); |
| 243 paramBuf.write(' '); |
| 244 paramBuf.write(paramName); |
| 245 ++paramCount; |
| 246 } |
| 247 } |
| 248 if (paramCount > requiredParameterCount) { |
| 249 paramBuf.write(hasNamedParameters ? '}' : ']'); |
| 250 } |
| 251 paramBuf.write(')'); |
| 252 protocol.Element element = _createElement( |
| 253 protocol.ElementKind.CONSTRUCTOR, null, |
| 254 parameters: paramBuf.toString()); |
| 255 element.name = completion; |
| 256 element.returnType = classDecl.name.name; |
| 257 CompletionSuggestion suggestion = new CompletionSuggestion( |
| 258 CompletionSuggestionKind.INVOCATION, |
| 259 isDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT, completion, |
| 260 completion.length, 0, isDeprecated, false, |
| 261 declaringType: classDecl.name.name, |
| 262 element: element, |
| 263 parameterNames: parameterNames, |
| 264 parameterTypes: parameterTypes, |
| 265 requiredParameterCount: requiredParameterCount, |
| 266 hasNamedParameters: hasNamedParameters); |
| 267 request.suggestions.add(suggestion); |
| 268 return suggestion; |
| 269 } |
| 270 |
| 271 /** |
| 272 * Determine the name of the type for the given constructor parameter. |
| 273 */ |
| 274 String _nameForParamType(NormalFormalParameter param) { |
| 275 if (param is SimpleFormalParameter) { |
| 276 return _nameForType(param.type); |
| 277 } |
| 278 SimpleIdentifier id = param.identifier; |
| 279 if (param is FieldFormalParameter && id != null) { |
| 280 String fieldName = id.name; |
| 281 AstNode classDecl = param.getAncestor((p) => p is ClassDeclaration); |
| 282 if (classDecl is ClassDeclaration) { |
| 283 for (ClassMember member in classDecl.members) { |
| 284 if (member is FieldDeclaration) { |
| 285 for (VariableDeclaration field in member.fields.variables) { |
| 286 if (field.name.name == fieldName) { |
| 287 return _nameForType(member.fields.type); |
| 288 } |
| 289 } |
| 290 } |
| 291 } |
| 292 } |
| 293 } |
| 294 return _DYNAMIC; |
| 295 } |
| 296 } |
| 297 |
| 298 /** |
| 59 * A visitor for collecting suggestions for break and continue labels. | 299 * A visitor for collecting suggestions for break and continue labels. |
| 60 */ | 300 */ |
| 61 class _LabelVisitor extends LocalDeclarationVisitor { | 301 class _LabelVisitor extends LocalDeclarationVisitor { |
| 62 final DartCompletionRequest request; | 302 final DartCompletionRequest request; |
| 63 | 303 |
| 64 /** | 304 /** |
| 65 * True if statement labels should be included as suggestions. | 305 * True if statement labels should be included as suggestions. |
| 66 */ | 306 */ |
| 67 final bool includeStatementLabels; | 307 final bool includeStatementLabels; |
| 68 | 308 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 protocol.Element.makeFlags(isPrivate: Identifier.isPrivateName(name)); | 411 protocol.Element.makeFlags(isPrivate: Identifier.isPrivateName(name)); |
| 172 return new protocol.Element(kind, name, flags); | 412 return new protocol.Element(kind, name, flags); |
| 173 } | 413 } |
| 174 } | 414 } |
| 175 | 415 |
| 176 /** | 416 /** |
| 177 * A visitor for collecting suggestions from the most specific child [AstNode] | 417 * A visitor for collecting suggestions from the most specific child [AstNode] |
| 178 * that contains the completion offset to the [CompilationUnit]. | 418 * that contains the completion offset to the [CompilationUnit]. |
| 179 */ | 419 */ |
| 180 class _LocalVisitor extends LocalDeclarationVisitor { | 420 class _LocalVisitor extends LocalDeclarationVisitor { |
| 181 static const DYNAMIC = 'dynamic'; | |
| 182 | |
| 183 static final TypeName NO_RETURN_TYPE = new TypeName( | |
| 184 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), null); | |
| 185 | |
| 186 final DartCompletionRequest request; | 421 final DartCompletionRequest request; |
| 187 final bool typesOnly; | 422 final bool typesOnly; |
| 188 final bool excludeVoidReturn; | 423 final bool excludeVoidReturn; |
| 189 | 424 |
| 190 _LocalVisitor( | 425 _LocalVisitor( |
| 191 this.request, int offset, this.typesOnly, this.excludeVoidReturn) | 426 this.request, int offset, this.typesOnly, this.excludeVoidReturn) |
| 192 : super(offset); | 427 : super(offset); |
| 193 | 428 |
| 194 @override | 429 @override |
| 195 void declaredClass(ClassDeclaration declaration) { | 430 void declaredClass(ClassDeclaration declaration) { |
| 196 bool isDeprecated = _isDeprecated(declaration); | 431 bool isDeprecated = _isDeprecated(declaration); |
| 197 CompletionSuggestion suggestion = _addSuggestion( | 432 CompletionSuggestion suggestion = _addSuggestion(declaration.name, |
| 198 declaration.name, NO_RETURN_TYPE, isDeprecated, DART_RELEVANCE_DEFAULT); | 433 _NO_RETURN_TYPE, isDeprecated, DART_RELEVANCE_DEFAULT); |
| 199 if (suggestion != null) { | 434 if (suggestion != null) { |
| 200 suggestion.element = _createElement( | 435 suggestion.element = _createElement( |
| 201 protocol.ElementKind.CLASS, declaration.name, | 436 protocol.ElementKind.CLASS, declaration.name, |
| 202 returnType: NO_RETURN_TYPE, | 437 returnType: _NO_RETURN_TYPE, |
| 203 isAbstract: declaration.isAbstract, | 438 isAbstract: declaration.isAbstract, |
| 204 isDeprecated: isDeprecated); | 439 isDeprecated: isDeprecated); |
| 205 } | 440 } |
| 206 } | 441 } |
| 207 | 442 |
| 208 @override | 443 @override |
| 209 void declaredClassTypeAlias(ClassTypeAlias declaration) { | 444 void declaredClassTypeAlias(ClassTypeAlias declaration) { |
| 210 bool isDeprecated = _isDeprecated(declaration); | 445 bool isDeprecated = _isDeprecated(declaration); |
| 211 CompletionSuggestion suggestion = _addSuggestion( | 446 CompletionSuggestion suggestion = _addSuggestion(declaration.name, |
| 212 declaration.name, NO_RETURN_TYPE, isDeprecated, DART_RELEVANCE_DEFAULT); | 447 _NO_RETURN_TYPE, isDeprecated, DART_RELEVANCE_DEFAULT); |
| 213 if (suggestion != null) { | 448 if (suggestion != null) { |
| 214 suggestion.element = _createElement( | 449 suggestion.element = _createElement( |
| 215 protocol.ElementKind.CLASS_TYPE_ALIAS, declaration.name, | 450 protocol.ElementKind.CLASS_TYPE_ALIAS, declaration.name, |
| 216 returnType: NO_RETURN_TYPE, | 451 returnType: _NO_RETURN_TYPE, |
| 217 isAbstract: true, | 452 isAbstract: true, |
| 218 isDeprecated: isDeprecated); | 453 isDeprecated: isDeprecated); |
| 219 } | 454 } |
| 220 } | 455 } |
| 221 | 456 |
| 222 @override | 457 @override |
| 223 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) { | 458 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) { |
| 224 if (typesOnly) { | 459 if (typesOnly) { |
| 225 return; | 460 return; |
| 226 } | 461 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 246 protocol.ElementKind kind; | 481 protocol.ElementKind kind; |
| 247 int defaultRelevance = DART_RELEVANCE_DEFAULT; | 482 int defaultRelevance = DART_RELEVANCE_DEFAULT; |
| 248 if (declaration.isGetter) { | 483 if (declaration.isGetter) { |
| 249 kind = protocol.ElementKind.GETTER; | 484 kind = protocol.ElementKind.GETTER; |
| 250 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR; | 485 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR; |
| 251 } else if (declaration.isSetter) { | 486 } else if (declaration.isSetter) { |
| 252 if (excludeVoidReturn) { | 487 if (excludeVoidReturn) { |
| 253 return; | 488 return; |
| 254 } | 489 } |
| 255 kind = protocol.ElementKind.SETTER; | 490 kind = protocol.ElementKind.SETTER; |
| 256 returnType = NO_RETURN_TYPE; | 491 returnType = _NO_RETURN_TYPE; |
| 257 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR; | 492 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR; |
| 258 } else { | 493 } else { |
| 259 if (excludeVoidReturn && _isVoid(returnType)) { | 494 if (excludeVoidReturn && _isVoid(returnType)) { |
| 260 return; | 495 return; |
| 261 } | 496 } |
| 262 kind = protocol.ElementKind.FUNCTION; | 497 kind = protocol.ElementKind.FUNCTION; |
| 263 defaultRelevance = DART_RELEVANCE_LOCAL_FUNCTION; | 498 defaultRelevance = DART_RELEVANCE_LOCAL_FUNCTION; |
| 264 } | 499 } |
| 265 CompletionSuggestion suggestion = _addSuggestion( | 500 CompletionSuggestion suggestion = _addSuggestion( |
| 266 declaration.name, returnType, isDeprecated, defaultRelevance); | 501 declaration.name, returnType, isDeprecated, defaultRelevance); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 int defaultRelevance = DART_RELEVANCE_DEFAULT; | 555 int defaultRelevance = DART_RELEVANCE_DEFAULT; |
| 321 if (declaration.isGetter) { | 556 if (declaration.isGetter) { |
| 322 kind = protocol.ElementKind.GETTER; | 557 kind = protocol.ElementKind.GETTER; |
| 323 parameters = null; | 558 parameters = null; |
| 324 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR; | 559 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR; |
| 325 } else if (declaration.isSetter) { | 560 } else if (declaration.isSetter) { |
| 326 if (excludeVoidReturn) { | 561 if (excludeVoidReturn) { |
| 327 return; | 562 return; |
| 328 } | 563 } |
| 329 kind = protocol.ElementKind.SETTER; | 564 kind = protocol.ElementKind.SETTER; |
| 330 returnType = NO_RETURN_TYPE; | 565 returnType = _NO_RETURN_TYPE; |
| 331 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR; | 566 defaultRelevance = DART_RELEVANCE_LOCAL_ACCESSOR; |
| 332 } else { | 567 } else { |
| 333 if (excludeVoidReturn && _isVoid(returnType)) { | 568 if (excludeVoidReturn && _isVoid(returnType)) { |
| 334 return; | 569 return; |
| 335 } | 570 } |
| 336 kind = protocol.ElementKind.METHOD; | 571 kind = protocol.ElementKind.METHOD; |
| 337 parameters = declaration.parameters.toSource(); | 572 parameters = declaration.parameters.toSource(); |
| 338 defaultRelevance = DART_RELEVANCE_LOCAL_METHOD; | 573 defaultRelevance = DART_RELEVANCE_LOCAL_METHOD; |
| 339 } | 574 } |
| 340 bool isDeprecated = _isDeprecated(declaration); | 575 bool isDeprecated = _isDeprecated(declaration); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 } | 672 } |
| 438 } | 673 } |
| 439 } | 674 } |
| 440 request.suggestions.add(suggestion); | 675 request.suggestions.add(suggestion); |
| 441 return suggestion; | 676 return suggestion; |
| 442 } | 677 } |
| 443 } | 678 } |
| 444 return null; | 679 return null; |
| 445 } | 680 } |
| 446 | 681 |
| 447 /** | |
| 448 * Create a new protocol Element for inclusion in a completion suggestion. | |
| 449 */ | |
| 450 protocol.Element _createElement( | |
| 451 protocol.ElementKind kind, SimpleIdentifier id, {String parameters, | |
| 452 TypeName returnType, bool isAbstract: false, bool isDeprecated: false}) { | |
| 453 String name = id.name; | |
| 454 int flags = protocol.Element.makeFlags( | |
| 455 isAbstract: isAbstract, | |
| 456 isDeprecated: isDeprecated, | |
| 457 isPrivate: Identifier.isPrivateName(name)); | |
| 458 return new protocol.Element(kind, name, flags, | |
| 459 parameters: parameters, returnType: _nameForType(returnType)); | |
| 460 } | |
| 461 | |
| 462 /** | |
| 463 * Return `true` if the @deprecated annotation is present | |
| 464 */ | |
| 465 bool _isDeprecated(AnnotatedNode node) { | |
| 466 if (node != null) { | |
| 467 NodeList<Annotation> metadata = node.metadata; | |
| 468 if (metadata != null) { | |
| 469 return metadata.any((Annotation a) { | |
| 470 return a.name is SimpleIdentifier && a.name.name == 'deprecated'; | |
| 471 }); | |
| 472 } | |
| 473 } | |
| 474 return false; | |
| 475 } | |
| 476 | |
| 477 bool _isVoid(TypeName returnType) { | 682 bool _isVoid(TypeName returnType) { |
| 478 if (returnType != null) { | 683 if (returnType != null) { |
| 479 Identifier id = returnType.name; | 684 Identifier id = returnType.name; |
| 480 if (id != null && id.name == 'void') { | 685 if (id != null && id.name == 'void') { |
| 481 return true; | 686 return true; |
| 482 } | 687 } |
| 483 } | 688 } |
| 484 return false; | 689 return false; |
| 485 } | 690 } |
| 486 | |
| 487 /** | |
| 488 * Return the name for the given type. | |
| 489 */ | |
| 490 String _nameForType(TypeName type) { | |
| 491 if (type == NO_RETURN_TYPE) { | |
| 492 return null; | |
| 493 } | |
| 494 if (type == null) { | |
| 495 return DYNAMIC; | |
| 496 } | |
| 497 Identifier id = type.name; | |
| 498 if (id == null) { | |
| 499 return DYNAMIC; | |
| 500 } | |
| 501 String name = id.name; | |
| 502 if (name == null || name.length <= 0) { | |
| 503 return DYNAMIC; | |
| 504 } | |
| 505 TypeArgumentList typeArgs = type.typeArguments; | |
| 506 if (typeArgs != null) { | |
| 507 //TODO (danrubel) include type arguments | |
| 508 } | |
| 509 return name; | |
| 510 } | |
| 511 } | 691 } |
| OLD | NEW |