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.search_engine; | 5 library services.search_engine; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:analysis_server/src/services/index/index.dart'; | 9 import 'package:analysis_server/src/services/index/index.dart'; |
10 import 'package:analysis_server/src/services/search/search_engine_internal.dart'
; | 10 import 'package:analysis_server/src/services/search/search_engine_internal.dart'
; |
11 import 'package:analyzer/dart/element/element.dart'; | 11 import 'package:analyzer/dart/element/element.dart'; |
| 12 import 'package:analyzer/dart/element/visitor.dart'; |
| 13 import 'package:analyzer/src/dart/element/element.dart'; |
| 14 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; |
12 import 'package:analyzer/src/generated/java_core.dart'; | 15 import 'package:analyzer/src/generated/java_core.dart'; |
13 import 'package:analyzer/src/generated/source.dart'; | 16 import 'package:analyzer/src/generated/source.dart'; |
14 | 17 |
15 /** | 18 /** |
16 * Returns a new [SearchEngine] instance based on the given [Index]. | 19 * Returns a new [SearchEngine] instance based on the given [Index]. |
17 */ | 20 */ |
18 SearchEngine createSearchEngine(Index index) { | 21 SearchEngine createSearchEngine(Index index) { |
19 return new SearchEngineImpl(index); | 22 return new SearchEngineImpl(index); |
20 } | 23 } |
21 | 24 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 */ | 121 */ |
119 Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern); | 122 Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern); |
120 } | 123 } |
121 | 124 |
122 /** | 125 /** |
123 * Instances of the class [SearchMatch] represent a match found by | 126 * Instances of the class [SearchMatch] represent a match found by |
124 * [SearchEngine]. | 127 * [SearchEngine]. |
125 */ | 128 */ |
126 class SearchMatch { | 129 class SearchMatch { |
127 /** | 130 /** |
| 131 * The [AnalysisContext] containing the match. |
| 132 */ |
| 133 final AnalysisContext context; |
| 134 |
| 135 /** |
| 136 * The URI of the source of the library containing the match. |
| 137 */ |
| 138 final String libraryUri; |
| 139 |
| 140 /** |
| 141 * The URI of the source of the unit containing the match. |
| 142 */ |
| 143 final String unitUri; |
| 144 |
| 145 /** |
128 * The kind of the match. | 146 * The kind of the match. |
129 */ | 147 */ |
130 final MatchKind kind; | 148 final MatchKind kind; |
131 | 149 |
132 /** | 150 /** |
133 * The element containing the source range that was matched. | |
134 */ | |
135 final Element element; | |
136 | |
137 /** | |
138 * The source range that was matched. | 151 * The source range that was matched. |
139 */ | 152 */ |
140 final SourceRange sourceRange; | 153 final SourceRange sourceRange; |
141 | 154 |
142 /** | 155 /** |
143 * Is `true` if the match is a resolved reference to some [Element]. | 156 * Is `true` if the match is a resolved reference to some [Element]. |
144 */ | 157 */ |
145 final bool isResolved; | 158 final bool isResolved; |
146 | 159 |
147 /** | 160 /** |
148 * Is `true` if field or method access is done using qualifier. | 161 * Is `true` if field or method access is done using qualifier. |
149 */ | 162 */ |
150 final bool isQualified; | 163 final bool isQualified; |
151 | 164 |
152 SearchMatch(this.kind, this.element, this.sourceRange, this.isResolved, | 165 Source _librarySource; |
153 this.isQualified); | 166 Source _unitSource; |
| 167 LibraryElement _libraryElement; |
| 168 Element _element; |
| 169 |
| 170 SearchMatch(this.context, this.libraryUri, this.unitUri, this.kind, |
| 171 this.sourceRange, this.isResolved, this.isQualified); |
| 172 |
| 173 /** |
| 174 * Return the [Element] containing the match. |
| 175 */ |
| 176 Element get element { |
| 177 if (_element == null) { |
| 178 CompilationUnitElement unitElement = |
| 179 context.getCompilationUnitElement(unitSource, librarySource); |
| 180 _ContainingElementFinder finder = |
| 181 new _ContainingElementFinder(sourceRange.offset); |
| 182 unitElement.accept(finder); |
| 183 _element = finder.containingElement; |
| 184 } |
| 185 return _element; |
| 186 } |
| 187 |
| 188 /** |
| 189 * The absolute path of the file containing the match. |
| 190 */ |
| 191 String get file => unitSource.fullName; |
154 | 192 |
155 @override | 193 @override |
156 int get hashCode => JavaArrays.makeHashCode([element, sourceRange, kind]); | 194 int get hashCode => |
| 195 JavaArrays.makeHashCode([libraryUri, unitUri, kind, sourceRange]); |
| 196 |
| 197 /** |
| 198 * Return the [LibraryElement] for the [libraryUri] in the [context]. |
| 199 */ |
| 200 LibraryElement get libraryElement { |
| 201 _libraryElement ??= context.getLibraryElement(librarySource); |
| 202 return _libraryElement; |
| 203 } |
| 204 |
| 205 /** |
| 206 * The library [Source] of the reference. |
| 207 */ |
| 208 Source get librarySource { |
| 209 _librarySource ??= context.sourceFactory.forUri(libraryUri); |
| 210 return _librarySource; |
| 211 } |
| 212 |
| 213 /** |
| 214 * The unit [Source] of the reference. |
| 215 */ |
| 216 Source get unitSource { |
| 217 _unitSource ??= context.sourceFactory.forUri(unitUri); |
| 218 return _unitSource; |
| 219 } |
157 | 220 |
158 @override | 221 @override |
159 bool operator ==(Object object) { | 222 bool operator ==(Object object) { |
160 if (identical(object, this)) { | 223 if (identical(object, this)) { |
161 return true; | 224 return true; |
162 } | 225 } |
163 if (object is SearchMatch) { | 226 if (object is SearchMatch) { |
164 return kind == object.kind && | 227 return kind == object.kind && |
| 228 libraryUri == object.libraryUri && |
| 229 unitUri == object.unitUri && |
165 isResolved == object.isResolved && | 230 isResolved == object.isResolved && |
166 isQualified == object.isQualified && | 231 isQualified == object.isQualified && |
167 sourceRange == object.sourceRange && | 232 sourceRange == object.sourceRange; |
168 element == object.element; | |
169 } | 233 } |
170 return false; | 234 return false; |
171 } | 235 } |
172 | 236 |
173 @override | 237 @override |
174 String toString() { | 238 String toString() { |
175 StringBuffer buffer = new StringBuffer(); | 239 StringBuffer buffer = new StringBuffer(); |
176 buffer.write("SearchMatch(kind="); | 240 buffer.write("SearchMatch(kind="); |
177 buffer.write(kind); | 241 buffer.write(kind); |
178 buffer.write(", element="); | 242 buffer.write(", libraryUri="); |
179 buffer.write(element.displayName); | 243 buffer.write(libraryUri); |
| 244 buffer.write(", unitUri="); |
| 245 buffer.write(unitUri); |
180 buffer.write(", range="); | 246 buffer.write(", range="); |
181 buffer.write(sourceRange); | 247 buffer.write(sourceRange); |
182 buffer.write(", isResolved="); | 248 buffer.write(", isResolved="); |
183 buffer.write(isResolved); | 249 buffer.write(isResolved); |
184 buffer.write(", isQualified="); | 250 buffer.write(", isQualified="); |
185 buffer.write(isQualified); | 251 buffer.write(isQualified); |
186 buffer.write(")"); | 252 buffer.write(")"); |
187 return buffer.toString(); | 253 return buffer.toString(); |
188 } | 254 } |
189 } | 255 } |
| 256 |
| 257 /** |
| 258 * A visitor that finds the deep-most [Element] that contains the [offset]. |
| 259 */ |
| 260 class _ContainingElementFinder extends GeneralizingElementVisitor { |
| 261 final int offset; |
| 262 Element containingElement; |
| 263 |
| 264 _ContainingElementFinder(this.offset); |
| 265 |
| 266 visitElement(Element element) { |
| 267 if (element is ElementImpl) { |
| 268 if (element.codeOffset != null && |
| 269 element.codeOffset <= offset && |
| 270 offset <= element.codeOffset + element.codeLength) { |
| 271 containingElement = element; |
| 272 super.visitElement(element); |
| 273 } |
| 274 } |
| 275 } |
| 276 } |
OLD | NEW |