| 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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
| 6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
| 7 | 7 |
| 8 library engine.index; | 8 library engine.index; |
| 9 | 9 |
| 10 import 'dart:collection' show Queue; | 10 import 'dart:collection' show Queue; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 * @return `true` if this operation should be removed from the operation queue
as a | 86 * @return `true` if this operation should be removed from the operation queue
as a |
| 87 * result of removing the resource | 87 * result of removing the resource |
| 88 */ | 88 */ |
| 89 bool removeWhenSourceRemoved(Source source); | 89 bool removeWhenSourceRemoved(Source source); |
| 90 } | 90 } |
| 91 | 91 |
| 92 /** | 92 /** |
| 93 * [IndexStore] which keeps full index in memory. | 93 * [IndexStore] which keeps full index in memory. |
| 94 */ | 94 */ |
| 95 class MemoryIndexStoreImpl implements MemoryIndexStore { | 95 class MemoryIndexStoreImpl implements MemoryIndexStore { |
| 96 static Object _WEAK_SET_VALUE = new Object(); | |
| 97 | |
| 98 /** | 96 /** |
| 99 * When logging is on, [AnalysisEngine] actually creates | 97 * When logging is on, [AnalysisEngine] actually creates |
| 100 * [InstrumentedAnalysisContextImpl], which wraps [AnalysisContextImpl] used t
o create | 98 * [InstrumentedAnalysisContextImpl], which wraps [AnalysisContextImpl] used t
o create |
| 101 * actual [Element]s. So, in index we have to unwrap [InstrumentedAnalysisCont
extImpl] | 99 * actual [Element]s. So, in index we have to unwrap [InstrumentedAnalysisCont
extImpl] |
| 102 * when perform any operation. | 100 * when perform any operation. |
| 103 */ | 101 */ |
| 104 static AnalysisContext unwrapContext(AnalysisContext context) { | 102 static AnalysisContext unwrapContext(AnalysisContext context) { |
| 105 if (context is InstrumentedAnalysisContextImpl) { | 103 if (context is InstrumentedAnalysisContextImpl) { |
| 106 context = (context as InstrumentedAnalysisContextImpl).basis; | 104 context = (context as InstrumentedAnalysisContextImpl).basis; |
| 107 } | 105 } |
| 108 return context; | 106 return context; |
| 109 } | 107 } |
| 110 | 108 |
| 111 /** | 109 /** |
| 112 * @return the [Source] of the enclosing [LibraryElement], may be `null`. | 110 * @return the [Source] of the enclosing [LibraryElement], may be `null`. |
| 113 */ | 111 */ |
| 114 static Source _getLibrarySourceOrNull(Element element) { | 112 static Source _getLibrarySourceOrNull(Element element) { |
| 115 LibraryElement library = element.library; | 113 LibraryElement library = element.library; |
| 116 if (library == null) { | 114 if (library == null) { |
| 117 return null; | 115 return null; |
| 118 } | 116 } |
| 119 if (library.isAngularHtml) { | 117 if (library.isAngularHtml) { |
| 120 return null; | 118 return null; |
| 121 } | 119 } |
| 122 return library.source; | 120 return library.source; |
| 123 } | 121 } |
| 124 | 122 |
| 125 /** | 123 /** |
| 126 * We add [AnalysisContext] to this weak set to ensure that we don't continue
to add | |
| 127 * relationships after some context was removed using [removeContext]. | |
| 128 */ | |
| 129 Expando _removedContexts = new Expando(); | |
| 130 | |
| 131 /** | |
| 132 * This map is used to canonicalize equal keys. | 124 * This map is used to canonicalize equal keys. |
| 133 */ | 125 */ |
| 134 Map<MemoryIndexStoreImpl_ElementRelationKey, MemoryIndexStoreImpl_ElementRelat
ionKey> _canonicalKeys = {}; | 126 Map<MemoryIndexStoreImpl_ElementRelationKey, MemoryIndexStoreImpl_ElementRelat
ionKey> _canonicalKeys = {}; |
| 135 | 127 |
| 136 /** | 128 /** |
| 137 * The mapping of [ElementRelationKey] to the [Location]s, one-to-many. | 129 * The mapping of [ElementRelationKey] to the [Location]s, one-to-many. |
| 138 */ | 130 */ |
| 139 Map<MemoryIndexStoreImpl_ElementRelationKey, Set<Location>> _keyToLocations =
{}; | 131 Map<MemoryIndexStoreImpl_ElementRelationKey, Set<Location>> _keyToLocations =
{}; |
| 140 | 132 |
| 141 /** | 133 /** |
| (...skipping 21 matching lines...) Expand all Loading... |
| 163 Map<AnalysisContext, Map<Source, Set<Source>>> _contextToUnitToLibraries = {}; | 155 Map<AnalysisContext, Map<Source, Set<Source>>> _contextToUnitToLibraries = {}; |
| 164 | 156 |
| 165 int _sourceCount = 0; | 157 int _sourceCount = 0; |
| 166 | 158 |
| 167 int _keyCount = 0; | 159 int _keyCount = 0; |
| 168 | 160 |
| 169 int _locationCount = 0; | 161 int _locationCount = 0; |
| 170 | 162 |
| 171 bool aboutToIndexDart(AnalysisContext context, CompilationUnitElement unitElem
ent) { | 163 bool aboutToIndexDart(AnalysisContext context, CompilationUnitElement unitElem
ent) { |
| 172 context = unwrapContext(context); | 164 context = unwrapContext(context); |
| 173 // may be already removed in other thread | 165 // may be already disposed in other thread |
| 174 if (_isRemovedContext(context)) { | 166 if (context.isDisposed) { |
| 175 return false; | 167 return false; |
| 176 } | 168 } |
| 177 // validate unit | 169 // validate unit |
| 178 if (unitElement == null) { | 170 if (unitElement == null) { |
| 179 return false; | 171 return false; |
| 180 } | 172 } |
| 181 LibraryElement libraryElement = unitElement.library; | 173 LibraryElement libraryElement = unitElement.library; |
| 182 if (libraryElement == null) { | 174 if (libraryElement == null) { |
| 183 return false; | 175 return false; |
| 184 } | 176 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 _sourceCount--; | 219 _sourceCount--; |
| 228 } | 220 } |
| 229 } | 221 } |
| 230 } | 222 } |
| 231 // OK, we can index | 223 // OK, we can index |
| 232 return true; | 224 return true; |
| 233 } | 225 } |
| 234 | 226 |
| 235 bool aboutToIndexHtml(AnalysisContext context, HtmlElement htmlElement) { | 227 bool aboutToIndexHtml(AnalysisContext context, HtmlElement htmlElement) { |
| 236 context = unwrapContext(context); | 228 context = unwrapContext(context); |
| 237 // may be already removed in other thread | 229 // may be already disposed in other thread |
| 238 if (_isRemovedContext(context)) { | 230 if (context.isDisposed) { |
| 239 return false; | 231 return false; |
| 240 } | 232 } |
| 241 // remove locations | 233 // remove locations |
| 242 Source source = htmlElement.source; | 234 Source source = htmlElement.source; |
| 243 _removeLocations(context, null, source); | 235 _removeLocations(context, null, source); |
| 244 // remove keys | 236 // remove keys |
| 245 { | 237 { |
| 246 Map<MemoryIndexStoreImpl_Source2, Set<MemoryIndexStoreImpl_ElementRelation
Key>> sourceToKeys = _contextToSourceToKeys[context]; | 238 Map<MemoryIndexStoreImpl_Source2, Set<MemoryIndexStoreImpl_ElementRelation
Key>> sourceToKeys = _contextToSourceToKeys[context]; |
| 247 if (sourceToKeys != null) { | 239 if (sourceToKeys != null) { |
| 248 MemoryIndexStoreImpl_Source2 source2 = new MemoryIndexStoreImpl_Source2(
null, source); | 240 MemoryIndexStoreImpl_Source2 source2 = new MemoryIndexStoreImpl_Source2(
null, source); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 } | 318 } |
| 327 if (locationSource == null) { | 319 if (locationSource == null) { |
| 328 return; | 320 return; |
| 329 } | 321 } |
| 330 if (elementContext == null && element is! NameElementImpl && element is! Uni
verseElementImpl) { | 322 if (elementContext == null && element is! NameElementImpl && element is! Uni
verseElementImpl) { |
| 331 return; | 323 return; |
| 332 } | 324 } |
| 333 if (elementSource == null && element is! NameElementImpl && element is! Univ
erseElementImpl) { | 325 if (elementSource == null && element is! NameElementImpl && element is! Univ
erseElementImpl) { |
| 334 return; | 326 return; |
| 335 } | 327 } |
| 336 // may be already removed in other thread | 328 // may be already disposed in other thread |
| 337 if (_isRemovedContext(elementContext)) { | 329 if (elementContext != null && elementContext.isDisposed) { |
| 338 return; | 330 return; |
| 339 } | 331 } |
| 340 if (_isRemovedContext(locationContext)) { | 332 if (locationContext.isDisposed) { |
| 341 return; | 333 return; |
| 342 } | 334 } |
| 343 // record: key -> location(s) | 335 // record: key -> location(s) |
| 344 MemoryIndexStoreImpl_ElementRelationKey key = _getCanonicalKey(element, rela
tionship); | 336 MemoryIndexStoreImpl_ElementRelationKey key = _getCanonicalKey(element, rela
tionship); |
| 345 { | 337 { |
| 346 Set<Location> locations = _keyToLocations.remove(key); | 338 Set<Location> locations = _keyToLocations.remove(key); |
| 347 if (locations == null) { | 339 if (locations == null) { |
| 348 locations = _createLocationIdentitySet(); | 340 locations = _createLocationIdentitySet(); |
| 349 } else { | 341 } else { |
| 350 _keyCount--; | 342 _keyCount--; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 } | 381 } |
| 390 locations.add(location); | 382 locations.add(location); |
| 391 } | 383 } |
| 392 } | 384 } |
| 393 | 385 |
| 394 void removeContext(AnalysisContext context) { | 386 void removeContext(AnalysisContext context) { |
| 395 context = unwrapContext(context); | 387 context = unwrapContext(context); |
| 396 if (context == null) { | 388 if (context == null) { |
| 397 return; | 389 return; |
| 398 } | 390 } |
| 399 // mark as removed | 391 // remove sources |
| 400 _markRemovedContext(context); | |
| 401 removeSources(context, null); | 392 removeSources(context, null); |
| 402 // remove context | 393 // remove context |
| 403 _contextToSourceToKeys.remove(context); | 394 _contextToSourceToKeys.remove(context); |
| 404 _contextToSourceToLocations.remove(context); | 395 _contextToSourceToLocations.remove(context); |
| 405 _contextToLibraryToUnits.remove(context); | 396 _contextToLibraryToUnits.remove(context); |
| 406 _contextToUnitToLibraries.remove(context); | 397 _contextToUnitToLibraries.remove(context); |
| 407 } | 398 } |
| 408 | 399 |
| 409 void removeSource(AnalysisContext context, Source unit) { | 400 void removeSource(AnalysisContext context, Source unit) { |
| 410 context = unwrapContext(context); | 401 context = unwrapContext(context); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 MemoryIndexStoreImpl_ElementRelationKey _getCanonicalKey(Element element, Rela
tionship relationship) { | 473 MemoryIndexStoreImpl_ElementRelationKey _getCanonicalKey(Element element, Rela
tionship relationship) { |
| 483 MemoryIndexStoreImpl_ElementRelationKey key = new MemoryIndexStoreImpl_Eleme
ntRelationKey(element, relationship); | 474 MemoryIndexStoreImpl_ElementRelationKey key = new MemoryIndexStoreImpl_Eleme
ntRelationKey(element, relationship); |
| 484 MemoryIndexStoreImpl_ElementRelationKey canonicalKey = _canonicalKeys[key]; | 475 MemoryIndexStoreImpl_ElementRelationKey canonicalKey = _canonicalKeys[key]; |
| 485 if (canonicalKey == null) { | 476 if (canonicalKey == null) { |
| 486 canonicalKey = key; | 477 canonicalKey = key; |
| 487 _canonicalKeys[key] = canonicalKey; | 478 _canonicalKeys[key] = canonicalKey; |
| 488 } | 479 } |
| 489 return canonicalKey; | 480 return canonicalKey; |
| 490 } | 481 } |
| 491 | 482 |
| 492 /** | |
| 493 * Checks if given [AnalysisContext] is marked as removed. | |
| 494 */ | |
| 495 bool _isRemovedContext(AnalysisContext context) => _removedContexts[context] !
= null; | |
| 496 | |
| 497 /** | |
| 498 * Marks given [AnalysisContext] as removed. | |
| 499 */ | |
| 500 void _markRemovedContext(AnalysisContext context) { | |
| 501 _removedContexts[context] = true; | |
| 502 } | |
| 503 | |
| 504 void _recordUnitInLibrary(AnalysisContext context, Source library, Source unit
) { | 483 void _recordUnitInLibrary(AnalysisContext context, Source library, Source unit
) { |
| 505 Map<Source, Set<Source>> unitToLibraries = _contextToUnitToLibraries[context
]; | 484 Map<Source, Set<Source>> unitToLibraries = _contextToUnitToLibraries[context
]; |
| 506 if (unitToLibraries == null) { | 485 if (unitToLibraries == null) { |
| 507 unitToLibraries = {}; | 486 unitToLibraries = {}; |
| 508 _contextToUnitToLibraries[context] = unitToLibraries; | 487 _contextToUnitToLibraries[context] = unitToLibraries; |
| 509 } | 488 } |
| 510 Set<Source> libraries = unitToLibraries[unit]; | 489 Set<Source> libraries = unitToLibraries[unit]; |
| 511 if (libraries == null) { | 490 if (libraries == null) { |
| 512 libraries = new Set(); | 491 libraries = new Set(); |
| 513 unitToLibraries[unit] = libraries; | 492 unitToLibraries[unit] = libraries; |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 * Return the unique identifier for this relationship. | 732 * Return the unique identifier for this relationship. |
| 754 * | 733 * |
| 755 * @return the unique identifier for this relationship | 734 * @return the unique identifier for this relationship |
| 756 */ | 735 */ |
| 757 String get identifier => _uniqueId; | 736 String get identifier => _uniqueId; |
| 758 | 737 |
| 759 String toString() => _uniqueId; | 738 String toString() => _uniqueId; |
| 760 } | 739 } |
| 761 | 740 |
| 762 /** | 741 /** |
| 763 * Implementation of [Index]. | |
| 764 */ | |
| 765 class IndexImpl implements Index { | |
| 766 IndexStore _store; | |
| 767 | |
| 768 OperationQueue _queue; | |
| 769 | |
| 770 OperationProcessor _processor; | |
| 771 | |
| 772 IndexImpl(IndexStore store, OperationQueue queue, OperationProcessor processor
) { | |
| 773 this._store = store; | |
| 774 this._queue = queue; | |
| 775 this._processor = processor; | |
| 776 } | |
| 777 | |
| 778 void getRelationships(Element element, Relationship relationship, Relationship
Callback callback) { | |
| 779 _queue.enqueue(new GetRelationshipsOperation(_store, element, relationship,
callback)); | |
| 780 } | |
| 781 | |
| 782 String get statistics => _store.statistics; | |
| 783 | |
| 784 void indexHtmlUnit(AnalysisContext context, ht.HtmlUnit unit) { | |
| 785 if (unit == null) { | |
| 786 return; | |
| 787 } | |
| 788 if (unit.element == null) { | |
| 789 return; | |
| 790 } | |
| 791 if (unit.element.angularCompilationUnit == null) { | |
| 792 return; | |
| 793 } | |
| 794 _queue.enqueue(new IndexHtmlUnitOperation(_store, context, unit)); | |
| 795 } | |
| 796 | |
| 797 void indexUnit(AnalysisContext context, CompilationUnit unit) { | |
| 798 if (unit == null) { | |
| 799 return; | |
| 800 } | |
| 801 if (unit.element == null) { | |
| 802 return; | |
| 803 } | |
| 804 _queue.enqueue(new IndexUnitOperation(_store, context, unit)); | |
| 805 } | |
| 806 | |
| 807 void removeContext(AnalysisContext context) { | |
| 808 _queue.enqueue(new RemoveContextOperation(_store, context)); | |
| 809 } | |
| 810 | |
| 811 void removeSource(AnalysisContext context, Source source) { | |
| 812 _queue.enqueue(new RemoveSourceOperation(_store, context, source)); | |
| 813 } | |
| 814 | |
| 815 void removeSources(AnalysisContext context, SourceContainer container) { | |
| 816 _queue.enqueue(new RemoveSourcesOperation(_store, context, container)); | |
| 817 } | |
| 818 | |
| 819 void run() { | |
| 820 _processor.run(); | |
| 821 } | |
| 822 | |
| 823 void stop() { | |
| 824 _processor.stop(false); | |
| 825 } | |
| 826 } | |
| 827 | |
| 828 /** | |
| 829 * Instances of the [RemoveSourcesOperation] implement an operation that removes
from the | 742 * Instances of the [RemoveSourcesOperation] implement an operation that removes
from the |
| 830 * index any data based on the content of source belonging to a [SourceContainer
]. | 743 * index any data based on the content of source belonging to a [SourceContainer
]. |
| 831 */ | 744 */ |
| 832 class RemoveSourcesOperation implements IndexOperation { | 745 class RemoveSourcesOperation implements IndexOperation { |
| 833 /** | 746 /** |
| 834 * The index store against which this operation is being run. | 747 * The index store against which this operation is being run. |
| 835 */ | 748 */ |
| 836 IndexStore _indexStore; | 749 IndexStore _indexStore; |
| 837 | 750 |
| 838 /** | 751 /** |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 | 783 |
| 871 /** | 784 /** |
| 872 * The interface `UniverseElement` defines element to use when we want to reques
t "defines" | 785 * The interface `UniverseElement` defines element to use when we want to reques
t "defines" |
| 873 * relations without specifying exact library. | 786 * relations without specifying exact library. |
| 874 */ | 787 */ |
| 875 abstract class UniverseElement implements Element { | 788 abstract class UniverseElement implements Element { |
| 876 static final UniverseElement INSTANCE = UniverseElementImpl.INSTANCE; | 789 static final UniverseElement INSTANCE = UniverseElementImpl.INSTANCE; |
| 877 } | 790 } |
| 878 | 791 |
| 879 /** | 792 /** |
| 880 * Instances of the [OperationProcessor] process the operations on a single | |
| 881 * [OperationQueue]. Each processor can be run one time on a single thread. | |
| 882 */ | |
| 883 class OperationProcessor { | |
| 884 /** | |
| 885 * The queue containing the operations to be processed. | |
| 886 */ | |
| 887 OperationQueue _queue; | |
| 888 | |
| 889 /** | |
| 890 * The current state of the processor. | |
| 891 */ | |
| 892 ProcessorState _state = ProcessorState.READY; | |
| 893 | |
| 894 /** | |
| 895 * The number of milliseconds for which the thread on which the processor is r
unning will wait for | |
| 896 * an operation to become available if there are no operations ready to be pro
cessed. | |
| 897 */ | |
| 898 static int _WAIT_DURATION = 100; | |
| 899 | |
| 900 /** | |
| 901 * Initialize a newly created operation processor to process the operations on
the given queue. | |
| 902 * | |
| 903 * @param queue the queue containing the operations to be processed | |
| 904 */ | |
| 905 OperationProcessor(OperationQueue queue) { | |
| 906 this._queue = queue; | |
| 907 } | |
| 908 | |
| 909 /** | |
| 910 * Start processing operations. If the processor is already running on a diffe
rent thread, then | |
| 911 * this method will return immediately with no effect. Otherwise, this method
will not return | |
| 912 * until after the processor has been stopped from a different thread or until
the thread running | |
| 913 * the processor has been interrupted. | |
| 914 */ | |
| 915 void run() { | |
| 916 // This processor is, or was, already running on a different thread. | |
| 917 if (_state != ProcessorState.READY) { | |
| 918 throw new IllegalStateException("Operation processors can only be run one
time"); | |
| 919 } | |
| 920 // OK, run. | |
| 921 _state = ProcessorState.RUNNING; | |
| 922 try { | |
| 923 while (isRunning) { | |
| 924 // wait for operation | |
| 925 IndexOperation operation = null; | |
| 926 { | |
| 927 operation = _queue.dequeue(_WAIT_DURATION); | |
| 928 } | |
| 929 // perform operation | |
| 930 if (operation != null) { | |
| 931 try { | |
| 932 operation.performOperation(); | |
| 933 } catch (exception) { | |
| 934 AnalysisEngine.instance.logger.logError2("Exception in indexing oper
ation: ${operation}", exception); | |
| 935 } | |
| 936 } | |
| 937 } | |
| 938 } finally { | |
| 939 _state = ProcessorState.STOPPED; | |
| 940 } | |
| 941 } | |
| 942 | |
| 943 /** | |
| 944 * Stop processing operations after the current operation has completed. If th
e argument is | |
| 945 * `true` then this method will wait until the last operation has completed; o
therwise this | |
| 946 * method might return before the last operation has completed. | |
| 947 * | |
| 948 * @param wait `true` if this method will wait until the last operation has co
mpleted before | |
| 949 * returning | |
| 950 * @return the library files for the libraries that need to be analyzed when a
new session is | |
| 951 * started. | |
| 952 */ | |
| 953 List<Source> stop(bool wait) { | |
| 954 if (identical(_state, ProcessorState.READY)) { | |
| 955 _state = ProcessorState.STOPPED; | |
| 956 return unanalyzedSources; | |
| 957 } else if (identical(_state, ProcessorState.STOPPED)) { | |
| 958 return unanalyzedSources; | |
| 959 } else if (identical(_state, ProcessorState.RUNNING)) { | |
| 960 _state = ProcessorState.STOP_REQESTED; | |
| 961 } | |
| 962 while (wait) { | |
| 963 if (identical(_state, ProcessorState.STOPPED)) { | |
| 964 return unanalyzedSources; | |
| 965 } | |
| 966 _waitOneMs(); | |
| 967 } | |
| 968 return unanalyzedSources; | |
| 969 } | |
| 970 | |
| 971 /** | |
| 972 * Waits until processors will switch from "ready" to "running" state. | |
| 973 * | |
| 974 * @return `true` if processor is now actually in "running" state, e.g. not in
"stopped" | |
| 975 * state. | |
| 976 */ | |
| 977 bool waitForRunning() { | |
| 978 while (identical(_state, ProcessorState.READY)) { | |
| 979 _threadYield(); | |
| 980 } | |
| 981 return identical(_state, ProcessorState.RUNNING); | |
| 982 } | |
| 983 | |
| 984 /** | |
| 985 * @return the [Source]s that are not indexed yet. | |
| 986 */ | |
| 987 List<Source> get unanalyzedSources { | |
| 988 Set<Source> sources = new Set(); | |
| 989 for (IndexOperation operation in _queue.operations) { | |
| 990 if (operation is IndexUnitOperation) { | |
| 991 Source source = operation.source; | |
| 992 sources.add(source); | |
| 993 } | |
| 994 } | |
| 995 return new List.from(sources); | |
| 996 } | |
| 997 | |
| 998 /** | |
| 999 * Return `true` if the current state is [ProcessorState#RUNNING]. | |
| 1000 * | |
| 1001 * @return `true` if this processor is running | |
| 1002 */ | |
| 1003 bool get isRunning => identical(_state, ProcessorState.RUNNING); | |
| 1004 | |
| 1005 void _threadYield() { | |
| 1006 } | |
| 1007 | |
| 1008 void _waitOneMs() { | |
| 1009 } | |
| 1010 } | |
| 1011 | |
| 1012 /** | |
| 1013 * The enumeration <code>ProcessorState</code> represents the possible states of
an operation | 793 * The enumeration <code>ProcessorState</code> represents the possible states of
an operation |
| 1014 * processor. | 794 * processor. |
| 1015 */ | 795 */ |
| 1016 class ProcessorState extends Enum<ProcessorState> { | 796 class ProcessorState extends Enum<ProcessorState> { |
| 1017 /** | 797 /** |
| 1018 * The processor is ready to be run (has not been run before). | 798 * The processor is ready to be run (has not been run before). |
| 1019 */ | 799 */ |
| 1020 static final ProcessorState READY = new ProcessorState('READY', 0); | 800 static final ProcessorState READY = new ProcessorState('READY', 0); |
| 1021 | 801 |
| 1022 /** | 802 /** |
| (...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2324 * Information about [ImportElement] and place where it is referenced using | 2104 * Information about [ImportElement] and place where it is referenced using |
| 2325 * [PrefixElement]. | 2105 * [PrefixElement]. |
| 2326 */ | 2106 */ |
| 2327 class IndexContributor_ImportElementInfo { | 2107 class IndexContributor_ImportElementInfo { |
| 2328 ImportElement _element; | 2108 ImportElement _element; |
| 2329 | 2109 |
| 2330 int _periodEnd = 0; | 2110 int _periodEnd = 0; |
| 2331 } | 2111 } |
| 2332 | 2112 |
| 2333 /** | 2113 /** |
| 2334 * Factory for [Index] and [IndexStore]. | |
| 2335 */ | |
| 2336 class IndexFactory { | |
| 2337 /** | |
| 2338 * @return the new instance of [Index] which uses given [IndexStore]. | |
| 2339 */ | |
| 2340 static Index newIndex(IndexStore store) { | |
| 2341 OperationQueue queue = new OperationQueue(); | |
| 2342 OperationProcessor processor = new OperationProcessor(queue); | |
| 2343 return new IndexImpl(store, queue, processor); | |
| 2344 } | |
| 2345 | |
| 2346 /** | |
| 2347 * @return the new instance of [MemoryIndexStore]. | |
| 2348 */ | |
| 2349 static MemoryIndexStore newMemoryIndexStore() => new MemoryIndexStoreImpl(); | |
| 2350 } | |
| 2351 | |
| 2352 /** | |
| 2353 * Instances of the [OperationQueue] represent a queue of operations against the
index that | |
| 2354 * are waiting to be performed. | |
| 2355 */ | |
| 2356 class OperationQueue { | |
| 2357 /** | |
| 2358 * The non-query operations that are waiting to be performed. | |
| 2359 */ | |
| 2360 Queue<IndexOperation> _nonQueryOperations = new Queue(); | |
| 2361 | |
| 2362 /** | |
| 2363 * The query operations that are waiting to be performed. | |
| 2364 */ | |
| 2365 Queue<IndexOperation> _queryOperations = new Queue(); | |
| 2366 | |
| 2367 /** | |
| 2368 * `true` if query operations should be returned by [dequeue] or {code false} | |
| 2369 * if not. | |
| 2370 */ | |
| 2371 bool _processQueries = true; | |
| 2372 | |
| 2373 /** | |
| 2374 * If this queue is not empty, then remove the next operation from the head of
this queue and | |
| 2375 * return it. If this queue is empty (see [setProcessQueries], then the behavi
or | |
| 2376 * of this method depends on the value of the argument. If the argument is les
s than or equal to | |
| 2377 * zero (<code>0</code>), then `null` will be returned immediately. If the arg
ument is | |
| 2378 * greater than zero, then this method will wait until at least one operation
has been added to | |
| 2379 * this queue or until the given amount of time has passed. If, at the end of
that time, this | |
| 2380 * queue is empty, then `null` will be returned. If this queue is not empty, t
hen the first | |
| 2381 * operation will be removed and returned. | |
| 2382 * | |
| 2383 * Note that `null` can be returned, even if a positive timeout is given. | |
| 2384 * | |
| 2385 * Note too that this method's timeout is not treated the same way as the time
out value used for | |
| 2386 * [Object#wait]. In particular, it is not possible to cause this method to wa
it for | |
| 2387 * an indefinite period of time. | |
| 2388 * | |
| 2389 * @param timeout the maximum number of milliseconds to wait for an operation
to be available | |
| 2390 * before giving up and returning `null` | |
| 2391 * @return the operation that was removed from the queue | |
| 2392 * @throws InterruptedException if the thread on which this method is running
was interrupted | |
| 2393 * while it was waiting for an operation to be added to the queue | |
| 2394 */ | |
| 2395 IndexOperation dequeue(int timeout) { | |
| 2396 if (_nonQueryOperations.isEmpty && (!_processQueries || _queryOperations.isE
mpty)) { | |
| 2397 if (timeout <= 0) { | |
| 2398 return null; | |
| 2399 } | |
| 2400 _waitForOperationAvailable(timeout); | |
| 2401 } | |
| 2402 if (!_nonQueryOperations.isEmpty) { | |
| 2403 return _nonQueryOperations.removeFirst(); | |
| 2404 } | |
| 2405 if (_processQueries && !_queryOperations.isEmpty) { | |
| 2406 return _queryOperations.removeFirst(); | |
| 2407 } | |
| 2408 return null; | |
| 2409 } | |
| 2410 | |
| 2411 /** | |
| 2412 * Add the given operation to the tail of this queue. | |
| 2413 * | |
| 2414 * @param operation the operation to be added to the queue | |
| 2415 */ | |
| 2416 void enqueue(IndexOperation operation) { | |
| 2417 if (operation is RemoveSourceOperation) { | |
| 2418 Source source = operation.source; | |
| 2419 _removeForSource(source, _nonQueryOperations); | |
| 2420 _removeForSource(source, _queryOperations); | |
| 2421 } | |
| 2422 if (operation.isQuery) { | |
| 2423 _queryOperations.add(operation); | |
| 2424 } else { | |
| 2425 _nonQueryOperations.add(operation); | |
| 2426 } | |
| 2427 _notifyOperationAvailable(); | |
| 2428 } | |
| 2429 | |
| 2430 /** | |
| 2431 * Return a list containing all of the operations that are currently on the qu
eue. Modifying this | |
| 2432 * list will not affect the state of the queue. | |
| 2433 * | |
| 2434 * @return all of the operations that are currently on the queue | |
| 2435 */ | |
| 2436 List<IndexOperation> get operations { | |
| 2437 List<IndexOperation> operations = []; | |
| 2438 operations.addAll(_nonQueryOperations); | |
| 2439 operations.addAll(_queryOperations); | |
| 2440 return operations; | |
| 2441 } | |
| 2442 | |
| 2443 /** | |
| 2444 * Set whether the receiver's [dequeue] method should return query operations. | |
| 2445 * | |
| 2446 * @param processQueries `true` if the receiver's [dequeue] method should | |
| 2447 * return query operations or `false` if query operations should be q
ueued but not | |
| 2448 * returned by the receiver's [dequeue] method until this method is c
alled | |
| 2449 * with a value of `true`. | |
| 2450 */ | |
| 2451 void set processQueries(bool processQueries) { | |
| 2452 if (this._processQueries != processQueries) { | |
| 2453 this._processQueries = processQueries; | |
| 2454 if (processQueries && !_queryOperations.isEmpty) { | |
| 2455 _notifyOperationAvailable(); | |
| 2456 } | |
| 2457 } | |
| 2458 } | |
| 2459 | |
| 2460 /** | |
| 2461 * Return the number of operations on the queue. | |
| 2462 * | |
| 2463 * @return the number of operations on the queue | |
| 2464 */ | |
| 2465 int size() => _nonQueryOperations.length + _queryOperations.length; | |
| 2466 | |
| 2467 void _notifyOperationAvailable() { | |
| 2468 } | |
| 2469 | |
| 2470 /** | |
| 2471 * Removes operations that should be removed when given [Source] is removed. | |
| 2472 */ | |
| 2473 void _removeForSource(Source source, Queue<IndexOperation> operations) { | |
| 2474 operations.removeWhere((_) => _.removeWhenSourceRemoved(source)); | |
| 2475 } | |
| 2476 | |
| 2477 void _waitForOperationAvailable(int timeout) { | |
| 2478 } | |
| 2479 } | |
| 2480 | |
| 2481 /** | |
| 2482 * Special [Element] which is used to index references to the name without speci
fying concrete | 2114 * Special [Element] which is used to index references to the name without speci
fying concrete |
| 2483 * kind of this name - field, method or something else. | 2115 * kind of this name - field, method or something else. |
| 2484 */ | 2116 */ |
| 2485 class NameElementImpl extends ElementImpl { | 2117 class NameElementImpl extends ElementImpl { |
| 2486 NameElementImpl(String name) : super.con2("name:${name}", -1); | 2118 NameElementImpl(String name) : super.con2("name:${name}", -1); |
| 2487 | 2119 |
| 2488 accept(ElementVisitor visitor) => null; | 2120 accept(ElementVisitor visitor) => null; |
| 2489 | 2121 |
| 2490 ElementKind get kind => ElementKind.NAME; | 2122 ElementKind get kind => ElementKind.NAME; |
| 2491 } | 2123 } |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2780 * element are available. For example, if the element is a field and the relat
ionship is the | 2412 * element are available. For example, if the element is a field and the relat
ionship is the |
| 2781 * is-referenced-by relationship, then this method will be invoked with each l
ocation at which the | 2413 * is-referenced-by relationship, then this method will be invoked with each l
ocation at which the |
| 2782 * field is referenced. | 2414 * field is referenced. |
| 2783 * | 2415 * |
| 2784 * @param element the [Element] that has the relationship with the locations | 2416 * @param element the [Element] that has the relationship with the locations |
| 2785 * @param relationship the relationship between the given element and the loca
tions | 2417 * @param relationship the relationship between the given element and the loca
tions |
| 2786 * @param locations the locations that were found | 2418 * @param locations the locations that were found |
| 2787 */ | 2419 */ |
| 2788 void hasRelationships(Element element, Relationship relationship, List<Locatio
n> locations); | 2420 void hasRelationships(Element element, Relationship relationship, List<Locatio
n> locations); |
| 2789 } | 2421 } |
| OLD | NEW |