Skip to content

Commit

Permalink
Add missing files
Browse files Browse the repository at this point in the history
  • Loading branch information
robinmaisch committed Mar 23, 2024
1 parent 9ad7388 commit 9c25f9f
Show file tree
Hide file tree
Showing 6 changed files with 326 additions and 0 deletions.
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;
}
}
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 + ']';
}

}
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;
}
}
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;
}
}
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 + ']';
}

}
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);

}

0 comments on commit 9c25f9f

Please sign in to comment.