diff --git a/packages/jsii-calc/lib/compliance.ts b/packages/jsii-calc/lib/compliance.ts index 07570c64c9..66e1342e29 100644 --- a/packages/jsii-calc/lib/compliance.ts +++ b/packages/jsii-calc/lib/compliance.ts @@ -2331,3 +2331,16 @@ export class ObjectWithPropertyProvider { private constructor() { } } + +/** + * Make sure structs are un-decorated on the way in. + * + * @see https://github.com/aws/aws-cdk/issues/5066 + */ +export class JsonFormatter { + public static stringify(value: any): string { + return JSON.stringify(value, null, 2); + } + + private constructor() { } +} diff --git a/packages/jsii-calc/test/assembly.jsii b/packages/jsii-calc/test/assembly.jsii index 7634c11c48..50fa95a0f7 100644 --- a/packages/jsii-calc/test/assembly.jsii +++ b/packages/jsii-calc/test/assembly.jsii @@ -6826,6 +6826,47 @@ } ] }, + "jsii-calc.JsonFormatter": { + "assembly": "jsii-calc", + "docs": { + "see": "https://github.com/aws/aws-cdk/issues/5066", + "stability": "experimental", + "summary": "Make sure structs are un-decorated on the way in." + }, + "fqn": "jsii-calc.JsonFormatter", + "kind": "class", + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2340 + }, + "methods": [ + { + "docs": { + "stability": "experimental" + }, + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2341 + }, + "name": "stringify", + "parameters": [ + { + "name": "value", + "type": { + "primitive": "any" + } + } + ], + "returns": { + "type": { + "primitive": "string" + } + }, + "static": true + } + ], + "name": "JsonFormatter" + }, "jsii-calc.LoadBalancedFargateServiceProps": { "assembly": "jsii-calc", "datatype": true, @@ -11413,5 +11454,5 @@ } }, "version": "0.20.6", - "fingerprint": "veHd1Q/376CoMR3O/DjjAiH9aVD/jcwnPEg88barg9I=" + "fingerprint": "xXC7/htdFP0Ns+aNf856G/K6PBPRJjPlsg5KtO3bEXY=" } 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 87804c0cae..16ba9abbfd 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 @@ -1297,5 +1297,18 @@ public void CanUseInterfaceSetters() obj.Property = "New Value"; Assert.True(obj.WasSet()); } + + [Fact(DisplayName = Prefix + nameof(StructsAreUndecoratedOntheWayToKernel))] + public void StructsAreUndecoratedOntheWayToKernel() + { + var json = JsonFormatter.Stringify(new StructB {RequiredString = "Bazinga!", OptionalBoolean = false}); + var actual = JObject.Parse(json); + + var expected = new JObject(); + expected.Add("RequiredString", "Bazinga!"); + expected.Add("OptionalBoolean", false); + + Assert.Equal(expected, actual); + } } } diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiByValueAttribute.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiByValueAttribute.cs index a9e578588b..832bcf4d97 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiByValueAttribute.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiByValueAttribute.cs @@ -7,9 +7,9 @@ public sealed class JsiiByValueAttribute : Attribute { public JsiiByValueAttribute(string fqn) { - Fqn = fqn ?? throw new ArgumentNullException(nameof(fqn)); + FullyQualifiedName = fqn ?? throw new ArgumentNullException(nameof(fqn)); } - public string Fqn { get; } + public string FullyQualifiedName { get; } } } \ No newline at end of file diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/FrameworkToJsiiConverter.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/FrameworkToJsiiConverter.cs index be9edb0b7e..e0a53e60f6 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/FrameworkToJsiiConverter.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/FrameworkToJsiiConverter.cs @@ -72,7 +72,7 @@ protected override bool TryConvertClass(Type type, IReferenceMap referenceMap, o } var structInfo = new JObject(); - structInfo.Add(new JProperty("fqn", byValueAttribute.Fqn)); + structInfo.Add(new JProperty("fqn", byValueAttribute.FullyQualifiedName)); structInfo.Add(new JProperty("data", data)); var resultObject = new JObject(); @@ -353,6 +353,12 @@ TypeReference InferType(IReferenceMap referenceMap, Type type) return new TypeReference(enumAttribute.FullyQualifiedName); } + JsiiByValueAttribute structAttribute = type.GetCustomAttribute(); + if (structAttribute != null) + { + return new TypeReference(structAttribute.FullyQualifiedName); + } + if (typeof(string).IsAssignableFrom(type)) { return new TypeReference(primitive: PrimitiveType.String); 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 ae27f1608d..f8e9c9b9da 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 @@ -1,5 +1,6 @@ package software.amazon.jsii.testing; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Test; @@ -1580,4 +1581,17 @@ public void canUseInterfaceSetters() { obj.setProperty("New Value"); assertTrue(obj.wasSet()); } + + @Test + public void structsAreUndecoratedOntheWayToKernel() throws IOException { + final ObjectMapper om = new ObjectMapper(); + final String json = JsonFormatter.stringify(StructB.builder().requiredString("Bazinga!").optionalBoolean(false).build()); + final JsonNode actual = om.readTree(json); + + final ObjectNode expected = om.createObjectNode(); + expected.put("requiredString", "Bazinga!"); + expected.put("optionalBoolean", Boolean.FALSE); + + assertEquals(expected, actual); + } } diff --git a/packages/jsii-kernel/lib/serialization.ts b/packages/jsii-kernel/lib/serialization.ts index 4961b1cb8d..ecddda6c5e 100644 --- a/packages/jsii-kernel/lib/serialization.ts +++ b/packages/jsii-kernel/lib/serialization.ts @@ -27,7 +27,7 @@ */ import * as spec from 'jsii-spec'; -import { isObjRef, isWireDate, isWireEnum, isWireMap, ObjRef, TOKEN_DATE, TOKEN_ENUM, TOKEN_MAP, WireDate, WireEnum } from './api'; +import { isObjRef, isWireDate, isWireEnum, isWireMap, ObjRef, TOKEN_DATE, TOKEN_ENUM, TOKEN_MAP, WireDate, WireEnum, isWireStruct, TOKEN_STRUCT } from './api'; import { jsiiTypeFqn, objectReference, ObjectTable } from './objects'; import { api } from '.'; @@ -520,6 +520,15 @@ export const SERIALIZERS: {[k: string]: Serializer} = { host.debug('ANY is a Ref'); return host.objects.findObject(value).instance; } + + // if the value has a struct token, it was serialized by a typed jsii + // struct, but since the deserialization target is ANY, all we can do is + // strip the data from $jsii.struct and continue to deserialize as ANY. + if (isWireStruct(value)) { + const { fqn, data } = value[TOKEN_STRUCT]; + host.debug(`ANY is a struct of type ${fqn}`); + return SERIALIZERS[SerializationClass.Any].deserialize(data, _type, host); + } // At this point again, deserialize by-value. host.debug('ANY is a Map'); diff --git a/packages/jsii-kernel/test/kernel.test.ts b/packages/jsii-kernel/test/kernel.test.ts index 475f8962ee..1743935724 100644 --- a/packages/jsii-kernel/test/kernel.test.ts +++ b/packages/jsii-kernel/test/kernel.test.ts @@ -1218,6 +1218,13 @@ defineTest('correctly deserializes struct unions', (sandbox) => { } }); +defineTest('structs are undecorated on the way to kernel', sandbox => { + const input = { '$jsii.struct': { 'fqn': 'jsii-calc.StructB', 'data': { 'requiredString': 'Bazinga!', 'optionalBoolean': false } } }; + const ret = sandbox.sinvoke({ fqn: 'jsii-calc.JsonFormatter', method: 'stringify', args: [input] }); + const json = JSON.parse(ret.result); + expect(json).toStrictEqual({ 'requiredString': 'Bazinga!', 'optionalBoolean': false }); +}); + // ================================================================================================= const testNames: { [name: string]: boolean } = { }; 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 7634c11c48..50fa95a0f7 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 @@ -6826,6 +6826,47 @@ } ] }, + "jsii-calc.JsonFormatter": { + "assembly": "jsii-calc", + "docs": { + "see": "https://github.com/aws/aws-cdk/issues/5066", + "stability": "experimental", + "summary": "Make sure structs are un-decorated on the way in." + }, + "fqn": "jsii-calc.JsonFormatter", + "kind": "class", + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2340 + }, + "methods": [ + { + "docs": { + "stability": "experimental" + }, + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2341 + }, + "name": "stringify", + "parameters": [ + { + "name": "value", + "type": { + "primitive": "any" + } + } + ], + "returns": { + "type": { + "primitive": "string" + } + }, + "static": true + } + ], + "name": "JsonFormatter" + }, "jsii-calc.LoadBalancedFargateServiceProps": { "assembly": "jsii-calc", "datatype": true, @@ -11413,5 +11454,5 @@ } }, "version": "0.20.6", - "fingerprint": "veHd1Q/376CoMR3O/DjjAiH9aVD/jcwnPEg88barg9I=" + "fingerprint": "xXC7/htdFP0Ns+aNf856G/K6PBPRJjPlsg5KtO3bEXY=" } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/JsonFormatter.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/JsonFormatter.cs new file mode 100644 index 0000000000..7846fed16e --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/JsonFormatter.cs @@ -0,0 +1,31 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// Make sure structs are un-decorated on the way in. + /// + /// stability: Experimental + /// see: + /// https://github.com/aws/aws-cdk/issues/5066 + /// + [JsiiClass(nativeType: typeof(Amazon.JSII.Tests.CalculatorNamespace.JsonFormatter), fullyQualifiedName: "jsii-calc.JsonFormatter")] + public class JsonFormatter : DeputyBase + { + protected JsonFormatter(ByRefValue reference): base(reference) + { + } + + protected JsonFormatter(DeputyProps props): base(props) + { + } + + /// + /// stability: Experimental + /// + [JsiiMethod(name: "stringify", returnsJson: "{\"type\":{\"primitive\":\"string\"}}", parametersJson: "[{\"name\":\"value\",\"type\":{\"primitive\":\"any\"}}]")] + public static string Stringify(object @value) + { + return InvokeStaticMethod(typeof(Amazon.JSII.Tests.CalculatorNamespace.JsonFormatter), new System.Type[]{typeof(object)}, new object[]{@value}); + } + } +} 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 3b14e94eaf..8df477385f 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 @@ -130,6 +130,7 @@ protected Class resolveClass(final String fqn) throws ClassNotFoundException case "jsii-calc.Jsii487Derived": return software.amazon.jsii.tests.calculator.Jsii487Derived.class; case "jsii-calc.Jsii496Derived": return software.amazon.jsii.tests.calculator.Jsii496Derived.class; case "jsii-calc.JsiiAgent": return software.amazon.jsii.tests.calculator.JsiiAgent.class; + case "jsii-calc.JsonFormatter": return software.amazon.jsii.tests.calculator.JsonFormatter.class; case "jsii-calc.LoadBalancedFargateServiceProps": return software.amazon.jsii.tests.calculator.LoadBalancedFargateServiceProps.class; case "jsii-calc.Multiply": return software.amazon.jsii.tests.calculator.Multiply.class; case "jsii-calc.Negate": return software.amazon.jsii.tests.calculator.Negate.class; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/JsonFormatter.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/JsonFormatter.java new file mode 100644 index 0000000000..e802833537 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/JsonFormatter.java @@ -0,0 +1,32 @@ +package software.amazon.jsii.tests.calculator; + +/** + * Make sure structs are un-decorated on the way in. + * + * EXPERIMENTAL + * + * @see https://github.com/aws/aws-cdk/issues/5066 + */ +@javax.annotation.Generated(value = "jsii-pacmak") +@software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) +@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.JsonFormatter") +public class JsonFormatter extends software.amazon.jsii.JsiiObject { + + protected JsonFormatter(final software.amazon.jsii.JsiiObjectRef objRef) { + super(objRef); + } + + protected JsonFormatter(final software.amazon.jsii.JsiiObject.InitializationMode initializationMode) { + super(initializationMode); + } + + /** + * EXPERIMENTAL + * + * @param value This parameter is required. + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + public static java.lang.String stringify(final java.lang.Object value) { + return software.amazon.jsii.JsiiObject.jsiiStaticCall(software.amazon.jsii.tests.calculator.JsonFormatter.class, "stringify", java.lang.String.class, new Object[] { value }); + } +} 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 3359599cce..39b7fcf2d0 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 @@ -4950,6 +4950,26 @@ def jsii_agent(cls) -> typing.Optional[str]: return jsii.sget(cls, "jsiiAgent") +class JsonFormatter(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.JsonFormatter"): + """Make sure structs are un-decorated on the way in. + + see + :see: https://github.com/aws/aws-cdk/issues/5066 + stability + :stability: experimental + """ + @jsii.member(jsii_name="stringify") + @classmethod + def stringify(cls, value: typing.Any) -> str: + """ + :param value: - + + stability + :stability: experimental + """ + return jsii.sinvoke(cls, "stringify", [value]) + + @jsii.data_type(jsii_type="jsii-calc.LoadBalancedFargateServiceProps", jsii_struct_bases=[], name_mapping={'container_port': 'containerPort', 'cpu': 'cpu', 'memory_mib': 'memoryMiB', 'public_load_balancer': 'publicLoadBalancer', 'public_tasks': 'publicTasks'}) class LoadBalancedFargateServiceProps(): def __init__(self, *, container_port: typing.Optional[jsii.Number]=None, cpu: typing.Optional[str]=None, memory_mib: typing.Optional[str]=None, public_load_balancer: typing.Optional[bool]=None, public_tasks: typing.Optional[bool]=None): @@ -8025,6 +8045,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", "AnonymousImplementationProvider", "AsyncVirtualMethods", "AugmentableClass", "BaseJsii976", "Bell", "BinaryOperation", "Calculator", "CalculatorProps", "ChildStruct982", "ClassThatImplementsTheInternalInterface", "ClassThatImplementsThePrivateInterface", "ClassWithCollections", "ClassWithDocs", "ClassWithJavaReservedWords", "ClassWithMutableObjectLiteralProperty", "ClassWithPrivateConstructorAndAutomaticProperties", "ConfusingToJackson", "ConfusingToJacksonStruct", "ConstructorPassesThisOut", "Constructors", "ConsumerCanRingBell", "ConsumersOfThisCrazyTypeSystem", "DataRenderer", "DefaultedConstructorArgument", "Demonstrate982", "DeprecatedClass", "DeprecatedEnum", "DeprecatedStruct", "DerivedClassHasNoProperties", "DerivedStruct", "DiamondInheritanceBaseLevelStruct", "DiamondInheritanceFirstMidLevelStruct", "DiamondInheritanceSecondMidLevelStruct", "DiamondInheritanceTopLevelStruct", "DisappointingCollectionSource", "DoNotOverridePrivates", "DoNotRecognizeAnyAsOptional", "DocumentedClass", "DontComplainAboutVariadicAfterOptional", "DoubleTrouble", "EnumDispenser", "EraseUndefinedHashValues", "EraseUndefinedHashValuesOptions", "ExperimentalClass", "ExperimentalEnum", "ExperimentalStruct", "ExportedBaseClass", "ExtendsInternalInterface", "GiveMeStructs", "Greetee", "GreetingAugmenter", "IAnonymousImplementationProvider", "IAnonymouslyImplementMe", "IAnotherPublicInterface", "IBell", "IBellRinger", "IConcreteBellRinger", "IDeprecatedInterface", "IExperimentalInterface", "IExtendsPrivateInterface", "IFriendlier", "IFriendlyRandomGenerator", "IInterfaceImplementedByAbstractClass", "IInterfaceThatShouldNotBeADataType", "IInterfaceWithInternal", "IInterfaceWithMethods", "IInterfaceWithOptionalMethodArguments", "IInterfaceWithProperties", "IInterfaceWithPropertiesExtension", "IJSII417Derived", "IJSII417PublicBaseOfBase", "IJsii487External", "IJsii487External2", "IJsii496", "IMutableObjectLiteral", "INonInternalInterface", "IObjectWithProperty", "IPrivatelyImplemented", "IPublicInterface", "IPublicInterface2", "IRandomNumberGenerator", "IReturnJsii976", "IReturnsNumber", "IStableInterface", "ImplementInternalInterface", "Implementation", "ImplementsInterfaceWithInternal", "ImplementsInterfaceWithInternalSubclass", "ImplementsPrivateInterface", "ImplictBaseOfBase", "InbetweenClass", "InterfaceInNamespaceIncludesClasses", "InterfaceInNamespaceOnlyInterface", "InterfacesMaker", "JSII417Derived", "JSII417PublicBaseOfBase", "JSObjectLiteralForInterface", "JSObjectLiteralToNative", "JSObjectLiteralToNativeClass", "JavaReservedWords", "Jsii487Derived", "Jsii496Derived", "JsiiAgent", "LoadBalancedFargateServiceProps", "Multiply", "Negate", "NestedStruct", "NodeStandardLibrary", "NullShouldBeTreatedAsUndefined", "NullShouldBeTreatedAsUndefinedData", "NumberGenerator", "ObjectRefsInCollections", "ObjectWithPropertyProvider", "Old", "OptionalArgumentInvoker", "OptionalConstructorArgument", "OptionalStruct", "OptionalStructConsumer", "OverridableProtectedMember", "OverrideReturnsObject", "ParentStruct982", "PartiallyInitializedThisConsumer", "Polymorphism", "Power", "PublicClass", "PythonReservedWords", "ReferenceEnumFromScopedPackage", "ReturnsPrivateImplementationOfInterface", "RootStruct", "RootStructValidator", "RuntimeTypeChecking", "SecondLevelStruct", "SingleInstanceTwoTypes", "SingletonInt", "SingletonIntEnum", "SingletonString", "SingletonStringEnum", "SomeTypeJsii976", "StableClass", "StableEnum", "StableStruct", "StaticContext", "Statics", "StringEnum", "StripInternal", "StructA", "StructB", "StructPassing", "StructUnionConsumer", "StructWithJavaReservedWords", "Sum", "SupportsNiceJavaBuilder", "SupportsNiceJavaBuilderProps", "SupportsNiceJavaBuilderWithRequiredProps", "SyncVirtualMethods", "Thrower", "TopLevelStruct", "UnaryOperation", "UnionProperties", "UseBundledDependency", "UseCalcBase", "UsesInterfaceWithProperties", "VariadicInvoker", "VariadicMethod", "VirtualMethodPlayground", "VoidCallback", "WithPrivatePropertyInConstructor", "__jsii_assembly__", "composition"] +__all__ = ["AbstractClass", "AbstractClassBase", "AbstractClassReturner", "Add", "AllTypes", "AllTypesEnum", "AllowedMethodNames", "AnonymousImplementationProvider", "AsyncVirtualMethods", "AugmentableClass", "BaseJsii976", "Bell", "BinaryOperation", "Calculator", "CalculatorProps", "ChildStruct982", "ClassThatImplementsTheInternalInterface", "ClassThatImplementsThePrivateInterface", "ClassWithCollections", "ClassWithDocs", "ClassWithJavaReservedWords", "ClassWithMutableObjectLiteralProperty", "ClassWithPrivateConstructorAndAutomaticProperties", "ConfusingToJackson", "ConfusingToJacksonStruct", "ConstructorPassesThisOut", "Constructors", "ConsumerCanRingBell", "ConsumersOfThisCrazyTypeSystem", "DataRenderer", "DefaultedConstructorArgument", "Demonstrate982", "DeprecatedClass", "DeprecatedEnum", "DeprecatedStruct", "DerivedClassHasNoProperties", "DerivedStruct", "DiamondInheritanceBaseLevelStruct", "DiamondInheritanceFirstMidLevelStruct", "DiamondInheritanceSecondMidLevelStruct", "DiamondInheritanceTopLevelStruct", "DisappointingCollectionSource", "DoNotOverridePrivates", "DoNotRecognizeAnyAsOptional", "DocumentedClass", "DontComplainAboutVariadicAfterOptional", "DoubleTrouble", "EnumDispenser", "EraseUndefinedHashValues", "EraseUndefinedHashValuesOptions", "ExperimentalClass", "ExperimentalEnum", "ExperimentalStruct", "ExportedBaseClass", "ExtendsInternalInterface", "GiveMeStructs", "Greetee", "GreetingAugmenter", "IAnonymousImplementationProvider", "IAnonymouslyImplementMe", "IAnotherPublicInterface", "IBell", "IBellRinger", "IConcreteBellRinger", "IDeprecatedInterface", "IExperimentalInterface", "IExtendsPrivateInterface", "IFriendlier", "IFriendlyRandomGenerator", "IInterfaceImplementedByAbstractClass", "IInterfaceThatShouldNotBeADataType", "IInterfaceWithInternal", "IInterfaceWithMethods", "IInterfaceWithOptionalMethodArguments", "IInterfaceWithProperties", "IInterfaceWithPropertiesExtension", "IJSII417Derived", "IJSII417PublicBaseOfBase", "IJsii487External", "IJsii487External2", "IJsii496", "IMutableObjectLiteral", "INonInternalInterface", "IObjectWithProperty", "IPrivatelyImplemented", "IPublicInterface", "IPublicInterface2", "IRandomNumberGenerator", "IReturnJsii976", "IReturnsNumber", "IStableInterface", "ImplementInternalInterface", "Implementation", "ImplementsInterfaceWithInternal", "ImplementsInterfaceWithInternalSubclass", "ImplementsPrivateInterface", "ImplictBaseOfBase", "InbetweenClass", "InterfaceInNamespaceIncludesClasses", "InterfaceInNamespaceOnlyInterface", "InterfacesMaker", "JSII417Derived", "JSII417PublicBaseOfBase", "JSObjectLiteralForInterface", "JSObjectLiteralToNative", "JSObjectLiteralToNativeClass", "JavaReservedWords", "Jsii487Derived", "Jsii496Derived", "JsiiAgent", "JsonFormatter", "LoadBalancedFargateServiceProps", "Multiply", "Negate", "NestedStruct", "NodeStandardLibrary", "NullShouldBeTreatedAsUndefined", "NullShouldBeTreatedAsUndefinedData", "NumberGenerator", "ObjectRefsInCollections", "ObjectWithPropertyProvider", "Old", "OptionalArgumentInvoker", "OptionalConstructorArgument", "OptionalStruct", "OptionalStructConsumer", "OverridableProtectedMember", "OverrideReturnsObject", "ParentStruct982", "PartiallyInitializedThisConsumer", "Polymorphism", "Power", "PublicClass", "PythonReservedWords", "ReferenceEnumFromScopedPackage", "ReturnsPrivateImplementationOfInterface", "RootStruct", "RootStructValidator", "RuntimeTypeChecking", "SecondLevelStruct", "SingleInstanceTwoTypes", "SingletonInt", "SingletonIntEnum", "SingletonString", "SingletonStringEnum", "SomeTypeJsii976", "StableClass", "StableEnum", "StableStruct", "StaticContext", "Statics", "StringEnum", "StripInternal", "StructA", "StructB", "StructPassing", "StructUnionConsumer", "StructWithJavaReservedWords", "Sum", "SupportsNiceJavaBuilder", "SupportsNiceJavaBuilderProps", "SupportsNiceJavaBuilderWithRequiredProps", "SyncVirtualMethods", "Thrower", "TopLevelStruct", "UnaryOperation", "UnionProperties", "UseBundledDependency", "UseCalcBase", "UsesInterfaceWithProperties", "VariadicInvoker", "VariadicMethod", "VirtualMethodPlayground", "VoidCallback", "WithPrivatePropertyInConstructor", "__jsii_assembly__", "composition"] publication.publish() diff --git a/packages/jsii-python-runtime/tests/test_compliance.py b/packages/jsii-python-runtime/tests/test_compliance.py index 5bd455839f..ceacb3f777 100644 --- a/packages/jsii-python-runtime/tests/test_compliance.py +++ b/packages/jsii-python-runtime/tests/test_compliance.py @@ -6,6 +6,8 @@ import jsii +from json import loads + from jsii_calc import ( AbstractClassReturner, Add, @@ -32,6 +34,7 @@ JsiiAgent, JSObjectLiteralForInterface, JSObjectLiteralToNative, + JsonFormatter, Multiply, Negate, NodeStandardLibrary, @@ -1073,3 +1076,7 @@ def test_can_use_interface_setters(): obj = ObjectWithPropertyProvider.provide() obj.property = 'New Value' assert obj.was_set() + +def test_structs_are_undecorated_on_the_way_to_kernel(): + json = JsonFormatter.stringify(StructB(required_string='Bazinga!', optional_boolean=False)) + assert loads(json) == {'requiredString': 'Bazinga!', 'optionalBoolean': False} diff --git a/packages/jsii-reflect/test/__snapshots__/jsii-tree.test.js.snap b/packages/jsii-reflect/test/__snapshots__/jsii-tree.test.js.snap index 2979b10ac0..9051fa15d9 100644 --- a/packages/jsii-reflect/test/__snapshots__/jsii-tree.test.js.snap +++ b/packages/jsii-reflect/test/__snapshots__/jsii-tree.test.js.snap @@ -858,6 +858,14 @@ exports[`jsii-tree --all 1`] = ` │ │ ├── immutable │ │ ├── static │ │ └── type: Optional + │ ├─┬ class JsonFormatter (experimental) + │ │ └─┬ members + │ │ └─┬ static stringify(value) method (experimental) + │ │ ├── static + │ │ ├─┬ parameters + │ │ │ └─┬ value + │ │ │ └── type: any + │ │ └── returns: string │ ├─┬ class Multiply (experimental) │ │ ├── base: BinaryOperation │ │ ├── interfaces: IFriendlier,IRandomNumberGenerator @@ -2341,6 +2349,7 @@ exports[`jsii-tree --inheritance 1`] = ` │ ├─┬ class Jsii496Derived │ │ └── interfaces: IJsii496 │ ├── class JsiiAgent + │ ├── class JsonFormatter │ ├─┬ class Multiply │ │ ├── base: BinaryOperation │ │ └── interfaces: IFriendlier,IRandomNumberGenerator @@ -2917,6 +2926,9 @@ exports[`jsii-tree --members 1`] = ` │ │ └─┬ members │ │ ├── () initializer │ │ └── static jsiiAgent property + │ ├─┬ class JsonFormatter + │ │ └─┬ members + │ │ └── static stringify(value) method │ ├─┬ class Multiply │ │ └─┬ members │ │ ├── (lhs,rhs) initializer @@ -3597,6 +3609,7 @@ exports[`jsii-tree --types 1`] = ` │ ├── class Jsii487Derived │ ├── class Jsii496Derived │ ├── class JsiiAgent + │ ├── class JsonFormatter │ ├── class Multiply │ ├── class Negate │ ├── class NodeStandardLibrary diff --git a/packages/jsii-reflect/test/__snapshots__/type-system.test.js.snap b/packages/jsii-reflect/test/__snapshots__/type-system.test.js.snap index c2142fc3ea..4bd5eb80e2 100644 --- a/packages/jsii-reflect/test/__snapshots__/type-system.test.js.snap +++ b/packages/jsii-reflect/test/__snapshots__/type-system.test.js.snap @@ -73,6 +73,7 @@ Array [ "Jsii487Derived", "Jsii496Derived", "JsiiAgent", + "JsonFormatter", "Multiply", "Negate", "NodeStandardLibrary",