genbindings: mark IL types as public for json export

This commit is contained in:
mappu 2024-08-07 18:56:14 +12:00
parent 3a802d0f5a
commit 6174c4c243
4 changed files with 76 additions and 76 deletions

View File

@ -7,9 +7,9 @@ import (
"strings" "strings"
) )
func parseHeader(inner []interface{}) (*parsedHeader, error) { func parseHeader(inner []interface{}) (*CppParsedHeader, error) {
var ret parsedHeader var ret CppParsedHeader
fmt.Printf("package miqt\n\n") fmt.Printf("package miqt\n\n")
@ -49,7 +49,7 @@ func parseHeader(inner []interface{}) (*parsedHeader, error) {
panic(err) panic(err)
} }
ret.classes = append(ret.classes, obj) ret.Classes = append(ret.Classes, obj)
} }
case "StaticAssertDecl": case "StaticAssertDecl":
@ -63,15 +63,15 @@ func parseHeader(inner []interface{}) (*parsedHeader, error) {
return &ret, nil // done return &ret, nil // done
} }
func processType(inner []interface{}, className string, visibility bool) (nativeClass, error) { func processType(inner []interface{}, className string, visibility bool) (CppClass, error) {
var ret nativeClass var ret CppClass
ret.className = className ret.ClassName = className
nextMethod: nextMethod:
for _, node := range inner { for _, node := range inner {
node, ok := node.(map[string]interface{}) node, ok := node.(map[string]interface{})
if !ok { if !ok {
return nativeClass{}, errors.New("inner[] element not an object") return CppClass{}, errors.New("inner[] element not an object")
} }
kind, ok := node["kind"] kind, ok := node["kind"]
@ -107,24 +107,24 @@ nextMethod:
// Method // Method
methodName, ok := node["name"].(string) methodName, ok := node["name"].(string)
if !ok { if !ok {
return nativeClass{}, errors.New("method has no name") return CppClass{}, errors.New("method has no name")
} }
var mm nativeMethod var mm CppMethod
mm.methodName = methodName mm.MethodName = methodName
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
// If anything here is too complicated, skip the whole method // If anything here is too complicated, skip the whole method
if strings.Contains(qualType, `::`) { if strings.Contains(qualType, `::`) {
log.Printf("Skipping method %q with complex type %q", mm.methodName, qualType) log.Printf("Skipping method %q with complex type %q", mm.MethodName, qualType)
continue nextMethod continue nextMethod
} }
// We only want up to the first ( character // We only want up to the first ( character
mm.returnType, _, _ = strings.Cut(qualType, `(`) mm.ReturnType, _, _ = strings.Cut(qualType, `(`)
mm.returnType = strings.TrimSpace(mm.returnType) mm.ReturnType = strings.TrimSpace(mm.ReturnType)
} }
} }
@ -132,7 +132,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 nativeClass{}, errors.New("inner[] element not an object") return CppClass{}, errors.New("inner[] element not an object")
} }
switch methodObj["kind"] { switch methodObj["kind"] {
@ -140,7 +140,7 @@ nextMethod:
// Parameter variable // Parameter variable
parmName, _ := methodObj["name"].(string) // n.b. may be unnamed parmName, _ := methodObj["name"].(string) // n.b. may be unnamed
if parmName == "" { if parmName == "" {
parmName = fmt.Sprintf("param%d", len(mm.parameters)+1) parmName = fmt.Sprintf("param%d", len(mm.Parameters)+1)
} }
var parmType string var parmType string
@ -156,9 +156,9 @@ nextMethod:
// Remove extra () -- if there are more than expected, skip method with complex type // Remove extra () -- if there are more than expected, skip method with complex type
// If this parameter is optional, expand it into multiple function overloads // If this parameter is optional, expand it into multiple function overloads
mm.parameters = append(mm.parameters, nativeParameter{ mm.Parameters = append(mm.Parameters, CppParameter{
name: parmName, ParameterName: parmName,
typ: parmType, ParameterType: parmType,
}) })
default: default:
@ -168,7 +168,7 @@ nextMethod:
} }
} }
ret.methods = append(ret.methods, mm) ret.Methods = append(ret.Methods, mm)
default: default:
fmt.Printf("==> NOT IMPLEMENTED %q\n", kind) fmt.Printf("==> NOT IMPLEMENTED %q\n", kind)

View File

