2016-07-21 8 views
0

Ich habe eine Methode m1 in Klasse A, die eine Variable b vom Typ Klasse B hat und m1 ruft eine Methode m2 in Klasse B durch Aufruf von b.m2 (...). Nun ist die Methode m2 nicht in Klasse B implementiert, sondern in einer Klasse C, aus der B abgeleitet wurde. Wenn Sie jQAssistant für dieses Szenario ausführen, erhalte ich die folgenden Beziehungen, wenn alle drei Klassen demselben Artefakt angehören: (A) - [: DECLARES] -> (m1) - [: INVOKES] -> (m2) < - [: DECLARES] - (B) < - [: EXTENDS] - (C) und (C) - [: DECLARES] -> (m2 '). Beachten Sie, dass (B) - [: DECLARES] -> (m2) eine Art synthetische Deklaration ist, da m2 nicht wirklich von B deklariert, sondern nur geerbt wird.classPath: Resolve löst Methodenaufrufe unter bestimmten Umständen nicht richtig

Angenommen, Klasse A gehört zu einem anderen Artefakt als Klasse B und C. Dann erzeugt der Auflösungsmechanismus nicht die synthetische Deklaration in der aufgelösten Klasse B. Genauer gesagt generiert das Scannen von A's Artefakt: (A) - [: DEKLAREN] -> (m1) - [: INVOKES] -> (m2 '') < - [: DEKLAREN] - (B '). Und Auflösung über das Konzept classPath: Resolve wird erstellen: (B ') - [: RESOLVES_TO] -> (B) aber es wird nicht (B) - [: DECLARES] -> (m2) und damit m2' ' kann nicht in m2 aufgelöst werden. Somit kann auch die Beziehung: INVOKES nicht aufgelöst werden.

+0

Klingt wie ein Problem, das behoben werden muss, kann ich bitte Sie, ein auf GitHub zu schaffen? Prost, Dirk –

Antwort

0

Für mich sind die folgenden Konzepte gearbeitet:

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