Example #1
0
// Returns which field index is an embedded storable.Document, or -1 if none.
func (p *Processor) processFields(s *types.Struct, done []*types.Struct) (base int, fields []*Field) {
	c := s.NumFields()

	base = -1
	fields = make([]*Field, 0)

	for i := 0; i < c; i++ {
		f := s.Field(i)
		if !f.Exported() {
			continue
		}

		t := reflect.StructTag(s.Tag(i))
		if f.Type().String() == BaseDocument {
			base = i
		}

		field := NewField(f.Name(), f.Type().Underlying().String(), t)
		field.CheckedNode = f
		str := p.tryGetStruct(f.Type())
		if f.Type().String() != BaseDocument && str != nil {
			field.Type = getStructType(f.Type())

			d := false
			for _, v := range done {
				if v == str {
					d = true
					break
				}
			}
			if !d {
				_, subfs := p.processFields(str, append(done, str))
				field.SetFields(subfs)
			}
		}

		fields = append(fields, field)
	}

	return base, fields
}
Example #2
0
//iterate over a struct's fields recursively and add its fields to the candidate list
func findStructFields(str *types.Struct, prefix string, fset *token.FileSet) []UnexportCandidate {
	candidates := []UnexportCandidate{}
	for i := 0; i < str.NumFields(); i++ {
		field := str.Field(i)
		if !field.Exported() || field.Anonymous() {
			continue
		}
		// Tags are a likely indicator that this field is used by something
		// like json or xml that uses reflection. Skip it to be safe.
		// TODO: override flag? whitelist?
		if str.Tag(i) != "" {
			continue
		}
		candidate := UnexportCandidate{field.Name(), prefix + "." + field.Name(), fset.Position(field.Pos())}
		candidates = append(candidates, candidate)
		if nested, ok := field.Type().(*types.Struct); ok {
			candidates = append(candidates, findStructFields(nested, candidate.DisplayName, fset)...)
		}
	}
	return candidates
}
Example #3
0
func Struct(path string, st reflect.StructTag, u *types.Struct, named *types.Named) IObj {
	rv := IStruct{}
	rv.name = strings.Split(st.Get("json"), ",")[0]
	rv.typ = getname(named, u)
	rv.description = st.Get("description")
	rv.path = pathAppend(path, rv.name)

	for i := 0; i < u.NumFields(); i++ {
		rv2 := dump(rv.path, u.Field(i).Type(), reflect.StructTag(u.Tag(i)))
		if rv2 == nil {
			continue
		}
		if st, ok := rv2.(IStruct); ok && st.name == "" {
			for _, j := range st.items {
				rv.items = append(rv.items, j)
			}
		} else {
			rv.items = append(rv.items, rv2)
		}
	}

	return rv
}
Example #4
0
func (p *Processor) processFields(s *types.Struct) int {
	c := s.NumFields()

	base := -1
	fields := make([]*Field, 0)
	if _, ok := p.fieldsForStr[s]; !ok {
		p.fieldsForStr[s] = &fields
	}

	for i := 0; i < c; i++ {
		f := s.Field(i)
		if !f.Exported() {
			continue
		}

		t := reflect.StructTag(s.Tag(i))
		if f.Type().String() == BaseDocument {
			base = i
		}

		field := NewField(f.Name(), f.Type().Underlying().String(), t)
		str := p.tryGetStruct(f.Type())
		if f.Type().String() != BaseDocument && str != nil {
			field.Type = getStructType(f.Type())
			field.CheckedNode = f
			_, ok := p.fieldsForStr[str]
			if !ok {
				p.processFields(str)
			}
		}

		fields = append(fields, field)
	}

	return base
}