Skip to content

Commit

Permalink
Code Map Update Test
Browse files Browse the repository at this point in the history
  • Loading branch information
goodjava committed Aug 27, 2024
1 parent 8229cdc commit 5303918
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 16 deletions.
171 changes: 160 additions & 11 deletions jcommon/ai/neo4j/src/main/java/run/mone/neo4j/MoneCodeParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.nodeTypes.NodeWithName;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
Expand Down Expand Up @@ -326,11 +329,11 @@ private static void createProjectNode(Session session, String projectName) {
/**
* 查找具有指定注解的类
*
* @param session 数据库会话
* @param session 数据库会话
* @param annotationToFind 要查找的注解
* @return 具有指定注解的类的列表,每个类以Map形式表示
*/
public List<Map<String, Object>> findClassesWithAnnotation(Session session, String annotationToFind) {
public List<Map<String, Object>> findClassesWithAnnotation(Session session, String annotationToFind) {
Map<String, Object> params = new HashMap<>();
params.put("annotation", annotationToFind);
Result result = session.run(
Expand All @@ -339,7 +342,7 @@ public List<Map<String, Object>> findClassesWithAnnotation(Session session, Stri
"RETURN c",
params
);
List<Map<String,Object>> list = new ArrayList<>();
List<Map<String, Object>> list = new ArrayList<>();
while (result.hasNext()) {
Record record = result.next();
System.out.println(record.get("c").asMap());
Expand Down Expand Up @@ -406,8 +409,6 @@ public void visit(ClassOrInterfaceDeclaration n, Void arg) {
//注解
classParams.put("annotations", annoList);

System.out.println(classParams);

session.run(
"MERGE (c:Class {name: $name}) " +
"ON CREATE SET c.full_name = $fullName, c.type = $type, c.code = $code, c.anno = $annotations " +
Expand Down Expand Up @@ -454,13 +455,135 @@ public void visit(ClassOrInterfaceDeclaration n, Void arg) {

}


private String getFullMethodName(MethodDeclaration method) {
String packageName = method.findCompilationUnit()
.flatMap(cu -> cu.getPackageDeclaration())
.map(pd -> pd.getNameAsString())
.orElse("");
String className = method.findAncestor(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.class)
.map(c -> c.getNameAsString())
.orElse("");
String methodName = method.getNameAsString();
return packageName + "." + className + "." + methodName;
}

/**
* 获取方法调用的完整路径,包括包名、类名和方法名
*
* @param methodCall 方法调用表达式
* @return 方法调用的完整路径
*/
public String getFullMethodPath(MethodCallExpr methodCall) {
StringBuilder fullPath = new StringBuilder();

// 获取包名
Optional<CompilationUnit> cu = methodCall.findCompilationUnit();
if (cu.isPresent()) {
cu.get().getPackageDeclaration().ifPresent(pkg ->
fullPath.append(pkg.getNameAsString()).append(".")
);
}

// 获取类名
String className = methodCall.findAncestor(ClassOrInterfaceDeclaration.class)
.map(ClassOrInterfaceDeclaration::getNameAsString)
.orElse("");

// 获取方法调用的对象
String objectName = methodCall.getScope()
.map(scope -> scope.toString())
.orElse("");


//静态调用
if (methodCall.getScope().isPresent() && methodCall.getScope().get() instanceof FieldAccessExpr) {
return objectName + "." + methodCall.getNameAsString();
}

//lombok 的log
if (isLogCall(methodCall)) {
return objectName + "." + methodCall.getNameAsString();
}

// 如果对象名不为空,尝试找到它的类型
if (!objectName.isEmpty()) {
Optional<FieldDeclaration> field = methodCall.findAncestor(ClassOrInterfaceDeclaration.class)
.flatMap(classDecl -> classDecl.getFieldByName(objectName));

if (field.isPresent()) {
ClassOrInterfaceType type = field.get().getVariable(0).getType().asClassOrInterfaceType();
String v = resolveTypePath(type);
return v + "." + methodCall.getNameAsString();
}
}


// 构建完整路径
fullPath.append(className).append(".");
fullPath.append(methodCall.getNameAsString());

return fullPath.toString();
}

public static String resolveTypePath(ClassOrInterfaceType type) {
String typeName = type.getNameAsString();

Optional<CompilationUnit> cu = type.findAncestor(CompilationUnit.class);
if (cu.isPresent()) {
// 尝试从导入声明中查找匹配
Optional<String> importedPath = findMatchingImport(cu.get(), typeName);
if (importedPath.isPresent()) {
return importedPath.get();
}

// 如果没有找到匹配的导入,检查是否在同一包中
Optional<String> currentPackage = getCurrentPackage(cu.get());
if (currentPackage.isPresent()) {
return currentPackage.get() + "." + typeName;
}
}

// 如果无法解析,返回原始类型名称
return typeName;
}

private static Optional<String> findMatchingImport(CompilationUnit cu, String typeName) {
return cu.getImports().stream()
.filter(importDecl -> !importDecl.isAsterisk() && importDecl.getNameAsString().endsWith("." + typeName))
.map(ImportDeclaration::getNameAsString)
.findFirst();
}

private static Optional<String> getCurrentPackage(CompilationUnit cu) {
return cu.getPackageDeclaration().map(pd -> pd.getNameAsString());
}

/**
* 判断方法调用是否为日志调用
*
* @param n 方法调用表达式
* @return 如果方法调用是日志调用则返回true,否则返回false
*/
private boolean isLogCall(MethodCallExpr n) {
if (!n.getScope().isPresent()) {
return false;
}
String scope = n.getScope().get().toString();
String method = n.getNameAsString();
return scope.equals("log") &&
(method.equals("trace") || method.equals("debug") || method.equals("info") ||
method.equals("warn") || method.equals("error"));
}


@Override
public void visit(MethodDeclaration n, Void arg) {
super.visit(n, arg);

// 创建 Method 节点
Map<String, Object> methodParams = new HashMap<>();
methodParams.put("name", n.getNameAsString());
methodParams.put("name", getFullMethodName(n));
methodParams.put("signature", n.getSignature().asString());
methodParams.put("code_vector", new float[]{}); // 替换为实际的代码向量

Expand All @@ -474,14 +597,42 @@ public void visit(MethodDeclaration n, Void arg) {
}

declaresParams.put("className", n.findAncestor(ClassOrInterfaceDeclaration.class).get().getNameAsString());
declaresParams.put("methodName", n.getNameAsString());
declaresParams.put("methodName", getFullMethodName(n));

session.run("MATCH (c:Class {name: $className}) " +
"MATCH (m:Method {name: $methodName}) " +
"MERGE (c)-[:DECLARES]->(m)",
declaresParams);

// 处理注释
processComments(n);

// 处理方法调用
processMethodCalls(n);

}

// 处理方法调用
private void processMethodCalls(MethodDeclaration n) {
n.findAll(MethodCallExpr.class).forEach(methodCall -> {
Map<String, Object> callParams = new HashMap<>();
callParams.put("callerName", getFullMethodName(n));
callParams.put("calleeName", getFullMethodPath(methodCall));

// 创建目标方法节点(如果不存在)
session.run("MERGE (callee:Method {name: $calleeName})", callParams);

// 创建 CALLS 关系
session.run("MATCH (caller:Method {name: $callerName}) " +
"MATCH (callee:Method {name: $calleeName}) " +
"MERGE (caller)-[:CALLS]->(callee)",
callParams);
});
}


// 处理注释
private void processComments(MethodDeclaration n) {
for (Comment comment : n.getAllContainedComments()) {
createCommentNode(comment, n);
}
Expand All @@ -495,7 +646,6 @@ public void visit(MethodDeclaration n, Void arg) {
if (commentOptional.isPresent()) {
createCommentNode(commentOptional.get(), n);
}

}

private void createCommentNode(Comment comment, MethodDeclaration n) {
Expand All @@ -508,7 +658,7 @@ private void createCommentNode(Comment comment, MethodDeclaration n) {
// 创建 DOCUMENTS 关系 (Comment -[:DOCUMENTS]-> Method)
Map<String, Object> documentsParams = new HashMap<>();
documentsParams.put("commentText", comment.getContent());
documentsParams.put("methodName", n.getNameAsString());
documentsParams.put("methodName", getFullMethodName(n));
documentsParams.put("methodSignature", n.getSignature().asString());
session.run("MATCH (comment:Comment {text: $commentText}) " +
"MATCH (m:Method {name: $methodName, signature: $methodSignature}) " +
Expand Down Expand Up @@ -545,5 +695,4 @@ public String readResourceFileContent(String fileName) {
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public void testWriteCatServiceToNeo4j() {
// MoneCodeParser.writeJavaFilesToNeo4j("/Users/zhangzhiyong/IdeaProjects/ai/m78/m78-service/src/main/java/run/mone/m78/service/database/SqlParseUtil.java");
// new MoneCodeParser().writeJavaFilesToNeo4j("/Users/zhangzhiyong/IdeaProjects/goodjava/mone/jcommon/ai/neo4j/src/test/java/run/mone/neo4j/test/A.java");
new MoneCodeParser().setPassword(System.getenv("password")).writeJavaFilesToNeo4j("/Users/zhangzhiyong/IdeaProjects/goodjava/mone/jcommon/ai/neo4j/src/test/java/run/mone/neo4j/test/m");
// new MoneCodeParser().setPassword(System.getenv("password")).writeJavaFilesToNeo4j("/Users/zhangzhiyong/IdeaProjects/goodjava/mone/jcommon/ai/neo4j/src/test/java/run/mone/neo4j/test/m/CatService.java");
// new MoneCodeParser().setPassword(System.getenv("password")).writeJavaFilesToNeo4j("/Users/zhangzhiyong/IdeaProjects/goodjava/mone/jcommon/ai/neo4j/src/test/java/run/mone/neo4j/test/m/PersonService.java");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package run.mone.neo4j.test.anno;

/**
* @author [email protected]
* @date 2024/8/21 16:06
*/
public @interface Test {
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
package run.mone.neo4j.test.m;

import lombok.extern.slf4j.Slf4j;
import run.mone.neo4j.test.anno.Resource;
import run.mone.neo4j.test.anno.RestController;
import run.mone.neo4j.test.anno.Service;
import run.mone.neo4j.test.m.cat.CatService;

/**
* @author [email protected]
* @date 2024/8/16 10:16
*/
@Service
@Slf4j
public class PersonService {


@Resource
private CatService catService;


//获取猫的数量
public int getCatCount() {
log.info("info");
System.out.println("abc");
return catService.getCatCount();
}


/**
* 计算两数之和
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package run.mone.neo4j.test.m;

import run.mone.neo4j.test.anno.Resource;
import run.mone.neo4j.test.anno.Service;
import run.mone.neo4j.test.anno.Test;

/**
* @author [email protected]
* @date 2024/8/26 18:23
*/
@Service
public class PersonServiceTest {

@Resource
private PersonService personService;

@Test
public void test1() {
int res = personService.getCatCount();
System.out.println(res);
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
package run.mone.neo4j.test.m;
package run.mone.neo4j.test.m.cat;

import run.mone.neo4j.test.anno.RestController;
import lombok.extern.slf4j.Slf4j;
import run.mone.neo4j.test.anno.Service;

import java.util.HashMap;
import java.util.Map;

/**
* @author [email protected]
* @date 2024/8/19 18:21
*/
@Service
@Slf4j
public class CatService {

private Map<String,String> data = new HashMap<>();
private HashMap<String,String> data = new HashMap<>();


//获取小猫的数量
//获取小猫的数量
public int getCatCount() {
log.info("abc");
System.out.println("123");
return data.size();
}

Expand Down

0 comments on commit 5303918

Please sign in to comment.