in lib/collections.go [732:792]
func dropEmpty(val ref.Val) ref.Val {
obj, ok := val.(iterator)
if !ok || !hasEmpty(obj) {
return val
}
switch obj := val.(type) {
case traits.Lister:
new := make([]ref.Val, 0, obj.Size().Value().(int64))
it := obj.Iterator()
for it.HasNext() == types.True {
elem := it.Next()
switch val := elem.(type) {
case iterator:
if val.Size() != types.IntZero {
res := dropEmpty(val)
if v, ok := res.(traits.Sizer); ok {
if v.Size() != types.IntZero {
new = append(new, res)
}
} else {
new = append(new, res)
}
}
default:
new = append(new, val)
}
}
return types.NewRefValList(types.DefaultTypeAdapter, new)
case traits.Mapper:
new := make(map[ref.Val]ref.Val)
m, err := obj.ConvertToNative(refValMap)
if err != nil {
return types.NewErr("unable to convert map to native: %v", err)
}
for k, v := range m.(map[ref.Val]ref.Val) {
switch val := v.(type) {
case iterator:
if val.Size() != types.IntZero {
res := dropEmpty(v)
if v, ok := res.(traits.Sizer); ok {
if v.Size() != types.IntZero {
new[k] = res
}
} else {
new[k] = res
}
}
default:
new[k] = v
}
}
return types.NewRefValMap(types.DefaultTypeAdapter, new)
default:
// This should never happen since non-iterator
// types will have been returned in the preamble.
return val
}
}