Хочу представить линтер для PHP readable. Сейчас в нем 16 правил, которые должны улучшить читабельность кода. К основным преимуществам можно отнести:
- скорость меньше секунды на 1000 файлов
- настройка baseline можно не исправлять все ошибки в проекте сразу, а создать конфигурацию с текущими ошибками. И игнорировать их, но реагировать на новые.
- правила писать проще чем в аналогах (субъективно)
Важные два дисклаймера:
- Я основной контрибьютор, поэтому могу быть субъективным. Изначально, readable написан для бельгийской компании officient. Они уже некоторое время его используют у себя внутри, и решили сделать readable открытым проектом.
- Он написан на JS.
Установка и запуск
readable устанавливаеться через npm:
$ npm install @officient/readable --save-dev
После установки, надо создать конфигурационный файл:
$ npx readable --init
И можно запускать:
$ npx readable
Правила
Сейчас в readable 16 правил:
- namespace-max-files максимальное количество файлов в неймспейсе
- argument-override запрет изменения значения аргументов функции
- file-max-size максимальное количество строк в файле
-
empty-catch запрет на пустой
catch
блок - class-comment перед объявлением класса должен быть какой-нибудь комментарий, что этот класс делает
-
forbidden-functions список запрещенных функция
(
eval
,print_r
...) -
missing-braces обязательные скобки в блоке
после
if
,for
... -
variable-length минимальная длина имени
переменной (можно добавлять исключения
$id
,$i
) - function-max-size максимальная длина функции
- loop-max-size максимальная длина цикла
-
forbidden-function-prefix запрет на
определенные слова в начале имени функции. Например,
checkSomething
возвращает булево значение, или бросает исключение? -
if-assigment присваивание внутри условия
if
-
complex-if смешивание
&&
и||
внутри условияif
- ternary-max-length максимальная длина строки с тернарным оператором
- loop-max-nest максимальная вложенность циклов
- max-nest максимальная вложенность блоков
Создание правил и внутренняя особенность
readable при проверки файла не строит синтаксическое дерево, а просто разбивает входной файл на массив токенов. Это существенное отличие от аналогов. Возможно, это где-то ограничивает возможности, но с другой стороны:
- readable быстрее. Так как, построение дерева из токенов довольно ресурсоёмкая задача.
- Правила писать субъективно проще. Потому что, не надо разбираться в конкретном представлении синтаксического дерева.
Давайте для примера возьмем правило loop-max-size. Весь его код:
const loops = ['for', 'foreach'];module.exports = { check(maxLines, tokens, report) { tokens.matchAll(loops, (token) => { const end = token.copy().step().stepToClosing(); // skip () end.step().stepToClosing(); const lines = (end.current().line - token.current().line); if (lines > maxLines) { report(`Loop is longer than ${maxLines} lines [${lines}].`, token.current()); } }); },};
В правиле указано:
- найти все
for
иforeach
. - Взять следующий токен
.step()
, это будет открывающая скобка(
. Дойти до закрывающей скобки.stepToClosing()
. - Повторить второй шаг но уже для тела цикла (
{
и}
). - Проверить длину тела цикла.
Вместо заключения
Я использую readable в своих проектах как дополнительный линтер для кода. Мне все нравится, особенно baseline (справедливости ради, такое есть и в Psalm). У него есть возможность занять нишу именно вспомогательного линтера.