Pular para o conteúdo principal

Personalizando a análise estática

Use um arquivo de opções de análise e comentários no código para personalizar a análise estática.

A análise estática permite encontrar problemas antes de executar uma única linha de código. É uma ferramenta poderosa usada para prevenir bugs e garantir que o código esteja em conformidade com as diretrizes de estilo.

Com a ajuda do analyzer, você pode encontrar erros de digitação simples. Por exemplo, talvez um ponto e vírgula acidental tenha se infiltrado em uma instrução if:

O analyzer também pode ajudar você a encontrar problemas mais sutis. Por exemplo, talvez você tenha esquecido de fechar um sink:

No ecossistema Dart, o Dart Analysis Server e outras ferramentas usam o pacote analyzer para realizar a análise estática.

Você pode personalizar a análise estática para procurar uma variedade de possíveis problemas, incluindo erros e avisos especificados na especificação da linguagem Dart. Você também pode configurar regras do linter para garantir que seu código esteja em conformidade com o Guia de Estilo do Dart e com outras diretrizes sugeridas no Effective Dart. Ferramentas como o dart analyze, o flutter analyze e as IDEs e editores usam o pacote analyzer para avaliar seu código.

Este documento explica como personalizar o comportamento do analyzer usando um arquivo de opções de análise ou comentários no código-fonte Dart. Se você quiser adicionar análise estática à sua ferramenta, consulte a documentação do pacote analyzer e a Especificação da API do Analysis Server.

O arquivo de opções de análise

#

Coloque o arquivo de opções de análise, analysis_options.yaml, na raiz do pacote, no mesmo diretório do arquivo pubspec.

Aqui está um exemplo de arquivo de opções de análise:

analysis_options.yaml
yaml
include:
  - package:lints/recommended.yaml
