Todo o poder do IntelliJ IDEA no exemplo de um idioma (nas imagens)

O modelo de desenvolvimento clássico para qualquer aplicativo implica uma boa documentação na interface do usuário e na API, bem como, se necessário, uma boa cobertura do código-fonte com comentários. Nesse caso, a finalização do sistema começa com um estudo da documentação, o código é alterado diretamente e, finalmente, todas as informações necessárias são atualizadas.

No entanto, um dos problemas dessa abordagem é que ela aumenta significativamente o custo e diminui o processo de desenvolvimento. E se tudo isso não for? Em seguida, o IDE é resgatado, graças ao qual você pode estudar a lógica atual usando código simples.

Quando desenvolvemos a plataforma lsFusion com uma linguagem incorporada, tínhamos várias opções. Reinvente a roda e escreva do zero seu próprio IDE, como a 1C fez ao mesmo tempo, ou implemente um plug-in para um já existente. Seguimos o segundo caminho e, neste artigo, mostrarei o que aconteceu.

Como a própria plataforma foi desenvolvida em Java, tivemos duas opções principais: Eclipse ou IDEA. Decidimos a última opção e não falhamos. Quando tomamos a decisão, o IDEA ainda não era popular o suficiente, mas desde então eles emergiram como líderes no mercado, e o Eclipse está silenciosamente para trás.

Não demorou muito tempo para desenvolver o plug - in , pois foi possível usar o código usado diretamente durante a execução da plataforma. Assim, com o mínimo esforço, obtivemos um IDE muito poderoso, em muitos aspectos significativamente superior em funcionalidade ao IDE de muitas outras plataformas de ERP (nativas e criadas no Eclipse).

É difícil superestimar o papel do IDE no desenvolvimento. Apesar do fato de que muitos desenvolvedores ainda usam o vim e acreditam que deveria. Esta posição tem direito à vida se uma pessoa desenvolver e apoiar ainda mais esse código. No entanto, em projetos maiores, onde um grande número de pessoas está envolvido, sua intercambialidade é muito importante. Os funcionários ficam doentes, saem de férias, saem no final. Além disso, a carga em projetos diferentes é desigual e, às vezes, é necessário conectar mais pessoas a um deles para cumprir os prazos. Nesses momentos, você precisa conectar novas pessoas às melhorias, que precisam descobrir rapidamente como o programa está funcionando no momento e fazer as alterações necessárias. E aqui vem o IDE.

Antes de tudo, precisávamos do seguinte no IDE:

  • Suporte de sintaxe . Destaque de palavra-chave, substituição automática, destaque de erro.
  • Navegação Vá para o anúncio, pesquise usos, pesquise por sequência de texto, arquivo ou nome, etc.
  • Análise . A hierarquia de classes e chamadas, bem como as propriedades e ações da classe.
  • Refatoração Renomeando classes, propriedades e ações.
  • Visualização de formulários . Exibir para o desenvolvedor o design atual de um determinado formulário.
  • Metaprogramação . A capacidade de gerar código baseado em metacódigo em tempo real .
  • Depurador A capacidade de definir pontos de interrupção (incluindo condições), depurar a lógica imperativa, assistir a relógios.
  • Injeção de linguagem . Destaque para sintaxe de navegação, refatoração, substituição automática e lsFusion quando usado em outros idiomas - Java e XML de JasperReports.

Como usamos o esquema padrão incorporado no IDEA para o plug-in, a saída do trabalho com lógica no lsFusion acabou sendo quase idêntica ao desenvolvimento em Java. Os mesmos itens de menu, teclas de atalho, depuração transparente, que podem alternar do código lsFusion para Java e vice-versa, e assim por diante.

Aqui estão alguns exemplos simples para mostrar como isso funciona na prática.

Suporte de sintaxe


O plug-in pode substituir palavras-chave válidas, possíveis propriedades, detectar automaticamente vários erros:

imagem

Navegação


Pegue a lógica do exemplo de Gerenciamento de material . Suponha que precisamos ver onde a propriedade Price é declarada. Para fazer isso, você precisa colocar o ponteiro do mouse sobre o cabeçalho da coluna que precisamos como usuário com direitos de administrador:

imagem

Na janela exibida, é possível ver imediatamente em qual módulo essa propriedade é criada (Remessa), qual número de linha está nela (37), a tabela na qual está armazenada (_auto_Shipment_ShipmentDetail) e várias outras informações.

Para ir diretamente para a declaração de propriedade, é necessário iniciar a pesquisa do arquivo e inserir Remessa na caixa de diálogo exibida:

imagem

imagem

Em seguida, usando Navegar - Linha / Coluna, vá para a 37ª linha, onde vemos a declaração da propriedade:

imagem

Pressionando CTRL + ALT + F7, enquanto o cursor está na propriedade desejada, você pode encontrar rapidamente todos os seus usos para todos os projetos:

imagem

