Simple inspect tool using CodeInspector from the test library.
Change-Id: Ie977bda0018a9f304608a55d13047a2aaa90626b
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/Main.java b/src/test/java/com/android/tools/r8/utils/codeinspector/Main.java
new file mode 100644
index 0000000..67d3597
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/Main.java
@@ -0,0 +1,78 @@
+// Copyright (c) 2018, the R8 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.
+package com.android.tools.r8.utils.codeinspector;
+
+import com.android.tools.r8.utils.StringUtils;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+
+public class Main {
+
+ private static final String USAGE = StringUtils.joinLines(
+ "Usage: --method <qualified-name> <input>*",
+ "where <qualified-name> is a fully qualified name of a method (eg, foo.Bar.baz)",
+ " and <input> is a series of input files (eg, .class, .dex, .jar, .zip or .apk)"
+ );
+
+ public static void main(String[] args) throws IOException, ExecutionException {
+ List<Path> inputs = new ArrayList<>();
+ String method = null;
+ for (int i = 0; i < args.length; i++) {
+ String arg = args[i].trim();
+ if (arg.startsWith("--")) {
+ if (arg.equals("--help")) {
+ System.out.println(USAGE);
+ System.exit(0);
+ return;
+ } else if (arg.equals("--method")) {
+ method = args[++i].trim();
+ continue;
+ }
+ throw error("Unknown argument: " + arg);
+ } else {
+ inputs.add(Paths.get(arg));
+ }
+ }
+ if (method == null) {
+ throw error("Requires a --method argument.");
+ }
+
+ CodeInspector inspector = new CodeInspector(inputs);
+ int methodStart = method.lastIndexOf('.');
+ if (methodStart < 0) {
+ throw error("Requires a valid --method argument, got '" + method + "'");
+ }
+ String clazz = method.substring(0, methodStart);
+ String methodName = method.substring(methodStart + 1);
+ ClassSubject clazzSubject = inspector.clazz(clazz);
+
+ if (!clazzSubject.isPresent()) {
+ System.out.println("No definition found for class: '" + clazz + "'");
+ return;
+ }
+
+ List<FoundMethodSubject> found = clazzSubject
+ .allMethods()
+ .stream()
+ .filter(m -> m.getOriginalName().equals(methodName))
+ .collect(Collectors.toList());
+
+ System.out.println("Methods found: " + found.size());
+ for (FoundMethodSubject methodSubject : found) {
+ System.out.println(methodSubject.getMethod().codeToString());
+ }
+ }
+
+ private static RuntimeException error(String message) {
+ System.err.println(message);
+ System.err.println(USAGE);
+ System.exit(1);
+ throw new RuntimeException();
+ }
+}
diff --git a/tools/inspect.py b/tools/inspect.py
new file mode 100755
index 0000000..6d655da
--- /dev/null
+++ b/tools/inspect.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, the R8 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 sys
+import toolhelper
+
+if __name__ == '__main__':
+ sys.exit(toolhelper.run_in_tests('com.android.tools.r8.utils.codeinspector.Main', sys.argv[1:]))
diff --git a/tools/toolhelper.py b/tools/toolhelper.py
index 1e6ebfd..56cd5a7 100644
--- a/tools/toolhelper.py
+++ b/tools/toolhelper.py
@@ -2,6 +2,7 @@
# 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 glob
import gradle
import os
import subprocess
@@ -31,6 +32,29 @@
utils.PrintCmd(cmd)
return subprocess.call(cmd)
+def run_in_tests(tool, args, build=None, debug=True, extra_args=None):
+ if build is None:
+ build, args = extract_build_from_args(args)
+ if build:
+ gradle.RunGradle([
+ 'copyMavenDeps',
+ 'compileTestJava',
+ ])
+ cmd = []
+ cmd.append('java')
+ if extra_args:
+ cmd.extend(extra_args)
+ if debug:
+ cmd.append('-ea')
+ cmd.extend(['-cp', ':'.join([
+ utils.BUILD_MAIN_DIR,
+ utils.BUILD_TEST_DIR,
+ ] + glob.glob('%s/*.jar' % utils.BUILD_DEPS_DIR))])
+ cmd.extend([tool])
+ cmd.extend(args)
+ utils.PrintCmd(cmd)
+ return subprocess.call(cmd)
+
def extract_build_from_args(input_args):
build = True
args = []
diff --git a/tools/utils.py b/tools/utils.py
index 7c5d83e..d28643d 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -20,11 +20,13 @@
MEMORY_USE_TMP_FILE = 'memory_use.tmp'
DEX_SEGMENTS_RESULT_PATTERN = re.compile('- ([^:]+): ([0-9]+)')
BUILD = os.path.join(REPO_ROOT, 'build')
+BUILD_DEPS_DIR = os.path.join(BUILD, 'deps')
+BUILD_MAIN_DIR = os.path.join(BUILD, 'classes', 'main')
+BUILD_TEST_DIR = os.path.join(BUILD, 'classes', 'test')
LIBS = os.path.join(BUILD, 'libs')
GENERATED_LICENSE_DIR = os.path.join(BUILD, 'generatedLicense')
SRC_ROOT = os.path.join(REPO_ROOT, 'src', 'main', 'java')
-
D8 = 'd8'
R8 = 'r8'
R8_SRC = 'sourceJar'