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