Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flatten and remove mixins from code generation #1680

Merged
merged 14 commits into from
Sep 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ references = ["smithy-rs#1603", "aws-sdk-rust#586"]
meta = { "breaking" = true, "tada" = false, "bug" = false, "target" = "client" }
author = "jdisanti"


[[aws-sdk-rust]]
message = """
Implemented customizable operations per [RFC-0017](https://awslabs.github.io/smithy-rs/design/rfcs/rfc0017_customizable_client_operations.html).
Expand Down Expand Up @@ -169,3 +168,9 @@ let response = client.some_operation()
references = ["smithy-rs#1647", "smithy-rs#1112"]
meta = { "breaking" = false, "tada" = true, "bug" = false, "target" = "client"}
author = "Velfi"

[[smithy-rs]]
message = "Smithy IDL v2 mixins are now supported"
references = ["smithy-rs#1680"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "all"}
author = "ogudavid"
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ open class ServerCodegenVisitor(
*/
protected fun baselineTransform(model: Model) =
model
// Flattens mixins out of the model and removes them from the model
.let { ModelTransformer.create().flattenAndRemoveMixins(it) }
// Add errors attached at the service level to the models
.let { ModelTransformer.create().copyServiceErrorsToOperations(it, settings.getService(it)) }
// Add `Box<T>` to recursive shapes as necessary
Expand All @@ -114,6 +116,12 @@ open class ServerCodegenVisitor(
// Normalize event stream operations
.let(EventStreamNormalizer::transform)

/**
* Exposure purely for unit test purposes.
*/
internal fun baselineTransformInternalTest(model: Model) =
baselineTransform(model)

/**
* Execute code generation
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.rust.codegen.server.smithy

import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Test
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.server.smithy.customizations.ServerRequiredCustomizations
import software.amazon.smithy.rust.codegen.smithy.ServerCodegenContext
import software.amazon.smithy.rust.codegen.smithy.customize.CombinedCodegenDecorator
import software.amazon.smithy.rust.codegen.testutil.asSmithyModel
import software.amazon.smithy.rust.codegen.testutil.generatePluginContext
import kotlin.io.path.createDirectory
import kotlin.io.path.writeText

class ServerCodegenVisitorTest {
@Test
fun `baseline transform verify mixins removed`() {
val model = """
namespace com.example

use aws.protocols#awsJson1_0

@awsJson1_0
@aws.api#service(sdkId: "Test", endpointPrefix: "differentPrefix")
service Example {
operations: [ BasicOperation ]
}

operation BasicOperation {
input: Shape
}

@mixin
structure SimpleMixin {
name: String
}

structure Shape with [
SimpleMixin
] {
greeting: String
}
""".asSmithyModel(smithyVersion = "2.0")
val (ctx, testDir) = generatePluginContext(model)
testDir.resolve("src").createDirectory()
testDir.resolve("src/main.rs").writeText("fn main() {}")
val codegenDecorator: CombinedCodegenDecorator<ServerCodegenContext> =
CombinedCodegenDecorator.fromClasspath(ctx, ServerRequiredCustomizations())
val visitor = ServerCodegenVisitor(ctx, codegenDecorator)
val baselineModel = visitor.baselineTransformInternalTest(model)
baselineModel.getShapesWithTrait(ShapeId.from("smithy.api#mixin")).isEmpty() shouldBe true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ class CodegenVisitor(context: PluginContext, private val codegenDecorator: RustC
* Base model transformation applied to all services
* See below for details.
*/
private fun baselineTransform(model: Model) =
internal fun baselineTransform(model: Model) =
model
// Flattens mixins out of the model and removes them from the model
.let { ModelTransformer.create().flattenAndRemoveMixins(it) }
// Add errors attached at the service level to the models
.let { ModelTransformer.create().copyServiceErrorsToOperations(it, settings.getService(it)) }
// Add `Box<T>` to recursive shapes as necessary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ fun testCodegenContext(
)

private const val SmithyVersion = "1.0"
fun String.asSmithyModel(sourceLocation: String? = null): Model {
val processed = letIf(!this.startsWith("\$version")) { "\$version: ${SmithyVersion.dq()}\n$it" }
fun String.asSmithyModel(sourceLocation: String? = null, smithyVersion: String = SmithyVersion): Model {
val processed = letIf(!this.startsWith("\$version")) { "\$version: ${smithyVersion.dq()}\n$it" }
return Model.assembler().discoverModels().addUnparsedModel(sourceLocation ?: "test.smithy", processed).assemble()
.unwrap()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.rust.codegen.smithy

import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Test
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.smithy.customizations.ClientCustomizations
import software.amazon.smithy.rust.codegen.smithy.customize.CombinedCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.customize.NoOpEventStreamSigningDecorator
import software.amazon.smithy.rust.codegen.smithy.customize.RequiredCustomizations
import software.amazon.smithy.rust.codegen.smithy.generators.client.FluentClientDecorator
import software.amazon.smithy.rust.codegen.testutil.asSmithyModel
import software.amazon.smithy.rust.codegen.testutil.generatePluginContext
import kotlin.io.path.createDirectory
import kotlin.io.path.writeText

class CodegenVisitorTest {
@Test
fun `baseline transform verify mixins removed`() {
val model = """
namespace com.example

use aws.protocols#awsJson1_0

@awsJson1_0
@aws.api#service(sdkId: "Test", endpointPrefix: "differentPrefix")
service Example {
operations: [ BasicOperation ]
}

operation BasicOperation {
input: Shape
}

@mixin
structure SimpleMixin {
name: String
}

structure Shape with [
SimpleMixin
] {
greeting: String
}
""".asSmithyModel(smithyVersion = "2.0")
val (ctx, testDir) = generatePluginContext(model)
testDir.resolve("src").createDirectory()
testDir.resolve("src/main.rs").writeText("fn main() {}")
val codegenDecorator =
CombinedCodegenDecorator.fromClasspath(
ctx,
ClientCustomizations(),
RequiredCustomizations(),
FluentClientDecorator(),
NoOpEventStreamSigningDecorator(),
)
val visitor = CodegenVisitor(ctx, codegenDecorator)
val baselineModel = visitor.baselineTransform(model)
baselineModel.getShapesWithTrait(ShapeId.from("smithy.api#mixin")).isEmpty() shouldBe true
}
}