Решение проблем: практическое руководство по DCM (часть 1)

DCM (Dart Code Metrics) и custom_lint — более сложные решения для линтинга, чем встроенный в Dart линтер. В этом руководстве показаны некоторые практические настройки DCM. Позже во второй части я расскажу о custom_lint.

Внимание: одновременно можно использовать только один подключаемый модуль анализатора, поэтому вам необходимо выбрать между отдельными модулями DCM и подключаемым модулем custom_lint. Подробнее об этом читайте здесь: https://github.com/dart-lang/sdk/issues/50981. Версия DCM для рабочих групп не реализована в виде подключаемого модуля анализатора, поэтому вы можете использовать версию DCM для рабочих групп и custom_lint вместе.

DCM не просто предлагает больше линтов, чем линтер Dart. Также он позволяет рассчитывать различные метрики, такие как цикломатическая сложность. Я не рассказываю о настройке DCM, так как она довольно хорошо задокументирована на их веб-сайте.

Без дальнейших церемоний, давайте сразу перейдем к линтам.

Линты

  • proper-super-calls помогает вам всегда вызывать метод super в правильном месте для initState и dispose. В документах для initState указано, что методы должны начинаться с вызова суперметода. В документах для dispose указано, что методы должны заканчиваться вызовом суперметода. Говоря об удалении, также существует правило (dispose-fields), гарантирующее правильное размещение полей. Я часто встречал ошибку, связанную с тем, что эти два супервызова ставились не на место в различных кодовых базах. Но не больше, так что это правило уже доказало свою полезность.
  • prefer-early-return Это довольно самоуверенно, но я твердо верю, что ранние возвраты приводят к коду, который намного легче понять, и это также предотвращает отступы Hadouken. На аналогичной ноте есть avoid-redundant-else

  • ban-name Этот ворс весьма полезен, несмотря на то, что на первый взгляд выглядит не очень полезным. Вот несколько примеров того, как это можно эффективно использовать.

Вы можете использовать ban-name, чтобы запретить использование addPostFrameCallback, как показано в следующем фрагменте кода. Часто его использование приводит к нежелательному мерцанию, так как код выполняется через кадр после отрисовки виджета. Тем не менее, могут быть вполне допустимые способы его использования.

dart_code_metrics:
  rules:
    - ban-name:
        entries:
          - ident: addPostFrameCallback
            description: Using addPostFrameCallback could create unwanted flicker.

Другой довольно распространенной проблемой является вызов firstWhere в пустом списке. В результате выбрасывается StateError. Вместо этого вы должны использовать firstWhereOrNull из пакета коллекции. Вы также можете указать это с помощью правила lint ban-name.

dart_code_metrics:
  rules:
    - ban-name:
        entries:
          - ident: firstWhere
            description: Use firstWhereOrNull from package collection instead. `firstWhere` can result in a StateError when the list is empty

Еще один очень интересный вариант использования — использовать ban-name для собственной библиотеки виджетов. Если вы создаете, например, свой собственный виджет кнопки FooButton и хотите обеспечить его использование, вы также можете использовать для него ban-name lint. Это значительно упрощает проверку кода, а также упрощает использование правильного виджета во время разработки. Это также упрощает адаптацию, поскольку вам не обязательно говорить людям использовать определенные виджеты, поскольку это обеспечивается инструментами.

dart_code_metrics:
  rules:
    - ban-name:
        entries:
          - ident: MaterialButton 
            description: Use `FooButton` instead.
  • prefer-commenting-analyzer-ignores Любое игнорируемое правило анализатора должно иметь веское обоснование. В противном случае, вы могли бы также не игнорировать его. Это помогает поддерживать код в сопровождении, указывая причины «плохого» поведения.

Это всего лишь несколько полезных правил lint, но есть куда и больше.

Метрики

Метрика обычно представляет собой числовое значение, используемое в качестве индикатора для количественного описания чего-либо.

  • Технический долг — это метрика, в которой вы можете настроить определенные свойства кода, чтобы они имели определенную стоимость (например, в деньгах). Вычислив этот показатель, вы получите приблизительную стоимость своего технического долга. Конечно, это не количественная оценка таких вещей, как архитектурный технический долг или стоимость исправления ошибок. Но это начало. Сама команда Flutter тоже так делает, пусть и не с DCM. Вы можете назначить различным категориям определенную стоимость, как показано в следующем фрагменте кода.
dart_code_metrics:
  metrics:
    technical-debt:
      threshold: 1
      todo-cost: 161
      ignore-cost: 320
      ignore-for-file-cost: 396
      as-dynamic-cost: 322
      deprecated-annotations-cost: 37
      file-nullsafety-migration-cost: 41
      unit-type: "USD"
  • Цикломатическая сложность — это метрика, используемая для описания сложности программы. Это количественная мера количества линейно независимых путей через исходный код программы. Методы имеют базовую сложность 1. Каждый оператор потока управления (например, if, catch, while и т. д.) и условное выражение (? ... : ...) увеличивают сложность. else, finally и default не считаются. Некоторые операторы, такие как &&, ||, ?., ?? и ??=, также увеличивают сложность. Цель состоит в том, чтобы просто иметь методы с низкой цикломатической сложностью, поскольку их легче понять, чем методы с высокой цикломатической сложностью. Вы настраиваете потолок для цикломатической сложности (как показано во фрагменте кода ниже), и когда метод превышает этот предел, DCM предупреждает вас.
dart_code_metrics:
  metrics:
    cyclomatic-complexity: 20
  • Уровень вложенности виджетов — это метрика, показывающая отступ вашего дерева виджетов. В целом, низкое число указывает на лучшее понимание дерева виджетов. Метрика количество используемых виджетов гарантирует, что вы не используете слишком много виджетов в одном виджете и, таким образом, обеспечиваете хорошую производительность. И то, и другое вместе поможет вам сделать ваши виджеты понятными и эффективными.
dart_code_metrics:
  metrics:
    widgets-nesting-level: 10
    number-of-used-widgets: 20

Есть даже больше метрик, чем те, что описаны в этой статье.

Разработчики DCM с невероятной скоростью выпускают новые правила и показатели lint и всегда открыты для предложений, поэтому обязательно сообщите им, если что-то упущено.

Подписывайтесь на меня в Твиттере, чтобы не пропустить другие мои записи в блоге.