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'