Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: lib/src/compiler/command.dart

Issue 2244703003: fixes #610, incorrect help output (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: fix usageexception printing Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/src/analyzer/context.dart ('k') | lib/src/compiler/compiler.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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';
8 import 'package:analyzer/src/generated/source.dart' show Source; 7 import 'package:analyzer/src/generated/source.dart' show Source;
9 import 'package:analyzer/src/summary/package_bundle_reader.dart' 8 import 'package:analyzer/src/summary/package_bundle_reader.dart'
10 show InSummarySource; 9 show InSummarySource;
10 import 'package:args/args.dart' show ArgParser, ArgResults;
11 import 'package:args/command_runner.dart' show UsageException;
12 import 'package:path/path.dart' as path;
13
11 import 'compiler.dart' 14 import 'compiler.dart'
12 show BuildUnit, CompilerOptions, JSModuleFile, ModuleCompiler; 15 show BuildUnit, CompilerOptions, JSModuleFile, ModuleCompiler;
13 import '../analyzer/context.dart' show AnalyzerOptions; 16 import '../analyzer/context.dart' show AnalyzerOptions;
14 import 'package:path/path.dart' as path;
15 17
16 typedef void MessageHandler(Object message); 18 final ArgParser _argParser = () {
19 var argParser = new ArgParser()
20 ..addFlag('help', abbr: 'h', help: 'Display this message.')
21 ..addOption('out', abbr: 'o', help: 'Output file (required).')
22 ..addOption('module-root',
23 help: 'Root module directory.\n'
24 'Generated module paths are relative to this root.')
25 ..addOption('library-root',
26 help: 'Root of source files.\n'
27 'Generated library names are relative to this root.')
28 ..addOption('build-root',
29 help: 'Deprecated in favor of --library-root', hide: true);
30 AnalyzerOptions.addArguments(argParser);
31 CompilerOptions.addArguments(argParser);
32 return argParser;
33 }();
17 34
18 /// The command for invoking the modular compiler. 35 /// Runs a single compile for dartdevc.
19 class CompileCommand extends Command { 36 ///
20 final MessageHandler messageHandler; 37 /// This handles argument parsing, usage, error handling.
21 CompilerOptions _compilerOptions; 38 /// See bin/dartdevc.dart for the actual entry point, which includes Bazel
22 39 /// worker support.
23 CompileCommand({MessageHandler messageHandler}) 40 int compile(List<String> args, {void printFn(Object obj)}) {
24 : this.messageHandler = messageHandler ?? print { 41 printFn ??= print;
25 argParser.addOption('out', abbr: 'o', help: 'Output file (required)'); 42 ArgResults argResults;
26 argParser.addOption('module-root', 43 try {
27 help: 'Root module directory. ' 44 argResults = _argParser.parse(args);
28 'Generated module paths are relative to this root.'); 45 } on FormatException catch (error) {
29 argParser.addOption('library-root', 46 printFn('$error\n\n$_usageMessage');
30 help: 'Root of source files. ' 47 return 64;
31 'Generated library names are relative to this root.');
32 argParser.addOption('build-root',
33 help: 'Deprecated in favor of --library-root');
34 CompilerOptions.addArguments(argParser);
35 AnalyzerOptions.addArguments(argParser);
36 } 48 }
37 49 try {
38 get name => 'compile'; 50 _compile(argResults, printFn);
39 get description => 'Compile a set of Dart files into a JavaScript module.'; 51 return 0;
40 52 } on UsageException catch (error) {
41 @override 53 // Incorrect usage, input file not found, etc.
42 void run() { 54 printFn(error);
43 var compiler = 55 return 64;
44 new ModuleCompiler(new AnalyzerOptions.fromArguments(argResults)); 56 } on CompileErrorException catch (error) {
45 _compilerOptions = new CompilerOptions.fromArguments(argResults); 57 // Code has error(s) and failed to compile.
46 var outPath = argResults['out']; 58 printFn(error);
47 59 return 1;
48 if (outPath == null) { 60 } catch (error, stackTrace) {
49 usageException('Please include the output file location. For example:\n' 61 // Anything else is likely a compiler bug.
50 ' -o PATH/TO/OUTPUT_FILE.js'); 62 //
51 } 63 // --unsafe-force-compile is a bit of a grey area, but it's nice not to
52 64 // crash while compiling
53 var libraryRoot = argResults['library-root'] as String; 65 // (of course, output code may crash, if it had errors).
54 libraryRoot ??= argResults['build-root'] as String; 66 //
55 if (libraryRoot != null) { 67 printFn('''
56 libraryRoot = path.absolute(libraryRoot); 68 We're sorry, you've found a bug in our compiler.
57 } else { 69 You can report this bug at:
58 libraryRoot = Directory.current.path; 70 https://github.com/dart-lang/dev_compiler/issues
59 } 71 Please include the information below in your report, along with
60 var moduleRoot = argResults['module-root'] as String; 72 any other information that may help us track it down. Thanks!
61 String modulePath; 73 dartdevc arguments: ${args.join(' ')}
62 if (moduleRoot != null) { 74 dart --version: ${Platform.version}
63 moduleRoot = path.absolute(moduleRoot); 75 ```
64 if (!path.isWithin(moduleRoot, outPath)) { 76 $error
65 usageException('Output file $outPath must be within the module root ' 77 $stackTrace
66 'directory $moduleRoot'); 78 ```''');
67 } 79 return 70;
68 modulePath =
69 path.withoutExtension(path.relative(outPath, from: moduleRoot));
70 } else {
71 moduleRoot = path.dirname(outPath);
72 modulePath = path.basenameWithoutExtension(outPath);
73 }
74
75 var unit = new BuildUnit(modulePath, libraryRoot, argResults.rest,
76 (source) => _moduleForLibrary(moduleRoot, source));
77
78 JSModuleFile module = compiler.compile(unit, _compilerOptions);
79 module.errors.forEach(messageHandler);
80
81 if (!module.isValid) throw new CompileErrorException();
82
83 // Write JS file, as well as source map and summary (if requested).
84 new File(outPath).writeAsStringSync(module.code);
85 if (module.sourceMap != null) {
86 var mapPath = outPath + '.map';
87 new File(mapPath)
88 .writeAsStringSync(JSON.encode(module.placeSourceMap(mapPath)));
89 }
90 if (module.summaryBytes != null) {
91 var summaryPath = path.withoutExtension(outPath) +
92 '.${_compilerOptions.summaryExtension}';
93 new File(summaryPath).writeAsBytesSync(module.summaryBytes);
94 }
95 }
96
97 String _moduleForLibrary(String moduleRoot, Source source) {
98 if (source is InSummarySource) {
99 var summaryPath = source.summaryPath;
100 var ext = '.${_compilerOptions.summaryExtension}';
101 if (path.isWithin(moduleRoot, summaryPath) && summaryPath.endsWith(ext)) {
102 var buildUnitPath =
103 summaryPath.substring(0, summaryPath.length - ext.length);
104 return path.relative(buildUnitPath, from: moduleRoot);
105 }
106
107 throw usageException(
108 'Imported file ${source.uri} is not within the module root '
109 'directory $moduleRoot');
110 }
111
112 throw usageException(
113 'Imported file "${source.uri}" was not found as a summary or source '
114 'file. Please pass in either the summary or the source file '
115 'for this import.');
116 } 80 }
117 } 81 }
118 82
83 void _compile(ArgResults argResults, void printFn(Object obj)) {
84 var compiler =
85 new ModuleCompiler(new AnalyzerOptions.fromArguments(argResults));
86 var compilerOpts = new CompilerOptions.fromArguments(argResults);
87 if (argResults['help']) {
88 printFn(_usageMessage);
89 return;
90 }
91 var outPath = argResults['out'];
92
93 if (outPath == null) {
94 _usageException('Please include the output file location. For example:\n'
95 ' -o PATH/TO/OUTPUT_FILE.js');
96 }
97
98 var libraryRoot = argResults['library-root'] as String;
99 libraryRoot ??= argResults['build-root'] as String;
100 if (libraryRoot != null) {
101 libraryRoot = path.absolute(libraryRoot);
102 } else {
103 libraryRoot = Directory.current.path;
104 }
105 var moduleRoot = argResults['module-root'] as String;
106 String modulePath;
107 if (moduleRoot != null) {
108 moduleRoot = path.absolute(moduleRoot);
109 if (!path.isWithin(moduleRoot, outPath)) {
110 _usageException('Output file $outPath must be within the module root '
111 'directory $moduleRoot');
112 }
113 modulePath =
114 path.withoutExtension(path.relative(outPath, from: moduleRoot));
115 } else {
116 moduleRoot = path.dirname(outPath);
117 modulePath = path.basenameWithoutExtension(outPath);
118 }
119
120 var unit = new BuildUnit(modulePath, libraryRoot, argResults.rest,
121 (source) => _moduleForLibrary(moduleRoot, source, compilerOpts));
122
123 JSModuleFile module = compiler.compile(unit, compilerOpts);
124 module.errors.forEach(printFn);
125
126 if (!module.isValid) throw new CompileErrorException();
127
128 // Write JS file, as well as source map and summary (if requested).
129 new File(outPath).writeAsStringSync(module.code);
130 if (module.sourceMap != null) {
131 var mapPath = outPath + '.map';
132 new File(mapPath)
133 .writeAsStringSync(JSON.encode(module.placeSourceMap(mapPath)));
134 }
135 if (module.summaryBytes != null) {
136 var summaryPath =
137 path.withoutExtension(outPath) + '.${compilerOpts.summaryExtension}';
138 new File(summaryPath).writeAsBytesSync(module.summaryBytes);
139 }
140 }
141
142 String _moduleForLibrary(
143 String moduleRoot, Source source, CompilerOptions compilerOpts) {
144 if (source is InSummarySource) {
145 var summaryPath = source.summaryPath;
146 var ext = '.${compilerOpts.summaryExtension}';
147 if (path.isWithin(moduleRoot, summaryPath) && summaryPath.endsWith(ext)) {
148 var buildUnitPath =
149 summaryPath.substring(0, summaryPath.length - ext.length);
150 return path.relative(buildUnitPath, from: moduleRoot);
151 }
152
153 _usageException('Imported file ${source.uri} is not within the module root '
154 'directory $moduleRoot');
155 }
156
157 _usageException(
158 'Imported file "${source.uri}" was not found as a summary or source '
159 'file. Please pass in either the summary or the source file '
160 'for this import.');
161 return null; // unreachable
162 }
163
164 final _usageMessage =
165 'Dart Development Compiler compiles Dart into a JavaScript module.'
166 '\n\n${_argParser.usage}';
167
168 void _usageException(String message) {
169 throw new UsageException(message, _usageMessage);
170 }
171
119 /// Thrown when the input source code has errors. 172 /// Thrown when the input source code has errors.
120 class CompileErrorException implements Exception { 173 class CompileErrorException implements Exception {
121 toString() => '\nPlease fix all errors before compiling (warnings are okay).'; 174 toString() => '\nPlease fix all errors before compiling (warnings are okay).';
122 } 175 }
OLDNEW
« no previous file with comments | « lib/src/analyzer/context.dart ('k') | lib/src/compiler/compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698