Chromium Code Reviews| Index: pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart |
| diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..15bc84ce9ee4e02426fa3ab477a3c8d7d68340b7 |
| --- /dev/null |
| +++ b/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart |
| @@ -0,0 +1,242 @@ |
| +// Copyright (c) 2016, 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. |
| + |
| +library services.src.search.search_engine2; |
| + |
| +import 'dart:async'; |
| + |
| +import 'package:analysis_server/src/services/index2/index2.dart'; |
| +import 'package:analysis_server/src/services/search/search_engine.dart'; |
| +import 'package:analyzer/dart/element/element.dart'; |
| +import 'package:analyzer/src/dart/element/member.dart'; |
| +import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
| +import 'package:analyzer/src/generated/source.dart' show SourceRange; |
| +import 'package:analyzer/src/summary/idl.dart'; |
| + |
| +/** |
| + * A [SearchEngine] implementation. |
| + */ |
| +class SearchEngineImpl2 implements SearchEngine { |
| + final AnalysisContext context; |
| + final Index2 _index; |
| + |
| + SearchEngineImpl2(this.context, this._index); |
| + |
| + @override |
| + Future<List<SearchMatch>> searchAllSubtypes(ClassElement type) { |
| + // TODO: implement searchAllSubtypes |
| + throw new UnimplementedError(); |
| + } |
| + |
| + @override |
| + Future<List<SearchMatch>> searchElementDeclarations(String name) { |
| + // TODO: implement searchElementDeclarations |
| + throw new UnimplementedError(); |
| + } |
| + |
| + @override |
| + Future<List<SearchMatch>> searchMemberDeclarations(String name) { |
| + // TODO: implement searchMemberDeclarations |
| + throw new UnimplementedError(); |
| + } |
| + |
| + @override |
| + Future<List<SearchMatch>> searchMemberReferences(String name) { |
| + // TODO: implement searchMemberReferences |
| + throw new UnimplementedError(); |
| + } |
| + |
| + @override |
| + Future<List<SearchMatch>> searchReferences(Element element) { |
| + if (element.kind == ElementKind.CLASS) { |
| + return _searchReferences(element); |
| + } else if (element.kind == ElementKind.COMPILATION_UNIT) { |
| + return _searchReferences(element); |
|
Brian Wilkerson
2016/03/04 19:34:43
Are the current calls to _searchReferences going t
|
| + } 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(element); |
| + } else if (element.kind == ElementKind.IMPORT) { |
| + return _searchReferences(element); |
| + } else if (element.kind == ElementKind.LABEL) { |
| + return _searchReferences(element); |
| + } else if (element.kind == ElementKind.LIBRARY) { |
| + return _searchReferences(element); |
| + } 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.PREFIX) { |
| + return _searchReferences(element); |
| + } else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) { |
| + return _searchReferences(element); |
| + } else if (element.kind == ElementKind.TYPE_PARAMETER) { |
| + return _searchReferences_TypeParameter(element); |
| + } |
| + return new Future.value(<SearchMatch>[]); |
| + } |
| + |
| + @override |
| + Future<List<SearchMatch>> searchSubtypes(ClassElement type) { |
| + // TODO: implement searchSubtypes |
| + throw new UnimplementedError(); |
| + } |
| + |
| + @override |
| + Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) { |
| + // TODO: implement searchTopLevelDeclarations |
| + throw new UnimplementedError(); |
| + } |
| + |
| + Future<List<SearchMatch>> _searchReferences(Element element) { |
| + _Requestor requestor = new _Requestor(context, _index); |
| + requestor.addElement( |
| + element, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); |
| + return requestor.merge(); |
| + } |
| + |
| + Future<List<SearchMatch>> _searchReferences_Constructor( |
| + ConstructorElement constructor) { |
| + _Requestor requestor = new _Requestor(context, _index); |
| + requestor.addElement( |
| + constructor, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); |
| + return requestor.merge(); |
| + } |
| + |
| + Future<List<SearchMatch>> _searchReferences_Field( |
| + PropertyInducingElement field) { |
| + PropertyAccessorElement getter = field.getter; |
| + PropertyAccessorElement setter = field.setter; |
| + _Requestor requestor = new _Requestor(context, _index); |
| + // field itself |
| + requestor.addElement( |
| + field, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); |
| + // getter |
| + if (getter != null) { |
| + requestor.addElement( |
| + getter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.READ); |
| + requestor.addElement( |
| + getter, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION); |
| + } |
| + // setter |
| + if (setter != null) { |
| + requestor.addElement( |
| + setter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.WRITE); |
| + } |
| + // done |
| + return requestor.merge(); |
| + } |
| + |
| + Future<List<SearchMatch>> _searchReferences_Function( |
| + FunctionElement function) { |
| + _Requestor requestor = new _Requestor(context, _index); |
| + requestor.addElement( |
| + function, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); |
| + requestor.addElement( |
| + function, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION); |
| + return requestor.merge(); |
| + } |
| + |
| + Future<List<SearchMatch>> _searchReferences_LocalVariable( |
| + LocalVariableElement variable) { |
| + // TODO(scheglov) implement using AST visitor |
| + throw new UnimplementedError(); |
| +// _Requestor requestor = new _Requestor(context, _index); |
| +// requestor.addElement(variable, IndexRelationKind.IS_READ_BY, MatchKind.READ); |
| +// requestor.addElement( |
| +// variable, IndexRelationKind.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE); |
| +// requestor.addElement( |
| +// variable, IndexRelationKind.IS_WRITTEN_BY, MatchKind.WRITE); |
| +// requestor.addElement( |
| +// variable, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION); |
| +// return requestor.merge(); |
| + } |
| + |
| + Future<List<SearchMatch>> _searchReferences_Method(MethodElement method) { |
| + _Requestor requestor = new _Requestor(context, _index); |
| + if (method is MethodMember) { |
| + method = (method as MethodMember).baseElement; |
| + } |
| + requestor.addElement( |
| + method, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); |
| + requestor.addElement( |
| + method, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION); |
| + return requestor.merge(); |
| + } |
| + |
| + Future<List<SearchMatch>> _searchReferences_Parameter( |
| + ParameterElement parameter) { |
| + // TODO(scheglov) implement using AST visitor |
| + throw new UnimplementedError(); |
| +// _Requestor requestor = new _Requestor(context, _index); |
| +// requestor.addElement(parameter, IndexRelationKind.IS_READ_BY, MatchKind.READ); |
| +// requestor.addElement( |
| +// parameter, IndexRelationKind.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE); |
| +// requestor.addElement( |
| +// parameter, IndexRelationKind.IS_WRITTEN_BY, MatchKind.WRITE); |
| +// requestor.addElement( |
| +// parameter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); |
| +// requestor.addElement( |
| +// parameter, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION); |
| +// return requestor.merge(); |
| + } |
| + |
| + Future<List<SearchMatch>> _searchReferences_TypeParameter( |
| + ParameterElement parameter) { |
| + // TODO(scheglov) implement using AST visitor |
| + throw new UnimplementedError(); |
| + } |
| +} |
| + |
| +class _Requestor { |
| + final AnalysisContext context; |
| + final Index2 index; |
| + final List<Future<List<SearchMatch>>> futures = <Future<List<SearchMatch>>>[]; |
| + |
| + _Requestor(this.context, this.index); |
| + |
| + void addElement( |
| + Element element, IndexRelationKind relationKind, MatchKind kind) { |
| + Future relationsFuture = index.getRelations(element, relationKind); |
| + Future matchesFuture = relationsFuture.then((List<Location> locations) { |
| + List<SearchMatch> matches = <SearchMatch>[]; |
| + for (Location location in locations) { |
| + matches.add(_convertLocation(location, kind)); |
| + } |
| + return matches; |
| + }); |
| + futures.add(matchesFuture); |
| + } |
| + |
| +// void addElement( |
| +// Element element, RelationshipImpl relationship, MatchKind kind) { |
| +// IndexableElement indexable = new IndexableElement(element); |
| +// add(indexable, relationship, kind); |
| +// } |
| + |
| + Future<List<SearchMatch>> merge() { |
| + return Future.wait(futures).then((List<List<SearchMatch>> matchesList) { |
| + return matchesList.expand((matches) => matches).toList(); |
| + }); |
| + } |
| + |
| + SearchMatch _convertLocation(Location location, MatchKind kind) { |
| + return new SearchMatch( |
| + context, |
| + location.libraryUri, |
| + location.unitUri, |
| + kind, |
| + new SourceRange(location.offset, location.length), |
| + true, |
| + location.isQualified); |
| + } |
| +} |