@@ -278,31 +278,78 @@ func convertPositionalToKeyed(f *dst.File, structDefs map[string][]string) {
278278 return true
279279 }
280280
281- if ! isPositionalLiteral (cl ) {
282- return true
283- }
281+ // Process this literal and all nested children
282+ processCompositeLit (cl , nil , structDefs )
284283
285- // Handle anonymous struct type
286- if st , ok := cl .Type .(* dst.StructType ); ok {
287- fieldNames := getFieldNamesFromStructType (st )
288- convertToKeyedLiteral (cl , fieldNames )
289- return true
290- }
284+ // Don't let dst.Inspect descend into children - we handle them
285+ return false
286+ })
287+ }
291288
292- // Handle named struct type
293- typeName := extractTypeName (cl .Type )
294- if typeName == "" {
295- return true
289+ func processCompositeLit (cl * dst.CompositeLit , inheritedFieldNames []string , structDefs map [string ][]string ) {
290+ // Determine field names for THIS literal
291+ fieldNames := resolveFieldNames (cl .Type , inheritedFieldNames , structDefs )
292+
293+ // Convert if positional and we know the field names
294+ if len (fieldNames ) > 0 && isPositionalLiteral (cl ) {
295+ convertToKeyedLiteral (cl , fieldNames )
296+ }
297+
298+ // Determine field names to pass to children (from element type)
299+ childFieldNames := getElementFieldNames (cl .Type , structDefs )
300+
301+ // Process all child elements
302+ for _ , elt := range cl .Elts {
303+ processElement (elt , childFieldNames , structDefs )
304+ }
305+ }
306+
307+ func processElement (elt dst.Expr , inheritedFieldNames []string , structDefs map [string ][]string ) {
308+ switch e := elt .(type ) {
309+ case * dst.CompositeLit :
310+ processCompositeLit (e , inheritedFieldNames , structDefs )
311+ case * dst.KeyValueExpr :
312+ // Value might be a composite literal (map values, struct fields)
313+ if child , ok := e .Value .(* dst.CompositeLit ); ok {
314+ processCompositeLit (child , inheritedFieldNames , structDefs )
296315 }
316+ }
317+ }
297318
298- fieldNames , exists := structDefs [typeName ]
299- if ! exists {
300- // Type not in this file - leave untouched
301- return true
319+ func resolveFieldNames (t dst.Expr , inherited []string , structDefs map [string ][]string ) []string {
320+ if t == nil {
321+ return inherited
322+ }
323+
324+ // Anonymous struct type
325+ if st , ok := t .(* dst.StructType ); ok {
326+ return getFieldNamesFromStructType (st )
327+ }
328+
329+ // Named type
330+ if typeName := extractTypeName (t ); typeName != "" {
331+ if names , exists := structDefs [typeName ]; exists {
332+ return names
302333 }
334+ }
303335
304- convertToKeyedLiteral (cl , fieldNames )
336+ return nil
337+ }
305338
306- return true
307- })
339+ func getElementFieldNames (t dst.Expr , structDefs map [string ][]string ) []string {
340+ if t == nil {
341+ return nil
342+ }
343+
344+ // Slice/array: []T or [N]T
345+ if at , ok := t .(* dst.ArrayType ); ok {
346+ return resolveFieldNames (at .Elt , nil , structDefs )
347+ }
348+
349+ // Map: map[K]V - return value type's field names
350+ if mt , ok := t .(* dst.MapType ); ok {
351+ return resolveFieldNames (mt .Value , nil , structDefs )
352+ }
353+
354+ return nil
308355}
0 commit comments