classPath:在某些情况下,Resolve不能正确解析方法调用

时间:2016-07-21 08:22:29

标签: java jqassistant

我在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关系。

1 个答案:

答案 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>