@ -5,7 +5,7 @@ import (
"strings" "strings"
) )
func emitParametersCpp(params []nativeParameter, selfType string) string { func emitParametersCpp(params []CppParameter, selfType string) string {
tmp := make([]string, 0, len(params)+1) tmp := make([]string, 0, len(params)+1)
if selfType != "" { if selfType != "" {
@ -13,12 +13,12 @@ func emitParametersCpp(params []nativeParameter, selfType string) string {
} }
for _, p := range params { for _, p := range params {
tmp = append(tmp, p.name+" "+p.typ) tmp = append(tmp, p.ParameterName+" "+p.ParameterType)
} }
return strings.Join(tmp, ", ") return strings.Join(tmp, ", ")
} }
func emitParametersNames(params []nativeParameter, selfType string) string { func emitParametersNames(params []CppParameter, selfType string) string {
tmp := make([]string, 0, len(params)+1) tmp := make([]string, 0, len(params)+1)
if selfType != "" { if selfType != "" {
@ -26,12 +26,12 @@ func emitParametersNames(params []nativeParameter, selfType string) string {
} }
for _, p := range params { for _, p := range params {
tmp = append(tmp, p.name) tmp = append(tmp, p.ParameterName)
} }
return strings.Join(tmp, ", ") return strings.Join(tmp, ", ")
} }
func emitBindingHeader(src *parsedHeader, filename string) (string, error) { func emitBindingHeader(src *CppParsedHeader, filename string) (string, error) {
ret := strings.Builder{} ret := strings.Builder{}
includeGuard := strings.ToUpper(strings.Replace(filename, `.`, `_`, -1)) + "_H" includeGuard := strings.ToUpper(strings.Replace(filename, `.`, `_`, -1)) + "_H"
@ -47,15 +47,15 @@ extern "C" {
`) `)
for _, c := range src.classes { for _, c := range src.Classes {
ret.WriteString(`typedef void* P` + c.className + ";\n\n") ret.WriteString(`typedef void* P` + c.ClassName + ";\n\n")
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), emitParametersCpp(ctor.parameters, ""))) ret.WriteString(fmt.Sprintf("P%s %s_new%s(%s);\n", c.ClassName, maybeSuffix(i), emitParametersCpp(ctor.Parameters, "")))
} }
for _, m := range c.methods { for _, m := range c.Methods {
ret.WriteString(fmt.Sprintf("%s %s_%s(%s);\n", m.returnType, c.className, m.SafeMethodName(), emitParametersCpp(m.parameters, "P"+c.className))) ret.WriteString(fmt.Sprintf("%s %s_%s(%s);\n", m.ReturnType, c.ClassName, m.SafeMethodName(), emitParametersCpp(m.Parameters, "P"+c.ClassName)))
} }
ret.WriteString("\n") ret.WriteString("\n")
@ -72,7 +72,7 @@ extern "C" {
return ret.String(), nil return ret.String(), nil
} }
func emitBindingCpp(src *parsedHeader, filename string) (string, error) { func emitBindingCpp(src *CppParsedHeader, filename string) (string, error) {
ret := strings.Builder{} ret := strings.Builder{}
ret.WriteString(`#include "gen_` + filename + `" ret.WriteString(`#include "gen_` + filename + `"
@ -80,25 +80,25 @@ func emitBindingCpp(src *parsedHeader, filename string) (string, error) {
`) `)
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( ret.WriteString(fmt.Sprintf(
"P%s %s_new%s(%s) {\n\treturn new %s(%s);\n}\n\n", c.className, maybeSuffix(i), emitParametersCpp(ctor.parameters, ""), "P%s %s_new%s(%s) {\n\treturn new %s(%s);\n}\n\n", c.ClassName, maybeSuffix(i), emitParametersCpp(ctor.Parameters, ""),
c.className, emitParametersNames(ctor.parameters, ""), c.ClassName, emitParametersNames(ctor.Parameters, ""),
)) ))
} }
for _, m := range c.methods { for _, m := range c.Methods {
// Need to take an extra 'self' parameter // Need to take an extra 'self' parameter
shouldReturn := "return " shouldReturn := "return "
if m.returnType == "void" { if m.ReturnType == "void" {
shouldReturn = "" shouldReturn = ""
} }
ret.WriteString(fmt.Sprintf("%s %s_%s(%s) {\n\t%sstatic_cast<%s*>(self)->%s(%s);\n}\n\n", m.returnType, c.className, m.SafeMethodName(), emitParametersCpp(m.parameters, "P"+c.className), ret.WriteString(fmt.Sprintf("%s %s_%s(%s) {\n\t%sstatic_cast<%s*>(self)->%s(%s);\n}\n\n", m.ReturnType, c.ClassName, m.SafeMethodName(), emitParametersCpp(m.Parameters, "P"+c.ClassName),
shouldReturn, c.className, m.methodName, emitParametersNames(m.parameters, c.className), shouldReturn, c.ClassName, m.MethodName, emitParametersNames(m.Parameters, c.ClassName),
)) ))
} }
} }

View File

