Code Analysis Technology |

Gobo Eiffel Lint is specially designed to be used in Continuous Integration cycles. For example, each time a developer commits some changes in the Source Control repository, we want to be sure that no Eiffel compilation error has been introduced. And this has to run fast in order to get feedback as soon as possible, before someone else commits other changes. Most of us will use our favorite Eiffel compiler and try to compile our Eiffel system in order to figure out whether our code still compiles correctly or not. But some Eiffel compilers do not check the validity of dead code (Eiffel code which is not reachable from the root creation procedure). Some other Eiffel compilers just take too long to compile the Eiffel system and therefore are not suitable as a Continuous Integration job. For example, at work we have to deal with 20,000 Eiffel classes. Following are benchmarks when using `ec.exe` or `ecb.exe` from ISE to check the validity of our Eiffel classes (in non-void-safe mode and non-full-class-checking mode):

    	ec.exe -config integration.ecf
    		21 minutes
    		RAM: 3.6 GB
    		EIFGEN: 1.8 GB

     	ecb.exe -config integration.ecf
     		16 minutes
     		RAM: 3.5 GB
     		EIFGEN: 1.8 GB

It's way too slow when part of a Continuous Integration cycle. gelint has been designed with this constraint in mind. First, it keeps all data about the Eiffel system in memory. No temporary files are written to disk. This makes the process run faster since memory accesses are much faster than disk accesses. In order to fit everything in memory, gelint only keeps track of what is strictly necessary in order to analyze the Eiffel code and to report useful messages in case of validity errors. For example the Gobo Eiffel parser can be configured to ignore comments, note clauses, etc. which are Eiffel constructs with no validity rules associated with them. Furthermore, the AST (Abstract Syntax Tree) is built in such a way that whenever an object can be shared, it will not be duplicated. After all these data fit into memory, the next design goal of gelint is to avoid the best that it can to create temporary objects. This avoids having a garbage collector which spends too much time reclaiming the memory for these objects instead of using these CPU cycles to actually analyze the Eiffel system under inspection. To achieve that, gelint uses extensively the Visitor Pattern, having objects traversing the AST to perfom some specific tasks rather than having each node in the AST perform these tasks themselves. That way these visitor objects can reuse the same intermediate objects when performing these tasks on the various nodes of the AST rather than having these intermediate objects being created by each AST node. Following are the benchmarks when using this technology:

     	gelint.exe integration.ecf
    		41 seconds
    		RAM: 2.0 GB
    		No disk usage

This is much more acceptable for a Continuous Integration job. In this benchmarks `gelint.exe` is almost 25 times faster than `ecb.exe`. In fact at work we are using gelint in full-class-checking mode, with the following results:

     	gelint.exe --flat integration.ecf
    		1 minute 19 seconds
    		RAM: 2.1 GB
    		No disk usage

which is still acceptable in our Continuous Integration cycle. Starting with Gobo Eiffel 4.2, gelint can now take advantage of multi-threading. Following are the results on a 4-CPU machine in full-class-checking mode:

     	gelint.exe --thread=4 --flat integration.ecf
    		29 seconds
    		RAM: 2.1 GB
    		No disk usage

Note that these benchmarks are when `gelint.exe` has been compiled with gec (the Gobo Eiffel Compiler) and executed with no GC. When using the Boehm GC, it will be slower by about 1 or 2 seconds and the memory usage will go down to 1.7 GB.

At work we have been using gelint for more than 10 years, and it was very successful at finding Eiffel validity rule violations with clear error messages. Some of my colleagues sometimes tell me that they better understand the error messages from gelint than those from ISE EiffelStudio. Apart from that, gelint and EiffelStudio will catch the same errors most of the time. It is even possible that from time to time gelint will report validity errors that EiffelStudio would have missed. On the other hand, if you find cases where gelint would have missed a validity error, please report it to me so that I can fix this issue.