genbindings: add namespaces support

This commit is contained in:
mappu 2024-08-27 19:12:08 +12:00
parent a5104aa614
commit 164ef8cb6c
3 changed files with 42 additions and 11 deletions

View File

@ -7,7 +7,7 @@ import (
"strings"
)
func parseHeader(topLevel []interface{}) (*CppParsedHeader, error) {
func parseHeader(topLevel []interface{}, addNamePrefix string) (*CppParsedHeader, error) {
var ret CppParsedHeader
@ -28,7 +28,7 @@ func parseHeader(topLevel []interface{}) (*CppParsedHeader, error) {
case "CXXRecordDecl":
// Process the inner class definition
obj, err := processClassType(node, "")
obj, err := processClassType(node, addNamePrefix)
if err != nil {
if errors.Is(err, ErrNoContent) {
log.Printf("-> Skipping (%v)\n", err)
@ -59,7 +59,30 @@ func parseHeader(topLevel []interface{}) (*CppParsedHeader, error) {
// ignore
case "NamespaceDecl":
// ignore
// Parse everything inside the namespace with prefix, as if it is
// a whole separate file
// Then copy the parsed elements back into our own file
namespace, ok := node["name"].(string)
if !ok {
panic("NamespaceDecl missing name")
}
namespaceInner, ok := node["inner"].([]interface{})
if !ok {
// A namespace declaration with no inner content means that, for
// the rest of this whole file, we are in this namespace
// Update our own `addNamePrefix` accordingly
addNamePrefix += namespace + "::"
} else {
contents, err := parseHeader(namespaceInner, namespace+"::")
if err != nil {
panic(err)
}
ret.AddContentFrom(contents)
}
case "FunctionDecl":
// TODO
@ -84,16 +107,15 @@ func parseHeader(topLevel []interface{}) (*CppParsedHeader, error) {
// TODO e.g. qfuturewatcher.h
// Probably can't be supported in the Go binding
case "TypeAliasDecl":
// TODO e.g. qglobal.h
// Should be treated like a typedef
case "UsingDirectiveDecl":
// TODO e.g. qtextstream.h
case "TypeAliasDecl", // qglobal.h
"UsingDirectiveDecl", // qtextstream.h
"UsingDecl", // qglobal.h
"UsingShadowDecl": // global.h
// TODO e.g.
// Should be treated like a typedef
case "TypedefDecl":
td, err := processTypedef(node, "")
td, err := processTypedef(node, addNamePrefix)
if err != nil {
return nil, fmt.Errorf("processTypedef: %w", err)
}
@ -103,6 +125,9 @@ func parseHeader(topLevel []interface{}) (*CppParsedHeader, error) {
// A C++ class method implementation directly in the header
// Skip over these
case "FullComment":
// Safe to skip
default:
return nil, fmt.Errorf("missing handling for clang ast node type %q", kind)
}

View File

@ -273,3 +273,9 @@ func (c CppParsedHeader) Empty() bool {
return len(c.Typedefs) == 0 &&
len(c.Classes) == 0
}
func (c *CppParsedHeader) AddContentFrom(other *CppParsedHeader) {
c.Classes = append(c.Classes, other.Classes...)
c.Enums = append(c.Enums, other.Enums...)
c.Typedefs = append(c.Typedefs, other.Typedefs...)
}

View File

@ -124,7 +124,7 @@ func main() {
}
// Convert it to our intermediate format
parsed, err := parseHeader(astInner)
parsed, err := parseHeader(astInner, "")
if err != nil {
panic(err)
}