diff --git a/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/ComplianceTest.java b/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/ComplianceTest.java index 227efb4ab6..d98dbd1ed2 100644 --- a/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/ComplianceTest.java +++ b/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/ComplianceTest.java @@ -50,6 +50,7 @@ import software.amazon.jsii.tests.calculator.SyncVirtualMethods; import software.amazon.jsii.tests.calculator.UnionProperties; import software.amazon.jsii.tests.calculator.UsesInterfaceWithProperties; +import software.amazon.jsii.tests.calculator.VariadicMethod; import software.amazon.jsii.tests.calculator.composition.CompositeOperation; import software.amazon.jsii.tests.calculator.lib.EnumFromScopedModule; import software.amazon.jsii.tests.calculator.lib.IFriendly; @@ -1029,6 +1030,13 @@ public void objectIdDoesNotGetReallocatedWhenTheConstructorPassesThisOut() { assertTrue(object != null); } + @Test + public void variadicMethodCanBeInvoked() { + final VariadicMethod variadicMethod = new VariadicMethod(1); + final List result = variadicMethod.asArray(3, 4, 5, 6); + assertEquals(Arrays.asList(1, 3, 4, 5, 6), result); + } + static class PartiallyInitializedThisConsumerImpl extends PartiallyInitializedThisConsumer { @Override public String consumePartiallyInitializedThis(final ConstructorPassesThisOut obj, diff --git a/packages/jsii-pacmak/lib/targets/java.ts b/packages/jsii-pacmak/lib/targets/java.ts index 2a577d9223..04109d78f5 100644 --- a/packages/jsii-pacmak/lib/targets/java.ts +++ b/packages/jsii-pacmak/lib/targets/java.ts @@ -997,9 +997,28 @@ class JavaGenerator extends Generator { private renderMethodCallArguments(method: spec.Method) { if (!method.parameters || method.parameters.length === 0) { return ''; } - const values = method.parameters.map(param => - isNullable(param) ? param.name : `java.util.Objects.requireNonNull(${param.name}, "${param.name} is required")`); - return `, new Object[] { ${values.join(', ')} }`; + const regularParams = method.parameters.filter(p => !p.variadic); + const values = regularParams.map(_renderParameter); + const valueStr = `new Object[] { ${values.join(', ')} }`; + if (method.variadic) { + const valuesStream = `java.util.Arrays.stream(${valueStr})`; + + const lastParam = method.parameters[method.parameters.length - 1]; + const restStream = `java.util.Arrays.stream(${lastParam.name})`; + + const fullStream = regularParams.length > 0 + ? `java.util.stream.Stream.concat(${valuesStream}, ${restStream})` + : restStream; + return `, ${fullStream}.toArray(Object[]::new)`; + } else { + return `, ${valueStr}`; + } + + function _renderParameter(param: spec.Parameter) { + return isNullable(param) + ? param.name + : `java.util.Objects.requireNonNull(${param.name}, "${param.name} is required")`; + } } private renderMethodCall(cls: spec.TypeReference, method: spec.Method, async: boolean) { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DontComplainAboutVariadicAfterOptional.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DontComplainAboutVariadicAfterOptional.java index 325a1eb378..04bbf2c7ce 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DontComplainAboutVariadicAfterOptional.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DontComplainAboutVariadicAfterOptional.java @@ -12,6 +12,6 @@ public DontComplainAboutVariadicAfterOptional() { } public java.lang.String optionalAndVariadic(@javax.annotation.Nullable final java.lang.String optional, final java.lang.String... things) { - return this.jsiiCall("optionalAndVariadic", java.lang.String.class, new Object[] { optional, java.util.Objects.requireNonNull(things, "things is required") }); + return this.jsiiCall("optionalAndVariadic", java.lang.String.class, java.util.stream.Stream.concat(java.util.Arrays.stream(new Object[] { optional }), java.util.Arrays.stream(things)).toArray(Object[]::new)); } } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/VariadicMethod.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/VariadicMethod.java index 912b4b1116..72602ae7da 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/VariadicMethod.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/VariadicMethod.java @@ -11,7 +11,7 @@ protected VariadicMethod(final software.amazon.jsii.JsiiObject.InitializationMod */ public VariadicMethod(final java.lang.Number... prefix) { super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); - software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this, new Object[] { java.util.Objects.requireNonNull(prefix, "prefix is required") }); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this, java.util.Arrays.stream(prefix).toArray(Object[]::new)); } /** @@ -19,6 +19,6 @@ public VariadicMethod(final java.lang.Number... prefix) { * @param others other elements to be included in the array. */ public java.util.List asArray(final java.lang.Number first, final java.lang.Number... others) { - return this.jsiiCall("asArray", java.util.List.class, new Object[] { java.util.Objects.requireNonNull(first, "first is required"), java.util.Objects.requireNonNull(others, "others is required") }); + return this.jsiiCall("asArray", java.util.List.class, java.util.stream.Stream.concat(java.util.Arrays.stream(new Object[] { java.util.Objects.requireNonNull(first, "first is required") }), java.util.Arrays.stream(others)).toArray(Object[]::new)); } }