Index: pkg/kernel/bin/dartk.dart |
diff --git a/pkg/kernel/bin/dartk.dart b/pkg/kernel/bin/dartk.dart |
deleted file mode 100755 |
index e06e0646176fbcff003757807cbe2dde8b220f01..0000000000000000000000000000000000000000 |
--- a/pkg/kernel/bin/dartk.dart |
+++ /dev/null |
@@ -1,454 +0,0 @@ |
-#!/usr/bin/env dart |
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-import 'dart:async'; |
-import 'dart:io'; |
- |
-import 'batch_util.dart'; |
-import 'util.dart'; |
- |
-import 'package:args/args.dart'; |
-import 'package:analyzer/src/kernel/loader.dart'; |
-import 'package:kernel/application_root.dart'; |
-import 'package:kernel/verifier.dart'; |
-import 'package:kernel/kernel.dart'; |
-import 'package:kernel/log.dart'; |
-import 'package:kernel/target/targets.dart'; |
-import 'package:kernel/transformations/treeshaker.dart'; |
-import 'package:path/path.dart' as path; |
- |
-// Returns the path to the current sdk based on `Platform.resolvedExecutable`. |
-String currentSdk() { |
- // The dart executable should be inside dart-sdk/bin/dart. |
- return path.dirname(path.dirname(path.absolute(Platform.resolvedExecutable))); |
-} |
- |
-ArgParser parser = new ArgParser(allowTrailingOptions: true) |
- ..addOption('format', |
- abbr: 'f', |
- allowed: ['text', 'bin'], |
- help: 'Output format.\n' |
- '(defaults to "text" unless output file ends with ".dill")') |
- ..addOption('out', |
- abbr: 'o', |
- help: 'Output file.\n' |
- '(defaults to "out.dill" if format is "bin", otherwise stdout)') |
- ..addOption('sdk', defaultsTo: currentSdk(), help: 'Path to the Dart SDK.') |
- ..addOption('packages', |
- abbr: 'p', help: 'Path to the .packages file or packages folder.') |
- ..addOption('package-root', help: 'Deprecated alias for --packages') |
- ..addOption('app-root', |
- help: 'Store library paths relative to the given directory.\n' |
- 'If none is given, absolute paths are used.\n' |
- 'Application libraries not inside the application root are stored ' |
- 'using absolute paths') |
- ..addOption('target', |
- abbr: 't', |
- help: 'Tailor the IR to the given target.', |
- allowed: targetNames, |
- defaultsTo: 'vm') |
- ..addFlag('strong', |
- help: 'Load .dart files in strong mode.\n' |
- 'Does not affect loading of binary files. Strong mode support is very\n' |
- 'unstable and not well integrated yet.') |
- ..addFlag('link', abbr: 'l', help: 'Link the whole program into one file.') |
- ..addFlag('no-output', negatable: false, help: 'Do not output any files.') |
- ..addOption('url-mapping', |
- allowMultiple: true, |
- help: 'A custom url mapping of the form `<scheme>:<name>::<uri>`.') |
- ..addOption('embedder-entry-points-manifest', |
- allowMultiple: true, |
- help: 'A path to a file describing entrypoints ' |
- '(lines of the form `<library>,<class>,<member>`).') |
- ..addFlag('verbose', |
- abbr: 'v', |
- negatable: false, |
- help: 'Print internal warnings and diagnostics to stderr.') |
- ..addFlag('print-metrics', |
- negatable: false, help: 'Print performance metrics.') |
- ..addFlag('verify-ir', help: 'Perform slow internal correctness checks.') |
- ..addFlag('tolerant', |
- help: 'Generate kernel even if there are compile-time errors.', |
- defaultsTo: false) |
- ..addOption('D', |
- abbr: 'D', |
- allowMultiple: true, |
- help: 'Define an environment variable.', |
- hide: true) |
- ..addFlag('show-external', |
- help: 'When printing a library as text, also print its dependencies\n' |
- 'on external libraries.') |
- ..addFlag('show-offsets', |
- help: 'When printing a library as text, also print node offsets') |
- ..addFlag('include-sdk', |
- help: 'Include the SDK in the output. Implied by --link.') |
- ..addFlag('tree-shake', |
- defaultsTo: false, help: 'Enable tree-shaking if the target supports it'); |
- |
-String getUsage() => """ |
-Usage: dartk [options] FILE |
- |
-Convert .dart or .dill files to kernel's IR and print out its textual |
-or binary form. |
- |
-Examples: |
- dartk foo.dart # print text IR for foo.dart |
- dartk foo.dart -ofoo.dill # write binary IR for foo.dart to foo.dill |
- dartk foo.dill # print text IR for binary file foo.dill |
- |
-Options: |
-${parser.usage} |
- |
- -D<name>=<value> Define an environment variable. |
-"""; |
- |
-dynamic fail(String message) { |
- stderr.writeln(message); |
- exit(1); |
- return null; |
-} |
- |
-ArgResults options; |
- |
-String defaultFormat() { |
- if (options['out'] != null && options['out'].endsWith('.dill')) { |
- return 'bin'; |
- } |
- return 'text'; |
-} |
- |
-String defaultOutput() { |
- if (options['format'] == 'bin') { |
- return 'out.dill'; |
- } |
- return null; |
-} |
- |
-void checkIsDirectoryOrNull(String path, String option) { |
- if (path == null) return; |
- var stat = new File(path).statSync(); |
- switch (stat.type) { |
- case FileSystemEntityType.DIRECTORY: |
- case FileSystemEntityType.LINK: |
- return; |
- case FileSystemEntityType.NOT_FOUND: |
- throw fail('$option not found: $path'); |
- default: |
- fail('$option is not a directory: $path'); |
- } |
-} |
- |
-void checkIsFile(String path, {String option}) { |
- var stat = new File(path).statSync(); |
- switch (stat.type) { |
- case FileSystemEntityType.DIRECTORY: |
- throw fail('$option is a directory: $path'); |
- |
- case FileSystemEntityType.NOT_FOUND: |
- throw fail('$option not found: $path'); |
- } |
-} |
- |
-void checkIsFileOrDirectoryOrNull(String path, String option) { |
- if (path == null) return; |
- var stat = new File(path).statSync(); |
- if (stat.type == FileSystemEntityType.NOT_FOUND) { |
- fail('$option not found: $path'); |
- } |
-} |
- |
-int getTotalSourceSize(List<String> files) { |
- int size = 0; |
- for (var filename in files) { |
- size += new File(filename).statSync().size; |
- } |
- return size; |
-} |
- |
-bool get shouldReportMetrics => options['print-metrics']; |
- |
-void dumpString(String value, [String filename]) { |
- if (filename == null) { |
- print(value); |
- } else { |
- new File(filename).writeAsStringSync(value); |
- } |
-} |
- |
-Map<Uri, Uri> parseCustomUriMappings(List<String> mappings) { |
- Map<Uri, Uri> customUriMappings = <Uri, Uri>{}; |
- |
- fatal(String mapping) { |
- fail('Invalid uri mapping "$mapping". Each mapping should have the ' |
- 'form "<scheme>:<name>::<uri>".'); |
- } |
- |
- // Each mapping has the form <uri>::<uri>. |
- for (var mapping in mappings) { |
- List<String> parts = mapping.split('::'); |
- if (parts.length != 2) { |
- fatal(mapping); |
- } |
- Uri fromUri = Uri.parse(parts[0]); |
- if (fromUri.scheme == '' || fromUri.path.contains('/')) { |
- fatal(mapping); |
- } |
- Uri toUri = Uri.parse(parts[1]); |
- if (toUri.scheme == '') { |
- toUri = new Uri.file(path.absolute(parts[1])); |
- } |
- customUriMappings[fromUri] = toUri; |
- } |
- |
- return customUriMappings; |
-} |
- |
-/// Maintains state that should be shared between batched executions when |
-/// running in batch mode (for testing purposes). |
-/// |
-/// This reuses the analyzer's in-memory copy of the Dart SDK between runs. |
-class BatchModeState { |
- bool isBatchMode = false; |
- DartLoaderBatch batch = new DartLoaderBatch(); |
-} |
- |
-main(List<String> args) async { |
- if (args.isNotEmpty && args[0] == '--batch') { |
- if (args.length != 1) { |
- return fail('--batch cannot be used with other arguments'); |
- } |
- var batchModeState = new BatchModeState()..isBatchMode = true; |
- await runBatch((args) => batchMain(args, batchModeState)); |
- } else { |
- CompilerOutcome outcome = await batchMain(args, new BatchModeState()); |
- exit(outcome == CompilerOutcome.Ok ? 0 : 1); |
- } |
-} |
- |
-bool isSupportedArgument(String arg) { |
- if (arg.startsWith('--')) { |
- int equals = arg.indexOf('='); |
- var name = equals != -1 ? arg.substring(2, equals) : arg.substring(2); |
- return parser.options.containsKey(name); |
- } |
- if (arg.startsWith('-')) { |
- return parser.findByAbbreviation(arg.substring(1)) != null; |
- } |
- return true; |
-} |
- |
-Future<CompilerOutcome> batchMain( |
- List<String> args, BatchModeState batchModeState) async { |
- if (args.contains('--ignore-unrecognized-flags')) { |
- args = args.where(isSupportedArgument).toList(); |
- } |
- |
- if (args.isEmpty) { |
- return fail(getUsage()); |
- } |
- |
- try { |
- options = parser.parse(args); |
- } on FormatException catch (e) { |
- return fail(e.message); // Don't puke stack traces. |
- } |
- |
- checkIsDirectoryOrNull(options['sdk'], 'Dart SDK'); |
- |
- String packagePath = options['packages'] ?? options['package-root']; |
- checkIsFileOrDirectoryOrNull(packagePath, 'Package root or .packages'); |
- |
- String applicationRootOption = options['app-root']; |
- checkIsDirectoryOrNull(applicationRootOption, 'Application root'); |
- if (applicationRootOption != null) { |
- applicationRootOption = new File(applicationRootOption).absolute.path; |
- } |
- var applicationRoot = new ApplicationRoot(applicationRootOption); |
- |
- // Set up logging. |
- if (options['verbose']) { |
- log.onRecord.listen((LogRecord rec) { |
- stderr.writeln(rec.message); |
- }); |
- } |
- |
- bool includeSdk = options['include-sdk']; |
- |
- List<String> inputFiles = options.rest; |
- if (inputFiles.length < 1 && !includeSdk) { |
- return fail('At least one file should be given.'); |
- } |
- |
- bool hasBinaryInput = false; |
- bool hasDartInput = includeSdk; |
- for (String file in inputFiles) { |
- checkIsFile(file, option: 'Input file'); |
- if (file.endsWith('.dill')) { |
- hasBinaryInput = true; |
- } else if (file.endsWith('.dart')) { |
- hasDartInput = true; |
- } else { |
- fail('Unrecognized file extension: $file'); |
- } |
- } |
- |
- if (hasBinaryInput && hasDartInput) { |
- fail('Mixed binary and dart input is not currently supported'); |
- } |
- |
- String format = options['format'] ?? defaultFormat(); |
- String outputFile = options['out'] ?? defaultOutput(); |
- |
- List<String> urlMapping = options['url-mapping'] as List<String>; |
- var customUriMappings = parseCustomUriMappings(urlMapping); |
- |
- List<String> embedderEntryPointManifests = |
- options['embedder-entry-points-manifest'] as List<String>; |
- List<ProgramRoot> programRoots = |
- parseProgramRoots(embedderEntryPointManifests); |
- |
- var program = new Program(); |
- |
- var watch = new Stopwatch()..start(); |
- List errors = const []; |
- TargetFlags targetFlags = new TargetFlags( |
- strongMode: options['strong'], |
- treeShake: options['tree-shake'], |
- kernelRuntime: Platform.script.resolve('../runtime/'), |
- programRoots: programRoots); |
- Target target = getTarget(options['target'], targetFlags); |
- |
- var declaredVariables = <String, String>{}; |
- declaredVariables.addAll(target.extraDeclaredVariables); |
- for (String define in options['D']) { |
- int separator = define.indexOf('='); |
- if (separator == -1) { |
- fail('Invalid define: -D$define. Format is -D<name>=<value>'); |
- } |
- String name = define.substring(0, separator); |
- String value = define.substring(separator + 1); |
- declaredVariables[name] = value; |
- } |
- |
- DartLoader loader; |
- if (hasDartInput) { |
- String packageDiscoveryPath = |
- batchModeState.isBatchMode || inputFiles.isEmpty |
- ? null |
- : inputFiles.first; |
- loader = await batchModeState.batch.getLoader( |
- program, |
- new DartOptions( |
- strongMode: target.strongMode, |
- strongModeSdk: target.strongModeSdk, |
- sdk: options['sdk'], |
- packagePath: packagePath, |
- customUriMappings: customUriMappings, |
- declaredVariables: declaredVariables, |
- applicationRoot: applicationRoot), |
- packageDiscoveryPath: packageDiscoveryPath); |
- if (includeSdk) { |
- for (var uri in batchModeState.batch.dartSdk.uris) { |
- loader.loadLibrary(Uri.parse(uri)); |
- } |
- } |
- loader.loadSdkInterface(program, target); |
- } |
- |
- for (String file in inputFiles) { |
- Uri fileUri = Uri.base.resolve(file); |
- |
- if (file.endsWith('.dill')) { |
- loadProgramFromBinary(file, program); |
- } else { |
- if (options['link']) { |
- loader.loadProgram(fileUri, target: target); |
- } else { |
- var library = loader.loadLibrary(fileUri); |
- program.mainMethod ??= library.procedures |
- .firstWhere((p) => p.name.name == 'main', orElse: () => null); |
- } |
- errors = loader.errors; |
- if (errors.isNotEmpty) { |
- const int errorLimit = 100; |
- stderr.writeln(errors.take(errorLimit).join('\n')); |
- if (errors.length > errorLimit) { |
- stderr.writeln( |
- '[error] ${errors.length - errorLimit} errors not shown'); |
- } |
- } |
- } |
- } |
- |
- bool canContinueCompilation = errors.isEmpty || options['tolerant']; |
- |
- int loadTime = watch.elapsedMilliseconds; |
- if (shouldReportMetrics) { |
- print('loader.time = $loadTime ms'); |
- } |
- |
- void runVerifier() { |
- if (options['verify-ir']) { |
- verifyProgram(program); |
- } |
- } |
- |
- if (canContinueCompilation) { |
- runVerifier(); |
- } |
- |
- if (options['link'] && program.mainMethodName == null) { |
- fail('[error] The program has no main method.'); |
- } |
- |
- // Apply target-specific transformations. |
- if (target != null && canContinueCompilation) { |
- target.performModularTransformations(program); |
- runVerifier(); |
- if (options['link']) { |
- target.performGlobalTransformations(program); |
- runVerifier(); |
- } |
- } |
- |
- if (options['no-output']) { |
- return CompilerOutcome.Ok; |
- } |
- |
- watch.reset(); |
- |
- Future ioFuture; |
- if (canContinueCompilation) { |
- switch (format) { |
- case 'text': |
- writeProgramToText(program, |
- path: outputFile, |
- showExternal: options['show-external'], |
- showOffsets: options['show-offsets']); |
- break; |
- case 'bin': |
- ioFuture = writeProgramToBinary(program, outputFile); |
- break; |
- } |
- } |
- |
- int time = watch.elapsedMilliseconds; |
- if (shouldReportMetrics) { |
- print('writer.time = $time ms'); |
- } |
- |
- await ioFuture; |
- |
- if (shouldReportMetrics) { |
- int flushTime = watch.elapsedMilliseconds - time; |
- print('writer.flush_time = $flushTime ms'); |
- } |
- |
- if (options['tolerant']) { |
- return CompilerOutcome.Ok; |
- } |
- |
- return errors.length > 0 ? CompilerOutcome.Fail : CompilerOutcome.Ok; |
-} |