Skip to content

Commit

Permalink
Fix #175
Browse files Browse the repository at this point in the history
When generating java proxy classes for interfaces,
make sure to create an overload for methods that include
optional arguments.
  • Loading branch information
Elad Ben-Israel committed Sep 5, 2018
1 parent b3c05f5 commit 7125e67
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 2 deletions.
8 changes: 8 additions & 0 deletions packages/jsii-calc/lib/compliance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -806,3 +806,11 @@ export namespace InterfaceInNamespaceIncludesClasses {
foo: number
}
}

/**
* awslabs/jsii#175
* Interface proxies (and builders) do not respect optional arguments in methods
*/
export interface InterfaceWithOptionalMethodArguments {
hello(arg1: string, arg2?: number): void
}
11 changes: 10 additions & 1 deletion packages/jsii-pacmak/lib/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,16 @@ export abstract class Generator implements IGenerator {
return this.excludeTypes.includes(name);
}

private createOverloadsForOptionals(method: spec.Method) {
/**
* Returns all the method overloads needed to satisfy optional arguments.
* For example, for the method `foo(bar: string, hello?: number, world?: number)`
* this method will return:
* - foo(bar: string)
* - foo(bar: string, hello: number)
*
* Notice that the method that contains all the arguments will not be returned.
*/
protected createOverloadsForOptionals(method: spec.Method) {
const methods = new Array<spec.Method>();

// if option disabled, just return the empty array.
Expand Down
4 changes: 4 additions & 0 deletions packages/jsii-pacmak/lib/targets/java.ts
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,10 @@ class JavaGenerator extends Generator {
for (const methodName of Object.keys(methods)) {
const method = methods[methodName];
this.emitMethod(ifc, method, /* overrides: */ true);

for (const overloadedMethod of this.createOverloadsForOptionals(method)) {
this.emitMethod(ifc, overloadedMethod, /* overrides: */ true);
}
}

this.code.closeBlock();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,35 @@
}
]
},
"jsii-calc.InterfaceWithOptionalMethodArguments": {
"assembly": "jsii-calc",
"docs": {
"comment": "awslabs/jsii#175\nInterface proxies (and builders) do not respect optional arguments in methods"
},
"fqn": "jsii-calc.InterfaceWithOptionalMethodArguments",
"kind": "interface",
"methods": [
{
"name": "hello",
"parameters": [
{
"name": "arg1",
"type": {
"primitive": "string"
}
},
{
"name": "arg2",
"type": {
"optional": true,
"primitive": "number"
}
}
]
}
],
"name": "InterfaceWithOptionalMethodArguments"
},
"jsii-calc.JSObjectLiteralForInterface": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.JSObjectLiteralForInterface",
Expand Down Expand Up @@ -2895,5 +2924,5 @@
}
},
"version": "0.7.1",
"fingerprint": "kLi/5UqkB6zGOVxj7UcMCVnDhIx51fN9Fo9aNKDHqPY="
"fingerprint": "3uROoDToOcKIpYs9haAGnS37Iebz1/+ldcknrh37qDQ="
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Amazon.JSII.Runtime.Deputy;

