如何获得其经隐式转换为可用的成员的`Symbol`?

问题描述 投票:0回答:1

我写这产生一些像这样的代码宏:

q"_root_.ru.lmars.macropack.TagsAndTags2.$tagName(..$tagParams)"

但我想生成只有$tagName定义这个代码,并有一定的“标记”(如注释或一些特殊的返回类型)。如何获得Symbol对这个$tagName

这很容易,如果$tagNameTagsAndTags2对象中定义的:

object TagsAndTags2
{
    def dialog(caption: String): String = ???
}

你可以写这样的事情来获得Symbol dialog的:

val tagParentAccess = q"_root_.ru.lmars.macropack.TagsAndTags2"
val tagParent = c.typecheck(tagParentAccess, silent = true)
val tagSymbol = tagParent.tpe.member(tagName)

但如何做同样的,如果通过$tagName的隐式转换可用?

implicit final class UserTags(x: TagsAndTags2.type)
{
    def dialog(caption: String): String = ???
}
scala scala-macros
1个回答
1
投票

这里是一个快速和肮脏的例子(我已经试过了在斯卡拉2.11):

温度/ Foo.scala:

package temp

import scala.language.experimental.macros

object Foo {
  def printSymbol(name: String): Unit = macro FooMacro.printSymbol
}

object FooTarget

private class FooMacro(val c: scala.reflect.macros.blackbox.Context) {

  import c.universe._

  def printSymbol(name: Tree): Tree = {
    name match {
      case Literal(Constant(lv)) =>
        val a = q"_root_.temp.FooTarget.${TermName(lv.toString)}"
        val ca = c.typecheck(a)
        println("checked apply symbol", ca.symbol)
    }

    q"()"
  }

}

温度/ Bar.scala:

package temp

object Implicits {

  implicit class BarObjContainer(f: FooTarget.type) {

    object bar

  }

}

object UseMacro {

  import Implicits._

  val v = Foo.printSymbol("bar")

}

ca.symbol你想要什么?

=== UPDATE ===

这里是快速和肮脏的演示与PARAM功能:

温度/ Foo.scala:

package temp

import scala.language.experimental.macros

object Foo {
  def printSymbol(name: String): Unit = macro FooMacro.printSymbol
}

object FooTarget

private class FooMacro(val c: scala.reflect.macros.blackbox.Context) {

  import c.universe._

  def printSymbol(name: Tree): Tree = {
    name match {
      case Literal(Constant(lv)) =>
        val nameStr = lv.toString
        val f = q"_root_.temp.FooTarget.${TermName(nameStr)}(_)"
        c.typecheck(f) match {
          case Function(_, Apply(s@Select(_, TermName(`nameStr`)), _)) =>
            println(s.symbol)
        }
    }

    q"()"
  }

}

温度/ Bar.scala:

package temp

object Implicits {

  implicit class BarObjContainer(f: FooTarget.type) {

    def bar(baz: String): Unit = ()

  }

}

object UseMacro {

  import Implicits._

  val v = Foo.printSymbol("bar")

}

s为“杆”的方法的符号。

© www.soinside.com 2019 - 2024. All rights reserved.