cutego/internal/binding/templater/function_go.go

273 lines
8.7 KiB
Go
Raw Normal View History

2015-10-24 18:18:24 +03:00
package templater
import (
"bytes"
2015-10-24 18:18:24 +03:00
"fmt"
"os"
2015-10-24 18:18:24 +03:00
"strings"
"github.com/therecipe/qt/internal/binding/converter"
"github.com/therecipe/qt/internal/binding/parser"
)
func goFunction(function *parser.Function) string {
var output = fmt.Sprintf("%v{\n%v\n}", goFunctionHeader(function), goFunctionBody(function))
2017-01-02 19:01:18 +03:00
if function.IsSupported() {
if UseStub() {
if function.SignalMode != parser.CALLBACK {
return output
}
} else {
return output
}
}
return ""
}
func goFunctionHeader(function *parser.Function) string {
2016-08-28 19:09:35 +03:00
return fmt.Sprintf("func %v %v(%v)%v",
func() string {
if function.Static || function.Meta == parser.CONSTRUCTOR || function.SignalMode == parser.CALLBACK {
return ""
}
2016-12-11 23:03:06 +03:00
return fmt.Sprintf("(ptr *%v)", function.ClassName())
}(),
2015-11-19 21:29:30 +03:00
converter.GoHeaderName(function),
converter.GoHeaderInput(function),
converter.GoHeaderOutput(function),
)
}
func goFunctionBody(function *parser.Function) string {
var bb = new(bytes.Buffer)
defer bb.Reset()
if strings.ToLower(os.Getenv("QT_DEBUG")) == "true" {
fmt.Fprintf(bb, "defer qt.Recover(\"\t%v%v%v(%v) %v\")\n",
2016-12-11 23:03:06 +03:00
function.ClassName(),
func() string {
2016-12-11 23:03:06 +03:00
return strings.Repeat(" ", 45-len(function.ClassName()))
}(),
converter.GoHeaderName(function), converter.GoHeaderInput(function), converter.GoHeaderOutput(function))
fmt.Fprintf(bb, "qt.Debug(\"\t%v%v%v(%v) %v\")\n",
2016-12-11 23:03:06 +03:00
function.ClassName(),
func() string {
2016-12-11 23:03:06 +03:00
return strings.Repeat(" ", 45-len(function.ClassName()))
}(),
converter.GoHeaderName(function), converter.GoHeaderInput(function), converter.GoHeaderOutput(function))
}
2017-01-02 19:01:18 +03:00
if parser.State.ClassMap[function.ClassName()].Stub {
if converter.GoHeaderOutput(function) != "" {
return fmt.Sprintf("\nreturn %v", converter.GoOutputParametersFromCFailed(function))
2015-11-19 21:29:30 +03:00
}
return ""
2015-11-19 21:29:30 +03:00
}
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
}
for _, parameter := range function.Parameters {
2017-01-02 19:01:18 +03:00
if parameter.Value == "..." || (parameter.Value == "T" && parser.State.ClassMap[function.ClassName()].Module == "QtAndroidExtras" && function.TemplateModeJNI == "") {
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-01-04 20:24:19 +03:00
}
}
}
2015-10-24 18:18:24 +03:00
if ((function.Meta == parser.PLAIN && function.SignalMode == "") ||
(function.Meta == parser.SLOT && function.SignalMode == "") ||
(function.Meta == parser.CONSTRUCTOR || function.Meta == parser.DESTRUCTOR) && function.SignalMode == "") ||
(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
//TODO:
2017-01-02 19:01:18 +03:00
if function.IsSupported() {
cppFunction(function)
2017-01-02 19:01:18 +03:00
if function.IsSupported() {
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)
}
2016-08-28 19:09:35 +03:00
var body = converter.GoOutputParametersFromC(function, fmt.Sprintf("C.%v(%v)", converter.CppHeaderName(function), converter.GoInputParametersForC(function)))
2016-08-20 00:20:42 +03:00
fmt.Fprint(bb, func() string {
if converter.GoHeaderOutput(function) != "" {
2016-08-28 19:09:35 +03:00
switch {
2017-01-02 19:01:18 +03:00
case function.NeedsFinalizer && parser.State.ClassMap[parser.CleanValue(function.Output)].IsSupported() || function.Meta == parser.CONSTRUCTOR && !(parser.State.ClassMap[function.Name].HasCallbackFunctions() || parser.State.ClassMap[function.Name].IsSubClassOfQObject()):
2016-08-28 19:09:35 +03:00
{
return fmt.Sprintf("var tmpValue = %v\nruntime.SetFinalizer(tmpValue, (%v).Destroy%v)\nreturn tmpValue%v",
body,
func() string {
2016-11-16 01:07:05 +03:00
if function.TemplateModeJNI != "" {
2017-01-02 19:01:18 +03:00
return fmt.Sprintf("*%v", parser.CleanValue(function.Output))
2016-08-28 19:09:35 +03:00
}
return converter.GoHeaderOutput(function)
}(),
func() string {
if function.Meta == parser.CONSTRUCTOR {
return function.Name
}
2017-01-02 19:01:18 +03:00
return parser.CleanValue(function.Output)
2016-08-28 19:09:35 +03:00
}(),
func() string {
2016-11-16 01:07:05 +03:00
if function.TemplateModeJNI == "String" {
2016-08-28 19:09:35 +03:00
return ".ToString()"
}
return ""
}())
2016-08-24 18:00:49 +03:00
}
2016-08-28 19:09:35 +03:00
2017-01-02 19:01:18 +03:00
case parser.State.ClassMap[parser.CleanValue(function.Output)].IsSubClassOfQObject() && converter.GoHeaderOutput(function) != "unsafe.Pointer" || function.Meta == parser.CONSTRUCTOR && parser.State.ClassMap[parser.CleanValue(function.Name)].IsSubClassOfQObject():
2016-08-28 19:09:35 +03:00
{
return fmt.Sprintf("var tmpValue = %v\nif !qt.ExistsSignal(fmt.Sprint(tmpValue.Pointer()), \"QObject::destroyed\") {\ntmpValue.ConnectDestroyed(func(%v){ tmpValue.SetPointer(nil) })\n}\nreturn tmpValue",
body,
func() string {
2017-01-02 19:01:18 +03:00
if parser.State.ClassMap[function.ClassName()].Module == "QtCore" {
2016-08-28 19:09:35 +03:00
return "*QObject"
}
return "*core.QObject"
}())
}
default:
{
return fmt.Sprintf("return %v", body)
2016-08-24 18:00:49 +03:00
}
2016-08-20 00:20:42 +03:00
}
}
return body
2016-08-28 19:09:35 +03:00
}())
2015-10-24 18:18:24 +03:00
}
function.Access = "public"
2015-10-24 18:18:24 +03:00
}
}
2015-12-22 18:59:41 +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",
func() string {
if function.Meta != parser.SLOT {
return "\n"
}
return ""
2016-12-11 23:03:06 +03:00
}(), function.ClassName(), function.Name, function.OverloadNumber)
if converter.GoHeaderOutput(function) == "" {
fmt.Fprintf(bb, "signal.(%v)(%v)", converter.GoHeaderInputSignalFunction(function), converter.GoInputParametersForCallback(function))
} else {
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{"
}
}
return ""
}(),
)
if converter.GoHeaderOutput(function) == "" {
2017-01-02 19:01:18 +03:00
if parser.State.Moc && function.PureBaseFunction {
2016-12-11 23:03:06 +03:00
} else {
2017-01-02 19:01:18 +03:00
if function.Virtual == parser.IMPURE && function.IsSupportedDefault() {
2016-12-11 23:03:06 +03:00
fmt.Fprintf(bb, "New%vFromPointer(ptr).%v%vDefault(%v)", strings.Title(function.ClassName()), strings.Replace(strings.Title(function.Name), parser.TILDE, "Destroy", -1), function.OverloadNumber, converter.GoInputParametersForCallback(function))
}
}
} else {
2017-01-02 19:01:18 +03:00
if parser.State.Moc && function.PureBaseFunction {
fmt.Fprintf(bb, "\nreturn %v", converter.GoInput(converter.GoOutputParametersFromCFailed(function), function.Output, function))
2016-12-11 23:03:06 +03:00
} else {
2017-01-02 19:01:18 +03:00
if function.Virtual == parser.IMPURE && function.IsSupportedDefault() {
2016-12-11 23:03:06 +03:00
fmt.Fprintf(bb, "\nreturn %v", converter.GoInput(fmt.Sprintf("New%vFromPointer(ptr).%v%vDefault(%v)", strings.Title(function.ClassName()), strings.Replace(strings.Title(function.Name), parser.TILDE, "Destroy", -1), function.OverloadNumber, converter.GoInputParametersForCallback(function)), function.Output, function))
} else {
fmt.Fprintf(bb, "\nreturn %v", converter.GoInput(converter.GoOutputParametersFromCFailed(function), function.Output, function))
}
2016-01-04 20:24:19 +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-10-24 18:18:24 +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)",
function.SignalMode,
2016-12-11 23:03:06 +03:00
function.ClassName(),
function.Name,
function.OverloadNumber,
func() string {
if function.SignalMode == parser.CONNECT {
return ", f"
}
return ""
}(),
)
}
2015-10-24 18:18:24 +03:00
}
if (function.Meta == parser.DESTRUCTOR || strings.Contains(function.Name, "deleteLater") || strings.HasPrefix(function.Name, parser.TILDE)) && function.SignalMode == "" {
2017-01-02 19:01:18 +03:00
if parser.State.ClassMap[function.ClassName()].HasCallbackFunctions() || parser.State.ClassMap[function.ClassName()].IsSubClassOfQObject() {
2016-08-24 18:00:49 +03:00
fmt.Fprint(bb, "\nqt.DisconnectAllSignals(fmt.Sprint(ptr.Pointer()))")
}
fmt.Fprint(bb, "\nptr.SetPointer(nil)")
2015-10-24 18:18:24 +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
}
}
return bb.String()
2015-10-24 18:18:24 +03:00
}