namespace Amazon.JSII.Tests.CalculatorNamespace
{
/// <summary>
/// awslabs/jsii#175
/// Interface proxies (and builders) do not respect optional arguments in methods
/// </summary>
[JsiiInterface(typeof(IInterfaceWithOptionalMethodArguments), "jsii-calc.InterfaceWithOptionalMethodArguments")]
public interface IInterfaceWithOptionalMethodArguments
{
[JsiiMethod("hello", null, "[{\"name\":\"arg1\",\"type\":{\"primitive\":\"string\"}},{\"name\":\"arg2\",\"type\":{\"primitive\":\"number\",\"optional\":true}}]")]
void Hello(string arg1, double? arg2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Amazon.JSII.Runtime.Deputy;

namespace Amazon.JSII.Tests.CalculatorNamespace
{
/// <summary>
/// awslabs/jsii#175
/// Interface proxies (and builders) do not respect optional arguments in methods
/// </summary>
[JsiiInterfaceProxy(typeof(IInterfaceWithOptionalMethodArguments), "jsii-calc.InterfaceWithOptionalMethodArguments")]
internal class InterfaceWithOptionalMethodArgumentsProxy : DeputyBase, IInterfaceWithOptionalMethodArguments
{
private InterfaceWithOptionalMethodArgumentsProxy(ByRefValue reference): base(reference)
{
}

[JsiiMethod("hello", null, "[{\"name\":\"arg1\",\"type\":{\"primitive\":\"string\"}},{\"name\":\"arg2\",\"type\":{\"primitive\":\"number\",\"optional\":true}}]")]
public virtual void Hello(string arg1, double? arg2)
{
InvokeInstanceVoidMethod(new object[]{arg1, arg2});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ protected Class<?> resolveClass(final String fqn) throws ClassNotFoundException
case "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo": return software.amazon.jsii.tests.calculator.InterfaceInNamespaceIncludesClasses.Foo.class;
case "jsii-calc.InterfaceInNamespaceIncludesClasses.Hello": return software.amazon.jsii.tests.calculator.InterfaceInNamespaceIncludesClasses.Hello.class;
case "jsii-calc.InterfaceInNamespaceOnlyInterface.Hello": return software.amazon.jsii.tests.calculator.InterfaceInNamespaceOnlyInterface.Hello.class;
case "jsii-calc.InterfaceWithOptionalMethodArguments": return software.amazon.jsii.tests.calculator.InterfaceWithOptionalMethodArguments.class;
case "jsii-calc.JSObjectLiteralForInterface": return software.amazon.jsii.tests.calculator.JSObjectLiteralForInterface.class;
case "jsii-calc.JSObjectLiteralToNative": return software.amazon.jsii.tests.calculator.JSObjectLiteralToNative.class;
case "jsii-calc.JSObjectLiteralToNativeClass": return software.amazon.jsii.tests.calculator.JSObjectLiteralToNativeClass.class;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package software.amazon.jsii.tests.calculator;

/**
* awslabs/jsii#175
* Interface proxies (and builders) do not respect optional arguments in methods
*/
@javax.annotation.Generated(value = "jsii-pacmak")
public interface InterfaceWithOptionalMethodArguments extends software.amazon.jsii.JsiiSerializable {
void hello(final java.lang.String arg1, @javax.annotation.Nullable final java.lang.Number arg2);
void hello(final java.lang.String arg1);

/**
* A proxy class which for javascript object literal which adhere to this interface.
*/
final class Jsii$Proxy extends software.amazon.jsii.JsiiObject implements software.amazon.jsii.tests.calculator.InterfaceWithOptionalMethodArguments {
protected Jsii$Proxy(final software.amazon.jsii.JsiiObject.InitializationMode mode) {
super(mode);
}

@Override
public void hello(final java.lang.String arg1, @javax.annotation.Nullable final java.lang.Number arg2) {
this.jsiiCall("hello", Void.class, java.util.stream.Stream.concat(java.util.stream.Stream.of(java.util.Objects.requireNonNull(arg1, "arg1 is required")), java.util.stream.Stream.of(arg2)).toArray());
}

@Override
public void hello(final java.lang.String arg1) {
this.jsiiCall("hello", Void.class, java.util.stream.Stream.of(java.util.Objects.requireNonNull(arg1, "arg1 is required")).toArray());
}
}
}
40 changes: 40 additions & 0 deletions packages/jsii-pacmak/test/expected.jsii-calc/sphinx/jsii-calc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,46 @@ Hello (interface)

.. py:currentmodule:: jsii-calc
InterfaceWithOptionalMethodArguments (interface)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. py:class:: InterfaceWithOptionalMethodArguments
**Language-specific names:**

.. tabs::

.. code-tab:: c#

using Amazon.JSII.Tests.CalculatorNamespace;

.. code-tab:: java

import software.amazon.jsii.tests.calculator.InterfaceWithOptionalMethodArguments;

.. code-tab:: javascript

// InterfaceWithOptionalMethodArguments is an interface

.. code-tab:: typescript

import { InterfaceWithOptionalMethodArguments } from 'jsii-calc';



awslabs/jsii#175 Interface proxies (and builders) do not respect optional arguments in methods




.. py:method:: hello(arg1, [arg2])
:param arg1:
:type arg1: string
:param arg2:
:type arg2: number or undefined


JSObjectLiteralForInterface
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down

0 comments on commit 7125e67

Please sign in to comment.