Uma ferramenta para adicionar e completar a documentação do código-fonte do PHP

Eu tenho vários projetos de PHP mais antigos e terminados com um monte de itens que eu gostaria de documentar no estilo javadoc / phpDocumentor.

Ao trabalhar com cada arquivo manualmente e ser forçado a fazer uma revisão de código ao lado da documentação seria a melhor coisa, eu sou, simplesmente sem restrições de tempo, interessado em ferramentas para me ajudar a automatizar a tarefa, tanto quanto possível.

A ferramenta em que eu penso seria idealmente as seguintes características:

Opcional:

  • Reconhecimento automático de tipos de parâmetros, valores de retorno e tal. Mas isso não é realmente necessário.

O idioma em questão é o PHP, embora eu possa imaginar que uma ferramenta C / Java possa ser capaz de lidar com arquivos PHP depois de alguns ajustes.

Obrigado pela sua excelente contribuição!

Eu acho que PHP_Codesniffer pode indicar quando não há docblock – veja os exemplos de relatórios nesta página (citando um desses) :

 -------------------------------------------------------------------------------- FOUND 5 ERROR(S) AND 1 WARNING(S) AFFECTING 5 LINE(S) -------------------------------------------------------------------------------- 2 | ERROR | Missing file doc comment 20 | ERROR | PHP keywords must be lowercase; expected "false" but found | | "FALSE" 47 | ERROR | Line not indented correctly; expected 4 spaces but found 1 47 | WARNING | Equals sign not aligned with surrounding assignments 51 | ERROR | Missing function doc comment 88 | ERROR | Line not indented correctly; expected 9 spaces but found 6 -------------------------------------------------------------------------------- 

Suponho que você poderia usar PHP_Codesniffer para pelo menos obter uma lista de todos os arquivos / classs / methods que não possuem documentação; Pelo que eu lembro, ele pode gerar XML como saída, o que seria mais fácil de analisar usando alguma ferramenta automatizada – que poderia ser o primeiro passo de algum docblock-generator 😉

Além disso, se você estiver usando o phpDocumentor para gerar a documentação, esse não pode reportar erros nos blocos em falta?

Após alguns testes, pode – por exemplo, executá-lo em um arquivo de class com muita documentação, com a opção --undocumentedelements , como esta:

 phpdoc --filename MyClass.php --target doc --undocumentedelements 

Dá isso no meio da saída:

 Reading file /home/squale/developpement/tests/temp/test-phpdoc/MyClass.php -- Parsing file WARNING in MyClass.php on line 2: Class "MyClass" has no Class-level DocBlock. WARNING in MyClass.php on line 2: no @package tag was used in a DocBlock for class MyClass WARNING in MyClass.php on line 5: Method "__construct" has no method-level DocBlock. WARNING in MyClass.php on line 16: File "/home/squale/developpement/tests/temp/test-phpdoc/MyClass.php" has no page-level DocBlock, use @package in the first DocBlock to create one done 

Mas, aqui, também, mesmo que seja útil como ferramenta de relatório, não é útil quando se trata de gerar os docblocks faltantes …

Agora, não conheço nenhuma ferramenta que gerasse previamente os docblocks faltantes para você: geralmente uso PHP_Codesniffer e / ou phpDocumentor em meu mecanismo de continuous integration, informa faltando docblocks e, então, cada desenvolvedor adiciona o que falta , do IDE …

… O que funciona muito bem: geralmente não há mais do que alguns documentos em falta todos os dias, então a tarefa pode ser feita à mão (e o Eclipse PDT fornece um recurso para pré-gerar o docblock para um método, quando você está editando um arquivo / método específico) .

A partir disso, não conheço nenhuma ferramenta totalmente automatizada para gerar docblocks … Mas tenho certeza de que conseguimos criar uma ferramenta interessante, usando:

  • A API Reflexão
  • token_get_all para analisar a origem de um arquivo PHP.

Depois de um pouco mais de pesquisa, no entanto, eu encontrei este blog-post (é em francês – talvez algumas pessoas aqui possam entender) : Adicionar automático de Tags phpDoc à l’aide de PHP_Beautifier .
Possível tradução do título: “Adicionando adicionalmente tags phpDoc, usando PHP_Beautifier”

A idéia não é realmente ruim:

  • A ferramenta PHP_Beautifier é bastante agradável e poderosa, quando se trata de formatar algum código PHP que não está bem formada
    • Eu usei muitas vezes para código que eu nem consegui ler ^^
  • E pode ser estendido, usando o que ele chama de ” filtros “.
    • veja PHP_Beautifier_Filter para obter uma lista de filtros fornecidos

