Código Limpo – Bom Código – Parte III

Continuando nossa série sobre código limpo, hoje vamos iniciar falando sobre as premissas do código limpo, quais regras devo seguir para que meu código possa ser considerado limpo e um bom código?

Use nomes reveladores da intenção

É fácil de entender que nomes de classes, métodos, variáreis, records, types etc, devem revelar a intensão do mesmo. Lembrem se que tudo que você lê no seu código deve deixar-lo feliz, por passar um entendimento claro do que esta acontecendo.

Eu outras palavras nomes de variáveis e métodos devem responder a seguinte questão. O nome deve revelar por que ele existe, o que ele faz e como ele faz, simples assim, pergunte-se após criar um novo método se isso esta claro. Se o nome requer um comentário então o nome não revela a intensão do método ou variável.

Evite nomes que revelam pistas falsas

Recentemente encontrei um nome de variável em um determinado método que recebia o resultado de um cálculo, o interessante é que nome da variável era, valorMenor. Provavelmente em algum momento essa variável foi utilizada para receber o menor valor do cálculo, mas por descuido ou desleixo foi alterado o método e ela passou a receber o resultado que poderia ser maior ou menor;

Outro exemplo que dificulta muito a leitura de um código é utilizar nome de métodos, variáveis, classes etc. preenchendo o mesmo com letras lowercase. Por exemplo, calculamedia, não seria mais fácil de ler se escrevesse-mos CalculaMedia? ou mesmo calculaMedia? Detalhes importantes que fazem toda diferença no momento da leitura do código fonte.

Faça Distinções Significativas

Programadores criam problemas para eles mesmo quando eles escrevem um código unicamente para o compilador interpretar. Se você precisar criar uma classe para receber informações e dados de produtos por exemplo, você deve evitar criar classes assim: TProduto1 = class e TProduto2 = class, ao invés disso crie, TProdutoData e TProdutoInfo. Parece óbvio mas encontro muitas coisas sem sentido por aí.

Use Nomes Pronunciáveis

Se você pode pronunciar o nome de uma variável ou classe então você pode discutir sobre ela sem parecer um idiota tentando pronunciar algo sem fonética.

Use Nomes pesquisáveis

Letras simples, números soltos tem um problema ao serem pesquisados pois não são fáceis de visualizar no código fonte. Eu particularmente prefiro usar nomes curtos para variáveis como letras soltas em variáveis locais onde o escopo de visibilidade seja pequeno. Nomes de Fields de uma classe por exemplo devem ser claros e de fácil localização.

Nome de Classes

Nome de classes e objetos devem ser substantivos, como Customer, Page, Account. Evite usar palavras como Manager, Processor que são verbos. Detalhe importante que facilita a leitura do seu código fonte e o entendimento da funcionalidade do objeto.

Nome de Métodos

Ao contrário das classes métodos devem ser verbos, como postPayment, deletePage, Save, Processar etc. Jamais esqueçam de seguir o nome padrão para métodos que retornam algo, usando Get ou Retorno. e Set ou Setar para os que definem valores.

Ao trabalhar com propriedades considere utilizar uma declaração simples sempre que não for necessário manipular o valor no Get ou no Set. Exemplo:

property Salario: Integer read FSalario write FSalario;

Use Nomes Inteligentes

Lembre que as pessoas que irão ler seu código são programadores portando vá em frente e use termos conhecidos pela computação, nomes de algoritmos, nomes de patterns, termos matemáticos e assim por diante.

O nome AccountVisitor significa que o programador esta familiarizado com o Visitor Pattern e assim por diante, o objetivo é sempre facilitar o entendimento do método. Um grande amigo uma vez me disse que um método bem nomeado é aquele que você sabe o que ele faz somente lendo seu nome.

Considerações Finais

É difícil pensar sobre escolher bons nomes que sejam fáceis de ler e que compartilhe com facilidade o objetivo daquele método, contudo precisamos ficar atentos a nome redundantes, principalmente de variáveis, algo que me deixa frustrado é ler em um com variáveis nomeadas com. Resulta1, Resultado2, Resultado3. Sem chance meus amigos, vamos colocar nossa cérebro para funcionar, tenho certeza que podemos fazer melhor do que isso. A partir do próximo artigo iremos começar a falar sobre métodos iniciando pelas funções e algumas regras de ouro para mantermos um código limpo.

Vejo vocês em breve, bons códigos a todos!

Código Limpo – Bom Código – Parte II

No artigo anterior falamos um pouco sobre analise de requisitos e o que nos leva a escrever um código ruim. Lembrei agora da citação de um amigo de longa data que disse uma vez em uma de suas palestras. “O código de nossa aplicação é como o nosso sangue, se nosso sangue estiver ruim com certeza ficaremos doente”. Eu sempre lembro dessa frase quando estou trabalhando em um código com problemas, ou escrevendo algo novo.

Entendemos até aqui a importância de escrevermos um código limpo. Então chegou o momento de nos perguntarmos, será que nós realmente sabemos o que é um código limpo? Gosto de pensar que um código fonte é como uma pintura, uma obra de arte, cada um de nós pode interpretar de uma maneira, o importante para que tenhamos um julgamento correto é entendermos o código. Reconhecer a arte é um dom e requer tempo de análise. A má noticia que bem ou mau todos nós sabemos pintar.

Escrever um código limpo requer disciplina, começar a aplicar pequenas regras e ser meticuloso linha a linha é um bom começo. Todo programador precisa ter um bom senso de código, pois a maioria consegue identificar um código ruim, mas não sabe como escrever um código bom. Senso de código é uma habilidade que pode ser desenvolvida durante anos de trabalho. A má notícia é que esse profissional precisa ser dedicado aos estudos e procurar melhorar sempre. So assim o senso de código será desenvolvido corretamente.

O que é Código Limpo (Clean Code)

Bjarne Stroustrup inventor do C++; Eu gosto do meu código elegante e eficiente. A lógica deve ser direto para ser difícil de esconder bugs, com o mínimo de dependências para facilitar a manutenção…

Quando Bjarne cita um código elegante ele quer dizer que o código deve ser fácil de ler, você precisa ler o código e entender o que ele faz sem muito esforço. Veremos mais para frente como pequenas alterações em nossas regras de codificação podem ajudar nessa tarefa.

Notem também outra chave para o sucesso em sua definição de um bom código, mínimo de dependência. Para os entusiastas da orientação a objeto essa premissa é básica. Lembram? Alta coesão e baixo acoplamento. Aqui esta a prova de que trabalhar utilizando técnicas de orientação a objeto é um bom começo para um código limpo.

Não posso deixar de chamar a atenção dos leitores da importância de entender e seguir de forma rigorosa as premissas da Orientação a Objeto. Infelizmente me deparo com códigos que são reconhecidos por seus criadores por serem escritos orientado a objeto que pecam em muitas dessas regras básicas. Não seguir as regras básicas de orientação a objeto é escrever um monstro, uma bagunça organizada, que será o pesadelo dos programadores que precisarem fazer manutenção nesse monstrinho.

Um código limpo é focado, cada função, cada classe, cada módulo expõe uma única funcionalidade que permanece nos detalhes.

Grady Booch, autor Object Oriented Analysis and Design with Application disse; Código limpo é simples e direto você lê como uma conversa bem escrita, o código limpo nunca esconde o objetivo, possui uma abstração nítida.

Big Dave Thomas fundador da OTI, pai do Eclipse descreve; Código limpo pode ser lido e melhorado por outros desenvolvedores sem dificuldades. Possui units de teste, e nomes destacando a funcionalidade. O código deve ser literal.

O que nos chama a atenção aqui é observarmos que ele chama a atenção para as units de teste. Preciso abrir um parênteses aqui e chamar a atenção dos leitores para que dediquem tempo a conhecer e estudar o TDD = Test Driven Development, desenvolver orientado a testes por assim dizer, garante uma qualidade no código e segurança na hora do deploy.

