From c36d14c540603cbcef2cc25e99522be6066f405f Mon Sep 17 00:00:00 2001 From: mappu Date: Sat, 23 Nov 2024 19:32:09 +1300 Subject: [PATCH] genbindings: allow some classes to inherit from QList<> --- cmd/genbindings/config-allowlist.go | 8 +++--- cmd/genbindings/emitgo.go | 12 ++++----- cmd/genbindings/intermediate.go | 42 ++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/cmd/genbindings/config-allowlist.go b/cmd/genbindings/config-allowlist.go index a391fd5a..9c124e3c 100644 --- a/cmd/genbindings/config-allowlist.go +++ b/cmd/genbindings/config-allowlist.go @@ -146,10 +146,10 @@ func AllowClass(className string) bool { switch className { case - "QTextStreamManipulator", // Only seems to contain garbage methods - "QException", // Extends std::exception, too hard - "QUnhandledException", // As above (child class) - "QItemSelection", // Extends a QList<>, too hard + "QTextStreamManipulator", // Only seems to contain garbage methods + "QException", // Extends std::exception, too hard + "QUnhandledException", // As above (child class) + // "QItemSelection", // Extends a QList<>, too hard "QXmlStreamAttributes", // Extends a QList<>, too hard "QPolygon", // Extends a QVector template class, too hard "QPolygonF", // Extends a QVector template class, too hard diff --git a/cmd/genbindings/emitgo.go b/cmd/genbindings/emitgo.go index 03f69ff0..2eaf9b27 100644 --- a/cmd/genbindings/emitgo.go +++ b/cmd/genbindings/emitgo.go @@ -738,7 +738,10 @@ import "C" // on these types already for _, base := range c.DirectInherits { - if pkg, ok := KnownClassnames[base]; ok && pkg.PackageName != gfs.currentPackageName { + if strings.HasPrefix(base, `QList<`) { + ret.WriteString("/* Also inherits unprojectable " + base + " */\n") + + } else if pkg, ok := KnownClassnames[base]; ok && pkg.PackageName != gfs.currentPackageName { // Cross-package parent class ret.WriteString("*" + path.Base(pkg.PackageName) + "." + cabiClassName(base) + "\n") gfs.imports[importPathForQtPackage(pkg.PackageName)] = struct{}{} @@ -788,12 +791,9 @@ import "C" extraUnsafeArgs += ", h_" + cabiClassName(base) + " unsafe.Pointer" } - for _, base := range c.DirectInherits { + for _, pkg := range c.DirectInheritClassInfo() { ctorPrefix := "" - pkg, ok := KnownClassnames[base] - if !ok { - panic("Class " + c.ClassName + " has unknown parent " + base) - } + base := pkg.Class.ClassName constructRequiresParams := pkg.Class.AllInherits() var ixxParams []string = make([]string, 0, len(constructRequiresParams)+1) diff --git a/cmd/genbindings/intermediate.go b/cmd/genbindings/intermediate.go index d6c30637..9346f788 100644 --- a/cmd/genbindings/intermediate.go +++ b/cmd/genbindings/intermediate.go @@ -435,10 +435,12 @@ func (c *CppClass) VirtualMethods() []CppMethod { // 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) + for _, cinfo := range c.DirectInheritClassInfo() { + + // If a base class is permanently unprojectable, the child classes + // should be too + if !AllowVirtualForClass(cinfo.Class.ClassName) { + return nil } for _, m := range cinfo.Class.Methods { @@ -491,15 +493,9 @@ func (c *CppClass) AllInherits() []string { // FIXME prevent duplicates arising from diamond inheritance - for _, baseClass := range c.DirectInherits { + for _, baseClassInfo := range c.DirectInheritClassInfo() { - 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) - } + ret = append(ret, baseClassInfo.Class.ClassName) recurseInfo := baseClassInfo.Class.AllInherits() for _, childClass := range recurseInfo { @@ -510,6 +506,28 @@ func (c *CppClass) AllInherits() []string { return ret } +// DirectInheritClassInfo looks up the CppClass for each entry in DirectInherits. +func (c *CppClass) DirectInheritClassInfo() []lookupResultClass { + var ret []lookupResultClass + + for _, inh := range c.DirectInherits { // AllInherits() { + cinfo, ok := KnownClassnames[inh] + if !ok { + if strings.HasPrefix(inh, `QList<`) { + // OK, allow this one to slip through + // e.g. QItemSelection extends a QList<> + continue + } else { + panic("Class " + c.ClassName + " inherits from unknown class " + inh) + } + } + + ret = append(ret, cinfo) + } + + return ret +} + type CppTypedef struct { Alias string UnderlyingType CppParameter