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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 * The results of analysis of the file might still be produced by the | 289 * The results of analysis of the file might still be produced by the |
290 * [results] stream. The driver will try to stop producing these results, | 290 * [results] stream. The driver will try to stop producing these results, |
291 * but does not guarantee this. | 291 * but does not guarantee this. |
292 */ | 292 */ |
293 void removeFile(String path) { | 293 void removeFile(String path) { |
294 _explicitFiles.remove(path); | 294 _explicitFiles.remove(path); |
295 _filesToAnalyze.remove(path); | 295 _filesToAnalyze.remove(path); |
296 } | 296 } |
297 | 297 |
298 /** | 298 /** |
| 299 * TODO(scheglov) see [_addToStoreUnlinked] |
| 300 */ |
| 301 void _addToStoreLinked( |
| 302 SummaryDataStore store, String uri, LinkedLibrary linked) { |
| 303 store.linkedMap[uri] = linked; |
| 304 } |
| 305 |
| 306 /** |
| 307 * TODO(scheglov) The existing [SummaryDataStore.addBundle] uses |
| 308 * [PackageBundle.unlinkedUnitUris] to add [PackageBundle.unlinkedUnits]. |
| 309 * But we store unlinked bundles with the hash of the file content. This |
| 310 * means that when two files are the same, but have different URIs, we |
| 311 * add [UnlinkedUnit] with wrong URI. |
| 312 * |
| 313 * We need to clean this up. |
| 314 */ |
| 315 void _addToStoreUnlinked( |
| 316 SummaryDataStore store, String uri, UnlinkedUnit unlinked) { |
| 317 store.unlinkedMap[uri] = unlinked; |
| 318 } |
| 319 |
| 320 /** |
299 * TODO(scheglov) replace with actual [AnalysisResult] computing. | 321 * TODO(scheglov) replace with actual [AnalysisResult] computing. |
300 */ | 322 */ |
301 List<String> _computeAndPrintErrors(_File file) { | 323 List<String> _computeAndPrintErrors(_File file) { |
302 // TODO(scheglov) Computing resolved unit fails for these units. | 324 // TODO(scheglov) Computing resolved unit fails for these units. |
303 // pkg/analyzer/lib/plugin/embedded_resolver_provider.dart | 325 // pkg/analyzer/lib/plugin/embedded_resolver_provider.dart |
304 // pkg/analyzer/lib/plugin/embedded_resolver_provider.dart | 326 // pkg/analyzer/lib/plugin/embedded_resolver_provider.dart |
305 if (file.path.endsWith( | 327 if (file.path.endsWith( |
306 'pkg/analyzer/lib/plugin/embedded_resolver_provider.dart') || | 328 'pkg/analyzer/lib/plugin/embedded_resolver_provider.dart') || |
307 file.path.endsWith('pkg/analyzer/lib/source/embedder.dart') || | 329 file.path.endsWith('pkg/analyzer/lib/source/embedder.dart') || |
308 file.path.endsWith('pkg/analyzer/lib/src/generated/ast.dart') || | 330 file.path.endsWith('pkg/analyzer/lib/src/generated/ast.dart') || |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 return null; | 437 return null; |
416 } | 438 } |
417 | 439 |
418 String libraryUriStr = libraryUri.toString(); | 440 String libraryUriStr = libraryUri.toString(); |
419 _LibraryNode node = nodes[libraryUriStr]; | 441 _LibraryNode node = nodes[libraryUriStr]; |
420 if (node == null) { | 442 if (node == null) { |
421 node = new _LibraryNode(this, nodes, libraryUri); | 443 node = new _LibraryNode(this, nodes, libraryUri); |
422 nodes[libraryUriStr] = node; | 444 nodes[libraryUriStr] = node; |
423 _ReferencedUris referenced = _getReferencedUris(libraryFile); | 445 _ReferencedUris referenced = _getReferencedUris(libraryFile); |
424 | 446 |
| 447 // Append the defining unit. |
| 448 { |
| 449 PackageBundle unlinked = _getUnlinked(libraryFile); |
| 450 node.unlinkedBundles.add(unlinked); |
| 451 _addToStoreUnlinked( |
| 452 store, libraryUriStr, unlinked.unlinkedUnits.single); |
| 453 } |
| 454 |
425 // Append unlinked bundles. | 455 // Append unlinked bundles. |
426 for (String uri in referenced.parted) { | 456 for (String uri in referenced.parted) { |
427 _File file = libraryFile.resolveUri(uri); | 457 _File file = libraryFile.resolveUri(uri); |
428 PackageBundle unlinked = _getUnlinked(file); | 458 PackageBundle unlinked = _getUnlinked(file); |
429 node.unlinkedBundles.add(unlinked); | 459 node.unlinkedBundles.add(unlinked); |
430 store.addBundle(null, unlinked); | 460 _addToStoreUnlinked( |
| 461 store, file.uri.toString(), unlinked.unlinkedUnits.single); |
431 } | 462 } |
432 | 463 |
433 // Create nodes for referenced libraries. | 464 // Create nodes for referenced libraries. |
434 for (String uri in referenced.imported) { | 465 for (String uri in referenced.imported) { |
435 _File file = libraryFile.resolveUri(uri); | 466 _File file = libraryFile.resolveUri(uri); |
436 createLibraryNodes(file); | 467 createLibraryNodes(file); |
437 } | 468 } |
438 for (String uri in referenced.exported) { | 469 for (String uri in referenced.exported) { |
439 _File file = libraryFile.resolveUri(uri); | 470 _File file = libraryFile.resolveUri(uri); |
440 createLibraryNodes(file); | 471 createLibraryNodes(file); |
441 } | 472 } |
442 } | 473 } |
443 | 474 |
444 // Done with this node. | 475 // Done with this node. |
445 return node; | 476 return node; |
446 } | 477 } |
447 | 478 |
448 _LibraryNode libraryNode = _logger.run('Compute library nodes', () { | 479 _LibraryNode libraryNode = _logger.run('Compute library nodes', () { |
449 return createLibraryNodes(libraryFile); | 480 return createLibraryNodes(libraryFile); |
450 }); | 481 }); |
451 | 482 |
452 Set<String> libraryUrisToLink = new Set<String>(); | 483 Set<String> libraryUrisToLink = new Set<String>(); |
453 _logger.run('Load linked bundles', () { | 484 _logger.run('Load linked bundles', () { |
454 for (_LibraryNode node in nodes.values) { | 485 for (_LibraryNode node in nodes.values) { |
455 String key = '${node.dependencySignature}.linked'; | 486 String key = '${node.dependencySignature}.linked'; |
456 List<int> bytes = _byteStore.get(key); | 487 List<int> bytes = _byteStore.get(key); |
457 if (bytes != null) { | 488 if (bytes != null) { |
458 PackageBundle linked = new PackageBundle.fromBuffer(bytes); | 489 PackageBundle linked = new PackageBundle.fromBuffer(bytes); |
459 store.addBundle(null, linked); | 490 _addToStoreLinked( |
| 491 store, node.uri.toString(), linked.linkedLibraries.single); |
460 } else { | 492 } else { |
461 libraryUrisToLink.add(node.uri.toString()); | 493 libraryUrisToLink.add(node.uri.toString()); |
462 } | 494 } |
463 } | 495 } |
464 int numOfLoaded = nodes.length - libraryUrisToLink.length; | 496 int numOfLoaded = nodes.length - libraryUrisToLink.length; |
465 _logger.writeln('Loaded $numOfLoaded linked bundles.'); | 497 _logger.writeln('Loaded $numOfLoaded linked bundles.'); |
466 }); | 498 }); |
467 | 499 |
468 Map<String, LinkedLibraryBuilder> linkedLibraries = {}; | 500 Map<String, LinkedLibraryBuilder> linkedLibraries = {}; |
469 _logger.run('Link bundles', () { | 501 _logger.run('Link bundles', () { |
(...skipping 16 matching lines...) Expand all Loading... |
486 linkedLibraries.forEach((uri, linkedBuilder) { | 518 linkedLibraries.forEach((uri, linkedBuilder) { |
487 _LibraryNode node = nodes[uri]; | 519 _LibraryNode node = nodes[uri]; |
488 String key = '${node.dependencySignature}.linked'; | 520 String key = '${node.dependencySignature}.linked'; |
489 List<int> bytes; | 521 List<int> bytes; |
490 { | 522 { |
491 PackageBundleAssembler assembler = new PackageBundleAssembler(); | 523 PackageBundleAssembler assembler = new PackageBundleAssembler(); |
492 assembler.addLinkedLibrary(uri, linkedBuilder); | 524 assembler.addLinkedLibrary(uri, linkedBuilder); |
493 bytes = assembler.assemble().toBuffer(); | 525 bytes = assembler.assemble().toBuffer(); |
494 } | 526 } |
495 PackageBundle linked = new PackageBundle.fromBuffer(bytes); | 527 PackageBundle linked = new PackageBundle.fromBuffer(bytes); |
496 store.addBundle(null, linked); | 528 _addToStoreLinked(store, uri, linked.linkedLibraries.single); |
497 _byteStore.put(key, bytes); | 529 _byteStore.put(key, bytes); |
498 }); | 530 }); |
499 | 531 |
500 return new _LibraryContext(libraryFile, libraryNode, store); | 532 return new _LibraryContext(libraryFile, libraryNode, store); |
501 }); | 533 }); |
502 } | 534 } |
503 | 535 |
504 /** | 536 /** |
505 * Return the [_File] for the given [path] in [_sourceFactory]. | 537 * Return the [_File] for the given [path] in [_sourceFactory]. |
506 */ | 538 */ |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 referencedUris.isLibrary = isLibrary; | 573 referencedUris.isLibrary = isLibrary; |
542 referencedUris.imported.addAll(imported); | 574 referencedUris.imported.addAll(imported); |
543 referencedUris.exported.addAll(exported); | 575 referencedUris.exported.addAll(exported); |
544 referencedUris.parted.addAll(parted); | 576 referencedUris.parted.addAll(parted); |
545 return referencedUris; | 577 return referencedUris; |
546 } | 578 } |
547 } | 579 } |
548 | 580 |
549 // Compute URIs. | 581 // Compute URIs. |
550 _ReferencedUris referencedUris = new _ReferencedUris(); | 582 _ReferencedUris referencedUris = new _ReferencedUris(); |
551 referencedUris.parted.add(file.uri.toString()); | |
552 for (Directive directive in file.unit.directives) { | 583 for (Directive directive in file.unit.directives) { |
553 if (directive is PartOfDirective) { | 584 if (directive is PartOfDirective) { |
554 referencedUris.isLibrary = false; | 585 referencedUris.isLibrary = false; |
555 } else if (directive is UriBasedDirective) { | 586 } else if (directive is UriBasedDirective) { |
556 String uri = directive.uri.stringValue; | 587 String uri = directive.uri.stringValue; |
557 if (directive is ImportDirective) { | 588 if (directive is ImportDirective) { |
558 referencedUris.imported.add(uri); | 589 referencedUris.imported.add(uri); |
559 } else if (directive is ExportDirective) { | 590 } else if (directive is ExportDirective) { |
560 referencedUris.exported.add(uri); | 591 referencedUris.exported.add(uri); |
561 } else if (directive is PartDirective) { | 592 } else if (directive is PartDirective) { |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 } | 883 } |
853 | 884 |
854 @override | 885 @override |
855 String toString() => uri.toString(); | 886 String toString() => uri.toString(); |
856 | 887 |
857 /** | 888 /** |
858 * Fill the [_content] and [_contentHash] fields. | 889 * Fill the [_content] and [_contentHash] fields. |
859 * | 890 * |
860 * If the [_content] field is still `null`, get the content from the | 891 * If the [_content] field is still `null`, get the content from the |
861 * content cache or from the [source]. If the content cannot be accessed | 892 * content cache or from the [source]. If the content cannot be accessed |
862 * because of an exception, it considers to be an empty string. | 893 * because of an exception, it is considered to be an empty string. |
863 * | 894 * |
864 * When a new content is read, the new [_contentHash] should be computed and | 895 * When a new content is read, the new [_contentHash] should be computed and |
865 * the current file state should be updated. | 896 * the current file state should be updated. |
866 */ | 897 */ |
867 void _readContentAndComputeHash() { | 898 void _readContentAndComputeHash() { |
868 try { | 899 try { |
869 _content = driver._contentCache.getContents(source); | 900 _content = driver._contentCache.getContents(source); |
870 _content ??= source.contents.data; | 901 _content ??= source.contents.data; |
871 } catch (_) { | 902 } catch (_) { |
872 // TODO(scheglov) Fix the bug with not existing sources. | |
873 // We should not put "self URI" into cached _ReferencedUris. | |
874 // Otherwise such not-existing/empty sources all have the same hash, | |
875 // but their "self URIs" must be all different. | |
876 _content = ''; | 903 _content = ''; |
| 904 // TODO(scheglov) We fail to report URI_DOES_NOT_EXIST. |
| 905 // On one hand we need to provide an unlinked bundle to prevent |
| 906 // analysis context from reading the file (we want it to work |
| 907 // hermetically and handle one one file at a time). OTOH, |
| 908 // ResynthesizerResultProvider happily reports that any source in the |
| 909 // SummaryDataStore has MODIFICATION_TIME `0`. We need to return `-1` |
| 910 // for missing files. Maybe add this feature to SummaryDataStore? |
877 } | 911 } |
878 // Compute the content hash. | 912 // Compute the content hash. |
879 List<int> textBytes = UTF8.encode(_content); | 913 List<int> textBytes = UTF8.encode(_content); |
880 List<int> hashBytes = md5.convert(textBytes).bytes; | 914 List<int> hashBytes = md5.convert(textBytes).bytes; |
881 _contentHash = hex.encode(hashBytes); | 915 _contentHash = hex.encode(hashBytes); |
882 // Update the current file state. | 916 // Update the current file state. |
883 driver._fileContentHashMap[path] = _contentHash; | 917 driver._fileContentHashMap[path] = _contentHash; |
884 } | 918 } |
885 } | 919 } |
886 | 920 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 | 1033 |
1000 /** | 1034 /** |
1001 * TODO(scheglov) document | 1035 * TODO(scheglov) document |
1002 */ | 1036 */ |
1003 class _ReferencedUris { | 1037 class _ReferencedUris { |
1004 bool isLibrary = true; | 1038 bool isLibrary = true; |
1005 final List<String> imported = <String>[]; | 1039 final List<String> imported = <String>[]; |
1006 final List<String> exported = <String>[]; | 1040 final List<String> exported = <String>[]; |
1007 final List<String> parted = <String>[]; | 1041 final List<String> parted = <String>[]; |
1008 } | 1042 } |
OLD | NEW |