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

View File

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

View File

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

View File

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