genbindings: support protected methods

This commit is contained in:
mappu 2024-11-11 18:27:15 +13:00
parent 47d4581628
commit 9b37750d64

View File

@ -185,6 +185,14 @@ func processTypedef(node map[string]interface{}, addNamePrefix string) (CppTyped
return CppTypedef{}, errors.New("processTypedef: ???")
}
type visibilityState int
const (
VsPublic visibilityState = 1
VsProtected = 2
VsPrivate = 3
)
// processClassType parses a single C++ class definition into our intermediate format.
func processClassType(node map[string]interface{}, addNamePrefix string) (CppClass, error) {
var ret CppClass
@ -229,10 +237,10 @@ func processClassType(node map[string]interface{}, addNamePrefix string) (CppCla
}
}
// Check if this was 'struct' (default visible) or 'class' (default invisible)
visibility := true
// Check if this was 'struct' (default public) or 'class' (default private)
visibility := VsPublic
if tagUsed, ok := node["tagUsed"].(string); ok && tagUsed == "class" {
visibility = false
visibility = VsPrivate
}
// Check if this is an abstract class
@ -289,9 +297,11 @@ nextMethod:
switch access {
case "public":
visibility = true
case "private", "protected":
visibility = false
visibility = VsPublic
case "protected":
visibility = VsProtected
case "private":
visibility = VsPrivate
default:
panic("unexpected access visibility '" + access + "'")
}
@ -315,7 +325,7 @@ nextMethod:
// Child class type definition e.g. QAbstractEventDispatcher::TimerInfo
// Parse as a whole child class
if !visibility {
if visibility != VsPublic {
continue // Skip private/protected
}
@ -341,7 +351,7 @@ nextMethod:
case "EnumDecl":
// Child class enum
if !visibility {
if visibility != VsPublic {
continue // Skip private/protected
}
@ -359,7 +369,7 @@ nextMethod:
// This is an implicit ctor. Therefore the class is constructable
// even if we're currently in a `private:` block.
} else if !visibility {
} else if visibility != VsPublic {
continue // Skip private/protected
}
@ -403,7 +413,8 @@ nextMethod:
continue
}
if !visibility {
if visibility != VsPublic {
// TODO Is there any use case for allowing MIQT to overload a virtual destructor?
ret.CanDelete = false
continue
}
@ -415,8 +426,12 @@ nextMethod:
}
case "CXXMethodDecl":
if !visibility {
continue // Skip private/protected
// If this is a virtual method, we want to allow overriding it even
// if it is protected
// But we can only call it if it is public
if visibility == VsPrivate {
continue // Skip private, ALLOW protected
}
// Check if this is `= delete`
@ -648,6 +663,10 @@ func parseMethod(node map[string]interface{}, mm *CppMethod) error {
mm.IsStatic = true
}
if virtual, ok := node["virtual"].(bool); ok && virtual {
mm.IsVirtual = true
}
if methodInner, ok := node["inner"].([]interface{}); ok {
paramCounter := 0
for _, methodObj := range methodInner {