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

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: 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 * 134 *
112 * This is the main entry point for [LibraryLoader]. 135 * This is the main entry point for [LibraryLoader].
113 */ 136 */
114 Future<LibraryElement> loadLibrary(Uri resolvedUri); 137 Future<LibraryElement> loadLibrary(Uri resolvedUri);
138 }
115 139
116 // TODO(johnniwinther): Remove this when patches don't need special parsing. 140 /// Callback for creating synthesized/patch libraries during library loading.
117 Future registerLibraryFromTag(LibraryDependencyHandler handler, 141 abstract class LibraryLoaderCallback {
floitsch 2014/06/23 19:12:33 Don't call this "callback". It took me some time t
Johnni Winther 2014/06/24 08:11:20 Done.
118 LibraryElement library, 142 /// Call this when a new synthesized/patch library has been created.
floitsch 2014/06/23 19:12:33 This is ambiguous. Who needs to call this method?
Johnni Winther 2014/06/24 08:11:20 Done.
119 LibraryDependency tag); 143 ///
144 /// This call ensures that [library] will part of library dependency graph
145 /// used for computing import/export scopes.
146 void onLibraryCreated(LibraryElement library);
147
148 /// Call this when a new synthesized/patch library has been scanned.
149 ///
150 /// On this call library tags in [library] will be processed, allowing for
151 /// imports/exports/parts in the synthesized/patch library.
152 Future onLibraryScanned(LibraryElement library);
120 } 153 }
121 154
122 /** 155 /**
123 * [CombinatorFilter] is a succinct representation of a list of combinators from 156 * [CombinatorFilter] is a succinct representation of a list of combinators from
124 * a library dependency tag. 157 * a library dependency tag.
125 */ 158 */
126 class CombinatorFilter { 159 class CombinatorFilter {
127 const CombinatorFilter(); 160 const CombinatorFilter();
128 161
129 /** 162 /**
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 final Map<String, LibraryElement> libraryNames = 247 final Map<String, LibraryElement> libraryNames =
215 new Map<String, LibraryElement>(); 248 new Map<String, LibraryElement>();
216 249
217 LibraryDependencyHandler currentHandler; 250 LibraryDependencyHandler currentHandler;
218 251
219 Future<LibraryElement> loadLibrary(Uri resolvedUri) { 252 Future<LibraryElement> loadLibrary(Uri resolvedUri) {
220 return measure(() { 253 return measure(() {
221 assert(currentHandler == null); 254 assert(currentHandler == null);
222 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the 255 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the
223 // loading of a library cluster. 256 // loading of a library cluster.
224 currentHandler = new LibraryDependencyHandler(compiler); 257 currentHandler = new LibraryDependencyHandler(this);
225 return createLibrary(currentHandler, null, resolvedUri) 258 return createLibrary(currentHandler, null, resolvedUri)
226 .then((LibraryElement library) { 259 .then((LibraryElement library) {
227 return compiler.withCurrentElement(library, () { 260 return compiler.withCurrentElement(library, () {
228 return measure(() { 261 return measure(() {
229 currentHandler.computeExports(); 262 currentHandler.computeExports();
230 Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; 263 Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{};
231 currentHandler.loadedLibraries.forEach( 264 currentHandler.loadedLibraries.forEach(
232 (LibraryElement loadedLibrary) { 265 (LibraryElement loadedLibrary) {
233 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; 266 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary;
234 }); 267 });
(...skipping 28 matching lines...) Expand all
263 MessageKind.GENERIC, {'text': 'Error: Out of order.'}); 296 MessageKind.GENERIC, {'text': 'Error: Out of order.'});
264 return tagState; 297 return tagState;
265 } 298 }
266 return TagState.NEXT[value]; 299 return TagState.NEXT[value];
267 } 300 }
268 301
269 bool importsDartCore = false; 302 bool importsDartCore = false;
270 var libraryDependencies = new LinkBuilder<LibraryDependency>(); 303 var libraryDependencies = new LinkBuilder<LibraryDependency>();
271 Uri base = library.entryCompilationUnit.script.readableUri; 304 Uri base = library.entryCompilationUnit.script.readableUri;
272 305
273 // TODO(rnystrom): Remove .toList() here if #11523 is fixed. 306 // TODO(rnystrom): Remove .toList() here if #11523 is fixed.
floitsch 2014/06/23 19:12:33 11523 has been closed with 'asDesigned'. It should
Johnni Winther 2014/06/24 08:11:20 Removed the comment. Still need the `toList()` cal
274 return Future.forEach(library.tags.reverse().toList(), (LibraryTag tag) { 307 return Future.forEach(library.tags.reverse().toList(), (LibraryTag tag) {
275 return compiler.withCurrentElement(library, () { 308 return compiler.withCurrentElement(library, () {
276 if (tag.isImport) { 309 if (tag.isImport) {
277 Import import = tag; 310 Import import = tag;
278 tagState = checkTag(TagState.IMPORT_OR_EXPORT, import); 311 tagState = checkTag(TagState.IMPORT_OR_EXPORT, import);
279 if (import.uri.dartString.slowToString() == 'dart:core') { 312 if (import.uri.dartString.slowToString() == 'dart:core') {
280 importsDartCore = true; 313 importsDartCore = true;
281 } 314 }
282 libraryDependencies.addLast(import); 315 libraryDependencies.addLast(import);
283 } else if (tag.isExport) { 316 } else if (tag.isExport) {
(...skipping 10 matching lines...) Expand all
294 Part part = tag; 327 Part part = tag;
295 StringNode uri = part.uri; 328 StringNode uri = part.uri;
296 Uri resolvedUri = base.resolve(uri.dartString.slowToString()); 329 Uri resolvedUri = base.resolve(uri.dartString.slowToString());
297 tagState = checkTag(TagState.SOURCE, part); 330 tagState = checkTag(TagState.SOURCE, part);
298 return scanPart(part, resolvedUri, library); 331 return scanPart(part, resolvedUri, library);
299 } else { 332 } else {
300 compiler.internalError(tag, "Unhandled library tag."); 333 compiler.internalError(tag, "Unhandled library tag.");
301 } 334 }
302 }); 335 });
303 }).then((_) { 336 }).then((_) {
304 // TODO(johnniwinther): Move callback to after patching. 337 return compiler.onLibraryScanned(library, handler);
305 compiler.onLibraryScanned(library); 338 }).then((_) {
306 return compiler.withCurrentElement(library, () { 339 return compiler.withCurrentElement(library, () {
307 checkDuplicatedLibraryName(library); 340 checkDuplicatedLibraryName(library);
308 // Apply patch, if any. 341
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. 342 // Import dart:core if not already imported.
316 if (!importsDartCore && !isDartCore(library.canonicalUri)) { 343 if (!importsDartCore && !isDartCore(library.canonicalUri)) {
317 return loadCoreLibrary(handler).then((LibraryElement coreLibrary) { 344 return loadCoreLibrary(handler).then((LibraryElement coreLibrary) {
318 handler.registerDependency(library, null, coreLibrary); 345 handler.registerDependency(library, null, coreLibrary);
319 }); 346 });
320 } 347 }
321 }); 348 });
322 }).then((_) { 349 }).then((_) {
323 // TODO(rnystrom): Remove .toList() here if #11523 is fixed. 350 // TODO(rnystrom): Remove .toList() here if #11523 is fixed.
324 return Future.forEach(libraryDependencies.toLink().toList(), (tag) { 351 return Future.forEach(libraryDependencies.toLink().toList(), (tag) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 return new Future.value(compiler.coreLibrary); 406 return new Future.value(compiler.coreLibrary);
380 } 407 }
381 408
382 Uri coreUri = new Uri(scheme: 'dart', path: 'core'); 409 Uri coreUri = new Uri(scheme: 'dart', path: 'core');
383 return createLibrary(handler, null, coreUri).then((LibraryElement library) { 410 return createLibrary(handler, null, coreUri).then((LibraryElement library) {
384 compiler.coreLibrary = library; 411 compiler.coreLibrary = library;
385 return library; 412 return library;
386 }); 413 });
387 } 414 }
388 415
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 /** 416 /**
400 * Handle a part tag in the scope of [library]. The [resolvedUri] given is 417 * Handle a part tag in the scope of [library]. The [resolvedUri] given is
401 * used as is, any URI resolution should be done beforehand. 418 * used as is, any URI resolution should be done beforehand.
402 */ 419 */
403 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) { 420 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) {
404 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri); 421 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri);
405 Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part); 422 Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part);
406 if (readableUri == null) return new Future.value(); 423 if (readableUri == null) return new Future.value();
407 return compiler.withCurrentElement(library, () { 424 return compiler.withCurrentElement(library, () {
408 return compiler.readScript(part, readableUri). 425 return compiler.readScript(part, readableUri).
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 LibraryElement library = compiler.libraries[resolvedUri.toString()]; 475 LibraryElement library = compiler.libraries[resolvedUri.toString()];
459 if (library != null) { 476 if (library != null) {
460 return new Future.value(library); 477 return new Future.value(library);
461 } 478 }
462 return compiler.withCurrentElement(importingLibrary, () { 479 return compiler.withCurrentElement(importingLibrary, () {
463 return compiler.readScript(node, readableUri) 480 return compiler.readScript(node, readableUri)
464 .then((Script script) { 481 .then((Script script) {
465 if (script == null) return null; 482 if (script == null) return null;
466 LibraryElement element = new LibraryElementX(script, resolvedUri); 483 LibraryElement element = new LibraryElementX(script, resolvedUri);
467 compiler.withCurrentElement(element, () { 484 compiler.withCurrentElement(element, () {
468 compiler.onLibraryCreated(element); 485 handler.onLibraryCreated(element);
469 handler.registerNewLibrary(element);
470 native.maybeEnableNative(compiler, element); 486 native.maybeEnableNative(compiler, element);
471 compiler.libraries[resolvedUri.toString()] = element; 487 compiler.libraries[resolvedUri.toString()] = element;
472 compiler.scanner.scanLibrary(element); 488 compiler.scanner.scanLibrary(element);
473 }); 489 });
474 return processLibraryTags(handler, element).then((_) { 490 return processLibraryTags(handler, element).then((_) {
475 compiler.withCurrentElement(element, () { 491 compiler.withCurrentElement(element, () {
476 handler.registerLibraryExports(element); 492 handler.registerLibraryExports(element);
477 }); 493 });
478 return element; 494 return element;
479 }); 495 });
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 } 816 }
801 817
802 /** 818 /**
803 * Helper class used for computing the possibly cyclic import/export scopes of 819 * Helper class used for computing the possibly cyclic import/export scopes of
804 * a set of libraries. 820 * a set of libraries.
805 * 821 *
806 * This class is used by [ScannerTask.scanLibrary] to collect all newly loaded 822 * 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 823 * libraries and to compute their import/export scopes through a fixed-point
808 * algorithm. 824 * algorithm.
809 */ 825 */
810 class LibraryDependencyHandler { 826 class LibraryDependencyHandler implements LibraryLoaderCallback {
811 final Compiler compiler; 827 final LibraryLoaderTask task;
812 828
813 /** 829 /**
814 * Newly loaded libraries and their corresponding node in the library 830 * Newly loaded libraries and their corresponding node in the library
815 * dependency graph. Libraries that have already been fully loaded are not 831 * 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 832 * part of the dependency graph of this handler since their export scopes have
817 * already been computed. 833 * already been computed.
818 */ 834 */
819 Map<LibraryElement, LibraryDependencyNode> nodeMap = 835 Map<LibraryElement, LibraryDependencyNode> nodeMap =
820 new Map<LibraryElement, LibraryDependencyNode>(); 836 new Map<LibraryElement, LibraryDependencyNode>();
821 837
822 LibraryDependencyHandler(Compiler this.compiler); 838 LibraryDependencyHandler(LibraryLoaderTask this.task);
839
840 Compiler get compiler => task.compiler;
823 841
824 /// The libraries loaded with this handler. 842 /// The libraries loaded with this handler.
825 Iterable<LibraryElement> get loadedLibraries => nodeMap.keys; 843 Iterable<LibraryElement> get loadedLibraries => nodeMap.keys;
826 844
827 /** 845 /**
828 * Performs a fixed-point computation on the export scopes of all registered 846 * 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 847 * libraries and creates the import/export of the libraries based on the
830 * fixed-point. 848 * fixed-point.
831 */ 849 */
832 void computeExports() { 850 void computeExports() {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 nodeMap[library] = new LibraryDependencyNode(library); 928 nodeMap[library] = new LibraryDependencyNode(library);
911 } 929 }
912 930
913 /** 931 /**
914 * Registers all top-level entities of [library] as starting point for the 932 * Registers all top-level entities of [library] as starting point for the
915 * fixed-point computation of the import/export scopes. 933 * fixed-point computation of the import/export scopes.
916 */ 934 */
917 void registerLibraryExports(LibraryElement library) { 935 void registerLibraryExports(LibraryElement library) {
918 nodeMap[library].registerInitialExports(); 936 nodeMap[library].registerInitialExports();
919 } 937 }
938
939 void onLibraryCreated(LibraryElement library) {
940 compiler.onLibraryCreated(library);
941 registerNewLibrary(library);
942 }
943
944 Future onLibraryScanned(LibraryElement library) {
945 return task.processLibraryTags(this, library);
946 }
920 } 947 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698