Skip to content

Commit

Permalink
Kotlin types, no resolve flag (#118)
Browse files Browse the repository at this point in the history
* add support for no-resolve-types flag

* fix test case

* fix test case

* fix failing test case

---------

Co-authored-by: Khemraj Rathore <khemraj.rathore@privado.ai>
  • Loading branch information
ankit-privado and khemrajrathore authored Oct 21, 2024
1 parent 2811110 commit b65b017
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ class Kotlin2Cpg extends X2CpgFrontend[Config] with UsesService {
defaultContentRootJars
}

private def gatherDirsForSourcesToCompile(sourceDir: String): Seq[String] = {
val dirsForSourcesToCompile = ContentSourcesPicker.dirsForRoot(sourceDir)
private def gatherDirsForSourcesToCompile(sourceDir: String, config: Config): Seq[String] = {
val dirsForSourcesToCompile = ContentSourcesPicker.dirsForRoot(sourceDir, config)
if (dirsForSourcesToCompile.isEmpty) {
logger.warn("The list of directories to analyze is empty.")
}
Expand Down Expand Up @@ -213,9 +213,9 @@ class Kotlin2Cpg extends X2CpgFrontend[Config] with UsesService {
val filesWithJavaExtension = gatherFilesWithJavaExtension(sourceDir, config)
val mavenCoordinates = gatherMavenCoordinates(sourceDir, config)
val defaultContentRootJars = gatherDefaultContentRootJars(sourceDir, config, filesWithJavaExtension)
val dirsForSourcesToCompile = gatherDirsForSourcesToCompile(sourceDir)
val dirsForSourcesToCompile = gatherDirsForSourcesToCompile(sourceDir, config)
val environment = CompilerAPI.makeEnvironment(
Seq(sourceDir),
dirsForSourcesToCompile,
filesWithJavaExtension,
defaultContentRootJars,
new ErrorLoggingMessageCollector
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ final case class Config(
includeJavaSourceFiles: Boolean = false,
generateNodesForDependencies: Boolean = false,
downloadDependencies: Boolean = false,
keepTypeArguments: Boolean = false
keepTypeArguments: Boolean = false,
resolveTypes: Boolean = true
) extends X2CpgConfig[Config]
with DependencyDownloadConfig[Config] {

Expand Down Expand Up @@ -54,6 +55,10 @@ final case class Config(
def withKeepTypeArguments(value: Boolean): Config = {
copy(keepTypeArguments = value).withInheritedFields(this)
}

def withResolveTypes(value: Boolean): Config = {
copy(resolveTypes = value).withInheritedFields(this)
}
}

private object Frontend {
Expand Down Expand Up @@ -91,7 +96,10 @@ private object Frontend {
opt[Unit]("keep-type-arguments")
.hidden()
.action((_, c) => c.withKeepTypeArguments(true))
.text("Type full names of variables keep their type arguments.")
.text("Type full names of variables keep their type arguments."),
opt[Unit]("no-resolve-types")
.action((_, c) => c.withResolveTypes(false))
.text("Skip generating types")
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package io.joern.kotlin2cpg.types

import better.files.{File => BFile}
import better.files.File as BFile
import io.joern.kotlin2cpg.Config
import io.joern.kotlin2cpg.DefaultContentRootJarPath
import io.joern.x2cpg.SourceFiles.toRelativePath

object ContentSourcesPicker {

Expand All @@ -18,13 +20,13 @@ object ContentSourcesPicker {
// The list of paths which are acceptable for the current version of the Kotlin compiler API is:
// `Seq("dir1/dir2/dir3")` and nothing else.

def dirsForRoot(rootDir: String): Seq[String] = {
def dirsForRoot(rootDir: String, config: Config): Seq[String] = {
val dir = BFile(rootDir)
val hasSubDirs = dir.list.exists(_.isDirectory)
if (!hasSubDirs) {
if (!hasSubDirs || !config.resolveTypes) {
return Seq(rootDir)
}
dir.listRecursively
val dirPaths = dir.listRecursively
.filter(_.isDirectory)
.flatMap { f =>
val hasKtsFile = f.listRecursively.exists { f => f.hasExtension && f.pathAsString.endsWith(".kts") }
Expand All @@ -36,5 +38,9 @@ object ContentSourcesPicker {
}
.flatten
.toSeq
dirPaths.filterNot(path =>
val t = toRelativePath(path, config.inputPath)
config.ignoredFilesRegex.matches(toRelativePath(path, config.inputPath))
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import better.files.File
import io.joern.kotlin2cpg.Config
import io.joern.kotlin2cpg.DefaultContentRootJarPath
import io.joern.kotlin2cpg.Kotlin2Cpg
import io.joern.kotlin2cpg.types.ContentSourcesPicker
import io.joern.x2cpg.utils.ExternalCommand
import io.joern.x2cpg.Defines
import io.shiftleft.semanticcpg.language.*
Expand Down Expand Up @@ -75,7 +76,7 @@ class CompilerAPITests extends AnyFreeSpec with Matchers {
ProjectRoot.relativise("joern-cli/frontends/kotlin2cpg/src/test/resources/code/springboot-kotlin-webgoat")
val projectDependenciesPath = Paths.get(projectDirPath, "build", "gatheredDependencies")

"should not contain methods with unresolved types/namespaces" ignore {
"should not contain methods with unresolved types/namespaces" in {
val command =
if (scala.util.Properties.isWin) "cmd.exe /C gradlew.bat gatherDependencies" else "./gradlew gatherDependencies"
ExternalCommand.run(command, projectDirPath) shouldBe Symbol("success")
Expand All @@ -87,5 +88,27 @@ class CompilerAPITests extends AnyFreeSpec with Matchers {
cpg.method.signature(s".*${Defines.UnresolvedNamespace}.*") shouldBe empty
}

"should return all the individual folder name" in {
val paths = ContentSourcesPicker.dirsForRoot(projectDirPath, Config().withInputPath(projectDirPath))
paths.size shouldBe 26
}

"should return all the individual folder name excluding paths, mentioned in exclusion regex" in {
import java.io.File
val paths = ContentSourcesPicker.dirsForRoot(
projectDirPath,
Config().withInputPath(projectDirPath).withIgnoredFilesRegex(s".*test.*")
)
paths.size shouldBe 21
}

"should return all the individual folder name excluding paths, when no-resolve-type" in {
val paths =
ContentSourcesPicker.dirsForRoot(projectDirPath, Config().withInputPath(projectDirPath).withResolveTypes(false))

paths.size shouldBe 1
paths.head shouldBe projectDirPath
}

}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.joern.kotlin2cpg.types

import io.joern.kotlin2cpg.Config
import io.joern.kotlin2cpg.compiler.{CompilerAPI, ErrorLoggingMessageCollector}
import org.jetbrains.kotlin.resolve.BindingContext
import org.scalatest.freespec.AnyFreeSpec
Expand All @@ -22,7 +23,7 @@ class KotlinScriptFilteringTests extends AnyFreeSpec with Matchers {

"should not return an empty binding context" in {
val sourceDir = "src/test/resources/external_projects/kotlin-dsl"
val dirsForSourcesToCompile = ContentSourcesPicker.dirsForRoot(sourceDir)
val dirsForSourcesToCompile = ContentSourcesPicker.dirsForRoot(sourceDir, config = Config())
val environment =
CompilerAPI.makeEnvironment(dirsForSourcesToCompile, Seq(), Seq(), new ErrorLoggingMessageCollector)
environment.getSourceFiles should not be List()
Expand Down

0 comments on commit b65b017

Please sign in to comment.