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

Scala example source code file (Calculate.scala)

This example Scala source code file (Calculate.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

calculate, int, map, nosymbol, reflection, reifier, reify, string, symbol, tree, type, unit

The Calculate.scala Scala example source code

package scala.reflect.reify
package phases

trait Calculate {
  self: Reifier =>

  import global._

  implicit class RichCalculateSymbol(sym: Symbol) {
    def metalevel: Int = { assert(sym != null && sym != NoSymbol); localSymbols.getOrElse(sym, 0) }
    def isLocalToReifee = (localSymbols contains sym) // todo. how do I account for local skolems?
  }

  implicit class RichCalculateType(tpe: Type) {
    def isLocalToReifee = tpe != null && (tpe exists (tp => (localSymbols contains tp.typeSymbol) || (localSymbols contains tp.termSymbol)))
  }

  private def localSymbols: Map[Symbol, Int] = state.localSymbols // set of all symbols that are local to the tree to be reified
  private def localSymbols_=(value: Map[Symbol, Int]): Unit = state.localSymbols = value
  private def registerLocalSymbol(sym: Symbol, metalevel: Int): Unit =
    if (sym != null && sym != NoSymbol) {
      if (localSymbols contains sym)
        assert(localSymbols(sym) == metalevel, "metalevel mismatch: expected %s, actual %s".format(localSymbols(sym), metalevel))
      else
        localSymbols += (sym -> metalevel)
    }

  /**
   *  Merely traverses the reifiee and records symbols local to the reifee along with their metalevels.
   */
  val calculate = new Traverser {
    // see the explanation of metalevels in `Metalevels`
    var currMetalevel = 1

    override def traverse(tree: Tree): Unit = tree match {
      case TreeSplice(_) =>
        currMetalevel -= 1
        try super.traverse(tree)
        finally currMetalevel += 1
      case tree if tree.isDef =>
        if (reifyDebug) println("boundSym: %s of type %s".format(tree.symbol, (tree.productIterator.toList collect { case tt: TypeTree => tt }).headOption.getOrElse(TypeTree(tree.tpe))))
        registerLocalSymbol(tree.symbol, currMetalevel)

        bindRelatedSymbol(tree.symbol.sourceModule, "sourceModule")
        bindRelatedSymbol(tree.symbol.moduleClass, "moduleClass")
        bindRelatedSymbol(tree.symbol.companionClass, "companionClass")
        bindRelatedSymbol(tree.symbol.companionModule, "companionModule")
        Some(tree.symbol) collect { case termSymbol: TermSymbol => bindRelatedSymbol(termSymbol.referenced, "referenced") }
        Some(tree) collect { case labelDef: LabelDef => labelDef.params foreach (param => bindRelatedSymbol(param.symbol, "labelParam")) }
        def bindRelatedSymbol(related: Symbol, name: String): Unit =
          if (related != null && related != NoSymbol) {
            if (reifyDebug) println("boundSym (" + name + "): " + related)
            registerLocalSymbol(related, currMetalevel)
          }
        super.traverse(tree)
      case _ =>
        super.traverse(tree)
    }
  }
}

Other Scala source code examples

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