alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (TypeDebugging.scala)

This example Scala source code file (TypeDebugging.scala) is included in my "Source Code Warehouse" project. The intent of this project is to help you more easily find Scala source code examples by using tags.

All credit for the original source code belongs to scala-lang.org; I'm just trying to make examples easier to find. (For my Scala work, see my Scala examples and tutorials.)

Scala tags/keywords

any, boolean, list, nil, red, reset, string, tree, type, typedef

The TypeDebugging.scala Scala example source code

/* NSC -- new Scala compiler
 * Copyright 2005-2013 LAMP/EPFL
 * @author  Paul Phillips
 */

package scala
package reflect
package internal

import util._

trait TypeDebugging {
  self: SymbolTable =>

  import definitions._

  /** There's a whole lot of implementation detail which is nothing but noise when
   *  you are trying to see what's going on. This is my attempt to filter it out.
   */
  object noPrint extends (Tree => Boolean) {
    def skipScalaName(name: Name) = name match {
      case tpnme.Any | tpnme.Nothing | tpnme.AnyRef => true
      case _                                        => false
    }
    def skipRefTree(t: RefTree) = t match {
      case Select(Select(Ident(nme.ROOTPKG), nme.scala_), name) if skipScalaName(name) => true
      case Select(sel, name) if sel.symbol == ScalaPackage && skipScalaName(name)      => true
      case Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)              => true
      case Ident(nme.ROOTPKG)                                                          => true
      case _                                                                           => skipSym(t.symbol)
    }
    def skipSym(sym: Symbol): Boolean = sym match {
      case null                    => false
      case NothingClass | AnyClass => true
      case PredefModule            => true
      case ObjectClass             => true
      case _                       => sym.hasPackageFlag
    }
    def skipType(tpe: Type): Boolean = (tpe eq null) || skipSym(tpe.typeSymbolDirect)

