Skip to main content
Glama
gen_class_to_source_map.py4.06 kB
# Copyright (c) Meta Platforms, Inc. and affiliates. # # This source code is licensed under both the MIT license found in the # LICENSE-MIT file in the root directory of this source tree and the Apache # License, Version 2.0 found in the LICENSE-APACHE file in the root directory # of this source tree. import argparse import json import os import sys import zipfile def _base_class_name_matches_base_source_path( base_class_name: str, base_source_path: str ): return base_class_name == base_source_path or base_source_path.endswith( "/" + base_class_name ) def main(argv): parser = argparse.ArgumentParser(fromfile_prefix_chars="@") parser.add_argument( "--include_classes_prefixes", "-i", default=[], nargs="*", help="Prefixes of classes to include in the output, even if their source isn't present", ) parser.add_argument( "--output", "-o", type=argparse.FileType("w"), default=sys.stdin ) parser.add_argument("--sources_jar", required=False) parser.add_argument("jar") parser.add_argument("sources", nargs="*") args = parser.parse_args(argv[1:]) sources = {} for src in args.sources: path = src base, ext = os.path.splitext(src) sources[base] = path classes = [] with zipfile.ZipFile(args.jar) as zf: for ent in zf.namelist(): base, ext = os.path.splitext(ent) # Ignore non-.class files. if ext != ".class": continue classname = base.replace("/", ".") # Make sure it is a .class file that corresponds to a top-level # .class file and not an inner class. if "$" in base: continue found = False for src_base, src_path in sources.items(): if _base_class_name_matches_base_source_path(base, src_base): classes.append( { "className": classname, "srcPath": src_path, } ) found = True break # Kotlin creates .class files with a "Kt" suffix when code is written outside of a class, # so strip that suffix and redo the comparison. elif base.endswith("Kt") and _base_class_name_matches_base_source_path( base[:-2], src_base ): classes.append( { "className": classname[:-2], "srcPath": src_path, } ) found = True break if not found: # If the class is not present in the sources, we still want to # include it if it has a prefix that we are interested in. # certain classes in "androidx.databinding.*" are generated and it's useful to know their presence in jars for prefix in args.include_classes_prefixes: if classname.startswith(prefix): classes.append( { "className": classname, } ) break if args.sources_jar: with zipfile.ZipFile(args.sources_jar, "w") as sources_jar: for d in classes: if "srcPath" in d: src_path = d["srcPath"] class_name = d["className"] _, src_path_ext = os.path.splitext(src_path) sources_jar.write( src_path, class_name.replace(".", "/") + src_path_ext ) json.dump( { "jarPath": args.jar, "classes": classes, }, args.output, ) print("", file=args.output) sys.exit(main(sys.argv))

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server