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

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

Issue 350693007: Load patches via callback. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 6 years, 6 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of dart2js; 5 library dart2js.library_loader;
6
7 import 'dart:async';
8 import 'dart2jslib.dart'
9 show Compiler,
10 CompilerTask,
11 MessageKind,
12 Script,
13 invariant;
14 import 'elements/elements.dart'
15 show CompilationUnitElement,
16 Element,
17 LibraryElement,
18 PrefixElement;
19 import 'elements/modelx.dart'
20 show CompilationUnitElementX,
21 DeferredLoaderGetterElementX,
22 ErroneousElementX,
23 LibraryElementX,
24 PrefixElementX;
25 import 'helpers/helpers.dart';
26 import 'native_handler.dart' as native;
27 import 'tree/tree.dart';
28 import 'util/util.dart' show Link, LinkBuilder;
6 29
7 /** 30 /**
8 * [CompilerTask] for loading libraries and setting up the import/export scopes. 31 * [CompilerTask] for loading libraries and setting up the import/export scopes.
9 * 32 *
10 * The library loader uses four different kinds of URIs in different parts of 33 * The library loader uses four different kinds of URIs in different parts of
11 * the loading process. 34 * the loading process.
12 * 35 *
13 * ## User URI ## 36 * ## User URI ##
14 * 37 *
15 * A 'user URI' is a URI provided by the user in code and as the main entry URI 38 * A 'user URI' is a URI provided by the user in code and as the main entry URI
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 * The distinction between readable URI and resource URI is necessary to ensure 113 * The distinction between readable URI and resource URI is necessary to ensure
91 * that these imports 114 * that these imports
92 * 115 *
93 * import 'package:foo.dart' as a; 116 * import 'package:foo.dart' as a;
94 * import 'packages/foo.dart' as b; 117 * import 'packages/foo.dart' as b;
95 * 118 *
96 * do _not_ resolve to the same library when the package root URI happens to 119 * do _not_ resolve to the same library when the package root URI happens to
97 * point to the 'packages' folder. 120 * point to the 'packages' folder.
98 * 121 *
99 */ 122 */
100 abstract class LibraryLoader extends CompilerTask { 123 abstract class LibraryLoaderTask implements CompilerTask {
101 LibraryLoader(Compiler compiler) : super(compiler); 124 factory LibraryLoaderTask(Compiler compiler) = _LibraryLoaderTask;
102 125
103 /** 126 /**
104 * Loads the library specified by the [resolvedUri] and returns its 127 * Loads the library specified by the [resolvedUri] and returns its
105 * [LibraryElement]. 128 * [LibraryElement].
106 * 129 *
107 * If the library is not already loaded, the method creates the 130 * If the library is not already loaded, the method creates the
108 * [LibraryElement] for the library and computes the import/export scope, 131 * [LibraryElement] for the library and computes the import/export scope,
109 * loading and computing the import/export scopes of all required libraries in 132 * loading and computing the import/export scopes of all required libraries in
110 * the process. The method handles cyclic dependency between libraries. 133 * the process. The method handles cyclic dependency between libraries.
111 *
112 * This is the main entry point for [LibraryLoader].
113 */ 134 */
114 Future<LibraryElement> loadLibrary(Uri resolvedUri); 135 Future<LibraryElement> loadLibrary(Uri resolvedUri);
136 }
115 137
116 // TODO(johnniwinther): Remove this when patches don't need special parsing. 138 /// Handle for creating synthesized/patch libraries during library loading.
117 Future registerLibraryFromTag(LibraryDependencyHandler handler, 139 abstract class LibraryLoader {
118 LibraryElement library, 140 /// This method must be called when a new synthesized/patch library has been
119 LibraryDependency tag); 141 /// created to ensure that [library] will part of library dependency graph
142 /// used for computing import/export scopes.
143 void registerNewLibrary(LibraryElement library);
144
145 /// This method must be called when a new synthesized/patch library has been
146 /// scanned in order to process the library tags in [library] and thus handle
147 /// imports/exports/parts in the synthesized/patch library.
148 Future processLibraryTags(LibraryElement library);
120 } 149 }
121 150
122 /** 151 /**
123 * [CombinatorFilter] is a succinct representation of a list of combinators from 152 * [CombinatorFilter] is a succinct representation of a list of combinators from
124 * a library dependency tag. 153 * a library dependency tag.
125 */ 154 */
126 class CombinatorFilter { 155 class CombinatorFilter {
127 const CombinatorFilter(); 156 const CombinatorFilter();
128 157
129 /** 158 /**
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 HideFilter(this.excludedNames); 227 HideFilter(this.excludedNames);
199 228
200 bool exclude(Element element) => excludedNames.contains(element.name); 229 bool exclude(Element element) => excludedNames.contains(element.name);
201 } 230 }
202 231
203 /** 232 /**
204 * Implementation class for [LibraryLoader]. The distinction between 233 * Implementation class for [LibraryLoader]. The distinction between
205 * [LibraryLoader] and [LibraryLoaderTask] is made to hide internal members from 234 * [LibraryLoader] and [LibraryLoaderTask] is made to hide internal members from
206 * the [LibraryLoader] interface. 235 * the [LibraryLoader] interface.
207 */ 236 */
208 class LibraryLoaderTask extends LibraryLoader { 237 class _LibraryLoaderTask extends CompilerTask implements LibraryLoaderTask {
209 LibraryLoaderTask(Compiler compiler) : super(compiler); 238 _LibraryLoaderTask(Compiler compiler) : super(compiler);
210 String get name => 'LibraryLoader'; 239 String get name => 'LibraryLoader';
211 240
212 final Map<Uri, LibraryElement> libraryResourceUriMap = 241 final Map<Uri, LibraryElement> libraryResourceUriMap =
213 new Map<Uri, LibraryElement>(); 242 new Map<Uri, LibraryElement>();
214 final Map<String, LibraryElement> libraryNames = 243 final Map<String, LibraryElement> libraryNames =
215 new Map<String, LibraryElement>(); 244 new Map<String, LibraryElement>();
216 245
217 LibraryDependencyHandler currentHandler; 246 LibraryDependencyHandler currentHandler;
218 247
219 Future<LibraryElement> loadLibrary(Uri resolvedUri) { 248 Future<LibraryElement> loadLibrary(Uri resolvedUri) {
220 return measure(() { 249 return measure(() {
221 assert(currentHandler == null); 250 assert(currentHandler == null);
222 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the 251 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the
223 // loading of a library cluster. 252 // loading of a library cluster.
224 currentHandler = new LibraryDependencyHandler(compiler); 253 currentHandler = new LibraryDependencyHandler(this);
225 return createLibrary(currentHandler, null, resolvedUri) 254 return createLibrary(currentHandler, null, resolvedUri)
226 .then((LibraryElement library) { 255 .then((LibraryElement library) {
227 return compiler.withCurrentElement(library, () { 256 return compiler.withCurrentElement(library, () {
228 return measure(() { 257 return measure(() {
229 currentHandler.computeExports(); 258 currentHandler.computeExports();
230 Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; 259 Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{};
231 currentHandler.loadedLibraries.forEach( 260 currentHandler.loadedLibraries.forEach(
232 (LibraryElement loadedLibrary) { 261 (LibraryElement loadedLibrary) {
233 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; 262 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary;
234 }); 263 });
(...skipping 28 matching lines...) Expand all
263 MessageKind.GENERIC, {'text': 'Error: Out of order.'}); 292 MessageKind.GENERIC, {'text': 'Error: Out of order.'});
264 return tagState; 293 return tagState;
265 } 294 }
266 return TagState.NEXT[value]; 295 return TagState.NEXT[value];
267 } 296 }
268 297
269 bool importsDartCore = false; 298 bool importsDartCore = false;
270 var libraryDependencies = new LinkBuilder<LibraryDependency>(); 299 var libraryDependencies = new LinkBuilder<LibraryDependency>();
271 Uri base = library.entryCompilationUnit.script.readableUri; 300 Uri base = library.entryCompilationUnit.script.readableUri;
272 301
273 // TODO(rnystrom): Remove .toList() here if #11523 is fixed. 302 // TODO(johnniwinther): Reverse the tag list on access and cache the result.
274 return Future.forEach(library.tags.reverse().toList(), (LibraryTag tag) { 303 return Future.forEach(library.tags.reverse().toList(), (LibraryTag tag) {
275 return compiler.withCurrentElement(library, () { 304 return compiler.withCurrentElement(library, () {
276 if (tag.isImport) { 305 if (tag.isImport) {
277 Import import = tag; 306 Import import = tag;
278 tagState = checkTag(TagState.IMPORT_OR_EXPORT, import); 307 tagState = checkTag(TagState.IMPORT_OR_EXPORT, import);
279 if (import.uri.dartString.slowToString() == 'dart:core') { 308 if (import.uri.dartString.slowToString() == 'dart:core') {
280 importsDartCore = true; 309 importsDartCore = true;
281 } 310 }
282 libraryDependencies.addLast(import); 311 libraryDependencies.addLast(import);
283 } else if (tag.isExport) { 312 } else if (tag.isExport) {
(...skipping 10 matching lines...) Expand all
294 Part part = tag; 323 Part part = tag;
295 StringNode uri = part.uri; 324 StringNode uri = part.uri;
296 Uri resolvedUri = base.resolve(uri.dartString.slowToString()); 325 Uri resolvedUri = base.resolve(uri.dartString.slowToString());
297 tagState = checkTag(TagState.SOURCE, part); 326 tagState = checkTag(TagState.SOURCE, part);
298 return scanPart(part, resolvedUri, library); 327 return scanPart(part, resolvedUri, library);
299 } else { 328 } else {
300 compiler.internalError(tag, "Unhandled library tag."); 329 compiler.internalError(tag, "Unhandled library tag.");
301 } 330 }
302 }); 331 });
303 }).then((_) { 332 }).then((_) {
304 // TODO(johnniwinther): Move callback to after patching. 333 return compiler.onLibraryScanned(library, handler);
305 compiler.onLibraryScanned(library); 334 }).then((_) {
306 return compiler.withCurrentElement(library, () { 335 return compiler.withCurrentElement(library, () {
307 checkDuplicatedLibraryName(library); 336 checkDuplicatedLibraryName(library);
308 // Apply patch, if any. 337
309 if (library.isPlatformLibrary) {
310 return patchDartLibrary(handler, library, library.canonicalUri.path);
311 }
312 });
313 }).then((_) {
314 return compiler.withCurrentElement(library, () {
315 // Import dart:core if not already imported. 338 // Import dart:core if not already imported.
316 if (!importsDartCore && !isDartCore(library.canonicalUri)) { 339 if (!importsDartCore && !isDartCore(library.canonicalUri)) {
317 return loadCoreLibrary(handler).then((LibraryElement coreLibrary) { 340 return loadCoreLibrary(handler).then((LibraryElement coreLibrary) {
318 handler.registerDependency(library, null, coreLibrary); 341 handler.registerDependency(library, null, coreLibrary);
319 }); 342 });
320 } 343 }
321 }); 344 });
322 }).then((_) { 345 }).then((_) {
323 // TODO(rnystrom): Remove .toList() here if #11523 is fixed.
324 return Future.forEach(libraryDependencies.toLink().toList(), (tag) { 346 return Future.forEach(libraryDependencies.toLink().toList(), (tag) {
325 return compiler.withCurrentElement(library, () { 347 return compiler.withCurrentElement(library, () {
326 return registerLibraryFromTag(handler, library, tag); 348 return registerLibraryFromTag(handler, library, tag);
327 }); 349 });
328 }); 350 });
329 }); 351 });
330 } 352 }
331 353
332 void checkDuplicatedLibraryName(LibraryElement library) { 354 void checkDuplicatedLibraryName(LibraryElement library) {
333 Uri resourceUri = library.entryCompilationUnit.script.resourceUri; 355 Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 return new Future.value(compiler.coreLibrary); 401 return new Future.value(compiler.coreLibrary);
380 } 402 }
381 403
382 Uri coreUri = new Uri(scheme: 'dart', path: 'core'); 404 Uri coreUri = new Uri(scheme: 'dart', path: 'core');
383 return createLibrary(handler, null, coreUri).then((LibraryElement library) { 405 return createLibrary(handler, null, coreUri).then((LibraryElement library) {
384 compiler.coreLibrary = library; 406 compiler.coreLibrary = library;
385 return library; 407 return library;
386 }); 408 });
387 } 409 }
388 410
389 Future patchDartLibrary(LibraryDependencyHandler handler,
390 LibraryElement library,
391 String dartLibraryPath) {
392 if (library.isPatched) return new Future.value();
393 Uri patchUri = compiler.resolvePatchUri(dartLibraryPath);
394 if (patchUri == null) return new Future.value();
395
396 return compiler.patchParser.patchLibrary(handler, patchUri, library);
397 }
398
399 /** 411 /**
400 * Handle a part tag in the scope of [library]. The [resolvedUri] given is 412 * Handle a part tag in the scope of [library]. The [resolvedUri] given is
401 * used as is, any URI resolution should be done beforehand. 413 * used as is, any URI resolution should be done beforehand.
402 */ 414 */
403 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) { 415 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) {
404 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri); 416 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri);
405 Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part); 417 Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part);
406 if (readableUri == null) return new Future.value(); 418 if (readableUri == null) return new Future.value();
407 return compiler.withCurrentElement(library, () { 419 return compiler.withCurrentElement(library, () {
408 return compiler.readScript(part, readableUri). 420 return compiler.readScript(part, readableUri).
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 LibraryElement library = compiler.libraries[resolvedUri.toString()]; 470 LibraryElement library = compiler.libraries[resolvedUri.toString()];
459 if (library != null) { 471 if (library != null) {
460 return new Future.value(library); 472 return new Future.value(library);
461 } 473 }
462 return compiler.withCurrentElement(importingLibrary, () { 474 return compiler.withCurrentElement(importingLibrary, () {
463 return compiler.readScript(node, readableUri) 475 return compiler.readScript(node, readableUri)
464 .then((Script script) { 476 .then((Script script) {
465 if (script == null) return null; 477 if (script == null) return null;
466 LibraryElement element = new LibraryElementX(script, resolvedUri); 478 LibraryElement element = new LibraryElementX(script, resolvedUri);
467 compiler.withCurrentElement(element, () { 479 compiler.withCurrentElement(element, () {
468 compiler.onLibraryCreated(element);
469 handler.registerNewLibrary(element); 480 handler.registerNewLibrary(element);
470 native.maybeEnableNative(compiler, element); 481 native.maybeEnableNative(compiler, element);
471 compiler.libraries[resolvedUri.toString()] = element; 482 compiler.libraries[resolvedUri.toString()] = element;
472 compiler.scanner.scanLibrary(element); 483 compiler.scanner.scanLibrary(element);
473 }); 484 });
474 return processLibraryTags(handler, element).then((_) { 485 return processLibraryTags(handler, element).then((_) {
475 compiler.withCurrentElement(element, () { 486 compiler.withCurrentElement(element, () {
476 handler.registerLibraryExports(element); 487 handler.registerLibraryExports(element);
477 }); 488 });
478 return element; 489 return element;
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 } 811 }
801 812
802 /** 813 /**
803 * Helper class used for computing the possibly cyclic import/export scopes of 814 * Helper class used for computing the possibly cyclic import/export scopes of
804 * a set of libraries. 815 * a set of libraries.
805 * 816 *
806 * This class is used by [ScannerTask.scanLibrary] to collect all newly loaded 817 * This class is used by [ScannerTask.scanLibrary] to collect all newly loaded
807 * libraries and to compute their import/export scopes through a fixed-point 818 * libraries and to compute their import/export scopes through a fixed-point
808 * algorithm. 819 * algorithm.
809 */ 820 */
810 class LibraryDependencyHandler { 821 class LibraryDependencyHandler implements LibraryLoader {
811 final Compiler compiler; 822 final _LibraryLoaderTask task;
812 823
813 /** 824 /**
814 * Newly loaded libraries and their corresponding node in the library 825 * Newly loaded libraries and their corresponding node in the library
815 * dependency graph. Libraries that have already been fully loaded are not 826 * dependency graph. Libraries that have already been fully loaded are not
816 * part of the dependency graph of this handler since their export scopes have 827 * part of the dependency graph of this handler since their export scopes have
817 * already been computed. 828 * already been computed.
818 */ 829 */
819 Map<LibraryElement, LibraryDependencyNode> nodeMap = 830 Map<LibraryElement, LibraryDependencyNode> nodeMap =
820 new Map<LibraryElement, LibraryDependencyNode>(); 831 new Map<LibraryElement, LibraryDependencyNode>();
821 832
822 LibraryDependencyHandler(Compiler this.compiler); 833 LibraryDependencyHandler(this.task);
834
835 Compiler get compiler => task.compiler;
823 836
824 /// The libraries loaded with this handler. 837 /// The libraries loaded with this handler.
825 Iterable<LibraryElement> get loadedLibraries => nodeMap.keys; 838 Iterable<LibraryElement> get loadedLibraries => nodeMap.keys;
826 839
827 /** 840 /**
828 * Performs a fixed-point computation on the export scopes of all registered 841 * Performs a fixed-point computation on the export scopes of all registered
829 * libraries and creates the import/export of the libraries based on the 842 * libraries and creates the import/export of the libraries based on the
830 * fixed-point. 843 * fixed-point.
831 */ 844 */
832 void computeExports() { 845 void computeExports() {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 message: "$library has not been registered")); 914 message: "$library has not been registered"));
902 importingNode.registerImportDependency(tag, loadedLibrary); 915 importingNode.registerImportDependency(tag, loadedLibrary);
903 } 916 }
904 } 917 }
905 918
906 /** 919 /**
907 * Registers [library] for the processing of its import/export scope. 920 * Registers [library] for the processing of its import/export scope.
908 */ 921 */
909 void registerNewLibrary(LibraryElement library) { 922 void registerNewLibrary(LibraryElement library) {
910 nodeMap[library] = new LibraryDependencyNode(library); 923 nodeMap[library] = new LibraryDependencyNode(library);
924 compiler.onLibraryCreated(library);
911 } 925 }
912 926
913 /** 927 /**
914 * Registers all top-level entities of [library] as starting point for the 928 * Registers all top-level entities of [library] as starting point for the
915 * fixed-point computation of the import/export scopes. 929 * fixed-point computation of the import/export scopes.
916 */ 930 */
917 void registerLibraryExports(LibraryElement library) { 931 void registerLibraryExports(LibraryElement library) {
918 nodeMap[library].registerInitialExports(); 932 nodeMap[library].registerInitialExports();
919 } 933 }
934
935 Future processLibraryTags(LibraryElement library) {
936 return task.processLibraryTags(this, library);
937 }
920 } 938 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698