@TypeChecked, @CompileStatic and GContracts

As of version 1.2.9 GContracts [0] - a Design by Contract library - supports Groovy's @CompileStatic and @TypedChecked annotations. With Groovy 2.0, @CompileStatic can be used to execute type checks during compile time, bypass the Groovy meta object protocol and force a Java-like byte-code generation.@TypeChecked can be used to apply type checks only. The newest version of GContracts enriches certain elements of the abstract syntax tree with type information during compile time.

Static Typing and Contracts == <3

Before 2.0, applying @Invariant, @Requires and @Ensures on code written in a dynamic language has been half-baked. As class definitions could be changed during runtime, there was always the chance of a contract being implicitly violated although the contract did successfully evaluate beforehand. With @TypeChecked and @CompileStatic we can ensure type safety and therefore strengthen the applicability of GContracts. Check out the following statically typed Stack example:
 

@Grab(group='org.gcontracts', module='gcontracts-core', version='[1.2.9,)')
import org.gcontracts.annotations.*

@groovy.transform.CompileStatic
@Invariant({ elements != null })
class Stack<T> {

    List<T> elements

    @Ensures({ is_empty() })
    def Stack()  {
        elements = []
    }

    @Requires({ preElements?.size() > 0 })
    @Ensures({ !is_empty() })
    def Stack(List<T> preElements)  {
        elements = preElements
    }

    boolean is_empty()  {
        elements.isEmpty()
    }

    @Requires({ !is_empty() })
    T last_item()  {
        elements.get(count() - 1)
    }

    def count() {
        elements.size()
    }

    @Ensures({ result == true ? count() > 0 : count() >= 0  })
    boolean has(T item)  {
        elements.contains(item)
    }

    @Ensures({ last_item() == item })
    def push(T item)  {
       elements.add(item)
    }

    @Requires({ !is_empty() })
    @Ensures({ last_item() == item })
    def replace(T item)  {
        remove()
        elements.add(item)
    }

    @Requires({ !is_empty() })
    @Ensures({ result != null })
    T remove()  {
        elements.remove(count() - 1)
    }

    String toString() { elements.toString() }
}

def stack = new Stack<Integer>()

 
The above example shows a statically compiled Stack class, that is fully annotated with pre-/postconditions and a class invariant.

Cool stuff - how can I get it?

If you want to play with GContracts and Groovy 2.0 and its static typing features, download Groovy [1], fire up the groovyConsole, copy and paste the above example and you are ready to go with GContracts and Groovy. Alternatively, you can use GContracts in your Gradle project by adding compile 'org.gcontracts:gcontracts-core:1.2.9' to your build.gradle. For an introduction to static typing and compilation in Groovy 2.0 I would suggest watching this Gr8Conf presentation by Cédric Champeau [2]. Happy hacking!

[0] GContracts - Design by Contract for Groovy
[1] Groovy Download Page
[2] Cédric Champeau: Static Type Checking and Compilation in Groovy 2.0