IDE generated code - a good idea?

In my previous post I mentioned how pain acted as a trigger to positive action. In this post, let's analyse potential solutions to the problem I had mentioned in the above post and what can we learn from them.

At the time of this incident, our team was using an IDE based on Eclipse. I had used code template feature of Eclipse to generate my logger code. These days I use IntelliJ IDEA, and it provides a similar feature called live templates. I can configure a live template to generate the code that creates a logger object as follows.

When you want to use the template created by you, just key in the abbreviation, you can also key in the first few letters of the abbreviation in combination with auto-completion.

There is an alternative way to solve this problem by customising the class template for Java under 'File and Code Templates'. This technique also falls under the same category of techniques which is code generation. You might have similar features for generating getters and setters, try-catch block etc.

While it was a reasonably simple use-case, let's try to analyse the technique of generating code using IDE templates in general. While it is undoubtedly better than copy-pasting the code, it has certain drawbacks.

One of the drawbacks of IDE generated code is that it's your responsibility to maintain the generated code and ensure continued correctness. If you update the templates, only subsequent invocations take the updated templates. What about the code that the previous version of the template produced? While we did not have better solutions in the earlier days, we can certainly do better today.

There is another limitation with the code generation using an IDE. If your team members are using different IDEs (may be an open source project), you might end up with inconsistent generated code. If you watch closely, this is a violation of the DRY principle. The situation can also arise if your team members use the same IDE, but do not share the settings.

I came across this better solution I talked about when I started working with Groovy language. Groovy provides an AST transformation named @Slf4j, which when applied, the compiler generates the code that is required to create the logger object. The Groovy source code looks as follows.

@groovy.util.logging.Slf4j
class MyClass {
}

The generated JVM code is as follows. Note Groovy compiles down to bytecode directly, it doesn't produce Java source code as an intermediate. The following code is obtained using the 'Inspect AST'  feature of 'groovyconsole'  tool.

public class MyClass extends java.lang.Object implements groovy.lang.GroovyObject { 
    private static final transient org.slf4j.Logger log
    static { 
        log = org.slf4j.LoggerFactory.getLogger('MyClass')
   }
   // code goes on
}

Since your source code doesn't contain any overhead (beyond the annotation), there are fewer moving parts and hence lesser scope for errors.

If you are a Java developer, don't worry.  Project lombok is there to cover you. Lombok provides @Log, @CommonsLog, and @Slf4j for java util logger, Apache commons logger and Slf4j respectively.

To summarise, I believe that IDE code generation is a good approach to start with. Once you have a reasonable idea of the code that needs to be generated, or you start invoking the code generation template frequently, it's worth considering other approaches such as annotation processing or AST transformation (depending on the language you use). Essentially, you offload the code generation to the compiler.