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

ch.epfl.scala.debugadapter.internal.evaluator.RuntimeTree.scala Maven / Gradle / Ivy

The newest version!
package ch.epfl.scala.debugadapter.internal.evaluator

import com.sun.jdi
import ch.epfl.scala.debugadapter.internal.evaluator.RuntimePrimitiveOps.*

sealed trait RuntimeEvaluationTree {
  def `type`: jdi.Type
  override def toString(): String = prettyPrint(0)
  def prettyPrint(depth: Int): String
}

object RuntimeEvaluationTree {
  sealed trait CallMethod extends RuntimeEvaluationTree {
    def method: jdi.Method
    def args: Seq[RuntimeEvaluationTree]
  }

  sealed trait Assignable extends RuntimeEvaluationTree

  sealed trait Field extends Assignable {
    def field: jdi.Field
    def isMutable: Boolean = !field.isFinal
  }

  case class LocalVar(name: String, `type`: jdi.Type) extends Assignable {
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|LocalVar(
          |${indent}name= $name,
          |${indent}type= ${`type`}
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class InstanceField(field: jdi.Field, qualifier: RuntimeEvaluationTree) extends Field {
    override lazy val `type` = field.`type`()
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|InstanceField(
          |${indent}field = $field,
          |${indent}qualifier = ${qualifier.prettyPrint(depth + 1)}
          |${indent.dropRight(1)})""".stripMargin
    }
  }
  case class StaticField(field: jdi.Field) extends Field {
    override lazy val `type` = field.`type`()
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|StaticField(
          |${indent}field = $field
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class CallInstanceMethod(
      method: jdi.Method,
      args: Seq[RuntimeEvaluationTree],
      qualifier: RuntimeEvaluationTree
  ) extends CallMethod {
    override lazy val `type` = method.returnType()
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|InstanceMethod(
          |${indent}method = $method -> ${method.returnType()},
          |${indent}args = ${args.map(_.prettyPrint(depth + 1)).mkString(",\n" + indent)},
          |${indent}qualifier = ${qualifier.prettyPrint(depth + 1)}
          |${indent.dropRight(1)})""".stripMargin
    }
  }
  case class CallStaticMethod(
      method: jdi.Method,
      args: Seq[RuntimeEvaluationTree],
      qualifier: jdi.ReferenceType
  ) extends CallMethod {
    override lazy val `type` = method.returnType()
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|CallStaticMethod(
          |${indent}m= $method,
          |${indent}args= ${args.map(_.prettyPrint(depth + 1)).mkString(",\n" + indent)},
          |${indent}qualifier= $qualifier
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class CallBinaryOp(
      lhs: RuntimeEvaluationTree,
      rhs: RuntimeEvaluationTree,
      op: BinaryOp
  ) extends RuntimeEvaluationTree {
    override lazy val `type` = op.typeCheck(lhs.`type`, rhs.`type`)
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|CallBinaryOp(
          |${indent}lhs = ${lhs.prettyPrint(depth + 1)},
          |${indent}rhs = ${rhs.prettyPrint(depth + 1)},
          |${indent}op = $op
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class ArrayElem(array: RuntimeEvaluationTree, index: RuntimeEvaluationTree, `type`: jdi.Type)
      extends RuntimeEvaluationTree {
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|ArrayElem(
          |${indent}array = $array,
          |${indent}index = $index
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class CallUnaryOp(
      rhs: RuntimeEvaluationTree,
      op: UnaryOp
  ) extends RuntimeEvaluationTree {
    override lazy val `type` = op.typeCheck(rhs.`type`)
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|UnaryOpCall(
          |${indent}rhs= ${rhs.prettyPrint(depth + 1)},
          |${indent}op= $op
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class NewInstance(init: CallStaticMethod) extends RuntimeEvaluationTree {
    override lazy val `type`: jdi.ReferenceType = init.method.declaringType() // .asInstanceOf[jdi.ClassType]
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|NewInstance(
          |${indent}init= ${init.prettyPrint(depth + 1)}
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class This(`type`: jdi.ReferenceType) extends RuntimeEvaluationTree {
    override def prettyPrint(depth: Int): String = s"This(${`type`})"
  }

  case class StaticModule(`type`: jdi.ClassType) extends RuntimeEvaluationTree {
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|StaticModule(
          |${indent}mod= ${`type`}
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class NestedModule(`type`: jdi.ReferenceType, init: CallInstanceMethod) extends RuntimeEvaluationTree {
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|NestedModule(
          |${indent}type = ${`type`}
          |${indent}init = ${init.prettyPrint(depth + 1)}
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class Value(value: Safe[JdiValue], `type`: jdi.Type) extends RuntimeEvaluationTree {
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|Value(
          |${indent}v= $value,
          |${indent}t= ${`type`}
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class Literal(value: Any, `type`: jdi.Type) extends RuntimeEvaluationTree {
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|Literal(
          |${indent}v= $value,
          |${indent}t= ${`type`}
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class If(
      p: RuntimeEvaluationTree,
      thenp: RuntimeEvaluationTree,
      elsep: RuntimeEvaluationTree,
      `type`: jdi.Type
  ) extends RuntimeEvaluationTree {
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|If(
          |${indent}p= ${p.prettyPrint(depth + 1)},
          |${indent}ifTrue= ${thenp.prettyPrint(depth + 1)},
          |${indent}ifFalse= ${elsep.prettyPrint(depth + 1)}
          |${indent}t= ${`type`}
          |${indent.dropRight(1)})""".stripMargin
    }
  }

  case class Assign(
      lhs: Assignable,
      rhs: RuntimeEvaluationTree,
      `type`: jdi.Type
  ) extends RuntimeEvaluationTree {
    override def prettyPrint(depth: Int): String = {
      val indent = "  " * (depth + 1)
      s"""|Assign(
          |${indent}lhs= ${lhs.prettyPrint(depth + 1)},
          |${indent}rhs= ${rhs.prettyPrint(depth + 1)},
          |${indent}t= ${`type`}
          |${indent.dropRight(1)})""".stripMargin
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy