OLD | NEW |
---|---|
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 /// Set of flags and options passed to the compiler | 5 /// Set of flags and options passed to the compiler |
6 library dev_compiler.src.options; | 6 library dev_compiler.src.options; |
7 | 7 |
8 import 'dart:io'; | 8 import 'dart:io'; |
9 | 9 |
10 import 'package:args/args.dart'; | 10 import 'package:args/args.dart'; |
11 import 'package:cli_util/cli_util.dart' show getSdkDir; | 11 import 'package:cli_util/cli_util.dart' show getSdkDir; |
12 import 'package:dev_compiler/config.dart'; | |
13 import 'package:logging/logging.dart' show Level; | 12 import 'package:logging/logging.dart' show Level; |
14 import 'package:path/path.dart' as path; | 13 import 'package:path/path.dart' as path; |
15 import 'package:yaml/yaml.dart'; | 14 import 'package:yaml/yaml.dart'; |
16 | 15 |
17 /// Options used by our checker. | 16 import 'package:dev_compiler/strong_mode.dart' show StrongModeOptions; |
18 // TODO(jmesserly): move useMultiPackage/packageRoot to CompilerOptions. | 17 |
19 class ResolverOptions { | 18 /// Options used to set up Source URI resolution in the analysis context. |
19 class SourceResolverOptions { | |
20 /// Whether to resolve 'package:' uris using the multi-package resolver. | 20 /// Whether to resolve 'package:' uris using the multi-package resolver. |
21 final bool useMultiPackage; | 21 final bool useMultiPackage; |
22 | 22 |
23 /// Custom URI mappings, such as "dart:foo" -> "path/to/foo.dart" | |
24 final Map<String, String> customUrlMappings; | |
25 | |
23 /// Package root when resolving 'package:' urls the standard way. | 26 /// Package root when resolving 'package:' urls the standard way. |
24 final String packageRoot; | 27 final String packageRoot; |
25 | 28 |
26 /// List of paths used for the multi-package resolver. | 29 /// List of paths used for the multi-package resolver. |
27 final List<String> packagePaths; | 30 final List<String> packagePaths; |
28 | 31 |
29 /// List of additional non-Dart resources to resolve and serve. | 32 /// List of additional non-Dart resources to resolve and serve. |
30 final List<String> resources; | 33 final List<String> resources; |
31 | 34 |
32 /// Whether to infer return types and field types from overriden members. | |
33 final bool inferFromOverrides; | |
34 static const inferFromOverridesDefault = true; | |
35 | |
36 /// Whether to infer types for consts and fields by looking at initializers on | |
37 /// the RHS. For example, in a constant declaration like: | |
38 /// | |
39 /// const A = B; | |
40 /// | |
41 /// We can infer the type of `A` based on the type of `B`. | |
42 /// | |
43 /// The inference algorithm determines what variables depend on others, and | |
44 /// computes types by visiting the variable dependency graph in topological | |
45 /// order. This ensures that the inferred type is deterministic when applying | |
46 /// inference on library cycles. | |
47 /// | |
48 /// When this feature is turned off, we don't use the type of `B` to infer the | |
49 /// type of `A`, even if `B` has a declared type. | |
50 final bool inferTransitively; | |
51 static const inferTransitivelyDefault = true; | |
52 | |
53 /// Restrict inference of fields and top-levels to those that are final and | |
54 /// const. | |
55 final bool onlyInferConstsAndFinalFields; | |
56 static const onlyInferConstAndFinalFieldsDefault = false; | |
57 | |
58 /// File where to start compilation from. | 35 /// File where to start compilation from. |
36 // TODO(jmesserly): this is used to configure SourceFactory resolvers only | |
37 // when [useImplicitHtml] is set. Probably useImplicitHtml should be factored | |
38 // out into ServerOptions or something along those lines. | |
59 final String entryPointFile; | 39 final String entryPointFile; |
60 | 40 |
61 // True if the resolver should implicitly provide an html entry point. | 41 // True if the resolver should implicitly provide an html entry point. |
62 final bool useImplicitHtml; | 42 final bool useImplicitHtml; |
63 static const String implicitHtmlFile = 'index.html'; | 43 static const String implicitHtmlFile = 'index.html'; |
64 | 44 |
65 ResolverOptions({this.useMultiPackage: false, this.packageRoot: 'packages/', | 45 /// Whether to use a mock-sdk during compilation. |
66 this.packagePaths: const <String>[], this.resources: const <String>[], | 46 final bool useMockSdk; |
67 this.inferFromOverrides: inferFromOverridesDefault, | 47 |
68 this.inferTransitively: inferTransitivelyDefault, | 48 /// Path to the dart-sdk. Null if `useMockSdk` is true or if the path couldn't |
69 this.onlyInferConstsAndFinalFields: onlyInferConstAndFinalFieldsDefault, | 49 /// be determined |
70 this.entryPointFile: null, this.useImplicitHtml: false}); | 50 final String dartSdkPath; |
51 | |
52 const SourceResolverOptions({this.useMockSdk: false, this.dartSdkPath, | |
53 this.useMultiPackage: false, this.customUrlMappings: const {}, | |
54 this.packageRoot: 'packages/', this.packagePaths: const <String>[], | |
55 this.resources: const <String>[], this.entryPointFile: null, | |
56 this.useImplicitHtml: false}); | |
71 } | 57 } |
72 | 58 |
73 // TODO(vsm): Merge RulesOptions and TypeOptions | 59 // TODO(jmesserly): refactor all codegen options here. |
74 /// Options used by our RestrictedRules. | 60 class CodegenOptions { |
75 class RulesOptions extends TypeOptions { | |
76 /// Whether to infer types downwards from local context | |
77 final bool inferDownwards; | |
78 static const inferDownwardsDefault = true; | |
79 | |
80 /// Whether to inject casts between Dart assignable types. | |
81 final bool relaxedCasts; | |
82 | |
83 RulesOptions( | |
84 {this.inferDownwards: inferDownwardsDefault, this.relaxedCasts: true}); | |
85 } | |
86 | |
87 class JSCodeOptions { | |
88 /// Whether to emit the source map files. | 61 /// Whether to emit the source map files. |
89 final bool emitSourceMaps; | 62 final bool emitSourceMaps; |
90 | 63 |
91 JSCodeOptions({this.emitSourceMaps: true}); | 64 /// Whether to force compilation of code with static errors. |
65 final bool forceCompile; | |
66 | |
67 /// Output directory for generated code. | |
68 final String outputDir; | |
69 | |
70 const CodegenOptions( | |
71 {this.emitSourceMaps: true, this.forceCompile: false, this.outputDir}); | |
92 } | 72 } |
93 | 73 |
94 /// General options used by the dev compiler. | 74 /// General options used by the dev compiler and server. |
95 class CompilerOptions implements RulesOptions, ResolverOptions, JSCodeOptions { | 75 class CompilerOptions { |
76 final StrongModeOptions strongOptions; | |
Jennifer Messerly
2015/06/10 22:34:17
decided to go composition over inheritance. Seemed
| |
77 final SourceResolverOptions sourceOptions; | |
78 final CodegenOptions codegenOptions; | |
79 | |
96 /// Whether to check the sdk libraries. | 80 /// Whether to check the sdk libraries. |
97 final bool checkSdk; | 81 final bool checkSdk; |
98 | 82 |
99 /// Whether to dump summary information on the console. | 83 /// Whether to dump summary information on the console. |
100 final bool dumpInfo; | 84 final bool dumpInfo; |
101 | 85 |
102 /// If not null, path to a file that will store a json representation of the | 86 /// If not null, path to a file that will store a json representation of the |
103 /// summary information (only used if [dumpInfo] is true). | 87 /// summary information (only used if [dumpInfo] is true). |
104 final String dumpInfoFile; | 88 final String dumpInfoFile; |
105 | 89 |
106 /// Whether to force compilation of code with static errors. | |
107 final bool forceCompile; | |
108 | |
109 /// Output directory for generated code. | |
110 final String outputDir; | |
111 | |
112 /// Whether to use colors when interacting on the console. | 90 /// Whether to use colors when interacting on the console. |
113 final bool useColors; | 91 final bool useColors; |
114 | 92 |
115 /// Whether the user asked for help. | 93 /// Whether the user asked for help. |
116 final bool help; | 94 final bool help; |
117 | 95 |
118 /// Whether to use a mock-sdk during compilation. | |
119 final bool useMockSdk; | |
120 | |
121 /// Path to the dart-sdk. Null if `useMockSdk` is true or if the path couldn't | |
122 /// be determined | |
123 final String dartSdkPath; | |
124 | |
125 /// Minimum log-level reported on the command-line. | 96 /// Minimum log-level reported on the command-line. |
126 final Level logLevel; | 97 final Level logLevel; |
127 | 98 |
128 /// File where to start compilation from. | |
129 final String entryPointFile; | |
130 | |
131 /// Whether to run as a development server. | 99 /// Whether to run as a development server. |
132 final bool serverMode; | 100 final bool serverMode; |
133 | 101 |
134 /// Whether to create an implicit HTML entry file in server mode. | |
135 final bool useImplicitHtml; | |
136 | |
137 /// Whether to enable hash-based caching of files. | 102 /// Whether to enable hash-based caching of files. |
138 final bool enableHashing; | 103 final bool enableHashing; |
139 | 104 |
140 /// Port used for the HTTP server when [serverMode] is on. | 105 /// Port used for the HTTP server when [serverMode] is on. |
141 final int port; | 106 final int port; |
142 | 107 |
143 /// Host name or address for HTTP server when [serverMode] is on. | 108 /// Host name or address for HTTP server when [serverMode] is on. |
144 final String host; | 109 final String host; |
145 | 110 |
146 /// Whether to inject casts between Dart assignable types. | |
147 @override | |
148 final bool relaxedCasts; | |
149 | |
150 /// Whether to resolve 'package:' uris using the multi-package resolver. | |
151 @override | |
152 final bool useMultiPackage; | |
153 | |
154 /// Package root when resolving 'package:' urls the standard way. | |
155 @override | |
156 final String packageRoot; | |
157 | |
158 /// List of paths used for the multi-package resolver. | |
159 @override | |
160 final List<String> packagePaths; | |
161 | |
162 /// List of additional non-Dart resources to resolve and serve. | |
163 @override | |
164 final List<String> resources; | |
165 | |
166 /// Whether to infer types downwards from local context | |
167 @override | |
168 final bool inferDownwards; | |
169 | |
170 /// Whether to infer return types and field types from overriden members. | |
171 @override | |
172 final bool inferFromOverrides; | |
173 | |
174 /// Whether to infer types for consts and static fields by looking at | |
175 /// identifiers on the RHS. | |
176 @override | |
177 final bool inferTransitively; | |
178 | |
179 /// Restrict inference of fields and top-levels to those that are final and | |
180 /// const. | |
181 @override | |
182 final bool onlyInferConstsAndFinalFields; | |
183 | |
184 /// List of non-nullable types. | |
185 @override | |
186 final List<String> nonnullableTypes; | |
187 | |
188 /// Whether to emit the source map files. | |
189 @override | |
190 final bool emitSourceMaps; | |
191 | |
192 /// Location for runtime files, such as `dart_runtime.js`. By default this is | 111 /// Location for runtime files, such as `dart_runtime.js`. By default this is |
193 /// inferred to be under `lib/runtime/` in the location of the `dev_compiler` | 112 /// inferred to be under `lib/runtime/` in the location of the `dev_compiler` |
194 /// package (if we can infer where that is located). | 113 /// package (if we can infer where that is located). |
195 final String runtimeDir; | 114 final String runtimeDir; |
196 | 115 |
197 /// Custom URI mappings, such as "dart:foo" -> "path/to/foo.dart" | 116 CompilerOptions({this.strongOptions: const StrongModeOptions(), |
198 final Map<String, String> customUrlMappings; | 117 this.sourceOptions: const SourceResolverOptions(), |
199 | 118 this.codegenOptions: const CodegenOptions(), this.checkSdk: false, |
200 CompilerOptions({this.checkSdk: false, this.dumpInfo: false, | 119 this.dumpInfo: false, this.dumpInfoFile, this.useColors: true, |
201 this.dumpInfoFile, this.forceCompile: false, this.outputDir, | 120 this.help: false, this.logLevel: Level.SEVERE, this.serverMode: false, |
202 this.useColors: true, this.relaxedCasts: true, | |
203 this.useMultiPackage: false, this.packageRoot: 'packages/', | |
204 this.packagePaths: const <String>[], this.resources: const <String>[], | |
205 this.inferDownwards: RulesOptions.inferDownwardsDefault, | |
206 this.inferFromOverrides: ResolverOptions.inferFromOverridesDefault, | |
207 this.inferTransitively: ResolverOptions.inferTransitivelyDefault, | |
208 this.onlyInferConstsAndFinalFields: ResolverOptions.onlyInferConstAndFinal FieldsDefault, | |
209 this.nonnullableTypes: TypeOptions.NONNULLABLE_TYPES, this.help: false, | |
210 this.useMockSdk: false, this.dartSdkPath, this.logLevel: Level.SEVERE, | |
211 this.emitSourceMaps: true, this.entryPointFile: null, | |
212 this.serverMode: false, this.useImplicitHtml: false, | |
213 this.enableHashing: false, this.host: 'localhost', this.port: 8080, | 121 this.enableHashing: false, this.host: 'localhost', this.port: 8080, |
214 this.runtimeDir, this.customUrlMappings: const {}}); | 122 this.runtimeDir}); |
215 } | 123 } |
216 | 124 |
217 /// Parses options from the command-line | 125 /// Parses options from the command-line |
218 CompilerOptions parseOptions(List<String> argv) { | 126 CompilerOptions parseOptions(List<String> argv) { |
219 ArgResults args = argParser.parse(argv); | 127 ArgResults args = argParser.parse(argv); |
220 bool showUsage = args['help']; | 128 bool showUsage = args['help']; |
221 | 129 |
222 var serverMode = args['server']; | 130 var serverMode = args['server']; |
223 var enableHashing = args['hashing']; | 131 var enableHashing = args['hashing']; |
224 if (enableHashing == null) { | 132 if (enableHashing == null) { |
(...skipping 29 matching lines...) Expand all Loading... | |
254 if (splitMapping.length != 2) { | 162 if (splitMapping.length != 2) { |
255 showUsage = true; | 163 showUsage = true; |
256 continue; | 164 continue; |
257 } | 165 } |
258 customUrlMappings[splitMapping[0]] = splitMapping[1]; | 166 customUrlMappings[splitMapping[0]] = splitMapping[1]; |
259 } | 167 } |
260 | 168 |
261 var entryPointFile = args.rest.length == 0 ? null : args.rest.first; | 169 var entryPointFile = args.rest.length == 0 ? null : args.rest.first; |
262 | 170 |
263 return new CompilerOptions( | 171 return new CompilerOptions( |
172 codegenOptions: new CodegenOptions( | |
173 emitSourceMaps: args['source-maps'], | |
174 forceCompile: args['force-compile'] || serverMode, | |
175 outputDir: outputDir), | |
176 sourceOptions: new SourceResolverOptions( | |
177 useMockSdk: args['mock-sdk'], | |
178 dartSdkPath: sdkPath, | |
179 entryPointFile: entryPointFile, | |
180 useImplicitHtml: serverMode && entryPointFile.endsWith('.dart'), | |
181 customUrlMappings: customUrlMappings, | |
182 useMultiPackage: args['use-multi-package'], | |
183 packageRoot: args['package-root'], | |
184 packagePaths: args['package-paths'].split(','), | |
185 resources: args['resources'] | |
186 .split(',') | |
187 .where((s) => s.isNotEmpty) | |
188 .toList()), | |
189 strongOptions: new StrongModeOptions.fromArguments(args), | |
264 checkSdk: args['sdk-check'], | 190 checkSdk: args['sdk-check'], |
265 dumpInfo: dumpInfo, | 191 dumpInfo: dumpInfo, |
266 dumpInfoFile: args['dump-info-file'], | 192 dumpInfoFile: args['dump-info-file'], |
267 forceCompile: args['force-compile'] || serverMode, | |
268 outputDir: outputDir, | |
269 relaxedCasts: args['relaxed-casts'], | |
270 useColors: useColors, | 193 useColors: useColors, |
271 customUrlMappings: customUrlMappings, | |
272 useMultiPackage: args['use-multi-package'], | |
273 packageRoot: args['package-root'], | |
274 packagePaths: args['package-paths'].split(','), | |
275 resources: args['resources'] | |
276 .split(',') | |
277 .where((s) => s.isNotEmpty) | |
278 .toList(), | |
279 inferDownwards: args['infer-downwards'], | |
280 inferFromOverrides: args['infer-from-overrides'], | |
281 inferTransitively: args['infer-transitively'], | |
282 onlyInferConstsAndFinalFields: args['infer-only-finals'], | |
283 nonnullableTypes: optionsToList(args['nonnullable'], | |
284 defaultValue: TypeOptions.NONNULLABLE_TYPES), | |
285 help: showUsage, | 194 help: showUsage, |
286 useMockSdk: args['mock-sdk'], | |
287 dartSdkPath: sdkPath, | |
288 logLevel: logLevel, | 195 logLevel: logLevel, |
289 emitSourceMaps: args['source-maps'], | |
290 entryPointFile: entryPointFile, | |
291 serverMode: serverMode, | 196 serverMode: serverMode, |
292 useImplicitHtml: serverMode && entryPointFile.endsWith('.dart'), | |
293 enableHashing: enableHashing, | 197 enableHashing: enableHashing, |
294 host: args['host'], | 198 host: args['host'], |
295 port: int.parse(args['port']), | 199 port: int.parse(args['port']), |
296 runtimeDir: runtimeDir); | 200 runtimeDir: runtimeDir); |
297 } | 201 } |
298 | 202 |
299 final ArgParser argParser = new ArgParser() | 203 final ArgParser argParser = StrongModeOptions.addArguments(new ArgParser() |
300 // resolver/checker options | |
301 ..addFlag('sdk-check', | 204 ..addFlag('sdk-check', |
302 abbr: 's', help: 'Typecheck sdk libs', defaultsTo: false) | 205 abbr: 's', help: 'Typecheck sdk libs', defaultsTo: false) |
303 ..addFlag('mock-sdk', | 206 ..addFlag('mock-sdk', |
304 abbr: 'm', help: 'Use a mock Dart SDK', defaultsTo: false) | 207 abbr: 'm', help: 'Use a mock Dart SDK', defaultsTo: false) |
305 ..addFlag('relaxed-casts', | |
306 help: 'Cast between Dart assignable types', defaultsTo: true) | |
307 ..addOption('nonnullable', | |
308 abbr: 'n', | |
309 help: 'Comma separated string of non-nullable types', | |
310 defaultsTo: null) | |
311 ..addFlag('infer-downwards', | |
312 help: 'Infer types downwards from local context', | |
313 defaultsTo: RulesOptions.inferDownwardsDefault) | |
314 ..addFlag('infer-from-overrides', | |
315 help: 'Infer unspecified types of fields and return types from\n' | |
316 'definitions in supertypes', | |
317 defaultsTo: ResolverOptions.inferFromOverridesDefault) | |
318 ..addFlag('infer-transitively', | |
319 help: 'Infer consts/fields from definitions in other libraries', | |
320 defaultsTo: ResolverOptions.inferTransitivelyDefault) | |
321 ..addFlag('infer-only-finals', | |
322 help: 'Do not infer non-const or non-final fields', | |
323 defaultsTo: ResolverOptions.onlyInferConstAndFinalFieldsDefault) | |
324 | 208 |
325 // input/output options | 209 // input/output options |
326 ..addOption('out', abbr: 'o', help: 'Output directory', defaultsTo: null) | 210 ..addOption('out', abbr: 'o', help: 'Output directory', defaultsTo: null) |
327 ..addOption('dart-sdk', help: 'Dart SDK Path', defaultsTo: null) | 211 ..addOption('dart-sdk', help: 'Dart SDK Path', defaultsTo: null) |
328 ..addOption('dump-src-to', help: 'Dump dart src code', defaultsTo: null) | 212 ..addOption('dump-src-to', help: 'Dump dart src code', defaultsTo: null) |
329 ..addOption('package-root', | 213 ..addOption('package-root', |
330 abbr: 'p', | 214 abbr: 'p', |
331 help: 'Package root to resolve "package:" imports', | 215 help: 'Package root to resolve "package:" imports', |
332 defaultsTo: 'packages/') | 216 defaultsTo: 'packages/') |
333 ..addOption('url-mapping', | 217 ..addOption('url-mapping', |
(...skipping 27 matching lines...) Expand all Loading... | |
361 help: 'Port to serve files from (used only when --serve is on)', | 245 help: 'Port to serve files from (used only when --serve is on)', |
362 defaultsTo: '8080') | 246 defaultsTo: '8080') |
363 ..addFlag('force-compile', | 247 ..addFlag('force-compile', |
364 help: 'Compile code with static errors', defaultsTo: false) | 248 help: 'Compile code with static errors', defaultsTo: false) |
365 ..addOption('log', abbr: 'l', help: 'Logging level (defaults to severe)') | 249 ..addOption('log', abbr: 'l', help: 'Logging level (defaults to severe)') |
366 ..addFlag('dump-info', | 250 ..addFlag('dump-info', |
367 abbr: 'i', help: 'Dump summary information', defaultsTo: null) | 251 abbr: 'i', help: 'Dump summary information', defaultsTo: null) |
368 ..addOption('dump-info-file', | 252 ..addOption('dump-info-file', |
369 abbr: 'f', | 253 abbr: 'f', |
370 help: 'Dump info json file (requires dump-info)', | 254 help: 'Dump info json file (requires dump-info)', |
371 defaultsTo: null); | 255 defaultsTo: null)); |
372 | 256 |
373 /// Tries to find the `lib/runtime/` directory of the dev_compiler package. This | 257 /// Tries to find the `lib/runtime/` directory of the dev_compiler package. This |
374 /// works when running devc from it's sources or from a snapshot that is | 258 /// works when running devc from it's sources or from a snapshot that is |
375 /// activated via `pub global activate`. | 259 /// activated via `pub global activate`. |
376 String _computeRuntimeDir() { | 260 String _computeRuntimeDir() { |
377 var scriptUri = Platform.script; | 261 var scriptUri = Platform.script; |
378 var scriptPath = scriptUri.path; | 262 var scriptPath = scriptUri.path; |
379 var file = path.basename(scriptPath); | 263 var file = path.basename(scriptPath); |
380 var dir = path.dirname(scriptPath); | 264 var dir = path.dirname(scriptPath); |
381 var lastdir = path.basename(dir); | 265 var lastdir = path.basename(dir); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
413 // The pub-cache directory is two levels up, but we verify that the layout | 297 // The pub-cache directory is two levels up, but we verify that the layout |
414 // looks correct. | 298 // looks correct. |
415 if (path.basename(dir) != 'dev_compiler') return null; | 299 if (path.basename(dir) != 'dev_compiler') return null; |
416 dir = path.dirname(dir); | 300 dir = path.dirname(dir); |
417 if (path.basename(dir) != 'global_packages') return null; | 301 if (path.basename(dir) != 'global_packages') return null; |
418 dir = path.dirname(dir); | 302 dir = path.dirname(dir); |
419 return path.join(dir, cacheDir, 'lib', 'runtime'); | 303 return path.join(dir, cacheDir, 'lib', 'runtime'); |
420 } | 304 } |
421 return null; | 305 return null; |
422 } | 306 } |
OLD | NEW |