Sim você precisa de mais tempo para escrever seu código de forma que as classes de testes possam ser criadas automaticamente, TDD existe para todas as linguagens e IDE’s, no Delphi costumo utilizar o DUnit que é um framework para criar as classes de teste. Recomendo fortemente que tomem nota desse assunto e que se aprofundem nele. Existe muito material legal na Web para que você possam estudar. E obviamente surgindo dúvidas estou a disposição.

Michael Feathers, autor de Working Effectively with Legacy Code, nos diz; Eu poderia listar as qualidades que percebo em um código limpo mas existe uma que é mais abrangente. Um código limpo sempre foi escrito por alguém que se importa com a qualidade.

Penso que se importar com a qualidade requer um trabalho minucioso. Eu particularmente gosto de escrever uma função, testar, e olhar para ela alguns instantes, então me pergunto. O que pode ser melhor? Como poderia ser mais eficaz? Os nomes de variáveis e parâmetros dizem a quem ler essa função o que ela faz? São pequenos detalhes que muitas vezes apontam para falhas óbvias que não enxergamos pois estamos com todo contexto do projeto em mente.

Ron Jeffries, autor de Extreme Progaming Installed e Extreme Programming Adventure in C#; Recentemente eu criei algumas regras para um código limpo, são elas.

  • Rodar todos os testes
  • Não conter partes duplicadas
  • Expressar todos os desejos e o objetivo da função
  • Minimizar o número de entidades tal como classes, métodos etc.

Vamos fazer um breve resumo para encerrar a parte II dessa série. Código limpo é aquele que temos prazer em ler, ao analisarmos uma função sabemos exatamente que parâmetro precisamos passar para ela e o que ela irá retornar. Cada classe criada é especialista em uma única funcionalidade, e não depende de outras classes para funcionar. Dependência mútua entre classes, expressamente proibido.

Declaro aqui a minha segunda regra inalterável. Não pode haver dependência mútua entre classes!!!!!!

Ficamos por aqui, em breve teremos outro artigo da séria Código Limpo.

Obrigado pela atenção dos amigos leitores e Bons Códigos!

Código Limpo – Bom Código – Parte I

A partir desse pequeno artigo, pretendo abordar um assunto de suma importância para nós programadores. Como podemos identificar bons códigos? O que podemos considerar um bom código? Quais critérios precisamos utilizar para podemos dizer que o código esta limpo e pode ser considerado um bom código?

Sejam bem vindos a essa série de artigos, o objetivo de todo trabalho é estarmos habilitados a escrever bons códigos e aos poucos podermos nos considerar bons programadores.

Não irei atentar a frases bonitas bem elaboradas, utilizando a concordância verbal perfeita e a maneira mais polida de falar sobre os temas que irei abortar. Então me perdoem se não estiver a contento, conto com a compreensão de todos.

Vamos ao que nos interessa, irei separar em tópicos tudo que considerar importante para termos ao final do trabalho um bom código. Contudo, quero chamar a atenção dos amigos que escrever um bom código não se trata apenas de seguir as boas práticas de programação, aplicar corretamente os conceitos de programação orientada a objeto, ter uma identação perfeita etc.

Um bom código precisa ser eficiente, e atender ao requisito apresentado, precisa ser de fácil leitura, precisa estar organizado, precisa ser em outras palavras coerente. Então vamos falar do primeiro critério de avaliação para um bom código.

Análise de Requisitos

Sim, item fundamental para que não percamos tempo desenvolvendo algo errado por não entender qual resultado final nosso código deve gerar. Analisar os requisitos para determinada funcionalidade, vai além de dedicar alguns minutos pensando e partir para o código feito louco. Jamais façam isso, por mais que a ansiedade de começar a produzir código seja grande, lembrem-se que ao analisarmos os requisitos com calma, criarmos diagramas de sequência, listarmos as partes que serão afetadas, etc. Tudo isso já é estar produzindo. Então você jamais deve se considerar improdutivo se passar um ou dois dias fazendo a análise minuciosa do requisito, levantando dúvidas e entendendo a funcionalidade para então podermos escrever um código eficaz e legível.

