Skip to content

Commit acc8f22

Browse files
costleyaRomainMuller
authored andcommitted
fix(jsii-dotnet-runtime): Proxy parameters should not throw exception. (#317)
Proxy types when passed as parameters were throwing an exception in the dotnet runtime. Removing the check and throw did not have an adverse effect on the runtime, so it was removed. Compliance test added that passes an interface as a parameter. Fixes #316
1 parent a55fe31 commit acc8f22

File tree

10 files changed

+390
-106
lines changed

10 files changed

+390
-106
lines changed

packages/jsii-calc/lib/compliance.ts

Lines changed: 205 additions & 71 deletions
Large diffs are not rendered by default.

packages/jsii-calc/test/assembly.jsii

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,31 @@
14811481
}
14821482
]
14831483
},
1484+
"jsii-calc.GreetingAugmenter": {
1485+
"assembly": "jsii-calc",
1486+
"fqn": "jsii-calc.GreetingAugmenter",
1487+
"initializer": {
1488+
"initializer": true
1489+
},
1490+
"kind": "class",
1491+
"methods": [
1492+
{
1493+
"name": "betterGreeting",
1494+
"parameters": [
1495+
{
1496+
"name": "friendly",
1497+
"type": {
1498+
"fqn": "@scope/jsii-calc-lib.IFriendly"
1499+
}
1500+
}
1501+
],
1502+
"returns": {
1503+
"primitive": "string"
1504+
}
1505+
}
1506+
],
1507+
"name": "GreetingAugmenter"
1508+
},
14841509
"jsii-calc.IFriendlier": {
14851510
"assembly": "jsii-calc",
14861511
"docs": {
@@ -3646,5 +3671,5 @@
36463671
}
36473672
},
36483673
"version": "0.7.10",
3649-
"fingerprint": "rxx0uqvwitnI8U0/tQLwhghDWxc85lS6Gghk4xDtIx0="
3674+
"fingerprint": "FD4+eWzYL86xxcqBEJh/D6O533Bbjwo/LHD4si6frmg="
36503675
}

packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/ComplianceTests.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,18 @@ public void TestLiteralInterface()
708708
Assert.Equal((double) 42, gen.Next());
709709
}
710710

