我在A类中有一个方法m1,它有一个B类型的变量b,而m1通过调用b.m2(...)来调用B类中的方法m2。现在,方法m2没有在B类中实现,而是在从中导出B的C类中实现。如果在该场景中运行jQAssistant,如果所有三个类属于同一个工件,则会得到以下关系: (A) - [:声明] - GT;(M1) - [:调用] - GT;(M2)< - [:声明] - (B)< - [:EXTENDS] - (C) 和(C) - [:DECLARES] - >(m2')。 请注意,(B) - [:DECLARES] - >(m2)是一种合成声明,因为m2实际上并未由B声明,而只是继承。
但是假设类A属于与B类和C类不同的工件。那么解析机制不会在已解析的类B中生成合成声明。更准确地说,扫描A的工件将生成: (A) - [:声明] - GT;(M1) - [:调用] - GT;(M2')< - [:声明] - (B')。 并通过概念classPath解析:Resolve将创建: (B') - [:RESOLVES_TO] - >(B)但是没有(B) - [:DECLARES] - >(m2)因此m2''不能被解析为m2。因此,也无法解决:INVOKES关系。
答案 0 :(得分:0)
对我来说,以下概念有效:
<concept id="missingResolves:AddInheritedMethodsToResolvedTypes">
<requiresConcept refId="classpath:ResolveMember"/>
<description>Sometimes the method needed to resolve a method m1 declared in a type t1 is not directly declared in the resolved type t2, but just inherited by t2, then we add this method to t2 (as synthetic-declare).</description>
<cypher><![CDATA[
MATCH (t1:Type)-[:RESOLVES_TO]->(t2:Type), (t1)-[:DECLARES]->(m1:Method)
WHERE NOT (m1)-[:RESOLVES_TO]->()
WITH DISTINCT t2, m1.signature AS methodSignature
MERGE (t2)-[:DECLARES {synthetic: true}]->(m2:Method {signature: methodSignature})
RETURN t2.name as type, methodSignature ORDER BY t2.name, methodSignature
]]></cypher>
</concept>
<concept id="missingResolves:ResolveMethodsUsingInheritedMethodsInResolvedTypes">
<requiresConcept refId="missingResolves:AddInheritedMethodsToResolvedTypes"/>
<description>Uses the synthetic methods added by the "AddInheritedMethodsToResolvedTypes" concept to add missing method resolves.</description>
<cypher><![CDATA[
MATCH (t1:Type)-[:RESOLVES_TO]->(t2:Type), (t1)-[:DECLARES]->(m1:Method)
WHERE NOT (m1)-[:RESOLVES_TO]->()
WITH t1, t2, m1 MATCH (t2)-[:DECLARES {synthetic: true}]->(m2:Method)
WHERE m1.signature = m2.signature
MERGE (m1)-[:RESOLVES_TO {resolved:true}]->(m2)
RETURN count(m1) as ResolvedMethods
]]></cypher>
</concept>
<concept id="missingResolves:ResolveInvokesAgain">
<requiresConcept refId="classpath:ResolveInvokes"/>
<requiresConcept refId="missingResolves:ResolveMethodsUsingInheritedMethodsInResolvedTypes"/>
<description>Resolve method invocations again (same as in original jQAssistant).</description>
<cypher><![CDATA[
MATCH (m:Method)-[i:INVOKES]->(m1:Method)-[:RESOLVES_TO]->(m2:Method)
WHERE NOT (m)-[:INVOKES{lineNumber:i.lineNumber,resolved:true}]->(m2)
MERGE (m)-[:INVOKES{lineNumber:i.lineNumber,resolved:true}]->(m2)
RETURN count(i) as ResolvedInvocations
]]></cypher>
</concept>
<concept id="missingResolves:Correct">
<requiresConcept refId="classpath:Resolve"/>
<requiresConcept refId="missingResolves:ResolveInvokesAgain"/>
<description>Performs a complete corrected resolve.</description>
<cypher><![CDATA[
MATCH ()-[r:RESOLVES_TO]->() RETURN count(r) as ResolvedElements
]]></cypher>
</concept>