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

quotidian.Debug.scala Maven / Gradle / Ivy

The newest version!
package quotidian

import quotidian.StringUtils.*

import scala.quoted.*

object Report:
  def debug(using Quotes)(tree: quotes.reflect.Tree): Unit =
    import quotes.reflect.*
    val prettyTerm = pprint(tree).toString
    report.errorAndAbort {
      s"""
${"SHOW".blue.underlined}
${tree.show}

${"TREE".blue.underlined}
$prettyTerm
"""
    }

object Debug:

  inline def debug[A](inline expr: A): A = ${ debugImpl('expr) }

  // def prettyPrint(using Quotes)(tree: quotes.reflect.Tree): String =
  //   import quotes.reflect.*

  //   val b = new StringBuilder

  //   def render(tree: Tree, indent: Int = 0): Unit =
  //     tree match
  //       // Ident("name")
  //       case Ident(name) =>
  //         b.append(s"Ident($name)")

  //       case Select(tree, name) =>
  //         b.append(s"Select(${render(tree)}, $name)")

  //       case Apply(func, args) =>
  //         b.append(s"Apply(${render(func)}, ${args.map(render).mkString(", ")})")

  //       case ApplyInfix(left, op, right) =>
  //         b.append(s"ApplyInfix(${render(left)}, $op, ${render(right)})")

  //       case Literal(value) =>
  //         b.append(s"Literal($value)")

  def debugImpl[A: Type](expr: Expr[A])(using Quotes): Expr[A] =
    import quotes.reflect.*

    val typeRepr       = TypeRepr.of[A]
    val showTypeRepr   = typeRepr.show
    val prettyTypeRepr = pprint(typeRepr).toString
    val showExpr       = expr.show

    val prettyTerm = pprint(expr.asTerm.underlyingArgument).toString
    val symbol     = typeRepr.typeSymbol
    val info       = SymbolInfo.fromSymbol(symbol)
    val message =
      s"""${"EXPR".blue.underlined}
        |$showExpr
        |
        |${"TERM".blue.underlined}
        |$prettyTerm
        |
        |${pprint(info)}
        |""".stripMargin
    report.errorAndAbort(message)

  inline def debugWithType[A](inline expr: A): A = ${ debugWithTypeImpl('expr) }

  def debugWithTypeImpl[A: Type](expr: Expr[A])(using Quotes): Expr[A] =
    import quotes.reflect.*

    val typeRepr       = TypeRepr.of[A]
    val showTypeRepr   = typeRepr.show
    val prettyTypeRepr = pprint(typeRepr).toString
    val showExpr       = expr.show
    val prettyTerm     = pprint(expr.asTerm.underlyingArgument).toString
    val message =
      s"""${"EXPR".blue.underlined}
        |$showExpr
        |
        |${"TERM".blue.underlined}
        |$prettyTerm
        |
        |${"TYPE".blue.underlined}
        |$showTypeRepr
        |
        |${"TYPE REPR".blue.underlined}
        |$prettyTypeRepr
        |""".stripMargin
    report.errorAndAbort(message)
    expr

final case class SymbolInfo(
    fullName: String,
    flags: String,
    docString: Option[String],
    annotations: List[String],
    declaredFields: List[String],
//    inheritedFields: List[String],
    declaredMethods: List[String],
//    methodMembers: List[String],
    declaredTypes: List[String],
    overridingSymbols: List[String] = Nil,
    companionClass: String,
    companionModule: String,
    children: List[String]
)

object SymbolInfo:
  def fromSymbol(using Quotes)(symbol: quotes.reflect.Symbol): SymbolInfo =
    SymbolInfo(
      symbol.fullName,
      symbol.flags.show,
      symbol.docstring,
      symbol.annotations.map(_.show),
      symbol.declaredFields.map(_.fullName),
//      (symbol.fieldMembers diff symbol.declaredFields).map(_.fullName),
      symbol.declaredMethods.map(_.fullName),
//      symbol.methodMembers.map(_.fullName),
      symbol.declaredTypes.map(_.fullName),
      symbol.allOverriddenSymbols.map(_.fullName).toList,
      symbol.companionClass.fullName,
      symbol.companionModule.fullName,
      symbol.children.map(_.fullName)
    )




© 2015 - 2024 Weber Informatics LLC | Privacy Policy