forked from jplag/JPlag
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9ad7388
commit 9c25f9f
Showing
6 changed files
with
326 additions
and
0 deletions.
There are no files selected for viewing
56 changes: 56 additions & 0 deletions
56
...es/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/AnyOfNEdge.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package de.jplag.java_cpg.transformation.matching.edges; | ||
|
||
import de.fraunhofer.aisec.cpg.graph.Node; | ||
|
||
/** | ||
* A {@link AnyOfNEdge} serves as a placeholder for a {@link CpgNthEdge} during transformation calculation as long as | ||
* the index is not known. | ||
*/ | ||
public class AnyOfNEdge<T extends Node, R extends Node> extends CpgNthEdge<T, R> { | ||
|
||
private final CpgMultiEdge<T, R> cpgMultiEdge; | ||
private final int minIndex; | ||
|
||
/** | ||
* Creates a new {@link AnyOfNEdge} for the corresponding {@link CpgMultiEdge}. | ||
*/ | ||
public AnyOfNEdge(CpgMultiEdge<T, R> cpgMultiEdge, int minIndex) { | ||
super(cpgMultiEdge, -1); | ||
this.cpgMultiEdge = cpgMultiEdge; | ||
this.minIndex = minIndex; | ||
} | ||
|
||
public int getMinimalIndex() { | ||
return minIndex; | ||
} | ||
|
||
/** | ||
* Gets the corresponding {@link CpgMultiEdge}. | ||
* @return the multi edge | ||
*/ | ||
@Override | ||
public CpgMultiEdge<T, R> getMultiEdge() { | ||
return cpgMultiEdge; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) | ||
return true; | ||
if (o == null || getClass() != o.getClass()) | ||
return false; | ||
if (!super.equals(o)) | ||
return false; | ||
|
||
AnyOfNEdge<?, ?> that = (AnyOfNEdge<?, ?>) o; | ||
|
||
return cpgMultiEdge.equals(that.cpgMultiEdge); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
int result = super.hashCode(); | ||
result = 31 * result + cpgMultiEdge.hashCode(); | ||
return result; | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
...in/java/de/jplag/java_cpg/transformation/matching/pattern/relation/ForAllRelatedNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package de.jplag.java_cpg.transformation.matching.pattern.relation; | ||
|
||
import java.util.List; | ||
|
||
import de.fraunhofer.aisec.cpg.graph.Node; | ||
import de.jplag.java_cpg.transformation.matching.edges.CpgMultiEdge; | ||
import de.jplag.java_cpg.transformation.matching.pattern.Match; | ||
import de.jplag.java_cpg.transformation.matching.pattern.NodePattern; | ||
|
||
/** | ||
* A {@link ForAllRelatedNode} describes a one-to-n relation where in a match, <b>all</b> candidate nodes must match the | ||
* given pattern. | ||
* @param <T> the parent node type | ||
* @param <R> the related node type | ||
*/ | ||
public final class ForAllRelatedNode<T extends Node, R extends Node> extends OneToNRelation<T, R> { | ||
|
||
public ForAllRelatedNode(NodePattern<? extends R> pattern, CpgMultiEdge<T, R> edge) { | ||
super(pattern, edge); | ||
} | ||
|
||
@Override | ||
public List<R> getTarget(T from) { | ||
return getEdge().getAllTargets(from); | ||
} | ||
|
||
@Override | ||
public <C extends T> void recursiveMatch(NodePattern<C> pattern, T parent, List<Match> openMatches) { | ||
List<? extends Node> candidates = getTarget(parent); | ||
|
||
for (Node candidate : candidates) { | ||
this.pattern.recursiveMatch(candidate, openMatches); | ||
openMatches.forEach(match -> match.remove(this.pattern)); | ||
} | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "ForAllRelatedNode[" + "pattern=" + pattern + ", " + "edge=" + edge + ']'; | ||
} | ||
|
||
} |
76 changes: 76 additions & 0 deletions
76
.../main/java/de/jplag/java_cpg/transformation/matching/pattern/relation/OneToNRelation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package de.jplag.java_cpg.transformation.matching.pattern.relation; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
import de.fraunhofer.aisec.cpg.graph.Node; | ||
import de.jplag.java_cpg.transformation.matching.edges.CpgMultiEdge; | ||
import de.jplag.java_cpg.transformation.matching.pattern.Match; | ||
import de.jplag.java_cpg.transformation.matching.pattern.NodePattern; | ||
|
||
/** | ||
* This is a superclass for the multiple kinds of one-to-n relations. | ||
* @param <T> the target node type | ||
* @param <R> the related node type | ||
*/ | ||
public sealed class OneToNRelation<T extends Node, R extends Node> extends Relation<T, R, List<R>> permits ForAllRelatedNode, RelatedOneToNNode { | ||
|
||
private final CpgMultiEdge<T, R> multiEdge; | ||
|
||
protected OneToNRelation(NodePattern<? extends R> pattern, CpgMultiEdge<T, R> edge) { | ||
super(pattern, edge); | ||
this.multiEdge = edge; | ||
} | ||
|
||
@Override | ||
public CpgMultiEdge<T, R> getEdge() { | ||
return this.multiEdge; | ||
} | ||
|
||
public List<R> getTarget(T from) { | ||
return multiEdge.getAllTargets(from); | ||
} | ||
|
||
@Override | ||
public boolean isEquivalentTo(Relation<?, ?, ?> targetRelated, boolean multipleCandidates) { | ||
return this.edge.isEquivalentTo(targetRelated.edge) | ||
&& (!multipleCandidates || this.pattern.getRole().equals(targetRelated.pattern.getRole())); | ||
} | ||
|
||
@Override | ||
public <C extends T> void recursiveMatch(NodePattern<C> pattern, T parent, List<Match> openMatches) { | ||
List<R> candidates = getTarget(parent); | ||
List<Match> resultMatches = IntStream.range(0, candidates.size()).mapToObj(i -> { | ||
R candidate = candidates.get(i); | ||
ArrayList<Match> openMatchesCopy = openMatches.stream().map(Match::copy).map(match -> match.resolveAnyOfNEdge(pattern, this, i)) | ||
.collect(Collectors.toCollection(ArrayList::new)); | ||
this.pattern.recursiveMatch(candidate, openMatchesCopy); | ||
return openMatchesCopy; | ||
}).flatMap(List::stream).toList(); | ||
openMatches.clear(); | ||
openMatches.addAll(resultMatches); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) | ||
return true; | ||
if (o == null || getClass() != o.getClass()) | ||
return false; | ||
if (!super.equals(o)) | ||
return false; | ||
|
||
OneToNRelation<?, ?> that = (OneToNRelation<?, ?>) o; | ||
|
||
return multiEdge.equals(that.multiEdge); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
int result = super.hashCode(); | ||
result = 31 * result + multiEdge.hashCode(); | ||
return result; | ||
} | ||
} |
78 changes: 78 additions & 0 deletions
78
...src/main/java/de/jplag/java_cpg/transformation/matching/pattern/relation/RelatedNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package de.jplag.java_cpg.transformation.matching.pattern.relation; | ||
|
||
import java.util.List; | ||
import java.util.Objects; | ||
|
||
import de.fraunhofer.aisec.cpg.graph.Node; | ||
import de.jplag.java_cpg.transformation.matching.edges.CpgEdge; | ||
import de.jplag.java_cpg.transformation.matching.pattern.Match; | ||
import de.jplag.java_cpg.transformation.matching.pattern.NodePattern; | ||
|
||
/** | ||
* Pair of a node patterns of a related node and a function to get from a reference node to a candidate related node. | ||
* @param <T> type of the target node | ||
* @param <R> type of the related node | ||
*/ | ||
public final class RelatedNode<T extends Node, R extends Node> extends Relation<T, R, R> { | ||
|
||
private final CpgEdge<T, R> cpgEdge; | ||
|
||
/** | ||
* @param pattern the patterns describing the related node | ||
* @param edge edge to get a related node given a reference node | ||
*/ | ||
public RelatedNode(NodePattern<? extends R> pattern, CpgEdge<T, R> edge) { | ||
super(pattern, edge); | ||
this.cpgEdge = edge; | ||
} | ||
|
||
@Override | ||
public CpgEdge<T, R> getEdge() { | ||
return cpgEdge; | ||
} | ||
|
||
public R getTarget(T from) { | ||
return cpgEdge.getRelated(from); | ||
} | ||
|
||
public <C extends T> void recursiveMatch(NodePattern<C> pattern, T parent, List<Match> openMatches) { | ||
R candidateNode = getTarget(parent); | ||
|
||
if (Objects.isNull(candidateNode)) { | ||
openMatches.clear(); | ||
} else { | ||
this.pattern.recursiveMatch(candidateNode, openMatches); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean isEquivalentTo(Relation<?, ?, ?> targetRelated, boolean multipleCandidates) { | ||
return this.cpgEdge.isEquivalentTo(targetRelated.edge); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "RelatedNode{%s}".formatted(pattern.toString()); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) | ||
return true; | ||
if (o == null || getClass() != o.getClass()) | ||
return false; | ||
if (!super.equals(o)) | ||
return false; | ||
|
||
RelatedNode<?, ?> that = (RelatedNode<?, ?>) o; | ||
|
||
return cpgEdge.equals(that.cpgEdge); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
int result = super.hashCode(); | ||
result = 31 * result + cpgEdge.hashCode(); | ||
return result; | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
...in/java/de/jplag/java_cpg/transformation/matching/pattern/relation/RelatedOneToNNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package de.jplag.java_cpg.transformation.matching.pattern.relation; | ||
|
||
import de.fraunhofer.aisec.cpg.graph.Node; | ||
import de.jplag.java_cpg.transformation.matching.edges.CpgMultiEdge; | ||
import de.jplag.java_cpg.transformation.matching.pattern.NodePattern; | ||
|
||
/** | ||
* Pair of a node patterns of a related node and a multi edge from a reference node to a list of candidate related | ||
* nodes. | ||
* @param <T> type of the target node | ||
* @param <R> type of the related node | ||
*/ | ||
public final class RelatedOneToNNode<T extends Node, R extends Node> extends OneToNRelation<T, R> { | ||
|
||
/** | ||
* @param pattern the patterns describing the related node | ||
* @param edge edge from a reference node to the related nodes | ||
*/ | ||
public RelatedOneToNNode(NodePattern<? extends R> pattern, CpgMultiEdge<T, R> edge) { | ||
super(pattern, edge); | ||
|
||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "RelatedOneToNNode[" + "pattern=" + pattern + ", " + "edge=" + edge + ']'; | ||
} | ||
|
||
} |
45 changes: 45 additions & 0 deletions
45
...pg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/relation/Relation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package de.jplag.java_cpg.transformation.matching.pattern.relation; | ||
|
||
import java.util.List; | ||
import java.util.Objects; | ||
|
||
import de.fraunhofer.aisec.cpg.graph.Node; | ||
import de.jplag.java_cpg.transformation.matching.edges.IEdge; | ||
import de.jplag.java_cpg.transformation.matching.pattern.Match; | ||
import de.jplag.java_cpg.transformation.matching.pattern.NodePattern; | ||
|
||
public abstract sealed class Relation<T extends Node, R extends Node, V> permits OneToNRelation, RelatedNode { | ||
public final NodePattern<? extends R> pattern; | ||
public final IEdge<T, R> edge; | ||
|
||
protected Relation(NodePattern<? extends R> pattern, IEdge<T, R> edge) { | ||
this.pattern = pattern; | ||
this.edge = edge; | ||
} | ||
|
||
public IEdge<T, R> getEdge() { | ||
return edge; | ||
} | ||
|
||
public abstract V getTarget(T from); | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (obj == this) | ||
return true; | ||
if (obj == null || obj.getClass() != this.getClass()) | ||
return false; | ||
var that = this.getClass().cast(obj); | ||
return Objects.equals(this.pattern, that.pattern) && Objects.equals(this.edge, that.edge); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(pattern, edge); | ||
} | ||
|
||
public abstract boolean isEquivalentTo(Relation<?, ?, ?> targetRelated, boolean multipleCandidates); | ||
|
||
public abstract <C extends T> void recursiveMatch(NodePattern<C> pattern, T parent, List<Match> openMatches); | ||
|
||
} |