| 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:analyzer/src/summary/idl.dart'; |  | 
|    8 import 'package:front_end/compiler_options.dart'; |    7 import 'package:front_end/compiler_options.dart'; | 
|    9 import 'package:front_end/file_system.dart'; |    8 import 'package:front_end/file_system.dart'; | 
|   10 import 'package:front_end/src/fasta/translate_uri.dart'; |    9 import 'package:front_end/src/fasta/translate_uri.dart'; | 
|   11 import 'package:front_end/src/base/performace_logger.dart'; |   10 import 'package:front_end/src/base/performace_logger.dart'; | 
|   12 import 'package:front_end/src/incremental/byte_store.dart'; |   11 import 'package:front_end/src/incremental/byte_store.dart'; | 
 |   12 import 'package:front_end/src/simple_error.dart'; | 
|   13 import 'package:package_config/packages_file.dart' as package_config; |   13 import 'package:package_config/packages_file.dart' as package_config; | 
 |   14 import 'package:kernel/kernel.dart' show Program, loadProgramFromBytes; | 
|   14  |   15  | 
|   15 /// Wrapper around [CompilerOptions] which exposes the options in a form useful |   16 /// Wrapper around [CompilerOptions] which exposes the options in a form useful | 
|   16 /// to the front end implementation. |   17 /// to the front end implementation. | 
|   17 /// |   18 /// | 
|   18 /// The intent is that the front end should immediately wrap any incoming |   19 /// The intent is that the front end should immediately wrap any incoming | 
|   19 /// [CompilerOptions] object in this class before doing further processing, and |   20 /// [CompilerOptions] object in this class before doing further processing, and | 
|   20 /// should thereafter access all options via the wrapper.  This ensures that |   21 /// should thereafter access all options via the wrapper.  This ensures that | 
|   21 /// options are interpreted in a consistent way and that data derived from |   22 /// options are interpreted in a consistent way and that data derived from | 
|   22 /// options is not unnecessarily recomputed. |   23 /// options is not unnecessarily recomputed. | 
|   23 class ProcessedOptions { |   24 class ProcessedOptions { | 
|   24   /// The raw [CompilerOptions] which this class wraps. |   25   /// The raw [CompilerOptions] which this class wraps. | 
|   25   final CompilerOptions _raw; |   26   final CompilerOptions _raw; | 
|   26  |   27  | 
|   27   /// The package map derived from the options, or `null` if the package map has |   28   /// The package map derived from the options, or `null` if the package map has | 
|   28   /// not been computed yet. |   29   /// not been computed yet. | 
|   29   Map<String, Uri> _packages; |   30   Map<String, Uri> _packages; | 
|   30  |   31  | 
|   31   /// The object that knows how to resolve "package:" and "dart:" URIs, |   32   /// The object that knows how to resolve "package:" and "dart:" URIs, | 
|   32   /// or `null` if it has not been computed yet. |   33   /// or `null` if it has not been computed yet. | 
|   33   TranslateUri _uriTranslator; |   34   TranslateUri _uriTranslator; | 
|   34  |   35  | 
|   35   /// The summary bundle for the SDK, or `null` if it has not been read yet. |   36   /// The SDK summary, or `null` if it has not been read yet. | 
|   36   PackageBundle _sdkSummary; |   37   Program _sdkSummaryProgram; | 
 |   38  | 
 |   39   /// The summary for each uri in `options.inputSummaries`. | 
 |   40   List<Program> _inputSummariesPrograms; | 
|   37  |   41  | 
|   38   /// The location of the SDK, or `null` if the location hasn't been determined |   42   /// The location of the SDK, or `null` if the location hasn't been determined | 
|   39   /// yet. |   43   /// yet. | 
|   40   Uri _sdkRoot; |   44   Uri _sdkRoot; | 
|   41  |   45  | 
 |   46   Uri get sdkRoot => _sdkRoot ??= _normalizeSdkRoot(); | 
 |   47  | 
|   42   /// Initializes a [ProcessedOptions] object wrapping the given [rawOptions]. |   48   /// Initializes a [ProcessedOptions] object wrapping the given [rawOptions]. | 
|   43   ProcessedOptions(CompilerOptions rawOptions) : this._raw = rawOptions; |   49   ProcessedOptions(CompilerOptions rawOptions) : this._raw = rawOptions; | 
|   44  |   50  | 
|   45   /// The logger to report compilation progress. |   51   /// The logger to report compilation progress. | 
|   46   PerformanceLog get logger { |   52   PerformanceLog get logger { | 
|   47     return _raw.logger; |   53     return _raw.logger; | 
|   48   } |   54   } | 
|   49  |   55  | 
|   50   /// The byte storage to get and put serialized data. |   56   /// The byte storage to get and put serialized data. | 
|   51   ByteStore get byteStore { |   57   ByteStore get byteStore { | 
|   52     return _raw.byteStore; |   58     return _raw.byteStore; | 
|   53   } |   59   } | 
|   54  |   60  | 
 |   61   /// 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. | 
 |   63   Future<bool> validateOptions() async { | 
 |   64     var fs = _raw.fileSystem; | 
 |   65     var root = _raw.sdkRoot; | 
 |   66  | 
 |   67     bool _report(String msg) { | 
 |   68       _raw.onError(new SimpleError(msg)); | 
 |   69       return false; | 
 |   70     } | 
 |   71  | 
 |   72     if (root != null && !await fs.entityForUri(root).exists()) { | 
 |   73       return _report("SDK root directory not found: ${_raw.sdkRoot}"); | 
 |   74     } | 
 |   75  | 
 |   76     var summary = _raw.sdkSummary; | 
 |   77     if (summary != null && !await fs.entityForUri(summary).exists()) { | 
 |   78       return _report("SDK summary not found: ${_raw.sdkSummary}"); | 
 |   79     } | 
 |   80  | 
 |   81     // TODO(sigmund): add checks for options that are meant to be disjoint (like | 
 |   82     // sdkRoot and sdkSummary). | 
 |   83     return true; | 
 |   84   } | 
 |   85  | 
|   55   /// Determine whether to generate code for the SDK when compiling a |   86   /// Determine whether to generate code for the SDK when compiling a | 
|   56   /// whole-program. |   87   /// whole-program. | 
|   57   bool get compileSdk => _raw.compileSdk; |   88   bool get compileSdk => _raw.compileSdk; | 
|   58  |   89  | 
|   59   /// Get the [FileSystem] which should be used by the front end to access |   90   /// Get the [FileSystem] which should be used by the front end to access | 
|   60   /// files. |   91   /// files. | 
|   61   /// |   92   /// | 
|   62   /// If the client supplied roots using [CompilerOptions.multiRoots], the |   93   /// If the client supplied roots using [CompilerOptions.multiRoots], the | 
|   63   /// returned [FileSystem] will automatically perform the appropriate mapping. |   94   /// returned [FileSystem] will automatically perform the appropriate mapping. | 
|   64   FileSystem get fileSystem { |   95   FileSystem get fileSystem { | 
|   65     // TODO(paulberry): support multiRoots. |   96     // TODO(paulberry): support multiRoots. | 
|   66     assert(_raw.multiRoots.isEmpty); |   97     assert(_raw.multiRoots.isEmpty); | 
|   67     return _raw.fileSystem; |   98     return _raw.fileSystem; | 
|   68   } |   99   } | 
|   69  |  100  | 
|   70   /// Whether to interpret Dart sources in strong-mode. |  101   /// Whether to interpret Dart sources in strong-mode. | 
|   71   bool get strongMode => _raw.strongMode; |  102   bool get strongMode => _raw.strongMode; | 
|   72  |  103  | 
|   73   /// Get the summary bundle for the SDK. |  104   /// Get an outline program that summarizes the SDK. | 
|   74   /// |  105   Future<Program> get sdkSummaryProgram async { | 
|   75   /// This is an asynchronous getter since file system operations are required. |  106     if (_sdkSummaryProgram == null) { | 
|   76   Future<PackageBundle> getSdkSummary() async { |  107       if (_raw.sdkSummary == null) return null; | 
|   77     if (_sdkSummary == null) { |  108       _sdkSummaryProgram = await _loadProgram(_raw.sdkSummary); | 
|   78       Uri summaryLocation; |  | 
|   79       if (_raw.sdkSummary != null) { |  | 
|   80         // Options sdkSummary and sdkRoot are mutually exclusive. |  | 
|   81         assert(_raw.sdkRoot == null); |  | 
|   82         // No need to look for the SDK; we were told where the SDK summary is. |  | 
|   83         summaryLocation = _raw.sdkSummary; |  | 
|   84       } else { |  | 
|   85         // Need to look for the SDK summary inside the SDK. |  | 
|   86         var sdkRoot = await _getSdkRoot(); |  | 
|   87         summaryLocation = sdkRoot.resolve( |  | 
|   88             'lib/_internal/' + (_raw.strongMode ? 'strong.sum' : 'spec.sum')); |  | 
|   89       } |  | 
|   90       var summaryBytes = |  | 
|   91           await fileSystem.entityForUri(summaryLocation).readAsBytes(); |  | 
|   92       _sdkSummary = new PackageBundle.fromBuffer(summaryBytes); |  | 
|   93     } |  109     } | 
|   94     return _sdkSummary; |  110     return _sdkSummaryProgram; | 
 |  111   } | 
 |  112  | 
 |  113   /// Get the summary programs for each of the underlying `inputSummaries` | 
 |  114   /// provided via [CompilerOptions]. | 
 |  115   Future<List<Program>> get inputSummariesPrograms async { | 
 |  116     if (_inputSummariesPrograms == null) { | 
 |  117       var uris = _raw.inputSummaries; | 
 |  118       if (uris == null || uris.isEmpty) return const <Program>[]; | 
 |  119       _inputSummariesPrograms = await Future.wait(uris.map(_loadProgram)); | 
 |  120     } | 
 |  121     return _inputSummariesPrograms; | 
 |  122   } | 
 |  123  | 
 |  124   Future<Program> _loadProgram(Uri uri) async { | 
 |  125     var bytes = await fileSystem.entityForUri(uri).readAsBytes(); | 
 |  126     return loadProgramFromBytes(bytes)..unbindCanonicalNames(); | 
|   95   } |  127   } | 
|   96  |  128  | 
|   97   /// Get the [TranslateUri] which resolves "package:" and "dart:" URIs. |  129   /// Get the [TranslateUri] which resolves "package:" and "dart:" URIs. | 
|   98   /// |  130   /// | 
|   99   /// This is an asynchronous method since file system operations may be |  131   /// This is an asynchronous method since file system operations may be | 
|  100   /// required to locate/read the packages file as well as SDK metadata. |  132   /// required to locate/read the packages file as well as SDK metadata. | 
|  101   Future<TranslateUri> getUriTranslator() async { |  133   Future<TranslateUri> getUriTranslator() async { | 
|  102     if (_uriTranslator == null) { |  134     if (_uriTranslator == null) { | 
|  103       await _getPackages(); |  135       await _getPackages(); | 
|  104       // TODO(scheglov) Load SDK libraries from whatever format we decide. |  136       // TODO(scheglov) Load SDK libraries from whatever format we decide. | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|  125         _packages = package_config.parse(contents, _raw.packagesFileUri); |  157         _packages = package_config.parse(contents, _raw.packagesFileUri); | 
|  126       } |  158       } | 
|  127     } |  159     } | 
|  128     return _packages; |  160     return _packages; | 
|  129   } |  161   } | 
|  130  |  162  | 
|  131   /// Get the location of the SDK. |  163   /// Get the location of the SDK. | 
|  132   /// |  164   /// | 
|  133   /// This is an asynchronous getter since file system operations may be |  165   /// This is an asynchronous getter since file system operations may be | 
|  134   /// required to locate the SDK. |  166   /// required to locate the SDK. | 
|  135   Future<Uri> _getSdkRoot() async { |  167   Uri _normalizeSdkRoot() { | 
|  136     if (_sdkRoot == null) { |  168     // If an SDK summary location was provided, the SDK itself should not be | 
|  137       // If an SDK summary location was provided, the SDK itself should not be |  169     // needed. | 
|  138       // needed. |  170     assert(_raw.sdkSummary == null); | 
|  139       assert(_raw.sdkSummary == null); |  171     if (_raw.sdkRoot == null) { | 
|  140       if (_raw.sdkRoot == null) { |  172       // TODO(paulberry): implement the algorithm for finding the SDK | 
|  141         // TODO(paulberry): implement the algorithm for finding the SDK |  173       // automagically. | 
|  142         // automagically. |  174       throw new UnimplementedError(); | 
|  143         throw new UnimplementedError(); |  | 
|  144       } |  | 
|  145       _sdkRoot = _raw.sdkRoot; |  | 
|  146       if (!_sdkRoot.path.endsWith('/')) { |  | 
|  147         _sdkRoot = _sdkRoot.replace(path: _sdkRoot.path + '/'); |  | 
|  148       } |  | 
|  149     } |  175     } | 
|  150     return _sdkRoot; |  176     var root = _raw.sdkRoot; | 
 |  177     if (!root.path.endsWith('/')) { | 
 |  178       root = root.replace(path: _sdkRoot.path + '/'); | 
 |  179     } | 
 |  180     return root; | 
|  151   } |  181   } | 
|  152 } |  182 } | 
| OLD | NEW |