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

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

Issue 11967010: Internal libraries supported. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 7 years, 11 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 part of dart2js;
6 6
7 /** 7 /**
8 * [CompilerTask] for loading libraries and setting up the import/export scopes. 8 * [CompilerTask] for loading libraries and setting up the import/export scopes.
9 *
10 * The library loader uses four different kinds of URIs in different parts of
11 * the loading process.
12 *
13 * ## User URI ##
14 *
15 * A 'user URI' is a URI provided by the user in code and as the main entry URI
16 * at the command line. These generally come in 3 versions:
17 *
18 * * A relative URI such as 'foo.dart', '../bar.dart', and 'baz/boz.dart'.
19 *
20 * * A dart URI such as 'dart:core' and 'dart:_js_helper'.
21 *
22 * * A package URI such as 'package:foo.dart' and 'package:bar/baz.dart'.
23 *
24 * A user URI can also be absolute, like 'file:///foo.dart' or
25 * 'http://example.com/bar.dart', but such URIs cannot necessarily be used for
26 * locating source files, since the scheme must be supported by the input
27 * provider. The standard input provider for dart2js only supports the 'file'
28 * scheme.
29 *
30 * ## Resolved URI ##
31 *
32 * A 'resolved URI' is a (user) URI that has been resolved to an absolute URI
33 * based on the readable URI (see below) from which it was loaded. A URI with an
34 * explicit scheme (such as 'dart:', 'package:' or 'file:') is already resolved.
35 * A relative URI like for instance '../foo/bar.dart' is translated into an
36 * resolved URI in one of three ways:
37 *
38 * * If provided as the main entry URI at the command line, the URI is resolved
39 * relative to the current working directory, say
40 * 'file:///current/working/dir/', and the resolved URI is therefore
41 * 'file:///current/working/foo/bar.dart'.
42 *
43 * * If the relative URI is provided in an import, export or part tag, and the
44 * readable URI of the enclosing compilation unit is a file URI,
45 * 'file://some/path/baz.dart', then the resolved URI is
46 * 'file://some/foo/bar.dart'.
47 *
48 * * If the relative URI is provided in an import, export or part tag, and the
49 * readable URI of the enclosing compilation unit is a package URI,
50 * 'package:some/path/baz.dart', then the resolved URI is
51 * 'package:some/foo/bar.dart'.
52 *
53 * The resolved URI thus preserves the scheme through resolution: A readable
54 * file URI results in an resolved file URI and a readable package URI results
55 * in an resolved package URI. Note that since a dart URI is not a readable URI,
56 * import, export or part tags within platform libraries are not interpreted as
57 * dart URIs but instead relative to the library source file location.
58 *
59 * The resolved URI of a library is also used as the canonical URI
60 * ([LibraryElement.canonicalUri]) by which we identify which libraries are
61 * identical. This means that libraries loaded through the 'package' scheme will
62 * resolve to the same library when loaded from within using relative URIs (see
63 * for instance the test 'standalone/package/package1_test.dart'). But loading a
64 * platform library using a relative URI will _not_ result in the same library
65 * as when loaded through the dart URI.
66 *
67 * ## Readable URI ##
68 *
69 * A 'readable URI' is an absolute URI whose scheme is either 'package' or
70 * something supported by the input provider, normally 'file'. Dart URIs such as
71 * 'dart:core' and 'dart:_js_helper' are not readable themselves but are instead
72 * resolved into a readable URI using the library root URI provided from the
73 * command line and the list of platform libraries found in
74 * 'sdk/lib/_internal/libraries.dart'. This is done through the
75 * [Compiler.translateResolvedUri] method which checks whether a library by that
76 * name exists and in case of internal libraries whether access is granted.
77 *
78 * ## Resource URI ##
79 *
80 * A 'resource URI' is an absolute URI with a scheme supported by the input
81 * provider. For the standard implementation this means a URI with the 'file'
82 * scheme. Readable URIs are converted into resource URIs as part of the
83 * [Compiler.readScript] method. In the standard implementation the package URIs
84 * are converted to file URIs using the package root URI provided on the
85 * command line as base. If the package root URI is
86 * 'file:///current/working/dir/' then the package URI 'package:foo/bar.dart'
87 * will be resolved to the resource URI
88 * 'file:///current/working/dir/foo/bar.dart'.
89 *
90 * The distinction between readable URI and resource URI is necessary to ensure
91 * that these imports
92 *
93 * import 'package:foo.dart' as a;
94 * import 'packages/foo.dart' as b;
95 *
96 * do _not_ resolve to the same library when the package root URI happens to
97 * point to the 'packages' folder.
98 *
9 */ 99 */
10 abstract class LibraryLoader extends CompilerTask { 100 abstract class LibraryLoader extends CompilerTask {
11 LibraryLoader(Compiler compiler) : super(compiler); 101 LibraryLoader(Compiler compiler) : super(compiler);
12 102
13 /** 103 /**
14 * Loads the library located at [uri] and returns its [LibraryElement]. 104 * Loads the library specified by the [resolvedUri] and returns its
105 * [LibraryElement].
15 * 106 *
16 * If the library is not already loaded, the method creates the 107 * If the library is not already loaded, the method creates the
17 * [LibraryElement] for the library and computes the import/export scope, 108 * [LibraryElement] for the library and computes the import/export scope,
18 * loading and computing the import/export scopes of all required libraries in 109 * loading and computing the import/export scopes of all required libraries in
19 * the process. The method handles cyclic dependency between libraries. 110 * the process. The method handles cyclic dependency between libraries.
20 * 111 *
21 * This is the main entry point for [LibraryLoader]. 112 * This is the main entry point for [LibraryLoader].
22 */ 113 */
23 LibraryElement loadLibrary(Uri uri, Node node, Uri canonicalUri); 114 // TODO(johnniwinther): Remove [canonicalUri] together with
115 // [Compiler.scanBuiltinLibrary].
116 LibraryElement loadLibrary(Uri resolvedUri, Node node, Uri canonicalUri);
24 117
25 // TODO(johnniwinther): Remove this when patches don't need special parsing. 118 // TODO(johnniwinther): Remove this when patches don't need special parsing.
26 void registerLibraryFromTag(LibraryDependencyHandler handler, 119 void registerLibraryFromTag(LibraryDependencyHandler handler,
27 LibraryElement library, 120 LibraryElement library,
28 LibraryDependency tag); 121 LibraryDependency tag);
29 122
30 /** 123 /**
31 * Adds the elements in the export scope of [importedLibrary] to the import 124 * Adds the elements in the export scope of [importedLibrary] to the import
32 * scope of [importingLibrary]. 125 * scope of [importingLibrary].
33 */ 126 */
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 */ 219 */
127 class LibraryLoaderTask extends LibraryLoader { 220 class LibraryLoaderTask extends LibraryLoader {
128 LibraryLoaderTask(Compiler compiler) : super(compiler); 221 LibraryLoaderTask(Compiler compiler) : super(compiler);
129 String get name => 'LibraryLoader'; 222 String get name => 'LibraryLoader';
130 223
131 final Map<String, LibraryElement> libraryNames = 224 final Map<String, LibraryElement> libraryNames =
132 new LinkedHashMap<String, LibraryElement>(); 225 new LinkedHashMap<String, LibraryElement>();
133 226
134 LibraryDependencyHandler currentHandler; 227 LibraryDependencyHandler currentHandler;
135 228
136 LibraryElement loadLibrary(Uri uri, Node node, Uri canonicalUri) { 229 LibraryElement loadLibrary(Uri resolvedUri, Node node, Uri canonicalUri) {
137 return measure(() { 230 return measure(() {
138 assert(currentHandler == null); 231 assert(currentHandler == null);
139 currentHandler = new LibraryDependencyHandler(compiler); 232 currentHandler = new LibraryDependencyHandler(compiler);
140 LibraryElement library = 233 LibraryElement library =
141 createLibrary(currentHandler, uri, node, canonicalUri); 234 createLibrary(currentHandler, null, resolvedUri, node, canonicalUri);
142 currentHandler.computeExports(); 235 currentHandler.computeExports();
143 currentHandler = null; 236 currentHandler = null;
144 return library; 237 return library;
145 }); 238 });
146 } 239 }
147 240
148 /** 241 /**
149 * Processes the library tags in [library]. 242 * Processes the library tags in [library].
150 * 243 *
151 * The imported/exported libraries are loaded and processed recursively but 244 * The imported/exported libraries are loaded and processed recursively but
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 tagState = checkTag(TagState.LIBRARY, tag); 279 tagState = checkTag(TagState.LIBRARY, tag);
187 if (library.libraryTag != null) { 280 if (library.libraryTag != null) {
188 compiler.cancel("duplicated library declaration", node: tag); 281 compiler.cancel("duplicated library declaration", node: tag);
189 } else { 282 } else {
190 library.libraryTag = tag; 283 library.libraryTag = tag;
191 } 284 }
192 checkDuplicatedLibraryName(library); 285 checkDuplicatedLibraryName(library);
193 } else if (tag.isPart) { 286 } else if (tag.isPart) {
194 Part part = tag; 287 Part part = tag;
195 StringNode uri = part.uri; 288 StringNode uri = part.uri;
196 Uri resolved = base.resolve(uri.dartString.slowToString()); 289 Uri resolvedUri = base.resolve(uri.dartString.slowToString());
197 tagState = checkTag(TagState.SOURCE, part); 290 tagState = checkTag(TagState.SOURCE, part);
198 scanPart(part, resolved, library); 291 scanPart(part, resolvedUri, library);
199 } else { 292 } else {
200 compiler.internalError("Unhandled library tag.", node: tag); 293 compiler.internalError("Unhandled library tag.", node: tag);
201 } 294 }
202 } 295 }
203 296
204 // Apply patch, if any. 297 // Apply patch, if any.
205 if (library.uri.scheme == 'dart') { 298 if (library.isPlatformLibrary) {
206 patchDartLibrary(handler, library, library.uri.path); 299 patchDartLibrary(handler, library, library.canonicalUri.path);
207 } 300 }
208 301
209 // Import dart:core if not already imported. 302 // Import dart:core if not already imported.
210 if (!importsDartCore && !isDartCore(library.uri)) { 303 if (!importsDartCore && !isDartCore(library.canonicalUri)) {
211 handler.registerDependency(library, null, loadCoreLibrary(handler)); 304 handler.registerDependency(library, null, loadCoreLibrary(handler));
212 } 305 }
213 306
214 for (LibraryDependency tag in libraryDependencies.toLink()) { 307 for (LibraryDependency tag in libraryDependencies.toLink()) {
215 registerLibraryFromTag(handler, library, tag); 308 registerLibraryFromTag(handler, library, tag);
216 } 309 }
217 } 310 }
218 311
219 void checkDuplicatedLibraryName(LibraryElement library) { 312 void checkDuplicatedLibraryName(LibraryElement library) {
220 LibraryName tag = library.libraryTag; 313 LibraryName tag = library.libraryTag;
(...skipping 17 matching lines...) Expand all
238 } 331 }
239 332
240 bool isDartCore(Uri uri) => uri.scheme == "dart" && uri.path == "core"; 333 bool isDartCore(Uri uri) => uri.scheme == "dart" && uri.path == "core";
241 334
242 /** 335 /**
243 * Lazily loads and returns the [LibraryElement] for the dart:core library. 336 * Lazily loads and returns the [LibraryElement] for the dart:core library.
244 */ 337 */
245 LibraryElement loadCoreLibrary(LibraryDependencyHandler handler) { 338 LibraryElement loadCoreLibrary(LibraryDependencyHandler handler) {
246 if (compiler.coreLibrary == null) { 339 if (compiler.coreLibrary == null) {
247 Uri coreUri = new Uri.fromComponents(scheme: 'dart', path: 'core'); 340 Uri coreUri = new Uri.fromComponents(scheme: 'dart', path: 'core');
248 compiler.coreLibrary = createLibrary(handler, coreUri, null, coreUri); 341 compiler.coreLibrary
342 = createLibrary(handler, null, coreUri, null, coreUri);
249 } 343 }
250 return compiler.coreLibrary; 344 return compiler.coreLibrary;
251 } 345 }
252 346
253 void patchDartLibrary(LibraryDependencyHandler handler, 347 void patchDartLibrary(LibraryDependencyHandler handler,
254 LibraryElement library, String dartLibraryPath) { 348 LibraryElement library, String dartLibraryPath) {
255 if (library.isPatched) return; 349 if (library.isPatched) return;
256 Uri patchUri = compiler.resolvePatchUri(dartLibraryPath); 350 Uri patchUri = compiler.resolvePatchUri(dartLibraryPath);
257 if (patchUri != null) { 351 if (patchUri != null) {
258 compiler.patchParser.patchLibrary(handler, patchUri, library); 352 compiler.patchParser.patchLibrary(handler, patchUri, library);
259 } 353 }
260 } 354 }
261 355
262 /** 356 /**
263 * Handle a part tag in the scope of [library]. The [path] given is used as 357 * Handle a part tag in the scope of [library]. The [resolvedUri] given is
264 * is, any URI resolution should be done beforehand. 358 * used as is, any URI resolution should be done beforehand.
265 */ 359 */
266 void scanPart(Part part, Uri path, LibraryElement library) { 360 void scanPart(Part part, Uri resolvedUri, LibraryElement library) {
267 if (!path.isAbsolute()) throw new ArgumentError(path); 361 if (!resolvedUri.isAbsolute()) throw new ArgumentError(resolvedUri);
268 Script sourceScript = compiler.readScript(path, part); 362 Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part);
363 Script sourceScript = compiler.readScript(readableUri, part);
269 CompilationUnitElement unit = 364 CompilationUnitElement unit =
270 new CompilationUnitElementX(sourceScript, library); 365 new CompilationUnitElementX(sourceScript, library);
271 compiler.withCurrentElement(unit, () { 366 compiler.withCurrentElement(unit, () {
272 compiler.scanner.scan(unit); 367 compiler.scanner.scan(unit);
273 if (unit.partTag == null) { 368 if (unit.partTag == null) {
274 bool wasDiagnosticEmitted = false; 369 bool wasDiagnosticEmitted = false;
275 compiler.withCurrentElement(library, () { 370 compiler.withCurrentElement(library, () {
276 wasDiagnosticEmitted = 371 wasDiagnosticEmitted =
277 compiler.onDeprecatedFeature(part, 'missing part-of tag'); 372 compiler.onDeprecatedFeature(part, 'missing part-of tag');
278 }); 373 });
279 if (wasDiagnosticEmitted) { 374 if (wasDiagnosticEmitted) {
280 compiler.reportMessage( 375 compiler.reportMessage(
281 compiler.spanFromElement(unit), 376 compiler.spanFromElement(unit),
282 MessageKind.MISSING_PART_OF_TAG.error([]), 377 MessageKind.MISSING_PART_OF_TAG.error([]),
283 api.Diagnostic.INFO); 378 api.Diagnostic.INFO);
284 } 379 }
285 } 380 }
286 }); 381 });
287 } 382 }
288 383
289 /** 384 /**
290 * Handle an import/export tag by loading the referenced library and 385 * Handle an import/export tag by loading the referenced library and
291 * registering its dependency in [handler] for the computation of the import/ 386 * registering its dependency in [handler] for the computation of the import/
292 * export scope. 387 * export scope.
293 */ 388 */
294 void registerLibraryFromTag(LibraryDependencyHandler handler, 389 void registerLibraryFromTag(LibraryDependencyHandler handler,
295 LibraryElement library, 390 LibraryElement library,
296 LibraryDependency tag) { 391 LibraryDependency tag) {
297 Uri base = library.entryCompilationUnit.script.uri; 392 Uri base = library.entryCompilationUnit.script.uri;
298 Uri resolved = base.resolve(tag.uri.dartString.slowToString()); 393 Uri resolvedUri = base.resolve(tag.uri.dartString.slowToString());
299 LibraryElement loadedLibrary = 394 LibraryElement loadedLibrary =
300 createLibrary(handler, resolved, tag.uri, resolved); 395 createLibrary(handler, library, resolvedUri, tag.uri, resolvedUri);
301 handler.registerDependency(library, tag, loadedLibrary); 396 handler.registerDependency(library, tag, loadedLibrary);
302 397
303 if (!loadedLibrary.hasLibraryName()) { 398 if (!loadedLibrary.hasLibraryName()) {
304 compiler.withCurrentElement(library, () { 399 compiler.withCurrentElement(library, () {
305 compiler.reportError(tag == null ? null : tag.uri, 400 compiler.reportError(tag == null ? null : tag.uri,
306 'no library name found in ${loadedLibrary.uri}'); 401 'no library name found in ${loadedLibrary.canonicalUri}');
307 }); 402 });
308 } 403 }
309 } 404 }
310 405
311 /** 406 /**
312 * Create (or reuse) a library element for the library located at [uri]. 407 * Create (or reuse) a library element for the library specified by the
408 * [resolvedUri].
409 *
313 * If a new library is created, the [handler] is notified. 410 * If a new library is created, the [handler] is notified.
314 */ 411 */
412 // TODO(johnniwinther): Remove [canonicalUri] and make [resolvedUri] the
413 // canonical uri when [Compiler.scanBuiltinLibrary] is removed.
315 LibraryElement createLibrary(LibraryDependencyHandler handler, 414 LibraryElement createLibrary(LibraryDependencyHandler handler,
316 Uri uri, Node node, Uri canonicalUri) { 415 LibraryElement importingLibrary,
416 Uri resolvedUri, Node node, Uri canonicalUri) {
317 bool newLibrary = false; 417 bool newLibrary = false;
418 Uri readableUri =
419 compiler.translateResolvedUri(importingLibrary, resolvedUri, node);
420 if (readableUri == null) return null;
318 LibraryElement createLibrary() { 421 LibraryElement createLibrary() {
319 newLibrary = true; 422 newLibrary = true;
320 Script script = compiler.readScript(uri, node); 423 Script script = compiler.readScript(readableUri, node);
321 LibraryElement element = new LibraryElementX(script, canonicalUri); 424 LibraryElement element = new LibraryElementX(script, canonicalUri);
322 handler.registerNewLibrary(element); 425 handler.registerNewLibrary(element);
323 native.maybeEnableNative(compiler, element, uri); 426 native.maybeEnableNative(compiler, element);
324 return element; 427 return element;
325 } 428 }
326 LibraryElement library; 429 LibraryElement library;
327 if (canonicalUri == null) { 430 if (canonicalUri == null) {
328 library = createLibrary(); 431 library = createLibrary();
329 } else { 432 } else {
330 library = compiler.libraries.putIfAbsent(canonicalUri.toString(), 433 library = compiler.libraries.putIfAbsent(canonicalUri.toString(),
331 createLibrary); 434 createLibrary);
332 } 435 }
333 if (newLibrary) { 436 if (newLibrary) {
334 compiler.withCurrentElement(library, () { 437 compiler.withCurrentElement(library, () {
335 compiler.scanner.scanLibrary(library); 438 compiler.scanner.scanLibrary(library);
336 processLibraryTags(handler, library); 439 processLibraryTags(handler, library);
337 handler.registerLibraryExports(library); 440 handler.registerLibraryExports(library);
338 compiler.onLibraryScanned(library, uri); 441 compiler.onLibraryScanned(library, resolvedUri);
339 }); 442 });
340 } 443 }
341 return library; 444 return library;
342 } 445 }
343 446
344 // TODO(johnniwinther): Remove this method when 'js_helper' is handled by 447 // TODO(johnniwinther): Remove this method when 'js_helper' is handled by
345 // [LibraryLoaderTask]. 448 // [LibraryLoaderTask].
346 void importLibrary(LibraryElement importingLibrary, 449 void importLibrary(LibraryElement importingLibrary,
347 LibraryElement importedLibrary, 450 LibraryElement importedLibrary,
348 Import tag) { 451 Import tag) {
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 } 828 }
726 829
727 /** 830 /**
728 * Registers all top-level entities of [library] as starting point for the 831 * Registers all top-level entities of [library] as starting point for the
729 * fixed-point computation of the import/export scopes. 832 * fixed-point computation of the import/export scopes.
730 */ 833 */
731 void registerLibraryExports(LibraryElement library) { 834 void registerLibraryExports(LibraryElement library) {
732 nodeMap[library].registerInitialExports(); 835 nodeMap[library].registerInitialExports();
733 } 836 }
734 } 837 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698