diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index 7d36001ddf..a2a98e7617 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -236,3 +236,9 @@ renamed to `with_retry_classifier` and `retry_classifier` respectively. Public m references = ["smithy-rs#1715", "smithy-rs#1717"] meta = { "breaking" = true, "tada" = false, "bug" = false } author = "jdisanti" + +[[smithy-rs]] +message = "Correctly determine nullability of members in IDLv2 models" +references = ["smithy-rs#1725"] +meta = { "breaking" = false, "tada" = false, "bug" = true, "target" = "all"} +author = "sugmanue" diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/ec2/EC2MakePrimitivesOptional.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/ec2/EC2MakePrimitivesOptional.kt new file mode 100644 index 0000000000..0554f860f4 --- /dev/null +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/ec2/EC2MakePrimitivesOptional.kt @@ -0,0 +1,23 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rustsdk.customize.ec2 + +import software.amazon.smithy.model.Model +import software.amazon.smithy.model.shapes.Shape +import software.amazon.smithy.model.traits.ClientOptionalTrait +import software.amazon.smithy.model.transform.ModelTransformer + +object EC2MakePrimitivesOptional { + fun processModel(model: Model): Model { + val updates = arrayListOf() + for (struct in model.structureShapes) { + for (member in struct.allMembers.values) { + updates.add(member.toBuilder().addTrait(ClientOptionalTrait()).build()) + } + } + return ModelTransformer.create().replaceShapes(model, updates) + } +} diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/ec2/Ec2Decorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/ec2/Ec2Decorator.kt index b1b5f91bb5..c9400a4190 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/ec2/Ec2Decorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/ec2/Ec2Decorator.kt @@ -26,7 +26,7 @@ class Ec2Decorator : RustCodegenDecorator { // need to be boxed for the API to work properly return model.letIf( applies(service), - BoxPrimitiveShapes::processModel, + EC2MakePrimitivesOptional::processModel, ) } diff --git a/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/customize/ec2/BoxPrimitiveShapesTest.kt b/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/customize/ec2/EC2MakePrimitivesOptionalTest.kt similarity index 69% rename from aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/customize/ec2/BoxPrimitiveShapesTest.kt rename to aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/customize/ec2/EC2MakePrimitivesOptionalTest.kt index 1677ea28d0..d7ec82737a 100644 --- a/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/customize/ec2/BoxPrimitiveShapesTest.kt +++ b/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/customize/ec2/EC2MakePrimitivesOptionalTest.kt @@ -7,13 +7,12 @@ package software.amazon.smithy.rustsdk.customize.ec2 import io.kotest.matchers.shouldBe import org.junit.jupiter.api.Test +import software.amazon.smithy.model.knowledge.NullableIndex import software.amazon.smithy.model.shapes.StructureShape -import software.amazon.smithy.model.traits.BoxTrait import software.amazon.smithy.rust.codegen.client.testutil.asSmithyModel -import software.amazon.smithy.rust.codegen.core.util.hasTrait import software.amazon.smithy.rust.codegen.core.util.lookup -internal class BoxPrimitiveShapesTest { +internal class EC2MakePrimitivesOptionalTest { @Test fun `primitive shapes are boxed`() { val baseModel = """ @@ -33,15 +32,11 @@ internal class BoxPrimitiveShapesTest { structure Other {} """.asSmithyModel() - val model = BoxPrimitiveShapes.processModel(baseModel) - + val model = EC2MakePrimitivesOptional.processModel(baseModel) + val nullableIndex = NullableIndex(model) val struct = model.lookup("test#Primitives") struct.members().forEach { - val target = model.expectShape(it.target) - when (target) { - is StructureShape -> target.hasTrait() shouldBe false - else -> target.hasTrait() shouldBe true - } + nullableIndex.isMemberNullable(it, NullableIndex.CheckMode.CLIENT_ZERO_VALUE_V1) shouldBe true } } } diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/CodegenVisitor.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/CodegenVisitor.kt index f160b3d4e1..87f1974fee 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/CodegenVisitor.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/CodegenVisitor.kt @@ -7,6 +7,7 @@ package software.amazon.smithy.rust.codegen.client.smithy import software.amazon.smithy.build.PluginContext import software.amazon.smithy.model.Model +import software.amazon.smithy.model.knowledge.NullableIndex import software.amazon.smithy.model.neighbor.Walker import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.shapes.Shape @@ -61,8 +62,8 @@ class CodegenVisitor(context: PluginContext, private val codegenDecorator: RustC SymbolVisitorConfig( runtimeConfig = settings.runtimeConfig, renameExceptions = settings.codegenConfig.renameExceptions, - handleRequired = false, handleRustBoxing = true, + nullabilityCheckMode = NullableIndex.CheckMode.CLIENT_ZERO_VALUE_V1, ) val baseModel = baselineTransform(context.model) val service = settings.getService(baseModel) diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/SymbolVisitor.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/SymbolVisitor.kt index e3087f1e21..7d749bf439 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/SymbolVisitor.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/SymbolVisitor.kt @@ -65,7 +65,7 @@ data class SymbolVisitorConfig( val runtimeConfig: RuntimeConfig, val renameExceptions: Boolean, val handleRustBoxing: Boolean, - val handleRequired: Boolean, + val nullabilityCheckMode: NullableIndex.CheckMode, ) /** @@ -210,13 +210,7 @@ open class SymbolVisitor( } private fun handleOptionality(symbol: Symbol, member: MemberShape): Symbol = - if (config.handleRequired && member.isRequired) { - symbol - } else if (nullableIndex.isNullable(member)) { - symbol.makeOptional() - } else { - symbol - } + symbol.letIf(nullableIndex.isMemberNullable(member, config.nullabilityCheckMode)) { symbol.makeOptional() } /** * Produce `Box` when the shape has the `RustBoxTrait` diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/testutil/TestHelpers.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/testutil/TestHelpers.kt index e5762296b2..4668052d6d 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/testutil/TestHelpers.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/testutil/TestHelpers.kt @@ -6,6 +6,7 @@ package software.amazon.smithy.rust.codegen.client.testutil import software.amazon.smithy.model.Model +import software.amazon.smithy.model.knowledge.NullableIndex import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.shapes.ShapeId import software.amazon.smithy.model.shapes.StructureShape @@ -37,7 +38,7 @@ val TestSymbolVisitorConfig = SymbolVisitorConfig( runtimeConfig = TestRuntimeConfig, renameExceptions = true, handleRustBoxing = true, - handleRequired = false, + nullabilityCheckMode = NullableIndex.CheckMode.CLIENT_ZERO_VALUE_V1, ) fun testRustSettings( diff --git a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/SymbolBuilderTest.kt b/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/SymbolBuilderTest.kt index 2b3eeb083c..96437c6140 100644 --- a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/SymbolBuilderTest.kt +++ b/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/SymbolBuilderTest.kt @@ -125,17 +125,13 @@ class SymbolBuilderTest { "PrimitiveBoolean, false, bool", ) fun `creates primitives`(primitiveType: String, optional: Boolean, rustName: String) { - val memberBuilder = MemberShape.builder().id("foo.bar#MyStruct\$quux").target("smithy.api#$primitiveType") - val member = memberBuilder.build() - val struct = StructureShape.builder() - .id("foo.bar#MyStruct") - .addMember(member) - .build() - val model = Model.assembler() - .addShapes(struct, member) - .assemble() - .unwrap() - + val model = """ + namespace foo.bar + structure MyStruct { + quux: $primitiveType + } +""".asSmithyModel() + val member = model.expectShape(ShapeId.from("foo.bar#MyStruct\$quux")) val provider: SymbolProvider = testSymbolProvider(model) val memberSymbol = provider.toSymbol(member) // builtins should not have a namespace set diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerCodegenVisitor.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerCodegenVisitor.kt index 3c37204bd8..24d2931180 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerCodegenVisitor.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/PythonServerCodegenVisitor.kt @@ -8,6 +8,7 @@ package software.amazon.smithy.rust.codegen.server.python.smithy import software.amazon.smithy.build.PluginContext import software.amazon.smithy.codegen.core.CodegenException +import software.amazon.smithy.model.knowledge.NullableIndex import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.shapes.StringShape import software.amazon.smithy.model.shapes.StructureShape @@ -46,8 +47,8 @@ class PythonServerCodegenVisitor( SymbolVisitorConfig( runtimeConfig = settings.runtimeConfig, renameExceptions = false, - handleRequired = true, handleRustBoxing = true, + nullabilityCheckMode = NullableIndex.CheckMode.SERVER, ) val baseModel = baselineTransform(context.model) val service = settings.getService(baseModel) diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerCodegenVisitor.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerCodegenVisitor.kt index d4cc316244..2f8dcc7eb7 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerCodegenVisitor.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerCodegenVisitor.kt @@ -7,6 +7,7 @@ package software.amazon.smithy.rust.codegen.server.smithy import software.amazon.smithy.build.PluginContext import software.amazon.smithy.model.Model +import software.amazon.smithy.model.knowledge.NullableIndex import software.amazon.smithy.model.neighbor.Walker import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.shapes.Shape @@ -69,8 +70,8 @@ open class ServerCodegenVisitor( SymbolVisitorConfig( runtimeConfig = settings.runtimeConfig, renameExceptions = false, - handleRequired = true, handleRustBoxing = true, + nullabilityCheckMode = NullableIndex.CheckMode.SERVER, ) val baseModel = baselineTransform(context.model) val service = settings.getService(baseModel) diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/testutil/ServerTestHelpers.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/testutil/ServerTestHelpers.kt index eadfabdf21..e6e930e631 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/testutil/ServerTestHelpers.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/testutil/ServerTestHelpers.kt @@ -6,6 +6,7 @@ package software.amazon.smithy.rust.codegen.server.smithy.testutil import software.amazon.smithy.model.Model +import software.amazon.smithy.model.knowledge.NullableIndex import software.amazon.smithy.model.node.ObjectNode import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.shapes.ShapeId @@ -24,7 +25,7 @@ val ServerTestSymbolVisitorConfig = SymbolVisitorConfig( runtimeConfig = TestRuntimeConfig, renameExceptions = false, handleRustBoxing = true, - handleRequired = true, + nullabilityCheckMode = NullableIndex.CheckMode.SERVER, ) fun serverTestSymbolProvider( diff --git a/gradle.properties b/gradle.properties index a5e8c71f08..9e739d51a7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,7 +15,7 @@ kotlin.code.style=official # codegen smithyGradlePluginVersion=0.6.0 -smithyVersion=1.23.1 +smithyVersion=1.25.0 # kotlin kotlinVersion=1.6.21