mirror of
https://github.com/mappu/miqt.git
synced 2025-04-28 08:00:22 +00:00
genbindings: remember precise QList/QMap container types
This commit is contained in:
parent
79024a373f
commit
5af3cc6dfe
@ -413,7 +413,7 @@ func AllowType(p CppParameter, isReturnType bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if t, ok := p.QListOf(); ok {
|
if t, _, ok := p.QListOf(); ok {
|
||||||
if err := AllowType(t, isReturnType); err != nil { // e.g. QGradientStops is a QVector<> (OK) of QGradientStop (not OK)
|
if err := AllowType(t, isReturnType); err != nil { // e.g. QGradientStops is a QVector<> (OK) of QGradientStop (not OK)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -424,7 +424,7 @@ func AllowType(p CppParameter, isReturnType bool) error {
|
|||||||
return ErrTooComplex
|
return ErrTooComplex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if kType, vType, ok := p.QMapOf(); ok {
|
if kType, vType, _, ok := p.QMapOf(); ok {
|
||||||
if err := AllowType(kType, isReturnType); err != nil {
|
if err := AllowType(kType, isReturnType); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -82,13 +82,13 @@ func (p CppParameter) RenderTypeCabi() string {
|
|||||||
} else if p.ParameterType == "QByteArray" {
|
} else if p.ParameterType == "QByteArray" {
|
||||||
return "struct miqt_string"
|
return "struct miqt_string"
|
||||||
|
|
||||||
} else if inner, ok := p.QListOf(); ok {
|
} else if inner, _, ok := p.QListOf(); ok {
|
||||||
return "struct miqt_array " + cppComment("of "+inner.RenderTypeCabi())
|
return "struct miqt_array " + cppComment("of "+inner.RenderTypeCabi())
|
||||||
|
|
||||||
} else if inner, ok := p.QSetOf(); ok {
|
} else if inner, ok := p.QSetOf(); ok {
|
||||||
return "struct miqt_array " + cppComment("set of "+inner.RenderTypeCabi())
|
return "struct miqt_array " + cppComment("set of "+inner.RenderTypeCabi())
|
||||||
|
|
||||||
} else if inner1, inner2, ok := p.QMapOf(); ok {
|
} else if inner1, inner2, _, ok := p.QMapOf(); ok {
|
||||||
return "struct miqt_map " + cppComment("of "+inner1.RenderTypeCabi()+" to "+inner2.RenderTypeCabi())
|
return "struct miqt_map " + cppComment("of "+inner1.RenderTypeCabi()+" to "+inner2.RenderTypeCabi())
|
||||||
|
|
||||||
} else if inner1, inner2, ok := p.QPairOf(); ok {
|
} else if inner1, inner2, ok := p.QPairOf(); ok {
|
||||||
@ -274,7 +274,7 @@ func emitCABI2CppForwarding(p CppParameter, indent string) (preamble string, for
|
|||||||
preamble += indent + "QByteArray " + nameprefix + "_QByteArray(" + p.cParameterName() + ".data, " + p.cParameterName() + ".len);\n"
|
preamble += indent + "QByteArray " + nameprefix + "_QByteArray(" + p.cParameterName() + ".data, " + p.cParameterName() + ".len);\n"
|
||||||
return preamble, nameprefix + "_QByteArray"
|
return preamble, nameprefix + "_QByteArray"
|
||||||
|
|
||||||
} else if listType, ok := p.QListOf(); ok {
|
} else if listType, _, ok := p.QListOf(); ok {
|
||||||
|
|
||||||
preamble += indent + p.GetQtCppType().ParameterType + " " + nameprefix + "_QList;\n"
|
preamble += indent + p.GetQtCppType().ParameterType + " " + nameprefix + "_QList;\n"
|
||||||
preamble += indent + nameprefix + "_QList.reserve(" + p.cParameterName() + ".len);\n"
|
preamble += indent + nameprefix + "_QList.reserve(" + p.cParameterName() + ".len);\n"
|
||||||
@ -296,12 +296,12 @@ func emitCABI2CppForwarding(p CppParameter, indent string) (preamble string, for
|
|||||||
return preamble, nameprefix + "_QList"
|
return preamble, nameprefix + "_QList"
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if kType, vType, ok := p.QMapOf(); ok {
|
} else if kType, vType, mapContainerType, ok := p.QMapOf(); ok {
|
||||||
preamble += indent + p.GetQtCppType().ParameterType + " " + nameprefix + "_QMap;\n"
|
preamble += indent + p.GetQtCppType().ParameterType + " " + nameprefix + "_QMap;\n"
|
||||||
|
|
||||||
// This container may be a QMap or a QHash
|
// This container may be a QMap or a QHash
|
||||||
// QHash supports .reserve(), but QMap doesn't
|
// QHash supports .reserve(), but QMap doesn't
|
||||||
if strings.HasPrefix(p.ParameterType, "QHash<") {
|
if mapContainerType == "QHash" {
|
||||||
preamble += indent + nameprefix + "_QMap.reserve(" + p.cParameterName() + ".len);\n"
|
preamble += indent + nameprefix + "_QMap.reserve(" + p.cParameterName() + ".len);\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +461,7 @@ func emitAssignCppToCabi(assignExpression string, p CppParameter, rvalue string)
|
|||||||
afterCall += indent + assignExpression + namePrefix + "_ms;\n"
|
afterCall += indent + assignExpression + namePrefix + "_ms;\n"
|
||||||
return indent + shouldReturn + rvalue + ";\n" + afterCall
|
return indent + shouldReturn + rvalue + ";\n" + afterCall
|
||||||
|
|
||||||
} else if t, ok := p.QListOf(); ok {
|
} else if t, _, ok := p.QListOf(); ok {
|
||||||
|
|
||||||
// In some cases rvalue is a function call and the temporary
|
// In some cases rvalue is a function call and the temporary
|
||||||
// is necessary; in some cases it's a literal and the temporary is
|
// is necessary; in some cases it's a literal and the temporary is
|
||||||
@ -503,7 +503,7 @@ func emitAssignCppToCabi(assignExpression string, p CppParameter, rvalue string)
|
|||||||
afterCall += indent + assignExpression + "" + namePrefix + "_out;\n"
|
afterCall += indent + assignExpression + "" + namePrefix + "_out;\n"
|
||||||
return indent + shouldReturn + rvalue + ";\n" + afterCall
|
return indent + shouldReturn + rvalue + ";\n" + afterCall
|
||||||
|
|
||||||
} else if kType, vType, ok := p.QMapOf(); ok {
|
} else if kType, vType, _, ok := p.QMapOf(); ok {
|
||||||
// QMap<K,V>
|
// QMap<K,V>
|
||||||
|
|
||||||
shouldReturn = p.RenderTypeQtCpp() + " " + namePrefix + "_ret = "
|
shouldReturn = p.RenderTypeQtCpp() + " " + namePrefix + "_ret = "
|
||||||
@ -635,13 +635,13 @@ func getCabiZeroValue(p CppParameter) string {
|
|||||||
} else if p.ParameterType == "QString" || p.ParameterType == "QByteArray" {
|
} else if p.ParameterType == "QString" || p.ParameterType == "QByteArray" {
|
||||||
return "(struct miqt_string){}"
|
return "(struct miqt_string){}"
|
||||||
|
|
||||||
} else if _, ok := p.QListOf(); ok {
|
} else if _, _, ok := p.QListOf(); ok {
|
||||||
return "(struct miqt_array){}"
|
return "(struct miqt_array){}"
|
||||||
|
|
||||||
} else if _, ok := p.QSetOf(); ok {
|
} else if _, ok := p.QSetOf(); ok {
|
||||||
return "(struct miqt_array){}"
|
return "(struct miqt_array){}"
|
||||||
|
|
||||||
} else if _, _, ok := p.QMapOf(); ok {
|
} else if _, _, _, ok := p.QMapOf(); ok {
|
||||||
return "(struct miqt_map){}"
|
return "(struct miqt_map){}"
|
||||||
|
|
||||||
} else if _, _, ok := p.QPairOf(); ok {
|
} else if _, _, ok := p.QPairOf(); ok {
|
||||||
@ -666,12 +666,12 @@ func getReferencedTypes(src *CppParsedHeader) []string {
|
|||||||
if p.QtClassType() {
|
if p.QtClassType() {
|
||||||
foundTypes[p.ParameterType] = struct{}{}
|
foundTypes[p.ParameterType] = struct{}{}
|
||||||
}
|
}
|
||||||
if t, ok := p.QListOf(); ok {
|
if t, containerType, ok := p.QListOf(); ok {
|
||||||
foundTypes["QList"] = struct{}{} // FIXME or QVector?
|
foundTypes[containerType] = struct{}{} // QList / QVector
|
||||||
maybeAddType(t)
|
maybeAddType(t)
|
||||||
}
|
}
|
||||||
if kType, vType, ok := p.QMapOf(); ok {
|
if kType, vType, containerType, ok := p.QMapOf(); ok {
|
||||||
foundTypes["QMap"] = struct{}{} // FIXME or QHash?
|
foundTypes[containerType] = struct{}{} // QMap / QHash
|
||||||
maybeAddType(kType)
|
maybeAddType(kType)
|
||||||
maybeAddType(vType)
|
maybeAddType(vType)
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ func (p CppParameter) RenderTypeGo(gfs *goFileState) string {
|
|||||||
return "[]byte"
|
return "[]byte"
|
||||||
}
|
}
|
||||||
|
|
||||||
if t, ok := p.QListOf(); ok {
|
if t, _, ok := p.QListOf(); ok {
|
||||||
return "[]" + t.RenderTypeGo(gfs)
|
return "[]" + t.RenderTypeGo(gfs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ func (p CppParameter) RenderTypeGo(gfs *goFileState) string {
|
|||||||
return "map[" + t.RenderTypeGo(gfs) + "]struct{}"
|
return "map[" + t.RenderTypeGo(gfs) + "]struct{}"
|
||||||
}
|
}
|
||||||
|
|
||||||
if t1, t2, ok := p.QMapOf(); ok {
|
if t1, t2, _, ok := p.QMapOf(); ok {
|
||||||
return "map[" + t1.RenderTypeGo(gfs) + "]" + t2.RenderTypeGo(gfs)
|
return "map[" + t1.RenderTypeGo(gfs) + "]" + t2.RenderTypeGo(gfs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ func (p CppParameter) parameterTypeCgo() string {
|
|||||||
return "C.struct_miqt_string"
|
return "C.struct_miqt_string"
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := p.QListOf(); ok {
|
if _, _, ok := p.QListOf(); ok {
|
||||||
return "C.struct_miqt_array"
|
return "C.struct_miqt_array"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ func (p CppParameter) parameterTypeCgo() string {
|
|||||||
return "C.struct_miqt_array"
|
return "C.struct_miqt_array"
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, _, ok := p.QMapOf(); ok {
|
if _, _, _, ok := p.QMapOf(); ok {
|
||||||
return "C.struct_miqt_map"
|
return "C.struct_miqt_map"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +359,7 @@ func (gfs *goFileState) emitParameterGo2CABIForwarding(p CppParameter) (preamble
|
|||||||
|
|
||||||
rvalue = nameprefix + "_alias"
|
rvalue = nameprefix + "_alias"
|
||||||
|
|
||||||
} else if listType, ok := p.QListOf(); ok {
|
} else if listType, _, ok := p.QListOf(); ok {
|
||||||
// QList<T>
|
// QList<T>
|
||||||
// Go: convert T[] -> t* and len
|
// Go: convert T[] -> t* and len
|
||||||
// CABI: create a real QList<>
|
// CABI: create a real QList<>
|
||||||
@ -386,7 +386,7 @@ func (gfs *goFileState) emitParameterGo2CABIForwarding(p CppParameter) (preamble
|
|||||||
} else if _, ok := p.QSetOf(); ok {
|
} else if _, ok := p.QSetOf(); ok {
|
||||||
panic("QSet<> arguments are not yet implemented") // n.b. doesn't seem to exist in QtCore/QtGui/QtWidgets at all
|
panic("QSet<> arguments are not yet implemented") // n.b. doesn't seem to exist in QtCore/QtGui/QtWidgets at all
|
||||||
|
|
||||||
} else if kType, vType, ok := p.QMapOf(); ok {
|
} else if kType, vType, _, ok := p.QMapOf(); ok {
|
||||||
// QMap<T>
|
// QMap<T>
|
||||||
|
|
||||||
gfs.imports["unsafe"] = struct{}{}
|
gfs.imports["unsafe"] = struct{}{}
|
||||||
@ -532,7 +532,7 @@ func (gfs *goFileState) emitCabiToGo(assignExpr string, rt CppParameter, rvalue
|
|||||||
afterword += assignExpr + namePrefix + "_ret"
|
afterword += assignExpr + namePrefix + "_ret"
|
||||||
return shouldReturn + " " + rvalue + "\n" + afterword
|
return shouldReturn + " " + rvalue + "\n" + afterword
|
||||||
|
|
||||||
} else if t, ok := rt.QListOf(); ok {
|
} else if t, _, ok := rt.QListOf(); ok {
|
||||||
gfs.imports["unsafe"] = struct{}{}
|
gfs.imports["unsafe"] = struct{}{}
|
||||||
|
|
||||||
shouldReturn = "var " + namePrefix + "_ma C.struct_miqt_array = "
|
shouldReturn = "var " + namePrefix + "_ma C.struct_miqt_array = "
|
||||||
@ -565,7 +565,7 @@ func (gfs *goFileState) emitCabiToGo(assignExpr string, rt CppParameter, rvalue
|
|||||||
afterword += assignExpr + " " + namePrefix + "_ret\n"
|
afterword += assignExpr + " " + namePrefix + "_ret\n"
|
||||||
return shouldReturn + " " + rvalue + "\n" + afterword
|
return shouldReturn + " " + rvalue + "\n" + afterword
|
||||||
|
|
||||||
} else if kType, vType, ok := rt.QMapOf(); ok {
|
} else if kType, vType, _, ok := rt.QMapOf(); ok {
|
||||||
gfs.imports["unsafe"] = struct{}{}
|
gfs.imports["unsafe"] = struct{}{}
|
||||||
|
|
||||||
shouldReturn = "var " + namePrefix + "_mm C.struct_miqt_map = "
|
shouldReturn = "var " + namePrefix + "_mm C.struct_miqt_map = "
|
||||||
|
@ -112,23 +112,23 @@ func (p CppParameter) IsKnownEnum() bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p CppParameter) QListOf() (CppParameter, bool) {
|
func (p CppParameter) QListOf() (CppParameter, string, bool) {
|
||||||
if strings.HasPrefix(p.ParameterType, "QList<") && strings.HasSuffix(p.ParameterType, `>`) {
|
if strings.HasPrefix(p.ParameterType, "QList<") && strings.HasSuffix(p.ParameterType, `>`) {
|
||||||
ret := parseSingleTypeString(p.ParameterType[6 : len(p.ParameterType)-1])
|
ret := parseSingleTypeString(p.ParameterType[6 : len(p.ParameterType)-1])
|
||||||
ret.ParameterName = p.ParameterName + "_lv"
|
ret.ParameterName = p.ParameterName + "_lv"
|
||||||
return ret, true
|
return ret, "QList", true
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(p.ParameterType, "QVector<") && strings.HasSuffix(p.ParameterType, `>`) {
|
if strings.HasPrefix(p.ParameterType, "QVector<") && strings.HasSuffix(p.ParameterType, `>`) {
|
||||||
ret := parseSingleTypeString(p.ParameterType[8 : len(p.ParameterType)-1])
|
ret := parseSingleTypeString(p.ParameterType[8 : len(p.ParameterType)-1])
|
||||||
ret.ParameterName = p.ParameterName + "_vv"
|
ret.ParameterName = p.ParameterName + "_vv"
|
||||||
return ret, true
|
return ret, "QVector", true
|
||||||
}
|
}
|
||||||
|
|
||||||
return CppParameter{}, false
|
return CppParameter{}, "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p CppParameter) QMapOf() (CppParameter, CppParameter, bool) {
|
func (p CppParameter) QMapOf() (CppParameter, CppParameter, string, bool) {
|
||||||
// n.b. Need to block QMap<k,v>::const_terator
|
// n.b. Need to block QMap<k,v>::const_terator
|
||||||
|
|
||||||
if strings.HasPrefix(p.ParameterType, `QMap<`) && strings.HasSuffix(p.ParameterType, `>`) {
|
if strings.HasPrefix(p.ParameterType, `QMap<`) && strings.HasSuffix(p.ParameterType, `>`) {
|
||||||
@ -141,7 +141,7 @@ func (p CppParameter) QMapOf() (CppParameter, CppParameter, bool) {
|
|||||||
first.ParameterName = p.ParameterName + "_mapkey"
|
first.ParameterName = p.ParameterName + "_mapkey"
|
||||||
second := parseSingleTypeString(interior[1])
|
second := parseSingleTypeString(interior[1])
|
||||||
second.ParameterName = p.ParameterName + "_mapval"
|
second.ParameterName = p.ParameterName + "_mapval"
|
||||||
return first, second, true
|
return first, second, "QMap", true
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(p.ParameterType, `QHash<`) && strings.HasSuffix(p.ParameterType, `>`) {
|
if strings.HasPrefix(p.ParameterType, `QHash<`) && strings.HasSuffix(p.ParameterType, `>`) {
|
||||||
@ -154,10 +154,10 @@ func (p CppParameter) QMapOf() (CppParameter, CppParameter, bool) {
|
|||||||
first.ParameterName = p.ParameterName + "_hashkey"
|
first.ParameterName = p.ParameterName + "_hashkey"
|
||||||
second := parseSingleTypeString(interior[1])
|
second := parseSingleTypeString(interior[1])
|
||||||
second.ParameterName = p.ParameterName + "_hashval"
|
second.ParameterName = p.ParameterName + "_hashval"
|
||||||
return first, second, true
|
return first, second, "QHash", true
|
||||||
}
|
}
|
||||||
|
|
||||||
return CppParameter{}, CppParameter{}, false
|
return CppParameter{}, CppParameter{}, "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p CppParameter) QPairOf() (CppParameter, CppParameter, bool) {
|
func (p CppParameter) QPairOf() (CppParameter, CppParameter, bool) {
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func applyTypedefs(p CppParameter) CppParameter {
|
func applyTypedefs(p CppParameter) CppParameter {
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -14,36 +10,30 @@ func applyTypedefs(p CppParameter) CppParameter {
|
|||||||
p.ApplyTypedef(td.Typedef.UnderlyingType)
|
p.ApplyTypedef(td.Typedef.UnderlyingType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t, ok := p.QListOf(); ok {
|
if t, containerType, ok := p.QListOf(); ok {
|
||||||
t2 := applyTypedefs(t) // recursive
|
t2 := applyTypedefs(t) // recursive
|
||||||
|
|
||||||
// Wipe out so that RenderTypeQtCpp() does not see it
|
// Wipe out so that RenderTypeQtCpp() does not see it
|
||||||
t2.QtCppOriginalType = nil
|
t2.QtCppOriginalType = nil
|
||||||
|
|
||||||
// QListOf returns for either QList< or QVector<
|
|
||||||
// Patch it up to the first < position and last character
|
|
||||||
bpos := strings.Index(p.ParameterType, `<`)
|
|
||||||
|
|
||||||
if p.QtCppOriginalType == nil {
|
if p.QtCppOriginalType == nil {
|
||||||
tmp := p // copy
|
tmp := p // copy
|
||||||
p.QtCppOriginalType = &tmp
|
p.QtCppOriginalType = &tmp
|
||||||
}
|
}
|
||||||
p.ParameterType = p.ParameterType[0:bpos] + `<` + t2.RenderTypeQtCpp() + `>`
|
p.ParameterType = containerType + `<` + t2.RenderTypeQtCpp() + `>`
|
||||||
|
|
||||||
} else if kType, vType, ok := p.QMapOf(); ok {
|
} else if kType, vType, containerType, ok := p.QMapOf(); ok {
|
||||||
kType2 := applyTypedefs(kType)
|
kType2 := applyTypedefs(kType)
|
||||||
kType2.QtCppOriginalType = nil
|
kType2.QtCppOriginalType = nil
|
||||||
|
|
||||||
vType2 := applyTypedefs(vType)
|
vType2 := applyTypedefs(vType)
|
||||||
vType2.QtCppOriginalType = nil
|
vType2.QtCppOriginalType = nil
|
||||||
|
|
||||||
bpos := strings.Index(p.ParameterType, `<`)
|
|
||||||
|
|
||||||
if p.QtCppOriginalType == nil {
|
if p.QtCppOriginalType == nil {
|
||||||
tmp := p // copy
|
tmp := p // copy
|
||||||
p.QtCppOriginalType = &tmp
|
p.QtCppOriginalType = &tmp
|
||||||
}
|
}
|
||||||
p.ParameterType = p.ParameterType[0:bpos] + `<` + kType2.RenderTypeQtCpp() + `, ` + vType2.RenderTypeQtCpp() + `>`
|
p.ParameterType = containerType + `<` + kType2.RenderTypeQtCpp() + `, ` + vType2.RenderTypeQtCpp() + `>`
|
||||||
|
|
||||||
} else if kType, vType, ok := p.QPairOf(); ok {
|
} else if kType, vType, ok := p.QPairOf(); ok {
|
||||||
kType2 := applyTypedefs(kType)
|
kType2 := applyTypedefs(kType)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user