0

クラス A にクラス B 型の変数 b を持つメソッド m1 があり、m1 は b.m2(...) を呼び出してクラス B のメソッド m2 を呼び出します。ここで、メソッド m2 はクラス B ではなく、B の派生元であるクラス C で実装されます。そのシナリオで jQAssistant を実行すると、3 つのクラスがすべて同じ成果物に属している場合、次の関係が得られます: (A)-[:DECLARES]->(m1)-[:INVOKES]->(m2)<-[:DECLARES ]-(B)<-[:EXTENDS]-(C) および (C)-[:DECLARES]->(m2')。(B)-[:DECLARES]->(m2) は一種の合成宣言であることに注意してください。m2 は実際には B によって宣言されているのではなく、継承されているだけだからです。

しかし、クラス A がクラス B および C とは異なるアーティファクトに属しているとします。この場合、解決メカニズムは、解決されたクラス B に合成宣言を生成しません。より正確に言うと、A のアーティファクトをスキャンすると、(A)-[:DECLARES が生成されます。 ]->(m1)-[:INVOKES]->(m2'')<-[:DECLARES]-(B')。そして、概念 classPath:Resolve を介して解決すると、 (B')-[:RESOLVES_TO]->(B) が作成されますが、(B)-[:DECLARES]->(m2) は存在しないため、m2'' は作成できません。 m2 に解決されます。したがって、:INVOKES 関係も解決できません。

4

1 に答える 1

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>
于 2016-07-21T08:24:02.587 に答える