Расширения верхнего уровня должны сохранять количество аннотаций, их разновидности и их имена, с единственным исключением, что класс может расширяться в одноименный класс плюс одноименный модуль, в котором если они автоматически становятся компаньонами согласно предыдущему правилу.
https://docs.scala-lang.org/overviews/macros/annotations.html
Таким образом, вы можете преобразовать верхний уровень
@annot
class A
в
class A
object A
или
@annot
object A
в
class A
object A
Также существовал c.introduceTopLevel
, но он был удален.
Context.introduceTopLevel
. API Context.introduceTopLevel
, который раньше был доступен в ранних этапах сборки Scala 2.11.0 как ступенька к макросам типов, был удален из окончательной версии, поскольку макросы типов были отклонены для включения в Scala и прекращены. в макро-раю.
https://docs.scala-lang.org/overviews/macros/changelog211.html
Scala Макрос: определение объекта верхнего уровня
introduceTopLevel
предоставил давно запрашиваемую функциональность по генерации определений, которые можно использовать вне макрорасширений. Однако метапрограммисты быстро обнаружили, что introduceTopLevel
опасно. Область верхнего уровня - это ресурс, совместно используемый проверкой типов и пользовательскими метапрограммами, поэтому изменение его с помощью introduceTopLevel
может привести к проблемам с порядком компиляции. Например, если один файл в процессе компиляции полагается на определения, созданные расширением макроса, выполняемым в другом файле, компиляция первого перед последним может привести к неожиданным ошибкам компиляции.
https://infoscience.epfl.ch/record/226166/files/EPFL_TH7159.pdf (раздел 5.2.3 Заключение)
Если компаньон, который вы хотите создать, уже существует, то компаньон, который вы возвращаете в аннотации макроса macroTransform
, заменит оригинал. Не нужно опасаться, что будет два «товарища», компилятор за этим будет следить. Но, конечно, обычно вы подходите, если это так (независимо от того, есть ли только аннотируемый или аннотируемый + компаньон).