【问题标题】:Using ClassSymbol in a quasiquote在 quasiquote 中使用 ClassSymbol
【发布时间】:2020-10-31 22:21:41
【问题描述】:

我有一个ClassSymbol 并想生成一个零参数方法抛出???。以下是我的尝试:

假设object Test 是我们拥有ClassSymbol 的类型。

我。

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

结果

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

二。

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

结果

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

III.

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

结果

Compiles successfully

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

是否有“原生”方式在准引用中使用ClassSymbol

【问题讨论】:

    标签: scala metaprogramming abstract-syntax-tree scala-macros scala-quasiquotes


    【解决方案1】:

    我们可以保存您的方法 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

    【讨论】:

    • 谢谢。我想当使用任意类类型时,应该在插入.type 后缀之前测试它是否是Module (isModule)。
    猜你喜欢
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多