All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.joern.php2cpg.passes.DependencySymbolsPass.scala Maven / Gradle / Ivy

The newest version!
package io.joern.php2cpg.passes

import better.files.File
import io.joern.php2cpg.parser.ClassParser
import io.joern.php2cpg.parser.ClassParser.*
import io.joern.x2cpg.ValidationMode.Disabled
import io.joern.x2cpg.passes.base.MethodStubCreator
import io.joern.x2cpg.{Ast, ValidationMode}
import io.shiftleft.codepropertygraph.generated.nodes.{NewMethod, NewTypeDecl}
import io.shiftleft.codepropertygraph.generated.{Cpg, DispatchTypes, NodeTypes}
import io.shiftleft.passes.ForkJoinParallelCpgPass
import io.shiftleft.semanticcpg.language.types.structure.NamespaceTraversal
import org.slf4j.LoggerFactory

import scala.util.{Failure, Success}

/** This pass parses the high-level symbols of the dependencies to include their types to the CPG.
  * @param cpg
  *   the code property graph.
  * @param dependencyDir
  *   the directory holding the downloaded dependencies.
  */
class DependencySymbolsPass(cpg: Cpg, dependencyDir: File) extends ForkJoinParallelCpgPass[ClassParserClass](cpg) {

  private val logger                          = LoggerFactory.getLogger(this.getClass)
  implicit val validationMode: ValidationMode = ValidationMode.Disabled

  override def generateParts(): Array[ClassParserClass] = new ClassParser(dependencyDir).parse() match {
    case Success(classes) => classes.toArray
    case Failure(exception) =>
      logger.error("Exception encountered while parsing symbols from dependencies", exception)
      Array.empty
  }

  override def runOnPart(builder: DiffGraphBuilder, clazz: ClassParserClass): Unit = {
    val className     = clazz.name
    val classFullName = s"${clazz.namespace}\\$className"
    val typeDecl = NewTypeDecl()
      .name(clazz.name)
      .fullName(classFullName)
      .isExternal(true)
      .astParentType(NodeTypes.NAMESPACE_BLOCK)
      .astParentFullName(NamespaceTraversal.globalNamespaceName)

    val functions = clazz.functions
      .map { case ClassParserFunction(name, modifiers) =>
        MethodStubCreator.createMethodStub(
          name = name,
          fullName = s"$classFullName->$name",
          signature = "",
          dispatchType = DispatchTypes.DYNAMIC_DISPATCH,
          parameterCount = 0,
          astParentType = NodeTypes.TYPE_DECL,
          astParentFullName = classFullName,
          dstGraph = builder
        )
      }
      .map(Ast.apply(_))

    Ast.storeInDiffGraph(Ast(typeDecl).withChildren(functions), builder)
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy