AI编程可视化Java项目拆解第一弹,解析本地Java项目

之前分享过一篇使用 AI 可视化 Java 项目的文章,同步在 AI 破局星球、知乎、掘金等地方都分享了。

原文在这里AI 编程:可视化 Java 项目

有很多人感兴趣,我打算写一个系列文章拆解这个项目,大家多多点赞支持~

今天分享的是第一篇:如何使用 Spoon + JavaParser 工具解析一个本地的 Java 项目。

解析这一步骤是整个项目的基础,是为了获得整个 Java 项目的元数据。

这个元数据包含什么呢?1)整个项目的所有的类信息;2)整个项目的所有方法信息

方法信息

序号字段名称字段描述
1method_id方法唯一id标识
2project_name
3method_name方法名
4class_id方法所属类名
5param_type参数类型
6response_type返回类型
7begin_line方法内容开始行
8end_line方法内容结束行
9branch分支
10method_desc方法描述
11chat_descGPT 描述
12invoke_count被调用数量
13mermaid_flow_graph流程图数据
14flow_graph_ignored是否忽略流程图
15annotation_info注解信息
16annotation_type注解类型
17access_modifier修饰符

类信息

序号字段名称字段描述
1class_id类唯一标识
2class_name类名
3project_name项目唯一标识
4package_name包名
5branch分支
6class_type类的类型
7chat_descGPT 类描述
8class_desc类注释
9annotation_info类注解
10method_annotation_info方法注解信息
11annotation_type注解类型

怎么拿到整个项目的类信息和方法信息呢?

首先我们需要一个类解析器、一个方法解析器。使用 Java 的反射,我们就能拿到具体类和方法的详细信息。

类解析器代码:

public void execute(List<CtType<?>> elements) {
        classStructs = Lists.newArrayList();
        for (CtType<?> type : elements) {
            try {
                // 匿名内部类和泛型会跳过解析
                if (type.isAnonymous()) {
                    continue;
                }
                if (Objects.isNull(type.getPackage())) {
                    continue;
                }
                // 获取类的简单类名
                String simpleClassName = type.getSimpleName();
                // GPT 接口获取解释
                String chatDesc = "";
                // 获取类所属包
                String packageName = type.getPackage().getQualifiedName();
                // 获取类注释信息
                String classComment = type.getDocComment();
                // 判断接口还是类
                ClassType classType = getClassType(type);
                // 获取类注解信息
                List<AnnotationInfo> annotationInfos = Lists.newArrayList();
                List<CtAnnotation<?>> annotations = type.getAnnotations();
                for (CtAnnotation<?> annotation : annotations) {
                    AnnotationInfo annotationInfo = new AnnotationInfo();
                    String annotationName = annotation.getAnnotationType().getSimpleName();
                    annotationInfo.setAnnotationName(annotationName);
                    Map<String, CtExpression> annotationValues = annotation.getValues();
                    for (Map.Entry<String, CtExpression> entry : annotationValues.entrySet()) {
                        String attributeName = entry.getKey();
                        Object attributeValue = entry.getValue();
                        annotationInfo.addAttributeName(attributeName, attributeValue.toString());
                    }
                    annotationInfos.add(annotationInfo);
                }
                // 构造类元信息
                ClassStruct classStruct = buildClassStruct(simpleClassName, packageName, classType,
                        classComment, annotationInfos, chatDesc);
                classStructs.add(classStruct);
            } catch (Exception e) {
                log.error("class parse error, className ==>{}, errMsg ==>", type.getSimpleName(), e);
            }
        }
        // 类元信息入库
    }

方法解析器