A idéia que é usada no blog post que eu ligue é:

  • crie um novo filtro PHP_Beautifier, que irá detectar os seguintes tokens:
    • T_CLASS
    • T_FUNCTION
    • T_INTERFACE
  • E adicione um bloco de documentos “rascunho” logo antes deles, se ainda não existe

Para executar a ferramenta em algum arquivo MyClass.php , tive que instalar o PHP_Beautifier pela primeira PHP_Beautifier :

 pear install --alldeps Php_Beautifier-beta 

Em seguida, baixe o filtro para o diretório no qual eu estava trabalhando (poderia colocá-lo no diretório padrão, é claro) :

 wget http://fxnion.free.fr/downloads/phpDoc.filter.phpcs cp phpDoc.filter.phpcs phpDoc.filter.php 

E, depois disso, criei um novo script beautifier-1.php (com base no que é proposto no blog post que eu beautifier-1.php , mais uma vez) , o que:

  • Carregue o conteúdo do meu arquivo MyClass.php
  • Instanciate PHP_Beautifier
  • Adicione alguns filtros para embelezar o código
  • Adicione o filtro phpDoc que acabamos de baixar
  • Embellize a fonte do nosso arquivo e faça eco para a saída padrão.

O código do roteiro beautifier-1.php gostará disto:
(Mais uma vez, a maior parte é uma cópia-colar do blog-post; eu apenas traduzi os comentários e alterei algumas coisas pequenas)

 require_once 'PHP/Beautifier.php'; // Load the content of my source-file, with missing docblocks $sourcecode = file_get_contents('MyClass.php'); $oToken = new PHP_Beautifier(); // The phpDoc.filter.php file is not in the default directory, // but in the "current" one => we need to add it to the list of // directories that PHP_Beautifier will search in for filters $oToken->addFilterDirectory(dirname(__FILE__)); // Adding some nice filters, to format the code $oToken->addFilter('ArrayNested'); $oToken->addFilter('Lowercase'); $oToken->addFilter('IndentStyles', array('style'=>'k&r')); // Adding the phpDoc filter, asking it to add a license // at the beginning of the file $oToken->addFilter('phpDoc', array('license'=>'php')); // The code is in $sourceCode // We could also have used the setInputFile method, // instead of having the code in a variable $oToken->setInputString($sourcecode); $oToken->process(); // And here we get the result, all clean ! echo $oToken->get(); 

Note que eu também tive que phpDoc.filter.php duas pequenas coisas em phpDoc.filter.php , para evitar um aviso e uma notificação …
O patch correspondente pode ser baixado lá: http://extern.pascal-martin.fr/so/phpDoc.filter-pmn.patch

Agora, se executarmos aquele beautifier-1.php script:

 $ php ./beautifier-1.php 

