scala - 在 scala 宏中获取完全限定的方法名称
问题描述
我使用 Scala 宏和匹配Apply
,我想获得被调用函数的完全限定名称。
例子:
println("") -> scala.Predef.println
scala.Predef.println("") -> scala.Predef.println
class Abc {
def met(): Unit = ???
}
case class X {
def met(): Unit = ???
def abc(): Abc = ???
}
val a = new Abc()
val x = new Abc()
a.met() -> Abc.met
new Abc().met() -> Abc.met
X() -> X.apply
X().met() -> X.met
x.met() -> X.met
x.abc.met() -> Abc.met
左边是我的代码,右边是我想要得到的。可能吗?如何?
解决方案
这是宏:
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
object ExampleMacro {
final val useFullyQualifiedName = false
def methodName(param: Any): String = macro debugParameters_Impl
def debugParameters_Impl(c: blackbox.Context)(param: c.Expr[Any]): c.Expr[String] = {
import c.universe._
param.tree match {
case Apply(Select(t, TermName(methodName)), _) =>
val baseClass = t.tpe.resultType.baseClasses.head // there may be a better way than this line
val className = if (useFullyQualifiedName) baseClass.fullName else baseClass.name
c.Expr[String](Literal(Constant(className + "." + methodName)))
case _ => sys.error("Not a method call: " + show(param.tree))
}
}
}
宏的用法:
object Main {
def main(args: Array[String]): Unit = {
class Abc {
def met(): Unit = ???
}
case class X() {
def met(): Unit = ???
def abc(): Abc = ???
}
val a = new Abc()
val x = X()
import sk.ygor.stackoverflow.q53326545.macros.ExampleMacro.methodName
println(methodName(Main.main(Array("foo", "bar"))))
println(methodName(a.met()))
println(methodName(new Abc().met()))
println(methodName(X()))
println(methodName(X().met()))
println(methodName(x.met()))
println(methodName(x.abc().met()))
println(methodName("a".getClass))
}
}
此示例的源代码包含以下内容:
- 它是一个多模块 SBT 项目,因为宏必须在单独的编译单元中,而不是使用宏的类
- 宏模块显式依赖于
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value,
推荐阅读
- javascript - 递归推送只添加最后一个元素
- polymorphism - 覆盖 vs 多态 vs 重载
- javascript - 如何使 Chrome 扩展程序将当前选项卡保存为 .url 的所需文件夹?
- vb.net - 替换文件中的字符串数据
- bash - composer 中的 bash 操作符,用于将最近的文件从一个 GCS 存储桶复制到另一个
- javascript - Javascript 如何在字符串中查找子字符串并查看图像
- flutter - Flutter中,如何给ListView添加跳转索引
- jsp - 自定义 JSP 标记属性不区分大小写
- dart - 如何比较相同类型的两个对象的值?
- javascript - 如何返回不同的数组?