[自用记录] Python 解析 java 文件

点击查看代码
import javalang

def get_full_type(param_type):
    """递归构建参数的完整类型,包括泛型和数组类型。"""
    if isinstance(param_type, javalang.tree.ReferenceType):
        # 处理泛型类型
        if param_type.arguments:
            args = ", ".join(get_full_type(arg.type) for arg in param_type.arguments if arg.type is not None)
            return f"{param_type.name}<{args}>"
        # 处理数组类型
        elif param_type.dimensions:
            return f"{param_type.name}{'[]'*len(param_type.dimensions)}"
        else:
            return param_type.name
    elif isinstance(param_type, javalang.tree.BasicType):
        # 处理基本类型
        return param_type.name
    else:
        return ""

def parse_method_body(method):
    """尝试以较为准确的方式提取方法体的内容,保留原有格式。"""
    if method.body:
        # javalang不直接提供格式化的方法体文本,这里我们使用position属性尝试重新构建
        start_pos = method.position.line
        end_pos = method.body[-1].position.line

        method_lines = original_lines[start_pos-1:end_pos]
        return "\n".join(method_lines)
    return ""

def parse_java_file(file_path):
    """使用javalang解析Java文件,并处理注释等情况。"""
    global original_lines  # 用于在解析方法体时,访问原始文件的行
    with open(file_path, 'r') as file:
        content = file.read()
        original_lines = content.split("\n")

    tree = javalang.parse.parse(content)

    methods_info = {}

    for _, node in tree.filter(javalang.tree.ClassDeclaration):
        class_name = node.name
        for method in node.methods:
            method_name = method.name
            descriptor = method.return_type or "void"
            if descriptor != "void":
                descriptor = get_full_type(descriptor)
            params = ", ".join(f"{get_full_type(param.type)} {param.name}" for param in method.parameters)

            full_method_name = f"{tree.package.name if tree.package else ''}.{class_name}.{method_name}"

            methods_info[full_method_name] = {
                'descriptor': descriptor,
                'params': params,
                'body': parse_method_body(method)
            }

    return methods_info

def main():
    java_file_path = 'YourJavaFile.java'
    methods_info = parse_java_file(java_file_path)

    for method_full_name, info in methods_info.items():
        print(f"Method Full Name: {method_full_name}")
        print(f"Descriptor: {info['descriptor']}")
        print(f"Parameters: {info['params']}")
        print(f"Body:\n{info['body']}\n")

if __name__ == "__main__":
    main()

posted @ 2024-02-08 00:16  CallMeMrX  阅读(739)  评论(0)    收藏  举报