Adicionar Funcionalidades ao Código

Não é raro estarmos trabalhando em determinado projeto com meia dúvida de requisitos listados, analisados, estudados, discutidos, e então começado a ser transcrito para o código da máquina, e um novo requisito aparece!

A capacidade de abstrair e entender o que o cliente precisa para dentro de um código é algo de suma importância, mas infelizmente não podemos prever novas ideias que o cliente apresenta no decorrer do projeto e que chegam a nós como um novo requisito a ser incorporado ao sistema.

Com certeza essa situação pouco a pouco se torna um grande pesadelo, pois teremos no mínimo dois impactos catastróficos por assim dizer. Primeiro, o prazo definido para a entrega do sistema dificilmente irá mudar, e voce estar atrasado. Segundo tentar adaptar a nova funcionalidade, por mais simples que pareça pode destruir nosso código. Nesse momento o bom código desaparece e a pressa para entregar no prazo aliada a necessidade de não falhar e fazer com que o requisito funcione com o menor esforço, obrigado os programadores a cometer um erro inadmissível. Criar uma pequena Gambiarra tenho certeza que os amigos ja conhecem essa palavra, e mais certeza de que um dia, vocês fizeram uma. Para atender um prazo, para facilitar sua vida naquele momento, etc. Motivos para uma que uma gambiarra seja feita normalmente não faltam.

Infelizmente uma leva a outra que leva a outra que caracteriza nosso código como um lixo. Sim estou sendo severo utilizando esse termo, mas se faz necessário para chamar a atenção do amigo(a) leitor(a) como é importante evitar essa abordagem. Afinal, quem irá fazer a manutenção no código? Provavelmente vocês, então quem irá se arrepender desse atalho? Com certeza vocês.

Então declaro aqui a minha primeira regra inalterável. Gambiarra Jamais!!!!!!

Eu entendo que muitas vezes estamos pressionados pelo chefe para terminar o projeto. Muitas vezes estamos pensando no backlog e em todas as outras coisas que voce prometeu fazer, afinal você quer ser um bom funcionário, talvez até receber um premio, bônus ou algo assim. Então você é aquele funcionário que diz “Sim Senhor” para tudo. Cuidado meu amigo isso pode lhe colocar em uma armadilha e obrigá-lo a escrever um código ruim para atender toda demanda.

Infelizmente o dia que esse código passar por uma análise e você for julgado como um mau programador por ter escrito um código ruim ou feito uma gambiarra, ninguém vai lembrar da quantidade de trabalho que você tinha e quanto estava produzindo deixando assim os chefes felizes. Lembre, em nossa profissão, tempo é dinheiro.

Finalizamos por aqui, em breve estarei publicando a parte II, meu objetivo é manter a sequência de um pequeno artigo por dia.

Até Breve e Bons Códigos a todos!

New in Delphi 10.4: Redesigned Code Insight

What do we mean by Code Insight?

First, some background. If you’re familiar with Code Insight, skip ahead…

Code Insight is our name for a set of IDE productivity features in the editor. For the purposes of this blog post, those features are:

  • Code Completion: the dropdown list box that predicts what you want to type. Appears when you type a period (.) after an identifier, or when you press Ctrl+Space.
  • Parameter Completion: the hint that appears showing the parameters for a method, including multiple variations for an overloaded method. Ctrl+Shift+Space inside method braces ().
  • Find Declaration: right-click on an identifier and click Find Declaration, and it will take you to where that method, variable, type etc is defined. You can also hold Control down and move your mouse over the editor, and applicable identifiers will turn into hyperlinks you can click on to find their declaration, which is known as Code Browsing.
  • Tooltip Insight: hover your mouse over a variable or type, and you will be shown information about it. Sometimes this includes XMLDoc, and is known as Help Insight. (We need to clarify names in our doc.)
  • Error Insight: displays errors in your code before you compile. These are otherwise known as ‘red squigglies’, many people’s preferred terminology – the red zigzag lines under your code. Errors are also shown in the Errors node in the Structure view.

