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

21 篇文章 1 订阅

之前分享过一篇使用 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 生成方法的流程图,请期待~

  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java开源项目JOONE是一个基于Java的神经网络框架,可以用来实现人工智能编程。下面是一个使用JOONE实现人工智能的例子: 假设我们要实现一个简单的人工智能程序,该程序能够识别手写数字。我们可以使用JOONE来训练一个神经网络,让它学会如何识别手写数字。 首先,我们需要准备一些手写数字的数据集。这些数据集可以是一个包含手写数字图像和对应标签的数据集。我们可以使用MNIST数据集,它是一个广泛使用的手写数字数据集。 接下来,我们需要使用JOONE构建一个神经网络,该网络将接受手写数字图像作为输入,输出该数字的标签。我们可以使用JOONE的神经网络模块来构建网络,例如: ``` NeuralNet nn = new NeuralNet(); Layer inputLayer = new InputLayer(); Layer hiddenLayer = new SigmoidLayer(); Layer outputLayer = new OutputLayer(); nn.addLayer(inputLayer); nn.addLayer(hiddenLayer); nn.addLayer(outputLayer); FullSynapse synapseIH = new FullSynapse(); FullSynapse synapseHO = new FullSynapse(); synapseIH.setInputLayer(inputLayer); synapseIH.setOutputLayer(hiddenLayer); synapseHO.setInputLayer(hiddenLayer); synapseHO.setOutputLayer(outputLayer); nn.addSynapse(synapseIH); nn.addSynapse(synapseHO); ``` 以上代码创建了一个包含一个输入层、一个隐藏层和一个输出层的神经网络。输入层接受手写数字图像,输出层输出该数字的标签。隐藏层使用Sigmoid函数作为激活函数。 接下来,我们需要使用JOONE的训练模块来训练神经网络。我们可以使用反向传播算法来训练网络,例如: ``` BackpropagationTrainer trainer = new BackpropagationTrainer(); trainer.setNeuralNet(nn); trainer.setTrainingPatterns(trainingPatterns); trainer.train(); ``` 以上代码使用训练模式来训练神经网络。训练模式包含一组输入和对应的输出标签,用于训练神经网络。训练模式可以从MNIST数据集中生成。 最后,我们可以使用训练好的神经网络来识别手写数字。例如: ``` double[] input = new double[784]; //将手写数字图像转换为一维数组,作为神经网络的输入 nn.setInput(input); //获取神经网络的输出,即识别出的手写数字标签 double[] output = nn.getOutput(); ``` 以上代码将手写数字图像转换为一维数组,作为神经网络的输入。然后获取神经网络的输出,即识别出的手写数字标签。 通过以上步骤,我们就可以使用JOONE来实现一个简单的手写数字识别人工智能程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伍六七AI编程

你猜你给我1分我要不要

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值