
Freqüentemente, os programadores precisam lidar com o código desconhecido de outra pessoa. Esse pode ser o estudo de projetos de código aberto interessantes e a necessidade de trabalho - no caso de ingressar em um novo projeto, ao analisar uma grande quantidade de código legado, etc. Eu acho que cada um de vocês já se deparou com isso.
No processo desse trabalho, sempre senti a necessidade de uma ferramenta especialmente adaptada para facilitar o processo de imersão rápida em grandes volumes de código desconhecido. Com o tempo, idéias cada vez mais interessantes apareceram em diferentes áreas, e todas elas exigiram o estudo de grandes volumes do código de outras pessoas. Redes descentralizadas, criptomoedas, compiladores, sistemas operacionais - todos esses são grandes projetos que requerem o estudo de quantidades significativas de código. Em algum momento, eu decidi: você só precisa pegar e fazer essa ferramenta especial. Neste artigo, apresento a sua atenção o que aconteceu como resultado.
O que geralmente pode ajudar na aprendizagem do código? Obviamente, é bom quando existe documentação detalhada para o código - como regra geral, não existe; um bom estilo de codificação e comentários também são bons, mas isso geralmente não é suficiente. Existem também vários geradores de documentação de código, como doxygen. Ao analisar a estrutura do código e os comentários especiais do documentário, eles geram documentação na forma de hipertexto no formato html. A principal desvantagem dessa documentação é sua não interatividade; no processo de estudar o código, o programador pode ter um novo entendimento e, para refleti-lo na documentação, é necessário escrever novos comentários no documentário e regenerar toda a documentação novamente.
Além disso, essa documentação não se relaciona diretamente ao código no ambiente de desenvolvimento, ou seja, clicar no hiperlink não abrirá o arquivo com este código no IDE. Existe uma boa analogia para essas ferramentas, enraizadas nos tempos antigos: os primeiros desmontadores eram ferramentas de linha de comando que geravam código sem a intervenção do usuário. Depois veio o primeiro desmontador interativo ("IDA pro"), que assumiu a participação ativa do usuário no processo de desmontagem - atribuindo nomes de variáveis e funções, definindo estruturas, escrevendo comentários sobre código etc.
A análise de grandes volumes de código estrangeiro em um idioma de alto nível é, de certa forma, muito semelhante à desmontagem. Assim, comecei a desenvolver uma idéia do que exatamente eu quero. A maioria dos IDEs possui painéis clássicos de Exibição de arquivo e Exibição de classe que exibem a estrutura dos arquivos e os espaços de nome / classe dentro deles. Mas essa estrutura geralmente está intimamente conectada à sintaxe do idioma e não permite que você faça carregamento semântico personalizado. Portanto, a primeira coisa que eu queria era a capacidade interativa de construir árvores arbitrárias contendo referências de código nomeadas de maneira significativa - para as mesmas classes e funções, ou para lugares arbitrários. E o segundo é o desejo de marcar de alguma forma o código diretamente no editor. As marcas podem ter vários significados: do simples "aprendido", "resolvido", "reescrito" ao código pertencente a diferentes grupos semânticos. Você pode marcar com um comentário, mas eu queria algo mais perceptível. Por exemplo, alterações na cor do plano de fundo de um pedaço de código. Portanto, os separadores de cores KDPV são uma analogia bastante precisa do mundo real.
Após os primeiros experimentos, percebi rapidamente que esse deveria ser um plug-in para o ambiente de desenvolvimento moderno, e não meu próprio editor. Trabalhar com dois editores ao mesmo tempo é estúpido e inconveniente; a perspectiva de repetir todas as possibilidades do ambiente de desenvolvimento não inspirou alegria e por que o que já foi feito? Portanto, o plugin. O Qt Creator foi escolhido como o primeiro IDE simplesmente porque as operações de navegação de código mais populares (Ir para definição, Localizar referências, etc.) são executadas o mais rápido possível. O próximo ambiente será o Visual Studio e, em seguida, em caso de sucesso do próprio conceito - implementação para outros IDEs.
Agora, sobre como tudo está organizado. O conceito de "comentários do marcador" é introduzido. Este é um comentário regular de uma linguagem de programação (no momento, é um comentário de linha única "//" usado em várias linguagens - C, C ++, C #, Java, ...), seguido por uma sequência de caracteres especiais, seguida por um identificador e / ou tags, que pode ser seguido por um comentário humano normal. Eu introduzi três tipos de comentários de marcador
- Comente para destacar uma área arbitrária. O único tipo que requer um comentário de marcador "fechado". Começa com "// <<" e termina com "// >>".
- Comentário para indicar uma linha arbitrária no código. Denotado por "// $$"
- Comentário para destacar o bloco de código sintaticamente correto. Começa com "// @@" e inclui o bloco de código abaixo, limitado pelas chaves "{" e "}", que são usadas para blocos de código na maioria das linguagens de programação tipo C. Uma análise completa de chaves foi implementada - colchetes aninhados são permitidos e o analisador ignora corretamente colchetes em linhas e comentários.
Além disso, imediatamente após os caracteres especiais, segue um ou mais identificadores, separados por vírgulas. Identificadores são "tags" e podem significar o que o programador deseja - sinais "estudados", "reescritos", "entendidos", autoria do código, relação do código com alguns grupos semânticos etc. Você também pode especificar um identificador exclusivo - ele é colocado primeiro e separado do resto por dois pontos. Se desejar, você pode especificar explicitamente a cor de plano de fundo do snippet de código - uma grade é colocada no final da lista de tags, após a qual a cor no formato RGB é indicada (embora esse método não seja o melhor - falaremos sobre outra maneira mais "correta" posteriormente). E, no final, você pode colocar um espaço e escrever um comentário legível por humanos. Tentei escolher a sintaxe de forma que fosse o mais simples possível para entrada rápida, não bagunçasse o código e fosse conveniente para comentários comuns.

Embora a entrada manual de comentários do marcador seja possível, é suposto usar botões especiais da barra de ferramentas para isso. O cursor está na posição desejada do código e o botão é pressionado (ou uma das últimas opções é selecionada no menu).

Se necessário, será aberta uma caixa de diálogo de entrada, na qual é possível inserir tags e identificadores dos comentários dos marcadores, uma descrição detalhada e também selecionar uma cor de fundo. Esses dados serão inseridos não apenas no código, mas também na árvore “CRContentTree”, exibida na lateral do painel da árvore (onde FileView, ClassView, etc.). Deve-se observar que a cor do plano de fundo pode ser "transparente" - nesse caso, a cor do plano de fundo do bloco anexo (se houver) é usada ou a luz de fundo não é usada.

No momento, a árvore consiste em três partes principais (nós de nível superior): ARQUIVOS, TAGS e NOTAS (essa pode não ser a solução final, porque o conceito ainda não é óbvio, além da conveniência dessa estrutura).

FILES é a estrutura de arquivos do projeto, extraída do arquivo do projeto ou do local das fontes no disco. Nós de arquivo são criados durante a geração inicial da árvore. Clicar duas vezes em um nó de arquivo geralmente abre o arquivo no editor IDE. Você pode especificar a adição de comentários do marcador em FILES - um nó filho aparecerá no arquivo correspondente. É aqui que os identificadores exclusivos de comentários do marcador são adicionados. O sistema verifica a exclusividade do identificador no nó do arquivo da árvore e possibilita gerar um nome exclusivo automaticamente.
TAGS é uma nuvem de tags de projeto global; as tags não estão vinculadas ao arquivo de código-fonte e podem ocorrer em qualquer arquivo de projeto quantas vezes você desejar.
O NOTES é um local para armazenar nós agrupados de maneira arbitrária e não vinculados à estrutura do arquivo. Cada nó contém um caminho de arquivo e um identificador. O principal objetivo é criar grupos lógicos personalizados. Por exemplo, "todas as funções que precisam ser reescritas" ou "todas as funções relacionadas à criptografia" ou "a sequência de funções de comunicação de rede com o servidor" (como os nós na árvore são ordenados, basta colocar os nós um após o outro para exibir qualquer sequência).
Cada nó da árvore possui um menu de contexto. O nó pode ser excluído (embora isso não remova comentários do marcador do código - desde que não tenha certeza de que isso seja necessário), você pode editá-lo. Você pode adicionar nós que não estão associados aos comentários do marcador: você pode adicionar, por exemplo, um link (Link). Clicar duas vezes nesse nó abrirá um recurso relacionado em um programa associado, por exemplo, um hiperlink em um navegador.
Cada nó pode ser desativado desmarcando a caixa de seleção no nó. Isso fará com que o destaque desse nó e todos os nós filhos no código sejam removidos. Assim, removendo, por exemplo, marcas de seleção dos três nós raiz (FILES, TAGS e NOTES), você pode desativar o realce de todos os comentários do marcador, exceto aqueles cuja cor é indicada explicitamente no código (através das barras).
Clicar duas vezes no nó abre o arquivo correspondente no IDE e posiciona o cursor na posição do código correspondente. Para tags que podem ocorrer repetidamente, em vez de abrir o arquivo, é formada uma lista de todas as ocorrências, carregada no painel Saída de CR, e clicando duas vezes na linha correspondente dessa lista, você pode abrir o arquivo e posicionar no código.
Cada nó possui um campo para uma descrição detalhada (texto de várias linhas de comprimento arbitrário). Essa descrição é carregada na área “CR Info” com uma seleção simples de um nó na árvore (com um único clique do mouse), além de colocar o cursor em qualquer lugar da área destacada no código e clicar no botão “Lookup” na barra de ferramentas. A edição está sempre disponível, o texto alterado é salvo automaticamente (por perda de foco). Estou pensando em dar suporte ao formato Markdown nessa área, mas até agora minhas mãos ainda não chegaram a esse ponto.

Nem sempre é desejável (ou nem sempre é conveniente) inserir comentários no código. Portanto, a segunda possibilidade é "assinaturas", ou seja, use como marcadores do próprio código. Uma assinatura é uma certa sequência de tokens (excluindo espaços e quebras de linha - ou seja, "foo (1,2,3)" e "foo (1, 2, 3) são um e o mesmo). Existem três tipos de assinaturas:
- bloco - um bloco é realçado, começando com uma assinatura e incluindo uma sequência de código entre colchetes.
- linha única - a linha inteira com a assinatura é destacada
- simbólico - somente a sequência da assinatura é destacada. É conveniente usar essas assinaturas para destacar nomes individuais - variáveis, funções, classes.
Trabalhar com blocos de assinatura é o mesmo que com blocos de marcador. Da mesma forma, nós em uma árvore são criados.
Se para nós de marcador o identificador e as tags foram criados separadamente, então para nós de assinatura é sugerido indicar exatamente como queremos considerar a assinatura - como um identificador (anexado a um arquivo) ou como uma etiqueta global. Por exemplo, para “nomes” é lógico usar o modo de marcação - o nome correspondente será destacado no código em todo o projeto.

Outro recurso interessante é a construção de cobertura de código. Uma função especial digitaliza o código e determina os locais que não estão marcados, e forma uma lista desses locais na "Saída CR". Isso não leva em consideração linhas e comentários vazios, ou seja, a verificação leva em consideração apenas códigos significativos. Ao clicar duas vezes na linha da lista, você pode ir para este local no código e, depois de estudá-lo, marcá-lo de uma maneira ou de outra.
Um pouco sobre o formato de armazenamento do banco de dados. Na verdade, apenas os comentários dos marcadores são armazenados no código-fonte; o conteúdo da árvore é armazenado em um arquivo xml especial com a extensão ".cr". Não há ligação explícita do arquivo de banco de dados aos projetos, embora, quando você abre um projeto, seja feita uma tentativa de abrir um arquivo cr com o mesmo nome se nenhum arquivo cr tiver sido baixado anteriormente.
Para resumir. Em geral, implementei quase tudo o que queria. O conceito é novo e incomum e, portanto, leva algum tempo e feedback do usuário para entender o que precisa ser desenvolvido e o que pode ser abandonado. Na tentativa de realizar o maior número possível de oportunidades, algo acabou por ser um pouco complicado demais, o que é inevitável. A interface em si ainda não foi estabelecida e será alterada. Mas, no geral, parece ter funcionado muito bem.
O que está nos planos. Esta versão é demo, amplamente bruta e não se destina ao uso comercial. Eu tenho um sonho - fazer meu próprio produto comercial, trazendo até uma renda pequena, mas constante, suficiente para realizar outros projetos interessantes. Além disso, algumas coisas não são adaptadas para uso comercial. Eu imagino como adaptar um sistema semelhante ao modo multiusuário, levando em consideração o fato de que o código pode ser editado por várias pessoas trabalhando simultaneamente através do sistema de controle de versão. Também é possível olhar para a geração de documentação familiar (html), possivelmente ferramentas para uma integração mais profunda com o código (analisando em vez de lexical / bracket, recebendo automaticamente listas de classes e métodos e convertendo-os em nós da árvore). Obviamente, é necessário corrigir bugs (que ainda estão lá) e melhorar os recursos. E é claro que estou aguardando seus comentários com idéias e sugestões :)
Isso é tudo por enquanto (embora ainda existam alguns recursos pequenos que não mencionei no artigo - por exemplo, considerei necessário adicionar guias, pois sem eles é muito triste - embora existam vários plugins para guias; alguns comandos básicos do Qt também são exibidos na barra de ferramentas Criador não relacionado ao plug-in; etc.).
Link para download:
https://www.dropbox.com/s/9iiw5x7elwy3tpe/CodeRainbow4.zip?dl=0Requisitos do sistema: Windows, Qt Creator> = 4.5.1 compilado pelo MSVC2015 32bit (este é o assembly padrão distribuído no download.qt.io)
instalação: descompacte o arquivo compactado e copie o plug-in para a pasta c: /Qt/Qt5.10.1/Tools/QtCreator/lib/qtcreator/plugins (este é um exemplo de posicionamento padrão do Qt, se você tiver o Qt instalado de forma diferente ou outra versão - o caminho será diferente) e (re) execute o Qt Creator.