| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 dart2js; | 5 library dart2js; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection' show Queue, LinkedHashMap; | 8 import 'dart:collection' show Queue, LinkedHashMap; |
| 9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 import 'dart:uri'; | 10 import 'dart:uri'; |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 if (arguments.isEmpty) { | 226 if (arguments.isEmpty) { |
| 227 helpAndFail('Error: No Dart file specified.'); | 227 helpAndFail('Error: No Dart file specified.'); |
| 228 } | 228 } |
| 229 if (arguments.length > 1) { | 229 if (arguments.length > 1) { |
| 230 var extra = arguments.getRange(1, arguments.length - 1); | 230 var extra = arguments.getRange(1, arguments.length - 1); |
| 231 helpAndFail('Error: Extra arguments: ${Strings.join(extra, " ")}'); | 231 helpAndFail('Error: Extra arguments: ${Strings.join(extra, " ")}'); |
| 232 } | 232 } |
| 233 | 233 |
| 234 void handler(Uri uri, int begin, int end, String message, | 234 void handler(Uri uri, int begin, int end, String message, |
| 235 api.Diagnostic kind) { | 235 api.Diagnostic kind) { |
| 236 if (identical(kind.name, 'source map')) { | |
| 237 // TODO(podivilov): We should find a better way to return source maps from | |
| 238 // emitter. Using diagnostic handler for that purpose is a temporary hack. | |
| 239 writeString(sourceMapOut, message); | |
| 240 return; | |
| 241 } | |
| 242 diagnosticHandler.diagnosticHandler(uri, begin, end, message, kind); | 236 diagnosticHandler.diagnosticHandler(uri, begin, end, message, kind); |
| 243 } | 237 } |
| 244 | 238 |
| 245 Uri uri = cwd.resolve(arguments[0]); | 239 Uri uri = cwd.resolve(arguments[0]); |
| 246 if (packageRoot == null) { | 240 if (packageRoot == null) { |
| 247 packageRoot = uri.resolve('./packages/'); | 241 packageRoot = uri.resolve('./packages/'); |
| 248 } | 242 } |
| 249 | 243 |
| 250 diagnosticHandler.info('package root is $packageRoot'); | 244 diagnosticHandler.info('package root is $packageRoot'); |
| 251 | 245 |
| 252 // TODO(ahe): We expect the future to be complete and call value | 246 int charactersWritten = 0; |
| 253 // directly. In effect, we don't support truly asynchronous API. | |
| 254 String code = deprecatedFutureValue( | |
| 255 api.compile(uri, libraryRoot, packageRoot, | |
| 256 inputProvider.readStringFromUri, | |
| 257 handler, | |
| 258 options)); | |
| 259 if (analyzeOnly) return; | |
| 260 | 247 |
| 261 if (code == null) { | 248 compilationDone(String code) { |
| 262 fail('Error: Compilation failed.'); | 249 if (analyzeOnly) return; |
| 250 if (code == null) { |
| 251 fail('Error: Compilation failed.'); |
| 252 } |
| 253 writeString(Uri.parse('$out.deps'), |
| 254 getDepsOutput(inputProvider.sourceFiles)); |
| 255 diagnosticHandler.info( |
| 256 'compiled ${inputProvider.dartCharactersRead} characters Dart ' |
| 257 '-> $charactersWritten characters $outputLanguage ' |
| 258 'in ${relativize(cwd, out, isWindows)}'); |
| 259 if (!explicitOut) { |
| 260 String input = uriPathToNative(arguments[0]); |
| 261 String output = relativize(cwd, out, isWindows); |
| 262 print('Dart file $input compiled to $outputLanguage: $output'); |
| 263 } |
| 263 } | 264 } |
| 264 String sourceMapFileName = | 265 |
| 265 sourceMapOut.path.substring(sourceMapOut.path.lastIndexOf('/') + 1); | 266 Sink<String> outputProvider(String name, String extension) { |
| 266 code = '$code\n//@ sourceMappingURL=${sourceMapFileName}'; | 267 Uri uri; |
| 267 writeString(out, code); | 268 String sourceMapFileName; |
| 268 writeString(Uri.parse('$out.deps'), | 269 bool isPrimaryOutput = false; |
| 269 getDepsOutput(inputProvider.sourceFiles)); | 270 if (name == '') { |
| 270 int dartBytesRead = inputProvider.dartBytesRead; | 271 if (extension == 'js' || extension == 'dart') { |
| 271 int bytesWritten = code.length; | 272 isPrimaryOutput = true; |
| 272 diagnosticHandler.info( | 273 uri = out; |
| 273 'compiled $dartBytesRead bytes Dart -> $bytesWritten bytes ' | 274 sourceMapFileName = |
| 274 '$outputLanguage in ${relativize(cwd, out, isWindows)}'); | 275 sourceMapOut.path.substring(sourceMapOut.path.lastIndexOf('/') + 1); |
| 275 if (!explicitOut) { | 276 } else if (extension == 'js.map' || extension == 'dart.map') { |
| 276 String input = uriPathToNative(arguments[0]); | 277 uri = sourceMapOut; |
| 277 String output = relativize(cwd, out, isWindows); | 278 } else { |
| 278 print('Dart file $input compiled to $outputLanguage: $output'); | 279 fail('Error: Unknown extension: $extension'); |
| 280 } |
| 281 } else { |
| 282 uri = out.resolve('$name.$extension'); |
| 283 } |
| 284 |
| 285 if (uri.scheme != 'file') { |
| 286 fail('Error: Unhandled scheme ${uri.scheme} in $uri.'); |
| 287 } |
| 288 var outputStream = new File(uriPathToNative(uri.path)).openOutputStream(); |
| 289 |
| 290 CountingSink sink; |
| 291 |
| 292 onDone() { |
| 293 if (sourceMapFileName != null) { |
| 294 String sourceMapTag = '//@ sourceMappingURL=$sourceMapFileName\n'; |
| 295 sink.count += sourceMapTag.length; |
| 296 outputStream.writeString(sourceMapTag); |
| 297 } |
| 298 outputStream.close(); |
| 299 if (isPrimaryOutput) { |
| 300 charactersWritten += sink.count; |
| 301 } |
| 302 } |
| 303 |
| 304 var controller = new StreamController<String>(); |
| 305 controller.stream.listen(outputStream.writeString, onDone: onDone); |
| 306 sink = new CountingSink(controller); |
| 307 return sink; |
| 279 } | 308 } |
| 309 |
| 310 api.compile(uri, libraryRoot, packageRoot, |
| 311 inputProvider.readStringFromUri, handler, |
| 312 options, outputProvider) |
| 313 .then(compilationDone); |
| 314 } |
| 315 |
| 316 // TODO(ahe): Get rid of this class if http://dartbug.com/8118 is fixed. |
| 317 class CountingSink implements Sink<String> { |
| 318 final Sink<String> sink; |
| 319 int count = 0; |
| 320 |
| 321 CountingSink(this.sink); |
| 322 |
| 323 add(String value) { |
| 324 sink.add(value); |
| 325 count += value.length; |
| 326 } |
| 327 |
| 328 close() => sink.close(); |
| 280 } | 329 } |
| 281 | 330 |
| 282 class AbortLeg { | 331 class AbortLeg { |
| 283 final message; | 332 final message; |
| 284 AbortLeg(this.message); | 333 AbortLeg(this.message); |
| 285 toString() => 'Aborted due to --throw-on-error: $message'; | 334 toString() => 'Aborted due to --throw-on-error: $message'; |
| 286 } | 335 } |
| 287 | 336 |
| 288 void writeString(Uri uri, String text) { | 337 void writeString(Uri uri, String text) { |
| 289 if (uri.scheme != 'file') { | 338 if (uri.scheme != 'file') { |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 } catch (ignored) { | 487 } catch (ignored) { |
| 439 print('Internal error: error while printing exception'); | 488 print('Internal error: error while printing exception'); |
| 440 } | 489 } |
| 441 try { | 490 try { |
| 442 print(trace); | 491 print(trace); |
| 443 } finally { | 492 } finally { |
| 444 exit(253); // 253 is recognized as a crash by our test scripts. | 493 exit(253); // 253 is recognized as a crash by our test scripts. |
| 445 } | 494 } |
| 446 } | 495 } |
| 447 } | 496 } |
| OLD | NEW |