Nesse caso, o primeiro uso do preço é no cálculo do valor por linha. Os dois últimos estão sendo adicionados aos formulários apropriados.

Se necessário, você pode ativar a pesquisa apenas por registro nesta propriedade, se remover a opção correspondente:

imagem

Somente a entrada nesta propriedade permanecerá na lista. Para descobrir qual valor específico está gravado nele, você precisa percorrer o preço de venda e clicar em Ir para declaração ou usos. Em seguida, volte para Navegação - Voltar e vá para a declaração da propriedade do item:

imagem

Para resumir, descobrimos onde essa propriedade que precisávamos foi declarada, em que casos ela é usada e quando a gravação vai para lá. No vídeo, eu fiz todas as ações com o mouse, embora, é claro, na prática, apenas o teclado seja usado. Essa técnica permite determinar rapidamente a lógica atual do sistema implementada e fazer alterações, tendo um entendimento completo do que isso levará.

Refatoração


Muitas vezes, há situações em que você precisa alterar o nome de uma propriedade, classe, formulário ou qualquer outro elemento do sistema. Para executar essa ação, você precisa permanecer nesse elemento e clicar em Refatorar - Renomear:

imagem

Renomear um elemento altera automaticamente o código-fonte em todos os locais de uso. Além disso, se o arquivo migration.script for criado, as entradas correspondentes serão adicionadas lá. O servidor precisa conhecer as alterações de nome para, por exemplo, migrar automaticamente os dados de uma coluna para outra. Caso contrário, é impossível distinguir renomear e criar uma nova propriedade com um nome diferente.

Análise


Antes de realizar a refatoração, muitas vezes é necessário descobrir "o que está acontecendo" e "quem são todas essas pessoas".

Para fazer isso, o IDEA, quase pronto, permite exibir a estrutura da classe selecionada (propriedades e ações disponíveis para esta classe):



Além disso, se você precisar obter uma imagem geral do que está acontecendo, o IDEA permitirá criar várias hierarquias:

  • herança da classe selecionada
  • Usos do item selecionado (por exemplo, propriedades ou formulários)



Todos os principais recursos são fornecidos pelo IDEA automaticamente (com gestos mínimos) após a implementação dos anúncios do mecanismo de pesquisa. O conjunto de recursos a seguir fez o plug-in mexer um pouco mais, mas ainda assim uma parte significativa da infraestrutura foi fornecida pelo IDEA (não sem problemas, é claro, mas mais sobre isso posteriormente).

Visualização de formulário


No lsFusion, a estrutura e o design dos formulários são definidos no mesmo código que a lógica do domínio usando construções especiais. Além disso, diferentes partes do formulário podem ser declaradas em diferentes módulos e, quando o servidor iniciar, elas serão "mescladas", dependendo dos módulos conectados.

Para ver o design resultante, é claro, você pode reiniciar o servidor e assistir o resultado no cliente. Mas a reinicialização do servidor leva algum tempo. Um plug-in pode:

  • Mostrar o design atual e a estrutura hierárquica do formulário em uma janela especial
  • Encontre elementos na estrutura da forma
  • Destacar o elemento de forma selecionado no design

Aqui está o que parece no IDE:

imagem

Ao criar um formulário, apenas o módulo ativo atual e tudo do qual ele depende são levados em consideração.

Ainda não é possível alterar visualmente o design atual, pois o formulário é formado a partir de vários blocos de código. Durante a modificação, é difícil determinar claramente em qual local você precisa fazer as alterações apropriadas. Além disso, o mesmo elemento pode ser modificado em vários blocos de código, e a plataforma garante que, se um módulo depende de outro, suas alterações serão aplicadas por último. No entanto, no futuro, planejamos adicionar determinadas funcionalidades para alterações no design visual.

Metaprogramação


Às vezes, é necessário criar o mesmo tipo de código para várias tarefas. O LsFusion possui um mecanismo de metacódigo que permite gerar código com base em algum modelo. Nesse caso, no caso de uma alteração no metacódigo, o código será atualizado automaticamente. De fato, é uma cópia / colagem automática com a capacidade de substituir determinados identificadores por valores especificados.

Para ativar esse mecanismo, você deve primeiro ativá-lo no menu. Depois disso, o IDE alterará automaticamente o código correspondente.

imagem

Quando o servidor iniciar, somente o código gerado será usado. Os próprios modelos META não serão levados em consideração ao iniciar o servidor.

A propósito, a implementação da possibilidade de metaprogramação nos forçou a dar outra contribuição ao código aberto (neste caso, Intellij IDEA). O fato é que, no ERP, os metacódigos são usados ​​de maneira bastante ativa e, consequentemente, geralmente é necessário gerar código / excluir o código gerado. Isso leva a um grande número de alterações de arquivos assíncronas, o que, por sua vez, leva a um bug muito peculiar. O problema é que eles não podiam ser reproduzidos no próprio JetBrains, então tudo se resumiu ao fato de que nós mesmos tivemos que escrever um teste de unidade que não funcionava. É claro que isso levou vários dias, mas indiretamente nos ajudou a implementar as duas possibilidades a seguir.

