##// END OF EJS Templates
- upgraded generator to generate polymorphic handlers for downcasting...
florianlink -
r29:fa33440a60c5
parent child
Show More
@@ -471,6 +471,8 public:
471 471 FunctionType functionType() const { return m_function_type; }
472 472 void setFunctionType(FunctionType type) { m_function_type = type; }
473 473
474 bool isVirtual() { return !(isFinal() || isSignal() || isStatic()); }
475
474 476 QStringList introspectionCompatibleSignatures(const QStringList &resolvedArguments = QStringList()) const;
475 477 QString signature() const;
476 478 QString targetLangSignature(bool minimal = false) const;
@@ -68,6 +68,7 QString GeneratorSetQtScript::generate() {
68 68 SetupGenerator setupGenerator;
69 69 setupGenerator.setOutputDirectory(outDir);
70 70 setupGenerator.setQtMetaTypeDeclaredTypeNames(declaredTypeNames);
71 setupGenerator.setClasses(classes);
71 72
72 73 /*
73 74 ClassGenerator classGenerator(&priGenerator, &setupGenerator);
@@ -30,7 +30,7
30 30
31 31 void SetupGenerator::addClass(const AbstractMetaClass *cls)
32 32 {
33 packHash[cls->package()].append(cls);
33 packHash[cls->package()].append(cls);
34 34 }
35 35
36 36 void writeQtScriptQtBindingsLicense(QTextStream &stream);
@@ -41,83 +41,175 bool hasDefaultConstructor(const AbstractMetaClass *meta_class);
41 41
42 42 void SetupGenerator::generate()
43 43 {
44 AbstractMetaClassList classes_with_polymorphic_id;
45 {
44 46 QHashIterator<QString, QList<const AbstractMetaClass*> > pack(packHash);
45 47 while (pack.hasNext()) {
46 pack.next();
47 QList<const AbstractMetaClass*> list = pack.value();
48 if (list.isEmpty())
49 continue;
50
51 QString packKey = pack.key();
52 QString packName = pack.key();
53 QStringList components = packName.split(".");
54 if ((components.size() > 2) && (components.at(0) == "com")
55 && (components.at(1) == "trolltech")) {
56 // kill com.trolltech in key
57 components.removeAt(0);
58 components.removeAt(0);
48 pack.next();
49 QList<const AbstractMetaClass*> list = pack.value();
50 foreach (const AbstractMetaClass *cls, list) {
51 if (cls->typeEntry()->isPolymorphicBase()) {
52 classes_with_polymorphic_id.append((AbstractMetaClass*)cls);
59 53 }
60 packName.replace(".", "_");
61 packKey.replace(".", "_");
54 }
55 }
56 }
57
58 QHashIterator<QString, QList<const AbstractMetaClass*> > pack(packHash);
59 while (pack.hasNext()) {
60 pack.next();
61 QList<const AbstractMetaClass*> list = pack.value();
62 if (list.isEmpty())
63 continue;
64
65 QString packKey = pack.key();
66 QString packName = pack.key();
67 QStringList components = packName.split(".");
68 if ((components.size() > 2) && (components.at(0) == "com")
69 && (components.at(1) == "trolltech")) {
70 // kill com.trolltech in key
71 components.removeAt(0);
72 components.removeAt(0);
73 }
74 packName.replace(".", "_");
75 packKey.replace(".", "_");
62 76
63 QString shortPackName;
64 foreach (QString comp, components) {
65 comp[0] = comp[0].toUpper();
66 shortPackName += comp;
67 }
68 // add missing camel case (workaround..)
69 if (shortPackName == "QtWebkit") {
70 shortPackName = "QtWebKit";
71 } else if (shortPackName == "QtXmlpatterns") {
72 shortPackName = "QtXmlPatterns";
73 } else if (shortPackName == "QtOpengl") {
74 shortPackName = "QtOpenGL";
75 } else if (shortPackName == "QtUitools") {
76 shortPackName = "QtUiTools";
77 }
77 QString shortPackName;
78 foreach (QString comp, components) {
79 comp[0] = comp[0].toUpper();
80 shortPackName += comp;
81 }
82 // add missing camel case (workaround..)
83 if (shortPackName == "QtWebkit") {
84 shortPackName = "QtWebKit";
85 } else if (shortPackName == "QtXmlpatterns") {
86 shortPackName = "QtXmlPatterns";
87 } else if (shortPackName == "QtOpengl") {
88 shortPackName = "QtOpenGL";
89 } else if (shortPackName == "QtUitools") {
90 shortPackName = "QtUiTools";
91 }
78 92
79 93
80 {
81 FileOut initFile(m_out_dir + "/generated_cpp/" + packName + "/" + packKey + "_init.cpp");
82 QTextStream &s = initFile.stream;
94 {
95 FileOut initFile(m_out_dir + "/generated_cpp/" + packName + "/" + packKey + "_init.cpp");
96 QTextStream &s = initFile.stream;
83 97
84 if (FileOut::license)
85 writeQtScriptQtBindingsLicense(s);
98 if (FileOut::license)
99 writeQtScriptQtBindingsLicense(s);
86 100
87 s << "#include <PythonQt.h>" << endl;
101 s << "#include <PythonQt.h>" << endl;
102
103 foreach (const AbstractMetaClass *cls, list) {
104 s << "#include \"" << ShellGenerator::wrapperClassName(cls) << ".h\"" << endl;
105 }
106 s << endl;
107
108 QStringList polymorphicHandlers = writePolymorphicHandler(s, list.at(0)->package(), classes_with_polymorphic_id);
109 s << endl;
110
111 // declare individual class creation functions
112 s << "void PythonQt_init_" << shortPackName << "() {" << endl;
113 QStringList cppClassNames;
114 foreach (const AbstractMetaClass *cls, list) {
115 if (ShellGenerator::isBuiltIn(cls->name())) { continue; }
116
117 QString shellCreator;
118 if (cls->generateShellClass()) {
119 shellCreator = ", PythonQtSetInstanceWrapperOnShell<" + ShellGenerator::shellClassName(cls) + ">";
120 }
121 if (cls->isQObject()) {
122 s << "PythonQt::self()->registerClass(&" << cls->qualifiedCppName() << "::staticMetaObject, \"" << shortPackName <<"\", PythonQtCreateObject<PythonQtWrapper_" << cls->name() << ">" << shellCreator << ");" << endl;
123 } else {
124 QString baseName = cls->baseClass()?cls->baseClass()->qualifiedCppName():"";
125 s << "PythonQt::self()->registerCPPClass(\""<< cls->qualifiedCppName() << "\", \"" << baseName << "\", \"" << shortPackName <<"\", PythonQtCreateObject<PythonQtWrapper_" << cls->name() << ">" << shellCreator << ");" << endl;
126 }
127 foreach(AbstractMetaClass* interface, cls->interfaces()) {
128 // the interface might be our own class... (e.g. QPaintDevice)
129 if (interface->qualifiedCppName() != cls->qualifiedCppName()) {
130 s << "PythonQt::self()->addParentClass(\""<< cls->qualifiedCppName() << "\", \"" << interface->qualifiedCppName() << "\",PythonQtUpcastingOffset<" << cls->qualifiedCppName() <<","<<interface->qualifiedCppName()<<">());" << endl;
131 }
132 }
133 }
134 s << endl;
135 foreach (QString handler, polymorphicHandlers) {
136 s << "PythonQt::self()->addPolymorphicHandler(\""<< handler << "\", polymorphichandler_" << handler << ");" << endl;
137 }
138
139 s << "}";
140 s << endl;
141 }
142 }
143 }
88 144
89 foreach (const AbstractMetaClass *cls, list) {
90 s << "#include \"" << ShellGenerator::wrapperClassName(cls) << ".h\"" << endl;
145 QStringList SetupGenerator::writePolymorphicHandler(QTextStream &s, const QString &package,
146 const AbstractMetaClassList &classes)
147 {
148 QStringList handlers;
149 foreach (AbstractMetaClass *cls, classes) {
150 const ComplexTypeEntry *centry = cls->typeEntry();
151 if (!centry->isPolymorphicBase())
152 continue;
153 bool isGraphicsItem = (cls->qualifiedCppName()=="QGraphicsItem");
154
155 AbstractMetaClassList classList = this->classes();
156 bool first = true;
157 foreach (AbstractMetaClass *clazz, classList) {
158 bool inherits = false;
159 if (isGraphicsItem) {
160 foreach(AbstractMetaClass* interfaze, clazz->interfaces()) {
161 if (interfaze->qualifiedCppName()=="QGraphicsItem") {
162 inherits = true;
163 break;
91 164 }
92 s << endl;
93
94 // declare individual class creation functions
95 s << "void PythonQt_init_" << shortPackName << "() {" << endl;
96 QStringList cppClassNames;
97 foreach (const AbstractMetaClass *cls, list) {
98 if (ShellGenerator::isBuiltIn(cls->name())) { continue; }
99
100 QString shellCreator;
101 if (cls->generateShellClass()) {
102 shellCreator = ", PythonQtSetInstanceWrapperOnShell<" + ShellGenerator::shellClassName(cls) + ">";
103 }
104 if (cls->isQObject()) {
105 s << "PythonQt::self()->registerClass(&" << cls->qualifiedCppName() << "::staticMetaObject, \"" << shortPackName <<"\", PythonQtCreateObject<PythonQtWrapper_" << cls->name() << ">" << shellCreator << ");" << endl;
106 } else {
107 QString baseName = cls->baseClass()?cls->baseClass()->qualifiedCppName():"";
108 s << "PythonQt::self()->registerCPPClass(\""<< cls->qualifiedCppName() << "\", \"" << baseName << "\", \"" << shortPackName <<"\", PythonQtCreateObject<PythonQtWrapper_" << cls->name() << ">" << shellCreator << ");" << endl;
109 }
110 foreach(AbstractMetaClass* interface, cls->interfaces()) {
111 // the interface might be our own class... (e.g. QPaintDevice)
112 if (interface->qualifiedCppName() != cls->qualifiedCppName()) {
113 s << "PythonQt::self()->addParentClass(\""<< cls->qualifiedCppName() << "\", \"" << interface->qualifiedCppName() << "\",PythonQtUpcastingOffset<" << cls->qualifiedCppName() <<","<<interface->qualifiedCppName()<<">());" << endl;
114 }
115 }
165 }
166 } else {
167 inherits = clazz->inheritsFrom(cls);
168 }
169 if (clazz->package() == package && inherits) {
170 if (!clazz->typeEntry()->polymorphicIdValue().isEmpty() || isGraphicsItem) {
171 // On first find, open the function
172 if (first) {
173 first = false;
174
175 QString handler = cls->name();
176 handlers.append(handler);
177
178 s << "static void* polymorphichandler_" << handler
179 << "(const void *ptr, char **class_name)" << endl
180 << "{" << endl
181 << " Q_ASSERT(ptr != 0);" << endl
182 << " " << cls->qualifiedCppName() << " *object = ("
183 << cls->qualifiedCppName() << " *)ptr;" << endl;
116 184 }
117 s << endl;
118 185
119 s << "}";
120 s << endl;
186 // For each, add case label
187 QString polyId = clazz->typeEntry()->polymorphicIdValue();
188 if (isGraphicsItem) {
189 polyId = "%1->type() == " + clazz->qualifiedCppName() + "::Type";
190 }
191 s << " if ("
192 << polyId.replace("%1", "object")
193 << ") {" << endl
194 << " *class_name = \"" << clazz->name() << "\";" << endl
195 << " return (" << clazz->qualifiedCppName() << "*)object;" << endl
196 << " }" << endl;
197 } else {
198 QString warning = QString("class '%1' inherits from polymorphic class '%2', but has no polymorphic id set")
199 .arg(clazz->name())
200 .arg(cls->name());
201
202 ReportHandler::warning(warning);
121 203 }
204 }
122 205 }
206
207 // Close the function if it has been opened
208 if (!first) {
209 s << " return NULL;" << endl
210 << "}" << endl;
211 }
212 }
213
214 return handlers;
123 215 }
@@ -37,7 +37,10 class SetupGenerator : public Generator
37 37 void addClass(const AbstractMetaClass *cls);
38 38
39 39 private:
40 QHash<QString, QList<const AbstractMetaClass*> > packHash;
40 QStringList writePolymorphicHandler(QTextStream &s, const QString &package,
41 const AbstractMetaClassList &classes);
42
43 QHash<QString, QList<const AbstractMetaClass*> > packHash;
41 44 };
42 45 #endif // SETUPGENERATOR_H
43 46
@@ -269,7 +269,7 AbstractMetaFunctionList ShellGenerator::getProtectedFunctionsThatNeedPromotion(
269 269 AbstractMetaFunctionList functions;
270 270 AbstractMetaFunctionList functions1 = getFunctionsToWrap(meta_class);
271 271 foreach(AbstractMetaFunction* func, functions1) {
272 if (!func->wasPublic()) {
272 if (!func->isPublic() || func->isVirtual()) {
273 273 functions << func;
274 274 }
275 275 }
@@ -117,7 +117,7 void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_c
117 117
118 118 foreach(AbstractMetaFunction* fun, promoteFunctions) {
119 119 s << "inline ";
120 writeFunctionSignature(s, fun, 0, QString(),
120 writeFunctionSignature(s, fun, 0, "promoted_",
121 121 Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces));
122 122 s << " { ";
123 123 QString scriptFunctionName = fun->originalName();
@@ -199,6 +199,8 void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_cla
199 199 }
200 200 }
201 201
202 QString wrappedObject = " (*theWrappedObject)";
203
202 204 // write member functions
203 205 for (int i = 0; i < functions.size(); ++i) {
204 206 AbstractMetaFunction *fun = functions.at(i);
@@ -208,12 +210,7 void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_cla
208 210 Option(FirstArgIsWrappedObject | OriginalName | ShowStatic | UnderscoreSpaces),
209 211 "PythonQtWrapper_");
210 212 s << endl << "{" << endl;
211 QString wrappedObject;
212 if (fun->wasPublic()) {
213 wrappedObject = " (*theWrappedObject)";
214 } else {
215 wrappedObject = " (*((" + promoterClassName(meta_class) + "*)theWrappedObject))";
216 }
213 s << " ";
217 214 if (ShellGenerator::isSpecialStreamingOperator(fun)) {
218 215 s << fun->arguments().at(0)->argumentName();
219 216 if (fun->originalName().startsWith("operator>>")) {
@@ -241,9 +238,13 void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_cla
241 238 if (fun->isStatic()) {
242 239 s << meta_class->qualifiedCppName() << "::";
243 240 } else {
244 s << wrappedObject << ".";
241 if (!fun->isPublic() || fun->isVirtual()) {
242 s << " ((" << promoterClassName(meta_class) << "*)theWrappedObject)->promoted_";
243 } else {
244 s << " theWrappedObject->";
245 }
245 246 }
246 s << fun->originalName() << "(";
247 s << fun->originalName() << "(";
247 248 for (int i = 0; i < args.size(); ++i) {
248 249 if (i > 0)
249 250 s << ", ";
@@ -1025,7 +1025,7
1025 1025 <access modifier="private"/>
1026 1026 </modify-function>
1027 1027 <modify-function signature="QImage(const uchar*,int,int,int,QImage::Format)">
1028 <remove/>
1028 <remove/>
1029 1029 </modify-function>
1030 1030 <modify-function signature="bits()const">
1031 1031 <remove/>
@@ -1401,7 +1401,7
1401 1401 <interface-type name="QLayoutItem"/>
1402 1402 <interface-type name="QPaintDevice"/>
1403 1403
1404 <interface-type name="QGraphicsItem" delete-in-main-thread="yes">
1404 <interface-type name="QGraphicsItem" delete-in-main-thread="yes" polymorphic-base="yes">
1405 1405 <modify-function signature="setMatrix(QMatrix, bool)" remove="all"/>
1406 1406
1407 1407 <modify-function signature="paint(QPainter*,const QStyleOptionGraphicsItem*,QWidget*)">
@@ -1476,7 +1476,7
1476 1476 <modify-argument index="1" invalidate-after-use="yes"/>
1477 1477 </modify-function>
1478 1478
1479 <modify-function signature="children()const" remove="all"/>
1479 <modify-function signature="children()const" remove="all"/>
1480 1480 <modify-function signature="installSceneEventFilter(QGraphicsItem *)">
1481 1481 <modify-argument index="1">
1482 1482 <!-- Safe to ignore because items in a scene are memory managed by the scene -->
@@ -5045,10 +5045,10
5045 5045 <access modifier="private"/>
5046 5046 </modify-function>
5047 5047 <modify-function signature="QApplication(int &amp;, char **, QApplication::Type, int)">
5048 <remove/>
5048 <remove/>
5049 5049 </modify-function>
5050 5050 <modify-function signature="QApplication(int &amp;, char **, bool, int)">
5051 <remove/>
5051 <remove/>
5052 5052 </modify-function>
5053 5053
5054 5054 <modify-function signature="font(const char*)">
General Comments 0
You need to be logged in to leave comments. Login now