Pular para o conteúdo
Tema
Idioma

Catálogo de Analyzers

English | Português (Brasil)

Esta página documenta os diagnósticos públicos expostos por ComplexityAnalysis.Analyzers e a evidência necessária para cada regra reportar.

O analyzer é intencionalmente conservador. Ele reporta apenas fatos e estimativas conhecidas sustentados pela sintaxe atual, pelo modelo semântico do Roslyn, pelo registro de operações conhecidas, pela análise limitada de métodos-fonte e pelo solver de recursão direta suportado. Comportamentos não suportados, inseguros, cíclicos, limitados por budget, numericamente inconclusivos ou não resolvidos permanecem Unknown em vez de serem estimados.

ID Título Categoria Severidade padrão Habilitado por padrão
BIG0001 Estimated algorithmic complexity Complexity Info false
BIG1001 Linear lookup inside iteration Complexity Info true
BIG1002 Materialization inside iteration Complexity Info true
BIG1003 Ordering inside iteration Complexity Info true
BIG1004 Input-dependent method call inside iteration Complexity Info true
BIG1005 Exponential recursive growth Complexity Info true
BIG1006 Method complexity exceeds configured threshold Complexity Info true
BIG2001 Cyclomatic complexity exceeds configured threshold Complexity Info true
BIG2002 Maximum nesting depth exceeds configured threshold Complexity Info true
BIG2003 Method NLOC exceeds configured threshold Complexity Info true
BIG2004 Statement count exceeds configured threshold Complexity Info true
BIG2005 Token count exceeds configured threshold Complexity Info true
BIG2006 Parameter count exceeds configured threshold Complexity Info true
BIG2007 Cognitive complexity exceeds configured threshold Complexity Info true
BIG9000 Analyzer execution probe Infrastructure Info false

O analyzer normaliza constructs executáveis C# suportados para um único pipeline interno de executable member. Cada raiz suportada precisa ter identidade de símbolo Roslyn, body explícito, localização estável de diagnóstico e ownership isolado do body.

Executable member Análise como raiz Análise interprocedural como callee Recursão direta
Método ordinário Sim Sim, quando o dispatch de fonte é seguro Sim, para recorrências suportadas
Construtor/static constructor Sim Deferred Não aplicável
Destructor/finalizer Não Não Não
Getter/setter/init accessor de propriedade Sim, com body explícito Deferred Conservadora; reporta apenas se a prova de recorrência existente tiver sucesso
Accessor add/remove de evento Sim, com body explícito Deferred Conservadora; reporta apenas se a prova de recorrência existente tiver sucesso
Operador Sim Deferred Conservadora; reporta apenas se a prova de recorrência existente tiver sucesso
Operador de conversão Sim Deferred Conservadora; reporta apenas se a prova de recorrência existente tiver sucesso
Local function Sim Sim, para chamadas diretas de local function Sim, para recorrências suportadas
Lambda simples/parenthesized Sim Deferred Deferred
Anonymous method Sim Deferred Deferred
Propriedade expression-bodied Sim, como getter Deferred Deferred
Membro method-like expression-bodied Sim, conforme o tipo de membro Igual ao tipo de membro Igual ao tipo de membro

Bodies executáveis aninhados não são contados como parte do pai lexical apenas por aparecerem dentro dele. Por exemplo, uma local function ou lambda declarada dentro de um método é analisada separadamente; o pai só a inclui quando um caminho de invocação suportado comprova execução. Variáveis capturadas não são tratadas como parâmetros independentes de tamanho de entrada.

O projeto define uma capacidade interna de métricas Halstead C# para executable members suportados. Ela registra as contagens primitivas n1, n2, N1 e N2 e deriva vocabulário, comprimento, comprimento calculado, volume, dificuldade, esforço, tempo estimado de implementação e bugs entregues estimados pela convenção documentada do projeto.

Métricas Halstead são independentes de Big-O, Cyclomatic Complexity, Maximum Nesting Depth, métricas de tamanho, Parameter Count e Cognitive Complexity. Bodies executáveis aninhados são isolados pelas mesmas regras de ownership descritas acima, e comentários/trivia não contribuem.

Ainda não há diagnóstico público de threshold Halstead. O projeto não adotou uma única métrica Halstead derivada cujo threshold seja suficientemente claro e defensável como guidance de manutenibilidade para projetos C# em geral. Portanto, nenhum ID BIG2xxx, propriedade de diagnóstico ou chave de configuração do analyzer é reservado para Halstead nesta fatia de release.

