genbindings: basic constructor support

This commit is contained in:
mappu 2024-08-10 12:52:45 +12:00
parent 545a819f81
commit aaa9340808
2 changed files with 95 additions and 72 deletions

View File

@ -98,10 +98,26 @@ nextMethod:
// Safe to ignore // Safe to ignore
case "CXXConstructorDecl": case "CXXConstructorDecl":
// panic("TODO")
var mm CppMethod
err := parseMethod(node, &mm)
if err != nil {
if errors.Is(err, ErrTooComplex) {
log.Printf("Skipping method %q with complex type", mm.MethodName)
continue nextMethod
}
// Real error
return CppClass{}, err
}
ret.Ctors = append(ret.Ctors, mm)
case "CXXDestructorDecl": case "CXXDestructorDecl":
// panic("TODO") // We don't need to expose destructors in the binding beyond offering
// a regular delete function
case "CXXMethodDecl": case "CXXMethodDecl":
if !visibility { if !visibility {
@ -121,6 +137,31 @@ nextMethod:
mm.MethodName = methodName[3:] mm.MethodName = methodName[3:]
} }
err := parseMethod(node, &mm)
if err != nil {
if errors.Is(err, ErrTooComplex) {
log.Printf("Skipping method %q with complex type", mm.MethodName)
continue nextMethod
}
// Real error
return CppClass{}, err
}
ret.Methods = append(ret.Methods, mm)
default:
fmt.Printf("==> NOT IMPLEMENTED %q\n", kind)
}
}
return ret, nil // done
}
var ErrTooComplex error = errors.New("Type declaration is too complex to parse")
func parseMethod(node map[string]interface{}, mm *CppMethod) error {
if typobj, ok := node["type"].(map[string]interface{}); ok { if typobj, ok := node["type"].(map[string]interface{}); ok {
if qualType, ok := typobj["qualType"].(string); ok { if qualType, ok := typobj["qualType"].(string); ok {
// The qualType is the whole type of the method, including its parameter types // The qualType is the whole type of the method, including its parameter types
@ -129,12 +170,7 @@ nextMethod:
var err error = nil var err error = nil
mm.ReturnType, mm.Parameters, err = parseTypeString(qualType) mm.ReturnType, mm.Parameters, err = parseTypeString(qualType)
if err != nil { if err != nil {
if errors.Is(err, ErrTooComplex) { return err
log.Printf("Skipping method %q with complex type %q", mm.MethodName, qualType)
continue nextMethod
}
// Real error
return CppClass{}, err
} }
} }
@ -145,7 +181,7 @@ nextMethod:
for _, methodObj := range methodInner { for _, methodObj := range methodInner {
methodObj, ok := methodObj.(map[string]interface{}) methodObj, ok := methodObj.(map[string]interface{})
if !ok { if !ok {
return CppClass{}, errors.New("inner[] element not an object") return errors.New("inner[] element not an object")
} }
switch methodObj["kind"] { switch methodObj["kind"] {
@ -184,22 +220,13 @@ nextMethod:
default: default:
// Something else inside a declaration?? // Something else inside a declaration??
fmt.Printf("==> NOT IMPLEMENTED CXXMethodDecl->%q\n", kind) fmt.Printf("==> NOT IMPLEMENTED CXXMethodDecl->%q\n", methodObj["kind"])
} }
} }
} }
ret.Methods = append(ret.Methods, mm) return nil
default:
fmt.Printf("==> NOT IMPLEMENTED %q\n", kind)
} }
}
return ret, nil // done
}
var ErrTooComplex error = errors.New("Type declaration is too complex to parse")
// parseTypeString converts a string like // parseTypeString converts a string like
// - `QString (const char *, const char *, int)` // - `QString (const char *, const char *, int)`

View File

@ -68,10 +68,6 @@ func emitParametersCabi(m CppMethod, selfType string) string {
// Go: converted to native Go string // Go: converted to native Go string
if m.ReturnType.ParameterType == "QString" { if m.ReturnType.ParameterType == "QString" {
tmp = append(tmp, "char** _out, size_t* _out_Strlen") tmp = append(tmp, "char** _out, size_t* _out_Strlen")
/*
} else if m.ReturnType.QtClassType() && !m.ReturnType.Pointer {
tmp = append(tmp, "P"+m.ReturnType.ParameterType+" _out")
*/
} }
return strings.Join(tmp, ", ") return strings.Join(tmp, ", ")
@ -167,7 +163,7 @@ extern "C" {
for _, c := range src.Classes { for _, c := range src.Classes {
for i, ctor := range c.Ctors { for i, ctor := range c.Ctors {
ret.WriteString(fmt.Sprintf("P%s %s_new%s(%s);\n", c.ClassName, maybeSuffix(i), emitParametersCabi(ctor, ""))) ret.WriteString(fmt.Sprintf("P%s %s_new%s(%s);\n", c.ClassName, c.ClassName, maybeSuffix(i), emitParametersCabi(ctor, "")))
} }
for _, m := range c.Methods { for _, m := range c.Methods {
@ -208,7 +204,7 @@ func emitBindingCpp(src *CppParsedHeader, filename string) (string, error) {
"\treturn new %s(%s);\n"+ "\treturn new %s(%s);\n"+
"}\n"+ "}\n"+
"\n", "\n",
c.ClassName, maybeSuffix(i), emitParametersCabi(ctor, ""), c.ClassName, c.ClassName, maybeSuffix(i), emitParametersCabi(ctor, ""),
preamble, preamble,
c.ClassName, forwarding, c.ClassName, forwarding,
)) ))