diff --git a/builder/assignto.go b/builder/assignto.go new file mode 100644 index 00000000..33cc1433 --- /dev/null +++ b/builder/assignto.go @@ -0,0 +1,55 @@ +package builder + +import ( + "github.com/dave/jennifer/jen" + "github.com/jmattheis/goverter/xtype" +) + +type AssignTo struct { + Must bool + Stmt *jen.Statement +} + +func assignOf(s *jen.Statement) *AssignTo { + return &AssignTo{Stmt: s} +} + +func (a *AssignTo) WithIndex(s *jen.Statement) *AssignTo { + return &AssignTo{ + Stmt: a.Stmt.Clone().Index(s), + } +} + +func (a *AssignTo) WithMust() *AssignTo { + a.Must = true + return a +} + +func ToAssignable(assignTo *AssignTo) func(stmt []jen.Code, nextID *xtype.JenID, err *Error) ([]jen.Code, *Error) { + return func(stmt []jen.Code, nextID *xtype.JenID, err *Error) ([]jen.Code, *Error) { + if err != nil { + return nil, err + } + stmt = append(stmt, assignTo.Stmt.Clone().Op("=").Add(nextID.Code)) + return stmt, nil + } +} + +func AssignByBuild(b Builder, gen Generator, ctx *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *Error) { + return ToAssignable(assignTo)(b.Build(gen, ctx, sourceID, source, target, errPath)) +} + +func BuildByAssign(b Builder, gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *xtype.JenID, *Error) { + buildStmt, valueVar, err := buildTargetVar(gen, ctx, sourceID, source, target, path) + if err != nil { + return nil, nil, err + } + + stmt, err := b.Assign(gen, ctx, assignOf(valueVar), sourceID, source, target, path) + if err != nil { + return nil, nil, err + } + + buildStmt = append(buildStmt, stmt...) + return buildStmt, xtype.VariableID(valueVar), nil +} diff --git a/builder/basic.go b/builder/basic.go index 43864941..28bdb4d4 100644 --- a/builder/basic.go +++ b/builder/basic.go @@ -22,6 +22,10 @@ func (*Basic) Build(_ Generator, _ *MethodContext, sourceID *xtype.JenID, source return nil, sourceID, nil } +func (b *Basic) Assign(gen Generator, ctx *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *Error) { + return AssignByBuild(b, gen, ctx, assignTo, sourceID, source, target, errPath) +} + // BasicTargetPointerRule handles edge conditions if the target type is a pointer. type BasicTargetPointerRule struct{} @@ -49,3 +53,7 @@ func (*BasicTargetPointerRule) Build(gen Generator, ctx *MethodContext, sourceID return stmt, xtype.OtherID(newID), err } + +func (b *BasicTargetPointerRule) Assign(gen Generator, ctx *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *Error) { + return AssignByBuild(b, gen, ctx, assignTo, sourceID, source, target, errPath) +} diff --git a/builder/builder.go b/builder/builder.go index 749e8cec..16040964 100644 --- a/builder/builder.go +++ b/builder/builder.go @@ -20,6 +20,13 @@ type Builder interface { sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *xtype.JenID, *Error) + + Assign(gen Generator, + ctx *MethodContext, + assignTo *AssignTo, + sourceID *xtype.JenID, + source, target *xtype.Type, + path ErrorPath) ([]jen.Code, *Error) } // Generator checks all existing builders if they can create a conversion implementations for the given source and target type @@ -31,6 +38,12 @@ type Generator interface { source, target *xtype.Type, path ErrorPath) ([]jen.Code, *xtype.JenID, *Error) + Assign(ctx *MethodContext, + assignTo *AssignTo, + sourceID *xtype.JenID, + source, target *xtype.Type, + path ErrorPath) ([]jen.Code, *Error) + CallMethod( ctx *MethodContext, method *method.Definition, diff --git a/builder/enum.go b/builder/enum.go index b291910f..3548fa1b 100644 --- a/builder/enum.go +++ b/builder/enum.go @@ -98,6 +98,10 @@ func (*Enum) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, sou return stmt, xtype.VariableID(nameVar), nil } +func (s *Enum) Assign(gen Generator, ctx *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *Error) { + return AssignByBuild(s, gen, ctx, assignTo, sourceID, source, target, path) +} + func caseAction(gen Generator, ctx *MethodContext, nameVar *jen.Statement, target *xtype.Type, targetEnum *xtype.Enum, targetName string, sourceID *xtype.JenID, errPath ErrorPath) (jen.Code, *Error) { if config.IsEnumAction(targetName) { switch targetName { diff --git a/builder/list.go b/builder/list.go index ed8220e2..55e2a9aa 100644 --- a/builder/list.go +++ b/builder/list.go @@ -14,41 +14,51 @@ func (*List) Matches(_ *MethodContext, source, target *xtype.Type) bool { } // Build creates conversion source code for the given source and target type. -func (*List) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *xtype.JenID, *Error) { +func (l *List) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *xtype.JenID, *Error) { ctx.SetErrorTargetVar(jen.Nil()) targetSlice := ctx.Name(target.ID()) + + stmt, err := l.Assign(gen, ctx, assignOf(jen.Id(targetSlice)), sourceID, source, target, path) + if err != nil { + return nil, nil, err + } + + var id jen.Code + if source.ListFixed { + id = jen.Id(targetSlice).Op(":=").Make(target.TypeAsJen(), jen.Len(sourceID.Code.Clone())) + } else { + id = jen.Var().Add(jen.Id(targetSlice), target.TypeAsJen()) + } + stmt = append([]jen.Code{id}, stmt...) + + return stmt, xtype.VariableID(jen.Id(targetSlice)), nil +} + +func (*List) Assign(gen Generator, ctx *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *Error) { + ctx.SetErrorTargetVar(jen.Nil()) index := ctx.Index() indexedSource := xtype.VariableID(sourceID.Code.Clone().Index(jen.Id(index))) - forBlock, newID, err := gen.Build(ctx, indexedSource, source.ListInner, target.ListInner, path.Index(jen.Id(index))) + forBlock, err := gen.Assign(ctx, assignTo.WithIndex(jen.Id(index)), indexedSource, source.ListInner, target.ListInner, path.Index(jen.Id(index))) if err != nil { - return nil, nil, err.Lift(&Path{ + return nil, err.Lift(&Path{ SourceID: "[]", SourceType: source.ListInner.String, TargetID: "[]", TargetType: target.ListInner.String, }) } - forBlock = append(forBlock, jen.Id(targetSlice).Index(jen.Id(index)).Op("=").Add(newID.Code)) forStmt := jen.For(jen.Id(index).Op(":=").Lit(0), jen.Id(index).Op("<").Len(sourceID.Code.Clone()), jen.Id(index).Op("++")). Block(forBlock...) - stmt := []jen.Code{} if source.ListFixed { - stmt = []jen.Code{ - jen.Id(targetSlice).Op(":=").Make(target.TypeAsJen(), jen.Len(sourceID.Code.Clone())), - forStmt, - } - } else { - stmt = []jen.Code{ - jen.Var().Add(jen.Id(targetSlice), target.TypeAsJen()), - jen.If(sourceID.Code.Clone().Op("!=").Nil()).Block( - jen.Id(targetSlice).Op("=").Make(target.TypeAsJen(), jen.Len(sourceID.Code.Clone())), - forStmt, - ), - } + return []jen.Code{forStmt}, nil } - - return stmt, xtype.VariableID(jen.Id(targetSlice)), nil + return []jen.Code{ + jen.If(sourceID.Code.Clone().Op("!=").Nil()).Block( + assignTo.Stmt.Clone().Op("=").Make(target.TypeAsJen(), jen.Len(sourceID.Code.Clone())), + forStmt, + ), + }, nil } diff --git a/builder/map.go b/builder/map.go index 49ddf84b..75f3c0cc 100644 --- a/builder/map.go +++ b/builder/map.go @@ -14,26 +14,30 @@ func (*Map) Matches(_ *MethodContext, source, target *xtype.Type) bool { } // Build creates conversion source code for the given source and target type. -func (*Map) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *xtype.JenID, *Error) { +func (m *Map) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *xtype.JenID, *Error) { + ctx.SetErrorTargetVar(jen.Nil()) + return BuildByAssign(m, gen, ctx, sourceID, source, target, errPath) +} + +func (*Map) Assign(gen Generator, ctx *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *Error) { ctx.SetErrorTargetVar(jen.Nil()) - targetMap := ctx.Name(target.ID()) key, value := ctx.Map() errPath = errPath.Key(jen.Id(key)) - block, newKey, err := gen.Build(ctx, xtype.VariableID(jen.Id(key)), source.MapKey, target.MapKey, errPath) + block, keyID, err := gen.Build(ctx, xtype.VariableID(jen.Id(key)), source.MapKey, target.MapKey, errPath) if err != nil { - return nil, nil, err.Lift(&Path{ + return nil, err.Lift(&Path{ SourceID: "[]", SourceType: " " + source.MapKey.String, TargetID: "[]", TargetType: " " + target.MapKey.String, }) } - valueStmt, valueKey, err := gen.Build( - ctx, xtype.VariableID(jen.Id(value)), source.MapValue, target.MapValue, errPath) + valueStmt, err := gen.Assign( + ctx, assignTo.WithIndex(keyID.Code).WithMust(), xtype.VariableID(jen.Id(value)), source.MapValue, target.MapValue, errPath) if err != nil { - return nil, nil, err.Lift(&Path{ + return nil, err.Lift(&Path{ SourceID: "[]", SourceType: " " + source.MapValue.String, TargetID: "[]", @@ -41,16 +45,14 @@ func (*Map) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, sour }) } block = append(block, valueStmt...) - block = append(block, jen.Id(targetMap).Index(newKey.Code).Op("=").Add(valueKey.Code)) stmt := []jen.Code{ - jen.Var().Add(jen.Id(targetMap), target.TypeAsJen()), jen.If(sourceID.Code.Clone().Op("!=").Nil()).Block( - jen.Id(targetMap).Op("=").Make(target.TypeAsJen(), jen.Len(sourceID.Code.Clone())), + assignTo.Stmt.Clone().Op("=").Make(target.TypeAsJen(), jen.Len(sourceID.Code.Clone())), jen.For(jen.List(jen.Id(key), jen.Id(value)).Op(":=").Range().Add(sourceID.Code)). Block(block...), ), } - return stmt, xtype.VariableID(jen.Id(targetMap)), nil + return stmt, nil } diff --git a/builder/pointer.go b/builder/pointer.go index 1e6f15b5..e2e7f271 100644 --- a/builder/pointer.go +++ b/builder/pointer.go @@ -14,13 +14,13 @@ func (*Pointer) Matches(_ *MethodContext, source, target *xtype.Type) bool { } // Build creates conversion source code for the given source and target type. -func (*Pointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *xtype.JenID, *Error) { +func (p *Pointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *xtype.JenID, *Error) { ctx.SetErrorTargetVar(jen.Nil()) + return BuildByAssign(p, gen, ctx, sourceID, source, target, errPath) +} - stmt, outerVar, err := buildTargetVar(gen, ctx, sourceID, source, target, errPath) - if err != nil { - return nil, nil, err - } +func (*Pointer) Assign(gen Generator, ctx *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *Error) { + ctx.SetErrorTargetVar(jen.Nil()) valueSourceID := jen.Op("*").Add(sourceID.Code.Clone()) if !source.PointerInner.Basic { @@ -32,7 +32,7 @@ func (*Pointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, nextBlock, id, err := gen.Build( ctx, innerID, source.PointerInner, target.PointerInner, errPath) if err != nil { - return nil, nil, err.Lift(&Path{ + return nil, err.Lift(&Path{ SourceID: "*", SourceType: source.PointerInner.String, TargetID: "*", @@ -43,13 +43,18 @@ func (*Pointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, pstmt, tmpID := id.Pointer(target.PointerInner, ctx.Name) ifBlock := append(nextBlock, pstmt...) - ifBlock = append(ifBlock, outerVar.Clone().Op("=").Add(tmpID.Code)) + ifBlock = append(ifBlock, assignTo.Stmt.Clone().Op("=").Add(tmpID.Code)) + + var elseCase []jen.Code + if assignTo.Must { + elseCase = append(elseCase, jen.Else().Block(assignTo.Stmt.Clone().Op("=").Nil())) + } - stmt = append(stmt, - jen.If(sourceID.Code.Clone().Op("!=").Nil()).Block(ifBlock...), - ) + stmt := []jen.Code{ + jen.If(sourceID.Code.Clone().Op("!=").Nil()).Block(ifBlock...).Add(elseCase...), + } - return stmt, xtype.VariableID(outerVar), err + return stmt, err } // SourcePointer handles type were only the source is a pointer. @@ -61,9 +66,11 @@ func (*SourcePointer) Matches(ctx *MethodContext, source, target *xtype.Type) bo } // Build creates conversion source code for the given source and target type. -func (*SourcePointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *xtype.JenID, *Error) { - ctx.SetErrorTargetVar(jen.Id(target.ID())) +func (s *SourcePointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *xtype.JenID, *Error) { + return BuildByAssign(s, gen, ctx, sourceID, source, target, path) +} +func (*SourcePointer) Assign(gen Generator, ctx *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *Error) { valueSourceID := jen.Op("*").Add(sourceID.Code.Clone()) if !source.PointerInner.Basic { valueSourceID = jen.Parens(valueSourceID) @@ -72,26 +79,21 @@ func (*SourcePointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.J innerID := xtype.OtherID(valueSourceID) innerID.ParentPointer = sourceID - stmt, valueVar, err := buildTargetVar(gen, ctx, sourceID, source, target, path) - if err != nil { - return nil, nil, err - } - nextInner, nextID, err := gen.Build(ctx, innerID, source.PointerInner, target, path) if err != nil { - return nil, nil, err.Lift(&Path{ + return nil, err.Lift(&Path{ SourceID: "*", SourceType: source.PointerInner.String, }) } - stmt = append(stmt, + stmt := []jen.Code{ jen.If(sourceID.Code.Clone().Op("!=").Nil()).Block( - append(nextInner, valueVar.Clone().Op("=").Add(nextID.Code))..., + append(nextInner, assignTo.Stmt.Clone().Op("=").Add(nextID.Code))..., ), - ) + } - return stmt, xtype.VariableID(valueVar), nil + return stmt, nil } // TargetPointer handles type were only the target is a pointer. @@ -119,3 +121,7 @@ func (*TargetPointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.J stmt = append(stmt, pstmt...) return stmt, nextID, nil } + +func (tp *TargetPointer) Assign(gen Generator, ctx *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *Error) { + return AssignByBuild(tp, gen, ctx, assignTo, sourceID, source, target, path) +} diff --git a/builder/skipcopy.go b/builder/skipcopy.go index 5b2e326b..ddbba94f 100644 --- a/builder/skipcopy.go +++ b/builder/skipcopy.go @@ -17,3 +17,7 @@ func (*SkipCopy) Matches(ctx *MethodContext, source, target *xtype.Type) bool { func (*SkipCopy) Build(_ Generator, _ *MethodContext, sourceID *xtype.JenID, _, _ *xtype.Type, _ ErrorPath) ([]jen.Code, *xtype.JenID, *Error) { return nil, sourceID, nil } + +func (*SkipCopy) Assign(_ Generator, _ *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, _, _ *xtype.Type, _ ErrorPath) ([]jen.Code, *Error) { + return []jen.Code{assignTo.Stmt.Clone().Op("=").Add(sourceID.Code)}, nil +} diff --git a/builder/struct.go b/builder/struct.go index 8d353629..609a6597 100644 --- a/builder/struct.go +++ b/builder/struct.go @@ -74,12 +74,11 @@ func (*Struct) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, s } stmt = append(stmt, mapStmt...) - fieldStmt, fieldID, err := gen.Build(ctx, nextID, nextSource, targetFieldType, targetFieldPath) + fieldStmt, err := gen.Assign(ctx, assignOf(nameVar.Clone().Dot(targetField.Name())), nextID, nextSource, targetFieldType, targetFieldPath) if err != nil { return nil, nil, err.Lift(lift...) } stmt = append(stmt, fieldStmt...) - stmt = append(stmt, nameVar.Clone().Dot(targetField.Name()).Op("=").Add(fieldID.Code)) } else { def := fieldMapping.Function @@ -134,6 +133,10 @@ func (*Struct) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, s return stmt, xtype.VariableID(nameVar), nil } +func (s *Struct) Assign(gen Generator, ctx *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *Error) { + return AssignByBuild(s, gen, ctx, assignTo, sourceID, source, target, path) +} + func mapField( gen Generator, ctx *MethodContext, diff --git a/builder/underlying.go b/builder/underlying.go index c02e192c..99e11aeb 100644 --- a/builder/underlying.go +++ b/builder/underlying.go @@ -62,6 +62,10 @@ You have to disable enum or useUnderlyingTypeMethods to resolve the setting conf return stmt, id, err } +func (u *UseUnderlyingTypeMethods) Assign(gen Generator, ctx *MethodContext, assignTo *AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *Error) { + return AssignByBuild(u, gen, ctx, assignTo, sourceID, source, target, errPath) +} + func findUnderlyingExtendMapping(ctx *MethodContext, source, target *xtype.Type) (underlyingSource, underlyingTarget bool) { if source.Named { if ctx.HasMethod(source.NamedType.Underlying(), target.NamedType) { diff --git a/docs/changelog.md b/docs/changelog.md index d61ce6fd..44790dca 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -9,7 +9,44 @@ import GH from './GH.vue'; - Error when the settings [`enum`](reference/enum.md) and [`useUnderlyingTypeMethods`](reference/useUnderlyingTypeMethods.md) conflict. -- Add [CLI](./reference/cli.md) commands `help` and `version`. +- Add [CLI](./reference/cli.md) commands `help` and `version`. + +- Improve generation by assigning variables directly if possible. + + :::details Examples + ```diff + func (c *ConverterImpl) Convert(source execution.Input) execution.Output { + var structsOutput execution.Output + - var pString *string + if source.Nested.Name != nil { + xstring := *source.Nested.Name + - pString = &xstring + + structsOutput.Name = &xstring + } + - structsOutput.Name = pString + return structsOutput + } + ``` + *** + ```diff + func (c *ConverterImpl) ConvertPToP(source []*int) []*int { + var pIntList []*int + if source != nil { + pIntList = make([]*int, len(source)) + for i := 0; i < len(source); i++ { + - var pInt *int + if source[i] != nil { + xint := *source[i] + - pInt = &xint + + pIntList[i] = &xint + } + - pIntList[i] = pInt + } + } + return pIntList + } + ``` + ::: ## v1.4.0 diff --git a/example/default/generated/generated.go b/example/default/generated/generated.go index 6eefb158..2f85d940 100644 --- a/example/default/generated/generated.go +++ b/example/default/generated/generated.go @@ -12,12 +12,10 @@ func (c *ConverterImpl) Convert(source *default1.Input) *default1.Output { if source != nil { var exampleOutput default1.Output exampleOutput.Age = (*source).Age - var pString *string if (*source).Name != nil { xstring := *(*source).Name - pString = &xstring + exampleOutput.Name = &xstring } - exampleOutput.Name = pString pExampleOutput = &exampleOutput } return pExampleOutput diff --git a/example/house/generated/generated.go b/example/house/generated/generated.go index 74881345..586ba8e3 100644 --- a/example/house/generated/generated.go +++ b/example/house/generated/generated.go @@ -12,27 +12,23 @@ func (c *ConverterImpl) ConvertApartment(source house.DBApartment) house.APIApar houseAPIApartment.Position = source.Position houseAPIApartment.Owner = c.ConvertPerson(source.Owner) houseAPIApartment.OwnerName = source.Owner.Name - var houseAPIPersonList []house.APIPerson if source.CoResident != nil { - houseAPIPersonList = make([]house.APIPerson, len(source.CoResident)) + houseAPIApartment.CoResident = make([]house.APIPerson, len(source.CoResident)) for i := 0; i < len(source.CoResident); i++ { - houseAPIPersonList[i] = c.ConvertPerson(source.CoResident[i]) + houseAPIApartment.CoResident[i] = c.ConvertPerson(source.CoResident[i]) } } - houseAPIApartment.CoResident = houseAPIPersonList return houseAPIApartment } func (c *ConverterImpl) ConvertHouse(source house.DBHouse) house.APIHouse { var houseAPIHouse house.APIHouse houseAPIHouse.Address = source.Address - var mapHouseAPIRoomNRHouseAPIApartment map[house.APIRoomNR]house.APIApartment if source.Apartments != nil { - mapHouseAPIRoomNRHouseAPIApartment = make(map[house.APIRoomNR]house.APIApartment, len(source.Apartments)) + houseAPIHouse.Apartments = make(map[house.APIRoomNR]house.APIApartment, len(source.Apartments)) for key, value := range source.Apartments { - mapHouseAPIRoomNRHouseAPIApartment[house.APIRoomNR(key)] = c.ConvertApartment(value) + houseAPIHouse.Apartments[house.APIRoomNR(key)] = c.ConvertApartment(value) } } - houseAPIHouse.Apartments = mapHouseAPIRoomNRHouseAPIApartment return houseAPIHouse } func (c *ConverterImpl) ConvertPerson(source house.DBPerson) house.APIPerson { @@ -41,13 +37,11 @@ func (c *ConverterImpl) ConvertPerson(source house.DBPerson) house.APIPerson { houseAPIPerson.MiddleName = house.SQLStringToPString(source.MiddleName) pString := source.Name houseAPIPerson.FirstName = &pString - var houseAPIPersonList []house.APIPerson if source.Friends != nil { - houseAPIPersonList = make([]house.APIPerson, len(source.Friends)) + houseAPIPerson.Friends = make([]house.APIPerson, len(source.Friends)) for i := 0; i < len(source.Friends); i++ { - houseAPIPersonList[i] = c.ConvertPerson(source.Friends[i]) + houseAPIPerson.Friends[i] = c.ConvertPerson(source.Friends[i]) } } - houseAPIPerson.Friends = houseAPIPersonList return houseAPIPerson } diff --git a/example/use-zero-value-on-pointer-inconsistency/generated/generated.go b/example/use-zero-value-on-pointer-inconsistency/generated/generated.go index fdc37e50..bc07343e 100644 --- a/example/use-zero-value-on-pointer-inconsistency/generated/generated.go +++ b/example/use-zero-value-on-pointer-inconsistency/generated/generated.go @@ -9,11 +9,9 @@ type ConverterImpl struct{} func (c *ConverterImpl) Convert(source usezerovalueonpointerinconsistency.Input) usezerovalueonpointerinconsistency.Output { var exampleOutput usezerovalueonpointerinconsistency.Output - var xstring string if source.Name != nil { - xstring = *source.Name + exampleOutput.Name = *source.Name } - exampleOutput.Name = xstring exampleOutput.Age = source.Age return exampleOutput } diff --git a/example/wrap-errors-using/generated/generated.go b/example/wrap-errors-using/generated/generated.go index f956b2e1..e70f42ea 100644 --- a/example/wrap-errors-using/generated/generated.go +++ b/example/wrap-errors-using/generated/generated.go @@ -27,34 +27,30 @@ func (c *ConverterImpl) Convert(source map[int]example.Input) (map[int]example.O } func (c *ConverterImpl) exampleInputToExampleOutput(source example.Input) (example.Output, error) { var exampleOutput example.Output - var exampleOutputList []example.Output if source.Friends != nil { - exampleOutputList = make([]example.Output, len(source.Friends)) + exampleOutput.Friends = make([]example.Output, len(source.Friends)) for i := 0; i < len(source.Friends); i++ { exampleOutput2, err := c.exampleInputToExampleOutput(source.Friends[i]) if err != nil { return exampleOutput, patherr.Wrap(err, patherr.Field("Friends"), patherr.Index(i)) } - exampleOutputList[i] = exampleOutput2 + exampleOutput.Friends[i] = exampleOutput2 } } - exampleOutput.Friends = exampleOutputList xint, err := strconv.Atoi(source.Age) if err != nil { return exampleOutput, patherr.Wrap(err, patherr.Field("Age")) } exampleOutput.Age = xint - var mapStringInt map[string]int if source.Attributes != nil { - mapStringInt = make(map[string]int, len(source.Attributes)) + exampleOutput.Attributes = make(map[string]int, len(source.Attributes)) for key, value := range source.Attributes { xint2, err := strconv.Atoi(value) if err != nil { return exampleOutput, patherr.Wrap(err, patherr.Field("Attributes"), patherr.Key(key)) } - mapStringInt[key] = xint2 + exampleOutput.Attributes[key] = xint2 } } - exampleOutput.Attributes = mapStringInt return exampleOutput, nil } diff --git a/example/wrap-errors-using/generated/minimal.go b/example/wrap-errors-using/generated/minimal.go index dee8bb05..7ec7bcc2 100644 --- a/example/wrap-errors-using/generated/minimal.go +++ b/example/wrap-errors-using/generated/minimal.go @@ -27,34 +27,30 @@ func (c *MinimalImpl) Convert(source map[int]example.Input) (map[int]example.Out } func (c *MinimalImpl) exampleInputToExampleOutput(source example.Input) (example.Output, error) { var exampleOutput example.Output - var exampleOutputList []example.Output if source.Friends != nil { - exampleOutputList = make([]example.Output, len(source.Friends)) + exampleOutput.Friends = make([]example.Output, len(source.Friends)) for i := 0; i < len(source.Friends); i++ { exampleOutput2, err := c.exampleInputToExampleOutput(source.Friends[i]) if err != nil { return exampleOutput, patherr.Wrap(err, patherr.Field("Friends"), patherr.Index(i)) } - exampleOutputList[i] = exampleOutput2 + exampleOutput.Friends[i] = exampleOutput2 } } - exampleOutput.Friends = exampleOutputList xint, err := strconv.Atoi(source.Age) if err != nil { return exampleOutput, patherr.Wrap(err, patherr.Field("Age")) } exampleOutput.Age = xint - var mapStringInt map[string]int if source.Attributes != nil { - mapStringInt = make(map[string]int, len(source.Attributes)) + exampleOutput.Attributes = make(map[string]int, len(source.Attributes)) for key, value := range source.Attributes { xint2, err := strconv.Atoi(value) if err != nil { return exampleOutput, patherr.Wrap(err, patherr.Field("Attributes"), patherr.Key(key)) } - mapStringInt[key] = xint2 + exampleOutput.Attributes[key] = xint2 } } - exampleOutput.Attributes = mapStringInt return exampleOutput, nil } diff --git a/generator/generator.go b/generator/generator.go index 5c8e17cb..a7f802d2 100644 --- a/generator/generator.go +++ b/generator/generator.go @@ -119,8 +119,7 @@ func (g *generator) buildMethod(genMethod *generatedMethod) *builder.Error { var funcBlock []jen.Code if def, ok := g.extend[ctx.Signature]; ok { - jenReturn, err := g.delegateMethod( - ctx, def, xtype.VariableID(sourceID.Clone()), source, target, nil) + jenReturn, err := g.delegateMethod(ctx, def, xtype.VariableID(sourceID.Clone())) if err != nil { return err } @@ -156,21 +155,21 @@ func (g *generator) buildNoLookup(ctx *builder.MethodContext, sourceID *xtype.Je } } - if source.Pointer && !target.Pointer { - return nil, nil, builder.NewError(fmt.Sprintf(`TypeMismatch: Cannot convert %s to %s -It is unclear how nil should be handled in the pointer to non pointer conversion. - -You can enable useZeroValueOnPointerInconsistency to instruct goverter to use the zero value if source is nil -https://goverter.jmattheis.de/reference/useZeroValueOnPointerInconsistency + return nil, nil, typeMismatch(source, target) +} -or you can define a custom conversion method with extend: -https://goverter.jmattheis.de/reference/extend`, source.T, target.T)) +func (g *generator) assignNoLookup(ctx *builder.MethodContext, assignTo *builder.AssignTo, sourceID *xtype.JenID, source, target *xtype.Type, errPath builder.ErrorPath) ([]jen.Code, *builder.Error) { + if err := g.getOverlappingStructDefinition(ctx, source, target); err != nil { + return nil, err } - return nil, nil, builder.NewError(fmt.Sprintf(`TypeMismatch: Cannot convert %s to %s + for _, rule := range BuildSteps { + if rule.Matches(ctx, source, target) { + return rule.Assign(g, ctx, assignTo, sourceID, source, target, errPath) + } + } -You can define a custom conversion method with extend: -https://goverter.jmattheis.de/reference/extend`, source.T, target.T)) + return nil, typeMismatch(source, target) } func (g *generator) CallMethod( @@ -245,8 +244,6 @@ func (g *generator) delegateMethod( ctx *builder.MethodContext, delegateTo *method.Definition, sourceID *xtype.JenID, - source, target *xtype.Type, - errPath builder.ErrorPath, ) (*jen.Statement, *builder.Error) { params := []jen.Code{} if delegateTo.SelfAsFirstParameter { @@ -298,6 +295,37 @@ func (g *generator) Build( return g.CallMethod(ctx, genMethod.Definition, sourceID, source, target, errPath) } + if g.shouldCreateSubMethod(ctx, source, target) { + return g.createSubMethod(ctx, sourceID, source, target, errPath) + } + + return g.buildNoLookup(ctx, sourceID, source, target, errPath) +} + +// Assign builds an implementation for the given source and target type, or uses an existing method for it. +func (g *generator) Assign( + ctx *builder.MethodContext, + assignTo *builder.AssignTo, + sourceID *xtype.JenID, + source, target *xtype.Type, + errPath builder.ErrorPath, +) ([]jen.Code, *builder.Error) { + signature := xtype.SignatureOf(source, target) + if def, ok := g.extend[signature]; ok { + return builder.ToAssignable(assignTo)(g.CallMethod(ctx, def, sourceID, source, target, errPath)) + } + if genMethod, ok := g.lookup[signature]; ok { + return builder.ToAssignable(assignTo)(g.CallMethod(ctx, genMethod.Definition, sourceID, source, target, errPath)) + } + + if g.shouldCreateSubMethod(ctx, source, target) { + return builder.ToAssignable(assignTo)(g.createSubMethod(ctx, sourceID, source, target, errPath)) + } + + return g.assignNoLookup(ctx, assignTo, sourceID, source, target, errPath) +} + +func (g *generator) shouldCreateSubMethod(ctx *builder.MethodContext, source, target *xtype.Type) bool { isCurrentPointerStructMethod := false if source.Struct && target.Struct { // This checks if we are currently inside the generation of one of the following combinations. @@ -330,11 +358,7 @@ func (g *generator) Build( } ctx.MarkSeen(source) - if createSubMethod { - return g.createSubMethod(ctx, sourceID, source, target, errPath) - } - - return g.buildNoLookup(ctx, sourceID, source, target, errPath) + return createSubMethod } func (g *generator) createSubMethod(ctx *builder.MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, errPAth builder.ErrorPath) ([]jen.Code, *xtype.JenID, *builder.Error) { @@ -415,3 +439,21 @@ and therefore the defined field settings would be ignored.`, strings.Join(def.Ra } return nil } + +func typeMismatch(source, target *xtype.Type) *builder.Error { + if source.Pointer && !target.Pointer { + return builder.NewError(fmt.Sprintf(`TypeMismatch: Cannot convert %s to %s +It is unclear how nil should be handled in the pointer to non pointer conversion. + +You can enable useZeroValueOnPointerInconsistency to instruct goverter to use the zero value if source is nil +https://goverter.jmattheis.de/reference/useZeroValueOnPointerInconsistency + +or you can define a custom conversion method with extend: +https://goverter.jmattheis.de/reference/extend`, source.T, target.T)) + } + + return builder.NewError(fmt.Sprintf(`TypeMismatch: Cannot convert %s to %s + +You can define a custom conversion method with extend: +https://goverter.jmattheis.de/reference/extend`, source.T, target.T)) +} diff --git a/scenario/auto_map_pointer.yml b/scenario/auto_map_pointer.yml index 2f1407ed..84d301ec 100644 --- a/scenario/auto_map_pointer.yml +++ b/scenario/auto_map_pointer.yml @@ -39,11 +39,9 @@ success: if source.Address != nil { pString = &source.Address.Street } - var pString2 *string if pString != nil { xstring := *pString - pString2 = &xstring + exampleFlatPerson.Street = &xstring } - exampleFlatPerson.Street = pString2 return exampleFlatPerson } diff --git a/scenario/gomap_nested_struct.yml b/scenario/gomap_nested_struct.yml index 6ff2288f..4b4f7040 100644 --- a/scenario/gomap_nested_struct.yml +++ b/scenario/gomap_nested_struct.yml @@ -19,21 +19,17 @@ success: if source != nil { mapStringMapUintMapBoolString = make(map[string]map[uint]map[bool]string, len(source)) for key, value := range source { - var mapUintMapBoolString map[uint]map[bool]string if value != nil { - mapUintMapBoolString = make(map[uint]map[bool]string, len(value)) + mapStringMapUintMapBoolString[key] = make(map[uint]map[bool]string, len(value)) for key2, value2 := range value { - var mapBoolString map[bool]string if value2 != nil { - mapBoolString = make(map[bool]string, len(value2)) + mapStringMapUintMapBoolString[key][key2] = make(map[bool]string, len(value2)) for key3, value3 := range value2 { - mapBoolString[key3] = value3 + mapStringMapUintMapBoolString[key][key2][key3] = value3 } } - mapUintMapBoolString[key2] = mapBoolString } } - mapStringMapUintMapBoolString[key] = mapUintMapBoolString } } return mapStringMapUintMapBoolString diff --git a/scenario/gomap_primitive_pointer.yml b/scenario/gomap_primitive_pointer.yml index a2da34de..f72ca805 100644 --- a/scenario/gomap_primitive_pointer.yml +++ b/scenario/gomap_primitive_pointer.yml @@ -31,12 +31,12 @@ success: if source != nil { mapStringPInt = make(map[string]*int, len(source)) for key, value := range source { - var pInt *int if value != nil { xint := *value - pInt = &xint + mapStringPInt[key] = &xint + } else { + mapStringPInt[key] = nil } - mapStringPInt[key] = pInt } } return mapStringPInt diff --git a/scenario/map_nested_complex.yml b/scenario/map_nested_complex.yml index b5d0dd7f..a1390956 100644 --- a/scenario/map_nested_complex.yml +++ b/scenario/map_nested_complex.yml @@ -39,11 +39,9 @@ success: if source.Nested != nil && source.Nested.Inner.Inner2 != nil { pString = source.Nested.Inner.Inner2.Name } - var pString2 *string if pString != nil { xstring := *pString - pString2 = &xstring + structsOutput.Name = &xstring } - structsOutput.Name = pString2 return structsOutput } diff --git a/scenario/map_nested_inner_pointer.yml b/scenario/map_nested_inner_pointer.yml index f87cb72e..c2ebbed2 100644 --- a/scenario/map_nested_inner_pointer.yml +++ b/scenario/map_nested_inner_pointer.yml @@ -29,11 +29,9 @@ success: func (c *ConverterImpl) Convert(source execution.Input) execution.Output { var structsOutput execution.Output - var pString *string if source.Nested.Name != nil { xstring := *source.Nested.Name - pString = &xstring + structsOutput.Name = &xstring } - structsOutput.Name = pString return structsOutput } diff --git a/scenario/map_nested_pointer.yml b/scenario/map_nested_pointer.yml index 8e98d8b8..91e0fb2f 100644 --- a/scenario/map_nested_pointer.yml +++ b/scenario/map_nested_pointer.yml @@ -33,11 +33,9 @@ success: if source.Nested != nil { pString = source.Nested.Name } - var pString2 *string if pString != nil { xstring := *pString - pString2 = &xstring + structsOutput.Name = &xstring } - structsOutput.Name = pString2 return structsOutput } diff --git a/scenario/map_nested_structpointer.yml b/scenario/map_nested_structpointer.yml index 56103058..d71a9354 100644 --- a/scenario/map_nested_structpointer.yml +++ b/scenario/map_nested_structpointer.yml @@ -33,11 +33,9 @@ success: if source.Nested != nil { pString = &source.Nested.Name } - var pString2 *string if pString != nil { xstring := *pString - pString2 = &xstring + structsOutput.Name = &xstring } - structsOutput.Name = pString2 return structsOutput } diff --git a/scenario/recursive4.yml b/scenario/recursive4.yml index b3106a86..73031e24 100644 --- a/scenario/recursive4.yml +++ b/scenario/recursive4.yml @@ -37,13 +37,11 @@ success: func (c *ConverterImpl) structsInputToStructsOutput(source execution.Input) execution.Output { var structsOutput execution.Output structsOutput.Name = source.Name - var structsOutputList []execution.Output if source.Values != nil { - structsOutputList = make([]execution.Output, len(source.Values)) + structsOutput.Values = make([]execution.Output, len(source.Values)) for i := 0; i < len(source.Values); i++ { - structsOutputList[i] = c.structsInputToStructsOutput(source.Values[i]) + structsOutput.Values[i] = c.structsInputToStructsOutput(source.Values[i]) } } - structsOutput.Values = structsOutputList return structsOutput } diff --git a/scenario/skipcopy_inner.yml b/scenario/skipcopy_inner.yml index e57446e4..032180d2 100644 --- a/scenario/skipcopy_inner.yml +++ b/scenario/skipcopy_inner.yml @@ -43,14 +43,12 @@ success: var skipOutput execution.Output skipOutput.ID = source.ID skipOutput.Map = source.Map - var mapStringSkipID map[string]execution.ID if source.MapDifferentType != nil { - mapStringSkipID = make(map[string]execution.ID, len(source.MapDifferentType)) + skipOutput.MapDifferentType = make(map[string]execution.ID, len(source.MapDifferentType)) for key, value := range source.MapDifferentType { - mapStringSkipID[key] = execution.ID(value) + skipOutput.MapDifferentType[key] = execution.ID(value) } } - skipOutput.MapDifferentType = mapStringSkipID skipOutput.CreatedAt = c.timeTimeToPTimeTime(source.CreatedAt) skipOutput.Unnamed = source.Unnamed return skipOutput diff --git a/scenario/slice_nested.yml b/scenario/slice_nested.yml index 5474c43e..7f12a721 100644 --- a/scenario/slice_nested.yml +++ b/scenario/slice_nested.yml @@ -19,21 +19,17 @@ success: if source != nil { intListListList = make([][][]int, len(source)) for i := 0; i < len(source); i++ { - var intListList [][]int if source[i] != nil { - intListList = make([][]int, len(source[i])) + intListListList[i] = make([][]int, len(source[i])) for j := 0; j < len(source[i]); j++ { - var intList []int if source[i][j] != nil { - intList = make([]int, len(source[i][j])) + intListListList[i][j] = make([]int, len(source[i][j])) for k := 0; k < len(source[i][j]); k++ { - intList[k] = source[i][j][k] + intListListList[i][j][k] = source[i][j][k] } } - intListList[j] = intList } } - intListListList[i] = intListList } } return intListListList diff --git a/scenario/slice_pointer.yml b/scenario/slice_pointer.yml index ad5658da..48ec0354 100644 --- a/scenario/slice_pointer.yml +++ b/scenario/slice_pointer.yml @@ -26,7 +26,6 @@ success: func (c *ConverterImpl) ConvertHouse(source execution.DBHouseNames) execution.APIHouseNames { var slices_arraysAPIHouseNames execution.APIHouseNames - var pStringList *[]string if source.Names != nil { var stringList []string if (*source.Names) != nil { @@ -35,8 +34,7 @@ success: stringList[i] = (*source.Names)[i] } } - pStringList = &stringList + slices_arraysAPIHouseNames.Names = &stringList } - slices_arraysAPIHouseNames.Names = pStringList return slices_arraysAPIHouseNames } diff --git a/scenario/slice_pointer3.yml b/scenario/slice_pointer3.yml index 19133521..3f7817f2 100644 --- a/scenario/slice_pointer3.yml +++ b/scenario/slice_pointer3.yml @@ -26,7 +26,6 @@ success: func (c *ConverterImpl) ConvertHouse(source execution.DBHouseNames) execution.APIHouseNames { var slices_arraysAPIHouseNames execution.APIHouseNames - var pPPStringList ***[]string if source.Names != nil { var pPStringList **[]string if (*source.Names) != nil { @@ -43,8 +42,7 @@ success: } pPStringList = &pStringList } - pPPStringList = &pPStringList + slices_arraysAPIHouseNames.Names = &pPStringList } - slices_arraysAPIHouseNames.Names = pPPStringList return slices_arraysAPIHouseNames } diff --git a/scenario/slice_primitive_pointer.yml b/scenario/slice_primitive_pointer.yml index 4ce616c1..23ff79ad 100644 --- a/scenario/slice_primitive_pointer.yml +++ b/scenario/slice_primitive_pointer.yml @@ -20,12 +20,10 @@ success: if source != nil { pIntList = make([]*int, len(source)) for i := 0; i < len(source); i++ { - var pInt *int if source[i] != nil { xint := *source[i] - pInt = &xint + pIntList[i] = &xint } - pIntList[i] = pInt } } return pIntList diff --git a/scenario/struct_method_nested.yml b/scenario/struct_method_nested.yml index ac23b112..78b40d48 100644 --- a/scenario/struct_method_nested.yml +++ b/scenario/struct_method_nested.yml @@ -37,11 +37,9 @@ success: xint := source.Nested.Age() pInt = &xint } - var pInt2 *int if pInt != nil { xint2 := *pInt - pInt2 = &xint2 + structsOutput.Age = &xint2 } - structsOutput.Age = pInt2 return structsOutput } diff --git a/scenario/struct_method_nested_with_error.yml b/scenario/struct_method_nested_with_error.yml index 1a4ceb37..564fe549 100644 --- a/scenario/struct_method_nested_with_error.yml +++ b/scenario/struct_method_nested_with_error.yml @@ -40,11 +40,9 @@ success: } pInt = &xint } - var pInt2 *int if pInt != nil { xint2 := *pInt - pInt2 = &xint2 + structsOutput.Age = &xint2 } - structsOutput.Age = pInt2 return structsOutput, nil } diff --git a/scenario/struct_pointer.yml b/scenario/struct_pointer.yml index a22d3729..1b80ce86 100644 --- a/scenario/struct_pointer.yml +++ b/scenario/struct_pointer.yml @@ -35,12 +35,10 @@ success: func (c *ConverterImpl) Convert(source execution.Input) execution.Output { var structsOutput execution.Output - var pPStructsX **execution.X if source.X != nil { pStructsX := c.pStructsXToPStructsX((*source.X)) - pPStructsX = &pStructsX + structsOutput.X = &pStructsX } - structsOutput.X = pPStructsX return structsOutput } func (c *ConverterImpl) pStructsXToPStructsX(source *execution.X) *execution.X { diff --git a/scenario/struct_primitive_pointer.yml b/scenario/struct_primitive_pointer.yml index 4c5ad323..ff5c331c 100644 --- a/scenario/struct_primitive_pointer.yml +++ b/scenario/struct_primitive_pointer.yml @@ -35,11 +35,9 @@ success: structsOutput.ID = &pStructsID pString := source.Name structsOutput.Name = &pString - var pInt *int if source.Age != nil { xint := *source.Age - pInt = &xint + structsOutput.Age = &xint } - structsOutput.Age = pInt return structsOutput } diff --git a/scenario/struct_slice_array.yml b/scenario/struct_slice_array.yml new file mode 100644 index 00000000..dd1c2e3f --- /dev/null +++ b/scenario/struct_slice_array.yml @@ -0,0 +1,32 @@ +input: + input.go: | + package slices_arrays + + // goverter:converter + type Converter interface { + Convert(Input) Output + } + + type Input struct { + Value [5]int + } + type Output struct { + Value []int + } +success: + - generated/generated.go: | + // Code generated by github.com/jmattheis/goverter, DO NOT EDIT. + + package generated + + import execution "github.com/jmattheis/goverter/execution" + + type ConverterImpl struct{} + + func (c *ConverterImpl) Convert(source execution.Input) execution.Output { + var slices_arraysOutput execution.Output + for i := 0; i < len(source.Value); i++ { + slices_arraysOutput.Value[i] = source.Value[i] + } + return slices_arraysOutput + } diff --git a/scenario/struct_unnamed_pointer.yml b/scenario/struct_unnamed_pointer.yml index 9b6d51c2..b206bfc2 100644 --- a/scenario/struct_unnamed_pointer.yml +++ b/scenario/struct_unnamed_pointer.yml @@ -34,30 +34,20 @@ success: func (c *ConverterImpl) ConvertHouse(source execution.Input) execution.Output { var structsOutput execution.Output - var pUnnamed *struct { - Inner *struct { - Name string - } - } if source.House != nil { var unnamed struct { Inner *struct { Name string } } - var pUnnamed2 *struct { - Name string - } if (*source.House).Inner != nil { var unnamed2 struct { Name string } unnamed2.Name = (*(*source.House).Inner).Name - pUnnamed2 = &unnamed2 + unnamed.Inner = &unnamed2 } - unnamed.Inner = pUnnamed2 - pUnnamed = &unnamed + structsOutput.House = &unnamed } - structsOutput.House = pUnnamed return structsOutput } diff --git a/scenario/struct_unnamed_slice.yml b/scenario/struct_unnamed_slice.yml index d074fe82..fae915d7 100644 --- a/scenario/struct_unnamed_slice.yml +++ b/scenario/struct_unnamed_slice.yml @@ -30,11 +30,8 @@ success: func (c *ConverterImpl) ConvertHouse(source execution.Input) execution.Output { var structsOutput execution.Output - var unnamedList []struct { - Name string - } if source.House != nil { - unnamedList = make([]struct { + structsOutput.House = make([]struct { Name string }, len(source.House)) for i := 0; i < len(source.House); i++ { @@ -42,9 +39,8 @@ success: Name string } unnamed.Name = source.House[i].Name - unnamedList[i] = unnamed + structsOutput.House[i] = unnamed } } - structsOutput.House = unnamedList return structsOutput } diff --git a/scenario/struct_unnamed_slice_nested.yml b/scenario/struct_unnamed_slice_nested.yml index d62d3374..e6b9613c 100644 --- a/scenario/struct_unnamed_slice_nested.yml +++ b/scenario/struct_unnamed_slice_nested.yml @@ -30,39 +30,29 @@ success: func (c *ConverterImpl) ConvertHouse(source execution.Input) execution.Output { var structsOutput execution.Output - var unnamedListList [][]struct { - Names []string - } if source.House != nil { - unnamedListList = make([][]struct { + structsOutput.House = make([][]struct { Names []string }, len(source.House)) for i := 0; i < len(source.House); i++ { - var unnamedList []struct { - Names []string - } if source.House[i] != nil { - unnamedList = make([]struct { + structsOutput.House[i] = make([]struct { Names []string }, len(source.House[i])) for j := 0; j < len(source.House[i]); j++ { var unnamed struct { Names []string } - var stringList []string if source.House[i][j].Names != nil { - stringList = make([]string, len(source.House[i][j].Names)) + unnamed.Names = make([]string, len(source.House[i][j].Names)) for k := 0; k < len(source.House[i][j].Names); k++ { - stringList[k] = source.House[i][j].Names[k] + unnamed.Names[k] = source.House[i][j].Names[k] } } - unnamed.Names = stringList - unnamedList[j] = unnamed + structsOutput.House[i][j] = unnamed } } - unnamedListList[i] = unnamedList } } - structsOutput.House = unnamedListList return structsOutput } diff --git a/scenario/use_zerovalue_on_pointer_inconsistency_map_nested.yml b/scenario/use_zerovalue_on_pointer_inconsistency_map_nested.yml index b3f0b428..3f8377d8 100644 --- a/scenario/use_zerovalue_on_pointer_inconsistency_map_nested.yml +++ b/scenario/use_zerovalue_on_pointer_inconsistency_map_nested.yml @@ -31,10 +31,8 @@ success: func (c *ConverterImpl) ConvertPerson(source execution.Person) execution.APIPerson { var structsAPIPerson execution.APIPerson - var xstring string if source.Inner.Name != nil { - xstring = *source.Inner.Name + structsAPIPerson.Name = *source.Inner.Name } - structsAPIPerson.Name = xstring return structsAPIPerson } diff --git a/scenario/use_zerovalue_on_pointer_inconsistency_map_nested2.yml b/scenario/use_zerovalue_on_pointer_inconsistency_map_nested2.yml index eaa2da33..f2c518f4 100644 --- a/scenario/use_zerovalue_on_pointer_inconsistency_map_nested2.yml +++ b/scenario/use_zerovalue_on_pointer_inconsistency_map_nested2.yml @@ -35,10 +35,8 @@ success: if source.Inner != nil { pString = source.Inner.Name } - var xstring string if pString != nil { - xstring = *pString + structsAPIPerson.Name = *pString } - structsAPIPerson.Name = xstring return structsAPIPerson } diff --git a/scenario/use_zerovalue_on_pointer_inconsistency_map_nested3.yml b/scenario/use_zerovalue_on_pointer_inconsistency_map_nested3.yml index 02865885..de5b8033 100644 --- a/scenario/use_zerovalue_on_pointer_inconsistency_map_nested3.yml +++ b/scenario/use_zerovalue_on_pointer_inconsistency_map_nested3.yml @@ -35,10 +35,8 @@ success: if source.Inner != nil { pString = &source.Inner.Name } - var xstring string if pString != nil { - xstring = *pString + structsAPIPerson.Name = *pString } - structsAPIPerson.Name = xstring return structsAPIPerson } diff --git a/scenario/use_zerovalue_on_pointer_inconsistency_multi_ptr.yml b/scenario/use_zerovalue_on_pointer_inconsistency_multi_ptr.yml index 9da3c9a4..f48bd4b6 100644 --- a/scenario/use_zerovalue_on_pointer_inconsistency_multi_ptr.yml +++ b/scenario/use_zerovalue_on_pointer_inconsistency_multi_ptr.yml @@ -27,14 +27,12 @@ success: func (c *ConverterImpl) ConvertHouse(source execution.DBHouseNames) execution.APIHouseNames { var slices_arraysAPIHouseNames execution.APIHouseNames - var xstring string if source.Name != nil { - var xstring2 string + var xstring string if (*source.Name) != nil { - xstring2 = *(*source.Name) + xstring = *(*source.Name) } - xstring = xstring2 + slices_arraysAPIHouseNames.Name = xstring } - slices_arraysAPIHouseNames.Name = xstring return slices_arraysAPIHouseNames } diff --git a/scenario/use_zerovalue_on_pointer_inconsistency_primitive.yml b/scenario/use_zerovalue_on_pointer_inconsistency_primitive.yml index 9544f2c9..198eec70 100644 --- a/scenario/use_zerovalue_on_pointer_inconsistency_primitive.yml +++ b/scenario/use_zerovalue_on_pointer_inconsistency_primitive.yml @@ -27,10 +27,8 @@ success: func (c *ConverterImpl) ConvertPerson(source execution.Person) execution.APIPerson { var structsAPIPerson execution.APIPerson - var xstring string if source.FirstName != nil { - xstring = *source.FirstName + structsAPIPerson.FirstName = *source.FirstName } - structsAPIPerson.FirstName = xstring return structsAPIPerson } diff --git a/scenario/use_zerovalue_on_pointer_inconsistency_slice.yml b/scenario/use_zerovalue_on_pointer_inconsistency_slice.yml index a0c5068c..78bcca0a 100644 --- a/scenario/use_zerovalue_on_pointer_inconsistency_slice.yml +++ b/scenario/use_zerovalue_on_pointer_inconsistency_slice.yml @@ -27,17 +27,15 @@ success: func (c *ConverterImpl) ConvertHouse(source execution.DBHouseNames) execution.APIHouseNames { var slices_arraysAPIHouseNames execution.APIHouseNames - var stringList []string if source.Names != nil { - var stringList2 []string + var stringList []string if (*source.Names) != nil { - stringList2 = make([]string, len((*source.Names))) + stringList = make([]string, len((*source.Names))) for i := 0; i < len((*source.Names)); i++ { - stringList2[i] = (*source.Names)[i] + stringList[i] = (*source.Names)[i] } } - stringList = stringList2 + slices_arraysAPIHouseNames.Names = stringList } - slices_arraysAPIHouseNames.Names = stringList return slices_arraysAPIHouseNames } diff --git a/scenario/use_zerovalue_on_pointer_inconsistency_struct.yml b/scenario/use_zerovalue_on_pointer_inconsistency_struct.yml index 5f60a188..ee90a46e 100644 --- a/scenario/use_zerovalue_on_pointer_inconsistency_struct.yml +++ b/scenario/use_zerovalue_on_pointer_inconsistency_struct.yml @@ -42,11 +42,9 @@ success: var structsAPIPersonInfo execution.APIPersonInfo if source != nil { var structsAPIPersonInfo2 execution.APIPersonInfo - var xstring string if (*source).FirstName != nil { - xstring = *(*source).FirstName + structsAPIPersonInfo2.FirstName = *(*source).FirstName } - structsAPIPersonInfo2.FirstName = xstring structsAPIPersonInfo = structsAPIPersonInfo2 } return structsAPIPersonInfo diff --git a/scenario/use_zerovalue_on_pointer_inconsistency_unnamed.yml b/scenario/use_zerovalue_on_pointer_inconsistency_unnamed.yml index 46a080af..46caa4e4 100644 --- a/scenario/use_zerovalue_on_pointer_inconsistency_unnamed.yml +++ b/scenario/use_zerovalue_on_pointer_inconsistency_unnamed.yml @@ -27,16 +27,12 @@ success: func (c *ConverterImpl) ConvertPerson(source execution.Input) execution.Output { var structsOutput execution.Output - var unnamed struct { - Name string - } if source.Thing != nil { - var unnamed2 struct { + var unnamed struct { Name string } - unnamed2.Name = (*source.Thing).Name - unnamed = unnamed2 + unnamed.Name = (*source.Thing).Name + structsOutput.Thing = unnamed } - structsOutput.Thing = unnamed return structsOutput } diff --git a/scenario/wrap_errors_using_nested.yml b/scenario/wrap_errors_using_nested.yml index 77ac9c38..04385ce2 100644 --- a/scenario/wrap_errors_using_nested.yml +++ b/scenario/wrap_errors_using_nested.yml @@ -40,19 +40,13 @@ success: func (c *ConverterImpl) Convert(source execution.Input) (execution.Output, error) { var structsOutput execution.Output - var mapStringMapIntUnnamed map[string]map[int]struct { - Age int - } if source.Values != nil { - mapStringMapIntUnnamed = make(map[string]map[int]struct { + structsOutput.Values = make(map[string]map[int]struct { Age int }, len(source.Values)) for key, value := range source.Values { - var mapIntUnnamed map[int]struct { - Age int - } if value != nil { - mapIntUnnamed = make(map[int]struct { + structsOutput.Values[key] = make(map[int]struct { Age int }, len(value)) for key2, value2 := range value { @@ -64,35 +58,29 @@ success: return structsOutput, patherr.Wrap(err, patherr.Field("Values"), patherr.Key(key), patherr.Key(key2), patherr.Field("Age")) } unnamed.Age = xint - mapIntUnnamed[key2] = unnamed + structsOutput.Values[key][key2] = unnamed } } - mapStringMapIntUnnamed[key] = mapIntUnnamed } } - structsOutput.Values = mapStringMapIntUnnamed var unnamed2 struct { Names []map[bool]int } - var mapBoolIntList []map[bool]int if source.S.Names != nil { - mapBoolIntList = make([]map[bool]int, len(source.S.Names)) + unnamed2.Names = make([]map[bool]int, len(source.S.Names)) for i := 0; i < len(source.S.Names); i++ { - var mapBoolInt map[bool]int if source.S.Names[i] != nil { - mapBoolInt = make(map[bool]int, len(source.S.Names[i])) + unnamed2.Names[i] = make(map[bool]int, len(source.S.Names[i])) for key3, value3 := range source.S.Names[i] { xint2, err := strconv.Atoi(value3) if err != nil { return structsOutput, patherr.Wrap(err, patherr.Field("S"), patherr.Field("Names"), patherr.Index(i), patherr.Key(key3)) } - mapBoolInt[key3] = xint2 + unnamed2.Names[i][key3] = xint2 } } - mapBoolIntList[i] = mapBoolInt } } - unnamed2.Names = mapBoolIntList structsOutput.S = unnamed2 return structsOutput, nil }