Veja Métricas Halstead para C# para a convenção reproduzível de classificação e fórmulas. Nenhuma equivalência numérica exata é alegada com Lizard, Visual Studio ou outra implementação.

Diagnósticos acionáveis seguem esta convenção quando há evidência disponível:

Dimensão Significado
WHAT O que foi detectado.
WHERE Qual operação, invocação, método ou construct causou o diagnóstico.
WHY Por que o padrão importa.
COST O custo conhecido de operação ou callee usado pelo analyzer.
CONTEXT O contexto de execução, como uma iteração analisável.
THRESHOLD O máximo configurado ultrapassado por uma estimativa conhecida.
GUIDANCE Direção condicional de melhoria, não uma correção obrigatória.
LIMIT O que o analyzer não está afirmando.

Mensagens de diagnóstico permanecem curtas para IDE/build. Raciocínio detalhado, exemplos, guidance e limitações ficam neste catálogo. A ausência de um diagnóstico não prova que o código seja eficiente; também pode significar que o analyzer não conseguiu comprovar os fatos necessários com segurança.

Diagnósticos podem incluir propriedades estruturadas estáveis para tooling futuro. Essas propriedades são strings determinísticas e não devem ser tratadas como um trace interno completo.

Propriedade Significado
complexity Estimativa conhecida emitida por BIG0001, BIG1005 ou BIG1006.
threshold Threshold configurado emitido por BIG1006, BIG2001, BIG2002, BIG2003, BIG2004, BIG2005, BIG2006 ou BIG2007.
cyclomaticComplexity Cyclomatic Complexity real emitida por BIG2001.
cyclomaticComplexityMode Modo de contabilização de switch emitido por BIG2001: standard ou modified_mccabe.
maximumNestingDepth Maximum Control-Flow Nesting Depth real emitida por BIG2002.
cognitiveComplexity Cognitive Complexity real emitida por BIG2007.
methodNloc NLOC real emitido por BIG2003.
statementCount Statement count estrutural real emitido por BIG2004.
tokenCount Token count real do corpo executável emitido por BIG2005.
parameterCount Parameter Count source-declared real emitido por BIG2006.
operation Nome estável da operação ou método responsável por um diagnóstico acionável.
operationComplexity Custo conhecido da operação ou callee no local do diagnóstico.
iterationComplexity Complexidade conhecida da iteração envolvente.
combinedComplexity Contribuição aninhada conhecida composta para o diagnóstico.
recurrenceClass Classe estável do resultado de recorrência, atualmente exponential.
diagnosticRole Papel estável de infraestrutura para BIG9000, atualmente execution-probe.
Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão false
Localização Localização estável do executable member
Mensagem Estimated algorithmic complexity for '{method}' is {complexity}
Diagnostic properties complexity

BIG0001 reporta a estimativa conhecida do analyzer para um executable member suportado, como O(1), O(log n), O(n), O(n log n), O(n^2), O(n^1.585) ou O(1.618^n).

O diagnóstico expõe o resultado por membro que serve de base para diagnostics acionáveis e de threshold. Ele é desabilitado por padrão porque pode gerar ruído em builds normais.

public void M(int[] values)
{
foreach (var value in values)
{
_ = value + 1;
}
}

Quando habilitado, M reporta Estimated algorithmic complexity for 'M' is O(n).

public void M(Service service)
{
service.Process();
}

Se a chamada não puder ser resolvida como operação conhecida suportada ou método-fonte seguro, a estimativa do método permanece Unknown e BIG0001 não reporta.

A estimativa pode incluir limites de loop suportados, operações BCL/LINQ conhecidas, callees de métodos-fonte ou local functions seguros na mesma compilation e formatos selecionados de recursão direta resolvida.

Estimativas de limites de loop exigem que a variável de controle e o bound permaneçam estáveis, exceto pela progressão reconhecida. Mutações diretas relevantes, aliases ref simples, chamadas ref/out e local functions invocadas que alterem qualquer um desses valores tornam a estimativa do loop Unknown.

Use BIG0001 quando quiser visibilidade das estimativas conhecidas ao ajustar thresholds ou revisar o comportamento da análise.

Unknown não é convertido em uma classe de complexidade especulativa. Comportamentos não suportados, não resolvidos, inseguros, limitados por budget, cancelados, baseados apenas em variável capturada ou incomparáveis podem suprimir o diagnóstico.

Habilite com:

[*.cs]
dotnet_diagnostic.BIG0001.severity = suggestion
Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Invocação da busca
Diagnostic properties operation, operationComplexity, iterationComplexity, combinedComplexity

BIG1001 reporta uma busca suportada cujo custo conhecido é não constante e cuja invocação está dentro de uma iteração analisável.

Buscas lineares repetidas podem multiplicar o custo do loop envolvente.

foreach (var customer in customers)
{
if (blockedCustomers.Contains(customer))
{
}
}

Quando blockedCustomers é um List<T> suportado, o analyzer pode reportar que List<T>.Contains tem custo linear conhecido dentro do loop.

foreach (var customer in customers)
{
if (blockedCustomers.Contains(customer))
{
}
}

Se blockedCustomers é um HashSet<T> suportado, a busca é registrada como O(1) esperado sob hipóteses explícitas de distribuição de hash e custo constante de hashing/igualdade, e esta regra não reporta.

O analyzer usa identidade do símbolo resolvido para a operação, resolve a dimensão do receiver/input, comprova uma iteração envolvente e compõe o custo da operação com o custo da iteração. combinedComplexity só é reportada quando essa composição é conhecida.

Considere uma busca indexada ou uma estrutura com semântica de conjunto quando a busca repetida por pertinência for necessária e semântica, ordenação, duplicatas, mutabilidade e custo de memória forem apropriados.

O analyzer não afirma que HashSet<T> ou qualquer coleção alternativa seja sempre semanticamente correta. Métodos customizados chamados Contains não são classificados como operações de framework apenas pelo nome.

Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Invocação de materialização
Diagnostic properties operation, operationComplexity, iterationComplexity, combinedComplexity

BIG1002 reporta materializadores LINQ suportados, como ToList, ToArray, ToDictionary e ToHashSet, quando executam dentro de uma iteração analisável.

Materialização pode enumerar a fonte e alocar um resultado em cada iteração.

foreach (var customer in customers)
{
var copy = items.ToList();
}
var copy = items.ToList();
foreach (var customer in customers)
{
_ = copy.Count;
}

O analyzer reporta apenas quando o materializador é uma operação conhecida suportada, o tamanho da fonte é conhecido, a iteração envolvente é analisável e a contribuição aninhada pode ser composta.

Considere mover a materialização para fora do loop quando o resultado materializado não depender da iteração atual e a alocação repetida não for necessária.

O analyzer não comprova que a materialização seja desnecessária. Materialização repetida pode ser necessária quando a fonte ou o snapshot desejado dependem da iteração atual.

Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Invocação de ordenação deferred
Diagnostic properties operation, operationComplexity, iterationComplexity, combinedComplexity

BIG1003 reporta operações de ordenação suportadas, como OrderBy, OrderByDescending, ThenBy e ThenByDescending, quando o analyzer consegue comprovar que a ordenação deferred é consumida dentro de uma iteração analisável.

Ordenar em cada iteração pode dominar o custo do corpo do loop.

foreach (var customer in customers)
{
var sorted = items.OrderBy(item => item).ToList();
}
var query = items.OrderBy(item => item);
foreach (var customer in customers)
{
_ = customer;
}
var sorted = query.ToList();

A criação da ordenação deferred isoladamente é tratada como trabalho de setup. O diagnóstico só é emitido quando um consumidor imediato suportado, como ToList, consome a sequência ordenada dentro do loop. O custo reportado da operação é o custo conhecido da ordenação consumida.

Considere ordenar uma vez fora do loop quando a ordenação e a fonte não dependem da iteração atual.

O analyzer não move a ordenação automaticamente e não afirma que ordenar fora do loop preserva semântica. Ele reporta apenas ordenação consumida cujo custo pode ser comprovado.

BIG1004 - Chamada Dependente de Entrada Dentro de Iteração

Seção intitulada “BIG1004 - Chamada Dependente de Entrada Dentro de Iteração”
Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Invocação do método-fonte
Diagnostic properties operation, operationComplexity, iterationComplexity, combinedComplexity

BIG1004 reporta uma chamada a método-fonte suportado com complexidade conhecida não constante e dependente da entrada quando essa chamada executa dentro de uma iteração analisável.

O trabalho dependente de entrada do callee pode ser repetido uma vez por iteração no caller.

foreach (var customer in customers)
{
CheckAgainstBlacklist(customer, blocked);
}
private static void CheckAgainstBlacklist(int customer, int[] blocked)
{
foreach (var value in blocked)
{
_ = value + customer;
}
}
foreach (var customer in customers)
{
Check(customer);
}
private static int Check(int value) => value + 1;

Callees constantes não reportam.

O analyzer resolve um alvo de método-fonte seguro, deriva ou reutiliza um template limitado do callee, substitui argumentos do call site e compõe o custo conhecido do callee com o custo da iteração envolvente. Detalhes de template e cache não são expostos.