These features have been available in Delphi for many years. Features like this are a key benefit to you when coding an IDE. Code completion especially saves a lot of typing, and error insight helps you make sure your code is working before you spend time compiling.

Classic Code Insight

As the language has grown and time has passed, these features have no longer always worked as well as we have wanted. The technology was cutting-edge when it was introduced, but there were definite improvements we could make today.

It’s been common to see bug reports about spurious errors (ie errors reported in the editor or in the Structure view when the source code is actually perfectly correct code.) Or that the IDE worked in the main thread, so would not respond to keystrokes while it was working to show the code completion list. (You could only press Escape to cancel.) Sometimes, for gigantic projects, calculating the data for code completion could use a lot of memory in the IDE. In addition, the features were implemented with multiple code parsers: code completion and error insight each had a different understanding of the code. And finally, code insight was disabled while debugging, so if you wrote code while debugging you had no productivity assistance.

We did not want this to continue. Our goals for 10.4 have been to:

  • Make Code Insight asynchronous – that is, run on another thread or in another process (or both) so that the IDE is always responsive when you type even if it’s doing work in the background
  • Reduce or even completely remove (you can see where this is going) the potential memory usage for code completion from the IDE
  • Ensure Error Insight always gives correct results – that is, it should give exactly the errors the compiler would, and correct code should show no errors
  • Help us move closer to having a single parser for Delphi source in the IDE, so that there is a ‘single source of truth’ or single understanding of what Delphi code means within the IDE
  • Modernize Delphi’s code tooling approach to use modern techniques
  • And solve a number of bugs in code completion at the same time
  • And add at least one code completion feature… Wait! Add two new code completion features at the same time!

All of this is in Delphi 10.4.

Excited? We are. This is one of the biggest and best changes to the Delphi IDE in fifteen years.

(And don’t worry – if you need, classic code insight is still there, complete with a few new bug fixes, and can be turned on in 10.4 if you want.)

Code Insight Technology in Delphi 10.4

In 10.4, the above Code insight features are implemented using a ‘LSP Server’. You may have heard of this technology, but if not, LSP refers to the Language Server Protocol, which is a standardized way to implement code insight-like features for many languages. An IDE talks to a ‘language server’, which is a small helper app that calculates and generates the information the IDE displays. It does so using a defined protocol, and that’s the language server protocol.

In other words, the IDE now talks to a helper app when you do something like open a project, or type a keystroke in your file, and the IDE can periodically ask it questions, such as: ‘What are the completion results at this location?’. That helper app keeps track of your code, and sends back an answer to any questions, plus any errors it ran into in the code along the way.

Our server app is built around the compiler, using the compiler as a service to provide LSP results. That means that what the IDE displays to you, including ‘red squiggly’ errors, is all data that comes from the compiler itself.

This means a few things:

  • Communication with another process is asynchronous. In the IDE, it’s implemented in another thread. You can keep typing, even close your file or open another project, while the IDE is waiting to hear back on the data it’s requested
  • The work is done in another process. This means all the memory usage for calculating results is no longer in the IDE itself. The IDE has more memory, and the helper app can use its entire memory space dedicated solely to providing results
  • It uses a modern, standardized protocol which applies to many languages
  • What you see onscreen is what the compiler sees. That means it should be accurate. If your code compiles, you won’t see any Error Insight errors; conversely, if you do see red squiggly underlines in your code or in the Structure view, your code will not compile.
  • You can get code completion while debugging.

These are all very good things.

But enough text. Let’s see what it looks like in action!

Modern Delphi Code Insight In Action

