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

Side by Side Diff: pkg/compiler/lib/src/apiimpl.dart

Issue 1408253006: Introduce "platform configurations" to replace categories and libraries.dart. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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
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 library leg_apiimpl; 5 library leg_apiimpl;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:convert'; 8 import 'dart:convert';
9 9
10 import 'package:package_config/packages.dart'; 10 import 'package:package_config/packages.dart';
11 import 'package:package_config/packages_file.dart' as pkgs; 11 import 'package:package_config/packages_file.dart' as pkgs;
12 import 'package:package_config/src/packages_impl.dart' show 12 import 'package:package_config/src/packages_impl.dart' show
13 MapPackages, 13 MapPackages,
14 NonFilePackagesDirectoryPackages; 14 NonFilePackagesDirectoryPackages;
15 import 'package:package_config/src/util.dart' show 15 import 'package:package_config/src/util.dart' show
16 checkValidPackageUri; 16 checkValidPackageUri;
17 import 'package:sdk_library_metadata/libraries.dart' as library_info;
18 17
19 import '../compiler_new.dart' as api; 18 import '../compiler_new.dart' as api;
20 import 'commandline_options.dart'; 19 import 'commandline_options.dart';
21 import 'common.dart'; 20 import 'common.dart';
22 import 'common/tasks.dart' show 21 import 'common/tasks.dart' show
23 GenericTask; 22 GenericTask;
24 import 'compiler.dart'; 23 import 'compiler.dart';
25 import 'diagnostics/diagnostic_listener.dart' show 24 import 'diagnostics/diagnostic_listener.dart' show
26 DiagnosticOptions; 25 DiagnosticOptions;
27 import 'diagnostics/messages.dart' show 26 import 'diagnostics/messages.dart' show
28 Message; 27 Message;
29 import 'elements/elements.dart' as elements; 28 import 'elements/elements.dart' as elements;
30 import 'io/source_file.dart'; 29 import 'io/source_file.dart';
30 import 'platform_configuration.dart' as platform_configuration;
31 import 'script.dart'; 31 import 'script.dart';
32 32
33 const bool forceIncrementalSupport = 33 const bool forceIncrementalSupport =
34 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); 34 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT');
35 35
36 /// Locations of the platform descriptor files relative to the library root.
37 const String _clientPlatform = "lib/dart_client.platform";
38 const String _serverPlatform = "lib/dart_server.platform";
39 const String _sharedPlatform = "lib/dart_shared.platform";
40 const String _dart2dartPlatform = "lib/dart2dart.platform";
41
36 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the 42 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the
37 /// sources. 43 /// sources.
38 class CompilerImpl extends Compiler { 44 class CompilerImpl extends Compiler {
39 api.CompilerInput provider; 45 api.CompilerInput provider;
40 api.CompilerDiagnostics handler; 46 api.CompilerDiagnostics handler;
41 final Uri libraryRoot; 47 final Uri platformConfigUri;
42 final Uri packageConfig; 48 final Uri packageConfig;
43 final Uri packageRoot; 49 final Uri packageRoot;
44 final api.PackagesDiscoveryProvider packagesDiscoveryProvider; 50 final api.PackagesDiscoveryProvider packagesDiscoveryProvider;
45 Packages packages; 51 Packages packages;
46 List<String> options; 52 List<String> options;
47 Map<String, dynamic> environment; 53 Map<String, dynamic> environment;
48 bool mockableLibraryUsed = false; 54 bool mockableLibraryUsed = false;
49 final Set<library_info.Category> allowedLibraryCategories; 55
56 /// A mapping of the dart: library-names to their location.
57 ///
58 /// Initialized in [setupSdk()].
Johnni Winther 2015/10/30 10:38:39 Remove ()
sigurdm 2015/10/30 11:38:27 Done.
59 Map<String, Uri> sdkLibraries;
50 60
51 GenericTask userHandlerTask; 61 GenericTask userHandlerTask;
52 GenericTask userProviderTask; 62 GenericTask userProviderTask;
53 GenericTask userPackagesDiscoveryTask; 63 GenericTask userPackagesDiscoveryTask;
54 64
65 Uri get libraryRoot => platformConfigUri.resolve(".");
66
55 CompilerImpl(this.provider, 67 CompilerImpl(this.provider,
56 api.CompilerOutput outputProvider, 68 api.CompilerOutput outputProvider,
57 this.handler, 69 this.handler,
58 this.libraryRoot, 70 Uri libraryRoot,
59 this.packageRoot, 71 this.packageRoot,
60 List<String> options, 72 List<String> options,
61 this.environment, 73 this.environment,
62 [this.packageConfig, 74 [this.packageConfig,
63 this.packagesDiscoveryProvider]) 75 this.packagesDiscoveryProvider])
64 : this.options = options, 76 : this.options = options,
65 this.allowedLibraryCategories = getAllowedLibraryCategories(options), 77 this.platformConfigUri = resolvePlatformConfig(libraryRoot, options),
66 super( 78 super(
67 outputProvider: outputProvider, 79 outputProvider: outputProvider,
68 enableTypeAssertions: hasOption(options, Flags.enableCheckedMode), 80 enableTypeAssertions: hasOption(options, Flags.enableCheckedMode),
69 enableUserAssertions: hasOption(options, Flags.enableCheckedMode), 81 enableUserAssertions: hasOption(options, Flags.enableCheckedMode),
70 trustTypeAnnotations: 82 trustTypeAnnotations:
71 hasOption(options, Flags.trustTypeAnnotations), 83 hasOption(options, Flags.trustTypeAnnotations),
72 trustPrimitives: 84 trustPrimitives:
73 hasOption(options, Flags.trustPrimitives), 85 hasOption(options, Flags.trustPrimitives),
74 enableMinification: hasOption(options, Flags.minify), 86 enableMinification: hasOption(options, Flags.minify),
75 useFrequencyNamer: 87 useFrequencyNamer:
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 // CSV: Comma separated values. 180 // CSV: Comma separated values.
169 static List<String> extractCsvOption(List<String> options, String prefix) { 181 static List<String> extractCsvOption(List<String> options, String prefix) {
170 for (String option in options) { 182 for (String option in options) {
171 if (option.startsWith(prefix)) { 183 if (option.startsWith(prefix)) {
172 return option.substring(prefix.length).split(','); 184 return option.substring(prefix.length).split(',');
173 } 185 }
174 } 186 }
175 return const <String>[]; 187 return const <String>[];
176 } 188 }
177 189
178 static Set<library_info.Category> getAllowedLibraryCategories( 190 static Uri resolvePlatformConfig(Uri libraryRoot,
179 List<String> options) { 191 List<String> options) {
Johnni Winther 2015/10/30 10:38:39 Indent to (
sigurdm 2015/10/30 11:38:27 Done.
180 Iterable<library_info.Category> categories = 192 String platformConfigPath =
181 extractCsvOption(options, '--categories=') 193 extractStringOption(options, "--platform-config=", null);
182 .map(library_info.parseCategory) 194 if (platformConfigPath != null) {
183 .where((x) => x != null); 195 return libraryRoot.resolve(platformConfigPath);
184 if (categories.isEmpty) { 196 } else if (hasOption(options, '--output-type=dart')) {
185 return new Set.from([library_info.Category.client]); 197 print("%%% ${libraryRoot.resolve(_dart2dartPlatform)}");
Johnni Winther 2015/10/30 10:38:39 Remove debug code. Maybe add as reporter.log(...)
sigurdm 2015/10/30 11:38:27 Removed
198 return libraryRoot.resolve(_dart2dartPlatform);
199 } else {
200 Iterable<String> categories = extractCsvOption(options, '--categories=');
201 if (categories.length == 0) {
202 return libraryRoot.resolve(_clientPlatform);
203 }
204 assert(categories.length <= 2);
205 if (categories.contains("Client")) {
206 if (categories.contains("Server")) {
207 return libraryRoot.resolve(_sharedPlatform);
208 }
209 return libraryRoot.resolve(_clientPlatform);
210 }
211 assert(categories.contains("Server"));
212 return libraryRoot.resolve(_serverPlatform);
186 } 213 }
187 return new Set.from(categories);
188 } 214 }
189 215
190 static bool hasOption(List<String> options, String option) { 216 static bool hasOption(List<String> options, String option) {
191 return options.indexOf(option) >= 0; 217 return options.indexOf(option) >= 0;
192 } 218 }
193 219
194 String lookupPatchPath(String dartLibraryName) {
195 library_info.LibraryInfo info = lookupLibraryInfo(dartLibraryName);
196 if (info == null) return null;
197 if (!info.isDart2jsLibrary) return null;
198 String path = info.dart2jsPatchPath;
199 if (path == null) return null;
200 return "lib/$path";
201 }
202
203 void log(message) { 220 void log(message) {
204 callUserHandler( 221 callUserHandler(
205 null, null, null, null, message, api.Diagnostic.VERBOSE_INFO); 222 null, null, null, null, message, api.Diagnostic.VERBOSE_INFO);
206 } 223 }
207 224
208 /// See [Compiler.translateResolvedUri]. 225 /// See [Compiler.translateResolvedUri].
209 Uri translateResolvedUri(elements.LibraryElement importingLibrary, 226 Uri translateResolvedUri(elements.LibraryElement importingLibrary,
210 Uri resolvedUri, Spannable spannable) { 227 Uri resolvedUri, Spannable spannable) {
211 if (resolvedUri.scheme == 'dart') { 228 if (resolvedUri.scheme == 'dart') {
212 return translateDartUri(importingLibrary, resolvedUri, spannable); 229 return translateDartUri(importingLibrary, resolvedUri, spannable);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 * See [LibraryLoader] for terminology on URIs. 314 * See [LibraryLoader] for terminology on URIs.
298 */ 315 */
299 Uri translateUri(Spannable node, Uri readableUri) { 316 Uri translateUri(Spannable node, Uri readableUri) {
300 switch (readableUri.scheme) { 317 switch (readableUri.scheme) {
301 case 'package': return translatePackageUri(node, readableUri); 318 case 'package': return translatePackageUri(node, readableUri);
302 default: return readableUri; 319 default: return readableUri;
303 } 320 }
304 } 321 }
305 322
306 /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative 323 /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative
307 /// to [libraryRoot] according to the information in [library_info.libraries]. 324 /// to [platformConfigUri] according to the information in the file at
325 /// [platformConfigUri].
308 /// 326 ///
309 /// Returns null and emits an error if the library could not be found or 327 /// Returns null and emits an error if the library could not be found or
310 /// imported into [importingLibrary]. 328 /// imported into [importingLibrary].
311 /// 329 ///
312 /// If [importingLibrary] is a platform or patch library all dart2js libraries 330 /// Internal libraries (whose name starts with '_') can be only resolved if
313 /// can be resolved. Otherwise only libraries with categories in 331 /// [importingLibrary] is a platform or patch library.
314 /// [allowedLibraryCategories] can be resolved.
315 Uri translateDartUri(elements.LibraryElement importingLibrary, 332 Uri translateDartUri(elements.LibraryElement importingLibrary,
316 Uri resolvedUri, Spannable spannable) { 333 Uri resolvedUri, Spannable spannable) {
317 334
318 library_info.LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path); 335 Uri location = lookupLibraryUri(resolvedUri.path);
319 336
320 bool allowInternalLibraryAccess = false; 337 if (location == null) {
321 if (importingLibrary != null) { 338 reporter.reportErrorMessage(
322 if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) { 339 spannable,
323 allowInternalLibraryAccess = true; 340 MessageKind.LIBRARY_NOT_FOUND,
324 } else if (importingLibrary.canonicalUri.path.contains( 341 {'resolvedUri': resolvedUri});
325 'sdk/tests/compiler/dart2js_native')) { 342 return null;
326 allowInternalLibraryAccess = true; 343 }
344
345 if (resolvedUri.path.startsWith('_') ) {
346 bool allowInternalLibraryAccess = false;
347 if (importingLibrary != null) {
348 if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) {
349 allowInternalLibraryAccess = true;
350 } else if (importingLibrary.canonicalUri.path.contains(
351 'sdk/tests/compiler/dart2js_native')) {
352 allowInternalLibraryAccess = true;
353 }
354 }
355
356 if (!allowInternalLibraryAccess) {
357 if (importingLibrary != null) {
358 reporter.reportErrorMessage(
359 spannable,
360 MessageKind.INTERNAL_LIBRARY_FROM,
361 {'resolvedUri': resolvedUri,
362 'importingUri': importingLibrary.canonicalUri});
363 } else {
364 reporter.reportErrorMessage(
365 spannable,
366 MessageKind.INTERNAL_LIBRARY,
367 {'resolvedUri': resolvedUri});
368 registerDisallowedLibraryUse(resolvedUri);
369 }
370 return null;
327 } 371 }
328 } 372 }
329 373
330 String computePath() { 374 if (location.scheme == "unsupported") {
331 if (libraryInfo == null) { 375 reporter.reportErrorMessage(
332 return null; 376 spannable,
333 } else if (!libraryInfo.isDart2jsLibrary) { 377 MessageKind.LIBRARY_NOT_SUPPORTED,
334 return null; 378 {'resolvedUri': resolvedUri});
335 } else { 379 registerDisallowedLibraryUse(resolvedUri);
336 if (libraryInfo.isInternal &&
337 !allowInternalLibraryAccess) {
338 if (importingLibrary != null) {
339 reporter.reportErrorMessage(
340 spannable,
341 MessageKind.INTERNAL_LIBRARY_FROM,
342 {'resolvedUri': resolvedUri,
343 'importingUri': importingLibrary.canonicalUri});
344 } else {
345 reporter.reportErrorMessage(
346 spannable,
347 MessageKind.INTERNAL_LIBRARY,
348 {'resolvedUri': resolvedUri});
349 registerDisallowedLibraryUse(resolvedUri);
350 }
351 return null;
352 } else if (!allowInternalLibraryAccess &&
353 !allowedLibraryCategories.any(libraryInfo.categories.contains)) {
354 registerDisallowedLibraryUse(resolvedUri);
355 // TODO(sigurdm): Currently we allow the sdk libraries to import
356 // libraries from any category. We might want to revisit this.
357 return null;
358 } else {
359 return (libraryInfo.dart2jsPath != null)
360 ? libraryInfo.dart2jsPath
361 : libraryInfo.path;
362 }
363 }
364 }
365
366 String path = computePath();
367
368 if (path == null) {
369 if (libraryInfo == null) {
370 reporter.reportErrorMessage(
371 spannable,
372 MessageKind.LIBRARY_NOT_FOUND,
373 {'resolvedUri': resolvedUri});
374 } else {
375 reporter.reportErrorMessage(
376 spannable,
377 MessageKind.LIBRARY_NOT_SUPPORTED,
378 {'resolvedUri': resolvedUri});
379 }
380 // TODO(johnniwinther): Support signaling the error through the returned
381 // value.
382 return null; 380 return null;
383 } 381 }
384 382
385 if (resolvedUri.path == 'html' || 383 if (resolvedUri.path == 'html' ||
386 resolvedUri.path == 'io') { 384 resolvedUri.path == 'io') {
387 // TODO(ahe): Get rid of mockableLibraryUsed when test.dart 385 // TODO(ahe): Get rid of mockableLibraryUsed when test.dart
388 // supports this use case better. 386 // supports this use case better.
389 mockableLibraryUsed = true; 387 mockableLibraryUsed = true;
390 } 388 }
391 return libraryRoot.resolve("lib/$path"); 389 return location;
392 }
393
394 Uri resolvePatchUri(String dartLibraryPath) {
395 String patchPath = lookupPatchPath(dartLibraryPath);
396 if (patchPath == null) return null;
397 return libraryRoot.resolve(patchPath);
398 } 390 }
399 391
400 Uri translatePackageUri(Spannable node, Uri uri) { 392 Uri translatePackageUri(Spannable node, Uri uri) {
401 try { 393 try {
402 checkValidPackageUri(uri); 394 checkValidPackageUri(uri);
403 } on ArgumentError catch (e) { 395 } on ArgumentError catch (e) {
404 reporter.reportErrorMessage( 396 reporter.reportErrorMessage(
405 node, 397 node,
406 MessageKind.INVALID_PACKAGE_URI, 398 MessageKind.INVALID_PACKAGE_URI,
407 {'uri': uri, 'exception': e.message}); 399 {'uri': uri, 'exception': e.message});
408 return null; 400 return null;
409 } 401 }
410 return packages.resolve(uri, 402 return packages.resolve(uri,
411 notFound: (Uri notFound) { 403 notFound: (Uri notFound) {
412 reporter.reportErrorMessage( 404 reporter.reportErrorMessage(
413 node, 405 node,
414 MessageKind.LIBRARY_NOT_FOUND, 406 MessageKind.LIBRARY_NOT_FOUND,
415 {'resolvedUri': uri}); 407 {'resolvedUri': uri});
416 return null; 408 return null;
417 }); 409 });
418 } 410 }
419 411
420 Future<elements.LibraryElement> analyzeUri( 412 Future<elements.LibraryElement> analyzeUri(
421 Uri uri, 413 Uri uri,
422 {bool skipLibraryWithPartOfTag: true}) { 414 {bool skipLibraryWithPartOfTag: true}) {
415 List<Future> setupFunctions = new List<Future>();
416 if (sdkLibraries == null) {
417 setupFunctions.add(setupSdk());
418 }
423 if (packages == null) { 419 if (packages == null) {
424 return setupPackages(uri).then((_) => super.analyzeUri(uri)); 420 setupFunctions.add(setupPackages(uri));
425 } 421 }
426 return super.analyzeUri( 422 return Future.wait(setupFunctions).then((_) => super.analyzeUri(uri));
427 uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag);
428 } 423 }
429 424
430 Future setupPackages(Uri uri) { 425 Future setupPackages(Uri uri) {
431 if (packageRoot != null) { 426 if (packageRoot != null) {
432 // Use "non-file" packages because the file version requires a [Directory] 427 // Use "non-file" packages because the file version requires a [Directory]
433 // and we can't depend on 'dart:io' classes. 428 // and we can't depend on 'dart:io' classes.
434 packages = new NonFilePackagesDirectoryPackages(packageRoot); 429 packages = new NonFilePackagesDirectoryPackages(packageRoot);
435 } else if (packageConfig != null) { 430 } else if (packageConfig != null) {
436 return callUserProvider(packageConfig).then((packageConfigContents) { 431 return callUserProvider(packageConfig).then((packageConfigContents) {
437 if (packageConfigContents is String) { 432 if (packageConfigContents is String) {
(...skipping 20 matching lines...) Expand all
458 packages = Packages.noPackages; 453 packages = Packages.noPackages;
459 } else { 454 } else {
460 return callUserPackagesDiscovery(uri).then((p) { 455 return callUserPackagesDiscovery(uri).then((p) {
461 packages = p; 456 packages = p;
462 }); 457 });
463 } 458 }
464 } 459 }
465 return new Future.value(); 460 return new Future.value();
466 } 461 }
467 462
463 Future<Null> setupSdk() {
464 if (sdkLibraries == null) {
465 return platform_configuration.load(platformConfigUri, provider)
466 .then((Map<String, Uri> mapping) {
467 sdkLibraries = mapping;
468 });
469 } else {
470 // The incremental compiler sets up the sdk before run.
471 // Therefore this will be called a second time.
472 return new Future.value(null);
473 }
474 }
475
468 Future<bool> run(Uri uri) { 476 Future<bool> run(Uri uri) {
469 log('Allowed library categories: $allowedLibraryCategories'); 477 log('Using platform configuration at ${platformConfigUri}');
470 478
471 return setupPackages(uri).then((_) { 479 return Future.wait([setupSdk(), setupPackages(uri)]).then((_) {
480 assert(sdkLibraries != null);
472 assert(packages != null); 481 assert(packages != null);
473 482
474 return super.run(uri).then((bool success) { 483 return super.run(uri).then((bool success) {
475 int cumulated = 0; 484 int cumulated = 0;
476 for (final task in tasks) { 485 for (final task in tasks) {
477 int elapsed = task.timing; 486 int elapsed = task.timing;
478 if (elapsed != 0) { 487 if (elapsed != 0) {
479 cumulated += elapsed; 488 cumulated += elapsed;
480 log('${task.name} took ${elapsed}msec'); 489 log('${task.name} took ${elapsed}msec');
481 for (String subtask in task.subtasks) { 490 for (String subtask in task.subtasks) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 Future<Packages> callUserPackagesDiscovery(Uri uri) { 561 Future<Packages> callUserPackagesDiscovery(Uri uri) {
553 try { 562 try {
554 return userPackagesDiscoveryTask.measure( 563 return userPackagesDiscoveryTask.measure(
555 () => packagesDiscoveryProvider(uri)); 564 () => packagesDiscoveryProvider(uri));
556 } catch (ex, s) { 565 } catch (ex, s) {
557 diagnoseCrashInUserCode('Uncaught exception in package discovery', ex, s); 566 diagnoseCrashInUserCode('Uncaught exception in package discovery', ex, s);
558 rethrow; 567 rethrow;
559 } 568 }
560 } 569 }
561 570
562
563 fromEnvironment(String name) => environment[name]; 571 fromEnvironment(String name) => environment[name];
564 572
565 library_info.LibraryInfo lookupLibraryInfo(String libraryName) { 573 Uri lookupLibraryUri(String libraryName) {
566 return library_info.libraries[libraryName]; 574 assert(invariant(NO_LOCATION_SPANNABLE,
575 sdkLibraries != null, message: "setupSdk() has not been run"));
576 return sdkLibraries[libraryName];
577 }
578
579 Uri resolvePatchUri(String libraryName) {
580 return backend.resolvePatchUri(libraryName, platformConfigUri);
567 } 581 }
568 } 582 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/common/backend_api.dart » ('j') | tests/compiler/dart2js/categories_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698