5
5
library leg_apiimpl;
6
6
7
7
import 'dart:async' ;
8
+ import 'dart:convert' ;
8
9
9
10
import '../compiler.dart' as api;
10
11
import 'dart2jslib.dart' as leg;
@@ -13,6 +14,11 @@ import 'elements/elements.dart' as elements;
13
14
import 'package:_internal/libraries.dart' hide LIBRARIES;
14
15
import 'package:_internal/libraries.dart' as library_info show LIBRARIES;
15
16
import 'io/source_file.dart' ;
17
+ import 'package:package_config/packages.dart' ;
18
+ import 'package:package_config/packages_file.dart' as pkgs;
19
+ import 'package:package_config/src/packages_impl.dart'
20
+ show NonFilePackagesDirectoryPackages, MapPackages;
21
+ import 'package:package_config/src/util.dart' show checkValidPackageUri;
16
22
17
23
const bool forceIncrementalSupport =
18
24
const bool .fromEnvironment ('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT' );
@@ -21,22 +27,28 @@ class Compiler extends leg.Compiler {
21
27
api.CompilerInputProvider provider;
22
28
api.DiagnosticHandler handler;
23
29
final Uri libraryRoot;
30
+ final Uri packageConfig;
24
31
final Uri packageRoot;
32
+ final api.PackagesDiscoveryProvider packagesDiscoveryProvider;
33
+ Packages packages;
25
34
List <String > options;
26
35
Map <String , dynamic > environment;
27
36
bool mockableLibraryUsed = false ;
28
37
final Set <String > allowedLibraryCategories;
29
38
30
39
leg.GenericTask userHandlerTask;
31
40
leg.GenericTask userProviderTask;
41
+ leg.GenericTask userPackagesDiscoveryTask;
32
42
33
43
Compiler (this .provider,
34
44
api.CompilerOutputProvider outputProvider,
35
45
this .handler,
36
46
this .libraryRoot,
37
47
this .packageRoot,
38
48
List <String > options,
39
- this .environment)
49
+ this .environment,
50
+ [this .packageConfig,
51
+ this .packagesDiscoveryProvider])
40
52
: this .options = options,
41
53
this .allowedLibraryCategories = getAllowedLibraryCategories (options),
42
54
super (
@@ -96,17 +108,20 @@ class Compiler extends leg.Compiler {
96
108
tasks.addAll ([
97
109
userHandlerTask = new leg.GenericTask ('Diagnostic handler' , this ),
98
110
userProviderTask = new leg.GenericTask ('Input provider' , this ),
111
+ userPackagesDiscoveryTask =
112
+ new leg.GenericTask ('Package discovery' , this ),
99
113
]);
100
114
if (libraryRoot == null ) {
101
115
throw new ArgumentError ("[libraryRoot] is null." );
102
116
}
103
117
if (! libraryRoot.path.endsWith ("/" )) {
104
118
throw new ArgumentError ("[libraryRoot] must end with a /." );
105
119
}
106
- if (packageRoot == null ) {
107
- throw new ArgumentError ("[packageRoot] is null." );
120
+ if (packageRoot != null && packageConfig != null ) {
121
+ throw new ArgumentError ("Only one of [packageRoot] or [packageConfig] "
122
+ "may be given." );
108
123
}
109
- if (! packageRoot.path.endsWith ("/" )) {
124
+ if (packageRoot != null && ! packageRoot.path.endsWith ("/" )) {
110
125
throw new ArgumentError ("[packageRoot] must end with a /." );
111
126
}
112
127
if (! analyzeOnly) {
@@ -160,8 +175,7 @@ class Compiler extends leg.Compiler {
160
175
161
176
// TODO(johnniwinther): Merge better with [translateDartUri] when
162
177
// [scanBuiltinLibrary] is removed.
163
- String lookupLibraryPath (String dartLibraryName) {
164
- LibraryInfo info = lookupLibraryInfo (dartLibraryName);
178
+ String lookupLibraryPath (LibraryInfo info) {
165
179
if (info == null ) return null ;
166
180
if (! info.isDart2jsLibrary) return null ;
167
181
if (! allowedLibraryCategories.contains (info.category)) return null ;
@@ -225,6 +239,7 @@ class Compiler extends leg.Compiler {
225
239
}
226
240
227
241
Uri resourceUri = translateUri (node, readableUri);
242
+ if (resourceUri == null ) return synthesizeScript (node, readableUri);
228
243
if (resourceUri.scheme == 'dart-ext' ) {
229
244
if (! allowNativeExtensions) {
230
245
withCurrentElement (element, () {
@@ -260,12 +275,11 @@ class Compiler extends leg.Compiler {
260
275
}
261
276
262
277
Future <leg.Script > synthesizeScript (leg.Spannable node, Uri readableUri) {
263
- Uri resourceUri = translateUri (node, readableUri);
264
278
return new Future .value (
265
279
new leg.Script (
266
- readableUri, resourceUri ,
280
+ readableUri, readableUri ,
267
281
new StringSourceFile .fromUri (
268
- resourceUri ,
282
+ readableUri ,
269
283
"// Synthetic source file generated for '$readableUri '." ),
270
284
isSynthesized: true ));
271
285
}
@@ -285,7 +299,7 @@ class Compiler extends leg.Compiler {
285
299
Uri translateDartUri (elements.LibraryElement importingLibrary,
286
300
Uri resolvedUri, tree.Node node) {
287
301
LibraryInfo libraryInfo = lookupLibraryInfo (resolvedUri.path);
288
- String path = lookupLibraryPath (resolvedUri.path );
302
+ String path = lookupLibraryPath (libraryInfo );
289
303
if (libraryInfo != null &&
290
304
libraryInfo.category == "Internal" ) {
291
305
bool allowInternalLibraryAccess = false ;
@@ -333,25 +347,66 @@ class Compiler extends leg.Compiler {
333
347
}
334
348
335
349
Uri translatePackageUri (leg.Spannable node, Uri uri) {
336
- return packageRoot.resolve (uri.path);
350
+ try {
351
+ checkValidPackageUri (uri);
352
+ } on ArgumentError catch (e) {
353
+ reportError (
354
+ node,
355
+ leg.MessageKind .INVALID_PACKAGE_URI ,
356
+ {'uri' : uri, 'exception' : e.message});
357
+ return null ;
358
+ }
359
+ return packages.resolve (uri,
360
+ notFound: (Uri notFound) {
361
+ reportError (
362
+ node,
363
+ leg.MessageKind .LIBRARY_NOT_FOUND ,
364
+ {'resolvedUri' : uri}
365
+ );
366
+ return null ;
367
+ });
368
+ }
369
+
370
+ Future setupPackages (Uri uri) async {
371
+ if (packageRoot != null ) {
372
+ // Use "non-file" packages because the file version requires a [Directory]
373
+ // and we can't depend on 'dart:io' classes.
374
+ packages = new NonFilePackagesDirectoryPackages (packageRoot);
375
+ } else if (packageConfig != null ) {
376
+ var packageConfigContents = await provider (packageConfig);
377
+ if (packageConfigContents is String ) {
378
+ packageConfigContents = UTF8 .encode (packageConfigContents);
379
+ }
380
+ packages =
381
+ new MapPackages (pkgs.parse (packageConfigContents, packageConfig));
382
+ } else {
383
+ if (packagesDiscoveryProvider == null ) {
384
+ packages = Packages .noPackages;
385
+ } else {
386
+ packages = await callUserPackagesDiscovery (uri);
387
+ }
388
+ }
337
389
}
338
390
339
- Future <bool > run (Uri uri) {
391
+ Future <bool > run (Uri uri) async {
340
392
log ('Allowed library categories: $allowedLibraryCategories ' );
341
- return super .run (uri).then ((bool success) {
342
- int cumulated = 0 ;
343
- for (final task in tasks) {
344
- int elapsed = task.timing;
345
- if (elapsed != 0 ) {
346
- cumulated += elapsed;
347
- log ('${task .name } took ${elapsed }msec' );
348
- }
393
+
394
+ await setupPackages (uri);
395
+ assert (packages != null );
396
+
397
+ bool success = await super .run (uri);
398
+ int cumulated = 0 ;
399
+ for (final task in tasks) {
400
+ int elapsed = task.timing;
401
+ if (elapsed != 0 ) {
402
+ cumulated += elapsed;
403
+ log ('${task .name } took ${elapsed }msec' );
349
404
}
350
- int total = totalCompileTime.elapsedMilliseconds;
351
- log ( 'Total compile-time ${ total }msec;'
352
- ' unaccounted ${total - cumulated }msec' );
353
- return success ;
354
- }) ;
405
+ }
406
+ int total = totalCompileTime.elapsedMilliseconds;
407
+ log ( 'Total compile-time ${total }msec;'
408
+ ' unaccounted ${ total - cumulated }msec' ) ;
409
+ return success ;
355
410
}
356
411
357
412
void reportDiagnostic (leg.Spannable node,
@@ -368,8 +423,7 @@ class Compiler extends leg.Compiler {
368
423
if (span == null || span.uri == null ) {
369
424
callUserHandler (null , null , null , '$message ' , kind);
370
425
} else {
371
- callUserHandler (
372
- translateUri (null , span.uri), span.begin, span.end, '$message ' , kind);
426
+ callUserHandler (span.uri, span.begin, span.end, '$message ' , kind);
373
427
}
374
428
}
375
429
@@ -400,6 +454,16 @@ class Compiler extends leg.Compiler {
400
454
}
401
455
}
402
456
457
+ Future <Packages > callUserPackagesDiscovery (Uri uri) {
458
+ try {
459
+ return userPackagesDiscoveryTask.measure (
460
+ () => packagesDiscoveryProvider (uri));
461
+ } catch (ex, s) {
462
+ diagnoseCrashInUserCode ('Uncaught exception in package discovery' , ex, s);
463
+ rethrow ;
464
+ }
465
+ }
466
+
403
467
void diagnoseCrashInUserCode (String message, exception, stackTrace) {
404
468
hasCrashed = true ;
405
469
print ('$message : ${tryToString (exception )}' );
0 commit comments