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:typed_data'; | 7 import 'dart:typed_data'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/error/error.dart'; | 10 import 'package:analyzer/error/error.dart'; |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
408 /** | 408 /** |
409 * TODO(scheglov) The existing [SummaryDataStore.addBundle] uses | 409 * TODO(scheglov) The existing [SummaryDataStore.addBundle] uses |
410 * [PackageBundle.unlinkedUnitUris] to add [PackageBundle.unlinkedUnits]. | 410 * [PackageBundle.unlinkedUnitUris] to add [PackageBundle.unlinkedUnits]. |
411 * But we store unlinked bundles with the hash of the file content. This | 411 * But we store unlinked bundles with the hash of the file content. This |
412 * means that when two files are the same, but have different URIs, we | 412 * means that when two files are the same, but have different URIs, we |
413 * add [UnlinkedUnit] with wrong URI. | 413 * add [UnlinkedUnit] with wrong URI. |
414 * | 414 * |
415 * We need to clean this up. | 415 * We need to clean this up. |
416 */ | 416 */ |
417 void _addToStoreUnlinked( | 417 void _addToStoreUnlinked( |
418 SummaryDataStore store, String uri, UnlinkedUnit unlinked) { | 418 SummaryDataStore store, Uri uri, UnlinkedUnit unlinked) { |
419 store.unlinkedMap[uri] = unlinked; | 419 String uriStr = uri.toString(); |
420 store.unlinkedMap[uriStr] = unlinked; | |
420 } | 421 } |
421 | 422 |
422 /** | 423 /** |
423 * Return the cached or newly computed analysis result of the file with the | 424 * Return the cached or newly computed analysis result of the file with the |
424 * given [path]. | 425 * given [path]. |
425 * | 426 * |
426 * The result will have the fully resolved unit and will always be newly | 427 * The result will have the fully resolved unit and will always be newly |
427 * compute only if [withUnit] is `true`. | 428 * compute only if [withUnit] is `true`. |
428 */ | 429 */ |
429 AnalysisResult _computeAnalysisResult(String path, {bool withUnit: false}) { | 430 AnalysisResult _computeAnalysisResult(String path, {bool withUnit: false}) { |
430 // If we don't need the fully resolved unit, check for the cached result. | 431 // If we don't need the fully resolved unit, check for the cached result. |
431 if (!withUnit) { | 432 if (!withUnit) { |
432 FileState file = _fsState.getFile(path); | 433 FileState file = _fsState.getFileForPath(path); |
433 // Prepare the key for the cached result. | 434 // Prepare the key for the cached result. |
434 String key = _getResolvedUnitKey(file); | 435 String key = _getResolvedUnitKey(file); |
435 if (key == null) { | 436 if (key == null) { |
436 _logger.run('Compute the dependency hash for $path', () { | 437 _logger.run('Compute the dependency hash for $path', () { |
437 _createLibraryContext(file); | 438 _createLibraryContext(file); |
438 key = _getResolvedUnitKey(file); | 439 key = _getResolvedUnitKey(file); |
439 }); | 440 }); |
440 } | 441 } |
441 // Check for the cached result. | 442 // Check for the cached result. |
442 AnalysisResult result = _getCachedAnalysisResult(file, key); | 443 AnalysisResult result = _getCachedAnalysisResult(file, key); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
527 | 528 |
528 String libraryUriStr = libraryUri.toString(); | 529 String libraryUriStr = libraryUri.toString(); |
529 _LibraryNode node = nodes[libraryUriStr]; | 530 _LibraryNode node = nodes[libraryUriStr]; |
530 if (node == null) { | 531 if (node == null) { |
531 node = new _LibraryNode(this, libraryFile, libraryUri); | 532 node = new _LibraryNode(this, libraryFile, libraryUri); |
532 nodes[libraryUriStr] = node; | 533 nodes[libraryUriStr] = node; |
533 | 534 |
534 // Append the defining unit. | 535 // Append the defining unit. |
535 { | 536 { |
536 UnlinkedUnit unlinked = libraryFile.unlinked; | 537 UnlinkedUnit unlinked = libraryFile.unlinked; |
537 _addToStoreUnlinked(store, libraryUriStr, unlinked); | 538 _addToStoreUnlinked(store, libraryFile.uri, unlinked); |
538 } | 539 } |
539 | 540 |
540 // Append parts. | 541 // Append parts. |
541 for (FileState part in libraryFile.partedFiles) { | 542 for (FileState part in libraryFile.partedFiles) { |
542 String partUriStr = part.uri.toString(); | |
543 UnlinkedUnit unlinked = part.unlinked; | 543 UnlinkedUnit unlinked = part.unlinked; |
544 _addToStoreUnlinked(store, partUriStr, unlinked); | 544 _addToStoreUnlinked(store, part.uri, unlinked); |
545 } | 545 } |
546 | 546 |
547 // Create nodes for referenced libraries. | 547 // Create nodes for referenced libraries. |
548 libraryFile.importedFiles.forEach(createLibraryNodes); | 548 libraryFile.importedFiles.forEach(createLibraryNodes); |
549 libraryFile.exportedFiles.forEach(createLibraryNodes); | 549 libraryFile.exportedFiles.forEach(createLibraryNodes); |
550 } | 550 } |
551 | 551 |
552 // Done with this node. | 552 // Done with this node. |
553 return node; | 553 return node; |
554 } | 554 } |
555 | 555 |
556 _LibraryNode libraryNode = _logger.run('Compute library nodes', () { | 556 _LibraryNode libraryNode = _logger.run('Compute library nodes', () { |
557 return createLibraryNodes(libraryFile); | 557 return createLibraryNodes(libraryFile); |
558 }); | 558 }); |
559 | 559 |
560 Set<String> libraryUrisToLink = new Set<String>(); | 560 Set<String> libraryUrisToLink = new Set<String>(); |
561 _logger.run('Load linked bundles', () { | 561 _logger.run('Load linked bundles', () { |
562 for (_LibraryNode node in nodes.values) { | 562 for (_LibraryNode node in nodes.values) { |
563 String key = '${node.dependencySignature}.linked'; | 563 String key = '${node.dependencySignature}.linked'; |
564 List<int> bytes = _byteStore.get(key); | 564 List<int> bytes = _byteStore.get(key); |
565 if (bytes != null) { | 565 if (bytes != null) { |
566 PackageBundle linked = new PackageBundle.fromBuffer(bytes); | 566 PackageBundle linked = new PackageBundle.fromBuffer(bytes); |
567 _addToStoreLinked( | 567 _addToStoreLinked( |
568 store, node.uri.toString(), linked.linkedLibraries.single); | 568 store, node.file.uri.toString(), linked.linkedLibraries.single); |
569 } else { | 569 } else { |
570 libraryUrisToLink.add(node.uri.toString()); | 570 libraryUrisToLink.add(node.uri.toString()); |
571 } | 571 } |
572 } | 572 } |
573 int numOfLoaded = nodes.length - libraryUrisToLink.length; | 573 int numOfLoaded = nodes.length - libraryUrisToLink.length; |
574 _logger.writeln('Loaded $numOfLoaded linked bundles.'); | 574 _logger.writeln('Loaded $numOfLoaded linked bundles.'); |
575 }); | 575 }); |
576 | 576 |
577 Map<String, LinkedLibraryBuilder> linkedLibraries = {}; | 577 Map<String, LinkedLibraryBuilder> linkedLibraries = {}; |
578 _logger.run('Link bundles', () { | 578 _logger.run('Link bundles', () { |
579 linkedLibraries = link(libraryUrisToLink, (String uri) { | 579 linkedLibraries = link(libraryUrisToLink, (String uri) { |
580 LinkedLibrary linkedLibrary = store.linkedMap[uri]; | 580 LinkedLibrary linkedLibrary = store.linkedMap[uri]; |
581 if (linkedLibrary == null) { | |
582 throw new StateError('No linked library for: $uri'); | |
583 } | |
584 return linkedLibrary; | 581 return linkedLibrary; |
585 }, (String uri) { | 582 }, (String uri) { |
586 UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri]; | 583 UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri]; |
587 if (unlinkedUnit == null) { | |
588 throw new StateError('No unlinked unit for: $uri'); | |
589 } | |
590 return unlinkedUnit; | 584 return unlinkedUnit; |
591 }, (_) => null, _analysisOptions.strongMode); | 585 }, (_) => null, _analysisOptions.strongMode); |
592 _logger.writeln('Linked ${linkedLibraries.length} bundles.'); | 586 _logger.writeln('Linked ${linkedLibraries.length} bundles.'); |
593 }); | 587 }); |
594 | 588 |
595 linkedLibraries.forEach((uri, linkedBuilder) { | 589 linkedLibraries.forEach((uri, linkedBuilder) { |
596 _LibraryNode node = nodes[uri]; | 590 _LibraryNode node = nodes[uri]; |
597 String key = '${node.dependencySignature}.linked'; | 591 String key = '${node.dependencySignature}.linked'; |
598 List<int> bytes; | 592 List<int> bytes; |
599 { | 593 { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
681 } | 675 } |
682 | 676 |
683 /** | 677 /** |
684 * Verify the API signature for the file with the given [path], and decide | 678 * Verify the API signature for the file with the given [path], and decide |
685 * which linked libraries should be invalidated, and files reanalyzed. | 679 * which linked libraries should be invalidated, and files reanalyzed. |
686 * | 680 * |
687 * TODO(scheglov) I see that adding a local var changes (full) API signature. | 681 * TODO(scheglov) I see that adding a local var changes (full) API signature. |
688 */ | 682 */ |
689 FileState _verifyApiSignature(String path) { | 683 FileState _verifyApiSignature(String path) { |
690 return _logger.run('Verify API signature of $path', () { | 684 return _logger.run('Verify API signature of $path', () { |
691 FileState file = _fsState.getFile(path); | 685 FileState file = _fsState.getFileForPath(path); |
692 bool apiChanged = file.refresh(); | 686 bool apiChanged = file.refresh(); |
Paul Berry
2016/11/03 21:39:34
Don't we need to refresh all files that are associ
scheglov
2016/11/04 04:03:38
Done.
| |
693 if (apiChanged) { | 687 if (apiChanged) { |
694 _logger.writeln('API signatures mismatch found for $path'); | 688 _logger.writeln('API signatures mismatch found for $path'); |
695 _dependencySignatureMap.clear(); | 689 _dependencySignatureMap.clear(); |
696 _filesToAnalyze.addAll(_explicitFiles); | 690 _filesToAnalyze.addAll(_explicitFiles); |
697 } | 691 } |
698 return file; | 692 return file; |
699 }); | 693 }); |
700 } | 694 } |
701 | 695 |
702 /** | 696 /** |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
954 /** | 948 /** |
955 * Complete the [signal] future if it is not completed yet. It is safe to | 949 * Complete the [signal] future if it is not completed yet. It is safe to |
956 * call this method multiple times, but the [signal] will complete only once. | 950 * call this method multiple times, but the [signal] will complete only once. |
957 */ | 951 */ |
958 void notify() { | 952 void notify() { |
959 if (!_completer.isCompleted) { | 953 if (!_completer.isCompleted) { |
960 _completer.complete(null); | 954 _completer.complete(null); |
961 } | 955 } |
962 } | 956 } |
963 } | 957 } |
OLD | NEW |