##// END OF EJS Templates
improved generator, requires uptodate pythonqt version...
florianlink -
r66:f93f1d21eb33
parent child
Show More
1 NO CONTENT: modified file
@@ -1,270 +1,276
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
4 4 **
5 5 ** This file is part of the Qt Script Generator project on Trolltech Labs.
6 6 **
7 7 ** This file may be used under the terms of the GNU General Public
8 8 ** License version 2.0 as published by the Free Software Foundation
9 9 ** and appearing in the file LICENSE.GPL included in the packaging of
10 10 ** this file. Please review the following information to ensure GNU
11 11 ** General Public Licensing requirements will be met:
12 12 ** http://www.trolltech.com/products/qt/opensource.html
13 13 **
14 14 ** If you are unsure which license is appropriate for your use, please
15 15 ** review the following information:
16 16 ** http://www.trolltech.com/products/qt/licensing.html or contact the
17 17 ** sales department at sales@trolltech.com.
18 18 **
19 19 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20 20 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 21 **
22 22 ****************************************************************************/
23 23
24 24 #include "shellimplgenerator.h"
25 25 #include "reporthandler.h"
26 26 #include "fileout.h"
27 27
28 28 extern void declareFunctionMetaTypes(QTextStream &stream,
29 29 const AbstractMetaFunctionList &functions,
30 30 QSet<QString> &registeredTypeNames);
31 31
32 32 QString ShellImplGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const
33 33 {
34 34 return QString("PythonQtWrapper_%1.cpp").arg(meta_class->name());
35 35 }
36 36
37 37 static bool include_less_than(const Include &a, const Include &b)
38 38 {
39 39 return a.name < b.name;
40 40 }
41 41
42 42 static void writeHelperCode(QTextStream &s, const AbstractMetaClass *)
43 43 {
44 44 }
45 45
46 46 void writeQtScriptQtBindingsLicense(QTextStream &stream);
47 47
48 48 void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class)
49 49 {
50 50 if (FileOut::license)
51 51 writeQtScriptQtBindingsLicense(s);
52 52
53 53 QString pro_file_name = meta_class->package().replace(".", "_") + "/" + meta_class->package().replace(".", "_") + ".pri";
54 54
55 55 if (!ShellGenerator::isBuiltIn(meta_class->name())) {
56 56 priGenerator->addSource(pro_file_name, fileNameForClass(meta_class));
57 57 }
58 58
59 59 s << "#include \"PythonQtWrapper_" << meta_class->name() << ".h\"" << endl << endl;
60 60
61 61 s << "#include <PythonQtSignalReceiver.h>" << endl;
62 62 s << "#include <PythonQtMethodInfo.h>" << endl;
63 63 s << "#include <PythonQtConversion.h>" << endl;
64 64
65 65 //if (!meta_class->generateShellClass())
66 66 // return;
67 67
68 68 IncludeList list = meta_class->typeEntry()->extraIncludes();
69 69 qSort(list.begin(), list.end());
70 70 foreach (const Include &inc, list) {
71 71 ShellGenerator::writeInclude(s, inc);
72 72 }
73 73 s << endl;
74 74
75 75 writeHelperCode(s, meta_class);
76 76
77 77 // find constructors
78 78 AbstractMetaFunctionList ctors;
79 79 ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors
80 80 | AbstractMetaClass::WasVisible
81 81 | AbstractMetaClass::NotRemovedFromTargetLang);
82 82 // find member functions
83 83 AbstractMetaFunctionList functions = getFunctionsToWrap(meta_class);
84 84
85 85 // write metatype declarations
86 86 {
87 87 // QSet<QString> registeredTypeNames = m_qmetatype_declared_typenames;
88 88 // declareFunctionMetaTypes(s, functions, registeredTypeNames);
89 89 // s << endl;
90 90 }
91 91
92 92 if (meta_class->generateShellClass()) {
93 93 AbstractMetaFunctionList virtualsForShell = getVirtualFunctionsForShell(meta_class);
94 94 foreach (const AbstractMetaFunction *fun, virtualsForShell) {
95 95 bool hasReturnValue = (fun->type());
96 96 writeFunctionSignature(s, fun, meta_class, QString(),
97 97 Option(OriginalName | ShowStatic | UnderscoreSpaces),
98 98 "PythonQtShell_");
99 99 s << endl << "{" << endl;
100 100
101 Option typeOptions = Option(OriginalName | UnderscoreSpaces);
101 Option typeOptions = Option(OriginalName | UnderscoreSpaces | SkipName);
102 102 AbstractMetaArgumentList args = fun->arguments();
103 103
104 104 s << "if (_wrapper) {" << endl;
105 105 s << " PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, \"" << fun->name() << "\");" << endl;
106 106 s << " PyErr_Clear();" << endl;
107 107 s << " if (obj && !PythonQtSlotFunction_Check(obj)) {" << endl;
108 s << " static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromMetaObjectAndSignature(" << endl;
109 s << " &" << wrapperClassName(meta_class) << "::staticMetaObject," << endl;
108 s << " static const char* argumentList[] ={\"";
109 if (hasReturnValue) {
110 // write the arguments, return type first
111 writeTypeInfo(s, fun->type(), typeOptions);
112 }
110 113 s << " \"";
111 // write the signature
112 s << fun->name() << "(" << meta_class->qualifiedCppName() << "*";
113 114 for (int i = 0; i < args.size(); ++i) {
114 s << ",";
115 s << " , \"";
115 116 writeTypeInfo(s, args.at(i)->type(), typeOptions);
117 s << "\"";
116 118 }
117 s << ")";
118 s << "\");" << endl;
119 s << "};" << endl;
120 s << " static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(" << QString::number(args.size()+1) << ", argumentList);" << endl;
119 121
120 122 if (hasReturnValue) {
121 123 s << " ";
122 124 writeTypeInfo(s, fun->type(), typeOptions);
123 125 s << " returnValue;" << endl;
124 126 // TODO: POD init to default is missing...
125 127 }
126 128 s << " void* args[" << QString::number(args.size()+1) << "] = {NULL";
127 129 for (int i = 0; i < args.size(); ++i) {
128 130 s << ", (void*)&" << args.at(i)->argumentName();
129 131 }
130 132 s << "};" << endl;
131 133
132 134 s << " PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);" << endl;
133 135 if (hasReturnValue) {
134 136 s << " if (result) {" << endl;
135 137 s << " args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);" << endl;
136 138 s << " if (args[0]!=&returnValue) {" << endl;
139 s << " if (args[0]==NULL) {" << endl;
140 s << " PythonQt::priv()->handleVirtualOverloadReturnError(\"" << fun->name() << "\", methodInfo, result);" << endl;
141 s << " } else {" << endl;
137 142 s << " returnValue = *((";
138 143 writeTypeInfo(s, fun->type(), typeOptions);
139 144 s << "*)args[0]);" << endl;
140 145 s << " }" << endl;
141 146 s << " }" << endl;
147 s << " }" << endl;
142 148 }
143 149 s << " if (result) { Py_DECREF(result); } " << endl;
144 150 s << " Py_DECREF(obj);" << endl;
145 151 if (hasReturnValue) {
146 152 s << " return returnValue;" << endl;
147 153 } else {
148 154 s << " return;" << endl;
149 155 }
150 156 s << " }" << endl;
151 157 s << "}" << endl;
152 158
153 159 s << " ";
154 160 if (fun->isAbstract()) {
155 161 if (fun->type()) {
156 162 // return empty default object
157 163 writeTypeInfo(s, fun->type(), typeOptions);
158 164 s << " result;" << endl;
159 165 s << "return result";
160 166 s << ";";
161 167 }
162 168 } else {
163 169 if (fun->type()) {
164 170 s << "return ";
165 171 }
166 172 // call the C++ implementation
167 173 s << meta_class->qualifiedCppName() << "::";
168 174 s << fun->originalName() << "(";
169 175 for (int i = 0; i < args.size(); ++i) {
170 176 if (i > 0)
171 177 s << ", ";
172 178 s << args.at(i)->argumentName();
173 179 }
174 180 s << ");";
175 181 }
176 182 s << endl << "}" << endl;
177 183 }
178 184 }
179 185
180 186 if (meta_class->generateShellClass() || !meta_class->isAbstract()) {
181 187
182 188 // write constructors
183 189 foreach (const AbstractMetaFunction *ctor, ctors) {
184 190 if (!ctor->isPublic() || ctor->isAbstract()) { continue; }
185 191
186 192 s << meta_class->qualifiedCppName() << "* ";
187 193 s << "PythonQtWrapper_" << meta_class->name() << "::";
188 194 writeFunctionSignature(s, ctor, 0, "new_", Option(OriginalName | ShowStatic));
189 195 s << endl;
190 196 s << "{ " << endl;
191 197 s << "return new " << (meta_class->generateShellClass()?shellClassName(meta_class):meta_class->qualifiedCppName()) << "(";
192 198 AbstractMetaArgumentList args = ctor->arguments();
193 199 for (int i = 0; i < args.size(); ++i) {
194 200 if (i > 0)
195 201 s << ", ";
196 202 s << args.at(i)->argumentName();
197 203 }
198 204 s << ");" << " }" << endl << endl;
199 205 }
200 206 }
201 207
202 208 QString wrappedObject = " (*theWrappedObject)";
203 209
204 210 // write member functions
205 211 for (int i = 0; i < functions.size(); ++i) {
206 212 AbstractMetaFunction *fun = functions.at(i);
207 213 if (fun->isSlot()) continue;
208 214
209 215 writeFunctionSignature(s, fun, meta_class, QString(),
210 216 Option(FirstArgIsWrappedObject | OriginalName | ShowStatic | UnderscoreSpaces),
211 217 "PythonQtWrapper_");
212 218 s << endl << "{" << endl;
213 219 s << " ";
214 220 if (ShellGenerator::isSpecialStreamingOperator(fun)) {
215 221 s << fun->arguments().at(0)->argumentName();
216 222 if (fun->originalName().startsWith("operator>>")) {
217 223 s << " >> ";
218 224 } else {
219 225 s << " << ";
220 226 }
221 227 s << wrappedObject;
222 228 } else {
223 229 QString scriptFunctionName = fun->originalName();
224 230 AbstractMetaArgumentList args = fun->arguments();
225 231 // call the C++ implementation
226 232 if (fun->type())
227 233 s << "return ";
228 234 if (scriptFunctionName.startsWith("operator>>")) {
229 235 s << wrappedObject << " >>" << args.at(0)->argumentName();
230 236 } else if (scriptFunctionName.startsWith("operator<<")) {
231 237 s << wrappedObject << " <<" << args.at(0)->argumentName();
232 238 } else if (scriptFunctionName.startsWith("operator[]")) {
233 239 s << wrappedObject << "[" << args.at(0)->argumentName() << "]";
234 240 } else if (scriptFunctionName.startsWith("operator") && args.size()==1) {
235 241 QString op = scriptFunctionName.mid(8);
236 242 s << wrappedObject << op << " " << args.at(0)->argumentName();
237 243 } else {
238 244 if (fun->isStatic()) {
239 245 s << meta_class->qualifiedCppName() << "::";
240 246 } else {
241 247 if (!fun->isPublic() || fun->isVirtual()) {
242 248 s << " ((" << promoterClassName(meta_class) << "*)theWrappedObject)->promoted_";
243 249 } else {
244 250 s << " theWrappedObject->";
245 251 }
246 252 }
247 253 s << fun->originalName() << "(";
248 254 for (int i = 0; i < args.size(); ++i) {
249 255 if (i > 0)
250 256 s << ", ";
251 257 s << args.at(i)->argumentName();
252 258 }
253 259 s << ")";
254 260 }
255 261 }
256 262 s << ";" << endl;
257 263
258 264 s << "}" << endl << endl;
259 265 }
260 266 }
261 267
262 268 void ShellImplGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class)
263 269 {
264 270 CodeSnipList code_snips = meta_class->typeEntry()->codeSnips();
265 271 foreach (const CodeSnip &cs, code_snips) {
266 272 if (cs.language == TypeSystem::ShellCode) {
267 273 s << cs.code() << endl;
268 274 }
269 275 }
270 276 }
General Comments 0
You need to be logged in to leave comments. Login now