Skip to content

Commit 23736d3

Browse files
committed
Version 1.11.0-dev.5.2
Cherry-pick fee40ca into dev Cherry-pick 63681d5 into dev
2 parents 1b39e02 + 451d94e commit 23736d3

File tree

15 files changed

+195
-66
lines changed

15 files changed

+195
-66
lines changed

DEPS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ vars = {
7676
"oauth2_rev": "@1bff41f4d54505c36f2d1a001b83b8b745c452f5",
7777
"observe_rev": "@eee2b8ec34236fa46982575fbccff84f61202ac6",
7878
"observatory_pub_packages_rev": "@45565",
79-
"package_config_tag": "@0.0.2+4",
79+
"package_config_tag": "@0.0.3+1",
8080
"path_rev": "@93b3e2aa1db0ac0c8bab9d341588d77acda60320",
8181
"petitparser_rev" : "@37878",
8282
"ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",

pkg/compiler/lib/compiler.dart

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
library compiler;
66

77
import 'dart:async';
8+
import 'package:package_config/packages.dart';
89
import 'src/apiimpl.dart';
910

1011
// Unless explicitly allowed, passing [:null:] for any argument to the
@@ -58,13 +59,19 @@ typedef EventSink<String> CompilerOutputProvider(String name,
5859
* [:null:]. If [uri] is not [:null:], neither are [begin] and
5960
* [end]. [uri] indicates the compilation unit from where the
6061
* diagnostic originates. [begin] and [end] are zero-based character
61-
* offsets from the beginning of the compilaton unit. [message] is the
62+
* offsets from the beginning of the compilation unit. [message] is the
6263
* diagnostic message, and [kind] indicates indicates what kind of
6364
* diagnostic it is.
6465
*/
6566
typedef void DiagnosticHandler(Uri uri, int begin, int end,
6667
String message, Diagnostic kind);
6768

69+
/**
70+
* Provides a package lookup mechanism in the case that no package root or
71+
* package resolution configuration file are explicitly specified.
72+
*/
73+
typedef Future<Packages> PackagesDiscoveryProvider(Uri uri);
74+
6875
/// Information resulting from the compilation.
6976
class CompilationResult {
7077
/// `true` if the compilation succeeded, that is, compilation didn't fail due
@@ -103,7 +110,9 @@ Future<CompilationResult> compile(
103110
DiagnosticHandler handler,
104111
[List<String> options = const [],
105112
CompilerOutputProvider outputProvider,
106-
Map<String, dynamic> environment = const {}]) {
113+
Map<String, dynamic> environment = const {},
114+
Uri packageConfig,
115+
PackagesDiscoveryProvider packagesDiscoveryProvider]) {
107116
if (!libraryRoot.path.endsWith("/")) {
108117
throw new ArgumentError("libraryRoot must end with a /");
109118
}
@@ -118,7 +127,9 @@ Future<CompilationResult> compile(
118127
libraryRoot,
119128
packageRoot,
120129
options,
121-
environment);
130+
environment,
131+
packageConfig,
132+
packagesDiscoveryProvider);
122133
return compiler.run(script).then((bool success) {
123134
return new CompilationResult(compiler, isSuccess: success);
124135
});

pkg/compiler/lib/src/apiimpl.dart

Lines changed: 91 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
library leg_apiimpl;
66

77
import 'dart:async';
8+
import 'dart:convert';
89

910
import '../compiler.dart' as api;
1011
import 'dart2jslib.dart' as leg;
@@ -13,6 +14,11 @@ import 'elements/elements.dart' as elements;
1314
import 'package:_internal/libraries.dart' hide LIBRARIES;
1415
import 'package:_internal/libraries.dart' as library_info show LIBRARIES;
1516
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;
1622

1723
const bool forceIncrementalSupport =
1824
const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT');
@@ -21,22 +27,28 @@ class Compiler extends leg.Compiler {
2127
api.CompilerInputProvider provider;
2228
api.DiagnosticHandler handler;
2329
final Uri libraryRoot;
30+
final Uri packageConfig;
2431
final Uri packageRoot;
32+
final api.PackagesDiscoveryProvider packagesDiscoveryProvider;
33+
Packages packages;
2534
List<String> options;
2635
Map<String, dynamic> environment;
2736
bool mockableLibraryUsed = false;
2837
final Set<String> allowedLibraryCategories;
2938

3039
leg.GenericTask userHandlerTask;
3140
leg.GenericTask userProviderTask;
41+
leg.GenericTask userPackagesDiscoveryTask;
3242

3343
Compiler(this.provider,
3444
api.CompilerOutputProvider outputProvider,
3545
this.handler,
3646
this.libraryRoot,
3747
this.packageRoot,
3848
List<String> options,
39-
this.environment)
49+
this.environment,
50+
[this.packageConfig,
51+
this.packagesDiscoveryProvider])
4052
: this.options = options,
4153
this.allowedLibraryCategories = getAllowedLibraryCategories(options),
4254
super(
@@ -95,17 +107,20 @@ class Compiler extends leg.Compiler {
95107
tasks.addAll([
96108
userHandlerTask = new leg.GenericTask('Diagnostic handler', this),
97109
userProviderTask = new leg.GenericTask('Input provider', this),
110+
userPackagesDiscoveryTask =
111+
new leg.GenericTask('Package discovery', this),
98112
]);
99113
if (libraryRoot == null) {
100114
throw new ArgumentError("[libraryRoot] is null.");
101115
}
102116
if (!libraryRoot.path.endsWith("/")) {
103117
throw new ArgumentError("[libraryRoot] must end with a /.");
104118
}
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.");
107122
}
108-
if (!packageRoot.path.endsWith("/")) {
123+
if (packageRoot != null && !packageRoot.path.endsWith("/")) {
109124
throw new ArgumentError("[packageRoot] must end with a /.");
110125
}
111126
if (!analyzeOnly) {
@@ -159,8 +174,7 @@ class Compiler extends leg.Compiler {
159174

160175
// TODO(johnniwinther): Merge better with [translateDartUri] when
161176
// [scanBuiltinLibrary] is removed.
162-
String lookupLibraryPath(String dartLibraryName) {
163-
LibraryInfo info = lookupLibraryInfo(dartLibraryName);
177+
String lookupLibraryPath(LibraryInfo info) {
164178
if (info == null) return null;
165179
if (!info.isDart2jsLibrary) return null;
166180
if (!allowedLibraryCategories.contains(info.category)) return null;
@@ -224,6 +238,7 @@ class Compiler extends leg.Compiler {
224238
}
225239

226240
Uri resourceUri = translateUri(node, readableUri);
241+
if (resourceUri == null) return synthesizeScript(node, readableUri);
227242
if (resourceUri.scheme == 'dart-ext') {
228243
if (!allowNativeExtensions) {
229244
withCurrentElement(element, () {
@@ -259,12 +274,11 @@ class Compiler extends leg.Compiler {
259274
}
260275

261276
Future<leg.Script> synthesizeScript(leg.Spannable node, Uri readableUri) {
262-
Uri resourceUri = translateUri(node, readableUri);
263277
return new Future.value(
264278
new leg.Script(
265-
readableUri, resourceUri,
279+
readableUri, readableUri,
266280
new StringSourceFile.fromUri(
267-
resourceUri,
281+
readableUri,
268282
"// Synthetic source file generated for '$readableUri'."),
269283
isSynthesized: true));
270284
}
@@ -284,7 +298,7 @@ class Compiler extends leg.Compiler {
284298
Uri translateDartUri(elements.LibraryElement importingLibrary,
285299
Uri resolvedUri, tree.Node node) {
286300
LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path);
287-
String path = lookupLibraryPath(resolvedUri.path);
301+
String path = lookupLibraryPath(libraryInfo);
288302
if (libraryInfo != null &&
289303
libraryInfo.category == "Internal") {
290304
bool allowInternalLibraryAccess = false;
@@ -332,25 +346,66 @@ class Compiler extends leg.Compiler {
332346
}
333347

334348
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+
}
336388
}
337389

338-
Future<bool> run(Uri uri) {
390+
Future<bool> run(Uri uri) async {
339391
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');
348403
}
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;
354409
}
355410

356411
void reportDiagnostic(leg.Spannable node,
@@ -367,8 +422,7 @@ class Compiler extends leg.Compiler {
367422
if (span == null || span.uri == null) {
368423
callUserHandler(null, null, null, '$message', kind);
369424
} else {
370-
callUserHandler(
371-
translateUri(null, span.uri), span.begin, span.end, '$message', kind);
425+
callUserHandler(span.uri, span.begin, span.end, '$message', kind);
372426
}
373427
}
374428

@@ -399,6 +453,16 @@ class Compiler extends leg.Compiler {
399453
}
400454
}
401455

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+
402466
void diagnoseCrashInUserCode(String message, exception, stackTrace) {
403467
hasCrashed = true;
404468
print('$message: ${tryToString(exception)}');

pkg/compiler/lib/src/dart2js.dart

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import 'util/uri_extras.dart';
1919
import 'util/util.dart' show stackTraceFilePrefix;
2020
import 'util/command_line.dart';
2121
import 'package:_internal/libraries.dart';
22+
import 'package:package_config/discovery.dart' show findPackages;
2223

2324
const String LIBRARY_ROOT = '../../../../../sdk';
2425
const String OUTPUT_LANGUAGE_DART = 'Dart';
@@ -105,6 +106,7 @@ Future<api.CompilationResult> compile(List<String> argv) {
105106
Uri libraryRoot = currentDirectory;
106107
Uri out = currentDirectory.resolve('out.js');
107108
Uri sourceMapOut = currentDirectory.resolve('out.js.map');
109+
Uri packageConfig = null;
108110
Uri packageRoot = null;
109111
List<String> options = new List<String>();
110112
bool explicitOut = false;
@@ -140,6 +142,10 @@ Future<api.CompilationResult> compile(List<String> argv) {
140142
packageRoot = currentDirectory.resolve(extractPath(argument));
141143
}
142144

145+
setPackageConfig(String argument) {
146+
packageConfig = currentDirectory.resolve(extractPath(argument));
147+
}
148+
143149
setOutput(Iterator<String> arguments) {
144150
optionsImplyCompilation.add(arguments.current);
145151
String path;
@@ -329,6 +335,7 @@ Future<api.CompilationResult> compile(List<String> argv) {
329335
(_) => setTrustPrimitives(
330336
'--trust-primitives')),
331337
new OptionHandler(r'--help|/\?|/h', (_) => wantHelp = true),
338+
new OptionHandler('--packages=.+', setPackageConfig),
332339
new OptionHandler('--package-root=.+|-p.+', setPackageRoot),
333340
new OptionHandler('--analyze-all', setAnalyzeAll),
334341
new OptionHandler('--analyze-only', setAnalyzeOnly),
@@ -403,9 +410,8 @@ Future<api.CompilationResult> compile(List<String> argv) {
403410
"checked mode.");
404411
}
405412

406-
Uri uri = currentDirectory.resolve(arguments[0]);
407-
if (packageRoot == null) {
408-
packageRoot = uri.resolve('./packages/');
413+
if (packageRoot != null && packageConfig != null) {
414+
helpAndFail("Cannot specify both '--package-root' and '--packages.");
409415
}
410416

411417
if ((analyzeOnly || analyzeAll) && !optionsImplyCompilation.isEmpty) {
@@ -431,8 +437,6 @@ Future<api.CompilationResult> compile(List<String> argv) {
431437
"combination with the '--output-type=dart' option.");
432438
}
433439

434-
diagnosticHandler.info('Package root is $packageRoot');
435-
436440
options.add('--out=$out');
437441
options.add('--source-map=$sourceMapOut');
438442

@@ -467,9 +471,10 @@ Future<api.CompilationResult> compile(List<String> argv) {
467471
return result;
468472
}
469473

470-
return compileFunc(uri, libraryRoot, packageRoot,
471-
inputProvider, diagnosticHandler,
472-
options, outputProvider, environment)
474+
Uri uri = currentDirectory.resolve(arguments[0]);
475+
return compileFunc(uri, libraryRoot, packageRoot, inputProvider,
476+
diagnosticHandler, options, outputProvider, environment,
477+
packageConfig, findPackages)
473478
.then(compilationDone);
474479
}
475480

@@ -551,7 +556,12 @@ Supported options:
551556
Display version information.
552557
553558
-p<path>, --package-root=<path>
554-
Where to find packages, that is, "package:..." imports.
559+
Where to find packages, that is, "package:..." imports. This option cannot
560+
be used with --packages.
561+
562+
--packages=<path>
563+
Path to the package resolution configuration file, which supplies a mapping
564+
of package names to paths. This option cannot be used with --package-root.
555565
556566
--analyze-all
557567
Analyze all code. Without this option, the compiler only analyzes

pkg/compiler/lib/src/mirrors/analyze.dart

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ Future<MirrorSystem> analyze(List<Uri> libraries,
2626
Uri packageRoot,
2727
api.CompilerInputProvider inputProvider,
2828
api.DiagnosticHandler diagnosticHandler,
29-
[List<String> options = const <String>[]]) {
29+
[List<String> options = const <String>[],
30+
Uri packageConfig,
31+
api.PackagesDiscoveryProvider findPackages]) {
3032
if (!libraryRoot.path.endsWith("/")) {
3133
throw new ArgumentError("libraryRoot must end with a /");
3234
}
@@ -54,9 +56,12 @@ Future<MirrorSystem> analyze(List<Uri> libraries,
5456
Compiler compiler = new apiimpl.Compiler(inputProvider,
5557
null,
5658
internalDiagnosticHandler,
57-
libraryRoot, packageRoot,
59+
libraryRoot,
60+
packageRoot,
5861
options,
59-
const {});
62+
const {},
63+
packageConfig,
64+
findPackages);
6065
compiler.librariesToAnalyzeWhenRun = libraries;
6166
return compiler.run(null).then((bool success) {
6267
if (success && !compilationFailed) {

0 commit comments

Comments
 (0)