It’s hard to show responsiveness in a blog. In these static screenshots, just imagine that you’re typing and you never see Windows wait cursor.

Imagination will become reality when we ship 10.4!

Code Insight While Debugging

The first new feature is a big one, that doesn’t need many words. You can use Code Insight while debugging.

Want to debug your app and type code at the same time, and get code completion? You can.

Yes, what you’re seeing is correct – that’s code completion and error insight both working while you are actively debugging the application.

Completion Results

Getting code completion is the same as in 10.3.3, with the exception that the IDE remains responsive in 10.4. But we’ve added another new feature, which allows you to find what you want through code completion more easily. In 10.4, code completion will now show more useful results than in the past – yet while still keeping 10.3.3’s items at the top of the results list.

Here’s 10.3.3’s code completion, typing ‘act’ after a VCL TButton instance:

Note that 10.3.3 shows very few results – only one, in fact. Classic code completion listed only items that start with what you typed.

Here’s 10.4 in action (pun intended) for the same completion:

In 10.4, code completion lists all items that contain what you typed. Other IDEs do this too, Visual Studio for example, but until now Delphi has shown a more limited list. This is useful because it allows you to search through completion.

For example, suppose you remember that a control has a something-Rect property but you can’t remember what it’s called. In 10.3.3, you’d have to google. In 10.4, just type ‘rect’ and you’ll see:

You can explore your code by typing.

Having more results may not always be what you seek, and you may expect only items that start with what you typed from habit. By default, and to keep the behaviour close to what you’re familiar with from 10.3.3, we sort the completion list so that all starts-with identifiers are placed above all contains identifiers. In other words, the list will give the same results as 10.3.3, but with extra results appended. You don’t need to use those if you don’t want to; they are located after the items that 10.3.3 would have shown you.

If you want behaviour like other IDEs, listing all results together, we have a setting: currently a registry key but we may expose it as UI. That means if you’re more used to what VSCode provides, you can get that too.

In 10.4, sorting all items that start with what you typed together, at the top of the list. This is what you’d see in 10.3.3, and is the default in 10.4.In 10.4, sorting by scope only, so that all items that contain what you typed are shown together. This is more similar to Visual Studio or other IDEs, and is off by default.

Selection in the completion list

Code completion automatically selects the best items in the list for you (so you can just press Enter or Space or ‘.’ or similar to choose that item and keep coding) in the following order:

  • An exact match against what you typed. If there’s no match:
  • Out of items that start with what you typed, the shortest identifier. If there are no starts-with items:
  • Out of items that contain what you typed, the shortest identifier

Prioritising starts-with over contains means the completion list will automatically select ‘Parent’ over ‘SetParent’. Choosing the shortest match means it will select ‘Parent’ over ‘ParentFont’. (You can see this in the above screenshots.) Generally, we find this matches what you are most likely to be typing. Of course you can scroll and press the up and down arrow to select anything you want.

Error Insight

Note in these screenshots you can see live Error Insight, which updates as you type. The partially-typed identifier ‘pare’, which is not valid code, is correctly underlined in red. (The underline will go away when you select an item from the completion list.) Error Insight results come from the compiler itself, and reflect and report exactly what the compiler sees.

You should never see incorrect errors in the editor or the Structure pane. What you see onscreen is accurate.

Multiprocess Architecture

The following is not important for features, but may interest you on a technical level.

I mentioned that the LSP server runs as a separate process, which has a number of benefits including a dedicated 4GB memory address space for code insight. If you look at 10.4 running in the Windows Task manager, you will see multiple DelphiLSP processes. The first controls multiple agents, and we have one agent dedicated to providing completion and other results, and one agent dedicated to providing error insight.

To my knowledge, we are the only LSP server that uses a multiprocess architecture.

Quality

While implementing this, we have also found and fixed a number of issues that affected code completion in the past.

Next Steps

