genbindings/inherits: direct vs indirect inheritance

This commit is contained in:
mappu 2024-11-19 19:24:50 +13:00
parent 73089d5120
commit 8d1c871de3
3 changed files with 40 additions and 10 deletions

View File

@ -265,7 +265,7 @@ func processClassType(node map[string]interface{}, addNamePrefix string) (CppCla
if typ, ok := base["type"].(map[string]interface{}); ok {
if qualType, ok := typ["qualType"].(string); ok {
ret.Inherits = append(ret.Inherits, qualType)
ret.DirectInherits = append(ret.DirectInherits, qualType)
}
}
}

View File

@ -709,7 +709,9 @@ import "C"
`)
// Embed all inherited types to directly allow calling inherited methods
for _, base := range c.Inherits {
// Only include the direct inherits; the recursive inherits will exist
// on these types already
for _, base := range c.DirectInherits {
if pkg, ok := KnownClassnames[base]; ok && pkg.PackageName != gfs.currentPackageName {
// Cross-package parent class

View File

@ -375,7 +375,7 @@ type CppClass struct {
ClassName string
Abstract bool
Ctors []CppMethod // only use the parameters
Inherits []string // other class names
DirectInherits []string // other class names. This only includes direct inheritance - use AllInherits() to find recursive inheritance
Methods []CppMethod
Props []CppProperty
CanDelete bool
@ -431,7 +431,10 @@ func (c *CppClass) VirtualMethods() []CppMethod {
retNames[m.CppCallTarget()] = struct{}{}
}
for _, inh := range c.Inherits {
// Only allow virtual overrides for direct inherits, not all inherits -
// Go will automatically allow virtual overrides for the base type because
// the parent struct is nested
for _, inh := range c.DirectInherits { // AllInherits() {
cinfo, ok := KnownClassnames[inh]
if !ok {
panic("Class " + c.ClassName + " inherits from unknown class " + inh)
@ -481,6 +484,31 @@ func (c *CppClass) VirtualMethods() []CppMethod {
return ret
}
// AllInherits recursively finds and lists all the parent classes of this class.
func (c *CppClass) AllInherits() []string {
var ret []string
// FIXME prevent duplicates arising from diamond inheritance
for _, baseClass := range c.DirectInherits {
ret = append(ret, baseClass)
// And everything that class inherits - unless - we've seen it before
baseClassInfo, ok := KnownClassnames[baseClass]
if !ok {
panic("Class " + c.ClassName + " inherits from unknown class " + baseClass)
}
recurseInfo := baseClassInfo.Class.AllInherits()
for _, childClass := range recurseInfo {
ret = append(ret, childClass)
}
}
return ret
}
type CppTypedef struct {
Alias string
UnderlyingType CppParameter