Created
January 19, 2013 09:27
-
-
Save wangzaixiang/4571571 to your computer and use it in GitHub Desktop.
Scala Macros Usage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package macro_basic | |
import scala.reflect.macros.Context | |
import scala.language.experimental.macros | |
object BeanMacros { | |
def ToString[A](obj: A): String = macro toStringMacro[A] | |
def toStringMacro[A](c: Context)(obj: c.Expr[A]): c.Expr[String] = { | |
import c.universe._ | |
val tpe = obj.actualType | |
val className = tpe.typeSymbol.name | |
val declaredGetters = tpe.declarations.filter(_.asTerm.isGetter) | |
// .+ is actually the method "$plus" | |
val plus = "$plus" | |
// start: "ClassName" | |
val startLit = Literal(Constant(className + "(")) | |
val getterBody = declaredGetters.foldLeft(startLit: TermTree) { (soFar, getSym) => | |
// ((((soFar.+(", ")).+(fieldName)).+("=")).+(obj.getter)) | |
val name = Apply(Select(soFar, plus), List(Literal(Constant(getSym.name.toString + "=")))) | |
val namePlusAccess = Apply(Select(name, plus), List(Select(obj.tree, getSym.name))) | |
// unless last getter, append a ", " | |
if (getSym != declaredGetters.last) { | |
Apply(Select(namePlusAccess, plus), List(Literal(Constant(", ")))) | |
} else { | |
namePlusAccess | |
} | |
} | |
// append end ")" | |
val body = Apply(Select(getterBody, plus), List(Literal(Constant(")")))) | |
c.Expr[String](body) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package macro_basic | |
import scala.reflect.macros.Context | |
import scala.language.experimental.macros | |
object LogMacros { | |
def print(msg: String) = macro Impls.print | |
def debug(msg: String) = macro Impls.debug | |
var isDebugEnabled = false | |
object Impls { | |
def print(c: Context)(msg: c.Expr[String]): c.Expr[Any] = { | |
println("inside macro print") | |
c.universe.reify { | |
Console.println("Hello:" + msg.splice) | |
} | |
} | |
def debug(c: Context)(msg: c.Expr[String]) = { | |
c.universe.reify { | |
if(isDebugEnabled) Console.println(msg.splice) | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package macro_basic | |
import scala.reflect.macros.Context | |
import scala.language.experimental.macros | |
object SourceMacros { | |
def __FUNC__ = macro Impl.__FUNC__Impl | |
def __LINE__ = macro Impl.__LINE__Impl | |
def __FILE__ = macro Impl.__FILE__Impl | |
object Impl { | |
def __FUNC__Impl(c: Context) = { | |
c.enclosingMethod match { | |
case c.universe.DefDef(_, name, _, _, _, _) => | |
c.universe.reify(c.literal(name.toString).splice) | |
case _ => c.abort(c.enclosingPosition, "no enclosing method") | |
} | |
} | |
def __LINE__Impl(c: Context) = { | |
c.universe.reify { c.literal(c.enclosingPosition.line).splice } | |
} | |
def __FILE__Impl(c: Context) = { | |
c.universe.reify( c.literal(c.enclosingPosition.source.path).splice ) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment