Eu estou meio que bloqueado com a seguinte situação ( anotação de macro ). Suponha que eu tenha uma anotação chamada @factory
que visa gerar um método apply
para o traço anotado no object complementar correspondente. Por exemplo, dada a trait A
:
@factory trait A { val a1: Int }
o código esperado a ser gerado é o seguinte:
object A extends Factory[A] { def apply(_a1: Int) = new A { val a1 = _a1 } }
Agora suponha que tenhamos uma característica B
que herda de A
:
@factory trait B extends A { val b1: String }
que é suposto gerar:
object B extends Factory[B] { def apply(_a1: Int, _b1: String) = new B { val a1 = _a1 val b1 = _b1 } }
Neste último caso, preciso saber quais são os atributos existentes em A
, mas não sei como obter informações sobre eles . Ao lidar com annotations de macro, eu tenho access somente ao traço B
AST (como um ClassDef
). Embora seu template
contenha referências aos pais (como TypeTrees
), os campos tpe
e symbol
estão vazios.
Seria ótimo para mim ter access ao A
AST. No entanto, acho que isso não é viável. Portanto, qualquer símbolo ou tipo (apontando o pai ou o tipo atual) seria bom o suficiente.
Se você quiser ver mais detalhes de implementação, enviei o projeto para https://github.com/jesuslopez-gonzalez/cool-factory . Pode gerar a apply
para os valores locais.
As trees que entram em argumentos de anotação de macro são intencionalmente sem tipagem. No entanto, executar c.typeCheck(q"(??? :
fornecerá as informações que faltam. Não se esqueça de duplicate
a tree antes de digitar, porque c.typeCheck
mutação da tree, o que pode ser indesejável.
No caso de pai e filho serem declarados no mesmo escopo de não-nível superior, haverá um problema de typeCheck não ver o pai, pois as annotations de macro do c.typeCheck são executadas no escopo léxico pai, para que as annotations não sejam para ver escopos semi-construídos. Algo semelhante foi relatado aqui: https://github.com/aztek/scala-workflow/issues/2#issuecomment-23947943 .
A decisão de excluir o escopo atual do typechecking não é final. Nesta semana, estarei pensando um pouco mais sobre como as annotations de macro devem interagir com os escopos de inclusão e, provavelmente, alterá-lo para fazer o que você gostaria que fosse feito. Eu faria a mudança agora, mas preciso ter certeza de que não haverá nenhum comportamento insano decorrente dessa mudança.