| 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:convert'; | 5 import 'dart:convert'; |
| 6 import 'dart:typed_data'; | 6 import 'dart:typed_data'; |
| 7 | 7 |
| 8 import 'package:analyzer/dart/ast/ast.dart'; | 8 import 'package:analyzer/dart/ast/ast.dart'; |
| 9 import 'package:analyzer/dart/ast/token.dart'; | 9 import 'package:analyzer/dart/ast/token.dart'; |
| 10 import 'package:analyzer/error/listener.dart'; | 10 import 'package:analyzer/error/listener.dart'; |
| 11 import 'package:analyzer/file_system/file_system.dart'; | 11 import 'package:analyzer/file_system/file_system.dart'; |
| 12 import 'package:analyzer/src/dart/analysis/byte_store.dart'; | 12 import 'package:analyzer/src/dart/analysis/byte_store.dart'; |
| 13 import 'package:analyzer/src/dart/analysis/driver.dart'; | 13 import 'package:analyzer/src/dart/analysis/driver.dart'; |
| 14 import 'package:analyzer/src/dart/scanner/reader.dart'; | 14 import 'package:analyzer/src/dart/scanner/reader.dart'; |
| 15 import 'package:analyzer/src/dart/scanner/scanner.dart'; | 15 import 'package:analyzer/src/dart/scanner/scanner.dart'; |
| 16 import 'package:analyzer/src/generated/engine.dart'; | 16 import 'package:analyzer/src/generated/engine.dart'; |
| 17 import 'package:analyzer/src/generated/parser.dart'; | 17 import 'package:analyzer/src/generated/parser.dart'; |
| 18 import 'package:analyzer/src/generated/source.dart'; | 18 import 'package:analyzer/src/generated/source.dart'; |
| 19 import 'package:analyzer/src/generated/utilities_dart.dart'; | 19 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 20 import 'package:analyzer/src/source/source_resource.dart'; | 20 import 'package:analyzer/src/source/source_resource.dart'; |
| 21 import 'package:analyzer/src/summary/api_signature.dart'; | 21 import 'package:analyzer/src/summary/api_signature.dart'; |
| 22 import 'package:analyzer/src/summary/format.dart'; | 22 import 'package:analyzer/src/summary/format.dart'; |
| 23 import 'package:analyzer/src/summary/idl.dart'; | 23 import 'package:analyzer/src/summary/idl.dart'; |
| 24 import 'package:analyzer/src/summary/summarize_ast.dart'; | 24 import 'package:analyzer/src/summary/summarize_ast.dart'; |
| 25 import 'package:analyzer/src/util/fast_uri.dart'; | 25 import 'package:analyzer/src/util/fast_uri.dart'; |
| 26 import 'package:convert/convert.dart'; | 26 import 'package:convert/convert.dart'; |
| 27 import 'package:crypto/crypto.dart'; | 27 import 'package:crypto/crypto.dart'; |
| 28 import 'package:meta/meta.dart'; |
| 28 | 29 |
| 29 /** | 30 /** |
| 30 * [FileContentOverlay] is used to temporary override content of files. | 31 * [FileContentOverlay] is used to temporary override content of files. |
| 31 */ | 32 */ |
| 32 class FileContentOverlay { | 33 class FileContentOverlay { |
| 33 final _map = <String, String>{}; | 34 final _map = <String, String>{}; |
| 34 | 35 |
| 35 /** | 36 /** |
| 36 * Return the content of the file with the given [path], or `null` the | 37 * Return the content of the file with the given [path], or `null` the |
| 37 * overlay does not override the content of the file. | 38 * overlay does not override the content of the file. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 | 84 |
| 84 String _content; | 85 String _content; |
| 85 String _contentHash; | 86 String _contentHash; |
| 86 LineInfo _lineInfo; | 87 LineInfo _lineInfo; |
| 87 UnlinkedUnit _unlinked; | 88 UnlinkedUnit _unlinked; |
| 88 List<int> _apiSignature; | 89 List<int> _apiSignature; |
| 89 | 90 |
| 90 List<FileState> _importedFiles; | 91 List<FileState> _importedFiles; |
| 91 List<FileState> _exportedFiles; | 92 List<FileState> _exportedFiles; |
| 92 List<FileState> _partedFiles; | 93 List<FileState> _partedFiles; |
| 93 List<FileState> _dependencies; | 94 Set<FileState> _directReferencedFiles = new Set<FileState>(); |
| 95 Set<FileState> _transitiveFiles; |
| 94 | 96 |
| 95 FileState._(this._fsState, this.path, this.uri, this.source); | 97 FileState._(this._fsState, this.path, this.uri, this.source); |
| 96 | 98 |
| 97 /** | 99 /** |
| 98 * The unlinked API signature of the file. | 100 * The unlinked API signature of the file. |
| 99 */ | 101 */ |
| 100 List<int> get apiSignature => _apiSignature; | 102 List<int> get apiSignature => _apiSignature; |
| 101 | 103 |
| 102 /** | 104 /** |
| 103 * The content of the file. | 105 * The content of the file. |
| 104 */ | 106 */ |
| 105 String get content => _content; | 107 String get content => _content; |
| 106 | 108 |
| 107 /** | 109 /** |
| 108 * The MD5 hash of the [content]. | 110 * The MD5 hash of the [content]. |
| 109 */ | 111 */ |
| 110 String get contentHash => _contentHash; | 112 String get contentHash => _contentHash; |
| 111 | 113 |
| 112 /** | 114 /** |
| 113 * Return the list of all direct dependencies. | 115 * Return the set of all directly referenced files - imported, exported or |
| 116 * parted. |
| 114 */ | 117 */ |
| 115 List<FileState> get dependencies => _dependencies; | 118 Set<FileState> get directReferencedFiles => _directReferencedFiles; |
| 116 | 119 |
| 117 /** | 120 /** |
| 118 * The list of files this file exports. | 121 * The list of files this file exports. |
| 119 */ | 122 */ |
| 120 List<FileState> get exportedFiles => _exportedFiles; | 123 List<FileState> get exportedFiles => _exportedFiles; |
| 121 | 124 |
| 122 @override | 125 @override |
| 123 int get hashCode => uri.hashCode; | 126 int get hashCode => uri.hashCode; |
| 124 | 127 |
| 125 /** | 128 /** |
| (...skipping 24 matching lines...) Expand all Loading... |
| 150 * Return information about line in the file. | 153 * Return information about line in the file. |
| 151 */ | 154 */ |
| 152 LineInfo get lineInfo => _lineInfo; | 155 LineInfo get lineInfo => _lineInfo; |
| 153 | 156 |
| 154 /** | 157 /** |
| 155 * The list of files this library file references as parts. | 158 * The list of files this library file references as parts. |
| 156 */ | 159 */ |
| 157 List<FileState> get partedFiles => _partedFiles; | 160 List<FileState> get partedFiles => _partedFiles; |
| 158 | 161 |
| 159 /** | 162 /** |
| 163 * Return the set of transitive files - the file itself and all of the |
| 164 * directly or indirectly referenced files. |
| 165 */ |
| 166 Set<FileState> get transitiveFiles { |
| 167 if (_transitiveFiles == null) { |
| 168 _transitiveFiles = new Set<FileState>(); |
| 169 |
| 170 void appendReferenced(FileState file) { |
| 171 if (_transitiveFiles.add(file)) { |
| 172 file._directReferencedFiles.forEach(appendReferenced); |
| 173 } |
| 174 } |
| 175 |
| 176 appendReferenced(this); |
| 177 } |
| 178 return _transitiveFiles; |
| 179 } |
| 180 |
| 181 /** |
| 160 * The [UnlinkedUnit] of the file. | 182 * The [UnlinkedUnit] of the file. |
| 161 */ | 183 */ |
| 162 UnlinkedUnit get unlinked => _unlinked; | 184 UnlinkedUnit get unlinked => _unlinked; |
| 163 | 185 |
| 164 @override | 186 @override |
| 165 bool operator ==(Object other) { | 187 bool operator ==(Object other) { |
| 166 return other is FileState && other.uri == uri; | 188 return other is FileState && other.uri == uri; |
| 167 } | 189 } |
| 168 | 190 |
| 169 /** | 191 /** |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 if (file != null) { | 304 if (file != null) { |
| 283 _partedFiles.add(file); | 305 _partedFiles.add(file); |
| 284 // TODO(scheglov) Sort for stable results? | 306 // TODO(scheglov) Sort for stable results? |
| 285 _fsState._partToLibraries | 307 _fsState._partToLibraries |
| 286 .putIfAbsent(file, () => <FileState>[]) | 308 .putIfAbsent(file, () => <FileState>[]) |
| 287 .add(this); | 309 .add(this); |
| 288 } | 310 } |
| 289 } | 311 } |
| 290 } | 312 } |
| 291 | 313 |
| 292 // Compute direct dependencies. | 314 // Compute referenced files. |
| 293 _dependencies = (new Set<FileState>() | 315 Set<FileState> oldDirectReferencedFiles = _directReferencedFiles; |
| 294 ..addAll(_importedFiles) | 316 _directReferencedFiles = new Set<FileState>() |
| 295 ..addAll(_exportedFiles) | 317 ..addAll(_importedFiles) |
| 296 ..addAll(_partedFiles)) | 318 ..addAll(_exportedFiles) |
| 297 .toList(); | 319 ..addAll(_partedFiles); |
| 320 |
| 321 // If the set of directly referenced files of this file is changed, |
| 322 // then the transitive sets of files that include this file are also |
| 323 // changed. Reset these transitive sets. |
| 324 if (_directReferencedFiles.length != oldDirectReferencedFiles.length || |
| 325 !_directReferencedFiles.containsAll(oldDirectReferencedFiles)) { |
| 326 for (FileState file in _fsState._uriToFile.values) { |
| 327 if (file._transitiveFiles != null && |
| 328 file._transitiveFiles.contains(this)) { |
| 329 file._transitiveFiles = null; |
| 330 } |
| 331 } |
| 332 } |
| 298 | 333 |
| 299 // Return whether the API signature changed. | 334 // Return whether the API signature changed. |
| 300 return apiSignatureChanged; | 335 return apiSignatureChanged; |
| 301 } | 336 } |
| 302 | 337 |
| 303 @override | 338 @override |
| 304 String toString() => path; | 339 String toString() => path; |
| 305 | 340 |
| 306 /** | 341 /** |
| 307 * Return the [FileState] for the given [relativeUri]. | 342 * Return the [FileState] for the given [relativeUri]. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 /** | 396 /** |
| 362 * Mapping from a path to the corresponding canonical [FileState]. | 397 * Mapping from a path to the corresponding canonical [FileState]. |
| 363 */ | 398 */ |
| 364 final Map<String, FileState> _pathToCanonicalFile = {}; | 399 final Map<String, FileState> _pathToCanonicalFile = {}; |
| 365 | 400 |
| 366 /** | 401 /** |
| 367 * Mapping from a part to the libraries it is a part of. | 402 * Mapping from a part to the libraries it is a part of. |
| 368 */ | 403 */ |
| 369 final Map<FileState, List<FileState>> _partToLibraries = {}; | 404 final Map<FileState, List<FileState>> _partToLibraries = {}; |
| 370 | 405 |
| 406 FileSystemStateTestView _testView; |
| 407 |
| 371 FileSystemState( | 408 FileSystemState( |
| 372 this._logger, | 409 this._logger, |
| 373 this._byteStore, | 410 this._byteStore, |
| 374 this._contentOverlay, | 411 this._contentOverlay, |
| 375 this._resourceProvider, | 412 this._resourceProvider, |
| 376 this._sourceFactory, | 413 this._sourceFactory, |
| 377 this._analysisOptions, | 414 this._analysisOptions, |
| 378 this._salt); | 415 this._salt) { |
| 416 _testView = new FileSystemStateTestView(this); |
| 417 } |
| 379 | 418 |
| 380 /** | 419 /** |
| 381 * Return the set of known files. | 420 * Return the set of known files. |
| 382 */ | 421 */ |
| 383 Set<String> get knownFiles => _pathToFiles.keys.toSet(); | 422 Set<String> get knownFiles => _pathToFiles.keys.toSet(); |
| 384 | 423 |
| 424 @visibleForTesting |
| 425 FileSystemStateTestView get test => _testView; |
| 426 |
| 385 /** | 427 /** |
| 386 * Return the canonical [FileState] for the given absolute [path]. The | 428 * Return the canonical [FileState] for the given absolute [path]. The |
| 387 * returned file has the last known state since if was last refreshed. | 429 * returned file has the last known state since if was last refreshed. |
| 388 * | 430 * |
| 389 * Here "canonical" means that if the [path] is in a package `lib` then the | 431 * Here "canonical" means that if the [path] is in a package `lib` then the |
| 390 * returned file will have the `package:` style URI. | 432 * returned file will have the `package:` style URI. |
| 391 */ | 433 */ |
| 392 FileState getFileForPath(String path) { | 434 FileState getFileForPath(String path) { |
| 393 FileState file = _pathToCanonicalFile[path]; | 435 FileState file = _pathToCanonicalFile[path]; |
| 394 if (file == null) { | 436 if (file == null) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 FileState canonicalFile = getFileForPath(path); | 488 FileState canonicalFile = getFileForPath(path); |
| 447 List<FileState> allFiles = _pathToFiles[path].toList(); | 489 List<FileState> allFiles = _pathToFiles[path].toList(); |
| 448 if (allFiles.length == 1) { | 490 if (allFiles.length == 1) { |
| 449 return allFiles; | 491 return allFiles; |
| 450 } | 492 } |
| 451 return allFiles | 493 return allFiles |
| 452 ..remove(canonicalFile) | 494 ..remove(canonicalFile) |
| 453 ..insert(0, canonicalFile); | 495 ..insert(0, canonicalFile); |
| 454 } | 496 } |
| 455 } | 497 } |
| 498 |
| 499 @visibleForTesting |
| 500 class FileSystemStateTestView { |
| 501 final FileSystemState state; |
| 502 |
| 503 FileSystemStateTestView(this.state); |
| 504 |
| 505 Set<FileState> get filesWithoutTransitive { |
| 506 return state._uriToFile.values |
| 507 .where((f) => f._transitiveFiles == null) |
| 508 .toSet(); |
| 509 } |
| 510 } |
| OLD | NEW |