blob: 37a6872e1b42ccbe73b81c5eee31c4f725184487 [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 'dart:async';
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 [SearchResult]s for [element] references.
*/
Future<List<SearchResult>> compute(
Element element, bool withPotential) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
List<SearchResult> results = <SearchResult>[];
// Add element references.
results.addAll(await _findElementsReferences(element));
// Add potential references.
if (withPotential && _isMemberElement(element)) {
String name = element.displayName;
List<SearchMatch> matches =
await searchEngine.searchMemberReferences(name);
matches = SearchMatch.withNotNullElement(matches);
results.addAll(matches.where((match) => !match.isResolved).map(toResult));
}
return results;
}
/**
* Returns a [Future] completing with a [List] of references to [element] or
* to the corresponding hierarchy [Element]s.
*/
Future<List<SearchResult>> _findElementsReferences(Element element) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
List<SearchResult> allResults = <SearchResult>[];
Iterable<Element> refElements = await _getRefElements(element);
for (Element refElement in refElements) {
List<SearchResult> elementResults =
await _findSingleElementReferences(refElement);
allResults.addAll(elementResults);
}
return allResults;
}
/**
* Returns a [Future] completing with a [List] of references to [element].
*/
Future<List<SearchResult>> _findSingleElementReferences(
Element element) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
List<SearchMatch> matches = await searchEngine.searchReferences(element);
matches = SearchMatch.withNotNullElement(matches);
return matches.map(toResult).toList();
}
/**
* 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 new 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;
}
}