Index: pkg/kernel/bin/reified_dart.dart |
diff --git a/pkg/kernel/bin/reified_dart.dart b/pkg/kernel/bin/reified_dart.dart |
new file mode 100755 |
index 0000000000000000000000000000000000000000..b87807db6b9230eb348e5191ce3f0b8b8c38e157 |
--- /dev/null |
+++ b/pkg/kernel/bin/reified_dart.dart |
@@ -0,0 +1,173 @@ |
+#!/usr/bin/env dart |
+// Copyright (c) 2017, 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:io'; |
+ |
+import 'package:args/args.dart' as args; |
+import 'package:path/path.dart' as path; |
+ |
+args.ArgParser parser = new args.ArgParser(allowTrailingOptions: true) |
+ ..addOption("sdk", |
+ abbr: "s", |
+ help: "Path to the Dart SDK. By default it will be searched at the path\n" |
+ "'../../../out/ReleaseX64/patched_sdk' relative to the directory\n" |
+ "of 'reified_dart'.", |
+ defaultsTo: null) |
+ ..addOption("dartk", |
+ abbr: "k", |
+ help: "Path to 'dartk' executable. By default it will be searched for\n" |
+ "in the same directory as 'reified_dart'.", |
+ defaultsTo: null) |
+ ..addOption("dill-output", |
+ abbr: "d", |
+ help: "Path to intermediate reified .dill file. If not specified,\n" |
+ "the intermediate file is created in a temporary location\n" |
+ "and is removed after program execution.", |
+ defaultsTo: null); |
+ |
+String getUsage() => """ |
+Usage: reified_dart [options] FILE |
+ |
+Reifies generic types in FILE and runs the transformed program. |
+ |
+Examples: |
+ reified_dart foo.dart |
+ reified_dart --sdk=/path/to/sdk foo.dart |
+ reified_dart --sdk=/path/to/sdk --dartk=/path/to/dartk foo.dart |
+ |
+Options: |
+${parser.usage} |
+"""; |
+ |
+void fail(String message) { |
+ stderr.writeln(message); |
+ exit(1); |
+} |
+ |
+args.ArgResults options; |
+ |
+void checkIsDirectory(String path, {String option, String description}) { |
+ description = (description == null ? "" : "$description\n"); |
+ switch (new File(path).statSync().type) { |
+ case FileSystemEntityType.DIRECTORY: |
+ case FileSystemEntityType.LINK: |
+ return; |
+ case FileSystemEntityType.NOT_FOUND: |
+ throw fail('$description$option not found: $path'); |
+ default: |
+ fail('$description$option is not a directory: $path'); |
+ } |
+} |
+ |
+void checkIsFile(String path, {String option, String description}) { |
+ description = (description == null ? "" : "$description\n"); |
+ var stat = new File(path).statSync(); |
+ switch (stat.type) { |
+ case FileSystemEntityType.DIRECTORY: |
+ throw fail('$description$option is a directory: $path'); |
+ |
+ case FileSystemEntityType.NOT_FOUND: |
+ throw fail('$description$option not found: $path'); |
+ } |
+} |
+ |
+String getDefaultSdk() { |
+ String currentFile = Platform.script.toFilePath(); |
+ |
+ // Respect different path separators. |
+ String relativePath = "../../../out/ReleaseX64/patched_sdk"; |
+ List<String> components = relativePath.split("/"); |
+ relativePath = ""; |
+ for (String component in components) { |
+ relativePath = path.join(relativePath, component); |
+ } |
+ |
+ String currentDir = path.dirname(currentFile); |
+ String sdkPath = path.normalize(path.join(currentDir, relativePath)); |
+ |
+ checkIsDirectory(sdkPath, |
+ option: "Path to Dart SDK", |
+ description: "The --sdk option wasn't specified, " |
+ "so default location was checked."); |
+ |
+ return sdkPath; |
+} |
+ |
+String getDefaultDartk() { |
+ String currentFile = Platform.script.toFilePath(); |
+ String dartkPath = path.join(path.dirname(currentFile), "dartk.dart"); |
+ |
+ checkIsFile(dartkPath, |
+ option: "Path to 'dartk'", |
+ description: "The --dartk option wasn't specified, " |
+ "so default location was checked."); |
+ |
+ return dartkPath; |
+} |
+ |
+main(List<String> arguments) async { |
+ if (arguments.length == 0) { |
+ fail(getUsage()); |
+ } |
+ |
+ try { |
+ options = parser.parse(arguments); |
+ } on FormatException catch (e) { |
+ fail(e.message); |
+ } |
+ |
+ if (options.rest.length != 1) { |
+ fail("Exactly one FILE should be given."); |
+ } |
+ |
+ String inputFilename = options.rest.single; |
+ checkIsFile(inputFilename, option: "Input file"); |
+ |
+ String sdkPath = options["sdk"] ?? getDefaultSdk(); |
+ checkIsDirectory(sdkPath, option: "Path to Dart SDK"); |
+ |
+ String dartkPath = options["dartk"] ?? getDefaultDartk(); |
+ checkIsFile(dartkPath, option: "Path to 'dartk'"); |
+ |
+ String dillOutput = options["dill-output"]; |
+ File tempFile = null; |
+ if (dillOutput == null) { |
+ Directory tmp = await Directory.systemTemp.createTemp(); |
+ Uri uri = tmp.uri.resolve("generated.dill"); |
+ dillOutput = uri.toFilePath(); |
+ tempFile = new File.fromUri(uri); |
+ } |
+ |
+ ProcessResult result = await Process.run(dartkPath, [ |
+ "--sdk=$sdkPath", |
+ "--target=vmreify", |
+ "--link", |
+ "--out=$dillOutput", |
+ inputFilename, |
+ ]); |
+ if (result.exitCode != 0) { |
+ tempFile?.parent?.delete(recursive: true); |
+ stdout.write(result.stdout); |
+ stderr.write(result.stderr); |
+ stderr.writeln("ERROR: execution of 'dartk' failed with exit code " |
+ "${result.exitCode}"); |
+ exit(result.exitCode); |
+ } |
+ |
+ result = await Process.run("/usr/bin/env", [ |
+ "dart", |
+ dillOutput, |
+ inputFilename, |
+ ]); |
+ |
+ stdout.write(result.stdout); |
+ stderr.write(result.stderr); |
+ tempFile?.parent?.delete(recursive: true); |
+ if (result.exitCode != 0) { |
+ stderr.writeln("ERROR: execution of 'dart' failed with exit code " |
+ "${result.exitCode}"); |
+ exit(result.exitCode); |
+ } |
+} |