The new code completion is different to 10.3.3 and earlier’s code completion. We’ve worked to make it as similar as possible, including tweaks like sorting starts-with items above others, to make it familiar to you when you first use it. We hope that within a few minutes you’ll get so used to it that you never want to go back to 10.3.3! But we don’t want to present this as exactly the same: you will find differences.

The new Code Insight in Delphi 10.4 solves a lot of issues, and makes using the IDE a much more pleasant and responsive experience for you as well. That’s not to mention the extra results, which can be extremely useful. We plan to continue working on it to move forward by the goals written above. In 10.4 though, we and our beta testers have found it’s a great addition to the IDE.

In addition, we even added two new features: allowing you to explore your code through code completion, and using Code Insight including code completion and other Code Insight features while debugging.

We’re really excited about this feature. Asynchronous. Responsive IDE. Modern protocol. Support for other languages. Code completion while debugging. It’s great stuff. We can’t wait for you to get 10.4 and try it out yourself.

The new LSP-based CodeInsight is fantastic. This is going to revolutionize the product.— Nick Hodges, who has used a beta preview

If you have update subscription, one of the perks is accessing beta builds of upcoming releases. There’s still time to join our beta program for 10.4!

This is a preview of an upcoming release of RAD Studio. There can always be last-minute bugs or changes. Nothing here is final until the release is officially made available.

original source: https://community.idera.com/developer-tools/b/blog/posts/new-in-delphi-10-4-redesigned-code-insight

Upgrading Delphi software, the smart way

This year (2020) Delphi celebrates its 25th anniversary. In those 25 years an enormous amount of code has been written. Many of these applications are still in full use by companies and individuals. This shows the power of Delphi; code written decades ago still works, even in the latest Delphi versions.

Still, there are some remarks to be made about this praise. Unfortunately we see that there are also many applications that are still being developed in old Delphi versions. That is a pity, because the new versions of Delphi really have a lot of advantages. Not only is the IDE much more pleasant to use, the new language enhancements are a real improvement.

There are a number of recurring problems when converting older Delphi applications to the latest Delphi version. For example, as of Delphi 2009 you have to take Unicode into account. In addition, there may be components that are no longer being developed, or that have been significantly modified. This means that there are still companies working with Delphi 5, Delphi 7 or some other old versions. Now, converting your source code is not always easy. At GDK Software we have had many projects and customers who came to us with older Delphi software. Because we often come across the same issues, we have developed a tool that makes conversion much easier; the GDK Compiler Helper. In this post I will briefly explain how the GDK Compiler Helper assists us with the conversion projects, and how GDK Software can also help you with the upgrade of your Delphi project.


GDK Compiler Help


The GDK Compiler Helper uses the Delphi compiler to automatically compile programs, search for errors and modify code to fix these errors. Because all changes are carried out via actions, you can just grab the latest codebase and restart the conversion every time. During the development of the GDK Compiler Helper we have always had in mind to automate the conversion as much as possible.

I will start with a brief introduction to the mechanics of the GDK Compiler Helper. After that I will give some examples of the different actions the tool can perform.

Pre-compilation

We perform a number of steps automatically before starting the compilation process. First we do a pre-compile action on all source code. This consists of the following actions:

  1. Convert all form files (.dfm files) to text files
  2. Perform all pre-process actions that are defined

To start with the first point; with Delphi it is possible to save form files as binary files. Since it is possible to replace components with the compiler helper, the form files must be saved as readable text files.

Then we perform all pre-process actions. Suppose we know that in every pascal file certain modifications have to be made, we can specify these in the action list. The compiler helper will first perform these actions on all source code, before starting the actual compilation.

Compilation

Then we use the Delphi compiler to compile the project and fix errors.

For the purpose of fixing errors, warnings and hints, we have created a database of actions, which the compiler helper uses to automatically perform code changes and recompiles the source code. An action can consist of:

  • Add a unit to the uses
  • Remove or rename units
  • Modify the code by using a simple replace
  • Modify the code using Regular Expressions
  • Add a prefix to an identifier or variable
  • Change the type of a variable
  • Replace a (design time) component
  • Replace all code by running a replace or Regular Expressions over the pascal file.

