diff --git a/dataflowengineoss/build.sbt b/dataflowengineoss/build.sbt index 07167eecd7c1..ea00f783fa71 100644 --- a/dataflowengineoss/build.sbt +++ b/dataflowengineoss/build.sbt @@ -1,6 +1,6 @@ name := "dataflowengineoss" -dependsOn(Projects.semanticcpg, Projects.x2cpg) +dependsOn(Projects.semanticcpg, Projects.x2cpg % "compile->compile;test->test") libraryDependencies ++= Seq( "org.antlr" % "antlr4-runtime" % Versions.antlr, diff --git a/dataflowengineoss/src/test/scala/io/joern/dataflowengineoss/testfixtures/SemanticTestCpg.scala b/dataflowengineoss/src/test/scala/io/joern/dataflowengineoss/testfixtures/SemanticTestCpg.scala new file mode 100644 index 000000000000..f2a68aa35341 --- /dev/null +++ b/dataflowengineoss/src/test/scala/io/joern/dataflowengineoss/testfixtures/SemanticTestCpg.scala @@ -0,0 +1,52 @@ +package io.joern.dataflowengineoss.testfixtures + +import io.joern.dataflowengineoss.DefaultSemantics +import io.joern.dataflowengineoss.layers.dataflows.{OssDataFlow, OssDataFlowOptions} +import io.joern.dataflowengineoss.queryengine.EngineContext +import io.joern.dataflowengineoss.semanticsloader.{FlowSemantic, Semantics} +import io.joern.x2cpg.testfixtures.TestCpg +import io.shiftleft.semanticcpg.layers.LayerCreatorContext + +/** Extends the capabilities of the test CPG to handle the configuration of data-flow enhancements. + */ +trait SemanticTestCpg { this: TestCpg => + + protected var _withOssDataflow = false + protected var _extraFlows = List.empty[FlowSemantic] + protected implicit var context: EngineContext = EngineContext() + + /** Allows one to enable data-flow analysis capabilities to the TestCpg. + */ + def withOssDataflow(value: Boolean = true): this.type = { + _withOssDataflow = value + this + } + + /** Allows one to add additional semantics to the engine context during PDG creation. + */ + def withExtraFlows(value: List[FlowSemantic] = List.empty): this.type = { + _extraFlows = value + this + } + + /** Some frontends require OSS data-flow to execute after post-processing, so we choose to expose this method without + * defining where it's executed. + */ + def applyOssDataFlow(): Unit = { + if (_withOssDataflow) { + val context = new LayerCreatorContext(this) + val options = new OssDataFlowOptions(extraFlows = _extraFlows) + new OssDataFlow(options).run(context) + this.context = EngineContext(Semantics.fromList(DefaultSemantics().elements ++ _extraFlows)) + } + } + +} + +/** Allows the tests to make use of the data-flow engine and any additional semantics. + */ +trait SemanticCpgTestFixture(extraFlows: List[FlowSemantic] = List.empty) { + + implicit val context: EngineContext = EngineContext(Semantics.fromList(DefaultSemantics().elements ++ extraFlows)) + +} diff --git a/joern-cli/frontends/c2cpg/build.sbt b/joern-cli/frontends/c2cpg/build.sbt index 7c17e5ef91b1..86872b25bd4d 100644 --- a/joern-cli/frontends/c2cpg/build.sbt +++ b/joern-cli/frontends/c2cpg/build.sbt @@ -1,6 +1,6 @@ name := "c2cpg" -dependsOn(Projects.semanticcpg, Projects.dataflowengineoss % Test, Projects.x2cpg % "compile->compile;test->test") +dependsOn(Projects.semanticcpg, Projects.dataflowengineoss % "compile->compile;test->test", Projects.x2cpg % "compile->compile;test->test") libraryDependencies ++= Seq( "org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.4", diff --git a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/testfixtures/CCodeToCpgSuite.scala b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/testfixtures/CCodeToCpgSuite.scala index e831feb126d1..21e369ec43db 100644 --- a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/testfixtures/CCodeToCpgSuite.scala +++ b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/testfixtures/CCodeToCpgSuite.scala @@ -1,11 +1,12 @@ package io.joern.c2cpg.testfixtures import better.files.File -import io.joern.c2cpg.{C2Cpg, Config} import io.joern.c2cpg.parser.FileDefaults +import io.joern.c2cpg.{C2Cpg, Config} +import io.joern.dataflowengineoss.semanticsloader.FlowSemantic +import io.joern.dataflowengineoss.testfixtures.{SemanticCpgTestFixture, SemanticTestCpg} import io.joern.x2cpg.testfixtures.{Code2CpgFixture, DefaultTestCpg, LanguageFrontend} import io.shiftleft.codepropertygraph.Cpg -import org.scalatest.Inside trait C2CpgFrontend extends LanguageFrontend { def execute(sourceCodePath: java.io.File): Cpg = { @@ -23,8 +24,18 @@ trait C2CpgFrontend extends LanguageFrontend { } } -class DefaultTestCpgWithC(val fileSuffix: String) extends DefaultTestCpg with C2CpgFrontend +class DefaultTestCpgWithC(val fileSuffix: String) extends DefaultTestCpg with C2CpgFrontend with SemanticTestCpg { + override protected def applyPasses(): Unit = { + super.applyPasses() + applyOssDataFlow() + } +} -class CCodeToCpgSuite(fileSuffix: String = FileDefaults.C_EXT) - extends Code2CpgFixture(() => new DefaultTestCpgWithC(fileSuffix)) - with Inside +class CCodeToCpgSuite( + fileSuffix: String = FileDefaults.C_EXT, + withOssDataflow: Boolean = false, + extraFlows: List[FlowSemantic] = List.empty +) extends Code2CpgFixture(() => + new DefaultTestCpgWithC(fileSuffix).withOssDataflow(withOssDataflow).withExtraFlows(extraFlows) + ) + with SemanticCpgTestFixture(extraFlows) diff --git a/joern-cli/frontends/csharpsrc2cpg/build.sbt b/joern-cli/frontends/csharpsrc2cpg/build.sbt index cb67ad0c8825..499ea6892393 100644 --- a/joern-cli/frontends/csharpsrc2cpg/build.sbt +++ b/joern-cli/frontends/csharpsrc2cpg/build.sbt @@ -7,7 +7,7 @@ import scala.util.Try name := "csharpsrc2cpg" -dependsOn(Projects.dataflowengineoss, Projects.x2cpg % "compile->compile;test->test") +dependsOn(Projects.dataflowengineoss % "compile->compile;test->test", Projects.x2cpg % "compile->compile;test->test") lazy val appProperties = settingKey[Config]("App Properties") appProperties := { diff --git a/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/utils/DotNetAstGenRunner.scala b/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/utils/DotNetAstGenRunner.scala index 53f95dc12a91..b920c0d0cfff 100644 --- a/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/utils/DotNetAstGenRunner.scala +++ b/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/utils/DotNetAstGenRunner.scala @@ -18,6 +18,9 @@ class DotNetAstGenRunner(config: Config) extends AstGenRunnerBase(config) { private val logger = LoggerFactory.getLogger(getClass) + // The x86 variant seems to run well enough on MacOS M-family chips, whereas the ARM build crashes + override val MacArm: String = MacX86 + override def fileFilter(file: String, out: File): Boolean = { file.stripSuffix(".json").replace(out.pathAsString, config.inputPath) match { case filePath if isIgnoredByUserConfig(filePath) => false diff --git a/joern-cli/frontends/csharpsrc2cpg/src/test/scala/io/joern/csharpsrc2cpg/testfixtures/CSharpCode2CpgFixture.scala b/joern-cli/frontends/csharpsrc2cpg/src/test/scala/io/joern/csharpsrc2cpg/testfixtures/CSharpCode2CpgFixture.scala index 25aa2edfe4ac..c3bdcb5aec81 100644 --- a/joern-cli/frontends/csharpsrc2cpg/src/test/scala/io/joern/csharpsrc2cpg/testfixtures/CSharpCode2CpgFixture.scala +++ b/joern-cli/frontends/csharpsrc2cpg/src/test/scala/io/joern/csharpsrc2cpg/testfixtures/CSharpCode2CpgFixture.scala @@ -2,21 +2,28 @@ package io.joern.csharpsrc2cpg.testfixtures import io.joern.csharpsrc2cpg.{CSharpSrc2Cpg, Config} import io.joern.dataflowengineoss.language.Path -import io.joern.dataflowengineoss.layers.dataflows.{OssDataFlow, OssDataFlowOptions} -import io.joern.dataflowengineoss.queryengine.EngineContext -import io.joern.x2cpg.{ValidationMode, X2Cpg} +import io.joern.dataflowengineoss.semanticsloader.FlowSemantic +import io.joern.dataflowengineoss.testfixtures.{SemanticCpgTestFixture, SemanticTestCpg} import io.joern.x2cpg.testfixtures.{Code2CpgFixture, DefaultTestCpg, LanguageFrontend} +import io.joern.x2cpg.{ValidationMode, X2Cpg} import io.shiftleft.codepropertygraph.generated.Cpg import io.shiftleft.semanticcpg.language.{ICallResolver, NoResolve} -import io.shiftleft.semanticcpg.layers.LayerCreatorContext import java.io.File -class CSharpCode2CpgFixture(withPostProcessing: Boolean = false, withDataFlow: Boolean = false) - extends Code2CpgFixture(() => new DefaultTestCpgWithCSharp(withPostProcessing, withDataFlow)) { +class CSharpCode2CpgFixture( + withPostProcessing: Boolean = false, + withDataFlow: Boolean = false, + extraFlows: List[FlowSemantic] = List.empty +) extends Code2CpgFixture(() => + new DefaultTestCpgWithCSharp() + .withOssDataflow(withDataFlow) + .withExtraFlows(extraFlows) + .withPostProcessingPasses(withPostProcessing) + ) + with SemanticCpgTestFixture(extraFlows) { - implicit val resolver: ICallResolver = NoResolve - implicit lazy val engineContext: EngineContext = EngineContext() + implicit val resolver: ICallResolver = NoResolve protected def flowToResultPairs(path: Path): List[(String, Integer)] = path.resultPairs().collect { case (firstElement: String, secondElement: Option[Integer]) => @@ -45,22 +52,11 @@ class CSharpCode2CpgFixture(withPostProcessing: Boolean = false, withDataFlow: B |""".stripMargin } -class DefaultTestCpgWithCSharp(withPostProcessing: Boolean, withDataFlow: Boolean) - extends DefaultTestCpg - with CSharpFrontend { - - override def applyPasses(): Unit = { - X2Cpg.applyDefaultOverlays(this) +class DefaultTestCpgWithCSharp extends DefaultTestCpg with CSharpFrontend with SemanticTestCpg { - if (withPostProcessing) { - CSharpSrc2Cpg.postProcessingPasses(this, config).foreach(_.createAndApply()) - } - - if (withDataFlow) { - val context = new LayerCreatorContext(this) - val options = new OssDataFlowOptions() - new OssDataFlow(options).run(context) - } + override def applyPostProcessingPasses(): Unit = { + CSharpSrc2Cpg.postProcessingPasses(this, config).foreach(_.createAndApply()) + super.applyPostProcessingPasses() } } diff --git a/joern-cli/frontends/gosrc2cpg/build.sbt b/joern-cli/frontends/gosrc2cpg/build.sbt index a40a1680c235..3cfce5fd88e8 100644 --- a/joern-cli/frontends/gosrc2cpg/build.sbt +++ b/joern-cli/frontends/gosrc2cpg/build.sbt @@ -5,7 +5,7 @@ import com.typesafe.config.{Config, ConfigFactory} name := "gosrc2cpg" -dependsOn(Projects.dataflowengineoss, Projects.x2cpg % "compile->compile;test->test") +dependsOn(Projects.dataflowengineoss % "compile->compile;test->test", Projects.x2cpg % "compile->compile;test->test") libraryDependencies ++= Seq( "io.shiftleft" %% "codepropertygraph" % Versions.cpg, diff --git a/joern-cli/frontends/gosrc2cpg/src/test/scala/io/joern/go2cpg/testfixtures/GoCodeToCpgSuite.scala b/joern-cli/frontends/gosrc2cpg/src/test/scala/io/joern/go2cpg/testfixtures/GoCodeToCpgSuite.scala index 4c3a423b0ece..112206c8868d 100644 --- a/joern-cli/frontends/gosrc2cpg/src/test/scala/io/joern/go2cpg/testfixtures/GoCodeToCpgSuite.scala +++ b/joern-cli/frontends/gosrc2cpg/src/test/scala/io/joern/go2cpg/testfixtures/GoCodeToCpgSuite.scala @@ -1,15 +1,13 @@ package io.joern.go2cpg.testfixtures import better.files.File -import io.joern.dataflowengineoss.layers.dataflows.{OssDataFlow, OssDataFlowOptions} -import io.joern.dataflowengineoss.queryengine.EngineContext -import io.joern.gosrc2cpg.datastructures.GoGlobal +import io.joern.dataflowengineoss.semanticsloader.FlowSemantic +import io.joern.dataflowengineoss.testfixtures.{SemanticCpgTestFixture, SemanticTestCpg} import io.joern.gosrc2cpg.{Config, GoSrc2Cpg} import io.joern.x2cpg.X2Cpg import io.joern.x2cpg.testfixtures.{Code2CpgFixture, DefaultTestCpg, LanguageFrontend} import io.shiftleft.codepropertygraph.Cpg import io.shiftleft.semanticcpg.language.{ICallResolver, NoResolve} -import io.shiftleft.semanticcpg.layers.LayerCreatorContext import org.scalatest.Inside trait Go2CpgFrontend extends LanguageFrontend { def execute(sourceCodePath: java.io.File): Cpg = { @@ -25,29 +23,22 @@ trait Go2CpgFrontend extends LanguageFrontend { } } -class DefaultTestCpgWithGo(val fileSuffix: String) extends DefaultTestCpg with Go2CpgFrontend { - - private var _withOssDataflow = false - - def withOssDataflow(value: Boolean = true): this.type = { - _withOssDataflow = value - this - } - - override def applyPasses(): Unit = { - X2Cpg.applyDefaultOverlays(this) - if (_withOssDataflow) { - val context = new LayerCreatorContext(this) - val options = new OssDataFlowOptions() - new OssDataFlow(options).run(context) - } +class DefaultTestCpgWithGo(val fileSuffix: String) extends DefaultTestCpg with Go2CpgFrontend with SemanticTestCpg { + override protected def applyPasses(): Unit = { + super.applyPasses() + applyOssDataFlow() } } -class GoCodeToCpgSuite(fileSuffix: String = ".go", withOssDataflow: Boolean = false) - extends Code2CpgFixture(() => new DefaultTestCpgWithGo(fileSuffix).withOssDataflow(withOssDataflow)) +class GoCodeToCpgSuite( + fileSuffix: String = ".go", + withOssDataflow: Boolean = false, + extraFlows: List[FlowSemantic] = List.empty +) extends Code2CpgFixture(() => + new DefaultTestCpgWithGo(fileSuffix).withOssDataflow(withOssDataflow).withExtraFlows(extraFlows) + ) + with SemanticCpgTestFixture(extraFlows) with Inside { - implicit val resolver: ICallResolver = NoResolve - implicit lazy val engineContext: EngineContext = EngineContext() + implicit val resolver: ICallResolver = NoResolve } diff --git a/joern-cli/frontends/javasrc2cpg/build.sbt b/joern-cli/frontends/javasrc2cpg/build.sbt index 863af1e809bb..8176528df43d 100644 --- a/joern-cli/frontends/javasrc2cpg/build.sbt +++ b/joern-cli/frontends/javasrc2cpg/build.sbt @@ -1,6 +1,6 @@ name := "javasrc2cpg" -dependsOn(Projects.dataflowengineoss, Projects.x2cpg % "compile->compile;test->test") +dependsOn(Projects.dataflowengineoss % "compile->compile;test->test", Projects.x2cpg % "compile->compile;test->test") libraryDependencies ++= Seq( "io.shiftleft" %% "codepropertygraph" % Versions.cpg, diff --git a/joern-cli/frontends/javasrc2cpg/src/test/scala/io/joern/javasrc2cpg/testfixtures/JavaSrcCodeToCpgFixture.scala b/joern-cli/frontends/javasrc2cpg/src/test/scala/io/joern/javasrc2cpg/testfixtures/JavaSrcCodeToCpgFixture.scala index f10697533e79..c1d4e5dea77d 100644 --- a/joern-cli/frontends/javasrc2cpg/src/test/scala/io/joern/javasrc2cpg/testfixtures/JavaSrcCodeToCpgFixture.scala +++ b/joern-cli/frontends/javasrc2cpg/src/test/scala/io/joern/javasrc2cpg/testfixtures/JavaSrcCodeToCpgFixture.scala @@ -1,15 +1,14 @@ package io.joern.javasrc2cpg.testfixtures -import io.joern.dataflowengineoss.layers.dataflows.{OssDataFlow, OssDataFlowOptions} import io.joern.dataflowengineoss.queryengine.EngineContext +import io.joern.dataflowengineoss.semanticsloader.FlowSemantic +import io.joern.dataflowengineoss.testfixtures.{SemanticCpgTestFixture, SemanticTestCpg} import io.joern.javasrc2cpg.{Config, JavaSrc2Cpg} import io.joern.x2cpg.X2Cpg -import io.joern.x2cpg.testfixtures.{Code2CpgFixture, LanguageFrontend, TestCpg} +import io.joern.x2cpg.testfixtures.{Code2CpgFixture, DefaultTestCpg, LanguageFrontend, TestCpg} import io.shiftleft.codepropertygraph.Cpg -import io.shiftleft.codepropertygraph.generated.PropertyNames -import io.shiftleft.codepropertygraph.generated.nodes.{Expression, Literal, StoredNode} +import io.shiftleft.codepropertygraph.generated.nodes.{Expression, Literal} import io.shiftleft.semanticcpg.language.* -import io.shiftleft.semanticcpg.layers.LayerCreatorContext import java.io.File @@ -23,31 +22,29 @@ trait JavaSrcFrontend extends LanguageFrontend { } } -class JavaSrcTestCpg(enableTypeRecovery: Boolean = false) extends TestCpg with JavaSrcFrontend { - private var _withOssDataflow = false +class JavaSrcTestCpg(enableTypeRecovery: Boolean = false) + extends DefaultTestCpg + with JavaSrcFrontend + with SemanticTestCpg { - def withOssDataflow(value: Boolean = true): this.type = { - _withOssDataflow = value - this - } - - override def applyPasses(): Unit = { - X2Cpg.applyDefaultOverlays(this) + override protected def applyPasses(): Unit = { + super.applyPasses() if (enableTypeRecovery) JavaSrc2Cpg.typeRecoveryPasses(this).foreach(_.createAndApply()) - if (_withOssDataflow) { - val context = new LayerCreatorContext(this) - val options = new OssDataFlowOptions() - new OssDataFlow(options).run(context) - } + applyOssDataFlow() } } -class JavaSrcCode2CpgFixture(withOssDataflow: Boolean = false, enableTypeRecovery: Boolean = false) - extends Code2CpgFixture(() => new JavaSrcTestCpg(enableTypeRecovery).withOssDataflow(withOssDataflow)) { +class JavaSrcCode2CpgFixture( + withOssDataflow: Boolean = false, + extraFlows: List[FlowSemantic] = List.empty, + enableTypeRecovery: Boolean = false +) extends Code2CpgFixture(() => + new JavaSrcTestCpg(enableTypeRecovery).withOssDataflow(withOssDataflow).withExtraFlows(extraFlows) + ) + with SemanticCpgTestFixture(extraFlows) { - implicit val resolver: ICallResolver = NoResolve - implicit lazy val engineContext: EngineContext = EngineContext() + implicit val resolver: ICallResolver = NoResolve def getConstSourceSink( cpg: Cpg, diff --git a/joern-cli/frontends/jimple2cpg/build.sbt b/joern-cli/frontends/jimple2cpg/build.sbt index 339822ec2f87..57124460b50f 100644 --- a/joern-cli/frontends/jimple2cpg/build.sbt +++ b/joern-cli/frontends/jimple2cpg/build.sbt @@ -1,6 +1,6 @@ name := "jimple2cpg" -dependsOn(Projects.dataflowengineoss, Projects.x2cpg % "compile->compile;test->test") +dependsOn(Projects.dataflowengineoss % "compile->compile;test->test", Projects.x2cpg % "compile->compile;test->test") libraryDependencies ++= Seq( "io.shiftleft" %% "codepropertygraph" % Versions.cpg, diff --git a/joern-cli/frontends/jimple2cpg/src/test/scala/io/joern/jimple2cpg/testfixtures/JimpleCodeToCpgFixture.scala b/joern-cli/frontends/jimple2cpg/src/test/scala/io/joern/jimple2cpg/testfixtures/JimpleCodeToCpgFixture.scala index 10b32feeaf02..c39e37c1c621 100644 --- a/joern-cli/frontends/jimple2cpg/src/test/scala/io/joern/jimple2cpg/testfixtures/JimpleCodeToCpgFixture.scala +++ b/joern-cli/frontends/jimple2cpg/src/test/scala/io/joern/jimple2cpg/testfixtures/JimpleCodeToCpgFixture.scala @@ -1,9 +1,10 @@ package io.joern.jimple2cpg.testfixtures -import better.files.File as BFile +import io.joern.dataflowengineoss.semanticsloader.FlowSemantic +import io.joern.dataflowengineoss.testfixtures.{SemanticCpgTestFixture, SemanticTestCpg} import io.joern.jimple2cpg.{Config, Jimple2Cpg} import io.joern.x2cpg.X2Cpg -import io.joern.x2cpg.testfixtures.{Code2CpgFixture, LanguageFrontend, TestCpg} +import io.joern.x2cpg.testfixtures.{Code2CpgFixture, DefaultTestCpg, LanguageFrontend, TestCpg} import io.shiftleft.codepropertygraph.Cpg import java.io.File @@ -22,16 +23,20 @@ trait Jimple2CpgFrontend extends LanguageFrontend { } } -class JimpleCode2CpgFixture() extends Code2CpgFixture(() => new JimpleTestCpg()) {} +class JimpleCode2CpgFixture(withOssDataflow: Boolean = false, extraFlows: List[FlowSemantic] = List.empty) + extends Code2CpgFixture(() => new JimpleTestCpg().withOssDataflow(withOssDataflow).withExtraFlows(extraFlows)) + with SemanticCpgTestFixture(extraFlows) {} -class JimpleTestCpg() extends TestCpg with Jimple2CpgFrontend { +class JimpleTestCpg extends DefaultTestCpg with Jimple2CpgFrontend with SemanticTestCpg { + + override protected def applyPasses(): Unit = { + super.applyPasses() + applyOssDataFlow() + } override protected def codeDirPreProcessing(rootFile: Path, codeFiles: List[Path]): Unit = JimpleCodeToCpgFixture.compileJava(rootFile, codeFiles.map(_.toFile)) - override protected def applyPasses(): Unit = { - X2Cpg.applyDefaultOverlays(this) - } } object JimpleCodeToCpgFixture { diff --git a/joern-cli/frontends/jssrc2cpg/build.sbt b/joern-cli/frontends/jssrc2cpg/build.sbt index 52f9a939bcad..9f9173b4ff96 100644 --- a/joern-cli/frontends/jssrc2cpg/build.sbt +++ b/joern-cli/frontends/jssrc2cpg/build.sbt @@ -5,7 +5,7 @@ import com.typesafe.config.{Config, ConfigFactory} name := "jssrc2cpg" -dependsOn(Projects.dataflowengineoss, Projects.x2cpg % "compile->compile;test->test") +dependsOn(Projects.dataflowengineoss % "compile->compile;test->test", Projects.x2cpg % "compile->compile;test->test") lazy val appProperties = settingKey[Config]("App Properties") appProperties := { diff --git a/joern-cli/frontends/jssrc2cpg/src/test/scala/io/joern/jssrc2cpg/testfixtures/JsSrc2CpgFrontend.scala b/joern-cli/frontends/jssrc2cpg/src/test/scala/io/joern/jssrc2cpg/testfixtures/JsSrc2CpgFrontend.scala index 3f247e452b89..070ee0d043d4 100644 --- a/joern-cli/frontends/jssrc2cpg/src/test/scala/io/joern/jssrc2cpg/testfixtures/JsSrc2CpgFrontend.scala +++ b/joern-cli/frontends/jssrc2cpg/src/test/scala/io/joern/jssrc2cpg/testfixtures/JsSrc2CpgFrontend.scala @@ -1,10 +1,12 @@ package io.joern.jssrc2cpg.testfixtures import better.files.File -import io.joern.jssrc2cpg.JsSrc2Cpg -import io.joern.jssrc2cpg.Config -import io.shiftleft.codepropertygraph.Cpg +import io.joern.dataflowengineoss.semanticsloader.FlowSemantic +import io.joern.dataflowengineoss.testfixtures.{SemanticCpgTestFixture, SemanticTestCpg} +import io.joern.jssrc2cpg.{Config, JsSrc2Cpg} +import io.joern.x2cpg.X2Cpg import io.joern.x2cpg.testfixtures.{Code2CpgFixture, DefaultTestCpg, LanguageFrontend} +import io.shiftleft.codepropertygraph.Cpg import org.scalatest.Inside trait JsSrc2CpgFrontend extends LanguageFrontend { @@ -21,8 +23,27 @@ trait JsSrc2CpgFrontend extends LanguageFrontend { } } -class DefaultTestCpgWithJsSrc(val fileSuffix: String) extends DefaultTestCpg with JsSrc2CpgFrontend +class DefaultTestCpgWithJsSrc(val fileSuffix: String) + extends DefaultTestCpg + with JsSrc2CpgFrontend + with SemanticTestCpg { + + override protected def applyPasses(): Unit = { + super.applyPasses() + applyOssDataFlow() + } + + override protected def applyPostProcessingPasses(): Unit = + JsSrc2Cpg.postProcessingPasses(this).foreach(_.createAndApply()) + +} -class JsSrc2CpgSuite(fileSuffix: String = ".js") - extends Code2CpgFixture(() => new DefaultTestCpgWithJsSrc(fileSuffix)) +class JsSrc2CpgSuite( + fileSuffix: String = ".js", + withOssDataflow: Boolean = false, + extraFlows: List[FlowSemantic] = List.empty +) extends Code2CpgFixture(() => + new DefaultTestCpgWithJsSrc(fileSuffix).withOssDataflow(withOssDataflow).withExtraFlows(extraFlows) + ) + with SemanticCpgTestFixture(extraFlows) with Inside diff --git a/joern-cli/frontends/kotlin2cpg/build.sbt b/joern-cli/frontends/kotlin2cpg/build.sbt index 9b3ebc5d6823..4c73205f078f 100644 --- a/joern-cli/frontends/kotlin2cpg/build.sbt +++ b/joern-cli/frontends/kotlin2cpg/build.sbt @@ -3,7 +3,7 @@ name := "kotlin2cpg" val kotlinVersion = "1.9.10" dependsOn( - Projects.dataflowengineoss, + Projects.dataflowengineoss % "compile->compile;test->test", Projects.x2cpg % "compile->compile;test->test", Projects.javasrc2cpg % "compile->compile;test->test" ) diff --git a/joern-cli/frontends/kotlin2cpg/src/main/scala/io/joern/kotlin2cpg/Kotlin2Cpg.scala b/joern-cli/frontends/kotlin2cpg/src/main/scala/io/joern/kotlin2cpg/Kotlin2Cpg.scala index b70b613c2a0d..99d0cb4701c1 100644 --- a/joern-cli/frontends/kotlin2cpg/src/main/scala/io/joern/kotlin2cpg/Kotlin2Cpg.scala +++ b/joern-cli/frontends/kotlin2cpg/src/main/scala/io/joern/kotlin2cpg/Kotlin2Cpg.scala @@ -37,7 +37,7 @@ object Kotlin2Cpg { type InputProvider = () => InputPair def postProcessingPass(cpg: Cpg): Unit = { - new KotlinTypeRecoveryPassGenerator(cpg).generate().map { _.createAndApply() } + new KotlinTypeRecoveryPassGenerator(cpg).generate().foreach(_.createAndApply()) new KotlinTypeHintCallLinker(cpg).createAndApply() } } diff --git a/joern-cli/frontends/kotlin2cpg/src/test/scala/io/joern/kotlin2cpg/testfixtures/KotlinCodeToCpgFixture.scala b/joern-cli/frontends/kotlin2cpg/src/test/scala/io/joern/kotlin2cpg/testfixtures/KotlinCodeToCpgFixture.scala index 73a60ebd1671..0ef23ea8c2f6 100644 --- a/joern-cli/frontends/kotlin2cpg/src/test/scala/io/joern/kotlin2cpg/testfixtures/KotlinCodeToCpgFixture.scala +++ b/joern-cli/frontends/kotlin2cpg/src/test/scala/io/joern/kotlin2cpg/testfixtures/KotlinCodeToCpgFixture.scala @@ -1,13 +1,15 @@ package io.joern.kotlin2cpg.testfixtures -import better.files.{File => BFile} -import io.shiftleft.codepropertygraph.Cpg -import io.joern.dataflowengineoss.language._ +import better.files.File as BFile +import io.joern.dataflowengineoss.language.* import io.joern.dataflowengineoss.layers.dataflows.{OssDataFlow, OssDataFlowOptions} import io.joern.dataflowengineoss.queryengine.EngineContext +import io.joern.dataflowengineoss.semanticsloader.FlowSemantic +import io.joern.dataflowengineoss.testfixtures.{SemanticCpgTestFixture, SemanticTestCpg} import io.joern.kotlin2cpg.{Config, Kotlin2Cpg} import io.joern.x2cpg.X2Cpg -import io.joern.x2cpg.testfixtures.{Code2CpgFixture, LanguageFrontend, TestCpg} +import io.joern.x2cpg.testfixtures.{Code2CpgFixture, DefaultTestCpg, LanguageFrontend, TestCpg} +import io.shiftleft.codepropertygraph.Cpg import io.shiftleft.semanticcpg.layers.LayerCreatorContext import io.shiftleft.utils.ProjectRoot @@ -30,43 +32,32 @@ trait KotlinFrontend extends LanguageFrontend { } } -class KotlinTestCpg(override protected val withTestResourcePaths: Boolean) extends TestCpg with KotlinFrontend { - private var _withOssDataflow = false - private var _withPostProcessing = false +class KotlinTestCpg(override protected val withTestResourcePaths: Boolean) + extends DefaultTestCpg + with KotlinFrontend + with SemanticTestCpg { - def withOssDataflow(value: Boolean = true): this.type = { - _withOssDataflow = value - this - } - def withPostProcessing(value: Boolean = true): this.type = { - _withPostProcessing = value - this + override protected def applyPasses(): Unit = { + super.applyPasses() + applyOssDataFlow() } - override def applyPasses(): Unit = { - X2Cpg.applyDefaultOverlays(this) + override protected def applyPostProcessingPasses(): Unit = Kotlin2Cpg.postProcessingPass(this) - if (_withOssDataflow) { - val context = new LayerCreatorContext(this) - val options = new OssDataFlowOptions() - new OssDataFlow(options).run(context) - } - - if (_withPostProcessing) { - Kotlin2Cpg.postProcessingPass(this) - } - } } class KotlinCode2CpgFixture( withOssDataflow: Boolean = false, withDefaultJars: Boolean = false, - withPostProcessing: Boolean = false + withPostProcessing: Boolean = false, + extraFlows: List[FlowSemantic] = List.empty ) extends Code2CpgFixture(() => - new KotlinTestCpg(withDefaultJars).withOssDataflow(withOssDataflow).withPostProcessing(withPostProcessing) - ) { - - implicit val context: EngineContext = EngineContext() + new KotlinTestCpg(withDefaultJars) + .withOssDataflow(withOssDataflow) + .withExtraFlows(extraFlows) + .withPostProcessingPasses(withPostProcessing) + ) + with SemanticCpgTestFixture(extraFlows) { protected def flowToResultPairs(path: Path): List[(String, Option[Integer])] = path.resultPairs() } diff --git a/joern-cli/frontends/php2cpg/build.sbt b/joern-cli/frontends/php2cpg/build.sbt index f5772906e05b..97eed6ed410d 100644 --- a/joern-cli/frontends/php2cpg/build.sbt +++ b/joern-cli/frontends/php2cpg/build.sbt @@ -10,7 +10,7 @@ val versionedParserBinName = s"php-parser-$phpParserVersion.phar" val phpParserDlUrl = s"https://github.com/joernio/PHP-Parser/releases/download/v$phpParserVersion/$upstreamParserBinName" -dependsOn(Projects.dataflowengineoss, Projects.x2cpg % "compile->compile;test->test") +dependsOn(Projects.dataflowengineoss % "compile->compile;test->test", Projects.x2cpg % "compile->compile;test->test") libraryDependencies ++= Seq( "com.lihaoyi" %% "upickle" % Versions.upickle, diff --git a/joern-cli/frontends/php2cpg/src/test/scala/io/joern/php2cpg/testfixtures/PhpCode2CpgFixture.scala b/joern-cli/frontends/php2cpg/src/test/scala/io/joern/php2cpg/testfixtures/PhpCode2CpgFixture.scala index 15a9c7f3ee50..a5eb2e5d46c3 100644 --- a/joern-cli/frontends/php2cpg/src/test/scala/io/joern/php2cpg/testfixtures/PhpCode2CpgFixture.scala +++ b/joern-cli/frontends/php2cpg/src/test/scala/io/joern/php2cpg/testfixtures/PhpCode2CpgFixture.scala @@ -1,19 +1,13 @@ package io.joern.php2cpg.testfixtures -import io.joern.dataflowengineoss.queryengine.EngineContext +import io.joern.dataflowengineoss.semanticsloader.FlowSemantic +import io.joern.dataflowengineoss.testfixtures.{SemanticCpgTestFixture, SemanticTestCpg} import io.joern.php2cpg.{Config, Php2Cpg} -import io.joern.x2cpg.testfixtures.{Code2CpgFixture, DefaultTestCpg, LanguageFrontend} -import io.joern.x2cpg.passes.frontend.XTypeRecoveryConfig +import io.joern.x2cpg.testfixtures.{Code2CpgFixture, LanguageFrontend, DefaultTestCpg} import io.shiftleft.codepropertygraph.Cpg import io.shiftleft.semanticcpg.language.{ICallResolver, NoResolve} import java.io.File -import io.joern.x2cpg.testfixtures.TestCpg -import io.joern.x2cpg.X2Cpg -import io.shiftleft.semanticcpg.layers.LayerCreatorContext -import io.joern.dataflowengineoss.layers.dataflows.OssDataFlowOptions -import io.joern.dataflowengineoss.layers.dataflows.OssDataFlow -import io.joern.php2cpg.passes.PhpSetKnownTypesPass trait PhpFrontend extends LanguageFrontend { override val fileSuffix: String = ".php" @@ -24,21 +18,28 @@ trait PhpFrontend extends LanguageFrontend { } } -class PhpTestCpg(runOssDataflow: Boolean) extends TestCpg with PhpFrontend { +class PhpTestCpg extends DefaultTestCpg with PhpFrontend with SemanticTestCpg { override protected def applyPasses(): Unit = { - X2Cpg.applyDefaultOverlays(this) - if (runOssDataflow) { - val context = new LayerCreatorContext(this) - val options = new OssDataFlowOptions() - new OssDataFlow(options).run(context) - } - Php2Cpg.postProcessingPasses(this).foreach(_.createAndApply()) + super.applyPasses() + applyOssDataFlow() } + + override protected def applyPostProcessingPasses(): Unit = + Php2Cpg.postProcessingPasses(this).foreach(_.createAndApply()) + } -class PhpCode2CpgFixture(runOssDataflow: Boolean = false) - extends Code2CpgFixture(() => new PhpTestCpg(runOssDataflow)) { - implicit val resolver: ICallResolver = NoResolve - implicit lazy val engineContext: EngineContext = EngineContext() +class PhpCode2CpgFixture( + runOssDataflow: Boolean = false, + extraFlows: List[FlowSemantic] = List.empty, + withPostProcessing: Boolean = true +) extends Code2CpgFixture(() => + new PhpTestCpg() + .withOssDataflow(runOssDataflow) + .withExtraFlows(extraFlows) + .withPostProcessingPasses(withPostProcessing) + ) + with SemanticCpgTestFixture(extraFlows) { + implicit val resolver: ICallResolver = NoResolve } diff --git a/joern-cli/frontends/pysrc2cpg/build.sbt b/joern-cli/frontends/pysrc2cpg/build.sbt index 30dc7d4d7f03..cb9497f777e0 100644 --- a/joern-cli/frontends/pysrc2cpg/build.sbt +++ b/joern-cli/frontends/pysrc2cpg/build.sbt @@ -1,6 +1,6 @@ name := "pysrc2cpg" -dependsOn(Projects.dataflowengineoss, Projects.x2cpg % "compile->compile;test->test") +dependsOn(Projects.dataflowengineoss % "compile->compile;test->test", Projects.x2cpg % "compile->compile;test->test") libraryDependencies ++= Seq( "io.shiftleft" %% "codepropertygraph" % Versions.cpg, diff --git a/joern-cli/frontends/pysrc2cpg/src/test/scala/io/joern/pysrc2cpg/PySrc2CpgFixture.scala b/joern-cli/frontends/pysrc2cpg/src/test/scala/io/joern/pysrc2cpg/PySrc2CpgFixture.scala index 85c164b3e410..b8014344f294 100644 --- a/joern-cli/frontends/pysrc2cpg/src/test/scala/io/joern/pysrc2cpg/PySrc2CpgFixture.scala +++ b/joern-cli/frontends/pysrc2cpg/src/test/scala/io/joern/pysrc2cpg/PySrc2CpgFixture.scala @@ -1,12 +1,14 @@ package io.joern.pysrc2cpg -import io.joern.dataflowengineoss.layers.dataflows.{OssDataFlow, OssDataFlowOptions} +import io.joern.dataflowengineoss.DefaultSemantics +import io.joern.dataflowengineoss.layers.dataflows.* import io.joern.dataflowengineoss.queryengine.EngineContext -import io.joern.dataflowengineoss.semanticsloader.FlowSemantic +import io.joern.dataflowengineoss.semanticsloader.{FlowSemantic, Semantics} +import io.joern.dataflowengineoss.testfixtures.{SemanticCpgTestFixture, SemanticTestCpg} import io.joern.x2cpg.X2Cpg import io.joern.x2cpg.passes.base.AstLinkerPass import io.joern.x2cpg.passes.callgraph.NaiveCallLinker -import io.joern.x2cpg.testfixtures.{Code2CpgFixture, LanguageFrontend, TestCpg} +import io.joern.x2cpg.testfixtures.{Code2CpgFixture, DefaultTestCpg, LanguageFrontend, TestCpg} import io.shiftleft.codepropertygraph.Cpg import io.shiftleft.semanticcpg.language.{ICallResolver, NoResolve} import io.shiftleft.semanticcpg.layers.LayerCreatorContext @@ -15,26 +17,18 @@ trait PythonFrontend extends LanguageFrontend { override val fileSuffix: String = ".py" override def execute(sourceCodePath: java.io.File): Cpg = { - new Py2CpgOnFileSystem().createCpg(sourceCodePath.getAbsolutePath)(new Py2CpgOnFileSystemConfig()).get + new Py2CpgOnFileSystem().createCpg(sourceCodePath.getAbsolutePath)(Py2CpgOnFileSystemConfig()).get } } -class PySrcTestCpg extends TestCpg with PythonFrontend { - private var _withOssDataflow = false - private var _extraFlows = List.empty[FlowSemantic] +class PySrcTestCpg extends DefaultTestCpg with PythonFrontend with SemanticTestCpg { - def withOssDataflow(value: Boolean = true): this.type = { - _withOssDataflow = value - this + override protected def applyPasses(): Unit = { + super.applyPasses() + if (!_withPostProcessing) applyOssDataFlow() } - def withExtraFlows(value: List[FlowSemantic] = List.empty): this.type = { - _extraFlows = value - this - } - - override def applyPasses(): Unit = { - X2Cpg.applyDefaultOverlays(this) + override def applyPostProcessingPasses(): Unit = { new ImportsPass(this).createAndApply() new PythonImportResolverPass(this).createAndApply() new PythonInheritanceNamePass(this).createAndApply() @@ -46,19 +40,23 @@ class PySrcTestCpg extends TestCpg with PythonFrontend { // Some of passes above create new methods, so, we // need to run the ASTLinkerPass one more time new AstLinkerPass(this).createAndApply() - - if (_withOssDataflow) { - val context = new LayerCreatorContext(this) - val options = new OssDataFlowOptions(extraFlows = _extraFlows) - new OssDataFlow(options).run(context) - } + applyOssDataFlow() } + } -class PySrc2CpgFixture(withOssDataflow: Boolean = false, extraFlows: List[FlowSemantic] = List.empty) - extends Code2CpgFixture(() => new PySrcTestCpg().withOssDataflow(withOssDataflow).withExtraFlows(extraFlows)) { +class PySrc2CpgFixture( + withOssDataflow: Boolean = false, + extraFlows: List[FlowSemantic] = List.empty, + withPostProcessing: Boolean = true +) extends Code2CpgFixture(() => + new PySrcTestCpg() + .withOssDataflow(withOssDataflow) + .withExtraFlows(extraFlows) + .withPostProcessingPasses(withPostProcessing) + ) + with SemanticCpgTestFixture(extraFlows) { implicit val resolver: ICallResolver = NoResolve - implicit val context: EngineContext = EngineContext() } diff --git a/joern-cli/frontends/rubysrc2cpg/build.sbt b/joern-cli/frontends/rubysrc2cpg/build.sbt index 539203b1990e..4f440ba2a18d 100644 --- a/joern-cli/frontends/rubysrc2cpg/build.sbt +++ b/joern-cli/frontends/rubysrc2cpg/build.sbt @@ -1,6 +1,6 @@ name := "rubysrc2cpg" -dependsOn(Projects.dataflowengineoss, Projects.x2cpg % "compile->compile;test->test") +dependsOn(Projects.dataflowengineoss % "compile->compile;test->test", Projects.x2cpg % "compile->compile;test->test") libraryDependencies ++= Seq( "io.shiftleft" %% "codepropertygraph" % Versions.cpg, diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/testfixtures/RubyCode2CpgFixture.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/testfixtures/RubyCode2CpgFixture.scala index 264a767ab2cf..f32bc6a20301 100644 --- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/testfixtures/RubyCode2CpgFixture.scala +++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/testfixtures/RubyCode2CpgFixture.scala @@ -1,15 +1,15 @@ package io.joern.rubysrc2cpg.testfixtures import io.joern.dataflowengineoss.language.Path -import io.joern.dataflowengineoss.layers.dataflows.{OssDataFlow, OssDataFlowOptions} import io.joern.dataflowengineoss.queryengine.EngineContext +import io.joern.dataflowengineoss.semanticsloader.FlowSemantic +import io.joern.dataflowengineoss.testfixtures.{SemanticCpgTestFixture, SemanticTestCpg} import io.joern.rubysrc2cpg.deprecated.utils.PackageTable import io.joern.rubysrc2cpg.{Config, RubySrc2Cpg} import io.joern.x2cpg.testfixtures.* import io.joern.x2cpg.{ValidationMode, X2Cpg} import io.shiftleft.codepropertygraph.Cpg import io.shiftleft.semanticcpg.language.{ICallResolver, NoResolve} -import io.shiftleft.semanticcpg.layers.LayerCreatorContext import org.scalatest.Tag import java.io.File @@ -29,31 +29,23 @@ trait RubyFrontend(useDeprecatedFrontend: Boolean) extends LanguageFrontend { } -class DefaultTestCpgWithRuby( - withPostProcessing: Boolean, - withDataFlow: Boolean, - packageTable: Option[PackageTable], - useDeprecatedFrontend: Boolean -) extends DefaultTestCpg - with RubyFrontend(useDeprecatedFrontend) { - - override def applyPasses(): Unit = { - X2Cpg.applyDefaultOverlays(this) +class DefaultTestCpgWithRuby(packageTable: Option[PackageTable], useDeprecatedFrontend: Boolean) + extends DefaultTestCpg + with RubyFrontend(useDeprecatedFrontend) + with SemanticTestCpg { - if (withPostProcessing) { - packageTable match { - case Some(table) => - RubySrc2Cpg.packageTableInfo.set(table) - case None => - } - RubySrc2Cpg.postProcessingPasses(this, config).foreach(_.createAndApply()) - } + override protected def applyPasses(): Unit = { + super.applyPasses() + applyOssDataFlow() + } - if (withDataFlow) { - val context = new LayerCreatorContext(this) - val options = new OssDataFlowOptions() - new OssDataFlow(options).run(context) + override protected def applyPostProcessingPasses(): Unit = { + packageTable match { + case Some(table) => + RubySrc2Cpg.packageTableInfo.set(table) + case None => } + RubySrc2Cpg.postProcessingPasses(this, config).foreach(_.createAndApply()) } } @@ -61,14 +53,18 @@ class DefaultTestCpgWithRuby( class RubyCode2CpgFixture( withPostProcessing: Boolean = false, withDataFlow: Boolean = false, + extraFlows: List[FlowSemantic] = List.empty, packageTable: Option[PackageTable] = None, useDeprecatedFrontend: Boolean = false ) extends Code2CpgFixture(() => - new DefaultTestCpgWithRuby(withPostProcessing, withDataFlow, packageTable, useDeprecatedFrontend) - ) { - - implicit val resolver: ICallResolver = NoResolve - implicit lazy val engineContext: EngineContext = EngineContext() + new DefaultTestCpgWithRuby(packageTable, useDeprecatedFrontend) + .withOssDataflow(withDataFlow) + .withExtraFlows(extraFlows) + .withPostProcessingPasses(withPostProcessing) + ) + with SemanticCpgTestFixture(extraFlows) { + + implicit val resolver: ICallResolver = NoResolve protected def flowToResultPairs(path: Path): List[(String, Integer)] = path.resultPairs().collect { case (firstElement: String, secondElement: Option[Integer]) => diff --git a/joern-cli/frontends/swiftsrc2cpg/build.sbt b/joern-cli/frontends/swiftsrc2cpg/build.sbt index 22140a00ef76..27aabef2b997 100644 --- a/joern-cli/frontends/swiftsrc2cpg/build.sbt +++ b/joern-cli/frontends/swiftsrc2cpg/build.sbt @@ -4,7 +4,7 @@ import com.typesafe.config.{Config, ConfigFactory} name := "swiftsrc2cpg" -dependsOn(Projects.dataflowengineoss, Projects.x2cpg % "compile->compile;test->test") +dependsOn(Projects.dataflowengineoss % "compile->compile;test->test", Projects.x2cpg % "compile->compile;test->test") lazy val appProperties = settingKey[Config]("App Properties") appProperties := { diff --git a/joern-cli/frontends/swiftsrc2cpg/src/test/scala/io/joern/swiftsrc2cpg/testfixtures/SwiftSrc2CpgFrontend.scala b/joern-cli/frontends/swiftsrc2cpg/src/test/scala/io/joern/swiftsrc2cpg/testfixtures/SwiftSrc2CpgFrontend.scala index 3b3df3ce667c..5dc963fb1f18 100644 --- a/joern-cli/frontends/swiftsrc2cpg/src/test/scala/io/joern/swiftsrc2cpg/testfixtures/SwiftSrc2CpgFrontend.scala +++ b/joern-cli/frontends/swiftsrc2cpg/src/test/scala/io/joern/swiftsrc2cpg/testfixtures/SwiftSrc2CpgFrontend.scala @@ -1,10 +1,11 @@ package io.joern.swiftsrc2cpg.testfixtures import better.files.File -import io.joern.swiftsrc2cpg.SwiftSrc2Cpg -import io.joern.swiftsrc2cpg.Config -import io.shiftleft.codepropertygraph.Cpg +import io.joern.dataflowengineoss.semanticsloader.FlowSemantic +import io.joern.dataflowengineoss.testfixtures.SemanticTestCpg +import io.joern.swiftsrc2cpg.{Config, SwiftSrc2Cpg} import io.joern.x2cpg.testfixtures.{Code2CpgFixture, DefaultTestCpg, LanguageFrontend} +import io.shiftleft.codepropertygraph.Cpg import org.scalatest.Inside trait SwiftSrc2CpgFrontend extends LanguageFrontend { @@ -20,8 +21,27 @@ trait SwiftSrc2CpgFrontend extends LanguageFrontend { } } -class DefaultTestCpgWithSwiftSrc(val fileSuffix: String) extends DefaultTestCpg with SwiftSrc2CpgFrontend +class DefaultTestCpgWithSwiftSrc(val fileSuffix: String) + extends DefaultTestCpg + with SwiftSrc2CpgFrontend + with SemanticTestCpg { + + override protected def applyPasses(): Unit = { + super.applyPasses() + applyOssDataFlow() + } + +} -class SwiftSrc2CpgSuite(fileSuffix: String = ".swift") - extends Code2CpgFixture(() => new DefaultTestCpgWithSwiftSrc(fileSuffix)) +class SwiftSrc2CpgSuite( + fileSuffix: String = ".swift", + withOssDataflow: Boolean = false, + extraFlows: List[FlowSemantic] = List.empty, + withPostProcessing: Boolean = false +) extends Code2CpgFixture(() => + new DefaultTestCpgWithSwiftSrc(fileSuffix) + .withOssDataflow(withOssDataflow) + .withExtraFlows(extraFlows) + .withPostProcessingPasses(withPostProcessing) + ) with Inside diff --git a/joern-cli/frontends/x2cpg/src/test/scala/io/joern/x2cpg/testfixtures/TestCpg.scala b/joern-cli/frontends/x2cpg/src/test/scala/io/joern/x2cpg/testfixtures/TestCpg.scala index 07443e4120bc..669b180eea9d 100644 --- a/joern-cli/frontends/x2cpg/src/test/scala/io/joern/x2cpg/testfixtures/TestCpg.scala +++ b/joern-cli/frontends/x2cpg/src/test/scala/io/joern/x2cpg/testfixtures/TestCpg.scala @@ -14,9 +14,10 @@ import scala.collection.mutable // The trait LanguageFrontend is mixed in and not property/field of this class in order // to allow the configuration of language frontend specific properties on the CPG object. abstract class TestCpg extends Cpg() with LanguageFrontend { - private var _graph = Option.empty[Graph] - private val codeFileNamePairs = mutable.ArrayBuffer.empty[(String, Path)] - private var fileNameCounter = 0 + private var _graph = Option.empty[Graph] + private val codeFileNamePairs = mutable.ArrayBuffer.empty[(String, Path)] + private var fileNameCounter = 0 + protected var _withPostProcessing = false @nowarn protected def codeFilePreProcessing(codeFile: Path): Unit = {} @@ -26,6 +27,8 @@ abstract class TestCpg extends Cpg() with LanguageFrontend { protected def applyPasses(): Unit + protected def applyPostProcessingPasses(): Unit = {} + def moreCode(code: String): this.type = { moreCode(code, s"Test$fileNameCounter$fileSuffix") fileNameCounter += 1 @@ -43,6 +46,11 @@ abstract class TestCpg extends Cpg() with LanguageFrontend { this } + def withPostProcessingPasses(value: Boolean = true): this.type = { + _withPostProcessing = value + this + } + private def checkGraphEmpty(): Unit = { if (_graph.isDefined) { throw new RuntimeException("Modifying test data is not allowed after accessing graph.") @@ -78,6 +86,7 @@ abstract class TestCpg extends Cpg() with LanguageFrontend { try { _graph = Option(execute(codeDir.toFile).graph) applyPasses() + if (_withPostProcessing) applyPostProcessingPasses() } finally { deleteDir(codeDir) }