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 library fasta.compiler_command_line; | 5 library fasta.compiler_command_line; |
6 | 6 |
7 import 'dart:io' show exit; | 7 import 'dart:io' show exit; |
8 | 8 |
9 import 'dart:async' show runZoned; | |
10 | |
11 import 'package:kernel/target/targets.dart' | 9 import 'package:kernel/target/targets.dart' |
12 show Target, getTarget, TargetFlags, targets; | 10 show Target, getTarget, TargetFlags, targets; |
13 | 11 |
12 import 'package:front_end/compiler_options.dart'; | |
13 import 'package:front_end/src/base/processed_options.dart'; | |
ahe
2017/07/18 16:54:37
Use relative URIs.
Siggi Cherem (dart-lang)
2017/07/18 22:50:43
Done.
BTW, the reason I used package:* here is th
| |
14 import 'command_line.dart' show CommandLine, deprecated_argumentError; | 14 import 'command_line.dart' show CommandLine, deprecated_argumentError; |
15 | 15 |
16 import 'compiler_context.dart' show CompilerContext, compilerContextKey; | 16 import 'compiler_context.dart' show CompilerContext; |
17 | |
18 import 'command_line_reporting.dart' as command_line_reporting; | |
19 | 17 |
20 import 'fasta_codes.dart' | 18 import 'fasta_codes.dart' |
21 show | 19 show |
22 LocatedMessage, | |
23 Message, | 20 Message, |
24 messageFastaUsageLong, | 21 messageFastaUsageLong, |
25 messageFastaUsageShort, | 22 messageFastaUsageShort, |
26 templateUnspecified; | 23 templateUnspecified; |
27 | 24 |
28 import 'severity.dart' show Severity; | |
29 | |
30 const Map<String, dynamic> optionSpecification = const <String, dynamic>{ | 25 const Map<String, dynamic> optionSpecification = const <String, dynamic>{ |
31 "--compile-sdk": Uri, | 26 "--compile-sdk": Uri, |
32 "--fatal": ",", | 27 "--fatal": ",", |
33 "--output": Uri, | 28 "--output": Uri, |
34 "-o": Uri, | 29 "-o": Uri, |
35 "--packages": Uri, | 30 "--packages": Uri, |
36 "--platform": Uri, | 31 "--platform": Uri, |
37 "--sdk": Uri, | 32 "--sdk": Uri, |
38 "--target": String, | 33 "--target": String, |
39 "-t": String, | 34 "-t": String, |
40 }; | 35 }; |
41 | 36 |
37 /// Parser for options accepted by the `fasta` command-line tools. | |
38 // TODO(ahe,sigmund): move this and other tools under pkg/front_end/tool/ | |
42 class CompilerCommandLine extends CommandLine { | 39 class CompilerCommandLine extends CommandLine { |
43 final String programName; | 40 final String programName; |
44 | 41 |
45 CompilerCommandLine(String programName, List<String> arguments) | 42 CompilerCommandLine(String programName, List<String> arguments) |
46 : programName = programName, | 43 : programName = programName, |
47 super(arguments, | 44 super(arguments, |
48 specification: optionSpecification, | 45 specification: optionSpecification, |
49 usage: computeUsage(programName, false)); | 46 usage: computeUsage(programName, false)); |
50 | 47 |
51 bool get verify => options.containsKey("--verify"); | 48 bool get verify => options.containsKey("--verify"); |
52 | 49 |
53 bool get dumpIr => options.containsKey("--dump-ir"); | 50 bool get dumpIr => options.containsKey("--dump-ir"); |
54 | 51 |
55 bool get excludeSource => options.containsKey("--exclude-source"); | 52 bool get excludeSource => options.containsKey("--exclude-source"); |
56 | 53 |
57 bool get help { | 54 bool get help { |
58 return options.containsKey("--help") || | 55 return options.containsKey("--help") || |
59 options.containsKey("-h") || | 56 options.containsKey("-h") || |
60 options.containsKey("/h") || | 57 options.containsKey("/h") || |
61 options.containsKey("/?"); | 58 options.containsKey("/?"); |
62 } | 59 } |
63 | 60 |
64 bool get setExitCodeOnProblem { | |
65 return options.containsKey("--set-exit-code-on-problem"); | |
66 } | |
67 | |
68 void validate() { | 61 void validate() { |
69 if (help) { | 62 if (help) { |
70 print(computeUsage(programName, verbose)); | 63 print(computeUsage(programName, verbose).message); |
71 exit(0); | 64 exit(0); |
72 } | 65 } |
73 | 66 |
74 if (options.containsKey("-o") && options.containsKey("--output")) { | 67 if (options.containsKey("-o") && options.containsKey("--output")) { |
75 return deprecated_argumentError( | 68 return deprecated_argumentError( |
76 usage, "Can't specify both '-o' and '--output'."); | 69 usage, "Can't specify both '-o' and '--output'."); |
77 } | 70 } |
78 if (options.containsKey("-t") && options.containsKey("--target")) { | 71 if (options.containsKey("-t") && options.containsKey("--target")) { |
79 return deprecated_argumentError( | 72 return deprecated_argumentError( |
80 usage, "Can't specify both '-t' and '--target'."); | 73 usage, "Can't specify both '-t' and '--target'."); |
81 } | 74 } |
82 if (options.containsKey("--compile-sdk") && | 75 if (options.containsKey("--compile-sdk") && |
83 options.containsKey("--platform")) { | 76 options.containsKey("--platform")) { |
84 return deprecated_argumentError( | 77 return deprecated_argumentError( |
85 usage, "Can't specify both '--compile-sdk' and '--platform'."); | 78 usage, "Can't specify both '--compile-sdk' and '--platform'."); |
86 } | 79 } |
87 if (programName == "compile_platform" && arguments.length != 3) { | 80 if (programName == "compile_platform") { |
88 return deprecated_argumentError(usage, "Expected three arguments."); | 81 if (arguments.length != 3) { |
82 return deprecated_argumentError(usage, "Expected three arguments."); | |
83 } | |
84 if (options.containsKey("--compile-sdk")) { | |
85 return deprecated_argumentError( | |
86 usage, "Ignored '--compile-sdk' option."); | |
ahe
2017/07/18 16:54:37
This option isn't really ignored as it's reporting
Siggi Cherem (dart-lang)
2017/07/18 22:50:43
Good point, rephrased
| |
87 } | |
88 options['--compile-sdk'] = | |
89 Uri.base.resolveUri(new Uri.file(arguments[0])); | |
89 } else if (arguments.isEmpty) { | 90 } else if (arguments.isEmpty) { |
90 return deprecated_argumentError(usage, "No Dart file specified."); | 91 return deprecated_argumentError(usage, "No Dart file specified."); |
91 } | 92 } |
92 | 93 |
93 Target target = | 94 Target target = |
94 getTarget(targetName, new TargetFlags(strongMode: strongMode)); | 95 getTarget(targetName, new TargetFlags(strongMode: strongMode)); |
95 if (target == null) { | 96 if (target == null) { |
96 return deprecated_argumentError( | 97 return deprecated_argumentError( |
97 usage, | 98 usage, |
98 "Target '${targetName}' not recognized. " | 99 "Target '${targetName}' not recognized. " |
99 "Valid targets are:\n ${targets.keys.join("\n ")}"); | 100 "Valid targets are:\n ${targets.keys.join("\n ")}"); |
100 } | 101 } |
101 options["target"] = target; | 102 options["target"] = target; |
102 } | 103 } |
103 | 104 |
104 Uri get output { | 105 Uri get output { |
105 return options["-o"] ?? options["--output"] ?? defaultOutput; | 106 return options["-o"] ?? options["--output"] ?? defaultOutput; |
106 } | 107 } |
107 | 108 |
108 Uri get defaultOutput => Uri.base.resolve("${arguments.first}.dill"); | 109 Uri get defaultOutput => Uri.base.resolve("${arguments.first}.dill"); |
109 | 110 |
110 Uri get platform { | 111 Uri get platform { |
111 return options.containsKey("--compile-sdk") | 112 return options.containsKey("--compile-sdk") |
112 ? null | 113 ? null |
113 : options["--platform"] ?? Uri.base.resolve("platform.dill"); | 114 : options["--platform"] ?? Uri.base.resolve("platform.dill"); |
114 } | 115 } |
115 | 116 |
116 Uri get packages => options["--packages"] ?? Uri.base.resolve(".packages"); | 117 Uri get packages => options["--packages"]; |
117 | 118 |
118 Uri get sdk => options["--sdk"] ?? options["--compile-sdk"]; | 119 Uri get sdk => options["--sdk"] ?? options["--compile-sdk"]; |
119 | 120 |
120 Set<String> get fatal { | 121 Set<String> get fatal { |
121 return new Set<String>.from(options["--fatal"] ?? <String>[]); | 122 return new Set<String>.from(options["--fatal"] ?? <String>[]); |
122 } | 123 } |
123 | 124 |
124 bool get errorsAreFatal => fatal.contains("errors"); | 125 bool get errorsAreFatal => fatal.contains("errors"); |
125 | 126 |
126 bool get warningsAreFatal => fatal.contains("warnings"); | 127 bool get warningsAreFatal => fatal.contains("warnings"); |
127 | 128 |
128 bool get nitsAreFatal => fatal.contains("nits"); | 129 bool get nitsAreFatal => fatal.contains("nits"); |
129 | 130 |
130 bool get strongMode => options.containsKey("--strong-mode"); | 131 bool get strongMode => options.containsKey("--strong-mode"); |
131 | 132 |
132 String get targetName { | 133 String get targetName { |
133 return options["-t"] ?? options["--target"] ?? "vm_fasta"; | 134 return options["-t"] ?? options["--target"] ?? "vm_fasta"; |
134 } | 135 } |
135 | 136 |
136 Target get target => options["target"]; | 137 Target get target => options["target"]; |
137 | 138 |
138 void Function(LocatedMessage, Severity) get report { | 139 static dynamic withGlobalOptions( |
139 return options["report"] ?? command_line_reporting.report; | 140 String programName, |
140 } | 141 List<String> arguments, |
142 bool areRestArgumentsInputs, | |
143 dynamic f(CompilerContext context, List<String> restArguments)) { | |
ahe
2017/07/18 10:40:50
This method needs to create a Ticker as the first
ahe
2017/07/18 16:54:37
We discussed this at our 1:1, handle as you see fi
Siggi Cherem (dart-lang)
2017/07/18 22:50:43
Thanks. The ticker is created in line 172 below ea
| |
144 // TODO(sigmund,ahe): delete this wrapper by moving validation into the | |
145 // callback. Note that this requires some subtle changes because validate | |
146 // sets some implicit options (like --compile-sdk in compile_platform). | |
147 var cl = CompilerContext.runWithDefaultOptions( | |
148 (_) => new CompilerCommandLine(programName, arguments)); | |
149 var options = new CompilerOptions() | |
150 ..compileSdk = cl.options.containsKey("--compile-sdk") | |
151 ..sdkRoot = cl.sdk | |
152 ..sdkSummary = cl.platform | |
153 ..packagesFileUri = cl.packages | |
154 ..strongMode = cl.strongMode | |
155 ..target = cl.target | |
156 ..errorsAreFatal = cl.errorsAreFatal | |
157 ..warningsAreFatal = cl.warningsAreFatal | |
158 ..nitsAreFatal = cl.nitsAreFatal | |
159 ..excludeSourceInformation = cl.excludeSource | |
160 // All command-line tools take only a single entry point and chase | |
161 // dependencies, and provide a non-zero exit code when errors are found. | |
162 ..chaseDependencies = true | |
163 ..setExitCodeOnProblem = true | |
164 ..debugDump = cl.dumpIr | |
165 ..verbose = cl.verbose | |
166 ..verify = cl.verify; | |
141 | 167 |
142 void Function(Message, Severity) get reportWithoutLocation { | 168 var inputs = <Uri>[]; |
143 return options["reportWithoutLocation"] ?? | 169 if (areRestArgumentsInputs) { |
144 command_line_reporting.reportWithoutLocation; | 170 inputs = cl.arguments.map(Uri.base.resolve).toList(); |
145 } | 171 } |
146 | 172 var pOptions = new ProcessedOptions(options, false, inputs, cl.output); |
147 String Function(LocatedMessage, Severity) get format { | 173 return CompilerContext.runWithOptions(pOptions, (c) => f(c, cl.arguments)); |
148 return options["format"] ?? command_line_reporting.format; | |
149 } | |
150 | |
151 String Function(Message, Severity) get formatWithoutLocation { | |
152 return options["formatWithoutLocation"] ?? | |
153 command_line_reporting.formatWithoutLocation; | |
154 } | |
155 | |
156 static dynamic withGlobalOptions(String programName, List<String> arguments, | |
157 dynamic f(CompilerContext context)) { | |
158 CompilerCommandLine cl = deprecated_withDefaultOptions( | |
159 () => new CompilerCommandLine(programName, arguments)); | |
160 return CompilerContext.withGlobalOptions(cl, f); | |
161 } | |
162 | |
163 // TODO(sigmund, ahe): delete. We use this to wrap places where we require a | |
164 // context but we shoudln't. Right now this includes: | |
165 // - constructor calls to CompilerCommandLine (because it is calling | |
166 // [validate] which may report errors). This should be fixed by doing | |
167 // validation after creating these objects. | |
168 // - top-level try-catch in command-line tools that capture | |
169 // deprecated_InputError, and then report errors using fasta's error | |
170 // reporting mechanism. Those should be unnecessary once we get rid of all | |
171 // deprecated_InputErrors. | |
172 static dynamic deprecated_withDefaultOptions(dynamic f()) { | |
173 var defaultContext = new CompilerContext(new CompilerCommandLine("", [""])); | |
174 return runZoned(f, zoneValues: {compilerContextKey: defaultContext}); | |
175 } | 174 } |
176 } | 175 } |
177 | 176 |
178 Message computeUsage(String programName, bool verbose) { | 177 Message computeUsage(String programName, bool verbose) { |
179 String basicUsage = "Usage: $programName [options] dartfile\n"; | 178 String basicUsage = "Usage: $programName [options] dartfile\n"; |
180 String summary; | 179 String summary; |
181 String options = | 180 String options = |
182 (verbose ? messageFastaUsageLong.message : messageFastaUsageShort.message) | 181 (verbose ? messageFastaUsageLong.message : messageFastaUsageShort.message) |
183 .trim(); | 182 .trim(); |
184 switch (programName) { | 183 switch (programName) { |
(...skipping 18 matching lines...) Expand all Loading... | |
203 StringBuffer sb = new StringBuffer(basicUsage); | 202 StringBuffer sb = new StringBuffer(basicUsage); |
204 if (summary != null) { | 203 if (summary != null) { |
205 sb.writeln(); | 204 sb.writeln(); |
206 sb.writeln(summary); | 205 sb.writeln(summary); |
207 sb.writeln(); | 206 sb.writeln(); |
208 } | 207 } |
209 sb.write(options); | 208 sb.write(options); |
210 // TODO(ahe): Don't use [templateUnspecified]. | 209 // TODO(ahe): Don't use [templateUnspecified]. |
211 return templateUnspecified.withArguments("$sb"); | 210 return templateUnspecified.withArguments("$sb"); |
212 } | 211 } |
OLD | NEW |