blob: def5e32cce804b7b9217e304c4bee443609bec2a [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.
// This code was auto-generated, is not intended to be edited, and is subject to
// significant change. Please see the README file for more information.
library services.src.search.search_engine;
import 'dart:async';
import 'package:analysis_services/index/index.dart';
import 'package:analysis_services/search/search_engine.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/source.dart';
/**
* A [SearchEngine] implementation.
*/
class SearchEngineImpl implements SearchEngine {
final Index _index;
SearchEngineImpl(this._index);
@override
Future<List<SearchMatch>> searchMemberDeclarations(String name) {
NameElement element = new NameElement(name);
_Requestor requestor = new _Requestor(_index);
requestor.add(
element,
IndexConstants.IS_DEFINED_BY,
MatchKind.NAME_DECLARATION);
return requestor.merge().then((matches) {
return matches.where((match) {
return match.element.enclosingElement is ClassElement;
}).toList();
});
}
@override
Future<List<SearchMatch>> searchMemberReferences(String name) {
NameElement element = new NameElement(name);
_Requestor requestor = new _Requestor(_index);
// rought
// requestor.add(
// element,
// IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
// MatchKind.NAME_REFERENCE_RESOLVED);
// requestor.add(
// element,
// IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
// MatchKind.NAME_REFERENCE_UNRESOLVED,
// isResolved: false);
// granular resolved operations
requestor.add(
element,
IndexConstants.NAME_IS_INVOKED_BY_RESOLVED,
MatchKind.NAME_INVOCATION_RESOLVED);
requestor.add(
element,
IndexConstants.NAME_IS_READ_BY_RESOLVED,
MatchKind.NAME_READ_RESOLVED);
requestor.add(
element,
IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED,
MatchKind.NAME_READ_WRITE_RESOLVED);
requestor.add(
element,
IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED,
MatchKind.NAME_WRITE_RESOLVED);
// granular unresolved operations
requestor.add(
element,
IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED,
MatchKind.NAME_INVOCATION_UNRESOLVED,
isResolved: false);
requestor.add(
element,
IndexConstants.NAME_IS_READ_BY_UNRESOLVED,
MatchKind.NAME_READ_UNRESOLVED,
isResolved: false);
requestor.add(
element,
IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED,
MatchKind.NAME_READ_WRITE_UNRESOLVED,
isResolved: false);
requestor.add(
element,
IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED,
MatchKind.NAME_WRITE_UNRESOLVED,
isResolved: false);
// done
return requestor.merge();
}
@override
Future<List<SearchMatch>> searchReferences(Element element) {
if (element.kind == ElementKind.ANGULAR_COMPONENT ||
element.kind == ElementKind.ANGULAR_CONTROLLER ||
element.kind == ElementKind.ANGULAR_FORMATTER ||
element.kind == ElementKind.ANGULAR_PROPERTY ||
element.kind == ElementKind.ANGULAR_SCOPE_PROPERTY ||
element.kind == ElementKind.ANGULAR_SELECTOR) {
return _searchReferences_Angular(element as AngularElement);
} else if (element.kind == ElementKind.CLASS) {
return _searchReferences_Class(element as ClassElement);
} else if (element.kind == ElementKind.COMPILATION_UNIT) {
return _searchReferences_CompilationUnit(
element as CompilationUnitElement);
} else if (element.kind == ElementKind.CONSTRUCTOR) {
return _searchReferences_Constructor(element as ConstructorElement);
} else if (element.kind == ElementKind.FIELD ||
element.kind == ElementKind.TOP_LEVEL_VARIABLE) {
return _searchReferences_Field(element as PropertyInducingElement);
} else if (element.kind == ElementKind.FUNCTION) {
return _searchReferences_Function(element as FunctionElement);
} else if (element.kind == ElementKind.GETTER ||
element.kind == ElementKind.SETTER) {
return _searchReferences_PropertyAccessor(
element as PropertyAccessorElement);
} else if (element.kind == ElementKind.IMPORT) {
return _searchReferences_Import(element as ImportElement);
} else if (element.kind == ElementKind.LIBRARY) {
return _searchReferences_Library(element as LibraryElement);
} else if (element.kind == ElementKind.LOCAL_VARIABLE) {
return _searchReferences_LocalVariable(element as LocalVariableElement);
} else if (element.kind == ElementKind.METHOD) {
return _searchReferences_Method(element as MethodElement);
} else if (element.kind == ElementKind.PARAMETER) {
return _searchReferences_Parameter(element as ParameterElement);
} else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) {
return _searchReferences_FunctionTypeAlias(
element as FunctionTypeAliasElement);
} else if (element.kind == ElementKind.TYPE_PARAMETER) {
return _searchReferences_TypeParameter(element as TypeParameterElement);
}
return new Future.value(<SearchMatch>[]);
}
@override
Future<List<SearchMatch>> searchSubtypes(ClassElement type) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
type,
IndexConstants.IS_EXTENDED_BY,
MatchKind.EXTENDS_REFERENCE);
requestor.add(
type,
IndexConstants.IS_MIXED_IN_BY,
MatchKind.WITH_REFERENCE);
requestor.add(
type,
IndexConstants.IS_IMPLEMENTED_BY,
MatchKind.IMPLEMENTS_REFERENCE);
return requestor.merge();
}
@override
Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) {
UniverseElement universe = UniverseElement.INSTANCE;
_Requestor requestor = new _Requestor(_index);
requestor.add(
universe,
IndexConstants.DEFINES_CLASS,
MatchKind.CLASS_DECLARATION);
requestor.add(
universe,
IndexConstants.DEFINES_CLASS_ALIAS,
MatchKind.CLASS_ALIAS_DECLARATION);
requestor.add(
universe,
IndexConstants.DEFINES_FUNCTION_TYPE,
MatchKind.FUNCTION_TYPE_DECLARATION);
requestor.add(
universe,
IndexConstants.DEFINES_FUNCTION,
MatchKind.FUNCTION_DECLARATION);
requestor.add(
universe,
IndexConstants.DEFINES_VARIABLE,
MatchKind.VARIABLE_DECLARATION);
RegExp regExp = new RegExp(pattern);
return requestor.merge().then((List<SearchMatch> matches) {
return matches.where((SearchMatch match) {
String name = match.element.displayName;
return regExp.hasMatch(name);
}).toList();
});
}
Future<List<SearchMatch>> _searchReferences_Angular(AngularElement element) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
element,
IndexConstants.ANGULAR_REFERENCE,
MatchKind.ANGULAR_REFERENCE);
requestor.add(
element,
IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE,
MatchKind.ANGULAR_CLOSING_TAG_REFERENCE);
return requestor.merge();
}
Future<List<SearchMatch>> _searchReferences_Class(ClassElement clazz) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
clazz,
IndexConstants.IS_REFERENCED_BY,
MatchKind.TYPE_REFERENCE);
return requestor.merge();
}
Future<List<SearchMatch>>
_searchReferences_CompilationUnit(CompilationUnitElement unit) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
unit,
IndexConstants.IS_REFERENCED_BY,
MatchKind.UNIT_REFERENCE);
return requestor.merge();
}
Future<List<SearchMatch>>
_searchReferences_Constructor(ConstructorElement constructor) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
constructor,
IndexConstants.IS_DEFINED_BY,
MatchKind.CONSTRUCTOR_DECLARATION);
requestor.add(
constructor,
IndexConstants.IS_REFERENCED_BY,
MatchKind.CONSTRUCTOR_REFERENCE);
return requestor.merge();
}
Future<List<SearchMatch>>
_searchReferences_Field(PropertyInducingElement field) {
PropertyAccessorElement getter = field.getter;
PropertyAccessorElement setter = field.setter;
_Requestor requestor = new _Requestor(_index);
// field itself
requestor.add(
field,
IndexConstants.IS_REFERENCED_BY,
MatchKind.FIELD_REFERENCE);
requestor.add(
field,
IndexConstants.IS_REFERENCED_BY_QUALIFIED,
MatchKind.FIELD_REFERENCE);
// getter
if (getter != null) {
requestor.add(
getter,
IndexConstants.IS_REFERENCED_BY_QUALIFIED,
MatchKind.FIELD_READ);
requestor.add(
getter,
IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
MatchKind.FIELD_READ);
requestor.add(
getter,
IndexConstants.IS_INVOKED_BY_QUALIFIED,
MatchKind.FIELD_INVOCATION);
requestor.add(
getter,
IndexConstants.IS_INVOKED_BY_UNQUALIFIED,
MatchKind.FIELD_INVOCATION);
}
// setter
if (setter != null) {
requestor.add(
setter,
IndexConstants.IS_REFERENCED_BY_QUALIFIED,
MatchKind.FIELD_WRITE);
requestor.add(
setter,
IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
MatchKind.FIELD_WRITE);
}
// done
return requestor.merge();
}
Future<List<SearchMatch>>
_searchReferences_Function(FunctionElement function) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
function,
IndexConstants.IS_REFERENCED_BY,
MatchKind.FUNCTION_REFERENCE);
requestor.add(
function,
IndexConstants.IS_INVOKED_BY,
MatchKind.FUNCTION_EXECUTION);
return requestor.merge();
}
Future<List<SearchMatch>>
_searchReferences_FunctionTypeAlias(FunctionTypeAliasElement alias) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
alias,
IndexConstants.IS_REFERENCED_BY,
MatchKind.FUNCTION_TYPE_REFERENCE);
return requestor.merge();
}
Future<List<SearchMatch>> _searchReferences_Import(ImportElement imp) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
imp,
IndexConstants.IS_REFERENCED_BY,
MatchKind.IMPORT_REFERENCE);
return requestor.merge();
}
Future<List<SearchMatch>> _searchReferences_Library(LibraryElement library) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
library,
IndexConstants.IS_REFERENCED_BY,
MatchKind.LIBRARY_REFERENCE);
return requestor.merge();
}
Future<List<SearchMatch>>
_searchReferences_LocalVariable(LocalVariableElement variable) {
_Requestor requestor = new _Requestor(_index);
requestor.add(variable, IndexConstants.IS_READ_BY, MatchKind.VARIABLE_READ);
requestor.add(
variable,
IndexConstants.IS_READ_WRITTEN_BY,
MatchKind.VARIABLE_READ_WRITE);
requestor.add(
variable,
IndexConstants.IS_WRITTEN_BY,
MatchKind.VARIABLE_WRITE);
requestor.add(
variable,
IndexConstants.IS_INVOKED_BY,
MatchKind.FUNCTION_EXECUTION);
return requestor.merge();
}
Future<List<SearchMatch>> _searchReferences_Method(MethodElement method) {
_Requestor requestor = new _Requestor(_index);
if (method is MethodMember) {
method = (method as MethodMember).baseElement;
}
requestor.add(
method,
IndexConstants.IS_REFERENCED_BY_QUALIFIED,
MatchKind.METHOD_REFERENCE);
requestor.add(
method,
IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
MatchKind.METHOD_REFERENCE);
requestor.add(
method,
IndexConstants.IS_INVOKED_BY_QUALIFIED,
MatchKind.METHOD_INVOCATION);
requestor.add(
method,
IndexConstants.IS_INVOKED_BY_UNQUALIFIED,
MatchKind.METHOD_INVOCATION);
return requestor.merge();
}
Future<List<SearchMatch>>
_searchReferences_Parameter(ParameterElement parameter) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
parameter,
IndexConstants.IS_READ_BY,
MatchKind.VARIABLE_READ);
requestor.add(
parameter,
IndexConstants.IS_READ_WRITTEN_BY,
MatchKind.VARIABLE_READ_WRITE);
requestor.add(
parameter,
IndexConstants.IS_WRITTEN_BY,
MatchKind.VARIABLE_WRITE);
requestor.add(
parameter,
IndexConstants.IS_REFERENCED_BY,
MatchKind.NAMED_PARAMETER_REFERENCE);
requestor.add(
parameter,
IndexConstants.IS_INVOKED_BY,
MatchKind.FUNCTION_EXECUTION);
return requestor.merge();
}
Future<List<SearchMatch>>
_searchReferences_PropertyAccessor(PropertyAccessorElement accessor) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
accessor,
IndexConstants.IS_REFERENCED_BY_QUALIFIED,
MatchKind.PROPERTY_ACCESSOR_REFERENCE);
requestor.add(
accessor,
IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
MatchKind.PROPERTY_ACCESSOR_REFERENCE);
return requestor.merge();
}
Future<List<SearchMatch>>
_searchReferences_TypeParameter(TypeParameterElement typeParameter) {
_Requestor requestor = new _Requestor(_index);
requestor.add(
typeParameter,
IndexConstants.IS_REFERENCED_BY,
MatchKind.TYPE_PARAMETER_REFERENCE);
return requestor.merge();
}
}
class _Requestor {
final List<Future<List<SearchMatch>>> futures = <Future<List<SearchMatch>>>[];
final Index index;
_Requestor(this.index);
void add(Element element2, Relationship relationship, MatchKind kind,
{bool isResolved: true}) {
Future relationsFuture = index.getRelationships(element2, relationship);
Future matchesFuture = relationsFuture.then((List<Location> locations) {
bool isQualified =
relationship == IndexConstants.IS_REFERENCED_BY_QUALIFIED ||
relationship == IndexConstants.IS_INVOKED_BY_QUALIFIED;
List<SearchMatch> matches = <SearchMatch>[];
for (Location location in locations) {
Element element = location.element;
matches.add(
new SearchMatch(
kind,
element,
new SourceRange(location.offset, location.length),
isResolved,
isQualified));
}
return matches;
});
futures.add(matchesFuture);
}
Future<List<SearchMatch>> merge() {
return Future.wait(futures).then((List<List<SearchMatch>> matchesList) {
return matchesList.expand((matches) => matches).toList();
});
}
}