blob: ba332d92ae3002f0f55e9a9b1b292ed3f8dcc3bc [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;
/// Computes [SearchResult]s for [element] references.
Future<List<SearchResult>> compute(
Element element, bool withPotential) async {
var results = <SearchResult>[];
// 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);
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 {
var allResults = <SearchResult>[];
var refElements = await _getRefElements(element);
for (var refElement in refElements) {
var elementResults = await _findSingleElementReferences(refElement);
return allResults;
/// Returns a [Future] completing with a [List] of references to [element].
Future<List<SearchResult>> _findSingleElementReferences(
Element element) async {
var matches = await searchEngine.searchReferences(element);
matches = SearchMatch.withNotNullElement(matches);
/// 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;