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

org.opalj.br.cfg.CatchNode.scala Maven / Gradle / Ivy

The newest version!
/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj.br.cfg

import org.opalj.br.ObjectType
import org.opalj.br.ExceptionHandler

/**
 * This node represents an exception handler.
 *
 * @note   `CatchNode`s are made explicit to handle/identify situations where the same
 *         exception handlers is responsible for handling multiple different exceptions.
 *         This situation generally arises in case of Java`s multi-catch expressions.
 *
 * @param  index The index of the underlying exception handler in the exception table.
 * @param  startPC The start pc of the try-block.
 * @param  endPC The pc of the first instruction after the try-block (exclusive!).
 * @param  handlerPC The first pc of the handler block.
 * @param  catchType The type of the handled exception.
 *
 * @author Erich Wittenbeck
 * @author Michael Eichberg
 */
final class CatchNode(
        val index:     Int, // primarily used to compute a unique id
        val startPC:   Int,
        val endPC:     Int,
        val handlerPC: Int,
        val catchType: Option[ObjectType]
) extends CFGNode {

    /**
     * @param handler The Handler.
     * @param index The unique index in the exception handler table; this enables us to assign
     *              unique nodeids to catch nodes.
     */
    def this(handler: ExceptionHandler, index: Int) =
        this(index, handler.startPC, handler.endPC, handler.handlerPC, handler.catchType)

    final override def nodeId: Int = {
        // OLD: the offset is required to ensure that catch node ids do not collide with basic
        // OLD: block ids (even if the index is zero!)
        // OLD: 0xFFFFFF + startPC + (index << 16)
        /*-1==normal exit, -2==abnormal exit*/ -3 - index
    }

    def copy(
        index:     Int                = this.index,
        startPC:   Int                = this.startPC,
        endPC:     Int                = this.endPC,
        handlerPC: Int                = this.handlerPC,
        catchType: Option[ObjectType] = this.catchType
    ): CatchNode = {
        new CatchNode(index, startPC, endPC, handlerPC, catchType)
    }

    final override def isBasicBlock: Boolean = false
    final override def isExitNode: Boolean = false
    final override def isAbnormalReturnExitNode: Boolean = false
    final override def isNormalReturnExitNode: Boolean = false
    final override def isStartOfSubroutine: Boolean = false

    final override def isCatchNode: Boolean = true
    final override def asCatchNode: this.type = this

    //
    // FOR DEBUGGING/VISUALIZATION PURPOSES
    //

    override def toHRR: Option[String] = Some(
        s"try[$startPC,$endPC) => $handlerPC{${catchType.map(_.toJava).getOrElse("Any")}}"
    )

    override def visualProperties: Map[String, String] = Map(
        "shape" -> "box",
        "labelloc" -> "l",
        "fillcolor" -> "orange",
        "style" -> "filled",
        "shape" -> "rectangle"
    )

    override def toString: String = {
        s"CatchNode([$startPC,$endPC)=>$handlerPC,${catchType.map(_.toJava).getOrElse("")})"
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy