Skip to content

Commit 6bf5efe

Browse files
authored
use chained implicits, in order to let go of .start (#1007)
* WIP * WIP: works for Expression.file * refactor, add typeDecl * more steps * WIP - probably want to revert * Revert "WIP - probably want to revert" This reverts commit e7e46e4. * fix test * literal * identifier * more implicits, refactor * more * more * more * call is also an expression - make implicits unique * more * remove many .start usages and trim imports * also chain cfgNode implicits: needed to make some implicits lower priority * remove superfluous steps which used to use .start and now led to recursive loop * remove more recursive loops * remove (almost) all .start invocations and (now) superfluous extension methods * format
1 parent 2bf6074 commit 6bf5efe

32 files changed

Lines changed: 295 additions & 222 deletions

File tree

dataflowengineoss/src/main/scala/io/shiftleft/dataflowengineoss/dotgenerator/DdgGenerator.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import io.shiftleft.codepropertygraph.generated.{EdgeKeys, EdgeTypes, nodes}
44
import io.shiftleft.dataflowengineoss.semanticsloader.Semantics
55
import io.shiftleft.semanticcpg.dotgenerator.DotSerializer.{Edge, Graph}
66
import overflowdb.Node
7-
import overflowdb.traversal._
87
import io.shiftleft.semanticcpg.language._
98
import io.shiftleft.dataflowengineoss.language._
9+
import overflowdb.traversal.jIteratortoTraversal
1010

1111
import scala.collection.mutable
1212

@@ -18,7 +18,7 @@ class DdgGenerator {
1818
def generate(methodNode: nodes.Method)(implicit semantics: Semantics): Graph = {
1919
val entryNode = methodNode
2020
val paramNodes = methodNode.parameter.l
21-
val allOtherNodes = methodNode.start.cfgNode.l
21+
val allOtherNodes = methodNode.cfgNode.l
2222
val exitNode = methodNode.methodReturn
2323
val allNodes: List[nodes.StoredNode] = List(entryNode, exitNode) ++ paramNodes ++ allOtherNodes
2424
val visibleNodes = allNodes.filter(shouldBeDisplayed)
@@ -39,16 +39,15 @@ class DdgGenerator {
3939
e.copy(src = surroundingCall(e.src), dst = surroundingCall(e.dst))
4040
}
4141
.filter(e => e.src != e.dst)
42-
.dedup
43-
.l
42+
.distinct
4443

4544
edgeCache.clear
4645
Graph(ddgNodes, ddgEdges)
4746
}
4847

4948
private def surroundingCall(node: nodes.StoredNode): nodes.StoredNode = {
5049
node match {
51-
case arg: nodes.Expression => arg.start.inCall.headOption.getOrElse(node)
50+
case arg: nodes.Expression => arg.inCall.headOption.getOrElse(node)
5251
case _ => node
5352
}
5453
}

dataflowengineoss/src/main/scala/io/shiftleft/dataflowengineoss/language/Path.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.shiftleft.dataflowengineoss.language
22

33
import io.shiftleft.codepropertygraph.generated.nodes
4-
import overflowdb.traversal._
54
import overflowdb.traversal.help.Table
65
import io.shiftleft.semanticcpg.language._
76

@@ -16,7 +15,7 @@ object Path {
1615
val method = trackingPoint.method
1716
val methodName = method.name
1817
val lineNumber = trackingPoint.cfgNode.lineNumber.getOrElse("N/A").toString
19-
val fileName = method.start.file.name.headOption.getOrElse("N/A")
18+
val fileName = method.file.name.headOption.getOrElse("N/A")
2019

2120
val trackedSymbol = trackingPoint match {
2221
case _: nodes.MethodParameterIn =>

dataflowengineoss/src/main/scala/io/shiftleft/dataflowengineoss/language/nodemethods/ExpressionMethods.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package io.shiftleft.dataflowengineoss.language.nodemethods
22

33
import io.shiftleft.codepropertygraph.generated.nodes
44
import io.shiftleft.dataflowengineoss.semanticsloader.{FlowSemantic, Semantics}
5-
import io.shiftleft.semanticcpg.language.{NoResolve, toExpression}
6-
import overflowdb.traversal.NodeOps
5+
import io.shiftleft.semanticcpg.language._
6+
import overflowdb.traversal.Traversal
77

88
class ExpressionMethods[NodeType <: nodes.Expression](val node: NodeType) extends AnyVal {
99

@@ -28,15 +28,15 @@ class ExpressionMethods[NodeType <: nodes.Expression](val node: NodeType) extend
2828
/**
2929
* Retrieve flow semantic for the call this argument is a part of.
3030
* */
31-
def semanticsForCallByArg(implicit semantics: Semantics): List[FlowSemantic] = {
31+
def semanticsForCallByArg(implicit semantics: Semantics): Traversal[FlowSemantic] = {
3232
argToMethods(node).flatMap { method =>
3333
semantics.forMethod(method.fullName)
3434
}
3535
}
3636

37-
private def argToMethods(arg: nodes.Expression): List[nodes.Method] = {
38-
arg.start.inCall.l.flatMap { call =>
39-
NoResolve.getCalledMethods(call).toList
37+
private def argToMethods(arg: nodes.Expression): Traversal[nodes.Method] = {
38+
arg.inCall.flatMap { call =>
39+
NoResolve.getCalledMethods(call)
4040
}
4141
}
4242

dataflowengineoss/src/main/scala/io/shiftleft/dataflowengineoss/language/package.scala

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ package object language {
1616
implicit def expressionMethods[NodeType <: nodes.Expression](node: NodeType): ExpressionMethods[NodeType] =
1717
new ExpressionMethods(node)
1818

19-
implicit def toTrackingPoint[NodeType <: nodes.TrackingPointBase](traversal: Traversal[NodeType]): TrackingPoint =
20-
new TrackingPoint(traversal.cast[nodes.TrackingPoint])
19+
implicit def toTrackingPoint[A, NodeType <: nodes.TrackingPointBase](a: A)(
20+
implicit f: A => Traversal[NodeType]): TrackingPoint =
21+
new TrackingPoint(f(a).cast[nodes.TrackingPoint])
2122

2223
implicit def trackingPointToAstNodeMethods(node: nodes.TrackingPoint) =
2324
new AstNodeMethods(trackingPointToAstNode(node))
@@ -28,10 +29,11 @@ package object language {
2829
case _ => ??? //TODO markus/fabs?
2930
}
3031

31-
implicit def trackingPointToAstBase(trav: Traversal[nodes.TrackingPoint]): AstNode[nodes.AstNode] =
32-
new AstNode(trav.map(trackingPointToAstNode))
32+
implicit def trackingPointToAstBase[A](a: A)(
33+
implicit f: A => Traversal[nodes.TrackingPoint]): AstNode[nodes.AstNode] =
34+
new AstNode(f(a).map(trackingPointToAstNode))
3335

34-
implicit def toDdgNodeDot(trav: Traversal[nodes.Method]): DdgNodeDot =
35-
new DdgNodeDot(trav)
36+
implicit def toDdgNodeDot[A](a: A)(implicit f: A => Traversal[nodes.Method]): DdgNodeDot =
37+
new DdgNodeDot(f(a))
3638

3739
}

dataflowengineoss/src/main/scala/io/shiftleft/dataflowengineoss/layers/dataflows/DumpCpg14.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import better.files.File
44
import io.shiftleft.codepropertygraph.Cpg
55
import io.shiftleft.semanticcpg.language._
66
import io.shiftleft.semanticcpg.layers.{LayerCreator, LayerCreatorContext, LayerCreatorOptions}
7-
import overflowdb.traversal._
87
import io.shiftleft.dataflowengineoss.language._
98
import io.shiftleft.dataflowengineoss.semanticsloader.Semantics
109

@@ -27,7 +26,7 @@ class DumpCpg14(options: Cpg14DumpOptions)(implicit semantics: Semantics) extend
2726
val cpg = context.cpg
2827
cpg.method.zipWithIndex.foreach {
2928
case (method, i) =>
30-
val str = method.start.dotCpg14.head
29+
val str = method.dotCpg14.head
3130
(File(options.outDir) / s"${i}-cpg.dot").write(str)
3231
}
3332
}

dataflowengineoss/src/main/scala/io/shiftleft/dataflowengineoss/layers/dataflows/DumpDdg.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import better.files.File
44
import io.shiftleft.codepropertygraph.Cpg
55
import io.shiftleft.semanticcpg.language._
66
import io.shiftleft.semanticcpg.layers.{LayerCreator, LayerCreatorContext, LayerCreatorOptions}
7-
import overflowdb.traversal._
87
import io.shiftleft.dataflowengineoss.language._
98
import io.shiftleft.dataflowengineoss.semanticsloader.Semantics
109

@@ -27,7 +26,7 @@ class DumpDdg(options: DdgDumpOptions)(implicit semantics: Semantics) extends La
2726
val cpg = context.cpg
2827
cpg.method.zipWithIndex.foreach {
2928
case (method, i) =>
30-
val str = method.start.dotDdg.head
29+
val str = method.dotDdg.head
3130
(File(options.outDir) / s"${i}-ddg.dot").write(str)
3231
}
3332
}

dataflowengineoss/src/main/scala/io/shiftleft/dataflowengineoss/layers/dataflows/DumpPdg.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import better.files.File
44
import io.shiftleft.codepropertygraph.Cpg
55
import io.shiftleft.semanticcpg.language._
66
import io.shiftleft.semanticcpg.layers.{LayerCreator, LayerCreatorContext, LayerCreatorOptions}
7-
import overflowdb.traversal._
87
import io.shiftleft.dataflowengineoss.language._
98
import io.shiftleft.dataflowengineoss.semanticsloader.Semantics
109

@@ -27,7 +26,7 @@ class DumpPdg(options: PdgDumpOptions)(implicit semantics: Semantics) extends La
2726
val cpg = context.cpg
2827
cpg.method.zipWithIndex.foreach {
2928
case (method, i) =>
30-
val str = method.start.dotPdg.head
29+
val str = method.dotPdg.head
3130
(File(options.outDir) / s"${i}-pdg.dot").write(str)
3231
}
3332
}

dataflowengineoss/src/main/scala/io/shiftleft/dataflowengineoss/passes/reachingdef/ReachingDefPass.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import io.shiftleft.codepropertygraph.Cpg
44
import io.shiftleft.codepropertygraph.generated.{nodes, _}
55
import io.shiftleft.passes.{DiffGraph, ParallelCpgPass}
66
import io.shiftleft.semanticcpg.language._
7-
import overflowdb.traversal._
87

98
/**
109
* A pass that calculates reaching definitions ("data dependencies").
@@ -79,7 +78,7 @@ class ReachingDefPass(cpg: Cpg) extends ParallelCpgPass[nodes.Method](cpg) {
7978
}
8079

8180
case methodReturn: nodes.MethodReturn =>
82-
methodReturn.start.cfgPrev.isReturn.foreach { ret =>
81+
methodReturn.cfgPrev.isReturn.foreach { ret =>
8382
addEdge(ret, methodReturn, "<RET>")
8483
}
8584

dataflowengineoss/src/main/scala/io/shiftleft/dataflowengineoss/passes/reachingdef/ReachingDefProblem.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ package io.shiftleft.dataflowengineoss.passes.reachingdef
22

33
import io.shiftleft.codepropertygraph.generated.nodes
44
import io.shiftleft.semanticcpg.accesspath.{AccessPath, MatchResult, TrackedBase}
5-
import io.shiftleft.semanticcpg.language.nodemethods.TrackingPointMethodsBase.ImplicitsAPI
65
import io.shiftleft.semanticcpg.language._
6+
import io.shiftleft.semanticcpg.language.nodemethods.TrackingPointMethodsBase.ImplicitsAPI
77
import org.slf4j.{Logger, LoggerFactory}
8+
import overflowdb.traversal._
89

910
import scala.jdk.CollectionConverters._
10-
import overflowdb.traversal._
1111

1212
object Definition {
1313

@@ -49,8 +49,8 @@ class ReachingDefFlowGraph(method: nodes.Method) extends FlowGraph {
4949
private def initSucc(ns: List[nodes.StoredNode]): Map[nodes.StoredNode, List[nodes.StoredNode]] = {
5050
ns.map {
5151
case n @ (ret: nodes.Return) => n -> List(ret.method.methodReturn)
52-
case n @ (cfgNode: nodes.CfgNode) => n -> cfgNode.start.cfgNext.l
53-
case n @ (param: nodes.MethodParameterIn) => n -> param.start.method.cfgFirst.l
52+
case n @ (cfgNode: nodes.CfgNode) => n -> cfgNode.cfgNext.l
53+
case n @ (param: nodes.MethodParameterIn) => n -> param.method.cfgFirst.l
5454
case n =>
5555
logger.warn(s"Node type ${n.getClass.getSimpleName} should not be part of the CFG");
5656
n -> List()
@@ -63,9 +63,9 @@ class ReachingDefFlowGraph(method: nodes.Method) extends FlowGraph {
6363
private def initPred(ns: List[nodes.StoredNode],
6464
method: nodes.Method): Map[nodes.StoredNode, List[nodes.StoredNode]] = {
6565
ns.map {
66-
case n @ (_: nodes.CfgNode) if method.start.cfgFirst.headOption.contains(n) =>
66+
case n @ (_: nodes.CfgNode) if method.cfgFirst.headOption.contains(n) =>
6767
n -> method.parameter.l.sortBy(_.order).lastOption.toList
68-
case n @ (cfgNode: nodes.CfgNode) => n -> cfgNode.start.cfgPrev.l
68+
case n @ (cfgNode: nodes.CfgNode) => n -> cfgNode.cfgPrev.l
6969
case n @ (_: nodes.MethodParameterIn) => n -> List(method)
7070
case n =>
7171
logger.warn(s"Node type ${n.getClass.getSimpleName} should not be part of the CFG");
@@ -97,17 +97,17 @@ class ReachingDefTransferFunction(method: nodes.Method) extends TransferFunction
9797
def initGen(method: nodes.Method): Map[nodes.StoredNode, Set[Definition]] = {
9898

9999
def defsMadeByCall(call: nodes.Call): Set[Definition] = {
100-
(Set(call) ++ call.start.argument.toSet
100+
(Set(call) ++ call.start.argument
101101
.filterNot(_.isInstanceOf[nodes.Literal])
102102
.filterNot(_.isInstanceOf[nodes.FieldIdentifier]))
103103
.map(x => Definition.fromNode(x.asInstanceOf[nodes.StoredNode]))
104104
}
105105

106-
val defsForParams = method.start.parameter.l.map { param =>
106+
val defsForParams = method.parameter.l.map { param =>
107107
param -> Set(Definition.fromNode(param.asInstanceOf[nodes.StoredNode]))
108108
}
109109

110-
val defsForCalls = method.start.call.l.map { call =>
110+
val defsForCalls = method.call.l.map { call =>
111111
call -> defsMadeByCall(call)
112112
}
113113

@@ -121,7 +121,7 @@ class ReachingDefTransferFunction(method: nodes.Method) extends TransferFunction
121121
def initKill(method: nodes.Method,
122122
gen: Map[nodes.StoredNode, Set[Definition]]): Map[nodes.StoredNode, Set[Definition]] = {
123123

124-
val baseToCalls: Map[TrackedBase, List[(nodes.Call, AccessPath)]] = method.start.call.l
124+
val baseToCalls: Map[TrackedBase, List[(nodes.Call, AccessPath)]] = method.call.l
125125
.map { call =>
126126
val (base, path) = call.trackedBaseAndAccessPath
127127
(base, (call, path))
@@ -153,7 +153,7 @@ class ReachingDefTransferFunction(method: nodes.Method) extends TransferFunction
153153

154154
// We are also adding nodes here that may not even be definitions, but that's
155155
// fine since `kill` is only subtracted
156-
method.start.call.map { call =>
156+
method.call.map { call =>
157157
val killedDefs = gen(call)
158158
.map { d =>
159159
allOtherInstancesOf(d.node)

dataflowengineoss/src/main/scala/io/shiftleft/dataflowengineoss/queryengine/Engine.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ object Engine {
168168
private def elemForArgument(e: Edge, curNode: nodes.Expression)(
169169
implicit semantics: Semantics): Option[PathElement] = {
170170
val parentNode = e.outNode().asInstanceOf[nodes.Expression]
171-
val parentNodeCall = parentNode.start.inCall.l
172-
val sameCallSite = parentNode.start.inCall.l == curNode.start.inCall.l
171+
val parentNodeCall = parentNode.inCall.l
172+
val sameCallSite = parentNode.inCall.l == curNode.start.inCall.l
173173

174174
if (sameCallSite && parentNode.isUsed && curNode.isDefined ||
175175
!sameCallSite && curNode.isUsed) {
@@ -189,7 +189,7 @@ object Engine {
189189
}
190190

191191
def argToMethods(arg: nodes.Expression): List[nodes.Method] = {
192-
arg.start.inCall.l.flatMap { call =>
192+
arg.inCall.l.flatMap { call =>
193193
methodsForCall(call)
194194
}
195195
}

0 commit comments

Comments
 (0)