From 8e5531c107d27bb374b420048a65bc0898582be4 Mon Sep 17 00:00:00 2001 From: Jason Del Ponte Date: Tue, 24 Nov 2020 08:37:46 -0800 Subject: [PATCH] codegen: Ensure API structs don't collide with API client type name (#3651) Updates the SDK's code generation to renames structures that collide with the service's API client struct name. For example, service Foo, has struct shape named Foo. The API client type would be generated as Foo, and the colliding struct shape would be renamed to Foo_, with a trailing underscore(_). --- private/model/api/passes.go | 6 ++++++ private/model/api/passes_test.go | 36 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/private/model/api/passes.go b/private/model/api/passes.go index 6a60f573cd1..fc2149d3c2e 100644 --- a/private/model/api/passes.go +++ b/private/model/api/passes.go @@ -334,6 +334,12 @@ func (a *API) renameExportable() { } newName := a.ExportableName(k) + if s.Type == "structure" && newName == a.StructName() { + // If struct collides client's struct type name the shape needs to + // be renamed with a trailing `_` to prevent collision. + newName += "_" + } + if newName != s.ShapeName { s.Rename(newName) } diff --git a/private/model/api/passes_test.go b/private/model/api/passes_test.go index 842efc0283a..0de453b8bf8 100644 --- a/private/model/api/passes_test.go +++ b/private/model/api/passes_test.go @@ -576,6 +576,42 @@ func TestCreateInputOutputShapes(t *testing.T) { "FirstOpInput", "FirstOpOutput", }, }, + "collidingShape": { + API: &API{ + name: "APIClientName", + Metadata: meta, + Operations: map[string]*Operation{ + "FirstOp": {Name: "FirstOp", + InputRef: ShapeRef{ShapeName: "FirstOpRequest"}, + }, + }, + Shapes: map[string]*Shape{ + "FirstOpRequest": {ShapeName: "FirstOpRequest", Type: "structure", + MemberRefs: map[string]*ShapeRef{ + "Foo": {ShapeName: "APIClientName"}, + "ooF": {ShapeName: "APIClientNameList"}, + }, + }, + "APIClientName": { + ShapeName: "APIClientName", Type: "structure", + }, + "APIClientNameList": { + ShapeName: "APIClientNameList", Type: "list", + MemberRef: ShapeRef{ShapeName: "APIClientName"}, + }, + }, + }, + ExpectOps: map[string]OpExpect{ + "FirstOp": { + Input: "FirstOpInput", + Output: "FirstOpOutput", + }, + }, + ExpectShapes: []string{ + "APIClientNameList", "APIClientName_", + "FirstOpInput", "FirstOpOutput", + }, + }, } for name, c := range cases {