Protect 'Reference' against recursive type definitions
@@ -282,7 +282,7 @@ func (a *AttributeExpr) Inherit(parent *AttributeExpr) {
a.Type = &Object{}
}
a.inheritValidations(parent)
- a.inheritRecursive(parent)
+ a.inheritRecursive(parent, make(map[*AttributeExpr]struct{}))
}
// AllRequired returns the list of all required fields from the underlying
@@ -500,7 +500,7 @@ func (a *AttributeExpr) validateEnumDefault(ctx string, parent eval.Expression)
return verr
}
-func (a *AttributeExpr) inheritRecursive(parent *AttributeExpr) {
+func (a *AttributeExpr) inheritRecursive(parent *AttributeExpr, seen map[*AttributeExpr]struct{}) {
if !a.shouldInherit(parent) {
return
}
@@ -517,8 +517,15 @@ func (a *AttributeExpr) inheritRecursive(parent *AttributeExpr) {
if att.Type == nil {
att.Type = patt.Type
} else if att.shouldInherit(patt) {
+ if _, ok := seen[att]; ok {
+ continue
+ }
+ seen[att] = struct{}{}
for _, nat := range *AsObject(att.Type) {
- nat.Attribute.Inherit(AsObject(patt.Type).Attribute(nat.Name))
+ child := nat.Attribute
+ parent := AsObject(patt.Type).Attribute(nat.Name)
+ child.inheritValidations(parent)
+ child.inheritRecursive(parent, seen)
}
}
}
