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

Side by Side Diff: pkg/front_end/lib/src/base/processed_options.dart

Issue 2953703002: Tweak public APIs and use them in patch_sdk, dart2js, and kernel-service (Closed)
Patch Set: Created 3 years, 5 months 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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 import 'dart:async'; 5 import 'dart:async';
6 6
7 import 'package:kernel/target/targets.dart';
8 import 'package:kernel/target/vm_fasta.dart';
7 import 'package:front_end/compiler_options.dart'; 9 import 'package:front_end/compiler_options.dart';
8 import 'package:front_end/file_system.dart'; 10 import 'package:front_end/file_system.dart';
9 import 'package:front_end/src/fasta/translate_uri.dart'; 11 import 'package:front_end/src/fasta/translate_uri.dart';
12 import 'package:front_end/src/fasta/ticker.dart';
10 import 'package:front_end/src/base/performace_logger.dart'; 13 import 'package:front_end/src/base/performace_logger.dart';
11 import 'package:front_end/src/incremental/byte_store.dart'; 14 import 'package:front_end/src/incremental/byte_store.dart';
12 import 'package:front_end/src/simple_error.dart'; 15 import 'package:front_end/src/simple_error.dart';
13 import 'package:package_config/packages_file.dart' as package_config; 16 import 'package:package_config/packages_file.dart' as package_config;
14 import 'package:kernel/kernel.dart' show Program, loadProgramFromBytes; 17 import 'package:kernel/kernel.dart'
18 show Program, loadProgramFromBytes, CanonicalName;
15 19
16 /// Wrapper around [CompilerOptions] which exposes the options in a form useful 20 /// Wrapper around [CompilerOptions] which exposes the options in a form useful
17 /// to the front end implementation. 21 /// to the front end implementation.
18 /// 22 ///
19 /// The intent is that the front end should immediately wrap any incoming 23 /// The intent is that the front end should immediately wrap any incoming
20 /// [CompilerOptions] object in this class before doing further processing, and 24 /// [CompilerOptions] object in this class before doing further processing, and
21 /// should thereafter access all options via the wrapper. This ensures that 25 /// should thereafter access all options via the wrapper. This ensures that
22 /// options are interpreted in a consistent way and that data derived from 26 /// options are interpreted in a consistent way and that data derived from
23 /// options is not unnecessarily recomputed. 27 /// options is not unnecessarily recomputed.
24 class ProcessedOptions { 28 class ProcessedOptions {
25 /// The raw [CompilerOptions] which this class wraps. 29 /// The raw [CompilerOptions] which this class wraps.
26 final CompilerOptions _raw; 30 final CompilerOptions _raw;
27 31
28 /// The package map derived from the options, or `null` if the package map has 32 /// The package map derived from the options, or `null` if the package map has
29 /// not been computed yet. 33 /// not been computed yet.
30 Map<String, Uri> _packages; 34 Map<String, Uri> _packages;
31 35
32 /// The object that knows how to resolve "package:" and "dart:" URIs, 36 /// The object that knows how to resolve "package:" and "dart:" URIs,
33 /// or `null` if it has not been computed yet. 37 /// or `null` if it has not been computed yet.
34 TranslateUri _uriTranslator; 38 TranslateUri _uriTranslator;
35 39
36 /// The SDK summary, or `null` if it has not been read yet. 40 /// The SDK summary, or `null` if it has not been read yet.
41 ///
42 /// A summary, also referred to as "outline" internally, is a [Program] where
43 /// all method bodies are left out. In essence, it contains just API
44 /// signatures and constants. When strong-mode is enabled, the summary already
45 /// includes inferred types.
37 Program _sdkSummaryProgram; 46 Program _sdkSummaryProgram;
38 47
39 /// The summary for each uri in `options.inputSummaries`. 48 /// The summary for each uri in `options.inputSummaries`.
49 ///
50 /// A summary, also referred to as "outline" internally, is a [Program] where
51 /// all method bodies are left out. In essence, it contains just API
52 /// signatures and constants. When strong-mode is enabled, the summary already
53 /// includes inferred types.
40 List<Program> _inputSummariesPrograms; 54 List<Program> _inputSummariesPrograms;
41 55
56 /// Other programs that are meant to be linked and compiled with the input
57 /// sources.
58 List<Program> _linkedDependencies;
59
42 /// The location of the SDK, or `null` if the location hasn't been determined 60 /// The location of the SDK, or `null` if the location hasn't been determined
43 /// yet. 61 /// yet.
44 Uri _sdkRoot; 62 Uri _sdkRoot;
63 Uri get sdkRoot => _sdkRoot ??= _normalizeSdkRoot();
45 64
46 Uri get sdkRoot => _sdkRoot ??= _normalizeSdkRoot(); 65 Uri _sdkSummary;
66 Uri get sdkSummary => _sdkSummary ??= _computeSdkSummaryUri();
67
68 Ticker _ticker;
69 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.
70
71 bool get verbose => _raw.verbose;
72 bool get verify => _raw.verify;
73 bool get debugDump => _raw.debugDump;
47 74
48 /// Initializes a [ProcessedOptions] object wrapping the given [rawOptions]. 75 /// Initializes a [ProcessedOptions] object wrapping the given [rawOptions].
49 ProcessedOptions(CompilerOptions rawOptions) : this._raw = rawOptions; 76 ProcessedOptions(CompilerOptions rawOptions) : this._raw = rawOptions;
50 77
51 /// The logger to report compilation progress. 78 /// The logger to report compilation progress.
52 PerformanceLog get logger { 79 PerformanceLog get logger {
53 return _raw.logger; 80 return _raw.logger;
54 } 81 }
55 82
56 /// The byte storage to get and put serialized data. 83 /// The byte storage to get and put serialized data.
57 ByteStore get byteStore { 84 ByteStore get byteStore {
58 return _raw.byteStore; 85 return _raw.byteStore;
59 } 86 }
60 87
61 /// Runs various validations checks on the input options. For instance, 88 /// Runs various validations checks on the input options. For instance,
62 /// if an option is a path to a file, it checks that the file exists. 89 /// if an option is a path to a file, it checks that the file exists.
63 Future<bool> validateOptions() async { 90 Future<bool> validateOptions() async {
64 var fs = _raw.fileSystem; 91 var fs = _raw.fileSystem;
65 var root = _raw.sdkRoot;
66 92
67 bool _report(String msg) { 93 bool _report(String msg) {
68 _raw.onError(new SimpleError(msg)); 94 _raw.onError(new SimpleError(msg));
69 return false; 95 return false;
70 } 96 }
71 97
72 if (root != null && !await fs.entityForUri(root).exists()) { 98 if (_raw.sdkRoot != null && !await fs.entityForUri(sdkRoot).exists()) {
73 return _report("SDK root directory not found: ${_raw.sdkRoot}"); 99 return _report("SDK root directory not found: ${sdkRoot}");
74 } 100 }
75 101
76 var summary = _raw.sdkSummary; 102 var summary = sdkSummary;
77 if (summary != null && !await fs.entityForUri(summary).exists()) { 103 if (summary != null && !await fs.entityForUri(summary).exists()) {
78 return _report("SDK summary not found: ${_raw.sdkSummary}"); 104 return _report("SDK summary not found: ${summary}");
79 } 105 }
80 106
81 // TODO(sigmund): add checks for options that are meant to be disjoint (like 107 if (compileSdk && summary != null) {
82 // sdkRoot and sdkSummary). 108 return _report(
109 "The compileSdk and sdkSummary options are mutually exclusive");
110 }
83 return true; 111 return true;
84 } 112 }
85 113
86 /// Determine whether to generate code for the SDK when compiling a 114 /// Determine whether to generate code for the SDK when compiling a
87 /// whole-program. 115 /// whole-program.
88 bool get compileSdk => _raw.compileSdk; 116 bool get compileSdk => _raw.compileSdk;
89 117
90 /// Get the [FileSystem] which should be used by the front end to access 118 /// Get the [FileSystem] which should be used by the front end to access
91 /// files. 119 /// files.
92 /// 120 ///
93 /// If the client supplied roots using [CompilerOptions.multiRoots], the 121 /// If the client supplied roots using [CompilerOptions.multiRoots], the
94 /// returned [FileSystem] will automatically perform the appropriate mapping. 122 /// returned [FileSystem] will automatically perform the appropriate mapping.
95 FileSystem get fileSystem { 123 FileSystem get fileSystem {
96 // TODO(paulberry): support multiRoots. 124 // TODO(paulberry): support multiRoots.
97 assert(_raw.multiRoots.isEmpty); 125 assert(_raw.multiRoots.isEmpty);
98 return _raw.fileSystem; 126 return _raw.fileSystem;
99 } 127 }
100 128
101 /// Whether to interpret Dart sources in strong-mode. 129 /// Whether to interpret Dart sources in strong-mode.
102 bool get strongMode => _raw.strongMode; 130 bool get strongMode => _raw.strongMode;
103 131
104 /// Get an outline program that summarizes the SDK. 132 Target _target;
105 Future<Program> get sdkSummaryProgram async { 133 Target get target => _target ??=
134 _raw.target ?? new VmFastaTarget(new TargetFlags(strongMode: strongMode));
135
136 /// Get an outline program that summarizes the SDK, if any.
137 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
106 if (_sdkSummaryProgram == null) { 138 if (_sdkSummaryProgram == null) {
107 if (_raw.sdkSummary == null) return null; 139 if (sdkSummary == null) return null;
108 _sdkSummaryProgram = await _loadProgram(_raw.sdkSummary); 140 _sdkSummaryProgram = await loadProgram(sdkSummary, nameRoot);
109 } 141 }
110 return _sdkSummaryProgram; 142 return _sdkSummaryProgram;
111 } 143 }
112 144
113 /// Get the summary programs for each of the underlying `inputSummaries` 145 /// Get the summary programs for each of the underlying `inputSummaries`
114 /// provided via [CompilerOptions]. 146 /// provided via [CompilerOptions].
115 Future<List<Program>> get inputSummariesPrograms async { 147 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.
116 if (_inputSummariesPrograms == null) { 148 if (_inputSummariesPrograms == null) {
117 var uris = _raw.inputSummaries; 149 var uris = _raw.inputSummaries;
118 if (uris == null || uris.isEmpty) return const <Program>[]; 150 if (uris == null || uris.isEmpty) return const <Program>[];
119 _inputSummariesPrograms = await Future.wait(uris.map(_loadProgram)); 151 _inputSummariesPrograms = <Program>[];
152 await Future.forEach(uris, (uri) async {
153 _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.
154 });
120 } 155 }
121 return _inputSummariesPrograms; 156 return _inputSummariesPrograms;
122 } 157 }
123 158
124 Future<Program> _loadProgram(Uri uri) async { 159 /// Load each of the [CompilerOptions.linkedDependencies] programs.
160 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.
161 if (_linkedDependencies == null) {
162 var uris = _raw.linkedDependencies;
163 if (uris == null || uris.isEmpty) return const <Program>[];
164 _linkedDependencies = <Program>[];
165 await Future.forEach(uris, (uri) async {
166 _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.
167 });
168 }
169 return _linkedDependencies;
170 }
171
172 /// Helper to load a .dill file from [uri] using the existing [nameRoot].
173 Future<Program> loadProgram(Uri uri, CanonicalName nameRoot) async {
125 var bytes = await fileSystem.entityForUri(uri).readAsBytes(); 174 var bytes = await fileSystem.entityForUri(uri).readAsBytes();
126 return loadProgramFromBytes(bytes)..unbindCanonicalNames(); 175 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
176 return result;
127 } 177 }
128 178
129 /// Get the [TranslateUri] which resolves "package:" and "dart:" URIs. 179 /// Get the [TranslateUri] which resolves "package:" and "dart:" URIs.
130 /// 180 ///
131 /// This is an asynchronous method since file system operations may be 181 /// This is an asynchronous method since file system operations may be
132 /// required to locate/read the packages file as well as SDK metadata. 182 /// required to locate/read the packages file as well as SDK metadata.
133 Future<TranslateUri> getUriTranslator() async { 183 Future<TranslateUri> getUriTranslator() async {
134 if (_uriTranslator == null) { 184 if (_uriTranslator == null) {
135 await _getPackages(); 185 await _getPackages();
136 // TODO(scheglov) Load SDK libraries from whatever format we decide. 186 // TODO(scheglov) Load SDK libraries from whatever format we decide.
137 // TODO(scheglov) Remove the field "_raw.dartLibraries". 187 // TODO(scheglov) Remove the field "_raw.dartLibraries".
138 _uriTranslator = new TranslateUri( 188 var libraries = _raw.dartLibraries ?? await _parseLibraries();
139 _packages, _raw.dartLibraries, const <String, List<Uri>>{}); 189 _uriTranslator =
140 _uriTranslator.dartLibraries.addAll(_raw.dartLibraries); 190 new TranslateUri(_packages, libraries, const <String, List<Uri>>{});
191 ticker.logMs("Read packages file");
141 } 192 }
142 return _uriTranslator; 193 return _uriTranslator;
143 } 194 }
144 195
196 Future<Map<String, Uri>> _parseLibraries() async {
197 Uri librariesJson = _raw.sdkRoot?.resolve("lib/libraries.json");
198 return await computeLibraries(fileSystem, librariesJson);
199 }
200
145 /// Get the package map which maps package names to URIs. 201 /// Get the package map which maps package names to URIs.
146 /// 202 ///
147 /// This is an asynchronous getter since file system operations may be 203 /// This is an asynchronous getter since file system operations may be
148 /// required to locate/read the packages file. 204 /// required to locate/read the packages file.
149 Future<Map<String, Uri>> _getPackages() async { 205 Future<Map<String, Uri>> _getPackages() async {
150 if (_packages == null) { 206 if (_packages == null) {
151 if (_raw.packagesFileUri == null) { 207 if (_raw.packagesFileUri == null) {
152 throw new UnimplementedError(); // TODO(paulberry): search for .packages 208 throw new UnimplementedError(); // TODO(paulberry): search for .packages
ahe 2017/07/05 13:29:39 Could we throw a string with information about wha
Siggi Cherem (dart-lang) 2017/07/05 18:42:08 Done, practically moved the TODO into the error me
153 } else if (_raw.packagesFileUri.path.isEmpty) { 209 } else if (_raw.packagesFileUri.path.isEmpty) {
154 _packages = {}; 210 _packages = {};
155 } else { 211 } else {
156 var contents = 212 var contents =
157 await fileSystem.entityForUri(_raw.packagesFileUri).readAsBytes(); 213 await fileSystem.entityForUri(_raw.packagesFileUri).readAsBytes();
158 _packages = package_config.parse(contents, _raw.packagesFileUri); 214 _packages = package_config.parse(contents, _raw.packagesFileUri);
159 } 215 }
160 } 216 }
161 return _packages; 217 return _packages;
162 } 218 }
163 219
164 /// Get the location of the SDK. 220 /// Get the location of the SDK.
165 /// 221 ///
166 /// This is an asynchronous getter since file system operations may be 222 /// This is an asynchronous getter since file system operations may be
ahe 2017/07/05 13:29:39 What is an asynchronous getter?
Siggi Cherem (dart-lang) 2017/07/05 18:42:09 Deleted comment, I believe long ago this used to b
167 /// required to locate the SDK. 223 /// required to locate the SDK.
168 Uri _normalizeSdkRoot() { 224 Uri _normalizeSdkRoot() {
169 // If an SDK summary location was provided, the SDK itself should not be 225 // If an SDK summary location was provided, the SDK itself should not be
170 // needed. 226 // needed.
171 assert(_raw.sdkSummary == null); 227 assert(_raw.sdkSummary == null);
172 if (_raw.sdkRoot == null) { 228 if (_raw.sdkRoot == null) {
173 // TODO(paulberry): implement the algorithm for finding the SDK 229 // TODO(paulberry): implement the algorithm for finding the SDK
174 // automagically. 230 // automagically.
175 throw new UnimplementedError(); 231 throw new UnimplementedError();
ahe 2017/07/05 13:29:39 Throw string about what isn't implemented?
Siggi Cherem (dart-lang) 2017/07/05 18:42:09 Done.
176 } 232 }
177 var root = _raw.sdkRoot; 233 var root = _raw.sdkRoot;
178 if (!root.path.endsWith('/')) { 234 if (!root.path.endsWith('/')) {
179 root = root.replace(path: _sdkRoot.path + '/'); 235 root = root.replace(path: root.path + '/');
180 } 236 }
181 return root; 237 return root;
182 } 238 }
239
240 /// Get or infer the location of the SDK summary.
241 Uri _computeSdkSummaryUri() {
242 if (_raw.sdkSummary != null) return _raw.sdkSummary;
243
244 // Infer based on the sdkRoot, but only when `compileSdk` is false,
245 // otherwise the default intent was to compile the sdk from sources and not
246 // to load an sdk summary file.
247 if (_raw.compileSdk) return null;
248 return sdkRoot.resolve('outline.dill');
249 }
183 } 250 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698