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

Scala example source code file (Origins.scala)

This example Scala source code file (Origins.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

array, class, int, oneline, origins, origins, originsname, rep, rep, stackslice, stackslice, string, string, t

The Scala Origins.scala source code

/* NSC -- new scala compiler
 * Copyright 2005-2011 LAMP/EPFL
 * @author Paul Phillips
 */

package scala.tools.nsc
package util

/** A debugging class for logging from whence a method is being called.
 *  Say you wanted to discover who was calling phase_= in SymbolTable.
 *  You could do this:
 *  
 *  {{{
 *    private lazy val origins = Origins[SymbolTable]("phase_=")
 *    // Commented out original enclosed for contrast
 *    // final def phase_=(p: Phase): Unit = {
 *    final def phase_=(p: Phase): Unit = origins {
 *  }}}
 *
 *  And that's it.  When the JVM exits it would issue a report something like this:
 {{{
 >> Origins scala.tools.nsc.symtab.SymbolTable.phase_= logged 145585 calls from 51 distinguished sources.

   71114   scala.tools.nsc.symtab.Symbols$Symbol.unsafeTypeParams(Symbols.scala:862)
   16584   scala.tools.nsc.symtab.Symbols$Symbol.rawInfo(Symbols.scala:757)
   15411   scala.tools.nsc.symtab.Symbols$Symbol.unsafeTypeParams(Symbols.scala:869)
   11507   scala.tools.nsc.symtab.Symbols$Symbol.rawInfo(Symbols.scala:770)
   10285   scala.tools.nsc.symtab.Symbols$Symbol.unsafeTypeParams(Symbols.scala:864)
    6860   scala.tools.nsc.transform.SpecializeTypes.specializedTypeVars(SpecializeTypes.scala:304)
    ...
 }}}
 *
 */

import scala.collection.{ mutable, immutable }
import Origins._

abstract class Origins {
  type Rep
  def newRep(xs: StackSlice): Rep
  def repString(rep: Rep): String
  def originClass: String
  
  private var _tag: String = null
  def tag: String = _tag
  def setTag(tag: String): this.type = {
    _tag = tag
    this
  }
  
  private val origins      = new mutable.HashMap[Rep, Int] withDefaultValue 0
  private def add(xs: Rep) = origins(xs) += 1
  private def total        = origins.values.foldLeft(0L)(_ + _)

  // We find the right line by dropping any from around here and any
  // from the method's origin class.
  private def dropStackElement(cn: String) =
    (cn startsWith OriginsName) || (cn startsWith originClass)

  // Create a stack and whittle it down to the interesting part.
  private def readStack(): Array[StackTraceElement] =
    (new Throwable).getStackTrace dropWhile (el => dropStackElement(el.getClassName))

  def apply[T](body: => T): T = {
    add(newRep(readStack()))
    body
  }
  def clear() = origins.clear()
  def show()  = {    
    println("\n>> Origins %s.%s logged %s calls from %s distinguished sources.\n".format(originClass, tag, total, origins.keys.size))
    origins.toList sortBy (-_._2) foreach {
      case (k, v) => println("%7s %s".format(v, repString(k)))
    }
  }
  def purge() = {
    show()
    clear()
  }
}

object Origins {
  private type StackSlice = Array[StackTraceElement]
  private val OriginsName = classOf[Origins].getName
  private val counters    = new mutable.HashSet[Origins]

  {
    // Console.println("\nOrigins loaded: registering shutdown hook to display results.")
    sys.addShutdownHook(counters foreach (_.purge()))
  }
  
  def apply[T: Manifest](tag: String): Origins = apply(tag, manifest[T].erasure)  
  def apply(tag: String, clazz: Class[_]): Origins = apply(tag, new OneLine(clazz))
  def apply(tag: String, orElse: => Origins): Origins = {
    counters find (_.tag == tag) getOrElse {
      returning(orElse setTag tag)(counters += _)
    }
  }

  class OneLine(clazz: Class[_]) extends Origins {
    type Rep                        = StackTraceElement
    val originClass                 = clazz.getName stripSuffix "$"
    def newRep(xs: StackSlice): Rep = xs(0)
    def repString(rep: Rep)         = "  " + rep
  }
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala Origins.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.