| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013, 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 compiler_isolate; | |
| 6 | |
| 7 import 'dart:async'; | |
| 8 import 'dart:html'; | |
| 9 import 'dart:isolate'; | |
| 10 import 'dart:convert' show JSON; | |
| 11 | |
| 12 import 'compilation.dart' show PRIVATE_SCHEME; | |
| 13 | |
| 14 import 'package:compiler/compiler.dart' as compiler; | |
| 15 | |
| 16 import 'package:compiler/src/old_to_new_api.dart' show | |
| 17 LegacyCompilerDiagnostics, LegacyCompilerInput; | |
| 18 | |
| 19 import 'package:dart2js_incremental/dart2js_incremental.dart' show | |
| 20 reuseCompiler, OutputProvider; | |
| 21 | |
| 22 import 'package:compiler/src/compiler.dart' show | |
| 23 Compiler; | |
| 24 | |
| 25 const bool THROW_ON_ERROR = false; | |
| 26 | |
| 27 final cachedSources = new Map<Uri, Future<String>>(); | |
| 28 | |
| 29 Uri sdkLocation; | |
| 30 List options = []; | |
| 31 | |
| 32 var communicateViaBlobs; | |
| 33 | |
| 34 var cachedCompiler; | |
| 35 | |
| 36 void notifyDartHtml(SendPort port) { | |
| 37 // Notify the controlling isolate (Try Dart UI) that the program imports | |
| 38 // dart:html. This is used to determine how to run the program: in an iframe | |
| 39 // or in a worker. | |
| 40 port.send('dart:html'); | |
| 41 } | |
| 42 | |
| 43 compile(source, SendPort replyTo) { | |
| 44 if (sdkLocation == null) { | |
| 45 // The first message received gives us the URI of this web app. | |
| 46 if (source.endsWith('/sdk.json')) { | |
| 47 var request = new HttpRequest(); | |
| 48 request.open('GET', source, async: false); | |
| 49 request.send(null); | |
| 50 if (request.status != 200) { | |
| 51 throw 'SDK not found at $source'; | |
| 52 } | |
| 53 sdkLocation = Uri.parse('sdk:/sdk/'); | |
| 54 JSON.decode(request.responseText).forEach((file, content) { | |
| 55 cachedSources[Uri.parse(file)] = new Future<String>.value(content); | |
| 56 }); | |
| 57 } else { | |
| 58 sdkLocation = Uri.parse(source); | |
| 59 } | |
| 60 replyTo.send(null); | |
| 61 return; | |
| 62 } | |
| 63 if (source is List) { | |
| 64 String messageType = (source.length > 0) ? source[0] : null; | |
| 65 var data = (source.length > 1) ? source[1] : null; | |
| 66 if (messageType == 'options') { | |
| 67 options = data as List; | |
| 68 } if (messageType == 'communicateViaBlobs') { | |
| 69 communicateViaBlobs = data as bool; | |
| 70 } | |
| 71 return; | |
| 72 } | |
| 73 int charactersRead = 0; | |
| 74 Future<String> inputProvider(Uri uri) { | |
| 75 Future<String> future; | |
| 76 if (uri.scheme == 'sdk') { | |
| 77 if (uri.path.endsWith('/lib/html/dart2js/html_dart2js.dart')) { | |
| 78 notifyDartHtml(replyTo); | |
| 79 } | |
| 80 future = cachedSources[uri]; | |
| 81 } else if (uri.scheme == 'http' || uri.scheme == 'https') { | |
| 82 future = | |
| 83 cachedSources.putIfAbsent(uri, () => HttpRequest.getString('$uri')); | |
| 84 } else if ('$uri' == '$PRIVATE_SCHEME:/main.dart') { | |
| 85 future = new Future<String>.value(source); | |
| 86 } else if (uri.scheme == PRIVATE_SCHEME) { | |
| 87 future = HttpRequest.getString('project${uri.path}'); | |
| 88 } | |
| 89 if (future == null) { | |
| 90 future = new Future<String>.error('$uri: Not found'); | |
| 91 } | |
| 92 return future.then((String value) { | |
| 93 charactersRead += value.length; | |
| 94 return value; | |
| 95 }).catchError((Event event) { | |
| 96 var target = event.target; | |
| 97 if (target is HttpRequest) { | |
| 98 throw '$uri: ${target.statusText}'; | |
| 99 } else { | |
| 100 throw event; | |
| 101 } | |
| 102 }, test: (error) => error is Event); | |
| 103 } | |
| 104 void handler(Uri uri, int begin, int end, | |
| 105 String message, compiler.Diagnostic kind) { | |
| 106 replyTo.send(['diagnostic', { 'uri': '$uri', | |
| 107 'begin': begin, | |
| 108 'end': end, | |
| 109 'message': message, | |
| 110 'kind': kind.name }]); | |
| 111 if (THROW_ON_ERROR && kind == compiler.Diagnostic.ERROR) { | |
| 112 throw new Exception('Throw on error'); | |
| 113 } | |
| 114 } | |
| 115 Stopwatch compilationTimer = new Stopwatch()..start(); | |
| 116 OutputProvider outputProvider = new OutputProvider(); | |
| 117 reuseCompiler( | |
| 118 diagnosticHandler: new LegacyCompilerDiagnostics(handler), | |
| 119 inputProvider: new LegacyCompilerInput(inputProvider), | |
| 120 outputProvider: outputProvider, | |
| 121 options: options, | |
| 122 cachedCompiler: cachedCompiler, | |
| 123 libraryRoot: sdkLocation, | |
| 124 packageRoot: Uri.base.resolve('/packages/'), | |
| 125 packagesAreImmutable: true).then((Compiler newCompiler) { | |
| 126 cachedCompiler = newCompiler; | |
| 127 return cachedCompiler.run(Uri.parse('$PRIVATE_SCHEME:/main.dart')); | |
| 128 }).then((success) { | |
| 129 compilationTimer.stop(); | |
| 130 print('Compilation took ${compilationTimer.elapsed}'); | |
| 131 if (cachedCompiler.libraryLoader | |
| 132 .lookupLibrary(Uri.parse('dart:html')) != null) { | |
| 133 notifyDartHtml(replyTo); | |
| 134 } | |
| 135 String js = outputProvider['.js']; | |
| 136 if (js == null) { | |
| 137 if (!options.contains('--analyze-only')) replyTo.send('failed'); | |
| 138 } else { | |
| 139 var url; | |
| 140 handler(null, 0, 0, | |
| 141 'Compiled ${source.length}/${charactersRead} characters Dart' | |
| 142 ' -> ${js.length} characters.', | |
| 143 compiler.Diagnostic.VERBOSE_INFO); | |
| 144 if (communicateViaBlobs) { | |
| 145 try { | |
| 146 // At least Safari and Firefox do not support creating an | |
| 147 // object URL from a web worker. MDN claims that it will be | |
| 148 // supported in Firefox 21. | |
| 149 url = Url.createObjectUrl(new Blob([js], 'application/javascript')); | |
| 150 } catch (_) { | |
| 151 // Ignored. | |
| 152 } | |
| 153 } else { | |
| 154 url = null; | |
| 155 } | |
| 156 if (url != null) { | |
| 157 replyTo.send(['url', url]); | |
| 158 } else { | |
| 159 replyTo.send(['code', js]); | |
| 160 } | |
| 161 } | |
| 162 }).catchError((e, trace) { | |
| 163 replyTo.send(['crash', '$e, $trace']); | |
| 164 }).whenComplete(() { | |
| 165 replyTo.send('done'); | |
| 166 }); | |
| 167 } | |
| 168 | |
| 169 void main(List<String> arguments, SendPort port) { | |
| 170 ReceivePort replyTo = new ReceivePort(); | |
| 171 port.send(replyTo.sendPort); | |
| 172 replyTo.listen((message) { | |
| 173 try { | |
| 174 List list = message as List; | |
| 175 compile(list[0], list[1]); | |
| 176 } catch (exception, stack) { | |
| 177 port.send('$exception\n$stack'); | |
| 178 } | |
| 179 }); | |
| 180 } | |
| OLD | NEW |