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 search.element_references; | 5 library search.element_references; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:analysis_server/src/collections.dart'; | |
10 import 'package:analysis_server/src/protocol_server.dart' | 9 import 'package:analysis_server/src/protocol_server.dart' |
11 show SearchResult, newSearchResult_fromMatch; | 10 show SearchResult, newSearchResult_fromMatch; |
12 import 'package:analysis_server/src/services/search/hierarchy.dart'; | 11 import 'package:analysis_server/src/services/search/hierarchy.dart'; |
13 import 'package:analysis_server/src/services/search/search_engine.dart'; | 12 import 'package:analysis_server/src/services/search/search_engine.dart'; |
14 import 'package:analyzer/dart/element/element.dart'; | 13 import 'package:analyzer/dart/element/element.dart'; |
15 import 'package:analyzer/src/generated/source.dart'; | 14 import 'package:analyzer/src/generated/source.dart'; |
16 | 15 |
17 /** | 16 /** |
18 * A computer for `search.findElementReferences` request results. | 17 * A computer for `search.findElementReferences` request results. |
19 */ | 18 */ |
20 class ElementReferencesComputer { | 19 class ElementReferencesComputer { |
21 final SearchEngine searchEngine; | 20 final SearchEngine searchEngine; |
22 | 21 |
23 ElementReferencesComputer(this.searchEngine); | 22 ElementReferencesComputer(this.searchEngine); |
24 | 23 |
25 /** | 24 /** |
26 * Computes [SearchResult]s for [element] references. | 25 * Computes [SearchResult]s for [element] references. |
27 */ | 26 */ |
28 Future<List<SearchResult>> compute(Element element, bool withPotential) { | 27 Future<List<SearchResult>> compute( |
29 var futureGroup = new _ConcatFutureGroup<SearchResult>(); | 28 Element element, bool withPotential) async { |
30 // find element references | 29 List<SearchResult> results = <SearchResult>[]; |
31 futureGroup.add(_findElementsReferences(element)); | 30 |
32 // add potential references | 31 // Add element references. |
| 32 results.addAll(await _findElementsReferences(element)); |
| 33 |
| 34 // Add potential references. |
33 if (withPotential && _isMemberElement(element)) { | 35 if (withPotential && _isMemberElement(element)) { |
34 String name = element.displayName; | 36 String name = element.displayName; |
35 var matchesFuture = searchEngine.searchMemberReferences(name); | 37 List<SearchMatch> matches = |
36 var resultsFuture = matchesFuture.then((List<SearchMatch> matches) { | 38 await searchEngine.searchMemberReferences(name); |
37 return matches.where((match) => !match.isResolved).map(toResult); | 39 matches = SearchMatch.withNotNullElement(matches); |
38 }); | 40 results.addAll(matches.where((match) => !match.isResolved).map(toResult)); |
39 futureGroup.add(resultsFuture); | |
40 } | 41 } |
41 // merge results | 42 |
42 return futureGroup.future; | 43 return results; |
43 } | 44 } |
44 | 45 |
45 /** | 46 /** |
46 * Returns a [Future] completing with a [List] of references to [element] or | 47 * Returns a [Future] completing with a [List] of references to [element] or |
47 * to the corresponding hierarchy [Element]s. | 48 * to the corresponding hierarchy [Element]s. |
48 */ | 49 */ |
49 Future<List<SearchResult>> _findElementsReferences(Element element) async { | 50 Future<List<SearchResult>> _findElementsReferences(Element element) async { |
| 51 List<SearchResult> allResults = <SearchResult>[]; |
50 Iterable<Element> refElements = await _getRefElements(element); | 52 Iterable<Element> refElements = await _getRefElements(element); |
51 var futureGroup = new _ConcatFutureGroup<SearchResult>(); | |
52 for (Element refElement in refElements) { | 53 for (Element refElement in refElements) { |
53 // add declaration | 54 // add declaration |
54 if (_isDeclarationInteresting(refElement)) { | 55 if (_isDeclarationInteresting(refElement)) { |
55 SearchResult searchResult = _newDeclarationResult(refElement); | 56 SearchResult searchResult = _newDeclarationResult(refElement); |
56 futureGroup.add(searchResult); | 57 allResults.add(searchResult); |
57 } | 58 } |
58 // do search | 59 // do search |
59 futureGroup.add(_findSingleElementReferences(refElement)); | 60 List<SearchResult> elementResults = |
| 61 await _findSingleElementReferences(refElement); |
| 62 allResults.addAll(elementResults); |
60 } | 63 } |
61 return futureGroup.future; | 64 return allResults; |
62 } | 65 } |
63 | 66 |
64 /** | 67 /** |
65 * Returns a [Future] completing with a [List] of references to [element]. | 68 * Returns a [Future] completing with a [List] of references to [element]. |
66 */ | 69 */ |
67 Future<List<SearchResult>> _findSingleElementReferences( | 70 Future<List<SearchResult>> _findSingleElementReferences( |
68 Element element) async { | 71 Element element) async { |
69 List<SearchMatch> matches = await searchEngine.searchReferences(element); | 72 List<SearchMatch> matches = await searchEngine.searchReferences(element); |
| 73 matches = SearchMatch.withNotNullElement(matches); |
70 return matches.map(toResult).toList(); | 74 return matches.map(toResult).toList(); |
71 } | 75 } |
72 | 76 |
73 /** | 77 /** |
74 * Returns a [Future] completing with [Element]s to search references to. | 78 * Returns a [Future] completing with [Element]s to search references to. |
75 * | 79 * |
76 * If a [ClassMemberElement] is given, each corresponding [Element] in the | 80 * If a [ClassMemberElement] is given, each corresponding [Element] in the |
77 * hierarchy is returned. | 81 * hierarchy is returned. |
78 * | 82 * |
79 * Otherwise, only references to [element] should be searched. | 83 * Otherwise, only references to [element] should be searched. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 return false; | 126 return false; |
123 } | 127 } |
124 | 128 |
125 static bool _isMemberElement(Element element) { | 129 static bool _isMemberElement(Element element) { |
126 if (element is ConstructorElement) { | 130 if (element is ConstructorElement) { |
127 return false; | 131 return false; |
128 } | 132 } |
129 return element.enclosingElement is ClassElement; | 133 return element.enclosingElement is ClassElement; |
130 } | 134 } |
131 } | 135 } |
132 | |
133 /** | |
134 * A collection of [Future]s that concats [List] results of added [Future]s into | |
135 * a single [List]. | |
136 */ | |
137 class _ConcatFutureGroup<E> { | |
138 final List<Future<List<E>>> _futures = <Future<List<E>>>[]; | |
139 | |
140 Future<List<E>> get future { | |
141 return Future.wait(_futures).then(concatToList); | |
142 } | |
143 | |
144 /** | |
145 * Adds a [Future] or an [E] value to results. | |
146 */ | |
147 void add(value) { | |
148 if (value is Future) { | |
149 _futures.add(value as Future<List<E>>); | |
150 } else { | |
151 _futures.add(new Future.value(<E>[value as E])); | |
152 } | |
153 } | |
154 } | |
OLD | NEW |