OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 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 | 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 import 'dart:async'; | 5 import 'dart:async'; |
6 | 6 |
7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
8 import 'package:analyzer/dart/element/element.dart'; | 8 import 'package:analyzer/dart/element/element.dart'; |
9 import 'package:analyzer/src/generated/source.dart'; | 9 import 'package:analyzer/src/generated/source.dart'; |
10 import 'package:analyzer/src/summary/format.dart'; | 10 import 'package:analyzer/src/summary/format.dart'; |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 | 215 |
216 /** | 216 /** |
217 * Helper for requesting information from a single [PackageIndex]. | 217 * Helper for requesting information from a single [PackageIndex]. |
218 */ | 218 */ |
219 class _PackageIndexRequester { | 219 class _PackageIndexRequester { |
220 final PackageIndex index; | 220 final PackageIndex index; |
221 | 221 |
222 _PackageIndexRequester(this.index); | 222 _PackageIndexRequester(this.index); |
223 | 223 |
224 /** | 224 /** |
225 * Return the [element]'s identifier in the [index] or `null` if the | 225 * Return the [element]'s identifier in the [index] or `-1` if the |
226 * [element] is not referenced in the [index]. | 226 * [element] is not referenced in the [index]. |
227 */ | 227 */ |
228 int findElementId(Element element) { | 228 int findElementId(Element element) { |
229 // Find the id of the element's unit. | 229 // Find the id of the element's unit. |
230 int unitId = getUnitId(element); | 230 int unitId = getUnitId(element); |
231 if (unitId == null) { | 231 if (unitId == -1) { |
232 return null; | 232 return -1; |
233 } | 233 } |
234 // Prepare the offset of the element. | 234 // Prepare the offset of the element. |
235 int offset = element.nameOffset; | 235 int offset = element.nameOffset; |
236 if (element is LibraryElement || element is CompilationUnitElement) { | 236 if (element is LibraryElement || element is CompilationUnitElement) { |
237 offset = 0; | 237 offset = 0; |
238 } | 238 } |
239 // Find the first occurrence of an element with the same offset. | 239 // Find the first occurrence of an element with the same offset. |
240 int elementId = _findFirstOccurrence(index.elementOffsets, offset); | 240 int elementId = _findFirstOccurrence(index.elementOffsets, offset); |
241 if (elementId == -1) { | 241 if (elementId == -1) { |
242 return null; | 242 return -1; |
243 } | 243 } |
244 // Try to find the element id using offset, unit and kind. | 244 // Try to find the element id using offset, unit and kind. |
245 IndexSyntheticElementKind kind = | 245 IndexSyntheticElementKind kind = |
246 PackageIndexAssembler.getIndexElementKind(element); | 246 PackageIndexAssembler.getIndexElementKind(element); |
247 for (; | 247 for (; |
248 elementId < index.elementOffsets.length && | 248 elementId < index.elementOffsets.length && |
249 index.elementOffsets[elementId] == offset; | 249 index.elementOffsets[elementId] == offset; |
250 elementId++) { | 250 elementId++) { |
251 if (index.elementUnits[elementId] == unitId && | 251 if (index.elementUnits[elementId] == unitId && |
252 index.elementKinds[elementId] == kind) { | 252 index.elementKinds[elementId] == kind) { |
253 return elementId; | 253 return elementId; |
254 } | 254 } |
255 } | 255 } |
256 return null; | 256 return -1; |
257 } | 257 } |
258 | 258 |
259 /** | 259 /** |
260 * Complete with a list of locations where elements of the given [kind] with | 260 * Complete with a list of locations where elements of the given [kind] with |
261 * names satisfying the given [regExp] are defined. | 261 * names satisfying the given [regExp] are defined. |
262 */ | 262 */ |
263 List<Location> getDefinedNames(RegExp regExp, IndexNameKind kind) { | 263 List<Location> getDefinedNames(RegExp regExp, IndexNameKind kind) { |
264 List<Location> locations = <Location>[]; | 264 List<Location> locations = <Location>[]; |
265 for (UnitIndex unitIndex in index.units) { | 265 for (UnitIndex unitIndex in index.units) { |
266 _UnitIndexRequester requester = new _UnitIndexRequester(this, unitIndex); | 266 _UnitIndexRequester requester = new _UnitIndexRequester(this, unitIndex); |
267 List<Location> unitLocations = requester.getDefinedNames(regExp, kind); | 267 List<Location> unitLocations = requester.getDefinedNames(regExp, kind); |
268 locations.addAll(unitLocations); | 268 locations.addAll(unitLocations); |
269 } | 269 } |
270 return locations; | 270 return locations; |
271 } | 271 } |
272 | 272 |
273 /** | 273 /** |
274 * Complete with a list of locations where the given [element] has relation | 274 * Complete with a list of locations where the given [element] has relation |
275 * of the given [kind]. | 275 * of the given [kind]. |
276 */ | 276 */ |
277 List<Location> getRelations(Element element, IndexRelationKind kind) { | 277 List<Location> getRelations(Element element, IndexRelationKind kind) { |
278 int elementId = findElementId(element); | 278 int elementId = findElementId(element); |
279 if (elementId == null) { | 279 if (elementId == -1) { |
280 return const <Location>[]; | 280 return const <Location>[]; |
281 } | 281 } |
282 List<Location> locations = <Location>[]; | 282 List<Location> locations = <Location>[]; |
283 for (UnitIndex unitIndex in index.units) { | 283 for (UnitIndex unitIndex in index.units) { |
284 _UnitIndexRequester requester = new _UnitIndexRequester(this, unitIndex); | 284 _UnitIndexRequester requester = new _UnitIndexRequester(this, unitIndex); |
285 List<Location> unitLocations = requester.getRelations(elementId, kind); | 285 List<Location> unitLocations = requester.getRelations(elementId, kind); |
286 locations.addAll(unitLocations); | 286 locations.addAll(unitLocations); |
287 } | 287 } |
288 return locations; | 288 return locations; |
289 } | 289 } |
290 | 290 |
291 /** | 291 /** |
292 * Return the identifier of [str] in the [index] or `-1` if [str] is not used | 292 * Return the identifier of [str] in the [index] or `-1` if [str] is not used |
293 * in the [index]. | 293 * in the [index]. |
294 */ | 294 */ |
295 int getStringId(String str) { | 295 int getStringId(String str) { |
296 return index.strings.indexOf(str); | 296 return binarySearch(index.strings, str); |
297 } | 297 } |
298 | 298 |
299 /** | 299 /** |
300 * Return the identifier of the [CompilationUnitElement] containing the | 300 * Return the identifier of the [CompilationUnitElement] containing the |
301 * [element] in the [index] or `-1` if not found. | 301 * [element] in the [index] or `-1` if not found. |
302 */ | 302 */ |
303 int getUnitId(Element element) { | 303 int getUnitId(Element element) { |
304 CompilationUnitElement unitElement = | 304 CompilationUnitElement unitElement = |
305 PackageIndexAssembler.getUnitElement(element); | 305 PackageIndexAssembler.getUnitElement(element); |
306 int libraryUriId = getUriId(unitElement.library.source.uri); | 306 int libraryUriId = getUriId(unitElement.library.source.uri); |
| 307 if (libraryUriId == -1) { |
| 308 return -1; |
| 309 } |
307 int unitUriId = getUriId(unitElement.source.uri); | 310 int unitUriId = getUriId(unitElement.source.uri); |
| 311 if (unitUriId == -1) { |
| 312 return -1; |
| 313 } |
308 for (int i = 0; i < index.unitLibraryUris.length; i++) { | 314 for (int i = 0; i < index.unitLibraryUris.length; i++) { |
309 if (index.unitLibraryUris[i] == libraryUriId && | 315 if (index.unitLibraryUris[i] == libraryUriId && |
310 index.unitUnitUris[i] == unitUriId) { | 316 index.unitUnitUris[i] == unitUriId) { |
311 return i; | 317 return i; |
312 } | 318 } |
313 } | 319 } |
314 return -1; | 320 return -1; |
315 } | 321 } |
316 | 322 |
317 /** | 323 /** |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 } | 423 } |
418 } | 424 } |
419 return locations; | 425 return locations; |
420 } | 426 } |
421 | 427 |
422 /** | 428 /** |
423 * Complete with a list of locations where a class members with the given | 429 * Complete with a list of locations where a class members with the given |
424 * [name] is referenced with a qualifier, but is not resolved. | 430 * [name] is referenced with a qualifier, but is not resolved. |
425 */ | 431 */ |
426 List<Location> getUnresolvedMemberReferences(String name) { | 432 List<Location> getUnresolvedMemberReferences(String name) { |
| 433 // Find the name ID in the package index. |
| 434 int nameId = packageRequester.getStringId(name); |
| 435 if (nameId == -1) { |
| 436 return const <Location>[]; |
| 437 } |
| 438 // Find the first usage of the name. |
| 439 int i =_findFirstOccurrence(unitIndex.usedNames, nameId); |
| 440 if (i == -1) { |
| 441 return const <Location>[]; |
| 442 } |
| 443 // Create locations for every usage of the name. |
427 List<Location> locations = <Location>[]; | 444 List<Location> locations = <Location>[]; |
428 String unitLibraryUri = null; | 445 String unitLibraryUri = null; |
429 String unitUnitUri = null; | 446 String unitUnitUri = null; |
430 for (int i = 0; i < unitIndex.usedNames.length; i++) { | 447 for (; i < unitIndex.usedNames.length && |
431 int nameIndex = unitIndex.usedNames[i]; | 448 unitIndex.usedNames[i] == nameId; i++) { |
432 if (packageRequester.index.strings[nameIndex] == name) { | 449 unitLibraryUri ??= packageRequester.getUnitLibraryUri(unitIndex.unit); |
433 unitLibraryUri ??= packageRequester.getUnitLibraryUri(unitIndex.unit); | 450 unitUnitUri ??= packageRequester.getUnitUnitUri(unitIndex.unit); |
434 unitUnitUri ??= packageRequester.getUnitUnitUri(unitIndex.unit); | 451 locations.add(new Location(unitLibraryUri, unitUnitUri, |
435 locations.add(new Location(unitLibraryUri, unitUnitUri, | 452 unitIndex.usedNameOffsets[i], name.length, true)); |
436 unitIndex.usedNameOffsets[i], name.length, true)); | |
437 } | |
438 } | 453 } |
439 return locations; | 454 return locations; |
440 } | 455 } |
441 } | 456 } |
OLD | NEW |