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