如何使用 jqassistant 检测/解析超级方法调用
How to detect / resolve super method invocations with jqassistant
我正在使用 jqassistant 1.8.0 来检测 class 层次结构中的超级方法调用。
似乎 class 层次结构中的一些方法调用丢失了,即使在应用 classpath:Resolve 概念之后也是如此。最小设置包含三个 classes:
public class SuperClass {
void superMethod() {
}
}
public class SubClass1 extends SuperClass {
void subMethod1() {
super.superMethod();
}
}
public class SubClass2 extends SuperClass {
void subMethod2() {
superMethod();
}
}
subMethod1 和 subMethod2 都在调用 SuperClass 的相同方法,但只有具有显式 "super." 调用的方法具有 :INVOKES 关系。
MATCH
(who)-[:INVOKES]->(m)<-[:DECLARES]-(:Type {fqn: 'SuperClass'})
Return who
数据库中存在两个具有签名 "void superMethod()" 的节点,一个由 SuperClass 声明,一个由 SubClass2 声明。似乎缺少一些链接两个相同方法的步骤。
是否有另一个内置概念(除了 classpath:Resolve)解决这个问题,还是 java-plugin 没有涵盖这个问题?谢谢!
super.superMethod()
和 superMethod()
的调用略有不同:
第一个指示JVM使用来自super class的方法,第二个依赖于在运行时解析该方法,SubClass2
中可能有一个实现(虚拟调用):
对于这种情况,创建的图包含对 SubClass2
中方法占位符的调用(仅具有签名 属性):
(method)-[:INVOKES]->(:Method{signature:"void superMethod()"})<-[:DECLARES]-(:Type{name:"SubClass2"})
有一个概念 java:MethodOverrides
应该创建与超级 class 方法的 OVERRIDES
关系,但遗憾的是它在这种情况下不起作用(直到 jQA 1.8.0)。已经应用了 jQA 1.9.0 附带的修复程序:
MATCH
(type:Type)-[:DECLARES]->(method:Method),
(superType:Type)-[:DECLARES]->(superMethod:Method),
path=shortestPath((type)-[:EXTENDS|IMPLEMENTS*]->(superType))
WHERE
method.signature = superMethod.signature
and superMethod.visibility <> "private"
WITH
type, method, superType, superMethod, length(path) as depth
ORDER BY
depth asc
WITH
method, head(collect(superMethod)) as overriddenMethod
MERGE
(method)-[:OVERRIDES]->(overriddenMethod)
RETURN
count(*) as OverriddenMethods
使用这个你应该能够执行以下查询:
MATCH
(:Type{name:"SuperClass"})-[:DECLARES]->(m:Method{name:"superMethod"}),
(who)-[:INVOKES]->(:Method)-[:OVERRIDES*0..1]->(m) // catching direct or virtual invocations
RETURN
who
我正在使用 jqassistant 1.8.0 来检测 class 层次结构中的超级方法调用。 似乎 class 层次结构中的一些方法调用丢失了,即使在应用 classpath:Resolve 概念之后也是如此。最小设置包含三个 classes:
public class SuperClass {
void superMethod() {
}
}
public class SubClass1 extends SuperClass {
void subMethod1() {
super.superMethod();
}
}
public class SubClass2 extends SuperClass {
void subMethod2() {
superMethod();
}
}
subMethod1 和 subMethod2 都在调用 SuperClass 的相同方法,但只有具有显式 "super." 调用的方法具有 :INVOKES 关系。
MATCH
(who)-[:INVOKES]->(m)<-[:DECLARES]-(:Type {fqn: 'SuperClass'})
Return who
数据库中存在两个具有签名 "void superMethod()" 的节点,一个由 SuperClass 声明,一个由 SubClass2 声明。似乎缺少一些链接两个相同方法的步骤。
是否有另一个内置概念(除了 classpath:Resolve)解决这个问题,还是 java-plugin 没有涵盖这个问题?谢谢!
super.superMethod()
和 superMethod()
的调用略有不同:
第一个指示JVM使用来自super class的方法,第二个依赖于在运行时解析该方法,SubClass2
中可能有一个实现(虚拟调用):
对于这种情况,创建的图包含对 SubClass2
中方法占位符的调用(仅具有签名 属性):
(method)-[:INVOKES]->(:Method{signature:"void superMethod()"})<-[:DECLARES]-(:Type{name:"SubClass2"})
有一个概念 java:MethodOverrides
应该创建与超级 class 方法的 OVERRIDES
关系,但遗憾的是它在这种情况下不起作用(直到 jQA 1.8.0)。已经应用了 jQA 1.9.0 附带的修复程序:
MATCH
(type:Type)-[:DECLARES]->(method:Method),
(superType:Type)-[:DECLARES]->(superMethod:Method),
path=shortestPath((type)-[:EXTENDS|IMPLEMENTS*]->(superType))
WHERE
method.signature = superMethod.signature
and superMethod.visibility <> "private"
WITH
type, method, superType, superMethod, length(path) as depth
ORDER BY
depth asc
WITH
method, head(collect(superMethod)) as overriddenMethod
MERGE
(method)-[:OVERRIDES]->(overriddenMethod)
RETURN
count(*) as OverriddenMethods
使用这个你应该能够执行以下查询:
MATCH
(:Type{name:"SuperClass"})-[:DECLARES]->(m:Method{name:"superMethod"}),
(who)-[:INVOKES]->(:Method)-[:OVERRIDES*0..1]->(m) // catching direct or virtual invocations
RETURN
who