From fc3d079556c6c7aaa052604d592c449ffdc52b19 Mon Sep 17 00:00:00 2001 From: Robin Maisch Date: Tue, 19 Mar 2024 17:42:18 +0100 Subject: [PATCH] Add more documentation --- .../de/jplag/java_cpg/JavaCpgLanguage.java | 1 + .../de/jplag/java_cpg/passes/DfgSortPass.kt | 2 +- .../jplag/java_cpg/token/CpgNodeListener.java | 4 +- ...ropertyEdge.java => CpgAttributeEdge.java} | 11 +++-- .../matching/edges/CpgMultiEdge.java | 1 - .../matching/pattern/Match.java | 3 +- .../matching/pattern/NodePattern.java | 44 ++++++++++++++++--- .../matching/pattern/SimpleGraphPattern.java | 15 +------ .../operations/RemoveOperation.java | 43 ++++++++---------- .../visitorStrategy/NodeOrderStrategy.java | 18 ++++---- 10 files changed, 80 insertions(+), 62 deletions(-) rename languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/{CpgPropertyEdge.java => CpgAttributeEdge.java} (61%) diff --git a/languages/java-cpg/src/main/java/de/jplag/java_cpg/JavaCpgLanguage.java b/languages/java-cpg/src/main/java/de/jplag/java_cpg/JavaCpgLanguage.java index a121597a3..d5a1668da 100644 --- a/languages/java-cpg/src/main/java/de/jplag/java_cpg/JavaCpgLanguage.java +++ b/languages/java-cpg/src/main/java/de/jplag/java_cpg/JavaCpgLanguage.java @@ -78,6 +78,7 @@ public boolean requiresCoreNormalization() { public void resetTransformations() { this.cpgAdapter.clearTransformations(); this.cpgAdapter.addTransformations(this.obligatoryTransformations()); + this.cpgAdapter.addTransformations(this.standardTransformations()); } /** diff --git a/languages/java-cpg/src/main/java/de/jplag/java_cpg/passes/DfgSortPass.kt b/languages/java-cpg/src/main/java/de/jplag/java_cpg/passes/DfgSortPass.kt index 0c8008bf0..665dcf6af 100644 --- a/languages/java-cpg/src/main/java/de/jplag/java_cpg/passes/DfgSortPass.kt +++ b/languages/java-cpg/src/main/java/de/jplag/java_cpg/passes/DfgSortPass.kt @@ -305,7 +305,7 @@ class DfgSortPass(ctx: TranslationContext) : TranslationUnitPass(ctx) { val block = parentInfo[it]!!.parent as Block val index = block.statements.indexOf(it) val cpgNthEdge: CpgNthEdge = CpgNthEdge(BLOCK__STATEMENTS, index) - RemoveOperation.apply(it, block, cpgNthEdge, true) + RemoveOperation.apply(block, it, cpgNthEdge, true) if (it is DeclarationStatement) { val deletedVariables = it.declarations.filterIsInstance() block.localEdges.removeIf { it.end in deletedVariables } diff --git a/languages/java-cpg/src/main/java/de/jplag/java_cpg/token/CpgNodeListener.java b/languages/java-cpg/src/main/java/de/jplag/java_cpg/token/CpgNodeListener.java index 37ff2010d..5cffe28d7 100644 --- a/languages/java-cpg/src/main/java/de/jplag/java_cpg/token/CpgNodeListener.java +++ b/languages/java-cpg/src/main/java/de/jplag/java_cpg/token/CpgNodeListener.java @@ -8,6 +8,8 @@ import java.util.LinkedList; import java.util.Objects; +import org.jetbrains.annotations.NotNull; + import de.fraunhofer.aisec.cpg.graph.Name; import de.fraunhofer.aisec.cpg.graph.Node; import de.fraunhofer.aisec.cpg.graph.declarations.*; @@ -401,7 +403,7 @@ public void visit(MemberCallExpression memberCallExpression) { * Visits a {@link Node}. * @param node the node */ - public void visit(Node node) { + public void visit(@NotNull Node node) { super.visit(node); } diff --git a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/CpgPropertyEdge.java b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/CpgAttributeEdge.java similarity index 61% rename from languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/CpgPropertyEdge.java rename to languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/CpgAttributeEdge.java index adbec8ef2..0bb8019a9 100644 --- a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/CpgPropertyEdge.java +++ b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/CpgAttributeEdge.java @@ -10,11 +10,16 @@ * @param getter function to get the property * @param setter function to set the property * @param the node type of the source - * @param the type of the property + * @param

the type of the property */ -public record CpgPropertyEdge(Function getter, BiConsumer setter) { +public record CpgAttributeEdge(Function getter, BiConsumer setter) { - public T get(S s) { + /** + * Gets the property related to the given node. + * @param s the source node + * @return the property + */ + public P get(S s) { return getter.apply(s); } } diff --git a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/CpgMultiEdge.java b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/CpgMultiEdge.java index 144b9d9ea..e1abee7f7 100644 --- a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/CpgMultiEdge.java +++ b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/edges/CpgMultiEdge.java @@ -136,7 +136,6 @@ public boolean isEdgeValued() { return this.valueType == ValueType.EDGE_VALUED; } - /** {@inheritDoc} */ @Override public boolean isEquivalentTo(IEdge other) { return Objects.equals(this, other); diff --git a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/Match.java b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/Match.java index 51b9fc7d0..0bc48902c 100644 --- a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/Match.java +++ b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/Match.java @@ -7,6 +7,7 @@ import de.fraunhofer.aisec.cpg.graph.Node; import de.jplag.java_cpg.transformation.matching.edges.CpgEdge; +import de.jplag.java_cpg.transformation.matching.edges.CpgMultiEdge; import de.jplag.java_cpg.transformation.matching.edges.CpgMultiEdge.AnyOfNEdge; import de.jplag.java_cpg.transformation.matching.edges.CpgNthEdge; import de.jplag.java_cpg.transformation.matching.pattern.WildcardGraphPattern.ParentNodePattern; @@ -130,7 +131,7 @@ public WildcardMatch getWildcardMatch(ParentNodePattern CpgNthEdge resolveAnyOfNEdge(NodePattern parent, NodePattern.RelatedOneToNNode relation, int index) { - AnyOfNEdge any1ofNEdge = relation.edge().getAnyOfNEdgeTo(relation.pattern()); + CpgMultiEdge.AnyOfNEdge any1ofNEdge = relation.edge().getAnyOfNEdgeTo(relation.pattern()); CpgNthEdge concreteEdgePattern = new CpgNthEdge<>(any1ofNEdge.getMultiEdge(), index); EdgeMapKey key = new EdgeMapKey(parent, any1ofNEdge); this.edgeMap.put(key, concreteEdgePattern); diff --git a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/NodePattern.java b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/NodePattern.java index 66576e233..b2c986a34 100644 --- a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/NodePattern.java +++ b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/NodePattern.java @@ -22,6 +22,12 @@ */ public interface NodePattern { + /** + * Creates a new {@link NodePattern} for the given {@link Node} type. + * @param tClass the node class + * @param the node type + * @return the node pattern + */ @NotNull static NodePattern forNodeType(Class tClass) { return new NodePatternImpl<>(tClass); @@ -40,9 +46,16 @@ static NodePattern forNodeType(Class tClass) { * @param the type of the related node * @param related the related NodePattern * @param edge an edge to candidates for the related node given a concrete match for this pattern + * @param a C class */ void addRelated1ToNNodePattern(NodePattern related, CpgMultiEdge edge); + /** + * Adds a for-all relation to this pattern + * @param related the pattern to match against all related nodes + * @param edge the edge that points to the related nodes + * @param a R class + */ void addForAllRelated(NodePattern related, CpgMultiEdge edge); /** @@ -51,6 +64,10 @@ static NodePattern forNodeType(Class tClass) { */ void addProperty(Predicate property); + /** + * Adds the given {@link MatchProperty} to this {@link NodePattern}. + * @param property the match property + */ void addMatchProperty(MatchProperty property); /** @@ -79,8 +96,12 @@ static NodePattern forNodeType(Class tClass) { * Gets the {@link List} of 1:n-related {@link NodePattern}s of this {@link NodePattern}. * @return the related node pattern */ - List> getRelated1ToNNodes(); + List> getRelated1ToNNodes(); + /** + * Gets the related 1-to-N sequences for this note pattern. + * @return the 1-to-N sequences + */ List> getRelated1ToNSequences(); /** @@ -95,10 +116,21 @@ static NodePattern forNodeType(Class tClass) { */ Class getRootClass(); + /** + * Set a flag that indicates that no graph operations should be created beyond this node pattern. + */ void markStopRecursion(); + /** + * Determines whether the STOP_RECURSION flag has been set for this node pattern. + * @return true if STOP_RECURSION is set + */ boolean shouldStopRecursion(); + /** + * Gets the list of node classes of possible candidates for this node pattern. + * @return a {@link List} object + */ List> getCandidateClasses(); /** @@ -126,7 +158,7 @@ class NodePatternImpl implements NodePattern { /** * List of related nodes (1:n relation). */ - private final List> related1ToNNodes; + private final List> related1ToNNodes; /** * List of related node sequences. */ @@ -163,7 +195,7 @@ public void addRelatedNodePattern(NodePattern rela @Override public void addRelated1ToNNodePattern(NodePattern related, CpgMultiEdge edge) { // Could be refactored to a map by the edge type instead of a list - related1ToNNodes.add(new Related1ToNNode<>(related, edge)); + related1ToNNodes.add(new RelatedOneToNNode<>(related, edge)); } @Override @@ -229,7 +261,7 @@ public void recursiveMatch(Node node, List matches, CpgEdge incomin Node candidate = candidates.get(i); var openMatchesCopy = new ArrayList<>(openMatches.stream().map(Match::copy).toList()); int finalI = i; - openMatchesCopy.forEach(match -> match.resolveAny1ofNEdge(this, pair, finalI)); + openMatchesCopy.forEach(match -> match.resolveAnyOfNEdge(this, pair, finalI)); pair.getPattern().recursiveMatch(candidate, openMatchesCopy, nthElement(pair.edge, i)); resultMatches.addAll(openMatchesCopy); } @@ -276,7 +308,7 @@ protected boolean localMatch(Node node) { } @Override - public List> getRelated1ToNNodes() { + public List> getRelated1ToNNodes() { return related1ToNNodes; } @@ -393,7 +425,7 @@ public String toString() { * @param pattern the pattern describing the related node * @param edge edge from a reference node to the related nodes */ - record Related1ToNNode(NodePattern pattern, CpgMultiEdge edge) { + record RelatedOneToNNode(NodePattern pattern, CpgMultiEdge edge) { List getCandidates(T from) { return edge.getAllTargets(from); } diff --git a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/SimpleGraphPattern.java b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/SimpleGraphPattern.java index 692400ac3..765fd44a5 100644 --- a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/SimpleGraphPattern.java +++ b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/matching/pattern/SimpleGraphPattern.java @@ -15,7 +15,7 @@ */ public class SimpleGraphPattern extends GraphPatternImpl { - private NodePattern root; + private final NodePattern root; /** * Creates a new {@link de.jplag.java_cpg.transformation.matching.pattern.SimpleGraphPattern} with the given root @@ -41,13 +41,11 @@ public NodePattern getRoot() { return root; } - /** {@inheritDoc} */ @Override public List> getRoots() { return List.of(root); } - /** {@inheritDoc} */ @Override public List match(Map, List> rootCandidates) { return rootCandidates.get(root).stream().map(this::recursiveMatch).flatMap(List::stream).toList(); @@ -68,7 +66,6 @@ public List recursiveMatch(C rootCandidate) { return matches; } - /** {@inheritDoc} */ @Override public boolean validate(Match match) { Node rootCandidate = match.get(this.root); @@ -76,7 +73,6 @@ public boolean validate(Match match) { return matches.stream().anyMatch(match::equals); } - /** {@inheritDoc} */ @Override public void compareTo(GraphPattern targetPattern, BiConsumer, NodePattern> compareFunction) { if (!(targetPattern instanceof SimpleGraphPattern tTarget && Objects.equals(root.getClass(), tTarget.root.getClass()))) { @@ -86,13 +82,4 @@ public void compareTo(GraphPattern targetPattern, BiConsumer, Nod compareFunction.accept(this.root, tTarget.getRoot()); } - /** - * Sets the root {@link de.jplag.java_cpg.transformation.matching.pattern.NodePattern} of this - * {@link de.jplag.java_cpg.transformation.matching.pattern.SimpleGraphPattern}. - * @param rootPattern the root - */ - protected void setRoot(NodePattern rootPattern) { - this.root = rootPattern; - } - } diff --git a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/operations/RemoveOperation.java b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/operations/RemoveOperation.java index b500fe005..0071b3b51 100644 --- a/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/operations/RemoveOperation.java +++ b/languages/java-cpg/src/main/java/de/jplag/java_cpg/transformation/operations/RemoveOperation.java @@ -10,7 +10,6 @@ import de.fraunhofer.aisec.cpg.graph.Node; import de.fraunhofer.aisec.cpg.graph.edge.Properties; import de.fraunhofer.aisec.cpg.graph.edge.PropertyEdge; -import de.jplag.java_cpg.transformation.TransformationException; import de.jplag.java_cpg.transformation.matching.edges.CpgEdge; import de.jplag.java_cpg.transformation.matching.edges.CpgMultiEdge; import de.jplag.java_cpg.transformation.matching.edges.CpgNthEdge; @@ -50,34 +49,31 @@ public RemoveOperation(NodePattern sourcePattern, CpgEdge edg } - /** {@inheritDoc} */ @Override - public void resolveAndApply(Match match, TranslationContext ctx) throws TransformationException { + public void resolveAndApply(Match match, TranslationContext ctx) { S parent = match.get(parentPattern); T element = edge.getter().apply(parent); - apply(element, parent, edge, disconnectEog); + apply(parent, element, edge, disconnectEog); } /** - *

- * apply. - *

- * @param element a T object - * @param parent a S object - * @param edge a {@link de.jplag.java_cpg.transformation.matching.edges.CpgEdge} object - * @param disconnectEog a boolean - * @param a S class - * @param a T class + * Applies a {@link RemoveOperation} to the given nodes. + * @param the source node type + * @param the target node type + * @param source the source node + * @param child the target node + * @param edge the edge + * @param disconnectEog if true, the target node will be disconnected from the EOG graph */ - public static void apply(T element, S parent, CpgEdge edge, boolean disconnectEog) { + public static void apply(S source, T child, CpgEdge edge, boolean disconnectEog) { if (!(edge instanceof CpgNthEdge nthEdge)) { - logger.debug("Remove " + element.toString()); - edge.setter().accept(parent, null); + logger.debug("Remove " + child.toString()); + edge.setter().accept(source, null); } else if (nthEdge.getMultiEdge().isEdgeValued()) { - logger.debug("Remove %s (Element no. %d of %s)".formatted(element.toString(), nthEdge.getIndex(), parent)); + logger.debug("Remove %s (Element no. %d of %s)".formatted(child.toString(), nthEdge.getIndex(), source)); // set edge indices of successors - List> siblingEdges = nthEdge.getMultiEdge().getAllEdges(parent); + List> siblingEdges = nthEdge.getMultiEdge().getAllEdges(source); int index = nthEdge.getIndex(); // remove edge @@ -91,29 +87,27 @@ public static void apply(T element, S parent, C } else { // nthEdge is node-valued - List siblings = nthEdge.getMultiEdge().getAllTargets(parent); - siblings.remove(element); + List siblings = nthEdge.getMultiEdge().getAllTargets(source); + siblings.remove(child); } if (!disconnectEog) { return; } - List predExits = TransformationUtil.disconnectFromPredecessor(element); - Node succEntry = TransformationUtil.disconnectFromSuccessor(element); + List predExits = TransformationUtil.disconnectFromPredecessor(child); + Node succEntry = TransformationUtil.disconnectFromSuccessor(child); if (!Objects.isNull(succEntry) && succEntry != DummyNeighbor.getInstance()) { predExits.forEach(exit -> TransformationUtil.connectNewSuccessor(exit, succEntry, false)); } } - /** {@inheritDoc} */ @Override public NodePattern getTarget() { return parentPattern; } - /** {@inheritDoc} */ @Override public GraphOperation instantiateWildcard(Match match) { WildcardGraphPattern.ParentNodePattern wcParent = (WildcardGraphPattern.ParentNodePattern) this.parentPattern; @@ -125,7 +119,6 @@ private RemoveOperation fromWildcardMatch return new RemoveOperation<>(wildcardMatch.parentPattern(), wildcardMatch.edge(), this.disconnectEog); } - /** {@inheritDoc} */ @Override public GraphOperation instantiateAnyOfNEdge(Match match) { CpgMultiEdge.AnyOfNEdge anyOfNEdge = (CpgMultiEdge.AnyOfNEdge) edge; diff --git a/languages/java-cpg/src/main/java/de/jplag/java_cpg/visitorStrategy/NodeOrderStrategy.java b/languages/java-cpg/src/main/java/de/jplag/java_cpg/visitorStrategy/NodeOrderStrategy.java index 87e558b63..1b9faff13 100644 --- a/languages/java-cpg/src/main/java/de/jplag/java_cpg/visitorStrategy/NodeOrderStrategy.java +++ b/languages/java-cpg/src/main/java/de/jplag/java_cpg/visitorStrategy/NodeOrderStrategy.java @@ -94,16 +94,14 @@ private List getTopLevelRecords(Node node) { List declarations = new ArrayList<>(List.of(node)); while (!declarations.isEmpty()) { Node declaration = declarations.removeFirst(); - if (declaration instanceof Component component) { - declarations.addAll(component.getTranslationUnits()); - } else if (declaration instanceof TranslationUnitDeclaration tu) { - declarations.addAll(tu.getDeclarations()); - } else if (declaration instanceof NamespaceDeclaration namespaceDeclaration) { - declarations.addAll(namespaceDeclaration.getDeclarations()); - } else if (declaration instanceof RecordDeclaration recordDeclaration) { - result.add(recordDeclaration); - } else { - // do nothing + switch (declaration) { + case Component component -> declarations.addAll(component.getTranslationUnits()); + case TranslationUnitDeclaration tu -> declarations.addAll(tu.getDeclarations()); + case NamespaceDeclaration namespaceDeclaration -> declarations.addAll(namespaceDeclaration.getDeclarations()); + case RecordDeclaration recordDeclaration -> result.add(recordDeclaration); + case null, default -> { + // do nothing + } } }