@@ -89,12 +89,19 @@ Uri _rootScript;
89
89
90
90
// Packages are either resolved looking up in a map or resolved from within a
91
91
// package root.
92
- bool _packagesReady () => (_packageRoot != null ) || (_packageMap != null );
92
+ bool get _packagesReady =>
93
+ (_packageRoot != null ) || (_packageMap != null ) || (_packageError != null );
94
+ // Error string set if there was an error resolving package configuration.
95
+ // For example not finding a .packages file or packages/ directory, malformed
96
+ // .packages file or any other related error.
97
+ String _packageError = null ;
93
98
// The directory to look in to resolve "package:" scheme URIs. By detault it is
94
99
// the 'packages' directory right next to the script.
95
100
Uri _packageRoot = null ; // Used to be _rootScript.resolve('packages/');
96
101
// The map describing how certain package names are mapped to Uris.
102
+ Uri _packageConfig = null ;
97
103
Map <String , Uri > _packageMap = null ;
104
+
98
105
// A list of pending packags which have been requested while resolving the
99
106
// location of the package root or the contents of the package map.
100
107
List <_LoadRequest > _pendingPackageLoads = [];
@@ -109,8 +116,9 @@ bool _pendingLoads() => !_reqMap.isEmpty || !_pendingPackageLoads.isEmpty;
109
116
bool _isWindows = false ;
110
117
111
118
// Logging from builtin.dart is prefixed with a '*'.
119
+ String _logId = (Isolate .current.hashCode % 0x100000 ).toRadixString (16 );
112
120
_log (msg) {
113
- _print ("* $msg " );
121
+ _print ("* $_logId $ msg " );
114
122
}
115
123
116
124
// A class wrapping the load error message in an Error object.
@@ -235,8 +243,10 @@ _setPackageRoot(String packageRoot) {
235
243
_packageRoot = _workingDirectory.resolveUri (new Uri .file (packageRoot));
236
244
}
237
245
// Now that we have determined the packageRoot value being used, set it
238
- // up for use in Platform.packageRoot.
239
- VMLibraryHooks .packageRoot = _packageRoot.toString ();
246
+ // up for use in Platform.packageRoot. This is only set when the embedder
247
+ // sets up the package root. Automatically discovered package root will
248
+ // not update the VMLibraryHooks value.
249
+ VMLibraryHooks .packageRootString = _packageRoot.toString ();
240
250
if (_traceLoading) {
241
251
_log ('Package root URI: $_packageRoot ' );
242
252
}
@@ -246,6 +256,9 @@ _setPackageRoot(String packageRoot) {
246
256
// Given a uri with a 'package' scheme, return a Uri that is prefixed with
247
257
// the package root.
248
258
Uri _resolvePackageUri (Uri uri) {
259
+ assert (uri.scheme == "package" );
260
+ assert (_packagesReady);
261
+
249
262
if (! uri.host.isEmpty) {
250
263
var path = '${uri .host }${uri .path }' ;
251
264
var right = 'package:$path ' ;
@@ -259,7 +272,12 @@ Uri _resolvePackageUri(Uri uri) {
259
272
_log ('Resolving package with uri path: ${uri .path }' );
260
273
}
261
274
var resolvedUri;
262
- if (_packageRoot != null ) {
275
+ if (_packageError != null ) {
276
+ if (_traceLoading) {
277
+ _log ("Resolving package with pending resolution error: $_packageError " );
278
+ }
279
+ throw _packageError;
280
+ } else if (_packageRoot != null ) {
263
281
resolvedUri = _packageRoot.resolve (uri.path);
264
282
} else {
265
283
var packageName = uri.pathSegments[0 ];
@@ -408,22 +426,33 @@ void _handlePackagesReply(msg) {
408
426
if (_traceLoading) {
409
427
_log ("Got failure response on package port: '$msg '" );
410
428
}
411
- throw msg;
412
- }
413
- if (msg.length == 1 ) {
414
- if (_traceLoading) {
415
- _log ("Received package root: '${msg [0 ]}'" );
429
+ // Remember the error message.
430
+ _packageError = msg;
431
+ } else if (msg is List ) {
432
+ if (msg.length == 1 ) {
433
+ if (_traceLoading) {
434
+ _log ("Received package root: '${msg [0 ]}'" );
435
+ }
436
+ _packageRoot = Uri .parse (msg[0 ]);
437
+ } else {
438
+ // First entry contains the location of the loaded .packages file.
439
+ assert ((msg.length % 2 ) == 0 );
440
+ assert (msg.length >= 2 );
441
+ assert (msg[1 ] == null );
442
+ _packageConfig = Uri .parse (msg[0 ]);
443
+ _packageMap = new Map <String , Uri >();
444
+ for (var i = 2 ; i < msg.length; i+= 2 ) {
445
+ // TODO(iposva): Complain about duplicate entries.
446
+ _packageMap[msg[i]] = Uri .parse (msg[i+ 1 ]);
447
+ }
448
+ if (_traceLoading) {
449
+ _log ("Setup package map: $_packageMap " );
450
+ }
416
451
}
417
- _packageRoot = Uri .parse (msg[0 ]);
418
452
} else {
419
- assert ((msg.length % 2 ) == 0 );
420
- _packageMap = new Map <String , Uri >();
421
- for (var i = 0 ; i < msg.length; i+= 2 ) {
422
- // TODO(iposva): Complain about duplicate entries.
423
- _packageMap[msg[i]] = Uri .parse (msg[i+ 1 ]);
424
- }
453
+ _packageError = "Bad type of packages reply: ${msg .runtimeType }" ;
425
454
if (_traceLoading) {
426
- _log ("Setup package map: $ _packageMap " );
455
+ _log (_packageError );
427
456
}
428
457
}
429
458
@@ -485,7 +514,8 @@ void _loadPackagesMap(String packagesParam) {
485
514
// resolve it against the working directory.
486
515
packagesUri = _workingDirectory.resolveUri (packagesUri);
487
516
}
488
- VMLibraryHooks .packageConfig = packagesUri.toString ();
517
+ var packagesUriStr = packagesUri.toString ();
518
+ VMLibraryHooks .packageConfigString = packagesUriStr;
489
519
if (_traceLoading) {
490
520
_log ('Resolved packages map to: $packagesUri ' );
491
521
}
@@ -500,7 +530,7 @@ void _loadPackagesMap(String packagesParam) {
500
530
msg[0 ] = sp;
501
531
msg[1 ] = _traceLoading;
502
532
msg[2 ] = - 2 ;
503
- msg[3 ] = packagesUri. toString () ;
533
+ msg[3 ] = packagesUriStr ;
504
534
_loadPort.send (msg);
505
535
506
536
// Signal that the resolution of the packages map has started. But in this
@@ -519,34 +549,6 @@ void _loadPackagesMap(String packagesParam) {
519
549
}
520
550
521
551
522
- // Embedder Entrypoint:
523
- // Add mapping from package name to URI.
524
- void _addPackageMapEntry (String key, String value) {
525
- if (! _setupCompleted) {
526
- _setupHooks ();
527
- }
528
- if (_traceLoading) {
529
- _log ("Adding packages map entry: $key -> $value " );
530
- }
531
- if (_packageRoot != null ) {
532
- if (_traceLoading) {
533
- _log ("_packageRoot already set: $_packageRoot " );
534
- }
535
- throw "Cannot add package map entry to an exisiting package root." ;
536
- }
537
- if (_packagesPort != null ) {
538
- if (_traceLoading) {
539
- _log ("Package map load request already pending." );
540
- }
541
- throw "Cannot add package map entry during package map resolution." ;
542
- }
543
- if (_packageMap == null ) {
544
- _packageMap = new Map <String , Uri >();
545
- }
546
- _packageMap[key] = _workingDirectory.resolve (value);
547
- }
548
-
549
-
550
552
void _asyncLoadError (_LoadRequest req, _LoadError error, StackTrace stack) {
551
553
if (_traceLoading) {
552
554
_log ("_asyncLoadError(${req ._uri }), error: $error \n stack: $stack " );
@@ -587,8 +589,22 @@ _loadDataFromLoadPort(int tag, String uri, Uri resourceUri, context) {
587
589
// Loading a package URI needs to first map the package name to a loadable
588
590
// URI.
589
591
_loadPackage (int tag, String uri, Uri resourceUri, context) {
590
- if (_packagesReady ()) {
591
- _loadData (tag, uri, _resolvePackageUri (resourceUri), context);
592
+ if (_packagesReady) {
593
+ var resolvedUri;
594
+ try {
595
+ resolvedUri = _resolvePackageUri (resourceUri);
596
+ } catch (e, s) {
597
+ if (_traceLoading) {
598
+ _log ("Exception ($e ) when resolving package URI: $resourceUri " );
599
+ }
600
+ // Wrap inside a _LoadError unless we are already propagating a previously
601
+ // seen _LoadError.
602
+ var error = (e is _LoadError ) ? e : new _LoadError (uri, e.toString ());
603
+ // Register a dummy load request and fail to load it.
604
+ var req = new _LoadRequest (tag, uri, resourceUri, context);
605
+ _asyncLoadError (req, error, s);
606
+ }
607
+ _loadData (tag, uri, resolvedUri, context);
592
608
} else {
593
609
if (_pendingPackageLoads.isEmpty) {
594
610
// Package resolution has not been setup yet, and this is the first
@@ -606,7 +622,7 @@ _loadPackage(int tag, String uri, Uri resourceUri, context) {
606
622
});
607
623
if (_traceLoading) {
608
624
_log ("Pending package load of '$uri ': "
609
- "${_pendingPackageLoads .length } pending" );
625
+ "${_pendingPackageLoads .length } pending" );
610
626
}
611
627
}
612
628
}
@@ -669,7 +685,7 @@ String _resolveUri(String base, String userString) {
669
685
670
686
// Handling of access to the package root or package map from user code.
671
687
_triggerPackageResolution (action) {
672
- if (_packagesReady () ) {
688
+ if (_packagesReady) {
673
689
// Packages are ready. Execute the action now.
674
690
action ();
675
691
} else {
@@ -684,7 +700,7 @@ _triggerPackageResolution(action) {
684
700
}
685
701
686
702
687
- Future <Uri > _getPackageRoot () {
703
+ Future <Uri > _getPackageRootFuture () {
688
704
if (_traceLoading) {
689
705
_log ("Request for package root from user code." );
690
706
}
@@ -696,19 +712,47 @@ Future<Uri> _getPackageRoot() {
696
712
}
697
713
698
714
699
- Future <Map < String , Uri >> _getPackageMap () {
715
+ Future <Uri > _getPackageConfigFuture () {
700
716
if (_traceLoading) {
701
- _log ("Request for package map from user code." );
717
+ _log ("Request for package config from user code." );
702
718
}
703
- var completer = new Completer <Map < String , Uri > >();
719
+ var completer = new Completer <Uri >();
704
720
_triggerPackageResolution (() {
705
- var result = (_packageMap != null ) ? new Map .from (_packageMap) : {};
706
- completer.complete (result);
721
+ completer.complete (_packageConfig);
707
722
});
708
723
return completer.future;
709
724
}
710
725
711
726
727
+ Future <Uri > _resolvePackageUriFuture (Uri packageUri) async {
728
+ if (_traceLoading) {
729
+ _log ("Request for package Uri resolution from user code: $packageUri " );
730
+ }
731
+ if (packageUri.scheme != "package" ) {
732
+ if (_traceLoading) {
733
+ _log ("Non-package Uri, returning unmodified: $packageUri " );
734
+ }
735
+ // Return the incoming parameter if not passed a package: URI.
736
+ return packageUri;
737
+ }
738
+
739
+ if (! _packagesReady) {
740
+ if (_traceLoading) {
741
+ _log ("Trigger loading by requesting the package config." );
742
+ }
743
+ // Make sure to trigger package resolution.
744
+ var dummy = await _getPackageConfigFuture ();
745
+ }
746
+ assert (_packagesReady);
747
+
748
+ var result = _resolvePackageUri (packageUri);
749
+ if (_traceLoading) {
750
+ _log ("Resolved '$packageUri ' to '$result '" );
751
+ }
752
+ return result;
753
+ }
754
+
755
+
712
756
// Handling of Resource class by dispatching to the load port.
713
757
Future <List <int >> _resourceReadAsBytes (Uri uri) {
714
758
var completer = new Completer <List <int >>();
@@ -836,6 +880,8 @@ _extensionPathFromUri(String userUri) {
836
880
_setupHooks () {
837
881
_setupCompleted = true ;
838
882
VMLibraryHooks .resourceReadAsBytes = _resourceReadAsBytes;
839
- VMLibraryHooks .getPackageRoot = _getPackageRoot;
840
- VMLibraryHooks .getPackageMap = _getPackageMap;
883
+
884
+ VMLibraryHooks .packageRootUriFuture = _getPackageRootFuture;
885
+ VMLibraryHooks .packageConfigUriFuture = _getPackageConfigFuture;
886
+ VMLibraryHooks .resolvePackageUriFuture = _resolvePackageUriFuture;
841
887
}
0 commit comments