Este artigo foi traduzido por máquina.

Cutting Edge

Análise de código estático e contratos de código

Dino Esposito

image: Dino EspositoPara muitos, é difícil acreditar que nunca houve um tempo quando você pode imprimir o código de origem inteiro de um aplicativo, lido de cima para baixo e detectar bugs ou escândalos possíveis.A complexidade do software moderno torna essa abordagem impraticável para seres humanos — mas não para alguns tipos de software inteligente, como, por exemplo, ferramentas de análise estática.

Análise estática de software consiste em inferir o comportamento de um trecho de código a partir de suas instruções.Uma ferramenta de análise estática realiza o exame do código-fonte, progressivamente, criando uma base de dados de conhecimento que ele usa para comprovar as instruções e sua saída certas ou erradas.Análise estática, na verdade, não executa o código; Ele apenas lê linhas e descobre as coisas.Que tipo de coisas?

Em geral, análise estática pode identificar possíveis bugs no código como também indicam como determinados segmentos de código correspondem às expectativas e especificações.

Ele tem sido conhecido por algum tempo — pelo menos tão antigos quanto o ótimo trabalho feito por Alan Turing na década de 1930 — que não há nenhuma maneira automática e completamente confiável para decidir se um determinado programa será encerrado sem erros.Em qualquer caso, ciência baseia-se principalmente na aproximação e sendo informado de que você provavelmente tem um bug em torno de algumas linhas é uma ajuda valiosa.Dimensionar essa Ajuda para o tamanho de um projeto moderno e você pode ver o valor real.Uma ferramenta de análise estática provavelmente não lhe darão absolutas certezas, mas trabalhando em tempo real, à medida que você escreve suas classes, ele pode dar feedback imediato sobre o que pode estar errado na sua implementação.

Análise e testes estáticos

Há uma diferença fundamental entre o teste e estático análise.Como desenvolvedor, você ativamente o teste de gravação mas passivamente suportar a análise estática.Se os testes, na verdade, não cobrem condições significativas ou não verificar com valores significativos, os resultados não será significativos.Uma ferramenta de análise estática lhe avisos sobre fatos (como a ferramenta entende-los) que violam a algumas das regras configuradas internas.Em geral, obter quase sem avisos de análise estática é uma boa indicação da qualidade do software.Por outro lado, receber avisos não significa automaticamente que seu software é houver bug e falhará na primeira execução.Análise estática provavelmente irá detectar erros de disco rígido de catch, o caso de canto que têm o potencial de travar o aplicativo.Com testes, análise estática pode detectar defeitos tão logo no início da fase de desenvolvimento, limitando assim o impacto dos erros de software em todo o projeto.

Tipos de analisadores de estáticos

Análise estática tem muitas facetas e uma variedade de níveis diferentes de implementação.Um tipo muito básico do analyzer estático é o compilador da linguagem.O compilador passa pelo seu código-fonte e o compara com as regras de sintaxe da linguagem.Esta é a primeira etapa de análise.Compiladores modernos, entretanto, pode fazer muito mais.

O mais recente C# compilador, por exemplo, detecta violações do princípio de Liskov somar os contratos de código em classes derivadas.Esse compilador pode freqüentemente destaque de ocorrências de variáveis não utilizadas.No entanto, um compilador que detecta e classifica como um aviso não necessariamente qualificam como um bug.Ainda assim, o compilador é uma etapa distinta, que você precisa executar.E ele pode demorar um pouco, dependendo do projeto e o ambiente.

Ferramentas como o FxCop ou, melhor ainda, o recurso de análise de código em 2010 Visual Studio, executar uma análise mais específica do código e pode ser configurado para ser executado sob demanda ou em cada compilação como a Figura 1 mostra.

Code Analysis Settings in a Visual Studio 2010 Project

Figura 1 as configurações de análise de código em um projeto de 2010 Visual Studio

Além disso, você pode definir declarativamente as regras que você deseja empregar quando seu código de processamento.Figura 2 mostra um exemplo de uma longa lista de avisos que pode ser exibida quando você ativar a opção todas as regras na análise de código de 2010 Visual Studio.Observe que alguns desses avisos são bastante específicos e muito útil para tornar seu código mais limpo e mais adherent para o Microsoft.Diretrizes do NET Framework.

Warnings Received When All Rules Are Enabled
(clique para ampliar)

Figura 2 avisos recebidos quando todas as regras estão habilitadas.

O ponto-chave sobre análise estática é que as ferramentas automáticas são completamente honestas e lhe dar avisos baseados-se estritamente a violações de regras.Violações de regra detectados não são necessariamente bugs; mas se uma violação é um bug, ele provavelmente mostrará os casos de borda e de total acordo com a lei de Murphy — apenas quando ele fará mais danos.

