feat: 1、Vo包装识别增强 2、去除 位置&类型 的色块
All checks were successful
序列化结构检查 / serialization-schema-check (push) Has been skipped

This commit is contained in:
2026-07-15 15:45:35 +08:00
parent 4dd4944107
commit 14f9f1fce7
9 changed files with 456 additions and 37 deletions

View File

@@ -65,4 +65,91 @@ class RedisKeyResolverTest {
buildCall, clazz, index.get("jnpf.util.TenantDbContentCacheHelper"));
assertEquals("tenant:db:content:*", pattern);
}
@Test
void resolvesLocalVariableAssignedFromStringFormat() {
String source = ""
+ "package demo;\n"
+ "public class CombinationRepo {\n"
+ " private static final String COMBINATION_QUERY_KEY = "
+ "\"data_analysis:combination_query_key:%s:%s\";\n"
+ " public void write(String tenantId, String hashKey) {\n"
+ " String key = String.format(COMBINATION_QUERY_KEY, tenantId, hashKey);\n"
+ " redisSet(key);\n"
+ " }\n"
+ " void redisSet(String k) {}\n"
+ "}\n";
SourceIndex index = new SourceIndex();
index.addSource(source);
CompilationUnit cu = StaticJavaParser.parse(source);
ClassOrInterfaceDeclaration clazz = cu.getType(0).asClassOrInterfaceDeclaration();
// redisSet(key) 的实参 key —— 局部变量使用点
MethodCallExpr redisSet = cu.findAll(MethodCallExpr.class).stream()
.filter(m -> "redisSet".equals(m.getNameAsString()))
.findFirst()
.orElseThrow(IllegalStateException::new);
Expression keyArg = redisSet.getArgument(0);
String pattern = new RedisKeyResolver(index).resolve(
keyArg, clazz, index.get("demo.CombinationRepo"));
assertEquals("data_analysis:combination_query_key:*:*", pattern);
}
@Test
void localReassignmentUsesNearestBindingBeforeUse() {
String source = ""
+ "package demo;\n"
+ "public class ReassignRepo {\n"
+ " private static final String A = \"prefix:a:%s\";\n"
+ " private static final String B = \"prefix:b:%s\";\n"
+ " public void write(String id) {\n"
+ " String key = String.format(A, id);\n"
+ " key = String.format(B, id);\n"
+ " redisSet(key);\n"
+ " }\n"
+ " void redisSet(String k) {}\n"
+ "}\n";
SourceIndex index = new SourceIndex();
index.addSource(source);
CompilationUnit cu = StaticJavaParser.parse(source);
ClassOrInterfaceDeclaration clazz = cu.getType(0).asClassOrInterfaceDeclaration();
MethodCallExpr redisSet = cu.findAll(MethodCallExpr.class).stream()
.filter(m -> "redisSet".equals(m.getNameAsString()))
.findFirst()
.orElseThrow(IllegalStateException::new);
String pattern = new RedisKeyResolver(index).resolve(
redisSet.getArgument(0), clazz, index.get("demo.ReassignRepo"));
assertEquals("prefix:b:*", pattern);
}
@Test
void staticConstantStillPreferredOverLocalNameCollision() {
// 局部变量名与静态常量同名时:仍优先静态常量(保持旧语义)
String source = ""
+ "package demo;\n"
+ "public class Collision {\n"
+ " private static final String KEY = \"const:prefix:%s\";\n"
+ " public void write(String id) {\n"
+ " String KEY = \"local:\" + id;\n"
+ " redisSet(KEY);\n"
+ " }\n"
+ " void redisSet(String k) {}\n"
+ "}\n";
SourceIndex index = new SourceIndex();
index.addSource(source);
CompilationUnit cu = StaticJavaParser.parse(source);
ClassOrInterfaceDeclaration clazz = cu.getType(0).asClassOrInterfaceDeclaration();
MethodCallExpr redisSet = cu.findAll(MethodCallExpr.class).stream()
.filter(m -> "redisSet".equals(m.getNameAsString()))
.findFirst()
.orElseThrow(IllegalStateException::new);
String pattern = new RedisKeyResolver(index).resolve(
redisSet.getArgument(0), clazz, index.get("demo.Collision"));
assertEquals("const:prefix:%s", pattern);
}
}