Adrninistrator / java-callgraph2

Programs for producing static call graphs for Java programs.
Apache License 2.0
184 stars 66 forks source link

关于类的继承/实现中泛型参数的关系 #50

Open 0o0b opened 1 month ago

0o0b commented 1 month ago

例如有三个类:

public interface BaseMapper<T> {}

public interface CommonMapper<S, T> extends BaseMapper<T> {}

public interface TestMapper extends CommonMapper<String, Integer> {}

按照当前的实现,jacg_class_signature_ei1表中会记录TestMapper的泛型参数:

seq sign_class_name
0 java.lang.String
1 java.lang.Integer

我觉得可以加一张表,记录下CommonMapperBaseMapper的泛型参数的关系:

seq upward_seq
1 0

这样我们才能知道,TestMapper是一个BaseMapper<Integer>

Adrninistrator commented 1 month ago

现在class_signature表里会记录当前类对应的接口或父类的信息,应该能满足要求吧 ![Uploading b820bb63bb97011736fdc3eb9c8007e.png…]()

Adrninistrator commented 1 month ago

示例数据如下 record_id simple_class_name type super_itf_class_name seq sign_class_name class_name 1 TestApplicationListener i org.springframework.context.ApplicationListener 0 org.springframework.context.ApplicationEvent tester.sql.applicationlistener.TestApplicationListener 2 JsonSerializerLocalDateTime e com.fasterxml.jackson.databind.JsonSerializer 0 java.time.LocalDateTime tester.sql.jsonserializer.JsonSerializerLocalDateTime 3 JsonSerializerTimestamp e com.fasterxml.jackson.databind.JsonSerializer 0 java.sql.Timestamp tester.sql.jsonserializer.JsonSerializerTimestamp 4 Service_guavaCache$1 e com.google.common.cache.CacheLoader 0 java.lang.String tester.sql.service.cache.Service_guavaCache$1 5 Service_guavaCache$1 e com.google.common.cache.CacheLoader 1 tester.sql.entity.TestSelectInsert tester.sql.service.cache.Service_guavaCache$1 6 Service_guavaCache$2 e com.google.common.cache.CacheLoader 0 java.lang.String tester.sql.service.cache.Service_guavaCache$2 7 Service_guavaCache$2 e com.google.common.cache.CacheLoader 1 tester.sql.entity.TestSelectInsert tester.sql.service.cache.Service_guavaCache$2 8 JsonUtil4WriteDb$1 e com.fasterxml.jackson.core.type.TypeReference 0 java.util.Map tester.sql.util.JsonUtil4WriteDb$1

0o0b commented 1 month ago

@Adrninistrator

我在1.0.16版本测试的结果是,并没有记录CommonMapperBaseMapper之间的泛型参数关系。

com.adrninistrator.javacg.parser.JarEntryHandleParser#recordSignatureArgumentInfo方法里只对copy.javassist.bytecode.SignatureAttribute.ClassType类型的objectType做了处理,没有对copy.javassist.bytecode.SignatureAttribute.TypeVariable类型的处理。

Adrninistrator commented 1 month ago

可能是因为对接口没有做这些处理,有空了我优化一下

Adrninistrator commented 4 weeks ago

在最新版2.0.2增加了处理,“interface CommonMapper<S, T> extends BaseMapper”会识别为CommonMapper继承了BaseMapper,使用的泛型类型是Object(对应T)

0o0b commented 4 weeks ago

@Adrninistrator 我看了你的 commit,按照新的实现,表中会比之前多出一条数据,这条数据表明CommonMapper<?, ?>是一个BaseMapper<Object>。很显然,这是不对的。

按照我一开始给出的例子,如果我们要使用java代码,通过反射来获取TestMapper中给出的BaseMapper<T>的泛型参数,那么我们需要dfs遍历继承/实现树,找到树里头的BaseMapper,然后在后序处理中,发现:

BaseMapper 的第 0 个泛型参数
-> CommonMapper 的第 1 个泛型参数
-> TestMapper 中声明的 CommonMapper 的第 1 个泛型参数为 Integer

这样我们才能确定,TestMapper是一个BaseMapper<Integer>

所以我们可能需要加一张表,来记录BaseMapper 的第 0 个泛型参数CommonMapper 的第 1 个泛型参数的对应关系,这张表大约需要有这些字段:

BaseMapperCommonMapper的关系对应这样一条数据:

simple_class_name seq upward_simple_class_name upward_seq
CommonMapper 1 BaseMapper 0
Adrninistrator commented 4 weeks ago

可以处理,有空了我改下