Index: pkg/analysis_services/lib/src/search/search_engine.dart |
diff --git a/pkg/analysis_services/lib/src/search/search_engine.dart b/pkg/analysis_services/lib/src/search/search_engine.dart |
index b9419b94a4d354f6323ef7672c179c8975a932f2..def5e32cce804b7b9217e304c4bee443609bec2a 100644 |
--- a/pkg/analysis_services/lib/src/search/search_engine.dart |
+++ b/pkg/analysis_services/lib/src/search/search_engine.dart |
@@ -7,1222 +7,451 @@ |
library services.src.search.search_engine; |
-///** |
-// * Instances of the class <code>AndSearchPattern</code> implement a search pattern that matches |
-// * elements that match all of several other search patterns. |
-// */ |
-//class AndSearchPattern implements SearchPattern { |
-// /** |
-// * The patterns used to determine whether this pattern matches an element. |
-// */ |
-// final List<SearchPattern> _patterns; |
-// |
-// /** |
-// * Initialize a newly created search pattern to match elements that match all of several other |
-// * search patterns. |
-// * |
-// * @param patterns the patterns used to determine whether this pattern matches an element |
-// */ |
-// AndSearchPattern(this._patterns); |
-// |
-// @override |
-// MatchQuality matches(Element element) { |
-// MatchQuality highestQuality = null; |
-// for (SearchPattern pattern in _patterns) { |
-// MatchQuality quality = pattern.matches(element); |
-// if (quality == null) { |
-// return null; |
-// } |
-// if (highestQuality == null) { |
-// highestQuality = quality; |
-// } else { |
-// highestQuality = highestQuality.max(quality); |
-// } |
-// } |
-// return highestQuality; |
-// } |
-//} |
-// |
-///** |
-// * Instances of the class <code>CamelCaseSearchPattern</code> implement a search pattern that |
-// * matches elements whose name matches a partial identifier where camel case conventions are used to |
-// * perform what is essentially multiple prefix matches. |
-// */ |
-//class CamelCaseSearchPattern implements SearchPattern { |
-// /** |
-// * The pattern that matching elements must match. |
-// */ |
-// List<int> _pattern; |
-// |
-// /** |
-// * A flag indicating whether the pattern and the name being matched must have exactly the same |
-// * number of parts (i.e. the same number of uppercase characters). |
-// */ |
-// final bool _samePartCount; |
-// |
-// /** |
-// * Initialize a newly created search pattern to match elements whose names match the given |
-// * camel-case pattern. |
-// * |
-// * @param pattern the pattern that matching elements must match |
-// * @param samePartCount `true` if the pattern and the name being matched must have |
-// * exactly the same number of parts (i.e. the same number of uppercase characters) |
-// */ |
-// CamelCaseSearchPattern(String pattern, this._samePartCount) { |
-// this._pattern = pattern.toCharArray(); |
-// } |
-// |
-// @override |
-// MatchQuality matches(Element element) { |
-// String name = element.displayName; |
-// if (name == null) { |
-// return null; |
-// } |
-// if (CharOperation.camelCaseMatch(_pattern, name.toCharArray(), _samePartCount)) { |
-// return MatchQuality.EXACT; |
-// } |
-// return null; |
-// } |
-//} |
-// |
-///** |
-// * Instances of the class `CountingSearchListener` listen for search results, passing those |
-// * results on to a wrapped listener, but ensure that the wrapped search listener receives only one |
-// * notification that the search is complete. |
-// */ |
-//class CountingSearchListener implements SearchListener { |
-// /** |
-// * The number of times that this listener expects to be told that the search is complete before |
-// * passing the information along to the wrapped listener. |
-// */ |
-// int _completionCount = 0; |
-// |
-// /** |
-// * The listener that will be notified as results are received and when the given number of search |
-// * complete notifications have been received. |
-// */ |
-// final SearchListener _wrappedListener; |
-// |
-// /** |
-// * Initialize a newly created search listener to pass search results on to the given listener and |
-// * to notify the given listener that the search is complete after getting the given number of |
-// * notifications. |
-// * |
-// * @param completionCount the number of times that this listener expects to be told that the |
-// * search is complete |
-// * @param wrappedListener the listener that will be notified as results are received |
-// */ |
-// CountingSearchListener(int completionCount, this._wrappedListener) { |
-// this._completionCount = completionCount; |
-// if (completionCount == 0) { |
-// _wrappedListener.searchComplete(); |
-// } |
-// } |
-// |
-// @override |
-// void matchFound(SearchMatch match) { |
-// _wrappedListener.matchFound(match); |
-// } |
-// |
-// @override |
-// void searchComplete() { |
-// _completionCount--; |
-// if (_completionCount <= 0) { |
-// _wrappedListener.searchComplete(); |
-// } |
-// } |
-//} |
-// |
-///** |
-// * Instances of the class <code>ExactSearchPattern</code> implement a search pattern that matches |
-// * elements whose name matches a specified identifier exactly. |
-// */ |
-//class ExactSearchPattern implements SearchPattern { |
-// /** |
-// * The identifier that matching elements must be equal to. |
-// */ |
-// final String _identifier; |
-// |
-// /** |
-// * A flag indicating whether a case sensitive match is to be performed. |
-// */ |
-// final bool _caseSensitive; |
-// |
-// /** |
-// * Initialize a newly created search pattern to match elements whose names begin with the given |
-// * prefix. |
-// * |
-// * @param identifier the identifier that matching elements must be equal to |
-// * @param caseSensitive `true` if a case sensitive match is to be performed |
-// */ |
-// ExactSearchPattern(this._identifier, this._caseSensitive); |
-// |
-// @override |
-// MatchQuality matches(Element element) { |
-// String name = element.displayName; |
-// if (name == null) { |
-// return null; |
-// } |
-// if (_caseSensitive && name == _identifier) { |
-// return MatchQuality.EXACT; |
-// } |
-// if (!_caseSensitive && javaStringEqualsIgnoreCase(name, _identifier)) { |
-// return MatchQuality.EXACT; |
-// } |
-// return null; |
-// } |
-//} |
-// |
-///** |
-// * Instances of the class <code>FilteredSearchListener</code> implement a search listener that |
-// * delegates to another search listener after removing matches that do not pass a given filter. |
-// */ |
-//class FilteredSearchListener extends WrappedSearchListener { |
-// /** |
-// * The filter used to filter the matches. |
-// */ |
-// final SearchFilter _filter; |
-// |
-// /** |
-// * Initialize a newly created search listener to pass on any matches that pass the given filter to |
-// * the given listener. |
-// * |
-// * @param filter the filter used to filter the matches |
-// * @param listener the search listener being wrapped |
-// */ |
-// FilteredSearchListener(this._filter, SearchListener listener) : super(listener); |
-// |
-// @override |
-// void matchFound(SearchMatch match) { |
-// if (_filter.passes(match)) { |
-// propagateMatch(match); |
-// } |
-// } |
-//} |
-// |
-///** |
-// * [SearchListener] used by [SearchEngineImpl] internally to gather asynchronous results |
-// * and return them synchronously. |
-// */ |
-//class GatheringSearchListener implements SearchListener { |
-// /** |
-// * A list containing the matches that have been found so far. |
-// */ |
-// List<SearchMatch> _matches = []; |
-// |
-// /** |
-// * A flag indicating whether the search is complete. |
-// */ |
-// bool _isComplete = false; |
-// |
-// /** |
-// * @return the the matches that have been found. |
-// */ |
-// List<SearchMatch> get matches { |
-// _matches.sort(SearchMatch.SORT_BY_ELEMENT_NAME); |
-// return _matches; |
-// } |
-// |
-// /** |
-// * Return `true` if the search is complete. |
-// * |
-// * @return `true` if the search is complete |
-// */ |
-// bool get isComplete => _isComplete; |
-// |
-// @override |
-// void matchFound(SearchMatch match) { |
-// _matches.add(match); |
-// } |
-// |
-// @override |
-// void searchComplete() { |
-// _isComplete = true; |
-// } |
-//} |
-// |
-///** |
-// * Instances of the class <code>LibrarySearchScope</code> implement a search scope that encompasses |
-// * everything in a given collection of libraries. |
-// */ |
-//class LibrarySearchScope implements SearchScope { |
-// /** |
-// * The libraries defining which elements are included in the scope. |
-// */ |
-// final List<LibraryElement> libraries; |
-// |
-// /** |
-// * Create a search scope that encompasses everything in the given libraries. |
-// * |
-// * @param libraries the libraries defining which elements are included in the scope |
-// */ |
-// LibrarySearchScope.con1(Iterable<LibraryElement> libraries) : this.con2(new List.from(libraries)); |
-// |
-// /** |
-// * Create a search scope that encompasses everything in the given libraries. |
-// * |
-// * @param libraries the libraries defining which elements are included in the scope |
-// */ |
-// LibrarySearchScope.con2(this.libraries); |
-// |
-// @override |
-// bool encloses(Element element) { |
-// LibraryElement elementLibrary = element.getAncestor((element) => element is LibraryElement); |
-// return ArrayUtils.contains(libraries, elementLibrary); |
-// } |
-//} |
-// |
-///** |
-// * Instances of the class <code>NameMatchingSearchListener</code> implement a search listener that |
-// * delegates to another search listener after removing matches that do not match a given pattern. |
-// */ |
-//class NameMatchingSearchListener extends WrappedSearchListener { |
-// /** |
-// * The pattern used to filter the matches. |
-// */ |
-// final SearchPattern _pattern; |
-// |
-// /** |
-// * Initialize a newly created search listener to pass on any matches that match the given pattern |
-// * to the given listener. |
-// * |
-// * @param pattern the pattern used to filter the matches |
-// * @param listener the search listener being wrapped |
-// */ |
-// NameMatchingSearchListener(this._pattern, SearchListener listener) : super(listener); |
-// |
-// @override |
-// void matchFound(SearchMatch match) { |
-// if (_pattern.matches(match.element) != null) { |
-// propagateMatch(match); |
-// } |
-// } |
-//} |
-// |
-///** |
-// * Instances of the class <code>OrSearchPattern</code> implement a search pattern that matches |
-// * elements that match any one of several other search patterns. |
-// */ |
-//class OrSearchPattern implements SearchPattern { |
-// /** |
-// * The patterns used to determine whether this pattern matches an element. |
-// */ |
-// final List<SearchPattern> _patterns; |
-// |
-// /** |
-// * Initialize a newly created search pattern to match elements that match any one of several other |
-// * search patterns. |
-// * |
-// * @param patterns the patterns used to determine whether this pattern matches an element |
-// */ |
-// OrSearchPattern(this._patterns); |
-// |
-// @override |
-// MatchQuality matches(Element element) { |
-// // Do we want to return the highest quality of match rather than stopping |
-// // after the first match? Doing so would be more accurate, but slower. |
-// for (SearchPattern pattern in _patterns) { |
-// MatchQuality quality = pattern.matches(element); |
-// if (quality != null) { |
-// return quality; |
-// } |
-// } |
-// return null; |
-// } |
-//} |
-// |
-///** |
-// * Instances of the class <code>PrefixSearchPattern</code> implement a search pattern that matches |
-// * elements whose name has a given prefix. |
-// */ |
-//class PrefixSearchPattern implements SearchPattern { |
-// /** |
-// * The prefix that matching elements must start with. |
-// */ |
-// final String _prefix; |
-// |
-// /** |
-// * A flag indicating whether a case sensitive match is to be performed. |
-// */ |
-// final bool _caseSensitive; |
-// |
-// /** |
-// * Initialize a newly created search pattern to match elements whose names begin with the given |
-// * prefix. |
-// * |
-// * @param prefix the prefix that matching elements must start with |
-// * @param caseSensitive `true` if a case sensitive match is to be performed |
-// */ |
-// PrefixSearchPattern(this._prefix, this._caseSensitive); |
-// |
-// @override |
-// MatchQuality matches(Element element) { |
-// if (element == null) { |
-// return null; |
-// } |
-// String name = element.displayName; |
-// if (name == null) { |
-// return null; |
-// } |
-// if (_caseSensitive && startsWith(name, _prefix)) { |
-// return MatchQuality.EXACT; |
-// } |
-// if (!_caseSensitive && startsWithIgnoreCase(name, _prefix)) { |
-// return MatchQuality.EXACT; |
-// } |
-// return null; |
-// } |
-//} |
-// |
-///** |
-// * Instances of the class <code>RegularExpressionSearchPattern</code> implement a search pattern |
-// * that matches elements whose name matches a given regular expression. |
-// */ |
-//class RegularExpressionSearchPattern implements SearchPattern { |
-// /** |
-// * The regular expression pattern that matching elements must match. |
-// */ |
-// RegExp _pattern; |
-// |
-// /** |
-// * Initialize a newly created search pattern to match elements whose names begin with the given |
-// * prefix. |
-// * |
-// * @param regularExpression the regular expression that matching elements must match |
-// * @param caseSensitive `true` if a case sensitive match is to be performed |
-// */ |
-// RegularExpressionSearchPattern(String regularExpression, bool caseSensitive) { |
-// _pattern = new RegExp(regularExpression); |
-// } |
-// |
-// @override |
-// MatchQuality matches(Element element) { |
-// if (element == null) { |
-// return null; |
-// } |
-// String name = element.displayName; |
-// if (name == null) { |
-// return null; |
-// } |
-// if (new JavaPatternMatcher(_pattern, name).matches()) { |
-// return MatchQuality.EXACT; |
-// } |
-// return null; |
-// } |
-//} |
-// |
-///** |
-// * Factory for [SearchEngine]. |
-// */ |
-//class SearchEngineFactory { |
-// /** |
-// * @return the new [SearchEngine] instance based on the given [Index]. |
-// */ |
-// static SearchEngine createSearchEngine(Index index) => new SearchEngineImpl(index); |
-//} |
+import 'dart:async'; |
-///** |
-// * Implementation of [SearchEngine]. |
-// */ |
-//class SearchEngineImpl implements SearchEngine { |
-// /** |
-// * Apply the given filter to the given listener. |
-// * |
-// * @param filter the filter to be used before passing matches on to the listener, or `null` |
-// * if all matches should be passed on |
-// * @param listener the listener that will only be given matches that pass the filter |
-// * @return a search listener that will pass to the given listener any matches that pass the given |
-// * filter |
-// */ |
-// static SearchListener _applyFilter(SearchFilter filter, SearchListener listener) { |
-// if (filter == null) { |
-// return listener; |
-// } |
-// return new FilteredSearchListener(filter, listener); |
-// } |
-// |
-// /** |
-// * Apply the given pattern to the given listener. |
-// * |
-// * @param pattern the pattern to be used before passing matches on to the listener, or |
-// * `null` if all matches should be passed on |
-// * @param listener the listener that will only be given matches that match the pattern |
-// * @return a search listener that will pass to the given listener any matches that match the given |
-// * pattern |
-// */ |
-// static SearchListener _applyPattern(SearchPattern pattern, SearchListener listener) { |
-// if (pattern == null) { |
-// return listener; |
-// } |
-// return new NameMatchingSearchListener(pattern, listener); |
-// } |
-// |
-// static List<Element> _createElements(SearchScope scope) { |
-// if (scope is LibrarySearchScope) { |
-// return scope.libraries; |
-// } |
-// return <Element> [IndexConstants.UNIVERSE]; |
-// } |
-// |
-// static RelationshipCallback _newCallback(MatchKind matchKind, SearchScope scope, SearchListener listener) => new SearchEngineImpl_RelationshipCallbackImpl(scope, matchKind, listener); |
-// |
-// /** |
-// * The index used to respond to the search requests. |
-// */ |
-// final Index _index; |
-// |
-// /** |
-// * Initialize a newly created search engine to use the given index. |
-// * |
-// * @param index the index used to respond to the search requests |
-// */ |
-// SearchEngineImpl(this._index); |
-// |
-// @override |
-// Set<DartType> searchAssignedTypes(PropertyInducingElement variable, SearchScope scope) { |
-// PropertyAccessorElement setter = variable.setter; |
-// int numRequests = (setter != null ? 2 : 0) + 2; |
-// // find locations |
-// List<Location> locations = []; |
-// CountDownLatch latch = new CountDownLatch(numRequests); |
-// if (setter != null) { |
-// _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, new Callback()); |
-// _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, new Callback()); |
-// } |
-// _index.getRelationships(variable, IndexConstants.IS_REFERENCED_BY, new Callback()); |
-// _index.getRelationships(variable, IndexConstants.IS_DEFINED_BY, new Callback()); |
-// Uninterruptibles.awaitUninterruptibly(latch); |
-// // get types from locations |
-// Set<DartType> types = new Set(); |
-// for (Location location in locations) { |
-// // check scope |
-// if (scope != null) { |
-// Element targetElement = location.element; |
-// if (!scope.encloses(targetElement)) { |
-// continue; |
-// } |
-// } |
-// // we need data |
-// if (location is! LocationWithData) { |
-// continue; |
-// } |
-// LocationWithData locationWithData = location as LocationWithData; |
-// // add type |
-// Object data = locationWithData.data; |
-// if (data is DartType) { |
-// DartType type = data as DartType; |
-// types.add(type); |
-// } |
-// } |
-// // done |
-// return types; |
-// } |
-// |
-// @override |
-// List<SearchMatch> searchDeclarations(String name, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchDeclarations(this, name, scope, filter)); |
-// |
-// @override |
-// void searchDeclarations2(String name, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// _index.getRelationships(new NameElementImpl(name), IndexConstants.IS_DEFINED_BY, _newCallback(MatchKind.NAME_DECLARATION, scope, listener)); |
-// } |
-// |
-// @override |
-// List<SearchMatch> searchFunctionDeclarations(SearchScope scope, SearchPattern pattern, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchFunctionDeclarations(this, scope, pattern, filter)); |
-// |
-// @override |
-// void searchFunctionDeclarations2(SearchScope scope, SearchPattern pattern, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// List<Element> elements = _createElements(scope); |
-// listener = _applyPattern(pattern, listener); |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(elements.length, listener); |
-// for (Element element in elements) { |
-// _index.getRelationships(element, IndexConstants.DEFINES_FUNCTION, _newCallback(MatchKind.FUNCTION_DECLARATION, scope, listener)); |
-// } |
-// } |
-// |
-// @override |
-// List<SearchMatch> searchQualifiedMemberReferences(String name, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchQualifiedMemberReferences(this, name, scope, filter)); |
-// |
-// @override |
-// void searchQualifiedMemberReferences2(String name, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(10, listener); |
-// _index.getRelationships(new NameElementImpl(name), IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _newCallback(MatchKind.NAME_REFERENCE_RESOLVED, scope, listener)); |
-// _index.getRelationships(new NameElementImpl(name), IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _newCallback(MatchKind.NAME_REFERENCE_UNRESOLVED, scope, listener)); |
-// // granular resolved operations |
-// _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_INVOKED_BY_RESOLVED, _newCallback(MatchKind.NAME_INVOCATION_RESOLVED, scope, listener)); |
-// _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_BY_RESOLVED, _newCallback(MatchKind.NAME_READ_RESOLVED, scope, listener)); |
-// _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED, _newCallback(MatchKind.NAME_READ_WRITE_RESOLVED, scope, listener)); |
-// _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED, _newCallback(MatchKind.NAME_WRITE_RESOLVED, scope, listener)); |
-// // granular unresolved operations |
-// _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED, _newCallback(MatchKind.NAME_INVOCATION_UNRESOLVED, scope, listener)); |
-// _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_BY_UNRESOLVED, _newCallback(MatchKind.NAME_READ_UNRESOLVED, scope, listener)); |
-// _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED, _newCallback(MatchKind.NAME_READ_WRITE_UNRESOLVED, scope, listener)); |
-// _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED, _newCallback(MatchKind.NAME_WRITE_UNRESOLVED, scope, listener)); |
-// } |
-// |
-// @override |
-// List<SearchMatch> searchReferences(Element element, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchReferences(this, element, scope, filter)); |
-// |
-// @override |
-// void searchReferences2(Element element, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// if (element == null) { |
-// listener.searchComplete(); |
-// return; |
-// } |
-// if (element is Member) { |
-// element = (element as Member).baseElement; |
-// } |
-// while (true) { |
-// 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) { |
-// _searchReferences(element as AngularElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.CLASS) { |
-// _searchReferences2(element as ClassElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.COMPILATION_UNIT) { |
-// _searchReferences3(element as CompilationUnitElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.CONSTRUCTOR) { |
-// _searchReferences4(element as ConstructorElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.FIELD || element.kind == ElementKind.TOP_LEVEL_VARIABLE) { |
-// _searchReferences12(element as PropertyInducingElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.FUNCTION) { |
-// _searchReferences5(element as FunctionElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.GETTER || element.kind == ElementKind.SETTER) { |
-// _searchReferences11(element as PropertyAccessorElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.IMPORT) { |
-// _searchReferences7(element as ImportElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.LIBRARY) { |
-// _searchReferences8(element as LibraryElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.LOCAL_VARIABLE) { |
-// _searchReferences14(element as LocalVariableElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.METHOD) { |
-// _searchReferences9(element as MethodElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.PARAMETER) { |
-// _searchReferences10(element as ParameterElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) { |
-// _searchReferences6(element as FunctionTypeAliasElement, scope, filter, listener); |
-// return; |
-// } else if (element.kind == ElementKind.TYPE_PARAMETER) { |
-// _searchReferences13(element as TypeParameterElement, scope, filter, listener); |
-// return; |
-// } else { |
-// listener.searchComplete(); |
-// return; |
-// } |
-// break; |
-// } |
-// } |
-// |
-// @override |
-// List<SearchMatch> searchSubtypes(ClassElement type, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchSubtypes(this, type, scope, filter)); |
-// |
-// @override |
-// void searchSubtypes2(ClassElement type, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(3, listener); |
-// _index.getRelationships(type, IndexConstants.IS_EXTENDED_BY, _newCallback(MatchKind.EXTENDS_REFERENCE, scope, listener)); |
-// _index.getRelationships(type, IndexConstants.IS_MIXED_IN_BY, _newCallback(MatchKind.WITH_REFERENCE, scope, listener)); |
-// _index.getRelationships(type, IndexConstants.IS_IMPLEMENTED_BY, _newCallback(MatchKind.IMPLEMENTS_REFERENCE, scope, listener)); |
-// } |
-// |
-// @override |
-// List<SearchMatch> searchTypeDeclarations(SearchScope scope, SearchPattern pattern, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchTypeDeclarations(this, scope, pattern, filter)); |
-// |
-// @override |
-// void searchTypeDeclarations2(SearchScope scope, SearchPattern pattern, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// List<Element> elements = _createElements(scope); |
-// listener = _applyPattern(pattern, listener); |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(elements.length * 3, listener); |
-// for (Element element in elements) { |
-// _index.getRelationships(element, IndexConstants.DEFINES_CLASS, _newCallback(MatchKind.CLASS_DECLARATION, scope, listener)); |
-// _index.getRelationships(element, IndexConstants.DEFINES_CLASS_ALIAS, _newCallback(MatchKind.CLASS_ALIAS_DECLARATION, scope, listener)); |
-// _index.getRelationships(element, IndexConstants.DEFINES_FUNCTION_TYPE, _newCallback(MatchKind.FUNCTION_TYPE_DECLARATION, scope, listener)); |
-// } |
-// } |
-// |
-// @override |
-// List<SearchMatch> searchVariableDeclarations(SearchScope scope, SearchPattern pattern, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchVariableDeclarations(this, scope, pattern, filter)); |
-// |
-// @override |
-// void searchVariableDeclarations2(SearchScope scope, SearchPattern pattern, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// List<Element> elements = _createElements(scope); |
-// listener = _applyPattern(pattern, listener); |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(elements.length, listener); |
-// for (Element element in elements) { |
-// _index.getRelationships(element, IndexConstants.DEFINES_VARIABLE, _newCallback(MatchKind.VARIABLE_DECLARATION, scope, listener)); |
-// } |
-// } |
-// |
-// /** |
-// * Use the given runner to perform the given number of asynchronous searches, then wait until the |
-// * search has completed and return the results that were produced. |
-// * |
-// * @param runner the runner used to perform an asynchronous search |
-// * @return the results that were produced @ if the results of at least one of the searched could |
-// * not be computed |
-// */ |
-// List<SearchMatch> _gatherResults(SearchEngineImpl_SearchRunner runner) { |
-// GatheringSearchListener listener = new GatheringSearchListener(); |
-// runner.performSearch(listener); |
-// while (!listener.isComplete) { |
-// Thread.yield(); |
-// } |
-// return listener.matches; |
-// } |
-// |
-// void _searchReferences(AngularElement element, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(2, listener); |
-// _index.getRelationships(element, IndexConstants.ANGULAR_REFERENCE, _newCallback(MatchKind.ANGULAR_REFERENCE, scope, listener)); |
-// _index.getRelationships(element, IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE, _newCallback(MatchKind.ANGULAR_CLOSING_TAG_REFERENCE, scope, listener)); |
-// } |
-// |
-// void _searchReferences2(ClassElement type, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// _index.getRelationships(type, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.TYPE_REFERENCE, scope, listener)); |
-// } |
-// |
-// void _searchReferences3(CompilationUnitElement unit, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// _index.getRelationships(unit, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.UNIT_REFERENCE, scope, listener)); |
-// } |
-// |
-// void _searchReferences4(ConstructorElement constructor, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(2, listener); |
-// _index.getRelationships(constructor, IndexConstants.IS_DEFINED_BY, _newCallback(MatchKind.CONSTRUCTOR_DECLARATION, scope, listener)); |
-// _index.getRelationships(constructor, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.CONSTRUCTOR_REFERENCE, scope, listener)); |
-// } |
-// |
-// void _searchReferences5(FunctionElement function, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(2, listener); |
-// _index.getRelationships(function, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.FUNCTION_REFERENCE, scope, listener)); |
-// _index.getRelationships(function, IndexConstants.IS_INVOKED_BY, _newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener)); |
-// } |
-// |
-// void _searchReferences6(FunctionTypeAliasElement alias, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// _index.getRelationships(alias, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.FUNCTION_TYPE_REFERENCE, scope, listener)); |
-// } |
-// |
-// void _searchReferences7(ImportElement imp, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// _index.getRelationships(imp, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.IMPORT_REFERENCE, scope, listener)); |
-// } |
-// |
-// void _searchReferences8(LibraryElement library, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// _index.getRelationships(library, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.LIBRARY_REFERENCE, scope, listener)); |
-// } |
-// |
-// void _searchReferences9(MethodElement method, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// // TODO(scheglov) use "5" when add named matches |
-// listener = new CountingSearchListener(4, listener); |
-// // exact matches |
-// _index.getRelationships(method, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, _newCallback(MatchKind.METHOD_INVOCATION, scope, listener)); |
-// _index.getRelationships(method, IndexConstants.IS_INVOKED_BY_QUALIFIED, _newCallback(MatchKind.METHOD_INVOCATION, scope, listener)); |
-// _index.getRelationships(method, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.METHOD_REFERENCE, scope, listener)); |
-// _index.getRelationships(method, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.METHOD_REFERENCE, scope, listener)); |
-// } |
-// |
-// void _searchReferences10(ParameterElement parameter, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(5, listener); |
-// _index.getRelationships(parameter, IndexConstants.IS_READ_BY, _newCallback(MatchKind.VARIABLE_READ, scope, listener)); |
-// _index.getRelationships(parameter, IndexConstants.IS_READ_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_READ_WRITE, scope, listener)); |
-// _index.getRelationships(parameter, IndexConstants.IS_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_WRITE, scope, listener)); |
-// _index.getRelationships(parameter, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.NAMED_PARAMETER_REFERENCE, scope, listener)); |
-// _index.getRelationships(parameter, IndexConstants.IS_INVOKED_BY, _newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener)); |
-// } |
-// |
-// void _searchReferences11(PropertyAccessorElement accessor, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(2, listener); |
-// _index.getRelationships(accessor, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.PROPERTY_ACCESSOR_REFERENCE, scope, listener)); |
-// _index.getRelationships(accessor, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.PROPERTY_ACCESSOR_REFERENCE, scope, listener)); |
-// } |
-// |
-// void _searchReferences12(PropertyInducingElement field, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// PropertyAccessorElement getter = field.getter; |
-// PropertyAccessorElement setter = field.setter; |
-// int numRequests = (getter != null ? 4 : 0) + (setter != null ? 2 : 0) + 2; |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(numRequests, listener); |
-// if (getter != null) { |
-// _index.getRelationships(getter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_READ, scope, listener)); |
-// _index.getRelationships(getter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.FIELD_READ, scope, listener)); |
-// _index.getRelationships(getter, IndexConstants.IS_INVOKED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_INVOCATION, scope, listener)); |
-// _index.getRelationships(getter, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, _newCallback(MatchKind.FIELD_INVOCATION, scope, listener)); |
-// } |
-// if (setter != null) { |
-// _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_WRITE, scope, listener)); |
-// _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.FIELD_WRITE, scope, listener)); |
-// } |
-// _index.getRelationships(field, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.FIELD_REFERENCE, scope, listener)); |
-// _index.getRelationships(field, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_REFERENCE, scope, listener)); |
-// } |
-// |
-// void _searchReferences13(TypeParameterElement typeParameter, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// _index.getRelationships(typeParameter, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.TYPE_PARAMETER_REFERENCE, scope, listener)); |
-// } |
-// |
-// void _searchReferences14(VariableElement variable, SearchScope scope, SearchFilter filter, SearchListener listener) { |
-// assert(listener != null); |
-// listener = _applyFilter(filter, listener); |
-// listener = new CountingSearchListener(4, listener); |
-// _index.getRelationships(variable, IndexConstants.IS_READ_BY, _newCallback(MatchKind.VARIABLE_READ, scope, listener)); |
-// _index.getRelationships(variable, IndexConstants.IS_READ_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_READ_WRITE, scope, listener)); |
-// _index.getRelationships(variable, IndexConstants.IS_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_WRITE, scope, listener)); |
-// _index.getRelationships(variable, IndexConstants.IS_INVOKED_BY, _newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener)); |
-// } |
-//} |
-// |
-///** |
-// * Instances of the class <code>RelationshipCallbackImpl</code> implement a callback that can be |
-// * used to report results to a search listener. |
-// */ |
-//class SearchEngineImpl_RelationshipCallbackImpl implements RelationshipCallback { |
-// final SearchScope _scope; |
-// |
-// /** |
-// * The kind of matches that are represented by the results that will be provided to this |
-// * callback. |
-// */ |
-// final MatchKind _matchKind; |
-// |
-// /** |
-// * The search listener that should be notified when results are found. |
-// */ |
-// final SearchListener _listener; |
-// |
-// /** |
-// * Initialize a newly created callback to report matches of the given kind to the given listener |
-// * when results are found. |
-// * |
-// * @param scope the [SearchScope] to return matches from, may be `null` to return |
-// * all matches |
-// * @param matchKind the kind of matches that are represented by the results |
-// * @param listener the search listener that should be notified when results are found |
-// */ |
-// SearchEngineImpl_RelationshipCallbackImpl(this._scope, this._matchKind, this._listener); |
-// |
-// @override |
-// void hasRelationships(Element element, Relationship relationship, List<Location> locations) { |
-// for (Location location in locations) { |
-// Element targetElement = location.element; |
-// // check scope |
-// if (_scope != null && !_scope.encloses(targetElement)) { |
-// continue; |
-// } |
-// SourceRange range = new SourceRange(location.offset, location.length); |
-// // TODO(scheglov) IndexConstants.DYNAMIC for MatchQuality.NAME |
-// MatchQuality quality = MatchQuality.EXACT; |
-// // MatchQuality quality = element.getResource() != IndexConstants.DYNAMIC |
-// // ? MatchQuality.EXACT : MatchQuality.NAME; |
-// SearchMatch match = new SearchMatch(quality, _matchKind, targetElement, range); |
-// match.qualified = identical(relationship, IndexConstants.IS_REFERENCED_BY_QUALIFIED) || identical(relationship, IndexConstants.IS_INVOKED_BY_QUALIFIED); |
-// _listener.matchFound(match); |
-// } |
-// _listener.searchComplete(); |
-// } |
-//} |
-// |
-///** |
-// * The interface <code>SearchRunner</code> defines the behavior of objects that can be used to |
-// * perform an asynchronous search. |
-// */ |
-//abstract class SearchEngineImpl_SearchRunner { |
-// /** |
-// * Perform an asynchronous search, passing the results to the given listener. |
-// * |
-// * @param listener the listener to which search results should be passed @ if the results could |
-// * not be computed |
-// */ |
-// void performSearch(SearchListener listener); |
-//} |
-// |
-///** |
-// * The interface <code>SearchListener</code> defines the behavior of objects that are listening for |
-// * the results of a search. |
-// */ |
-//abstract class SearchListener { |
-// /** |
-// * Record the fact that the given match was found. |
-// * |
-// * @param match the match that was found |
-// */ |
-// void matchFound(SearchMatch match); |
-// |
-// /** |
-// * This method is invoked when the search is complete and no additional matches will be found. |
-// */ |
-// void searchComplete(); |
-//} |
+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'; |
-///** |
-// * The class <code>SearchPatternFactory</code> defines utility methods that can be used to create |
-// * search patterns. |
-// */ |
-//class SearchPatternFactory { |
-// /** |
-// * Create a pattern that will match any element that is matched by all of the given patterns. If |
-// * no patterns are given, then the resulting pattern will not match any elements. |
-// * |
-// * @param patterns the patterns that must all be matched in order for the new pattern to be |
-// * matched |
-// * @return the pattern that was created |
-// */ |
-// static SearchPattern createAndPattern(List<SearchPattern> patterns) { |
-// if (patterns.length == 1) { |
-// return patterns[0]; |
-// } |
-// return new AndSearchPattern(patterns); |
-// } |
-// |
-// /** |
-// * Create a pattern that will match any element whose name matches a partial identifier where |
-// * camel case conventions are used to perform what is essentially multiple prefix matches. |
-// * |
-// * @param pattern the pattern that matching elements must match |
-// * @param samePartCount `true` if the pattern and the name being matched must have |
-// * exactly the same number of parts (i.e. the same number of uppercase characters) |
-// * @return the pattern that was created |
-// */ |
-// static SearchPattern createCamelCasePattern(String prefix, bool samePartCount) => new CamelCaseSearchPattern(prefix, samePartCount); |
-// |
-// /** |
-// * Create a pattern that will match any element whose name matches a specified identifier exactly. |
-// * |
-// * @param identifier the identifier that matching elements must be equal to |
-// * @param caseSensitive `true` if a case sensitive match is to be performed |
-// * @return the pattern that was created |
-// */ |
-// static SearchPattern createExactPattern(String identifier, bool caseSensitive) => new ExactSearchPattern(identifier, caseSensitive); |
-// |
-// /** |
-// * Create a pattern that will match any element that is matched by at least one of the given |
-// * patterns. If no patterns are given, then the resulting pattern will not match any elements. |
-// * |
-// * @param patterns the patterns used to determine whether the new pattern is matched |
-// * @return the pattern that was created |
-// */ |
-// static SearchPattern createOrPattern(List<SearchPattern> patterns) { |
-// if (patterns.length == 1) { |
-// return patterns[0]; |
-// } |
-// return new OrSearchPattern(patterns); |
-// } |
-// |
-// /** |
-// * Create a pattern that will match any element whose name starts with the given prefix. |
-// * |
-// * @param prefix the prefix of names that match the pattern |
-// * @param caseSensitive `true` if a case sensitive match is to be performed |
-// * @return the pattern that was created |
-// */ |
-// static SearchPattern createPrefixPattern(String prefix, bool caseSensitive) => new PrefixSearchPattern(prefix, caseSensitive); |
-// |
-// /** |
-// * Create a pattern that will match any element whose name matches a regular expression. |
-// * |
-// * @param regularExpression the regular expression that matching elements must match |
-// * @param caseSensitive `true` if a case sensitive match is to be performed |
-// * @return the pattern that was created |
-// */ |
-// static SearchPattern createRegularExpressionPattern(String regularExpression, bool caseSensitive) => new RegularExpressionSearchPattern(regularExpression, caseSensitive); |
-// |
-// /** |
-// * Create a pattern that will match any element whose name matches a pattern containing wildcard |
-// * characters. The wildcard characters that are currently supported are '?' (to match any single |
-// * character) and '*' (to match zero or more characters). |
-// * |
-// * @param pattern the pattern that matching elements must match |
-// * @param caseSensitive `true` if a case sensitive match is to be performed |
-// * @return the pattern that was created |
-// */ |
-// static SearchPattern createWildcardPattern(String pattern, bool caseSensitive) => new WildcardSearchPattern(pattern, caseSensitive); |
-//} |
-// |
-//class SearchRunner_SearchEngineImpl_searchDeclarations implements SearchEngineImpl_SearchRunner { |
-// final SearchEngineImpl SearchEngineImpl_this; |
-// |
-// String name; |
-// |
-// SearchScope scope; |
-// |
-// SearchFilter filter; |
-// |
-// SearchRunner_SearchEngineImpl_searchDeclarations(this.SearchEngineImpl_this, this.name, this.scope, this.filter); |
-// |
-// @override |
-// void performSearch(SearchListener listener) { |
-// SearchEngineImpl_this.searchDeclarations2(name, scope, filter, listener); |
-// } |
-//} |
-// |
-//class SearchRunner_SearchEngineImpl_searchFunctionDeclarations implements SearchEngineImpl_SearchRunner { |
-// final SearchEngineImpl SearchEngineImpl_this; |
-// |
-// SearchScope scope; |
-// |
-// SearchPattern pattern; |
-// |
-// SearchFilter filter; |
-// |
-// SearchRunner_SearchEngineImpl_searchFunctionDeclarations(this.SearchEngineImpl_this, this.scope, this.pattern, this.filter); |
-// |
-// @override |
-// void performSearch(SearchListener listener) { |
-// SearchEngineImpl_this.searchFunctionDeclarations2(scope, pattern, filter, listener); |
-// } |
-//} |
-// |
-//class SearchRunner_SearchEngineImpl_searchQualifiedMemberReferences implements SearchEngineImpl_SearchRunner { |
-// final SearchEngineImpl SearchEngineImpl_this; |
-// |
-// String name; |
-// |
-// SearchScope scope; |
-// |
-// SearchFilter filter; |
-// |
-// SearchRunner_SearchEngineImpl_searchQualifiedMemberReferences(this.SearchEngineImpl_this, this.name, this.scope, this.filter); |
-// |
-// @override |
-// void performSearch(SearchListener listener) { |
-// SearchEngineImpl_this.searchQualifiedMemberReferences2(name, scope, filter, listener); |
-// } |
-//} |
-// |
-//class SearchRunner_SearchEngineImpl_searchReferences implements SearchEngineImpl_SearchRunner { |
-// final SearchEngineImpl SearchEngineImpl_this; |
-// |
-// Element element; |
-// |
-// SearchScope scope; |
-// |
-// SearchFilter filter; |
-// |
-// SearchRunner_SearchEngineImpl_searchReferences(this.SearchEngineImpl_this, this.element, this.scope, this.filter); |
-// |
-// @override |
-// void performSearch(SearchListener listener) { |
-// SearchEngineImpl_this.searchReferences2(element, scope, filter, listener); |
-// } |
-//} |
-// |
-//class SearchRunner_SearchEngineImpl_searchSubtypes implements SearchEngineImpl_SearchRunner { |
-// final SearchEngineImpl SearchEngineImpl_this; |
-// |
-// ClassElement type; |
-// |
-// SearchScope scope; |
-// |
-// SearchFilter filter; |
-// |
-// SearchRunner_SearchEngineImpl_searchSubtypes(this.SearchEngineImpl_this, this.type, this.scope, this.filter); |
-// |
-// @override |
-// void performSearch(SearchListener listener) { |
-// SearchEngineImpl_this.searchSubtypes2(type, scope, filter, listener); |
-// } |
-//} |
-// |
-//class SearchRunner_SearchEngineImpl_searchTypeDeclarations implements SearchEngineImpl_SearchRunner { |
-// final SearchEngineImpl SearchEngineImpl_this; |
-// |
-// SearchScope scope; |
-// |
-// SearchPattern pattern; |
-// |
-// SearchFilter filter; |
-// |
-// SearchRunner_SearchEngineImpl_searchTypeDeclarations(this.SearchEngineImpl_this, this.scope, this.pattern, this.filter); |
-// |
-// @override |
-// void performSearch(SearchListener listener) { |
-// SearchEngineImpl_this.searchTypeDeclarations2(scope, pattern, filter, listener); |
-// } |
-//} |
-// |
-//class SearchRunner_SearchEngineImpl_searchVariableDeclarations implements SearchEngineImpl_SearchRunner { |
-// final SearchEngineImpl SearchEngineImpl_this; |
-// |
-// SearchScope scope; |
-// |
-// SearchPattern pattern; |
-// |
-// SearchFilter filter; |
-// |
-// SearchRunner_SearchEngineImpl_searchVariableDeclarations(this.SearchEngineImpl_this, this.scope, this.pattern, this.filter); |
-// |
-// @override |
-// void performSearch(SearchListener listener) { |
-// SearchEngineImpl_this.searchVariableDeclarations2(scope, pattern, filter, listener); |
-// } |
-//} |
-// |
-///** |
-// * The class <code>SearchScopeFactory</code> defines utility methods that can be used to create |
-// * search scopes. |
-// */ |
-//class SearchScopeFactory { |
-// /** |
-// * A search scope that encompasses everything in the "universe". Because it does not hold any |
-// * state there is no reason not to share a single instance. |
-// */ |
-// static SearchScope _UNIVERSE_SCOPE = new UniverseSearchScope(); |
-// |
-// /** |
-// * Create a search scope that encompasses everything in the given library. |
-// * |
-// * @param library the library defining which elements are included in the scope |
-// * @return the search scope that was created |
-// */ |
-// static SearchScope createLibraryScope(Iterable<LibraryElement> libraries) => new LibrarySearchScope.con1(libraries); |
-// |
-// /** |
-// * Create a search scope that encompasses everything in the given libraries. |
-// * |
-// * @param libraries the libraries defining which elements are included in the scope |
-// * @return the search scope that was created |
-// */ |
-// static SearchScope createLibraryScope2(List<LibraryElement> libraries) => new LibrarySearchScope.con2(libraries); |
-// |
-// /** |
-// * Create a search scope that encompasses everything in the given library. |
-// * |
-// * @param library the library defining which elements are included in the scope |
-// * @return the search scope that was created |
-// */ |
-// static SearchScope createLibraryScope3(LibraryElement library) => new LibrarySearchScope.con2([library]); |
-// |
-// /** |
-// * Create a search scope that encompasses everything in the universe. |
-// * |
-// * @return the search scope that was created |
-// */ |
-// static SearchScope createUniverseScope() => _UNIVERSE_SCOPE; |
-//} |
-// |
-///** |
-// * The [SearchScope] that encompasses everything in the universe. |
-// */ |
-//class UniverseSearchScope implements SearchScope { |
-// @override |
-// bool encloses(Element element) => true; |
-//} |
-// |
-///** |
-// * Instances of the class <code>WildcardSearchPattern</code> implement a search pattern that matches |
-// * elements whose name matches a pattern with wildcard characters. The wildcard characters that are |
-// * currently supported are '?' (to match any single character) and '*' (to match zero or more |
-// * characters). |
-// */ |
-//class WildcardSearchPattern implements SearchPattern { |
-// /** |
-// * The pattern that matching elements must match. |
-// */ |
-// List<int> _pattern; |
-// |
-// /** |
-// * A flag indicating whether a case sensitive match is to be performed. |
-// */ |
-// final bool _caseSensitive; |
-// |
-// /** |
-// * Initialize a newly created search pattern to match elements whose names begin with the given |
-// * prefix. |
-// * |
-// * @param pattern the pattern that matching elements must match |
-// * @param caseSensitive `true` if a case sensitive match is to be performed |
-// */ |
-// WildcardSearchPattern(String pattern, this._caseSensitive) { |
-// this._pattern = _caseSensitive ? pattern.toCharArray() : pattern.toLowerCase().toCharArray(); |
-// } |
-// |
-// @override |
-// MatchQuality matches(Element element) { |
-// if (element == null) { |
-// return null; |
-// } |
-// String name = element.displayName; |
-// if (name == null) { |
-// return null; |
-// } |
-// if (CharOperation.match(_pattern, name.toCharArray(), _caseSensitive)) { |
-// return MatchQuality.EXACT; |
-// } |
-// return null; |
-// } |
-//} |
-// |
-///** |
-// * Instances of the class <code>ScopedSearchListener</code> implement a search listener that |
-// * delegates to another search listener after removing matches that are outside a given scope. |
-// */ |
-//abstract class WrappedSearchListener implements SearchListener { |
-// /** |
-// * The listener being wrapped. |
-// */ |
-// SearchListener _baseListener; |
-// |
-// /** |
-// * Initialize a newly created search listener to wrap the given listener. |
-// * |
-// * @param listener the search listener being wrapped |
-// */ |
-// WrappedSearchListener(SearchListener listener) { |
-// _baseListener = listener; |
-// } |
-// |
-// @override |
-// void searchComplete() { |
-// _baseListener.searchComplete(); |
-// } |
-// |
-// /** |
-// * Pass the given match on to the wrapped listener. |
-// * |
-// * @param match the match to be propagated |
-// */ |
-// void propagateMatch(SearchMatch match) { |
-// _baseListener.matchFound(match); |
-// } |
-//} |
+ |
+/** |
+ * 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(); |
+ }); |
+ } |
+} |