diff --git a/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/CSharpSrc2Cpg.scala b/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/CSharpSrc2Cpg.scala index f7324287fcd4..0bb524516293 100644 --- a/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/CSharpSrc2Cpg.scala +++ b/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/CSharpSrc2Cpg.scala @@ -74,32 +74,18 @@ class CSharpSrc2Cpg extends X2CpgFrontend[Config] { } private def createBuiltinSummary(config: Config, internalSummary: CSharpProgramSummary): CSharpProgramSummary = { - if (config.useBuiltinSummaries) { - CSharpProgramSummary( - mutable.Map - .fromSpecific(CSharpProgramSummary.BuiltinTypes.view.filterKeys(internalSummary.imports)) - .result() - ) - } else { - CSharpProgramSummary() - } + Option + .when(config.useBuiltinSummaries)(CSharpProgramSummary.builtinTypesSummary) + .map(_.filter(namespacePred = (ns, _) => internalSummary.imports.contains(ns))) + .getOrElse(CSharpProgramSummary()) } private def createExternalSummary(config: Config, internalSummary: CSharpProgramSummary): CSharpProgramSummary = { - if (config.externalSummaryPaths.nonEmpty) { - CSharpProgramSummary( - mutable.Map - .fromSpecific( - CSharpProgramSummary - .fromExternalJsons(config.externalSummaryPaths) - .view - .filterKeys(internalSummary.imports) - ) - .result() - ) - } else { - CSharpProgramSummary() - } + val jsonFilePaths = config.externalSummaryPaths + Option + .when(jsonFilePaths.nonEmpty)(CSharpProgramSummary.externalTypesSummary(jsonFilePaths)) + .map(_.filter(namespacePred = (ns, _) => internalSummary.imports.contains(ns))) + .getOrElse(CSharpProgramSummary()) } private def buildFiles(config: Config): List[String] = { diff --git a/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/datastructures/CSharpProgramSummary.scala b/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/datastructures/CSharpProgramSummary.scala index 2b4d389b2229..f8fb66cb41c7 100644 --- a/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/datastructures/CSharpProgramSummary.scala +++ b/joern-cli/frontends/csharpsrc2cpg/src/main/scala/io/joern/csharpsrc2cpg/datastructures/CSharpProgramSummary.scala @@ -40,6 +40,28 @@ case class CSharpProgramSummary(namespaceToType: NamespaceToTypeMap, imports: Se ) } + /** Builds a new `CSharpProgramSummary` by filtering the current one's fields. + * + * @param namespacePred + * filtering predicate for `namespaceToType` + * + * @param importsPred + * filtering predicate for `imports` + * + * @param globalImportsPred + * filtering predicate for `globalImports` + */ + def filter( + namespacePred: (String, mutable.Set[CSharpType]) => Boolean = (_, _) => true, + importsPred: String => Boolean = _ => true, + globalImportsPred: String => Boolean = _ => true + ): CSharpProgramSummary = + copy( + namespaceToType = mutable.Map.fromSpecific(namespaceToType.view.filter(namespacePred(_, _))), + imports = imports.filter(importsPred), + globalImports = globalImports.filter(globalImportsPred) + ) + } object CSharpProgramSummary { @@ -63,7 +85,7 @@ object CSharpProgramSummary { /** @return * a mapping of the `System` package types. */ - def BuiltinTypes: NamespaceToTypeMap = { + private def BuiltinTypes: NamespaceToTypeMap = { jsonToInitialMapping(mergeBuiltInTypesJson) match { case Failure(exception) => logger.warn("Unable to parse JSON type entry from builtin types", exception); mutable.Map.empty @@ -71,7 +93,20 @@ object CSharpProgramSummary { } } - def fromExternalJsons(paths: Set[String]): NamespaceToTypeMap = { + /** Returns the `CSharpProgramSummary` for the builtin types bundle. + */ + def builtinTypesSummary: CSharpProgramSummary = + CSharpProgramSummary(BuiltinTypes) + + /** Returns the `CSharpProgramSummary` for the given JSON file paths. + * + * @param paths + * the JSON file paths to load types from + */ + def externalTypesSummary(paths: Set[String]): CSharpProgramSummary = + CSharpProgramSummary(fromExternalJsons(paths)) + + private def fromExternalJsons(paths: Set[String]): NamespaceToTypeMap = { val jsonFiles = paths.flatMap(SourceFiles.determine(_, Set(".json"))(VisitOptions.default)).toList val inputStreams = jsonFiles.flatMap { path => Try(java.io.FileInputStream(path)) match {