@ -6,15 +6,15 @@ import (
"strings" "strings"
) )
func emitParametersGo(params []nativeParameter) string { func emitParametersGo(params []CppParameter) string {
tmp := make([]string, 0, len(params)) tmp := make([]string, 0, len(params))
for _, p := range params { for _, p := range params {
tmp = append(tmp, p.typ+" "+p.name) tmp = append(tmp, p.ParameterType+" "+p.ParameterName)
} }
return strings.Join(tmp, ", ") return strings.Join(tmp, ", ")
} }
func emitGo(src *parsedHeader) (string, error) { func emitGo(src *CppParsedHeader) (string, error) {
ret := strings.Builder{} ret := strings.Builder{}
ret.WriteString(`package miqt ret.WriteString(`package miqt
@ -30,14 +30,14 @@ import "C"
`) `)
for _, c := range src.classes { for _, c := range src.Classes {
ret.WriteString(` ret.WriteString(`
type ` + c.className + ` struct { type ` + c.ClassName + ` struct {
h C.P` + c.className + ` h C.P` + c.ClassName + `
} }
func (this *` + c.className + `) cPointer() C.P` + c.className + ` { func (this *` + c.ClassName + `) cPointer() C.P` + c.ClassName + ` {
if this == nil { if this == nil {
return nil return nil
} }
@ -46,30 +46,30 @@ import "C"
`) `)
for i, ctor := range c.ctors { for i, ctor := range c.Ctors {
ret.WriteString(` ret.WriteString(`
// New` + c.className + maybeSuffix(i) + ` constructs a new ` + c.className + ` object. // New` + c.ClassName + maybeSuffix(i) + ` constructs a new ` + c.ClassName + ` object.
func New` + c.className + maybeSuffix(i) + `(` + emitParametersGo(ctor.parameters) + `) { func New` + c.ClassName + maybeSuffix(i) + `(` + emitParametersGo(ctor.Parameters) + `) {
ret := C.` + c.className + `_new` + maybeSuffix(i) + `(` + emitParametersNames(ctor.parameters, "") + `) ret := C.` + c.ClassName + `_new` + maybeSuffix(i) + `(` + emitParametersNames(ctor.Parameters, "") + `)
return &` + c.className + `{h: ret} return &` + c.ClassName + `{h: ret}
} }
`) `)
} }
for _, m := range c.methods { for _, m := range c.Methods {
// TODO for any known pointer type, call its cPointer() method instead of passing it directly // TODO for any known pointer type, call its cPointer() method instead of passing it directly
shouldReturn := "return " shouldReturn := "return "
returnTypeDecl := m.returnType returnTypeDecl := m.ReturnType
if returnTypeDecl == "void" { if returnTypeDecl == "void" {
shouldReturn = "" shouldReturn = ""
returnTypeDecl = "" returnTypeDecl = ""
} }
ret.WriteString(` ret.WriteString(`
func (this *` + c.className + `) ` + m.methodName + `(` + emitParametersGo(m.parameters) + `) ` + returnTypeDecl + ` { func (this *` + c.ClassName + `) ` + m.MethodName + `(` + emitParametersGo(m.Parameters) + `) ` + returnTypeDecl + ` {
` + shouldReturn + ` C.` + c.className + `_` + m.SafeMethodName() + `(` + emitParametersNames(m.parameters, c.className) + `) ` + shouldReturn + ` C.` + c.ClassName + `_` + m.SafeMethodName() + `(` + emitParametersNames(m.Parameters, c.ClassName) + `)
} }
`) `)

View File

@ -4,24 +4,24 @@ import (
"strings" "strings"
) )
type nativeParameter struct { type CppParameter struct {
name string ParameterName string
typ string ParameterType string
} }
type nativeProperty struct { type CppProperty struct {
propertyName string PropertyName string
propertyType string PropertyType string
visibility string Visibility string
} }
type nativeMethod struct { type CppMethod struct {
methodName string MethodName string
returnType string ReturnType string
parameters []nativeParameter Parameters []CppParameter
} }
func (nm nativeMethod) SafeMethodName() string { func (nm CppMethod) SafeMethodName() string {
// Operator-overload methods have names not representable in binding // Operator-overload methods have names not representable in binding
// languages. Replace more specific cases first // languages. Replace more specific cases first
replacer := strings.NewReplacer( replacer := strings.NewReplacer(
@ -52,17 +52,17 @@ func (nm nativeMethod) SafeMethodName() string {
`()`, `Call`, `()`, `Call`,
) )
return replacer.Replace(nm.methodName) return replacer.Replace(nm.MethodName)
} }
type nativeClass struct { type CppClass struct {
className string ClassName string
ctors []nativeMethod // only use the parameters Ctors []CppMethod // only use the parameters
extends []string Extends []string
methods []nativeMethod Methods []CppMethod
props []nativeProperty Props []CppProperty
} }
type parsedHeader struct { type CppParsedHeader struct {
classes []nativeClass Classes []CppClass
} }