【问题标题】:How to preserve sugar, formatting, and whitespace in macro annotations (inline-meta)?如何在宏注释(内联元)中保留糖、格式和空格?
【发布时间】:2026-01-24 13:50:01
【问题描述】:

我正在将 Scala 函数导出为外部格式。为此,我使用scala.metaStaticAnnotation。比如:

@ExportFunctions
object MyFunctions {
  def max(x: Int, y: Int): Int = x max y
}

class ExportFunctions extends StaticAnnotation {
  inline def apply(defn: Any): Any = meta {
    defn match {
      case q"object $name extends { ..$earlydefns } with ..$parents { ..$stats }" =>
        stats.flatMap{
          case defn@Defn.Def(modifiers, fname, tparams, paramss, Some(returnType), body) =>
            println(body.syntax)
        }
      case _ =>
    }
    defn
  }
}

ExportFunctions extends StaticAnnotation 的实现中,函数体表示为一棵脱糖树:x.max(y)

但是,出于文档目的,拥有实际源代码会更好。或者至少是糖(x max y)。

有没有办法保留原始格式/糖?

【问题讨论】:

    标签: scala macros scala-macros scala-macro-paradise scalameta


    【解决方案1】:

    从 3.0.0-M8 开始,scala.meta 天堂宏注释被实现为从 scala-reflect 树到 scala.meta 树的树转换。这种方法无法获得诸如格式化或 cmets 之类的琐事,因此对您的问题的快速回答是:不,不使用宏注释。

    然而,scala.meta 有一个 api,它对格式和 cmets 等细节提供一流的支持。根据您的应用,您可能不需要宏注解,您可以将scala.meta parser 直接用作库。

    【讨论】: