2015-08-16

All field constructor in Groovy

TupleConstructor annotation in Groovy generate constructors for class with each of its properties (eventually also fields). The class below

@TupleConstructor(includeFields = true)
class Person {
   String firstName
   String lastName
   private boolean male
}

will have constructors: Person(), Persion(String), Person(String, String) and Person(String, String, boolean). You could test it using code below.

class TupleConstructorTest extends GroovyTestCase{
    @Test
    void testSimpleTupleConstructorShouldGenerateConstructor() {
        assertScript '''
            import groovy.transform.TupleConstructor
            @TupleConstructor(includeFields = true)
            class Person {
                private final String firstName
                private final String lastName
                private final boolean male
                String toString(){ "$firstName $lastName $male" }
            }

            assert Person.constructors.size() == 4

            assert new Person().toString() == 'null null false'
            assert new Person('John').toString() == 'John null false'
            assert new Person('John','Smith').toString() == 'John Smith false'
            assert new Person('John','Smith', true).toString() == 'John Smith true'
        '''
    }
}

I almost always create classes with all private final fields and generate constructior with all fields using my IDE.

So I have prepared new transformation AllFieldConstructor which bases on TupleConstructor and generates only constructor with all fields as parameters.

class AllFieldConstructorTest extends GroovyTestCase{
    @Test
    void testSimpleTupleConstructorShouldGenerateConstructor() {
        assertScript '''
            import com.blogspot.przybyszd.transformations.AllFieldConstructor
            @AllFieldConstructor
            class Person {
                private final String firstName
                private final String lastName
                private final boolean male
                String toString(){ "$firstName $lastName $male" }
            }

            assert Person.constructors.size() == 1

            assert new Person('John','Smith', true).toString() == 'John Smith true'
        '''
    }
}

The sources are available here