OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:collection'; | 6 import 'dart:collection'; |
7 | 7 |
8 import 'package:analyzer/dart/ast/ast.dart'; | 8 import 'package:analyzer/dart/ast/ast.dart'; |
9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
11 import 'package:analyzer/file_system/file_system.dart'; | 11 import 'package:analyzer/file_system/file_system.dart'; |
12 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; | 12 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; |
13 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart'
; | 13 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart'
; |
14 import 'package:analyzer_plugin/src/utilities/completion/suggestion_builder.dart
'; | 14 import 'package:analyzer_plugin/src/utilities/completion/suggestion_builder.dart
'; |
15 import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor
.dart'; | 15 import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor
.dart'; |
16 import 'package:analyzer_plugin/utilities/completion/completion_core.dart'; | 16 import 'package:analyzer_plugin/utilities/completion/completion_core.dart'; |
17 import 'package:analyzer_plugin/utilities/completion/relevance.dart'; | 17 import 'package:analyzer_plugin/utilities/completion/relevance.dart'; |
18 import 'package:analyzer_plugin/utilities/completion/suggestion_builder.dart'; | 18 import 'package:analyzer_plugin/utilities/completion/suggestion_builder.dart'; |
19 | 19 |
20 /** | 20 /** |
21 * A completion contributor that will generate suggestions for instance | 21 * A completion contributor that will generate suggestions for instance |
22 * invocations and accesses. | 22 * invocations and accesses. |
23 */ | 23 */ |
24 class TypeMemberContributor implements CompletionContributor { | 24 class TypeMemberContributor implements CompletionContributor { |
| 25 /** |
| 26 * Clients should not overload this function. |
| 27 */ |
| 28 Future<Null> computeSuggestionsWithEntryPoint(CompletionRequest request, |
| 29 CompletionCollector collector, AstNode entryPoint) async { |
| 30 LibraryElement containingLibrary = request.result.libraryElement; |
| 31 // Gracefully degrade if the library element is not resolved |
| 32 // e.g. detached part file or source change |
| 33 if (containingLibrary == null) { |
| 34 return; |
| 35 } |
| 36 |
| 37 // Recompute the target since resolution may have changed it |
| 38 Expression expression = _computeDotTarget(request, entryPoint); |
| 39 if (expression == null || expression.isSynthetic) { |
| 40 return; |
| 41 } |
| 42 _computeSuggestions(request, collector, containingLibrary, expression); |
| 43 } |
| 44 |
| 45 /** |
| 46 * Plugin contributors should primarily overload this function. |
| 47 * Should more parameters be needed for autocompletion needs, the |
| 48 * overloaded function should define those parameters and |
| 49 * call on `computeSuggestionsWithEntryPoint`. |
| 50 */ |
25 @override | 51 @override |
26 Future<Null> computeSuggestions( | 52 Future<Null> computeSuggestions( |
27 CompletionRequest request, CompletionCollector collector) async { | 53 CompletionRequest request, CompletionCollector collector) async { |
28 LibraryElement containingLibrary = request.result.libraryElement; | 54 LibraryElement containingLibrary = request.result.libraryElement; |
29 // Gracefully degrade if the library element is not resolved | 55 // Gracefully degrade if the library element is not resolved |
30 // e.g. detached part file or source change | 56 // e.g. detached part file or source change |
31 if (containingLibrary == null) { | 57 if (containingLibrary == null) { |
32 return; | 58 return; |
33 } | 59 } |
34 | 60 |
35 // Recompute the target since resolution may have changed it | 61 // Recompute the target since resolution may have changed it |
36 Expression expression = _computeDotTarget(request); | 62 Expression expression = _computeDotTarget(request, null); |
37 if (expression == null || expression.isSynthetic) { | 63 if (expression == null || expression.isSynthetic) { |
38 return; | 64 return; |
39 } | 65 } |
| 66 _computeSuggestions(request, collector, containingLibrary, expression); |
| 67 } |
| 68 |
| 69 void _computeSuggestions( |
| 70 CompletionRequest request, |
| 71 CompletionCollector collector, |
| 72 LibraryElement containingLibrary, |
| 73 Expression expression) { |
40 if (expression is Identifier) { | 74 if (expression is Identifier) { |
41 Element element = expression.bestElement; | 75 Element element = expression.bestElement; |
42 if (element is ClassElement) { | 76 if (element is ClassElement) { |
43 // Suggestions provided by StaticMemberContributor | 77 // Suggestions provided by StaticMemberContributor |
44 return; | 78 return; |
45 } | 79 } |
46 if (element is PrefixElement) { | 80 if (element is PrefixElement) { |
47 // Suggestions provided by LibraryMemberContributor | 81 // Suggestions provided by LibraryMemberContributor |
48 return; | 82 return; |
49 } | 83 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 if (type is InterfaceType) { | 133 if (type is InterfaceType) { |
100 _SuggestionBuilder builder = new _SuggestionBuilder( | 134 _SuggestionBuilder builder = new _SuggestionBuilder( |
101 request.resourceProvider, collector, containingLibrary); | 135 request.resourceProvider, collector, containingLibrary); |
102 builder.buildSuggestions(type, containingMethodName); | 136 builder.buildSuggestions(type, containingMethodName); |
103 } | 137 } |
104 } | 138 } |
105 | 139 |
106 /** | 140 /** |
107 * Update the completion [target] and [dotTarget] based on the given [unit]. | 141 * Update the completion [target] and [dotTarget] based on the given [unit]. |
108 */ | 142 */ |
109 Expression _computeDotTarget(CompletionRequest request) { | 143 Expression _computeDotTarget(CompletionRequest request, AstNode entryPoint) { |
110 CompletionTarget target = | 144 CompletionTarget target = new CompletionTarget.forOffset( |
111 new CompletionTarget.forOffset(request.result.unit, request.offset); | 145 request.result.unit, request.offset, |
| 146 entryPoint: entryPoint); |
112 AstNode node = target.containingNode; | 147 AstNode node = target.containingNode; |
113 if (node is MethodInvocation) { | 148 if (node is MethodInvocation) { |
114 if (identical(node.methodName, target.entity)) { | 149 if (identical(node.methodName, target.entity)) { |
115 return node.realTarget; | 150 return node.realTarget; |
116 } else if (node.isCascaded && node.operator.offset + 1 == target.offset) { | 151 } else if (node.isCascaded && node.operator.offset + 1 == target.offset) { |
117 return node.realTarget; | 152 return node.realTarget; |
118 } | 153 } |
119 } | 154 } |
120 if (node is PropertyAccess) { | 155 if (node is PropertyAccess) { |
121 if (identical(node.propertyName, target.entity)) { | 156 if (identical(node.propertyName, target.entity)) { |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 // in the reverse order. | 489 // in the reverse order. |
455 typesToVisit.addAll(nextType.interfaces); | 490 typesToVisit.addAll(nextType.interfaces); |
456 if (nextType.superclass != null) { | 491 if (nextType.superclass != null) { |
457 typesToVisit.add(nextType.superclass); | 492 typesToVisit.add(nextType.superclass); |
458 } | 493 } |
459 typesToVisit.addAll(nextType.mixins); | 494 typesToVisit.addAll(nextType.mixins); |
460 } | 495 } |
461 return result; | 496 return result; |
462 } | 497 } |
463 } | 498 } |
OLD | NEW |