Index: pkg/front_end/lib/src/base/processed_options.dart |
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart |
index a42d2b54caa8c554bb705ee450a79a3a61a8ab64..6681e2dc929a2f1df49f63cff9a2f434bdd1793a 100644 |
--- a/pkg/front_end/lib/src/base/processed_options.dart |
+++ b/pkg/front_end/lib/src/base/processed_options.dart |
@@ -4,14 +4,18 @@ |
import 'dart:async'; |
+import 'package:kernel/target/targets.dart'; |
+import 'package:kernel/target/vm_fasta.dart'; |
import 'package:front_end/compiler_options.dart'; |
import 'package:front_end/file_system.dart'; |
import 'package:front_end/src/fasta/translate_uri.dart'; |
+import 'package:front_end/src/fasta/ticker.dart'; |
import 'package:front_end/src/base/performace_logger.dart'; |
import 'package:front_end/src/incremental/byte_store.dart'; |
import 'package:front_end/src/simple_error.dart'; |
import 'package:package_config/packages_file.dart' as package_config; |
-import 'package:kernel/kernel.dart' show Program, loadProgramFromBytes; |
+import 'package:kernel/kernel.dart' |
+ show Program, loadProgramFromBytes, CanonicalName; |
/// Wrapper around [CompilerOptions] which exposes the options in a form useful |
/// to the front end implementation. |
@@ -34,17 +38,40 @@ class ProcessedOptions { |
TranslateUri _uriTranslator; |
/// The SDK summary, or `null` if it has not been read yet. |
+ /// |
+ /// A summary, also referred to as "outline" internally, is a [Program] where |
+ /// all method bodies are left out. In essence, it contains just API |
+ /// signatures and constants. When strong-mode is enabled, the summary already |
+ /// includes inferred types. |
Program _sdkSummaryProgram; |
/// The summary for each uri in `options.inputSummaries`. |
+ /// |
+ /// A summary, also referred to as "outline" internally, is a [Program] where |
+ /// all method bodies are left out. In essence, it contains just API |
+ /// signatures and constants. When strong-mode is enabled, the summary already |
+ /// includes inferred types. |
List<Program> _inputSummariesPrograms; |
+ /// Other programs that are meant to be linked and compiled with the input |
+ /// sources. |
+ List<Program> _linkedDependencies; |
+ |
/// The location of the SDK, or `null` if the location hasn't been determined |
/// yet. |
Uri _sdkRoot; |
- |
Uri get sdkRoot => _sdkRoot ??= _normalizeSdkRoot(); |
+ Uri _sdkSummary; |
+ Uri get sdkSummary => _sdkSummary ??= _computeSdkSummaryUri(); |
+ |
+ Ticker _ticker; |
+ Ticker get ticker => _ticker ??= new Ticker(isVerbose: _raw.verbose); |
ahe
2017/07/05 13:29:39
The ticker should be created eagerly. Otherwise it
Siggi Cherem (dart-lang)
2017/07/05 18:42:08
Done.
|
+ |
+ bool get verbose => _raw.verbose; |
+ bool get verify => _raw.verify; |
+ bool get debugDump => _raw.debugDump; |
+ |
/// Initializes a [ProcessedOptions] object wrapping the given [rawOptions]. |
ProcessedOptions(CompilerOptions rawOptions) : this._raw = rawOptions; |
@@ -62,24 +89,25 @@ class ProcessedOptions { |
/// if an option is a path to a file, it checks that the file exists. |
Future<bool> validateOptions() async { |
var fs = _raw.fileSystem; |
- var root = _raw.sdkRoot; |
bool _report(String msg) { |
_raw.onError(new SimpleError(msg)); |
return false; |
} |
- if (root != null && !await fs.entityForUri(root).exists()) { |
- return _report("SDK root directory not found: ${_raw.sdkRoot}"); |
+ if (_raw.sdkRoot != null && !await fs.entityForUri(sdkRoot).exists()) { |
+ return _report("SDK root directory not found: ${sdkRoot}"); |
} |
- var summary = _raw.sdkSummary; |
+ var summary = sdkSummary; |
if (summary != null && !await fs.entityForUri(summary).exists()) { |
- return _report("SDK summary not found: ${_raw.sdkSummary}"); |
+ return _report("SDK summary not found: ${summary}"); |
} |
- // TODO(sigmund): add checks for options that are meant to be disjoint (like |
- // sdkRoot and sdkSummary). |
+ if (compileSdk && summary != null) { |
+ return _report( |
+ "The compileSdk and sdkSummary options are mutually exclusive"); |
+ } |
return true; |
} |
@@ -101,29 +129,51 @@ class ProcessedOptions { |
/// Whether to interpret Dart sources in strong-mode. |
bool get strongMode => _raw.strongMode; |
- /// Get an outline program that summarizes the SDK. |
- Future<Program> get sdkSummaryProgram async { |
+ Target _target; |
+ Target get target => _target ??= |
+ _raw.target ?? new VmFastaTarget(new TargetFlags(strongMode: strongMode)); |
+ |
+ /// Get an outline program that summarizes the SDK, if any. |
+ Future<Program> loadSdkSummary(CanonicalName nameRoot) async { |
ahe
2017/07/05 13:29:39
This doesn't feel like an option to me.
Siggi Cherem (dart-lang)
2017/07/05 18:42:09
Agree - I don't believe we want to put this separa
|
if (_sdkSummaryProgram == null) { |
- if (_raw.sdkSummary == null) return null; |
- _sdkSummaryProgram = await _loadProgram(_raw.sdkSummary); |
+ if (sdkSummary == null) return null; |
+ _sdkSummaryProgram = await loadProgram(sdkSummary, nameRoot); |
} |
return _sdkSummaryProgram; |
} |
/// Get the summary programs for each of the underlying `inputSummaries` |
/// provided via [CompilerOptions]. |
- Future<List<Program>> get inputSummariesPrograms async { |
+ Future<List<Program>> loadInputSummaries(CanonicalName nameRoot) async { |
ahe
2017/07/05 13:29:39
Ditto.
Siggi Cherem (dart-lang)
2017/07/05 18:42:09
Acknowledged.
|
if (_inputSummariesPrograms == null) { |
var uris = _raw.inputSummaries; |
if (uris == null || uris.isEmpty) return const <Program>[]; |
- _inputSummariesPrograms = await Future.wait(uris.map(_loadProgram)); |
+ _inputSummariesPrograms = <Program>[]; |
+ await Future.forEach(uris, (uri) async { |
+ _inputSummariesPrograms.add(await loadProgram(uri, nameRoot)); |
Paul Berry
2017/06/29 18:51:07
Previously, the use of Future.wait() would mean th
Siggi Cherem (dart-lang)
2017/06/30 04:12:02
It was initially deliberate, but I didn't need to
ahe
2017/07/05 13:29:39
We should throttle the number of concurrent operat
Siggi Cherem (dart-lang)
2017/07/05 18:42:08
Good to know. Added TODO for now.
|
+ }); |
} |
return _inputSummariesPrograms; |
} |
- Future<Program> _loadProgram(Uri uri) async { |
+ /// Load each of the [CompilerOptions.linkedDependencies] programs. |
+ Future<List<Program>> loadLinkDependencies(CanonicalName nameRoot) async { |
ahe
2017/07/05 13:29:39
Also doesn't seem like an option.
Siggi Cherem (dart-lang)
2017/07/05 18:42:08
Acknowledged.
|
+ if (_linkedDependencies == null) { |
+ var uris = _raw.linkedDependencies; |
+ if (uris == null || uris.isEmpty) return const <Program>[]; |
+ _linkedDependencies = <Program>[]; |
+ await Future.forEach(uris, (uri) async { |
+ _linkedDependencies.add(await loadProgram(uri, nameRoot)); |
Paul Berry
2017/06/29 18:51:07
Similar concern here.
Siggi Cherem (dart-lang)
2017/06/30 04:12:02
Done.
|
+ }); |
+ } |
+ return _linkedDependencies; |
+ } |
+ |
+ /// Helper to load a .dill file from [uri] using the existing [nameRoot]. |
+ Future<Program> loadProgram(Uri uri, CanonicalName nameRoot) async { |
var bytes = await fileSystem.entityForUri(uri).readAsBytes(); |
- return loadProgramFromBytes(bytes)..unbindCanonicalNames(); |
+ var result = loadProgramFromBytes(bytes, new Program(nameRoot: nameRoot)); |
Paul Berry
2017/06/29 18:51:07
Nit: why not just
return loadProgramFromBytes(...
Siggi Cherem (dart-lang)
2017/06/30 04:12:02
Thanks - I had an extra debugging step earlier and
|
+ return result; |
} |
/// Get the [TranslateUri] which resolves "package:" and "dart:" URIs. |
@@ -135,13 +185,19 @@ class ProcessedOptions { |
await _getPackages(); |
// TODO(scheglov) Load SDK libraries from whatever format we decide. |
// TODO(scheglov) Remove the field "_raw.dartLibraries". |
- _uriTranslator = new TranslateUri( |
- _packages, _raw.dartLibraries, const <String, List<Uri>>{}); |
- _uriTranslator.dartLibraries.addAll(_raw.dartLibraries); |
+ var libraries = _raw.dartLibraries ?? await _parseLibraries(); |
+ _uriTranslator = |
+ new TranslateUri(_packages, libraries, const <String, List<Uri>>{}); |
+ ticker.logMs("Read packages file"); |
} |
return _uriTranslator; |
} |
+ Future<Map<String, Uri>> _parseLibraries() async { |
+ Uri librariesJson = _raw.sdkRoot?.resolve("lib/libraries.json"); |
+ return await computeLibraries(fileSystem, librariesJson); |
+ } |
+ |
/// Get the package map which maps package names to URIs. |
/// |
/// This is an asynchronous getter since file system operations may be |
@@ -176,8 +232,19 @@ class ProcessedOptions { |
} |
var root = _raw.sdkRoot; |
if (!root.path.endsWith('/')) { |
- root = root.replace(path: _sdkRoot.path + '/'); |
+ root = root.replace(path: root.path + '/'); |
} |
return root; |
} |
+ |
+ /// Get or infer the location of the SDK summary. |
+ Uri _computeSdkSummaryUri() { |
+ if (_raw.sdkSummary != null) return _raw.sdkSummary; |
+ |
+ // Infer based on the sdkRoot, but only when `compileSdk` is false, |
+ // otherwise the default intent was to compile the sdk from sources and not |
+ // to load an sdk summary file. |
+ if (_raw.compileSdk) return null; |
+ return sdkRoot.resolve('outline.dill'); |
+ } |
} |