​
analyzer:
  exclude: [build/**]
  language:
    strict-casts: true
    strict-raw-types: true
​
linter:
  rules:
    - cancel_subscriptions

O exemplo ilustra as entradas de nível superior mais comuns:

Se o analyzer não encontrar um arquivo de opções de análise na raiz do pacote, ele percorre a árvore de diretórios procurando por um. Se nenhum arquivo estiver disponível, o analyzer usa as verificações padrão.

Considere a seguinte estrutura de diretórios para um projeto grande:

project root contains analysis_options.yaml (#1) and 3 packages, one of which (my_package) contains an analysis_options.yaml file (#2).

O analyzer usa o arquivo #1 para analisar o código em my_other_package e my_other_other_package, e o arquivo #2 para analisar o código em my_package.

Habilitando verificações de tipo mais rigorosas

#

Se você quiser verificações estáticas mais rigorosas do que o sistema de tipos do Dart exige, considere habilitar os modos de linguagem strict-casts, strict-inference e strict-raw-types:

analysis_options.yaml
yaml
analyzer:
  language:
    strict-casts: true
    strict-inference: true
    strict-raw-types: true

Você pode usar os modos juntos ou separadamente; todos têm false como padrão.

strict-casts: <bool>

Um valor true garante que o mecanismo de inferência de tipos nunca faça um cast implícito de dynamic para um tipo mais específico. O código Dart válido a seguir inclui um downcast implícito do valor dynamic retornado por jsonDecode para List<String>, que pode falhar em tempo de execução. Este modo reporta o possível erro, exigindo que você adicione um cast explícito ou ajuste o seu código de outra forma.

análise estática: falha dart
void foo(List<String> lines) {
  ...
}
​
void bar(String jsonText) {
  foo(jsonDecode(jsonText)); // Implicit cast
}
error - The argument type 'dynamic' can't be assigned to the parameter type 'List<String>'. - argument_type_not_assignable
strict-inference: <bool>

Um valor true garante que o mecanismo de inferência de tipos nunca escolha o tipo dynamic quando não conseguir determinar um tipo estático. O código Dart válido a seguir cria um Map cujo argumento de tipo não pode ser inferido, o que resulta em uma dica de falha de inferência deste modo:

análise estática: falha dart
final lines = {}; // Inference failure
lines['Dart'] = 10000;
lines['C++'] = 'one thousand';
lines['Go'] = 2000;
print('Lines: ${lines.values.reduce((a, b) => a + b)}'); // Runtime error
warning - The type argument(s) of 'Map' can't be inferred - inference_failure_on_collection_literal
strict-raw-types: <bool>

Um valor true garante que o mecanismo de inferência de tipos nunca escolha o tipo dynamic quando não conseguir determinar um tipo estático por causa de argumentos de tipo omitidos. O código Dart válido a seguir tem uma variável List com tipo bruto (raw), o que resulta em uma dica de tipo bruto deste modo:

análise estática: falha dart
List numbers = [1, 2, 3]; // List with raw type
for (final n in numbers) {
  print(n.length); // Runtime error
}
warning - The generic type 'List<dynamic>' should have explicit type arguments but doesn't - strict_raw_type

Habilitando e desabilitando regras do linter

#

O pacote analyzer também fornece um linter de código. Há uma grande variedade de regras do linter disponíveis. Os linters tendem a ser não denominacionais: as regras não precisam concordar entre si. Por exemplo, algumas regras são mais adequadas para pacotes Dart comuns, e outras são projetadas para aplicativos Flutter. Observe que as regras do linter podem gerar falsos positivos, ao contrário da análise estática.

Habilitando as regras de lint recomendadas pela equipe do Dart

#

A equipe do Dart oferece dois conjuntos de regras de lint recomendadas no pacote lints:

Regras essenciais (core)

Ajudam a identificar problemas críticos que provavelmente causam falhas ao executar ou consumir código Dart. Todo código deve passar por essas regras do linter. Os pacotes publicados no pub.dev têm uma pontuação do pacote que se baseia, em parte, na aprovação nessas regras.

Regras recomendadas

Ajudam a identificar problemas adicionais que podem causar falhas ao executar ou consumir código Dart, e impõem um estilo e formato únicos e idiomáticos. Recomendamos que todo código Dart use essas regras, que são um superconjunto das regras essenciais.

Para habilitar qualquer um dos conjuntos de lints, adicione o pacote lints como dev dependency:

dart pub add --dev lints

Em seguida, edite o arquivo analysis_options.yaml para incluir o conjunto de regras de sua preferência:

yaml
include: package:lints/<RULE_SET>.yaml

Por exemplo, você pode incluir o conjunto de regras recomendadas assim:

yaml
include: package:lints/recommended.yaml

Habilitando regras individuais

#

Para habilitar uma única regra do linter, adicione linter: ao arquivo de opções de análise como uma chave de nível superior, seguida de rules: como chave de segundo nível. Nas linhas seguintes, especifique as regras que deseja aplicar, precedidas de hífens (a sintaxe de uma lista YAML). Por exemplo:

yaml
linter:
  rules:
    - always_declare_return_types
    - annotate_redeclares
    - cancel_subscriptions
    - close_sinks
    - combinators_ordering
    - comment_references
    - invalid_case_patterns
    - only_throw_errors
    - prefer_single_quotes

Desabilitando regras individuais

#

Se você incluir um arquivo de opções de análise como o do lints, pode querer desabilitar algumas das regras incluídas. Desabilitar regras individuais é semelhante a habilitá-las, mas exige o uso de um mapa em vez de uma lista como valor da entrada rules:, então cada linha deve conter o nome de uma regra seguido de : false ou : true.

Aqui está um exemplo de arquivo de opções de análise que usa todas as regras recomendadas do lints exceto avoid_shadowing_type_parameters. Ele também habilita o lint await_only_futures:

analysis_options.yaml
yaml
include: package:lints/recommended.yaml
​
linter:
  rules:
    avoid_shadowing_type_parameters: false
    await_only_futures: true

Incluindo opções compartilhadas

#

Um arquivo de opções de análise pode incluir opções especificadas em outro arquivo de opções, ou até em uma lista de outros arquivos de opções. Você pode especificar esses arquivos usando o campo de nível superior include::

analysis_options.yaml
yaml
include: package:flutter_lints/recommended.yaml

Um arquivo de opções incluído pode ser especificado com um URI package: ou com um caminho relativo. Para incluir vários arquivos de opções de análise, use uma lista:

analysis_options.yaml
yaml
include:
  - package:flutter_lints/recommended.yaml
  - ../team_options.yaml

Ao incluir vários arquivos, o analyzer mescla as opções na ordem da lista:

  1. O primeiro arquivo incluído é avaliado, incluindo quaisquer arquivos que ele inclua recursivamente.
  2. Cada arquivo incluído subsequente é aplicado em ordem, adicionando novas opções ou sobrescrevendo as conflitantes.
  3. Por fim, as opções definidas diretamente no arquivo analysis_options.yaml atual sobrescrevem quaisquer opções incluídas.

Ao mesclar as opções, o analyzer combina configurações compatíveis em vez de substituir seções inteiras. Por exemplo, habilitar uma regra individual do linter em um arquivo posterior acrescenta ou sobrescreve regras de arquivos anteriores sem descartar o restante do conjunto de regras incluído.

Por exemplo, dados os seguintes arquivos de opções:

three.yaml
yaml
include: two.yaml
# ...

E um arquivo de opções final que os inclui:

analysis_options.yaml
yaml
include:
  - one.yaml
  - three.yaml
# ...

Então o analyzer aplica as opções de one.yaml, depois as de two.yaml, depois as de three.yaml e, por fim, as de analysis_options.yaml.

Habilitando plugins do analyzer (experimental)

#

O analyzer tem suporte experimental a plugins legados. Esses plugins se integram ao analyzer para adicionar funcionalidades como novos diagnósticos, correções rápidas e autocompletar personalizado. Você pode habilitar apenas um plugin por arquivo analysis_options.yaml. Habilitar um plugin legado do analyzer aumenta a quantidade de memória que o analyzer usa.

Não use plugins legados do analyzer se a sua situação atender a qualquer uma das condições a seguir:

  • Você usa uma máquina de desenvolvimento com menos de 16 GB de memória.
  • Você usa um mono-repo com mais de 10 arquivos pubspec.yaml e analysis_options.yaml.

Você pode encontrar alguns plugins legados do analyzer em pub.dev.

Para habilitar um plugin legado:

  1. Adicione o pacote que contém o plugin como dev dependency.

    dart pub add --dev <your_favorite_analyzer_plugin_package>
    
  2. Edit your analysis_options.yaml file to enable the plugin.

    yaml
    analyzer:
      plugins:
        - your_favorite_analyzer_plugin_package
    

    Para indicar funcionalidades específicas do plugin a serem habilitadas, como novos diagnósticos, pode ser necessária uma configuração adicional.

Excluindo código da análise

#

Às vezes é aceitável que algum código falhe na análise. Por exemplo, você pode depender de código gerado por um pacote que não é seu: o código gerado funciona, mas produz avisos durante a análise estática. Ou uma regra do linter pode causar um falso positivo que você quer suprimir.

Você tem algumas formas de excluir código da análise:

  • Excluir arquivos inteiros da análise.
  • Impedir que regras específicas que não são de erro sejam aplicadas a arquivos individuais.
  • Impedir que regras específicas que não são de erro sejam aplicadas a linhas de código individuais.

Você também pode desabilitar regras específicas para todos os arquivos ou alterar a severidade das regras.

Excluindo arquivos

#

Para excluir arquivos da análise estática, use a opção exclude: do analyzer. Você pode listar arquivos individuais ou usar a sintaxe de padrões glob. Todos os padrões glob devem ser relativos ao diretório que contém o arquivo analysis_options.yaml.

yaml
analyzer:
  exclude:
    - lib/client.dart
    - lib/server/*.g.dart
    - test/_data/**

Suprimindo diagnósticos de um arquivo

#

Para ignorar um diagnóstico específico que não seja de erro em um arquivo específico, adicione um comentário ignore_for_file ao arquivo:

dart
// ignore_for_file: unused_local_variable

Isso vale para o arquivo inteiro, antes ou depois do comentário, e é especialmente útil para código gerado.

Para suprimir mais de um diagnóstico, use uma lista separada por vírgulas:

dart
// ignore_for_file: unused_local_variable, duplicate_ignore, dead_code

Para suprimir todas as regras do linter, adicione o especificador type=lint:

dart
// ignore_for_file: type=lint

Suprimindo diagnósticos de uma linha de código

#

Para suprimir um diagnóstico específico que não seja de erro em uma linha específica de código Dart, coloque um comentário ignore acima da linha de código. Aqui está um exemplo de como ignorar código que causa um erro em tempo de execução, como você poderia fazer em um teste de linguagem:

dart
// ignore: invalid_assignment
int x = '';

Para suprimir mais de um diagnóstico, forneça uma lista separada por vírgulas:

dart
// ignore: invalid_assignment, const_initialized_with_non_constant_value
const x = y;

Como alternativa, acrescente o comentário ignore à linha à qual ele se aplica:

dart
int x = ''; // ignore: invalid_assignment

Suprimindo diagnósticos em um arquivo pubspec

#

Se você precisar suprimir um diagnóstico que não seja de erro do analyzer em um arquivo pubspec.yaml, adicione um comentário ignore acima da linha afetada.

O exemplo a seguir ignora o lint sort_pub_dependencies porque a dependência flutter deve vir primeiro:

pubspec.yaml
yaml
dependencies:
  flutter:
    sdk: flutter
​
  # ignore: sort_pub_dependencies
  collection: ^1.19.0

Personalizando as regras de análise

#

Cada diagnóstico do analyzer e regra do linter tem uma severidade padrão. Você pode usar o arquivo de opções de análise para alterar a severidade de regras individuais ou para sempre ignorar algumas regras.

O analyzer oferece suporte a três níveis de severidade:

info

Uma mensagem informativa que não faz a análise falhar. Exemplo: dead_code

warning

Um aviso que não faz a análise falhar, a menos que o analyzer esteja configurado para tratar avisos como erros. Exemplo: invalid_null_aware_operator

error

Um erro que faz a análise falhar. Exemplo: invalid_assignment

Ignorando regras

#

Você pode ignorar diagnósticos do analyzer e regras do linter específicos usando o campo errors:. Liste a regra, seguida de : ignore. Por exemplo, o arquivo de opções de análise a seguir instrui as ferramentas de análise a ignorar a regra TODO:

yaml
analyzer:
  errors:
    todo: ignore

Alterando a severidade das regras

#

Você pode alterar globalmente a severidade de uma regra específica. Essa técnica funciona tanto para problemas comuns de análise quanto para lints. Por exemplo, o arquivo de opções de análise a seguir instrui as ferramentas de análise a tratar atribuições inválidas como avisos e retornos ausentes como erros, e a fornecer informações (mas não um aviso ou erro) sobre código morto:

yaml
analyzer:
  errors:
    invalid_assignment: warning
    missing_return: error
    dead_code: info

Configurando o dart format

#

Você pode configurar o comportamento do dart format adicionando uma seção formatter ao arquivo de opções de análise.

Opções configuráveis

#

page_width

#

Você pode especificar o page_width (comprimento de linha) desejado. O padrão é 80 caracteres.

Para mais informações, leia Configurando a largura de página do formatador.

trailing_commas

#

Você pode configurar como o formatador trata as vírgulas finais nas listas de argumentos e de parâmetros usando a opção trailing_commas. Ela aceita um de dois valores:

automate (padrão)

O formatador adiciona e remove vírgulas finais com base na sua decisão de dividir a construção ao redor.

preserve

Uma vírgula final força a construção ao redor a ser dividida. O formatador adiciona uma vírgula final quando divide uma construção, mas não remove uma.

analysis_options.yaml
yaml
formatter:
  page_width: 120
  trailing_commas: preserve

Recursos

#

Use os recursos a seguir para saber mais sobre análise estática no Dart:

Encontrou essa página sem tradução ou que precisa de correção? Abra uma issue e nos ajude a manter esse site em PT-BR para ajudar pessoas como você.