public void execute(List<CtType<?>> elements) {
        methodStructs = Lists.newArrayList();
        for (CtType<?> element : elements) {
            if (element.isAnonymous()) {
                continue;
            }
            if (Objects.isNull(element.getPackage())) {
                continue;
            }
            // 获取包名
            String packageName = element.getPackage().getQualifiedName();
            // 获取类名
            String className = element.getSimpleName();
            // 获取方法列表
            Set<CtMethod<?>> methods = element.getMethods();
            for (CtMethod<?> method : methods) {
                try {
                    // 获取简单方法名
                    String methodName = method.getSimpleName();
                    // 获取全限定参数
                    String signatureParameters = method.getSignature();
                    int firstIndex = method.getSignature().indexOf("(");
                    int lastIndex = method.getSignature().indexOf(")");
                    String parameters = signatureParameters.substring(firstIndex + 1, lastIndex);
                    List<String> methodParameters = Splitter.on(",").omitEmptyStrings().splitToList(parameters);
                    // 获取响应体类型
                    String responseType = method.getType().getQualifiedName();
                    // 获取方法开始的行
                    int startLine = method.getPosition().getLine();
                    // 获取方法结束的行
                    int endLine = method.getPosition().getEndLine();
                    // 获取方法注释
                    String methodComment = method.getDocComment();
                    // 获取方法包含的注解信息
                    List<AnnotationInfo> annotationInfos = Lists.newArrayList();
                    List<CtAnnotation<?>> annotations = method.getAnnotations();
                    for (CtAnnotation<?> annotation : annotations) {
                        AnnotationInfo annotationInfo = new AnnotationInfo();
                        String annotationName = annotation.getAnnotationType().getSimpleName();
                        annotationInfo.setAnnotationName(annotationName);
                        Map<String, CtExpression> annotationValues = annotation.getValues();
                        for (Map.Entry<String, CtExpression> entry : annotationValues.entrySet()) {
                            String attributeName = entry.getKey();
                            Object attributeValue = entry.getValue();
                            annotationInfo.addAttributeName(attributeName, attributeValue.toString());
                        }
                        annotationInfos.add(annotationInfo);
                    }
                    // 获取方法的访问修饰符
                    String accessModifier = "";
                    if (Objects.isNull(method.getVisibility())) {
                        accessModifier = "default";
                    } else {
                        accessModifier = method.getVisibility().toString();
                    }
                    String methodId = generateIdentityUtil.generateMethodId(MethodSignature.builder()
                            .packagePath(packageName)
                            .className(className)
                            .methodName(methodName)
                            .parameterTypeString(methodParameters)
                            .build(), endLine - startLine + 1);


                    MethodStruct old = null;
                    // 基于规则判断一波是否需要询问chat
                    int lineCount = endLine - startLine;

                    MethodStruct methodStruct = MethodStruct.builder()
                            .appCode(GlobalVariableUtil.getAppCodeName())
                            .methodId(methodId)
                            .methodName(methodName)
                            .classId(generateIdentityUtil.generateClassId(className, packageName, GlobalVariableUtil.getAppCodeName()))
                            .paramTypes(methodParameters)
                            .responseType(responseType)
                            .beginLine(startLine)
                            .endLine(endLine)
                            .branch(GlobalVariableUtil.getBranch())
                            .methodDesc(methodComment)
                            .annotationInfos(annotationInfos)
                            .accessModifier(accessModifier)
                            .invokeCount(old == null ? 0 : old.getInvokeCount())
                            .mermaidFlowGraph(old == null ? "" : old.getMermaidFlowGraph())
                            .build();
                    if (old == null) {
                        methodStructs.add(methodStruct);
                    }
                } catch (Exception e) {
                    log.error("method parse error, className ==>{}, methodName ==>{}, errMsg ==>",
                           className, method.getSimpleName(), e);
                }
            }
        }
//       方法元信息入库
    }

通过这种方式,我们就能拿到整个 Java 项目的方法信息。

需要注意的是,我们这个时候还没有使用 AI 技术,所以这个元信息中部分字段是空的。

我们看到类解析器和方法解析器方法的入参都是 List<CtType<?>> elements

那么,这个信息从哪里来的呢?

我这里使用的是 Spoon 工具。

Spoon 是什么?

Spoon 框架常被用于解析和处理 Java 源代码。Spoon 是一个强大的源码分析与转换工具,它通过构建抽象语法树(Abstract Syntax Tree, AST)来表示 Java 源代码,并提供了一套丰富的 API 供开发者操作 AST。

Spoon 能够完整且准确地捕获源代码的所有细节,所以它非常适合于进行复杂的静态代码分析、重构、自动插入代码逻辑等工作。

Spoon 不会用?没关系,AI 可以帮你写代码。

我们可以看到,GPT 直接帮我们生成完整代码,我们只需要在对应的地方,替换成我们的类解析器和方法解析器即可。

提示词如下:

