diff --git a/README.md b/README.md index 5e0640a..f439d73 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.daanvdh.javadataflow/JavaDataFlow.svg)](https://search.maven.org/search?q=g:com.github.daanvdh.javadataflow) # JavaDataFlow Creating Data Flow Graphs from java input classes @@ -9,6 +10,8 @@ Nodes are always defined within a specific method, constructor, codeBlock. We refer to such a code block as owner. Every Node has an owner. Every owner can also have an owner, for instance a method is owned by a class. +To make it possible to only parse a part of an application we model calls to a method and the dataflow inside the method itself separately. +At any moment the flow through a method can be linked to a call to that method to follow the flow of data though multiple methods or classes. ## Example @@ -35,7 +38,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,8 +49,8 @@ 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". + +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,19 +58,33 @@ Add the dependency below to the pom of your project. com.github.daanvdh.javadataflow JavaDataFlow - 0.0.2 + 0.0.5 - ## Definitions -- The owner of a DataFlowNode represents structure in which the node is defined. + +- Any **object or primitive** is modelled as a DataFlowNode. + A DataFlowNode can have 0 or more input or output DataFlowEdge's. + Such an edge represents a data flow from one node to another. +- The **owner** of a DataFlowNode represents structure in which the node is defined. For the method setA, the parameter inputA has a ParameterList as input. The ParameterList has the DataFlowMethod for "setA" as owner. The owner of the method is the DataFlowGraph representing Example.java +- Each **usage of an object** is modelled as a separate DataFlowNode. + A DataFlowNode representing the usage of an earlier defined object will contain an edge as input from either the last usage before that or the definition of the object. + This way the order in which a node was used is maintained. +- A NodeCall represents a **call to another code block**, for instance a method call. + If a NodeCall was called directly on an object, that object will be modelled as a DataFlowNode and the NodeCall will have a reference to that DataFlowNode via NodeCall::getInstance. + That same DataFlowNode will then have a reference to the NodeCall via DataFlowNode::getNodeCall. + A DataFlowNode can only have a single NodeCall, since every object usage is modelled as a separate node. + If a NodeCall was not directly called on an object, it can be found via DataFlowMethod::getNodeCalls on the method in which the NodeCall was done. + ## Features - 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/pom.xml b/pom.xml index 4784ad0..97d0b23 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.github.daanvdh.javadataflow JavaDataFlow - 0.0.3 + 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 b69b49b..c6127a4 100644 --- a/src/main/java/factory/MethodNodeHandler.java +++ b/src/main/java/factory/MethodNodeHandler.java @@ -166,7 +166,11 @@ private Optional handleMethodCallExpr(DataFlowGraph graph, DataFlo } calledMethod.setIn(params.build()); + 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. return calledMethod.getReturnNode(); @@ -264,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/factory/NodeCallFactory.java b/src/main/java/factory/NodeCallFactory.java index daaa2b0..3732ad8 100644 --- a/src/main/java/factory/NodeCallFactory.java +++ b/src/main/java/factory/NodeCallFactory.java @@ -68,9 +68,8 @@ public Optional create(OwnedNode owner, MethodCallExpr node, DataFl } private NodeCall createMethodCall(OwnedNode owner, ResolvedMethodLikeDeclaration resolved, MethodCallExpr node, DataFlowNode instance) { - NodeCall methodCall = - NodeCall.builder().name(resolved.getName()).claz(resolved.getClassName()).peckage(resolved.getPackageName()).owner(owner).representedNode(node).build(); - methodCall.setInstance(instance); + NodeCall methodCall = NodeCall.builder().name(resolved.getName()).claz(resolved.getClassName()).peckage(resolved.getPackageName()).owner(owner) + .representedNode(node).instance(instance).build(); setReturn(methodCall, owner, node, resolved); return methodCall; } diff --git a/src/main/java/model/DataFlowMethod.java b/src/main/java/model/DataFlowMethod.java index b84cce6..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; } @@ -180,7 +180,8 @@ public void addChangedFields(DataFlowNode... fields) { } /** - * @return List of {@link DataFlowMethod}s containing both the input and output methods. + * @return List of {@link NodeCall}s representing the method calls that where not called directly on an object, for instance static or methods from within the + * same class. */ public List getNodeCalls() { return this.nodeCalls; diff --git a/src/main/java/model/DataFlowNode.java b/src/main/java/model/DataFlowNode.java index 16089ec..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; @@ -56,6 +58,13 @@ public class DataFlowNode extends OwnedNode { */ private OwnedNode owner; + /** + * If a method was called on the current {@link DataFlowNode} this {@link NodeCall} will represent that NodeCall. Each {@link DataFlowNode} can only have a + * single nodeCall, since each usage of a single variable is modeled to be a separate dataFlowNode. All method called on a given dataFlowNode can be collected + * by walking through the graph. This value will be null if no method was called. + */ + private NodeCall nodeCall; + public DataFlowNode(Node representedNode) { super(representedNode); } @@ -72,6 +81,7 @@ private DataFlowNode(Builder builder) { this.out.addAll(builder.out); this.setType(builder.type); this.owner = builder.owner; + this.nodeCall = builder.nodeCall; } public List getIn() { @@ -104,6 +114,14 @@ public void setType(String type) { this.type = type; } + public Optional getNodeCall() { + return Optional.ofNullable(nodeCall); + } + + public void setNodeCall(NodeCall nodeCall) { + this.nodeCall = nodeCall; + } + public boolean isField() { return this.getOwner().map(DataFlowGraph.class::isInstance).orElse(false); } @@ -124,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. @@ -241,6 +278,7 @@ public static final class Builder extends NodeRepresenter.Builder in = new ArrayList<>(); private List out = new ArrayList<>(); private String type; + private NodeCall nodeCall; private Builder() { // Builder should only be constructed via the parent class @@ -258,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; @@ -268,6 +312,11 @@ public Builder owner(OwnedNode owner) { return this; } + public Builder nodeCall(NodeCall nodeCall) { + this.nodeCall = nodeCall; + return this; + } + public DataFlowNode build() { return new DataFlowNode(this); } diff --git a/src/main/java/model/NodeCall.java b/src/main/java/model/NodeCall.java index 08e8c9e..015bf17 100644 --- a/src/main/java/model/NodeCall.java +++ b/src/main/java/model/NodeCall.java @@ -76,6 +76,7 @@ private NodeCall(Builder builder) { this.claz = builder.claz == null ? this.claz : builder.claz; this.peckage = builder.peckage == null ? this.peckage : builder.peckage; this.returnNode = builder.returnNode == null ? this.returnNode : builder.returnNode; + this.instance = builder.instance == null ? this.instance : builder.instance; } @Override @@ -98,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); @@ -199,6 +200,7 @@ public static final class Builder extends NodeRepresenter.Builder 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()); } 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 ef77d93..dd3826f 100644 --- a/src/test/java/factory/MethodNodeHandlerTest.java +++ b/src/test/java/factory/MethodNodeHandlerTest.java @@ -36,8 +36,6 @@ import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.expr.NameExpr; -import factory.MethodNodeHandler; -import factory.NodeCallFactory; import model.DataFlowGraph; import model.DataFlowMethod; import model.DataFlowNode; @@ -72,11 +70,14 @@ public void testHandleMethodCallExpr_inputMethod() { NodeCall methodCall = NodeCall.builder().in(ParameterList.builder().nodes(Arrays.asList(DataFlowNode.builder().name("param1").build())).build()) .returnNode(returnNode).build(); DataFlowMethod method = DataFlowMethod.builder().build(); - mockNodeCallFactory(method, node, cu.findAll(NameExpr.class).get(0), methodCall); + NameExpr sbUsage = cu.findAll(NameExpr.class).get(0); + mockNodeCallFactory(method, node, sbUsage, methodCall); Optional resultNode = execute(node, method); Assert.assertTrue(resultNode.isPresent()); + Assert.assertEquals(returnNode, resultNode.get()); + Assert.assertEquals(methodCall, method.getNode(sbUsage).getNodeCall().get()); Assert.assertEquals(Arrays.asList(methodCall), method.getNodeCalls()); } @@ -93,11 +94,14 @@ public void testHandleMethodCallExpr_outputMethod() { NodeCall methodCall = NodeCall.builder().in(ParameterList.builder().nodes(Arrays.asList(DataFlowNode.builder().name("param1").build())).build()) .returnNode(returnNode).build(); DataFlowMethod method = DataFlowMethod.builder().build(); - mockNodeCallFactory(method, node, cu.findAll(NameExpr.class).get(0), methodCall); + NameExpr sbUsage = cu.findAll(NameExpr.class).get(0); + mockNodeCallFactory(method, node, sbUsage, methodCall); Optional resultNode = execute(node, method); Assert.assertTrue(resultNode.isPresent()); + Assert.assertEquals(returnNode, resultNode.get()); + Assert.assertEquals(methodCall, method.getNode(sbUsage).getNodeCall().get()); Assert.assertEquals(Arrays.asList(methodCall), method.getNodeCalls()); } @@ -124,6 +128,9 @@ public void testHandleMethodCallExpr_methodConcatenation() { Optional resultNode = execute(charrAt, method); Assert.assertTrue(resultNode.isPresent()); + Assert.assertEquals(dfnCharrAt, resultNode.get()); + Assert.assertEquals(appendCall, method.getNode(instance).getNodeCall().get()); + Assert.assertEquals(charrAtCall, method.getNode(append).getNodeCall().get()); Assert.assertEquals(Arrays.asList(appendCall, charrAtCall), method.getNodeCalls()); } 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);