##// END OF EJS Templates
added destructor creation for shells...
florianlink -
r178:12aa9315d296
parent child
Show More
@@ -1,312 +1,314
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
55 55 void ShellHeaderGenerator::writeFieldAccessors(QTextStream &s, const AbstractMetaField *field)
56 56 {
57 57 const AbstractMetaFunction *setter = field->setter();
58 58 const AbstractMetaFunction *getter = field->getter();
59 59
60 60 // static fields are not supported (yet?)
61 61 if (setter->isStatic()) return;
62 62
63 63 // Uuid data4 did not work (TODO: move to typesystem...(
64 64 if (field->enclosingClass()->name()=="QUuid" && setter->name()=="data4") return;
65 65 if (field->enclosingClass()->name()=="QIPv6Address") return;
66 66
67 67 if (!field->type()->isConstant()) {
68 68 writeFunctionSignature(s, setter, 0, QString(),
69 69 Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | ShowStatic | UnderscoreSpaces));
70 70 s << "{ theWrappedObject->" << field->name() << " = " << setter->arguments()[0]->argumentName() << "; }\n";
71 71 }
72 72
73 73 writeFunctionSignature(s, getter, 0, QString(),
74 74 Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
75 75 s << "{ return theWrappedObject->" << field->name() << "; }\n";
76 76 }
77 77
78 78 void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class)
79 79 {
80 80 QString builtIn = ShellGenerator::isBuiltIn(meta_class->name())?"_builtin":"";
81 81 QString pro_file_name = meta_class->package().replace(".", "_") + builtIn + "/" + meta_class->package().replace(".", "_") + builtIn + ".pri";
82 82 priGenerator->addHeader(pro_file_name, fileNameForClass(meta_class));
83 83 setupGenerator->addClass(meta_class->package().replace(".", "_") + builtIn, meta_class);
84 84
85 85 QString include_block = "PYTHONQTWRAPPER_" + meta_class->name().toUpper() + "_H";
86 86
87 87 s << "#ifndef " << include_block << endl
88 88 << "#define " << include_block << endl << endl;
89 89
90 90 Include inc = meta_class->typeEntry()->include();
91 91 ShellGenerator::writeInclude(s, inc);
92 92
93 93 s << "#include <QObject>" << endl << endl;
94 94 s << "#include <PythonQt.h>" << endl << endl;
95 95
96 96 IncludeList list = meta_class->typeEntry()->extraIncludes();
97 97 qSort(list.begin(), list.end());
98 98 foreach (const Include &inc, list) {
99 99 ShellGenerator::writeInclude(s, inc);
100 100 }
101 101 s << endl;
102 102
103 103 AbstractMetaFunctionList ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors
104 104 | AbstractMetaClass::WasVisible
105 105 | AbstractMetaClass::NotRemovedFromTargetLang);
106 106
107 107 // Shell-------------------------------------------------------------------
108 108 if (meta_class->generateShellClass()) {
109 109
110 110 AbstractMetaFunctionList virtualsForShell = getVirtualFunctionsForShell(meta_class);
111 111
112 112 s << "class " << shellClassName(meta_class)
113 113 << " : public " << meta_class->qualifiedCppName() << endl << "{" << endl;
114 114 s << "public:" << endl;
115 115 foreach(AbstractMetaFunction* fun, ctors) {
116 116 s << " ";
117 117 writeFunctionSignature(s, fun, 0,"PythonQtShell_",
118 118 Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
119 119 s << ":" << meta_class->qualifiedCppName() << "(";
120 120 QString scriptFunctionName = fun->originalName();
121 121 AbstractMetaArgumentList args = fun->arguments();
122 122 for (int i = 0; i < args.size(); ++i) {
123 123 if (i > 0)
124 124 s << ", ";
125 125 s << args.at(i)->argumentName();
126 126 }
127 127 s << "),_wrapper(NULL) {};" << endl;
128 128 }
129 129 s << endl;
130 s << " ~" << shellClassName(meta_class) << "();" << endl;
131 s << endl;
130 132
131 133 foreach(AbstractMetaFunction* fun, virtualsForShell) {
132 134 s << "virtual ";
133 135 writeFunctionSignature(s, fun, 0, QString(),
134 136 Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
135 137 s << ";" << endl;
136 138 }
137 139 s << endl;
138 140 s << " PythonQtInstanceWrapper* _wrapper; " << endl;
139 141
140 142 s << "};" << endl << endl;
141 143 }
142 144
143 145 // Promoter-------------------------------------------------------------------
144 146 AbstractMetaFunctionList promoteFunctions = getProtectedFunctionsThatNeedPromotion(meta_class);
145 147 if (!promoteFunctions.isEmpty()) {
146 148 s << "class " << promoterClassName(meta_class)
147 149 << " : public " << meta_class->qualifiedCppName() << endl << "{ public:" << endl;
148 150
149 151 foreach(AbstractMetaFunction* fun, promoteFunctions) {
150 152 s << "inline ";
151 153 writeFunctionSignature(s, fun, 0, "promoted_",
152 154 Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
153 155 s << " { ";
154 156 QString scriptFunctionName = fun->originalName();
155 157 AbstractMetaArgumentList args = fun->arguments();
156 158 if (fun->type())
157 159 s << "return ";
158 160 s << meta_class->qualifiedCppName() << "::";
159 161 s << fun->originalName() << "(";
160 162 for (int i = 0; i < args.size(); ++i) {
161 163 if (i > 0)
162 164 s << ", ";
163 165 s << args.at(i)->argumentName();
164 166 }
165 167 s << "); }" << endl;
166 168 }
167 169
168 170 s << "};" << endl << endl;
169 171 }
170 172
171 173 // Wrapper-------------------------------------------------------------------
172 174
173 175 s << "class " << wrapperClassName(meta_class)
174 176 << " : public QObject" << endl
175 177 << "{ Q_OBJECT" << endl;
176 178
177 179 s << "public:" << endl;
178 180
179 181 AbstractMetaEnumList enums1 = meta_class->enums();
180 182 AbstractMetaEnumList enums;
181 183 QList<FlagsTypeEntry*> flags;
182 184 foreach(AbstractMetaEnum* enum1, enums1) {
183 185 // catch gadgets and enums that are not exported on QObjects...
184 186 if (enum1->wasPublic() && (!meta_class->isQObject() || !enum1->hasQEnumsDeclaration())) {
185 187 enums << enum1;
186 188 if (enum1->typeEntry()->flags()) {
187 189 flags << enum1->typeEntry()->flags();
188 190 }
189 191 }
190 192 }
191 193 if (enums.count()) {
192 194 s << "Q_ENUMS(";
193 195 foreach(AbstractMetaEnum* enum1, enums) {
194 196 s << enum1->name() << " ";
195 197 }
196 198 s << ")" << endl;
197 199
198 200 if (flags.count()) {
199 201 s << "Q_FLAGS(";
200 202 foreach(FlagsTypeEntry* flag1, flags) {
201 203 QString origName = flag1->originalName();
202 204 int idx = origName.lastIndexOf("::");
203 205 if (idx!= -1) {
204 206 origName = origName.mid(idx+2);
205 207 }
206 208 s << origName << " ";
207 209 }
208 210 s << ")" << endl;
209 211 }
210 212
211 213 foreach(AbstractMetaEnum* enum1, enums) {
212 214 s << "enum " << enum1->name() << "{" << endl;
213 215 bool first = true;
214 216 foreach(AbstractMetaEnumValue* value, enum1->values()) {
215 217 if (first) { first = false; }
216 218 else { s << ", "; }
217 219 s << " " << value->name() << " = " << meta_class->qualifiedCppName() << "::" << value->name();
218 220 }
219 221 s << "};" << endl;
220 222 }
221 223 if (flags.count()) {
222 224 foreach(AbstractMetaEnum* enum1, enums) {
223 225 if (enum1->typeEntry()->flags()) {
224 226 QString origName = enum1->typeEntry()->flags()->originalName();
225 227 int idx = origName.lastIndexOf("::");
226 228 if (idx!= -1) {
227 229 origName = origName.mid(idx+2);
228 230 }
229 231 s << "Q_DECLARE_FLAGS("<< origName << ", " << enum1->name() <<")"<<endl;
230 232 }
231 233 }
232 234 }
233 235 }
234 236 s << "public slots:" << endl;
235 237 if (meta_class->generateShellClass() || !meta_class->isAbstract()) {
236 238
237 239 bool copyConstructorSeen = false;
238 240 bool defaultConstructorSeen = false;
239 241 foreach (const AbstractMetaFunction *fun, ctors) {
240 242 if (!fun->isPublic() || fun->isAbstract()) { continue; }
241 243 s << meta_class->qualifiedCppName() << "* ";
242 244 writeFunctionSignature(s, fun, 0, "new_",
243 245 Option(IncludeDefaultExpression | OriginalName | ShowStatic));
244 246 s << ";" << endl;
245 247 if (fun->arguments().size()==1 && meta_class->qualifiedCppName() == fun->arguments().at(0)->type()->typeEntry()->qualifiedCppName()) {
246 248 copyConstructorSeen = true;
247 249 }
248 250 if (fun->arguments().size()==0) {
249 251 defaultConstructorSeen = true;
250 252 }
251 253 }
252 254
253 255 if (meta_class->typeEntry()->isValue()
254 256 && !copyConstructorSeen && defaultConstructorSeen) {
255 257 QString className = meta_class->generateShellClass()?shellClassName(meta_class):meta_class->qualifiedCppName();
256 258 s << meta_class->qualifiedCppName() << "* new_" << meta_class->name() << "(const " << meta_class->qualifiedCppName() << "& other) {" << endl;
257 259 s << className << "* a = new " << className << "();" << endl;
258 260 s << "*((" << meta_class->qualifiedCppName() << "*)a) = other;" << endl;
259 261 s << "return a; }" << endl;
260 262 }
261 263 }
262 264 if (meta_class->hasPublicDestructor() && !meta_class->isNamespace()) {
263 265 s << "void delete_" << meta_class->name() << "(" << meta_class->qualifiedCppName() << "* obj) { delete obj; } ";
264 266 s << endl;
265 267 }
266 268 if (meta_class->name()=="QTreeWidgetItem") {
267 269 s << "bool py_hasOwner(QTreeWidgetItem* theWrappedObject) { return theWrappedObject->treeWidget()!=NULL || theWrappedObject->parent()!=NULL; }" << endl;
268 270 } else if (meta_class->name()=="QGraphicsItem") {
269 271 s << "bool py_hasOwner(QGraphicsItem* theWrappedObject) { return theWrappedObject->scene()!=NULL || theWrappedObject->parentItem()!=NULL; }" << endl;
270 272 }
271 273
272 274 AbstractMetaFunctionList functions = getFunctionsToWrap(meta_class);
273 275
274 276 foreach (const AbstractMetaFunction *function, functions) {
275 277 if (!function->isSlot() || function->isVirtual()) {
276 278 s << " ";
277 279 writeFunctionSignature(s, function, 0, QString(),
278 280 Option(ConvertReferenceToPtr | FirstArgIsWrappedObject| IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
279 281 s << ";" << endl;
280 282 }
281 283 }
282 284 if (meta_class->hasDefaultToStringFunction() || meta_class->hasToStringCapability()) {
283 285 s << " QString py_toString(" << meta_class->qualifiedCppName() << "*);" << endl;
284 286 }
285 287 if (meta_class->hasDefaultIsNull()) {
286 288 s << " bool __nonzero__(" << meta_class->qualifiedCppName() << "* obj) { return !obj->isNull(); }" << endl;
287 289 }
288 290
289 291 // Field accessors
290 292 foreach (const AbstractMetaField *field, meta_class->fields()) {
291 293 if (field->isPublic()) {
292 294 writeFieldAccessors(s, field);
293 295 }
294 296 }
295 297
296 298 writeInjectedCode(s, meta_class);
297 299
298 300
299 301 s << "};" << endl << endl
300 302 << "#endif // " << include_block << endl;
301 303
302 304 }
303 305
304 306 void ShellHeaderGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class)
305 307 {
306 308 CodeSnipList code_snips = meta_class->typeEntry()->codeSnips();
307 309 foreach (const CodeSnip &cs, code_snips) {
308 310 if (cs.language == TypeSystem::PyWrapperDeclaration) {
309 311 s << cs.code() << endl;
310 312 }
311 313 }
312 314 }
@@ -1,318 +1,324
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 #include <iostream>
46 46
47 47 extern void declareFunctionMetaTypes(QTextStream &stream,
48 48 const AbstractMetaFunctionList &functions,
49 49 QSet<QString> &registeredTypeNames);
50 50
51 51 QString ShellImplGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const
52 52 {
53 53 return QString("PythonQtWrapper_%1.cpp").arg(meta_class->name());
54 54 }
55 55
56 56 static bool include_less_than(const Include &a, const Include &b)
57 57 {
58 58 return a.name < b.name;
59 59 }
60 60
61 61 static void writeHelperCode(QTextStream &s, const AbstractMetaClass *)
62 62 {
63 63 }
64 64
65 65
66 66
67 67 void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class)
68 68 {
69 69 QString builtIn = ShellGenerator::isBuiltIn(meta_class->name())?"_builtin":"";
70 70 QString pro_file_name = meta_class->package().replace(".", "_") + builtIn + "/" + meta_class->package().replace(".", "_") + builtIn + ".pri";
71 71 priGenerator->addSource(pro_file_name, fileNameForClass(meta_class));
72 72
73 73 s << "#include \"PythonQtWrapper_" << meta_class->name() << ".h\"" << endl << endl;
74 74
75 75 s << "#include <PythonQtSignalReceiver.h>" << endl;
76 76 s << "#include <PythonQtMethodInfo.h>" << endl;
77 77 s << "#include <PythonQtConversion.h>" << endl;
78 78
79 79 //if (!meta_class->generateShellClass())
80 80 // return;
81 81
82 82 IncludeList list = meta_class->typeEntry()->extraIncludes();
83 83 qSort(list.begin(), list.end());
84 84 foreach (const Include &inc, list) {
85 85 ShellGenerator::writeInclude(s, inc);
86 86 }
87 87 s << endl;
88 88
89 89 writeHelperCode(s, meta_class);
90 90
91 91 // find constructors
92 92 AbstractMetaFunctionList ctors;
93 93 ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors
94 94 | AbstractMetaClass::WasVisible
95 95 | AbstractMetaClass::NotRemovedFromTargetLang);
96 96 // find member functions
97 97 AbstractMetaFunctionList functions = getFunctionsToWrap(meta_class);
98 98
99 99 // write metatype declarations
100 100 {
101 101 // QSet<QString> registeredTypeNames = m_qmetatype_declared_typenames;
102 102 // declareFunctionMetaTypes(s, functions, registeredTypeNames);
103 103 // s << endl;
104 104 }
105 105
106 106 if (meta_class->generateShellClass()) {
107
108 s << shellClassName(meta_class) << "::~" << shellClassName(meta_class) << "() {" << endl;
109 s << " PythonQtPrivate* priv = PythonQt::priv();" << endl;
110 s << " if (priv) { priv->shellClassDeleted(this); }" << endl;
111 s << "}" << endl;
112
107 113 AbstractMetaFunctionList virtualsForShell = getVirtualFunctionsForShell(meta_class);
108 114 foreach (const AbstractMetaFunction *fun, virtualsForShell) {
109 115 bool hasReturnValue = (fun->type());
110 116 writeFunctionSignature(s, fun, meta_class, QString(),
111 117 Option(OriginalName | ShowStatic | UnderscoreSpaces),
112 118 "PythonQtShell_");
113 119 s << endl << "{" << endl;
114 120
115 121 Option typeOptions = Option(OriginalName | UnderscoreSpaces | SkipName);
116 122 AbstractMetaArgumentList args = fun->arguments();
117 123
118 124 s << "if (_wrapper) {" << endl;
119 125 s << " PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, \"" << fun->name() << "\");" << endl;
120 126 s << " PyErr_Clear();" << endl;
121 127 s << " if (obj && !PythonQtSlotFunction_Check(obj)) {" << endl;
122 128 s << " static const char* argumentList[] ={\"";
123 129 if (hasReturnValue) {
124 130 // write the arguments, return type first
125 131 writeTypeInfo(s, fun->type(), typeOptions);
126 132 }
127 133 s << "\"";
128 134 for (int i = 0; i < args.size(); ++i) {
129 135 s << " , \"";
130 136 writeTypeInfo(s, args.at(i)->type(), typeOptions);
131 137 s << "\"";
132 138 }
133 139 s << "};" << endl;
134 140 s << " static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(" << QString::number(args.size()+1) << ", argumentList);" << endl;
135 141
136 142 if (hasReturnValue) {
137 143 s << " ";
138 144 writeTypeInfo(s, fun->type(), typeOptions);
139 145 s << " returnValue;" << endl;
140 146 // TODO: POD init to default is missing...
141 147 }
142 148 s << " void* args[" << QString::number(args.size()+1) << "] = {NULL";
143 149 for (int i = 0; i < args.size(); ++i) {
144 150 s << ", (void*)&" << args.at(i)->argumentName();
145 151 }
146 152 s << "};" << endl;
147 153
148 154 s << " PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);" << endl;
149 155 if (hasReturnValue) {
150 156 s << " if (result) {" << endl;
151 157 s << " args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);" << endl;
152 158 s << " if (args[0]!=&returnValue) {" << endl;
153 159 s << " if (args[0]==NULL) {" << endl;
154 160 s << " PythonQt::priv()->handleVirtualOverloadReturnError(\"" << fun->name() << "\", methodInfo, result);" << endl;
155 161 s << " } else {" << endl;
156 162 s << " returnValue = *((";
157 163 writeTypeInfo(s, fun->type(), typeOptions);
158 164 s << "*)args[0]);" << endl;
159 165 s << " }" << endl;
160 166 s << " }" << endl;
161 167 s << " }" << endl;
162 168 }
163 169 s << " if (result) { Py_DECREF(result); } " << endl;
164 170 s << " Py_DECREF(obj);" << endl;
165 171 if (hasReturnValue) {
166 172 s << " return returnValue;" << endl;
167 173 } else {
168 174 s << " return;" << endl;
169 175 }
170 176 s << " }" << endl;
171 177 s << "}" << endl;
172 178
173 179 s << " ";
174 180 if (fun->isAbstract()) {
175 181 if (fun->type()) {
176 182 // return empty default object
177 183 s << "return ";
178 184 if (fun->type()->indirections()>0) {
179 185 s << "0;";
180 186 } else {
181 187 writeTypeInfo(s, fun->type(), typeOptions);
182 188 s << "();";
183 189 }
184 190 }
185 191 } else {
186 192 if (fun->type()) {
187 193 s << "return ";
188 194 }
189 195 s << meta_class->qualifiedCppName() << "::";
190 196 s << fun->originalName() << "(";
191 197 for (int i = 0; i < args.size(); ++i) {
192 198 if (i > 0)
193 199 s << ", ";
194 200 s << args.at(i)->argumentName();
195 201 }
196 202 s << ");";
197 203 }
198 204 s << endl << "}" << endl;
199 205 }
200 206 }
201 207
202 208 if (meta_class->generateShellClass() || !meta_class->isAbstract()) {
203 209
204 210 // write constructors
205 211 foreach (const AbstractMetaFunction *ctor, ctors) {
206 212 if (!ctor->isPublic() || ctor->isAbstract()) { continue; }
207 213
208 214 s << meta_class->qualifiedCppName() << "* ";
209 215 s << "PythonQtWrapper_" << meta_class->name() << "::";
210 216 writeFunctionSignature(s, ctor, 0, "new_", Option(OriginalName | ShowStatic));
211 217 s << endl;
212 218 s << "{ " << endl;
213 219 s << "return new " << (meta_class->generateShellClass()?shellClassName(meta_class):meta_class->qualifiedCppName()) << "(";
214 220 AbstractMetaArgumentList args = ctor->arguments();
215 221 for (int i = 0; i < args.size(); ++i) {
216 222 if (i > 0)
217 223 s << ", ";
218 224 s << args.at(i)->argumentName();
219 225 }
220 226 s << ");" << " }" << endl << endl;
221 227 }
222 228 }
223 229
224 230 QString wrappedObject = " (*theWrappedObject)";
225 231
226 232 // write member functions
227 233 for (int i = 0; i < functions.size(); ++i) {
228 234 AbstractMetaFunction *fun = functions.at(i);
229 235 bool needsWrapping = (!fun->isSlot() || fun->isVirtual());
230 236 if (!needsWrapping) {
231 237 continue;
232 238 }
233 239 writeFunctionSignature(s, fun, meta_class, QString(),
234 240 Option(ConvertReferenceToPtr | FirstArgIsWrappedObject | OriginalName | ShowStatic | UnderscoreSpaces),
235 241 "PythonQtWrapper_");
236 242 s << endl << "{" << endl;
237 243 s << " ";
238 244 if (ShellGenerator::isSpecialStreamingOperator(fun)) {
239 245 s << fun->arguments().at(0)->argumentName();
240 246 if (fun->originalName().startsWith("operator>>")) {
241 247 s << " >> ";
242 248 } else {
243 249 s << " << ";
244 250 }
245 251 s << wrappedObject;
246 252 } else {
247 253 QString scriptFunctionName = fun->originalName();
248 254 AbstractMetaArgumentList args = fun->arguments();
249 255 // call the C++ implementation
250 256 if (fun->type()) {
251 257 s << "return ";
252 258 // call the C++ implementation
253 259 if (fun->type()->isReference()) {
254 260 s << "&";
255 261 }
256 262 }
257 263 s << "(";
258 264 if (scriptFunctionName.startsWith("operator>>")) {
259 265 s << wrappedObject << " >>" << args.at(0)->argumentName();
260 266 } else if (scriptFunctionName.startsWith("operator<<")) {
261 267 s << wrappedObject << " <<" << args.at(0)->argumentName();
262 268 } else if (scriptFunctionName.startsWith("operator[]")) {
263 269 s << wrappedObject << "[" << args.at(0)->argumentName() << "]";
264 270 } else if (scriptFunctionName.startsWith("operator") && args.size()==1) {
265 271 QString op = scriptFunctionName.mid(8);
266 272 s << wrappedObject << op << " " << args.at(0)->argumentName();
267 273 } else {
268 274 if (fun->isStatic()) {
269 275 s << meta_class->qualifiedCppName() << "::";
270 276 } else {
271 277 if (!fun->isPublic() || fun->isVirtual()) {
272 278 s << " ((" << promoterClassName(meta_class) << "*)theWrappedObject)->promoted_";
273 279 } else {
274 280 s << " theWrappedObject->";
275 281 }
276 282 }
277 283 s << fun->originalName() << "(";
278 284 for (int i = 0; i < args.size(); ++i) {
279 285 if (i > 0)
280 286 s << ", ";
281 287 s << args.at(i)->argumentName();
282 288 }
283 289 s << ")";
284 290 }
285 291 s << ")";
286 292 }
287 293 s << ";" << endl;
288 294
289 295 s << "}" << endl << endl;
290 296 }
291 297
292 298 if (meta_class->hasDefaultToStringFunction()) {
293 299 s << "QString PythonQtWrapper_" << meta_class->name() << "::py_toString(" << meta_class->qualifiedCppName() << "* obj) { return obj->toString(); }" << endl;
294 300 } else if (meta_class->hasToStringCapability()) {
295 301 FunctionModelItem fun = meta_class->hasToStringCapability();
296 302 int indirections = fun->arguments().at(1)->type().indirections();
297 303 QString deref = QLatin1String(indirections == 0 ? "*" : "");
298 304 s << "QString PythonQtWrapper_" << meta_class->name() << "::py_toString(" << meta_class->qualifiedCppName() << "* obj) {" << endl;
299 305 s << " QString result;" << endl;
300 306 s << " QDebug d(&result);" << endl;
301 307 s << " d << " << deref << "obj;" << endl;
302 308 s << " return result;" << endl;
303 309 s << "}" << endl << endl;
304 310 }
305 311
306 312 writeInjectedCode(s, meta_class);
307 313
308 314 }
309 315
310 316 void ShellImplGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class)
311 317 {
312 318 CodeSnipList code_snips = meta_class->typeEntry()->codeSnips();
313 319 foreach (const CodeSnip &cs, code_snips) {
314 320 if (cs.language == TypeSystem::PyWrapperCode) {
315 321 s << cs.code() << endl;
316 322 }
317 323 }
318 324 }
General Comments 0
You need to be logged in to leave comments. Login now