| 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 |