宏注释的类型 [英] Type of a macro annottee

查看:56
本文介绍了宏注释的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获取宏注释"类型(当前")?

How do I get the ("current") type of a macro annottee?

import scala.annotation.StaticAnnotation
import scala.reflect.macros._
import language.experimental.macros

class myself extends StaticAnnotation {
  def macroTransform(annottees: Any*) = macro myselfMacro.impl
}
object myselfMacro {
  def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
    import c.universe._
    val a = annottees.head
    println(s"static type = ${a.staticType}")
    println(s"actual type = ${a.actualType}")
    c.Expr[Any](Literal(Constant()))
  }
}

测试:

@myself class Foo

输出:

static type = Nothing
actual type = null

我想要该类型的原因是我想将其用作类型参数,例如Bar[Foo]

The reason I want that type is that I want to use it as a type parameter, e.g. Bar[Foo]

修改:

好的,所以我认为正确的方法是这样的:

Ok, so I think the correct approach is like this:

def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
  import c.universe._
  val v    = annottees.head.asInstanceOf[ClassDef]
  val tpe  = v.tpe // <- tpe is null as the annotated type is not yet type checked!
  val tpe2 = if (tpe == null)
    c.typeCheck(v).tpe // <- fails with a compiler error (assertion failure)
  else
    tpe
  println(s"Type of annottee: $tpe2")
  ???
}

但是给Eugene Burmako的帖子,它看起来像目前不可能 ...

But given this post by Eugene Burmako, it looks like it is currently not possible...

推荐答案

在扩展宏注释时,注释者尚未为其创建符号(有时是,但是没有给出).结果,它不能由符号/类型来引用,而只能由树(例如树)来引用. Ident(TypeName("Foo")).当然,c.typecheck的结果将为您提供一些符号/类型,但仅用于自省,不能用作参考.

When the macro annotation is being expanded, the annottee doesn't have a symbol created for it yet (sometimes it does, but it's not at given). As a result, it cannot be referenced by a symbol/type, only by a tree, e.g. Ident(TypeName("Foo")). Sure, the result of c.typecheck will give you some symbol/type, but it would be usable only for introspection purposes, not as a point of reference.

如果您避免出现卫生问题,则此方法应该很好用.如果您的同伴对象定义了名为Foo的类/类型成员,则Serializer[Foo]中的Foo将绑定到同伴的成员,而不是原始类.目前,还没有很好的解决方法(scalac本身必须在为案例类生成应用/未应用方法时解决此问题,但您不希望知道如何完成).我们正计划为此提供解决方案,但我们只会在下个月开始研究它,因此要等到它降落在树干甚至是天堂之前,还需要一段时间.

This approach should work just fine if you steer clear from hygiene problems. If your companion object defines a class/type member called Foo, then Foo in Serializer[Foo] is going to bind to companion's member, not to the original class. At the moment there's no good way of dealing with that (scalac itself has to solve this problem when generating apply/unapplymethods for case classes, but you don't want to know how it's done). We're planning to provide a solution for this, but we'll only start working on it in the next month, so it'll be a while until it lands in trunk or even paradise.

这篇关于宏注释的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