func IsPrivateSignal(f *parser.Function) bool { var fData string switch runtime.GOOS { case "darwin": fData = utils.Load(fmt.Sprintf("/usr/local/Qt5.5.1/5.5/clang_64/lib/%v.framework/Versions/5/Headers/%v", strings.Title(parser.ClassMap[f.Class()].DocModule), filepath.Base(f.Filepath))) case "windows": fData = utils.Load(fmt.Sprintf("C:\\Qt\\Qt5.5.1\\5.5\\mingw492_32\\include\\%v\\%v", strings.Title(parser.ClassMap[f.Class()].DocModule), filepath.Base(f.Filepath))) case "linux": switch runtime.GOARCH { case "amd64": { fData = utils.Load(fmt.Sprintf("/usr/local/Qt5.5.1/5.5/gcc_64/include/%v/%v", strings.Title(parser.ClassMap[f.Class()].DocModule), filepath.Base(f.Filepath))) } case "386": { fData = utils.Load(fmt.Sprintf("/usr/local/Qt5.5.1/5.5/gcc/include/%v/%v", strings.Title(parser.ClassMap[f.Class()].DocModule), filepath.Base(f.Filepath))) } } } if fData != "" { return strings.Contains(strings.Split(strings.Split(fData, f.Name+"(")[1], ")")[0], "QPrivateSignal") } else { fmt.Println("converter.IsPrivateSignal", f.Class()) } return false }
func CppBodyInput(f *parser.Function) (o string) { if f.Meta == "slot" { for _, p := range f.Parameters { o += fmt.Sprintf(", Q_ARG(%v, %v)", CppBodyInputSlotValue(f, p), cppInput(p.Name, p.Value, f)) } return } if f.Meta == "signal" { for _, p := range f.Parameters { if isEnum(f.Class(), cleanValue(p.Value)) { o += fmt.Sprintf("%v, ", cppEnum(f, cleanValue(p.Value), true)) } else { o += fmt.Sprintf("%v, ", p.Value) } } return strings.TrimSuffix(o, ", ") } for _, p := range f.Parameters { o += fmt.Sprintf("%v, ", cppInput(p.Name, p.Value, f)) } return strings.TrimSuffix(o, ", ") }
func isBlocked(f *parser.Function) bool { for _, n := range []string{"relations", "scriptValueFromQMetaObject", "fromScriptValue", "QPlaceProposedSearchResult", "evaluateTo", "detected", "isRecordType", "replace", "insert", "remove", "find", "changedStates", "requestTexture", "draw", "setTabPositions", "setExtraSelections", "disconnect", "QJsonObject", "QJsonArray", "QAccessibleStateChangeEvent", "hitTest", "setupUi", "setEditFocus", "toUnicode", "registerConverter", "registerEqualsComparator", "registerComparators", "hasRegisteredConverterFunction", "hasRegisteredComparators", "setNavigationMode", "navigationMode", "setNativeArguments", "setAlphaChannel", "setDefaultAction", "unregisterEventNotifier", "QXmlStreamWriter", "hasEditFocus", "QTextStream", "QStringRef", "QSignalBlocker", "defaultAction", "canConvert", "queryItemValue", "hasQueryItem", "hasEncodedQueryItem", "hasLocalData", "registerEventNotifier", "registerTimer", "setYMD", "nativeArguments"} { if f.Name == n { f.Access = "unsupported_isBlocked" return true } } for _, n := range []string{"QAccessibleInterface::state", "QAccessibleWidget::state"} { if f.Fullname == n { f.Access = "unsupported_isBlocked" return true } } //Android Only for _, blockedAndroid := range []string{"setAsDockMenu", "setSelect"} { if f.Name == blockedAndroid { f.Access = "unsupported_isBlocked_Android" return true } } if f.Name == "value" && f.Class() == "QVariant" { f.Access = "unsupported_goFunction" return true } if f.Class() == "QAudioBuffer" && strings.Contains(f.Output, "T") { f.Access = "unsupported_goFunction" return true } return false }
func goInput(name string, value string, f *parser.Function) string { var vOld = value name = cleanName(name) value = cleanValue(value) switch value { case "QStringList": { return fmt.Sprintf("C.CString(strings.Join(%v, \"|\"))", name) } case "uchar", "char", "QString": { if strings.Contains(vOld, "**") { return fmt.Sprintf("C.CString(strings.Join(%v, \"|\"))", name) } return fmt.Sprintf("C.CString(%v)", name) } case "bool": { return fmt.Sprintf("C.int(qt.GoBoolToInt(%v))", name) } case "int": { return fmt.Sprintf("C.int(%v)", name) } case "qreal": { return fmt.Sprintf("C.double(%v)", name) } case "jclass": { return name } } switch { case isEnum(f.Class(), value): { return fmt.Sprintf("C.int(%v)", name) } case isClass(value): { if m := module(parser.ClassMap[value].Module); m != module(f) { return fmt.Sprintf("%v.PointerFrom%v(%v)", m, strings.Title(value), name) } return fmt.Sprintf("PointerFrom%v(%v)", strings.Title(value), name) } } f.Access = "unsupported_goInput" return f.Access }
func goOutputFailed(value string, f *parser.Function) string { var vOld = value value = cleanValue(value) switch value { case "bool": return "false" case "int", "qreal", "qint64": return "0" case "uchar", "char", "QString": return "\"\"" case "QStringList": return "make([]string, 0)" case "void", "": if strings.Contains(vOld, "*") { return "nil" } return "" case "T", "JavaVM", "jclass", "jobject": switch f.TemplateMode { case "Int": { return "0" } case "Boolean": { return "false" } case "Void": { return "" } } return "nil" } switch { case isEnum(f.Class(), value): return "0" case isClass(value): return "nil" default: f.Access = "unsupported_GoBodyOutputFailed" return f.Access } }
func cppType(f *parser.Function, value string) string { var vOld = value value = cleanValue(value) switch value { case "uchar", "char", "QString", "QStringList": { return "char*" } case "bool", "int": { return "int" } case "void", "": { if strings.Contains(vOld, "*") { return "void*" } return "void" } case "T", "JavaVM", "jclass": { return "void*" } case "qreal": { return "double" } case "...": { return "" } } switch { case isEnum(f.Class(), value): { return "int" } case isClass(value): { return "void*" } } f.Access = "unsupported_cppType" return f.Access }
func CppBodyInputSlotValue(f *parser.Function, p *parser.Parameter) string { if strings.Contains(p.Value, "*") { return fmt.Sprintf("%v*", cleanValue(p.Value)) } if isEnum(f.Class(), p.Value) { return cppEnum(f, p.Value, false) } return cleanValue(p.Value) }
func cgoOutput(name string, value string, f *parser.Function) string { name = cleanName(name) value = cleanValue(value) switch value { case "QStringList": { return fmt.Sprintf("strings.Split(%v, \"|\")", cgoOutput(name, "QString", f)) } case "uchar", "char", "QString": { return fmt.Sprintf("C.GoString(%v)", name) } case "int": { return fmt.Sprintf("int(%v)", name) } case "bool": { return fmt.Sprintf("%v != 0", cgoOutput(name, "int", f)) } case "void", "": { return "" } } switch { case isEnum(f.Class(), value): { if c, exists := parser.ClassMap[class(cppEnum(f, value, false))]; exists && module(c.Module) != module(f) && module(c.Module) != "" { return fmt.Sprintf("%v.%v(%v)", module(c.Module), goEnum(f, value), name) } return fmt.Sprintf("%v(%v)", goEnum(f, value), name) } case isClass(value): { if m := module(parser.ClassMap[value].Module); m != module(f) { return fmt.Sprintf("%v.New%vFromPointer(%v)", m, value, name) } return fmt.Sprintf("New%vFromPointer(%v)", value, name) } } f.Access = "unsupported_cgoOutput" return f.Access }
func CppBodyInputCallback(f *parser.Function) (o string) { for _, p := range f.Parameters { if isEnum(f.Class(), cleanValue(p.Value)) { o += fmt.Sprintf("%v %v, ", cppEnum(f, cleanValue(p.Value), true), cleanName(p.Name)) } else { o += fmt.Sprintf("%v %v, ", p.Value, cleanName(p.Name)) } } return strings.TrimSuffix(o, ", ") }
func goFunction(f *parser.Function) string { if f.Meta == "signal" && !f.Overload { var tmp string for _, signalMode := range []string{"Connect", "Disconnect", "callback"} { f.SignalMode = signalMode if signalMode == "callback" { tmp += fmt.Sprintf("//export callback%v%v\n", f.Class(), strings.Title(f.Name)) } tmp += fmt.Sprintf("%v{\n%v\n}\n\n", goFunctionHeader(f), goFunctionBody(f)) } f.SignalMode = "" return tmp } return fmt.Sprintf("%v{\n%v\n}", goFunctionHeader(f), goFunctionBody(f)) }
func goFunction(f *parser.Function) string { if f.Meta == "signal" || strings.Contains(f.Virtual, "impure") && f.Output == "void" { var tmp string for _, signalMode := range []string{"Connect", "Disconnect", "callback"} { f.SignalMode = signalMode if signalMode == "callback" { tmp += fmt.Sprintf("//export callback%v%v", f.Class(), strings.Replace(strings.Title(f.Name), "~", "Destroy", -1)) if f.Overload { tmp += f.OverloadNumber } tmp += "\n" } tmp += fmt.Sprintf("%v{\n%v\n}\n\n", goFunctionHeader(f), goFunctionBody(f)) } f.SignalMode = "" var isPrivate bool if f.Meta == "signal" { isPrivate = converter.IsPrivateSignal(f) } var tmpMeta = f.Meta f.Meta = "plain" if !isPrivate { tmp += fmt.Sprintf("%v{\n%v\n}\n\n", goFunctionHeader(f), goFunctionBody(f)) if tmpMeta != "signal" { var tmpTmp = strings.Replace(fmt.Sprintf("%v{\n%v\n}\n\n", goFunctionHeader(f), goFunctionBody(f)), "_"+strings.Title(f.Name)+"(", "_"+strings.Title(f.Name)+"Default(", -1) tmp += strings.Replace(tmpTmp, ")"+strings.Title(f.Name)+"(", ")"+strings.Title(f.Name)+"Default(", -1) } } f.Meta = tmpMeta return tmp } if isGeneric(f) { var tmp string for _, m := range jniGenericModes(f) { f.TemplateMode = m tmp += fmt.Sprintf("%v{\n%v\n}\n", goFunctionHeader(f), goFunctionBody(f)) } f.TemplateMode = "" return tmp } return fmt.Sprintf("%v{\n%v\n}", goFunctionHeader(f), goFunctionBody(f)) }
func cgoType(f *parser.Function, value string) string { value = cleanValue(value) switch value { case "uchar", "char", "QString", "QStringList": { return "*C.char" } case "bool", "int": { return "C.int" } case "void", "": { return "" } case "qreal": { return "C.double" } case "qint64": { return "C.longlong" } } switch { case isEnum(f.Class(), value): { return "C.int" } case isClass(value): { return "unsafe.Pointer" } } f.Access = "unsupported_cgoType" return f.Access }
func isDerivedFromSlot(of *parser.Function) bool { var c = parser.ClassMap[of.Class()] for _, bcName := range c.GetAllBases([]string{}) { if bc, exists := parser.ClassMap[bcName]; exists { for _, f := range bc.Functions { if strings.Contains(f.Virtual, "impure") && f.Output == "void" { if of.Name == f.Name && (of.Meta == "slot" || f.Meta == "slot") { return true } } } } } return false }
func CppBodyOutputCallback(f *parser.Function) (o string) { //TODO: parse from docs var this = "this" if strings.Contains(strings.Split(f.Signature, ")")[1], "const") { this = fmt.Sprintf("const_cast<My%v*>(this)", f.Class()) } if parser.ClassMap[f.Class()].IsQObjectSubClass() { o += fmt.Sprintf("%v, %v", this, cppOutput("this->objectName()", "QString", f)) } else { o += fmt.Sprintf("%v, %v", this, cppOutput("this->objectNameAbs()", "QString", f)) } for _, p := range f.Parameters { o += fmt.Sprintf(", %v", cppOutput(p.Name, p.Value, f)) } return }
func isDerivedFromPure(of *parser.Function) bool { var c = parser.ClassMap[of.Class()] for _, bcName := range c.GetAllBases([]string{}) { if bc, exists := parser.ClassMap[bcName]; exists { for _, f := range bc.Functions { if f.Virtual == "impure" && !isDerivedFromSlot(of) { return false } if f.Virtual == "pure" && f.Output == "void" { if of.Name == f.Name { return true } } } } } return false }
func GoHeaderName(f *parser.Function) (o string) { if f.SignalMode == "callback" { var tmp = fmt.Sprintf("callback%v%v", f.Class(), strings.Replace(strings.Title(f.Name), "~", "Destroy", -1)) if f.Overload { tmp += f.OverloadNumber } return tmp } if f.Static { o += fmt.Sprintf("%v_", strings.Split(f.Fullname, "::")[0]) } switch f.Meta { case "constructor": o += "New" case "destructor": o += "Destroy" } o += f.SignalMode o += strings.Title(f.Name) o += f.TemplateMode if f.Overload { o += f.OverloadNumber } if strings.ContainsAny(o, "&<>=/!()[]{}-^|*+-") || strings.Contains(o, "Operator") { f.Access = "unsupported_GoHeaderName" return f.Access } return strings.Replace(o, "~", "", -1) }
func goFunctionBody(f *parser.Function) (o string) { if !f.Static && f.Meta != "constructor" && f.SignalMode != "callback" { o += fmt.Sprintf("if ptr.Pointer() != nil {\n") } if converter.GoHeaderOutput(f) != "" { o += "return " } /* if (f.Meta == "destructor" && isObjectSubClass(f.Class())) || (f.Meta == "slot" && strings.Contains(f.Name, "deleteLater")) { o += "getSignal(ptr.ObjectName(), \"destroyed\").(func(QObject, QObject))(ptr, ptr)\n" } */ if f.SignalMode == "callback" { o += fmt.Sprintf("qt.GetSignal(C.GoString(ptrName), \"%v\").(%v)(%v)", f.Name, converter.GoHeaderInputSignalFunction(f), converter.GoBodyInputSignalValues(f)) } else { o += converter.GoBodyOutput(f, fmt.Sprintf("C.%v(%v)", converter.CppHeaderName(f), converter.GoBodyInput(f))) } if f.SignalMode == "Connect" { o += fmt.Sprintf("\nqt.ConnectSignal(ptr.ObjectName(), \"%v\", f)", f.Name) } if f.SignalMode == "Disconnect" { o += fmt.Sprintf("\nqt.DisconnectSignal(ptr.ObjectName(), \"%v\")", f.Name) } if (f.Meta == "destructor" && isObjectSubClass(f.Class())) || (f.Meta == "slot" && strings.Contains(f.Name, "deleteLater")) { o += "\nptr.SetPointer(nil)" } if !f.Static && f.Meta != "constructor" && f.SignalMode != "callback" { o += "\n}" if converter.GoHeaderOutput(f) != "" { o += fmt.Sprintf("\nreturn %v", converter.GoBodyOutputFailed(f.Output, f)) } } if parser.ClassMap[f.Class()].Stub { if f.Meta == "constructor" { return fmt.Sprintf("\nreturn New%vFromPointer(%v)", f.Class(), converter.GoBodyOutputFailed(f.Class(), f)) } else { return fmt.Sprintf("\nreturn %v", converter.GoBodyOutputFailed(f.Output, f)) } } return o }
func goInput(name string, value string, f *parser.Function) string { var vOld = value name = cleanName(name) value = cleanValue(value) switch value { case "QStringList": { return fmt.Sprintf("C.CString(strings.Join(%v, \"|\"))", name) } case "uchar", "char", "QString": { if strings.Contains(vOld, "**") { return fmt.Sprintf("C.CString(strings.Join(%v, \"|\"))", name) } return fmt.Sprintf("C.CString(%v)", name) } case "bool": { return fmt.Sprintf("C.int(qt.GoBoolToInt(%v))", name) } case "int": { return fmt.Sprintf("C.int(%v)", name) } case "qreal": { return fmt.Sprintf("C.double(%v)", name) } case "qint64": { return fmt.Sprintf("C.longlong(%v)", name) } case "jclass", "jobject": { return name } case "...": { var tmp string for i := 0; i < 10; i++ { tmp += fmt.Sprintf("p%v, ", i) } return strings.TrimSuffix(tmp, ", ") } case "T": { switch f.TemplateMode { case "Int": return fmt.Sprintf("C.int(%v)", name) case "Boolean": return fmt.Sprintf("C.int(qt.GoBoolToInt(%v))", name) } if module(f) == "androidextras" { return "p0" } } } switch { case isEnum(f.Class(), value): { return fmt.Sprintf("C.int(%v)", name) } case isClass(value): { if m := module(parser.ClassMap[value].Module); m != module(f) { if parser.ClassMap[f.Class()].WeakLink[parser.ClassMap[value].Module] { return name } return fmt.Sprintf("%v.PointerFrom%v(%v)", m, strings.Title(value), name) } return fmt.Sprintf("PointerFrom%v(%v)", strings.Title(value), name) } } f.Access = "unsupported_goInput" return f.Access }
func cppInput(name string, value string, f *parser.Function) string { var vOld = value name = cleanName(name) value = cleanValue(value) switch value { case "QStringList": { return fmt.Sprintf("%v.split(\"|\", QString::SkipEmptyParts)", cppInput(name, "QString", f)) } case "QString": { if strings.Contains(vOld, "&") { if strings.Contains(vOld, "const") { return fmt.Sprintf("%v(%v)", value, name) } f.Access = "unsupported_CppInput" return f.Access } if strings.Contains(vOld, "*") { return fmt.Sprintf("new %v(%v)", value, name) } return fmt.Sprintf("%v(%v)", value, name) } case "bool": { if strings.Contains(vOld, "*") { return "NULL" } return fmt.Sprintf("%v != 0", name) } case "int": { if strings.Contains(vOld, "*") { return fmt.Sprintf("&%v", name) } if strings.Contains(vOld, "&") && name == "argc" { return "argcs" } return name } case "char": { if strings.Contains(vOld, "const") { if strings.Contains(vOld, "*") { return fmt.Sprintf("const_cast<const %v*>(%v)", value, name) } } if strings.Contains(vOld, "**") { return "argvs" //return "const_cast<char **>(argvs.data())" } if strings.Contains(vOld, "*") { return name } return fmt.Sprintf("*%v", name) } case "qreal": { if strings.Contains(vOld, "*") { f.Access = "unsupported_CppInput" return f.Access //return fmt.Sprintf("&static_cast<double>(%v)", name) } return fmt.Sprintf("static_cast<double>(%v)", name) } case "qint64": { if strings.Contains(vOld, "*") { f.Access = "unsupported_CppInput" return f.Access } return fmt.Sprintf("static_cast<long long>(%v)", name) } case "jclass", "jobject": { return fmt.Sprintf("static_cast<%v>(%v)", value, name) } case "...": { var tmp string for i := 0; i < 10; i++ { if i == 9 { tmp += fmt.Sprintf("static_cast<jobject>(%v), ", name) } else { tmp += fmt.Sprintf("static_cast<jobject>(%v%v), ", name, i) } } return strings.TrimSuffix(tmp, ", ") } case "T": { switch f.TemplateMode { case "Int", "Boolean": return name } if module(f) == "androidextras" { return fmt.Sprintf("static_cast<jobject>(%v)", name) } } } switch { case isEnum(f.Class(), value): { if !strings.Contains(vOld, "*") { return fmt.Sprintf("static_cast<%v>(%v)", cppEnum(f, value, false), name) } } case isClass(value): { if strings.Contains(vOld, "*") { if strings.Contains(vOld, "&") { break } return fmt.Sprintf("static_cast<%v*>(%v)", value, name) } return fmt.Sprintf("*static_cast<%v*>(%v)", value, name) } } f.Access = "unsupported_CppInput" return f.Access }
func cppFunctionBody(f *parser.Function) (o string) { /* for _, p := range f.Parameters { if strings.Contains(p.Value, "**") && p.Name == "argv" { o += "QList<QByteArray> aList = QByteArray(argv).split('|');\n" o += "\tQVarLengthArray<const char*> argvs(argc);\n" o += "\tstatic int argcs = argc;\n" o += "\tfor (int i = 0; i < argc; i++)\n" o += "\t\targvs[i] = static_cast<const char*>(aList[i].constData());\n\n\t" } } */ for _, p := range f.Parameters { if strings.Contains(p.Value, "**") && p.Name == "argv" { o += "QList<QByteArray> aList = QByteArray(argv).split('|');\n" o += "\tchar *argvs[argc];\n" o += "\tstatic int argcs = argc;\n" o += "\tfor (int i = 0; i < argc; i++)\n" o += "\t\targvs[i] = aList[i].data();\n\n\t" } } if f.Name == "objectNameAbs" || f.Name == "setObjectNameAbs" { o += fmt.Sprintf("if (dynamic_cast<My%v*>(static_cast<%v*>(ptr))) {\n\t\t", f.Class(), f.Class()) } if converter.CppHeaderOutput(f) != "void" { o += "return " } var tmpMeta string if strings.Contains(f.Virtual, "impure") { if isDerivedFromSlot(f) { tmpMeta = f.Meta f.Meta = "slot" } } switch f.Meta { case "constructor": { if hasVirtualFunction(parser.ClassMap[f.Class()]) { o += fmt.Sprintf("new My%v(%v)", f.Class(), converter.CppBodyInput(f)) } else { o += fmt.Sprintf("new %v(%v)", f.Class(), converter.CppBodyInput(f)) } } case "slot": { if f.Static { o += fmt.Sprintf("QMetaObject::invokeMethod(%v::instance(), \"%v\"%v)", f.Class(), f.Name, converter.CppBodyInput(f)) } else { o += fmt.Sprintf("QMetaObject::invokeMethod(static_cast<%v*>(ptr), \"%v\"%v)", f.Class(), f.Name, converter.CppBodyInput(f)) } } case "plain", "destructor": { if f.Static { o += converter.CppBodyOutput(f, fmt.Sprintf("%v::%v%v(%v)", f.Class(), f.Name, converter.DeduceGeneric(f), converter.CppBodyInput(f))) } else { if f.Output == "T" && f.Class() == "QObject" { o += converter.CppBodyOutput(f, fmt.Sprintf("static_cast<%v*>(ptr)->%v<QObject*>(%v)", f.Class(), f.Name, converter.CppBodyInput(f))) } else if f.Output == "T" && f.Class() == "QMediaService" { o += converter.CppBodyOutput(f, fmt.Sprintf("static_cast<%v*>(ptr)->%v<QMediaControl*>(%v)", f.Class(), f.Name, converter.CppBodyInput(f))) } else { if parser.ClassMap[f.Class()].IsQObjectSubClass() { o += converter.CppBodyOutput(f, fmt.Sprintf("static_cast<%v*>(ptr)->%v%v(%v)", f.Class(), f.Name, converter.DeduceGeneric(f), converter.CppBodyInput(f))) } else { if f.Name == "objectNameAbs" || f.Name == "setObjectNameAbs" { o += converter.CppBodyOutput(f, fmt.Sprintf("static_cast<My%v*>(ptr)->%v%v(%v)", f.Class(), f.Name, converter.DeduceGeneric(f), converter.CppBodyInput(f))) } else { o += converter.CppBodyOutput(f, fmt.Sprintf("static_cast<%v*>(ptr)->%v%v(%v)", f.Class(), f.Name, converter.DeduceGeneric(f), converter.CppBodyInput(f))) } } } } } case "signal": { if converter.IsPrivateSignal(f) { o += fmt.Sprintf("QObject::%v(%v, &%v::%v, static_cast<My%v*>(ptr), static_cast<%v (My%v::*)(%v)>(&My%v::Signal_%v%v));", strings.ToLower(f.SignalMode), fmt.Sprintf("static_cast<%v*>(%v)", f.Class(), "ptr"), f.Class(), f.Name, f.Class(), f.Output, f.Class(), converter.CppBodyInput(f), f.Class(), strings.Title(f.Name), cppFunctionSignalOverload(f)) } else { o += fmt.Sprintf("QObject::%v(%v, static_cast<void (%v::*)(%v)>(&%v::%v), static_cast<My%v*>(ptr), static_cast<%v (My%v::*)(%v)>(&My%v::Signal_%v%v));", strings.ToLower(f.SignalMode), fmt.Sprintf("static_cast<%v*>(%v)", f.Class(), "ptr"), f.Class(), converter.CppBodyInput(f), f.Class(), f.Name, f.Class(), f.Output, f.Class(), converter.CppBodyInput(f), f.Class(), strings.Title(f.Name), cppFunctionSignalOverload(f)) } } default: { f.Access = "unsupported_CppFunctionBody" return f.Access } } if tmpMeta != "" { f.Meta = tmpMeta } if f.Name == "objectNameAbs" { o += fmt.Sprintf(";\n\t}\n\treturn QString(\"%v_BASE\").toUtf8().data()", f.Class()) } else if f.Name == "setObjectNameAbs" { return o + ";\n\t}" } return o + ";" }
func goOutput(name string, value string, f *parser.Function) string { var vOld = value name = cleanName(name) value = cleanValue(value) switch value { case "QStringList": { return fmt.Sprintf("strings.Split(%v, \"|\")", goOutput(name, "QString", f)) } case "uchar", "char", "QString": { return fmt.Sprintf("C.GoString(%v)", name) } case "int": { return fmt.Sprintf("int(%v)", name) } case "bool": { return fmt.Sprintf("%v != 0", name) } case "void", "": { if strings.Contains(vOld, "*") { return fmt.Sprintf("unsafe.Pointer(%v)", name) } return name } case "T", "JavaVM", "jclass", "jobject": { switch f.TemplateMode { case "Int": { return fmt.Sprintf("int(%v)", name) } case "Boolean": { return fmt.Sprintf("int(%v) != 0", name) } case "Void": { return name } } return fmt.Sprintf("unsafe.Pointer(%v)", name) } case "qreal": { return fmt.Sprintf("float64(%v)", name) } case "qint64": { return fmt.Sprintf("int64(%v)", name) } } switch { case isEnum(f.Class(), value): { if c, exists := parser.ClassMap[class(cppEnum(f, value, false))]; exists && module(c.Module) != module(f) && module(c.Module) != "" { if parser.ClassMap[f.Class()].WeakLink[c.Module] { return fmt.Sprintf("int64(%v)", name) } return fmt.Sprintf("%v.%v(%v)", module(c.Module), goEnum(f, value), name) } return fmt.Sprintf("%v(%v)", goEnum(f, value), name) } case isClass(value): { if m := module(parser.ClassMap[value].Module); m != module(f) { if parser.ClassMap[f.Class()].WeakLink[parser.ClassMap[value].Module] { return fmt.Sprintf("unsafe.Pointer(%v)", name) } return fmt.Sprintf("%v.New%vFromPointer(%v)", m, value, name) } if f.Meta == "constructor" { return fmt.Sprintf("new%vFromPointer(%v)", value, name) } return fmt.Sprintf("New%vFromPointer(%v)", value, name) } } f.Access = "unsupported_goOutput" return f.Access }
func cppOutput(name string, value string, f *parser.Function) string { var vOld = value name = cleanName(name) value = cleanValue(value) switch value { case "QStringList": { return cppOutput(fmt.Sprintf("%v.join(\"|\")", name), "QString", f) } case "QString": { if strings.Contains(vOld, "*") { return fmt.Sprintf("%v->toUtf8().data()", name) } return fmt.Sprintf("%v.toUtf8().data()", name) } case "bool", "int", "void", "", "T", "JavaVM", "jclass": { if value == "void" { if strings.Contains(vOld, "*") { if strings.Contains(vOld, "const") { return fmt.Sprintf("const_cast<%v*>(%v)", value, name) } return name } } return name } case "qreal": { return fmt.Sprintf("static_cast<double>(%v)", name) } } switch { case isEnum(f.Class(), value): { return name } case isClass(value): { if strings.Contains(vOld, "*") { if strings.Contains(vOld, "const") { return fmt.Sprintf("const_cast<%v*>(%v)", value, name) } return name } switch value { case "QModelIndex": { return fmt.Sprintf("%v.internalPointer()", name) } case "QJSValue", "QScriptValue", "QVariant", "QStringRef", "QDateTime", "QTimeZone", "QRegularExpressionMatchIterator", "QRegularExpressionMatch", "QRegularExpression", "QDir", "QByteArray", "QEasingCurve", "QCommandLineOption", "QRegExp", "QJsonObject", "QJsonArray", "QJsonDocument", "QRegion", "QBrush", "QColor": { return fmt.Sprintf("new %v(%v)", value, name) } case "QAndroidJniObject": { return name } } } } f.Access = "unsupported_cppOutput" return f.Access }
func cppType(f *parser.Function, value string) string { var vOld = value value = cleanValue(value) switch value { case "uchar", "char", "QString", "QStringList": { return "char*" } case "bool", "int": { return "int" } case "void", "": { if strings.Contains(vOld, "*") { return "void*" } return "void" } case "T": { switch f.TemplateMode { case "Int": { return "int" } case "Boolean": { return "int" } case "Void": { return "void" } } return "void*" } case "JavaVM", "jclass", "jobject": { return "void*" } case "...": { var tmp string for i := 0; i < 10; i++ { if i == 9 { tmp += "void*" } else { tmp += fmt.Sprintf("void* %v%v, ", "v", i) } } return strings.TrimSuffix(tmp, ", ") } case "qreal": { return "double" } case "qint64": { return "long long" } } switch { case isEnum(f.Class(), value): { return "int" } case isClass(value): { return "void*" } } f.Access = "unsupported_cppType" return f.Access }
func goType(f *parser.Function, value string) string { var vOld = value value = cleanValue(value) switch value { case "uchar", "char", "QString": { if strings.Contains(vOld, "**") { return "[]string" } return "string" } case "QStringList": { return "[]string" } case "void": { if strings.Contains(vOld, "*") { return "unsafe.Pointer" } return "" } case "bool", "int", "": { return value } case "T": { switch f.TemplateMode { case "Int": { return "int" } case "Boolean": { return "bool" } case "Void": return "" } if module(f) == "androidextras" && f.Name != "object" { return fmt.Sprintf("interface{}") } return "unsafe.Pointer" } case "JavaVM", "jclass", "jobject": { return "unsafe.Pointer" } case "...": { if parser.ClassMap[f.Class()].Module == "QtAndroidExtras" { return "...interface{}" } } case "qreal": { return "float64" } case "qint64": { return "int64" } } switch { case isEnum(f.Class(), value): { if c, exists := parser.ClassMap[class(cppEnum(f, value, false))]; exists && module(c.Module) != module(f) && module(c.Module) != "" { if parser.ClassMap[f.Class()].WeakLink[c.Module] { return "int64" } return module(c.Module) + "." + goEnum(f, value) } return goEnum(f, value) } case isClass(value): { if m := module(parser.ClassMap[value].Module); m != module(f) { if parser.ClassMap[f.Class()].WeakLink[parser.ClassMap[value].Module] { return "unsafe.Pointer" } return m + "." + value } return value } } f.Access = "unsupported_goType" return f.Access }
func goFunctionHeader(f *parser.Function) string { if f.Static || f.Meta == "constructor" || f.SignalMode == "callback" { return fmt.Sprintf("func %v", goInterface(f)) } return fmt.Sprintf("func (ptr *%v)%v", f.Class(), goInterface(f)) }
func cppInput(name string, value string, f *parser.Function) string { var vOld = value name = cleanName(name) value = cleanValue(value) switch value { case "QStringList": { return fmt.Sprintf("%v.split(\"|\", QString::SkipEmptyParts)", cppInput(name, "QString", f)) } case "QString": { if strings.Contains(vOld, "&") { if strings.Contains(vOld, "const") { return fmt.Sprintf("%v(%v)", value, name) } f.Access = "unsupported_CppInput" return f.Access } if strings.Contains(vOld, "*") { return fmt.Sprintf("new %v(%v)", value, name) } return fmt.Sprintf("%v(%v)", value, name) } case "bool": { if strings.Contains(vOld, "*") { return "NULL" } return fmt.Sprintf("%v != 0", name) } case "int": { if strings.Contains(vOld, "*") { return fmt.Sprintf("&%v", name) } if strings.Contains(vOld, "&") && name == "argc" { return "argcs" } return name } case "char": { if strings.Contains(vOld, "const") { if strings.Contains(vOld, "*") { return fmt.Sprintf("const_cast<const %v*>(%v)", value, name) } } if strings.Contains(vOld, "**") { return "argvs" //return "const_cast<char **>(argvs.data())" } if strings.Contains(vOld, "*") { return name } return fmt.Sprintf("*%v", name) } case "qreal": { if strings.Contains(vOld, "*") { f.Access = "unsupported_CppInput" return f.Access //return fmt.Sprintf("&static_cast<qreal>(%v)", name) } return fmt.Sprintf("static_cast<qreal>(%v)", name) } case "jclass": { return fmt.Sprintf("static_cast<%v>(%v)", value, name) } } switch { case isEnum(f.Class(), value): { if !strings.Contains(vOld, "*") { return fmt.Sprintf("static_cast<%v>(%v)", cppEnum(f, value, false), name) } } case isClass(value): { if strings.Contains(vOld, "*") { if strings.Contains(vOld, "&") { break } return fmt.Sprintf("static_cast<%v*>(%v)", value, name) } return fmt.Sprintf("*static_cast<%v*>(%v)", value, name) } } f.Access = "unsupported_CppInput" return f.Access }
func goFunctionBody(f *parser.Function) (o string) { if parser.ClassMap[f.Class()].Stub { if converter.GoHeaderOutput(f) != "" { return fmt.Sprintf("\nreturn %v", converter.GoBodyOutputFailed(f)) } return "" } if f.SignalMode != "" { o += fmt.Sprintf("defer qt.Recovering(\"%v %v\")\n\n", strings.ToLower(f.SignalMode), f.Fullname) } else { o += fmt.Sprintf("defer qt.Recovering(\"%v\")\n\n", f.Fullname) } //o += fmt.Sprintf("println(\"%v\")\n\n", f.Fullname) if !f.Static && f.Meta != "constructor" && f.SignalMode != "callback" { o += fmt.Sprintf("if ptr.Pointer() != nil {\n") } for _, p := range f.Parameters { if p.Value == "..." { for i := 0; i < 10; i++ { o += fmt.Sprintf("var p%v,d%v = assertion(%v, v...)\n", i, i, i) o += fmt.Sprintf("if d%v != nil {\ndefer d%v()\n}\n", i, i) } } if p.Value == "T" && parser.ClassMap[f.Class()].Module == "QtAndroidExtras" && f.TemplateMode == "" { o += fmt.Sprintf("var p0,d0 = assertion(0, %v)\n", p.Name) o += "if d0 != nil {\ndefer d0()\n}\n" } } if converter.GoHeaderOutput(f) != "" { o += "return " } /* if (f.Meta == "destructor" && isObjectSubClass(f.Class())) || (f.Meta == "slot" && strings.Contains(f.Name, "deleteLater")) { o += "getSignal(ptr.ObjectName(), \"destroyed\").(func(QObject, QObject))(ptr, ptr)\n" } */ if f.SignalMode == "callback" { o += fmt.Sprintf("if signal := qt.GetSignal(C.GoString(ptrName), \"%v%v\"); signal != nil {\n", f.Name, cppFunctionSignalOverload(f)) o += fmt.Sprintf("\tsignal.(%v)(%v)\n", converter.GoHeaderInputSignalFunction(f), converter.GoBodyInputSignalValues(f)) if f.Virtual == "impure" { if isDerivedFromPure(f) { o += "}\n" } else { if f.Meta == "slot" || isDerivedFromSlot(f) { o += fmt.Sprintf("\treturn true\n}\nreturn false\n") } else { o += fmt.Sprintf("} else {\n\tNew%vFromPointer(ptr).%vDefault(%v)\n}", f.Class(), strings.Title(f.Name), converter.GoBodyInputSignalValues(f)) } } } else { o += "}\n" } } else { if strings.Contains(f.Virtual, "impure") && f.SignalMode != "" { } else { o += converter.GoBodyOutput(f, fmt.Sprintf("C.%v(%v)", converter.CppHeaderName(f), converter.GoBodyInput(f))) } } if f.SignalMode == "Connect" { if parser.ClassMap[f.Class()].IsQObjectSubClass() { o += fmt.Sprintf("\nqt.ConnectSignal(ptr.ObjectName(), \"%v%v\", f)", f.Name, cppFunctionSignalOverload(f)) } else { o += fmt.Sprintf("\nqt.ConnectSignal(ptr.ObjectNameAbs(), \"%v%v\", f)", f.Name, cppFunctionSignalOverload(f)) } } if f.SignalMode == "Disconnect" { if parser.ClassMap[f.Class()].IsQObjectSubClass() { o += fmt.Sprintf("\nqt.DisconnectSignal(ptr.ObjectName(), \"%v%v\")", f.Name, cppFunctionSignalOverload(f)) } else { o += fmt.Sprintf("\nqt.DisconnectSignal(ptr.ObjectNameAbs(), \"%v%v\")", f.Name, cppFunctionSignalOverload(f)) } } if (f.Meta == "destructor" && isObjectSubClass(f.Class())) || (f.Meta == "slot" && strings.Contains(f.Name, "deleteLater")) { o += "\nptr.SetPointer(nil)" } if !f.Static && f.Meta != "constructor" && f.SignalMode != "callback" { o += "\n}" if converter.GoHeaderOutput(f) != "" { o += fmt.Sprintf("\nreturn %v", converter.GoBodyOutputFailed(f)) } } return o }
func goType(f *parser.Function, value string) string { var vOld = value value = cleanValue(value) switch value { case "uchar", "char", "QString": { if strings.Contains(vOld, "**") { return "[]string" } return "string" } case "QStringList": { return "[]string" } case "void": { if strings.Contains(vOld, "*") { return "unsafe.Pointer" } return "" } case "bool", "int", "": { return value } case "T", "JavaVM", "jclass": { return "unsafe.Pointer" } case "qreal": { return "float64" } case "...": { return "" } } switch { case isEnum(f.Class(), value): { if c, exists := parser.ClassMap[class(cppEnum(f, value, false))]; exists && module(c.Module) != module(f) && module(c.Module) != "" { return module(c.Module) + "." + goEnum(f, value) } return goEnum(f, value) } case isClass(value): { if m := module(parser.ClassMap[value].Module); m != module(f) { return m + "." + value } return value } } f.Access = "unsupported_goType" return f.Access }
func cppFunctionBody(f *parser.Function) (o string) { /* for _, p := range f.Parameters { if strings.Contains(p.Value, "**") && p.Name == "argv" { o += "QList<QByteArray> aList = QByteArray(argv).split('|');\n" o += "\tQVarLengthArray<const char*> argvs(argc);\n" o += "\tstatic int argcs = argc;\n" o += "\tfor (int i = 0; i < argc; i++)\n" o += "\t\targvs[i] = static_cast<const char*>(aList[i].constData());\n\n\t" } } */ for _, p := range f.Parameters { if strings.Contains(p.Value, "**") && p.Name == "argv" { o += "QList<QByteArray> aList = QByteArray(argv).split('|');\n" o += "\tchar *argvs[argc];\n" o += "\tstatic int argcs = argc;\n" o += "\tfor (int i = 0; i < argc; i++)\n" o += "\t\targvs[i] = aList[i].data();\n\n\t" } } if converter.CppHeaderOutput(f) != "void" { o += "return " } switch f.Meta { case "constructor": o += fmt.Sprintf("new %v(%v)", f.Class(), converter.CppBodyInput(f)) case "slot": if f.Static { o += fmt.Sprintf("QMetaObject::invokeMethod(%v::instance(), \"%v\"%v)", f.Class(), f.Name, converter.CppBodyInput(f)) } else { o += fmt.Sprintf("QMetaObject::invokeMethod(static_cast<%v*>(ptr), \"%v\"%v)", f.Class(), f.Name, converter.CppBodyInput(f)) } case "plain", "destructor": if f.Static { o += converter.CppBodyOutput(f, fmt.Sprintf("%v::%v(%v)", f.Class(), f.Name, converter.CppBodyInput(f))) } else { if f.Output == "T" && f.Class() == "QObject" { o += converter.CppBodyOutput(f, fmt.Sprintf("static_cast<%v*>(ptr)->%v<QObject*>(%v)", f.Class(), f.Name, converter.CppBodyInput(f))) } else if f.Output == "T" && f.Class() == "QMediaService" { o += converter.CppBodyOutput(f, fmt.Sprintf("static_cast<%v*>(ptr)->%v<QMediaControl*>(%v)", f.Class(), f.Name, converter.CppBodyInput(f))) } else { o += converter.CppBodyOutput(f, fmt.Sprintf("static_cast<%v*>(ptr)->%v(%v)", f.Class(), f.Name, converter.CppBodyInput(f))) } } case "signal": if converter.PrivateSignal(f) { o += fmt.Sprintf("QObject::%v(%v, &%v::%v, static_cast<My%v*>(ptr), static_cast<%v (My%v::*)(%v)>(&My%v::Signal_%v));", strings.ToLower(f.SignalMode), fmt.Sprintf("static_cast<%v*>(%v)", f.Class(), "ptr"), f.Class(), f.Name, f.Class(), f.Output, f.Class(), converter.CppBodyInput(f), f.Class(), strings.Title(f.Name)) } else { o += fmt.Sprintf("QObject::%v(%v, static_cast<void (%v::*)(%v)>(&%v::%v), static_cast<My%v*>(ptr), static_cast<%v (My%v::*)(%v)>(&My%v::Signal_%v));", strings.ToLower(f.SignalMode), fmt.Sprintf("static_cast<%v*>(%v)", f.Class(), "ptr"), f.Class(), converter.CppBodyInput(f), f.Class(), f.Name, f.Class(), f.Output, f.Class(), converter.CppBodyInput(f), f.Class(), strings.Title(f.Name)) } default: f.Access = "unsupported_CppFunctionBody" return f.Access } return fmt.Sprintf("%v;", o) }
func cppFunctionSignal(f *parser.Function) string { return fmt.Sprintf("void Signal_%v(%v){callback%v%v(%v);}", strings.Title(f.Name), converter.CppBodyInputCallback(f), f.Class(), strings.Title(f.Name), converter.CppBodyOutputCallback(f)) }