2015-10-24 18:18:24 +03:00
|
|
|
package templater
|
|
|
|
|
|
|
|
import (
|
2016-04-28 20:43:44 +03:00
|
|
|
"bytes"
|
2015-10-24 18:18:24 +03:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/therecipe/qt/internal/binding/converter"
|
|
|
|
"github.com/therecipe/qt/internal/binding/parser"
|
|
|
|
)
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
func goFunction(function *parser.Function) string {
|
|
|
|
var output = fmt.Sprintf("%v{\n%v\n}", goFunctionHeader(function), goFunctionBody(function))
|
|
|
|
if functionIsSupported(parser.ClassMap[function.Class()], function) {
|
|
|
|
return output
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
func goFunctionHeader(function *parser.Function) string {
|
|
|
|
return fmt.Sprintf("func %v %v%v(%v)%v",
|
|
|
|
func() string {
|
|
|
|
if function.Static || function.Meta == parser.CONSTRUCTOR || function.SignalMode == parser.CALLBACK {
|
|
|
|
return ""
|
2016-04-18 23:31:34 +03:00
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
return fmt.Sprintf("(ptr *%v)", function.Class())
|
|
|
|
}(),
|
2015-11-19 21:29:30 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
converter.GoHeaderName(function),
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
func() string {
|
|
|
|
if function.Default {
|
|
|
|
return "Default"
|
2016-01-04 04:05:31 +03:00
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
return ""
|
|
|
|
}(),
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
converter.GoHeaderInput(function),
|
|
|
|
|
|
|
|
converter.GoHeaderOutput(function),
|
|
|
|
)
|
|
|
|
}
|
2015-12-15 04:01:51 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
func goFunctionBody(function *parser.Function) string {
|
|
|
|
var bb = new(bytes.Buffer)
|
|
|
|
defer bb.Reset()
|
|
|
|
|
|
|
|
if parser.ClassMap[function.Class()].Stub {
|
|
|
|
if converter.GoHeaderOutput(function) != "" {
|
|
|
|
return fmt.Sprintf("\nreturn %v", converter.GoOutputParametersFromCFailed(function))
|
2015-11-19 21:29:30 +03:00
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
return ""
|
2015-11-19 21:29:30 +03:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprintf(bb, "defer qt.Recovering(\"%v%v\")\n\n",
|
|
|
|
func() string {
|
|
|
|
if function.SignalMode != "" {
|
|
|
|
return strings.ToLower(function.SignalMode) + " "
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}(),
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
function.Fullname,
|
|
|
|
)
|
|
|
|
|
|
|
|
if !(function.Static || function.Meta == parser.CONSTRUCTOR || function.SignalMode == parser.CALLBACK) {
|
|
|
|
fmt.Fprintf(bb, "if ptr.Pointer() != nil {\n")
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
for _, parameter := range function.Parameters {
|
|
|
|
if parameter.Value == "..." || (parameter.Value == "T" && parser.ClassMap[function.Class()].Module == "QtAndroidExtras" && function.TemplateMode == "") {
|
|
|
|
for i := 0; i < 10; i++ {
|
|
|
|
if parameter.Value == "T" {
|
|
|
|
fmt.Fprintf(bb, "var p%v, d%v = assertion(%v, %v)\n", i, i, i, parameter.Name)
|
|
|
|
} else {
|
|
|
|
fmt.Fprintf(bb, "var p%v, d%v = assertion(%v, v...)\n", i, i, i)
|
|
|
|
}
|
|
|
|
fmt.Fprintf(bb, "if d%v != nil {\ndefer d%v()\n}\n", i, i)
|
|
|
|
|
|
|
|
if parameter.Value == "T" {
|
|
|
|
break
|
2016-04-18 23:31:34 +03:00
|
|
|
}
|
2016-01-04 20:24:19 +03:00
|
|
|
}
|
2016-01-04 04:05:31 +03:00
|
|
|
}
|
2015-12-15 04:01:51 +03:00
|
|
|
}
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
if ((function.Meta == parser.PLAIN && function.SignalMode == "") ||
|
|
|
|
(function.Meta == parser.SLOT && function.SignalMode == "") ||
|
|
|
|
function.Meta == parser.CONSTRUCTOR || function.Meta == parser.DESTRUCTOR) ||
|
2016-05-21 23:50:57 +03:00
|
|
|
(function.Meta == parser.SIGNAL && (function.SignalMode == "" || function.SignalMode == parser.CONNECT || function.SignalMode == parser.DISCONNECT)) ||
|
|
|
|
(function.Meta == parser.GETTER || function.Meta == parser.SETTER) {
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
//TODO:
|
|
|
|
if functionIsSupported(parser.ClassMap[function.Class()], function) {
|
|
|
|
cppFunction(function)
|
|
|
|
if functionIsSupported(parser.ClassMap[function.Class()], function) {
|
2015-11-19 21:29:30 +03:00
|
|
|
|
2016-08-20 00:20:42 +03:00
|
|
|
for _, alloc := range converter.GoInputParametersForCAlloc(function) {
|
|
|
|
fmt.Fprint(bb, alloc)
|
|
|
|
}
|
|
|
|
|
|
|
|
var body = converter.GoOutputParametersFromC(function, fmt.Sprintf("C.%v%v(%v)",
|
|
|
|
|
|
|
|
converter.CppHeaderName(function),
|
2015-12-06 02:56:16 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
func() string {
|
2016-08-20 00:20:42 +03:00
|
|
|
if function.Default {
|
|
|
|
return "Default"
|
2016-04-28 20:43:44 +03:00
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}(),
|
2016-01-04 05:43:27 +03:00
|
|
|
|
2016-08-20 00:20:42 +03:00
|
|
|
converter.GoInputParametersForC(function)))
|
|
|
|
|
|
|
|
fmt.Fprint(bb, func() string {
|
|
|
|
if converter.GoHeaderOutput(function) != "" {
|
2016-08-26 20:43:21 +03:00
|
|
|
if function.NeedsFinalizer && classIsSupported(parser.ClassMap[converter.CleanValue(function.Output)]) || classIsSupported(parser.ClassMap[function.Class()]) && function.Meta == parser.CONSTRUCTOR && !(parser.ClassMap[function.Class()].IsQObjectSubClass() || needsCallbackFunctions(parser.ClassMap[function.Class()])) {
|
2016-08-20 00:20:42 +03:00
|
|
|
return fmt.Sprintf(`var tmpValue = %v
|
|
|
|
runtime.SetFinalizer(tmpValue, (%v).Destroy%v)
|
|
|
|
return tmpValue%v`, body,
|
|
|
|
|
|
|
|
func() string {
|
|
|
|
if function.TemplateMode == "String" {
|
|
|
|
return fmt.Sprintf("*%v", function.Class())
|
|
|
|
}
|
|
|
|
return converter.GoHeaderOutput(function)
|
|
|
|
}(),
|
|
|
|
|
2016-08-23 23:51:01 +03:00
|
|
|
func() string {
|
|
|
|
var out = strings.TrimPrefix(converter.GoHeaderOutput(function), "*")
|
|
|
|
if strings.Contains(out, ".") {
|
|
|
|
return strings.Split(out, ".")[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
if function.TemplateMode != "" {
|
|
|
|
return converter.CleanValue(function.Output)
|
|
|
|
}
|
|
|
|
|
|
|
|
return out
|
|
|
|
}(),
|
2016-08-20 00:20:42 +03:00
|
|
|
|
|
|
|
func() string {
|
|
|
|
if function.TemplateMode == "String" {
|
|
|
|
return ".ToString()"
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}(),
|
|
|
|
)
|
2016-08-24 18:00:49 +03:00
|
|
|
} else {
|
|
|
|
var out = strings.TrimPrefix(converter.GoHeaderOutput(function), "*")
|
|
|
|
if strings.Contains(out, ".") {
|
|
|
|
out = strings.Split(out, ".")[1]
|
|
|
|
}
|
|
|
|
if class, exists := parser.ClassMap[out]; exists && classIsSupported(class) && class.IsQObjectSubClass() {
|
|
|
|
return fmt.Sprintf(`var tmpValue = %v
|
|
|
|
if !qt.ExistsSignal(fmt.Sprint(tmpValue.Pointer()), "QObject::destroyed") {
|
2016-08-26 16:33:11 +03:00
|
|
|
tmpValue.ConnectDestroyed(func(%v){ tmpValue.SetPointer(nil) })
|
2016-08-24 18:00:49 +03:00
|
|
|
}
|
|
|
|
return tmpValue`, body, func() string {
|
|
|
|
if parser.ClassMap[function.Class()].Module == "QtCore" {
|
|
|
|
return "*QObject"
|
|
|
|
}
|
|
|
|
return "*core.QObject"
|
|
|
|
}())
|
|
|
|
}
|
2016-08-20 00:20:42 +03:00
|
|
|
}
|
|
|
|
return fmt.Sprintf("return %v", body)
|
|
|
|
}
|
|
|
|
return body
|
|
|
|
}(),
|
2016-04-28 20:43:44 +03:00
|
|
|
)
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
}
|
|
|
|
function.Access = "public"
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
}
|
2015-12-22 18:59:41 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
switch function.SignalMode {
|
|
|
|
case parser.CALLBACK:
|
|
|
|
{
|
2016-08-24 18:00:49 +03:00
|
|
|
fmt.Fprintf(bb, "%vif signal := qt.GetSignal(fmt.Sprint(ptr), \"%v::%v%v\"); signal != nil {\n",
|
2016-04-28 20:43:44 +03:00
|
|
|
func() string {
|
|
|
|
if function.Meta != parser.SLOT {
|
|
|
|
return "\n"
|
|
|
|
}
|
|
|
|
return ""
|
2016-08-24 18:00:49 +03:00
|
|
|
}(), function.Class(), function.Name, function.OverloadNumber)
|
2015-12-15 04:01:51 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
if converter.GoHeaderOutput(function) == "" {
|
|
|
|
fmt.Fprintf(bb, "signal.(%v)(%v)", converter.GoHeaderInputSignalFunction(function), converter.GoInputParametersForCallback(function))
|
2016-01-04 04:05:31 +03:00
|
|
|
} else {
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprintf(bb, "return %v", converter.GoInput(fmt.Sprintf("signal.(%v)(%v)", converter.GoHeaderInputSignalFunction(function), converter.GoInputParametersForCallback(function)), function.Output, function))
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Fprintf(bb, "\n}%v\n",
|
|
|
|
func() string {
|
|
|
|
if converter.GoHeaderOutput(function) == "" {
|
|
|
|
if function.Virtual == parser.IMPURE {
|
|
|
|
return "else{"
|
2016-04-16 19:48:26 +03:00
|
|
|
}
|
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
return ""
|
|
|
|
}(),
|
|
|
|
)
|
|
|
|
|
|
|
|
if converter.GoHeaderOutput(function) == "" {
|
2016-04-30 20:03:25 +03:00
|
|
|
if function.Virtual == parser.IMPURE && functionIsSupportedDefault(function) {
|
2016-05-22 01:54:06 +03:00
|
|
|
fmt.Fprintf(bb, "New%vFromPointer(ptr).%v%vDefault(%v)", strings.Title(function.Class()), strings.Title(function.Name), function.OverloadNumber, converter.GoInputParametersForCallback(function))
|
2016-04-28 20:43:44 +03:00
|
|
|
}
|
|
|
|
} else {
|
2016-04-30 20:03:25 +03:00
|
|
|
if function.Virtual == parser.IMPURE && functionIsSupportedDefault(function) {
|
2016-05-22 01:54:06 +03:00
|
|
|
fmt.Fprintf(bb, "\nreturn %v", converter.GoInput(fmt.Sprintf("New%vFromPointer(ptr).%v%vDefault(%v)", strings.Title(function.Class()), strings.Title(function.Name), function.OverloadNumber, converter.GoInputParametersForCallback(function)), function.Output, function))
|
2016-04-28 20:43:44 +03:00
|
|
|
} else {
|
|
|
|
fmt.Fprintf(bb, "\nreturn %v", converter.GoInput(converter.GoOutputParametersFromCFailed(function), function.Output, function))
|
2016-01-04 20:24:19 +03:00
|
|
|
}
|
2016-01-04 04:05:31 +03:00
|
|
|
}
|
2015-12-15 04:01:51 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprintf(bb, "%v",
|
|
|
|
func() string {
|
|
|
|
if converter.GoHeaderOutput(function) == "" {
|
|
|
|
if function.Virtual == parser.IMPURE {
|
|
|
|
return "\n}"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}(),
|
|
|
|
)
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2015-12-15 04:01:51 +03:00
|
|
|
}
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
case parser.CONNECT, parser.DISCONNECT:
|
|
|
|
{
|
2016-08-24 18:00:49 +03:00
|
|
|
fmt.Fprintf(bb, "\nqt.%vSignal(fmt.Sprint(ptr.Pointer()), \"%v::%v%v\"%v)",
|
2016-04-28 20:43:44 +03:00
|
|
|
function.SignalMode,
|
|
|
|
|
2016-08-23 23:51:01 +03:00
|
|
|
function.Class(),
|
2016-04-28 20:43:44 +03:00
|
|
|
|
|
|
|
function.Name,
|
|
|
|
|
|
|
|
function.OverloadNumber,
|
|
|
|
|
|
|
|
func() string {
|
|
|
|
if function.SignalMode == parser.CONNECT {
|
|
|
|
return ", f"
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}(),
|
|
|
|
)
|
2015-12-15 04:01:51 +03:00
|
|
|
}
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
if (function.Meta == parser.DESTRUCTOR || strings.Contains(function.Name, "deleteLater")) && function.SignalMode == "" {
|
2016-08-26 20:43:21 +03:00
|
|
|
if needsCallbackFunctions(parser.ClassMap[function.Class()]) || parser.ClassMap[function.Class()].IsQObjectSubClass() {
|
2016-08-24 18:00:49 +03:00
|
|
|
fmt.Fprint(bb, "\nqt.DisconnectAllSignals(fmt.Sprint(ptr.Pointer()))")
|
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprint(bb, "\nptr.SetPointer(nil)")
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
if !(function.Static || function.Meta == parser.CONSTRUCTOR || function.SignalMode == parser.CALLBACK) {
|
|
|
|
fmt.Fprint(bb, "\n}")
|
|
|
|
if converter.GoHeaderOutput(function) != "" {
|
|
|
|
fmt.Fprintf(bb, "\nreturn %v", converter.GoOutputParametersFromCFailed(function))
|
2015-11-12 03:29:32 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
return bb.String()
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|