| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2015, 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 import 'dart:io'; | |
| 6 | |
| 7 import 'dart:async' show | |
| 8 EventSink, | |
| 9 Future, | |
| 10 Stream, | |
| 11 StreamController, | |
| 12 StreamSubscription; | |
| 13 | |
| 14 import 'package:dart2js_incremental/dart2js_incremental.dart' show | |
| 15 IncrementalCompilationFailed, | |
| 16 IncrementalCompiler; | |
| 17 | |
| 18 import 'package:compiler/compiler_new.dart' show | |
| 19 CompilerOutput; | |
| 20 | |
| 21 import 'package:compiler/src/old_to_new_api.dart' show | |
| 22 LegacyCompilerDiagnostics, | |
| 23 LegacyCompilerInput; | |
| 24 | |
| 25 import 'package:compiler/src/source_file_provider.dart' show | |
| 26 FormattingDiagnosticHandler; | |
| 27 | |
| 28 import 'watcher.dart'; | |
| 29 | |
| 30 main(List<String> arguments) { | |
| 31 int updateCount = 0; | |
| 32 StreamSubscription<CompilerEvent> subscription = | |
| 33 compile(Uri.base.resolve(arguments.first)).listen(null); | |
| 34 subscription.onData((CompilerEvent event) { | |
| 35 switch (event.kind) { | |
| 36 case IncrementalKind.FULL: | |
| 37 updateCount = 0; | |
| 38 print('// Compiled JavaScript:'); | |
| 39 print(event['.js']); | |
| 40 break; | |
| 41 | |
| 42 case IncrementalKind.INCREMENTAL: | |
| 43 Stopwatch sw = event.stopwatch..start(); | |
| 44 String updates = '${event.compiler.allUpdates()}'; | |
| 45 sw.stop(); | |
| 46 | |
| 47 print('// Patch after ${++updateCount} updates,'); | |
| 48 print('// computed in ${sw.elapsedMicroseconds/1000000} seconds:'); | |
| 49 print(updates); | |
| 50 break; | |
| 51 | |
| 52 case IncrementalKind.ERROR: | |
| 53 updateCount = 0; | |
| 54 print("Compilation failed"); | |
| 55 break; | |
| 56 | |
| 57 default: | |
| 58 throw "Unknown kind: ${event.kind}"; | |
| 59 } | |
| 60 }); | |
| 61 subscription.onError((error, StackTrace trace) { | |
| 62 if (error is IncrementalCompilationFailed) { | |
| 63 print("Incremental compilation failed due to:\n${error.reason}"); | |
| 64 } else { | |
| 65 throw error; | |
| 66 } | |
| 67 }); | |
| 68 } | |
| 69 | |
| 70 Stream<CompilerEvent> compile(Uri originalInput) { | |
| 71 StreamController<CompilerEvent> controller = | |
| 72 new StreamController<CompilerEvent>(); | |
| 73 compileToStream(originalInput, controller); | |
| 74 return controller.stream; | |
| 75 } | |
| 76 | |
| 77 compileToStream( | |
| 78 Uri originalInput, | |
| 79 StreamController<CompilerEvent> controller) async { | |
| 80 var watcher = new Watcher(); | |
| 81 | |
| 82 Uri libraryRoot = Uri.base.resolve('sdk/'); | |
| 83 Uri packageRoot = Uri.base.resolve('packages/'); | |
| 84 | |
| 85 FormattingDiagnosticHandler diagnosticHandler = | |
| 86 new FormattingDiagnosticHandler(); | |
| 87 | |
| 88 OutputProvider outputProvider = new OutputProvider(); | |
| 89 | |
| 90 void resilientDiagnosticHandler( | |
| 91 Uri uri, int begin, int end, String message, kind) { | |
| 92 try { | |
| 93 diagnosticHandler(uri, begin, end, message, kind); | |
| 94 } catch (e) { | |
| 95 String name = diagnosticHandler.provider.relativizeUri(uri); | |
| 96 print('$name@$begin+${end - begin}: [$kind] $message}'); | |
| 97 } | |
| 98 } | |
| 99 | |
| 100 Future inputProvider(Uri uri) { | |
| 101 if (uri.scheme == "file") { | |
| 102 if (!'$uri'.startsWith('$libraryRoot')) { | |
| 103 watcher.watchFile(uri); | |
| 104 } | |
| 105 } | |
| 106 return diagnosticHandler.provider(uri); | |
| 107 } | |
| 108 | |
| 109 while (true) { | |
| 110 Stopwatch sw = new Stopwatch()..start(); | |
| 111 IncrementalCompiler compiler = new IncrementalCompiler( | |
| 112 libraryRoot: libraryRoot, | |
| 113 packageRoot: packageRoot, | |
| 114 inputProvider: new LegacyCompilerInput(inputProvider), | |
| 115 diagnosticHandler: | |
| 116 new LegacyCompilerDiagnostics(resilientDiagnosticHandler), | |
| 117 outputProvider: outputProvider); | |
| 118 | |
| 119 bool success = await compiler.compile(originalInput); | |
| 120 sw.stop(); | |
| 121 if (success) { | |
| 122 controller.add( | |
| 123 new CompilerEvent( | |
| 124 IncrementalKind.FULL, compiler, outputProvider.output, sw)); | |
| 125 } else { | |
| 126 controller.add( | |
| 127 new CompilerEvent( | |
| 128 IncrementalKind.ERROR, compiler, outputProvider.output, sw)); | |
| 129 } | |
| 130 | |
| 131 while (await watcher.hasChanges()) { | |
| 132 try { | |
| 133 Map<Uri, Uri> changes = watcher.readChanges(); | |
| 134 | |
| 135 sw = new Stopwatch()..start(); | |
| 136 String updates = await compiler.compileUpdates(changes); | |
| 137 sw.stop(); | |
| 138 | |
| 139 controller.add( | |
| 140 new CompilerEvent( | |
| 141 IncrementalKind.INCREMENTAL, compiler, outputProvider.output, | |
| 142 sw, updates: updates)); | |
| 143 | |
| 144 } on IncrementalCompilationFailed catch (error, trace) { | |
| 145 controller.addError(error, trace); | |
| 146 break; | |
| 147 } | |
| 148 } | |
| 149 } | |
| 150 } | |
| 151 | |
| 152 /// Output provider which collects output in [output]. | |
| 153 class OutputProvider implements CompilerOutput { | |
| 154 final Map<String, String> output = new Map<String, String>(); | |
| 155 | |
| 156 EventSink<String> createEventSink(String name, String extension) { | |
| 157 return new StringEventSink((String data) { | |
| 158 output['$name.$extension'] = data; | |
| 159 }); | |
| 160 } | |
| 161 | |
| 162 String operator[](String key) => output[key]; | |
| 163 } | |
| 164 | |
| 165 /// Helper class to collect sources. | |
| 166 class StringEventSink implements EventSink<String> { | |
| 167 List<String> data = <String>[]; | |
| 168 | |
| 169 final Function onClose; | |
| 170 | |
| 171 StringEventSink(this.onClose); | |
| 172 | |
| 173 void add(String event) { | |
| 174 if (data == null) throw 'StringEventSink is closed.'; | |
| 175 data.add(event); | |
| 176 } | |
| 177 | |
| 178 void addError(errorEvent, [StackTrace stackTrace]) { | |
| 179 throw 'addError($errorEvent, $stackTrace)'; | |
| 180 } | |
| 181 | |
| 182 void close() { | |
| 183 if (data != null) { | |
| 184 onClose(data.join()); | |
| 185 data = null; | |
| 186 } | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 enum IncrementalKind { | |
| 191 FULL, | |
| 192 INCREMENTAL, | |
| 193 ERROR, | |
| 194 } | |
| 195 | |
| 196 class CompilerEvent { | |
| 197 final IncrementalKind kind; | |
| 198 | |
| 199 final IncrementalCompiler compiler; | |
| 200 | |
| 201 final Map<String, String> _output; | |
| 202 | |
| 203 final Stopwatch stopwatch; | |
| 204 | |
| 205 final String updates; | |
| 206 | |
| 207 CompilerEvent( | |
| 208 this.kind, this.compiler, this._output, this.stopwatch, {this.updates}); | |
| 209 | |
| 210 String operator[](String key) => _output[key]; | |
| 211 } | |
| OLD | NEW |