DEV Community

Toshi Ossada for flutterbrasil

Posted on

Macros no Flutter/Dart: A Revolução da Metaprogramação que Você Esperava

Macros no Flutter/Dart: A Revolução da Metaprogramação que Você Esperava

Fala Devs,

No ultimo Google I/O tivemos muitas novidades, e uma delas que era uma das mais esperadas foi a confirmação dos Macros para fase experimental (que significa que logo sairá pra stable).

Mas o que são Macros?

Macros são um recurso que visa revolucionar a metaprogramação, ou seja, a habilidade de escrever código que manipula outros códigos.

Mas o que isso significa?

Imagine uma tarefa comum que realizamos com frequência hoje toJson() e fromJson().

Hoje temos duas maneiras de realizar essa tarefa, podemos simplesmente fazer os métodos na mão.

O problema desse método é que toda hora que precisamos adicionar um campo novo é no mínimo em 3 lugares que precisamos fazer alteração, um processo que pode ser chato.

Outra forma é utilizarmos uma biblioteca terceira que irá gerar todo esse código com a ajuda do odiado build_runner, como por exemplo o json_serializable

Nesse caso temos alguns fatos que podem frustrar os desenvolvedores, primeiro é que preciso adicionar um “quase” extenso boilerplate

E “outro” problema é que toda alteração precisamos executar novamente o build_runner, as vezes não é um processo tão demorado, entretanto se torna um processo chato de ter que executar o build_runner em toda alteração

Hoje temos que fazer estes processos pois no dart que está embedado no Flutter é nerfado e não temos a possibilidade de utilizar Reflections ou as famigeradas Mirrors alegando que há trade-off que talvez não valeria a pena para habilitar as Mirros no Flutter.

Mas calma, a equipe do Flutter não deu as costas e ignorou este problema. No Flutter Foward que ocorreu ano passado (2023) eles anunciaram que iriam começar a trabalhar em uma nova feature para resolver este problema, eles anunciaram que brevemente iriam lançar as Macros.

Depois de muita espera, chegaram até rolar boatos que eles iriam desistir das macros, neste Google I/O (2024) eles anunciaram que já encontra em fase experimental.

Para começar a testar as macros precisamos ter em mente que ainda está em fase experimental, então não está disponível no canal stable (Espero que você esteja usando esse canal para desenvolver sus apps) então nossa primeira tarefa para habilitar a utilização dos macros é apontar para o canal master

Execute:

flutter channel master

Isso fará com que apontemos para o dart 3.5

E se executarmos o comando flutter channel irá nos apresentar que está apontando para a master com um asterisco (*)

Outra etapa (caso use visual studio code) é apontarmos as extensões do dart e flutter para a pré release, procure as extensões e pressione o botão “switch to Pre-Release Version”

Faça o mesmo procedimento para o Flutter

Precisamos também habilitar no analysis_options.yaml a feature experimental dos macros

Pronto agora já podemos utilizar a macros, algo bom que é que não partiremos de um mundo que teremos que criar todas as macros pois a equipe do Dart em paralelo já está desenvolvendo alguns macros que para utiliza-los basta importar em nosso projeto e para esse processo que citamos acima do toJson() e fromJson() existe o pacote json que está publicado por labs.dart.dev (publicador da equipe do dart para pacotes que estão em experimental)

Para adicionar basta executar um pub add

Para utiliza-lo basta colocarmos a annotation em nossa classe @JsonCodable()

Note que no VS Code ele habilitou um botão “Go to Augmentation” se clicarmos nele podemos ver os macros que foram gerados

E se alterar o código da classe e salvar ele automaticamente vai alterar minhas macros

Impressionante a velocidade

Outro ponto legal é que também podemos fazer nossos próprios macros, vamos então automatizar a geração do toString()

Notamos que iremos necessitar de 2 informações da classe, o nome da classe e os campos

Para criar uma classe iremos criar uma class com o modificador macro e devemos implementar a ClassDeclaration, um ponto importante é que fica obrigatório a criação de um construtor que seja constante.

Feito isso implementamos o método buildDeclarationsForClass que tem dois parâmetros, a clazz (está com Z pois class é uma palavra reservada do dart) que é onde irá conter as informações da classe (como o nome da classe) e também temos o builder que iremos utilizar para gerar o código na macro.

Para recuperar o nome da classe utilizamos o clazz.identifier.name e para recuperar os atributos da classe utilizamos o builder.fieldsOf(clazz) lembrando que ele é uma Feature então precisamos usar o await na execução do método e adicionar o async na função.

Para gerar o código utilizaremos o builder.declareIntype() e geraremos o código em uma String que podemos separar por virgula(,) para que não fique uma linha gigantesca

Ressaltando que a saída do nosso código será “campo: $campo” então é necessário adicionar o & com a tag escape na frente (**).

Para utiliza-lo em nossa classe basta adicionar a annotation que será o mesmo nome do macro criado.

E ele automaticamente irá gerar o código no macro

Agora podemos utiliza-lo em nosso main.dart

Para executar precisamos adicionar a tag — enable-experiment=macros

Ou podemos também deixar configurado em nosso launch.json

Ressaltando novamente que os macros está em fase experimental e podemos ter alguns bugs que estão sendo corrigidos pela equipe do Dart, mas esperamos que logo(talvez ainda esse ano) já sairá uma versão em em stable para nós deliciar com os macros.

Se quiser ler mais a respeito das macros visite https://dart.dev/go/macros

Tembém gravei um video no canal da Flutter Brasil de como podemos utilizar os macros, confira:


Monorepo (Por Que Essa Estratégia Funciona em Grandes Empresas?)

Entre em nosso discord para interagir com a comunidade e ficar por dentro de todas as nossas publicações: https://www.flutterbrasil.com.br

Top comments (0)