你是一个Java技术专家。
我需要解析本地的一个 Java 项目,获得这个项目中的类信息和方法信息。我会给你提供这个 Java 项目的绝对路径。
请你使用 Spoon 生成解析代码

写到这里,我要告诉你的是,其实类解析器和方法解析的代码,也可以交给 AI 来完成哟~ 你可以试试看,如果有问题,随时找阿七给你解答。

到这里,我们今天的内容就结束啦。

下一篇,我们分享使用 AI 生成方法的流程图,请期待~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/318982.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习使用Rainyun搭建网站

我们选择了白嫖雨云的二级域名 浏览器输入https://www.rainyun.com/z22_ 创建账号然后选择一个你喜欢的子域名我建议后缀选择ates.top的 选择自定义地址&#xff0c;类型选择cname 现在要选择记录值了&#xff0c;有a&#xff0c;aa&#xff0c;txt等 根据实际情况填写。就可以…

【CAN】CANoe添加模拟节点报错解决方法

文章目录 1. 问题现象2. 问题解决方法 >>返回总目录<< 1. 问题现象 通过CANoe添加模拟节点时&#xff0c;提示无法加载动态链接库CANOEILNLSPA.DLL。 2. 问题解决方法 右键模拟节点&#xff0c;选择Configuration选项&#xff0c;弹出Node Configuration界面&am…

【计算机组成原理】高速缓冲存储器 Cache 的三种映射方式(Cache Mapping)

Cache映射 Cache Mapping 缓存是计算机系统中常见的一种高速存储器&#xff0c;用于临时存储常用数据&#xff0c;以便快速访问。在缓存中&#xff0c;有三种常见的映射方式&#xff0c;分别是直接映射、全相联映射和组相联映射。 直接映射 Direct Mapping 在直接映射中&…

uniapp 编译后文字乱码的解决方案

问题: 新建的页面中编写代码&#xff0c;其中数字和图片都可以正常显示&#xff0c;只有中文编译后展示乱码 页面展示也是乱码 解决方案: 打开HuilderX编辑器的【文件】- 【以指定编码重新打开】- 【选择UTF-8】 然后重新编译就可以啦~ 希望可以帮到你啊~

OpenHarmony社区运营报告(2023年12月)

• 截至2023年12月22日&#xff0c;OpenAtom OpenHarmony&#xff08;简称“OpenHarmony"&#xff09;社区累计超过6700名贡献者&#xff0c;产生26.9万多个PR&#xff0c;2.4万多个Star&#xff0c;6.7万多个Fork&#xff0c;59个SIG。 • 2023年12月16日&#xff0c;以“…

Windows+Qt5.14.2+android x86配置与处理adb报错

资源下载 可在部分国内镜像源下载Qt5.14.2&#xff1a;Index of /qt/archive/qt/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror其他工具 android studio:下载 Android Studio 和应用工具 - Android 开发者 | Android Developerssdk manager 、ndk、java 安装过…

使用emu8086实现——分支结构程序设计

一、实验目的 1. 掌握分支结构程序的编程方法 2. 掌握汇编语言程序设计方法&#xff0c;自己编写程序&#xff0c;并调试运行验证结果。 二、实验内容 1.在键盘上输入一个字符&#xff0c;判断是否为小写字母&#xff0c;若不是&#xff0c;显示错误信息&#xff0c;若是&…

win桌面图标间距变大如何调整

1、win键R-->输入regedit-->回车 2、 找到 IconSpacing 和 IconVerticalSpacing -->HKEY_CURRENT_USER-->Control Panel-->Desktop-->WindowMetrics-->IconSpacing-->IconVerticalSpacing 3、分别将其值改成-1125&#xff08;系统默认的值&#xff09…

Cortex-M移植

常用寄存器 PRIMASK寄存器 PRIMASK寄存器为1位宽的中断屏蔽寄存器。在置位时&#xff0c;它会阻止不可屏蔽中断&#xff08;NMI&#xff09;和HardFault异常之外的所有异常&#xff08;包括中断&#xff09;。实际上&#xff0c;它是将当前异常优先级提升为0&#xff0c;这就是…

#Prompt##提示词工程##AIGC##LLM#使用大型预训练语言模型的关键考量

