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 | 11 show |
12 AnalysisEngine, | 12 AnalysisEngine, |
13 AnalysisErrorInfo, | 13 AnalysisErrorInfo, |
14 AnalysisErrorInfoImpl, | 14 AnalysisErrorInfoImpl, |
15 AnalysisOptions, | 15 AnalysisOptions, |
16 CacheState, | 16 CacheState, |
17 InternalAnalysisContext; | 17 InternalAnalysisContext; |
18 import 'package:analyzer/src/generated/error.dart'; | 18 import 'package:analyzer/src/generated/error.dart'; |
19 import 'package:analyzer/src/generated/source.dart'; | 19 import 'package:analyzer/src/generated/source.dart'; |
20 import 'package:analyzer/src/generated/utilities_collection.dart'; | 20 import 'package:analyzer/src/generated/utilities_collection.dart'; |
21 import 'package:analyzer/src/task/dart.dart'; | 21 import 'package:analyzer/src/task/dart.dart'; |
22 import 'package:analyzer/src/task/driver.dart'; | 22 import 'package:analyzer/src/task/html.dart'; |
23 import 'package:analyzer/task/dart.dart'; | 23 import 'package:analyzer/task/dart.dart'; |
24 import 'package:analyzer/task/general.dart'; | |
25 import 'package:analyzer/task/model.dart'; | 24 import 'package:analyzer/task/model.dart'; |
26 | 25 |
27 /** | 26 /** |
28 * The manager for Dart specific analysis. | 27 * The manager for Dart specific analysis. |
29 */ | 28 */ |
30 class DartWorkManager implements WorkManager { | 29 class DartWorkManager implements WorkManager { |
31 /** | 30 /** |
32 * The list of errors that are reported for raw Dart [Source]s. | 31 * The list of errors that are reported for raw Dart [Source]s. |
33 */ | 32 */ |
34 static final List<ResultDescriptor> _SOURCE_ERRORS = <ResultDescriptor>[ | 33 static final List<ResultDescriptor> _SOURCE_ERRORS = <ResultDescriptor>[ |
35 BUILD_DIRECTIVES_ERRORS, | 34 BUILD_DIRECTIVES_ERRORS, |
36 BUILD_LIBRARY_ERRORS, | 35 BUILD_LIBRARY_ERRORS, |
37 PARSE_ERRORS, | 36 PARSE_ERRORS, |
38 SCAN_ERRORS | 37 SCAN_ERRORS |
39 ]; | 38 ]; |
40 | 39 |
41 /** | 40 /** |
42 * The list of errors that are reported for raw Dart [LibrarySpecificUnit]s. | 41 * The list of errors that are reported for raw Dart [LibrarySpecificUnit]s. |
43 */ | 42 */ |
44 static final List<ResultDescriptor> _UNIT_ERRORS = <ResultDescriptor>[ | 43 static final List<ResultDescriptor> _UNIT_ERRORS = <ResultDescriptor>[ |
45 HINTS, | 44 HINTS, |
46 RESOLVE_REFERENCES_ERRORS, | 45 LINTS, |
| 46 LIBRARY_UNIT_ERRORS, |
47 RESOLVE_TYPE_NAMES_ERRORS, | 47 RESOLVE_TYPE_NAMES_ERRORS, |
| 48 RESOLVE_UNIT_ERRORS, |
48 VARIABLE_REFERENCE_ERRORS, | 49 VARIABLE_REFERENCE_ERRORS, |
49 VERIFY_ERRORS | 50 VERIFY_ERRORS |
50 ]; | 51 ]; |
51 | 52 |
52 final InternalAnalysisContext context; | 53 final InternalAnalysisContext context; |
53 | 54 |
54 /** | 55 /** |
55 * The [TargetedResult]s that should be computed with priority. | 56 * The [TargetedResult]s that should be computed with priority. |
56 */ | 57 */ |
57 final LinkedHashSet<TargetedResult> priorityResultQueue = | 58 final LinkedHashSet<TargetedResult> priorityResultQueue = |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 context.privateAnalysisCachePartition; | 107 context.privateAnalysisCachePartition; |
107 | 108 |
108 /** | 109 /** |
109 * Specifies that the client want the given [result] of the given [target] | 110 * Specifies that the client want the given [result] of the given [target] |
110 * to be computed with priority. | 111 * to be computed with priority. |
111 */ | 112 */ |
112 void addPriorityResult(AnalysisTarget target, ResultDescriptor result) { | 113 void addPriorityResult(AnalysisTarget target, ResultDescriptor result) { |
113 priorityResultQueue.add(new TargetedResult(target, result)); | 114 priorityResultQueue.add(new TargetedResult(target, result)); |
114 } | 115 } |
115 | 116 |
116 /** | 117 @override |
117 * Notifies the manager about changes in the explicit source list. | |
118 */ | |
119 void applyChange(List<Source> addedSources, List<Source> changedSources, | 118 void applyChange(List<Source> addedSources, List<Source> changedSources, |
120 List<Source> removedSources) { | 119 List<Source> removedSources) { |
121 addedSources = addedSources.where(_isDartSource).toList(); | 120 addedSources = addedSources.where(_isDartSource).toList(); |
122 changedSources = changedSources.where(_isDartSource).toList(); | 121 changedSources = changedSources.where(_isDartSource).toList(); |
123 removedSources = removedSources.where(_isDartSource).toList(); | 122 removedSources = removedSources.where(_isDartSource).toList(); |
124 // unknown queue | 123 // unknown queue |
125 unknownSourceQueue.addAll(addedSources); | 124 unknownSourceQueue.addAll(addedSources); |
126 unknownSourceQueue.addAll(changedSources); | 125 unknownSourceQueue.addAll(changedSources); |
127 unknownSourceQueue.removeAll(removedSources); | 126 unknownSourceQueue.removeAll(removedSources); |
128 // library queue | 127 // library queue |
(...skipping 30 matching lines...) Expand all Loading... |
159 } else if (sourceKind == SourceKind.PART) { | 158 } else if (sourceKind == SourceKind.PART) { |
160 List<Source> libraries = context.getLibrariesContaining(target); | 159 List<Source> libraries = context.getLibrariesContaining(target); |
161 for (Source library in libraries) { | 160 for (Source library in libraries) { |
162 addPriorityResult(library, LIBRARY_ERRORS_READY); | 161 addPriorityResult(library, LIBRARY_ERRORS_READY); |
163 } | 162 } |
164 } | 163 } |
165 } | 164 } |
166 } | 165 } |
167 } | 166 } |
168 | 167 |
169 /** | 168 @override |
170 * Return an [AnalysisErrorInfo] containing the list of all of the errors and | 169 List<AnalysisError> getErrors(Source source) { |
171 * the line info associated with the given [source]. The list of errors will | 170 if (!_isDartSource(source) && source is! DartScript) { |
172 * be empty if the source is not known to the context or if there are no | 171 return AnalysisError.NO_ERRORS; |
173 * errors in the source. The errors contained in the list can be incomplete. | 172 } |
174 */ | 173 // If analysis is finished, use all the errors. |
175 AnalysisErrorInfo getErrors(Source source) { | |
176 if (analysisCache.getState(source, DART_ERRORS) == CacheState.VALID) { | 174 if (analysisCache.getState(source, DART_ERRORS) == CacheState.VALID) { |
177 List<AnalysisError> errors = analysisCache.getValue(source, DART_ERRORS); | 175 return analysisCache.getValue(source, DART_ERRORS); |
178 LineInfo lineInfo = analysisCache.getValue(source, LINE_INFO); | |
179 return new AnalysisErrorInfoImpl(errors, lineInfo); | |
180 } | 176 } |
| 177 // If analysis is in progress, combine all known partial results. |
181 List<AnalysisError> errors = <AnalysisError>[]; | 178 List<AnalysisError> errors = <AnalysisError>[]; |
182 for (ResultDescriptor descriptor in _SOURCE_ERRORS) { | 179 for (ResultDescriptor descriptor in _SOURCE_ERRORS) { |
183 errors.addAll(analysisCache.getValue(source, descriptor)); | 180 errors.addAll(analysisCache.getValue(source, descriptor)); |
184 } | 181 } |
185 for (Source library in context.getLibrariesContaining(source)) { | 182 for (Source library in context.getLibrariesContaining(source)) { |
186 LibrarySpecificUnit unit = new LibrarySpecificUnit(library, source); | 183 LibrarySpecificUnit unit = new LibrarySpecificUnit(library, source); |
187 for (ResultDescriptor descriptor in _UNIT_ERRORS) { | 184 for (ResultDescriptor descriptor in _UNIT_ERRORS) { |
188 errors.addAll(analysisCache.getValue(unit, descriptor)); | 185 errors.addAll(analysisCache.getValue(unit, descriptor)); |
189 } | 186 } |
190 } | 187 } |
191 LineInfo lineInfo = analysisCache.getValue(source, LINE_INFO); | 188 return errors; |
192 return new AnalysisErrorInfoImpl(errors, lineInfo); | |
193 } | 189 } |
194 | 190 |
195 /** | 191 /** |
196 * Returns libraries containing the given [part]. | 192 * Returns libraries containing the given [part]. |
197 * Maybe empty, but not null. | 193 * Maybe empty, but not null. |
198 */ | 194 */ |
199 List<Source> getLibrariesContainingPart(Source part) { | 195 List<Source> getLibrariesContainingPart(Source part) { |
200 List<Source> libraries = partLibrariesMap[part]; | 196 List<Source> libraries = partLibrariesMap[part]; |
201 return libraries != null ? libraries : Source.EMPTY_LIST; | 197 return libraries != null ? libraries : Source.EMPTY_LIST; |
202 } | 198 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 /** | 257 /** |
262 * Notifies the manager about [SourceFactory] changes. | 258 * Notifies the manager about [SourceFactory] changes. |
263 */ | 259 */ |
264 void onSourceFactoryChanged() { | 260 void onSourceFactoryChanged() { |
265 _invalidateAllLocalResolutionInformation(true); | 261 _invalidateAllLocalResolutionInformation(true); |
266 } | 262 } |
267 | 263 |
268 @override | 264 @override |
269 void resultsComputed( | 265 void resultsComputed( |
270 AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs) { | 266 AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs) { |
| 267 bool isDartSource = _isDartSource(target); |
271 // Organize sources. | 268 // Organize sources. |
272 if (_isDartSource(target)) { | 269 bool isDartLibrarySource = false; |
| 270 if (isDartSource) { |
273 Source source = target; | 271 Source source = target; |
274 SourceKind kind = outputs[SOURCE_KIND]; | 272 SourceKind kind = outputs[SOURCE_KIND]; |
275 if (kind != null) { | 273 if (kind != null) { |
276 unknownSourceQueue.remove(source); | 274 unknownSourceQueue.remove(source); |
277 if (kind == SourceKind.LIBRARY) { | 275 if (kind == SourceKind.LIBRARY) { |
| 276 isDartLibrarySource = true; |
278 if (context.prioritySources.contains(source)) { | 277 if (context.prioritySources.contains(source)) { |
279 _schedulePriorityLibrarySourceAnalysis(source); | 278 _schedulePriorityLibrarySourceAnalysis(source); |
280 } else { | 279 } else { |
281 bool needErrors = _shouldErrorsBeComputed(source); | 280 bool needErrors = _shouldErrorsBeComputed(source); |
282 if (needErrors) { | 281 if (needErrors) { |
283 librarySourceQueue.add(target); | 282 librarySourceQueue.add(target); |
284 } | 283 } |
285 } | 284 } |
286 } | 285 } |
287 } | 286 } |
288 } | 287 } |
289 // Update parts in libraries. | 288 // Update parts in libraries. |
290 if (_isDartSource(target)) { | 289 if (isDartLibrarySource) { |
291 Source library = target; | 290 Source library = target; |
292 List<Source> includedParts = outputs[INCLUDED_PARTS]; | 291 List<Source> includedParts = outputs[INCLUDED_PARTS]; |
293 if (includedParts != null) { | 292 if (includedParts != null) { |
294 libraryPartsMap[library] = includedParts; | 293 libraryPartsMap[library] = includedParts; |
295 for (Source part in includedParts) { | 294 for (Source part in includedParts) { |
296 List<Source> libraries = | 295 List<Source> libraries = |
297 partLibrariesMap.putIfAbsent(part, () => <Source>[]); | 296 partLibrariesMap.putIfAbsent(part, () => <Source>[]); |
298 if (!libraries.contains(library)) { | 297 if (!libraries.contains(library)) { |
299 libraries.add(library); | 298 libraries.add(library); |
300 _invalidateContainingLibraries(part); | 299 _invalidateContainingLibraries(part); |
301 } | 300 } |
302 } | 301 } |
303 } | 302 } |
304 } | 303 } |
305 // Update notice. | 304 // Update notice. |
306 if (_isDartSource(target)) { | 305 if (isDartSource) { |
307 bool shouldSetErrors = false; | 306 bool shouldSetErrors = false; |
308 outputs.forEach((ResultDescriptor descriptor, value) { | 307 outputs.forEach((ResultDescriptor descriptor, value) { |
309 if (descriptor == PARSED_UNIT && value != null) { | 308 if (descriptor == PARSED_UNIT && value != null) { |
310 context.getNotice(target).parsedDartUnit = value; | 309 context.getNotice(target).parsedDartUnit = value; |
311 shouldSetErrors = true; | 310 shouldSetErrors = true; |
312 } | 311 } |
313 if (descriptor == DART_ERRORS) { | 312 if (descriptor == DART_ERRORS) { |
314 shouldSetErrors = true; | 313 shouldSetErrors = true; |
315 } | 314 } |
316 }); | 315 }); |
317 if (shouldSetErrors) { | 316 if (shouldSetErrors) { |
318 AnalysisErrorInfo info = getErrors(target); | 317 AnalysisErrorInfo info = context.getErrors(target); |
319 context.getNotice(target).setErrors(info.errors, info.lineInfo); | 318 context.getNotice(target).setErrors(info.errors, info.lineInfo); |
320 } | 319 } |
321 } | 320 } |
322 if (target is LibrarySpecificUnit) { | 321 if (target is LibrarySpecificUnit) { |
323 Source source = target.source; | 322 Source source = target.source; |
324 bool shouldSetErrors = false; | 323 bool shouldSetErrors = false; |
325 outputs.forEach((ResultDescriptor descriptor, value) { | 324 outputs.forEach((ResultDescriptor descriptor, value) { |
326 if (descriptor == RESOLVED_UNIT && value != null) { | 325 if (descriptor == RESOLVED_UNIT && value != null) { |
327 context.getNotice(source).resolvedDartUnit = value; | 326 context.getNotice(source).resolvedDartUnit = value; |
328 shouldSetErrors = true; | 327 shouldSetErrors = true; |
329 } | 328 } |
330 }); | 329 }); |
331 if (shouldSetErrors) { | 330 if (shouldSetErrors) { |
332 AnalysisErrorInfo info = getErrors(source); | 331 AnalysisErrorInfo info = context.getErrors(source); |
333 context.getNotice(source).setErrors(info.errors, info.lineInfo); | 332 context.getNotice(source).setErrors(info.errors, info.lineInfo); |
334 } | 333 } |
335 } | 334 } |
336 } | 335 } |
337 | 336 |
338 void unitIncrementallyResolved(Source librarySource, Source unitSource) { | 337 void unitIncrementallyResolved(Source librarySource, Source unitSource) { |
339 librarySourceQueue.add(librarySource); | 338 librarySourceQueue.add(librarySource); |
340 } | 339 } |
341 | 340 |
342 /** | 341 /** |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 } | 436 } |
438 } | 437 } |
439 | 438 |
440 bool _shouldErrorsBeComputed(Source source) => | 439 bool _shouldErrorsBeComputed(Source source) => |
441 context.shouldErrorsBeAnalyzed(source, null); | 440 context.shouldErrorsBeAnalyzed(source, null); |
442 | 441 |
443 static bool _isDartSource(AnalysisTarget target) { | 442 static bool _isDartSource(AnalysisTarget target) { |
444 return target is Source && AnalysisEngine.isDartFileName(target.fullName); | 443 return target is Source && AnalysisEngine.isDartFileName(target.fullName); |
445 } | 444 } |
446 } | 445 } |
OLD | NEW |