##// END OF EJS Templates
added builtin support for variants etc., this will replace the direct includes in PythonQt...
florianlink -
r93:7b53f64eae84
parent child
Show More
@@ -1,30 +1,26
1 1 TARGET = pythonqt_generator
2 2 CONFIG -= debug
3 3 CONFIG += release
4 4 DESTDIR = .
5 5
6 6 include(generator.pri)
7 7
8 8
9 9 # Input
10 10 HEADERS += \
11 11 generatorsetqtscript.h \
12 12 metaqtscriptbuilder.h \
13 13 metaqtscript.h \
14 classgenerator.h \
15 14 shellgenerator.h \
16 15 shellimplgenerator.h \
17 16 shellheadergenerator.h \
18 setupgenerator.h \
19 docgenerator.h
17 setupgenerator.h
20 18
21 19 SOURCES += \
22 20 generatorsetqtscript.cpp \
23 21 metaqtscriptbuilder.cpp \
24 22 metaqtscript.cpp \
25 classgenerator.cpp \
26 23 shellgenerator.cpp \
27 24 shellimplgenerator.cpp \
28 25 shellheadergenerator.cpp \
29 setupgenerator.cpp \
30 docgenerator.cpp
26 setupgenerator.cpp
@@ -1,137 +1,123
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
4 4 ** All rights reserved.
5 5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 6 **
7 7 ** This file is part of the Qt Script Generator project on Qt Labs.
8 8 **
9 9 ** $QT_BEGIN_LICENSE:LGPL$
10 10 ** No Commercial Usage
11 11 ** This file contains pre-release code and may not be distributed.
12 12 ** You may use this file in accordance with the terms and conditions
13 13 ** contained in the Technology Preview License Agreement accompanying
14 14 ** this package.
15 15 **
16 16 ** GNU Lesser General Public License Usage
17 17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 18 ** General Public License version 2.1 as published by the Free Software
19 19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 20 ** packaging of this file. Please review the following information to
21 21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 23 **
24 24 ** In addition, as a special exception, Nokia gives you certain additional
25 25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 27 **
28 28 ** If you have questions regarding the use of this file, please contact
29 29 ** Nokia at qt-info@nokia.com.
30 30 **
31 31 **
32 32 **
33 33 **
34 34 **
35 35 **
36 36 **
37 37 **
38 38 ** $QT_END_LICENSE$
39 39 **
40 40 ****************************************************************************/
41 41
42 42 #include "generatorsetqtscript.h"
43 43 #include "reporthandler.h"
44 #include "classgenerator.h"
45 44 #include "shellheadergenerator.h"
46 45 #include "shellimplgenerator.h"
47 #include "docgenerator.h"
48 46
49 47 GeneratorSet *GeneratorSet::getInstance() {
50 48 return new GeneratorSetQtScript();
51 49 }
52 50
53 51 GeneratorSetQtScript::GeneratorSetQtScript()
54 52 {}
55 53
56 54 QString GeneratorSetQtScript::usage() {
57 55 QString usage =
58 56 "QtScript:\n"
59 57 " --nothing-to-report-yet \n";
60 58
61 59 return usage;
62 60 }
63 61
64 62 bool GeneratorSetQtScript::readParameters(const QMap<QString, QString> args) {
65 63 return GeneratorSet::readParameters(args);
66 64 }
67 65
68 66 void GeneratorSetQtScript::buildModel(const QString pp_file) {
69 67 // Building the code inforamation...
70 68 ReportHandler::setContext("MetaJavaBuilder");
71 69 builder.setFileName(pp_file);
72 70 builder.build();
73 71 }
74 72
75 73 void GeneratorSetQtScript::dumpObjectTree() {
76 74
77 75 }
78 76
79 77 QString GeneratorSetQtScript::generate() {
80 78 AbstractMetaClassList classes = builder.classesTopologicalSorted();
81 79 QSet<QString> declaredTypeNames = builder.qtMetaTypeDeclaredTypeNames();
82 80
83 81 PriGenerator priGenerator;
84 82 priGenerator.setOutputDirectory(outDir);
85 83
86 84 SetupGenerator setupGenerator;
87 85 setupGenerator.setOutputDirectory(outDir);
88 86 setupGenerator.setQtMetaTypeDeclaredTypeNames(declaredTypeNames);
89 87 setupGenerator.setClasses(classes);
90 88
91 /*
92 ClassGenerator classGenerator(&priGenerator, &setupGenerator);
93 classGenerator.setOutputDirectory(outDir);
94 classGenerator.setClasses(classes);
95 classGenerator.setQtMetaTypeDeclaredTypeNames(declaredTypeNames);
96 classGenerator.generate();
97 */
98 89 ShellImplGenerator shellImplGenerator(&priGenerator);
99 90 shellImplGenerator.setOutputDirectory(outDir);
100 91 shellImplGenerator.setClasses(classes);
101 92 shellImplGenerator.setQtMetaTypeDeclaredTypeNames(declaredTypeNames);
102 93 shellImplGenerator.generate();
103 94
104 95 ShellHeaderGenerator shellHeaderGenerator(&priGenerator, &setupGenerator);
105 96 shellHeaderGenerator.setOutputDirectory(outDir);
106 97 shellHeaderGenerator.setClasses(classes);
107 98 shellHeaderGenerator.generate();
108 99
109 //DocGenerator docGenerator;
110 //docGenerator.setOutputDirectory(outDir);
111 //docGenerator.setClasses(classes);
112 //docGenerator.generate();
113
114 100 priGenerator.generate();
115 101 setupGenerator.generate();
116 102
117 103 return QString("Classes in typesystem: %1\n"
118 104 "Generated:\n"
119 105 " - header....: %4 (%5)\n"
120 106 " - impl......: %6 (%7)\n"
121 107 " - modules...: %8 (%9)\n"
122 108 " - pri.......: %10 (%11)\n"
123 109 )
124 110 .arg(builder.classes().size())
125 111
126 112 .arg(shellHeaderGenerator.numGenerated())
127 113 .arg(shellHeaderGenerator.numGeneratedAndWritten())
128 114
129 115 .arg(shellImplGenerator.numGenerated())
130 116 .arg(shellImplGenerator.numGeneratedAndWritten())
131 117
132 118 .arg(setupGenerator.numGenerated())
133 119 .arg(setupGenerator.numGeneratedAndWritten())
134 120
135 121 .arg(priGenerator.numGenerated())
136 122 .arg(priGenerator.numGeneratedAndWritten());
137 123 }
@@ -1,157 +1,162
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
4 4 ** All rights reserved.
5 5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 6 **
7 7 ** This file is part of the Qt Script Generator project on Qt Labs.
8 8 **
9 9 ** $QT_BEGIN_LICENSE:LGPL$
10 10 ** No Commercial Usage
11 11 ** This file contains pre-release code and may not be distributed.
12 12 ** You may use this file in accordance with the terms and conditions
13 13 ** contained in the Technology Preview License Agreement accompanying
14 14 ** this package.
15 15 **
16 16 ** GNU Lesser General Public License Usage
17 17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 18 ** General Public License version 2.1 as published by the Free Software
19 19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 20 ** packaging of this file. Please review the following information to
21 21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 23 **
24 24 ** In addition, as a special exception, Nokia gives you certain additional
25 25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 27 **
28 28 ** If you have questions regarding the use of this file, please contact
29 29 ** Nokia at qt-info@nokia.com.
30 30 **
31 31 **
32 32 **
33 33 **
34 34 **
35 35 **
36 36 **
37 37 **
38 38 ** $QT_END_LICENSE$
39 39 **
40 40 ****************************************************************************/
41 41
42 42 #include "prigenerator.h"
43 43 #include "shellgenerator.h"
44 44 #include "reporthandler.h"
45 45 #include "fileout.h"
46 46
47 47 void PriGenerator::addHeader(const QString &folder, const QString &header)
48 48 {
49 49 priHash[folder].headers << header;
50 50 }
51 51
52 52 void PriGenerator::addSource(const QString &folder, const QString &source)
53 53 {
54 54 priHash[folder].sources << source;
55 55 }
56 56
57 57 static void collectAndRemoveFile(QTextStream& stream, const QString& file) {
58 58 QFile f(file);
59 59 if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
60 60 QString s = QString::fromLatin1(f.readAll());
61 61 if (file.endsWith(".cpp")) {
62 62 // remove first line include
63 63 s = s.mid(s.indexOf('\n')+1);
64 64 }
65 65 stream << s;
66 66 f.close();
67 67 QFile::remove(file);
68 68 }
69 69 }
70 70
71 71 static QString combineIncludes(const QString& text) {
72 72 QStringList lines = text.split('\n');
73 73 QSet<QString> includes;
74 74 QString result;
75 75 foreach(QString line, lines) {
76 76 if (line.startsWith("#include")) {
77 77 includes.insert(line);
78 78 } else if (line.startsWith("#")) {
79 79 // skip preprocessor stuff
80 80 } else {
81 81 result += line + "\n";
82 82 }
83 83 }
84 84 QStringList includeList = includes.toList();
85 85 qSort(includeList);
86 86 result = includeList.join("\n") + result;
87 87 return result;
88 88 }
89 89
90 90 static QStringList compactFiles(const QStringList& list, const QString& ext, const QString& dir, const QString& prefix) {
91 91 QStringList outList;
92 92 int count = list.count();
93 93 int fileNum = 0;
94 QString srcDir = dir;
95 if (dir.endsWith("_builtin")) {
96 srcDir = dir.left(dir.length()-strlen("_builtin"));
97 }
94 98 while (count>0) {
95 99 QString outFileName = prefix + QString::number(fileNum) + ext;
96 100 FileOut file(dir + "/" + outFileName);
97 101 if (ext == ".cpp") {
98 102 file.stream << "#include \"" + prefix + QString::number(fileNum) + ".h\"\n";
99 103 }
100 104 outList << outFileName;
101 105 QString allText;
102 106 QTextStream ts(&allText);
103 107 for (int i = 0; i<MAX_CLASSES_PER_FILE && count>0; i++) {
104 collectAndRemoveFile(ts, dir + "/" + list.at(list.length()-count));
108 collectAndRemoveFile(ts, srcDir + "/" + list.at(list.length()-count));
105 109 count--;
106 110 }
107 111 allText = combineIncludes(allText);
108 112 file.stream << allText;
109 113 fileNum++;
110 114 }
111 115 return outList;
112 116 }
113 117
114 118 void PriGenerator::generate()
115 119 {
116 120 QHashIterator<QString, Pri> pri(priHash);
117 121 while (pri.hasNext()) {
118 122 pri.next();
119 123 QStringList list = pri.value().headers;
120 124 if (list.isEmpty())
121 125 continue;
122 126
123 127 QString folder = pri.key();
124 128 folder.replace('\\','/');
125 folder = folder.left(folder.indexOf('/'));
129 int idx = folder.indexOf('/');
130 folder = folder.left(idx);
126 131
127 132 qSort(list.begin(), list.end());
128 133 FileOut file(m_out_dir + "/generated_cpp/" + pri.key());
129 134
130 135 // strange idea to do the file compacting so late, but it is the most effective way without patching the generator a lot
131 136 bool compact = true;
132 137 if (compact) {
133 138 list = compactFiles(list, ".h", m_out_dir + "/generated_cpp/" + folder, folder);
134 139 }
135 140
136 141 file.stream << "HEADERS += \\\n";
137 142 foreach (const QString &entry, list) {
138 143 file.stream << " $$PWD/" << entry << " \\\n";
139 144 }
140 145
141 146 file.stream << "\n";
142 147 file.stream << "SOURCES += \\\n";
143 148 list = pri.value().sources;
144 149 qSort(list.begin(), list.end());
145 150 if (compact) {
146 151 list = compactFiles(list, ".cpp", m_out_dir + "/generated_cpp/" + folder, folder);
147 152 }
148 153 foreach (const QString &entry, list) {
149 154 file.stream << " $$PWD/" << entry << " \\\n";
150 155 }
151 156 file.stream << " $$PWD/" << folder << "_init.cpp\n";
152 157
153 158 if (file.done())
154 159 ++m_num_generated_written;
155 160 ++m_num_generated;
156 161 }
157 162 }
@@ -1,228 +1,233
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
4 4 ** All rights reserved.
5 5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 6 **
7 7 ** This file is part of the Qt Script Generator project on Qt Labs.
8 8 **
9 9 ** $QT_BEGIN_LICENSE:LGPL$
10 10 ** No Commercial Usage
11 11 ** This file contains pre-release code and may not be distributed.
12 12 ** You may use this file in accordance with the terms and conditions
13 13 ** contained in the Technology Preview License Agreement accompanying
14 14 ** this package.
15 15 **
16 16 ** GNU Lesser General Public License Usage
17 17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 18 ** General Public License version 2.1 as published by the Free Software
19 19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 20 ** packaging of this file. Please review the following information to
21 21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 23 **
24 24 ** In addition, as a special exception, Nokia gives you certain additional
25 25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 27 **
28 28 ** If you have questions regarding the use of this file, please contact
29 29 ** Nokia at qt-info@nokia.com.
30 30 **
31 31 **
32 32 **
33 33 **
34 34 **
35 35 **
36 36 **
37 37 **
38 38 ** $QT_END_LICENSE$
39 39 **
40 40 ****************************************************************************/
41 41
42 42 #include "setupgenerator.h"
43 43 #include "shellgenerator.h"
44 44 #include "reporthandler.h"
45 45 #include "fileout.h"
46 46
47 47 //#define Q_SCRIPT_LAZY_GENERATOR
48 48
49 void SetupGenerator::addClass(const AbstractMetaClass *cls)
49 void SetupGenerator::addClass(const QString& package, const AbstractMetaClass *cls)
50 50 {
51 packHash[cls->package()].append(cls);
51 packHash[package].append(cls);
52 52 }
53 53
54 54 void maybeDeclareMetaType(QTextStream &stream, const QString &typeName,
55 55 QSet<QString> &registeredTypeNames);
56 56 bool hasDefaultConstructor(const AbstractMetaClass *meta_class);
57 57
58 58 void SetupGenerator::generate()
59 59 {
60 60 AbstractMetaClassList classes_with_polymorphic_id;
61 61 {
62 62 QHashIterator<QString, QList<const AbstractMetaClass*> > pack(packHash);
63 63 while (pack.hasNext()) {
64 64 pack.next();
65 65 QList<const AbstractMetaClass*> list = pack.value();
66 66 foreach (const AbstractMetaClass *cls, list) {
67 67 if (cls->typeEntry()->isPolymorphicBase()) {
68 68 classes_with_polymorphic_id.append((AbstractMetaClass*)cls);
69 69 }
70 70 }
71 71 }
72 72 }
73 73
74 74 QHashIterator<QString, QList<const AbstractMetaClass*> > pack(packHash);
75 75 while (pack.hasNext()) {
76 76 pack.next();
77 77 QList<const AbstractMetaClass*> list = pack.value();
78 78 if (list.isEmpty())
79 79 continue;
80 80
81 81 QString packKey = pack.key();
82 82 QString packName = pack.key();
83 QStringList components = packName.split(".");
83 QStringList components = packName.split("_");
84 84 if ((components.size() > 2) && (components.at(0) == "com")
85 85 && (components.at(1) == "trolltech")) {
86 86 // kill com.trolltech in key
87 87 components.removeAt(0);
88 88 components.removeAt(0);
89 89 }
90 packName.replace(".", "_");
91 packKey.replace(".", "_");
92 90
93 91 QString shortPackName;
94 92 foreach (QString comp, components) {
95 93 comp[0] = comp[0].toUpper();
96 94 shortPackName += comp;
97 95 }
98 96 // add missing camel case (workaround..)
99 97 if (shortPackName == "QtWebkit") {
100 98 shortPackName = "QtWebKit";
101 99 } else if (shortPackName == "QtXmlpatterns") {
102 100 shortPackName = "QtXmlPatterns";
103 101 } else if (shortPackName == "QtOpengl") {
104 102 shortPackName = "QtOpenGL";
105 103 } else if (shortPackName == "QtUitools") {
106 104 shortPackName = "QtUiTools";
107 105 }
108 106
109 107
110 108 {
111 109 FileOut initFile(m_out_dir + "/generated_cpp/" + packName + "/" + packKey + "_init.cpp");
112 110 QTextStream &s = initFile.stream;
113 111
114 112 s << "#include <PythonQt.h>" << endl;
115 113
116 114 for (int i=0; i<(list.count()+MAX_CLASSES_PER_FILE-1) / MAX_CLASSES_PER_FILE; i++) {
117 115 s << "#include \"" << packKey << QString::number(i) << ".h\"" << endl;
118 116 }
119 117 s << endl;
120 118
121 QStringList polymorphicHandlers = writePolymorphicHandler(s, list.at(0)->package(), classes_with_polymorphic_id);
122 s << endl;
123
119 QStringList polymorphicHandlers;
120 if (!packName.endsWith("_builtin")) {
121 polymorphicHandlers = writePolymorphicHandler(s, list.at(0)->package(), classes_with_polymorphic_id);
122 s << endl;
123 }
124
124 125 // declare individual class creation functions
125 126 s << "void PythonQt_init_" << shortPackName << "() {" << endl;
127
128 if (shortPackName.endsWith("Builtin")) {
129 shortPackName = shortPackName.mid(shortPackName.length()-strlen("builtin"));
130 }
131
126 132 QStringList cppClassNames;
127 133 foreach (const AbstractMetaClass *cls, list) {
128 if (ShellGenerator::isBuiltIn(cls->name())) { continue; }
129 134
130 135 QString shellCreator;
131 136 if (cls->generateShellClass()) {
132 137 shellCreator = ", PythonQtSetInstanceWrapperOnShell<" + ShellGenerator::shellClassName(cls) + ">";
133 138 }
134 139 if (cls->isQObject()) {
135 140 s << "PythonQt::self()->registerClass(&" << cls->qualifiedCppName() << "::staticMetaObject, \"" << shortPackName <<"\", PythonQtCreateObject<PythonQtWrapper_" << cls->name() << ">" << shellCreator << ");" << endl;
136 141 } else {
137 142 QString baseName = cls->baseClass()?cls->baseClass()->qualifiedCppName():"";
138 143 s << "PythonQt::self()->registerCPPClass(\""<< cls->qualifiedCppName() << "\", \"" << baseName << "\", \"" << shortPackName <<"\", PythonQtCreateObject<PythonQtWrapper_" << cls->name() << ">" << shellCreator << ");" << endl;
139 144 }
140 145 foreach(AbstractMetaClass* interface, cls->interfaces()) {
141 146 // the interface might be our own class... (e.g. QPaintDevice)
142 147 if (interface->qualifiedCppName() != cls->qualifiedCppName()) {
143 148 s << "PythonQt::self()->addParentClass(\""<< cls->qualifiedCppName() << "\", \"" << interface->qualifiedCppName() << "\",PythonQtUpcastingOffset<" << cls->qualifiedCppName() <<","<<interface->qualifiedCppName()<<">());" << endl;
144 149 }
145 150 }
146 151 }
147 152 s << endl;
148 153 foreach (QString handler, polymorphicHandlers) {
149 154 s << "PythonQt::self()->addPolymorphicHandler(\""<< handler << "\", polymorphichandler_" << handler << ");" << endl;
150 155 }
151 156
152 157 s << "}";
153 158 s << endl;
154 159 }
155 160 }
156 161 }
157 162
158 163 QStringList SetupGenerator::writePolymorphicHandler(QTextStream &s, const QString &package,
159 164 const AbstractMetaClassList &classes)
160 165 {
161 166 QStringList handlers;
162 167 foreach (AbstractMetaClass *cls, classes) {
163 168 const ComplexTypeEntry *centry = cls->typeEntry();
164 169 if (!centry->isPolymorphicBase())
165 170 continue;
166 171 bool isGraphicsItem = (cls->qualifiedCppName()=="QGraphicsItem");
167 172
168 173 AbstractMetaClassList classList = this->classes();
169 174 bool first = true;
170 175 foreach (AbstractMetaClass *clazz, classList) {
171 176 bool inherits = false;
172 177 if (isGraphicsItem) {
173 178 foreach(AbstractMetaClass* interfaze, clazz->interfaces()) {
174 179 if (interfaze->qualifiedCppName()=="QGraphicsItem") {
175 180 inherits = true;
176 181 break;
177 182 }
178 183 }
179 184 } else {
180 185 inherits = clazz->inheritsFrom(cls);
181 186 }
182 187 if (clazz->package() == package && inherits) {
183 188 if (!clazz->typeEntry()->polymorphicIdValue().isEmpty() || isGraphicsItem) {
184 189 // On first find, open the function
185 190 if (first) {
186 191 first = false;
187 192
188 193 QString handler = cls->name();
189 194 handlers.append(handler);
190 195
191 196 s << "static void* polymorphichandler_" << handler
192 197 << "(const void *ptr, char **class_name)" << endl
193 198 << "{" << endl
194 199 << " Q_ASSERT(ptr != 0);" << endl
195 200 << " " << cls->qualifiedCppName() << " *object = ("
196 201 << cls->qualifiedCppName() << " *)ptr;" << endl;
197 202 }
198 203
199 204 // For each, add case label
200 205 QString polyId = clazz->typeEntry()->polymorphicIdValue();
201 206 if (isGraphicsItem) {
202 207 polyId = "%1->type() == " + clazz->qualifiedCppName() + "::Type";
203 208 }
204 209 s << " if ("
205 210 << polyId.replace("%1", "object")
206 211 << ") {" << endl
207 212 << " *class_name = \"" << clazz->name() << "\";" << endl
208 213 << " return (" << clazz->qualifiedCppName() << "*)object;" << endl
209 214 << " }" << endl;
210 215 } else {
211 216 QString warning = QString("class '%1' inherits from polymorphic class '%2', but has no polymorphic id set")
212 217 .arg(clazz->name())
213 218 .arg(cls->name());
214 219
215 220 ReportHandler::warning(warning);
216 221 }
217 222 }
218 223 }
219 224
220 225 // Close the function if it has been opened
221 226 if (!first) {
222 227 s << " return NULL;" << endl
223 228 << "}" << endl;
224 229 }
225 230 }
226 231
227 232 return handlers;
228 233 }
@@ -1,68 +1,68
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
4 4 ** All rights reserved.
5 5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 6 **
7 7 ** This file is part of the Qt Script Generator project on Qt Labs.
8 8 **
9 9 ** $QT_BEGIN_LICENSE:LGPL$
10 10 ** No Commercial Usage
11 11 ** This file contains pre-release code and may not be distributed.
12 12 ** You may use this file in accordance with the terms and conditions
13 13 ** contained in the Technology Preview License Agreement accompanying
14 14 ** this package.
15 15 **
16 16 ** GNU Lesser General Public License Usage
17 17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 18 ** General Public License version 2.1 as published by the Free Software
19 19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 20 ** packaging of this file. Please review the following information to
21 21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 23 **
24 24 ** In addition, as a special exception, Nokia gives you certain additional
25 25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 27 **
28 28 ** If you have questions regarding the use of this file, please contact
29 29 ** Nokia at qt-info@nokia.com.
30 30 **
31 31 **
32 32 **
33 33 **
34 34 **
35 35 **
36 36 **
37 37 **
38 38 ** $QT_END_LICENSE$
39 39 **
40 40 ****************************************************************************/
41 41
42 42 #ifndef SETUPGENERATOR_H
43 43 #define SETUPGENERATOR_H
44 44
45 45 #include "generator.h"
46 46 #include "metaqtscript.h"
47 47
48 48 class SetupGenerator : public Generator
49 49 {
50 50 Q_OBJECT
51 51
52 52 public:
53 53 virtual void generate();
54 54
55 void addClass(const AbstractMetaClass *cls);
55 void addClass(const QString& package, const AbstractMetaClass *cls);
56 56
57 57 static void writeInclude(QTextStream &stream, const Include &inc);
58 58
59 59 static bool isSpecialStreamingOperator(const AbstractMetaFunction *fun);
60 60
61 61 private:
62 62 QStringList writePolymorphicHandler(QTextStream &s, const QString &package,
63 63 const AbstractMetaClassList &classes);
64 64
65 65 QHash<QString, QList<const AbstractMetaClass*> > packHash;
66 66 };
67 67 #endif // SETUPGENERATOR_H
68 68
@@ -1,102 +1,102
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
4 4 ** All rights reserved.
5 5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 6 **
7 7 ** This file is part of the Qt Script Generator project on Qt Labs.
8 8 **
9 9 ** $QT_BEGIN_LICENSE:LGPL$
10 10 ** No Commercial Usage
11 11 ** This file contains pre-release code and may not be distributed.
12 12 ** You may use this file in accordance with the terms and conditions
13 13 ** contained in the Technology Preview License Agreement accompanying
14 14 ** this package.
15 15 **
16 16 ** GNU Lesser General Public License Usage
17 17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 18 ** General Public License version 2.1 as published by the Free Software
19 19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 20 ** packaging of this file. Please review the following information to
21 21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 23 **
24 24 ** In addition, as a special exception, Nokia gives you certain additional
25 25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 27 **
28 28 ** If you have questions regarding the use of this file, please contact
29 29 ** Nokia at qt-info@nokia.com.
30 30 **
31 31 **
32 32 **
33 33 **
34 34 **
35 35 **
36 36 **
37 37 **
38 38 ** $QT_END_LICENSE$
39 39 **
40 40 ****************************************************************************/
41 41
42 42 #ifndef SHELLGENERATOR_H
43 43 #define SHELLGENERATOR_H
44 44
45 45 #include "generator.h"
46 46 #include "metaqtscript.h"
47 47 #include "prigenerator.h"
48 48
49 #define MAX_CLASSES_PER_FILE 20
49 #define MAX_CLASSES_PER_FILE 30
50 50
51 51 class ShellGenerator : public Generator
52 52 {
53 53 Q_OBJECT
54 54
55 55 public:
56 56 virtual QString subDirectoryForClass(const AbstractMetaClass *cls) const
57 57 {
58 58 return "generated_cpp/" + cls->package().replace(".", "_") + "/";
59 59 }
60 60
61 61 static void writeTypeInfo(QTextStream &s, const AbstractMetaType *type, Option option = NoOption);
62 62 static void writeFunctionSignature(QTextStream &s, const AbstractMetaFunction *meta_function,
63 63 const AbstractMetaClass *implementor = 0,
64 64 const QString &name_prefix = QString(),
65 65 Option option = NoOption,
66 66 const QString &classname_prefix = QString(),
67 67 const QStringList &extra_arguments = QStringList(),
68 68 int numArguments = -1);
69 69 static void writeFunctionArguments(QTextStream &s, const AbstractMetaClass* owner, const AbstractMetaArgumentList &arguments,
70 70 Option option = NoOption,
71 71 int numArguments = -1);
72 72
73 73 bool shouldGenerate(const AbstractMetaClass *meta_class) const;
74 74
75 75 static QString shellClassName(const AbstractMetaClass *meta_class) {
76 76 return "PythonQtShell_" + meta_class->name();
77 77 }
78 78 static QString wrapperClassName(const AbstractMetaClass *meta_class) {
79 79 return "PythonQtWrapper_" + meta_class->name();
80 80 }
81 81 static QString promoterClassName(const AbstractMetaClass *meta_class) {
82 82 return "PythonQtPublicPromoter_" + meta_class->name();
83 83 }
84 84
85 85 static AbstractMetaFunctionList getFunctionsToWrap(const AbstractMetaClass* cls);
86 86 static AbstractMetaFunctionList getVirtualFunctionsForShell(const AbstractMetaClass* cls);
87 87 static AbstractMetaFunctionList getProtectedFunctionsThatNeedPromotion(const AbstractMetaClass* cls);
88 88
89 89 // PythonQt builtins..., dont put them in pri files and dont register them, but generate the code
90 90 static bool isBuiltIn(const QString& name);
91 91
92 92 static bool isSpecialStreamingOperator(const AbstractMetaFunction *fun);
93 93
94 94 static void writeInclude(QTextStream &stream, const Include &inc);
95 95
96 96 protected:
97 97 PriGenerator *priGenerator;
98 98
99 99 };
100 100
101 101
102 102 #endif // SHELLGENERATOR_H
@@ -1,289 +1,279
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
4 4 ** All rights reserved.
5 5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 6 **
7 7 ** This file is part of the Qt Script Generator project on Qt Labs.
8 8 **
9 9 ** $QT_BEGIN_LICENSE:LGPL$
10 10 ** No Commercial Usage
11 11 ** This file contains pre-release code and may not be distributed.
12 12 ** You may use this file in accordance with the terms and conditions
13 13 ** contained in the Technology Preview License Agreement accompanying
14 14 ** this package.
15 15 **
16 16 ** GNU Lesser General Public License Usage
17 17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 18 ** General Public License version 2.1 as published by the Free Software
19 19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 20 ** packaging of this file. Please review the following information to
21 21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 23 **
24 24 ** In addition, as a special exception, Nokia gives you certain additional
25 25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 27 **
28 28 ** If you have questions regarding the use of this file, please contact
29 29 ** Nokia at qt-info@nokia.com.
30 30 **
31 31 **
32 32 **
33 33 **
34 34 **
35 35 **
36 36 **
37 37 **
38 38 ** $QT_END_LICENSE$
39 39 **
40 40 ****************************************************************************/
41 41
42 42 #include "shellheadergenerator.h"
43 43 #include "fileout.h"
44 44
45 45 #include <QtCore/QDir>
46 46
47 47 #include <qdebug.h>
48 48
49 49 QString ShellHeaderGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const
50 50 {
51 51 return QString("PythonQtWrapper_%1.h").arg(meta_class->name());
52 52 }
53 53
54 54 void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class)
55 55 {
56 if (!ShellGenerator::isBuiltIn(meta_class->name())) {
57 setupGenerator->addClass(meta_class);
58 }
56 QString builtIn = ShellGenerator::isBuiltIn(meta_class->name())?"_builtin":"";
57 QString pro_file_name = meta_class->package().replace(".", "_") + builtIn + "/" + meta_class->package().replace(".", "_") + builtIn + ".pri";
58 priGenerator->addHeader(pro_file_name, fileNameForClass(meta_class));
59 setupGenerator->addClass(meta_class->package().replace(".", "_") + builtIn, meta_class);
59 60
60 61 QString include_block = "PYTHONQTWRAPPER_" + meta_class->name().toUpper() + "_H";
61 62
62 63 s << "#ifndef " << include_block << endl
63 64 << "#define " << include_block << endl << endl;
64 65
65 66 Include inc = meta_class->typeEntry()->include();
66 67 ShellGenerator::writeInclude(s, inc);
67 68
68 69 s << "#include <QObject>" << endl << endl;
69 70 s << "#include <PythonQt.h>" << endl << endl;
70 71
71 72 IncludeList list = meta_class->typeEntry()->extraIncludes();
72 73 qSort(list.begin(), list.end());
73 74 foreach (const Include &inc, list) {
74 75 ShellGenerator::writeInclude(s, inc);
75 76 }
76 77 s << endl;
77 78
78 QString pro_file_name = meta_class->package().replace(".", "_") + "/" + meta_class->package().replace(".", "_") + ".pri";
79
80 // if (!meta_class->generateShellClass()) {
81 // s << "#endif" << endl << endl;
82 // priGenerator->addHeader(pro_file_name, fileNameForClass(meta_class));
83 // return ;
84 // }
85
86 79 AbstractMetaFunctionList ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors
87 80 | AbstractMetaClass::WasVisible
88 81 | AbstractMetaClass::NotRemovedFromTargetLang);
89 82
90 83 // Shell-------------------------------------------------------------------
91 84 if (meta_class->generateShellClass()) {
92 85
93 86 AbstractMetaFunctionList virtualsForShell = getVirtualFunctionsForShell(meta_class);
94 87
95 88 s << "class " << shellClassName(meta_class)
96 89 << " : public " << meta_class->qualifiedCppName() << endl << "{" << endl;
97 90 s << "public:" << endl;
98 91 foreach(AbstractMetaFunction* fun, ctors) {
99 92 s << " ";
100 93 writeFunctionSignature(s, fun, 0,"PythonQtShell_",
101 94 Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
102 95 s << ":" << meta_class->qualifiedCppName() << "(";
103 96 QString scriptFunctionName = fun->originalName();
104 97 AbstractMetaArgumentList args = fun->arguments();
105 98 for (int i = 0; i < args.size(); ++i) {
106 99 if (i > 0)
107 100 s << ", ";
108 101 s << args.at(i)->argumentName();
109 102 }
110 103 s << "),_wrapper(NULL) {};" << endl;
111 104 }
112 105 s << endl;
113 106
114 107 foreach(AbstractMetaFunction* fun, virtualsForShell) {
115 108 s << "virtual ";
116 109 writeFunctionSignature(s, fun, 0, QString(),
117 110 Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
118 111 s << ";" << endl;
119 112 }
120 113 s << endl;
121 114 s << " PythonQtInstanceWrapper* _wrapper; " << endl;
122 115
123 116 s << "};" << endl << endl;
124 117 }
125 118
126 119 // Promoter-------------------------------------------------------------------
127 120 AbstractMetaFunctionList promoteFunctions = getProtectedFunctionsThatNeedPromotion(meta_class);
128 121 if (!promoteFunctions.isEmpty()) {
129 122 s << "class " << promoterClassName(meta_class)
130 123 << " : public " << meta_class->qualifiedCppName() << endl << "{ public:" << endl;
131 124
132 125 foreach(AbstractMetaFunction* fun, promoteFunctions) {
133 126 s << "inline ";
134 127 writeFunctionSignature(s, fun, 0, "promoted_",
135 128 Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
136 129 s << " { ";
137 130 QString scriptFunctionName = fun->originalName();
138 131 AbstractMetaArgumentList args = fun->arguments();
139 132 if (fun->type())
140 133 s << "return ";
141 134 s << meta_class->qualifiedCppName() << "::";
142 135 s << fun->originalName() << "(";
143 136 for (int i = 0; i < args.size(); ++i) {
144 137 if (i > 0)
145 138 s << ", ";
146 139 s << args.at(i)->argumentName();
147 140 }
148 141 s << "); }" << endl;
149 142 }
150 143
151 144 s << "};" << endl << endl;
152 145 }
153 146
154 147 // Wrapper-------------------------------------------------------------------
155 148
156 149 s << "class " << wrapperClassName(meta_class)
157 150 << " : public QObject" << endl
158 151 << "{ Q_OBJECT" << endl;
159 152
160 153 s << "public:" << endl;
161 154
162 155 AbstractMetaEnumList enums1 = meta_class->enums();
163 156 AbstractMetaEnumList enums;
164 157 QList<FlagsTypeEntry*> flags;
165 158 foreach(AbstractMetaEnum* enum1, enums1) {
166 159 // catch gadgets and enums that are not exported on QObjects...
167 160 if (enum1->wasPublic() && (!meta_class->isQObject() || !enum1->hasQEnumsDeclaration())) {
168 161 enums << enum1;
169 162 if (enum1->typeEntry()->flags()) {
170 163 flags << enum1->typeEntry()->flags();
171 164 }
172 165 }
173 166 }
174 167 if (enums.count()) {
175 168 s << "Q_ENUMS(";
176 169 foreach(AbstractMetaEnum* enum1, enums) {
177 170 s << enum1->name() << " ";
178 171 }
179 172 s << ")" << endl;
180 173
181 174 if (flags.count()) {
182 175 s << "Q_FLAGS(";
183 176 foreach(FlagsTypeEntry* flag1, flags) {
184 177 QString origName = flag1->originalName();
185 178 int idx = origName.lastIndexOf("::");
186 179 if (idx!= -1) {
187 180 origName = origName.mid(idx+2);
188 181 }
189 182 s << origName << " ";
190 183 }
191 184 s << ")" << endl;
192 185 }
193 186
194 187 foreach(AbstractMetaEnum* enum1, enums) {
195 188 s << "enum " << enum1->name() << "{" << endl;
196 189 bool first = true;
197 190 foreach(AbstractMetaEnumValue* value, enum1->values()) {
198 191 if (first) { first = false; }
199 192 else { s << ", "; }
200 193 s << " " << value->name() << " = " << meta_class->qualifiedCppName() << "::" << value->name();
201 194 }
202 195 s << "};" << endl;
203 196 }
204 197 if (flags.count()) {
205 198 foreach(AbstractMetaEnum* enum1, enums) {
206 199 if (enum1->typeEntry()->flags()) {
207 200 QString origName = enum1->typeEntry()->flags()->originalName();
208 201 int idx = origName.lastIndexOf("::");
209 202 if (idx!= -1) {
210 203 origName = origName.mid(idx+2);
211 204 }
212 205 s << "Q_DECLARE_FLAGS("<< origName << ", " << enum1->name() <<")"<<endl;
213 206 }
214 207 }
215 208 }
216 209 }
217 210 s << "public slots:" << endl;
218 211 if (meta_class->generateShellClass() || !meta_class->isAbstract()) {
219 212
220 213 bool copyConstructorSeen = false;
221 214 bool defaultConstructorSeen = false;
222 215 foreach (const AbstractMetaFunction *fun, ctors) {
223 216 if (!fun->isPublic() || fun->isAbstract()) { continue; }
224 217 s << meta_class->qualifiedCppName() << "* ";
225 218 writeFunctionSignature(s, fun, 0, "new_",
226 219 Option(IncludeDefaultExpression | OriginalName | ShowStatic));
227 220 s << ";" << endl;
228 221 if (fun->arguments().size()==1 && meta_class->qualifiedCppName() == fun->arguments().at(0)->type()->typeEntry()->qualifiedCppName()) {
229 222 copyConstructorSeen = true;
230 223 }
231 224 if (fun->arguments().size()==0) {
232 225 defaultConstructorSeen = true;
233 226 }
234 227 }
235 228
236 229 if (meta_class->typeEntry()->isValue()
237 230 && !copyConstructorSeen && defaultConstructorSeen) {
238 231 QString className = meta_class->generateShellClass()?shellClassName(meta_class):meta_class->qualifiedCppName();
239 232 s << meta_class->qualifiedCppName() << "* new_" << meta_class->name() << "(const " << meta_class->qualifiedCppName() << "& other) {" << endl;
240 233 s << className << "* a = new " << className << "();" << endl;
241 234 s << "*((" << meta_class->qualifiedCppName() << "*)a) = other;" << endl;
242 235 s << "return a; }" << endl;
243 236 }
244 237 }
245 238 if (meta_class->hasPublicDestructor() && !meta_class->isNamespace()) {
246 239 s << "void delete_" << meta_class->name() << "(" << meta_class->qualifiedCppName() << "* obj) { delete obj; } ";
247 240 s << endl;
248 241 }
249 242 if (meta_class->name()=="QTreeWidgetItem") {
250 243 s << "bool hasOwner(QTreeWidgetItem* theWrappedObject) { return theWrappedObject->treeWidget()!=NULL || theWrappedObject->parent()!=NULL; }" << endl;
251 244 } else if (meta_class->name()=="QGraphicsItem") {
252 245 s << "bool hasOwner(QGraphicsItem* theWrappedObject) { return theWrappedObject->scene()!=NULL || theWrappedObject->parentItem()!=NULL; }" << endl;
253 246 }
254 247
255 248 AbstractMetaFunctionList functions = getFunctionsToWrap(meta_class);
256 249
257 250 foreach (const AbstractMetaFunction *function, functions) {
258 251 if (!function->isSlot()) {
259 252 s << " ";
260 253 writeFunctionSignature(s, function, 0, QString(),
261 254 Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
262 255 s << ";" << endl;
263 256 }
264 257 }
265 258 if (!meta_class->hasDefaultToStringFunction() && meta_class->hasToStringCapability()) {
266 259 s << " QString toString(" << meta_class->qualifiedCppName() << "*);" << endl;
267 260 }
268 261
269 262 // writeInjectedCode(s, meta_class);
270 263
271 264 // s << endl << " QScriptValue __qtscript_self;" << endl;
272 265
273 266 s << "};" << endl << endl
274 267 << "#endif // " << include_block << endl;
275 268
276 if (!ShellGenerator::isBuiltIn(meta_class->name())) {
277 priGenerator->addHeader(pro_file_name, fileNameForClass(meta_class));
278 }
279 269 }
280 270
281 271 void ShellHeaderGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class)
282 272 {
283 273 CodeSnipList code_snips = meta_class->typeEntry()->codeSnips();
284 274 foreach (const CodeSnip &cs, code_snips) {
285 275 if (cs.language == TypeSystem::ShellDeclaration) {
286 276 s << cs.code() << endl;
287 277 }
288 278 }
289 279 }
@@ -1,309 +1,306
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
4 4 ** All rights reserved.
5 5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 6 **
7 7 ** This file is part of the Qt Script Generator project on Qt Labs.
8 8 **
9 9 ** $QT_BEGIN_LICENSE:LGPL$
10 10 ** No Commercial Usage
11 11 ** This file contains pre-release code and may not be distributed.
12 12 ** You may use this file in accordance with the terms and conditions
13 13 ** contained in the Technology Preview License Agreement accompanying
14 14 ** this package.
15 15 **
16 16 ** GNU Lesser General Public License Usage
17 17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 18 ** General Public License version 2.1 as published by the Free Software
19 19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 20 ** packaging of this file. Please review the following information to
21 21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 23 **
24 24 ** In addition, as a special exception, Nokia gives you certain additional
25 25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 27 **
28 28 ** If you have questions regarding the use of this file, please contact
29 29 ** Nokia at qt-info@nokia.com.
30 30 **
31 31 **
32 32 **
33 33 **
34 34 **
35 35 **
36 36 **
37 37 **
38 38 ** $QT_END_LICENSE$
39 39 **
40 40 ****************************************************************************/
41 41
42 42 #include "shellimplgenerator.h"
43 43 #include "reporthandler.h"
44 44 #include "fileout.h"
45 45
46 46 extern void declareFunctionMetaTypes(QTextStream &stream,
47 47 const AbstractMetaFunctionList &functions,
48 48 QSet<QString> &registeredTypeNames);
49 49
50 50 QString ShellImplGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const
51 51 {
52 52 return QString("PythonQtWrapper_%1.cpp").arg(meta_class->name());
53 53 }
54 54
55 55 static bool include_less_than(const Include &a, const Include &b)
56 56 {
57 57 return a.name < b.name;
58 58 }
59 59
60 60 static void writeHelperCode(QTextStream &s, const AbstractMetaClass *)
61 61 {
62 62 }
63 63
64 64 void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class)
65 65 {
66
67 QString pro_file_name = meta_class->package().replace(".", "_") + "/" + meta_class->package().replace(".", "_") + ".pri";
68
69 if (!ShellGenerator::isBuiltIn(meta_class->name())) {
70 priGenerator->addSource(pro_file_name, fileNameForClass(meta_class));
71 }
66 QString builtIn = ShellGenerator::isBuiltIn(meta_class->name())?"_builtin":"";
67 QString pro_file_name = meta_class->package().replace(".", "_") + builtIn + "/" + meta_class->package().replace(".", "_") + builtIn + ".pri";
68 priGenerator->addSource(pro_file_name, fileNameForClass(meta_class));
72 69
73 70 s << "#include \"PythonQtWrapper_" << meta_class->name() << ".h\"" << endl << endl;
74 71
75 72 s << "#include <PythonQtSignalReceiver.h>" << endl;
76 73 s << "#include <PythonQtMethodInfo.h>" << endl;
77 74 s << "#include <PythonQtConversion.h>" << endl;
78 75
79 76 //if (!meta_class->generateShellClass())
80 77 // return;
81 78
82 79 IncludeList list = meta_class->typeEntry()->extraIncludes();
83 80 qSort(list.begin(), list.end());
84 81 foreach (const Include &inc, list) {
85 82 ShellGenerator::writeInclude(s, inc);
86 83 }
87 84 s << endl;
88 85
89 86 writeHelperCode(s, meta_class);
90 87
91 88 // find constructors
92 89 AbstractMetaFunctionList ctors;
93 90 ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors
94 91 | AbstractMetaClass::WasVisible
95 92 | AbstractMetaClass::NotRemovedFromTargetLang);
96 93 // find member functions
97 94 AbstractMetaFunctionList functions = getFunctionsToWrap(meta_class);
98 95
99 96 // write metatype declarations
100 97 {
101 98 // QSet<QString> registeredTypeNames = m_qmetatype_declared_typenames;
102 99 // declareFunctionMetaTypes(s, functions, registeredTypeNames);
103 100 // s << endl;
104 101 }
105 102
106 103 if (meta_class->generateShellClass()) {
107 104 AbstractMetaFunctionList virtualsForShell = getVirtualFunctionsForShell(meta_class);
108 105 foreach (const AbstractMetaFunction *fun, virtualsForShell) {
109 106 bool hasReturnValue = (fun->type());
110 107 writeFunctionSignature(s, fun, meta_class, QString(),
111 108 Option(OriginalName | ShowStatic | UnderscoreSpaces),
112 109 "PythonQtShell_");
113 110 s << endl << "{" << endl;
114 111
115 112 Option typeOptions = Option(OriginalName | UnderscoreSpaces | SkipName);
116 113 AbstractMetaArgumentList args = fun->arguments();
117 114
118 115 s << "if (_wrapper) {" << endl;
119 116 s << " PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, \"" << fun->name() << "\");" << endl;
120 117 s << " PyErr_Clear();" << endl;
121 118 s << " if (obj && !PythonQtSlotFunction_Check(obj)) {" << endl;
122 119 s << " static const char* argumentList[] ={\"";
123 120 if (hasReturnValue) {
124 121 // write the arguments, return type first
125 122 writeTypeInfo(s, fun->type(), typeOptions);
126 123 }
127 124 s << "\"";
128 125 for (int i = 0; i < args.size(); ++i) {
129 126 s << " , \"";
130 127 writeTypeInfo(s, args.at(i)->type(), typeOptions);
131 128 s << "\"";
132 129 }
133 130 s << "};" << endl;
134 131 s << " static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(" << QString::number(args.size()+1) << ", argumentList);" << endl;
135 132
136 133 if (hasReturnValue) {
137 134 s << " ";
138 135 writeTypeInfo(s, fun->type(), typeOptions);
139 136 s << " returnValue;" << endl;
140 137 // TODO: POD init to default is missing...
141 138 }
142 139 s << " void* args[" << QString::number(args.size()+1) << "] = {NULL";
143 140 for (int i = 0; i < args.size(); ++i) {
144 141 s << ", (void*)&" << args.at(i)->argumentName();
145 142 }
146 143 s << "};" << endl;
147 144
148 145 s << " PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);" << endl;
149 146 if (hasReturnValue) {
150 147 s << " if (result) {" << endl;
151 148 s << " args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);" << endl;
152 149 s << " if (args[0]!=&returnValue) {" << endl;
153 150 s << " if (args[0]==NULL) {" << endl;
154 151 s << " PythonQt::priv()->handleVirtualOverloadReturnError(\"" << fun->name() << "\", methodInfo, result);" << endl;
155 152 s << " } else {" << endl;
156 153 s << " returnValue = *((";
157 154 writeTypeInfo(s, fun->type(), typeOptions);
158 155 s << "*)args[0]);" << endl;
159 156 s << " }" << endl;
160 157 s << " }" << endl;
161 158 s << " }" << endl;
162 159 }
163 160 s << " if (result) { Py_DECREF(result); } " << endl;
164 161 s << " Py_DECREF(obj);" << endl;
165 162 if (hasReturnValue) {
166 163 s << " return returnValue;" << endl;
167 164 } else {
168 165 s << " return;" << endl;
169 166 }
170 167 s << " }" << endl;
171 168 s << "}" << endl;
172 169
173 170 s << " ";
174 171 if (fun->isAbstract()) {
175 172 if (fun->type()) {
176 173 // return empty default object
177 174 writeTypeInfo(s, fun->type(), typeOptions);
178 175 s << " result;" << endl;
179 176 s << "return result";
180 177 s << ";";
181 178 }
182 179 } else {
183 180 if (fun->type()) {
184 181 s << "return ";
185 182 }
186 183 s << meta_class->qualifiedCppName() << "::";
187 184 s << fun->originalName() << "(";
188 185 for (int i = 0; i < args.size(); ++i) {
189 186 if (i > 0)
190 187 s << ", ";
191 188 s << args.at(i)->argumentName();
192 189 }
193 190 s << ");";
194 191 }
195 192 s << endl << "}" << endl;
196 193 }
197 194 }
198 195
199 196 if (meta_class->generateShellClass() || !meta_class->isAbstract()) {
200 197
201 198 // write constructors
202 199 foreach (const AbstractMetaFunction *ctor, ctors) {
203 200 if (!ctor->isPublic() || ctor->isAbstract()) { continue; }
204 201
205 202 s << meta_class->qualifiedCppName() << "* ";
206 203 s << "PythonQtWrapper_" << meta_class->name() << "::";
207 204 writeFunctionSignature(s, ctor, 0, "new_", Option(OriginalName | ShowStatic));
208 205 s << endl;
209 206 s << "{ " << endl;
210 207 s << "return new " << (meta_class->generateShellClass()?shellClassName(meta_class):meta_class->qualifiedCppName()) << "(";
211 208 AbstractMetaArgumentList args = ctor->arguments();
212 209 for (int i = 0; i < args.size(); ++i) {
213 210 if (i > 0)
214 211 s << ", ";
215 212 s << args.at(i)->argumentName();
216 213 }
217 214 s << ");" << " }" << endl << endl;
218 215 }
219 216 }
220 217
221 218 QString wrappedObject = " (*theWrappedObject)";
222 219
223 220 // write member functions
224 221 for (int i = 0; i < functions.size(); ++i) {
225 222 AbstractMetaFunction *fun = functions.at(i);
226 223 if (fun->isSlot()) continue;
227 224
228 225 writeFunctionSignature(s, fun, meta_class, QString(),
229 226 Option(ConvertReferenceToPtr | FirstArgIsWrappedObject | OriginalName | ShowStatic | UnderscoreSpaces),
230 227 "PythonQtWrapper_");
231 228 s << endl << "{" << endl;
232 229 s << " ";
233 230 if (ShellGenerator::isSpecialStreamingOperator(fun)) {
234 231 s << fun->arguments().at(0)->argumentName();
235 232 if (fun->originalName().startsWith("operator>>")) {
236 233 s << " >> ";
237 234 } else {
238 235 s << " << ";
239 236 }
240 237 s << wrappedObject;
241 238 } else {
242 239 QString scriptFunctionName = fun->originalName();
243 240 AbstractMetaArgumentList args = fun->arguments();
244 241 // call the C++ implementation
245 242 if (fun->type()) {
246 243 s << "return ";
247 244 // call the C++ implementation
248 245 if (fun->type()->isReference()) {
249 246 s << "&";
250 247 }
251 248 }
252 249 s << "(";
253 250 if (scriptFunctionName.startsWith("operator>>")) {
254 251 s << wrappedObject << " >>" << args.at(0)->argumentName();
255 252 } else if (scriptFunctionName.startsWith("operator<<")) {
256 253 s << wrappedObject << " <<" << args.at(0)->argumentName();
257 254 } else if (scriptFunctionName.startsWith("operator[]")) {
258 255 s << wrappedObject << "[" << args.at(0)->argumentName() << "]";
259 256 } else if (scriptFunctionName.startsWith("operator") && args.size()==1) {
260 257 QString op = scriptFunctionName.mid(8);
261 258 s << wrappedObject << op << " " << args.at(0)->argumentName();
262 259 } else {
263 260 if (fun->isStatic()) {
264 261 s << meta_class->qualifiedCppName() << "::";
265 262 } else {
266 263 if (!fun->isPublic() || fun->isVirtual()) {
267 264 s << " ((" << promoterClassName(meta_class) << "*)theWrappedObject)->promoted_";
268 265 } else {
269 266 s << " theWrappedObject->";
270 267 }
271 268 }
272 269 s << fun->originalName() << "(";
273 270 for (int i = 0; i < args.size(); ++i) {
274 271 if (i > 0)
275 272 s << ", ";
276 273 s << args.at(i)->argumentName();
277 274 }
278 275 s << ")";
279 276 }
280 277 s << ")";
281 278 }
282 279 s << ";" << endl;
283 280
284 281 s << "}" << endl << endl;
285 282 }
286 283
287 284 if (!meta_class->hasDefaultToStringFunction() && meta_class->hasToStringCapability()) {
288 285 FunctionModelItem fun = meta_class->hasToStringCapability();
289 286 int indirections = fun->arguments().at(1)->type().indirections();
290 287 QString deref = QLatin1String(indirections == 0 ? "*" : "");
291 288 s << "QString PythonQtWrapper_" << meta_class->name() << "::toString(" << meta_class->qualifiedCppName() << "* obj) {" << endl;
292 289 s << " QString result;" << endl;
293 290 s << " QDebug d(&result);" << endl;
294 291 s << " d << " << deref << "obj;" << endl;
295 292 s << " return result;" << endl;
296 293 s << "}" << endl << endl;
297 294 }
298 295
299 296 }
300 297
301 298 void ShellImplGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class)
302 299 {
303 300 CodeSnipList code_snips = meta_class->typeEntry()->codeSnips();
304 301 foreach (const CodeSnip &cs, code_snips) {
305 302 if (cs.language == TypeSystem::ShellCode) {
306 303 s << cs.code() << endl;
307 304 }
308 305 }
309 306 }
1 NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (1842 lines changed) Show them Hide them
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now