genbindings: improvements for deleted ctors/dtors/overloads

This commit is contained in:
mappu 2024-08-20 20:10:57 +12:00
parent 2e2b436a51
commit 1ea3f220e6
5 changed files with 34 additions and 17 deletions

View File

@ -146,6 +146,7 @@ func parseHeader(topLevel []interface{}) (*CppParsedHeader, error) {
func processClassType(node map[string]interface{}, className string) (CppClass, error) {
var ret CppClass
ret.ClassName = className
ret.CanDelete = true
inner, _ := node["inner"].([]interface{}) // Cannot fail, the parent call already checked that `inner` was present
@ -241,7 +242,7 @@ nextMethod:
}
// Check if this is `= delete`
if explicitlyDeleted, ok := node["explicitlyDeleted"].(bool); ok && explicitlyDeleted {
if isExplicitlyDeleted(node) {
continue
}
@ -270,6 +271,19 @@ nextMethod:
case "CXXDestructorDecl":
// We don't need to expose destructors in the binding beyond offering
// a regular delete function
// However if this destructor is private or deleted, we should
// not bind it
if !visibility {
ret.CanDelete = false
continue
}
// Check if this is `= delete`
if isExplicitlyDeleted(node) {
ret.CanDelete = false
continue
}
case "CXXMethodDecl":
if !visibility {
@ -277,7 +291,7 @@ nextMethod:
}
// Check if this is `= delete`
if explicitlyDeleted, ok := node["explicitlyDeleted"].(bool); ok && explicitlyDeleted {
if isExplicitlyDeleted(node) {
continue
}
@ -334,6 +348,20 @@ nextMethod:
return ret, nil // done
}
// isExplicitlyDeleted checks if this node is marked `= delete`.
func isExplicitlyDeleted(node map[string]interface{}) bool {
if explicitlyDeleted, ok := node["explicitlyDeleted"].(bool); ok && explicitlyDeleted {
return true
}
if explicitlyDefaulted, ok := node["explicitlyDefaulted"].(string); ok && explicitlyDefaulted == "deleted" {
return true
}
return false
}
var ErrTooComplex error = errors.New("Type declaration is too complex to parse")
func parseMethod(node map[string]interface{}, mm *CppMethod) error {

View File

@ -394,7 +394,7 @@ extern "C" {
}
// delete
if AllowDelete(c) {
if c.CanDelete {
ret.WriteString(fmt.Sprintf("void %s_Delete(%s* self);\n", c.ClassName, c.ClassName))
}
@ -562,7 +562,7 @@ extern "C" {
}
// Delete
if AllowDelete(c) {
if c.CanDelete {
ret.WriteString(fmt.Sprintf(
"void %s_Delete(%s* self) {\n"+
"\tdelete self;\n"+

View File

@ -400,7 +400,7 @@ import "C"
}
}
if AllowDelete(c) {
if c.CanDelete {
ret.WriteString(`
func (this *` + c.ClassName + `) Delete() {
C.` + c.ClassName + `_Delete(this.h)

View File

@ -39,18 +39,6 @@ func AllowHeader(fullpath string) bool {
return true
}
func AllowDelete(c CppClass) bool {
switch c.ClassName {
case "QClipboard",
"QSessionManager",
"QTextObject",
"QTextBlockGroup",
"QInputMethod":
return false // The destructor is marked private. TODO grab this from the AST
}
return true
}
func ImportHeaderForClass(className string) bool {
if className[0] != 'Q' {
return false

View File

@ -169,6 +169,7 @@ type CppClass struct {
Inherits []string // other class names
Methods []CppMethod
Props []CppProperty
CanDelete bool
}
type CppTypedef struct {