我想创建一个密封的抽象和案例类的宏生成层次结构。有一个与http://docs.scala-lang.org/overviews/macros/typemacros.html类似的例子,但现在已经过时了。这还有可能吗?
我认为为某些指定的语法生成类型安全的AST会非常强大。理想情况下,IDE可以解析所有类。
答案 0 :(得分:22)
首先进行一些无耻的自我推销:Eugene Burmako我明天type providers就Scalar 2014这个密切相关的主题发表演讲,我鼓励你去看一看如果您对此类事情感兴趣,我们会在the example project进行讨论。
虽然不再支持类型宏,但您可以使用macro annotations中的macro paradise完成相同的操作(可作为Scala 2.10和2.11的插件使用):
import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.Context
// Add constructor arguments here.
class expand extends StaticAnnotation {
def macroTransform(annottees: Any*) = macro Expander.expand_impl
}
object Expander {
def expand_impl(c: Context)(annottees: c.Expr[Any]*) = {
import c.universe._
annottees.map(_.tree) match {
case List(q"trait $name") => c.Expr[Any](
// Add your own logic here, possibly using arguments on the annotation.
q"""
sealed trait $name
case class Foo(i: Int) extends $name
case class Bar(s: String) extends $name
case object Baz extends $name
"""
)
// Add validation and error handling here.
}
}
}
然后:
scala> @expand trait MyADT
defined trait MyADT
defined class Foo
defined class Bar
defined module Baz
您可以在编译时为注释添加参数,例如,允许您解析可用于生成ADT实现的外部资源。
宏观注释非常具有实验性,它们的状态仍然悬而未决 - 例如,无法保证它们将与Scala 2.12一起发布。使用普通的def
宏和结构类型可以实现类似的东西(虽然不是很干净) - 请参阅上面链接的the example project以获取更多细节和一些演示。在任何情况下,这种机制都是许多人感兴趣的,包括Scala宏系统的开发人员,所以即使宏观注释在某些时候消失,也可能有某种方法来完成你在这里描述的内容。