| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 library dart2js_incremental; | |
| 6 | |
| 7 import 'dart:async' show | |
| 8 EventSink, | |
| 9 Future; | |
| 10 | |
| 11 import 'dart:developer' show | |
| 12 UserTag; | |
| 13 | |
| 14 import 'package:compiler/src/apiimpl.dart' show | |
| 15 CompilerImpl; | |
| 16 | |
| 17 import 'package:compiler/compiler_new.dart' show | |
| 18 CompilerDiagnostics, | |
| 19 CompilerInput, | |
| 20 CompilerOutput, | |
| 21 Diagnostic; | |
| 22 | |
| 23 import 'package:compiler/src/options.dart' show | |
| 24 CompilerOptions; | |
| 25 | |
| 26 import 'package:compiler/src/null_compiler_output.dart' show | |
| 27 NullCompilerOutput; | |
| 28 | |
| 29 import 'package:compiler/src/js_backend/js_backend.dart' show | |
| 30 JavaScriptBackend; | |
| 31 | |
| 32 import 'package:compiler/src/js_emitter/full_emitter/emitter.dart' | |
| 33 as full show Emitter; | |
| 34 | |
| 35 import 'package:compiler/src/elements/elements.dart' show | |
| 36 LibraryElement; | |
| 37 | |
| 38 import 'library_updater.dart' show | |
| 39 IncrementalCompilerContext, | |
| 40 LibraryUpdater, | |
| 41 Logger; | |
| 42 | |
| 43 import 'package:compiler/src/js/js.dart' as jsAst; | |
| 44 | |
| 45 part 'caching_compiler.dart'; | |
| 46 | |
| 47 const List<String> INCREMENTAL_OPTIONS = const <String>[ | |
| 48 '--disable-type-inference', | |
| 49 '--incremental-support', | |
| 50 '--generate-code-with-compile-time-errors', | |
| 51 '--no-source-maps', // TODO(ahe): Remove this. | |
| 52 ]; | |
| 53 | |
| 54 class IncrementalCompiler { | |
| 55 final Uri libraryRoot; | |
| 56 final Uri packageRoot; | |
| 57 final Uri packageConfig; | |
| 58 final CompilerInput inputProvider; | |
| 59 final CompilerDiagnostics diagnosticHandler; | |
| 60 final List<String> options; | |
| 61 final CompilerOutput outputProvider; | |
| 62 final Map<String, dynamic> environment; | |
| 63 final List<String> _updates = <String>[]; | |
| 64 final IncrementalCompilerContext _context = new IncrementalCompilerContext(); | |
| 65 | |
| 66 CompilerImpl _compiler; | |
| 67 | |
| 68 IncrementalCompiler({ | |
| 69 this.libraryRoot, | |
| 70 this.packageRoot, | |
| 71 this.packageConfig, | |
| 72 this.inputProvider, | |
| 73 this.diagnosticHandler, | |
| 74 this.options, | |
| 75 this.outputProvider, | |
| 76 this.environment}) { | |
| 77 if (libraryRoot == null) { | |
| 78 throw new ArgumentError('libraryRoot is null.'); | |
| 79 } | |
| 80 if (inputProvider == null) { | |
| 81 throw new ArgumentError('inputProvider is null.'); | |
| 82 } | |
| 83 if (outputProvider == null) { | |
| 84 throw new ArgumentError('outputProvider is null.'); | |
| 85 } | |
| 86 if (diagnosticHandler == null) { | |
| 87 throw new ArgumentError('diagnosticHandler is null.'); | |
| 88 } | |
| 89 _context.incrementalCompiler = this; | |
| 90 } | |
| 91 | |
| 92 LibraryElement get mainApp => _compiler.mainApp; | |
| 93 | |
| 94 CompilerImpl get compiler => _compiler; | |
| 95 | |
| 96 Future<bool> compile(Uri script) { | |
| 97 return _reuseCompiler(null).then((CompilerImpl compiler) { | |
| 98 _compiler = compiler; | |
| 99 return compiler.run(script); | |
| 100 }); | |
| 101 } | |
| 102 | |
| 103 Future<CompilerImpl> _reuseCompiler( | |
| 104 Future<bool> reuseLibrary(LibraryElement library)) { | |
| 105 List<String> options = this.options == null | |
| 106 ? <String> [] : new List<String>.from(this.options); | |
| 107 options.addAll(INCREMENTAL_OPTIONS); | |
| 108 return reuseCompiler( | |
| 109 cachedCompiler: _compiler, | |
| 110 libraryRoot: libraryRoot, | |
| 111 packageRoot: packageRoot, | |
| 112 packageConfig: packageConfig, | |
| 113 inputProvider: inputProvider, | |
| 114 diagnosticHandler: diagnosticHandler, | |
| 115 options: options, | |
| 116 outputProvider: outputProvider, | |
| 117 environment: environment, | |
| 118 reuseLibrary: reuseLibrary); | |
| 119 } | |
| 120 | |
| 121 Future<String> compileUpdates( | |
| 122 Map<Uri, Uri> updatedFiles, | |
| 123 {Logger logTime, | |
| 124 Logger logVerbose}) { | |
| 125 if (logTime == null) { | |
| 126 logTime = (_) {}; | |
| 127 } | |
| 128 if (logVerbose == null) { | |
| 129 logVerbose = (_) {}; | |
| 130 } | |
| 131 Future mappingInputProvider(Uri uri) { | |
| 132 Uri updatedFile = updatedFiles[uri]; | |
| 133 return inputProvider.readFromUri(updatedFile == null ? uri : updatedFile); | |
| 134 } | |
| 135 LibraryUpdater updater = new LibraryUpdater( | |
| 136 _compiler, | |
| 137 mappingInputProvider, | |
| 138 logTime, | |
| 139 logVerbose, | |
| 140 _context); | |
| 141 _context.registerUriWithUpdates(updatedFiles.keys); | |
| 142 Future<CompilerImpl> future = _reuseCompiler(updater.reuseLibrary); | |
| 143 return future.then((CompilerImpl compiler) { | |
| 144 _compiler = compiler; | |
| 145 if (compiler.compilationFailed) { | |
| 146 return null; | |
| 147 } else { | |
| 148 String update = updater.computeUpdateJs(); | |
| 149 _updates.add(update); | |
| 150 return update; | |
| 151 } | |
| 152 }); | |
| 153 } | |
| 154 | |
| 155 String allUpdates() { | |
| 156 jsAst.Node updates = jsAst.js.escapedString(_updates.join("")); | |
| 157 | |
| 158 JavaScriptBackend backend = _compiler.backend; | |
| 159 | |
| 160 jsAst.FunctionDeclaration mainRunner = jsAst.js.statement(r""" | |
| 161 function dartMainRunner(main, args) { | |
| 162 #helper.patch(#updates + "\n//# sourceURL=initial_patch.js\n"); | |
| 163 return main(args); | |
| 164 }""", {'updates': updates, 'helper': backend.namer.accessIncrementalHelper}); | |
| 165 | |
| 166 return jsAst.prettyPrint(mainRunner, _compiler).getText(); | |
| 167 } | |
| 168 } | |
| 169 | |
| 170 class IncrementalCompilationFailed { | |
| 171 final String reason; | |
| 172 | |
| 173 const IncrementalCompilationFailed(this.reason); | |
| 174 | |
| 175 String toString() => "Can't incrementally compile program.\n\n$reason"; | |
| 176 } | |
| OLD | NEW |