diff --git a/.gitignore b/.gitignore index 098af53bc4..b70cc9f0e6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ node_modules/ lerna-debug.log .DS_Store .idea +.vs /dist diff --git a/packages/jsii-calc/lib/compliance.ts b/packages/jsii-calc/lib/compliance.ts index 81e7c5739d..82a37aa5bb 100644 --- a/packages/jsii-calc/lib/compliance.ts +++ b/packages/jsii-calc/lib/compliance.ts @@ -1583,3 +1583,20 @@ export class ConsumersOfThisCrazyTypeSystem { return { a: obj.a, b: obj.b, c: obj.c }; } } + + +// +// Ensure the JSII kernel can pass "this" out to JSII remotes from within the constructor (this is dirty, but possible) +/// +export abstract class PartiallyInitializedThisConsumer { + public abstract consumePartiallyInitializedThis(obj: ConstructorPassesThisOut, dt: Date, ev: AllTypesEnum): string; +} + +export class ConstructorPassesThisOut { + constructor(consumer: PartiallyInitializedThisConsumer) { + const result = consumer.consumePartiallyInitializedThis(this, new Date(0), AllTypesEnum.ThisIsGreat); + if (result !== 'OK') { + throw new Error(`Expected OK but received ${result}`); + } + } +} diff --git a/packages/jsii-calc/package.json b/packages/jsii-calc/package.json index 0a9caf90ce..6c1019c133 100644 --- a/packages/jsii-calc/package.json +++ b/packages/jsii-calc/package.json @@ -36,11 +36,13 @@ ], "dependencies": { "@scope/jsii-calc-base": "^0.8.0", + "@scope/jsii-calc-base-of-base": "^0.8.0", "@scope/jsii-calc-lib": "^0.8.0", "jsii-calc-bundled": "^0.8.0" }, "peerDependencies": { "@scope/jsii-calc-base": "^0.8.0", + "@scope/jsii-calc-base-of-base": "^0.8.0", "@scope/jsii-calc-lib": "^0.8.0" }, "devDependencies": { diff --git a/packages/jsii-calc/test/assembly.jsii b/packages/jsii-calc/test/assembly.jsii index 20fac29cd7..dc9f5f0401 100644 --- a/packages/jsii-calc/test/assembly.jsii +++ b/packages/jsii-calc/test/assembly.jsii @@ -84,6 +84,30 @@ }, "version": "0.8.0" }, + "@scope/jsii-calc-base-of-base": { + "peer": true, + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base-of-base", + "groupId": "software.amazon.jsii.tests" + }, + "package": "software.amazon.jsii.tests.calculator.baseofbase" + }, + "js": { + "npm": "@scope/jsii-calc-base-of-base" + }, + "python": { + "distName": "scope.jsii-calc-base-of-base", + "module": "scope.jsii_calc_base_of_base" + } + }, + "version": "0.8.0" + }, "@scope/jsii-calc-lib": { "dependencies": { "@scope/jsii-calc-base": { @@ -1250,6 +1274,23 @@ } ] }, + "jsii-calc.ConstructorPassesThisOut": { + "assembly": "jsii-calc", + "fqn": "jsii-calc.ConstructorPassesThisOut", + "initializer": { + "initializer": true, + "parameters": [ + { + "name": "consumer", + "type": { + "fqn": "jsii-calc.PartiallyInitializedThisConsumer" + } + } + ] + }, + "kind": "class", + "name": "ConstructorPassesThisOut" + }, "jsii-calc.Constructors": { "assembly": "jsii-calc", "fqn": "jsii-calc.Constructors", @@ -3327,6 +3368,45 @@ ], "name": "OverrideReturnsObject" }, + "jsii-calc.PartiallyInitializedThisConsumer": { + "abstract": true, + "assembly": "jsii-calc", + "fqn": "jsii-calc.PartiallyInitializedThisConsumer", + "initializer": { + "initializer": true + }, + "kind": "class", + "methods": [ + { + "abstract": true, + "name": "consumePartiallyInitializedThis", + "parameters": [ + { + "name": "obj", + "type": { + "fqn": "jsii-calc.ConstructorPassesThisOut" + } + }, + { + "name": "dt", + "type": { + "primitive": "date" + } + }, + { + "name": "ev", + "type": { + "fqn": "jsii-calc.AllTypesEnum" + } + } + ], + "returns": { + "primitive": "string" + } + } + ], + "name": "PartiallyInitializedThisConsumer" + }, "jsii-calc.Polymorphism": { "assembly": "jsii-calc", "fqn": "jsii-calc.Polymorphism", @@ -4500,5 +4580,5 @@ } }, "version": "0.8.0", - "fingerprint": "WIFIhqgEwUDjCsDr7gliujhqcKZQSkDP+NstBfmdvZU=" + "fingerprint": "J0bhm0cu1dlTAyMfBlAMWCVXZf6e8k2pHkmxye6P7Wk=" } diff --git a/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/Amazon.JSII.Runtime.IntegrationTests.csproj b/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/Amazon.JSII.Runtime.IntegrationTests.csproj index bb130050b1..59dea45c8f 100644 --- a/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/Amazon.JSII.Runtime.IntegrationTests.csproj +++ b/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/Amazon.JSII.Runtime.IntegrationTests.csproj @@ -7,20 +7,20 @@ - + - - - - - - + + + + + + - + diff --git a/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/ComplianceTests.cs b/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/ComplianceTests.cs index 8b35565b87..7c3e510f5f 100644 --- a/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/ComplianceTests.cs +++ b/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/ComplianceTests.cs @@ -892,10 +892,31 @@ public void EraseUnsetDataValues() Assert.True(EraseUndefinedHashValues.DoesKeyExist(opts, "option1")); Assert.False(EraseUndefinedHashValues.DoesKeyExist(opts, "option2")); - + Assert.Equal(new Dictionary { ["prop2"] = "value2" }, EraseUndefinedHashValues.Prop1IsNull()); Assert.Equal(new Dictionary { [ "prop1"] = "value1" }, EraseUndefinedHashValues.Prop2IsUndefined()); } + + [Fact(DisplayName = Prefix + nameof(ObjectIdDoesNotGetReallocatedWhenTheConstructorPassesThisOut), Skip = "Currently broken")] + public void ObjectIdDoesNotGetReallocatedWhenTheConstructorPassesThisOut() + { + var reflector = new PartiallyInitializedThisConsumerImpl(); + var obj = new ConstructorPassesThisOut(reflector); + + Assert.NotNull(obj); + } + + class PartiallyInitializedThisConsumerImpl : PartiallyInitializedThisConsumer + { + public override String ConsumePartiallyInitializedThis(ConstructorPassesThisOut obj, DateTime dt, AllTypesEnum ev) + { + Assert.NotNull(obj); + Assert.Equal(new DateTime(0), dt); + Assert.Equal(AllTypesEnum.ThisIsGreat, ev); + + return "OK"; + } + } class NumberReturner : DeputyBase, IIReturnsNumber { public NumberReturner(double number) diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/CallbackExtensions.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/CallbackExtensions.cs index 8fe9067aae..fef3002435 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/CallbackExtensions.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/CallbackExtensions.cs @@ -4,7 +4,9 @@ using Amazon.JSII.Runtime.Deputy; using Amazon.JSII.Runtime.Services; using Amazon.JSII.Runtime.Services.Converters; +using Newtonsoft.Json.Linq; using System; +using System.Linq; using System.Reflection; namespace Amazon.JSII.Runtime @@ -71,11 +73,11 @@ static CallbackResult InvokeMethod(InvokeRequest request, IReferenceMap referenc if (methodInfo == null) { - throw new InvalidOperationException($"Received callback for {deputy.GetType().Name}.{request.Method} getter, but this method does not exist"); + throw new InvalidOperationException($"Received callback for {deputy.GetType().Name}.{request.Method} method, but this method does not exist"); } JsiiMethodAttribute attribute = methodInfo.GetCustomAttribute(); - return new CallbackResult(attribute?.Returns, methodInfo.Invoke(deputy, request.Arguments)); + return new CallbackResult(attribute?.Returns, methodInfo.Invoke(deputy, request.Arguments.Select(arg => FromKernel(arg, referenceMap)).ToArray())); } static CallbackResult InvokeGetter(GetRequest request, IReferenceMap referenceMap) @@ -117,7 +119,24 @@ static void InvokeSetter(SetRequest request, IReferenceMap referenceMap) throw new InvalidOperationException($"Received callback for {deputy.GetType().Name}.{request.Property} setter, but this property does not have a setter"); } - methodInfo.Invoke(deputy, new object[] { request.Value }); + methodInfo.Invoke(deputy, new object[] { FromKernel(request.Value, referenceMap) }); + } + + /* + * This is a temporary workaround / hack to solve an immediate problem, but does not completely solve the + * problem to it's full extent. See https://github.com/awslabs/jsii/issues/404 for more information. + */ + private static object FromKernel(object obj, IReferenceMap referenceMap) + { + if (obj is JObject) + { + var prop = ((JObject)obj).Property("$jsii.byref"); + if (prop != null) + { + return referenceMap.GetOrCreateNativeReference(new ByRefValue(prop.Value.Value())); + } + } + return obj; } } diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/DeputyBase.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/DeputyBase.cs index c315018125..bf04054421 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/DeputyBase.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/DeputyBase.cs @@ -54,7 +54,7 @@ protected DeputyBase(DeputyProps props = null) Reference = new ByRefValue(response["$jsii.byref"]); IReferenceMap referenceMap = serviceProvider.GetRequiredService(); - referenceMap.AddNativeReference(Reference, this); + referenceMap.AddNativeReference(Reference, this, true); Override[] GetOverrides() { diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/IReferenceMap.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/IReferenceMap.cs index 3294f2de5f..48de5ea9db 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/IReferenceMap.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/IReferenceMap.cs @@ -5,7 +5,7 @@ namespace Amazon.JSII.Runtime.Services { public interface IReferenceMap { - void AddNativeReference(ByRefValue reference, DeputyBase nativeReference); + void AddNativeReference(ByRefValue reference, DeputyBase nativeReference, bool force = false); DeputyBase GetOrCreateNativeReference(ObjectReference reference); diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ReferenceMap.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ReferenceMap.cs index 609ab784fb..4ffaef5cc6 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ReferenceMap.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ReferenceMap.cs @@ -16,9 +16,9 @@ public ReferenceMap(ITypeCache types) _types = types ?? throw new ArgumentNullException(nameof(types)); } - public void AddNativeReference(ByRefValue reference, DeputyBase nativeReference) + public void AddNativeReference(ByRefValue reference, DeputyBase nativeReference, bool force) { - if (_references.ContainsKey(reference.Value)) + if (_references.ContainsKey(reference.Value) && !force) { throw new ArgumentException( $"Cannot add reference for {reference.Value}: A reference with this name already exists", 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 b15956ab4c..9791cc269a 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 @@ -8,6 +8,7 @@ import software.amazon.jsii.tests.calculator.AbstractClassReturner; import software.amazon.jsii.tests.calculator.Add; import software.amazon.jsii.tests.calculator.AllTypes; +import software.amazon.jsii.tests.calculator.AllTypesEnum; import software.amazon.jsii.tests.calculator.AsyncVirtualMethods; import software.amazon.jsii.tests.calculator.Calculator; import software.amazon.jsii.tests.calculator.CalculatorProps; @@ -38,6 +39,7 @@ import software.amazon.jsii.tests.calculator.NullShouldBeTreatedAsUndefined; import software.amazon.jsii.tests.calculator.NullShouldBeTreatedAsUndefinedData; import software.amazon.jsii.tests.calculator.NumberGenerator; +import software.amazon.jsii.tests.calculator.PartiallyInitializedThisConsumer; import software.amazon.jsii.tests.calculator.Polymorphism; import software.amazon.jsii.tests.calculator.Power; import software.amazon.jsii.tests.calculator.PublicClass; @@ -55,6 +57,7 @@ import software.amazon.jsii.tests.calculator.lib.Number; import software.amazon.jsii.tests.calculator.lib.StructWithOnlyOptionals; import software.amazon.jsii.tests.calculator.lib.Value; +import software.amazon.jsii.tests.calculator.ConstructorPassesThisOut; import java.io.IOException; import java.time.Instant; @@ -1010,6 +1013,27 @@ public void eraseUnsetDataValues() { assertEquals("{prop1=value1}", EraseUndefinedHashValues.prop2IsUndefined().toString()); } + @Test + public void objectIdDoesNotGetReallocatedWhenTheConstructorPassesThisOut() { + final PartiallyInitializedThisConsumer reflector = new PartiallyInitializedThisConsumerImpl(); + final ConstructorPassesThisOut object = new ConstructorPassesThisOut(reflector); + + assertTrue(object != null); + } + + static class PartiallyInitializedThisConsumerImpl extends PartiallyInitializedThisConsumer { + @Override + public String consumePartiallyInitializedThis(final ConstructorPassesThisOut obj, + final Instant dt, + final AllTypesEnum en) { + assertNotNull(obj); + assertEquals(Instant.EPOCH, dt); + assertEquals(AllTypesEnum.ThisIsGreat, en); + + return "OK"; + } + } + static class MulTen extends Multiply { public MulTen(final int value) { super(new Number(value), new Number(10)); diff --git a/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/JsiiClientTest.java b/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/JsiiClientTest.java index 3c9da690e4..480383adbb 100644 --- a/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/JsiiClientTest.java +++ b/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/JsiiClientTest.java @@ -116,7 +116,7 @@ public void asyncMethodOverrides() { assertEquals("overrideMe", first.getInvoke().getMethod()); assertEquals("myCookie", first.getCookie()); assertEquals(1, first.getInvoke().getArgs().size()); - assertEquals(10, first.getInvoke().getArgs().get(0)); + assertEquals(JsiiObjectMapper.valueToTree(10), first.getInvoke().getArgs().get(0)); assertEquals(obj.getObjId(), JsiiObjectRef.parse(first.getInvoke().getObjref()).getObjId()); // now complete the callback with some override value @@ -146,7 +146,7 @@ public void asyncMethodOverridesThrow() { assertEquals("overrideMe", first.getInvoke().getMethod()); assertEquals("myCookie", first.getCookie()); assertEquals(1, first.getInvoke().getArgs().size()); - assertEquals(10, first.getInvoke().getArgs().get(0)); + assertEquals(JsiiObjectMapper.valueToTree(10), first.getInvoke().getArgs().get(0)); assertEquals(obj.getObjId(), JsiiObjectRef.parse(first.getInvoke().getObjref()).getObjId()); // now complete the callback with an error @@ -171,7 +171,7 @@ public void syncVirtualMethods() { jsiiRuntime.setCallbackHandler(callback -> { assertEquals(obj.getObjId(), JsiiObjectRef.parse(callback.getInvoke().getObjref()).getObjId()); assertEquals("virtualMethod", callback.getInvoke().getMethod()); - assertEquals(10, callback.getInvoke().getArgs().get(0)); + assertEquals(JsiiObjectMapper.valueToTree(10), callback.getInvoke().getArgs().get(0)); assertEquals("myCookie", callback.getCookie()); // interact with jsii from inside the callback @@ -226,8 +226,7 @@ public void staticMethods() { */ @Test public void serializeViaJsiiToJsonIfExists() { - JsiiObjectMapper om = JsiiObjectMapper.instance; - JsonNode result = om.valueToTree(new JsiiSerializable() { + JsonNode result = JsiiObjectMapper.INSTANCE.valueToTree(new JsiiSerializable() { public JsonNode $jsii$toJson() { ObjectNode node = JSON.objectNode(); node.set("foo", OM.valueToTree("bar")); diff --git a/packages/jsii-java-runtime/package.json b/packages/jsii-java-runtime/package.json index 5f6ddfcfbb..6c5509e8dd 100644 --- a/packages/jsii-java-runtime/package.json +++ b/packages/jsii-java-runtime/package.json @@ -8,7 +8,7 @@ "scripts": { "gen": "/bin/bash ./generate.sh", "build": "tsc && npm run gen && cd project && mvn deploy -D altDeploymentRepository=local::default::file://${PWD}/../maven-repo", - "test": "echo 'Tests are performed by jsii-java-runtime-test'", + "test": "echo 'Tests are run as part of the build target'", "package": "package-java" }, "devDependencies": { diff --git a/packages/jsii-java-runtime/pom.xml.t.js b/packages/jsii-java-runtime/pom.xml.t.js index 12eb2aed90..d77310c4d0 100644 --- a/packages/jsii-java-runtime/pom.xml.t.js +++ b/packages/jsii-java-runtime/pom.xml.t.js @@ -83,6 +83,30 @@ process.stdout.write(` [1.3.2,) provided + + + + org.junit.jupiter + junit-jupiter-api + 5.4.1 + test + + + + + org.junit.jupiter + junit-jupiter-engine + 5.4.1 + test + + + + + org.mockito + mockito-core + 2.25.1 + test + @@ -128,6 +152,16 @@ process.stdout.write(` protected + + + maven-surefire-plugin + 2.22.0 + + + + maven-failsafe-plugin + 2.22.0 + diff --git a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiClient.java b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiClient.java index 7f5b84d3db..bdd86f20cb 100644 --- a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiClient.java +++ b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiClient.java @@ -5,7 +5,6 @@ import software.amazon.jsii.api.JsiiOverride; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -27,16 +26,6 @@ public final class JsiiClient { */ private static final JsonNodeFactory JSON = JsonNodeFactory.instance; - /** - * JSON object mapper. - */ - private static final ObjectMapper STD_OM = new ObjectMapper(); - - /** - * Jsii custom object mapper. - */ - private static final JsiiObjectMapper JSII_OM = JsiiObjectMapper.instance; - /** * TCP port to connect to (always "localhost"). */ @@ -95,7 +84,7 @@ public JsiiObjectRef createObject(final String fqn, request.setArgs(initializerArgs); request.setOverrides(overrides); - ObjectNode req = JSII_OM.valueToTree(request); + ObjectNode req = JsiiObjectMapper.valueToTree(request); req.put("api", "create"); JsonNode resp = this.runtime.requestResponse(req); @@ -245,11 +234,7 @@ public List pendingCallbacks() { List result = new ArrayList<>(); callbacksArray.forEach(node -> { - try { - result.add(STD_OM.treeToValue(node, Callback.class)); - } catch (JsonProcessingException e) { - throw new JsiiException(e); - } + result.add(JsiiObjectMapper.treeToValue(node, Callback.class)); }); return result; diff --git a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiEngine.java b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiEngine.java index 975d3a29f7..c957574a31 100644 --- a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiEngine.java +++ b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiEngine.java @@ -5,7 +5,10 @@ import software.amazon.jsii.api.InvokeRequest; import software.amazon.jsii.api.JsiiOverride; import software.amazon.jsii.api.SetRequest; + +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.base.Throwables; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -45,11 +48,6 @@ public final class JsiiEngine implements JsiiCallbackHandler { */ private final JsiiRuntime runtime = new JsiiRuntime(); - /** - * JSON object mapper. - */ - private static final JsiiObjectMapper OM = JsiiObjectMapper.instance; - /** * The set of modules we already loaded into the VM. */ @@ -253,7 +251,7 @@ private JsiiObject createNative(final String fqn) { + e.getMessage(), e); } } catch (ClassNotFoundException e) { - System.err.println("WARNING: Cannot find the class: " + fqn + ". Defaulting to JsiiObject"); + this.log("WARNING: Cannot find the class: %s. Defaulting to JsiiObject", fqn); return new JsiiObject(JsiiObject.InitializationMode.Jsii); } } @@ -323,7 +321,7 @@ private JsonNode invokeCallbackGet(final GetRequest req) { String methodName = javaScriptPropertyToJavaPropertyName("get", req.getProperty()); try { Method getter = obj.getClass().getMethod(methodName); - return OM.valueToTree(invokeMethod(obj, getter)); + return JsiiObjectMapper.valueToTree(invokeMethod(obj, getter)); } catch (NoSuchMethodException e) { throw new JsiiException(e); } @@ -350,7 +348,8 @@ private JsonNode invokeCallbackSet(final SetRequest req) { throw new JsiiException("Unable to find property setter " + setterMethodName); } - return OM.valueToTree(invokeMethod(obj, setter, req.getValue())); + final Object arg = JsiiObjectMapper.treeToValue(req.getValue(), setter.getParameterTypes()[0]); + return JsiiObjectMapper.valueToTree(invokeMethod(obj, setter, arg)); } /** @@ -362,7 +361,14 @@ private JsonNode invokeCallbackSet(final SetRequest req) { private JsonNode invokeCallbackMethod(final InvokeRequest req, final String cookie) { Object obj = this.getObject(req.getObjref()); Method method = this.findCallbackMethod(obj.getClass(), cookie); - return OM.valueToTree(invokeMethod(obj, method, req.getArgs().toArray())); + + final Class[] argTypes = method.getParameterTypes(); + final Object[] args = new Object[argTypes.length]; + for (int i = 0; i < argTypes.length; i++) { + args[i] = JsiiObjectMapper.treeToValue(req.getArgs().get(i), argTypes[i]); + } + + return JsiiObjectMapper.valueToTree(invokeMethod(obj, method, args)); } /** @@ -379,7 +385,12 @@ private Object invokeMethod(final Object obj, final Method method, final Object. method.setAccessible(true); try { - return method.invoke(obj, args); + try { + return method.invoke(obj, args); + } catch (Exception e) { + this.log("Error while invoking %s with %s: %s", method, Arrays.toString(args), Throwables.getStackTraceAsString(e)); + throw e; + } } catch (InvocationTargetException e) { throw new JsiiException(e.getTargetException()); } catch (IllegalAccessException e) { @@ -508,6 +519,10 @@ private static Collection discoverOverrides(final Class classTo return overrides.values(); } + private void log(final String format, final Object... args) { + System.err.println(String.format(format, args)); + } + /** * Attempts to find the @Jsii annotation from a type. * @param type The type. diff --git a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObject.java b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObject.java index d3f1afc2b8..d6cc888cf6 100644 --- a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObject.java +++ b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObject.java @@ -11,11 +11,6 @@ */ public class JsiiObject implements JsiiSerializable { - /** - * JSON object mapper. - */ - private static final JsiiObjectMapper OM = JsiiObjectMapper.instance; - /** * The jsii engine used by this object. */ @@ -58,16 +53,11 @@ public enum InitializationMode { */ @Nullable protected final T jsiiCall(final String method, final Class returnType, @Nullable final Object... args) { - try { - return OM.treeToValue(JsiiObject.engine.getClient().callMethod( - this.objRef, - method, - OM.valueToTree(args)), - returnType); - - } catch (JsonProcessingException e) { - throw new JsiiException(e); - } + return JsiiObjectMapper.treeToValue(JsiiObject.engine.getClient() + .callMethod(this.objRef, + method, + JsiiObjectMapper.valueToTree(args)), + returnType); } /** @@ -82,16 +72,9 @@ protected final T jsiiCall(final String method, final Class returnType, @ @Nullable protected static T jsiiStaticCall(final Class nativeClass, final String method, final Class returnType, @Nullable final Object... args) { String fqn = engine.loadModuleForClass(nativeClass); - try { - return OM.treeToValue(engine.getClient().callStaticMethod( - fqn, - method, - OM.valueToTree(args)), - returnType); - - } catch (JsonProcessingException e) { - throw new JsiiException(e); - } + return JsiiObjectMapper.treeToValue(engine.getClient() + .callStaticMethod(fqn, method, JsiiObjectMapper.valueToTree(args)), + returnType); } /** @@ -104,17 +87,12 @@ protected static T jsiiStaticCall(final Class nativeClass, final String m */ @Nullable protected final T jsiiAsyncCall(final String method, final Class returnType, @Nullable final Object... args) { - try { - JsiiClient client = engine.getClient(); - JsiiPromise promise = client.beginAsyncMethod(this.objRef, method, OM.valueToTree(args)); + JsiiClient client = engine.getClient(); + JsiiPromise promise = client.beginAsyncMethod(this.objRef, method, JsiiObjectMapper.valueToTree(args)); - engine.processAllPendingCallbacks(); + engine.processAllPendingCallbacks(); - JsonNode ret = client.endAsyncMethod(promise); - return OM.treeToValue(ret, returnType); - } catch (JsonProcessingException e) { - throw new JsiiException(e); - } + return JsiiObjectMapper.treeToValue(client.endAsyncMethod(promise), returnType); } /** @@ -126,11 +104,7 @@ protected final T jsiiAsyncCall(final String method, final Class returnTy */ @Nullable protected final T jsiiGet(final String property, final Class type) { - try { - return OM.treeToValue(engine.getClient().getPropertyValue(this.objRef, property), type); - } catch (JsonProcessingException e) { - throw new JsiiException(e); - } + return JsiiObjectMapper.treeToValue(engine.getClient().getPropertyValue(this.objRef, property), type); } /** @@ -143,12 +117,8 @@ protected final T jsiiGet(final String property, final Class type) { */ @Nullable protected static T jsiiStaticGet(final Class nativeClass, final String property, final Class type) { - try { - String fqn = engine.loadModuleForClass(nativeClass); - return OM.treeToValue(engine.getClient().getStaticPropertyValue(fqn, property), type); - } catch (JsonProcessingException e) { - throw new JsiiException(e); - } + String fqn = engine.loadModuleForClass(nativeClass); + return JsiiObjectMapper.treeToValue(engine.getClient().getStaticPropertyValue(fqn, property), type); } /** @@ -157,7 +127,7 @@ protected static T jsiiStaticGet(final Class nativeClass, final String pr * @param value The property value. */ protected final void jsiiSet(final String property, @Nullable final Object value) { - engine.getClient().setPropertyValue(this.objRef, property, OM.valueToTree(value)); + engine.getClient().setPropertyValue(this.objRef, property, JsiiObjectMapper.valueToTree(value)); } /** @@ -168,7 +138,7 @@ protected final void jsiiSet(final String property, @Nullable final Object value */ protected static void jsiiStaticSet(final Class nativeClass, final String property, @Nullable final Object value) { String fqn = engine.loadModuleForClass(nativeClass); - engine.getClient().setStaticPropertyValue(fqn, property, OM.valueToTree(value)); + engine.getClient().setStaticPropertyValue(fqn, property, JsiiObjectMapper.valueToTree(value)); } /** diff --git a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObjectMapper.java b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObjectMapper.java index 15bfcf4dfc..f562de697d 100644 --- a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObjectMapper.java +++ b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObjectMapper.java @@ -1,186 +1,250 @@ package software.amazon.jsii; -import com.fasterxml.jackson.annotation.JsonInclude; +import java.io.IOException; +import java.time.Instant; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.Version; +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.BeanProperty; +import com.fasterxml.jackson.databind.DeserializationConfig; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier; +import com.fasterxml.jackson.databind.deser.ContextualDeserializer; +import com.fasterxml.jackson.databind.deser.ResolvableDeserializer; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import java.io.IOException; -import java.time.Instant; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import static software.amazon.jsii.JsiiEngine.tryGetJsiiAnnotation; +import com.fasterxml.jackson.databind.type.MapLikeType; +import com.fasterxml.jackson.databind.type.MapType; +import com.google.common.annotations.VisibleForTesting; /** - * Implements serialization/deserialization of jsii data. + * Provides a correctly configured JSON processor for handling JSII requests and responses. */ public final class JsiiObjectMapper { - /** - * Singleton instance of the object mapper. - */ - public static JsiiObjectMapper instance = new JsiiObjectMapper(); + public static final long serialVersionUID = 1L; + + /** + * An ObjectMapper that can be used to serialize and deserialize JSII requests and responses. + */ + public static final ObjectMapper INSTANCE = new JsiiObjectMapper().getObjectMapper(); + + /** + * Similar to calling JsiiObjectMapper.INSTANCE.treeToValue, but handles a null JsonNode argument + * well, and throws JsiiException instead of JsonProcessingException. + */ + public static T treeToValue(final JsonNode tree, final Class valueType) { + if (tree == null) { + return null; + } + try { + return INSTANCE.treeToValue(tree, valueType); + } catch (final JsonProcessingException jpe) { + throw new JsiiException(jpe); + } + } + + /** + * Similar to calling JsiiObjectMapper.INSTANCE.valueToTree, but handles a null argument well by + * returning null. + */ + public static T valueToTree(final Object value) { + if (value == null) { + return null; + } + return INSTANCE.valueToTree(value); + } - /** - * JSON token that represents an object reference. - */ - private static final String TOKEN_REF = JsiiObjectRef.TOKEN_REF; + private static final String TOKEN_REF = JsiiObjectRef.TOKEN_REF; - /** - * JSON token to represent a date. - */ - private static final String TOKEN_DATE = "$jsii.date"; + private static final String TOKEN_DATE = "$jsii.date"; - /** - * JSON token to represent an enum. - */ - private static final String TOKEN_ENUM = "$jsii.enum"; + private static final String TOKEN_ENUM = "$jsii.enum"; - /** - * The standard JSON mapper. - */ - private static ObjectMapper standardMapper = new ObjectMapper(); + private final ObjectMapper objectMapper; - /** - * Object mapper configured for jsii serialization. - */ - private ObjectMapper serializer; + private final JsiiEngine jsiiEngine; - /** - * Creates an object mapper. - */ - private JsiiObjectMapper() { - this.serializer = new ObjectMapper(); - this.serializer.setSerializationInclusion(JsonInclude.Include.NON_NULL); + private JsiiObjectMapper() { + this(JsiiEngine.getInstance()); + } - SimpleModule module = new SimpleModule(); - module.addSerializer(JsiiSerializable.class, new JsiiSerializer()); - module.addSerializer(Instant.class, new DateSerializer()); - module.addSerializer(Enum.class, new EnumSerializer()); + @VisibleForTesting + JsiiObjectMapper(final JsiiEngine jsiiEngine) { + this.jsiiEngine = jsiiEngine; + this.objectMapper = new ObjectMapper(); + this.objectMapper.setSerializationInclusion(Include.NON_NULL); - this.serializer.registerModule(module); - } + final SimpleModule module = new SimpleModule("JSII", Version.unknownVersion()); + module.setDeserializerModifier(new JsiiDeserializerModifier()); + module.addSerializer(Enum.class, new EnumSerializer()); + module.addSerializer(Instant.class, new Instanterializer()); + module.addSerializer(JsiiSerializable.class, new JsiiSerializer()); - /** - * Converts a local value to a jsii JSON representation. - * - * @param value The local java value. - * @param The return type. - * @return A JSON tree. - */ - public T valueToTree(final Object value) { - if (value == null) { - return null; - } + this.objectMapper.findAndRegisterModules(); + this.objectMapper.registerModule(module); + } - return this.serializer.valueToTree(value); - } + @VisibleForTesting + ObjectMapper getObjectMapper() { + return this.objectMapper; + } + + /** + * A JsonDeserializer designed to correctly handle JSII "magic objects" that are used to remodel "pass-by-reference" + * values, dates, and enum constants. + */ + private final class JsiiDeserializer extends StdDeserializer implements ContextualDeserializer, ResolvableDeserializer{ + public static final long serialVersionUID = 1L; + + private final JsonDeserializer standardDeserializer; /** - * Converts a jsii JSON tree to a local Java type. - * @param tree The JSON tree. - * @param type The expected return type. - * @param The return type. - * @return The local Java value. - * @throws JsonProcessingException If there was a problem reading the JSON tree. + * @param standardDeserializer a standard Jackson deserialize that can be delegated to in case the object is not a + * JSII "magic object". */ - @SuppressWarnings("unchecked") - public T treeToValue(final JsonNode tree, final Class type) throws JsonProcessingException { - if (tree == null) { - return null; - } + public JsiiDeserializer(final JsonDeserializer standardDeserializer) { + super(Object.class); + this.standardDeserializer = standardDeserializer; + } - if (tree.isArray()) { - ArrayNode array = (ArrayNode) tree; - ArrayList out = new ArrayList<>(); - for (JsonNode x : array) { - out.add(treeToValue(x, Object.class)); - } - return (T) out; - } + @Override + public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { + final JsonNode node = p.readValueAsTree(); - if (tree.isObject() && tree.has(TOKEN_DATE)) { - return (T) Instant.parse(tree.get(TOKEN_DATE).textValue()); + if (node.isObject()) { + if (node.has(TOKEN_DATE)) { + return Instant.parse(node.get(TOKEN_DATE).textValue()); } - - if (tree.isObject() && tree.has(TOKEN_REF)) { - return (T) JsiiEngine.getInstance().nativeFromObjRef(JsiiObjectRef.parse(tree)); + if (node.has(TOKEN_ENUM)) { + return jsiiEngine.findEnumValue(node.get(TOKEN_ENUM).textValue()); } - - if (tree.isObject() && tree.has(TOKEN_ENUM)) { - return (T) JsiiEngine.getInstance().findEnumValue(tree.get(TOKEN_ENUM).textValue()); + if (node.has(TOKEN_REF)) { + return jsiiEngine.nativeFromObjRef(JsiiObjectRef.parse(node)); } + } - // json type - if (ObjectNode.class.isAssignableFrom(type)) { - return (T) tree; - } + final JsonParser nodeParser = node.traverse(p.getCodec()); + nodeParser.nextToken(); + return standardDeserializer.deserialize(nodeParser, ctxt); + } - if (tree.isObject()) { - ObjectNode objectNode = (ObjectNode) tree; - Map map = new HashMap<>(); - Iterable fields = objectNode::fieldNames; - for (String field : fields) { - Object value = treeToValue(objectNode.get(field), Object.class); - map.put(field, value); - } - return (T) map; - } + @Override + public JsonDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { + if (this.standardDeserializer instanceof ContextualDeserializer) { + return new JsiiDeserializer(((ContextualDeserializer)this.standardDeserializer).createContextual(ctxt, property)); + } + return this; + } - return standardMapper.treeToValue(tree, type); + @Override + public void resolve(DeserializationContext ctxt) throws JsonMappingException { + if (this.standardDeserializer instanceof ResolvableDeserializer) { + ((ResolvableDeserializer)this.standardDeserializer).resolve(ctxt); + } + } + } + + public final class JsiiDeserializerModifier extends BeanDeserializerModifier { + @Override + public JsonDeserializer modifyDeserializer(DeserializationConfig config, + BeanDescription beanDesc, + JsonDeserializer deserializer) { + return new JsiiDeserializer(deserializer); } - /** - * Serializer for enum values. - */ - @SuppressWarnings("rawtypes") - private static class EnumSerializer extends JsonSerializer { - @Override - public void serialize(final Enum value, final JsonGenerator gen, final SerializerProvider serializers) - throws IOException { - Jsii jsii = tryGetJsiiAnnotation(value.getClass(), false); - if (jsii == null) { - throw new JsiiException("Cannot serialize non-jsii enums"); - } else { - gen.writeStartObject(); - gen.writeStringField(TOKEN_ENUM, jsii.fqn() + "/" + value.toString()); - gen.writeEndObject(); - } - } + @Override + public JsonDeserializer modifyEnumDeserializer(DeserializationConfig config, + JavaType type, + BeanDescription beanDesc, + JsonDeserializer deserializer) { + return new JsiiDeserializer(deserializer); } - /** - * Serializer for dates. - */ - private static class DateSerializer extends JsonSerializer { - @Override - public void serialize(final Instant value, final JsonGenerator gen, final SerializerProvider serializers) - throws IOException { - gen.writeStartObject(); - gen.writeStringField(TOKEN_DATE, value.toString()); - gen.writeEndObject(); - } + @Override + public JsonDeserializer modifyMapDeserializer(DeserializationConfig config, + MapType type, + BeanDescription beanDesc, + JsonDeserializer deserializer) { + return new JsiiDeserializer(deserializer); } - /** - * Serializer for classes that extend JsiiObject and any other class that implements a jsii interface. - * We use the JsiiSerializable interface as a way to identify "anything jsii-able". - */ - private static class JsiiSerializer extends JsonSerializer { - @Override - public void serialize(final JsiiSerializable o, - final JsonGenerator jsonGenerator, - final SerializerProvider serializerProvider) throws IOException { + @Override + public JsonDeserializer modifyMapLikeDeserializer(DeserializationConfig config, + MapLikeType type, + BeanDescription beanDesc, + JsonDeserializer deserializer) { + return new JsiiDeserializer(deserializer); + } + } + + /** + * Serializer for classes that extend JsiiObject and any other class that implements a jsii interface. + * We use the JsiiSerializable interface as a way to identify "anything jsii-able". + */ + private static final class JsiiSerializer extends JsonSerializer { + @Override + public void serialize(final JsiiSerializable o, + final JsonGenerator jsonGenerator, + final SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeTree(o.$jsii$toJson()); + } + } + + /** + * Serializer for enum values. + */ + @SuppressWarnings("rawtypes") + private static final class EnumSerializer extends JsonSerializer { + @Override + public void serialize(final Enum value, final JsonGenerator gen, final SerializerProvider serializers) throws IOException { + Jsii jsii = this.tryGetJsiiAnnotation(value.getClass(), false); + if (jsii == null) { + throw new JsiiException("Cannot serialize non-jsii enums"); + } else { + gen.writeStartObject(); + gen.writeStringField(TOKEN_ENUM, jsii.fqn() + "/" + value.toString()); + gen.writeEndObject(); + } + } - jsonGenerator.writeTree(o.$jsii$toJson()); - } + private Jsii tryGetJsiiAnnotation(final Class type, final boolean inherited) { + Jsii[] ann; + + if (inherited) { + ann = (Jsii[]) type.getAnnotationsByType(Jsii.class); + } else { + ann = (Jsii[]) type.getDeclaredAnnotationsByType(Jsii.class); + } + + if (ann.length == 0) { + return null; + } + + return ann[0]; + } + } + + /** + * Serializer for Instants. + */ + private static final class Instanterializer extends JsonSerializer { + @Override + public void serialize(final Instant value, final JsonGenerator gen, final SerializerProvider serializers) throws IOException { + gen.writeStartObject(); + gen.writeStringField(TOKEN_DATE, value.toString()); + gen.writeEndObject(); } + } } diff --git a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObjectRef.java b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObjectRef.java index 76d372211b..3fe7826e3c 100644 --- a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObjectRef.java +++ b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiObjectRef.java @@ -91,4 +91,21 @@ public String getObjId() { public String toString() { return objId; } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || !(obj instanceof JsiiObjectRef)) { + return false; + } + final JsiiObjectRef other = (JsiiObjectRef) obj; + return this.objId.equals(other.objId); + } + + @Override + public int hashCode() { + return this.objId.hashCode(); + } } diff --git a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiRuntime.java b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiRuntime.java index f27d2d6121..9cd0755092 100644 --- a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiRuntime.java +++ b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/JsiiRuntime.java @@ -3,7 +3,6 @@ import software.amazon.jsii.api.Callback; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -28,11 +27,6 @@ public final class JsiiRuntime { */ private static final String VERSION_BUILD_PART_REGEX = "\\+[a-z0-9]+$"; - /** - * JSON object mapper. - */ - private static final ObjectMapper OM = new ObjectMapper(); - /** * True to print server traces to STDERR. */ @@ -129,12 +123,7 @@ private JsonNode processCallbackResponse(final JsonNode resp) { throw new JsiiException("Cannot process callback since callbackHandler was not set"); } - Callback callback; - try { - callback = OM.treeToValue(resp.get("callback"), Callback.class); - } catch (JsonProcessingException e) { - throw new JsiiException(e); - } + Callback callback = JsiiObjectMapper.treeToValue(resp.get("callback"), Callback.class); JsonNode result = null; String error = null; @@ -222,7 +211,7 @@ private void startRuntimeIfNeeded() { if (traceEnabled) { pb.environment().put("JSII_DEBUG", "1"); } - + pb.environment().put("JSII_AGENT", "Java/" + System.getProperty("java.version")); try { @@ -282,7 +271,7 @@ JsonNode readNextResponse() { String error = this.stderr.lines().collect(Collectors.joining("\n\t")); throw new JsiiException("Child process exited unexpectedly: " + error); } - return OM.readTree(responseLine); + return JsiiObjectMapper.INSTANCE.readTree(responseLine); } catch (IOException e) { throw new JsiiException("Unable to read reply from jsii-runtime: " + e.toString(), e); } diff --git a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/api/InvokeRequest.java b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/api/InvokeRequest.java index 6381844459..3fd51a9c59 100644 --- a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/api/InvokeRequest.java +++ b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/api/InvokeRequest.java @@ -1,5 +1,6 @@ package software.amazon.jsii.api; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import java.util.List; @@ -21,7 +22,7 @@ public class InvokeRequest { /** * Method arguments. */ - private List args; + private List args; /** * @return The object reference. @@ -54,14 +55,14 @@ public void setMethod(final String method) { /** * @return Method arguments. */ - public List getArgs() { + public List getArgs() { return args; } /** * @param args Method arguments. */ - public void setArgs(final List args) { + public void setArgs(final List args) { this.args = args; } } diff --git a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/api/SetRequest.java b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/api/SetRequest.java index 8849a2caa3..13dd37eafd 100644 --- a/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/api/SetRequest.java +++ b/packages/jsii-java-runtime/project/src/main/java/software/amazon/jsii/api/SetRequest.java @@ -19,7 +19,7 @@ public class SetRequest { /** * The new value. */ - private Object value; + private JsonNode value; /** * @return The jsii object reference. @@ -52,14 +52,14 @@ public void setProperty(final String property) { /** * @return The new value. */ - public Object getValue() { + public JsonNode getValue() { return value; } /** * @param value The new value. */ - public void setValue(final Object value) { + public void setValue(final JsonNode value) { this.value = value; } } diff --git a/packages/jsii-java-runtime/project/src/test/java/software/amazon/jsii/JsiiObjectMapperTest.java b/packages/jsii-java-runtime/project/src/test/java/software/amazon/jsii/JsiiObjectMapperTest.java new file mode 100644 index 0000000000..c12f129e6d --- /dev/null +++ b/packages/jsii-java-runtime/project/src/test/java/software/amazon/jsii/JsiiObjectMapperTest.java @@ -0,0 +1,131 @@ +package software.amazon.jsii; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.time.Instant; +import java.util.List; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Charsets; +import com.google.common.io.Resources; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public final class JsiiObjectMapperTest { + private JsiiEngine jsiiEngine; + private ObjectMapper subject; + + @BeforeEach + public void setUp() { + this.jsiiEngine = mock(JsiiEngine.class); + this.subject = new JsiiObjectMapper(jsiiEngine).getObjectMapper(); + } + + @AfterEach + public void cleanUp() { + this.jsiiEngine = null; + this.subject = null; + } + + @Test + public void testDeserialization() throws Exception { + final Object mockObject1 = new Object(); + when(jsiiEngine.nativeFromObjRef(JsiiObjectRef.fromObjId("module.Type@1"))).thenReturn(mockObject1); + + when((TestEnum) jsiiEngine.findEnumValue("module.Enum#value")).thenReturn(TestEnum.DUMMY); + + final String json = + Resources.toString(Resources.getResource(this.getClass(), "complex-callback.json"), Charsets.UTF_8); + final TestCallback callback = subject.treeToValue(subject.readTree(json), TestCallback.class); + + assertEquals("CallbackID", callback.getCbid()); + assertNotNull(callback.getInvoke()); + if (callback.getCbid() != null) { + assertEquals("methodName", callback.getInvoke().getMethod()); + assertEquals(1337, callback.getInvoke().getArgs().get(0)); + assertEquals(mockObject1, callback.getInvoke().getArgs().get(1)); + assertEquals(Instant.ofEpochMilli(1553624863569L), callback.getInvoke().getArgs().get(2)); + assertEquals(TestEnum.DUMMY, callback.getInvoke().getArgs().get(3)); + } + } + + @Test + public void testSerializationOfJsiiSerializables() throws Exception { + final String dummyValue = "{\"foo\":\"Bar\"}"; + final JsiiSerializable object = mock(JsiiSerializable.class); + when(object.$jsii$toJson()).thenReturn(new ObjectMapper().readTree(dummyValue)); + + final String json = subject.writeValueAsString(object); + + assertEquals(dummyValue, json); + } + + @Test + public void testSerializationOfInstant() throws Exception { + final Instant object = Instant.ofEpochMilli(1553691207095L); + + final String json = subject.writeValueAsString(object); + + assertEquals("{\"$jsii.date\":\"2019-03-27T12:53:27.095Z\"}", json); + } + + private static enum TestEnum { + DUMMY + } + + /** + * Kinda like the Callback object expcet it does not model stuff as JsonNodes, + * so we can verify the deserialization behaviour. + */ + public static final class TestCallback { + private String cbid; + + private TestInvokeRequest invoke; + + public String getCbid() { + return cbid; + } + + public void setCbid(String cbid) { + this.cbid = cbid; + } + + public TestInvokeRequest getInvoke() { + return invoke; + } + + public void setInvoke(TestInvokeRequest invoke) { + this.invoke = invoke; + } + } + + /** + * Kinda like the InvokeRequest, except it does not model anything as JsonNode, + * so we can test the deserialization behavior properly. + */ + public static final class TestInvokeRequest { + private String method; + + private List args; + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public List getArgs() { + return args; + } + + public void setArgs(List args) { + this.args = args; + } + } +} diff --git a/packages/jsii-java-runtime/project/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/packages/jsii-java-runtime/project/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000000..1f0955d450 --- /dev/null +++ b/packages/jsii-java-runtime/project/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline diff --git a/packages/jsii-java-runtime/project/src/test/resources/software/amazon/jsii/complex-callback.json b/packages/jsii-java-runtime/project/src/test/resources/software/amazon/jsii/complex-callback.json new file mode 100644 index 0000000000..8216ba356c --- /dev/null +++ b/packages/jsii-java-runtime/project/src/test/resources/software/amazon/jsii/complex-callback.json @@ -0,0 +1,12 @@ +{ + "cbid": "CallbackID", + "invoke": { + "method": "methodName", + "args": [ + 1337, + { "$jsii.byref": "module.Type@1" }, + { "$jsii.date": "2019-03-26T18:27:43.569Z" }, + { "$jsii.enum": "module.Enum#value" } + ] + } +} diff --git a/packages/jsii-kernel/lib/kernel.ts b/packages/jsii-kernel/lib/kernel.ts index d76fafe0ce..c262a00532 100644 --- a/packages/jsii-kernel/lib/kernel.ts +++ b/packages/jsii-kernel/lib/kernel.ts @@ -768,7 +768,7 @@ export class Kernel { throw new Error(`Module '${moduleName}' not found`); } - const types = assembly.metadata.types || {}; + const types = assembly.metadata.types || {}; const fqnInfo = types[fqn]; if (!fqnInfo) { throw new Error(`Type '${fqn}' not found`); @@ -1074,4 +1074,4 @@ function mapSource(err: Error, sourceMaps: { [assm: string]: SourceMapConsumer } } } -const ANY_TYPE: spec.PrimitiveTypeReference = { primitive: spec.PrimitiveType.Any }; \ No newline at end of file +const ANY_TYPE: spec.PrimitiveTypeReference = { primitive: spec.PrimitiveType.Any }; diff --git a/packages/jsii-kernel/lib/objects.ts b/packages/jsii-kernel/lib/objects.ts index 0801b1d1e6..4d0a6a17be 100644 --- a/packages/jsii-kernel/lib/objects.ts +++ b/packages/jsii-kernel/lib/objects.ts @@ -89,6 +89,11 @@ export class ObjectTable { throw new Error('FQN cannot be undefined'); } + const existingRef = objectReference(obj); + if (existingRef) { + return existingRef; + } + const objid = this.makeId(fqn); this.objects[objid] = { instance: obj, fqn }; tagObject(obj, objid); @@ -132,4 +137,4 @@ export class ObjectTable { export interface RegisteredObject { instance: any; fqn: string; -} \ No newline at end of file +} diff --git a/packages/jsii-kernel/test/test.kernel.ts b/packages/jsii-kernel/test/test.kernel.ts index 9b34419021..1bae70b6b5 100644 --- a/packages/jsii-kernel/test/test.kernel.ts +++ b/packages/jsii-kernel/test/test.kernel.ts @@ -1090,6 +1090,28 @@ defineTest('can set and retrieve union properties', async (test, sandbox) => { test.equal(get(sandbox, unionArray[1])('value'), 33); }); +defineTest('Object ID does not get re-allocated when the constructor passes "this" out', async (test, sandbox) => { + sandbox.callbackHandler = makeSyncCallbackHandler((callback) => { + test.equal(callback.invoke && callback.invoke.method, 'consumePartiallyInitializedThis'); + test.deepEqual(callback.invoke && callback.invoke.args && callback.invoke.args, [{ + [api.TOKEN_REF]: 'jsii-calc.ConstructorPassesThisOut@10001' + }, { + [api.TOKEN_DATE]: '1970-01-01T00:00:00.000Z' + }, { + [api.TOKEN_ENUM]: 'jsii-calc.AllTypesEnum/ThisIsGreat' + }]); + return 'OK'; + }); + const reflector = sandbox.create({ + fqn: 'jsii-calc.PartiallyInitializedThisConsumer', + overrides: [{ method: 'consumePartiallyInitializedThis' }] + }); + test.equal(reflector[api.TOKEN_REF], 'jsii-calc.PartiallyInitializedThisConsumer@10000'); + + const classRef = sandbox.create({ fqn: 'jsii-calc.ConstructorPassesThisOut', args: [reflector] }); + test.equal(classRef[api.TOKEN_REF], 'jsii-calc.ConstructorPassesThisOut@10001'); +}); + // ================================================================================================= const testNames: { [name: string]: boolean } = { }; diff --git a/packages/jsii-pacmak/lib/generator.ts b/packages/jsii-pacmak/lib/generator.ts index f038dd432e..c5a8ef8df9 100644 --- a/packages/jsii-pacmak/lib/generator.ts +++ b/packages/jsii-pacmak/lib/generator.ts @@ -252,7 +252,7 @@ export abstract class Generator implements IGenerator { this.addAbstractPostfixToClassName(classSpec); } this.onBeginClass(classSpec, abstract); - this.visitClass(classSpec, abstract); + this.visitClass(classSpec); visitChildren(); this.onEndClass(classSpec); break; @@ -360,9 +360,9 @@ export abstract class Generator implements IGenerator { } } - private visitClass(cls: spec.ClassType, abstract: boolean | undefined) { + private visitClass(cls: spec.ClassType) { let initializer = cls.initializer; - if (!abstract && initializer) { + if (initializer) { this.onInitializer(cls, initializer); diff --git a/packages/jsii-pacmak/lib/targets/java.ts b/packages/jsii-pacmak/lib/targets/java.ts index 6c2fdc17db..8422cfdd53 100644 --- a/packages/jsii-pacmak/lib/targets/java.ts +++ b/packages/jsii-pacmak/lib/targets/java.ts @@ -804,7 +804,7 @@ class JavaGenerator extends Generator { // emit $jsii$toJson which will be called to serialize this object when sent to JS this.code.line(); this.code.openBlock(`public com.fasterxml.jackson.databind.JsonNode $jsii$toJson()`); - this.code.line(`software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance;`); + this.code.line(`com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE;`); // tslint:disable-next-line:max-line-length this.code.line(`com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode();`); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/Base.java b/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/Base.java index 7a64b8e3d7..aa712c99bf 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/Base.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/Base.java @@ -9,6 +9,10 @@ public abstract class Base extends software.amazon.jsii.JsiiObject { protected Base(final software.amazon.jsii.JsiiObject.InitializationMode mode) { super(mode); } + public Base() { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this); + } /** * @return the name of the class (to verify native type names are created for derived classes). diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/BaseProps.java b/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/BaseProps.java index 3a7e75c7c1..ada23728e0 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/BaseProps.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/BaseProps.java @@ -58,7 +58,7 @@ public software.amazon.jsii.tests.calculator.baseofbase.Very getFoo() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("bar", om.valueToTree(this.getBar())); obj.set("foo", om.valueToTree(this.getFoo())); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/MyFirstStruct.java b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/MyFirstStruct.java index a78ea35ce8..0fd8d95830 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/MyFirstStruct.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/MyFirstStruct.java @@ -87,7 +87,7 @@ public java.util.List getFirstOptional() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("anumber", om.valueToTree(this.getAnumber())); obj.set("astring", om.valueToTree(this.getAstring())); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/Operation.java b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/Operation.java index 2ae2a27035..b689b90d26 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/Operation.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/Operation.java @@ -9,6 +9,10 @@ public abstract class Operation extends software.amazon.jsii.tests.calculator.li protected Operation(final software.amazon.jsii.JsiiObject.InitializationMode mode) { super(mode); } + public Operation() { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this); + } /** * String representation of the value. diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/StructWithOnlyOptionals.java b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/StructWithOnlyOptionals.java index 7eecb3e01a..87ac4d7100 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/StructWithOnlyOptionals.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/StructWithOnlyOptionals.java @@ -88,7 +88,7 @@ public java.lang.Boolean getOptional3() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("optional1", om.valueToTree(this.getOptional1())); obj.set("optional2", om.valueToTree(this.getOptional2())); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/Value.java b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/Value.java index 16b9db138a..21ce8bdd18 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/Value.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/Value.java @@ -9,6 +9,10 @@ public abstract class Value extends software.amazon.jsii.tests.calculator.base.B protected Value(final software.amazon.jsii.JsiiObject.InitializationMode mode) { super(mode); } + public Value() { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this); + } /** * String representation of the value. diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii index 20fac29cd7..dc9f5f0401 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii @@ -84,6 +84,30 @@ }, "version": "0.8.0" }, + "@scope/jsii-calc-base-of-base": { + "peer": true, + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base-of-base", + "groupId": "software.amazon.jsii.tests" + }, + "package": "software.amazon.jsii.tests.calculator.baseofbase" + }, + "js": { + "npm": "@scope/jsii-calc-base-of-base" + }, + "python": { + "distName": "scope.jsii-calc-base-of-base", + "module": "scope.jsii_calc_base_of_base" + } + }, + "version": "0.8.0" + }, "@scope/jsii-calc-lib": { "dependencies": { "@scope/jsii-calc-base": { @@ -1250,6 +1274,23 @@ } ] }, + "jsii-calc.ConstructorPassesThisOut": { + "assembly": "jsii-calc", + "fqn": "jsii-calc.ConstructorPassesThisOut", + "initializer": { + "initializer": true, + "parameters": [ + { + "name": "consumer", + "type": { + "fqn": "jsii-calc.PartiallyInitializedThisConsumer" + } + } + ] + }, + "kind": "class", + "name": "ConstructorPassesThisOut" + }, "jsii-calc.Constructors": { "assembly": "jsii-calc", "fqn": "jsii-calc.Constructors", @@ -3327,6 +3368,45 @@ ], "name": "OverrideReturnsObject" }, + "jsii-calc.PartiallyInitializedThisConsumer": { + "abstract": true, + "assembly": "jsii-calc", + "fqn": "jsii-calc.PartiallyInitializedThisConsumer", + "initializer": { + "initializer": true + }, + "kind": "class", + "methods": [ + { + "abstract": true, + "name": "consumePartiallyInitializedThis", + "parameters": [ + { + "name": "obj", + "type": { + "fqn": "jsii-calc.ConstructorPassesThisOut" + } + }, + { + "name": "dt", + "type": { + "primitive": "date" + } + }, + { + "name": "ev", + "type": { + "fqn": "jsii-calc.AllTypesEnum" + } + } + ], + "returns": { + "primitive": "string" + } + } + ], + "name": "PartiallyInitializedThisConsumer" + }, "jsii-calc.Polymorphism": { "assembly": "jsii-calc", "fqn": "jsii-calc.Polymorphism", @@ -4500,5 +4580,5 @@ } }, "version": "0.8.0", - "fingerprint": "WIFIhqgEwUDjCsDr7gliujhqcKZQSkDP+NstBfmdvZU=" + "fingerprint": "J0bhm0cu1dlTAyMfBlAMWCVXZf6e8k2pHkmxye6P7Wk=" } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon.JSII.Tests.CalculatorPackageId.csproj b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon.JSII.Tests.CalculatorPackageId.csproj index bca205b843..88e65f9c6c 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon.JSII.Tests.CalculatorPackageId.csproj +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon.JSII.Tests.CalculatorPackageId.csproj @@ -19,6 +19,7 @@ + diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ConstructorPassesThisOut.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ConstructorPassesThisOut.cs new file mode 100644 index 0000000000..e31c3513f0 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ConstructorPassesThisOut.cs @@ -0,0 +1,20 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + [JsiiClass(typeof(ConstructorPassesThisOut), "jsii-calc.ConstructorPassesThisOut", "[{\"name\":\"consumer\",\"type\":{\"fqn\":\"jsii-calc.PartiallyInitializedThisConsumer\"}}]")] + public class ConstructorPassesThisOut : DeputyBase + { + public ConstructorPassesThisOut(PartiallyInitializedThisConsumer consumer): base(new DeputyProps(new object[]{consumer})) + { + } + + protected ConstructorPassesThisOut(ByRefValue reference): base(reference) + { + } + + protected ConstructorPassesThisOut(DeputyProps props): base(props) + { + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Internal/DependencyResolution/Anchor.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Internal/DependencyResolution/Anchor.cs index af4f74d979..d7d966706c 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Internal/DependencyResolution/Anchor.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Internal/DependencyResolution/Anchor.cs @@ -5,6 +5,7 @@ public class Anchor public Anchor() { new Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace.Internal.DependencyResolution.Anchor(); + new Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace.Internal.DependencyResolution.Anchor(); new Amazon.JSII.Tests.CalculatorNamespace.LibNamespace.Internal.DependencyResolution.Anchor(); } } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/PartiallyInitializedThisConsumer.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/PartiallyInitializedThisConsumer.cs new file mode 100644 index 0000000000..f578f5321f --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/PartiallyInitializedThisConsumer.cs @@ -0,0 +1,24 @@ +using Amazon.JSII.Runtime.Deputy; +using System; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + [JsiiClass(typeof(PartiallyInitializedThisConsumer), "jsii-calc.PartiallyInitializedThisConsumer", "[]")] + public abstract class PartiallyInitializedThisConsumer : DeputyBase + { + protected PartiallyInitializedThisConsumer(): base(new DeputyProps(new object[]{})) + { + } + + protected PartiallyInitializedThisConsumer(ByRefValue reference): base(reference) + { + } + + protected PartiallyInitializedThisConsumer(DeputyProps props): base(props) + { + } + + [JsiiMethod("consumePartiallyInitializedThis", "{\"primitive\":\"string\"}", "[{\"name\":\"obj\",\"type\":{\"fqn\":\"jsii-calc.ConstructorPassesThisOut\"}},{\"name\":\"dt\",\"type\":{\"primitive\":\"date\"}},{\"name\":\"ev\",\"type\":{\"fqn\":\"jsii-calc.AllTypesEnum\"}}]")] + public abstract string ConsumePartiallyInitializedThis(ConstructorPassesThisOut obj, DateTime dt, AllTypesEnum ev); + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/PartiallyInitializedThisConsumerProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/PartiallyInitializedThisConsumerProxy.cs new file mode 100644 index 0000000000..2ebb268de0 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/PartiallyInitializedThisConsumerProxy.cs @@ -0,0 +1,19 @@ +using Amazon.JSII.Runtime.Deputy; +using System; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + [JsiiTypeProxy(typeof(PartiallyInitializedThisConsumer), "jsii-calc.PartiallyInitializedThisConsumer")] + internal sealed class PartiallyInitializedThisConsumerProxy : PartiallyInitializedThisConsumer + { + private PartiallyInitializedThisConsumerProxy(ByRefValue reference): base(reference) + { + } + + [JsiiMethod("consumePartiallyInitializedThis", "{\"primitive\":\"string\"}", "[{\"name\":\"obj\",\"type\":{\"fqn\":\"jsii-calc.ConstructorPassesThisOut\"}},{\"name\":\"dt\",\"type\":{\"primitive\":\"date\"}},{\"name\":\"ev\",\"type\":{\"fqn\":\"jsii-calc.AllTypesEnum\"}}]")] + public override string ConsumePartiallyInitializedThis(ConstructorPassesThisOut obj, DateTime dt, AllTypesEnum ev) + { + return InvokeInstanceMethod(new object[]{obj, dt, ev}); + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/pom.xml b/packages/jsii-pacmak/test/expected.jsii-calc/java/pom.xml index 37ffffcdd2..6d9f336cfd 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/pom.xml +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/pom.xml @@ -60,12 +60,12 @@ 0.8.0 - calculator-lib + calculator-base-of-base software.amazon.jsii.tests 0.8.0 - calculator-base-of-base + calculator-lib software.amazon.jsii.tests 0.8.0 diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java index 770fbe051a..f780997301 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java @@ -12,7 +12,7 @@ public final class $Module extends JsiiModule { @Override public List> getDependencies() { - return asList(software.amazon.jsii.tests.calculator.base.$Module.class, software.amazon.jsii.tests.calculator.lib.$Module.class); + return asList(software.amazon.jsii.tests.calculator.base.$Module.class, software.amazon.jsii.tests.calculator.baseofbase.$Module.class, software.amazon.jsii.tests.calculator.lib.$Module.class); } @Override @@ -34,6 +34,7 @@ protected Class resolveClass(final String fqn) throws ClassNotFoundException case "jsii-calc.ClassThatImplementsThePrivateInterface": return software.amazon.jsii.tests.calculator.ClassThatImplementsThePrivateInterface.class; case "jsii-calc.ClassWithMutableObjectLiteralProperty": return software.amazon.jsii.tests.calculator.ClassWithMutableObjectLiteralProperty.class; case "jsii-calc.ClassWithPrivateConstructorAndAutomaticProperties": return software.amazon.jsii.tests.calculator.ClassWithPrivateConstructorAndAutomaticProperties.class; + case "jsii-calc.ConstructorPassesThisOut": return software.amazon.jsii.tests.calculator.ConstructorPassesThisOut.class; case "jsii-calc.Constructors": return software.amazon.jsii.tests.calculator.Constructors.class; case "jsii-calc.ConsumersOfThisCrazyTypeSystem": return software.amazon.jsii.tests.calculator.ConsumersOfThisCrazyTypeSystem.class; case "jsii-calc.DefaultedConstructorArgument": return software.amazon.jsii.tests.calculator.DefaultedConstructorArgument.class; @@ -92,6 +93,7 @@ protected Class resolveClass(final String fqn) throws ClassNotFoundException case "jsii-calc.ObjectRefsInCollections": return software.amazon.jsii.tests.calculator.ObjectRefsInCollections.class; case "jsii-calc.OptionalConstructorArgument": return software.amazon.jsii.tests.calculator.OptionalConstructorArgument.class; case "jsii-calc.OverrideReturnsObject": return software.amazon.jsii.tests.calculator.OverrideReturnsObject.class; + case "jsii-calc.PartiallyInitializedThisConsumer": return software.amazon.jsii.tests.calculator.PartiallyInitializedThisConsumer.class; case "jsii-calc.Polymorphism": return software.amazon.jsii.tests.calculator.Polymorphism.class; case "jsii-calc.Power": return software.amazon.jsii.tests.calculator.Power.class; case "jsii-calc.PublicClass": return software.amazon.jsii.tests.calculator.PublicClass.class; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/AbstractClass.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/AbstractClass.java index 97e11233a7..78061b7876 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/AbstractClass.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/AbstractClass.java @@ -6,6 +6,10 @@ public abstract class AbstractClass extends software.amazon.jsii.tests.calculato protected AbstractClass(final software.amazon.jsii.JsiiObject.InitializationMode mode) { super(mode); } + public AbstractClass() { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this); + } public abstract java.lang.String abstractMethod(final java.lang.String name); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/AbstractClassBase.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/AbstractClassBase.java index 15756d5fb6..381fb205c6 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/AbstractClassBase.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/AbstractClassBase.java @@ -6,6 +6,10 @@ public abstract class AbstractClassBase extends software.amazon.jsii.JsiiObject protected AbstractClassBase(final software.amazon.jsii.JsiiObject.InitializationMode mode) { super(mode); } + public AbstractClassBase() { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this); + } public java.lang.String getAbstractProperty() { return this.jsiiGet("abstractProperty", java.lang.String.class); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/BinaryOperation.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/BinaryOperation.java index c75105c770..a2f38995bc 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/BinaryOperation.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/BinaryOperation.java @@ -9,6 +9,15 @@ public abstract class BinaryOperation extends software.amazon.jsii.tests.calcula protected BinaryOperation(final software.amazon.jsii.JsiiObject.InitializationMode mode) { super(mode); } + /** + * Creates a BinaryOperation + * @param lhs Left-hand side operand + * @param rhs Right-hand side operand + */ + public BinaryOperation(final software.amazon.jsii.tests.calculator.lib.Value lhs, final software.amazon.jsii.tests.calculator.lib.Value rhs) { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this, java.util.stream.Stream.concat(java.util.stream.Stream.of(java.util.Objects.requireNonNull(lhs, "lhs is required")), java.util.stream.Stream.of(java.util.Objects.requireNonNull(rhs, "rhs is required"))).toArray()); + } /** * Say hello! diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/CalculatorProps.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/CalculatorProps.java index b338d7a347..b965bc1b48 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/CalculatorProps.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/CalculatorProps.java @@ -66,7 +66,7 @@ public java.lang.Number getMaximumValue() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("initialValue", om.valueToTree(this.getInitialValue())); obj.set("maximumValue", om.valueToTree(this.getMaximumValue())); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ConstructorPassesThisOut.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ConstructorPassesThisOut.java new file mode 100644 index 0000000000..0090358fca --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ConstructorPassesThisOut.java @@ -0,0 +1,13 @@ +package software.amazon.jsii.tests.calculator; + +@javax.annotation.Generated(value = "jsii-pacmak") +@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.ConstructorPassesThisOut") +public class ConstructorPassesThisOut extends software.amazon.jsii.JsiiObject { + protected ConstructorPassesThisOut(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + public ConstructorPassesThisOut(final software.amazon.jsii.tests.calculator.PartiallyInitializedThisConsumer consumer) { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this, java.util.stream.Stream.of(java.util.Objects.requireNonNull(consumer, "consumer is required")).toArray()); + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DerivedStruct.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DerivedStruct.java index 3521a946d2..9e0a7ef4a8 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DerivedStruct.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DerivedStruct.java @@ -192,7 +192,7 @@ public java.util.List getFirstOptional() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("anotherRequired", om.valueToTree(this.getAnotherRequired())); obj.set("bool", om.valueToTree(this.getBool())); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/EraseUndefinedHashValuesOptions.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/EraseUndefinedHashValuesOptions.java index 5679345465..6c3d314d83 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/EraseUndefinedHashValuesOptions.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/EraseUndefinedHashValuesOptions.java @@ -63,7 +63,7 @@ public java.lang.String getOption2() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("option1", om.valueToTree(this.getOption1())); obj.set("option2", om.valueToTree(this.getOption2())); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ExtendsInternalInterface.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ExtendsInternalInterface.java index 2dd56d0f9e..2147ac9850 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ExtendsInternalInterface.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ExtendsInternalInterface.java @@ -42,7 +42,7 @@ public java.lang.Boolean getBoom() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("boom", om.valueToTree(this.getBoom())); return obj; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ExtendsPrivateInterface.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ExtendsPrivateInterface.java index ddddccb47e..a54e9c9b96 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ExtendsPrivateInterface.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ExtendsPrivateInterface.java @@ -42,7 +42,7 @@ public java.util.List getMoreThings() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("moreThings", om.valueToTree(this.getMoreThings())); return obj; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ImplictBaseOfBase.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ImplictBaseOfBase.java index 81e1bd0256..7467b51816 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ImplictBaseOfBase.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ImplictBaseOfBase.java @@ -74,7 +74,7 @@ public software.amazon.jsii.tests.calculator.baseofbase.Very getFoo() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("goo", om.valueToTree(this.getGoo())); obj.set("bar", om.valueToTree(this.getBar())); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceImplementedByAbstractClass.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceImplementedByAbstractClass.java index 7a86e32bdf..2d82ab4fda 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceImplementedByAbstractClass.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceImplementedByAbstractClass.java @@ -46,7 +46,7 @@ public java.lang.String getPropFromInterface() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("propFromInterface", om.valueToTree(this.getPropFromInterface())); return obj; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Hello.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Hello.java index 5be456c296..df4d2c11a9 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Hello.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Hello.java @@ -42,7 +42,7 @@ public java.lang.Number getFoo() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("foo", om.valueToTree(this.getFoo())); return obj; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceOnlyInterface/Hello.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceOnlyInterface/Hello.java index 16c645adbf..cd5d24e776 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceOnlyInterface/Hello.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceOnlyInterface/Hello.java @@ -42,7 +42,7 @@ public java.lang.Number getFoo() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("foo", om.valueToTree(this.getFoo())); return obj; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/LoadBalancedFargateServiceProps.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/LoadBalancedFargateServiceProps.java index dd8791035c..39ce1d3ac4 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/LoadBalancedFargateServiceProps.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/LoadBalancedFargateServiceProps.java @@ -189,7 +189,7 @@ public java.lang.Boolean getPublicTasks() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("containerPort", om.valueToTree(this.getContainerPort())); obj.set("cpu", om.valueToTree(this.getCpu())); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/NullShouldBeTreatedAsUndefinedData.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/NullShouldBeTreatedAsUndefinedData.java index bdef5fc26a..ec17387884 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/NullShouldBeTreatedAsUndefinedData.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/NullShouldBeTreatedAsUndefinedData.java @@ -61,7 +61,7 @@ public java.lang.Object getThisShouldBeUndefined() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("arrayWithThreeElementsAndUndefinedAsSecondArgument", om.valueToTree(this.getArrayWithThreeElementsAndUndefinedAsSecondArgument())); obj.set("thisShouldBeUndefined", om.valueToTree(this.getThisShouldBeUndefined())); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/PartiallyInitializedThisConsumer.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/PartiallyInitializedThisConsumer.java new file mode 100644 index 0000000000..744968b276 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/PartiallyInitializedThisConsumer.java @@ -0,0 +1,29 @@ +package software.amazon.jsii.tests.calculator; + +@javax.annotation.Generated(value = "jsii-pacmak") +@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.PartiallyInitializedThisConsumer") +public abstract class PartiallyInitializedThisConsumer extends software.amazon.jsii.JsiiObject { + protected PartiallyInitializedThisConsumer(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + public PartiallyInitializedThisConsumer() { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this); + } + + public abstract java.lang.String consumePartiallyInitializedThis(final software.amazon.jsii.tests.calculator.ConstructorPassesThisOut obj, final java.time.Instant dt, final software.amazon.jsii.tests.calculator.AllTypesEnum ev); + + /** + * A proxy class which represents a concrete javascript instance of this type. + */ + final static class Jsii$Proxy extends software.amazon.jsii.tests.calculator.PartiallyInitializedThisConsumer { + protected Jsii$Proxy(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + + @Override + public java.lang.String consumePartiallyInitializedThis(final software.amazon.jsii.tests.calculator.ConstructorPassesThisOut obj, final java.time.Instant dt, final software.amazon.jsii.tests.calculator.AllTypesEnum ev) { + return this.jsiiCall("consumePartiallyInitializedThis", java.lang.String.class, java.util.stream.Stream.concat(java.util.stream.Stream.concat(java.util.stream.Stream.of(java.util.Objects.requireNonNull(obj, "obj is required")), java.util.stream.Stream.of(java.util.Objects.requireNonNull(dt, "dt is required"))), java.util.stream.Stream.of(java.util.Objects.requireNonNull(ev, "ev is required"))).toArray()); + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnaryOperation.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnaryOperation.java index 546cec81e7..2ffb511e1e 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnaryOperation.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnaryOperation.java @@ -9,6 +9,10 @@ public abstract class UnaryOperation extends software.amazon.jsii.tests.calculat protected UnaryOperation(final software.amazon.jsii.JsiiObject.InitializationMode mode) { super(mode); } + public UnaryOperation(final software.amazon.jsii.tests.calculator.lib.Value operand) { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this, java.util.stream.Stream.of(java.util.Objects.requireNonNull(operand, "operand is required")).toArray()); + } public software.amazon.jsii.tests.calculator.lib.Value getOperand() { return this.jsiiGet("operand", software.amazon.jsii.tests.calculator.lib.Value.class); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnionProperties.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnionProperties.java index ff141b54da..03d9389fc2 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnionProperties.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnionProperties.java @@ -88,7 +88,7 @@ public java.lang.Object getFoo() { } public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { - software.amazon.jsii.JsiiObjectMapper om = software.amazon.jsii.JsiiObjectMapper.instance; + com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); obj.set("bar", om.valueToTree(this.getBar())); obj.set("foo", om.valueToTree(this.getFoo())); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/composition/CompositeOperation.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/composition/CompositeOperation.java index 95d5a79bc7..c85dbb5b21 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/composition/CompositeOperation.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/composition/CompositeOperation.java @@ -9,6 +9,10 @@ public abstract class CompositeOperation extends software.amazon.jsii.tests.calc protected CompositeOperation(final software.amazon.jsii.JsiiObject.InitializationMode mode) { super(mode); } + public CompositeOperation() { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this); + } /** * String representation of the value. diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/python/setup.py b/packages/jsii-pacmak/test/expected.jsii-calc/python/setup.py index 0372a8337b..cc6eee5749 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/python/setup.py +++ b/packages/jsii-pacmak/test/expected.jsii-calc/python/setup.py @@ -32,6 +32,7 @@ "jsii", "publication>=0.0.3", "scope.jsii-calc-base~=0.8.0", + "scope.jsii-calc-base-of-base~=0.8.0", "scope.jsii-calc-lib~=0.8.0" ] } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/__init__.py b/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/__init__.py index 3db9cadad7..8b9b0c3b50 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/__init__.py +++ b/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/__init__.py @@ -10,6 +10,7 @@ from jsii.python import classproperty import scope.jsii_calc_base +import scope.jsii_calc_base_of_base import scope.jsii_calc_lib __jsii_assembly__ = jsii.JSIIAssembly.load("jsii-calc", "0.8.0", __name__, "jsii-calc@0.8.0.jsii.tgz") class AbstractClassBase(metaclass=jsii.JSIIAbstractClass, jsii_type="jsii-calc.AbstractClassBase"): @@ -365,6 +366,11 @@ def mutable_object(self, value: "IMutableObjectLiteral"): return jsii.set(self, "mutableObject", value) +class ConstructorPassesThisOut(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.ConstructorPassesThisOut"): + def __init__(self, consumer: "PartiallyInitializedThisConsumer") -> None: + jsii.create(ConstructorPassesThisOut, self, [consumer]) + + class Constructors(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.Constructors"): def __init__(self) -> None: jsii.create(Constructors, self, []) @@ -1643,6 +1649,26 @@ def test(self, obj: "IReturnsNumber") -> jsii.Number: return jsii.invoke(self, "test", [obj]) +class PartiallyInitializedThisConsumer(metaclass=jsii.JSIIAbstractClass, jsii_type="jsii-calc.PartiallyInitializedThisConsumer"): + @staticmethod + def __jsii_proxy_class__(): + return _PartiallyInitializedThisConsumerProxy + + def __init__(self) -> None: + jsii.create(PartiallyInitializedThisConsumer, self, []) + + @jsii.member(jsii_name="consumePartiallyInitializedThis") + @abc.abstractmethod + def consume_partially_initialized_this(self, obj: "ConstructorPassesThisOut", dt: datetime.datetime, ev: "AllTypesEnum") -> str: + ... + + +class _PartiallyInitializedThisConsumerProxy(PartiallyInitializedThisConsumer): + @jsii.member(jsii_name="consumePartiallyInitializedThis") + def consume_partially_initialized_this(self, obj: "ConstructorPassesThisOut", dt: datetime.datetime, ev: "AllTypesEnum") -> str: + return jsii.invoke(self, "consumePartiallyInitializedThis", [obj, dt, ev]) + + class Polymorphism(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.Polymorphism"): def __init__(self) -> None: jsii.create(Polymorphism, self, []) @@ -2351,6 +2377,6 @@ def parts(self, value: typing.List[scope.jsii_calc_lib.Value]): return jsii.set(self, "parts", value) -__all__ = ["AbstractClass", "AbstractClassBase", "AbstractClassReturner", "Add", "AllTypes", "AllTypesEnum", "AllowedMethodNames", "AsyncVirtualMethods", "AugmentableClass", "BinaryOperation", "Calculator", "CalculatorProps", "ClassThatImplementsTheInternalInterface", "ClassThatImplementsThePrivateInterface", "ClassWithMutableObjectLiteralProperty", "ClassWithPrivateConstructorAndAutomaticProperties", "Constructors", "ConsumersOfThisCrazyTypeSystem", "DefaultedConstructorArgument", "DerivedClassHasNoProperties", "DerivedStruct", "DoNotOverridePrivates", "DoNotRecognizeAnyAsOptional", "DontComplainAboutVariadicAfterOptional", "DoubleTrouble", "EraseUndefinedHashValues", "EraseUndefinedHashValuesOptions", "ExportedBaseClass", "ExtendsInternalInterface", "ExtendsPrivateInterface", "GiveMeStructs", "GreetingAugmenter", "IAnotherPublicInterface", "IFriendlier", "IFriendlyRandomGenerator", "IInterfaceThatShouldNotBeADataType", "IInterfaceWithInternal", "IInterfaceWithMethods", "IInterfaceWithOptionalMethodArguments", "IInterfaceWithProperties", "IInterfaceWithPropertiesExtension", "IMutableObjectLiteral", "INonInternalInterface", "IPrivatelyImplemented", "IPublicInterface", "IPublicInterface2", "IRandomNumberGenerator", "IReturnsNumber", "ImplementInternalInterface", "ImplementsInterfaceWithInternal", "ImplementsInterfaceWithInternalSubclass", "ImplementsPrivateInterface", "ImplictBaseOfBase", "InbetweenClass", "InterfaceImplementedByAbstractClass", "InterfaceInNamespaceIncludesClasses", "InterfaceInNamespaceOnlyInterface", "JSObjectLiteralForInterface", "JSObjectLiteralToNative", "JSObjectLiteralToNativeClass", "JavaReservedWords", "JsiiAgent", "LoadBalancedFargateServiceProps", "Multiply", "Negate", "NodeStandardLibrary", "NullShouldBeTreatedAsUndefined", "NullShouldBeTreatedAsUndefinedData", "NumberGenerator", "ObjectRefsInCollections", "OptionalConstructorArgument", "OverrideReturnsObject", "Polymorphism", "Power", "PublicClass", "PythonReservedWords", "ReferenceEnumFromScopedPackage", "ReturnsPrivateImplementationOfInterface", "RuntimeTypeChecking", "SingleInstanceTwoTypes", "Statics", "StringEnum", "StripInternal", "Sum", "SyncVirtualMethods", "Thrower", "UnaryOperation", "UnionProperties", "UseBundledDependency", "UseCalcBase", "UsesInterfaceWithProperties", "VariadicMethod", "VirtualMethodPlayground", "__jsii_assembly__", "composition"] +__all__ = ["AbstractClass", "AbstractClassBase", "AbstractClassReturner", "Add", "AllTypes", "AllTypesEnum", "AllowedMethodNames", "AsyncVirtualMethods", "AugmentableClass", "BinaryOperation", "Calculator", "CalculatorProps", "ClassThatImplementsTheInternalInterface", "ClassThatImplementsThePrivateInterface", "ClassWithMutableObjectLiteralProperty", "ClassWithPrivateConstructorAndAutomaticProperties", "ConstructorPassesThisOut", "Constructors", "ConsumersOfThisCrazyTypeSystem", "DefaultedConstructorArgument", "DerivedClassHasNoProperties", "DerivedStruct", "DoNotOverridePrivates", "DoNotRecognizeAnyAsOptional", "DontComplainAboutVariadicAfterOptional", "DoubleTrouble", "EraseUndefinedHashValues", "EraseUndefinedHashValuesOptions", "ExportedBaseClass", "ExtendsInternalInterface", "ExtendsPrivateInterface", "GiveMeStructs", "GreetingAugmenter", "IAnotherPublicInterface", "IFriendlier", "IFriendlyRandomGenerator", "IInterfaceThatShouldNotBeADataType", "IInterfaceWithInternal", "IInterfaceWithMethods", "IInterfaceWithOptionalMethodArguments", "IInterfaceWithProperties", "IInterfaceWithPropertiesExtension", "IMutableObjectLiteral", "INonInternalInterface", "IPrivatelyImplemented", "IPublicInterface", "IPublicInterface2", "IRandomNumberGenerator", "IReturnsNumber", "ImplementInternalInterface", "ImplementsInterfaceWithInternal", "ImplementsInterfaceWithInternalSubclass", "ImplementsPrivateInterface", "ImplictBaseOfBase", "InbetweenClass", "InterfaceImplementedByAbstractClass", "InterfaceInNamespaceIncludesClasses", "InterfaceInNamespaceOnlyInterface", "JSObjectLiteralForInterface", "JSObjectLiteralToNative", "JSObjectLiteralToNativeClass", "JavaReservedWords", "JsiiAgent", "LoadBalancedFargateServiceProps", "Multiply", "Negate", "NodeStandardLibrary", "NullShouldBeTreatedAsUndefined", "NullShouldBeTreatedAsUndefinedData", "NumberGenerator", "ObjectRefsInCollections", "OptionalConstructorArgument", "OverrideReturnsObject", "PartiallyInitializedThisConsumer", "Polymorphism", "Power", "PublicClass", "PythonReservedWords", "ReferenceEnumFromScopedPackage", "ReturnsPrivateImplementationOfInterface", "RuntimeTypeChecking", "SingleInstanceTwoTypes", "Statics", "StringEnum", "StripInternal", "Sum", "SyncVirtualMethods", "Thrower", "UnaryOperation", "UnionProperties", "UseBundledDependency", "UseCalcBase", "UsesInterfaceWithProperties", "VariadicMethod", "VirtualMethodPlayground", "__jsii_assembly__", "composition"] publication.publish() diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/_jsii/__init__.py b/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/_jsii/__init__.py index 90f4bfb6dc..565b8a9c38 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/_jsii/__init__.py +++ b/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/_jsii/__init__.py @@ -10,6 +10,7 @@ from jsii.python import classproperty import scope.jsii_calc_base +import scope.jsii_calc_base_of_base import scope.jsii_calc_lib __all__ = [] diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/sphinx/jsii-calc.rst b/packages/jsii-pacmak/test/expected.jsii-calc/sphinx/jsii-calc.rst index a88becce56..004982f54a 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/sphinx/jsii-calc.rst +++ b/packages/jsii-pacmak/test/expected.jsii-calc/sphinx/jsii-calc.rst @@ -1258,6 +1258,36 @@ ClassWithPrivateConstructorAndAutomaticProperties :type: string +ConstructorPassesThisOut +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. py:class:: ConstructorPassesThisOut(consumer) + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.ConstructorPassesThisOut; + + .. code-tab:: javascript + + const { ConstructorPassesThisOut } = require('jsii-calc'); + + .. code-tab:: typescript + + import { ConstructorPassesThisOut } from 'jsii-calc'; + + + + :param consumer: + :type consumer: :py:class:`~jsii-calc.PartiallyInitializedThisConsumer`\ + Constructors ^^^^^^^^^^^^ @@ -4253,6 +4283,47 @@ OverrideReturnsObject :rtype: number +PartiallyInitializedThisConsumer +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. py:class:: PartiallyInitializedThisConsumer() + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.PartiallyInitializedThisConsumer; + + .. code-tab:: javascript + + const { PartiallyInitializedThisConsumer } = require('jsii-calc'); + + .. code-tab:: typescript + + import { PartiallyInitializedThisConsumer } from 'jsii-calc'; + + + + :abstract: Yes + + .. py:method:: consumePartiallyInitializedThis(obj, dt, ev) -> string + + :param obj: + :type obj: :py:class:`~jsii-calc.ConstructorPassesThisOut`\ + :param dt: + :type dt: date + :param ev: + :type ev: :py:class:`~jsii-calc.AllTypesEnum`\ + :rtype: string + :abstract: Yes + + Polymorphism ^^^^^^^^^^^^ diff --git a/packages/jsii-python-runtime/.gitignore b/packages/jsii-python-runtime/.gitignore index f340dffb9a..3696b9726d 100644 --- a/packages/jsii-python-runtime/.gitignore +++ b/packages/jsii-python-runtime/.gitignore @@ -10,5 +10,6 @@ dist/ __pycache__ .mypy_cache +.pytest_cache README.md diff --git a/packages/jsii-python-runtime/tests/test_compliance.py b/packages/jsii-python-runtime/tests/test_compliance.py index e1ca7ab010..96bd1b2d71 100644 --- a/packages/jsii-python-runtime/tests/test_compliance.py +++ b/packages/jsii-python-runtime/tests/test_compliance.py @@ -13,6 +13,7 @@ AsyncVirtualMethods, Calculator, ClassWithPrivateConstructorAndAutomaticProperties, + ConstructorPassesThisOut, DoNotOverridePrivates, DoubleTrouble, GreetingAugmenter, @@ -28,6 +29,7 @@ NodeStandardLibrary, NullShouldBeTreatedAsUndefined, NumberGenerator, + PartiallyInitializedThisConsumer, Polymorphism, Power, PythonReservedWords, @@ -895,3 +897,14 @@ def test_eraseUnsetDataValues(): } assert EraseUndefinedHashValues.does_key_exist(opts, "option1") assert not EraseUndefinedHashValues.does_key_exist(opts, "option2") + + +@xfail_callbacks +def test_objectIdDoesNotGetReallocatedWhenTheConstructorPassesThisOut(): + class PartiallyInitializedThisConsumerImpl(PartiallyInitializedThisConsumer): + def consume_partially_initialized_this(self): + return "OK" + + reflector = PartiallyInitializedThisConsumerImpl() + obj = ConstructorPassesThisOut(reflector) + assert obj is not None diff --git a/packages/jsii-reflect/test/classes.expected.txt b/packages/jsii-reflect/test/classes.expected.txt index e29d7390be..192c5f05ac 100644 --- a/packages/jsii-reflect/test/classes.expected.txt +++ b/packages/jsii-reflect/test/classes.expected.txt @@ -15,6 +15,7 @@ ClassThatImplementsThePrivateInterface ClassWithMutableObjectLiteralProperty ClassWithPrivateConstructorAndAutomaticProperties CompositeOperation +ConstructorPassesThisOut Constructors ConsumersOfThisCrazyTypeSystem DefaultedConstructorArgument @@ -48,6 +49,7 @@ ObjectRefsInCollections Operation OptionalConstructorArgument OverrideReturnsObject +PartiallyInitializedThisConsumer Polymorphism Power PublicClass diff --git a/packages/jsii-reflect/test/jsii-tree.test.all.expected.txt b/packages/jsii-reflect/test/jsii-tree.test.all.expected.txt index fc41e4bedc..bcc7c81eec 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.all.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.all.expected.txt @@ -2,6 +2,7 @@ assemblies ├─┬ jsii-calc │ ├─┬ dependencies │ │ ├── @scope/jsii-calc-base + │ │ ├── @scope/jsii-calc-base-of-base │ │ └── @scope/jsii-calc-lib │ └─┬ types │ ├─┬ class AbstractClass @@ -278,6 +279,13 @@ assemblies │ │ │ └── type: primitive:string │ │ └─┬ readWriteString property │ │ └── type: primitive:string + │ ├─┬ class ConstructorPassesThisOut + │ │ └─┬ members + │ │ └─┬ (consumer) method + │ │ ├─┬ parameters + │ │ │ └─┬ consumer + │ │ │ └── type: class:jsii-calc.PartiallyInitializedThisConsumer + │ │ └── returns: void │ ├─┬ class Constructors │ │ └─┬ members │ │ ├─┬ () method @@ -770,6 +778,20 @@ assemblies │ │ │ └─┬ obj │ │ │ └── type: interface:jsii-calc.IReturnsNumber │ │ └── returns: primitive:number + │ ├─┬ class PartiallyInitializedThisConsumer + │ │ └─┬ members + │ │ ├─┬ () method + │ │ │ └── returns: void + │ │ └─┬ consumePartiallyInitializedThis(obj,dt,ev) method + │ │ ├── abstract + │ │ ├─┬ parameters + │ │ │ ├─┬ obj + │ │ │ │ └── type: class:jsii-calc.ConstructorPassesThisOut + │ │ │ ├─┬ dt + │ │ │ │ └── type: primitive:date + │ │ │ └─┬ ev + │ │ │ └── type: enum:jsii-calc.AllTypesEnum + │ │ └── returns: primitive:string │ ├─┬ class Polymorphism │ │ └─┬ members │ │ ├─┬ () method diff --git a/packages/jsii-reflect/test/jsii-tree.test.inheritance.expected.txt b/packages/jsii-reflect/test/jsii-tree.test.inheritance.expected.txt index f0bda4dddb..40abaf6846 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.inheritance.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.inheritance.expected.txt @@ -24,6 +24,7 @@ assemblies │ ├── class ClassWithMutableObjectLiteralProperty │ ├─┬ class ClassWithPrivateConstructorAndAutomaticProperties │ │ └── interfaces: IInterfaceWithProperties + │ ├── class ConstructorPassesThisOut │ ├── class Constructors │ ├── class ConsumersOfThisCrazyTypeSystem │ ├── class DefaultedConstructorArgument @@ -66,6 +67,7 @@ assemblies │ ├── class ObjectRefsInCollections │ ├── class OptionalConstructorArgument │ ├── class OverrideReturnsObject + │ ├── class PartiallyInitializedThisConsumer │ ├── class Polymorphism │ ├─┬ class Power │ │ └── base: CompositeOperation diff --git a/packages/jsii-reflect/test/jsii-tree.test.members.expected.txt b/packages/jsii-reflect/test/jsii-tree.test.members.expected.txt index 23a8d2c2de..393039e798 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.members.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.members.expected.txt @@ -111,6 +111,9 @@ assemblies │ │ ├── create(readOnlyString,readWriteString) method │ │ ├── readOnlyString property │ │ └── readWriteString property + │ ├─┬ class ConstructorPassesThisOut + │ │ └─┬ members + │ │ └── (consumer) method │ ├─┬ class Constructors │ │ └─┬ members │ │ ├── () method @@ -327,6 +330,10 @@ assemblies │ │ └─┬ members │ │ ├── () method │ │ └── test(obj) method + │ ├─┬ class PartiallyInitializedThisConsumer + │ │ └─┬ members + │ │ ├── () method + │ │ └── consumePartiallyInitializedThis(obj,dt,ev) method │ ├─┬ class Polymorphism │ │ └─┬ members │ │ ├── () method diff --git a/packages/jsii-reflect/test/jsii-tree.test.types.expected.txt b/packages/jsii-reflect/test/jsii-tree.test.types.expected.txt index da05887ea3..d5e5609b4c 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.types.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.types.expected.txt @@ -15,6 +15,7 @@ assemblies │ ├── class ClassThatImplementsThePrivateInterface │ ├── class ClassWithMutableObjectLiteralProperty │ ├── class ClassWithPrivateConstructorAndAutomaticProperties + │ ├── class ConstructorPassesThisOut │ ├── class Constructors │ ├── class ConsumersOfThisCrazyTypeSystem │ ├── class DefaultedConstructorArgument @@ -47,6 +48,7 @@ assemblies │ ├── class ObjectRefsInCollections │ ├── class OptionalConstructorArgument │ ├── class OverrideReturnsObject + │ ├── class PartiallyInitializedThisConsumer │ ├── class Polymorphism │ ├── class Power │ ├── class PublicClass