Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update CPG packages to v7 (major) #736

Merged
merged 5 commits into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ open class CPGBackend(config: BackendConfiguration) : Backend {
.failOnError(failOnError)
.useParallelFrontends(useParallelFrontends)
.typeSystemActiveInFrontend(typeSystemActiveInFrontend)
.defaultLanguages()
.sourceLocations(source.map { (it.toFile()) })
.symbols(symbols)
.useUnityBuild(useUnityBuild)
Expand All @@ -86,6 +85,15 @@ open class CPGBackend(config: BackendConfiguration) : Backend {
if (defaultPasses) translationConfiguration.defaultPasses()
passes.forEach { translationConfiguration.registerPass(it) }

translationConfiguration.optionalLanguage(
"de.fraunhofer.aisec.cpg.frontends.cxx.CLanguage"
)
translationConfiguration.optionalLanguage(
"de.fraunhofer.aisec.cpg.frontends.cxx.CPPLanguage"
)
translationConfiguration.optionalLanguage(
"de.fraunhofer.aisec.cpg.frontends.java.JavaLanguage"
)
translationConfiguration.optionalLanguage(
"de.fraunhofer.aisec.cpg.frontends.python.PythonLanguage"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import de.fraunhofer.aisec.codyze.core.backend.BackendConfiguration
import de.fraunhofer.aisec.cpg.passes.Pass
import mu.KotlinLogging
import java.nio.file.Path
import kotlin.reflect.KClass

private val logger = KotlinLogging.logger {}

Expand All @@ -44,7 +45,7 @@ data class CPGConfiguration(
val defaultPasses: Boolean,
val additionalLanguages: Set<String>,
val symbols: Map<String, String>,
val passes: List<Pass>,
val passes: List<KClass<out Pass<*>>>,
val loadIncludes: Boolean,
val includePaths: List<Path>,
val includeAllowlist: List<Path>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import de.fraunhofer.aisec.codyze.core.config.combineSources
import de.fraunhofer.aisec.codyze.core.config.resolvePaths
import de.fraunhofer.aisec.cpg.passes.Pass
import java.nio.file.Path
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.full.isSuperclassOf

/**
* Holds the common CLI options for all CPG based Codyze backends.
Expand Down Expand Up @@ -173,10 +176,10 @@ class CPGOptionGroup : BackendOptions(helpName = "CPG Backend Options") {
)
}

private val rawPasses: List<Pass> by option("--passes", help = "Definition of additional symbols.")
private val rawPasses: List<KClass<out Pass<*>>> by option("--passes", help = "Definition of additional symbols.")
.convert { convertPass(it) }
.multiple()
private val rawPassesAdditions: List<Pass> by option(
private val rawPassesAdditions: List<KClass<out Pass<*>>> by option(
"--passes-additions",
help =
"See --passes, but appends the values to the ones specified in configuration file."
Expand All @@ -185,7 +188,9 @@ class CPGOptionGroup : BackendOptions(helpName = "CPG Backend Options") {
.multiple()

/** Lazy property that combines all symbols from the different options into a single map. */
val passes: List<Pass> by lazy { resolvePasses(passes = rawPasses, additionalPasses = rawPassesAdditions) }
val passes: List<KClass<out Pass<*>>> by lazy {
resolvePasses(passes = rawPasses, additionalPasses = rawPassesAdditions)
}

val loadIncludes: Boolean by option(
"--analyze-includes",
Expand Down Expand Up @@ -285,17 +290,20 @@ class CPGOptionGroup : BackendOptions(helpName = "CPG Backend Options") {
return symbols + additionalSymbols
}

private fun resolvePasses(passes: List<Pass>, additionalPasses: List<Pass>): List<Pass> {
private fun resolvePasses(
passes: List<KClass<out Pass<*>>>,
additionalPasses: List<KClass<out Pass<*>>>
): List<KClass<out Pass<*>>> {
return passes + additionalPasses
}

@Suppress("SwallowedException", "ThrowsCount")
private fun convertPass(className: String) =
@Suppress("SwallowedException", "ThrowsCount", "UNCHECKED_CAST")
private fun convertPass(className: String): KClass<out Pass<*>> =
try {
val clazz = Class.forName(className)
if (Pass::class.java.isAssignableFrom(clazz)) {
// TODO: use 'isSubtypeOf' ?
clazz.getDeclaredConstructor().newInstance() as Pass
val clazz = Class.forName(className).kotlin
if (clazz.isSubclassOf(Pass::class)) {
if (clazz.isSuperclassOf(Pass::class)) throw ReflectiveOperationException("Cannot register $className")
(clazz as? KClass<out Pass<*>>) ?: throw ReflectiveOperationException("$className is not a CPG Pass")
} else {
throw ReflectiveOperationException("$className is not a CPG Pass")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import de.fraunhofer.aisec.codyze.specificationLanguages.coko.core.dsl.FunctionO
import de.fraunhofer.aisec.codyze.specificationLanguages.coko.core.dsl.Op
import de.fraunhofer.aisec.codyze.specificationLanguages.coko.core.dsl.Order
import de.fraunhofer.aisec.codyze.specificationLanguages.coko.core.ordering.*
import de.fraunhofer.aisec.cpg.graph.AssignmentTarget
import de.fraunhofer.aisec.cpg.graph.Node
import de.fraunhofer.aisec.cpg.graph.followNextEOG
import de.fraunhofer.aisec.cpg.graph.*
import de.fraunhofer.aisec.cpg.graph.declarations.VariableDeclaration
import de.fraunhofer.aisec.cpg.graph.statements.expressions.DeclaredReferenceExpression
import mu.KotlinLogging
import kotlin.reflect.full.createType
import kotlin.reflect.full.declaredMemberFunctions
Expand Down Expand Up @@ -162,8 +162,12 @@ class OrderEvaluator(val baseNodes: Collection<Node>, val order: Order) : Evalua
dfa = dfa,
hashToMethod = hashToMethod,
nodeToRelevantMethod = nodesToOp,
consideredBases = baseNodes.map { node ->
node.followNextEOG { it.end is AssignmentTarget }!!.last().end
consideredBases = baseNodes.flatMap { node ->
node.followNextDFGEdgesUntilHit { next ->
next is VariableDeclaration || next is DeclaredReferenceExpression
}.fulfilled.mapNotNull { path ->
path.lastOrNull()
}
}.toSet(),
consideredResetNodes = baseNodes.toSet(),
context = context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ class CpgOptionGroupTest {
)

val expectedPassesNames =
listOf(EdgeCachePass(), FilenameMapper(), CallResolver()).map { p ->
p::class.qualifiedName
listOf(EdgeCachePass::class, FilenameMapper::class, CallResolver::class).map { p ->
p.qualifiedName
}
val actualPassesNames = cli.cpgOptions.passes.map { p -> p::class.qualifiedName }
val actualPassesNames = cli.cpgOptions.passes.map { p -> p.qualifiedName }

logger.info { actualPassesNames.joinToString(",") }

Expand Down Expand Up @@ -330,7 +330,7 @@ class CpgOptionGroupTest {
assertNotNull(translationOptionName)

return Stream.of(
Arguments.of(arrayOf("--passes", passName)),
Arguments.of(arrayOf("--source", testDir1.toString(), "--passes", passName)),
Arguments.of(arrayOf("--passes", "my.passes.MyPass")),
Arguments.of(arrayOf("--passes", translationOptionName))
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fun createCpgConfiguration(vararg sourceFile: Path) =
includePaths = listOf(),
includeAllowlist = listOf(),
loadIncludes = false,
passes = listOf(EdgeCachePass(), UnreachableEOGPass()),
passes = listOf(EdgeCachePass::class, UnreachableEOGPass::class),
)

@Rule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class CokoCpgIntegrationTest {
includePaths = listOf(),
includeAllowlist = listOf(),
loadIncludes = false,
passes = listOf(UnreachableEOGPass(), EdgeCachePass()),
passes = listOf(UnreachableEOGPass::class, EdgeCachePass::class),
)

/**
Expand Down Expand Up @@ -89,7 +89,7 @@ class CokoCpgIntegrationTest {
val run = executor.evaluate()

// assertions for the order rule
assertEquals(run.results?.size, 16)
assertEquals(16, run.results?.size)
}

/**
Expand Down Expand Up @@ -119,7 +119,7 @@ class CokoCpgIntegrationTest {
val run = executor.evaluate()

// assertions for the order rule
assertEquals(run.results?.size, 1)
assertEquals(1, run.results?.size)
}

/**
Expand Down Expand Up @@ -148,7 +148,7 @@ class CokoCpgIntegrationTest {
val executor = CokoExecutor(cokoConfiguration, backend)

val run = executor.evaluate()
assertEquals(run.results?.size, 16)
assertEquals(16, run.results?.size)
}

/**
Expand Down Expand Up @@ -177,7 +177,7 @@ class CokoCpgIntegrationTest {
val executor = CokoExecutor(cokoConfiguration, backend)

val run = executor.evaluate()
assertEquals(run.results?.size, 16)
assertEquals(16, run.results?.size)
}

/**
Expand Down Expand Up @@ -208,7 +208,7 @@ class CokoCpgIntegrationTest {
val executor = CokoExecutor(cokoConfiguration, backend)

val run = executor.evaluate()
assertEquals(run.results?.size, 16)
assertEquals(16, run.results?.size)
}

/**
Expand Down
17 changes: 11 additions & 6 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[versions]
kotlin = "1.8.22"
cpg = "6.2.2"
cpg = "7.0.0"
koin = "3.4.1"
detekt = "1.23.0"
spotless = "6.19.0"
Expand All @@ -13,13 +13,18 @@ kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serializa
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin"}

# CPG official releases
#cpg-core = { module = "de.fraunhofer.aisec:cpg-core", version.ref = "cpg"}
#cpg-analysis = { module = "de.fraunhofer.aisec:cpg-analysis", version.ref = "cpg"}
cpg-core = { module = "de.fraunhofer.aisec:cpg-core", version.ref = "cpg"}
cpg-analysis = { module = "de.fraunhofer.aisec:cpg-analysis", version.ref = "cpg"}
cpg-language-cxx = { module = "de.fraunhofer.aisec:cpg-language-cxx", version.ref = "cpg"}
cpg-language-java = { module = "de.fraunhofer.aisec:cpg-language-java", version.ref = "cpg"}
#cpg-language-go = { module = "de.fraunhofer.aisec:cpg-language-go", version.ref = "cpg"}
#cpg-language-python = { module = "de.fraunhofer.aisec:cpg-language-python", version.ref = "cpg"}
#cpg-language-llvm = { module = "de.fraunhofer.aisec:cpg-language-llvm", version.ref = "cpg"}
#cpg-language-typescript = { module = "de.fraunhofer.aisec:cpg-language-typescript", version.ref = "cpg"}

# CPG GitHub builds using JitPack
cpg-core = { module = "de.fraunhofer.aisec:cpg-core", version.ref = "cpg"}
cpg-analysis = { module = "de.fraunhofer.aisec:cpg-analysis", version.ref = "cpg"}
#cpg-core = { module = "com.github.Fraunhofer-AISEC.cpg:cpg-core", version.ref = "cpg"}
#cpg-analysis = { module = "com.github.Fraunhofer-AISEC.cpg:cpg-analysis", version.ref = "cpg"}
#cpg-language-go = { module = "com.github.Fraunhofer-AISEC.cpg:cpg-language-go", version.ref = "cpg"}

kotlin-logging = { module = "io.github.microutils:kotlin-logging-jvm", version = "3.0.5"}
Expand Down Expand Up @@ -49,7 +54,7 @@ dokka-base = { module = "org.jetbrains.dokka:dokka-base", version.ref = "dokka"


[bundles]
cpg = ["cpg-core", "cpg-analysis"] # without "cpg-language-go"
cpg = ["cpg-core", "cpg-analysis", "cpg-language-cxx", "cpg-language-java"] # without "cpg-language-go"
sarif = ["sarif4k", "kotlinx-serialization-json"]

[plugins]
Expand Down