Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 excludeSourceInformation => _raw.excludeSourceInformation; | |
| 95 | |
| 96 bool get errorsAreFatal => _raw.errorsAreFatal; | |
| 97 | |
| 98 bool get warningsAreFatal => _raw.warningsAreFatal; | |
| 99 | |
| 100 bool get nitsAreFatal => _raw.nitsAreFatal; | |
| 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, |
| 107 ticker = new Ticker(isVerbose: rawOptions.verbose); | 121 ticker = new Ticker(isVerbose: rawOptions.verbose); |
| 108 | 122 |
| 109 /// The logger to report compilation progress. | 123 /// The logger to report compilation progress. |
| 110 PerformanceLog get logger { | 124 PerformanceLog get logger { |
| 111 return _raw.logger; | 125 return _raw.logger; |
| 112 } | 126 } |
| 113 | 127 |
| 114 /// The byte storage to get and put serialized data. | 128 /// The byte storage to get and put serialized data. |
| 115 ByteStore get byteStore { | 129 ByteStore get byteStore { |
| 116 return _raw.byteStore; | 130 return _raw.byteStore; |
| 117 } | 131 } |
| 118 | 132 |
| 119 void reportMessage(LocatedMessage message) { | 133 bool get _reportMessages => _raw.reportMessages ?? (_raw.onError == null); |
| 120 _raw.onError(new _CompilationMessage(message)); | 134 |
| 135 void report(LocatedMessage message, Severity severity) { | |
| 136 if (_raw.onError != null) { | |
| 137 _raw.onError(new _CompilationMessage(message, severity)); | |
| 138 } | |
| 139 | |
| 140 if (_reportMessages) command_line_reporting.report(message, severity); | |
| 121 } | 141 } |
| 122 | 142 |
| 123 void reportMessageWithoutLocation(Message message) => | 143 void reportWithoutLocation(Message message, Severity severity) { |
| 124 reportMessage(message.withLocation(null, -1)); | 144 if (_raw.onError != null) { |
| 145 _raw.onError( | |
| 146 new _CompilationMessage(message.withLocation(null, -1), severity)); | |
| 147 } | |
| 148 | |
| 149 if (_reportMessages) { | |
| 150 command_line_reporting.reportWithoutLocation(message, severity); | |
| 151 } | |
| 152 } | |
| 125 | 153 |
| 126 /// Runs various validations checks on the input options. For instance, | 154 /// 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. | 155 /// if an option is a path to a file, it checks that the file exists. |
| 128 Future<bool> validateOptions() async { | 156 Future<bool> validateOptions() async { |
| 157 if (verbose) print(debugString()); | |
| 158 | |
| 129 if (inputs.isEmpty) { | 159 if (inputs.isEmpty) { |
| 130 reportMessageWithoutLocation(messageMissingInput); | 160 reportWithoutLocation(messageMissingInput, Severity.error); |
| 131 return false; | 161 return false; |
| 132 } | 162 } |
| 133 | 163 |
| 134 for (var source in inputs) { | 164 for (var source in inputs) { |
| 135 // Note: we don't translate Uris at this point because some of the | 165 // 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 | 166 // validation further below must be done before we even construct an |
| 137 // UriTranslator | 167 // UriTranslator |
| 138 // TODO(sigmund): consider validating dart/packages uri right after we | 168 // TODO(sigmund): consider validating dart/packages uri right after we |
| 139 // build the uri translator. | 169 // build the uri translator. |
| 140 if (source.scheme != 'dart' && | 170 if (source.scheme != 'dart' && |
| 141 source.scheme != 'packages' && | 171 source.scheme != 'packages' && |
| 142 !await fileSystem.entityForUri(source).exists()) { | 172 !await fileSystem.entityForUri(source).exists()) { |
| 143 reportMessageWithoutLocation( | 173 reportWithoutLocation( |
| 144 templateInputFileNotFound.withArguments('$source')); | 174 templateInputFileNotFound.withArguments('$source'), Severity.error); |
| 145 return false; | 175 return false; |
| 146 } | 176 } |
| 147 } | 177 } |
| 148 | 178 |
| 149 if (_raw.sdkRoot != null && | 179 if (_raw.sdkRoot != null && |
| 150 !await fileSystem.entityForUri(sdkRoot).exists()) { | 180 !await fileSystem.entityForUri(sdkRoot).exists()) { |
| 151 reportMessageWithoutLocation( | 181 reportWithoutLocation( |
| 152 templateSdkRootNotFound.withArguments('$sdkRoot')); | 182 templateSdkRootNotFound.withArguments('$sdkRoot'), Severity.error); |
| 153 return false; | 183 return false; |
| 154 } | 184 } |
| 155 | 185 |
| 156 var summary = sdkSummary; | 186 var summary = sdkSummary; |
| 157 if (summary != null && !await fileSystem.entityForUri(summary).exists()) { | 187 if (summary != null && !await fileSystem.entityForUri(summary).exists()) { |
| 158 reportMessageWithoutLocation( | 188 reportWithoutLocation( |
| 159 templateSdkSummaryNotFound.withArguments('$summary')); | 189 templateSdkSummaryNotFound.withArguments('$summary'), Severity.error); |
| 160 return false; | 190 return false; |
| 161 } | 191 } |
| 162 | 192 |
| 163 if (compileSdk && summary != null) { | 193 if (compileSdk && summary != null) { |
| 164 reportMessageWithoutLocation( | 194 reportWithoutLocation( |
| 165 templateInternalProblemUnsupported.withArguments( | 195 templateInternalProblemUnsupported.withArguments( |
| 166 "The compileSdk and sdkSummary options are mutually exclusive")); | 196 "The compileSdk and sdkSummary options are mutually exclusive"), |
| 197 Severity.internalProblem); | |
| 167 return false; | 198 return false; |
| 168 } | 199 } |
| 169 return true; | 200 return true; |
| 170 } | 201 } |
| 171 | 202 |
| 172 /// Determine whether to generate code for the SDK when compiling a | 203 /// Determine whether to generate code for the SDK when compiling a |
| 173 /// whole-program. | 204 /// whole-program. |
| 174 bool get compileSdk => _raw.compileSdk; | 205 bool get compileSdk => _raw.compileSdk; |
| 175 | 206 |
| 176 FileSystem _fileSystem; | 207 FileSystem _fileSystem; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 Future<Map<String, Uri>> _parseDartLibraries() async { | 287 Future<Map<String, Uri>> _parseDartLibraries() async { |
| 257 Uri librariesJson = _raw.sdkRoot?.resolve("lib/libraries.json"); | 288 Uri librariesJson = _raw.sdkRoot?.resolve("lib/libraries.json"); |
| 258 return await computeDartLibraries(fileSystem, librariesJson); | 289 return await computeDartLibraries(fileSystem, librariesJson); |
| 259 } | 290 } |
| 260 | 291 |
| 261 /// Get the package map which maps package names to URIs. | 292 /// Get the package map which maps package names to URIs. |
| 262 /// | 293 /// |
| 263 /// This is an asynchronous getter since file system operations may be | 294 /// This is an asynchronous getter since file system operations may be |
| 264 /// required to locate/read the packages file. | 295 /// required to locate/read the packages file. |
| 265 Future<Packages> _getPackages() async { | 296 Future<Packages> _getPackages() async { |
| 266 if (_packages == null) { | 297 if (_packages != null) return _packages; |
| 267 if (_raw.packagesFileUri == null) { | 298 if (_raw.packagesFileUri != null) { |
| 268 if (inputs.length > 1) { | 299 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 } | 300 } |
| 280 return _packages; | 301 |
| 302 if (inputs.length > 1) { | |
| 303 // TODO(sigmund): consider not reporting an error if we would infer | |
| 304 // the same .packages file from all of the inputs. | |
| 305 reportWithoutLocation( | |
| 306 messageCantInferPackagesFromManyInputs, Severity.error); | |
| 307 return _packages = Packages.noPackages; | |
| 308 } | |
| 309 | |
| 310 var input = inputs.first; | |
| 311 | |
| 312 // When compiling the SDK the input files are normaly `dart:` URIs. | |
|
Siggi Cherem (dart-lang)
2017/07/18 00:11:07
*FYI this is new logic (handling more error cases)
| |
| 313 if (input.scheme == 'dart') return _packages = Packages.noPackages; | |
| 314 | |
| 315 if (input.scheme == 'packages') { | |
| 316 report(messageCantInferPackagesFromPackageUri.withLocation(input, -1), | |
| 317 Severity.error); | |
| 318 return _packages = Packages.noPackages; | |
| 319 } | |
| 320 | |
| 321 return _packages = await _findPackages(inputs.first); | |
| 281 } | 322 } |
| 282 | 323 |
| 283 /// Create a [Packages] given the Uri to a `.packages` file. | 324 /// Create a [Packages] given the Uri to a `.packages` file. |
| 284 Future<Packages> createPackagesFromFile(Uri file) async { | 325 Future<Packages> createPackagesFromFile(Uri file) async { |
| 285 try { | 326 try { |
| 286 List<int> contents = await fileSystem.entityForUri(file).readAsBytes(); | 327 List<int> contents = await fileSystem.entityForUri(file).readAsBytes(); |
| 287 Map<String, Uri> map = package_config.parse(contents, file); | 328 Map<String, Uri> map = package_config.parse(contents, file); |
| 288 return new MapPackages(map); | 329 return new MapPackages(map); |
| 289 } catch (e) { | 330 } catch (e) { |
| 290 reportMessage(templateCannotReadPackagesFile | 331 report( |
| 291 .withArguments("$e") | 332 templateCannotReadPackagesFile |
| 292 .withLocation(file, -1)); | 333 .withArguments("$e") |
| 334 .withLocation(file, -1), | |
| 335 Severity.error); | |
| 293 return Packages.noPackages; | 336 return Packages.noPackages; |
| 294 } | 337 } |
| 295 } | 338 } |
| 296 | 339 |
| 297 /// Finds a package resolution strategy using a [FileSystem]. | 340 /// Finds a package resolution strategy using a [FileSystem]. |
| 298 /// | 341 /// |
| 299 /// The [scriptUri] points to a Dart script with a valid scheme accepted by | 342 /// The [scriptUri] points to a Dart script with a valid scheme accepted by |
| 300 /// the [FileSystem]. | 343 /// the [FileSystem]. |
| 301 /// | 344 /// |
| 302 /// This function first tries to locate a `.packages` file in the `scriptUri` | 345 /// 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 | 346 /// 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 | 347 /// `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 | 348 /// checking parent directories for a `.packages` file, and stops if it finds |
| 306 /// it. Otherwise it gives up and returns [Packages.noPackages]. | 349 /// it. Otherwise it gives up and returns [Packages.noPackages]. |
| 307 /// | 350 /// |
| 308 /// Note: this is a fork from `package:package_config/discovery.dart` to adapt | 351 /// 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 | 352 /// it to use [FileSystem]. The logic here is a mix of the logic in the |
| 310 /// `findPackagesFromFile` and `findPackagesFromNonFile`: | 353 /// `findPackagesFromFile` and `findPackagesFromNonFile`: |
| 311 /// | 354 /// |
| 312 /// * Like `findPackagesFromFile` resolution searches for parent | 355 /// * Like `findPackagesFromFile` resolution searches for parent |
| 313 /// directories | 356 /// directories |
| 314 /// | 357 /// |
| 315 /// * Like `findPackagesFromNonFile` if we resolve packages as the | 358 /// * Like `findPackagesFromNonFile` if we resolve packages as the |
| 316 /// `packages/` directory, we can't provide a list of packages that are | 359 /// `packages/` directory, we can't provide a list of packages that are |
| 317 /// visible. | 360 /// visible. |
| 318 Future<Packages> _findPackages(Uri scriptUri) async { | 361 Future<Packages> _findPackages(Uri scriptUri) async { |
| 319 var dir = scriptUri.resolve('.'); | 362 var dir = scriptUri.resolve('.'); |
| 320 if (!dir.isAbsolute) { | 363 if (!dir.isAbsolute) { |
| 321 reportMessageWithoutLocation(templateInternalProblemUnsupported | 364 reportWithoutLocation( |
| 322 .withArguments("Expected input Uri to be absolute: $scriptUri.")); | 365 templateInternalProblemUnsupported |
| 366 .withArguments("Expected input Uri to be absolute: $scriptUri."), | |
| 367 Severity.internalProblem); | |
| 323 return Packages.noPackages; | 368 return Packages.noPackages; |
| 324 } | 369 } |
| 325 | 370 |
| 326 Future<Uri> checkInDir(Uri dir) async { | 371 Future<Uri> checkInDir(Uri dir) async { |
| 327 Uri candidate = dir.resolve('.packages'); | 372 Uri candidate = dir.resolve('.packages'); |
| 328 if (await fileSystem.entityForUri(candidate).exists()) return candidate; | 373 if (await fileSystem.entityForUri(candidate).exists()) return candidate; |
| 329 return null; | 374 return null; |
| 330 } | 375 } |
| 331 | 376 |
| 332 // Check for $cwd/.packages | 377 // Check for $cwd/.packages |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 406 allInputs.add(sdkRoot.resolve("lib/libraries.json")); | 451 allInputs.add(sdkRoot.resolve("lib/libraries.json")); |
| 407 } | 452 } |
| 408 | 453 |
| 409 /// Note: Searching the file-system for the package-config is not | 454 /// Note: Searching the file-system for the package-config is not |
| 410 /// supported in hermetic builds. | 455 /// supported in hermetic builds. |
| 411 if (_raw.packagesFileUri != null) allInputs.add(_raw.packagesFileUri); | 456 if (_raw.packagesFileUri != null) allInputs.add(_raw.packagesFileUri); |
| 412 result = new HermeticFileSystem(allInputs, result); | 457 result = new HermeticFileSystem(allInputs, result); |
| 413 } | 458 } |
| 414 return result; | 459 return result; |
| 415 } | 460 } |
| 461 | |
| 462 String debugString() { | |
|
ahe
2017/07/18 16:54:36
Nice.
| |
| 463 var sb = new StringBuffer(); | |
| 464 writeList(String name, List elements) { | |
| 465 if (elements.isEmpty) { | |
| 466 sb.writeln('$name: <empty>'); | |
| 467 return; | |
| 468 } | |
| 469 sb.writeln('$name:'); | |
| 470 elements.forEach((s) { | |
| 471 sb.writeln(' - $s'); | |
| 472 }); | |
| 473 } | |
| 474 | |
| 475 sb.writeln('Inputs: ${inputs}'); | |
| 476 sb.writeln('Output: ${output}'); | |
| 477 | |
| 478 sb.writeln('Was error handler provided: ' | |
| 479 '${_raw.onError == null ? "no" : "yes"}'); | |
| 480 | |
| 481 sb.writeln('FileSystem: ${_fileSystem.runtimeType} ' | |
| 482 '(provided: ${_raw.fileSystem.runtimeType})'); | |
| 483 | |
| 484 writeList('Input Summaries', _raw.inputSummaries); | |
| 485 writeList('Linked Dependencies', _raw.linkedDependencies); | |
| 486 writeList('Multiroots', _raw.multiRoots); | |
| 487 | |
| 488 sb.writeln('Modular: ${_modularApi}'); | |
| 489 sb.writeln('Hermetic: ${!chaseDependencies}' | |
| 490 ' (provided: ${!_raw.chaseDependencies})'); | |
| 491 sb.writeln('Packages uri: ${_raw.packagesFileUri}'); | |
| 492 sb.writeln('Packages: ${_packages}'); | |
| 493 | |
| 494 sb.writeln('Compile SDK: ${compileSdk}'); | |
| 495 sb.writeln('SDK root: ${_sdkRoot} (provided: ${_raw.sdkRoot})'); | |
| 496 sb.writeln('SDK summary: ${_sdkSummary} (provided: ${_raw.sdkSummary})'); | |
| 497 | |
| 498 sb.writeln('Strong: ${strongMode}'); | |
| 499 sb.writeln('Target: ${_target?.name} (provided: ${_raw.target?.name})'); | |
| 500 | |
| 501 sb.writeln('errorsAreFatal: ${errorsAreFatal}'); | |
| 502 sb.writeln('warningsAreFatal: ${warningsAreFatal}'); | |
| 503 sb.writeln('nitsAreFatal: ${nitsAreFatal}'); | |
| 504 sb.writeln('exit on problem: ${setExitCodeOnProblem}'); | |
| 505 sb.writeln('Exclude sources: ${excludeSourceInformation}'); | |
| 506 sb.writeln('debugDump: ${debugDump}'); | |
| 507 sb.writeln('verbose: ${verbose}'); | |
| 508 sb.writeln('verify: ${verify}'); | |
| 509 return '$sb'; | |
| 510 } | |
| 416 } | 511 } |
| 417 | 512 |
| 418 /// A [FileSystem] that only allows access to files that have been explicitly | 513 /// A [FileSystem] that only allows access to files that have been explicitly |
| 419 /// whitelisted. | 514 /// whitelisted. |
| 420 class HermeticFileSystem implements FileSystem { | 515 class HermeticFileSystem implements FileSystem { |
| 421 final Set<Uri> includedFiles; | 516 final Set<Uri> includedFiles; |
| 422 final FileSystem _realFileSystem; | 517 final FileSystem _realFileSystem; |
| 423 | 518 |
| 424 HermeticFileSystem(this.includedFiles, this._realFileSystem); | 519 HermeticFileSystem(this.includedFiles, this._realFileSystem); |
| 425 | 520 |
| 426 FileSystemEntity entityForUri(Uri uri) { | 521 FileSystemEntity entityForUri(Uri uri) { |
| 427 if (includedFiles.contains(uri)) return _realFileSystem.entityForUri(uri); | 522 if (includedFiles.contains(uri)) return _realFileSystem.entityForUri(uri); |
| 428 throw new HermeticAccessException(uri); | 523 throw new HermeticAccessException(uri); |
| 429 } | 524 } |
| 430 } | 525 } |
| 431 | 526 |
| 432 class HermeticAccessException extends FileSystemException { | 527 class HermeticAccessException extends FileSystemException { |
| 433 HermeticAccessException(Uri uri) | 528 HermeticAccessException(Uri uri) |
| 434 : super( | 529 : super( |
| 435 uri, | 530 uri, |
| 436 'Invalid access to $uri: ' | 531 'Invalid access to $uri: ' |
| 437 'the file is accessed in a modular hermetic build, ' | 532 'the file is accessed in a modular hermetic build, ' |
| 438 'but it was not explicitly listed as an input.'); | 533 'but it was not explicitly listed as an input.'); |
| 439 | 534 |
| 440 @override | 535 @override |
| 441 String toString() => message; | 536 String toString() => message; |
| 442 } | 537 } |
| 443 | 538 |
| 444 /// Wraps a [LocatedMessage] to implement the public [CompilationError] API. | 539 /// Wraps a [LocatedMessage] to implement the public [CompilationMessage] API. |
| 445 class _CompilationMessage implements CompilationError { | 540 class _CompilationMessage implements CompilationMessage { |
|
ahe
2017/07/18 16:54:37
You may be able to merge this class with Compilati
Siggi Cherem (dart-lang)
2017/07/18 22:50:43
I have a slight preference to keep them separate b
| |
| 446 final LocatedMessage original; | 541 final LocatedMessage _original; |
| 542 final Severity severity; | |
| 447 | 543 |
| 448 String get message => original.message; | 544 String get message => _original.message; |
| 449 | 545 |
| 450 String get tip => original.tip; | 546 String get tip => _original.tip; |
| 547 | |
| 548 String get analyzerCode => _original.code.analyzerCode; | |
| 549 | |
| 550 String get dart2jsCode => _original.code.dart2jsCode; | |
| 451 | 551 |
| 452 SourceSpan get span => | 552 SourceSpan get span => |
| 453 new SourceLocation(original.charOffset, sourceUrl: original.uri) | 553 new SourceLocation(_original.charOffset, sourceUrl: _original.uri) |
| 454 .pointSpan(); | 554 .pointSpan(); |
| 455 | 555 |
| 456 _CompilationMessage(this.original); | 556 _CompilationMessage(this._original, this.severity); |
| 457 | 557 |
| 458 String toString() => message; | 558 String toString() => message; |
| 459 } | 559 } |
| OLD | NEW |