Considere pré-computação, cache, memoization ou outro formato de dados quando o resultado do callee puder ser reutilizado semanticamente entre iterações.

O analyzer não afirma que chamadas repetidas sejam redundantes. Ele evita dispatch virtual/interface inseguro, métodos externos disponíveis apenas em metadata, chamadas não resolvidas, ciclos e estimativas em fronteiras de budget.

Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Identificador do método recursivo
Mensagem Recursive method '{method}' exhibits exponential growth with estimated complexity {complexity}
Diagnostic properties complexity, recurrenceClass

BIG1005 reporta um método de recursão direta suportado cuja recorrência extraída é resolvida como crescimento exponencial.

Crescimento recursivo exponencial pode se tornar impraticável mesmo para entradas moderadas.

int Fibonacci(int n)
{
if (n <= 1)
{
return n;
}
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
int CountDown(int n)
{
if (n <= 1)
{
return 1;
}
return CountDown(n - 1) + 1;
}

Essa recorrência suportada é linear, não exponencial, então BIG1005 não reporta.

O analyzer precisa comprovar recursão direta semântica, evidência compatível de base case, argumentos recursivos redutores, trabalho local conhecido e uma recorrência resolvida por um solver suportado. T(n)=T(n-1)+T(n-2)+O(1), no estilo Fibonacci, é documentada como forma representativa suportada.

Considere memoization ou uma abordagem iterativa quando subproblemas recursivos repetidos forem semanticamente equivalentes.

O diagnóstico não inclui a equação completa de recorrência porque o pipeline atual do diagnóstico carrega a estimativa exponencial resolvida, não um contrato público estável de texto de recorrência. Recursão não suportada permanece Unknown.

BIG1006 - Complexidade Acima do Threshold Configurado

Seção intitulada “BIG1006 - Complexidade Acima do Threshold Configurado”
Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Localização estável do executable member
Mensagem Method '{method}' has estimated complexity {actual}, exceeding configured maximum {threshold}
Diagnostic properties complexity, threshold

BIG1006 reporta um método cuja complexidade estimada conhecida e comparável é maior que complexity_analyzers.maximum_complexity.

A regra permite que um projeto aplique uma política explícita de complexidade máxima.

[*.cs]
complexity_analyzers.maximum_complexity = n_log_n
dotnet_diagnostic.BIG1006.severity = warning
void M(int[] values)
{
foreach (var outer in values)
{
foreach (var inner in values)
{
_ = outer + inner;
}
}
}

Uma estimativa conhecida O(n^2) excede O(n log n).

void M(int[] values)
{
foreach (var value in values)
{
_ = value + 1;
}
}

Com maximum_complexity = n, igualdade não reporta. Apenas estimativas conhecidas estritamente maiores reportam.

O analyzer reporta apenas quando a estimativa do método é conhecida, o threshold configurado é concreto, a estimativa e o threshold são comparáveis e a comparação retorna maior.

Considere reduzir o trabalho dominante comprovado do método, separar responsabilidades quando isso melhorar clareza, ou ajustar o threshold configurado quando o projeto aceitar intencionalmente o custo.

Unknown e expressões multivariadas incomparáveis não produzem diagnóstico de threshold. BIG1006 é um sinal prático de análise estática, não uma prova matemática universal.

BIG2001 - Cyclomatic Complexity Acima do Threshold Configurado

Seção intitulada “BIG2001 - Cyclomatic Complexity Acima do Threshold Configurado”
Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Localização estável do executable member
Mensagem Member '{member}' has cyclomatic complexity {actual}, exceeding configured maximum {threshold} ({mode} mode)
Diagnostic properties cyclomaticComplexity, threshold, cyclomaticComplexityMode

BIG2001 reporta um executable member suportado cuja Cyclomatic Complexity estrutural é estritamente maior que complexity_analyzers.maximum_cyclomatic_complexity.

Cyclomatic Complexity mede complexidade de caminhos de controle. Ela é independente da complexidade algorítmica de tempo: um membro pode ser O(n) e, ao mesmo tempo, possuir muitos branches, guards e caminhos independentes.

[*.cs]
complexity_analyzers.maximum_cyclomatic_complexity = 2
dotnet_diagnostic.BIG2001.severity = warning
int M(int value)
{
if (value > 0)
{
return 1;
}
else if (value < 0)
{
return -1;
}
return 0;
}

O método tem baseline 1, mais uma decisão para if e uma para else if, então o valor real é 3.

int M(int value)
{
if (value > 0)
{
return 1;
}
return 0;
}

Com maximum_cyclomatic_complexity = 2, igualdade não reporta.

A convenção standard conta 1 + decision points. Decision points incluem if, loops, catch, filtros de catch, expressões condicionais, short-circuit &&/||, cases de switch não default, arms de switch expression não discard, arms discard com guarda em switch expression, guards when e patterns or. else, try, finally, blocos simples, initializers, ??, ?., pattern and e pattern not não adicionam pontos por si só.

No modo modified_mccabe, cada switch statement ou switch expression contribui uma decisão para a família de switch, em vez de uma por case não default, arm não discard ou arm discard com guarda. Guards e patterns or continuam adicionando pontos.

Considere dividir ou simplificar o fluxo de controle quando um membro acumula muitos caminhos independentes e o threshold do projeto representa a política de manutenibilidade do time.

Este diagnóstico não é uma estimativa Big-O e não afirma que o membro seja lento. Local functions, lambdas e anonymous methods aninhados são analisados como executable members próprios em vez de inflarem o pai lexical.

BIG2002 - Maximum Nesting Depth Acima do Threshold Configurado

Seção intitulada “BIG2002 - Maximum Nesting Depth Acima do Threshold Configurado”
Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Localização estável do executable member
Mensagem Member '{member}' has maximum control-flow nesting depth {actual}, exceeding configured maximum {threshold}
Diagnostic properties maximumNestingDepth, threshold

BIG2002 reporta um executable member suportado cuja Maximum Control-Flow Nesting Depth é estritamente maior que complexity_analyzers.maximum_nesting_depth.

Maximum nesting depth mede quão profundamente estruturas de fluxo de controle estão aninhadas, não quantos caminhos independentes existem. A métrica é independente de Big-O e Cyclomatic Complexity. Muitas decisões planas podem ter nesting baixo; poucas decisões profundamente aninhadas podem ter nesting alto.

[*.cs]
complexity_analyzers.maximum_nesting_depth = 2
dotnet_diagnostic.BIG2002.severity = warning
void M(int[] values, bool flag)
{
if (flag)
{
foreach (var value in values)
{
if (value > 0)
{
}
}
}
}

A cadeia mais profunda é if -> foreach -> if, então o depth real é 3.

void M(bool a, bool b, bool c)
{
if (a)
{
}
if (b)
{
}
if (c)
{
}
}

Os três if são branches irmãos, então o depth máximo é 1, não 3.

Construct Adiciona nível de nesting?
if Sim
else if na mesma cadeia Não adiciona nesting artificial da cadeia; o else if é avaliado no depth da cadeia
else Não
for, foreach, while, do Sim
statement switch Sim
seção/case/default de switch Não
switch expression Sim
arm de switch expression Não
try Sim
catch e finally Não adicionam nível próprio; são branches irmãos do try
expressão condicional ?: Sim
&&, `
lock, using, fixed, checked, unchecked Não
bloco léxico simples Não
initializers de object, collection, array, property e anonymous object Não
body de local function, lambda ou anonymous method aninhado no pai Não

O threshold é opt-in. Configuração ausente ou inválida não produz BIG2002. Valores válidos são inteiros decimais não negativos. Igualdade não reporta; apenas valor real estritamente maior reporta.

Considere achatar ou extrair branches profundamente aninhados quando o threshold do projeto representar uma política de manutenibilidade e a refatoração preservar o fluxo de controle pretendido.

Este diagnóstico não é métrica de quantidade de caminhos, estimativa Big-O, contagem de linhas, contagem de statements, contagem de tokens nem Cognitive Complexity. Ele não conta nesting sintático simples e não infere execução por bodies executáveis aninhados apenas porque foram declarados dentro do membro pai.

BIG2003 - Method NLOC Acima do Threshold Configurado

Seção intitulada “BIG2003 - Method NLOC Acima do Threshold Configurado”
Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Localização estável do executable member
Mensagem Member '{member}' has NLOC {actual}, exceeding configured maximum {threshold}
Diagnostic properties methodNloc, threshold

BIG2003 reporta um executable member suportado cujo NLOC é estritamente maior que complexity_analyzers.maximum_method_nloc.

NLOC é um sinal de tamanho, não uma pontuação de complexidade algorítmica ou de fluxo de controle. Ele ajuda a aplicar uma política de manutenibilidade sobre quanto código-fonte relevante pertence a um único executable member.

NLOC conta linhas de origem dentro do corpo executável pertencente ao membro que contêm pelo menos um token relevante de código. Linhas em branco, linhas somente com comentários, linhas somente com chaves e linhas somente com delimitadores não contam. Comentários no fim da linha não adicionam linhas.

Linhas de declaração/header fora do corpo executável não participam. Um membro com bloco é contado a partir do bloco; um expression-bodied member é contado apenas a partir da expressão. Local functions, lambdas e anonymous methods aninhados são analisados independentemente e não inflam o NLOC do pai.

[*.cs]
complexity_analyzers.maximum_method_nloc = 2
dotnet_diagnostic.BIG2003.severity = warning
void M()
{
var value = 0;
if (value == 0)
{
value++;
}
}

As linhas relevantes do corpo são a declaração, o if e o incremento; portanto, o NLOC real é 3.

Este diagnóstico não mede LOC físico, totais por arquivo/projeto, statement count, token count, Big-O, Cyclomatic Complexity, Maximum Nesting Depth, Cognitive Complexity ou Halstead Metrics.

BIG2004 - Statement Count Acima do Threshold Configurado

Seção intitulada “BIG2004 - Statement Count Acima do Threshold Configurado”
Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Localização estável do executable member
Mensagem Member '{member}' has statement count {actual}, exceeding configured maximum {threshold}
Diagnostic properties statementCount, threshold

BIG2004 reporta um executable member suportado cujo statement count estrutural C# é estritamente maior que complexity_analyzers.maximum_statement_count.

O analyzer conta nós Roslyn StatementSyntax no corpo pertencente ao membro, excluindo containers BlockSyntax para evitar contar a representação de blocos como trabalho executável. Statements filhos dentro de constructs de fluxo de controle continuam contando: um if com um expression statement no corpo contribui dois statements.

Expression-bodied members contam como um statement sintético de expressão. Local functions, lambdas e anonymous methods aninhados são analisados independentemente; a declaração de local function conta como um statement do pai, mas o corpo dela não infla o pai.

Statement count é independente de NLOC, token count, Big-O, Cyclomatic Complexity, Maximum Nesting Depth, Cognitive Complexity e Halstead Metrics.

BIG2005 - Token Count Acima do Threshold Configurado

Seção intitulada “BIG2005 - Token Count Acima do Threshold Configurado”
Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Localização estável do executable member
Mensagem Member '{member}' has token count {actual}, exceeding configured maximum {threshold}
Diagnostic properties tokenCount, threshold

BIG2005 reporta um executable member suportado cujo token count do corpo executável é estritamente maior que complexity_analyzers.maximum_token_count.

Token count conta tokens sintáticos C# não ausentes pertencentes ao corpo executável, incluindo keywords, identificadores, literais, operadores, chaves, pontuação e delimitadores. Trivia é excluída; portanto, comentários e whitespace não afetam o valor.

Em expression-bodied members, apenas tokens da expressão participam. Local functions, lambdas e anonymous methods aninhados são analisados independentemente; bodies executáveis aninhados não inflam o token count do pai.

Token count é uma métrica sintática de tamanho. Ela é independente de NLOC, statement count, Big-O, Cyclomatic Complexity, Maximum Nesting Depth, Cognitive Complexity e Halstead Metrics.

BIG2006 - Parameter Count Acima do Threshold Configurado

Seção intitulada “BIG2006 - Parameter Count Acima do Threshold Configurado”
Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Localização estável do executable member
Mensagem Member '{member}' declares {actual} parameters, exceeding configured maximum {threshold}
Diagnostic properties parameterCount, threshold

BIG2006 reporta um executable member suportado cujo Parameter Count source-declared é estritamente maior que complexity_analyzers.maximum_parameters.

Parameter Count é baseado na sintaxe de fonte, não em slots de argumento de runtime nem em parâmetros gerados pelo compilador. Ele conta parâmetros source-declared ordinários, parâmetros de construtor, operadores/conversões, local functions, lambdas, anonymous methods e o receiver this explícito de extension methods. Parâmetros opcionais/defaulted, params, ref, in, out e modificadores modernos de parâmetro continuam contando como um parâmetro declarado cada.

Type parameters genéricos e constraints genéricas não contam. Variáveis capturadas não contam. O this implícito de instância não conta. O value implícito de property setter/init e event add/remove não conta porque é um parâmetro implícito da linguagem, não uma declaração de parâmetro na fonte.

Para roots de accessor de indexer suportados, os parâmetros explícitos do indexer contam e o value implícito de setter/init continua sem contar. Propriedades expression-bodied contam como roots de getter com 0 parâmetros. Primary constructors permanecem deferred porque declarações de class, struct e record não são roots de executable member na matriz atual.

[*.cs]
complexity_analyzers.maximum_parameters = 2
dotnet_diagnostic.BIG2006.severity = warning
void M(int id, string name, bool active)
{
}

O método declara três parâmetros, excedendo o máximo configurado de dois.

T Convert<T, TResult>(T value)
{
return value;
}

Com maximum_parameters = 1, isso não reporta: T e TResult são type parameters, não parâmetros do método.

Parameter Count não é métrica de Big-O, fluxo de controle, linhas, statements, tokens, Cognitive Complexity, Halstead, quantidade de dependências ou design de API. Ele não infere se Parameter Object, redesign de injeção de dependência ou breaking API change são apropriados.

BIG2007 - Cognitive Complexity Acima do Threshold Configurado

Seção intitulada “BIG2007 - Cognitive Complexity Acima do Threshold Configurado”
Propriedade Valor
Categoria Complexity
Severidade padrão Info
Habilitado por padrão true
Localização Localização estável do executable member
Mensagem Member '{member}' has cognitive complexity {actual}, exceeding configured maximum {threshold}
Diagnostic properties cognitiveComplexity, threshold

BIG2007 reporta um executable member suportado cuja Cognitive Complexity é estritamente maior que complexity_analyzers.maximum_cognitive_complexity.

A métrica implementada é a convenção C# de Cognitive Complexity documentada deste projeto. Não há alegação de equivalência exata com ferramentas externas. A convenção completa e reproduzível está documentada em Convenção de Cognitive Complexity.

Cognitive Complexity mede custo de compreensão estrutural a partir de quebras de fluxo de controle e nesting local. Ela complementa Cyclomatic Complexity e Maximum Nesting Depth sem substituir ou combinar essas métricas.

[*.cs]
complexity_analyzers.maximum_cognitive_complexity = 5
dotnet_diagnostic.BIG2007.severity = warning
void M(bool a, bool b, bool c)
{
if (a)
{
while (b)
{
if (c)
{
}
}
}
}

O score é 6: o if externo contribui 1, o while contribui 2, e o if interno contribui 3.

void M(bool a, bool b, bool c)
{
if (a) {}
if (b) {}
if (c) {}
}

Os três if irmãos executam no nesting 0, então o score é 3. Com maximum_cognitive_complexity = 3, igualdade não reporta.

Código straight-line começa em 0. Constructs estruturais como if, loops, famílias de switch, catch, when e ?: adicionam 1 + nesting atual conforme a convenção. else adiciona 1 sem penalidade de nesting. Sequências lógicas booleanas e de pattern adicionam um ponto pela sequência e mais um ponto por mudança de operador. Recursão direta a si mesmo adiciona um ponto uma vez por membro quando comprovada por identidade de símbolo. break, continue e goto adicionam um ponto cada.

Local functions, lambdas e anonymous methods aninhados são analisados como executable members separados em vez de inflarem o pai lexical.

Este diagnóstico não é estimativa Big-O, contagem de caminhos, valor de profundidade máxima, contagem de linhas, token count, Parameter Count, métrica Halstead, score subjetivo de legibilidade ou recomendação automática de refatoração.

Propriedade Valor
Categoria Infrastructure
Severidade padrão Info
Habilitado por padrão false
Localização Início de um arquivo-fonte quando disponível; caso contrário, sem localização
Mensagem ComplexityAnalysis.Analyzers execution probe is active
Diagnostic properties diagnosticRole

BIG9000 comprova que o pacote do analyzer foi carregado, inicializado e executado.

Ele é útil para smoke tests de consumo do pacote e validação de compatibilidade.

[*.cs]
dotnet_diagnostic.BIG9000.severity = warning
[*.cs]
dotnet_diagnostic.BIG9000.severity = none

Nenhum. Este é um probe de infraestrutura, não uma regra de análise de complexidade.

Habilite temporariamente apenas ao validar carregamento do analyzer e depois desabilite novamente.

BIG9000 não é recomendação de performance e não indica que algum código-fonte seja custoso. Quando habilitado, reporta no máximo uma vez por compilation.

O analyzer documenta deliberadamente um conjunto limitado de operações conhecidas.

Exemplos BCL incluem operações selecionadas de:

  • List<T>;
  • Dictionary<TKey,TValue>;
  • HashSet<T>;
  • arrays;
  • strings.

As classificações BCL auditadas são deliberadamente condicionais:

Operações Classificação Hipóteses exigidas
Length de array/string, List<T>.Count, indexer de List<T> Upper bound de pior caso O(1) Símbolo concreto suportado.
List<T>.Contains, List<T>.IndexOf Upper bound de pior caso O(n) Igualdade com custo constante.
List<T>.Sort Upper bound de pior caso O(n log n) Comparação com custo constante.
List<T>.Add O(1) amortizado Crescimento geométrico da capacidade ao longo de uma sequência de appends e atribuição com custo constante; um crescimento individual pode ser O(n).
Dictionary<TKey,TValue>.ContainsKey, HashSet<T>.Contains O(1) esperado Distribuição suficiente de hash e hashing/igualdade com custo constante; sem alegar pior caso constante.
Dictionary<TKey,TValue>.ContainsValue Upper bound de pior caso O(n) Igualdade com custo constante.

Interfaces genéricas de coleção como ICollection<T>, IList<T>, ISet<T>, IDictionary<TKey,TValue> e suas equivalentes somente leitura não garantem um custo específico de implementação. O dispatch tipado pela interface permanece Unknown, salvo quando o próprio símbolo resolvido pertence ao subconjunto concreto suportado.

Operações LINQ imediatas/terminais suportadas incluem:

  • Any, All, Contains, Count, LongCount;
  • ToList, ToArray, ToDictionary, ToHashSet;
  • Sum, Min, Max, Aggregate.

Operações deferred suportadas incluem:

  • Where, Select, SelectMany;
  • OrderBy, OrderByDescending, ThenBy, ThenByDescending;
  • Distinct, GroupBy.

Mappings são baseados nos símbolos resolvidos. Métodos do usuário com o mesmo nome não são mapeados automaticamente.

A criação de uma pipeline deferred é tratada como trabalho de setup. O custo de enumeração ou ordenação só é cobrado quando consumo suportado é comprovado. Uma pipeline armazenada em um local estável preserva a cardinalidade conhecida da fonte e os custos das operações, e cada consumo terminal ou reenumeração por foreach comprovado é analisado. Corpos de predicates e selectors só contribuem quando o delegate é uma lambda ou anonymous method inline, um delegate local estável ou um alvo de método fonte/local seguro com corpo disponível. Parâmetros delegate, method groups externos, locais reatribuídos e estado capturado mutável permanecem Unknown no consumo.

A análise interprocedural é limitada a métodos-fonte ordinários e local functions diretas na mesma Roslyn Compilation quando o dispatch é seguro.

Formas suportadas incluem:

  • métodos static;
  • métodos private;
  • métodos ordinários não virtuais;
  • dispatch sealed quando o alvo de runtime pode ser comprovado.
  • invocações diretas de local functions.

O traversal é sob demanda e limitado. A profundidade máxima padrão é 5, configurável até 16. O máximo padrão de expansões de métodos-fonte por raiz é 32, configurável até 128.

Ficam fora do escopo de callee suportado dispatch virtual/interface inseguro, dynamic dispatch, assemblies externos, construtores, accessors de propriedade, accessors de evento, operadores, conversões, lambdas, anonymous methods, call graphs de compilation inteira e análise de solution inteira.

Ciclos são detectados de forma conservadora. Recursão direta pode ser delegada ao pipeline de recorrências; recursão mútua continua sem suporte para resolução.

Uma recorrência só pode ser resolvida quando o analyzer consegue comprovar recursão direta semântica, evidência compatível de base case, argumento recursivo redutor e trabalho local conhecido.

As famílias suportadas incluem:

  • formas de soma/decremento como T(n)=T(n-c)+f(n) para tolls suportados;
  • um subconjunto exponencial simples e limitado, incluindo formatos no estilo Fibonacci;
  • formas do Master Theorem;
  • um subconjunto restrito/limitado de Akra-Bazzi com termos recursivos por escala suportados.

Resultados representativos:

T(n)=T(n-1)+1 => O(n)
T(n)=T(n-1)+n => O(n^2)
T(n)=T(n-1)+log n => O(n log n)
2T(n-1)+1 => O(2^n)
T(n-1)+T(n-2)+1 => O(1.618^n)
T(n/2)+1 => O(log n)
2T(n/2)+n => O(n log n)
3T(n/2)+n => O(n^1.585)
T(n/3)+T(2n/3)+n => O(n log n)

O analyzer não implementa Akra-Bazzi completo, resolução arbitrária por polinômio característico, parsing simbólico geral de recorrências, integração numérica geral ou integração com solvers externos MathNet/SymPy.

Casos não suportados permanecem Unknown.

Use a configuração padrão de severidade do Roslyn:

dotnet_diagnostic.<RULE_ID>.severity = <severity>

Opções comportamentais, como budgets de análise e threshold máximo de complexidade, estão documentadas em Configuração.