如果有不清楚的地方可以评论区留言&#xff0c;我会给大家补上的&#xff01; 本文包括&#xff1a; Prompt 的一些行业术语介绍 Prompt 写好提示词的方法经验介绍&#xff08;附示例教程&#xff09; LLM自身存在的问题&#xff08;可以用Prompt解决的以及无法用Prompt解决的&…

【Maven】007-Maven 工程的继承和聚合关系

【Maven】007-Maven 工程的继承和聚合关系 文章目录 【Maven】007-Maven 工程的继承和聚合关系一、Maven 工程的继承关系1、继承的概念2、继承的作用3、继承的语法4、父工程统一管理依赖版本父工程声明依赖版本子工程继承以来版本 二、Maven 工程的聚合关系1、聚合的概念2、聚合…

十三、QPalette的简单使用(Qt5 GUI系列)

目录 一、设计需求 二、实现代码 三、代码解析 四、总结 一、设计需求 在实际应用中&#xff0c;经常需要改变某个控件的颜色外观&#xff0c;如背景、文字颜色等。Qt提供的调色板类 QPalette 专门用于管理对话框的外观显示。QPalette 类相当于对话框或是控件的调色板&…

centos7系统部署rancher2.x,并创建k8s集群

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 前言 一 本文目标&#xff1a; 1、部署rancher-server UI&#xff0c;版本&#xff1a;2.3.5 2、通过rancher部署一个k8s集群c…

网络协议与攻击模拟_04ICMP协议与ICMP重定向

ICMP协议是网络层协议&#xff0c; 利用ICMP协议可以实现网络中监听服务和拒绝服务&#xff0c;如 ICMP重定向的攻击。 一、ICMP基本概念 1、ICMP协议 ICMP是Internet控制报文协议&#xff0c;用于在IP主机、路由器之间传递控制消息&#xff0c;控制消息指网络通不通、主机是…

Python 二维平面Delaunay三角网建立

目录 一、算法概念二、代码实现三、结果示例根据二维平面内的离散点建立平面三角网。 一、算法概念 三角剖分与Delaunay剖分定义:如何把一个散点集剖分成不均匀的三角形网格,即在给定的平面点集上,生成三角形集合的过程。考虑平面点集P={p1,p2,p3,…,pn},我们希望得到三…

CMake+QT+大漠插件的桌面应用开发

文章目录 CMakeQT大漠插件的桌面应用开发说明环境项目结构配置编译环境代码 CMakeQT大漠插件的桌面应用开发 说明 在CMake大漠插件的应用开发——处理dm.dll&#xff0c;免注册调用大漠插件中已经说明了如何免注册调用大漠插件&#xff0c;以及做了几个简单的功能调用&#x…

金南瓜SECS/GEM发送event、VID

金南瓜SECS/GEM发送事件&#xff08;CEID&#xff09;很简单&#xff0c;只需一步就完成。 最重要是简单易懂&#xff0c;任何人一看就上手。无需懂得内部逻辑&#xff0c;以及一大堆的导入问题。 代码如下 C#的代码&#xff1a; // 扫码成功 private void buttonReadBarco…

【教学类-43-20】20240113 数独(二)4宫格、9宫格 无空行A4模板

作品展示&#xff1a; 4宫格 9宫格 题目连在一起 背景需求&#xff1a; 制作十宫格数独模板&#xff0c;为了凑满20行&#xff0c;删除了每个数独题之间的行列分割线 【教学类-43-18】A4最终版 20240111 数独11.0 十宫格X*YZ套(n10)&#xff0c;套用没有分割行列的A4横版模板…

浅谈对Maven的理解

一、什么是Maven Maven——是Java社区事实标准的项目管理工具&#xff0c;能帮你从琐碎的手工劳动中解脱出来&#xff0c;帮你规范整个组织的构建系统。不仅如此&#xff0c;它还有依赖管理、自动生成项目站点等特性&#xff0c;已经有无数的开源项目使用它来构建项目并促进团队…

将 OpenCV Java 与 Eclipse 结合使用

配置 Eclipse 首先&#xff0c;从下载页面获取 OpenCV 的新版本&#xff0c;并将其解压缩到一个简单的位置&#xff0c;例如 .我使用的是 2.4.6 版&#xff0c;但其他版本的步骤或多或少相同。C:\OpenCV-2.4.6\ 现在&#xff0c;我们将 OpenCV 定义为 Eclipse 中的用户库&…
最新文章