genbindings: expand typedefs over inner list classes

This commit is contained in:
mappu 2024-08-28 17:59:21 +12:00
parent 0566582ccf
commit 95e8ab2e02
4 changed files with 108 additions and 31 deletions

View File

@ -649,9 +649,44 @@ func tokenizeMultipleParameters(p string) []string {
return tokens
}
func tokenizeSingleParameter(p string) []string {
// Tokenize into top-level strings
templateDepth := 0
tokens := []string{}
wip := ""
p = strings.TrimSpace(p)
for _, c := range p {
if c == '<' || c == '(' {
wip += string(c)
templateDepth++
} else if c == '>' || c == ')' {
wip += string(c)
templateDepth--
} else if (c == '*' || c == '&') && templateDepth == 0 {
if len(wip) > 0 {
tokens = append(tokens, wip)
}
tokens = append(tokens, string(c))
wip = ""
} else if c == ' ' && templateDepth == 0 {
if len(wip) > 0 {
tokens = append(tokens, wip)
}
wip = ""
} else {
wip += string(c)
}
}
if len(wip) > 0 {
tokens = append(tokens, wip)
}
return tokens
}
func parseSingleTypeString(p string) CppParameter {
tokens := strings.Split(strings.TrimSpace(p), " ")
tokens := tokenizeSingleParameter(p) // strings.Split(strings.TrimSpace(p), " ")
insert := CppParameter{}
for _, tok := range tokens {

View File

@ -5,7 +5,7 @@ import (
"testing"
)
func TestParseTypeString(t *testing.T) {
func TestParseMethodTypes(t *testing.T) {
type testCase struct {
input string
expectReturn CppParameter
@ -23,14 +23,19 @@ func TestParseTypeString(t *testing.T) {
},
testCase{
input: "bool (QList<QPair<Foo, Bar>>, QString)",
/*
expectReturn: CppParameter{ParameterType: "bool"},
expectParams: []CppParameter{
CppParameter{ParameterType: "QList<QPair<Foo, Bar>>"},
CppParameter{ParameterType: "QString"},
},
*/
expectErr: true,
// expectErr: true,
},
testCase{
input: "bool (QList<QWidget*>)",
expectReturn: CppParameter{ParameterType: "bool"},
expectParams: []CppParameter{
CppParameter{ParameterType: "QList<QWidget*>"},
},
},
}
@ -58,3 +63,21 @@ func TestParseTypeString(t *testing.T) {
}
}
}
func TestParseInnerListTypes(t *testing.T) {
l := parseSingleTypeString(`QList<QWidget*>`)
tok, ok := l.QListOf()
if !ok {
t.Fatal("expected QListOf")
}
if !tok.Pointer {
t.Error("expected pointer")
}
if tok.ParameterType != "QWidget" {
t.Errorf("expected QWidget, got %q", tok.ParameterType)
}
}

View File

@ -1,5 +1,30 @@
package main
import (
"strings"
)
func applyTypedefs(p CppParameter) CppParameter {
if td, ok := KnownTypedefs[p.ParameterType]; ok {
p = td.UnderlyingType.CopyWithAlias(p)
}
if t, ok := p.QListOf(); ok {
t2 := applyTypedefs(t) // recursive
// Wipe out so that RenderTypeQtCpp() does not see it
t2.TypeAlias = ""
// QListOf returns for either QList< or QVector<
// Patch it up to the first < position and last character
bpos := strings.Index(p.ParameterType, `<`)
p.ParameterType = p.ParameterType[0:bpos] + `<` + t2.RenderTypeQtCpp() + `>`
}
return p
}
// astTransformTypedefs replaces the ParameterType with any known typedef value.
func astTransformTypedefs(parsed *CppParsedHeader) {
@ -8,25 +33,17 @@ func astTransformTypedefs(parsed *CppParsedHeader) {
for j, m := range c.Methods {
for k, p := range m.Parameters {
if td, ok := KnownTypedefs[p.ParameterType]; ok {
p = td.UnderlyingType.CopyWithAlias(p)
}
m.Parameters[k] = p
m.Parameters[k] = applyTypedefs(p)
}
if td, ok := KnownTypedefs[m.ReturnType.ParameterType]; ok {
m.ReturnType = td.UnderlyingType.CopyWithAlias(m.ReturnType)
}
m.ReturnType = applyTypedefs(m.ReturnType)
c.Methods[j] = m
}
for j, m := range c.Ctors {
for k, p := range m.Parameters {
if td, ok := KnownTypedefs[p.ParameterType]; ok {
p = td.UnderlyingType.CopyWithAlias(p)
}
m.Parameters[k] = p
m.Parameters[k] = applyTypedefs(p)
}
c.Ctors[j] = m

View File

@ -31,15 +31,17 @@ func TestTransformTypedefs(t *testing.T) {
}
// t.Logf("Existing typedefs: %#v\n", KnownTypedefs)
parsed := makeTest("WId")
runTest := func(check string, expect string) {
parsed := makeTest(check)
astTransformTypedefs(&parsed)
got := parsed.Classes[0].Ctors[0].Parameters[0].ParameterType
expect := "uintptr_t"
if got != expect {
t.Errorf("Transform of WId got %q, expected %q", got, expect)
}
}
runTest("WId", "uintptr_t")
runTest("QList<WId>", "QList<uintptr_t>")
runTest("QVector<WId>", "QVector<uintptr_t>")
}