Além das ferramentas de varredura como compiladores e instalações de FxCop, outra categoria de ferramentas pode fornecer muita feedback para você — mas eles funcionam de forma assíncrona.Para esta categoria pertence o ReSharper, que fornece o mesmo tipo de sugestões úteis como análise de código, mas dinamicamente conforme você digita.Ele também oferece para editar o código para você, ao custo de um ou dois cliques.Por exemplo, detecta reSharper variáveis não atribuídas, o código inacessível, possíveis referências nulas e uma variedade de código de smells tais como chamadas de virtuais em um construtor e o acesso ao recessos modificados em expressões de LINQ.Mais importante, ReSharper permite formalizar smells seus próprio código e automaticamente localizar e substituí-los com inteligência, conforme você os digita.Para obter mais informações e um exemplo passo a passo detalhado da pesquisa estrutural do ReSharper e substituir, leia a postagem no blog de bit.ly/eCMvCL.

Finalmente, a análise estática na.NET Framework 4 e 2010 de Visual Studio também ocorre usando a ferramenta Verificador estático criada pela equipe de contratos de código.

Verificador estático em ação

Com o código de contratos, a Microsoft fornece a ferramenta Verificador estático, que pode ir através de seu código, mesmo sem você compilar e destacar os contratos de código que não estão sendo verificados ou apenas impossível comprovar certo ou errado.Você pode obter o verificador estáticos somente se você tiver Visual Studio Premium de 2010 ou Ultimate ou Visual Studio do Team System 2008.Esses requisitos de versão são compatíveis com os requisitos para o recurso de análise de código — ou seja, nenhum desses recursos estão disponíveis no Professional de Visual Studio ou edições Express.

Como regravador de linguagem intermediária, o verificador estático é um download separado que aprimora a 2010 de Visual Studio.Você pode obter os bits de contratos de código mais recentes do bit.ly/fF3wzl.Você precisará explicitamente habilitar a verificação estática em uma base de configuração por projeto, conforme mostrado na a Figura 3.

Enabling Static Checking of Code Contracts in Visual Studio 2010

Figura 3 Ativando a verificação estática de código de contratos em 2010 de Visual Studio

O verificador de estático pode ser executado em segundo plano se desejar e explicitamente pode mostrar a linha ondulante para cada aviso.Execução do plano de fundo significa que o verificador de estática está programado para executar em paralelo com o compilador, como uma compilação acontece e o código é alterado.

Você pode fazer com que o verificador estático procure implícito, bem como contratos explícitos.Um contrato explícito é qualquer contrato que você declara em um método de classe, como, por exemplo, uma pré-condição, uma pós-condição ou constante.Além disso, o verificador estático pode também levar em conta alguns contratos internos de código e verifique se os índices de matriz sempre permanecer dentro de limites de matriz, se quaisquer referências nulas são usadas ou se qualquer divisão por zero irá ocorrer.Controlar o implícito contratos de código por meio das caixas de seleção mostradas na a Figura 3.Observe a contratos implícita do código de ativação pode inundar sua janela de saída com uma tonelada de mensagens e avisos.Talvez você não queira fazer isso o tempo todo e provavelmente não após o início.Aqui está um exemplo de código que será identificado como um possível erro quando você tiver um contrato implícito obrigações de limites de matriz em:

var numbers = new int[2];
numbers[3] = 0;

A maioria da potência do verificador de estático, porém, resultados de usá-lo com contratos explícitos, como, por exemplo, anteriores e posteriores.

Contratos explícitos

Suponha que você tem o seguinte código em um dos seus métodos:

var orderId = GetLatestOrderId(); 
ProcessOrder(orderId);

Uma variável é obtida de uma chamada de função e repassada a outro método para processamento posterior. Não há qualquer verificador muito estático pode fazer para tentar provar essas instruções certas ou erradas sem algumas informações de contrato explícito. Por outro lado, se o método GetLatestOrderId expõe uma pós-condição significativa, como no código a seguir, o verificador poderá comprovar se a chamada sucessiva é válida:

public int GetLatestOrderId()
{
  Contract.Ensures(Contract.Result<int>() >0);
  ...
return n;
}

O método GetLatestOrderId explicitamente declara que ele irá devolver um valor maior que zero. Como o verificador faz sua passagem, captura essa informação e o adiciona à sua base de conhecimentos. No futuro, quando ele encontra a que o valor de retorno do método de GetLatestOrderId está sendo usado como entrada para outro método com uma pré-condição explícito, o verificador razoavelmente pode tentar ver se a operação é consistente com os contratos declarados. Vamos considerar o seguinte contrato de pré-condição:

