genbindings: handle qualified/unqualified class inherit parent names

This commit is contained in:
mappu 2025-04-12 15:59:38 +12:00
parent 862bd100f4
commit e06fa37950
3 changed files with 54 additions and 20 deletions

View File

@ -193,6 +193,11 @@ const (
VsPrivate = 3
)
type ClassParentName struct {
Unqualified string
Qualified string
}
// processClassType parses a single C++ class definition into our intermediate format.
func processClassType(node map[string]interface{}, addNamePrefix string) (CppClass, error) {
var ret CppClass
@ -265,7 +270,15 @@ 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.DirectInherits = append(ret.DirectInherits, qualType)
// The name that we're inheriting may- or may not- be
// Even `qualType` doesn't necessarily figure this out
// for us
// Stash both the qualified + unqualified names for later
// resolution
ret.DirectInherits = append(ret.DirectInherits, ClassParentName{
Qualified: addNamePrefix + qualType,
Unqualified: qualType,
})
}
}
}

View File

@ -800,18 +800,15 @@ import "C"
// Embed all inherited types to directly allow calling inherited methods
// Only include the direct inherits; the recursive inherits will exist
// on these types already
for _, base := range c.DirectInherits {
for _, parentClass := range c.DirectInheritClassInfo() {
if strings.HasPrefix(base, `QList<`) {
ret.WriteString("/* Also inherits unprojectable " + base + " */\n")
} else if pkg, ok := KnownClassnames[base]; ok && pkg.PackageName != gfs.currentPackageName {
if parentClass.PackageName != gfs.currentPackageName {
// Cross-package parent class
ret.WriteString("*" + path.Base(pkg.PackageName) + "." + cabiClassName(base) + "\n")
gfs.imports[importPathForQtPackage(pkg.PackageName)] = struct{}{}
ret.WriteString("*" + path.Base(parentClass.PackageName) + "." + cabiClassName(parentClass.Class.ClassName) + "\n")
gfs.imports[importPathForQtPackage(parentClass.PackageName)] = struct{}{}
} else {
// Same-package parent class
ret.WriteString("*" + cabiClassName(base) + "\n")
ret.WriteString("*" + cabiClassName(parentClass.Class.ClassName) + "\n")
}
}

View File

@ -1,6 +1,7 @@
package main
import (
"fmt"
"log"
"regexp"
"strings"
@ -401,8 +402,8 @@ func (e CppEnum) ShortEnumName() string {
type CppClass struct {
ClassName string
Abstract bool
Ctors []CppMethod // only use the parameters
DirectInherits []string // other class names. This only includes direct inheritance - use AllInherits() to find recursive inheritance
Ctors []CppMethod // only use the parameters
DirectInherits []ClassParentName // other class names. This only includes direct inheritance - use AllInherits() to find recursive inheritance
Methods []CppMethod
Props []CppProperty
CanDelete bool
@ -621,18 +622,41 @@ func (c *CppClass) AllInheritsClassInfo() []lookupResultClass {
func (c *CppClass) DirectInheritClassInfo() []lookupResultClass {
var ret []lookupResultClass
nextInherit:
for _, inh := range c.DirectInherits {
cinfo, ok := KnownClassnames[inh]
if !ok {
if !AllowInheritedParent(inh) {
// OK, allow this one to slip through
continue
} else {
panic("Class " + c.ClassName + " inherits from unknown class " + inh)
}
// TODO expand to cover all unprojected container types?
if strings.HasPrefix(inh.Unqualified, `QList<`) {
continue
}
ret = append(ret, cinfo)
checkParents := []string{
inh.Qualified,
inh.Unqualified,
}
if nparts := strings.Split(inh.Qualified, `::`); len(nparts) == 4 {
// qtermwidget5: finds `Konsole::RegExpFilter::Filter::HotSpot` but
// needs to match Konsole (namespace) :: Filter::HotSpot
checkParents = append(checkParents, nparts[0]+`::`+nparts[2]+`::`+nparts[3])
}
for _, checkParent := range checkParents {
cinfo, ok := KnownClassnames[checkParent]
if ok {
ret = append(ret, cinfo)
continue nextInherit
}
if !AllowInheritedParent(checkParent) {
// OK, allow this one to slip through
continue nextInherit
}
// Name didn't match
}
// None of the names matched
panic(fmt.Sprintf("Class %q inherits from unknown class (tried: %v)", c.ClassName, checkParents))
}
return ret