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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/dart2js.dart

Issue 692513002: Remove old dart2js code. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013, 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 library dart2js.cmdline;
6
7 import 'dart:async'
8 show Future, EventSink;
9 import 'dart:io'
10 show exit, File, FileMode, Platform, RandomAccessFile, FileSystemException,
11 stdin, stderr;
12
13 import '../compiler.dart' as api;
14 import 'source_file.dart';
15 import 'source_file_provider.dart';
16 import 'filenames.dart';
17 import 'util/uri_extras.dart';
18 import 'util/util.dart' show stackTraceFilePrefix;
19 import 'util/command_line.dart';
20 import '../../libraries.dart';
21
22 const String LIBRARY_ROOT = '../../../../..';
23 const String OUTPUT_LANGUAGE_DART = 'Dart';
24
25 /**
26 * A string to identify the revision or build.
27 *
28 * This ID is displayed if the compiler crashes and in verbose mode, and is
29 * an aid in reproducing bug reports.
30 *
31 * The actual string is rewritten by a wrapper script when included in the sdk.
32 */
33 String BUILD_ID = null;
34
35 /**
36 * The data passed to the [HandleOption] callback is either a single
37 * string argument, or the arguments iterator for multiple arguments
38 * handlers.
39 */
40 typedef void HandleOption(data);
41
42 class OptionHandler {
43 final String pattern;
44 final HandleOption handle;
45 final bool multipleArguments;
46
47 OptionHandler(this.pattern, this.handle, {this.multipleArguments: false});
48 }
49
50 /**
51 * Extract the parameter of an option.
52 *
53 * For example, in ['--out=fisk.js'] and ['-ohest.js'], the parameters
54 * are ['fisk.js'] and ['hest.js'], respectively.
55 */
56 String extractParameter(String argument, {bool isOptionalArgument: false}) {
57 // m[0] is the entire match (which will be equal to argument). m[1]
58 // is something like "-o" or "--out=", and m[2] is the parameter.
59 Match m = new RegExp('^(-[a-z]|--.+=)(.*)').firstMatch(argument);
60 if (m == null) {
61 if (isOptionalArgument) return null;
62 helpAndFail('Unknown option "$argument".');
63 }
64 return m[2];
65 }
66
67 String extractPath(String argument) {
68 String path = nativeToUriPath(extractParameter(argument));
69 return path.endsWith("/") ? path : "$path/";
70 }
71
72 void parseCommandLine(List<OptionHandler> handlers, List<String> argv) {
73 // TODO(ahe): Use ../../args/args.dart for parsing options instead.
74 var patterns = <String>[];
75 for (OptionHandler handler in handlers) {
76 patterns.add(handler.pattern);
77 }
78 var pattern = new RegExp('^(${patterns.join(")\$|^(")})\$');
79
80 Iterator<String> arguments = argv.iterator;
81 OUTER: while (arguments.moveNext()) {
82 String argument = arguments.current;
83 Match match = pattern.firstMatch(argument);
84 assert(match.groupCount == handlers.length);
85 for (int i = 0; i < handlers.length; i++) {
86 if (match[i + 1] != null) {
87 OptionHandler handler = handlers[i];
88 if (handler.multipleArguments) {
89 handler.handle(arguments);
90 } else {
91 handler.handle(argument);
92 }
93 continue OUTER;
94 }
95 }
96 throw 'Internal error: "$argument" did not match';
97 }
98 }
99
100 FormattingDiagnosticHandler diagnosticHandler;
101
102 Future compile(List<String> argv) {
103 stackTraceFilePrefix = '$currentDirectory';
104 Uri libraryRoot = currentDirectory;
105 Uri out = currentDirectory.resolve('out.js');
106 Uri sourceMapOut = currentDirectory.resolve('out.js.map');
107 Uri packageRoot = null;
108 List<String> options = new List<String>();
109 bool explicitOut = false;
110 bool wantHelp = false;
111 bool wantVersion = false;
112 String outputLanguage = 'JavaScript';
113 bool stripArgumentSet = false;
114 bool analyzeOnly = false;
115 bool analyzeAll = false;
116 bool trustTypeAnnotations = false;
117 bool checkedMode = false;
118 // List of provided options that imply that output is expected.
119 List<String> optionsImplyCompilation = <String>[];
120 bool hasDisallowUnsafeEval = false;
121 // TODO(johnniwinther): Measure time for reading files.
122 SourceFileProvider inputProvider = new CompilerSourceFileProvider();
123 diagnosticHandler = new FormattingDiagnosticHandler(inputProvider);
124 Map<String, dynamic> environment = new Map<String, dynamic>();
125
126 passThrough(String argument) => options.add(argument);
127
128 if (BUILD_ID != null) {
129 passThrough("--build-id=$BUILD_ID");
130 }
131
132 setLibraryRoot(String argument) {
133 libraryRoot = currentDirectory.resolve(extractPath(argument));
134 }
135
136 setPackageRoot(String argument) {
137 packageRoot = currentDirectory.resolve(extractPath(argument));
138 }
139
140 setOutput(Iterator<String> arguments) {
141 optionsImplyCompilation.add(arguments.current);
142 String path;
143 if (arguments.current == '-o') {
144 if (!arguments.moveNext()) {
145 helpAndFail('Error: Missing file after -o option.');
146 }
147 path = arguments.current;
148 } else {
149 path = extractParameter(arguments.current);
150 }
151 explicitOut = true;
152 out = currentDirectory.resolve(nativeToUriPath(path));
153 sourceMapOut = Uri.parse('$out.map');
154 }
155
156 setOutputType(String argument) {
157 optionsImplyCompilation.add(argument);
158 if (argument == '--output-type=dart' ||
159 argument == '--output-type=dart-multi') {
160 outputLanguage = OUTPUT_LANGUAGE_DART;
161 if (!explicitOut) {
162 out = currentDirectory.resolve('out.dart');
163 sourceMapOut = currentDirectory.resolve('out.dart.map');
164 }
165 }
166 passThrough(argument);
167 }
168
169 String getDepsOutput(Map<String, SourceFile> sourceFiles) {
170 var filenames = new List.from(sourceFiles.keys);
171 filenames.sort();
172 return filenames.join("\n");
173 }
174
175 setStrip(String argument) {
176 optionsImplyCompilation.add(argument);
177 stripArgumentSet = true;
178 passThrough(argument);
179 }
180
181 setAnalyzeOnly(String argument) {
182 analyzeOnly = true;
183 passThrough(argument);
184 }
185
186 setAnalyzeAll(String argument) {
187 analyzeAll = true;
188 passThrough(argument);
189 }
190
191 setVerbose(_) {
192 diagnosticHandler.verbose = true;
193 passThrough('--verbose');
194 }
195
196 implyCompilation(String argument) {
197 optionsImplyCompilation.add(argument);
198 passThrough(argument);
199 }
200
201 setTrustTypeAnnotations(String argument) {
202 trustTypeAnnotations = true;
203 implyCompilation(argument);
204 }
205
206 setCheckedMode(String argument) {
207 checkedMode = true;
208 passThrough(argument);
209 }
210
211 addInEnvironment(String argument) {
212 int eqIndex = argument.indexOf('=');
213 String name = argument.substring(2, eqIndex);
214 String value = argument.substring(eqIndex + 1);
215 environment[name] = value;
216 }
217
218 setCategories(String argument) {
219 List<String> categories = extractParameter(argument).split(',');
220 Set<String> allowedCategories =
221 LIBRARIES.values.map((x) => x.category).toSet();
222 allowedCategories.remove('Shared');
223 allowedCategories.remove('Internal');
224 List<String> allowedCategoriesList =
225 new List<String>.from(allowedCategories);
226 allowedCategoriesList.sort();
227 if (categories.contains('all')) {
228 categories = allowedCategoriesList;
229 } else {
230 String allowedCategoriesString = allowedCategoriesList.join(', ');
231 for (String category in categories) {
232 if (!allowedCategories.contains(category)) {
233 fail('Unsupported library category "$category", '
234 'supported categories are: $allowedCategoriesString');
235 }
236 }
237 }
238 passThrough('--categories=${categories.join(",")}');
239 }
240
241 void handleThrowOnError(String argument) {
242 diagnosticHandler.throwOnError = true;
243 String parameter = extractParameter(argument, isOptionalArgument: true);
244 if (parameter != null) {
245 diagnosticHandler.throwOnErrorCount = int.parse(parameter);
246 }
247 }
248
249 handleShortOptions(String argument) {
250 var shortOptions = argument.substring(1).split("");
251 for (var shortOption in shortOptions) {
252 switch (shortOption) {
253 case 'v':
254 setVerbose(null);
255 break;
256 case 'h':
257 case '?':
258 wantHelp = true;
259 break;
260 case 'c':
261 setCheckedMode('--enable-checked-mode');
262 break;
263 case 'm':
264 implyCompilation('--minify');
265 break;
266 default:
267 throw 'Internal error: "$shortOption" did not match';
268 }
269 }
270 }
271
272 List<String> arguments = <String>[];
273 List<OptionHandler> handlers = <OptionHandler>[
274 new OptionHandler('-[chvm?]+', handleShortOptions),
275 new OptionHandler('--throw-on-error(?:=[0-9]+)?', handleThrowOnError),
276 new OptionHandler('--suppress-warnings', (_) {
277 diagnosticHandler.showWarnings = false;
278 passThrough('--suppress-warnings');
279 }),
280 new OptionHandler('--suppress-hints',
281 (_) => diagnosticHandler.showHints = false),
282 new OptionHandler(
283 '--output-type=dart|--output-type=dart-multi|--output-type=js',
284 setOutputType),
285 new OptionHandler('--verbose', setVerbose),
286 new OptionHandler('--version', (_) => wantVersion = true),
287 new OptionHandler('--library-root=.+', setLibraryRoot),
288 new OptionHandler('--out=.+|-o.*', setOutput, multipleArguments: true),
289 new OptionHandler('--allow-mock-compilation', passThrough),
290 new OptionHandler('--minify|-m', implyCompilation),
291 new OptionHandler('--preserve-uris', passThrough),
292 new OptionHandler('--force-strip=.*', setStrip),
293 new OptionHandler('--disable-diagnostic-colors',
294 (_) => diagnosticHandler.enableColors = false),
295 new OptionHandler('--enable-diagnostic-colors',
296 (_) => diagnosticHandler.enableColors = true),
297 new OptionHandler('--enable[_-]checked[_-]mode|--checked',
298 (_) => setCheckedMode('--enable-checked-mode')),
299 new OptionHandler('--enable-concrete-type-inference',
300 (_) => implyCompilation(
301 '--enable-concrete-type-inference')),
302 new OptionHandler('--trust-type-annotations',
303 (_) => setTrustTypeAnnotations(
304 '--trust-type-annotations')),
305 new OptionHandler(r'--help|/\?|/h', (_) => wantHelp = true),
306 new OptionHandler('--package-root=.+|-p.+', setPackageRoot),
307 new OptionHandler('--analyze-all', setAnalyzeAll),
308 new OptionHandler('--analyze-only', setAnalyzeOnly),
309 new OptionHandler('--analyze-signatures-only', setAnalyzeOnly),
310 new OptionHandler('--disable-native-live-type-analysis', passThrough),
311 new OptionHandler('--categories=.*', setCategories),
312 new OptionHandler('--disable-type-inference', implyCompilation),
313 new OptionHandler('--terse', passThrough),
314 new OptionHandler('--dump-info', implyCompilation),
315 new OptionHandler('--disallow-unsafe-eval',
316 (_) => hasDisallowUnsafeEval = true),
317 new OptionHandler('--show-package-warnings', passThrough),
318 new OptionHandler('--csp', passThrough),
319 new OptionHandler('-D.+=.*', addInEnvironment),
320
321 // The following two options must come last.
322 new OptionHandler('-.*', (String argument) {
323 helpAndFail("Unknown option '$argument'.");
324 }),
325 new OptionHandler('.*', (String argument) {
326 arguments.add(nativeToUriPath(argument));
327 })
328 ];
329
330 parseCommandLine(handlers, argv);
331 if (wantHelp || wantVersion) {
332 helpAndExit(wantHelp, wantVersion, diagnosticHandler.verbose);
333 }
334
335 if (hasDisallowUnsafeEval) {
336 String precompiledName =
337 relativize(currentDirectory,
338 RandomAccessFileOutputProvider.computePrecompiledUri(out),
339 Platform.isWindows);
340 helpAndFail("Option '--disallow-unsafe-eval' has been removed."
341 " Instead, the compiler generates a file named"
342 " '$precompiledName'.");
343 }
344
345 if (outputLanguage != OUTPUT_LANGUAGE_DART && stripArgumentSet) {
346 helpAndFail("Option '--force-strip' may only be used with "
347 "'--output-type=dart'.");
348 }
349 if (arguments.isEmpty) {
350 helpAndFail('No Dart file specified.');
351 }
352 if (arguments.length > 1) {
353 var extra = arguments.sublist(1);
354 helpAndFail('Extra arguments: ${extra.join(" ")}');
355 }
356
357 if (checkedMode && trustTypeAnnotations) {
358 helpAndFail("Option '--trust-type-annotations' may not be used in "
359 "checked mode.");
360 }
361
362 Uri uri = currentDirectory.resolve(arguments[0]);
363 if (packageRoot == null) {
364 packageRoot = uri.resolve('./packages/');
365 }
366
367 if ((analyzeOnly || analyzeAll) && !optionsImplyCompilation.isEmpty) {
368 if (!analyzeOnly) {
369 diagnosticHandler.info(
370 "Option '--analyze-all' implies '--analyze-only'.",
371 api.Diagnostic.INFO);
372 }
373 diagnosticHandler.info(
374 "Options $optionsImplyCompilation indicate that output is expected, "
375 "but compilation is turned off by the option '--analyze-only'.",
376 api.Diagnostic.INFO);
377 }
378 if (analyzeAll) analyzeOnly = true;
379
380 diagnosticHandler.info('Package root is $packageRoot');
381
382 options.add('--out=$out');
383 options.add('--source-map=$sourceMapOut');
384
385 RandomAccessFileOutputProvider outputProvider =
386 new RandomAccessFileOutputProvider(
387 out, sourceMapOut, onInfo: diagnosticHandler.info, onFailure: fail);
388
389 compilationDone(String code) {
390 if (analyzeOnly) return;
391 if (code == null) {
392 fail('Compilation failed.');
393 }
394 writeString(Uri.parse('$out.deps'),
395 getDepsOutput(inputProvider.sourceFiles));
396 diagnosticHandler.info(
397 'Compiled ${inputProvider.dartCharactersRead} characters Dart '
398 '-> ${outputProvider.totalCharactersWritten} characters '
399 '$outputLanguage in '
400 '${relativize(currentDirectory, out, Platform.isWindows)}');
401 if (diagnosticHandler.verbose) {
402 String input = uriPathToNative(arguments[0]);
403 print('Dart file ($input) compiled to $outputLanguage.');
404 print('Wrote the following files:');
405 for (String filename in outputProvider.allOutputFiles) {
406 print(" $filename");
407 }
408 } else if (!explicitOut) {
409 String input = uriPathToNative(arguments[0]);
410 String output = relativize(currentDirectory, out, Platform.isWindows);
411 print('Dart file ($input) compiled to $outputLanguage: $output');
412 }
413 }
414
415 return compileFunc(uri, libraryRoot, packageRoot,
416 inputProvider, diagnosticHandler,
417 options, outputProvider, environment)
418 .then(compilationDone);
419 }
420
421 class AbortLeg {
422 final message;
423 AbortLeg(this.message);
424 toString() => 'Aborted due to --throw-on-error: $message';
425 }
426
427 void writeString(Uri uri, String text) {
428 if (uri.scheme != 'file') {
429 fail('Unhandled scheme ${uri.scheme}.');
430 }
431 var file = new File(uri.toFilePath()).openSync(mode: FileMode.WRITE);
432 file.writeStringSync(text);
433 file.closeSync();
434 }
435
436 void fail(String message) {
437 if (diagnosticHandler != null) {
438 diagnosticHandler.diagnosticHandler(
439 null, -1, -1, message, api.Diagnostic.ERROR);
440 } else {
441 print('Error: $message');
442 }
443 exitFunc(1);
444 }
445
446 Future compilerMain(List<String> arguments) {
447 var root = uriPathToNative("/$LIBRARY_ROOT");
448 arguments = <String>['--library-root=${Platform.script.toFilePath()}$root']
449 ..addAll(arguments);
450 return compile(arguments);
451 }
452
453 void help() {
454 // This message should be no longer than 20 lines. The default
455 // terminal size normally 80x24. Two lines are used for the prompts
456 // before and after running the compiler. Another two lines may be
457 // used to print an error message.
458 print('''
459 Usage: dart2js [options] dartfile
460
461 Compiles Dart to JavaScript.
462
463 Common options:
464 -o <file> Generate the output into <file>.
465 -c Insert runtime type checks and enable assertions (checked mode).
466 -m Generate minified output.
467 -h Display this message (add -v for information about all options).''') ;
468 }
469
470 void verboseHelp() {
471 print(r'''
472 Usage: dart2js [options] dartfile
473
474 Compiles Dart to JavaScript.
475
476 Supported options:
477 -o <file>, --out=<file>
478 Generate the output into <file>.
479
480 -c, --enable-checked-mode, --checked
481 Insert runtime type checks and enable assertions (checked mode).
482
483 -m, --minify
484 Generate minified output.
485
486 -h, /h, /?, --help
487 Display this message (add -v for information about all options).
488
489 -v, --verbose
490 Display verbose information.
491
492 -D<name>=<value>
493 Define an environment variable.
494
495 --version
496 Display version information.
497
498 -p<path>, --package-root=<path>
499 Where to find packages, that is, "package:..." imports.
500
501 --analyze-all
502 Analyze all code. Without this option, the compiler only analyzes
503 code that is reachable from [main]. This option implies --analyze-only.
504
505 --analyze-only
506 Analyze but do not generate code.
507
508 --analyze-signatures-only
509 Skip analysis of method bodies and field initializers. This option implies
510 --analyze-only.
511
512 --suppress-warnings
513 Do not display any warnings.
514
515 --suppress-hints
516 Do not display any hints.
517
518 --enable-diagnostic-colors
519 Add colors to diagnostic messages.
520
521 --terse
522 Emit diagnostics without suggestions for how to get rid of the diagnosed
523 problems.
524
525 --show-package-warnings
526 Show warnings and hints generated from packages.
527
528 --preserve-uris
529 Preserve the source URIs in the reflection data. Without this flag the
530 `uri` getter for `LibraryMirror`s is mangled in minified mode.
531
532 --csp
533 Disables dynamic generation of code in the generated output. This is
534 necessary to satisfy CSP restrictions (see http://www.w3.org/TR/CSP/).
535
536 The following options are only used for compiler development and may
537 be removed in a future version:
538
539 --output-type=dart
540 Output Dart code instead of JavaScript.
541
542 --throw-on-error
543 Throw an exception if a compile-time error is detected.
544
545 --library-root=<directory>
546 Where to find the Dart platform libraries.
547
548 --allow-mock-compilation
549 Do not generate a call to main if either of the following
550 libraries are used: dart:dom, dart:html dart:io.
551
552 --enable-concrete-type-inference
553 Enable experimental concrete type inference.
554
555 --disable-native-live-type-analysis
556 Disable the optimization that removes unused native types from dart:html
557 and related libraries.
558
559 --categories=<categories>
560 A comma separated list of allowed library categories. The default
561 is "Client". Possible categories can be seen by providing an
562 unsupported category, for example, --categories=help. To enable
563 all categories, use --categories=all.
564
565 --dump-info
566 Generates an out.info.json file with information about the generated code.
567 You can inspect the generated file with the viewer at:
568 https://dart-lang.github.io/dump-info-visualizer/
569
570 '''.trim());
571 }
572
573 void helpAndExit(bool wantHelp, bool wantVersion, bool verbose) {
574 if (wantVersion) {
575 var version = (BUILD_ID == null)
576 ? '<non-SDK build>'
577 : BUILD_ID;
578 print('Dart-to-JavaScript compiler (dart2js) version: $version');
579 }
580 if (wantHelp) {
581 if (verbose) {
582 verboseHelp();
583 } else {
584 help();
585 }
586 }
587 exitFunc(0);
588 }
589
590 void helpAndFail(String message) {
591 help();
592 print('');
593 fail(message);
594 }
595
596 void main(List<String> arguments) {
597 // Since the sdk/bin/dart2js script adds its own arguments in front of
598 // user-supplied arguments we search for '--batch' at the end of the list.
599 if (arguments.length > 0 && arguments.last == "--batch") {
600 batchMain(arguments.sublist(0, arguments.length - 1));
601 return;
602 }
603 internalMain(arguments);
604 }
605
606 var exitFunc = exit;
607 var compileFunc = api.compile;
608
609 Future internalMain(List<String> arguments) {
610 onError(exception, trace) {
611 try {
612 print('The compiler crashed: $exception');
613 } catch (ignored) {
614 print('The compiler crashed: error while printing exception');
615 }
616
617 try {
618 if (trace != null) {
619 print(trace);
620 }
621 } finally {
622 exitFunc(253); // 253 is recognized as a crash by our test scripts.
623 }
624 }
625
626 try {
627 return compilerMain(arguments).catchError(onError);
628 } catch (exception, trace) {
629 onError(exception, trace);
630 return new Future.value();
631 }
632 }
633
634 const _EXIT_SIGNAL = const Object();
635
636 void batchMain(List<String> batchArguments) {
637 int exitCode;
638
639 exitFunc = (errorCode) {
640 // Since we only throw another part of the compiler might intercept our
641 // exception and try to exit with a different code.
642 if (exitCode == 0) {
643 exitCode = errorCode;
644 }
645 throw _EXIT_SIGNAL;
646 };
647
648 runJob() {
649 new Future.sync(() {
650 exitCode = 0;
651 String line = stdin.readLineSync();
652 if (line == null) exit(0);
653 List<String> args = <String>[];
654 args.addAll(batchArguments);
655 args.addAll(splitLine(line, windows: Platform.isWindows));
656 return internalMain(args);
657 })
658 .catchError((exception, trace) {
659 if (!identical(exception, _EXIT_SIGNAL)) {
660 exitCode = 253;
661 }
662 })
663 .whenComplete(() {
664 // The testing framework waits for a status line on stdout and stderr
665 // before moving to the next test.
666 if (exitCode == 0){
667 print(">>> TEST OK");
668 } else if (exitCode == 253) {
669 print(">>> TEST CRASH");
670 } else {
671 print(">>> TEST FAIL");
672 }
673 stderr.writeln(">>> EOF STDERR");
674 runJob();
675 });
676 }
677
678 runJob();
679 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698