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

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: Update MockCompiler 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 * ## Absolute URI ##
ahe 2013/01/24 10:00:57 I would call this "resolved".
Johnni Winther 2013/01/24 13:04:59 Done.
31 *
32 * An 'absolute 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 absolute.
35 * A relative URI like for instance '../foo/bar.dart' is resolved into an
36 * absolute 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 absolute 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 absolute 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 absolute URI is
51 * 'package:some/foo/bar.dart'.
52 *
53 * The absolute URI thus preserves the scheme through resolution: A readable
54 * file URI results in an absolute file URI and a readable package URI results
55 * in an absolute 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 absolute 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 ##
ahe 2013/01/24 10:00:57 I don't understand why we need both "readable URIs
Johnni Winther 2013/01/24 13:04:59 Added a discussion of this.
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.resolveAbsoluteUri] method which checks whether a library by that
76 * name exacts and in case of internal libraries whether access is granted.
ahe 2013/01/24 10:00:57 exacts -> exists
Johnni Winther 2013/01/24 13:04:59 Done.
77 *
78 * ## Resource URI ##
79 *
80 * A 'resource URI' is an absolute URI with is 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'
ahe 2013/01/24 10:00:57 This is a good example of something that shouldn't
Johnni Winther 2013/01/24 13:04:59 Changed the example since that was not crucial to
87 * will be resolved to the resource URI 'file:///current/working/foo/bar.dart'.
88 *
9 */ 89 */
10 abstract class LibraryLoader extends CompilerTask { 90 abstract class LibraryLoader extends CompilerTask {
11 LibraryLoader(Compiler compiler) : super(compiler); 91 LibraryLoader(Compiler compiler) : super(compiler);
12 92
13 /** 93 /**
14 * Loads the library located at [uri] and returns its [LibraryElement]. 94 * Loads the library specified by the [absoluteUri] and returns its
95 * [LibraryElement].
15 * 96 *
16 * If the library is not already loaded, the method creates the 97 * If the library is not already loaded, the method creates the
17 * [LibraryElement] for the library and computes the import/export scope, 98 * [LibraryElement] for the library and computes the import/export scope,
18 * loading and computing the import/export scopes of all required libraries in 99 * loading and computing the import/export scopes of all required libraries in
19 * the process. The method handles cyclic dependency between libraries. 100 * the process. The method handles cyclic dependency between libraries.
20 * 101 *
21 * This is the main entry point for [LibraryLoader]. 102 * This is the main entry point for [LibraryLoader].
22 */ 103 */
23 LibraryElement loadLibrary(Uri uri, Node node, Uri canonicalUri); 104 // TODO(johnniwinther): Remove [canonicalUri] together with
105 // [Compiler.scanBuiltinLibrary].
106 LibraryElement loadLibrary(Uri absoluteUri, Node node, Uri canonicalUri);
24 107
25 // TODO(johnniwinther): Remove this when patches don't need special parsing. 108 // TODO(johnniwinther): Remove this when patches don't need special parsing.
26 void registerLibraryFromTag(LibraryDependencyHandler handler, 109 void registerLibraryFromTag(LibraryDependencyHandler handler,
27 LibraryElement library, 110 LibraryElement library,
28 LibraryDependency tag); 111 LibraryDependency tag);
29 112
30 /** 113 /**
31 * Adds the elements in the export scope of [importedLibrary] to the import 114 * Adds the elements in the export scope of [importedLibrary] to the import
32 * scope of [importingLibrary]. 115 * scope of [importingLibrary].
33 */ 116 */
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 */ 209 */
127 class LibraryLoaderTask extends LibraryLoader { 210 class LibraryLoaderTask extends LibraryLoader {
128 LibraryLoaderTask(Compiler compiler) : super(compiler); 211 LibraryLoaderTask(Compiler compiler) : super(compiler);
129 String get name => 'LibraryLoader'; 212 String get name => 'LibraryLoader';
130 213
131 final Map<String, LibraryElement> libraryNames = 214 final Map<String, LibraryElement> libraryNames =
132 new LinkedHashMap<String, LibraryElement>(); 215 new LinkedHashMap<String, LibraryElement>();
133 216
134 LibraryDependencyHandler currentHandler; 217 LibraryDependencyHandler currentHandler;
135 218
136 LibraryElement loadLibrary(Uri uri, Node node, Uri canonicalUri) { 219 LibraryElement loadLibrary(Uri absoluteUri, Node node, Uri canonicalUri) {
137 return measure(() { 220 return measure(() {
138 assert(currentHandler == null); 221 assert(currentHandler == null);
139 currentHandler = new LibraryDependencyHandler(compiler); 222 currentHandler = new LibraryDependencyHandler(compiler);
140 LibraryElement library = 223 LibraryElement library =
141 createLibrary(currentHandler, uri, node, canonicalUri); 224 createLibrary(currentHandler, null, absoluteUri, node, canonicalUri);
142 currentHandler.computeExports(); 225 currentHandler.computeExports();
143 currentHandler = null; 226 currentHandler = null;
144 return library; 227 return library;
145 }); 228 });
146 } 229 }
147 230
148 /** 231 /**
149 * Processes the library tags in [library]. 232 * Processes the library tags in [library].
150 * 233 *
151 * The imported/exported libraries are loaded and processed recursively but 234 * 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); 269 tagState = checkTag(TagState.LIBRARY, tag);
187 if (library.libraryTag != null) { 270 if (library.libraryTag != null) {
188 compiler.cancel("duplicated library declaration", node: tag); 271 compiler.cancel("duplicated library declaration", node: tag);
189 } else { 272 } else {
190 library.libraryTag = tag; 273 library.libraryTag = tag;
191 } 274 }
192 checkDuplicatedLibraryName(library); 275 checkDuplicatedLibraryName(library);
193 } else if (tag.isPart) { 276 } else if (tag.isPart) {
194 Part part = tag; 277 Part part = tag;
195 StringNode uri = part.uri; 278 StringNode uri = part.uri;
196 Uri resolved = base.resolve(uri.dartString.slowToString()); 279 Uri absoluteUri = base.resolve(uri.dartString.slowToString());
197 tagState = checkTag(TagState.SOURCE, part); 280 tagState = checkTag(TagState.SOURCE, part);
198 scanPart(part, resolved, library); 281 scanPart(part, absoluteUri, library);
199 } else { 282 } else {
200 compiler.internalError("Unhandled library tag.", node: tag); 283 compiler.internalError("Unhandled library tag.", node: tag);
201 } 284 }
202 } 285 }
203 286
204 // Apply patch, if any. 287 // Apply patch, if any.
205 if (library.uri.scheme == 'dart') { 288 if (library.isPlatformLibrary) {
206 patchDartLibrary(handler, library, library.uri.path); 289 patchDartLibrary(handler, library, library.canonicalUri.path);
207 } 290 }
208 291
209 // Import dart:core if not already imported. 292 // Import dart:core if not already imported.
210 if (!importsDartCore && !isDartCore(library.uri)) { 293 if (!importsDartCore && !isDartCore(library.canonicalUri)) {
211 handler.registerDependency(library, null, loadCoreLibrary(handler)); 294 handler.registerDependency(library, null, loadCoreLibrary(handler));
212 } 295 }
213 296
214 for (LibraryDependency tag in libraryDependencies.toLink()) { 297 for (LibraryDependency tag in libraryDependencies.toLink()) {
215 registerLibraryFromTag(handler, library, tag); 298 registerLibraryFromTag(handler, library, tag);
216 } 299 }
217 } 300 }
218 301
219 void checkDuplicatedLibraryName(LibraryElement library) { 302 void checkDuplicatedLibraryName(LibraryElement library) {
220 LibraryName tag = library.libraryTag; 303 LibraryName tag = library.libraryTag;
(...skipping 17 matching lines...) Expand all
238 } 321 }
239 322
240 bool isDartCore(Uri uri) => uri.scheme == "dart" && uri.path == "core"; 323 bool isDartCore(Uri uri) => uri.scheme == "dart" && uri.path == "core";
241 324
242 /** 325 /**
243 * Lazily loads and returns the [LibraryElement] for the dart:core library. 326 * Lazily loads and returns the [LibraryElement] for the dart:core library.
244 */ 327 */
245 LibraryElement loadCoreLibrary(LibraryDependencyHandler handler) { 328 LibraryElement loadCoreLibrary(LibraryDependencyHandler handler) {
246 if (compiler.coreLibrary == null) { 329 if (compiler.coreLibrary == null) {
247 Uri coreUri = new Uri.fromComponents(scheme: 'dart', path: 'core'); 330 Uri coreUri = new Uri.fromComponents(scheme: 'dart', path: 'core');
248 compiler.coreLibrary = createLibrary(handler, coreUri, null, coreUri); 331 compiler.coreLibrary
332 = createLibrary(handler, null, coreUri, null, coreUri);
249 } 333 }
250 return compiler.coreLibrary; 334 return compiler.coreLibrary;
251 } 335 }
252 336
253 void patchDartLibrary(LibraryDependencyHandler handler, 337 void patchDartLibrary(LibraryDependencyHandler handler,
254 LibraryElement library, String dartLibraryPath) { 338 LibraryElement library, String dartLibraryPath) {
255 if (library.isPatched) return; 339 if (library.isPatched) return;
256 Uri patchUri = compiler.resolvePatchUri(dartLibraryPath); 340 Uri patchUri = compiler.resolvePatchUri(dartLibraryPath);
257 if (patchUri != null) { 341 if (patchUri != null) {
258 compiler.patchParser.patchLibrary(handler, patchUri, library); 342 compiler.patchParser.patchLibrary(handler, patchUri, library);
259 } 343 }
260 } 344 }
261 345
262 /** 346 /**
263 * Handle a part tag in the scope of [library]. The [path] given is used as 347 * Handle a part tag in the scope of [library]. The [absoluteUri] given is
264 * is, any URI resolution should be done beforehand. 348 * used as is, any URI resolution should be done beforehand.
265 */ 349 */
266 void scanPart(Part part, Uri path, LibraryElement library) { 350 void scanPart(Part part, Uri absoluteUri, LibraryElement library) {
267 if (!path.isAbsolute()) throw new ArgumentError(path); 351 if (!absoluteUri.isAbsolute()) throw new ArgumentError(absoluteUri);
268 Script sourceScript = compiler.readScript(path, part); 352 Uri readableUri = compiler.resolveAbsoluteUri(library, absoluteUri, part);
353 Script sourceScript = compiler.readScript(readableUri, part);
269 CompilationUnitElement unit = 354 CompilationUnitElement unit =
270 new CompilationUnitElementX(sourceScript, library); 355 new CompilationUnitElementX(sourceScript, library);
271 compiler.withCurrentElement(unit, () { 356 compiler.withCurrentElement(unit, () {
272 compiler.scanner.scan(unit); 357 compiler.scanner.scan(unit);
273 if (unit.partTag == null) { 358 if (unit.partTag == null) {
274 bool wasDiagnosticEmitted = false; 359 bool wasDiagnosticEmitted = false;
275 compiler.withCurrentElement(library, () { 360 compiler.withCurrentElement(library, () {
276 wasDiagnosticEmitted = 361 wasDiagnosticEmitted =
277 compiler.onDeprecatedFeature(part, 'missing part-of tag'); 362 compiler.onDeprecatedFeature(part, 'missing part-of tag');
278 }); 363 });
279 if (wasDiagnosticEmitted) { 364 if (wasDiagnosticEmitted) {
280 compiler.reportMessage( 365 compiler.reportMessage(
281 compiler.spanFromElement(unit), 366 compiler.spanFromElement(unit),
282 MessageKind.MISSING_PART_OF_TAG.error([]), 367 MessageKind.MISSING_PART_OF_TAG.error([]),
283 api.Diagnostic.INFO); 368 api.Diagnostic.INFO);
284 } 369 }
285 } 370 }
286 }); 371 });
287 } 372 }
288 373
289 /** 374 /**
290 * Handle an import/export tag by loading the referenced library and 375 * Handle an import/export tag by loading the referenced library and
291 * registering its dependency in [handler] for the computation of the import/ 376 * registering its dependency in [handler] for the computation of the import/
292 * export scope. 377 * export scope.
293 */ 378 */
294 void registerLibraryFromTag(LibraryDependencyHandler handler, 379 void registerLibraryFromTag(LibraryDependencyHandler handler,
295 LibraryElement library, 380 LibraryElement library,
296 LibraryDependency tag) { 381 LibraryDependency tag) {
297 Uri base = library.entryCompilationUnit.script.uri; 382 Uri base = library.entryCompilationUnit.script.uri;
298 Uri resolved = base.resolve(tag.uri.dartString.slowToString()); 383 Uri absoluteUri = base.resolve(tag.uri.dartString.slowToString());
299 LibraryElement loadedLibrary = 384 LibraryElement loadedLibrary =
300 createLibrary(handler, resolved, tag.uri, resolved); 385 createLibrary(handler, library, absoluteUri, tag.uri, absoluteUri);
301 handler.registerDependency(library, tag, loadedLibrary); 386 handler.registerDependency(library, tag, loadedLibrary);
302 387
303 if (!loadedLibrary.hasLibraryName()) { 388 if (!loadedLibrary.hasLibraryName()) {
304 compiler.withCurrentElement(library, () { 389 compiler.withCurrentElement(library, () {
305 compiler.reportError(tag == null ? null : tag.uri, 390 compiler.reportError(tag == null ? null : tag.uri,
306 'no library name found in ${loadedLibrary.uri}'); 391 'no library name found in ${loadedLibrary.canonicalUri}');
307 }); 392 });
308 } 393 }
309 } 394 }
310 395
311 /** 396 /**
312 * Create (or reuse) a library element for the library located at [uri]. 397 * Create (or reuse) a library element for the library specified by the
398 * [absoluteUri].
399 *
313 * If a new library is created, the [handler] is notified. 400 * If a new library is created, the [handler] is notified.
314 */ 401 */
402 // TODO(johnniwinther): Remove [canonicalUri] and make [absoluteUri] the
403 // canonical uri when [Compiler.scanBuiltinLibrary] is removed.
315 LibraryElement createLibrary(LibraryDependencyHandler handler, 404 LibraryElement createLibrary(LibraryDependencyHandler handler,
316 Uri uri, Node node, Uri canonicalUri) { 405 LibraryElement importingLibrary,
406 Uri absoluteUri, Node node, Uri canonicalUri) {
317 bool newLibrary = false; 407 bool newLibrary = false;
408 Uri readableUri =
409 compiler.resolveAbsoluteUri(importingLibrary, absoluteUri, node);
410 if (readableUri == null) return null;
318 LibraryElement createLibrary() { 411 LibraryElement createLibrary() {
319 newLibrary = true; 412 newLibrary = true;
320 Script script = compiler.readScript(uri, node); 413 Script script = compiler.readScript(readableUri, node);
321 LibraryElement element = new LibraryElementX(script, canonicalUri); 414 LibraryElement element = new LibraryElementX(script, canonicalUri);
322 handler.registerNewLibrary(element); 415 handler.registerNewLibrary(element);
323 native.maybeEnableNative(compiler, element, uri); 416 native.maybeEnableNative(compiler, element);
324 return element; 417 return element;
325 } 418 }
326 LibraryElement library; 419 LibraryElement library;
327 if (canonicalUri == null) { 420 if (canonicalUri == null) {
328 library = createLibrary(); 421 library = createLibrary();
329 } else { 422 } else {
330 library = compiler.libraries.putIfAbsent(canonicalUri.toString(), 423 library = compiler.libraries.putIfAbsent(canonicalUri.toString(),
331 createLibrary); 424 createLibrary);
332 } 425 }
333 if (newLibrary) { 426 if (newLibrary) {
334 compiler.withCurrentElement(library, () { 427 compiler.withCurrentElement(library, () {
335 compiler.scanner.scanLibrary(library); 428 compiler.scanner.scanLibrary(library);
336 processLibraryTags(handler, library); 429 processLibraryTags(handler, library);
337 handler.registerLibraryExports(library); 430 handler.registerLibraryExports(library);
338 compiler.onLibraryScanned(library, uri); 431 compiler.onLibraryScanned(library, absoluteUri);
339 }); 432 });
340 } 433 }
341 return library; 434 return library;
342 } 435 }
343 436
344 // TODO(johnniwinther): Remove this method when 'js_helper' is handled by 437 // TODO(johnniwinther): Remove this method when 'js_helper' is handled by
345 // [LibraryLoaderTask]. 438 // [LibraryLoaderTask].
346 void importLibrary(LibraryElement importingLibrary, 439 void importLibrary(LibraryElement importingLibrary,
347 LibraryElement importedLibrary, 440 LibraryElement importedLibrary,
348 Import tag) { 441 Import tag) {
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 } 818 }
726 819
727 /** 820 /**
728 * Registers all top-level entities of [library] as starting point for the 821 * Registers all top-level entities of [library] as starting point for the
729 * fixed-point computation of the import/export scopes. 822 * fixed-point computation of the import/export scopes.
730 */ 823 */
731 void registerLibraryExports(LibraryElement library) { 824 void registerLibraryExports(LibraryElement library) {
732 nodeMap[library].registerInitialExports(); 825 nodeMap[library].registerInitialExports();
733 } 826 }
734 } 827 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698