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.task.dart_work_manager; | 5 library analyzer.src.task.dart_work_manager; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/src/context/cache.dart'; | 9 import 'package:analyzer/src/context/cache.dart'; |
10 import 'package:analyzer/src/generated/engine.dart' | 10 import 'package:analyzer/src/generated/engine.dart' |
11 show AnalysisEngine, CacheState, InternalAnalysisContext; | 11 show AnalysisEngine, CacheState, InternalAnalysisContext; |
12 import 'package:analyzer/src/generated/source.dart'; | 12 import 'package:analyzer/src/generated/source.dart'; |
13 import 'package:analyzer/src/generated/utilities_collection.dart'; | |
13 import 'package:analyzer/src/task/dart.dart'; | 14 import 'package:analyzer/src/task/dart.dart'; |
14 import 'package:analyzer/src/task/driver.dart'; | 15 import 'package:analyzer/src/task/driver.dart'; |
15 import 'package:analyzer/task/dart.dart'; | 16 import 'package:analyzer/task/dart.dart'; |
16 import 'package:analyzer/task/model.dart'; | 17 import 'package:analyzer/task/model.dart'; |
17 import 'package:analyzer/src/generated/utilities_collection.dart'; | |
18 | 18 |
19 /** | 19 /** |
20 * The manager for Dart specific analysis. | 20 * The manager for Dart specific analysis. |
21 */ | 21 */ |
22 class DartWorkManager implements WorkManager { | 22 class DartWorkManager implements WorkManager { |
23 final InternalAnalysisContext context; | 23 final InternalAnalysisContext context; |
24 | 24 |
25 /** | 25 /** |
26 * The known library source. | 26 * The known library source. |
27 */ | 27 */ |
28 final HashSet<Source> librarySources = new HashSet<Source>(); | 28 final HashSet<Source> librarySources = new HashSet<Source>(); |
29 | 29 |
30 /** | 30 /** |
31 * The know part sources. | 31 * The know part sources. |
32 */ | 32 */ |
33 final HashSet<Source> partSources = new HashSet<Source>(); | 33 final HashSet<Source> partSources = new HashSet<Source>(); |
34 | 34 |
35 /** | 35 /** |
36 * The [TargetedResult]s that should be computed with priority. | |
37 */ | |
38 final LinkedHashSet<TargetedResult> priorityResultQueue = | |
39 new LinkedHashSet<TargetedResult>(); | |
40 | |
41 /** | |
36 * The sources whose kind we don't know yet. | 42 * The sources whose kind we don't know yet. |
37 */ | 43 */ |
38 final LinkedHashSet<Source> unknownSourceQueue = new LinkedHashSet<Source>(); | 44 final LinkedHashSet<Source> unknownSourceQueue = new LinkedHashSet<Source>(); |
39 | 45 |
40 /** | 46 /** |
41 * The queue of library sources to process. | 47 * The queue of library sources to process. |
42 */ | 48 */ |
43 final LinkedHashSet<Source> librarySourceQueue = new LinkedHashSet<Source>(); | 49 final LinkedHashSet<Source> librarySourceQueue = new LinkedHashSet<Source>(); |
44 | 50 |
45 /** | 51 /** |
46 * Initialize a newly created manager. | 52 * Initialize a newly created manager. |
47 */ | 53 */ |
48 DartWorkManager(this.context); | 54 DartWorkManager(this.context); |
49 | 55 |
50 /** | 56 /** |
57 * Specifies that the client want the given [result] of the given [target] | |
58 * to be computed with priority. | |
59 */ | |
60 void addPriorityResult(AnalysisTarget target, ResultDescriptor result) { | |
61 priorityResultQueue.add(new TargetedResult(target, result)); | |
62 } | |
63 | |
64 /** | |
51 * Notifies the manager about changes in the explicit source list. | 65 * Notifies the manager about changes in the explicit source list. |
52 */ | 66 */ |
53 void applyChange(List<Source> addedSources, List<Source> changedSources, | 67 void applyChange(List<Source> addedSources, List<Source> changedSources, |
54 List<Source> removedSources) { | 68 List<Source> removedSources) { |
55 addedSources = addedSources.where(_isDartSource).toList(); | 69 addedSources = addedSources.where(_isDartSource).toList(); |
56 changedSources = changedSources.where(_isDartSource).toList(); | 70 changedSources = changedSources.where(_isDartSource).toList(); |
57 removedSources = removedSources.where(_isDartSource).toList(); | 71 removedSources = removedSources.where(_isDartSource).toList(); |
58 // library | 72 // library |
59 librarySources.removeAll(changedSources); | 73 librarySources.removeAll(changedSources); |
60 librarySources.removeAll(removedSources); | 74 librarySources.removeAll(removedSources); |
(...skipping 19 matching lines...) Expand all Loading... | |
80 entry.getValue(LIBRARY_ERRORS_READY) != true) { | 94 entry.getValue(LIBRARY_ERRORS_READY) != true) { |
81 librarySourceQueue.add(target); | 95 librarySourceQueue.add(target); |
82 } | 96 } |
83 } | 97 } |
84 } | 98 } |
85 } | 99 } |
86 } | 100 } |
87 | 101 |
88 @override | 102 @override |
89 TargetedResult getNextResult() { | 103 TargetedResult getNextResult() { |
104 // Try to find a priority result to compute. | |
105 while (priorityResultQueue.isNotEmpty) { | |
106 TargetedResult result = priorityResultQueue.first; | |
107 if (!_needsComputing(result.target, result.result)) { | |
108 priorityResultQueue.remove(result); | |
109 continue; | |
110 } | |
111 return result; | |
112 } | |
90 // Try to find a new library to analyze. | 113 // Try to find a new library to analyze. |
91 while (librarySourceQueue.isNotEmpty) { | 114 while (librarySourceQueue.isNotEmpty) { |
92 Source librarySource = librarySourceQueue.first; | 115 Source librarySource = librarySourceQueue.first; |
93 CacheEntry entry = context.getCacheEntry(librarySource); | |
94 CacheState state = entry.getState(LIBRARY_ERRORS_READY); | |
95 // Maybe done with this library. | 116 // Maybe done with this library. |
96 if (state == CacheState.VALID || state == CacheState.ERROR) { | 117 if (!_needsComputing(librarySource, LIBRARY_ERRORS_READY)) { |
97 librarySourceQueue.remove(librarySource); | 118 librarySourceQueue.remove(librarySource); |
98 continue; | 119 continue; |
99 } | 120 } |
100 // Analyze this library. | 121 // Analyze this library. |
101 return new TargetedResult(librarySource, LIBRARY_ERRORS_READY); | 122 return new TargetedResult(librarySource, LIBRARY_ERRORS_READY); |
102 } | 123 } |
103 // No libraries in the queue, check whether there are sources to organize. | 124 // No libraries in the queue, check whether there are sources to organize. |
104 while (unknownSourceQueue.isNotEmpty) { | 125 while (unknownSourceQueue.isNotEmpty) { |
105 Source source = unknownSourceQueue.first; | 126 Source source = unknownSourceQueue.first; |
106 CacheEntry entry = context.getCacheEntry(source); | |
107 CacheState state = entry.getState(SOURCE_KIND); | |
108 // Maybe done with this source. | 127 // Maybe done with this source. |
109 if (state == CacheState.VALID || state == CacheState.ERROR) { | 128 if (!_needsComputing(source, SOURCE_KIND)) { |
110 unknownSourceQueue.remove(source); | 129 unknownSourceQueue.remove(source); |
111 continue; | 130 continue; |
112 } | 131 } |
113 // Compute the kind of this source. | 132 // Compute the kind of this source. |
114 return new TargetedResult(source, SOURCE_KIND); | 133 return new TargetedResult(source, SOURCE_KIND); |
115 } | 134 } |
116 // TODO(scheglov) Report errors for parts that remained in the queue after | 135 // TODO(scheglov) Report errors for parts that remained in the queue after |
117 // all libraries had been processed. | 136 // all libraries had been processed. |
118 // No results to compute. | 137 // No results to compute. |
119 return null; | 138 return null; |
120 } | 139 } |
121 | 140 |
122 @override | 141 @override |
123 WorkOrderPriority getNextResultPriority() { | 142 WorkOrderPriority getNextResultPriority() { |
124 if (unknownSourceQueue.isNotEmpty || librarySourceQueue.isNotEmpty) { | 143 if (priorityResultQueue.isNotEmpty || |
Brian Wilkerson
2015/05/11 18:36:49
Should a non-empty priorityResultQueue return a hi
scheglov
2015/05/11 18:46:07
Good catch.
Fixed.
| |
144 unknownSourceQueue.isNotEmpty || | |
145 librarySourceQueue.isNotEmpty) { | |
125 return WorkOrderPriority.NORMAL; | 146 return WorkOrderPriority.NORMAL; |
126 } | 147 } |
127 return WorkOrderPriority.NONE; | 148 return WorkOrderPriority.NONE; |
128 } | 149 } |
129 | 150 |
130 @override | 151 @override |
131 void resultsComputed( | 152 void resultsComputed( |
132 AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs) { | 153 AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs) { |
133 // Organize sources. | 154 // Organize sources. |
134 if (_isDartSource(target)) { | 155 if (_isDartSource(target)) { |
135 SourceKind kind = outputs[SOURCE_KIND]; | 156 SourceKind kind = outputs[SOURCE_KIND]; |
136 if (kind != null) { | 157 if (kind != null) { |
137 unknownSourceQueue.remove(target); | 158 unknownSourceQueue.remove(target); |
138 if (kind == SourceKind.PART) { | 159 if (kind == SourceKind.PART) { |
139 librarySources.remove(target); | 160 librarySources.remove(target); |
140 partSources.add(target); | 161 partSources.add(target); |
141 } else { | 162 } else { |
142 librarySources.add(target); | 163 librarySources.add(target); |
143 partSources.remove(target); | 164 partSources.remove(target); |
144 librarySourceQueue.add(target); | 165 librarySourceQueue.add(target); |
145 } | 166 } |
146 } | 167 } |
147 } | 168 } |
148 } | 169 } |
149 | 170 |
150 bool _isDartSource(AnalysisTarget target) { | 171 bool _isDartSource(AnalysisTarget target) { |
151 return target is Source && AnalysisEngine.isDartFileName(target.fullName); | 172 return target is Source && AnalysisEngine.isDartFileName(target.fullName); |
152 } | 173 } |
174 | |
175 /** | |
176 * Returns `true` if the given [result] of the given [target] needs | |
177 * computing, i.e. it is not in the valid and not in the error state. | |
178 */ | |
179 bool _needsComputing(AnalysisTarget target, ResultDescriptor result) { | |
180 CacheEntry entry = context.getCacheEntry(target); | |
181 CacheState state = entry.getState(result); | |
182 return state != CacheState.VALID && state != CacheState.ERROR; | |
183 } | |
153 } | 184 } |
OLD | NEW |