| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'dart:collection' show HashSet, Queue; | 5 import 'dart:collection' show HashSet, Queue; |
| 6 import 'dart:convert' show BASE64, JSON, UTF8; | 6 import 'dart:convert' show BASE64, JSON, UTF8; |
| 7 import 'dart:io' show File; | 7 import 'dart:io' show File; |
| 8 import 'package:analyzer/dart/element/element.dart' show LibraryElement; | 8 import 'package:analyzer/dart/element/element.dart' show LibraryElement; |
| 9 import 'package:analyzer/analyzer.dart' | 9 import 'package:analyzer/analyzer.dart' |
| 10 show AnalysisError, CompilationUnit, ErrorSeverity; | 10 show AnalysisError, CompilationUnit, ErrorSeverity; |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 /// Not yet supporting: | 254 /// Not yet supporting: |
| 255 /// * Atom (1.5.4) | 255 /// * Atom (1.5.4) |
| 256 /// * Electron (0.36.3) | 256 /// * Electron (0.36.3) |
| 257 // TODO(ochafik): Simplify this code when our target platforms catch up. | 257 // TODO(ochafik): Simplify this code when our target platforms catch up. |
| 258 final bool destructureNamedParams; | 258 final bool destructureNamedParams; |
| 259 | 259 |
| 260 /// Mapping from absolute file paths to bazel short path to substitute in | 260 /// Mapping from absolute file paths to bazel short path to substitute in |
| 261 /// source maps. | 261 /// source maps. |
| 262 final Map<String, String> bazelMapping; | 262 final Map<String, String> bazelMapping; |
| 263 | 263 |
| 264 /// If specified, the path to write the summary file. |
| 265 /// Used when building the SDK. |
| 266 final String summaryOutPath; |
| 267 |
| 264 const CompilerOptions( | 268 const CompilerOptions( |
| 265 {this.sourceMap: true, | 269 {this.sourceMap: true, |
| 266 this.sourceMapComment: true, | 270 this.sourceMapComment: true, |
| 267 this.inlineSourceMap: false, | 271 this.inlineSourceMap: false, |
| 268 this.summarizeApi: true, | 272 this.summarizeApi: true, |
| 269 this.summaryExtension: 'sum', | 273 this.summaryExtension: 'sum', |
| 270 this.unsafeForceCompile: false, | 274 this.unsafeForceCompile: false, |
| 271 this.replCompile: false, | 275 this.replCompile: false, |
| 272 this.emitMetadata: false, | 276 this.emitMetadata: false, |
| 273 this.closure: false, | 277 this.closure: false, |
| 274 this.destructureNamedParams: false, | 278 this.destructureNamedParams: false, |
| 275 this.hoistInstanceCreation: true, | 279 this.hoistInstanceCreation: true, |
| 276 this.hoistSignatureTypes: false, | 280 this.hoistSignatureTypes: false, |
| 277 this.nameTypeTests: true, | 281 this.nameTypeTests: true, |
| 278 this.hoistTypeTests: true, | 282 this.hoistTypeTests: true, |
| 279 this.useAngular2Whitelist: false, | 283 this.useAngular2Whitelist: false, |
| 280 this.bazelMapping: const {}}); | 284 this.bazelMapping: const {}, |
| 285 this.summaryOutPath}); |
| 281 | 286 |
| 282 CompilerOptions.fromArguments(ArgResults args) | 287 CompilerOptions.fromArguments(ArgResults args) |
| 283 : sourceMap = args['source-map'], | 288 : sourceMap = args['source-map'], |
| 284 sourceMapComment = args['source-map-comment'], | 289 sourceMapComment = args['source-map-comment'], |
| 285 inlineSourceMap = args['inline-source-map'], | 290 inlineSourceMap = args['inline-source-map'], |
| 286 summarizeApi = args['summarize'], | 291 summarizeApi = args['summarize'], |
| 287 summaryExtension = args['summary-extension'], | 292 summaryExtension = args['summary-extension'], |
| 288 unsafeForceCompile = args['unsafe-force-compile'], | 293 unsafeForceCompile = args['unsafe-force-compile'], |
| 289 replCompile = args['repl-compile'], | 294 replCompile = args['repl-compile'], |
| 290 emitMetadata = args['emit-metadata'], | 295 emitMetadata = args['emit-metadata'], |
| 291 closure = args['closure-experimental'], | 296 closure = args['closure-experimental'], |
| 292 destructureNamedParams = args['destructure-named-params'], | 297 destructureNamedParams = args['destructure-named-params'], |
| 293 hoistInstanceCreation = args['hoist-instance-creation'], | 298 hoistInstanceCreation = args['hoist-instance-creation'], |
| 294 hoistSignatureTypes = args['hoist-signature-types'], | 299 hoistSignatureTypes = args['hoist-signature-types'], |
| 295 nameTypeTests = args['name-type-tests'], | 300 nameTypeTests = args['name-type-tests'], |
| 296 hoistTypeTests = args['hoist-type-tests'], | 301 hoistTypeTests = args['hoist-type-tests'], |
| 297 useAngular2Whitelist = args['unsafe-angular2-whitelist'], | 302 useAngular2Whitelist = args['unsafe-angular2-whitelist'], |
| 298 bazelMapping = _parseBazelMappings(args['bazel-mapping']); | 303 bazelMapping = _parseBazelMappings(args['bazel-mapping']), |
| 304 summaryOutPath = args['summary-out']; |
| 299 | 305 |
| 300 static void addArguments(ArgParser parser) { | 306 static void addArguments(ArgParser parser) { |
| 301 parser | 307 parser |
| 302 ..addFlag('summarize', help: 'emit an API summary file', defaultsTo: true) | 308 ..addFlag('summarize', help: 'emit an API summary file', defaultsTo: true) |
| 303 ..addOption('summary-extension', | 309 ..addOption('summary-extension', |
| 304 help: 'file extension for Dart summary files', | 310 help: 'file extension for Dart summary files', |
| 305 defaultsTo: 'sum', | 311 defaultsTo: 'sum', |
| 306 hide: true) | 312 hide: true) |
| 307 ..addFlag('source-map', help: 'emit source mapping', defaultsTo: true) | 313 ..addFlag('source-map', help: 'emit source mapping', defaultsTo: true) |
| 308 ..addFlag('source-map-comment', | 314 ..addFlag('source-map-comment', |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 help: 'Name types used in type tests', defaultsTo: true, hide: true) | 348 help: 'Name types used in type tests', defaultsTo: true, hide: true) |
| 343 ..addFlag('hoist-type-tests', | 349 ..addFlag('hoist-type-tests', |
| 344 help: 'Hoist types used in type tests', defaultsTo: true, hide: true) | 350 help: 'Hoist types used in type tests', defaultsTo: true, hide: true) |
| 345 ..addFlag('unsafe-angular2-whitelist', defaultsTo: false, hide: true) | 351 ..addFlag('unsafe-angular2-whitelist', defaultsTo: false, hide: true) |
| 346 ..addOption('bazel-mapping', | 352 ..addOption('bazel-mapping', |
| 347 help: | 353 help: |
| 348 '--bazel-mapping=genfiles/to/library.dart,to/library.dart uses \n' | 354 '--bazel-mapping=genfiles/to/library.dart,to/library.dart uses \n' |
| 349 'to/library.dart as the path for library.dart in source maps.', | 355 'to/library.dart as the path for library.dart in source maps.', |
| 350 allowMultiple: true, | 356 allowMultiple: true, |
| 351 splitCommas: false, | 357 splitCommas: false, |
| 352 hide: true); | 358 hide: true) |
| 359 ..addOption('summary-out', |
| 360 help: 'location to write the summary file', hide: true); |
| 353 } | 361 } |
| 354 | 362 |
| 355 static Map<String, String> _parseBazelMappings(Iterable argument) { | 363 static Map<String, String> _parseBazelMappings(Iterable argument) { |
| 356 var mappings = <String, String>{}; | 364 var mappings = <String, String>{}; |
| 357 for (var mapping in argument) { | 365 for (var mapping in argument) { |
| 358 var splitMapping = mapping.split(','); | 366 var splitMapping = mapping.split(','); |
| 359 if (splitMapping.length >= 2) { | 367 if (splitMapping.length >= 2) { |
| 360 mappings[path.absolute(splitMapping[0])] = splitMapping[1]; | 368 mappings[path.absolute(splitMapping[0])] = splitMapping[1]; |
| 361 } | 369 } |
| 362 } | 370 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 /// True if this library was successfully compiled. | 428 /// True if this library was successfully compiled. |
| 421 bool get isValid => moduleTree != null; | 429 bool get isValid => moduleTree != null; |
| 422 | 430 |
| 423 /// Gets the source code and source map for this JS module, given the | 431 /// Gets the source code and source map for this JS module, given the |
| 424 /// locations where the JS file and map file will be served from. | 432 /// locations where the JS file and map file will be served from. |
| 425 /// | 433 /// |
| 426 /// Relative URLs will be used to point from the .js file to the .map file | 434 /// Relative URLs will be used to point from the .js file to the .map file |
| 427 // | 435 // |
| 428 // TODO(jmesserly): this should match our old logic, but I'm not sure we are | 436 // TODO(jmesserly): this should match our old logic, but I'm not sure we are |
| 429 // correctly handling the pointer from the .js file to the .map file. | 437 // correctly handling the pointer from the .js file to the .map file. |
| 430 JSModuleCode getCode( | 438 JSModuleCode getCode(ModuleFormat format, String jsUrl, String mapUrl, |
| 431 ModuleFormat format, bool singleOutFile, String jsUrl, String mapUrl) { | 439 {bool singleOutFile: false}) { |
| 432 var opts = new JS.JavaScriptPrintingOptions( | 440 var opts = new JS.JavaScriptPrintingOptions( |
| 433 emitTypes: options.closure, | 441 emitTypes: options.closure, |
| 434 allowKeywordsInProperties: true, | 442 allowKeywordsInProperties: true, |
| 435 allowSingleLineIfStatements: true); | 443 allowSingleLineIfStatements: true); |
| 436 JS.SimpleJavaScriptPrintingContext printer; | 444 JS.SimpleJavaScriptPrintingContext printer; |
| 437 SourceMapBuilder sourceMap; | 445 SourceMapBuilder sourceMap; |
| 438 if (options.sourceMap) { | 446 if (options.sourceMap) { |
| 439 var sourceMapContext = new SourceMapPrintingContext(); | 447 var sourceMapContext = new SourceMapPrintingContext(); |
| 440 sourceMap = sourceMapContext.sourceMap; | 448 sourceMap = sourceMapContext.sourceMap; |
| 441 printer = sourceMapContext; | 449 printer = sourceMapContext; |
| 442 } else { | 450 } else { |
| 443 printer = new JS.SimpleJavaScriptPrintingContext(); | 451 printer = new JS.SimpleJavaScriptPrintingContext(); |
| 444 } | 452 } |
| 445 | 453 |
| 446 var tree = transformModuleFormat(format, singleOutFile, moduleTree); | 454 var tree = |
| 455 transformModuleFormat(format, moduleTree, singleOutFile: singleOutFile); |
| 447 tree.accept( | 456 tree.accept( |
| 448 new JS.Printer(opts, printer, localNamer: new JS.TemporaryNamer(tree))); | 457 new JS.Printer(opts, printer, localNamer: new JS.TemporaryNamer(tree))); |
| 449 | 458 |
| 450 Map builtMap; | 459 Map builtMap; |
| 451 if (options.sourceMap && sourceMap != null) { | 460 if (options.sourceMap && sourceMap != null) { |
| 452 builtMap = | 461 builtMap = |
| 453 placeSourceMap(sourceMap.build(jsUrl), mapUrl, options.bazelMapping); | 462 placeSourceMap(sourceMap.build(jsUrl), mapUrl, options.bazelMapping); |
| 454 | 463 |
| 455 if (options.sourceMapComment) { | 464 if (options.sourceMapComment) { |
| 456 var relativeMapUrl = path | 465 var relativeMapUrl = path |
| (...skipping 13 matching lines...) Expand all Loading... |
| 470 } | 479 } |
| 471 } | 480 } |
| 472 | 481 |
| 473 return new JSModuleCode(printer.getText(), builtMap); | 482 return new JSModuleCode(printer.getText(), builtMap); |
| 474 } | 483 } |
| 475 | 484 |
| 476 /// Similar to [getCode] but immediately writes the resulting files. | 485 /// Similar to [getCode] but immediately writes the resulting files. |
| 477 /// | 486 /// |
| 478 /// If [mapPath] is not supplied but [options.sourceMap] is set, mapPath | 487 /// If [mapPath] is not supplied but [options.sourceMap] is set, mapPath |
| 479 /// will default to [jsPath].map. | 488 /// will default to [jsPath].map. |
| 480 void writeCodeSync(ModuleFormat format, bool singleOutFile, String jsPath) { | 489 void writeCodeSync(ModuleFormat format, String jsPath, |
| 490 {bool singleOutFile: false}) { |
| 481 String mapPath = jsPath + '.map'; | 491 String mapPath = jsPath + '.map'; |
| 482 var code = getCode(format, singleOutFile, jsPath, mapPath); | 492 var code = getCode(format, jsPath, mapPath, singleOutFile: singleOutFile); |
| 483 var c = code.code; | 493 var c = code.code; |
| 484 if (singleOutFile) { | 494 if (singleOutFile) { |
| 485 // In singleOutFile mode we wrap each module in an eval statement to | 495 // In singleOutFile mode we wrap each module in an eval statement to |
| 486 // leverage sourceURL to improve the debugging experience when source maps | 496 // leverage sourceURL to improve the debugging experience when source maps |
| 487 // are not enabled. | 497 // are not enabled. |
| 488 c += '\n//# sourceURL=${name}.js\n'; | 498 c += '\n//# sourceURL=${name}.js\n'; |
| 489 c = 'eval(${JSON.encode(c)});\n'; | 499 c = 'eval(${JSON.encode(c)});\n'; |
| 490 } | 500 } |
| 491 new File(jsPath).writeAsStringSync(c); | 501 new File(jsPath).writeAsStringSync(c); |
| 492 // TODO(jacobr): it is a bit strange we are writing the source map to a file | 502 // TODO(jacobr): it is a bit strange we are writing the source map to a file |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 // Fall back to a relative path. | 542 // Fall back to a relative path. |
| 533 return path.toUri(path.relative(path.fromUri(uri), from: dir)).toString(); | 543 return path.toUri(path.relative(path.fromUri(uri), from: dir)).toString(); |
| 534 } | 544 } |
| 535 | 545 |
| 536 for (int i = 0; i < list.length; i++) { | 546 for (int i = 0; i < list.length; i++) { |
| 537 list[i] = transformUri(list[i]); | 547 list[i] = transformUri(list[i]); |
| 538 } | 548 } |
| 539 map['file'] = transformUri(map['file']); | 549 map['file'] = transformUri(map['file']); |
| 540 return map; | 550 return map; |
| 541 } | 551 } |
| OLD | NEW |