From 170dbb03296cec5edcccd57b61ac42ee3b08ad2a Mon Sep 17 00:00:00 2001 From: Daan van den Heuvel Date: Tue, 24 Dec 2019 16:52:33 +0100 Subject: [PATCH 1/9] Implement collectNodeCalls method and rename getInputParameters --- README.md | 2 ++ src/main/java/factory/MethodNodeHandler.java | 5 ++- src/main/java/model/DataFlowMethod.java | 2 +- src/main/java/model/DataFlowNode.java | 27 ++++++++++++++++ src/main/java/model/NodeCall.java | 2 +- src/main/java/model/ParameterList.java | 2 +- src/test/java/common/GraphBuilder.java | 2 +- .../factory/DataFlowGraphFactoryTest.java | 6 ++-- .../java/factory/MethodNodeHandlerTest.java | 6 ++-- src/test/java/model/DataFlowMethodTest.java | 4 +-- src/test/java/model/DataFlowNodeTest.java | 32 +++++++++++++++++++ src/test/java/util/GraphUtilTest.java | 6 ++-- 12 files changed, 78 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 238b102..a2c1b55 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,8 @@ Add the dependency below to the pom of your project. - JavaDataFlow uses [JavaParser](https://github.com/javaparser/javaparser/) for parsing the input classes. Each DataFlowNode has a representedNode which is the JavaParser Node that it represents. If you have a given JavaParser Node you can get the JavaDataFlowNode via DataFlowGraph::getNode. +- Collect all methods that where called on a given object by executing DataFlowNode::collectNodeCalls. + A scope can be added to this method to only find calls within a certain method or graph, you can for example use DataFlowMethod::owns. ## Roadmap - Include Constructors in the JavaDataFlow graph. diff --git a/src/main/java/factory/MethodNodeHandler.java b/src/main/java/factory/MethodNodeHandler.java index c6d8f40..01b73b0 100644 --- a/src/main/java/factory/MethodNodeHandler.java +++ b/src/main/java/factory/MethodNodeHandler.java @@ -166,11 +166,10 @@ private Optional handleMethodCallExpr(DataFlowGraph graph, DataFlo } calledMethod.setIn(params.build()); - if (instance == null) { - method.addMethodCall(calledMethod); - } else { + if (instance != null) { instance.setNodeCall(calledMethod); } + method.addMethodCall(calledMethod); calledMethod.getReturnNode().ifPresent(method::addNode); // Return the return node of the called method so that the return value can be assigned to the caller. diff --git a/src/main/java/model/DataFlowMethod.java b/src/main/java/model/DataFlowMethod.java index 615c59c..261d914 100644 --- a/src/main/java/model/DataFlowMethod.java +++ b/src/main/java/model/DataFlowMethod.java @@ -111,7 +111,7 @@ public final void setReturnNode(DataFlowNode returnNode) { this.addNode(returnNode); } - public ParameterList getInputParameters() { + public ParameterList getParameters() { return inputParameters; } diff --git a/src/main/java/model/DataFlowNode.java b/src/main/java/model/DataFlowNode.java index 03376b5..9adbfab 100644 --- a/src/main/java/model/DataFlowNode.java +++ b/src/main/java/model/DataFlowNode.java @@ -18,10 +18,12 @@ package model; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.function.Predicate; +import java.util.stream.Collectors; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -140,6 +142,25 @@ public List walkBackUntil(Predicate predicate, Predi return GraphUtil.walkBackUntil(this, predicate, scope); } + /** + * Returns all {@link NodeCall} that are called directly on this {@link DataFlowNode} or on any other {@link DataFlowNode} that has an {@link DataFlowEdge} + * resulting from this node. Only nodes within the defined scope are considered. + * + * @param scope The scope for searching for {@link NodeCall}s. + * @return List of {@link NodeCall}. + */ + public List collectNodeCalls(Predicate scope) { + if (!scope.test(this)) { + return new ArrayList<>(); + } + List collect = + this.getOut().stream().map(DataFlowEdge::getTo).map(dfn -> dfn.collectNodeCalls(scope)).flatMap(List::stream).collect(Collectors.toList()); + if (this.nodeCall != null) { + collect.add(nodeCall); + } + return collect; + } + /** * @param node The {@link DataFlowNode} to check. * @return True if this node is equal to the given node or has a direct incoming edge from the input node, false otherwise. @@ -275,6 +296,12 @@ public Builder out(List out) { return this; } + public Builder out(DataFlowEdge... out) { + this.out.clear(); + this.out.addAll(Arrays.asList(out)); + return this; + } + public Builder type(String type) { this.type = type; return this; diff --git a/src/main/java/model/NodeCall.java b/src/main/java/model/NodeCall.java index 0d71d04..015bf17 100644 --- a/src/main/java/model/NodeCall.java +++ b/src/main/java/model/NodeCall.java @@ -99,7 +99,7 @@ public Optional getCalledMethod() { public void setCalledMethod(DataFlowMethod calledMethod) { this.calledMethod = calledMethod; - this.in.connectTo(calledMethod.getInputParameters()); + this.in.connectTo(calledMethod.getParameters()); if (this.returnNode != null) { if (calledMethod.getReturnNode().isPresent()) { calledMethod.getReturnNode().get().addEdgeTo(returnNode); diff --git a/src/main/java/model/ParameterList.java b/src/main/java/model/ParameterList.java index 6b067fe..1a55a95 100644 --- a/src/main/java/model/ParameterList.java +++ b/src/main/java/model/ParameterList.java @@ -119,7 +119,7 @@ public void connectTo(ParameterList otherParams) { public boolean isInputParametersForMethod() { boolean isInputParam = false; - if (this.owner != null && this.owner instanceof DataFlowMethod && ((DataFlowMethod) this.owner).getInputParameters() == this) { + if (this.owner != null && this.owner instanceof DataFlowMethod && ((DataFlowMethod) this.owner).getParameters() == this) { isInputParam = true; } return isInputParam; diff --git a/src/test/java/common/GraphBuilder.java b/src/test/java/common/GraphBuilder.java index effc43e..9cfb965 100644 --- a/src/test/java/common/GraphBuilder.java +++ b/src/test/java/common/GraphBuilder.java @@ -100,7 +100,7 @@ private void addNode(DataFlowGraph graph, NodeBuilder nodeBuilder, Map assertMethodsEqual(Collection exp, Coll } private Optional assertMethodEqual(DataFlowMethod expMethod, DataFlowMethod equalMethod) { - Optional parametersEqual = dfnTest.assertNodesEqual(expMethod.getInputParameters().getNodes(), equalMethod.getInputParameters().getNodes()) + Optional parametersEqual = dfnTest.assertNodesEqual(expMethod.getParameters().getNodes(), equalMethod.getParameters().getNodes()) .map(s -> "for " + expMethod.getName() + " parameters not equal: " + s); Optional nodesEqual = parametersEqual.isPresent() ? parametersEqual : dfnTest.assertNodesEqual(expMethod.getNodes(), equalMethod.getNodes()).map(s -> "for " + expMethod.getName() + ": " + s); @@ -398,8 +398,8 @@ private Matcher createMatcher(DataFlowMethod method) { EqualFeatureMatcher methodNameMatcher = new EqualFeatureMatcher<>(DataFlowMethod::getName, method.getName(), "methodName"); EqualFeatureMatcher> parameterMatcher = - new EqualFeatureMatcher<>((m) -> m.getInputParameters().getNodes().stream().map(DataFlowNode::getName).collect(Collectors.toList()), - method.getInputParameters().getNodes().stream().map(DataFlowNode::getName).collect(Collectors.toList()), "methodParameters"); + new EqualFeatureMatcher<>((m) -> m.getParameters().getNodes().stream().map(DataFlowNode::getName).collect(Collectors.toList()), + method.getParameters().getNodes().stream().map(DataFlowNode::getName).collect(Collectors.toList()), "methodParameters"); return Matchers.allOf(methodNameMatcher, parameterMatcher); } diff --git a/src/test/java/factory/MethodNodeHandlerTest.java b/src/test/java/factory/MethodNodeHandlerTest.java index a6a28c2..dd3826f 100644 --- a/src/test/java/factory/MethodNodeHandlerTest.java +++ b/src/test/java/factory/MethodNodeHandlerTest.java @@ -78,7 +78,7 @@ public void testHandleMethodCallExpr_inputMethod() { Assert.assertTrue(resultNode.isPresent()); Assert.assertEquals(returnNode, resultNode.get()); Assert.assertEquals(methodCall, method.getNode(sbUsage).getNodeCall().get()); - Assert.assertTrue(method.getNodeCalls().isEmpty()); + Assert.assertEquals(Arrays.asList(methodCall), method.getNodeCalls()); } @Test @@ -102,7 +102,7 @@ public void testHandleMethodCallExpr_outputMethod() { Assert.assertTrue(resultNode.isPresent()); Assert.assertEquals(returnNode, resultNode.get()); Assert.assertEquals(methodCall, method.getNode(sbUsage).getNodeCall().get()); - Assert.assertTrue(method.getNodeCalls().isEmpty()); + Assert.assertEquals(Arrays.asList(methodCall), method.getNodeCalls()); } @Test @@ -131,7 +131,7 @@ public void testHandleMethodCallExpr_methodConcatenation() { Assert.assertEquals(dfnCharrAt, resultNode.get()); Assert.assertEquals(appendCall, method.getNode(instance).getNodeCall().get()); Assert.assertEquals(charrAtCall, method.getNode(append).getNodeCall().get()); - Assert.assertTrue(method.getNodeCalls().isEmpty()); + Assert.assertEquals(Arrays.asList(appendCall, charrAtCall), method.getNodeCalls()); } private void mockNodeCallFactory(DataFlowMethod method, MethodCallExpr node, Node instance, NodeCall methodCall) { diff --git a/src/test/java/model/DataFlowMethodTest.java b/src/test/java/model/DataFlowMethodTest.java index df9db3a..f791533 100644 --- a/src/test/java/model/DataFlowMethodTest.java +++ b/src/test/java/model/DataFlowMethodTest.java @@ -45,7 +45,7 @@ public class DataFlowMethodTest { public void testDataFlowMethod_minimum() { DataFlowMethod dataFlowMethod = DataFlowMethod.builder().build(); - Assert.assertNull("Unexpected inputParameters", dataFlowMethod.getInputParameters()); + Assert.assertNull("Unexpected inputParameters", dataFlowMethod.getParameters()); Assert.assertTrue("Unexpected inputFields", dataFlowMethod.getInputFields().isEmpty()); Assert.assertTrue("Unexpected changedFields", dataFlowMethod.getChangedFields().isEmpty()); } @@ -54,7 +54,7 @@ public void testDataFlowMethod_minimum() { public void testDataFlowMethod_maximum() { DataFlowMethod dataFlowMethod = createAndFillBuilder().build(); - Assert.assertEquals("Unexpected inputParameters", INPUT_PARAMETERS, dataFlowMethod.getInputParameters()); + Assert.assertEquals("Unexpected inputParameters", INPUT_PARAMETERS, dataFlowMethod.getParameters()); Assert.assertEquals("Unexpected inputFields", INPUT_FIELDS, dataFlowMethod.getInputFields()); Assert.assertEquals("Unexpected changedFields", CHANGED_FIELDS, dataFlowMethod.getChangedFields()); } diff --git a/src/test/java/model/DataFlowNodeTest.java b/src/test/java/model/DataFlowNodeTest.java index 6b75b4f..6a5f459 100644 --- a/src/test/java/model/DataFlowNodeTest.java +++ b/src/test/java/model/DataFlowNodeTest.java @@ -106,6 +106,38 @@ public void testHashCode_Different() { verifyHashCode_Different(DataFlowNode.Builder::out, Collections.singletonList(DataFlowEdge.builder().build())); } + @Test + public void testCollectNodeCalls_empty() { + Assert.assertTrue(DataFlowNode.builder().build().collectNodeCalls(x -> true).isEmpty()); + } + + @Test + public void testCollectNodeCalls() { + DataFlowNode n3 = DataFlowNode.builder().nodeCall(NodeCall.builder().build()).build(); + DataFlowNode n2 = DataFlowNode.builder().out(DataFlowEdge.builder().to(n3).build()).build(); + DataFlowNode n1 = DataFlowNode.builder().out(DataFlowEdge.builder().to(n2).build()).nodeCall(NodeCall.builder().build()).build(); + + Assert.assertEquals(2, n1.collectNodeCalls(x -> true).size()); + } + + @Test + public void testCollectNodeCalls_predicate() { + DataFlowNode n3 = DataFlowNode.builder().nodeCall(NodeCall.builder().build()).build(); + DataFlowNode n2 = DataFlowNode.builder().out(DataFlowEdge.builder().to(n3).build()).build(); + DataFlowNode n1 = DataFlowNode.builder().out(DataFlowEdge.builder().to(n2).build()).nodeCall(NodeCall.builder().build()).build(); + + Assert.assertEquals(1, n1.collectNodeCalls(x -> !x.equals(n3)).size()); + } + + @Test + public void testCollectNodeCalls_predicateFalseForFirst() { + DataFlowNode n3 = DataFlowNode.builder().nodeCall(NodeCall.builder().build()).build(); + DataFlowNode n2 = DataFlowNode.builder().out(DataFlowEdge.builder().to(n3).build()).build(); + DataFlowNode n1 = DataFlowNode.builder().out(DataFlowEdge.builder().to(n2).build()).nodeCall(NodeCall.builder().build()).build(); + + Assert.assertEquals(0, n1.collectNodeCalls(x -> !x.equals(n1)).size()); + } + /** * Assert that the names and all incoming and outgoing edges are equal, regardless of the order. * diff --git a/src/test/java/util/GraphUtilTest.java b/src/test/java/util/GraphUtilTest.java index 977d3a6..8d1405d 100644 --- a/src/test/java/util/GraphUtilTest.java +++ b/src/test/java/util/GraphUtilTest.java @@ -42,7 +42,7 @@ public void testWalkBackUntil_simple() { DataFlowGraph graph = GraphBuilder.withStartingNodes(NodeBuilder.ofParameter("setS", "a").to("setS.a").to("setS.b").to(NodeBuilder.ofField("s"))).build(); DataFlowMethod m = graph.getMethods().iterator().next(); DataFlowNode node = m.getChangedFields().get(0); - DataFlowNode expected = m.getInputParameters().getNodes().get(0); + DataFlowNode expected = m.getParameters().getNodes().get(0); List result = GraphUtil.walkBackUntil(node, m::isInputBoundary, graph::owns); Assert.assertEquals(Collections.singletonList(expected), result); @@ -52,7 +52,7 @@ public void testWalkBackUntil_simple() { public void testWalkBackUntil_inputIsBoundaryNode() { DataFlowGraph graph = GraphBuilder.withStartingNodes(NodeBuilder.ofParameter("setS", "a").to("setS.a").to("setS.b").to(NodeBuilder.ofField("s"))).build(); DataFlowMethod m = graph.getMethods().iterator().next(); - DataFlowNode expected = m.getInputParameters().getNodes().get(0); + DataFlowNode expected = m.getParameters().getNodes().get(0); List result = GraphUtil.walkBackUntil(expected, m::isInputBoundary, graph::owns); Assert.assertEquals(Collections.singletonList(expected), result); @@ -69,7 +69,7 @@ public void testWalkBackUntil_multipleOutput() { DataFlowGraph graph = withStartingNodes.build(); DataFlowMethod m = graph.getMethods().iterator().next(); DataFlowNode node = m.getChangedFields().get(0); - List parameters = m.getInputParameters().getNodes(); + List parameters = m.getParameters().getNodes(); List result = GraphUtil.walkBackUntil(node, m::isInputBoundary, graph::owns); Assert.assertEquals(Arrays.asList(parameters.get(0), parameters.get(1)), result); From b09400c5186033c041b84ae3cd32d3a08e22e366 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2020 17:40:25 +0000 Subject: [PATCH 2/9] Bump junit from 4.12 to 4.13.1 Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9a9d85c..4784ad0 100644 --- a/pom.xml +++ b/pom.xml @@ -140,7 +140,7 @@ junit junit - 4.12 + 4.13.1 test From 33c68eaa97a7a24ab68fef68a40864f254e0284c Mon Sep 17 00:00:00 2001 From: Daan van den Heuvel Date: Wed, 14 Oct 2020 08:40:34 +0200 Subject: [PATCH 3/9] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8ef8e4d..3ebd93f 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,8 @@ A DataFlowGraph represents a single class. Now if we want to gather all input nodes to this class that can influence the output of the method "getA", we can do that as given below. First get the given method. Now we need to walk back until we reach a node that is an input parameter of a method, for this we can use the method DataFlowNode::isInputParameter. -For this example we don't want to go outside this class so we add dfg::owns as scope to the method walkBackUntil. -The scope determines when to stop walking over the nodes, this can become important multiple data flow graphs are connected to each other. +For this example we don't want to go outside of this class so we add dfg::owns as scope to the method walkBackUntil. +The scope determines when to stop walking over the nodes, this can become important if multiple data flow graphs are connected to each other. However, this is currently not supported yet. DataFlowMethod getA = dfg.getMethods().stream().filter(m -> m.getName().equals("getA")).findFirst().get(); @@ -76,4 +76,4 @@ Add the dependency below to the pom of your project. ## License -JavaDataFlow is available under the terms of the Apache License. http://www.apache.org/licenses/LICENSE-2.0 \ No newline at end of file +JavaDataFlow is available under the terms of the Apache License. http://www.apache.org/licenses/LICENSE-2.0 From 37862e5276ab241031f4755a188aa1af666fc247 Mon Sep 17 00:00:00 2001 From: Daan van den Heuvel Date: Thu, 10 Feb 2022 17:22:29 +0100 Subject: [PATCH 4/9] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 3ebd93f..5e0640a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Join the chat at https://gitter.im/JavaDataFlow/community](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/JavaDataFlow/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + # JavaDataFlow Creating Data Flow Graphs from java input classes From aee27aca58382737c8792e39e19cc420c604a8d8 Mon Sep 17 00:00:00 2001 From: Daan van den Heuvel Date: Thu, 10 Mar 2022 17:04:51 +0100 Subject: [PATCH 5/9] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e0640a..57ca51f 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ However, this is currently not supported yet. List inputNodes = getA.getReturnNode().get().walkBackUntil(DataFlowNode::isInputParameter, dfg::owns); System.out.println(inputNodes.get(0).getName()); -The above code will output the name "inputA". +The above code will output the name "inputA". All code above is also given in an [example project](https://github.com/daanvdh/JavaDataFlowExample). ## Setup Add the dependency below to the pom of your project. @@ -55,7 +55,7 @@ Add the dependency below to the pom of your project. com.github.daanvdh.javadataflow JavaDataFlow - 0.0.2 + 0.0.3 ## Definitions From 47b5a1ce7595628e4ff289a5a97dc065b175a5a5 Mon Sep 17 00:00:00 2001 From: Daan van den Heuvel Date: Thu, 10 Mar 2022 17:30:05 +0100 Subject: [PATCH 6/9] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c34815f..ce596e4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [![Join the chat at https://gitter.im/JavaDataFlow/community](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/JavaDataFlow/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Maven Central](https://img.shields.io/maven-central/v/com.github.javaparser/javaparser-core.svg)](https://search.maven.org/search?q=g:com.github.daanvdh.javadataflow) # JavaDataFlow Creating Data Flow Graphs from java input classes From 535e0d1a06a8cf66b57a7a3d6316d108b8406f80 Mon Sep 17 00:00:00 2001 From: Daan van den Heuvel Date: Thu, 10 Mar 2022 17:52:31 +0100 Subject: [PATCH 7/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce596e4..20b5192 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![Join the chat at https://gitter.im/JavaDataFlow/community](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/JavaDataFlow/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Maven Central](https://img.shields.io/maven-central/v/com.github.javaparser/javaparser-core.svg)](https://search.maven.org/search?q=g:com.github.daanvdh.javadataflow) +[![maven-central](https://img.shields.io/maven-central/v/com.github.daanvdh.javadataflow/JavaDataFlow.svg)](https://search.maven.org/search?q=g:com.github.daanvdh.javadataflow) # JavaDataFlow Creating Data Flow Graphs from java input classes From e6d6d05840deb2e3d5bdf63434279a07d60fce2c Mon Sep 17 00:00:00 2001 From: "daan.vandenheuvel" Date: Tue, 22 Mar 2022 14:05:13 +0100 Subject: [PATCH 8/9] Bump JP version --- README.md | 6 ++--- pom.xml | 4 +-- .../java/factory/DataFlowNodeFactory.java | 9 ++++--- src/main/java/factory/MethodNodeHandler.java | 26 +++++++++---------- src/main/java/util/ParserUtil.java | 6 ++--- 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index a2c1b55..6eff6a5 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ A DataFlowGraph represents a single class. String input = "/relativePath/Example.java"; StaticJavaDataFlow.getConfig().setProjectPaths(projectPath); DataFlowGraph dfg = JavaDataFlow.create(projectPath + input); - + Now if we want to gather all input nodes to this class that can influence the output of the method "getA", we can do that as given below. First get the given method. Now we need to walk back until we reach a node that is an input parameter of a method, for this we can use the method DataFlowNode::isInputParameter. @@ -46,7 +46,7 @@ However, this is currently not supported yet. DataFlowMethod getA = dfg.getMethods().stream().filter(m -> m.getName().equals("getA")).findFirst().get(); List inputNodes = getA.getReturnNode().get().walkBackUntil(DataFlowNode::isInputParameter, dfg::owns); System.out.println(inputNodes.get(0).getName()); - + The above code will output the name "inputA". ## Setup @@ -55,7 +55,7 @@ Add the dependency below to the pom of your project. com.github.daanvdh.javadataflow JavaDataFlow - 0.0.4 + 0.0.5 ## Definitions diff --git a/pom.xml b/pom.xml index a86caa2..962a3f2 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.github.daanvdh.javadataflow JavaDataFlow - 0.0.4 + 0.0.5 jar JavaDataFlow @@ -154,7 +154,7 @@ com.github.javaparser javaparser-symbol-solver-core - 3.15.4 + 3.24.0 diff --git a/src/main/java/factory/DataFlowNodeFactory.java b/src/main/java/factory/DataFlowNodeFactory.java index 03cf8fc..613d66e 100644 --- a/src/main/java/factory/DataFlowNodeFactory.java +++ b/src/main/java/factory/DataFlowNodeFactory.java @@ -21,9 +21,10 @@ import org.slf4j.LoggerFactory; import com.github.javaparser.ast.Node; +import com.github.javaparser.ast.expr.SimpleName; import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; import com.github.javaparser.ast.stmt.ReturnStmt; -import com.github.javaparser.printer.Printable; +import com.github.javaparser.printer.Stringable; import model.DataFlowNode; import model.OwnedNode; @@ -45,8 +46,10 @@ public DataFlowNode create(Node n, OwnedNode owner) { if (nodeWithName instanceof NodeWithSimpleName) { builder.name(((NodeWithSimpleName) nodeWithName).getNameAsString()); - } else if (nodeWithName instanceof Printable) { - builder.name(((Printable) nodeWithName).asString()); + } else if (nodeWithName instanceof Stringable) { + builder.name(((Stringable) nodeWithName).asString()); + } else if (nodeWithName instanceof SimpleName) { + builder.name(((SimpleName) nodeWithName).asString()); } else { LOG.warn("Not supported to add a name to a created DataFlowNode for node of type {}, input node is {}", n.getClass(), n); } diff --git a/src/main/java/factory/MethodNodeHandler.java b/src/main/java/factory/MethodNodeHandler.java index 01b73b0..444c0a9 100644 --- a/src/main/java/factory/MethodNodeHandler.java +++ b/src/main/java/factory/MethodNodeHandler.java @@ -268,30 +268,30 @@ private Optional handleAssignExpr(DataFlowGraph graph, DataFlowMet return Optional.of(flowNode); } - /** - * TODO javadoc - * - * @param graph - * @param method - * @param overwriddenValues - * @param node - * @return - */ private Optional getDataFlowNode(DataFlowGraph graph, DataFlowMethod method, Map overwriddenValues, Node node) { Optional optionalResolvedNode = parserUtil.getJavaParserNode(method, node); DataFlowNode flowNode = null; if (optionalResolvedNode.isPresent()) { Node resolvedNode = optionalResolvedNode.get(); - flowNode = overwriddenValues.get(resolvedNode); - flowNode = flowNode != null ? flowNode : graph.getNode(resolvedNode); - flowNode = flowNode != null ? flowNode : method.getNode(resolvedNode); + flowNode = getLastFlowNode(graph, method, overwriddenValues, resolvedNode); + flowNode = (flowNode != null && !(resolvedNode instanceof VariableDeclarationExpr)) ? flowNode + : ((VariableDeclarationExpr) resolvedNode).getVariables().stream().map(child -> getLastFlowNode(graph, method, overwriddenValues, child)) + .filter(n -> n != null).findFirst().orElse(null); } if (flowNode == null) { - LOG.warn("In method {} did not resolve the type of node {} of type {}", method.getName(), node, node.getClass()); + LOG.warn("In method {} did not resolve the type of node {} of type {}, resolvedNode was {}", method.getName(), node, node.getClass(), + optionalResolvedNode); } return Optional.ofNullable(flowNode); } + private DataFlowNode getLastFlowNode(DataFlowGraph graph, DataFlowMethod method, Map overwriddenValues, Node resolvedNode) { + DataFlowNode flowNode = overwriddenValues.get(resolvedNode); + flowNode = flowNode != null ? flowNode : method.getNode(resolvedNode); + flowNode = flowNode != null ? flowNode : graph.getNode(resolvedNode); + return flowNode; + } + private String nameForInBetweenNode(DataFlowMethod method, Map overriddenValues, Node realAssignedJP, NodeWithSimpleName nodeWithName) { String namePostFix = ""; diff --git a/src/main/java/util/ParserUtil.java b/src/main/java/util/ParserUtil.java index bd14933..fe5afeb 100644 --- a/src/main/java/util/ParserUtil.java +++ b/src/main/java/util/ParserUtil.java @@ -34,7 +34,7 @@ import com.github.javaparser.resolution.Resolvable; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserFieldDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserParameterDeclaration; -import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration; +import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserVariableDeclaration; import com.google.common.util.concurrent.UncheckedExecutionException; import model.DataFlowMethod; @@ -58,8 +58,8 @@ public Optional getJavaParserNode(DataFlowMethod method, Node node) { resolvedNode = ((JavaParserFieldDeclaration) resolved).getVariableDeclarator(); } else if (resolved instanceof JavaParserParameterDeclaration) { resolvedNode = ((JavaParserParameterDeclaration) resolved).getWrappedNode(); - } else if (resolved instanceof JavaParserSymbolDeclaration) { - resolvedNode = ((JavaParserSymbolDeclaration) resolved).getWrappedNode(); + } else if (resolved instanceof JavaParserVariableDeclaration) { + resolvedNode = ((JavaParserVariableDeclaration) resolved).getWrappedNode(); } else { LOG.warn("In method {}, resolving is not supported for node {} of type {}", method.getName(), node, resolved == null ? null : resolved.getClass()); } From 8961addb4d28b5b0884f1cc5874422ef7ff01bed Mon Sep 17 00:00:00 2001 From: "daan.vandenheuvel" Date: Tue, 22 Mar 2022 14:22:38 +0100 Subject: [PATCH 9/9] fix class cast exception in mvn --- src/main/java/factory/MethodNodeHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/factory/MethodNodeHandler.java b/src/main/java/factory/MethodNodeHandler.java index 444c0a9..c6127a4 100644 --- a/src/main/java/factory/MethodNodeHandler.java +++ b/src/main/java/factory/MethodNodeHandler.java @@ -274,7 +274,7 @@ private Optional getDataFlowNode(DataFlowGraph graph, DataFlowMeth if (optionalResolvedNode.isPresent()) { Node resolvedNode = optionalResolvedNode.get(); flowNode = getLastFlowNode(graph, method, overwriddenValues, resolvedNode); - flowNode = (flowNode != null && !(resolvedNode instanceof VariableDeclarationExpr)) ? flowNode + flowNode = (flowNode != null || !(resolvedNode instanceof VariableDeclarationExpr)) ? flowNode : ((VariableDeclarationExpr) resolvedNode).getVariables().stream().map(child -> getLastFlowNode(graph, method, overwriddenValues, child)) .filter(n -> n != null).findFirst().orElse(null); }