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 import 'dart:collection'; | 6 import 'dart:collection'; |
7 import 'dart:convert'; | 7 import 'dart:convert'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 /** | 201 /** |
202 * Return the [Stream] that produces [AnalysisResult]s for added files. | 202 * Return the [Stream] that produces [AnalysisResult]s for added files. |
203 * | 203 * |
204 * Analysis starts when the client starts listening to the stream, and stops | 204 * Analysis starts when the client starts listening to the stream, and stops |
205 * when the client cancels the subscription. | 205 * when the client cancels the subscription. |
206 * | 206 * |
207 * When the client starts listening, the analysis state transitions to | 207 * When the client starts listening, the analysis state transitions to |
208 * "analyzing" and an analysis result is produced for every added file prior | 208 * "analyzing" and an analysis result is produced for every added file prior |
209 * to the next time the analysis state transitions to "idle". | 209 * to the next time the analysis state transitions to "idle". |
210 * | 210 * |
| 211 * At least one analysis result is produced for every file passed to |
| 212 * [addFile] or [changeFile] prior to the next time the analysis state |
| 213 * transitions to "idle", unless the file is later removed from analysis |
| 214 * using [removeFile]. Analysis results for other files are produced only if |
| 215 * the changes affect analysis results of other files. |
| 216 * |
211 * More than one result might be produced for the same file, even if the | 217 * More than one result might be produced for the same file, even if the |
212 * client does not change the state of the files. | 218 * client does not change the state of the files. |
213 * | 219 * |
214 * Results might be produced even for files that have never been added | 220 * Results might be produced even for files that have never been added |
215 * using [addFile], for example when [getResult] was called for a file. | 221 * using [addFile], for example when [getResult] was called for a file. |
216 */ | 222 */ |
217 Stream<AnalysisResult> get results async* { | 223 Stream<AnalysisResult> get results async* { |
218 try { | 224 try { |
219 PerformanceLogSection analysisSection = null; | 225 PerformanceLogSection analysisSection = null; |
220 while (true) { | 226 while (true) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 * Return the stream that produces [AnalysisStatus] events. | 298 * Return the stream that produces [AnalysisStatus] events. |
293 */ | 299 */ |
294 Stream<AnalysisStatus> get status => _statusController.stream; | 300 Stream<AnalysisStatus> get status => _statusController.stream; |
295 | 301 |
296 /** | 302 /** |
297 * Add the file with the given [path] to the set of files to analyze. | 303 * Add the file with the given [path] to the set of files to analyze. |
298 * | 304 * |
299 * The [path] must be absolute and normalized. | 305 * The [path] must be absolute and normalized. |
300 * | 306 * |
301 * The results of analysis are eventually produced by the [results] stream. | 307 * The results of analysis are eventually produced by the [results] stream. |
302 * | |
303 * Causes the analysis state to transition to "analyzing" (if it is not in | |
304 * that state already). At least one analysis result will be produced the | |
305 * file prior to the next time the analysis state transitions to "idle", | |
306 * unless the file is later removed from analysis using [removeFile]. | |
307 */ | 308 */ |
308 void addFile(String path) { | 309 void addFile(String path) { |
309 _explicitFiles.add(path); | 310 _explicitFiles.add(path); |
310 _filesToAnalyze.add(path); | 311 _filesToAnalyze.add(path); |
311 _transitionToAnalyzing(); | 312 _transitionToAnalyzing(); |
312 _hasWork.notify(); | 313 _hasWork.notify(); |
313 } | 314 } |
314 | 315 |
315 /** | 316 /** |
316 * The file with the given [path] might have changed - updated, added or | 317 * The file with the given [path] might have changed - updated, added or |
317 * removed. Or not, we don't know. Or it might have, but then changed back. | 318 * removed. Or not, we don't know. Or it might have, but then changed back. |
318 * | 319 * |
319 * The [path] must be absolute and normalized. | 320 * The [path] must be absolute and normalized. |
320 * | 321 * |
321 * The [path] can be any file - explicitly or implicitly analyzed, or neither. | 322 * The [path] can be any file - explicitly or implicitly analyzed, or neither. |
322 * | 323 * |
323 * Causes the analysis state to transition to "analyzing" (if it is not in | 324 * Causes the analysis state to transition to "analyzing" (if it is not in |
324 * that state already). Schedules the file contents for [path] to be read | 325 * that state already). Schedules the file contents for [path] to be read |
325 * into the current file state prior to the next time the analysis state | 326 * into the current file state prior to the next time the analysis state |
326 * transitions to "idle". | 327 * transitions to "idle". |
327 * | 328 * |
328 * If the file content is the same, no new results will be produced because | |
329 * of this notification, including no result for the file itself. Otherwise, | |
330 * one or more results will be produced - for the file itself and other | |
331 * files that that change in the file might affect. | |
332 * | |
333 * Invocation of this method will not prevent a [Future] returned from | 329 * Invocation of this method will not prevent a [Future] returned from |
334 * [getResult] from completing with a result, but the result is not | 330 * [getResult] from completing with a result, but the result is not |
335 * guaranteed to be consistent with the new current file state after this | 331 * guaranteed to be consistent with the new current file state after this |
336 * [changeFile] invocation. | 332 * [changeFile] invocation. |
337 */ | 333 */ |
338 void changeFile(String path) { | 334 void changeFile(String path) { |
339 _changedFiles.add(path); | 335 _changedFiles.add(path); |
340 if (_explicitFiles.contains(path)) { | 336 if (_explicitFiles.contains(path)) { |
341 _filesToAnalyze.add(path); | 337 _filesToAnalyze.add(path); |
342 } | 338 } |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 } | 674 } |
679 | 675 |
680 /** | 676 /** |
681 * Verify the API signature for the file with the given [path], and decide | 677 * Verify the API signature for the file with the given [path], and decide |
682 * which linked libraries should be invalidated, and files reanalyzed. | 678 * which linked libraries should be invalidated, and files reanalyzed. |
683 * | 679 * |
684 * TODO(scheglov) I see that adding a local var changes (full) API signature. | 680 * TODO(scheglov) I see that adding a local var changes (full) API signature. |
685 */ | 681 */ |
686 void _verifyApiSignatureOfChangedFile(String path) { | 682 void _verifyApiSignatureOfChangedFile(String path) { |
687 _logger.run('Verify API signature of $path', () { | 683 _logger.run('Verify API signature of $path', () { |
688 String oldContentHash = _fileContentHashMap[path]; | |
689 String oldSignature = _fileApiSignatureMap[path]; | 684 String oldSignature = _fileApiSignatureMap[path]; |
690 // Compute the new API signature. | 685 // Compute the new API signature. |
691 // _File.forResolution() also updates the content hash in the cache. | 686 // _File.forResolution() also updates the content hash in the cache. |
692 Source source = _sourceForPath(path); | 687 Source source = _sourceForPath(path); |
693 _File newFile = new _File.forResolution(this, source); | 688 _File newFile = new _File.forResolution(this, source); |
694 // If the file content hash is the same, we don't need analyzing it. | 689 String newSignature = newFile.unlinked.apiSignature; |
695 if (newFile.contentHash == oldContentHash) { | |
696 _filesToAnalyze.remove(path); | |
697 return; | |
698 } | |
699 // If the old API signature is not null, then the file was used to | 690 // If the old API signature is not null, then the file was used to |
700 // compute at least one dependency signature. If the new API signature | 691 // compute at least one dependency signature. If the new API signature |
701 // is different, then potentially all dependency signatures and | 692 // is different, then potentially all dependency signatures and |
702 // resolution results are invalid. | 693 // resolution results are invalid. |
703 String newSignature = newFile.unlinked.apiSignature; | |
704 if (oldSignature != null && oldSignature != newSignature) { | 694 if (oldSignature != null && oldSignature != newSignature) { |
705 _logger.writeln('API signatures mismatch found for $newFile'); | 695 _logger.writeln('API signatures mismatch found for $newFile'); |
706 _dependencySignatureMap.clear(); | 696 _dependencySignatureMap.clear(); |
707 _filesToAnalyze.addAll(_explicitFiles); | 697 _filesToAnalyze.addAll(_explicitFiles); |
708 } | 698 } |
709 }); | 699 }); |
710 } | 700 } |
711 | 701 |
712 /** | 702 /** |
713 * Remove and return the first item in the given [set]. | 703 * Remove and return the first item in the given [set]. |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 } | 1197 } |
1208 } | 1198 } |
1209 for (UnlinkedExportPublic export in unit.publicNamespace.exports) { | 1199 for (UnlinkedExportPublic export in unit.publicNamespace.exports) { |
1210 referenced.exported.add(export.uri); | 1200 referenced.exported.add(export.uri); |
1211 } | 1201 } |
1212 return referenced; | 1202 return referenced; |
1213 } | 1203 } |
1214 | 1204 |
1215 _ReferencedUris._(); | 1205 _ReferencedUris._(); |
1216 } | 1206 } |
OLD | NEW |