OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library services.src.search.search_engine2; | |
6 | |
7 import 'dart:async'; | |
8 | |
9 import 'package:analysis_server/src/services/index2/index2.dart'; | |
10 import 'package:analysis_server/src/services/search/search_engine.dart'; | |
11 import 'package:analyzer/dart/element/element.dart'; | |
12 import 'package:analyzer/src/dart/element/member.dart'; | |
13 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; | |
14 import 'package:analyzer/src/generated/source.dart' show SourceRange; | |
15 import 'package:analyzer/src/summary/idl.dart'; | |
16 | |
17 /** | |
18 * A [SearchEngine] implementation. | |
19 */ | |
20 class SearchEngineImpl2 implements SearchEngine { | |
21 final AnalysisContext context; | |
22 final Index2 _index; | |
23 | |
24 SearchEngineImpl2(this.context, this._index); | |
25 | |
26 @override | |
27 Future<List<SearchMatch>> searchAllSubtypes(ClassElement type) { | |
28 // TODO: implement searchAllSubtypes | |
29 throw new UnimplementedError(); | |
30 } | |
31 | |
32 @override | |
33 Future<List<SearchMatch>> searchElementDeclarations(String name) { | |
34 // TODO: implement searchElementDeclarations | |
35 throw new UnimplementedError(); | |
36 } | |
37 | |
38 @override | |
39 Future<List<SearchMatch>> searchMemberDeclarations(String name) { | |
40 // TODO: implement searchMemberDeclarations | |
41 throw new UnimplementedError(); | |
42 } | |
43 | |
44 @override | |
45 Future<List<SearchMatch>> searchMemberReferences(String name) { | |
46 // TODO: implement searchMemberReferences | |
47 throw new UnimplementedError(); | |
48 } | |
49 | |
50 @override | |
51 Future<List<SearchMatch>> searchReferences(Element element) { | |
52 if (element.kind == ElementKind.CLASS) { | |
53 return _searchReferences(element); | |
54 } else if (element.kind == ElementKind.COMPILATION_UNIT) { | |
55 return _searchReferences(element); | |
Brian Wilkerson
2016/03/04 19:34:43
Are the current calls to _searchReferences going t
| |
56 } else if (element.kind == ElementKind.CONSTRUCTOR) { | |
57 return _searchReferences_Constructor(element as ConstructorElement); | |
58 } else if (element.kind == ElementKind.FIELD || | |
59 element.kind == ElementKind.TOP_LEVEL_VARIABLE) { | |
60 return _searchReferences_Field(element as PropertyInducingElement); | |
61 } else if (element.kind == ElementKind.FUNCTION) { | |
62 return _searchReferences_Function(element as FunctionElement); | |
63 } else if (element.kind == ElementKind.GETTER || | |
64 element.kind == ElementKind.SETTER) { | |
65 return _searchReferences(element); | |
66 } else if (element.kind == ElementKind.IMPORT) { | |
67 return _searchReferences(element); | |
68 } else if (element.kind == ElementKind.LABEL) { | |
69 return _searchReferences(element); | |
70 } else if (element.kind == ElementKind.LIBRARY) { | |
71 return _searchReferences(element); | |
72 } else if (element.kind == ElementKind.LOCAL_VARIABLE) { | |
73 return _searchReferences_LocalVariable(element as LocalVariableElement); | |
74 } else if (element.kind == ElementKind.METHOD) { | |
75 return _searchReferences_Method(element as MethodElement); | |
76 } else if (element.kind == ElementKind.PARAMETER) { | |
77 return _searchReferences_Parameter(element as ParameterElement); | |
78 } else if (element.kind == ElementKind.PREFIX) { | |
79 return _searchReferences(element); | |
80 } else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) { | |
81 return _searchReferences(element); | |
82 } else if (element.kind == ElementKind.TYPE_PARAMETER) { | |
83 return _searchReferences_TypeParameter(element); | |
84 } | |
85 return new Future.value(<SearchMatch>[]); | |
86 } | |
87 | |
88 @override | |
89 Future<List<SearchMatch>> searchSubtypes(ClassElement type) { | |
90 // TODO: implement searchSubtypes | |
91 throw new UnimplementedError(); | |
92 } | |
93 | |
94 @override | |
95 Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) { | |
96 // TODO: implement searchTopLevelDeclarations | |
97 throw new UnimplementedError(); | |
98 } | |
99 | |
100 Future<List<SearchMatch>> _searchReferences(Element element) { | |
101 _Requestor requestor = new _Requestor(context, _index); | |
102 requestor.addElement( | |
103 element, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); | |
104 return requestor.merge(); | |
105 } | |
106 | |
107 Future<List<SearchMatch>> _searchReferences_Constructor( | |
108 ConstructorElement constructor) { | |
109 _Requestor requestor = new _Requestor(context, _index); | |
110 requestor.addElement( | |
111 constructor, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); | |
112 return requestor.merge(); | |
113 } | |
114 | |
115 Future<List<SearchMatch>> _searchReferences_Field( | |
116 PropertyInducingElement field) { | |
117 PropertyAccessorElement getter = field.getter; | |
118 PropertyAccessorElement setter = field.setter; | |
119 _Requestor requestor = new _Requestor(context, _index); | |
120 // field itself | |
121 requestor.addElement( | |
122 field, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); | |
123 // getter | |
124 if (getter != null) { | |
125 requestor.addElement( | |
126 getter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.READ); | |
127 requestor.addElement( | |
128 getter, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION); | |
129 } | |
130 // setter | |
131 if (setter != null) { | |
132 requestor.addElement( | |
133 setter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.WRITE); | |
134 } | |
135 // done | |
136 return requestor.merge(); | |
137 } | |
138 | |
139 Future<List<SearchMatch>> _searchReferences_Function( | |
140 FunctionElement function) { | |
141 _Requestor requestor = new _Requestor(context, _index); | |
142 requestor.addElement( | |
143 function, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); | |
144 requestor.addElement( | |
145 function, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION); | |
146 return requestor.merge(); | |
147 } | |
148 | |
149 Future<List<SearchMatch>> _searchReferences_LocalVariable( | |
150 LocalVariableElement variable) { | |
151 // TODO(scheglov) implement using AST visitor | |
152 throw new UnimplementedError(); | |
153 // _Requestor requestor = new _Requestor(context, _index); | |
154 // requestor.addElement(variable, IndexRelationKind.IS_READ_BY, MatchKind.REA D); | |
155 // requestor.addElement( | |
156 // variable, IndexRelationKind.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE); | |
157 // requestor.addElement( | |
158 // variable, IndexRelationKind.IS_WRITTEN_BY, MatchKind.WRITE); | |
159 // requestor.addElement( | |
160 // variable, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION); | |
161 // return requestor.merge(); | |
162 } | |
163 | |
164 Future<List<SearchMatch>> _searchReferences_Method(MethodElement method) { | |
165 _Requestor requestor = new _Requestor(context, _index); | |
166 if (method is MethodMember) { | |
167 method = (method as MethodMember).baseElement; | |
168 } | |
169 requestor.addElement( | |
170 method, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); | |
171 requestor.addElement( | |
172 method, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION); | |
173 return requestor.merge(); | |
174 } | |
175 | |
176 Future<List<SearchMatch>> _searchReferences_Parameter( | |
177 ParameterElement parameter) { | |
178 // TODO(scheglov) implement using AST visitor | |
179 throw new UnimplementedError(); | |
180 // _Requestor requestor = new _Requestor(context, _index); | |
181 // requestor.addElement(parameter, IndexRelationKind.IS_READ_BY, MatchKind.RE AD); | |
182 // requestor.addElement( | |
183 // parameter, IndexRelationKind.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE) ; | |
184 // requestor.addElement( | |
185 // parameter, IndexRelationKind.IS_WRITTEN_BY, MatchKind.WRITE); | |
186 // requestor.addElement( | |
187 // parameter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.REFERENCE); | |
188 // requestor.addElement( | |
189 // parameter, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION); | |
190 // return requestor.merge(); | |
191 } | |
192 | |
193 Future<List<SearchMatch>> _searchReferences_TypeParameter( | |
194 ParameterElement parameter) { | |
195 // TODO(scheglov) implement using AST visitor | |
196 throw new UnimplementedError(); | |
197 } | |
198 } | |
199 | |
200 class _Requestor { | |
201 final AnalysisContext context; | |
202 final Index2 index; | |
203 final List<Future<List<SearchMatch>>> futures = <Future<List<SearchMatch>>>[]; | |
204 | |
205 _Requestor(this.context, this.index); | |
206 | |
207 void addElement( | |
208 Element element, IndexRelationKind relationKind, MatchKind kind) { | |
209 Future relationsFuture = index.getRelations(element, relationKind); | |
210 Future matchesFuture = relationsFuture.then((List<Location> locations) { | |
211 List<SearchMatch> matches = <SearchMatch>[]; | |
212 for (Location location in locations) { | |
213 matches.add(_convertLocation(location, kind)); | |
214 } | |
215 return matches; | |
216 }); | |
217 futures.add(matchesFuture); | |
218 } | |
219 | |
220 // void addElement( | |
221 // Element element, RelationshipImpl relationship, MatchKind kind) { | |
222 // IndexableElement indexable = new IndexableElement(element); | |
223 // add(indexable, relationship, kind); | |
224 // } | |
225 | |
226 Future<List<SearchMatch>> merge() { | |
227 return Future.wait(futures).then((List<List<SearchMatch>> matchesList) { | |
228 return matchesList.expand((matches) => matches).toList(); | |
229 }); | |
230 } | |
231 | |
232 SearchMatch _convertLocation(Location location, MatchKind kind) { | |
233 return new SearchMatch( | |
234 context, | |
235 location.libraryUri, | |
236 location.unitUri, | |
237 kind, | |
238 new SourceRange(location.offset, location.length), | |
239 true, | |
240 location.isQualified); | |
241 } | |
242 } | |
OLD | NEW |