| 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 import 'dart:io'; | 6 import 'dart:io'; |
| 7 | 7 |
| 8 import 'package:front_end/file_system.dart'; | 8 import 'package:front_end/file_system.dart'; |
| 9 import 'package:front_end/incremental_kernel_generator.dart'; | 9 import 'package:front_end/incremental_kernel_generator.dart'; |
| 10 import 'package:front_end/incremental_resolved_ast_generator.dart'; | 10 import 'package:front_end/incremental_resolved_ast_generator.dart'; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 } | 38 } |
| 39 | 39 |
| 40 /// Implementation of [IncrementalKernelGenerator]. | 40 /// Implementation of [IncrementalKernelGenerator]. |
| 41 /// | 41 /// |
| 42 /// TODO(scheglov) Update the documentation. | 42 /// TODO(scheglov) Update the documentation. |
| 43 /// | 43 /// |
| 44 /// Theory of operation: an instance of [IncrementalResolvedAstGenerator] is | 44 /// Theory of operation: an instance of [IncrementalResolvedAstGenerator] is |
| 45 /// used to obtain resolved ASTs, and these are fed into kernel code generation | 45 /// used to obtain resolved ASTs, and these are fed into kernel code generation |
| 46 /// logic. | 46 /// logic. |
| 47 class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { | 47 class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { |
| 48 /// The version of data format, should be incremented on every format change. |
| 49 static const int DATA_VERSION = 1; |
| 50 |
| 48 /// The compiler options, such as the [FileSystem], the SDK dill location, | 51 /// The compiler options, such as the [FileSystem], the SDK dill location, |
| 49 /// etc. | 52 /// etc. |
| 50 final ProcessedOptions _options; | 53 final ProcessedOptions _options; |
| 51 | 54 |
| 52 /// The object that knows how to resolve "package:" and "dart:" URIs. | 55 /// The object that knows how to resolve "package:" and "dart:" URIs. |
| 53 final TranslateUri _uriTranslator; | 56 final TranslateUri _uriTranslator; |
| 54 | 57 |
| 55 /// The logger to report compilation progress. | 58 /// The logger to report compilation progress. |
| 56 final PerformanceLog _logger; | 59 final PerformanceLog _logger; |
| 57 | 60 |
| 58 /// The current file system state. | 61 /// The current file system state. |
| 59 final FileSystemState _fsState; | 62 final FileSystemState _fsState; |
| 60 | 63 |
| 61 /// The byte storage to get and put serialized data. | 64 /// The byte storage to get and put serialized data. |
| 62 final ByteStore _byteStore; | 65 final ByteStore _byteStore; |
| 63 | 66 |
| 64 /// The URI of the program entry point. | 67 /// The URI of the program entry point. |
| 65 final Uri _entryPoint; | 68 final Uri _entryPoint; |
| 66 | 69 |
| 70 /// The salt to mix into all hashes used as keys for serialized data. |
| 71 List<int> _salt; |
| 72 |
| 67 /// Latest compilation signatures produced by [computeDelta] for libraries. | 73 /// Latest compilation signatures produced by [computeDelta] for libraries. |
| 68 final Map<Uri, String> _uriToLatestSignature = {}; | 74 final Map<Uri, String> _latestSignature = {}; |
| 69 | 75 |
| 70 /// The set of absolute file URIs that were reported through [invalidate] | 76 /// The set of absolute file URIs that were reported through [invalidate] |
| 71 /// and not checked for actual changes yet. | 77 /// and not checked for actual changes yet. |
| 72 final Set<Uri> _invalidatedFiles = new Set<Uri>(); | 78 final Set<Uri> _invalidatedFiles = new Set<Uri>(); |
| 73 | 79 |
| 74 IncrementalKernelGeneratorImpl( | 80 IncrementalKernelGeneratorImpl( |
| 75 this._options, this._uriTranslator, this._entryPoint) | 81 this._options, this._uriTranslator, this._entryPoint) |
| 76 : _logger = _options.logger, | 82 : _logger = _options.logger, |
| 77 _fsState = new FileSystemState(_options.fileSystem, _uriTranslator), | 83 _fsState = new FileSystemState(_options.fileSystem, _uriTranslator), |
| 78 _byteStore = _options.byteStore; | 84 _byteStore = _options.byteStore { |
| 85 _computeSalt(); |
| 86 } |
| 79 | 87 |
| 80 @override | 88 @override |
| 81 Future<DeltaProgram> computeDelta( | 89 Future<DeltaProgram> computeDelta( |
| 82 {Future<Null> watch(Uri uri, bool used)}) async { | 90 {Future<Null> watch(Uri uri, bool used)}) async { |
| 83 return await _logger.runAsync('Compute delta', () async { | 91 return await _logger.runAsync('Compute delta', () async { |
| 84 await _refreshInvalidatedFiles(); | 92 await _refreshInvalidatedFiles(); |
| 85 | 93 |
| 86 // Ensure that the graph starting at the entry point is ready. | 94 // Ensure that the graph starting at the entry point is ready. |
| 87 FileState entryLibrary = await _fsState.getFile(_entryPoint); | 95 FileState entryLibrary = await _fsState.getFile(_entryPoint); |
| 88 | 96 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 104 results.add(result); | 112 results.add(result); |
| 105 } | 113 } |
| 106 }); | 114 }); |
| 107 | 115 |
| 108 Program program = new Program(nameRoot: nameRoot); | 116 Program program = new Program(nameRoot: nameRoot); |
| 109 | 117 |
| 110 // Add affected libraries (with different signatures). | 118 // Add affected libraries (with different signatures). |
| 111 for (_LibraryCycleResult result in results) { | 119 for (_LibraryCycleResult result in results) { |
| 112 for (Library library in result.kernelLibraries) { | 120 for (Library library in result.kernelLibraries) { |
| 113 Uri uri = library.importUri; | 121 Uri uri = library.importUri; |
| 114 if (_uriToLatestSignature[uri] != result.signature) { | 122 if (_latestSignature[uri] != result.signature) { |
| 115 _uriToLatestSignature[uri] = result.signature; | 123 _latestSignature[uri] = result.signature; |
| 116 program.libraries.add(library); | 124 program.libraries.add(library); |
| 117 } | 125 } |
| 118 } | 126 } |
| 119 } | 127 } |
| 120 | 128 |
| 121 // TODO(scheglov) Add libraries which import changed libraries. | 129 // TODO(scheglov) Add libraries which import changed libraries. |
| 122 | 130 |
| 123 return new DeltaProgram(program); | 131 return new DeltaProgram(program); |
| 124 }); | 132 }); |
| 125 } | 133 } |
| 126 | 134 |
| 127 @override | 135 @override |
| 128 void invalidate(Uri uri) { | 136 void invalidate(Uri uri) { |
| 129 _invalidatedFiles.add(uri); | 137 _invalidatedFiles.add(uri); |
| 130 } | 138 } |
| 131 | 139 |
| 132 @override | 140 @override |
| 133 void invalidateAll() => unimplemented(); | 141 void invalidateAll() => unimplemented(); |
| 134 | 142 |
| 135 /// Ensure that [dillTarget] includes the [cycle] libraries. It already | 143 /// Ensure that [dillTarget] includes the [cycle] libraries. It already |
| 136 /// contains all the libraries that sorted before the given [cycle] in | 144 /// contains all the libraries that sorted before the given [cycle] in |
| 137 /// topological order. Return the result with the cycle libraries. | 145 /// topological order. Return the result with the cycle libraries. |
| 138 Future<_LibraryCycleResult> _compileCycle( | 146 Future<_LibraryCycleResult> _compileCycle( |
| 139 CanonicalName nameRoot, DillTarget dillTarget, LibraryCycle cycle) async { | 147 CanonicalName nameRoot, DillTarget dillTarget, LibraryCycle cycle) async { |
| 140 return _logger.runAsync('Compile cycle $cycle', () async { | 148 return _logger.runAsync('Compile cycle $cycle', () async { |
| 141 String signature; | 149 String signature; |
| 142 { | 150 { |
| 143 var signatureBuilder = new ApiSignature(); | 151 var signatureBuilder = new ApiSignature(); |
| 144 // TODO(scheglov) add salt | 152 signatureBuilder.addBytes(_salt); |
| 145 // signature.addUint32List(_fsState._salt); | |
| 146 Set<FileState> transitiveFiles = cycle.libraries | 153 Set<FileState> transitiveFiles = cycle.libraries |
| 147 .map((library) => library.transitiveFiles) | 154 .map((library) => library.transitiveFiles) |
| 148 .expand((files) => files) | 155 .expand((files) => files) |
| 149 .toSet(); | 156 .toSet(); |
| 150 signatureBuilder.addInt(transitiveFiles.length); | 157 signatureBuilder.addInt(transitiveFiles.length); |
| 151 for (var file in transitiveFiles) { | 158 for (var file in transitiveFiles) { |
| 152 signatureBuilder.addString(file.uri.toString()); | 159 signatureBuilder.addString(file.uri.toString()); |
| 153 // TODO(scheglov) use API signature | 160 // TODO(scheglov) use API signature |
| 154 signatureBuilder.addBytes(file.contentHash); | 161 signatureBuilder.addBytes(file.contentHash); |
| 155 } | 162 } |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 } | 253 } |
| 247 }); | 254 }); |
| 248 } else { | 255 } else { |
| 249 // TODO(scheglov) How to handle this? | 256 // TODO(scheglov) How to handle this? |
| 250 } | 257 } |
| 251 } | 258 } |
| 252 } | 259 } |
| 253 } while (wasChanged); | 260 } while (wasChanged); |
| 254 } | 261 } |
| 255 | 262 |
| 263 /// Compute salt and put into [_salt]. |
| 264 void _computeSalt() { |
| 265 var saltBuilder = new ApiSignature(); |
| 266 saltBuilder.addInt(DATA_VERSION); |
| 267 saltBuilder.addBool(_options.strongMode); |
| 268 saltBuilder.addString(_entryPoint.toString()); |
| 269 _salt = saltBuilder.toByteList(); |
| 270 } |
| 271 |
| 256 /// Refresh all the invalidated files and update dependencies. | 272 /// Refresh all the invalidated files and update dependencies. |
| 257 Future<Null> _refreshInvalidatedFiles() async { | 273 Future<Null> _refreshInvalidatedFiles() async { |
| 258 await _logger.runAsync('Refresh invalidated files', () async { | 274 await _logger.runAsync('Refresh invalidated files', () async { |
| 259 for (var fileUri in _invalidatedFiles) { | 275 for (var fileUri in _invalidatedFiles) { |
| 260 var file = await _fsState.getFile(fileUri); | 276 var file = await _fsState.getFile(fileUri); |
| 261 await file.refresh(); | 277 await file.refresh(); |
| 262 } | 278 } |
| 263 _invalidatedFiles.clear(); | 279 _invalidatedFiles.clear(); |
| 264 }); | 280 }); |
| 265 } | 281 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 284 /// TODO(scheglov) Use API signatures. | 300 /// TODO(scheglov) Use API signatures. |
| 285 /// TODO(scheglov) Or use tree shaking and compute signatures of outlines. | 301 /// TODO(scheglov) Or use tree shaking and compute signatures of outlines. |
| 286 final String signature; | 302 final String signature; |
| 287 | 303 |
| 288 /// Kernel libraries for libraries in the [cycle]. Bodies of dependencies | 304 /// Kernel libraries for libraries in the [cycle]. Bodies of dependencies |
| 289 /// are not included, but but references to those dependencies are included. | 305 /// are not included, but but references to those dependencies are included. |
| 290 final List<Library> kernelLibraries; | 306 final List<Library> kernelLibraries; |
| 291 | 307 |
| 292 _LibraryCycleResult(this.cycle, this.signature, this.kernelLibraries); | 308 _LibraryCycleResult(this.cycle, this.signature, this.kernelLibraries); |
| 293 } | 309 } |
| OLD | NEW |