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

io.shiftleft.semanticcpg.language.NodeOrdering.scala Maven / Gradle / Ivy

package io.shiftleft.semanticcpg.language

import scala.collection.mutable

object NodeOrdering {

  /** For a given CFG with the entry node `cfgEntry` and an expansion function `expand`, return a map that associates
    * each node with an index such that nodes are numbered in post order.
    */
  def postOrderNumbering[NodeType](
    cfgEntry: NodeType,
    expand: NodeType => Iterator[NodeType]
  ): mutable.LinkedHashMap[NodeType, Int] = {
    var stack      = (cfgEntry, expand(cfgEntry)) :: Nil
    val visited    = mutable.Set.empty[NodeType]
    val numbering  = mutable.LinkedHashMap.empty[NodeType, Int]
    var nextNumber = 0

    while (stack.nonEmpty) {
      val (node, successors) = stack.head
      visited += node

      if (successors.hasNext) {
        val successor = successors.next()
        if (!visited.contains(successor)) {
          stack = (successor, expand(successor)) :: stack
        }
      } else {
        stack = stack.tail
        numbering.put(node, nextNumber)
        nextNumber += 1
      }
    }
    numbering
  }

  /** For a list of (node, number) pairs, return the list of nodes obtained by sorting nodes according to number in
    * reverse order.
    */
  def reverseNodeList[NodeType](nodeNumberPairs: List[(NodeType, Int)]): List[NodeType] = {
    nodeNumberPairs
      .sortBy { case (_, num) => -num }
      .map { case (node, _) => node }
  }

  /** For a list of (node, number) pairs, return the list of nodes obtained by sorting nodes according to number.
    */
  def nodeList[NodeType](nodeNumberPairs: List[(NodeType, Int)]): List[NodeType] = {
    nodeNumberPairs
      .sortBy { case (_, num) => num }
      .map { case (node, _) => node }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy