Метод context.report

Назначение и роль в архитектуре правила

context.report является центральным механизмом внутри пользовательских правил ESLint, отвечающим за фиксацию найденных нарушений. Любое правило, анализирующее AST-код, в конечном итоге использует именно этот метод для передачи информации о проблеме в ядро линтера.

Объект context, передаваемый в функцию правила, инкапсулирует среду выполнения правила: текущий файл, настройки, утилиты для работы с кодом и, ключевое, метод report. Через него правило сообщает ESLint:

  • что именно нарушено;
  • где находится нарушение;
  • насколько оно критично;
  • как его можно исправить.

Фактически context.report связывает анализ и результирующую диагностику.


Базовая сигнатура и варианты вызова

Современный ESLint поддерживает два основных формата вызова:

Объектный формат (рекомендуемый)
context.report({
  node,
  message: "Unexpected console statement"
});
Устаревший позиционный формат
context.report(node, "Unexpected console statement");

Позиционный формат сохраняется для обратной совместимости, но в современных правилах используется объектный вариант как расширяемый и более безопасный.


Основные поля объекта отчёта

node

Указывает на узел AST, к которому относится ошибка. ESLint использует этот узел для вычисления позиции (строка, столбец) и для подсветки фрагмента кода.

context.report({
  node: node,
  message: "Запрещённый вызов"
});

Ключевое поведение:

  • позиция берётся автоматически из node.loc;
  • диапазон подсветки определяется через node.range;
  • если узел отсутствует, требуется явное указание loc.

message

Основной текст ошибки.

context.report({
  node,
  message: "Использование eval запрещено"
});

Ограничения:

  • строка должна быть статической или шаблонной;
  • динамическая генерация допускается, но не влияет на форматирование ESLint;
  • не поддерживает HTML или markdown.

data

Позволяет параметризовать сообщение через шаблоны.

context.report({
  node,
  message: "Неожиданный тип: {{type}}",
  data: {
    type: node.type
  }
});

Механизм подстановки:

  • {{key}} заменяется значением из data;
  • используется для унификации сообщений;
  • снижает дублирование строк.

loc

Используется, когда нет AST-узла, но необходимо указать позицию вручную.

context.report({
  loc: {
    start: { line: 1, column: 0 },
    end: { line: 1, column: 10 }
  },
  message: "Ошибка в диапазоне без узла"
});

Применяется в случаях:

  • синтетических проверок;
  • анализа токенов;
  • генерации ошибок вне AST-узлов.

Расширенный формат: fix

Одной из ключевых возможностей context.report является автоматическое исправление кода.

context.report({
  node,
  message: "Удалите console.log",
  fix(fixer) {
    return fixer.remove(node);
  }
});

Механизм работы:

  • функция fix получает объект fixer;
  • возвращается одно или несколько исправлений;
  • ESLint применяет их при --fix.

Основные методы fixer:

  • remove(node) — удаление узла;
  • insertTextBefore(node, text) — вставка перед;
  • insertTextAfter(node, text) — вставка после;
  • replaceText(node, text) — полная замена;
  • replaceTextRange(range, text) — замена по диапазону.

Пример замены:

context.report({
  node,
  message: "Замените var на let",
  fix(fixer) {
    return fixer.replaceText(node, "let");
  }
});

Множественные фиксы

fix может возвращать массив:

context.report({
  node,
  message: "Упрощение конструкции",
  fix(fixer) {
    return [
      fixer.remove(node.left),
      fixer.replaceText(node.right, "value")
    ];
  }
});

Ограничения:

  • фиксы не должны пересекаться;
  • порядок применения важен;
  • конфликтующие изменения отклоняются ESLint.

Использование suggest

Помимо автоматического исправления, ESLint поддерживает альтернативные предложения:

context.report({
  node,
  message: "Возможное улучшение",
  suggest: [
    {
      desc: "Заменить на const",
      fix(fixer) {
        return fixer.replaceText(node.kind, "const");
      }
    }
  ]
});

Свойства:

  • desc — описание предложения;
  • fix — функция исправления.

Особенности:

  • предложения не применяются автоматически;
  • используются IDE и расширениями.

Условия вызова report

Метод вызывается только при соблюдении логики правила:

if (node.name === "eval") {
  context.report({
    node,
    message: "Запрещён вызов eval"
  });
}

Рекомендации архитектуры правил:

  • минимизировать количество вызовов;
  • избегать дублирования сообщений;
  • не вызывать report в обход AST-логики.

Работа с несколькими узлами

Одно правило может генерировать множество ошибок:

for (const n of nodes) {
  context.report({
    node: n,
    message: "Недопустимый идентификатор"
  });
}

Поведение ESLint:

  • каждая ошибка становится отдельным diagnostic;
  • агрегируется в итоговом отчёте;
  • может быть фильтрована через конфигурацию.

Производительность и ограничения

Использование context.report влияет на:

  • объём итогового отчёта;
  • время рендеринга в CLI;
  • поведение IDE-интеграций.

Рекомендации:

  • избегать лишних вызовов в глубоких обходах AST;
  • не генерировать отчёты в циклах без условий;
  • не использовать тяжёлые вычисления внутри report.

Связь с AST и Source Code

context.report тесно связан с объектом SourceCode, доступным через:

const sourceCode = context.getSourceCode();

Использование:

  • уточнение диапазонов;
  • работа с токенами;
  • расширение информации об ошибке.

Пример:

const token = sourceCode.getFirstToken(node);

context.report({
  node,
  loc: token.loc,
  message: "Проблемный токен"
});

Диапазоны и точность ошибок

ESLint поддерживает два уровня точности:

  • узловой (node) — стандартный вариант;
  • токеновый (loc) — более точный.

Пример токеновой диагностики:

const token = sourceCode.getTokenAfter(node);

context.report({
  loc: token.loc,
  message: "Лишний токен"
});

Используется при:

  • анализе синтаксических конструкций;
  • работе с пробелами и пунктуацией;
  • стилистических правилах.

Влияние на итоговый формат отчёта ESLint

Каждый вызов context.report формирует объект результата:

{
  ruleId: "no-console",
  message: "Unexpected console statement",
  line: 3,
  column: 5,
  nodeType: "MemberExpression"
}

Дополнительные поля:

  • fixable — наличие fix;
  • suggestions — список альтернатив;
  • severity — уровень ошибки.

Ошибки использования context.report

Типичные проблемы:

  1. Отсутствие node или loc → ESLint не может определить позицию.

  2. Динамически изменяемые сообщения без data → ухудшение читаемости и консистентности.

  3. Пересекающиеся фиксы → автоматическое отключение исправления.

  4. Частые вызовы в глубокой рекурсии → деградация производительности.


Поведение в разных режимах ESLint

CLI режим
  • ошибки выводятся построчно;
  • группируются по файлам;
  • фиксируются при --fix.
IDE режим
  • report используется для inline диагностики;
  • suggest отображается как quick fix;
  • обновления происходят инкрементально.
Flat config (современная конфигурация)

context.report не изменяет интерфейс, но влияет на:

  • модульную структуру правил;
  • изоляцию контекстов;
  • порядок исполнения анализаторов.

Роль в разработке кастомных правил

Любое кастомное правило ESLint строится вокруг связки:

  • обход AST;
  • проверка условий;
  • вызов context.report.

Минимальная структура:

export default {
  create(context) {
    return {
      Identifier(node) {
        if (node.name === "debug") {
          context.report({
            node,
            message: "Запрещён debug"
          });
        }
      }
    };
  }
};

Эта модель делает context.report фундаментальным элементом всей системы ESLint-правил.