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

Side by Side Diff: lib/src/options.dart

Issue 1879373004: Implement modular compilation (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 8 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/multi_package_resolver.dart ('k') | lib/src/report.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /// Set of flags and options passed to the compiler
6
7 import 'dart:io';
8
9 import 'package:args/args.dart';
10 import 'package:cli_util/cli_util.dart' show getSdkDir;
11 import 'package:logging/logging.dart' show Level;
12 import 'package:path/path.dart' as path;
13 import 'package:yaml/yaml.dart';
14
15 import 'utils.dart' show parseEnum, getEnumName;
16
17 const String _V8_BINARY_DEFAULT = 'node';
18 const bool _CLOSURE_DEFAULT = false;
19
20 /// Older V8 versions do not accept default values with destructuring in
21 /// arrow functions yet (e.g. `({a} = {}) => 1`) but happily accepts them
22 /// with regular functions (e.g. `function({a} = {}) { return 1 }`).
23 ///
24 /// Supporting the syntax:
25 /// * Chrome Canary (51)
26 /// * Firefox
27 ///
28 /// Not yet supporting:
29 /// * Atom (1.5.4)
30 /// * Electron (0.36.3)
31 ///
32 // TODO(ochafik): Simplify this code when our target platforms catch up.
33 const bool _DESTRUCTURE_NAMED_PARAMS_DEFAULT = false;
34
35 /// Options used to set up Source URI resolution in the analysis context.
36 class SourceResolverOptions {
37 /// Whether to resolve 'package:' uris using the multi-package resolver.
38 final bool useMultiPackage;
39
40 /// Custom URI mappings, such as "dart:foo" -> "path/to/foo.dart"
41 final Map<String, String> customUrlMappings;
42
43 /// Package root when resolving 'package:' urls the standard way.
44 final String packageRoot;
45
46 /// List of paths used for the multi-package resolver.
47 final List<String> packagePaths;
48
49 /// Whether to use a mock-sdk during compilation.
50 final bool useMockSdk;
51
52 /// Path to the dart-sdk. Null if `useMockSdk` is true or if the path couldn't
53 /// be determined
54 final String dartSdkPath;
55
56 const SourceResolverOptions(
57 {this.useMockSdk: false,
58 this.dartSdkPath,
59 this.useMultiPackage: false,
60 this.customUrlMappings: const {},
61 this.packageRoot: 'packages/',
62 this.packagePaths: const <String>[]});
63 }
64
65 enum ModuleFormat { es6, legacy, node }
66 ModuleFormat parseModuleFormat(String s) => parseEnum(s, ModuleFormat.values);
67
68 // TODO(jmesserly): refactor all codegen options here.
69 class CodegenOptions {
70 /// Whether to emit the source map files.
71 final bool emitSourceMaps;
72
73 /// Whether to force compilation of code with static errors.
74 final bool forceCompile;
75
76 /// Output directory for generated code.
77 final String outputDir;
78
79 /// Emit Closure Compiler-friendly code.
80 final bool closure;
81
82 /// Enable ES6 destructuring of named parameters.
83 final bool destructureNamedParams;
84
85 /// Which module format to support.
86 /// Currently 'es6' and 'legacy' are supported.
87 final ModuleFormat moduleFormat;
88
89 const CodegenOptions(
90 {this.emitSourceMaps: true,
91 this.forceCompile: false,
92 this.closure: _CLOSURE_DEFAULT,
93 this.destructureNamedParams: _DESTRUCTURE_NAMED_PARAMS_DEFAULT,
94 this.outputDir,
95 this.moduleFormat: ModuleFormat.legacy});
96 }
97
98 /// Options for devrun.
99 class RunnerOptions {
100 /// V8-based binary to be used to run the .js output (d8, iojs, node).
101 /// Can be just the executable name if it's in the path, or a path to the
102 /// executable.
103 final String v8Binary;
104
105 const RunnerOptions({this.v8Binary: _V8_BINARY_DEFAULT});
106 }
107
108 /// General options used by the dev compiler and server.
109 class CompilerOptions {
110 final SourceResolverOptions sourceOptions;
111 final CodegenOptions codegenOptions;
112 final RunnerOptions runnerOptions;
113
114 /// Whether to check the sdk libraries.
115 final bool checkSdk;
116
117 /// Whether to use colors when interacting on the console.
118 final bool useColors;
119
120 /// Whether the user asked for help.
121 final bool help;
122
123 /// Whether the user asked for the app version.
124 final bool version;
125
126 /// Minimum log-level reported on the command-line.
127 final Level logLevel;
128
129 /// Location for runtime files, such as `dart_runtime.js`. By default this is
130 /// inferred to be under `lib/runtime/` in the location of the `dev_compiler`
131 /// package (if we can infer where that is located).
132 final String runtimeDir;
133
134 /// The files to compile.
135 final List<String> inputs;
136
137 /// The base directory for [inputs]. Module imports will be generated relative
138 /// to this directory.
139 final String inputBaseDir;
140
141 const CompilerOptions(
142 {this.sourceOptions: const SourceResolverOptions(),
143 this.codegenOptions: const CodegenOptions(),
144 this.runnerOptions: const RunnerOptions(),
145 this.checkSdk: false,
146 this.useColors: true,
147 this.help: false,
148 this.version: false,
149 this.logLevel: Level.WARNING,
150 this.runtimeDir,
151 this.inputs,
152 this.inputBaseDir});
153 }
154
155 /// Parses options from the command-line
156 CompilerOptions parseOptions(List<String> argv, {bool forceOutDir: false}) {
157 ArgResults args = argParser.parse(argv);
158 bool showUsage = args['help'];
159 bool showVersion = args['version'];
160
161 var logLevel = Level.WARNING;
162 var levelName = args['log'];
163 if (levelName != null) {
164 levelName = levelName.toUpperCase();
165 logLevel = Level.LEVELS
166 .firstWhere((l) => l.name == levelName, orElse: () => logLevel);
167 }
168 var useColors = stdioType(stdout) == StdioType.TERMINAL;
169 var sdkPath = args['dart-sdk'];
170 if (sdkPath == null && !args['mock-sdk']) {
171 sdkPath = getSdkDir(argv).path;
172 }
173 var runtimeDir = args['runtime-dir'];
174 if (runtimeDir == null) {
175 runtimeDir = _computeRuntimeDir();
176 }
177 var outputDir = args['out'];
178 if (outputDir == null && forceOutDir) {
179 outputDir = Directory.systemTemp.createTempSync("dev_compiler_out_").path;
180 }
181
182 var v8Binary = args['v8-binary'];
183 if (v8Binary == null) v8Binary = _V8_BINARY_DEFAULT;
184
185 var customUrlMappings = <String, String>{};
186 for (var mapping in args['url-mapping']) {
187 var splitMapping = mapping.split(',');
188 if (splitMapping.length != 2) {
189 showUsage = true;
190 continue;
191 }
192 customUrlMappings[splitMapping[0]] = splitMapping[1];
193 }
194
195 return new CompilerOptions(
196 codegenOptions: new CodegenOptions(
197 emitSourceMaps: args['source-maps'],
198 forceCompile: args['force-compile'],
199 closure: args['closure'],
200 destructureNamedParams: args['destructure-named-params'],
201 outputDir: outputDir,
202 moduleFormat: parseModuleFormat(args['modules'])),
203 sourceOptions: new SourceResolverOptions(
204 useMockSdk: args['mock-sdk'],
205 dartSdkPath: sdkPath,
206 customUrlMappings: customUrlMappings,
207 useMultiPackage: args['use-multi-package'],
208 packageRoot: args['package-root'],
209 packagePaths: args['package-paths'].split(',')),
210 runnerOptions: new RunnerOptions(v8Binary: v8Binary),
211 checkSdk: args['sdk-check'],
212 useColors: useColors,
213 help: showUsage,
214 version: showVersion,
215 logLevel: logLevel,
216 runtimeDir: runtimeDir,
217 inputs: args.rest);
218 }
219
220 final ArgParser argParser = new ArgParser()
221 ..addFlag('sdk-check',
222 abbr: 's', help: 'Typecheck sdk libs', defaultsTo: false)
223 ..addFlag('mock-sdk',
224 abbr: 'm', help: 'Use a mock Dart SDK', defaultsTo: false)
225
226 // input/output options
227 ..addOption('out', abbr: 'o', help: 'Output directory', defaultsTo: null)
228 ..addOption('dart-sdk', help: 'Dart SDK Path', defaultsTo: null)
229 ..addOption('package-root',
230 abbr: 'p',
231 help: 'Package root to resolve "package:" imports',
232 defaultsTo: 'packages/')
233 ..addOption('url-mapping',
234 help: '--url-mapping=libraryUri,/path/to/library.dart uses library.dart\n'
235 'as the source for an import of of "libraryUri".',
236 allowMultiple: true,
237 splitCommas: false)
238 ..addFlag('use-multi-package',
239 help: 'Whether to use the multi-package resolver for "package:" imports',
240 defaultsTo: false)
241 ..addOption('package-paths',
242 help: 'if using the multi-package resolver, the list of directories to\n'
243 'look for packages in.',
244 defaultsTo: '')
245 ..addFlag('source-maps',
246 help: 'Whether to emit source map files', defaultsTo: true)
247 ..addOption('runtime-dir',
248 help: 'Where to find dev_compiler\'s runtime files', defaultsTo: null)
249 ..addOption('modules',
250 help: 'Which module pattern to emit',
251 allowed: ModuleFormat.values.map(getEnumName).toList(),
252 allowedHelp: {
253 getEnumName(ModuleFormat.es6): 'es6 modules',
254 getEnumName(ModuleFormat.legacy):
255 'a custom format used by dartdevc, similar to AMD',
256 getEnumName(ModuleFormat.node):
257 'node.js modules (https://nodejs.org/api/modules.html)'
258 },
259 defaultsTo: getEnumName(ModuleFormat.legacy))
260
261 // general options
262 ..addFlag('help', abbr: 'h', help: 'Display this message')
263 ..addFlag('version',
264 negatable: false, help: 'Display the Dev Compiler verion')
265 ..addFlag('closure',
266 help: 'Emit Closure Compiler-friendly code (experimental)',
267 defaultsTo: _CLOSURE_DEFAULT)
268 ..addFlag('destructure-named-params',
269 help: 'Destructure named parameters (requires ES6-enabled runtime)',
270 defaultsTo: _DESTRUCTURE_NAMED_PARAMS_DEFAULT)
271 ..addFlag('force-compile',
272 abbr: 'f', help: 'Compile code with static errors', defaultsTo: false)
273 ..addOption('log', abbr: 'l', help: 'Logging level (defaults to warning)')
274 ..addOption('v8-binary',
275 help: 'V8-based binary to run JavaScript output with (iojs, node, d8)',
276 defaultsTo: _V8_BINARY_DEFAULT);
277
278 // TODO: Switch over to the `pub_cache` package (or the Resource API)?
279
280 const _ENTRY_POINTS = const [
281 'dartdevc.dart',
282 'dev_compiler.dart',
283 'devrun.dart'
284 ];
285
286 final _ENTRY_POINT_SNAPSHOTS = _ENTRY_POINTS.map((f) => "$f.snapshot");
287
288 /// Tries to find the `lib/runtime/` directory of the dev_compiler package. This
289 /// works when running devc from it's sources or from a snapshot that is
290 /// activated via `pub global activate`.
291 String _computeRuntimeDir() {
292 var scriptPath = path.fromUri(Platform.script);
293 var file = path.basename(scriptPath);
294 var dir = path.dirname(scriptPath);
295 var lastdir = path.basename(dir);
296 dir = path.dirname(dir);
297
298 // Both the source dartdevc.dart and the snapshot generated by pub global acti vate
299 // are under a bin folder.
300 if (lastdir != 'bin') return null;
301
302 // And both under a project directory containing a pubspec.lock file.
303 var lockfile = path.join(dir, 'pubspec.lock');
304 if (!new File(lockfile).existsSync()) return null;
305
306 // If running from sources we found it!
307 if (_ENTRY_POINTS.contains(file)) {
308 return path.join(dir, 'lib', 'runtime');
309 }
310
311 // If running from a pub global snapshot, we need to read the lock file to
312 // find where the actual sources are located in the pub cache.
313 if (_ENTRY_POINT_SNAPSHOTS.contains(file)) {
314 // Note: this depends on implementation details of pub.
315 var yaml = loadYaml(new File(lockfile).readAsStringSync());
316 var info = yaml['packages']['dev_compiler'];
317 if (info == null) return null;
318
319 var cacheDir;
320 if (info['source'] == 'hosted') {
321 cacheDir = path.join(
322 'hosted', 'pub.dartlang.org', 'dev_compiler-${info["version"]}');
323 } else if (info['source'] == 'git') {
324 var ref = info['description']['resolved-ref'];
325 cacheDir = path.join('git', 'dev_compiler-${ref}');
326 }
327
328 // We should be under "/path/to/pub-cache/global_packages/dev_compiler".
329 // The pub-cache directory is two levels up, but we verify that the layout
330 // looks correct.
331 if (path.basename(dir) != 'dev_compiler') return null;
332 dir = path.dirname(dir);
333 if (path.basename(dir) != 'global_packages') return null;
334 dir = path.dirname(dir);
335 return path.join(dir, cacheDir, 'lib', 'runtime');
336 }
337 return null;
338 }
OLDNEW
« no previous file with comments | « lib/src/multi_package_resolver.dart ('k') | lib/src/report.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698