Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
3.0.9
-
IntelliJ 2021.1.1 x64
AdoptOpenJDK-11.0.11+9
WIN 10
Description
- When using named paramters on an @NamedVariant annotated ctor or method, default values for parameters not passed are ignored and the parameters are set to null instead
- This does not occur when no paramaters are passed, or (trivially) if all named parameters are passed
- Default parameters are a powerful feature of Groovy, not having them supported requires one to
- Treat parameters who cannot have null as an allowed value who are passed as null as having the default value (leading to a lot of clutter / boiler plate code)
- Parameters for which null is a valid value, special-meaning e.g. EMPTY instances have to be implemented and given as the default parameter value, to be mapped to the actual value as with the null values above, which evidently is even more cumbersome & inelegant
- Sample code
- Note: assertEquals is used since at least in IntelliJ it supplies a link to the integrated text diff viewer, allowing to conevniently compare the expected and actual results:
import groovy.transform.NamedVariant import org.junit.Test import simple.groovy.helper.Foo import simple.groovy.helper.NamedVariantTestClass import static org.junit.Assert.assertEquals //@CompileStatic // compile-static or not does not matter class NamedVariantTest2 { @Test void namedVariantCtorBug_DefaultArgumentsAreIgnored() { final resultList = [ new NamedVariantTestClass(), new NamedVariantTestClass(text:"cba"), new NamedVariantTestClass(text:"cba", foo:new Foo(8765,'Oof')), new NamedVariantTestClass(text:"cba", foo:new Foo(8765,'Oof'), number:4321), //new NamedVariantTestClass("cba", foo:new Foo(321,'foot'), number:7777) ] // Fails: all non-given ctor arguments are incorrectly set to null instead of being given their default value, unless all or no arguments are passed. assertEquals resultList.join('\n'), """ NVTC(number=1234, text=abc, foo=Foo(5678,'Foo')) NVTC(number=1234, text=cba, foo=Foo(8765,'Oof')) NVTC(number=1234, text=cba, foo=Foo(8765,'Oof')) NVTC(number=4321, text=cba, foo=Foo(8765,'Oof')) """.trim() } @Test void namedVariantMethodBug_DefaultArgumentsAreIgnored() { final resultList = [ namedVariantTestMethod(), namedVariantTestMethod(text:"cba"), namedVariantTestMethod(text:"cba", foo:new Foo(8765,'Oof')), namedVariantTestMethod(text:"cba", foo:new Foo(8765,'Oof'), number:4321) ] resultList.each { println it } // Fails: all non-given method arguments are incorrectly set to null instead of being given their default value, unless all or no arguments are passed. assertEquals resultList.join('\n'), """ nvtm(number=1234, text=abc, foo=Foo(5678,'Foo')) nvtm(number=1234, text=cba, foo=Foo(8765,'Oof')) nvtm(number=1234, text=cba, foo=Foo(8765,'Oof')) nvtm(number=4321, text=cba, foo=Foo(8765,'Oof')) """.trim() } @NamedVariant String namedVariantTestMethod(Integer number = 1234, String text = "abc", Foo foo = new Foo(5678, 'Foo')) { "nvtm(number=$number, text=$text, foo=$foo)" } }
- Note: assertEquals is used since at least in IntelliJ it supplies a link to the integrated text diff viewer, allowing to conevniently compare the expected and actual results:
class NamedVariantTestClass { final Integer number; final String text; final Foo foo @NamedVariant NamedVariantTestClass(Integer number = 1234, String text = "abc", Foo foo = new Foo(5678, 'Foo')) { this.number = number; this.text = text; this.foo = foo } @Override String toString() { "NVTC(number=$number, text=$text, foo=$foo)" } }
class Foo { final Number x; final String s Foo(Number x, String s) { this.x = x; this.s = s } @Override String toString() { "Foo($x,'$s')" } }
Attachments
Issue Links
- is related to
-
GROOVY-10176 @NamedVariant with primitives can't find method
- Closed