func CompareStruct()

in dev/tools/controllerbuilder/pkg/io/compare.go [62:151]


func CompareStruct(code, otherCode string, factors ...string) (*Results, error) {
	aFset := token.NewFileSet()
	aFile, err := parser.ParseFile(aFset, "", code, parser.ParseComments)
	if err != nil {
		return nil, fmt.Errorf("parsing first go code snippet: %w", err)
	}

	bFset := token.NewFileSet()
	// Make sure src package exists otherwise the parser will fail
	_, _, found := strings.Cut(otherCode, "package")
	if !found {
		otherCode = "package main" + "\n" + otherCode
	}
	bFile, err := parser.ParseFile(bFset, "", otherCode, parser.ParseComments)
	if err != nil {
		return nil, fmt.Errorf("parsing second go code snippet: %w", err)
	}

	compareAll := false
	if factors == nil {
		compareAll = true
	}

	pairMap := make(map[string]*structPair)
	for _, c := range factors {
		pairMap[c] = &structPair{}
	}

	ast.Inspect(aFile, func(n ast.Node) bool {
		x, ok := n.(*ast.GenDecl)
		if !ok || x.Tok != token.TYPE {
			return true
		}

		for _, spec := range x.Specs {
			typeSpec, ok := spec.(*ast.TypeSpec)
			if !ok {
				continue
			}
			// record A for comparison
			if pair, ok := pairMap[typeSpec.Name.Name]; compareAll || ok {
				structType, typeOk := typeSpec.Type.(*ast.StructType)
				if !typeOk {
					continue
				}
				if pair == nil {
					pair = &structPair{}
				}
				pair.A = structType
				pairMap[typeSpec.Name.Name] = pair
			}
		}
		return true
	})

	ast.Inspect(bFile, func(n ast.Node) bool {
		x, ok := n.(*ast.GenDecl)
		if !ok || x.Tok != token.TYPE {
			return true
		}

		for _, spec := range x.Specs {
			typeSpec, ok := spec.(*ast.TypeSpec)
			if !ok {
				continue
			}
			// record B for comparison
			if pair, ok := pairMap[typeSpec.Name.Name]; compareAll || ok {
				structType, typeOk := typeSpec.Type.(*ast.StructType)
				if !typeOk {
					continue
				}
				if pair == nil {
					pair = &structPair{}
				}
				pair.B = structType
				pairMap[typeSpec.Name.Name] = pair
			}
		}
		return true
	})

	results := &Results{}
	for name, pair := range pairMap {
		r := compareFields(pair)
		fmt.Println("Compare: ", name, "Result: ", r)
		*results = append(*results, *r)
	}
	return results, nil
}