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

Scala example source code file (Helpers.scala)

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

compiler, contextparam, exprclassof, list, macro, macrocontextuniverse, nil, nosymbol, nothingtpe, nsc, reflection, symbol, tree, type

The Helpers.scala Scala example source code

package scala.reflect.macros
package util

import scala.tools.nsc.typechecker.Analyzer

trait Helpers {
  self: Analyzer =>

  import global._
  import definitions._

  /** Transforms parameters lists of a macro impl.
   *  The `transform` function is invoked only for WeakTypeTag evidence parameters.
   *
   *  The transformer takes two arguments: a value parameter from the parameter list
   *  and a type parameter that is witnesses by the value parameter.
   *
   *  If the transformer returns a NoSymbol, the value parameter is not included from the result.
   *  If the transformer returns something else, this something else is included in the result instead of the value parameter.
   *
   *  Despite of being highly esoteric, this function significantly simplifies signature analysis.
   *  For example, it can be used to strip macroImpl.paramss from the evidences (necessary when checking def <-> impl correspondence)
   *  or to streamline creation of the list of macro arguments.
   */
  def transformTypeTagEvidenceParams(macroImplRef: Tree, transform: (Symbol, Symbol) => Symbol): List[List[Symbol]] = {
    val runDefinitions = currentRun.runDefinitions
    import runDefinitions._

    val MacroContextUniverse = definitions.MacroContextUniverse
    val treeInfo.MacroImplReference(isBundle, _, _, macroImpl, _) = macroImplRef
    val paramss = macroImpl.paramss
    val ContextParam = paramss match {
      case Nil | _ :+ Nil                                       => NoSymbol // no implicit parameters in the signature => nothing to do
      case _ if isBundle                                        => macroImpl.owner.tpe member nme.c
      case (cparam :: _) :: _ if isMacroContextType(cparam.tpe) => cparam
      case _                                                    => NoSymbol // no context parameter in the signature => nothing to do
    }
    def transformTag(param: Symbol): Symbol = param.tpe.dealias match {
      case TypeRef(SingleType(SingleType(_, ContextParam), MacroContextUniverse), WeakTypeTagClass, targ :: Nil) => transform(param, targ.typeSymbol)
      case _                                                                                                     => param
    }
    ContextParam match {
      case NoSymbol => paramss
      case _        =>
        paramss.last map transformTag filter (_.exists) match {
          case Nil         => paramss.init
          case transformed => paramss.init :+ transformed
        }
    }
  }

  /** Increases metalevel of the type, i.e. transforms:
   *    * T to c.Expr[T]
   *
   *  @see Metalevels.scala for more information and examples about metalevels
   */
  def increaseMetalevel(pre: Type, tp: Type): Type = {
    val runDefinitions = currentRun.runDefinitions
    import runDefinitions._

    transparentShallowTransform(RepeatedParamClass, tp) {
      case tp => typeRef(pre, MacroContextExprClass, List(tp))
    }
  }

  /** Transforms c.Expr[T] types into c.Tree and leaves the rest unchanged.
   */
  def untypeMetalevel(tp: Type): Type = {
    val runDefinitions = currentRun.runDefinitions
    import runDefinitions._

    transparentShallowTransform(RepeatedParamClass, tp) {
      case ExprClassOf(_) => typeRef(tp.prefix, TreesTreeType, Nil)
      case tp => tp
    }
  }

  /** Decreases metalevel of the type, i.e. transforms:
   *    * c.Expr[T] to T
   *    * Nothing to Nothing
   *    * Anything else to NoType
   *
   *  @see Metalevels.scala for more information and examples about metalevels
   */
  def decreaseMetalevel(tp: Type): Type = {
    val runDefinitions = currentRun.runDefinitions
    import runDefinitions._
    transparentShallowTransform(RepeatedParamClass, tp) {
      case ExprClassOf(runtimeType) => runtimeType
      // special-casing Nothing here is a useful convention
      // that enables no-hassle prototyping with `macro ???` and `macro { ...; ??? }`
      case nothing if nothing =:= NothingTpe => NothingTpe
      case _ => NoType
    }
  }
}

Other Scala source code examples

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