| 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 show Element, | 9 import 'package:analysis_server/src/protocol.dart' as protocol show Element, |
| 10 ElementKind; | 10 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_ast_visitor.dart'
; |
| 14 import 'package:analyzer/src/generated/ast.dart'; | 15 import 'package:analyzer/src/generated/ast.dart'; |
| 15 import 'package:analyzer/src/generated/scanner.dart'; | 16 import 'package:analyzer/src/generated/scanner.dart'; |
| 16 | 17 |
| 17 /** | 18 /** |
| 18 * A computer for calculating `completion.getSuggestions` request results | 19 * A computer for calculating `completion.getSuggestions` request results |
| 19 * for the local library in which the completion is requested. | 20 * for the local library in which the completion is requested. |
| 20 */ | 21 */ |
| 21 class LocalComputer extends DartCompletionComputer { | 22 class LocalComputer extends DartCompletionComputer { |
| 22 | 23 |
| 23 @override | 24 @override |
| 24 bool computeFast(DartCompletionRequest request) { | 25 bool computeFast(DartCompletionRequest request) { |
| 25 | 26 |
| 26 // Collect suggestions from the specific child [AstNode] that contains | 27 // Determine the type of suggestions to be made |
| 27 // the completion offset and all of its parents recursively. | 28 OpTypeAstVisitor opTypeVisitor = new OpTypeAstVisitor(request.offset); |
| 28 request.node.accept(new _LocalVisitor(request, request.offset)); | 29 request.node.accept(opTypeVisitor); |
| 30 |
| 31 // Build the suggestions |
| 32 if (opTypeVisitor.includeTopLevelSuggestions) { |
| 33 _LocalVisitor localVisitor = new _LocalVisitor(request, request.offset); |
| 34 localVisitor.typesOnly = opTypeVisitor.includeOnlyTypeNameSuggestions; |
| 35 localVisitor.excludeVoidReturn = |
| 36 !opTypeVisitor.includeVoidReturnSuggestions; |
| 37 |
| 38 // Collect suggestions from the specific child [AstNode] that contains |
| 39 // the completion offset and all of its parents recursively. |
| 40 request.node.accept(localVisitor); |
| 41 } |
| 29 | 42 |
| 30 // If the unit is not a part and does not reference any parts | 43 // If the unit is not a part and does not reference any parts |
| 31 // then work is complete | 44 // then work is complete |
| 32 return !request.unit.directives.any( | 45 return !request.unit.directives.any( |
| 33 (Directive directive) => | 46 (Directive directive) => |
| 34 directive is PartOfDirective || directive is PartDirective); | 47 directive is PartOfDirective || directive is PartDirective); |
| 35 } | 48 } |
| 36 | 49 |
| 37 @override | 50 @override |
| 38 Future<bool> computeFull(DartCompletionRequest request) { | 51 Future<bool> computeFull(DartCompletionRequest request) { |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 suggestion.element = _createElement( | 254 suggestion.element = _createElement( |
| 242 protocol.ElementKind.TOP_LEVEL_VARIABLE, | 255 protocol.ElementKind.TOP_LEVEL_VARIABLE, |
| 243 varDecl.name, | 256 varDecl.name, |
| 244 null, | 257 null, |
| 245 varList.type, | 258 varList.type, |
| 246 false, | 259 false, |
| 247 isDeprecated); | 260 isDeprecated); |
| 248 } | 261 } |
| 249 } | 262 } |
| 250 | 263 |
| 251 @override | |
| 252 bool visitCascadeExpression(CascadeExpression node) { | |
| 253 Expression target = node.target; | |
| 254 // This computer handles the expression | |
| 255 // while InvocationComputer handles the cascade selector | |
| 256 if (target != null && offset <= target.end) { | |
| 257 return visitNode(node); | |
| 258 } else { | |
| 259 return finished; | |
| 260 } | |
| 261 } | |
| 262 | |
| 263 @override | |
| 264 visitCombinator(Combinator node) { | |
| 265 // Handled by CombinatorComputer | |
| 266 } | |
| 267 | |
| 268 @override | |
| 269 visitConstructorName(ConstructorName node) { | |
| 270 // InvocationComputer adds suggestions for prefixed elements | |
| 271 // but this computer adds suggestions for the prefix itself | |
| 272 Token period = node.period; | |
| 273 if (period == null || request.offset <= period.offset) { | |
| 274 visitNode(node); | |
| 275 } | |
| 276 } | |
| 277 | |
| 278 @override | |
| 279 visitMethodInvocation(MethodInvocation node) { | |
| 280 // InvocationComputer adds suggestions for method selector | |
| 281 Token period = node.period; | |
| 282 if (period != null && period.offset < request.offset) { | |
| 283 ArgumentList argumentList = node.argumentList; | |
| 284 if (argumentList == null || request.offset <= argumentList.offset) { | |
| 285 return; | |
| 286 } | |
| 287 } | |
| 288 visitNode(node); | |
| 289 } | |
| 290 | |
| 291 @override | |
| 292 bool visitNamespaceDirective(NamespaceDirective node) { | |
| 293 // No suggestions | |
| 294 return finished; | |
| 295 } | |
| 296 | |
| 297 @override | |
| 298 visitPrefixedIdentifier(PrefixedIdentifier node) { | |
| 299 // InvocationComputer adds suggestions for prefixed elements | |
| 300 // but this computer adds suggestions for the prefix itself | |
| 301 Token period = node.period; | |
| 302 if (period == null || request.offset <= period.offset) { | |
| 303 visitNode(node); | |
| 304 } | |
| 305 } | |
| 306 | |
| 307 @override | |
| 308 visitPropertyAccess(PropertyAccess node) { | |
| 309 // InvocationComputer adds suggestions for property access selector | |
| 310 } | |
| 311 | |
| 312 @override | |
| 313 bool visitStringLiteral(StringLiteral node) { | |
| 314 // ignore | |
| 315 return finished; | |
| 316 } | |
| 317 | |
| 318 @override | |
| 319 visitTypeName(TypeName node) { | |
| 320 // TODO (danrubel) refactor this and imported_computer | |
| 321 // to reduce duplicate code | |
| 322 // If suggesting completions within a TypeName node | |
| 323 // then limit suggestions to only types in specific situations | |
| 324 AstNode p = node.parent; | |
| 325 if (p is IsExpression || p is ConstructorName || p is AsExpression) { | |
| 326 typesOnly = true; | |
| 327 } else if (p is VariableDeclarationList) { | |
| 328 // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS | |
| 329 // the user may be either (1) entering a type for the assignment | |
| 330 // or (2) starting a new statement. | |
| 331 // Consider suggesting only types | |
| 332 // if only spaces separates the 1st and 2nd identifiers. | |
| 333 } | |
| 334 return visitNode(node); | |
| 335 } | |
| 336 | |
| 337 @override | |
| 338 bool visitVariableDeclaration(VariableDeclaration node) { | |
| 339 // Do not add suggestions if editing the name in a var declaration | |
| 340 SimpleIdentifier name = node.name; | |
| 341 if (name == null || name.offset < offset || offset > name.end) { | |
| 342 return visitNode(node); | |
| 343 } else { | |
| 344 return finished; | |
| 345 } | |
| 346 } | |
| 347 | |
| 348 CompletionSuggestion _addSuggestion(SimpleIdentifier id, TypeName typeName, | 264 CompletionSuggestion _addSuggestion(SimpleIdentifier id, TypeName typeName, |
| 349 ClassDeclaration classDecl, bool isDeprecated) { | 265 ClassDeclaration classDecl, bool isDeprecated) { |
| 350 if (id != null) { | 266 if (id != null) { |
| 351 String completion = id.name; | 267 String completion = id.name; |
| 352 if (completion != null && completion.length > 0 && completion != '_') { | 268 if (completion != null && completion.length > 0 && completion != '_') { |
| 353 CompletionSuggestion suggestion = new CompletionSuggestion( | 269 CompletionSuggestion suggestion = new CompletionSuggestion( |
| 354 CompletionSuggestionKind.INVOCATION, | 270 CompletionSuggestionKind.INVOCATION, |
| 355 isDeprecated ? CompletionRelevance.LOW : CompletionRelevance.DEFAULT
, | 271 isDeprecated ? CompletionRelevance.LOW : CompletionRelevance.DEFAULT
, |
| 356 completion, | 272 completion, |
| 357 completion.length, | 273 completion.length, |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 if (name == null || name.length <= 0) { | 372 if (name == null || name.length <= 0) { |
| 457 return DYNAMIC; | 373 return DYNAMIC; |
| 458 } | 374 } |
| 459 TypeArgumentList typeArgs = type.typeArguments; | 375 TypeArgumentList typeArgs = type.typeArguments; |
| 460 if (typeArgs != null) { | 376 if (typeArgs != null) { |
| 461 //TODO (danrubel) include type arguments | 377 //TODO (danrubel) include type arguments |
| 462 } | 378 } |
| 463 return name; | 379 return name; |
| 464 } | 380 } |
| 465 } | 381 } |
| OLD | NEW |