Com um arquivo MyClass.php que inicialmente contém esse código:

 class MyClass { public function __construct($myString, $myInt) { // } /** * Method with some comment * @param array $params blah blah */ public function doSomething(array $params = array()) { // ... } protected $_myVar; } 

Aqui está o tipo de resultado que obtemos – uma vez que nosso arquivo está embutido:

  * @copyright 2009 FirstName LastName * @link * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version CVS: $Id:$ */ /** * @todo Description of class MyClass * @author * @version * @package * @subpackage * @category * @link */ class MyClass { /** * @todo Description of function __construct * @param $myString * @param $myInt * @return */ public function __construct($myString, $myInt) { // } /** * Method with some comment * @param array $params blah blah */ public function doSomething(array $params = array()) { // ... } protected $_myVar; } 

Podemos observar:

  • O bloco de licença no início do arquivo
  • O docblock que foi adicionado na class MyClass
  • O docblock que foi adicionado no método __construct
  • O docblock no doSomething já estava presente no nosso código: não foi removido.
  • Existem algumas tags @todo ^^

Agora, não é perfeito, é claro:

  • Não documenta todas as coisas que poderíamos querer também
    • Por exemplo, aqui, não documentou o protected $_myVar
  • Não aprimora os docblocks existentes
  • E não abre o arquivo em nenhum editor gráfico
    • Mas isso seria muito mais difícil, acho …

Mas eu tenho muita certeza de que essa idéia poderia ser usada como ponto de partida para algo muito mais interessante:

  • Sobre as coisas que não são documentadas: adicionar novas tags que serão reconhecidas não devem ser muito difíceis
    • Você só precisa adicioná-los a uma lista no início do filtro
  • Melhorar os docblocks existentes pode ser mais difícil, devo admitir
  • Uma coisa legal é que isso pode ser totalmente automatizado
  • Usando o Eclipse PDT, talvez isso possa ser definido como uma Ferramenta Externa , então podemos, pelo menos, iniciá-lo a partir do nosso IDE?

Uma vez que o PHPCS já foi mencionado, eu lanço a Reflection API para verificar o DocBlocks em falta. O artigo abaixo é um breve tutorial sobre como você pode abordar seu problema:

Existe também um pacote PEAR PHP_DocBlockGenerator que pode criar o bloco de página do arquivo e o DocBlocks para include, variables ​​globais, funções, parâmetros, classs, constantes, propriedades e methods (e outras coisas).

Você pode usar o Código Sniffer para PHP para testar seu código contra um conjunto predefinido de diretrizes de codificação. Ele também verificará os docblocks em falta e gerará um relatório que você pode usar para identificar os arquivos.

O php-tracer-weaver pode codificar o instrumento e gerar docblocks com os tipos de parâmetros, deduzidos através da análise de tempo de execução.

As versões 1.4.x do phpDocumentor têm a opção -u (–undocumentedelementos) [1], o que causará que os elementos não documentados sejam listados como avisos na página errors.html que ele gera durante a execução da doc.

Além disso, PHP_DocBlockGenerator [2] da PEAR parece que pode gerar docblocks faltantes para você.

[1] – http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.howto.pkg.html#using.command-line.undocumentedelements

[2] – http://pear.php.net/package/PHP_DocBlockGenerator

Utilizamos codeniffer para esta funcionalidade no trabalho, usando padrão padrão PEAR ou Zend. Não permitirá que você edite os arquivos sobre a marcha, mas definitivamente lhe dará uma lista, com linhas e descrição do tipo de docblock faltando.

HTH, Jc

Não há idéia se é alguma ajuda, mas se Codesniffer pode apontar as funções / methods, então um IDE decente do PHP (eu ofereço PHPEd) pode facilmente inspecionar e armazenar os comentários PHPDoc para cada function.

Basta digitar /** acima de cada function e pressionar ENTER e PHPEd irá preencher automaticamente o código com @param1 , @param1 , @return , etc. preenchido corretamente, pronto para suas descrições extras. Aqui é o primeiro que tentei fornecer um exemplo:

  /** * put your comment here... * * @param mixed $url * @param mixed $method * @param mixed $timeout * @param mixed $vars * @param mixed $allow_redirects * @return mixed */ public static function curl_get_file_contents($url, $method = 'get', $timeout = 30, $vars = array(), $allow_redirects = true) 

Isso é facilmente ajustado para:

  /** * Retrieves a file using the cURL extension * * @param string $url * @param string $method * @param int $timeout * @param array $vars parameters to pass to cURL * @param int $allow_redirects boolean choice to follow any redirects $url serves up * @return mixed */ public static function curl_get_file_contents($url, $method = 'get', $timeout = 30, $vars = array(), $allow_redirects = true) 

Não é exatamente uma solução automatizada, mas rápido o suficiente para mim como desenvolvedor preguiçoso 🙂

Você quer realmente automatizar o problema de preencher os dados do tipo “javadoc”?

O DMS Software Reengineering Toolkit pode ser configurado para fazer isso.

Ele analisa o texto original, assim como os compiladores, constrói estruturas de compilation internas, permite implementar análises arbitrárias, fazer modificações nessas estruturas, e depois regenerar (“prettyprint”) o texto de origem alterado de acordo com as mudanças de estrutura. Mesmo preserva comentários e formatação do texto original; você pode, naturalmente, inserir comentários adicionais e eles aparecerão e isso parece ser seu principal objective. DMS faz isso para muitos idiomas, incluindo PHP

O que você gostaria de fazer é analisar cada arquivo PHP, localizar cada class / método, gerar os comentários “javadoc” que devem ser essa entidade (diferença para classs e methods, certo?) E depois verifique se os comentários correspondentes estavam realmente presentes na estruturas compiladoras. Caso contrário, basta inseri-los. PrettyPrint o resultado final. Como ele tem access às estruturas do compilador que representam o código, não deve ser difícil gerar parâmetros e informações de retorno, como você sugeriu. O que não pode fazer, é claro, é gerar comentários sobre o propósito da intenção ; mas pode gerar um espaço reservado para você preencher mais tarde.

Eu tive que fazer um grande lote de automação de docblock corrigindo recentemente, principalmente com base na resposta correta acima kwith algumas mudanças específicas do contexto. É um hack, mas estou ligando de volta aqui, caso seja útil para outras pessoas no futuro. Essencialmente, ele faz análises básicas em tokens de blocos de comentários dentro do PHP Beautifier.

https://gist.github.com/israelshirk/408f2656100196e73367

Intereting Posts