Examples of actions

Because we have performed many conversions at GDK software, we have compiled quite an extensive list of these actions. Through the GDK Compiler Helper we can easily add and edit these actions:

Edit form for actions

Some examples of compiler errors and the corresponding actions are:

error E2003: Undeclared identifier: 'CurrencyString'

The solution is the action AddPrefixToIdentifier and the prefix or solution is FormatSetting.. Here the GDK Compiler Helper automatically updates the code to FormatSettings.CurrencyString. Likewise for the following errors:

error E2003: Undeclared identifier: 'CurrencyFormat'
error E2003: Undeclared identifier: 'CurrencyDecimals'
error E2003: Undeclared identifier: 'DateSeparator'
error E2003: Undeclared identifier: 'TimeSeparator'
[...and so on]

Another example:

error E2003: Undeclared identifier: 'VarArrayOf'

In this case a unit must be added to the uses class. This is done by using the action AddUnitToInterface where the unit System.Variantsis added.

An example of a more complex action is the solution to the following problem:

error E1050: WideChar reduced to byte char in set expressions.  Consider using 'CharInSet' function in 'SysUtils' unit.

In this example, we have identified the Delphi warnings to show as errors. The solution to this problem is the ReplaceByRegEx action. For a replace action (both the regular action and the Regular Expressions action) we need to specify two parameters; the search string, and the result. In this particular case, the search string was a rather complex Regular Expressions function

([\w\^]+[[]?[\w\+\.\-\s]+[]]?)\s+[Ii][Nn]\s+([a-zA-Z0-9[\s]*[Cc][Hh][Rr][(][\d]+[)]*[a-zA-Z0-9'?,\s(\]]*[Cc][Hh][Rr][(][\d]+[)]*[]\)]?)

and the result

CharInSet(\1, \2)

The Compiler Helper will apply this solution to the specific line of code, after which the compilation process will continue with the rest of the source code.

Adding actions

While working on a conversion, you obviously want to add new actions as easily as possible. Although the GDK Compiler Helper can solve quite a lot of things automatically, there are always specific problems that need to be solved for a project. That’s why you can easily add your own solutions and actions.

As an illustration I will show an example of a part of the conversion of the (open source) MPEG Audio Collection Library. One of the Delphi projects gives the following error message:

error E2003: Undeclared identifier: 'ReadLn'

The corresponding code line is

Str := TCP.ReadLn;

By analyzing the source code I know that the ReadLn function of the Indy Libraries is now in unit TCP.IOHandler instead of in the unit TCP. So we need the action ReplaceIdentifier and replace TCP. with TCP.IOHandler. Adding this action is now very easy:

Adding actions

The main advantage of modifying your source code in this way is that it is transferrable. If this specific code occurs again somewhere else, the GDK Compiler Helper will automatically apply this solution there and continue compiling.


As you have seen it is incredibly easy to update existing Delphi projects to the latest Delphi version with the GDK Compiler Helper. You can also continue the existing development for the old version of the software during the conversion project. Because all changes are stored in actions you can just grab the latest codebase and restart the conversion every time.

How we can help

At GDK Software we want to share our knowledge with other developers, and we want to help companies to get and keep their Delphi software up to date. Therefore we have interesting options to use the GDK Compiler Helper for your software project as well.

Are you interested in a personal demo of the GDK Compiler Helper, or are you looking for help converting a Delphi project? Please contact me via info@gdksoftware.co.uk, or via our website GDK Software.

Thanks for reading!

Fonte do artigo: https://medium.com/@marcogeuze/upgrading-delphi-software-the-smart-way-2cc250aa8a02

Mais informações pelo e-mail da empresa acima, ou se preferir entrem em contato comigo para que possam receber mais informações sobre a ferramenta.

O que posso adiantar é que temos a capacidade de migrar códigos fontes em Delphi para a nova versão em horas.

Forte Abraço!