在类引用中使用ClassSymbol

问题描述

我有一个PHP,并且想生成一个抛出ClassSymbol的零参数方法。这是我的尝试:

假设???是我们object Test的类型。

I。

ClassSymbol

结果

val sym = //the ClassSymbol
val tpe = tq"$sym.type"
q"def foo(): $tpe = ???"

II。

[error]  stable identifier required,but Test.type found.

结果

val sym = //the ClassSymbol
val tpe = tq"${sym.name}.type"
q"def foo(): $tpe = ???"

III。

[error]  found   : c.universe.TypeName
[error]  required: c.universe.TermName
[error]         val tpe = tq"${sym.name}.type"

结果

val sym = //the ClassSymbol
val tpe = tq"${TermName(sym.name.toString)}.type"
q"def foo(): $tpe = ???"

所以我最终使用了看起来很吓人的方法 III

在准引用中使用Compiles successfully 的“本地”方法吗?

解决方法

我们可以保存您的方法II

val tpe = tq"${sym.name.toTermName}.type"

这类似于III,但没有手动处理字符串。

也不要忘记,除了准引用之外,您始终可以使用手动解析来构建树

val tree = tb.parse(s"def foo(): ${sym.name}.type = ???") // for macros c.parse instead of tb.parse 

关于“本机”方式,现在最好使用ModuleSymbol

val sym = rm.moduleSymbol(Test.getClass)

val sym = typeOf[Test.type].termSymbol.asModule 

而不是ClassSymbol

val sym0 = rm.classSymbol(Test.getClass)

val sym0 = typeOf[Test.type].typeSymbol.asClass 

测试:

val tpe = tq"$sym.type"
val tree = q"def foo(): $tpe = ???"
tb.typecheck(tree) // no exception

我使用了运行时反射,但是对于宏来说却很相似。

如果您已经拥有ClassSymbol,则可以将其转换为ModuleSymbol

val sym = sym0.companionSymbol // not sym0.companion but .companionSymbol is deprecated

val sym = sym0.asInstanceOf[scala.reflect.internal.Symbols#ClassSymbol].sourceModule.asInstanceOf[ModuleSymbol]

val sym = sym0.owner.info.decl(sym0.name.toTermName)

Get the module symbol,given I have the module class,scala macro

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...