Как сгенерировать класс / объект верхнего уровня с макросом scala - PullRequest
0 голосов
/ 16 июня 2020

Как мы знаем, в некоторых методах легко создать внутренний класс с помощью макроса scala. Но я хотел бы знать, можно ли создать класс / объект верхнего уровня? Если да, то как избежать генерации одного и того же класса дважды? моя scala версия - 2.11

1 Ответ

3 голосов
/ 16 июня 2020
Расширения верхнего уровня должны сохранять количество аннотаций, их разновидности и их имена, с единственным исключением, что класс может расширяться в одноименный класс плюс одноименный модуль, в котором если они автоматически становятся компаньонами согласно предыдущему правилу.

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, заменит оригинал. Не нужно опасаться, что будет два «товарища», компилятор за этим будет следить. Но, конечно, обычно вы подходите, если это так (независимо от того, есть ли только аннотируемый или аннотируемый + компаньон).

...