func isRecursiveStruct()

in codegen/type_converter.go [1257:1290]


func isRecursiveStruct(spec compile.TypeSpec, seenSoFar map[string]bool) bool {
	switch t := spec.(type) {
	case *compile.StructSpec:
		// detected cycle; second time seeing this type
		if _, found := seenSoFar[t.Name]; found {
			return true
		}

		// mark this type as seen
		seenSoFar[t.Name] = true

		// search all fields of this struct
		for _, field := range t.Fields {
			if isRecursiveStruct(field.Type, seenSoFar) {
				return true
			}
		}

		// unmark
		delete(seenSoFar, t.Name)

	// for lists and maps, check element/key types the same way
	case *compile.MapSpec:
		if isRecursiveStruct(t.KeySpec, seenSoFar) || isRecursiveStruct(t.ValueSpec, seenSoFar) {
			return true
		}
	case *compile.ListSpec:
		if isRecursiveStruct(t.ValueSpec, seenSoFar) {
			return true
		}
	}

	return false
}