OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 analyzer.src.context.cache; | 5 library analyzer.src.context.cache; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 | 9 |
10 import 'package:analyzer/src/generated/engine.dart' | 10 import 'package:analyzer/src/generated/engine.dart' |
(...skipping 23 matching lines...) Expand all Loading... |
34 * An array containing the partitions of which this cache is comprised. | 34 * An array containing the partitions of which this cache is comprised. |
35 */ | 35 */ |
36 final List<CachePartition> _partitions; | 36 final List<CachePartition> _partitions; |
37 | 37 |
38 /** | 38 /** |
39 * The [StreamController] reporting [InvalidatedResult]s. | 39 * The [StreamController] reporting [InvalidatedResult]s. |
40 */ | 40 */ |
41 final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated = | 41 final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated = |
42 new ReentrantSynchronousStream<InvalidatedResult>(); | 42 new ReentrantSynchronousStream<InvalidatedResult>(); |
43 | 43 |
| 44 final List< |
| 45 ReentrantSynchronousStreamSubscription> onResultInvalidatedPartitionSubscr
iptions = < |
| 46 ReentrantSynchronousStreamSubscription>[]; |
| 47 |
44 /** | 48 /** |
45 * Initialize a newly created cache to have the given [partitions]. The | 49 * Initialize a newly created cache to have the given [_partitions]. The |
46 * partitions will be searched in the order in which they appear in the array, | 50 * partitions will be searched in the order in which they appear in the array, |
47 * so the most specific partition (usually an [SdkCachePartition]) should be | 51 * so the most specific partition (usually an [SdkCachePartition]) should be |
48 * first and the most general (usually a [UniversalCachePartition]) last. | 52 * first and the most general (usually a [UniversalCachePartition]) last. |
49 */ | 53 */ |
50 AnalysisCache(this._partitions) { | 54 AnalysisCache(this._partitions) { |
51 for (CachePartition partition in _partitions) { | 55 for (CachePartition partition in _partitions) { |
52 partition.onResultInvalidated.listen((InvalidatedResult event) { | 56 ReentrantSynchronousStreamSubscription<InvalidatedResult> subscription = |
| 57 partition.onResultInvalidated.listen((InvalidatedResult event) { |
53 onResultInvalidated.add(event); | 58 onResultInvalidated.add(event); |
54 }); | 59 }); |
| 60 onResultInvalidatedPartitionSubscriptions.add(subscription); |
55 } | 61 } |
56 } | 62 } |
57 | 63 |
| 64 /** |
| 65 * Return an iterator returning all of the [Source] targets. |
| 66 */ |
| 67 Iterable<Source> get sources { |
| 68 return _partitions |
| 69 .map((CachePartition partition) => partition._sources) |
| 70 .expand((Iterable<Source> sources) => sources); |
| 71 } |
| 72 |
58 // TODO(brianwilkerson) Implement or delete this. | 73 // TODO(brianwilkerson) Implement or delete this. |
59 // /** | 74 // /** |
60 // * Return information about each of the partitions in this cache. | 75 // * Return information about each of the partitions in this cache. |
61 // */ | 76 // */ |
62 // List<AnalysisContextStatistics_PartitionData> get partitionData { | 77 // List<AnalysisContextStatistics_PartitionData> get partitionData { |
63 // int count = _partitions.length; | 78 // int count = _partitions.length; |
64 // List<AnalysisContextStatistics_PartitionData> data = | 79 // List<AnalysisContextStatistics_PartitionData> data = |
65 // new List<AnalysisContextStatistics_PartitionData>(count); | 80 // new List<AnalysisContextStatistics_PartitionData>(count); |
66 // for (int i = 0; i < count; i++) { | 81 // for (int i = 0; i < count; i++) { |
67 // CachePartition partition = _partitions[i]; | 82 // CachePartition partition = _partitions[i]; |
68 // data[i] = new AnalysisContextStatisticsImpl_PartitionDataImpl( | 83 // data[i] = new AnalysisContextStatisticsImpl_PartitionDataImpl( |
69 // partition.astSize, | 84 // partition.astSize, |
70 // partition.map.length); | 85 // partition.map.length); |
71 // } | 86 // } |
72 // return data; | 87 // return data; |
73 // } | 88 // } |
74 | 89 |
75 /** | 90 /** |
76 * Return an iterator returning all of the [Source] targets. | 91 * Free any allocated resources and references. |
77 */ | 92 */ |
78 Iterable<Source> get sources { | 93 void dispose() { |
79 return _partitions | 94 for (ReentrantSynchronousStreamSubscription subscription |
80 .map((CachePartition partition) => partition._sources) | 95 in onResultInvalidatedPartitionSubscriptions) { |
81 .expand((Iterable<Source> sources) => sources); | 96 subscription.cancel(); |
| 97 } |
82 } | 98 } |
83 | 99 |
84 /** | 100 /** |
85 * Return the entry associated with the given [target]. | 101 * Return the entry associated with the given [target]. |
86 */ | 102 */ |
87 CacheEntry get(AnalysisTarget target) { | 103 CacheEntry get(AnalysisTarget target) { |
88 int count = _partitions.length; | 104 int count = _partitions.length; |
89 for (int i = 0; i < count; i++) { | 105 for (int i = 0; i < count; i++) { |
90 CachePartition partition = _partitions[i]; | 106 CachePartition partition = _partitions[i]; |
91 if (partition.isResponsibleFor(target)) { | 107 if (partition.isResponsibleFor(target)) { |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1035 * Check whether this delta affects the result described by the given | 1051 * Check whether this delta affects the result described by the given |
1036 * [descriptor] and [target]. | 1052 * [descriptor] and [target]. |
1037 */ | 1053 */ |
1038 DeltaResult validate(InternalAnalysisContext context, AnalysisTarget target, | 1054 DeltaResult validate(InternalAnalysisContext context, AnalysisTarget target, |
1039 ResultDescriptor descriptor) { | 1055 ResultDescriptor descriptor) { |
1040 return DeltaResult.INVALIDATE; | 1056 return DeltaResult.INVALIDATE; |
1041 } | 1057 } |
1042 } | 1058 } |
1043 | 1059 |
1044 /** | 1060 /** |
1045 * The possible results of validating analysis results againt a [Delta]. | 1061 * The possible results of validating analysis results against a [Delta]. |
1046 */ | 1062 */ |
1047 enum DeltaResult { | 1063 enum DeltaResult { |
1048 /** | 1064 /** |
1049 * Invalidate this result and continue visiting dependent results | 1065 * Invalidate this result and continue visiting dependent results |
1050 * with this [Delta]. | 1066 * with this [Delta]. |
1051 */ | 1067 */ |
1052 INVALIDATE, | 1068 INVALIDATE, |
1053 | 1069 |
1054 /** | 1070 /** |
1055 * Invalidate this result and stop using this [Delta], so unconditionally | 1071 * Invalidate this result and stop using this [Delta], so unconditionally |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 for (Function listener in listeners) { | 1127 for (Function listener in listeners) { |
1112 listener(event); | 1128 listener(event); |
1113 } | 1129 } |
1114 } | 1130 } |
1115 | 1131 |
1116 /** | 1132 /** |
1117 * Listen for the events in this stream. | 1133 * Listen for the events in this stream. |
1118 * Note that if the [listener] fires a new event, then the [listener] will be | 1134 * Note that if the [listener] fires a new event, then the [listener] will be |
1119 * invoked again before returning from the [add] invocation. | 1135 * invoked again before returning from the [add] invocation. |
1120 */ | 1136 */ |
1121 void listen(void listener(T event)) { | 1137 ReentrantSynchronousStreamSubscription<T> listen(void listener(T event)) { |
1122 listeners.add(listener); | 1138 listeners.add(listener); |
| 1139 return new ReentrantSynchronousStreamSubscription<T>(this, listener); |
1123 } | 1140 } |
1124 } | 1141 } |
1125 | 1142 |
| 1143 /** |
| 1144 * A subscription on events from a [ReentrantSynchronousStream]. |
| 1145 */ |
| 1146 class ReentrantSynchronousStreamSubscription<T> { |
| 1147 final ReentrantSynchronousStream<T> _stream; |
| 1148 final Function _listener; |
| 1149 |
| 1150 ReentrantSynchronousStreamSubscription(this._stream, this._listener); |
| 1151 |
| 1152 /** |
| 1153 * Cancels this subscription. |
| 1154 * It will no longer receive events. |
| 1155 */ |
| 1156 void cancel() { |
| 1157 _stream.listeners.remove(_listener); |
| 1158 } |
| 1159 } |
| 1160 |
1126 /** | 1161 /** |
1127 * The data about a single analysis result that is stored in a [CacheEntry]. | 1162 * The data about a single analysis result that is stored in a [CacheEntry]. |
1128 */ | 1163 */ |
1129 // TODO(brianwilkerson) Consider making this a generic class so that the value | 1164 // TODO(brianwilkerson) Consider making this a generic class so that the value |
1130 // can be typed. | 1165 // can be typed. |
1131 class ResultData { | 1166 class ResultData { |
1132 /** | 1167 /** |
1133 * The [ResultDescriptor] this result is for. | 1168 * The [ResultDescriptor] this result is for. |
1134 */ | 1169 */ |
1135 final ResultDescriptor descriptor; | 1170 final ResultDescriptor descriptor; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 void resultAccessed(TargetedResult result) {} | 1261 void resultAccessed(TargetedResult result) {} |
1227 | 1262 |
1228 @override | 1263 @override |
1229 List<TargetedResult> resultStored(TargetedResult newResult, newValue) { | 1264 List<TargetedResult> resultStored(TargetedResult newResult, newValue) { |
1230 return TargetedResult.EMPTY_LIST; | 1265 return TargetedResult.EMPTY_LIST; |
1231 } | 1266 } |
1232 | 1267 |
1233 @override | 1268 @override |
1234 void targetRemoved(AnalysisTarget target) {} | 1269 void targetRemoved(AnalysisTarget target) {} |
1235 } | 1270 } |
OLD | NEW |