Chromium Code Reviews| 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 |