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 |