blob: afccf671fbaa50d6553e61a94d491fcda19a29b5 [file] [log] [blame]
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/protocol_server.dart'
show SearchResult, newSearchResult_fromMatch;
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/dart/element/element.dart';
/// A computer for `search.findElementReferences` request results.
class ElementReferencesComputer {
final SearchEngine searchEngine;
ElementReferencesComputer(this.searchEngine);
/// Computes [SearchMatch]es for [element] references.
Future<List<SearchMatch>> compute(Element element, bool withPotential) async {
var results = <SearchMatch>[];
// Add element references.
results.addAll(await _findElementsReferences(element));
// Add potential references.
if (withPotential && _isMemberElement(element)) {
var name = element.displayName;
var matches = await searchEngine.searchMemberReferences(name);
results.addAll(matches.where((match) => !match.isResolved));
}
return results;
}
/// Returns a [Future] completing with a [List] of references to [element] or
/// to the corresponding hierarchy [Element]s.
Future<List<SearchMatch>> _findElementsReferences(Element element) async {
var allResults = <SearchMatch>[];
var refElements = await _getRefElements(element);
for (var refElement in refElements) {
var elementResults = await _findSingleElementReferences(refElement);
allResults.addAll(elementResults);
}
return allResults;
}
/// Returns a [Future] completing with a [List] of references to [element].
Future<List<SearchMatch>> _findSingleElementReferences(
Element element) async {
return searchEngine.searchReferences(element);
}
/// Returns a [Future] completing with [Element]s to search references to.
///
/// If a [ClassMemberElement] or a named [ParameterElement] is given, each
/// corresponding [Element] in the hierarchy is returned.
///
/// Otherwise, only references to [element] should be searched.
Future<Iterable<Element>> _getRefElements(Element element) {
if (element is ParameterElement && element.isNamed) {
return getHierarchyNamedParameters(searchEngine, element);
}
if (element is ClassMemberElement) {
return getHierarchyMembers(searchEngine, element);
}
return Future.value([element]);
}
static SearchResult toResult(SearchMatch match) {
return newSearchResult_fromMatch(match);
}
static bool _isMemberElement(Element element) {
if (element is ConstructorElement) {
return false;
}
return element.enclosingElement is ClassElement;
}
}