| 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:convert' show JSON; | 5 import 'dart:convert' show JSON; |
| 6 import 'dart:io'; | 6 import 'dart:io'; |
| 7 import 'package:args/command_runner.dart'; | 7 import 'package:args/command_runner.dart'; |
| 8 import 'package:analyzer/src/generated/source.dart' show Source; | 8 import 'package:analyzer/src/generated/source.dart' show Source; |
| 9 import 'package:analyzer/src/summary/package_bundle_reader.dart' | 9 import 'package:analyzer/src/summary/package_bundle_reader.dart' |
| 10 show InSummarySource; | 10 show InSummarySource; |
| 11 import 'compiler.dart' | 11 import 'compiler.dart' |
| 12 show BuildUnit, CompilerOptions, JSModuleFile, ModuleCompiler; | 12 show BuildUnit, CompilerOptions, JSModuleFile, ModuleCompiler; |
| 13 import '../analyzer/context.dart' show AnalyzerOptions; | 13 import '../analyzer/context.dart' show AnalyzerOptions; |
| 14 import 'package:path/path.dart' as path; | 14 import 'package:path/path.dart' as path; |
| 15 | 15 |
| 16 typedef void MessageHandler(Object message); | 16 typedef void MessageHandler(Object message); |
| 17 | 17 |
| 18 /// The command for invoking the modular compiler. | 18 /// The command for invoking the modular compiler. |
| 19 class CompileCommand extends Command { | 19 class CompileCommand extends Command { |
| 20 get name => 'compile'; | |
| 21 get description => 'Compile a set of Dart files into a JavaScript module.'; | |
| 22 final MessageHandler messageHandler; | 20 final MessageHandler messageHandler; |
| 21 CompilerOptions _compilerOptions; |
| 23 | 22 |
| 24 CompileCommand({MessageHandler messageHandler}) | 23 CompileCommand({MessageHandler messageHandler}) |
| 25 : this.messageHandler = messageHandler ?? print { | 24 : this.messageHandler = messageHandler ?? print { |
| 26 argParser.addOption('out', abbr: 'o', help: 'Output file (required)'); | 25 argParser.addOption('out', abbr: 'o', help: 'Output file (required)'); |
| 27 argParser.addOption('module-root', | 26 argParser.addOption('module-root', |
| 28 help: 'Root module directory. ' | 27 help: 'Root module directory. ' |
| 29 'Generated module paths are relative to this root.'); | 28 'Generated module paths are relative to this root.'); |
| 30 argParser.addOption('build-root', | 29 argParser.addOption('build-root', |
| 31 help: 'Root of source files. ' | 30 help: 'Root of source files. ' |
| 32 'Generated library names are relative to this root.'); | 31 'Generated library names are relative to this root.'); |
| 33 CompilerOptions.addArguments(argParser); | 32 CompilerOptions.addArguments(argParser); |
| 34 AnalyzerOptions.addArguments(argParser); | 33 AnalyzerOptions.addArguments(argParser); |
| 35 } | 34 } |
| 36 | 35 |
| 36 get name => 'compile'; |
| 37 get description => 'Compile a set of Dart files into a JavaScript module.'; |
| 38 |
| 37 @override | 39 @override |
| 38 void run() { | 40 void run() { |
| 39 var compiler = | 41 var compiler = |
| 40 new ModuleCompiler(new AnalyzerOptions.fromArguments(argResults)); | 42 new ModuleCompiler(new AnalyzerOptions.fromArguments(argResults)); |
| 41 var compilerOptions = new CompilerOptions.fromArguments(argResults); | 43 _compilerOptions = new CompilerOptions.fromArguments(argResults); |
| 42 var outPath = argResults['out']; | 44 var outPath = argResults['out']; |
| 43 | 45 |
| 44 if (outPath == null) { | 46 if (outPath == null) { |
| 45 usageException('Please include the output file location. For example:\n' | 47 usageException('Please include the output file location. For example:\n' |
| 46 ' -o PATH/TO/OUTPUT_FILE.js'); | 48 ' -o PATH/TO/OUTPUT_FILE.js'); |
| 47 } | 49 } |
| 48 | 50 |
| 49 var buildRoot = argResults['build-root'] as String; | 51 var buildRoot = argResults['build-root'] as String; |
| 50 if (buildRoot != null) { | 52 if (buildRoot != null) { |
| 51 buildRoot = path.absolute(buildRoot); | 53 buildRoot = path.absolute(buildRoot); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 67 modulePath = path.basenameWithoutExtension(outPath); | 69 modulePath = path.basenameWithoutExtension(outPath); |
| 68 } | 70 } |
| 69 | 71 |
| 70 if (argResults.rest.isEmpty) { | 72 if (argResults.rest.isEmpty) { |
| 71 usageException('Please pass at least one source file as an argument.'); | 73 usageException('Please pass at least one source file as an argument.'); |
| 72 } | 74 } |
| 73 | 75 |
| 74 var unit = new BuildUnit(modulePath, buildRoot, argResults.rest, | 76 var unit = new BuildUnit(modulePath, buildRoot, argResults.rest, |
| 75 (source) => _moduleForLibrary(moduleRoot, source)); | 77 (source) => _moduleForLibrary(moduleRoot, source)); |
| 76 | 78 |
| 77 JSModuleFile module = compiler.compile(unit, compilerOptions); | 79 JSModuleFile module = compiler.compile(unit, _compilerOptions); |
| 78 module.errors.forEach(messageHandler); | 80 module.errors.forEach(messageHandler); |
| 79 | 81 |
| 80 if (!module.isValid) throw new CompileErrorException(); | 82 if (!module.isValid) throw new CompileErrorException(); |
| 81 | 83 |
| 82 // Write JS file, as well as source map and summary (if requested). | 84 // Write JS file, as well as source map and summary (if requested). |
| 83 new File(outPath).writeAsStringSync(module.code); | 85 new File(outPath).writeAsStringSync(module.code); |
| 84 if (module.sourceMap != null) { | 86 if (module.sourceMap != null) { |
| 85 var mapPath = outPath + '.map'; | 87 var mapPath = outPath + '.map'; |
| 86 new File(mapPath) | 88 new File(mapPath) |
| 87 .writeAsStringSync(JSON.encode(module.placeSourceMap(mapPath))); | 89 .writeAsStringSync(JSON.encode(module.placeSourceMap(mapPath))); |
| 88 } | 90 } |
| 89 if (module.summaryBytes != null) { | 91 if (module.summaryBytes != null) { |
| 90 var summaryPath = path.withoutExtension(outPath) + '.sum'; | 92 var summaryPath = path.withoutExtension(outPath) + |
| 93 '.${_compilerOptions.summaryExtension}'; |
| 91 new File(summaryPath).writeAsBytesSync(module.summaryBytes); | 94 new File(summaryPath).writeAsBytesSync(module.summaryBytes); |
| 92 } | 95 } |
| 93 } | 96 } |
| 94 | 97 |
| 95 String _moduleForLibrary(String moduleRoot, Source source) { | 98 String _moduleForLibrary(String moduleRoot, Source source) { |
| 96 if (source is InSummarySource) { | 99 if (source is InSummarySource) { |
| 97 var summaryPath = source.summaryPath; | 100 var summaryPath = source.summaryPath; |
| 98 if (path.isWithin(moduleRoot, summaryPath)) { | 101 var ext = '.${_compilerOptions.summaryExtension}'; |
| 99 return path | 102 if (path.isWithin(moduleRoot, summaryPath) && summaryPath.endsWith(ext)) { |
| 100 .withoutExtension(path.relative(summaryPath, from: moduleRoot)); | 103 var buildUnitPath = |
| 104 summaryPath.substring(0, summaryPath.length - ext.length); |
| 105 return path.relative(buildUnitPath, from: moduleRoot); |
| 101 } | 106 } |
| 102 | 107 |
| 103 throw usageException( | 108 throw usageException( |
| 104 'Imported file ${source.uri} is not within the module root ' | 109 'Imported file ${source.uri} is not within the module root ' |
| 105 'directory $moduleRoot'); | 110 'directory $moduleRoot'); |
| 106 } | 111 } |
| 107 | 112 |
| 108 throw usageException( | 113 throw usageException( |
| 109 'Imported file "${source.uri}" was not found as a summary or source ' | 114 'Imported file "${source.uri}" was not found as a summary or source ' |
| 110 'file. Please pass in either the summary or the source file ' | 115 'file. Please pass in either the summary or the source file ' |
| 111 'for this import.'); | 116 'for this import.'); |
| 112 } | 117 } |
| 113 } | 118 } |
| 114 | 119 |
| 115 /// Thrown when the input source code has errors. | 120 /// Thrown when the input source code has errors. |
| 116 class CompileErrorException implements Exception { | 121 class CompileErrorException implements Exception { |
| 117 toString() => '\nPlease fix all errors before compiling (warnings are okay).'; | 122 toString() => '\nPlease fix all errors before compiling (warnings are okay).'; |
| 118 } | 123 } |
| OLD | NEW |