| 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 |