public void ProcessOrder(int orderId)
{
  Contract.Requires<ArgumentException>(orderId >0);
  ...
}

Esses dois contratos explícitos fornecem informações suficientes para o verificador de provar o contrato. Nesse caso, você não obtendo qualquer aviso extra. Mas e se estão faltando alguns desses contratos? O verificador de estático retorna uma saída semelhante ao que você vê na a Figura 4. O verificador detecta que, digamos, um método tem um requer um contrato e recebe dados a partir de outro que não fala nada sobre sua saída retornada.

Unproven Contracts

Figura 4 contratos não comprovados

Ele deve ser claro, agora que, para obter o máximo do verificador de estático, você deve usar o código contratos tudo em todo o código. Os contratos mais explícitos trazer, mais confiável que o verificador estático pode ser.

Assumir e Assert

Às vezes, no entanto, você precisa integrar o novo código com o código herdado que outras pessoas escreveram e que não pode ser atualizado. Se o código antigo não tiver quaisquer contratos, você vai obter irritantes avisos do verificador estático. A API de contratos de código oferece uma solução alternativa para isso.

Essencialmente, os avisos de contrato não comprovado se originam da falta de informações — o verificador é não é possível localizar as informações necessárias. No entanto, como desenvolvedor, você pode fornecer mais detalhes — especificamente, as suposições. Dê uma olhada em a Figura 5.

A Warning from the Static Checker

Figura 5 um aviso do verificador estático

Você vê uma dica de ferramenta que avisa sobre uma referência nula possível. Aparentemente, a variável contexto está sendo usado sem ter sido atribuído. Quem é responsável realmente a dica de ferramenta? É o verificador, ou é outra coisa?

Nesse caso, a dica de ferramenta proveniente de ReSharper, cujo mecanismo de análise corretamente determina uma referência nula possível. Por que não recebemos uma mensagem de análoga do verificador? Que é devido a primeira linha de a Figura 5:

Contract.Assume(context != null);

Com essa instrução, você garante o verificador de que a variável contexto nunca é nulo. O verificador basta você confie e adiciona essa informação para a sua base de conhecimentos. O reSharper atualmente não oferece suporte completo.NET código contratos, que explica por que ele ainda proporciona um aviso. Por outro lado, ReSharper dá suporte a seu próprio conjunto de anotações que você pode usar a mesma maneira como com suposições. Consulte bit.ly/lVSnkj para obter mais detalhes.

Uso otimizado da análise estática

Análise estática é difícil, e até mesmo provavelmente não é uma ciência exata. Acontece freqüentemente que você preenche seu código com informações de contrato com melhores intenções, apenas para descobrir que ele diminui significativamente o processo de compilação. Há duas abordagens a serem considerados para otimizar o uso de contratos e análise subseqüente.

Primeiro, você talvez queira criar uma configuração de build especial e ativar a verificação estática somente em que. Alterne para ele periodicamente, pegue os comentários e aplicá-lo. Quando terminar, você voltar para desenvolver sua solução, como de costume, sem a sobrecarga adicional de análise estática.

Em segundo lugar, você pode tentar usar contratos gradativamente. Aplicar contratos extensivamente no código, mas você desativar contratos no nível do assembly. Você pode fazer isso, simplesmente adicionando o atributo a seguir para as propriedades do assembly:

[assembly: ContractVerification(false)]

Em seguida, reabilitar o contrato de verificação somente onde você estiver atualmente concentrado: classe, método ou assembly. Você pode usar o mesmo atributo com um valor true.

Conclusão

Análise estática é uma técnica que visa avaliar a correção do seu código-fonte sem executá-lo. Existem algumas ferramentas que fazem isso para várias extensões. Uma é simplesmente o compilador; outra ferramenta de análise é o verificador estático — um executável que normalmente se integra com o processo de compilação. No.NET Framework, uma ferramenta especial do verificador estático funciona aprendendo fatos sobre o seu código de contratos de código. O verificador, em seguida, avalia esses fatos e destaca os possíveis erros e violações do contrato.

Cada vez quando a complexidade aumenta continuamente e equipes de desenvolvimento sempre executar a falta de tempo, integrada de análise estática salva um pouco de tempo em compilações e, mais importante, evita que você bugs desagradáveis que chegam a seu software apenas em casos de canto.

Dino Esposito é o autor de "Programming Microsoft ASP.NET MVC"(Microsoft Press, 2010) e co-autor do"Microsoft.NET: arquitetura de aplicativos corporativos "(Microsoft Press, 2008). Residente na Itália, Esposito é um palestrante sempre presente em eventos do setor no mundo inteiro. Ele siga Twitter no twitter.com/despos.

Graças aos seguinte técnico especialista para revisar este artigo: Manuel Fahndrich