Skip to content

Commit f1f6447

Browse files
authored
fix: correct waiters with broken subfield projections (#846)
1 parent 2e1d018 commit f1f6447

File tree

4 files changed

+114
-9
lines changed

4 files changed

+114
-9
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"id": "3cf671d8-1ec4-4e2f-a4ae-0f1f08f73fd1",
3+
"type": "bugfix",
4+
"description": "Fix broken shape cursor when generating acceptor subfield projections."
5+
}

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/KotlinJmespathExpressionVisitor.kt

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ class KotlinJmespathExpressionVisitor(
9090
if (!condition) throw CodegenException(lazyMessage())
9191
}
9292

93-
private fun flatMappingBlock(right: JmespathExpression, leftName: String, leftShape: Shape): String {
94-
if (right is CurrentExpression) return leftName // Nothing to map
93+
private fun flatMappingBlock(right: JmespathExpression, leftName: String, leftShape: Shape): VisitedExpression {
94+
if (right is CurrentExpression) return VisitedExpression(leftName, leftShape) // nothing to map
9595

9696
val outerName = bestTempVarName("projection")
9797
writer.openBlock("val #L = #L.flatMap {", outerName, leftName)
@@ -104,7 +104,7 @@ class KotlinJmespathExpressionVisitor(
104104
writer.write(innerCollector)
105105

106106
writer.closeBlock("}")
107-
return outerName
107+
return VisitedExpression(outerName, innerResult.shape)
108108
}
109109

110110
private fun subfield(expression: FieldExpression, parentName: String): VisitedExpression {
@@ -187,8 +187,7 @@ class KotlinJmespathExpressionVisitor(
187187
write("#L == true", comparison.identifier)
188188
}
189189

190-
val ident = flatMappingBlock(expression.right, filteredName, left.shape)
191-
return VisitedExpression(ident, left.shape)
190+
return flatMappingBlock(expression.right, filteredName, left.shape)
192191
}
193192

194193
override fun visitFlatten(expression: FlattenExpression): VisitedExpression {
@@ -279,8 +278,7 @@ class KotlinJmespathExpressionVisitor(
279278
val valuesExpr = ensureNullGuard(left.shape, "values")
280279
val valuesName = addTempVar("${left.identifier}Values", "${left.identifier}$valuesExpr")
281280

282-
val ident = flatMappingBlock(expression.right, valuesName, left.shape)
283-
return VisitedExpression(ident, left.shape)
281+
return flatMappingBlock(expression.right, valuesName, left.shape)
284282
}
285283

286284
override fun visitOr(expression: OrExpression): VisitedExpression {
@@ -299,8 +297,7 @@ class KotlinJmespathExpressionVisitor(
299297
val left = acceptSubexpression(expression.left)
300298
requireNotNull(left.shape) { "projection is operating on nothing?" }
301299

302-
val ident = flatMappingBlock(expression.right, left.identifier, left.shape)
303-
return VisitedExpression(ident, left.shape)
300+
return flatMappingBlock(expression.right, left.identifier, left.shape)
304301
}
305302

306303
override fun visitSlice(expression: SliceExpression): VisitedExpression {

tests/codegen/waiter-tests/model/waiter-operations.smithy

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,36 @@ service WaitersTestService {
699699
}
700700
]
701701
},
702+
703+
// subfield projection
704+
HasStructWithStringByProjection: {
705+
acceptors: [
706+
{
707+
state: "success",
708+
matcher: {
709+
output: {
710+
path: "lists.structs[].primitives.string"
711+
expected: "foo",
712+
comparator: "anyStringEquals"
713+
}
714+
}
715+
}
716+
]
717+
},
718+
HasStructWithSubstructWithStringByProjection: {
719+
acceptors: [
720+
{
721+
state: "success",
722+
matcher: {
723+
output: {
724+
path: "lists.structs[].subStructs[].subStructPrimitives.string"
725+
expected: "foo",
726+
comparator: "anyStringEquals"
727+
}
728+
}
729+
}
730+
]
731+
},
702732
)
703733
@readonly
704734
@http(method: "GET", uri: "/entities/{name}", code: 200)
@@ -833,4 +863,13 @@ structure Struct {
833863
primitives: EntityPrimitives,
834864
strings: StringList,
835865
enums: EnumList,
866+
subStructs: SubStructList,
867+
}
868+
869+
list SubStructList {
870+
member: SubStruct,
871+
}
872+
873+
structure SubStruct {
874+
subStructPrimitives: EntityPrimitives,
836875
}

tests/codegen/waiter-tests/src/test/kotlin/com/test/WaiterTest.kt

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,4 +681,68 @@ class WaiterTest {
681681
}
682682
},
683683
)
684+
685+
// subfield projection
686+
@Test fun testHasStructWithStringByProjection() = successTest(
687+
WaitersTestClient::waitUntilHasStructWithStringByProjection,
688+
GetEntityResponse { },
689+
GetEntityResponse { lists = EntityLists { } },
690+
GetEntityResponse {
691+
lists = EntityLists { structs = listOf() }
692+
},
693+
GetEntityResponse {
694+
lists = EntityLists { structs = listOf(Struct { }) }
695+
},
696+
GetEntityResponse {
697+
lists = EntityLists {
698+
structs = listOf(
699+
Struct { primitives = EntityPrimitives { string = "bar" } },
700+
)
701+
}
702+
},
703+
GetEntityResponse {
704+
lists = EntityLists {
705+
structs = listOf(
706+
Struct { primitives = EntityPrimitives { string = "bar" } },
707+
Struct { primitives = EntityPrimitives { string = "foo" } },
708+
)
709+
}
710+
},
711+
)
712+
@Test fun testHasStructWithSubstructWithStringByProjection() = successTest(
713+
WaitersTestClient::waitUntilHasStructWithSubstructWithStringByProjection,
714+
GetEntityResponse { },
715+
GetEntityResponse { lists = EntityLists { } },
716+
GetEntityResponse {
717+
lists = EntityLists { structs = listOf() }
718+
},
719+
GetEntityResponse {
720+
lists = EntityLists {
721+
structs = listOf(
722+
Struct { subStructs = listOf(SubStruct { }) },
723+
)
724+
}
725+
},
726+
GetEntityResponse {
727+
lists = EntityLists {
728+
structs = listOf(
729+
Struct { subStructs = listOf(SubStruct { subStructPrimitives = EntityPrimitives { string = "bar" } }) },
730+
Struct { subStructs = listOf(SubStruct { }) },
731+
)
732+
}
733+
},
734+
GetEntityResponse {
735+
lists = EntityLists {
736+
structs = listOf(
737+
Struct {
738+
subStructs = listOf(
739+
SubStruct { subStructPrimitives = EntityPrimitives { string = "bar" } },
740+
SubStruct { subStructPrimitives = EntityPrimitives { string = "baz" } },
741+
)
742+
},
743+
Struct { subStructs = listOf(SubStruct { subStructPrimitives = EntityPrimitives { string = "foo" } }) },
744+
)
745+
}
746+
},
747+
)
684748
}

0 commit comments

Comments
 (0)