Depurador


Quando o código não está totalmente claro o que está acontecendo, você precisa acessar o depurador. Em qualquer linha da lógica imperativa (ações, eventos, restrições), você pode colocar um ponto de interrupção. Assim que a execução do servidor atingir esse ponto, ela será interrompida e o controle passará para o depurador. Neste momento, você pode assistir a relógios e também continuar a execução linha por linha. À esquerda, um rastreamento de pilha será mostrado, ao longo do qual você pode navegar como se estivesse depurando um aplicativo Java comum.

imagem

Ao visualizar valores atuais, você pode acessar os objetos atuais (por exemplo, Remessas) e quaisquer outros objetos do banco de dados (por exemplo, Item i). No entanto, o próprio desenvolvedor é responsável por adicionar dados aos relógios, cuja leitura levará muito tempo ou memória e levará a uma queda no desempenho.

Você também pode definir pontos de interrupção em uma propriedade específica. A execução será interrompida em qualquer lugar quando um registro for feito:

imagem

Isso é útil quando você precisa determinar qual evento ou ação altera o valor de uma propriedade.

Para realmente implementar o depurador, usamos o IDEA Java Debugger existente. Ou seja, a plataforma está sendo depurada como um aplicativo Java comum, mas para ações lsFusion criamos métodos java proxy e substituímos sua exibição pelo nosso código (como eu o entendo no IDEA, isso é feito para oferecer suporte ao Scala e outros wrappers sobre Java). E aqui foi um momento engraçado. Em algum momento, os desenvolvedores do IDEA tornaram o construtor de seu Java Debugger privado. E se a situação de chamar métodos privados ainda puder ser contornada através do Reflection, então como herdar de uma classe com um construtor privado não será claro. Mas exatamente naquele momento houve um confronto com um bug da seção superior, e nós “trocamos” decidimos pedir às pessoas do JetBrains para tornar esse construtor protegido de volta, ao qual eles reagiram muito rapidamente (pelo que, é claro, muito obrigado a eles).

Injeção de linguagem


Um dos recursos mais incomuns do IDEA é a capacidade de fornecer suporte para o seu idioma nas constantes de strings de outros idiomas. Para fazer isso, basta informar à IDEA exatamente quais constantes de sequência se aplicam ao seu idioma e, em seguida, a própria IDEA automaticamente:

  • gera um arquivo virtual (ou vários arquivos) com os prefixos fornecidos para cada constante de cadeia
  • cria no editor do arquivo de origem para todas as constantes uma espécie de “janela” nesse arquivo virtual
  • fornece neste arquivo virtual suporte para todos os recursos do idioma "incorporado", como destacar erros, alternar para um anúncio, preenchimento automático, pesquisar usos e, mais importante, refatorar. Ou seja, ao renomear qualquer elemento em um idioma, ele é renomeado automaticamente em todas as constantes de string que se referem a esse elemento em outros idiomas. Assim, você é automaticamente protegido contra links quebrados.



Aqui na IDEA houve (e ainda existe) um pequeno bug . Quando o arquivo virtual é grande, se a IDEA deve ir para o início da "janela de implementação" quando continuar a usá-lo, na verdade vai para o final da "janela de implementação" anterior (ou seja, para o uso anterior da propriedade no arquivo Java). Obviamente, uma solução simples para esse bug é criar um arquivo virtual separado para cada literal de string. Mas essa abordagem fica mais lenta quando há mais de 30 usos, portanto, nesse caso, você ainda precisa usar um arquivo virtual grande (por outro lado, quando há muitos usos, não é tão difícil encontrar o caminho certo, ou seja, o seguinte). Pedimos para corrigir esse bug novamente no âmbito da "troca de serviços", e os desenvolvedores do JetBrains o corrigiram, mas, como se viu mais tarde, de alguma forma não era (ainda era visível pelo commit, mas achamos que não era apenas entendeu ele no final). No entanto, todos nós estamos acostumados a esse bug há muito tempo, pois a situação com o uso de mais de 30 elementos em um arquivo é bastante rara.

Conclusão


O artigo descreve apenas os principais casos de uso. Ele também tem a capacidade de procurar implementações de propriedades e classes abstratas, visualizar dependências entre módulos e propriedades, gerar automaticamente formulários baseados em xml / json e muito mais. E, é claro, há uma integração embutida com os principais sistemas de controle de versão do Git e Subversion, além de suporte ao Maven e Ant.

Seguindo o caminho de desenvolvimento do plug-in IDEA, com pouco esforço, obtivemos um ambiente de desenvolvimento integrado gratuito muito poderoso que supera o IDE dos concorrentes em muitos aspectos.

Source: https://habr.com/ru/post/pt465573/


All Articles