Add ff_pipeline:do parse transform - #111
Conversation
| transform_do(Tree) -> | ||
| TreePos = erl_syntax:get_pos(Tree), | ||
| case Tree of | ||
| ?Q("do(_@Tag, fun() -> _@@Body end)") -> |
There was a problem hiding this comment.
Мне кажется не очень корректным перефигачивать конструкции с do(...), даже в том случае, если эту псевдофункцию не импортировали в модуль. Кажется лучше было бы пойти по одному из двух путей:
- перефигачивать, только если был импорт;
- перефигачивать вообще все
do, не требуя никаких имортов, только включения parse transform (не пытаться сделать вид, чтоdo‒ это функция в модулеff_pipeline).
There was a problem hiding this comment.
Да, согласен, это не достаточно явно.
перефигачивать, только если был импорт;
Попробую сделать.
перефигачивать вообще все do, не требуя никаких имортов
На это агрятся IDE. Плагин, что я использовал, ожидаемо не смог обработать parse transform.
Ну и, справедливости ради, do это все же функция ff_pipeline, тут делается что-то вроде инлайнинга частных случаев.
There was a problem hiding this comment.
Попробую сделать.
👍
На это агрятся IDE. Плагин, что я использовал, ожидаемо не смог обработать parse transform.
Забавно, я не считаю это ожидаемым поведением. Это же просто ещё одна опция компиляции.
Ну и, справедливости ради,
doэто все же функцияff_pipeline, тут делается что-то вроде инлайнинга.
О, это я упустил.
| ?Q("-import(ff_pipeline, ['@_@FilteredImports'/0])."). | ||
|
|
||
| is_import_not_replaced(ImportItem) -> | ||
| case ?Q("-export(['@_ImportItem'/0]).") of |
There was a problem hiding this comment.
Очень долго думал, почему тут export. Может комментом описать, что тут происходит и почему так?
There was a problem hiding this comment.
Да, добавлю. Или посмотрю, чем из erl_syntax можно воспользоваться чтобы стало понятнее.
Это нужно потому, что грамматика языка не позволяет однозначно распарсить do/1. И, по-умолчанию, приоритет отдается предположению, что это деление атома на число. Как конструкцию "нечто с арностью" парсер интерпретирует это выражение только когда оно находится внутри атрибутов модуля. Причем не всех, а только известных ему.
|
если это место переделывать, то может быть есть смысл добавить кумулятивный контекст (номер строки, имя файла) возникновения/пробрасывания ошибки. иначе затруднительно анализировать без полного знания кода. |
Продолжение #26
Dialyzer порой не может проверить типы в конструкциях вида
do(fun() -> bar end), он часто определяет тип возвращаемого внутренней функцией значения какany().Как решение этой проблемы, в этом PR предлагается автоматически преобразовать такие конструкции в более дружественную к dialyzer форму.