| 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 |