Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/deferred_load.dart

Issue 177543002: Constrain type annotations with deferred types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 'dart2jslib.dart' show 7 import 'dart2jslib.dart' show
8 Compiler, 8 Compiler,
9 CompilerTask, 9 CompilerTask,
10 Constant, 10 Constant,
11 ConstructedConstant, 11 ConstructedConstant,
12 MessageKind, 12 MessageKind,
13 StringConstant, 13 StringConstant,
14 invariant; 14 invariant;
15 15
16 import 'dart_backend/dart_backend.dart' show
17 DartBackend;
18
16 import 'elements/elements.dart' show 19 import 'elements/elements.dart' show
17 Element, 20 Element,
18 ClassElement, 21 ClassElement,
19 ElementKind, 22 ElementKind,
20 Elements, 23 Elements,
21 FunctionElement, 24 FunctionElement,
22 LibraryElement, 25 LibraryElement,
23 MetadataAnnotation, 26 MetadataAnnotation,
24 ScopeContainerElement, 27 ScopeContainerElement,
28 PrefixElement,
25 ClosureContainer; 29 ClosureContainer;
26 30
27 import 'util/util.dart' show 31 import 'util/util.dart' show
28 Link; 32 Link;
29 33
30 import 'util/setlet.dart' show 34 import 'util/setlet.dart' show
31 Setlet; 35 Setlet;
32 36
33 import 'tree/tree.dart' show 37 import 'tree/tree.dart' show
34 LibraryTag, 38 LibraryTag,
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 // sure that only one OutputUnit is created for [fakeMainImport]. 183 // sure that only one OutputUnit is created for [fakeMainImport].
180 if (import == _fakeMainImport) { 184 if (import == _fakeMainImport) {
181 _constantToOutputUnit[constant] = mainOutputUnit; 185 _constantToOutputUnit[constant] = mainOutputUnit;
182 } 186 }
183 _constantToOutputUnit.putIfAbsent(constant, () => new OutputUnit()) 187 _constantToOutputUnit.putIfAbsent(constant, () => new OutputUnit())
184 .imports.add(import); 188 .imports.add(import);
185 } 189 }
186 190
187 /// Answers whether the [import] has a [DeferredLibrary] annotation. 191 /// Answers whether the [import] has a [DeferredLibrary] annotation.
188 bool _isImportDeferred(Import import) { 192 bool _isImportDeferred(Import import) {
189 Link<MetadataAnnotation> metadatalist = import.metadata; 193 return _allDeferredImports.containsKey(import);
190 if (metadatalist == null) return false; 194 }
191 for (MetadataAnnotation metadata in metadatalist) { 195
196 /// Checks whether the [import] has a [DeferredLibrary] annotation and stores
197 /// the information in [_allDeferredImports] and on the corresponding
198 /// prefixElement.
199 void _markIfDeferred(Import import, LibraryElement library) {
200 Link<MetadataAnnotation> metadataList = import.metadata;
201 if (metadataList == null) return;
202 for (MetadataAnnotation metadata in metadataList) {
192 metadata.ensureResolved(compiler); 203 metadata.ensureResolved(compiler);
193 Element element = metadata.value.computeType(compiler).element; 204 Element element = metadata.value.computeType(compiler).element;
194 if (metadata.value.computeType(compiler).element 205 if (element == deferredLibraryClass) {
195 == deferredLibraryClass) { 206 _allDeferredImports[import] = library.getLibraryFromTag(import);
196 return true; 207 // On encountering a deferred library without a prefix we report an
208 // error, but continue the compilation to possibly give more
209 // information. Therefore it is neccessary to check if there is a prefix
210 // here.
211 Element maybePrefix = library.find(import.prefix.toString());
212 if (maybePrefix != null && maybePrefix.isPrefix()) {
213 PrefixElement prefix = maybePrefix;
214 prefix.markAsDeferred();
215 }
197 } 216 }
198 } 217 }
199 return false;
200 } 218 }
201 219
202 /// Answers whether [element] is explicitly deferred when referred to from 220 /// Answers whether [element] is explicitly deferred when referred to from
203 /// [library]. 221 /// [library].
204 bool _isExplicitlyDeferred(Element element, LibraryElement library) { 222 bool _isExplicitlyDeferred(Element element, LibraryElement library) {
205 Link<Import> imports = _getImports(element, library); 223 Link<Import> imports = _getImports(element, library);
206 // If the element is not imported explicitly, it is implicitly imported 224 // If the element is not imported explicitly, it is implicitly imported
207 // not deferred. 225 // not deferred.
208 if (imports.isEmpty) return false; 226 if (imports.isEmpty) return false;
209 // An element could potentially be loaded by several imports. If all of them 227 // An element could potentially be loaded by several imports. If all of them
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 // 2. 663 // 2.
646 // @DeferredLibrary("a") import "lib.dart" as a; 664 // @DeferredLibrary("a") import "lib.dart" as a;
647 // import "lib2.dart" as a; 665 // import "lib2.dart" as a;
648 // 3. 666 // 3.
649 // import "lib.dart" as a; 667 // import "lib.dart" as a;
650 // @DeferredLibrary("a") import "lib2.dart" as a; 668 // @DeferredLibrary("a") import "lib2.dart" as a;
651 // 4. 669 // 4.
652 // import "lib.dart" as a; 670 // import "lib.dart" as a;
653 // import "lib2.dart" as a; 671 // import "lib2.dart" as a;
654 // We must be able to signal error for case 1, 2, 3, but accept case 4. 672 // We must be able to signal error for case 1, 2, 3, but accept case 4.
655 673
656 // The prefixes that have been used by any imports in this library. 674 // The prefixes that have been used by any imports in this library.
657 Setlet<String> usedPrefixes = new Setlet<String>(); 675 Setlet<String> usedPrefixes = new Setlet<String>();
658 // The last deferred import we saw with a given prefix (if any). 676 // The last deferred import we saw with a given prefix (if any).
659 Map<String, Import> prefixDeferredImport = new Map<String, Import>(); 677 Map<String, Import> prefixDeferredImport = new Map<String, Import>();
660 for (LibraryElement library in compiler.libraries.values) { 678 for (LibraryElement library in compiler.libraries.values) {
661 compiler.withCurrentElement(library, () { 679 compiler.withCurrentElement(library, () {
662 prefixDeferredImport.clear(); 680 prefixDeferredImport.clear();
663 usedPrefixes.clear(); 681 usedPrefixes.clear();
664 // TODO(sigurdm): Make helper getLibraryImportTags when tags is a List 682 // TODO(sigurdm): Make helper getLibraryImportTags when tags is a List
665 // instead of a Link. 683 // instead of a Link.
666 for (LibraryTag tag in library.tags) { 684 for (LibraryTag tag in library.tags) {
667 if (tag is! Import) continue; 685 if (tag is! Import) continue;
668 Import import = tag; 686 Import import = tag;
687 _markIfDeferred(import, library);
669 String prefix = (import.prefix != null) 688 String prefix = (import.prefix != null)
670 ? import.prefix.toString() 689 ? import.prefix.toString()
671 : null; 690 : null;
672 // The last import we saw with the same prefix. 691 // The last import we saw with the same prefix.
673 Import previousDeferredImport = prefixDeferredImport[prefix]; 692 Import previousDeferredImport = prefixDeferredImport[prefix];
674 bool isDeferred = _isImportDeferred(import); 693 bool isDeferred = _isImportDeferred(import);
675 if (isDeferred) { 694 if (isDeferred) {
676 if (prefix == null) { 695 if (prefix == null) {
677 compiler.reportError(import, 696 compiler.reportError(import,
678 MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX); 697 MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX);
679 } else { 698 } else {
680 prefixDeferredImport[prefix] = import; 699 prefixDeferredImport[prefix] = import;
681 } 700 }
682 splitProgram = true; 701 splitProgram = true;
683 _allDeferredImports[tag] = library.getLibraryFromTag(tag);
684 lastDeferred = import.metadata.first; 702 lastDeferred = import.metadata.first;
685 if (library == compiler.mainApp) { 703 if (library == compiler.mainApp) {
686 deferredUsedFromMain = true; 704 deferredUsedFromMain = true;
687 } 705 }
688 } 706 }
689 if (prefix != null) { 707 if (prefix != null) {
690 if (previousDeferredImport != null || 708 if (previousDeferredImport != null ||
691 (isDeferred && usedPrefixes.contains(prefix))) { 709 (isDeferred && usedPrefixes.contains(prefix))) {
692 Import failingImport = (previousDeferredImport != null) 710 Import failingImport = (previousDeferredImport != null)
693 ? previousDeferredImport 711 ? previousDeferredImport
694 : import; 712 : import;
695 compiler.reportError(failingImport.prefix, 713 compiler.reportError(failingImport.prefix,
696 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX); 714 MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX);
697 } 715 }
698 usedPrefixes.add(prefix); 716 usedPrefixes.add(prefix);
699 } 717 }
700 } 718 }
701 }); 719 });
702 } 720 }
721 if (splitProgram && compiler.backend is DartBackend) {
722 // TODO(sigurdm): Implement deferred loading for dart2dart.
723 splitProgram = false;
724 compiler.reportInfo(
725 lastDeferred,
726 MessageKind.DEFERRED_LIBRARY_DART_2_DART);
727 }
703 if (splitProgram && !deferredUsedFromMain) { 728 if (splitProgram && !deferredUsedFromMain) {
704 compiler.reportInfo( 729 compiler.reportInfo(
705 lastDeferred, 730 lastDeferred,
706 MessageKind.DEFERRED_LIBRARY_NOT_FROM_MAIN); 731 MessageKind.DEFERRED_LIBRARY_NOT_FROM_MAIN);
707 splitProgram = false; 732 splitProgram = false;
708 } 733 }
709 } 734 }
710 } 735 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698