| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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 library trydart.compilation; | 5 library trydart.compilation; |
| 6 | 6 |
| 7 import 'dart:html' show | 7 import 'dart:html' show |
| 8 Blob, | 8 Blob, |
| 9 Element, | 9 Element, |
| 10 ErrorEvent, | 10 ErrorEvent, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 if (!CompilationProcess.shouldStartCompilation()) return false; | 64 if (!CompilationProcess.shouldStartCompilation()) return false; |
| 65 new CompilationProcess(currentSource, outputDiv).start(); | 65 new CompilationProcess(currentSource, outputDiv).start(); |
| 66 return true; | 66 return true; |
| 67 } | 67 } |
| 68 | 68 |
| 69 class CompilationProcess { | 69 class CompilationProcess { |
| 70 final String source; | 70 final String source; |
| 71 final Element console; | 71 final Element console; |
| 72 final ReceivePort receivePort = new ReceivePort(); | 72 final ReceivePort receivePort = new ReceivePort(); |
| 73 final Set<String> seenMessages = new Set<String>(); | 73 final Set<String> seenMessages = new Set<String>(); |
| 74 bool isCleared = false; | |
| 75 bool isDone = false; | 74 bool isDone = false; |
| 76 bool usesDartHtml = false; | 75 bool usesDartHtml = false; |
| 77 Worker worker; | 76 Worker worker; |
| 78 List<String> objectUrls = <String>[]; | 77 List<String> objectUrls = <String>[]; |
| 79 | 78 |
| 80 static CompilationProcess current; | 79 static CompilationProcess current; |
| 81 | 80 |
| 82 CompilationProcess(this.source, this.console); | 81 CompilationProcess(this.source, this.console); |
| 83 | 82 |
| 84 static bool shouldStartCompilation() { | 83 static bool shouldStartCompilation() { |
| 85 if (compilerPort == null) return false; | 84 if (compilerPort == null) return false; |
| 86 if (isMalformedInput) return false; | 85 if (isMalformedInput) return false; |
| 87 if (current != null) return current.isDone; | 86 if (current != null) return current.isDone; |
| 88 return true; | 87 return true; |
| 89 } | 88 } |
| 90 | 89 |
| 91 void clear() { | |
| 92 if (verboseCompiler) return; | |
| 93 if (!isCleared) console.nodes.clear(); | |
| 94 isCleared = true; | |
| 95 } | |
| 96 | |
| 97 void start() { | 90 void start() { |
| 98 if (!shouldStartCompilation()) { | 91 if (!shouldStartCompilation()) { |
| 99 receivePort.close(); | 92 receivePort.close(); |
| 100 return; | 93 return; |
| 101 } | 94 } |
| 102 if (current != null) current.dispose(); | 95 if (current != null) current.dispose(); |
| 103 current = this; | 96 current = this; |
| 104 console.nodes.clear(); | |
| 105 var options = [ | 97 var options = [ |
| 106 '--analyze-main', | 98 '--analyze-main', |
| 107 '--disable-type-inference', | 99 '--disable-type-inference', |
| 108 '--incremental-support', | 100 '--incremental-support', |
| 109 '--no-source-maps', | 101 '--no-source-maps', |
| 110 ]; | 102 ]; |
| 111 if (verboseCompiler) options.add('--verbose'); | 103 if (verboseCompiler) options.add('--verbose'); |
| 112 if (minified) options.add('--minify'); | 104 if (minified) options.add('--minify'); |
| 113 if (onlyAnalyze) options.add('--analyze-only'); | 105 if (onlyAnalyze) options.add('--analyze-only'); |
| 114 interaction.compilationStarting(); | 106 interaction.compilationStarting(); |
| 115 compilerPort.send([['options', options], receivePort.sendPort]); | 107 compilerPort.send([['options', options], receivePort.sendPort]); |
| 116 console.appendHtml('<i class="icon-spinner icon-spin"></i>'); | |
| 117 console.appendText(' Compiling Dart program...\n'); | |
| 118 outputFrame.style.display = 'none'; | |
| 119 receivePort.listen(onMessage); | 108 receivePort.listen(onMessage); |
| 120 compilerPort.send([source, receivePort.sendPort]); | 109 compilerPort.send([source, receivePort.sendPort]); |
| 121 } | 110 } |
| 122 | 111 |
| 123 void dispose() { | 112 void dispose() { |
| 124 if (worker != null) worker.terminate(); | 113 if (worker != null) worker.terminate(); |
| 125 objectUrls.forEach(Url.revokeObjectUrl); | 114 objectUrls.forEach(Url.revokeObjectUrl); |
| 126 } | 115 } |
| 127 | 116 |
| 128 onMessage(message) { | 117 onMessage(message) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 139 default: | 128 default: |
| 140 throw ['Unknown message kind', message]; | 129 throw ['Unknown message kind', message]; |
| 141 } | 130 } |
| 142 } | 131 } |
| 143 | 132 |
| 144 onDartHtml(_) { | 133 onDartHtml(_) { |
| 145 usesDartHtml = true; | 134 usesDartHtml = true; |
| 146 } | 135 } |
| 147 | 136 |
| 148 onFail(_) { | 137 onFail(_) { |
| 149 clear(); | 138 // TODO(ahe): Call interaction.onCompilationFailed(). |
| 150 consolePrint('Compilation failed'); | 139 interaction.consolePrintLine('Compilation failed'); |
| 151 } | 140 } |
| 152 | 141 |
| 153 onDone(_) { | 142 onDone(_) { |
| 154 interaction.onCompilationDone(); | 143 interaction.onCompilationDone(); |
| 155 isDone = true; | 144 isDone = true; |
| 156 receivePort.close(); | 145 receivePort.close(); |
| 157 } | 146 } |
| 158 | 147 |
| 159 // This is called in browsers that support creating Object URLs in a | 148 // This is called in browsers that support creating Object URLs in a |
| 160 // web worker. For example, Chrome and Firefox 21. | 149 // web worker. For example, Chrome and Firefox 21. |
| 161 onUrl(String url) { | 150 onUrl(String url) { |
| 162 objectUrls.add(url); | 151 objectUrls.add(url); |
| 163 clear(); | |
| 164 String wrapper = ''' | 152 String wrapper = ''' |
| 165 // Fool isolate_helper.dart so it does not think this is an isolate. | 153 // Fool isolate_helper.dart so it does not think this is an isolate. |
| 166 var window = self; | 154 var window = self; |
| 167 function dartPrint(msg) { | 155 function dartPrint(msg) { |
| 168 self.postMessage(msg); | 156 self.postMessage(msg); |
| 169 }; | 157 }; |
| 170 self.importScripts("$url"); | 158 self.importScripts("$url"); |
| 171 '''; | 159 '''; |
| 172 var wrapperUrl = | 160 var wrapperUrl = |
| 173 Url.createObjectUrl(new Blob([wrapper], 'application/javascript')); | 161 Url.createObjectUrl(new Blob([wrapper], 'application/javascript')); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 187 if (usesDartHtml && !alwaysRunInWorker) { | 175 if (usesDartHtml && !alwaysRunInWorker) { |
| 188 retryInIframe(null); | 176 retryInIframe(null); |
| 189 } else { | 177 } else { |
| 190 runInWorker(wrapperUrl, onError); | 178 runInWorker(wrapperUrl, onError); |
| 191 } | 179 } |
| 192 } | 180 } |
| 193 | 181 |
| 194 // This is called in browsers that do not support creating Object | 182 // This is called in browsers that do not support creating Object |
| 195 // URLs in a web worker. For example, Safari and Firefox < 21. | 183 // URLs in a web worker. For example, Safari and Firefox < 21. |
| 196 onCode(String code) { | 184 onCode(String code) { |
| 197 clear(); | |
| 198 | |
| 199 void retryInIframe(_) { | 185 void retryInIframe(_) { |
| 200 // The obvious thing would be to call [makeOutputFrame], but | 186 // The obvious thing would be to call [makeOutputFrame], but |
| 201 // Safari doesn't support access to Object URLs in an iframe. | 187 // Safari doesn't support access to Object URLs in an iframe. |
| 202 | 188 |
| 203 var frame = new IFrameElement() | 189 var frame = new IFrameElement() |
| 204 ..src = 'iframe.html' | 190 ..src = 'iframe.html' |
| 205 ..style.width = '100%' | 191 ..style.width = '100%' |
| 206 ..style.height = '0px'; | 192 ..style.height = '0px'; |
| 207 frame.onLoad.listen((_) { | 193 frame.onLoad.listen((_) { |
| 208 frame.contentWindow.postMessage(['source', code], '*'); | 194 frame.contentWindow.postMessage(['source', code], '*'); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 229 if (usesDartHtml && !alwaysRunInWorker) { | 215 if (usesDartHtml && !alwaysRunInWorker) { |
| 230 retryInIframe(null); | 216 retryInIframe(null); |
| 231 } else { | 217 } else { |
| 232 runInWorker(url, onError); | 218 runInWorker(url, onError); |
| 233 } | 219 } |
| 234 } | 220 } |
| 235 | 221 |
| 236 void runInWorker(String url, void onError(String errorMessage)) { | 222 void runInWorker(String url, void onError(String errorMessage)) { |
| 237 worker = new Worker(url) | 223 worker = new Worker(url) |
| 238 ..onMessage.listen((MessageEvent event) { | 224 ..onMessage.listen((MessageEvent event) { |
| 239 consolePrint(event.data); | 225 interaction.consolePrintLine(event.data); |
| 240 }) | 226 }) |
| 241 ..onError.listen((ErrorEvent event) { | 227 ..onError.listen((ErrorEvent event) { |
| 242 worker.terminate(); | 228 worker.terminate(); |
| 243 worker = null; | 229 worker = null; |
| 244 onError(event.message); | 230 onError(event.message); |
| 245 }); | 231 }); |
| 246 } | 232 } |
| 247 | 233 |
| 248 onDiagnostic(Map<String, dynamic> diagnostic) { | 234 onDiagnostic(Map<String, dynamic> diagnostic) { |
| 249 if (currentSource != source) return; | 235 if (currentSource != source) return; |
| 250 String kind = diagnostic['kind']; | 236 String kind = diagnostic['kind']; |
| 251 String message = diagnostic['message']; | 237 String message = diagnostic['message']; |
| 252 if (kind == 'verbose info') { | 238 if (kind == 'verbose info') { |
| 253 if (verboseCompiler) { | 239 interaction.verboseCompilerMessage(message); |
| 254 consolePrint(message); | |
| 255 } else { | |
| 256 console.appendText('.'); | |
| 257 } | |
| 258 return; | 240 return; |
| 259 } | 241 } |
| 260 String uri = diagnostic['uri']; | 242 String uri = diagnostic['uri']; |
| 261 if (uri != '${PRIVATE_SCHEME}:/main.dart') { | 243 if (uri != '${PRIVATE_SCHEME}:/main.dart') { |
| 262 consolePrint('$uri: [$kind] $message'); | 244 interaction.consolePrintLine('$uri: [$kind] $message'); |
| 263 return; | 245 return; |
| 264 } | 246 } |
| 265 int begin = diagnostic['begin']; | 247 int begin = diagnostic['begin']; |
| 266 int end = diagnostic['end']; | 248 int end = diagnostic['end']; |
| 267 if (begin == null) return; | 249 if (begin == null) return; |
| 268 if (seenMessages.add('$begin:$end: [$kind] $message')) { | 250 if (seenMessages.add('$begin:$end: [$kind] $message')) { |
| 269 // Guard against duplicated messages. | 251 // Guard against duplicated messages. |
| 270 addDiagnostic(kind, message, begin, end); | 252 addDiagnostic(kind, message, begin, end); |
| 271 } | 253 } |
| 272 } | 254 } |
| 273 | 255 |
| 274 onCrash(data) { | 256 onCrash(data) { |
| 275 consolePrint(data); | 257 interaction.consolePrintLine(data); |
| 276 } | |
| 277 | |
| 278 void consolePrint(message) { | |
| 279 if (window.parent != window) { | |
| 280 // Test support. | |
| 281 // TODO(ahe): Use '/' instead of '*' when Firefox is upgraded to version | |
| 282 // 30 across build bots. Support for '/' was added in version 29, and we | |
| 283 // support the two most recent versions. | |
| 284 window.parent.postMessage('$message\n', '*'); | |
| 285 } | |
| 286 console.appendText('$message\n'); | |
| 287 } | 258 } |
| 288 } | 259 } |
| OLD | NEW |