From c9a4a47e1c707ced1e904b42a32ee6586dfd375c Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Fri, 26 Nov 2021 15:07:50 +0900 Subject: [PATCH] pass all test cases --- internal/encoder/code.go | 44 +++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/internal/encoder/code.go b/internal/encoder/code.go index 4faadcf..2ac8085 100644 --- a/internal/encoder/code.go +++ b/internal/encoder/code.go @@ -690,7 +690,9 @@ func (c *StructFieldCode) ToAnonymousOpcode(ctx *compileContext, isFirstField, i } flags := c.flags() flags |= AnonymousHeadFlags - flags |= AnonymousKeyFlags + if c.isAnonymous { + flags |= AnonymousKeyFlags + } field := &Opcode{ Idx: opcodeOffset(ctx.ptrIndex), Flags: flags, @@ -1304,13 +1306,41 @@ func getFieldMap(fields []*StructFieldCode) map[string][]*StructFieldCode { fieldMap := map[string][]*StructFieldCode{} for _, field := range fields { if field.isAnonymous { - structCode := field.getAnonymousStruct() - if structCode != nil && !structCode.isRecursive { - for k, v := range getFieldMap(structCode.fields) { - fieldMap[k] = append(fieldMap[k], v...) - } - continue + for k, v := range getAnonymousFieldMap(field) { + fieldMap[k] = append(fieldMap[k], v...) } + continue + } + fieldMap[field.key] = append(fieldMap[field.key], field) + } + return fieldMap +} + +func getAnonymousFieldMap(field *StructFieldCode) map[string][]*StructFieldCode { + fieldMap := map[string][]*StructFieldCode{} + structCode := field.getAnonymousStruct() + if structCode == nil || structCode.isRecursive { + fieldMap[field.key] = append(fieldMap[field.key], field) + return fieldMap + } + for k, v := range getFieldMapFromAnonymousParent(structCode.fields) { + fieldMap[k] = append(fieldMap[k], v...) + } + return fieldMap +} + +func getFieldMapFromAnonymousParent(fields []*StructFieldCode) map[string][]*StructFieldCode { + fieldMap := map[string][]*StructFieldCode{} + for _, field := range fields { + if field.isAnonymous { + for k, v := range getAnonymousFieldMap(field) { + // Do not handle tagged key when embedding more than once + for _, vv := range v { + vv.isTaggedKey = false + } + fieldMap[k] = append(fieldMap[k], v...) + } + continue } fieldMap[field.key] = append(fieldMap[field.key], field) }