mirror of
https://github.com/mappu/miqt.git
synced 2024-12-22 17:08:38 +00:00
genbindings: track private methods, exclude from virtual overrides
This commit is contained in:
parent
aa2fdf98ca
commit
d25301c910
@ -351,8 +351,8 @@ nextMethod:
|
|||||||
case "EnumDecl":
|
case "EnumDecl":
|
||||||
// Child class enum
|
// Child class enum
|
||||||
|
|
||||||
if visibility != VsPublic {
|
if visibility == VsPrivate {
|
||||||
continue // Skip private/protected
|
continue // Skip private, ALLOW protected
|
||||||
}
|
}
|
||||||
|
|
||||||
en, err := processEnum(node, nodename+"::")
|
en, err := processEnum(node, nodename+"::")
|
||||||
@ -427,10 +427,17 @@ nextMethod:
|
|||||||
|
|
||||||
case "CXXMethodDecl":
|
case "CXXMethodDecl":
|
||||||
|
|
||||||
|
// Method
|
||||||
|
methodName, ok := node["name"].(string)
|
||||||
|
if !ok {
|
||||||
|
return CppClass{}, errors.New("method has no name")
|
||||||
|
}
|
||||||
|
|
||||||
// If this is a virtual method, we want to allow overriding it even
|
// If this is a virtual method, we want to allow overriding it even
|
||||||
// if it is protected
|
// if it is protected
|
||||||
// But we can only call it if it is public
|
// But we can only call it if it is public
|
||||||
if visibility == VsPrivate {
|
if visibility == VsPrivate {
|
||||||
|
ret.PrivateMethods = append(ret.PrivateMethods, methodName)
|
||||||
continue // Skip private, ALLOW protected
|
continue // Skip private, ALLOW protected
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,12 +446,6 @@ nextMethod:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method
|
|
||||||
methodName, ok := node["name"].(string)
|
|
||||||
if !ok {
|
|
||||||
return CppClass{}, errors.New("method has no name")
|
|
||||||
}
|
|
||||||
|
|
||||||
var mm CppMethod
|
var mm CppMethod
|
||||||
mm.MethodName = methodName
|
mm.MethodName = methodName
|
||||||
|
|
||||||
|
@ -382,6 +382,7 @@ type CppClass struct {
|
|||||||
ChildTypedefs []CppTypedef
|
ChildTypedefs []CppTypedef
|
||||||
ChildClassdefs []CppClass
|
ChildClassdefs []CppClass
|
||||||
ChildEnums []CppEnum
|
ChildEnums []CppEnum
|
||||||
|
PrivateMethods []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Virtual checks if the class has any virtual methods. This requires global
|
// Virtual checks if the class has any virtual methods. This requires global
|
||||||
@ -390,6 +391,7 @@ type CppClass struct {
|
|||||||
func (c *CppClass) VirtualMethods() []CppMethod {
|
func (c *CppClass) VirtualMethods() []CppMethod {
|
||||||
var ret []CppMethod
|
var ret []CppMethod
|
||||||
var retNames = make(map[string]struct{}, 0) // if name is present, a child class found it first
|
var retNames = make(map[string]struct{}, 0) // if name is present, a child class found it first
|
||||||
|
var block = slice_to_set(c.PrivateMethods)
|
||||||
|
|
||||||
for _, m := range c.Methods {
|
for _, m := range c.Methods {
|
||||||
if !m.IsVirtual {
|
if !m.IsVirtual {
|
||||||
@ -426,9 +428,31 @@ func (c *CppClass) VirtualMethods() []CppMethod {
|
|||||||
continue // Already found in a child class
|
continue // Already found in a child class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It's possible that a child class marked a parent method as private
|
||||||
|
// (e.g. Qt 5 QAbstractTableModel marks parent() as private)
|
||||||
|
// But then we find the protected version further down
|
||||||
|
// Use a blocklist to prevent exposing any deeper methods in the call chain
|
||||||
|
if _, ok := block[m.MethodName]; ok {
|
||||||
|
continue // Marked as private in a child class
|
||||||
|
}
|
||||||
|
|
||||||
|
// The class info we loaded has not had all typedefs applied to it
|
||||||
|
// m is copied by value. Mutate it
|
||||||
|
applyTypedefs_Method(&m)
|
||||||
|
// Same with astTransformBlocklist
|
||||||
|
if !blocklist_MethodAllowed(&m) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
ret = append(ret, m)
|
ret = append(ret, m)
|
||||||
retNames[m.MethodName] = struct{}{}
|
retNames[m.MethodName] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Append this parent's private-virtuals to blocklist so that we
|
||||||
|
// do not consider them for grandparent classes
|
||||||
|
for _, privMethod := range c.PrivateMethods {
|
||||||
|
block[privMethod] = struct{}{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
@ -38,3 +38,11 @@ func ifv[T any](condition bool, trueval T, falseval T) T {
|
|||||||
func addr[T any](s T) *T {
|
func addr[T any](s T) *T {
|
||||||
return &s
|
return &s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func slice_to_set[T comparable](list []T) map[T]struct{} {
|
||||||
|
ret := make(map[T]struct{}, len(list))
|
||||||
|
for _, v := range list {
|
||||||
|
ret[v] = struct{}{}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user