Skip to content

Commit

Permalink
Merge pull request #301 from asteris-llc/fix/294-field-name-conflicts
Browse files Browse the repository at this point in the history
Fix/294 field name conflicts
  • Loading branch information
rebeccaskinner authored Sep 22, 2016
2 parents bc9ac04 + 16466c6 commit c976f52
Show file tree
Hide file tree
Showing 2 changed files with 453 additions and 215 deletions.
20 changes: 13 additions & 7 deletions render/preprocessor/preprocessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ func EvalTerms(obj interface{}, terms ...string) (interface{}, error) {
// a struct.
func fieldMap(val interface{}) (map[string]string, error) {
fieldMap := make(map[string]string)
conflictMap := make(map[string]struct{})
var t reflect.Type
switch typed := val.(type) {
case reflect.Type:
Expand All @@ -277,33 +278,38 @@ func fieldMap(val interface{}) (map[string]string, error) {
if t.Kind() != reflect.Struct {
return nil, fmt.Errorf("cannot access fields of non-struct type %T", val)
}
return addFieldsToMap(fieldMap, t)
return addFieldsToMap(fieldMap, conflictMap, t)
}

func addFieldsToMap(m map[string]string, t reflect.Type) (map[string]string, error) {
func addFieldsToMap(m map[string]string, conflicts map[string]struct{}, t reflect.Type) (map[string]string, error) {
if cached, ok := fieldMapCache[t]; ok {
return cached, nil
}

for idx := 0; idx < t.NumField(); idx++ {
field := t.Field(idx)
if field.Anonymous {
lower := strings.ToLower(field.Name)
if _, ok := m[lower]; !ok {
m[lower] = field.Name
}
var err error
anonType := interfaceToConcreteType(field.Type)
if anonType.Kind() == reflect.Struct {
if m, err = addFieldsToMap(m, anonType); err != nil {
if m, err = addFieldsToMap(m, conflicts, anonType); err != nil {
return nil, err
}
}
continue
}

name := field.Name
lower := strings.ToLower(name)
if _, ok := m[lower]; ok {
return nil, fmt.Errorf("multiple potential matches for %s", name)
conflicts[lower] = struct{}{}
} else {
if _, ok := conflicts[lower]; !ok {
m[lower] = name
}
}
m[lower] = name
}
fieldMapCache[t] = m
return m, nil
Expand Down
Loading

0 comments on commit c976f52

Please sign in to comment.