From 4668b09f48e7fcadd72895e021572a6fcb6f7404 Mon Sep 17 00:00:00 2001 From: Jason Del Ponte Date: Mon, 23 Nov 2020 14:52:33 -0800 Subject: [PATCH] codegen: Ensure API structs don't collide with API client type name 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 {