711+
[Fact(DisplayName = Prefix + nameof(TestInterfaceParameter))]
712+
public void TestInterfaceParameter()
713+
{
714+
var obj = new JSObjectLiteralForInterface();
715+
var friendly = obj.GiveMeFriendly();
716+
Assert.Equal("I am literally friendly!", friendly.Hello());
717+
718+
var greetingAugmenter = new GreetingAugmenter();
719+
var betterGreeting = greetingAugmenter.BetterGreeting(friendly);
720+
Assert.Equal("I am literally friendly! Let me buy you a drink!", betterGreeting);
721+
}
722+
711723
[Fact(DisplayName = Prefix + nameof(Structs_StepBuilders), Skip = "There is no fluent API for C#")]
712724
public void Structs_StepBuilders()
713725
{
@@ -842,7 +854,7 @@ public void NullShouldBeTreatedAsUndefined()
842854
obj.GiveMeUndefinedInsideAnObject(new NullShouldBeTreatedAsUndefinedData
843855
{
844856
ThisShouldBeUndefined = null,
845-
ArrayWithThreeElementsAndUndefinedAsSecondArgument = new[] { "hello", null, "world" }
857+
ArrayWithThreeElementsAndUndefinedAsSecondArgument = new[] {"hello", null, "world"}
846858
});
847859

848860
// property

packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/FrameworkToJsiiConverter.cs

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
using Amazon.JSII.JsonModel.Spec;
2-
using Amazon.JSII.Runtime.Deputy;
3-
using Newtonsoft.Json.Linq;
4-
using System;
1+
using System;
52
using System.Collections.Generic;
63
using System.Linq;
74
using System.Reflection;
5+
using Amazon.JSII.JsonModel.Spec;
6+
using Amazon.JSII.Runtime.Deputy;
7+
using Newtonsoft.Json.Linq;
8+
using Type = System.Type;
89

910
namespace Amazon.JSII.Runtime.Services.Converters
1011
{
@@ -33,18 +34,7 @@ protected override bool TryConvertClass(IReferenceMap referenceMap, object value
3334
return true;
3435
}
3536

36-
System.Type type = value.GetType();
37-
38-
if (type.GetCustomAttribute<JsiiTypeProxyAttribute>() != null)
39-
{
40-
throw new ArgumentException
41-
(
42-
"Interface proxies are one-way (jsii to framework). " +
43-
"They may not be converted back to jsii. " +
44-
"Instead, use a concrete type that implements the interface.",
45-
nameof(value)
46-
);
47-
}
37+
Type type = value.GetType();
4838

4939
if (value is DeputyBase deputyValue)
5040
{
@@ -56,15 +46,16 @@ protected override bool TryConvertClass(IReferenceMap referenceMap, object value
5646
return false;
5747
}
5848

59-
protected override bool TryConvertEnum(object value, bool isOptional, string fullyQualifiedName, out object result)
49+
protected override bool TryConvertEnum(object value, bool isOptional, string fullyQualifiedName,
50+
out object result)
6051
{
6152
if (value == null)
6253
{
6354
result = null;
6455
return isOptional;
6556
}
6657

67-
System.Type valueType = value.GetType();
58+
Type valueType = value.GetType();
6859
JsiiEnumAttribute attribute = value.GetType().GetCustomAttribute<JsiiEnumAttribute>();
6960

7061
if (attribute == null || attribute.FullyQualifiedName != fullyQualifiedName)
@@ -121,7 +112,7 @@ protected override bool TryConvertDate(object value, bool isOptional, out object
121112

122113
if (value.GetType().IsAssignableFrom(typeof(DateTime)))
123114
{
124-
result = new DateValue((DateTime)value);
115+
result = new DateValue((DateTime) value);
125116
return true;
126117
}
127118

@@ -175,15 +166,16 @@ protected override bool TryConvertString(object value, out object result)
175166

176167
if (value.GetType().IsAssignableFrom(typeof(string)))
177168
{
178-
result = (string)value;
169+
result = (string) value;
179170
return true;
180171
}
181172

182173
result = null;
183174
return false;
184175
}
185176

186-
protected override bool TryConvertArray(IReferenceMap referenceMap, TypeReference elementType, object value, out object result)
177+
protected override bool TryConvertArray(IReferenceMap referenceMap, TypeReference elementType, object value,
178+
out object result)
187179
{
188180
if (value == null)
189181
{
@@ -197,7 +189,7 @@ protected override bool TryConvertArray(IReferenceMap referenceMap, TypeReferenc
197189
return false;
198190
}
199191

200-
Array array = (Array)value;
192+
Array array = (Array) value;
201193

202194
JArray resultArray = new JArray();
203195
foreach (object element in array)
@@ -220,41 +212,45 @@ protected override bool TryConvertArray(IReferenceMap referenceMap, TypeReferenc
220212
return true;
221213
}
222214

223-
protected override bool TryConvertMap(IReferenceMap referenceMap, TypeReference elementType, object value, out object result)
215+
protected override bool TryConvertMap(IReferenceMap referenceMap, TypeReference elementType, object value,
216+
out object result)
224217
{
225218
if (value == null)
226219
{
227220
result = null;
228221
return true;
229222
}
230223

231-
System.Type valueType = value.GetType();
232-
System.Type dictionaryInterface = valueType.GetInterfaces()
224+
Type valueType = value.GetType();
225+
Type dictionaryInterface = valueType.GetInterfaces()
233226
.FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<,>));
234227

235-
if (dictionaryInterface == null || !dictionaryInterface.GetGenericArguments()[0].IsAssignableFrom(typeof(string)))
228+
if (dictionaryInterface == null ||
229+
!dictionaryInterface.GetGenericArguments()[0].IsAssignableFrom(typeof(string)))
236230
{
237231
result = null;
238232
return false;
239233
}
240234

241-
IEnumerable<string> keys = (IEnumerable<string>)valueType.GetProperty("Keys").GetValue(value);
235+
IEnumerable<string> keys = (IEnumerable<string>) valueType.GetProperty("Keys").GetValue(value);
242236
PropertyInfo indexer = ReflectionUtils.GetIndexer(valueType);
243237

244238
JObject resultObject = new JObject();
245239
foreach (string key in keys)
246240
{
247-
object element = indexer.GetValue(value, new object[] { key });
241+
object element = indexer.GetValue(value, new object[] {key});
248242
if (!TryConvert(elementType, referenceMap, element, out object convertedElement))
249243
{
250244
result = null;
251245
return false;
252246
}
253247

254-
if (convertedElement != null && !(convertedElement is String) && !convertedElement.GetType().IsPrimitive)
248+
if (convertedElement != null && !(convertedElement is String) &&
249+
!convertedElement.GetType().IsPrimitive)
255250
{
256251
convertedElement = JObject.FromObject(convertedElement);
257252
}
253+
258254
resultObject.Add(new JProperty(key, convertedElement));
259255
}
260256

@@ -269,7 +265,7 @@ protected override TypeReference InferType(IReferenceMap referenceMap, object va
269265
return InferType(referenceMap, value.GetType());
270266
}
271267

272-
TypeReference InferType(IReferenceMap referenceMap, System.Type type)
268+
TypeReference InferType(IReferenceMap referenceMap, Type type)
273269
{
274270
type = type ?? throw new ArgumentNullException(nameof(type));
275271

@@ -322,7 +318,7 @@ TypeReference InferType(IReferenceMap referenceMap, System.Type type)
322318
);
323319
}
324320

325-
System.Type dictionaryInterface = type.GetInterfaces()
321+
Type dictionaryInterface = type.GetInterfaces()
326322
.FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<,>));
327323
if (dictionaryInterface != null)
328324
{
@@ -331,7 +327,7 @@ TypeReference InferType(IReferenceMap referenceMap, System.Type type)
331327
throw new ArgumentException("All dictionaries must have string keys", nameof(type));
332328
}
333329

334-
System.Type elementType = dictionaryInterface.GetGenericArguments()[1];
330+
Type elementType = dictionaryInterface.GetGenericArguments()[1];
335331
return new TypeReference
336332
(
337333
collection: new CollectionTypeReference

packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/ComplianceTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import software.amazon.jsii.tests.calculator.DoNotOverridePrivates;
1515
import software.amazon.jsii.tests.calculator.DoubleTrouble;
1616
import software.amazon.jsii.tests.calculator.GiveMeStructs;
17+
import software.amazon.jsii.tests.calculator.GreetingAugmenter;
1718
import software.amazon.jsii.tests.calculator.IFriendlier;
1819
import software.amazon.jsii.tests.calculator.IFriendlyRandomGenerator;
1920
import software.amazon.jsii.tests.calculator.InterfaceWithProperties;
@@ -705,6 +706,17 @@ public void testLiteralInterface() {
705706
assertEquals(42, gen.next());
706707
}
707708

709+
@Test
710+
public void testInterfaceParameter() {
711+
JSObjectLiteralForInterface obj = new JSObjectLiteralForInterface();
712+
IFriendly friendly = obj.giveMeFriendly();
713+
assertEquals("I am literally friendly!", friendly.hello());
714+
715+
GreetingAugmenter greetingAugmenter = new GreetingAugmenter();
716+
String betterGreeting = greetingAugmenter.betterGreeting(friendly);
717+
assertEquals("I am literally friendly! Let me buy you a drink!", betterGreeting);
718+
}
719+
708720
@Test
709721
public void structs_stepBuilders() {
710722
Instant someInstant = Instant.now();

packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,31 @@
14811481
}
14821482
]
14831483
},
1484+
"jsii-calc.GreetingAugmenter": {
1485+
"assembly": "jsii-calc",
1486+
"fqn": "jsii-calc.GreetingAugmenter",
1487+
"initializer": {
1488+
"initializer": true
1489+
},
1490+
"kind": "class",
1491+
"methods": [
1492+
{
1493+
"name": "betterGreeting",
1494+
"parameters": [
1495+
{
1496+
"name": "friendly",
1497+
"type": {
1498+
"fqn": "@scope/jsii-calc-lib.IFriendly"
1499+
}
1500+
}
1501+
],
1502+
"returns": {
1503+
"primitive": "string"
1504+
}
1505+
}
1506+
],
1507+
"name": "GreetingAugmenter"
1508+
},
14841509
"jsii-calc.IFriendlier": {
14851510
"assembly": "jsii-calc",
14861511
"docs": {
@@ -3646,5 +3671,5 @@
36463671
}
36473672
},
36483673
"version": "0.7.10",
3649-
"fingerprint": "rxx0uqvwitnI8U0/tQLwhghDWxc85lS6Gghk4xDtIx0="
3674+
"fingerprint": "FD4+eWzYL86xxcqBEJh/D6O533Bbjwo/LHD4si6frmg="
36503675
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Amazon.JSII.Runtime.Deputy;
2+
using Amazon.JSII.Tests.CalculatorNamespace.LibNamespace;
3+
4+
namespace Amazon.JSII.Tests.CalculatorNamespace
5+
{
6+
[JsiiClass(typeof(GreetingAugmenter), "jsii-calc.GreetingAugmenter", "[]")]
7+
public class GreetingAugmenter : DeputyBase
8+
{
9+
public GreetingAugmenter(): base(new DeputyProps(new object[]{}))
10+
{
11+
}
12+
13+
protected GreetingAugmenter(ByRefValue reference): base(reference)
14+
{
15+
}
16+
17+
protected GreetingAugmenter(DeputyProps props): base(props)
18+
{
19+
}
20+
21+
[JsiiMethod("betterGreeting", "{\"primitive\":\"string\"}", "[{\"name\":\"friendly\",\"type\":{\"fqn\":\"@scope/jsii-calc-lib.IFriendly\"}}]")]
22+
public virtual string BetterGreeting(IIFriendly friendly)
23+
{
24+
return InvokeInstanceMethod<string>(new object[]{friendly});
25+
}
26+
}
27+
}

packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ protected Class<?> resolveClass(final String fqn) throws ClassNotFoundException
4040
case "jsii-calc.DontComplainAboutVariadicAfterOptional": return software.amazon.jsii.tests.calculator.DontComplainAboutVariadicAfterOptional.class;
4141
case "jsii-calc.DoubleTrouble": return software.amazon.jsii.tests.calculator.DoubleTrouble.class;
4242
case "jsii-calc.GiveMeStructs": return software.amazon.jsii.tests.calculator.GiveMeStructs.class;
43+
case "jsii-calc.GreetingAugmenter": return software.amazon.jsii.tests.calculator.GreetingAugmenter.class;
4344
case "jsii-calc.IFriendlier": return software.amazon.jsii.tests.calculator.IFriendlier.class;
4445
case "jsii-calc.IFriendlyRandomGenerator": return software.amazon.jsii.tests.calculator.IFriendlyRandomGenerator.class;
4546
case "jsii-calc.IInterfaceThatShouldNotBeADataType": return software.amazon.jsii.tests.calculator.IInterfaceThatShouldNotBeADataType.class;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package software.amazon.jsii.tests.calculator;
2+
3+
@javax.annotation.Generated(value = "jsii-pacmak")
4+
@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.GreetingAugmenter")
5+
public class GreetingAugmenter extends software.amazon.jsii.JsiiObject {
6+
protected GreetingAugmenter(final software.amazon.jsii.JsiiObject.InitializationMode mode) {
7+
super(mode);
8+
}
9+
public GreetingAugmenter() {
10+
super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii);
11+
software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this);
12+
}
13+
14+
public java.lang.String betterGreeting(final software.amazon.jsii.tests.calculator.lib.IFriendly friendly) {
15+
return this.jsiiCall("betterGreeting", java.lang.String.class, java.util.stream.Stream.of(java.util.Objects.requireNonNull(friendly, "friendly is required")).toArray());
16+
}
17+
}

0 commit comments

Comments
 (0)