scala - 在运行时访问函数源代码的宏

标签 scala reflection macros scala-macros

使用 Scala 宏我想访问函数 f 的源代码。

这是我的问题的简化示例:

def logFImplementation(f: => Boolean) {
    val sourceCodeOfF: String = ... // <-- how to get source code of f??

    println("Scala source of f=" + sourceCodeOfF)
}

因此对于:
logFImplementation { val i = 5; List(1, 2, 3); true }

它应该打印:
Scala source of f=val i: Int = 5; immutable.this.List.apply[Int](1, 2, 3); true

(现在我测试了 Macro to access source code text at runtime 它对 { val i = 5; List(1, 2, 3); true }.logValueImpl 非常有效,但对于 f.logValueImpl 它只打印 f 。)

感谢您的任何建议。

最佳答案

这可能是“线程死灵术”,因为这个问题已经很老了。我不得不努力解决这个问题。

import scala.reflect.macros.blackbox.Context
import scala.language.experimental.macros
object FunctionWrapper {

  implicit def apply[P, R](fn: P => R): FunctionWrapper[P, R] = macro apply_impl[P, R]

  def apply_impl[P: c.WeakTypeTag, R: c.WeakTypeTag](c: Context)(fn: c.Expr[P => R]): 
                  c.Expr[FunctionWrapper[P, R]] = {
    import c.universe._
     c.Expr(q" new FunctionWrapper($fn, ${show(fn.tree))})")
  }
}
class FunctionWrapper[P, R](val fn: P => R, description: String) 
      extends Function1[P, R] {
  def apply(p: P) = fn(p)
  override def toString = description
}

它的一个使用示例(必须在单独的编译模块中)是:
 object FunctionWrapperUser {
  def main(args: Array[String]): Unit = {
    val double = FunctionWrapper((i: Int) => i * 2)
    println(s"double to String is $double")
    println(double(4))
  }
}

关于scala - 在运行时访问函数源代码的宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25409219/

相关文章:

java - 如何使用泛型类型访问静态内部类中的字段? (非常困难)

c++ - 在 C++ 中使自己的宏先于库宏

java - Spark RDD- map 与 mapPartitions

scala - SBT Publish local 不包含依赖

c# - 反编译动态创建的类/类型

c - 这些奇怪的宏定义是什么意思(它们是否正确?)

c++ - 错误 C2070 - 未指定外部数组大小。 - 传递给 MACRO 的数组

html - HTML 模板中的 playframework JsValue

scala - Kafka 流与 Scala

java - 使用反射替换 java.net.URL URLStreamHandlerFactory 是个好主意吗?