|  | #!/usr/bin/env python3 | 
|  | # 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. | 
|  |  | 
|  | ''' | 
|  | Compare the R8 API used by the API usage sample to the API kept by @Keep. | 
|  | ''' | 
|  |  | 
|  | import argparse | 
|  | import jdk | 
|  | import os | 
|  | import subprocess | 
|  | import utils | 
|  |  | 
|  | parser = argparse.ArgumentParser(description=__doc__.strip(), | 
|  | formatter_class=argparse.RawTextHelpFormatter) | 
|  | parser.add_argument('-o', '--output-dir') | 
|  |  | 
|  | API_SAMPLE_JAR = 'tests/d8_api_usage_sample.jar' | 
|  |  | 
|  |  | 
|  | def main(output_dir=None): | 
|  | if output_dir is None: | 
|  | output_dir = '' | 
|  |  | 
|  | javaExecutable = jdk.GetJavaExecutable() | 
|  | printseeds_path = os.path.join(output_dir, 'keep-seeds.txt') | 
|  | printseeds_args = [ | 
|  | javaExecutable, '-jar', utils.R8_JAR, 'printseeds', | 
|  | utils.RT_JAR, utils.R8_JAR, utils.R8LIB_KEEP_RULES, | 
|  | ] | 
|  | write_sorted_lines(printseeds_args, printseeds_path) | 
|  |  | 
|  | printuses_path = os.path.join(output_dir, 'sample-uses.txt') | 
|  | printuses_args = [ | 
|  | javaExecutable, '-jar', utils.R8_JAR, 'printuses', | 
|  | utils.RT_JAR, utils.R8_JAR, API_SAMPLE_JAR, | 
|  | ] | 
|  | write_sorted_lines(printuses_args, printuses_path) | 
|  |  | 
|  | print_diff(printseeds_path, printuses_path) | 
|  |  | 
|  |  | 
|  | def write_sorted_lines(cmd_args, output_path): | 
|  | utils.PrintCmd(cmd_args) | 
|  | output_lines = subprocess.check_output(cmd_args).splitlines(True) | 
|  | print("Write output to %s" % output_path) | 
|  | output_lines.sort() | 
|  | with open(output_path, 'w') as fp: | 
|  | for line in output_lines: | 
|  | fp.write(line) | 
|  |  | 
|  |  | 
|  | def print_diff(printseeds_path, printuses_path): | 
|  | with open(printseeds_path) as fp: | 
|  | seeds = set(fp.read().splitlines()) | 
|  | with open(printuses_path) as fp: | 
|  | uses = set(fp.read().splitlines()) | 
|  | only_in_seeds = seeds - uses | 
|  | only_in_uses = uses - seeds | 
|  | if only_in_seeds: | 
|  | print("%s lines with '-' are marked @Keep " % len(only_in_seeds) + | 
|  | "but not used by sample.") | 
|  | if only_in_uses: | 
|  | print("%s lines with '+' are used by sample " % len(only_in_uses) + | 
|  | "but are missing @Keep annotations.") | 
|  | for line in sorted(only_in_seeds): | 
|  | print('-' + line) | 
|  | for line in sorted(only_in_uses): | 
|  | print('+' + line) | 
|  | if not only_in_seeds and not only_in_uses: | 
|  | print('Sample uses the entire set of members marked @Keep. Well done!') | 
|  |  | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | main(**vars(parser.parse_args())) |