Chromium Code Reviews| 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; |
| + } |
| +} |