Index: dart/sdk/lib/_internal/compiler/implementation/deferred_load.dart |
diff --git a/dart/sdk/lib/_internal/compiler/implementation/deferred_load.dart b/dart/sdk/lib/_internal/compiler/implementation/deferred_load.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7753fb4e0d48888b434f63d6f72121ee87ed295f |
--- /dev/null |
+++ b/dart/sdk/lib/_internal/compiler/implementation/deferred_load.dart |
@@ -0,0 +1,103 @@ |
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library deferred_load; |
+ |
+import 'dart:uri'; |
+ |
+import 'dart2jslib.dart' |
+ show Compiler, |
+ CompilerTask, |
+ ConstructedConstant, |
+ SourceString; |
+ |
+import 'elements/elements.dart' |
+ show ClassElement, |
+ Element, |
+ LibraryElement, |
+ MetadataAnnotation; |
+ |
+import 'util/util.dart' |
+ show Link; |
+ |
+import 'tree/tree.dart' |
+ show LibraryTag; |
+ |
+class DeferredLoadTask extends CompilerTask { |
ngeoffray
2013/02/19 10:04:57
Is there some time you would like to measure for t
ahe
2013/02/19 11:10:36
Done.
|
+ final Set<LibraryElement> deferredLibraries = new Set<LibraryElement>(); |
+ |
+ ClassElement cachedDeferredLibraryClass; |
+ |
+ DeferredLoadTask(Compiler compiler) : super(compiler); |
+ |
+ String get name => 'Lazy'; |
+ |
+ /// DeferredLibrary from dart:async |
+ ClassElement get deferredLibraryClass { |
+ if (cachedDeferredLibraryClass == null) { |
+ cachedDeferredLibraryClass = findDeferredLibraryClass(); |
+ } |
+ return cachedDeferredLibraryClass; |
+ } |
+ |
+ ClassElement findDeferredLibraryClass() { |
+ var uri = new Uri.fromComponents(scheme: 'dart', path: 'async'); |
+ LibraryElement asyncLibrary = |
+ compiler.libraryLoader.loadLibrary(uri, null, uri); |
+ var element = asyncLibrary.find(const SourceString('DeferredLibrary')); |
+ if (element == null) { |
+ internalErrorOnElement( |
+ asyncLibrary, |
+ 'dart:async library does not contain required class: ' |
+ 'DeferredLibrary'); |
+ } |
+ return element; |
+ } |
+ |
+ bool isDeferred(Element element) { |
+ // TODO(ahe): This is really a graph coloring problem. We should |
+ // make sure that libraries and elements only used by a deferred |
+ // library are also deferred. |
+ // Also, if something is deferred depends on your |
+ // perspective. Inside a deferred library, other elements of the |
+ // same library are not deferred. We should add an extra parameter |
+ // to this method to indicate "from where". |
+ return deferredLibraries.contains(element.getLibrary()); |
+ } |
+ |
+ void registerMainApp(LibraryElement mainApp) { |
+ if (mainApp == null) return; |
+ compiler.withCurrentElement(mainApp, () { |
+ deferredLibraries.addAll(findDeferredLibraries(mainApp)); |
+ }); |
+ } |
+ |
+ Link<Element> findDeferredLibraries(LibraryElement library) { |
+ Link<LibraryElement> link = const Link<LibraryElement>(); |
+ for (LibraryTag tag in library.tags) { |
+ Link<MetadataAnnotation> metadata = tag.metadata; |
+ if (metadata == null) continue; |
+ for (MetadataAnnotation metadata in tag.metadata) { |
+ metadata.ensureResolved(compiler); |
+ Element element = metadata.value.computeType(compiler).element; |
+ if (element == deferredLibraryClass) { |
+ ConstructedConstant value = metadata.value; |
+ SourceString expectedName = value.fields[0].toDartString().source; |
+ LibraryElement deferredLibrary = library.getLibraryFromTag(tag); |
+ link = link.prepend(deferredLibrary); |
+ SourceString actualName = |
+ new SourceString(deferredLibrary.getLibraryOrScriptName()); |
+ if (expectedName != actualName) { |
+ compiler.reportErrorCode( |
+ metadata, |
+ MessageKind.DEFERRED_LIBRARY_NAME_MISMATCH, |
+ { 'expectedName': expectedName.slowToString(), |
+ 'actualName': actualName.slowToString()}); |
+ } |
+ } |
+ } |
+ } |
+ return link; |
+ } |
+} |