| 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; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 static final TypeName NO_RETURN_TYPE = new TypeName( | 52 static final TypeName NO_RETURN_TYPE = new TypeName( |
| 53 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), | 53 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), |
| 54 null); | 54 null); |
| 55 | 55 |
| 56 static final TypeName STACKTRACE_TYPE = new TypeName( | 56 static final TypeName STACKTRACE_TYPE = new TypeName( |
| 57 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, 'StackTrace', 0
)), | 57 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, 'StackTrace', 0
)), |
| 58 null); | 58 null); |
| 59 | 59 |
| 60 final DartCompletionRequest request; | 60 final DartCompletionRequest request; |
| 61 bool typesOnly = false; | 61 bool typesOnly = false; |
| 62 bool excludeVoidReturn; |
| 62 | 63 |
| 63 _LocalVisitor(this.request); | 64 _LocalVisitor(this.request) { |
| 65 excludeVoidReturn = _computeExcludeVoidReturn(request.node); |
| 66 } |
| 64 | 67 |
| 65 @override | 68 @override |
| 66 visitBlock(Block node) { | 69 visitBlock(Block node) { |
| 67 node.statements.forEach((Statement stmt) { | 70 node.statements.forEach((Statement stmt) { |
| 68 if (stmt.offset < request.offset) { | 71 if (stmt.offset < request.offset) { |
| 69 if (stmt is LabeledStatement) { | 72 if (stmt is LabeledStatement) { |
| 70 stmt.labels.forEach((Label label) { | 73 stmt.labels.forEach((Label label) { |
| 71 // _addSuggestion(label.label, CompletionSuggestionKind.LABEL); | 74 // _addSuggestion(label.label, CompletionSuggestionKind.LABEL); |
| 72 }); | 75 }); |
| 73 } else if (stmt is VariableDeclarationStatement) { | 76 } else if (stmt is VariableDeclarationStatement) { |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 false, | 308 false, |
| 306 isDeprecated || _isDeprecated(varDecl.metadata)); | 309 isDeprecated || _isDeprecated(varDecl.metadata)); |
| 307 } | 310 } |
| 308 }); | 311 }); |
| 309 } | 312 } |
| 310 | 313 |
| 311 void _addFunctionSuggestion(FunctionDeclaration declaration) { | 314 void _addFunctionSuggestion(FunctionDeclaration declaration) { |
| 312 if (typesOnly) { | 315 if (typesOnly) { |
| 313 return; | 316 return; |
| 314 } | 317 } |
| 318 if (excludeVoidReturn && _isVoid(declaration.returnType)) { |
| 319 return; |
| 320 } |
| 315 CompletionSuggestion suggestion = _addSuggestion( | 321 CompletionSuggestion suggestion = _addSuggestion( |
| 316 declaration.name, | 322 declaration.name, |
| 317 CompletionSuggestionKind.FUNCTION, | 323 CompletionSuggestionKind.FUNCTION, |
| 318 declaration.returnType, | 324 declaration.returnType, |
| 319 null); | 325 null); |
| 320 if (suggestion != null) { | 326 if (suggestion != null) { |
| 321 suggestion.element = _createElement( | 327 suggestion.element = _createElement( |
| 322 protocol.ElementKind.FUNCTION, | 328 protocol.ElementKind.FUNCTION, |
| 323 declaration.name, | 329 declaration.name, |
| 324 declaration.returnType, | 330 declaration.returnType, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 346 void _addMethodSuggestion(ClassDeclaration node, MethodDeclaration classMbr) { | 352 void _addMethodSuggestion(ClassDeclaration node, MethodDeclaration classMbr) { |
| 347 if (typesOnly) { | 353 if (typesOnly) { |
| 348 return; | 354 return; |
| 349 } | 355 } |
| 350 protocol.ElementKind kind; | 356 protocol.ElementKind kind; |
| 351 CompletionSuggestionKind csKind; | 357 CompletionSuggestionKind csKind; |
| 352 if (classMbr.isGetter) { | 358 if (classMbr.isGetter) { |
| 353 kind = protocol.ElementKind.GETTER; | 359 kind = protocol.ElementKind.GETTER; |
| 354 csKind = CompletionSuggestionKind.GETTER; | 360 csKind = CompletionSuggestionKind.GETTER; |
| 355 } else if (classMbr.isSetter) { | 361 } else if (classMbr.isSetter) { |
| 362 if (excludeVoidReturn) { |
| 363 return; |
| 364 } |
| 356 kind = protocol.ElementKind.SETTER; | 365 kind = protocol.ElementKind.SETTER; |
| 357 csKind = CompletionSuggestionKind.SETTER; | 366 csKind = CompletionSuggestionKind.SETTER; |
| 358 } else { | 367 } else { |
| 368 if (excludeVoidReturn && _isVoid(classMbr.returnType)) { |
| 369 return; |
| 370 } |
| 359 kind = protocol.ElementKind.METHOD; | 371 kind = protocol.ElementKind.METHOD; |
| 360 csKind = CompletionSuggestionKind.METHOD; | 372 csKind = CompletionSuggestionKind.METHOD; |
| 361 } | 373 } |
| 362 CompletionSuggestion suggestion = | 374 CompletionSuggestion suggestion = |
| 363 _addSuggestion(classMbr.name, csKind, classMbr.returnType, node); | 375 _addSuggestion(classMbr.name, csKind, classMbr.returnType, node); |
| 364 suggestion.element = _createElement( | 376 suggestion.element = _createElement( |
| 365 kind, | 377 kind, |
| 366 classMbr.name, | 378 classMbr.name, |
| 367 classMbr.returnType, | 379 classMbr.returnType, |
| 368 classMbr.isAbstract, | 380 classMbr.isAbstract, |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 protocol.ElementKind.TOP_LEVEL_VARIABLE, | 473 protocol.ElementKind.TOP_LEVEL_VARIABLE, |
| 462 varDecl.name, | 474 varDecl.name, |
| 463 varList.type, | 475 varList.type, |
| 464 false, | 476 false, |
| 465 isDeprecated || _isDeprecated(varDecl.metadata)); | 477 isDeprecated || _isDeprecated(varDecl.metadata)); |
| 466 } | 478 } |
| 467 }); | 479 }); |
| 468 } | 480 } |
| 469 } | 481 } |
| 470 | 482 |
| 483 bool _computeExcludeVoidReturn(AstNode node) { |
| 484 if (node is Block) { |
| 485 return false; |
| 486 } else if (node is SimpleIdentifier) { |
| 487 return node.parent is ExpressionStatement ? false : true; |
| 488 } else { |
| 489 return true; |
| 490 } |
| 491 } |
| 492 |
| 471 /** | 493 /** |
| 472 * Create a new protocol Element for inclusion in a completion suggestion. | 494 * Create a new protocol Element for inclusion in a completion suggestion. |
| 473 */ | 495 */ |
| 474 protocol.Element _createElement(protocol.ElementKind kind, | 496 protocol.Element _createElement(protocol.ElementKind kind, |
| 475 SimpleIdentifier id, TypeName returnType, bool isAbstract, bool isDeprecat
ed) { | 497 SimpleIdentifier id, TypeName returnType, bool isAbstract, bool isDeprecat
ed) { |
| 476 String name = id.name; | 498 String name = id.name; |
| 477 int flags = protocol.Element.makeFlags( | 499 int flags = protocol.Element.makeFlags( |
| 478 isAbstract: isAbstract, | 500 isAbstract: isAbstract, |
| 479 isDeprecated: isDeprecated, | 501 isDeprecated: isDeprecated, |
| 480 isPrivate: Identifier.isPrivateName(name)); | 502 isPrivate: Identifier.isPrivateName(name)); |
| 481 return new protocol.Element( | 503 return new protocol.Element( |
| 482 kind, | 504 kind, |
| 483 name, | 505 name, |
| 484 flags, | 506 flags, |
| 485 returnType: _nameForType(returnType)); | 507 returnType: _nameForType(returnType)); |
| 486 } | 508 } |
| 487 | 509 |
| 488 /** | 510 /** |
| 489 * Return `true` if the @deprecated annotation is present | 511 * Return `true` if the @deprecated annotation is present |
| 490 */ | 512 */ |
| 491 bool _isDeprecated(NodeList<Annotation> metadata) => | 513 bool _isDeprecated(NodeList<Annotation> metadata) => |
| 492 metadata != null && | 514 metadata != null && |
| 493 metadata.any( | 515 metadata.any( |
| 494 (Annotation a) => a.name is SimpleIdentifier && a.name.name == 'de
precated'); | 516 (Annotation a) => a.name is SimpleIdentifier && a.name.name == 'de
precated'); |
| 495 | 517 |
| 518 bool _isVoid(TypeName returnType) { |
| 519 if (returnType != null) { |
| 520 Identifier id = returnType.name; |
| 521 if (id != null && id.name == 'void') { |
| 522 return true; |
| 523 } |
| 524 } |
| 525 return false; |
| 526 } |
| 527 |
| 496 /** | 528 /** |
| 497 * Return the name for the given type. | 529 * Return the name for the given type. |
| 498 */ | 530 */ |
| 499 String _nameForType(TypeName type) { | 531 String _nameForType(TypeName type) { |
| 500 if (type == NO_RETURN_TYPE) { | 532 if (type == NO_RETURN_TYPE) { |
| 501 return null; | 533 return null; |
| 502 } | 534 } |
| 503 if (type == null) { | 535 if (type == null) { |
| 504 return DYNAMIC; | 536 return DYNAMIC; |
| 505 } | 537 } |
| 506 Identifier id = type.name; | 538 Identifier id = type.name; |
| 507 if (id == null) { | 539 if (id == null) { |
| 508 return DYNAMIC; | 540 return DYNAMIC; |
| 509 } | 541 } |
| 510 String name = id.name; | 542 String name = id.name; |
| 511 if (name == null || name.length <= 0) { | 543 if (name == null || name.length <= 0) { |
| 512 return DYNAMIC; | 544 return DYNAMIC; |
| 513 } | 545 } |
| 514 TypeArgumentList typeArgs = type.typeArguments; | 546 TypeArgumentList typeArgs = type.typeArguments; |
| 515 if (typeArgs != null) { | 547 if (typeArgs != null) { |
| 516 //TODO (danrubel) include type arguments | 548 //TODO (danrubel) include type arguments |
| 517 } | 549 } |
| 518 return name; | 550 return name; |
| 519 } | 551 } |
| 520 } | 552 } |
| OLD | NEW |