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

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

Issue 2982093003: Unifying compiler context (Closed)
Patch Set: revert change to kernel-service.dart 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:front_end/compilation_error.dart'; 7 import 'package:front_end/compilation_message.dart';
8 import 'package:front_end/compiler_options.dart'; 8 import 'package:front_end/compiler_options.dart';
9 import 'package:front_end/file_system.dart'; 9 import 'package:front_end/file_system.dart';
10 import 'package:front_end/src/base/performace_logger.dart'; 10 import 'package:front_end/src/base/performace_logger.dart';
11 import 'package:front_end/src/fasta/fasta_codes.dart'; 11 import 'package:front_end/src/fasta/fasta_codes.dart';
12 import 'package:front_end/src/fasta/problems.dart' show unimplemented;
13 import 'package:front_end/src/fasta/severity.dart';
12 import 'package:front_end/src/fasta/ticker.dart'; 14 import 'package:front_end/src/fasta/ticker.dart';
13 import 'package:front_end/src/fasta/uri_translator.dart'; 15 import 'package:front_end/src/fasta/uri_translator.dart';
14 import 'package:front_end/src/fasta/uri_translator_impl.dart'; 16 import 'package:front_end/src/fasta/uri_translator_impl.dart';
15 import 'package:front_end/src/fasta/problems.dart' show unimplemented;
16 import 'package:front_end/src/incremental/byte_store.dart'; 17 import 'package:front_end/src/incremental/byte_store.dart';
17 import 'package:front_end/src/multi_root_file_system.dart'; 18 import 'package:front_end/src/multi_root_file_system.dart';
18 import 'package:kernel/kernel.dart' 19 import 'package:kernel/kernel.dart'
19 show Program, loadProgramFromBytes, CanonicalName; 20 show Program, loadProgramFromBytes, CanonicalName;
20 import 'package:kernel/target/targets.dart'; 21 import 'package:kernel/target/targets.dart';
21 import 'package:kernel/target/vm_fasta.dart'; 22 import 'package:kernel/target/vm_fasta.dart';
22 import 'package:package_config/packages.dart' show Packages; 23 import 'package:package_config/packages.dart' show Packages;
23 import 'package:package_config/src/packages_impl.dart' 24 import 'package:package_config/src/packages_impl.dart'
24 show NonFilePackagesDirectoryPackages, MapPackages; 25 show NonFilePackagesDirectoryPackages, MapPackages;
25 import 'package:package_config/packages_file.dart' as package_config; 26 import 'package:package_config/packages_file.dart' as package_config;
26 import 'package:source_span/source_span.dart' show SourceSpan, SourceLocation; 27 import 'package:source_span/source_span.dart' show SourceSpan, SourceLocation;
28 import 'package:front_end/src/fasta/command_line_reporting.dart'
29 as command_line_reporting;
27 30
28 /// All options needed for the front end implementation. 31 /// All options needed for the front end implementation.
29 /// 32 ///
30 /// This includes: all of [CompilerOptions] in a form useful to the 33 /// This includes: all of [CompilerOptions] in a form useful to the
31 /// implementation, default values for options that were not provided, 34 /// implementation, default values for options that were not provided,
32 /// and information derived from how the compiler was invoked (like the 35 /// and information derived from how the compiler was invoked (like the
33 /// entry-points given to the compiler and whether a modular or whole-program 36 /// entry-points given to the compiler and whether a modular or whole-program
34 /// API was used). 37 /// API was used).
35 /// 38 ///
36 /// The intent is that the front end should immediately wrap any incoming 39 /// The intent is that the front end should immediately wrap any incoming
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 Ticker ticker; 84 Ticker ticker;
82 85
83 bool get verbose => _raw.verbose; 86 bool get verbose => _raw.verbose;
84 87
85 bool get verify => _raw.verify; 88 bool get verify => _raw.verify;
86 89
87 bool get debugDump => _raw.debugDump; 90 bool get debugDump => _raw.debugDump;
88 91
89 bool get setExitCodeOnProblem => _raw.setExitCodeOnProblem; 92 bool get setExitCodeOnProblem => _raw.setExitCodeOnProblem;
90 93
94 bool get embedSourceText => _raw.embedSourceText;
95
96 bool get throwOnErrors => _raw.throwOnErrors;
97
98 bool get throwOnWarnings => _raw.throwOnWarnings;
99
100 bool get throwOnNits => _raw.throwOnNits;
101
91 /// Like [CompilerOptions.chaseDependencies] but with the appropriate default 102 /// Like [CompilerOptions.chaseDependencies] but with the appropriate default
92 /// value filled in. 103 /// value filled in.
93 bool get chaseDependencies => _raw.chaseDependencies ?? !_modularApi; 104 bool get chaseDependencies => _raw.chaseDependencies ?? !_modularApi;
94 105
95 /// Whether the compiler was invoked with a modular API. 106 /// Whether the compiler was invoked with a modular API.
96 /// 107 ///
97 /// Used to determine the default behavior for [chaseDependencies]. 108 /// Used to determine the default behavior for [chaseDependencies].
98 final bool _modularApi; 109 final bool _modularApi;
99 110
100 /// The entry-points provided to the compiler. 111 /// The entry-points provided to the compiler.
101 final List<Uri> inputs; 112 final List<Uri> inputs;
102 113
114 /// The Uri where output is generated, may be null.
115 final Uri output;
116
103 /// Initializes a [ProcessedOptions] object wrapping the given [rawOptions]. 117 /// Initializes a [ProcessedOptions] object wrapping the given [rawOptions].
104 ProcessedOptions(CompilerOptions rawOptions, 118 ProcessedOptions(CompilerOptions rawOptions,
105 [this._modularApi = false, this.inputs = const []]) 119 [this._modularApi = false, this.inputs = const [], this.output])
106 : this._raw = rawOptions, 120 : this._raw = rawOptions,
121 // TODO(sigmund, ahe): create ticker even earlier or pass in a stopwatch
122 // collecting time since the start of the VM.
107 ticker = new Ticker(isVerbose: rawOptions.verbose); 123 ticker = new Ticker(isVerbose: rawOptions.verbose);
108 124
109 /// The logger to report compilation progress. 125 /// The logger to report compilation progress.
110 PerformanceLog get logger { 126 PerformanceLog get logger {
111 return _raw.logger; 127 return _raw.logger;
112 } 128 }
113 129
114 /// The byte storage to get and put serialized data. 130 /// The byte storage to get and put serialized data.
115 ByteStore get byteStore { 131 ByteStore get byteStore {
116 return _raw.byteStore; 132 return _raw.byteStore;
117 } 133 }
118 134
119 void reportMessage(LocatedMessage message) { 135 bool get _reportMessages => _raw.reportMessages ?? (_raw.onError == null);
120 _raw.onError(new _CompilationMessage(message)); 136
137 void report(LocatedMessage message, Severity severity) {
138 if (_raw.onError != null) {
139 _raw.onError(new _CompilationMessage(message, severity));
140 }
141
142 if (_reportMessages) command_line_reporting.report(message, severity);
121 } 143 }
122 144
123 void reportMessageWithoutLocation(Message message) => 145 void reportWithoutLocation(Message message, Severity severity) {
124 reportMessage(message.withLocation(null, -1)); 146 if (_raw.onError != null) {
147 _raw.onError(
148 new _CompilationMessage(message.withLocation(null, -1), severity));
149 }
150
151 if (_reportMessages) {
152 command_line_reporting.reportWithoutLocation(message, severity);
153 }
154 }
125 155
126 /// Runs various validations checks on the input options. For instance, 156 /// Runs various validations checks on the input options. For instance,
127 /// if an option is a path to a file, it checks that the file exists. 157 /// if an option is a path to a file, it checks that the file exists.
128 Future<bool> validateOptions() async { 158 Future<bool> validateOptions() async {
159 if (verbose) print(debugString());
160
129 if (inputs.isEmpty) { 161 if (inputs.isEmpty) {
130 reportMessageWithoutLocation(messageMissingInput); 162 reportWithoutLocation(messageMissingInput, Severity.error);
131 return false; 163 return false;
132 } 164 }
133 165
134 for (var source in inputs) { 166 for (var source in inputs) {
135 // Note: we don't translate Uris at this point because some of the 167 // Note: we don't translate Uris at this point because some of the
136 // validation further below must be done before we even construct an 168 // validation further below must be done before we even construct an
137 // UriTranslator 169 // UriTranslator
138 // TODO(sigmund): consider validating dart/packages uri right after we 170 // TODO(sigmund): consider validating dart/packages uri right after we
139 // build the uri translator. 171 // build the uri translator.
140 if (source.scheme != 'dart' && 172 if (source.scheme != 'dart' &&
141 source.scheme != 'packages' && 173 source.scheme != 'packages' &&
142 !await fileSystem.entityForUri(source).exists()) { 174 !await fileSystem.entityForUri(source).exists()) {
143 reportMessageWithoutLocation( 175 reportWithoutLocation(
144 templateInputFileNotFound.withArguments('$source')); 176 templateInputFileNotFound.withArguments('$source'), Severity.error);
145 return false; 177 return false;
146 } 178 }
147 } 179 }
148 180
149 if (_raw.sdkRoot != null && 181 if (_raw.sdkRoot != null &&
150 !await fileSystem.entityForUri(sdkRoot).exists()) { 182 !await fileSystem.entityForUri(sdkRoot).exists()) {
151 reportMessageWithoutLocation( 183 reportWithoutLocation(
152 templateSdkRootNotFound.withArguments('$sdkRoot')); 184 templateSdkRootNotFound.withArguments('$sdkRoot'), Severity.error);
153 return false; 185 return false;
154 } 186 }
155 187
156 var summary = sdkSummary; 188 var summary = sdkSummary;
157 if (summary != null && !await fileSystem.entityForUri(summary).exists()) { 189 if (summary != null && !await fileSystem.entityForUri(summary).exists()) {
158 reportMessageWithoutLocation( 190 reportWithoutLocation(
159 templateSdkSummaryNotFound.withArguments('$summary')); 191 templateSdkSummaryNotFound.withArguments('$summary'), Severity.error);
160 return false; 192 return false;
161 } 193 }
162 194
163 if (compileSdk && summary != null) { 195 if (compileSdk && summary != null) {
164 reportMessageWithoutLocation( 196 reportWithoutLocation(
165 templateInternalProblemUnsupported.withArguments( 197 templateInternalProblemUnsupported.withArguments(
166 "The compileSdk and sdkSummary options are mutually exclusive")); 198 "The compileSdk and sdkSummary options are mutually exclusive"),
199 Severity.internalProblem);
167 return false; 200 return false;
168 } 201 }
169 return true; 202 return true;
170 } 203 }
171 204
172 /// Determine whether to generate code for the SDK when compiling a 205 /// Determine whether to generate code for the SDK when compiling a
173 /// whole-program. 206 /// whole-program.
174 bool get compileSdk => _raw.compileSdk; 207 bool get compileSdk => _raw.compileSdk;
175 208
176 FileSystem _fileSystem; 209 FileSystem _fileSystem;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 Future<Map<String, Uri>> _parseDartLibraries() async { 289 Future<Map<String, Uri>> _parseDartLibraries() async {
257 Uri librariesJson = _raw.sdkRoot?.resolve("lib/libraries.json"); 290 Uri librariesJson = _raw.sdkRoot?.resolve("lib/libraries.json");
258 return await computeDartLibraries(fileSystem, librariesJson); 291 return await computeDartLibraries(fileSystem, librariesJson);
259 } 292 }
260 293
261 /// Get the package map which maps package names to URIs. 294 /// Get the package map which maps package names to URIs.
262 /// 295 ///
263 /// This is an asynchronous getter since file system operations may be 296 /// This is an asynchronous getter since file system operations may be
264 /// required to locate/read the packages file. 297 /// required to locate/read the packages file.
265 Future<Packages> _getPackages() async { 298 Future<Packages> _getPackages() async {
266 if (_packages == null) { 299 if (_packages != null) return _packages;
267 if (_raw.packagesFileUri == null) { 300 if (_raw.packagesFileUri != null) {
268 if (inputs.length > 1) { 301 return _packages = await createPackagesFromFile(_raw.packagesFileUri);
269 // TODO(sigmund): consider not reporting an error if we would infer
270 // the same .packages file from all of the inputs.
271 reportMessageWithoutLocation(messageCantInferPackagesFromManyInputs);
272 _packages = Packages.noPackages;
273 } else {
274 _packages = await _findPackages(inputs.first);
275 }
276 } else {
277 _packages = await createPackagesFromFile(_raw.packagesFileUri);
278 }
279 } 302 }
280 return _packages; 303
304 if (inputs.length > 1) {
305 // TODO(sigmund): consider not reporting an error if we would infer
306 // the same .packages file from all of the inputs.
307 reportWithoutLocation(
308 messageCantInferPackagesFromManyInputs, Severity.error);
309 return _packages = Packages.noPackages;
310 }
311
312 var input = inputs.first;
313
314 // When compiling the SDK the input files are normaly `dart:` URIs.
315 if (input.scheme == 'dart') return _packages = Packages.noPackages;
316
317 if (input.scheme == 'packages') {
318 report(messageCantInferPackagesFromPackageUri.withLocation(input, -1),
319 Severity.error);
320 return _packages = Packages.noPackages;
321 }
322
323 return _packages = await _findPackages(inputs.first);
281 } 324 }
282 325
283 /// Create a [Packages] given the Uri to a `.packages` file. 326 /// Create a [Packages] given the Uri to a `.packages` file.
284 Future<Packages> createPackagesFromFile(Uri file) async { 327 Future<Packages> createPackagesFromFile(Uri file) async {
285 try { 328 try {
286 List<int> contents = await fileSystem.entityForUri(file).readAsBytes(); 329 List<int> contents = await fileSystem.entityForUri(file).readAsBytes();
287 Map<String, Uri> map = package_config.parse(contents, file); 330 Map<String, Uri> map = package_config.parse(contents, file);
288 return new MapPackages(map); 331 return new MapPackages(map);
289 } catch (e) { 332 } catch (e) {
290 reportMessage(templateCannotReadPackagesFile 333 report(
291 .withArguments("$e") 334 templateCannotReadPackagesFile
292 .withLocation(file, -1)); 335 .withArguments("$e")
336 .withLocation(file, -1),
337 Severity.error);
293 return Packages.noPackages; 338 return Packages.noPackages;
294 } 339 }
295 } 340 }
296 341
297 /// Finds a package resolution strategy using a [FileSystem]. 342 /// Finds a package resolution strategy using a [FileSystem].
298 /// 343 ///
299 /// The [scriptUri] points to a Dart script with a valid scheme accepted by 344 /// The [scriptUri] points to a Dart script with a valid scheme accepted by
300 /// the [FileSystem]. 345 /// the [FileSystem].
301 /// 346 ///
302 /// This function first tries to locate a `.packages` file in the `scriptUri` 347 /// This function first tries to locate a `.packages` file in the `scriptUri`
303 /// directory. If that is not found, it instead checks for the presence of a 348 /// directory. If that is not found, it instead checks for the presence of a
304 /// `packages/` directory in the same place. If that also fails, it starts 349 /// `packages/` directory in the same place. If that also fails, it starts
305 /// checking parent directories for a `.packages` file, and stops if it finds 350 /// checking parent directories for a `.packages` file, and stops if it finds
306 /// it. Otherwise it gives up and returns [Packages.noPackages]. 351 /// it. Otherwise it gives up and returns [Packages.noPackages].
307 /// 352 ///
308 /// Note: this is a fork from `package:package_config/discovery.dart` to adapt 353 /// Note: this is a fork from `package:package_config/discovery.dart` to adapt
309 /// it to use [FileSystem]. The logic here is a mix of the logic in the 354 /// it to use [FileSystem]. The logic here is a mix of the logic in the
310 /// `findPackagesFromFile` and `findPackagesFromNonFile`: 355 /// `findPackagesFromFile` and `findPackagesFromNonFile`:
311 /// 356 ///
312 /// * Like `findPackagesFromFile` resolution searches for parent 357 /// * Like `findPackagesFromFile` resolution searches for parent
313 /// directories 358 /// directories
314 /// 359 ///
315 /// * Like `findPackagesFromNonFile` if we resolve packages as the 360 /// * Like `findPackagesFromNonFile` if we resolve packages as the
316 /// `packages/` directory, we can't provide a list of packages that are 361 /// `packages/` directory, we can't provide a list of packages that are
317 /// visible. 362 /// visible.
318 Future<Packages> _findPackages(Uri scriptUri) async { 363 Future<Packages> _findPackages(Uri scriptUri) async {
319 var dir = scriptUri.resolve('.'); 364 var dir = scriptUri.resolve('.');
320 if (!dir.isAbsolute) { 365 if (!dir.isAbsolute) {
321 reportMessageWithoutLocation(templateInternalProblemUnsupported 366 reportWithoutLocation(
322 .withArguments("Expected input Uri to be absolute: $scriptUri.")); 367 templateInternalProblemUnsupported
368 .withArguments("Expected input Uri to be absolute: $scriptUri."),
369 Severity.internalProblem);
323 return Packages.noPackages; 370 return Packages.noPackages;
324 } 371 }
325 372
326 Future<Uri> checkInDir(Uri dir) async { 373 Future<Uri> checkInDir(Uri dir) async {
327 Uri candidate = dir.resolve('.packages'); 374 Uri candidate = dir.resolve('.packages');
328 if (await fileSystem.entityForUri(candidate).exists()) return candidate; 375 if (await fileSystem.entityForUri(candidate).exists()) return candidate;
329 return null; 376 return null;
330 } 377 }
331 378
332 // Check for $cwd/.packages 379 // Check for $cwd/.packages
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 allInputs.add(sdkRoot.resolve("lib/libraries.json")); 453 allInputs.add(sdkRoot.resolve("lib/libraries.json"));
407 } 454 }
408 455
409 /// Note: Searching the file-system for the package-config is not 456 /// Note: Searching the file-system for the package-config is not
410 /// supported in hermetic builds. 457 /// supported in hermetic builds.
411 if (_raw.packagesFileUri != null) allInputs.add(_raw.packagesFileUri); 458 if (_raw.packagesFileUri != null) allInputs.add(_raw.packagesFileUri);
412 result = new HermeticFileSystem(allInputs, result); 459 result = new HermeticFileSystem(allInputs, result);
413 } 460 }
414 return result; 461 return result;
415 } 462 }
463
464 String debugString() {
465 var sb = new StringBuffer();
466 writeList(String name, List elements) {
467 if (elements.isEmpty) {
468 sb.writeln('$name: <empty>');
469 return;
470 }
471 sb.writeln('$name:');
472 elements.forEach((s) {
473 sb.writeln(' - $s');
474 });
475 }
476
477 sb.writeln('Inputs: ${inputs}');
478 sb.writeln('Output: ${output}');
479
480 sb.writeln('Was error handler provided: '
481 '${_raw.onError == null ? "no" : "yes"}');
482
483 sb.writeln('FileSystem: ${_fileSystem.runtimeType} '
484 '(provided: ${_raw.fileSystem.runtimeType})');
485
486 writeList('Input Summaries', _raw.inputSummaries);
487 writeList('Linked Dependencies', _raw.linkedDependencies);
488 writeList('Multiroots', _raw.multiRoots);
489
490 sb.writeln('Modular: ${_modularApi}');
491 sb.writeln('Hermetic: ${!chaseDependencies}'
492 ' (provided: ${!_raw.chaseDependencies})');
493 sb.writeln('Packages uri: ${_raw.packagesFileUri}');
494 sb.writeln('Packages: ${_packages}');
495
496 sb.writeln('Compile SDK: ${compileSdk}');
497 sb.writeln('SDK root: ${_sdkRoot} (provided: ${_raw.sdkRoot})');
498 sb.writeln('SDK summary: ${_sdkSummary} (provided: ${_raw.sdkSummary})');
499
500 sb.writeln('Strong: ${strongMode}');
501 sb.writeln('Target: ${_target?.name} (provided: ${_raw.target?.name})');
502
503 sb.writeln('throwOnErrorsAreFatal: ${throwOnErrors}');
504 sb.writeln('throwOnWarningsAreFatal: ${throwOnWarnings}');
505 sb.writeln('throwOnNits: ${throwOnNits}');
506 sb.writeln('exit on problem: ${setExitCodeOnProblem}');
507 sb.writeln('Embed sources: ${embedSourceText}');
508 sb.writeln('debugDump: ${debugDump}');
509 sb.writeln('verbose: ${verbose}');
510 sb.writeln('verify: ${verify}');
511 return '$sb';
512 }
416 } 513 }
417 514
418 /// A [FileSystem] that only allows access to files that have been explicitly 515 /// A [FileSystem] that only allows access to files that have been explicitly
419 /// whitelisted. 516 /// whitelisted.
420 class HermeticFileSystem implements FileSystem { 517 class HermeticFileSystem implements FileSystem {
421 final Set<Uri> includedFiles; 518 final Set<Uri> includedFiles;
422 final FileSystem _realFileSystem; 519 final FileSystem _realFileSystem;
423 520
424 HermeticFileSystem(this.includedFiles, this._realFileSystem); 521 HermeticFileSystem(this.includedFiles, this._realFileSystem);
425 522
426 FileSystemEntity entityForUri(Uri uri) { 523 FileSystemEntity entityForUri(Uri uri) {
427 if (includedFiles.contains(uri)) return _realFileSystem.entityForUri(uri); 524 if (includedFiles.contains(uri)) return _realFileSystem.entityForUri(uri);
428 throw new HermeticAccessException(uri); 525 throw new HermeticAccessException(uri);
429 } 526 }
430 } 527 }
431 528
432 class HermeticAccessException extends FileSystemException { 529 class HermeticAccessException extends FileSystemException {
433 HermeticAccessException(Uri uri) 530 HermeticAccessException(Uri uri)
434 : super( 531 : super(
435 uri, 532 uri,
436 'Invalid access to $uri: ' 533 'Invalid access to $uri: '
437 'the file is accessed in a modular hermetic build, ' 534 'the file is accessed in a modular hermetic build, '
438 'but it was not explicitly listed as an input.'); 535 'but it was not explicitly listed as an input.');
439 536
440 @override 537 @override
441 String toString() => message; 538 String toString() => message;
442 } 539 }
443 540
444 /// Wraps a [LocatedMessage] to implement the public [CompilationError] API. 541 /// Wraps a [LocatedMessage] to implement the public [CompilationMessage] API.
445 class _CompilationMessage implements CompilationError { 542 class _CompilationMessage implements CompilationMessage {
446 final LocatedMessage original; 543 final LocatedMessage _original;
544 final Severity severity;
447 545
448 String get message => original.message; 546 String get message => _original.message;
449 547
450 String get tip => original.tip; 548 String get tip => _original.tip;
549
550 String get analyzerCode => _original.code.analyzerCode;
551
552 String get dart2jsCode => _original.code.dart2jsCode;
451 553
452 SourceSpan get span => 554 SourceSpan get span =>
453 new SourceLocation(original.charOffset, sourceUrl: original.uri) 555 new SourceLocation(_original.charOffset, sourceUrl: _original.uri)
454 .pointSpan(); 556 .pointSpan();
455 557
456 _CompilationMessage(this.original); 558 _CompilationMessage(this._original, this.severity);
457 559
458 String toString() => message; 560 String toString() => message;
459 } 561 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698