    def skip(t: Tree): Boolean = t match {
      case EmptyTree                                          => true
      case PackageDef(_, _)                                   => true
      case t: RefTree                                         => skipRefTree(t)
      case TypeBoundsTree(lo, hi)                             => skip(lo) && skip(hi)
      case Block(Nil, expr)                                   => skip(expr)
      case Apply(fn, Nil)                                     => skip(fn)
      case Block(stmt :: Nil, expr)                           => skip(stmt) && skip(expr)
      case DefDef(_, nme.CONSTRUCTOR, Nil, ListOfNil, _, rhs) => skip(rhs)
      case Literal(Constant(()))                              => true
      case tt @ TypeTree()                                    => skipType(tt.tpe)
      case _                                                  => skipSym(t.symbol)
    }
    def apply(t: Tree) = skip(t)
  }

  /** Light color wrappers.
   */
  object typeDebug {
    import scala.Console._

    private val colorsOk = sys.props contains "scala.color"
    private def inColor(s: String, color: String) = if (colorsOk && s != "") color +        s + RESET else s
    private def inBold(s: String, color: String)  = if (colorsOk && s != "") color + BOLD + s + RESET else s

    def inLightRed(s: String)          = inColor(s, RED)
    def inLightGreen(s: String)        = inColor(s, GREEN)
    def inLightMagenta(s: String)      = inColor(s, MAGENTA)
    def inLightCyan(s: String): String = inColor(s, CYAN)
    def inGreen(s: String): String     = inBold(s, GREEN)
    def inRed(s: String): String       = inBold(s, RED)
    def inBlue(s: String): String      = inBold(s, BLUE)
    def inCyan(s: String): String      = inBold(s, CYAN)
    def inMagenta(s: String)           = inBold(s, MAGENTA)
    def resetColor(s: String): String  = if (colorsOk) s + RESET else s

    private def to_s(x: Any): String = x match {
      // otherwise case classes are caught looking like products
      case _: Tree | _: Type     => "" + x
      case x: TraversableOnce[_] => x mkString ", "
      case x: Product            => x.productIterator mkString ("(", ", ", ")")
      case _                     => "" + x
    }
    def ptBlock(label: String, pairs: (String, Any)*): String = {
      if (pairs.isEmpty) label + "{ }"
      else {
        val width = (pairs map (_._1.length)).max
        val fmt   = "%-" + (width + 1) + "s %s"
        val strs  = pairs map { case (k, v) => fmt.format(k, to_s(v)) }

        strs.mkString(label + " {\n  ", "\n  ", "\n}")
      }
    }
    def ptLine(pairs: (String, Any)*): String = (
      pairs
              map { case (k,  v) => (k, to_s(v)) }
        filterNot { case (_,  v) => v == "" }
              map { case ("", v) => v ; case (k, v) => s"$k=$v" }
        mkString ", "
    )
    def ptTree(t: Tree): String = t match {
      case PackageDef(pid, _)                                                      => s"package $pid"
      case ModuleDef(_, name, _)                                                   => s"object $name"
      case DefDef(_, name, tparams, _, _, _)                                       => "def " + name + ptTypeParams(tparams)
      case ClassDef(_, name, Nil, _) if t.symbol != null && t.symbol.isModuleClass => s"module class $name"
      case ClassDef(_, name, tparams, _)                                           => "class " + name + ptTypeParams(tparams)
      case td: TypeDef                                                             => ptTypeParam(td)
      case TypeBoundsTree(lo, hi)                                                  =>
        val lo_s = if (noPrint(lo)) "" else " >: " + ptTree(lo)
        val hi_s = if (noPrint(hi)) "" else " <: " + ptTree(hi)
        lo_s + hi_s
      case _ if (t.symbol eq null) || (t.symbol eq NoSymbol) => to_s(t)
      case _                                                 => "" + t.symbol.tpe
    }
    def ptTypeParam(td: TypeDef): String = {
      val TypeDef(_, name, tparams, rhs) = td
      name + ptTypeParams(tparams) + ptTree(rhs)
    }
    def ptTypeParams(tparams: List[TypeDef]): String = str brackets (tparams map ptTypeParam)

    object str {
      def parentheses(xs: List[_]): String     = xs.mkString("(", ", ", ")")
      def brackets(xs: List[_]): String        = if (xs.isEmpty) "" else xs.mkString("[", ", ", "]")
      def tparams(tparams: List[Type]): String = brackets(tparams map debug)
      def parents(ps: List[Type]): String      = (ps map debug).mkString(" with ")
      def refine(defs: Scope): String          = defs.toList.mkString("{", " ;\n ", "}")
      def bounds(lo: Type, hi: Type): String   = {
        val lo_s = if (typeIsNothing(lo)) "" else s" >: $lo"
        val hi_s = if (typeIsAny(hi)) "" else s" <: $hi"
        lo_s + hi_s
      }
    }
    import str._
    private def debug(tp: Type): String = tp match {
      case TypeRef(pre, sym, args)         => s"${debug(pre)}.${sym.nameString}.${tparams(args)}"
      case ThisType(sym)                   => s"${sym.nameString}.this"
      case SingleType(pre, sym)            => s"${debug(pre)}.${sym.nameString}.type"
      case RefinedType(ps, decls)          => s"${parents(ps)} ${refine(decls)}"
      case ClassInfoType(ps, decls, clazz) => s"class ${clazz.nameString} ${parents(ps)} ${refine(decls)}"
      case PolyType(tparams, result)       => s"${brackets(tparams)}${debug(result)}"
      case TypeBounds(lo, hi)              => bounds(lo, hi)
      case tv @ TypeVar(_, _)              => "" + tv
      case ExistentialType(tparams, qtpe)  => s"forSome ${brackets(tparams)} ${debug(qtpe)}"
      case _                               => s"?${shortClassOfInstance(tp)}?" // tp.toString might produce cyclic error...
    }
    def debugString(tp: Type) = debug(tp)
  }
  def paramString(tp: Type)      = typeDebug.str parentheses (tp.params map (_.defString))
  def typeParamsString(tp: Type) = typeDebug.str brackets (tp.typeParams map (_.defString))
  def debugString(tp: Type)      = typeDebug debugString tp
}

Other Scala source code examples

Here is a short list of links related to this Scala TypeDebugging.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.