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.contributor.dart.local; | 5 library services.completion.contributor.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/local_suggestion_builder
.dart'; | 14 import 'package:analysis_server/src/services/completion/local_suggestion_builder
.dart'; |
15 import 'package:analysis_server/src/services/completion/optype.dart'; | 15 import 'package:analysis_server/src/services/completion/optype.dart'; |
16 import 'package:analyzer/src/generated/ast.dart'; | 16 import 'package:analyzer/src/generated/ast.dart'; |
17 import 'package:analyzer/src/generated/source.dart'; | |
18 import 'package:analyzer/src/generated/utilities_dart.dart'; | 17 import 'package:analyzer/src/generated/utilities_dart.dart'; |
19 | 18 |
20 /** | 19 /** |
21 * A contributor for calculating `completion.getSuggestions` request results | 20 * A contributor for calculating `completion.getSuggestions` request results |
22 * for the local library in which the completion is requested. | 21 * for the local library in which the completion is requested. |
23 */ | 22 */ |
24 class LocalReferenceContributor extends DartCompletionContributor { | 23 class LocalReferenceContributor extends DartCompletionContributor { |
25 @override | 24 @override |
26 bool computeFast(DartCompletionRequest request) { | 25 bool computeFast(DartCompletionRequest request) { |
27 OpType optype = request.optype; | 26 OpType optype = request.optype; |
28 | 27 |
29 // Collect suggestions from the specific child [AstNode] that contains | 28 // Collect suggestions from the specific child [AstNode] that contains |
30 // the completion offset and all of its parents recursively. | 29 // the completion offset and all of its parents recursively. |
31 if (!optype.isPrefixed) { | 30 if (!optype.isPrefixed) { |
32 if (optype.includeReturnValueSuggestions || | 31 if (optype.includeReturnValueSuggestions || |
33 optype.includeTypeNameSuggestions || | 32 optype.includeTypeNameSuggestions || |
34 optype.includeVoidReturnSuggestions) { | 33 optype.includeVoidReturnSuggestions) { |
35 _LocalVisitor localVisitor = | 34 _LocalVisitor localVisitor = |
36 new _LocalVisitor(request, request.offset, optype); | 35 new _LocalVisitor(request, request.offset, optype); |
37 localVisitor.visit(request.target.containingNode); | 36 localVisitor.visit(request.target.containingNode); |
38 } | 37 } |
39 if (optype.includeStatementLabelSuggestions || | 38 if (optype.includeStatementLabelSuggestions || |
40 optype.includeCaseLabelSuggestions) { | 39 optype.includeCaseLabelSuggestions) { |
41 _LabelVisitor labelVisitor = new _LabelVisitor(request, | 40 _LabelVisitor labelVisitor = new _LabelVisitor( |
| 41 request, |
42 optype.includeStatementLabelSuggestions, | 42 optype.includeStatementLabelSuggestions, |
43 optype.includeCaseLabelSuggestions); | 43 optype.includeCaseLabelSuggestions); |
44 labelVisitor.visit(request.target.containingNode); | 44 labelVisitor.visit(request.target.containingNode); |
45 } | 45 } |
46 if (optype.includeConstructorSuggestions) { | 46 if (optype.includeConstructorSuggestions) { |
47 new _ConstructorVisitor(request).visit(request.target.containingNode); | 47 new _ConstructorVisitor(request).visit(request.target.containingNode); |
48 } | 48 } |
49 } | 49 } |
50 | 50 |
51 // If target is an argument in an argument list | 51 // If target is an argument in an argument list |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 if (paramCount > requiredParameterCount) { | 181 if (paramCount > requiredParameterCount) { |
182 paramBuf.write(hasNamedParameters ? '}' : ']'); | 182 paramBuf.write(hasNamedParameters ? '}' : ']'); |
183 } | 183 } |
184 paramBuf.write(')'); | 184 paramBuf.write(')'); |
185 protocol.Element element = createElement( | 185 protocol.Element element = createElement( |
186 request.source, protocol.ElementKind.CONSTRUCTOR, elemId, | 186 request.source, protocol.ElementKind.CONSTRUCTOR, elemId, |
187 parameters: paramBuf.toString()); | 187 parameters: paramBuf.toString()); |
188 element.returnType = classDecl.name.name; | 188 element.returnType = classDecl.name.name; |
189 CompletionSuggestion suggestion = new CompletionSuggestion( | 189 CompletionSuggestion suggestion = new CompletionSuggestion( |
190 CompletionSuggestionKind.INVOCATION, | 190 CompletionSuggestionKind.INVOCATION, |
191 deprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT, completion, | 191 deprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT, |
192 completion.length, 0, deprecated, false, | 192 completion, |
| 193 completion.length, |
| 194 0, |
| 195 deprecated, |
| 196 false, |
193 declaringType: classDecl.name.name, | 197 declaringType: classDecl.name.name, |
194 element: element, | 198 element: element, |
195 parameterNames: parameterNames, | 199 parameterNames: parameterNames, |
196 parameterTypes: parameterTypes, | 200 parameterTypes: parameterTypes, |
197 requiredParameterCount: requiredParameterCount, | 201 requiredParameterCount: requiredParameterCount, |
198 hasNamedParameters: hasNamedParameters); | 202 hasNamedParameters: hasNamedParameters); |
199 request.addSuggestion(suggestion); | 203 request.addSuggestion(suggestion); |
200 return suggestion; | 204 return suggestion; |
201 } | 205 } |
202 | 206 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 // Labels are only accessible within the local function, so stop visiting | 322 // Labels are only accessible within the local function, so stop visiting |
319 // once we reach a function boundary. | 323 // once we reach a function boundary. |
320 finished(); | 324 finished(); |
321 } | 325 } |
322 | 326 |
323 CompletionSuggestion _addSuggestion(SimpleIdentifier id) { | 327 CompletionSuggestion _addSuggestion(SimpleIdentifier id) { |
324 if (id != null) { | 328 if (id != null) { |
325 String completion = id.name; | 329 String completion = id.name; |
326 if (completion != null && completion.length > 0 && completion != '_') { | 330 if (completion != null && completion.length > 0 && completion != '_') { |
327 CompletionSuggestion suggestion = new CompletionSuggestion( | 331 CompletionSuggestion suggestion = new CompletionSuggestion( |
328 CompletionSuggestionKind.IDENTIFIER, DART_RELEVANCE_DEFAULT, | 332 CompletionSuggestionKind.IDENTIFIER, |
329 completion, completion.length, 0, false, false); | 333 DART_RELEVANCE_DEFAULT, |
| 334 completion, |
| 335 completion.length, |
| 336 0, |
| 337 false, |
| 338 false); |
330 request.addSuggestion(suggestion); | 339 request.addSuggestion(suggestion); |
331 return suggestion; | 340 return suggestion; |
332 } | 341 } |
333 } | 342 } |
334 return null; | 343 return null; |
335 } | 344 } |
336 } | 345 } |
337 | 346 |
338 /** | 347 /** |
339 * A visitor for collecting suggestions from the most specific child [AstNode] | 348 * A visitor for collecting suggestions from the most specific child [AstNode] |
340 * that contains the completion offset to the [CompilationUnit]. | 349 * that contains the completion offset to the [CompilationUnit]. |
341 */ | 350 */ |
342 class _LocalVisitor extends LocalDeclarationVisitor { | 351 class _LocalVisitor extends LocalDeclarationVisitor { |
343 final DartCompletionRequest request; | 352 final DartCompletionRequest request; |
344 final OpType optype; | 353 final OpType optype; |
345 | 354 |
346 _LocalVisitor(this.request, int offset, this.optype) : super(offset); | 355 _LocalVisitor(this.request, int offset, this.optype) : super(offset) { |
| 356 includeLocalInheritedTypes = !optype.inStaticMethodBody; |
| 357 } |
347 | 358 |
348 @override | 359 @override |
349 void declaredClass(ClassDeclaration declaration) { | 360 void declaredClass(ClassDeclaration declaration) { |
350 if (optype.includeTypeNameSuggestions) { | 361 if (optype.includeTypeNameSuggestions) { |
351 _addSuggestion( | 362 _addSuggestion( |
352 declaration.name, NO_RETURN_TYPE, protocol.ElementKind.CLASS, | 363 declaration.name, NO_RETURN_TYPE, protocol.ElementKind.CLASS, |
353 isAbstract: declaration.isAbstract, | 364 isAbstract: declaration.isAbstract, |
354 isDeprecated: isDeprecated(declaration)); | 365 isDeprecated: isDeprecated(declaration)); |
355 } | 366 } |
356 } | 367 } |
(...skipping 11 matching lines...) Expand all Loading... |
368 void declaredEnum(EnumDeclaration declaration) { | 379 void declaredEnum(EnumDeclaration declaration) { |
369 if (optype.includeTypeNameSuggestions) { | 380 if (optype.includeTypeNameSuggestions) { |
370 _addSuggestion( | 381 _addSuggestion( |
371 declaration.name, NO_RETURN_TYPE, protocol.ElementKind.ENUM, | 382 declaration.name, NO_RETURN_TYPE, protocol.ElementKind.ENUM, |
372 isDeprecated: isDeprecated(declaration)); | 383 isDeprecated: isDeprecated(declaration)); |
373 } | 384 } |
374 } | 385 } |
375 | 386 |
376 @override | 387 @override |
377 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) { | 388 void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) { |
378 if (optype.includeReturnValueSuggestions) { | 389 if (optype.includeReturnValueSuggestions && |
| 390 (!optype.inStaticMethodBody || fieldDecl.isStatic)) { |
379 CompletionSuggestion suggestion = | 391 CompletionSuggestion suggestion = |
380 createFieldSuggestion(request.source, fieldDecl, varDecl); | 392 createFieldSuggestion(request.source, fieldDecl, varDecl); |
381 if (suggestion != null) { | 393 if (suggestion != null) { |
382 request.addSuggestion(suggestion); | 394 request.addSuggestion(suggestion); |
383 } | 395 } |
384 } | 396 } |
385 } | 397 } |
386 | 398 |
387 @override | 399 @override |
388 void declaredFunction(FunctionDeclaration declaration) { | 400 void declaredFunction(FunctionDeclaration declaration) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 @override | 445 @override |
434 void declaredLocalVar(SimpleIdentifier id, TypeName typeName) { | 446 void declaredLocalVar(SimpleIdentifier id, TypeName typeName) { |
435 if (optype.includeReturnValueSuggestions) { | 447 if (optype.includeReturnValueSuggestions) { |
436 _addSuggestion(id, typeName, protocol.ElementKind.LOCAL_VARIABLE, | 448 _addSuggestion(id, typeName, protocol.ElementKind.LOCAL_VARIABLE, |
437 relevance: DART_RELEVANCE_LOCAL_VARIABLE); | 449 relevance: DART_RELEVANCE_LOCAL_VARIABLE); |
438 } | 450 } |
439 } | 451 } |
440 | 452 |
441 @override | 453 @override |
442 void declaredMethod(MethodDeclaration declaration) { | 454 void declaredMethod(MethodDeclaration declaration) { |
443 if (optype.includeReturnValueSuggestions || | 455 if ((optype.includeReturnValueSuggestions || |
444 optype.includeVoidReturnSuggestions) { | 456 optype.includeVoidReturnSuggestions) && |
| 457 (!optype.inStaticMethodBody || declaration.isStatic)) { |
445 protocol.ElementKind elemKind; | 458 protocol.ElementKind elemKind; |
446 FormalParameterList param; | 459 FormalParameterList param; |
447 TypeName typeName = declaration.returnType; | 460 TypeName typeName = declaration.returnType; |
448 int relevance = DART_RELEVANCE_DEFAULT; | 461 int relevance = DART_RELEVANCE_DEFAULT; |
449 if (declaration.isGetter) { | 462 if (declaration.isGetter) { |
450 elemKind = protocol.ElementKind.GETTER; | 463 elemKind = protocol.ElementKind.GETTER; |
451 param = null; | 464 param = null; |
452 relevance = DART_RELEVANCE_LOCAL_ACCESSOR; | 465 relevance = DART_RELEVANCE_LOCAL_ACCESSOR; |
453 } else if (declaration.isSetter) { | 466 } else if (declaration.isSetter) { |
454 if (!optype.includeVoidReturnSuggestions) { | 467 if (!optype.includeVoidReturnSuggestions) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 } | 529 } |
517 if (type == null) { | 530 if (type == null) { |
518 return 'dynamic'; | 531 return 'dynamic'; |
519 } | 532 } |
520 Identifier typeId = type.name; | 533 Identifier typeId = type.name; |
521 if (typeId == null) { | 534 if (typeId == null) { |
522 return 'dynamic'; | 535 return 'dynamic'; |
523 } | 536 } |
524 return typeId.name; | 537 return typeId.name; |
525 }).toList(); | 538 }).toList(); |
526 suggestion.requiredParameterCount = paramList.where( | 539 suggestion.requiredParameterCount = paramList |
527 (FormalParameter param) => param is! DefaultFormalParameter).length; | 540 .where((FormalParameter param) => param is! DefaultFormalParameter) |
| 541 .length; |
528 suggestion.hasNamedParameters = paramList | 542 suggestion.hasNamedParameters = paramList |
529 .any((FormalParameter param) => param.kind == ParameterKind.NAMED); | 543 .any((FormalParameter param) => param.kind == ParameterKind.NAMED); |
530 } | 544 } |
531 | 545 |
532 void _addSuggestion( | 546 void _addSuggestion( |
533 SimpleIdentifier id, TypeName typeName, protocol.ElementKind elemKind, | 547 SimpleIdentifier id, TypeName typeName, protocol.ElementKind elemKind, |
534 {bool isAbstract: false, bool isDeprecated: false, | 548 {bool isAbstract: false, |
535 ClassDeclaration classDecl, FormalParameterList param, | 549 bool isDeprecated: false, |
| 550 ClassDeclaration classDecl, |
| 551 FormalParameterList param, |
536 int relevance: DART_RELEVANCE_DEFAULT}) { | 552 int relevance: DART_RELEVANCE_DEFAULT}) { |
537 CompletionSuggestion suggestion = createSuggestion( | 553 CompletionSuggestion suggestion = createSuggestion( |
538 id, isDeprecated, relevance, typeName, classDecl: classDecl); | 554 id, isDeprecated, relevance, typeName, |
| 555 classDecl: classDecl); |
539 if (suggestion != null) { | 556 if (suggestion != null) { |
540 request.addSuggestion(suggestion); | 557 request.addSuggestion(suggestion); |
541 suggestion.element = createElement(request.source, elemKind, id, | 558 suggestion.element = createElement(request.source, elemKind, id, |
542 isAbstract: isAbstract, | 559 isAbstract: isAbstract, |
543 isDeprecated: isDeprecated, | 560 isDeprecated: isDeprecated, |
544 parameters: param != null ? param.toSource() : null, | 561 parameters: param != null ? param.toSource() : null, |
545 returnType: typeName); | 562 returnType: typeName); |
546 if ((elemKind == protocol.ElementKind.METHOD || | 563 if ((elemKind == protocol.ElementKind.METHOD || |
547 elemKind == protocol.ElementKind.FUNCTION) && | 564 elemKind == protocol.ElementKind.FUNCTION) && |
548 param != null) { | 565 param != null) { |
549 _addParameterInfo(suggestion, param); | 566 _addParameterInfo(suggestion, param); |
550 } | 567 } |
551 } | 568 } |
552 } | 569 } |
553 | 570 |
554 bool _isVoid(TypeName returnType) { | 571 bool _isVoid(TypeName returnType) { |
555 if (returnType != null) { | 572 if (returnType != null) { |
556 Identifier id = returnType.name; | 573 Identifier id = returnType.name; |
557 if (id != null && id.name == 'void') { | 574 if (id != null && id.name == 'void') { |
558 return true; | 575 return true; |
559 } | 576 } |
560 } | 577 } |
561 return false; | 578 return false; |
562 } | 579 } |
563 } | 580 } |
OLD | NEW |