aboutsummaryrefslogtreecommitdiff
path: root/libraries/capture_args/macros.scala
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/capture_args/macros.scala')
-rw-r--r--libraries/capture_args/macros.scala50
1 files changed, 50 insertions, 0 deletions
diff --git a/libraries/capture_args/macros.scala b/libraries/capture_args/macros.scala
new file mode 100644
index 0000000..8f2d747
--- /dev/null
+++ b/libraries/capture_args/macros.scala
@@ -0,0 +1,50 @@
+package cbt.capture_args
+import scala.reflect._
+import scala.reflect.macros.blackbox.Context
+
+case class Argument( annotations: Seq[annotation.Annotation], name: String, values: Option[Seq[String]] ){
+ def toSeqOption = values.map( name +: _ )
+}
+case class Signature( name: String, args: Seq[Argument] )
+object `package`{
+ def captureArgsImplementation(c: Context): c.Tree = {
+ import c.universe._
+
+ def literal( a: Any ) = Literal(Constant(a))
+ def ident( name: String ) = Ident(TermName(name))
+
+ def findOwnerRecursive(symbol: Symbol, predicate: Symbol => Boolean): Option[Symbol] = {
+ Option(symbol).flatMap{
+ s =>
+ if(s == NoSymbol) None else if(predicate(s)) Some(s) else findOwnerRecursive(s.owner, predicate)
+ }
+ }
+
+ val method: MethodSymbol = (
+ findOwnerRecursive(c.internal.enclosingOwner, _.isMethod).map(_.asMethod)
+ orElse
+ findOwnerRecursive(c.internal.enclosingOwner, _.isClass).map(_.asClass.primaryConstructor.asMethod)
+ getOrElse {
+ c.error(
+ c.enclosingPosition,
+ "embed needs to be called in the body of a qualified method"
+ )
+ ???
+ }
+ )
+ val name = literal(method.name.decodedName.toString)
+ // Note: method.paramLists requires explicitly annotated result type
+ val params = method.paramLists.flatten.map(_.asTerm)
+
+ val args = params.map{ s =>
+ val name = literal( s.name.decodedName.toString )
+ val i = ident( s.name.toString )
+ q"_root_.cbt.capture_args.Argument( _root_.scala.Seq( ..${s.annotations.map(_.tree)} ), $name, valueToStrings($i) )"
+ }
+ val tree = q"""
+ _root_.cbt.capture_args.Signature( name = $name, args = Seq( ..$args ) )
+ """
+ tree
+ }
+ def captureArgs: Signature = macro captureArgsImplementation
+}