Skip to content

Commit

Permalink
fix(java): Correctly pass variadic arguments (#465)
Browse files Browse the repository at this point in the history
The previous iteration was incorrectly forwarding variadic methods'
"rest" argument to the JSII runtime, causing a runtime failure at the
deserialization site.
  • Loading branch information
RomainMuller authored Apr 17, 2019
1 parent 3a6b21c commit 6e91eb7
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1029,6 +1030,13 @@ public void objectIdDoesNotGetReallocatedWhenTheConstructorPassesThisOut() {
assertTrue(object != null);
}

@Test
public void variadicMethodCanBeInvoked() {
final VariadicMethod variadicMethod = new VariadicMethod(1);
final List<java.lang.Number> 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,
Expand Down
25 changes: 22 additions & 3 deletions packages/jsii-pacmak/lib/targets/java.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.<Object>stream(${valueStr})`;

const lastParam = method.parameters[method.parameters.length - 1];
const restStream = `java.util.Arrays.<Object>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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.<Object>stream(new Object[] { optional }), java.util.Arrays.<Object>stream(things)).toArray(Object[]::new));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ 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.<Object>stream(prefix).toArray(Object[]::new));
}

/**
* @param first the first element of the array to be returned (after the `prefix` provided at construction time).
* @param others other elements to be included in the array.
*/
public java.util.List<java.lang.Number> 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.<Object>stream(new Object[] { java.util.Objects.requireNonNull(first, "first is required") }), java.util.Arrays.<Object>stream(others)).toArray(Object[]::new));
}
}

0 comments on commit 6e91eb7

Please sign in to comment.