| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library deferred_load; | 5 library deferred_load; |
| 6 | 6 |
| 7 import 'common/backend_api.dart' show | 7 import 'common/backend_api.dart' show |
| 8 Backend; | 8 Backend; |
| 9 import 'common/tasks.dart' show | 9 import 'common/tasks.dart' show |
| 10 CompilerTask; | 10 CompilerTask; |
| 11 import 'compiler.dart' show | 11 import 'compiler.dart' show |
| 12 Compiler; | 12 Compiler; |
| 13 import 'constants/values.dart' show | 13 import 'constants/values.dart' show |
| 14 ConstantValue, | 14 ConstantValue, |
| 15 ConstructedConstantValue, | 15 ConstructedConstantValue, |
| 16 DeferredConstantValue, | 16 DeferredConstantValue, |
| 17 StringConstantValue; | 17 StringConstantValue; |
| 18 import 'dart_types.dart'; | 18 import 'dart_types.dart'; |
| 19 import 'diagnostics/messages.dart' show | 19 import 'diagnostics/messages.dart' show |
| 20 MessageKind; | 20 MessageKind; |
| 21 import 'diagnostics/spannable.dart' show | 21 import 'diagnostics/spannable.dart' show |
| 22 Spannable; | 22 Spannable; |
| 23 import 'elements/elements.dart' show | 23 import 'elements/elements.dart' show |
| 24 AccessorElement, | 24 AccessorElement, |
| 25 AstElement, | 25 AstElement, |
| 26 ClassElement, | 26 ClassElement, |
| 27 Element, | 27 Element, |
| 28 ElementKind, | 28 ElementKind, |
| 29 Elements, | 29 Elements, |
| 30 ExportElement, |
| 30 FunctionElement, | 31 FunctionElement, |
| 32 ImportElement, |
| 31 LibraryElement, | 33 LibraryElement, |
| 32 MetadataAnnotation, | 34 MetadataAnnotation, |
| 33 PrefixElement, | 35 PrefixElement, |
| 34 ScopeContainerElement, | 36 ScopeContainerElement, |
| 35 TypedefElement, | 37 TypedefElement, |
| 36 VoidElement; | 38 VoidElement; |
| 37 import 'js_backend/js_backend.dart' show | 39 import 'js_backend/js_backend.dart' show |
| 38 JavaScriptBackend; | 40 JavaScriptBackend; |
| 39 import 'resolution/resolution.dart' show | 41 import 'resolution/resolution.dart' show |
| 40 AnalyzableElementX; | 42 AnalyzableElementX; |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 void registerConstantDeferredUse(DeferredConstantValue constant, | 222 void registerConstantDeferredUse(DeferredConstantValue constant, |
| 221 PrefixElement prefix) { | 223 PrefixElement prefix) { |
| 222 OutputUnit outputUnit = new OutputUnit(); | 224 OutputUnit outputUnit = new OutputUnit(); |
| 223 outputUnit.imports.add(new _DeclaredDeferredImport(prefix.deferredImport)); | 225 outputUnit.imports.add(new _DeclaredDeferredImport(prefix.deferredImport)); |
| 224 _constantToOutputUnit[constant] = outputUnit; | 226 _constantToOutputUnit[constant] = outputUnit; |
| 225 } | 227 } |
| 226 | 228 |
| 227 /// Answers whether [element] is explicitly deferred when referred to from | 229 /// Answers whether [element] is explicitly deferred when referred to from |
| 228 /// [library]. | 230 /// [library]. |
| 229 bool _isExplicitlyDeferred(Element element, LibraryElement library) { | 231 bool _isExplicitlyDeferred(Element element, LibraryElement library) { |
| 230 Link<Import> imports = _getImports(element, library); | 232 Iterable<ImportElement> imports = _getImports(element, library); |
| 231 // If the element is not imported explicitly, it is implicitly imported | 233 // If the element is not imported explicitly, it is implicitly imported |
| 232 // not deferred. | 234 // not deferred. |
| 233 if (imports.isEmpty) return false; | 235 if (imports.isEmpty) return false; |
| 234 // An element could potentially be loaded by several imports. If all of them | 236 // An element could potentially be loaded by several imports. If all of them |
| 235 // is explicitly deferred, we say the element is explicitly deferred. | 237 // is explicitly deferred, we say the element is explicitly deferred. |
| 236 // TODO(sigurdm): We might want to give a warning if the imports do not | 238 // TODO(sigurdm): We might want to give a warning if the imports do not |
| 237 // agree. | 239 // agree. |
| 238 return imports.every((Import import) => import.isDeferred); | 240 return imports.every((ImportElement import) => import.isDeferred); |
| 239 } | 241 } |
| 240 | 242 |
| 241 /// Returns a [Link] of every [Import] that imports [element] into [library]. | 243 /// Returns a [Link] of every [Import] that imports [element] into [library]. |
| 242 Link<Import> _getImports(Element element, LibraryElement library) { | 244 Iterable<ImportElement> _getImports(Element element, LibraryElement library) { |
| 243 if (element.isClassMember) { | 245 if (element.isClassMember) { |
| 244 element = element.enclosingClass; | 246 element = element.enclosingClass; |
| 245 } | 247 } |
| 246 if (element.isAccessor) { | 248 if (element.isAccessor) { |
| 247 element = (element as AccessorElement).abstractField; | 249 element = (element as AccessorElement).abstractField; |
| 248 } | 250 } |
| 249 return library.getImportsFor(element); | 251 return library.getImportsFor(element); |
| 250 } | 252 } |
| 251 | 253 |
| 252 /// Finds all elements and constants that [element] depends directly on. | 254 /// Finds all elements and constants that [element] depends directly on. |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 Set<LibraryElement> _nonDeferredReachableLibraries(LibraryElement root) { | 392 Set<LibraryElement> _nonDeferredReachableLibraries(LibraryElement root) { |
| 391 Set<LibraryElement> result = new Set<LibraryElement>(); | 393 Set<LibraryElement> result = new Set<LibraryElement>(); |
| 392 | 394 |
| 393 void traverseLibrary(LibraryElement library) { | 395 void traverseLibrary(LibraryElement library) { |
| 394 if (result.contains(library)) return; | 396 if (result.contains(library)) return; |
| 395 result.add(library); | 397 result.add(library); |
| 396 | 398 |
| 397 iterateTags(LibraryElement library) { | 399 iterateTags(LibraryElement library) { |
| 398 // TODO(sigurdm): Make helper getLibraryDependencyTags when tags is | 400 // TODO(sigurdm): Make helper getLibraryDependencyTags when tags is |
| 399 // changed to be a List instead of a Link. | 401 // changed to be a List instead of a Link. |
| 400 for (LibraryTag tag in library.tags) { | 402 for (ImportElement import in library.imports) { |
| 401 if (tag is! LibraryDependency) continue; | 403 if (!import.isDeferred) { |
| 402 LibraryDependency libraryDependency = tag; | 404 LibraryElement importedLibrary = import.importedLibrary; |
| 403 if (!(libraryDependency is Import && libraryDependency.isDeferred)) { | |
| 404 LibraryElement importedLibrary = library.getLibraryFromTag(tag); | |
| 405 traverseLibrary(importedLibrary); | 405 traverseLibrary(importedLibrary); |
| 406 } | 406 } |
| 407 } | 407 } |
| 408 for (ExportElement export in library.exports) { |
| 409 LibraryElement exportedLibrary = export.exportedLibrary; |
| 410 traverseLibrary(exportedLibrary); |
| 411 } |
| 408 } | 412 } |
| 409 | 413 |
| 410 iterateTags(library); | 414 iterateTags(library); |
| 411 if (library.isPatched) { | 415 if (library.isPatched) { |
| 412 iterateTags(library.implementation); | 416 iterateTags(library.implementation); |
| 413 } | 417 } |
| 414 } | 418 } |
| 415 traverseLibrary(root); | 419 traverseLibrary(root); |
| 416 result.add(compiler.coreLibrary); | 420 result.add(compiler.coreLibrary); |
| 417 return result; | 421 return result; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 | 465 |
| 462 // This call can modify [dependentElements] and [dependentConstants]. | 466 // This call can modify [dependentElements] and [dependentConstants]. |
| 463 _collectAllElementsAndConstantsResolvedFrom( | 467 _collectAllElementsAndConstantsResolvedFrom( |
| 464 element, dependentElements, dependentConstants, isMirrorUsage); | 468 element, dependentElements, dependentConstants, isMirrorUsage); |
| 465 | 469 |
| 466 library = element.library; | 470 library = element.library; |
| 467 } | 471 } |
| 468 | 472 |
| 469 for (Element dependency in dependentElements) { | 473 for (Element dependency in dependentElements) { |
| 470 if (_isExplicitlyDeferred(dependency, library)) { | 474 if (_isExplicitlyDeferred(dependency, library)) { |
| 471 for (Import deferredImport in _getImports(dependency, library)) { | 475 for (ImportElement deferredImport in _getImports(dependency, library)) { |
| 472 _mapDependencies( | 476 _mapDependencies(element: dependency, |
| 473 element: dependency, | |
| 474 import: new _DeclaredDeferredImport(deferredImport)); | 477 import: new _DeclaredDeferredImport(deferredImport)); |
| 475 } | 478 } |
| 476 } else { | 479 } else { |
| 477 _mapDependencies(element: dependency, import: import); | 480 _mapDependencies(element: dependency, import: import); |
| 478 } | 481 } |
| 479 } | 482 } |
| 480 | 483 |
| 481 for (ConstantValue dependency in dependentConstants) { | 484 for (ConstantValue dependency in dependentConstants) { |
| 482 if (dependency is DeferredConstantValue) { | 485 if (dependency is DeferredConstantValue) { |
| 483 _mapConstantDependencies(dependency, | 486 _mapConstantDependencies(dependency, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 494 void _addMirrorElements() { | 497 void _addMirrorElements() { |
| 495 void mapDependenciesIfResolved(Element element, | 498 void mapDependenciesIfResolved(Element element, |
| 496 _DeferredImport deferredImport) { | 499 _DeferredImport deferredImport) { |
| 497 // If an element is the target of a MirrorsUsed annotation but never used | 500 // If an element is the target of a MirrorsUsed annotation but never used |
| 498 // It will not be resolved, and we should not call isNeededForReflection. | 501 // It will not be resolved, and we should not call isNeededForReflection. |
| 499 // TODO(sigurdm): Unresolved elements should just answer false when | 502 // TODO(sigurdm): Unresolved elements should just answer false when |
| 500 // asked isNeededForReflection. Instead an internal error is triggered. | 503 // asked isNeededForReflection. Instead an internal error is triggered. |
| 501 // So we have to filter them out here. | 504 // So we have to filter them out here. |
| 502 if (element is AnalyzableElementX && !element.hasTreeElements) return; | 505 if (element is AnalyzableElementX && !element.hasTreeElements) return; |
| 503 if (compiler.backend.isAccessibleByReflection(element)) { | 506 if (compiler.backend.isAccessibleByReflection(element)) { |
| 504 _mapDependencies(element: element, import: deferredImport, | 507 _mapDependencies( |
| 505 isMirrorUsage: true); | 508 element: element, import: deferredImport, isMirrorUsage: true); |
| 506 } | 509 } |
| 507 } | 510 } |
| 508 | 511 |
| 509 // For each deferred import we analyze all elements reachable from the | 512 // For each deferred import we analyze all elements reachable from the |
| 510 // imported library through non-deferred imports. | 513 // imported library through non-deferred imports. |
| 511 handleLibrary(LibraryElement library, _DeferredImport deferredImport) { | 514 void handleLibrary(LibraryElement library, _DeferredImport deferredImport) { |
| 512 library.implementation.forEachLocalMember((Element element) { | 515 library.implementation.forEachLocalMember((Element element) { |
| 513 mapDependenciesIfResolved(element, deferredImport); | 516 mapDependenciesIfResolved(element, deferredImport); |
| 514 }); | 517 }); |
| 515 | 518 |
| 516 for (MetadataAnnotation metadata in library.metadata) { | 519 void processMetadata(Element element) { |
| 517 ConstantValue constant = | 520 for (MetadataAnnotation metadata in element.metadata) { |
| 518 backend.constants.getConstantValueForMetadata(metadata); | |
| 519 if (constant != null) { | |
| 520 _mapConstantDependencies(constant, deferredImport); | |
| 521 } | |
| 522 } | |
| 523 for (LibraryTag tag in library.tags) { | |
| 524 for (MetadataAnnotation metadata in tag.metadata) { | |
| 525 ConstantValue constant = | 521 ConstantValue constant = |
| 526 backend.constants.getConstantValueForMetadata(metadata); | 522 backend.constants.getConstantValueForMetadata(metadata); |
| 527 if (constant != null) { | 523 if (constant != null) { |
| 528 _mapConstantDependencies(constant, deferredImport); | 524 _mapConstantDependencies(constant, deferredImport); |
| 529 } | 525 } |
| 530 } | 526 } |
| 531 } | 527 } |
| 528 |
| 529 processMetadata(library); |
| 530 library.imports.forEach(processMetadata); |
| 531 library.exports.forEach(processMetadata); |
| 532 } | 532 } |
| 533 | 533 |
| 534 for (_DeferredImport deferredImport in _allDeferredImports.keys) { | 534 for (_DeferredImport deferredImport in _allDeferredImports.keys) { |
| 535 LibraryElement deferredLibrary = _allDeferredImports[deferredImport]; | 535 LibraryElement deferredLibrary = _allDeferredImports[deferredImport]; |
| 536 for (LibraryElement library in | 536 for (LibraryElement library in |
| 537 _nonDeferredReachableLibraries(deferredLibrary)) { | 537 _nonDeferredReachableLibraries(deferredLibrary)) { |
| 538 handleLibrary(library, deferredImport); | 538 handleLibrary(library, deferredImport); |
| 539 } | 539 } |
| 540 } | 540 } |
| 541 } | 541 } |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 // import "lib.dart" as a; | 705 // import "lib.dart" as a; |
| 706 // import "lib2.dart" deferred as a; | 706 // import "lib2.dart" deferred as a; |
| 707 // 4. | 707 // 4. |
| 708 // import "lib.dart" as a; | 708 // import "lib.dart" as a; |
| 709 // import "lib2.dart" as a; | 709 // import "lib2.dart" as a; |
| 710 // We must be able to signal error for case 1, 2, 3, but accept case 4. | 710 // We must be able to signal error for case 1, 2, 3, but accept case 4. |
| 711 | 711 |
| 712 // The prefixes that have been used by any imports in this library. | 712 // The prefixes that have been used by any imports in this library. |
| 713 Setlet<String> usedPrefixes = new Setlet<String>(); | 713 Setlet<String> usedPrefixes = new Setlet<String>(); |
| 714 // The last deferred import we saw with a given prefix (if any). | 714 // The last deferred import we saw with a given prefix (if any). |
| 715 Map<String, Import> prefixDeferredImport = new Map<String, Import>(); | 715 Map<String, ImportElement> prefixDeferredImport = |
| 716 new Map<String, ImportElement>(); |
| 716 for (LibraryElement library in compiler.libraryLoader.libraries) { | 717 for (LibraryElement library in compiler.libraryLoader.libraries) { |
| 717 compiler.withCurrentElement(library, () { | 718 compiler.withCurrentElement(library, () { |
| 718 prefixDeferredImport.clear(); | 719 prefixDeferredImport.clear(); |
| 719 usedPrefixes.clear(); | 720 usedPrefixes.clear(); |
| 720 // TODO(sigurdm): Make helper getLibraryImportTags when tags is a List | 721 // TODO(sigurdm): Make helper getLibraryImportTags when tags is a List |
| 721 // instead of a Link. | 722 // instead of a Link. |
| 722 for (LibraryTag tag in library.tags) { | 723 for (ImportElement import in library.imports) { |
| 723 if (tag is! Import) continue; | |
| 724 Import import = tag; | |
| 725 | |
| 726 /// Give an error if the old annotation-based syntax has been used. | 724 /// Give an error if the old annotation-based syntax has been used. |
| 727 List<MetadataAnnotation> metadataList = import.metadata; | 725 List<MetadataAnnotation> metadataList = import.metadata; |
| 728 if (metadataList != null) { | 726 if (metadataList != null) { |
| 729 for (MetadataAnnotation metadata in metadataList) { | 727 for (MetadataAnnotation metadata in metadataList) { |
| 730 metadata.ensureResolved(compiler); | 728 metadata.ensureResolved(compiler); |
| 731 ConstantValue value = | 729 ConstantValue value = |
| 732 compiler.constants.getConstantValue(metadata.constant); | 730 compiler.constants.getConstantValue(metadata.constant); |
| 733 Element element = value.getType(compiler.coreTypes).element; | 731 Element element = value.getType(compiler.coreTypes).element; |
| 734 if (element == deferredLibraryClass) { | 732 if (element == deferredLibraryClass) { |
| 735 compiler.reportError( | 733 compiler.reportError( |
| 736 import, MessageKind.DEFERRED_OLD_SYNTAX); | 734 import, MessageKind.DEFERRED_OLD_SYNTAX); |
| 737 } | 735 } |
| 738 } | 736 } |
| 739 } | 737 } |
| 740 | 738 |
| 741 String prefix = (import.prefix != null) | 739 String prefix = (import.prefix != null) |
| 742 ? import.prefix.toString() | 740 ? import.prefix.name |
| 743 : null; | 741 : null; |
| 744 // The last import we saw with the same prefix. | 742 // The last import we saw with the same prefix. |
| 745 Import previousDeferredImport = prefixDeferredImport[prefix]; | 743 ImportElement previousDeferredImport = prefixDeferredImport[prefix]; |
| 746 if (import.isDeferred) { | 744 if (import.isDeferred) { |
| 747 _DeferredImport key = new _DeclaredDeferredImport(import); | 745 _DeferredImport key = new _DeclaredDeferredImport(import); |
| 748 LibraryElement importedLibrary = library.getLibraryFromTag(import); | 746 LibraryElement importedLibrary = import.importedLibrary; |
| 749 _allDeferredImports[key] = importedLibrary; | 747 _allDeferredImports[key] = importedLibrary; |
| 750 | 748 |
| 751 if (prefix == null) { | 749 if (prefix == null) { |
| 752 compiler.reportError(import, | 750 compiler.reportError(import, |
| 753 MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX); | 751 MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX); |
| 754 } else { | 752 } else { |
| 755 prefixDeferredImport[prefix] = import; | 753 prefixDeferredImport[prefix] = import; |
| 756 _deferredImportDescriptions[key] = | 754 _deferredImportDescriptions[key] = |
| 757 new ImportDescription(import, library, compiler); | 755 new ImportDescription(import, library, compiler); |
| 758 } | 756 } |
| 759 isProgramSplit = true; | 757 isProgramSplit = true; |
| 760 lastDeferred = import; | 758 lastDeferred = import; |
| 761 } | 759 } |
| 762 if (prefix != null) { | 760 if (prefix != null) { |
| 763 if (previousDeferredImport != null || | 761 if (previousDeferredImport != null || |
| 764 (import.isDeferred && usedPrefixes.contains(prefix))) { | 762 (import.isDeferred && usedPrefixes.contains(prefix))) { |
| 765 Import failingImport = (previousDeferredImport != null) | 763 ImportElement failingImport = (previousDeferredImport != null) |
| 766 ? previousDeferredImport | 764 ? previousDeferredImport |
| 767 : import; | 765 : import; |
| 768 compiler.reportError(failingImport.prefix, | 766 compiler.reportError(failingImport.prefix, |
| 769 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX); | 767 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX); |
| 770 } | 768 } |
| 771 usedPrefixes.add(prefix); | 769 usedPrefixes.add(prefix); |
| 772 } | 770 } |
| 773 } | 771 } |
| 774 }); | 772 }); |
| 775 } | 773 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 } | 867 } |
| 870 } | 868 } |
| 871 | 869 |
| 872 class ImportDescription { | 870 class ImportDescription { |
| 873 /// Relative uri to the importing library. | 871 /// Relative uri to the importing library. |
| 874 final String importingUri; | 872 final String importingUri; |
| 875 /// The prefix this import is imported as. | 873 /// The prefix this import is imported as. |
| 876 final String prefix; | 874 final String prefix; |
| 877 final LibraryElement _importingLibrary; | 875 final LibraryElement _importingLibrary; |
| 878 | 876 |
| 879 ImportDescription(Import import, | 877 ImportDescription(ImportElement import, |
| 880 LibraryElement importingLibrary, | 878 LibraryElement importingLibrary, |
| 881 Compiler compiler) | 879 Compiler compiler) |
| 882 : importingUri = uri_extras.relativize( | 880 : importingUri = uri_extras.relativize( |
| 883 compiler.mainApp.canonicalUri, | 881 compiler.mainApp.canonicalUri, |
| 884 importingLibrary.canonicalUri, false), | 882 importingLibrary.canonicalUri, false), |
| 885 prefix = import.prefix.source, | 883 prefix = import.prefix.name, |
| 886 _importingLibrary = importingLibrary; | 884 _importingLibrary = importingLibrary; |
| 887 | 885 |
| 888 String get importingLibraryName { | 886 String get importingLibraryName { |
| 889 String libraryName = _importingLibrary.getLibraryName(); | 887 return _importingLibrary.hasLibraryName |
| 890 return libraryName == "" | 888 ? _importingLibrary.libraryName : "<unnamed>"; |
| 891 ? "<unnamed>" | |
| 892 : libraryName; | |
| 893 } | 889 } |
| 894 } | 890 } |
| 895 | 891 |
| 896 /// A node in the deferred import graph. | 892 /// A node in the deferred import graph. |
| 897 /// | 893 /// |
| 898 /// This class serves as the root node; the 'import' of the main library. | 894 /// This class serves as the root node; the 'import' of the main library. |
| 899 class _DeferredImport { | 895 class _DeferredImport { |
| 900 const _DeferredImport(); | 896 const _DeferredImport(); |
| 901 | 897 |
| 902 /// Computes a suggestive name for this import. | 898 /// Computes a suggestive name for this import. |
| 903 String computeImportDeferName(Compiler compiler) => 'main'; | 899 String computeImportDeferName(Compiler compiler) => 'main'; |
| 904 } | 900 } |
| 905 | 901 |
| 906 /// A node in the deferred import graph defined by a deferred import directive. | 902 /// A node in the deferred import graph defined by a deferred import directive. |
| 907 class _DeclaredDeferredImport implements _DeferredImport { | 903 class _DeclaredDeferredImport implements _DeferredImport { |
| 908 final Import declaration; | 904 final ImportElement declaration; |
| 909 | 905 |
| 910 _DeclaredDeferredImport(this.declaration); | 906 _DeclaredDeferredImport(this.declaration); |
| 911 | 907 |
| 912 @override | 908 @override |
| 913 String computeImportDeferName(Compiler compiler) { | 909 String computeImportDeferName(Compiler compiler) { |
| 914 String result; | 910 String result; |
| 915 if (declaration.isDeferred) { | 911 if (declaration.isDeferred) { |
| 916 result = declaration.prefix.toString(); | 912 result = declaration.prefix.name; |
| 917 } else { | 913 } else { |
| 918 // Finds the first argument to the [DeferredLibrary] annotation | 914 // Finds the first argument to the [DeferredLibrary] annotation |
| 919 List<MetadataAnnotation> metadatas = declaration.metadata; | 915 List<MetadataAnnotation> metadatas = declaration.metadata; |
| 920 assert(metadatas != null); | 916 assert(metadatas != null); |
| 921 for (MetadataAnnotation metadata in metadatas) { | 917 for (MetadataAnnotation metadata in metadatas) { |
| 922 metadata.ensureResolved(compiler); | 918 metadata.ensureResolved(compiler); |
| 923 ConstantValue value = | 919 ConstantValue value = |
| 924 compiler.constants.getConstantValue(metadata.constant); | 920 compiler.constants.getConstantValue(metadata.constant); |
| 925 Element element = value.getType(compiler.coreTypes).element; | 921 Element element = value.getType(compiler.coreTypes).element; |
| 926 if (element == compiler.deferredLibraryClass) { | 922 if (element == compiler.deferredLibraryClass) { |
| 927 ConstructedConstantValue constant = value; | 923 ConstructedConstantValue constant = value; |
| 928 StringConstantValue s = constant.fields.values.single; | 924 StringConstantValue s = constant.fields.values.single; |
| 929 result = s.primitiveValue.slowToString(); | 925 result = s.primitiveValue.slowToString(); |
| 930 break; | 926 break; |
| 931 } | 927 } |
| 932 } | 928 } |
| 933 } | 929 } |
| 934 assert(result != null); | 930 assert(result != null); |
| 935 return result; | 931 return result; |
| 936 } | 932 } |
| 937 | 933 |
| 938 bool operator ==(other) { | 934 bool operator ==(other) { |
| 939 if (other is! _DeclaredDeferredImport) return false; | 935 if (other is! _DeclaredDeferredImport) return false; |
| 940 return declaration == other.declaration; | 936 return declaration == other.declaration; |
| 941 } | 937 } |
| 942 | 938 |
| 943 int get hashCode => declaration.hashCode * 17; | 939 int get hashCode => declaration.hashCode * 17; |
| 944 } | 940 } |
| OLD | NEW |