Как стать автором
Обновить

Комментарии 11

А AST нельзя обходить с помощью Visitor или Listener?

хмм. https://habrahabr.ru/post/269887/
Это больше похоже на перевод статьи из официального блога https://blog.golang.org/generate
Более подробно разверну свою мысль — в указанной статье описание использование утилиты go generate и обзор возможности кодогенерации. Это хорошая статья, в которой в частности разобрана утилита stringer (именно поэтому я назвал её «эталонной»). Я же решил показать небольшой пример как достаточно просто и быстро написать свой генератор кода на основе разбора ast. В данном случае одно дополняет другое.
Достаточно понятно написано, спасибо.
Остался только небольшой вопрос — как это все вызывается в реальном мире? Видел в коде костыли типа предложенного в официальном мануале:
//go:generate go tool yacc -o gopher.go -p parser gopher.y

но там не очень понятна связь генератора с тем местом, где а) он будет вызываться, б) где генерируемое будет использоваться.
А) вызываться будет в директории пакета при запуске утилиты go generate б) в вашем примере сгенерированный код будет просто положен в файл gopher.go (с первой строчкой package parser), дальше сборка идёт как обычно

Идея хороша, только выглядит чуть менее прозрачно, чем можно было бы.
Смысл того, что делается — автоматическая генерация конструктора. И весьма костыльно выглядит рождение коллекции объектов одного типа по методу у рандомного объекта этого типа.


То есть вместо Colors{}.List() более понятно для незнакомого с кодом человека генерировать обычную функцию ListOfAllColors()


Хотя, дело вкуса, наверное.

А если при добавлении константы забыть вызвать генератор? Чем это лучше, чем забыть обновить вручную написанную функцию? Или генерация автоматически происходит?

Запускать можно вручную или через go generate. Забыть запустить генератор можно, но это отчасти решается скриптом вида go generate && go build. Если есть отдельная система сборки/деплоя/ci то генерация прописывается туда наряду например с запуском тестов.

Всегда писать go generate && go build, с учетом того, что в 99% запусков ничего перегенерировать не надо? Разработчики будут забивать, ввиду бессмысленности, что таки чревато.


Гошная кодогенерация разве поощряется на уровне сборки/ci? Вроде же все пишут что надо сгенерированное коммитить в vcs.

Насчет ci вы правы, действительно я тут погорячился. go generate && go build можно положить в условный make.sh. Суть в том, что в любом случае надо постоянно запускать такие инструменты как например go fmt, go test, go vet. К ним добавляется еще go generate при условии использования генераторов.
Возможно в дальнейшем автозапуск go generate добавят например на уровне плагинов, например idea при коммите в vcs предварительно автоматически умеет запускать go fmt.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории