OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library services.src.search.search_engine; | 5 library services.src.search.search_engine; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:analysis_server/analysis/index/index_core.dart'; | 9 import 'package:analysis_server/analysis/index/index_core.dart'; |
10 import 'package:analysis_server/src/services/correction/source_range.dart'; | 10 import 'package:analysis_server/src/services/correction/source_range.dart'; |
11 import 'package:analysis_server/src/services/index/index.dart'; | 11 import 'package:analysis_server/src/services/index/index.dart'; |
12 import 'package:analysis_server/src/services/index/indexable_element.dart'; | 12 import 'package:analysis_server/src/services/index/indexable_element.dart'; |
13 import 'package:analysis_server/src/services/search/search_engine.dart'; | 13 import 'package:analysis_server/src/services/search/search_engine.dart'; |
14 import 'package:analyzer/src/generated/element.dart'; | 14 import 'package:analyzer/src/generated/element.dart'; |
15 import 'package:analyzer/src/generated/source.dart'; | 15 import 'package:analyzer/src/generated/source.dart'; |
16 | 16 |
17 /** | 17 /** |
18 * A [SearchEngine] implementation. | 18 * A [SearchEngine] implementation. |
19 */ | 19 */ |
20 class SearchEngineImpl implements SearchEngine { | 20 class SearchEngineImpl implements SearchEngine { |
21 final Index _index; | 21 final Index _index; |
22 | 22 |
23 SearchEngineImpl(this._index); | 23 SearchEngineImpl(this._index); |
24 | 24 |
25 @override | 25 @override |
26 Future<List<SearchMatch>> searchElementDeclarations(String name) { | 26 Future<List<SearchMatch>> searchElementDeclarations(String name) { |
27 NameElement element = new NameElement(name); | 27 IndexableName indexableName = new IndexableName(name); |
28 _Requestor requestor = new _Requestor(_index); | 28 _Requestor requestor = new _Requestor(_index); |
29 requestor.add( | 29 requestor.add(indexableName, IndexConstants.NAME_IS_DEFINED_BY, |
30 element, IndexConstants.NAME_IS_DEFINED_BY, MatchKind.DECLARATION); | 30 MatchKind.DECLARATION); |
31 return requestor.merge(); | 31 return requestor.merge(); |
32 } | 32 } |
33 | 33 |
34 @override | 34 @override |
35 Future<List<SearchMatch>> searchMemberDeclarations(String name) { | 35 Future<List<SearchMatch>> searchMemberDeclarations(String name) { |
36 return searchElementDeclarations(name).then((matches) { | 36 return searchElementDeclarations(name).then((matches) { |
37 return matches.where((match) { | 37 return matches.where((match) { |
38 return match.element.enclosingElement is ClassElement; | 38 return match.element.enclosingElement is ClassElement; |
39 }).toList(); | 39 }).toList(); |
40 }); | 40 }); |
41 } | 41 } |
42 | 42 |
43 @override | 43 @override |
44 Future<List<SearchMatch>> searchMemberReferences(String name) { | 44 Future<List<SearchMatch>> searchMemberReferences(String name) { |
45 NameElement element = new NameElement(name); | 45 IndexableName indexableName = new IndexableName(name); |
46 _Requestor requestor = new _Requestor(_index); | 46 _Requestor requestor = new _Requestor(_index); |
47 requestor.add(element, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); | |
48 requestor.add(element, IndexConstants.IS_READ_BY, MatchKind.READ); | |
49 requestor.add( | 47 requestor.add( |
50 element, IndexConstants.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE); | 48 indexableName, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); |
51 requestor.add(element, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE); | 49 requestor.add(indexableName, IndexConstants.IS_READ_BY, MatchKind.READ); |
| 50 requestor.add( |
| 51 indexableName, IndexConstants.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE); |
| 52 requestor.add(indexableName, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE); |
52 return requestor.merge(); | 53 return requestor.merge(); |
53 } | 54 } |
54 | 55 |
55 @override | 56 @override |
56 Future<List<SearchMatch>> searchReferences(Element element) { | 57 Future<List<SearchMatch>> searchReferences(Element element) { |
57 if (element.kind == ElementKind.CLASS) { | 58 if (element.kind == ElementKind.CLASS) { |
58 return _searchReferences(element); | 59 return _searchReferences(element); |
59 } else if (element.kind == ElementKind.COMPILATION_UNIT) { | 60 } else if (element.kind == ElementKind.COMPILATION_UNIT) { |
60 return _searchReferences(element); | 61 return _searchReferences(element); |
61 } else if (element.kind == ElementKind.CONSTRUCTOR) { | 62 } else if (element.kind == ElementKind.CONSTRUCTOR) { |
(...skipping 24 matching lines...) Expand all Loading... |
86 return _searchReferences(element); | 87 return _searchReferences(element); |
87 } else if (element.kind == ElementKind.TYPE_PARAMETER) { | 88 } else if (element.kind == ElementKind.TYPE_PARAMETER) { |
88 return _searchReferences(element); | 89 return _searchReferences(element); |
89 } | 90 } |
90 return new Future.value(<SearchMatch>[]); | 91 return new Future.value(<SearchMatch>[]); |
91 } | 92 } |
92 | 93 |
93 @override | 94 @override |
94 Future<List<SearchMatch>> searchSubtypes(ClassElement type) { | 95 Future<List<SearchMatch>> searchSubtypes(ClassElement type) { |
95 _Requestor requestor = new _Requestor(_index); | 96 _Requestor requestor = new _Requestor(_index); |
96 requestor.add(type, IndexConstants.IS_EXTENDED_BY, MatchKind.REFERENCE); | 97 requestor.addElement( |
97 requestor.add(type, IndexConstants.IS_MIXED_IN_BY, MatchKind.REFERENCE); | 98 type, IndexConstants.IS_EXTENDED_BY, MatchKind.REFERENCE); |
98 requestor.add(type, IndexConstants.IS_IMPLEMENTED_BY, MatchKind.REFERENCE); | 99 requestor.addElement( |
| 100 type, IndexConstants.IS_MIXED_IN_BY, MatchKind.REFERENCE); |
| 101 requestor.addElement( |
| 102 type, IndexConstants.IS_IMPLEMENTED_BY, MatchKind.REFERENCE); |
99 return requestor.merge(); | 103 return requestor.merge(); |
100 } | 104 } |
101 | 105 |
102 @override | 106 @override |
103 Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) { | 107 Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) { |
104 RegExp regExp = new RegExp(pattern); | 108 RegExp regExp = new RegExp(pattern); |
105 List<Element> elements = | 109 List<Element> elements = |
106 _index.getTopLevelDeclarations((String name) => regExp.hasMatch(name)); | 110 _index.getTopLevelDeclarations((String name) => regExp.hasMatch(name)); |
107 List<SearchMatch> matches = <SearchMatch>[]; | 111 List<SearchMatch> matches = <SearchMatch>[]; |
108 for (Element element in elements) { | 112 for (Element element in elements) { |
109 matches.add(new SearchMatch(MatchKind.DECLARATION, element, | 113 matches.add(new SearchMatch(MatchKind.DECLARATION, element, |
110 rangeElementName(element), true, false)); | 114 rangeElementName(element), true, false)); |
111 } | 115 } |
112 return new Future.value(matches); | 116 return new Future.value(matches); |
113 } | 117 } |
114 | 118 |
115 Future<List<SearchMatch>> _searchReferences(Element element) { | 119 Future<List<SearchMatch>> _searchReferences(Element element) { |
116 _Requestor requestor = new _Requestor(_index); | 120 _Requestor requestor = new _Requestor(_index); |
117 requestor.add( | 121 requestor.addElement( |
118 element, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); | 122 element, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); |
119 return requestor.merge(); | 123 return requestor.merge(); |
120 } | 124 } |
121 | 125 |
122 Future<List<SearchMatch>> _searchReferences_Constructor( | 126 Future<List<SearchMatch>> _searchReferences_Constructor( |
123 ConstructorElement constructor) { | 127 ConstructorElement constructor) { |
124 _Requestor requestor = new _Requestor(_index); | 128 _Requestor requestor = new _Requestor(_index); |
125 requestor.add( | 129 requestor.addElement( |
126 constructor, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); | 130 constructor, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); |
127 return requestor.merge(); | 131 return requestor.merge(); |
128 } | 132 } |
129 | 133 |
130 Future<List<SearchMatch>> _searchReferences_Field( | 134 Future<List<SearchMatch>> _searchReferences_Field( |
131 PropertyInducingElement field) { | 135 PropertyInducingElement field) { |
132 PropertyAccessorElement getter = field.getter; | 136 PropertyAccessorElement getter = field.getter; |
133 PropertyAccessorElement setter = field.setter; | 137 PropertyAccessorElement setter = field.setter; |
134 _Requestor requestor = new _Requestor(_index); | 138 _Requestor requestor = new _Requestor(_index); |
135 // field itself | 139 // field itself |
136 requestor.add(field, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); | 140 requestor.addElement( |
137 requestor.add(field, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE); | 141 field, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); |
| 142 requestor.addElement(field, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE); |
138 // getter | 143 // getter |
139 if (getter != null) { | 144 if (getter != null) { |
140 requestor.add(getter, IndexConstants.IS_REFERENCED_BY, MatchKind.READ); | 145 requestor.addElement( |
141 requestor.add(getter, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); | 146 getter, IndexConstants.IS_REFERENCED_BY, MatchKind.READ); |
| 147 requestor.addElement( |
| 148 getter, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); |
142 } | 149 } |
143 // setter | 150 // setter |
144 if (setter != null) { | 151 if (setter != null) { |
145 requestor.add(setter, IndexConstants.IS_REFERENCED_BY, MatchKind.WRITE); | 152 requestor.addElement( |
| 153 setter, IndexConstants.IS_REFERENCED_BY, MatchKind.WRITE); |
146 } | 154 } |
147 // done | 155 // done |
148 return requestor.merge(); | 156 return requestor.merge(); |
149 } | 157 } |
150 | 158 |
151 Future<List<SearchMatch>> _searchReferences_Function( | 159 Future<List<SearchMatch>> _searchReferences_Function( |
152 FunctionElement function) { | 160 FunctionElement function) { |
153 _Requestor requestor = new _Requestor(_index); | 161 _Requestor requestor = new _Requestor(_index); |
154 requestor.add( | 162 requestor.addElement( |
155 function, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); | 163 function, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); |
156 requestor.add(function, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); | 164 requestor.addElement( |
| 165 function, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); |
157 return requestor.merge(); | 166 return requestor.merge(); |
158 } | 167 } |
159 | 168 |
160 Future<List<SearchMatch>> _searchReferences_LocalVariable( | 169 Future<List<SearchMatch>> _searchReferences_LocalVariable( |
161 LocalVariableElement variable) { | 170 LocalVariableElement variable) { |
162 _Requestor requestor = new _Requestor(_index); | 171 _Requestor requestor = new _Requestor(_index); |
163 requestor.add(variable, IndexConstants.IS_READ_BY, MatchKind.READ); | 172 requestor.addElement(variable, IndexConstants.IS_READ_BY, MatchKind.READ); |
164 requestor.add( | 173 requestor.addElement( |
165 variable, IndexConstants.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE); | 174 variable, IndexConstants.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE); |
166 requestor.add(variable, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE); | 175 requestor.addElement( |
167 requestor.add(variable, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); | 176 variable, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE); |
| 177 requestor.addElement( |
| 178 variable, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); |
168 return requestor.merge(); | 179 return requestor.merge(); |
169 } | 180 } |
170 | 181 |
171 Future<List<SearchMatch>> _searchReferences_Method(MethodElement method) { | 182 Future<List<SearchMatch>> _searchReferences_Method(MethodElement method) { |
172 _Requestor requestor = new _Requestor(_index); | 183 _Requestor requestor = new _Requestor(_index); |
173 if (method is MethodMember) { | 184 if (method is MethodMember) { |
174 method = (method as MethodMember).baseElement; | 185 method = (method as MethodMember).baseElement; |
175 } | 186 } |
176 requestor.add(method, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); | 187 requestor.addElement( |
177 requestor.add(method, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); | 188 method, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); |
| 189 requestor.addElement( |
| 190 method, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); |
178 return requestor.merge(); | 191 return requestor.merge(); |
179 } | 192 } |
180 | 193 |
181 Future<List<SearchMatch>> _searchReferences_Parameter( | 194 Future<List<SearchMatch>> _searchReferences_Parameter( |
182 ParameterElement parameter) { | 195 ParameterElement parameter) { |
183 _Requestor requestor = new _Requestor(_index); | 196 _Requestor requestor = new _Requestor(_index); |
184 requestor.add(parameter, IndexConstants.IS_READ_BY, MatchKind.READ); | 197 requestor.addElement(parameter, IndexConstants.IS_READ_BY, MatchKind.READ); |
185 requestor.add( | 198 requestor.addElement( |
186 parameter, IndexConstants.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE); | 199 parameter, IndexConstants.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE); |
187 requestor.add(parameter, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE); | 200 requestor.addElement( |
188 requestor.add( | 201 parameter, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE); |
| 202 requestor.addElement( |
189 parameter, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); | 203 parameter, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE); |
190 requestor.add( | 204 requestor.addElement( |
191 parameter, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); | 205 parameter, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION); |
192 return requestor.merge(); | 206 return requestor.merge(); |
193 } | 207 } |
194 } | 208 } |
195 | 209 |
196 class _Requestor { | 210 class _Requestor { |
197 final List<Future<List<SearchMatch>>> futures = <Future<List<SearchMatch>>>[]; | 211 final List<Future<List<SearchMatch>>> futures = <Future<List<SearchMatch>>>[]; |
198 final Index index; | 212 final Index index; |
199 | 213 |
200 _Requestor(this.index); | 214 _Requestor(this.index); |
201 | 215 |
202 void add(Element element, RelationshipImpl relationship, MatchKind kind) { | 216 void add(IndexableObject indexable, RelationshipImpl relationship, |
203 Future relationsFuture = | 217 MatchKind kind) { |
204 index.getRelationships(new IndexableElement(element), relationship); | 218 Future relationsFuture = index.getRelationships(indexable, relationship); |
205 Future matchesFuture = relationsFuture.then((List<LocationImpl> locations) { | 219 Future matchesFuture = relationsFuture.then((List<LocationImpl> locations) { |
206 List<SearchMatch> matches = <SearchMatch>[]; | 220 List<SearchMatch> matches = <SearchMatch>[]; |
207 for (LocationImpl location in locations) { | 221 for (LocationImpl location in locations) { |
208 IndexableObject indexable = location.indexable; | 222 IndexableObject indexable = location.indexable; |
209 if (indexable is IndexableElement) { | 223 if (indexable is IndexableElement) { |
210 matches.add(new SearchMatch( | 224 matches.add(new SearchMatch( |
211 kind, | 225 kind, |
212 indexable.element, | 226 indexable.element, |
213 new SourceRange(location.offset, location.length), | 227 new SourceRange(location.offset, location.length), |
214 location.isResolved, | 228 location.isResolved, |
215 location.isQualified)); | 229 location.isQualified)); |
216 } | 230 } |
217 } | 231 } |
218 return matches; | 232 return matches; |
219 }); | 233 }); |
220 futures.add(matchesFuture); | 234 futures.add(matchesFuture); |
221 } | 235 } |
222 | 236 |
| 237 void addElement( |
| 238 Element element, RelationshipImpl relationship, MatchKind kind) { |
| 239 IndexableElement indexable = new IndexableElement(element); |
| 240 add(indexable, relationship, kind); |
| 241 } |
| 242 |
223 Future<List<SearchMatch>> merge() { | 243 Future<List<SearchMatch>> merge() { |
224 return Future.wait(futures).then((List<List<SearchMatch>> matchesList) { | 244 return Future.wait(futures).then((List<List<SearchMatch>> matchesList) { |
225 return matchesList.expand((matches) => matches).toList(); | 245 return matchesList.expand((matches) => matches).toList(); |
226 }); | 246 }); |
227 } | 247 } |
228 } | 248 } |
OLD | NEW |