Accidentally left off the list. ---------- Forwarded message --------- From: Paul King <pa...@asert.com.au> Date: Wed, Oct 7, 2020 at 7:52 AM Subject: Re: Private/protected no-arg constructor with @MapConstructor/@Immutable? To: Damir Murat <damir.mu...@gmail.com>
It is certainly possible to write an additional helper AST transform. It is complicated somewhat for the TupleConstructor case by the fact that it is not until the class generation phase that the non-full tuple related constructors are created. The easiest approach would be to only support changing the no-arg constructor produced from @MapConstructor. There is currently a little wiggle room in the implementation details which while not guaranteed forever is likely not to change until possibly Groovy 5 or beyond. It allows a trick of manually using the normally internal @Generated marker interface as follows: import groovy.transform.* import static groovy.transform.options.Visibility.PRIVATE @Immutable @MapConstructor(noArg=false) @TupleConstructor(visibilityId='hidden') @VisibilityOptions(id = 'hidden', value = PRIVATE) class Foo { String a, b, c @Generated private Foo(){ this([:]) } } // private no-arg, public map, private full tuple constructor assert Foo.declaredConstructors*.modifiers == [2, 1, 2] Cheers, Paul. On Wed, Oct 7, 2020 at 4:56 AM Damir Murat <damir.mu...@gmail.com> wrote: > > It's a little strange in that the visibilityId would control visibility > for both the map and no-arg variations > > unless the noArgVisibilityId attribute was set. > > Yes, it is strange a little, but not unbearable :-) > > > Also, if you set noArg=false for @MapConstructor and defaults=true > for @TupleConstructor, you get the > > no-arg constructor from the tuple constructor defaults with no way to > set the visibility independently > > for the 2 or more related constructors. > > Actually, this might work for me, since I want only a map constructor > anyway. But, I guess it's not > appropriate as a general solution. > > Is it possible to write an AST transform that will reduce the visibility > of the default constructor if it exists? > I mean, MapConstructorASTTransformation and > TupleConstructorASTTransformation are assigned to the > CANONICALIZATION phase, and that new transformation should execute after > them, I believe. Is it possible > to arrange such ordering without changing Groovy code? > > Tnx, > Damir > >