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"
|
2015-12-06 02:56:16 +03:00
|
|
|
"sort"
|
2015-10-24 18:18:24 +03:00
|
|
|
"strings"
|
|
|
|
|
2016-01-04 04:05:31 +03:00
|
|
|
"github.com/therecipe/qt/internal/binding/converter"
|
2015-10-24 18:18:24 +03:00
|
|
|
"github.com/therecipe/qt/internal/binding/parser"
|
|
|
|
)
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
func CppTemplate(module string) []byte {
|
|
|
|
var bb = new(bytes.Buffer)
|
|
|
|
defer bb.Reset()
|
2016-01-08 04:44:20 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
var tmpArray = getSortedClassNamesForModule(module)
|
2016-01-08 04:44:20 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
if module == parser.MOC {
|
2016-04-16 19:48:26 +03:00
|
|
|
var items = make(map[string]string)
|
|
|
|
|
|
|
|
for _, class := range tmpArray {
|
|
|
|
items[class] = parser.ClassMap[class].Bases
|
|
|
|
}
|
|
|
|
|
|
|
|
var provided = make([]string, 0)
|
|
|
|
|
|
|
|
for len(items) > 0 {
|
|
|
|
for item, dependency := range items {
|
|
|
|
var existsInOtherModule bool
|
2016-04-28 20:43:44 +03:00
|
|
|
if parser.ClassMap[dependency].Module != parser.MOC {
|
2016-04-16 19:48:26 +03:00
|
|
|
existsInOtherModule = true
|
|
|
|
}
|
|
|
|
var existsInCurrentOrder bool
|
|
|
|
for _, providedItem := range provided {
|
|
|
|
if dependency == providedItem {
|
|
|
|
existsInCurrentOrder = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if existsInOtherModule || existsInCurrentOrder {
|
|
|
|
provided = append(provided, item)
|
|
|
|
delete(items, item)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tmpArray = provided
|
|
|
|
}
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
for _, className := range tmpArray {
|
|
|
|
var class = parser.ClassMap[className]
|
2016-04-16 19:48:26 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
//all class enums
|
|
|
|
for _, enum := range class.Enums {
|
|
|
|
for _, value := range enum.Values {
|
|
|
|
if converter.EnumNeedsCppGlue(value.Value) {
|
|
|
|
fmt.Fprintf(bb, "%v\n\n", cppEnum(enum, value))
|
2016-04-16 19:48:26 +03:00
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if classIsSupported(class) {
|
|
|
|
var implementedVirtuals = make(map[string]bool)
|
|
|
|
|
2016-05-21 23:50:57 +03:00
|
|
|
if needsCallbackFunctions(class) || class.Module == parser.MOC {
|
2015-12-15 04:01:51 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprintf(bb,
|
|
|
|
`class %v%v: public %v
|
|
|
|
{
|
|
|
|
%vpublic:
|
|
|
|
`,
|
|
|
|
func() string {
|
|
|
|
if module == parser.MOC {
|
|
|
|
return ""
|
2016-01-04 04:05:31 +03:00
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
return "My"
|
|
|
|
}(),
|
|
|
|
|
|
|
|
class.Name,
|
|
|
|
|
|
|
|
func() string {
|
|
|
|
if module == parser.MOC {
|
|
|
|
return class.GetBases()[0]
|
|
|
|
}
|
|
|
|
return class.Name
|
|
|
|
}(),
|
|
|
|
|
|
|
|
func() string {
|
|
|
|
if module == parser.MOC {
|
|
|
|
return "Q_OBJECT\n"
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}())
|
|
|
|
|
|
|
|
if !class.IsQObjectSubClass() {
|
|
|
|
fmt.Fprintln(bb, "\tQString _objectName;")
|
|
|
|
fmt.Fprintln(bb, "\tQString objectNameAbs() const { return this->_objectName; };")
|
|
|
|
fmt.Fprintln(bb, "\tvoid setObjectNameAbs(const QString &name) { this->_objectName = name; };")
|
2016-01-04 04:05:31 +03:00
|
|
|
}
|
2015-12-15 04:01:51 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
if !hasUnimplementedPureVirtualFunctions(class.Name) {
|
|
|
|
for _, function := range class.Functions {
|
|
|
|
if function.Meta == parser.CONSTRUCTOR {
|
|
|
|
if functionIsSupported(class, function) {
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
var input = make([]string, len(function.Parameters))
|
|
|
|
for i, p := range function.Parameters {
|
|
|
|
input[i] = func() string {
|
|
|
|
if p.Name == "" {
|
|
|
|
return "v"
|
|
|
|
}
|
|
|
|
return p.Name
|
|
|
|
}()
|
2015-12-15 04:01:51 +03:00
|
|
|
}
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprintf(bb, "\t%v%v(%v) : %v(%v) {};\n",
|
|
|
|
func() string {
|
|
|
|
if module == parser.MOC {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return "My"
|
|
|
|
}(),
|
|
|
|
|
|
|
|
function.Class(),
|
|
|
|
|
|
|
|
strings.Split(strings.Split(function.Signature, "(")[1], ")")[0],
|
|
|
|
|
|
|
|
func() string {
|
|
|
|
if module == parser.MOC {
|
|
|
|
return class.GetBases()[0]
|
|
|
|
}
|
|
|
|
return function.Class()
|
|
|
|
}(),
|
|
|
|
|
|
|
|
strings.Join(input, ", "),
|
|
|
|
)
|
|
|
|
|
2016-04-16 19:48:26 +03:00
|
|
|
}
|
2015-12-15 04:01:51 +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
|
|
|
//all class functions
|
|
|
|
for _, function := range class.Functions {
|
|
|
|
implementedVirtuals[fmt.Sprint(function.Fullname, function.OverloadNumber)] = true
|
|
|
|
if functionIsSupported(class, function) && !strings.Contains(function.Meta, "structor") {
|
|
|
|
if function.Virtual == parser.IMPURE || function.Virtual == parser.PURE || function.Meta == parser.SIGNAL || function.Meta == parser.SLOT {
|
|
|
|
if !(module == parser.MOC && function.Meta == parser.SLOT) {
|
|
|
|
fmt.Fprintf(bb, "\t%v\n", cppFunctionCallback(function))
|
2015-12-23 18:22:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-01-04 04:05:31 +03:00
|
|
|
}
|
2015-12-23 18:22:00 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
//virtual parent functions
|
|
|
|
for _, parentClassName := range class.GetAllBases() {
|
|
|
|
var parentClass = parser.ClassMap[parentClassName]
|
|
|
|
if classIsSupported(parentClass) {
|
|
|
|
|
|
|
|
for _, function := range parentClass.Functions {
|
|
|
|
if _, exists := implementedVirtuals[fmt.Sprint(fmt.Sprintf("%v::%v", class.Name, function.Name), function.OverloadNumber)]; !exists {
|
|
|
|
implementedVirtuals[fmt.Sprint(fmt.Sprintf("%v::%v", class.Name, function.Name), function.OverloadNumber)] = true
|
|
|
|
if functionIsSupported(class, function) && !strings.Contains(function.Meta, "structor") {
|
|
|
|
|
|
|
|
var function = *function
|
|
|
|
function.Fullname = fmt.Sprintf("%v::%v", class.Name, function.Name)
|
|
|
|
if function.Virtual == parser.IMPURE || function.Virtual == parser.PURE || function.Meta == parser.SLOT {
|
|
|
|
fmt.Fprintf(bb, "\t%v\n", cppFunctionCallback(&function))
|
2015-12-23 18:22:00 +03:00
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
|
2015-12-15 04:01:51 +03:00
|
|
|
}
|
|
|
|
}
|
2015-12-06 02:56:16 +03:00
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
|
|
|
}
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
if module == parser.MOC {
|
|
|
|
fmt.Fprintln(bb, "signals:")
|
|
|
|
for _, function := range class.Functions {
|
|
|
|
if function.Meta == parser.SIGNAL {
|
|
|
|
var function = *function
|
|
|
|
function.Meta = parser.SLOT
|
|
|
|
fmt.Fprintf(bb, "\t%v;\n", cppFunctionCallbackHeader(&function))
|
2016-04-16 19:48:26 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprintln(bb, "public slots:")
|
|
|
|
for _, function := range class.Functions {
|
|
|
|
if function.Meta == parser.SLOT {
|
|
|
|
fmt.Fprintf(bb, "\t%v\n", cppFunctionCallback(function))
|
2016-04-16 19:48:26 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprint(bb, "};\n\n")
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
implementedVirtuals = make(map[string]bool)
|
|
|
|
|
|
|
|
//all class functions
|
|
|
|
for _, function := range class.Functions {
|
|
|
|
implementedVirtuals[fmt.Sprint(function.Fullname, function.OverloadNumber)] = true
|
|
|
|
if functionIsSupported(class, function) {
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case function.Meta == parser.SIGNAL:
|
|
|
|
{
|
|
|
|
for _, signalMode := range []string{parser.CONNECT, parser.DISCONNECT} {
|
|
|
|
var function = *function
|
|
|
|
function.SignalMode = signalMode
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprintf(bb, "%v\n\n", cppFunction(&function))
|
2016-01-04 04:05:31 +03:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
var function = *function
|
|
|
|
function.Meta = parser.PLAIN
|
|
|
|
if !converter.IsPrivateSignal(&function) {
|
|
|
|
fmt.Fprintf(bb, "%v\n\n", cppFunction(&function))
|
|
|
|
}
|
2015-12-06 02:56:16 +03:00
|
|
|
}
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
case (function.Virtual == parser.IMPURE || function.Virtual == parser.PURE) && !strings.Contains(function.Meta, "structor"):
|
|
|
|
{
|
|
|
|
var function = *function
|
|
|
|
if function.Meta != parser.SLOT {
|
|
|
|
function.Meta = parser.PLAIN
|
|
|
|
}
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprintf(bb, "%v\n\n", cppFunction(&function))
|
|
|
|
if function.Virtual == parser.IMPURE {
|
|
|
|
function.Meta = parser.PLAIN
|
|
|
|
function.Default = true
|
|
|
|
fmt.Fprintf(bb, "%v\n\n", cppFunction(&function))
|
|
|
|
}
|
|
|
|
}
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
case isGeneric(function):
|
|
|
|
{
|
|
|
|
for _, mode := range converter.CppOutputParametersJNIGenericModes(function) {
|
|
|
|
var function = *function
|
|
|
|
function.TemplateMode = mode
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprintf(bb, "%v\n\n", cppFunction(&function))
|
|
|
|
}
|
|
|
|
}
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
if !(function.Meta == parser.CONSTRUCTOR && hasUnimplementedPureVirtualFunctions(class.Name)) {
|
|
|
|
fmt.Fprintf(bb, "%v\n\n", cppFunction(function))
|
2016-01-04 04:05:31 +03:00
|
|
|
}
|
|
|
|
}
|
2015-12-06 02:56:16 +03:00
|
|
|
}
|
2016-01-04 04:05:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
//virtual parent functions
|
|
|
|
for _, parentClassName := range class.GetAllBases() {
|
|
|
|
var parentClass = parser.ClassMap[parentClassName]
|
|
|
|
if classIsSupported(parentClass) {
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
for _, function := range parentClass.Functions {
|
|
|
|
if _, exists := implementedVirtuals[fmt.Sprint(fmt.Sprintf("%v::%v", class.Name, function.Name), function.OverloadNumber)]; !exists {
|
|
|
|
implementedVirtuals[fmt.Sprint(fmt.Sprintf("%v::%v", class.Name, function.Name), function.OverloadNumber)] = true
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
if functionIsSupported(parentClass, function) {
|
2016-04-30 20:03:25 +03:00
|
|
|
if function.Meta != parser.SIGNAL && (function.Virtual == parser.IMPURE || function.Virtual == parser.PURE || function.Meta == parser.SLOT) && !strings.Contains(function.Meta, "structor") {
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
var function = *function
|
|
|
|
function.Fullname = fmt.Sprintf("%v::%v", class.Name, function.Name)
|
|
|
|
if function.Meta != parser.SLOT {
|
|
|
|
function.Meta = parser.PLAIN
|
|
|
|
}
|
2016-04-30 20:03:25 +03:00
|
|
|
fmt.Fprintf(bb, "%v\n\n", cppFunction(&function))
|
2016-04-16 19:48:26 +03:00
|
|
|
|
2016-04-30 20:03:25 +03:00
|
|
|
function.Meta = parser.PLAIN
|
|
|
|
function.Default = true
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprintf(bb, "%v\n\n", cppFunction(&function))
|
|
|
|
|
2016-01-04 04:05:31 +03:00
|
|
|
}
|
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
|
2016-01-04 04:05:31 +03:00
|
|
|
}
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
return preambleCpp(module, bb.Bytes())
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
func preambleCpp(module string, input []byte) []byte {
|
|
|
|
var bb = new(bytes.Buffer)
|
|
|
|
defer bb.Reset()
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2016-05-28 19:18:42 +03:00
|
|
|
fmt.Fprintf(bb, `%v
|
|
|
|
|
|
|
|
#define protected public
|
2016-04-28 20:43:44 +03:00
|
|
|
#define private public
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
#include "%v.h"
|
|
|
|
#include "_cgo_export.h"
|
2015-12-06 02:56:16 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
`,
|
2016-05-28 19:18:42 +03:00
|
|
|
func() string {
|
|
|
|
switch {
|
|
|
|
case Minimal:
|
|
|
|
{
|
|
|
|
return "// +build minimal"
|
|
|
|
}
|
|
|
|
|
2016-06-19 05:24:38 +03:00
|
|
|
case module == parser.MOC:
|
2016-05-28 19:18:42 +03:00
|
|
|
{
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2016-06-19 05:24:38 +03:00
|
|
|
case module == "QtAndroidExtras":
|
|
|
|
{
|
|
|
|
return "// +build android"
|
|
|
|
}
|
|
|
|
|
|
|
|
case module == "QtSailfish":
|
|
|
|
{
|
|
|
|
return "// +build sailfish"
|
|
|
|
}
|
|
|
|
|
2016-05-28 19:18:42 +03:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
return "// +build !minimal"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}(),
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
func() string {
|
|
|
|
switch module {
|
|
|
|
case parser.MOC:
|
|
|
|
{
|
|
|
|
return "moc"
|
|
|
|
}
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
case "QtAndroidExtras":
|
|
|
|
{
|
|
|
|
return fmt.Sprintf("%v_android", shortModule(module))
|
|
|
|
}
|
2016-01-04 04:05:31 +03:00
|
|
|
|
2016-06-19 05:24:38 +03:00
|
|
|
case "QtSailfish":
|
|
|
|
{
|
|
|
|
return fmt.Sprintf("%v_sailfish", shortModule(module))
|
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
return shortModule(module)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}(),
|
|
|
|
)
|
|
|
|
|
|
|
|
var classes = make([]string, 0)
|
|
|
|
for _, class := range parser.ClassMap {
|
|
|
|
if strings.Contains(string(input), class.Name) && !(strings.HasPrefix(class.Name, "Qt") || class.Module == parser.MOC) {
|
|
|
|
classes = append(classes, class.Name)
|
2016-04-16 19:48:26 +03:00
|
|
|
}
|
2015-12-06 02:56:16 +03:00
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
sort.Stable(sort.StringSlice(classes))
|
2015-12-06 02:56:16 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
for _, class := range classes {
|
2016-06-19 05:24:38 +03:00
|
|
|
if class == "SailfishApp" {
|
|
|
|
fmt.Fprintln(bb, "#include <sailfishapp.h>")
|
|
|
|
} else {
|
|
|
|
fmt.Fprintf(bb, "#include <%v>\n", class)
|
|
|
|
}
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|
2016-04-28 20:43:44 +03:00
|
|
|
fmt.Fprint(bb, "\n")
|
|
|
|
|
|
|
|
bb.Write(input)
|
2015-10-24 18:18:24 +03:00
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
if module == parser.MOC {
|
|
|
|
fmt.Fprintln(bb, "#include \"moc_moc.h\"")
|
2016-04-16 19:48:26 +03:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:43:44 +03:00
|
|
|
return bb.Bytes()
|
2015-10-24 18:18:24 +03:00
|
|
|
}
|