Mercurial > projects > qtd
annotate generator/cppheadergenerator.cpp @ 259:515d6e1c7b10 lifetime
another iteration
author | maxter |
---|---|
date | Thu, 17 Sep 2009 16:28:41 +0000 |
parents | 17b5e13364b7 |
children | b5773ccab07d |
rev | line source |
---|---|
1 | 1 /**************************************************************************** |
2 ** | |
3 ** Copyright (C) 1992-2008 Nokia. All rights reserved. | |
4 ** | |
5 ** This file is part of Qt Jambi. | |
6 ** | |
7 ** * Commercial Usage | |
8 * Licensees holding valid Qt Commercial licenses may use this file in | |
9 * accordance with the Qt Commercial License Agreement provided with the | |
10 * Software or, alternatively, in accordance with the terms contained in | |
11 * a written agreement between you and Nokia. | |
12 * | |
13 * | |
14 * GNU General Public License Usage | |
15 * Alternatively, this file may be used under the terms of the GNU | |
16 * General Public License versions 2.0 or 3.0 as published by the Free | |
17 * Software Foundation and appearing in the file LICENSE.GPL included in | |
18 * the packaging of this file. Please review the following information | |
19 * to ensure GNU General Public Licensing requirements will be met: | |
20 * http://www.fsf.org/licensing/licenses/info/GPLv2.html and | |
21 * http://www.gnu.org/copyleft/gpl.html. In addition, as a special | |
22 * exception, Nokia gives you certain additional rights. These rights | |
23 * are described in the Nokia Qt GPL Exception version 1.2, included in | |
24 * the file GPL_EXCEPTION.txt in this package. | |
25 * | |
26 * Qt for Windows(R) Licensees | |
27 * As a special exception, Nokia, as the sole copyright holder for Qt | |
28 * Designer, grants users of the Qt/Eclipse Integration plug-in the | |
29 * right for the Qt/Eclipse Integration to link to functionality | |
30 * provided by Qt Designer and its related libraries. | |
31 * | |
32 * | |
33 * If you are unsure which license is appropriate for your use, please | |
34 * contact the sales department at qt-sales@nokia.com. | |
35 | |
36 ** | |
37 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | |
38 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
39 ** | |
40 ****************************************************************************/ | |
41 | |
42 #include "cppheadergenerator.h" | |
43 | |
44 #include <QtCore/QDir> | |
45 | |
46 #include <qdebug.h> | |
259 | 47 #include <iostream> |
1 | 48 |
49 QString CppHeaderGenerator::fileNameForClass(const AbstractMetaClass *java_class) const | |
50 { | |
51 return QString("%1_shell.h").arg(java_class->name()); | |
52 } | |
53 | |
54 void CppHeaderGenerator::writeFieldAccessors(QTextStream &s, const AbstractMetaField *java_field) | |
55 { | |
56 Q_ASSERT(java_field->isProtected()); | |
57 | |
58 const AbstractMetaFunction *setter = java_field->setter(); | |
59 const AbstractMetaFunction *getter = java_field->getter(); | |
60 | |
61 // qtd2 | |
62 if(notWrappedYet(getter)) | |
63 return; | |
64 | |
65 if (getter->isModifiedRemoved(TypeSystem::ShellCode)) | |
66 return; | |
67 | |
68 s << " "; | |
69 writeFunctionSignature(s, getter, 0, QString(), Option(ShowStatic)); | |
70 s << ";" << endl; | |
71 | |
72 // qtd2 | |
73 if(notWrappedYet(setter)) | |
74 return; | |
75 | |
76 if (!java_field->type()->isConstant()) { | |
77 if (setter->isModifiedRemoved(TypeSystem::ShellCode)) | |
78 return; | |
79 | |
80 s << " "; | |
81 writeFunctionSignature(s, setter, 0, QString(), Option(ShowStatic)); | |
82 s << ";" << endl; | |
83 } | |
84 } | |
85 | |
86 void CppHeaderGenerator::writeSignalWrapper(QTextStream &s, const AbstractMetaFunction *signal) | |
87 { | |
88 s << " "; | |
89 writeFunctionSignature(s, signal, 0, signalWrapperPrefix(), | |
90 Option(NormalizeAndFixTypeSignature | OriginalName | OriginalTypeDescription | IncludeDefaultExpression)); | |
91 s << ";" << endl; | |
92 } | |
93 | |
94 void CppHeaderGenerator::writeSignalWrappers(QTextStream &s, const AbstractMetaClass *java_class) | |
95 { | |
96 AbstractMetaFunctionList signal_funcs = signalFunctions(java_class); | |
97 if (signal_funcs.size() > 0) { | |
98 s << endl << "public slots:" << endl; | |
99 foreach (const AbstractMetaFunction *signal, signal_funcs) { | |
100 writeSignalWrapper(s, signal); | |
101 } | |
102 } | |
103 } | |
104 | |
105 void CppHeaderGenerator::writeWrapperClass(QTextStream &s, const AbstractMetaClass *java_class) | |
106 { | |
107 AbstractMetaFunctionList signal_functions = | |
108 java_class->queryFunctions(AbstractMetaClass::Signals | AbstractMetaClass::Visible | AbstractMetaClass::NotRemovedFromTargetLang); | |
109 if (signal_functions.size() == 0) | |
110 return ; | |
111 | |
112 s << "class QtJambi_SignalWrapper_" << java_class->name() << ": public QObject" << endl | |
113 << "{" << endl | |
114 << " Q_OBJECT" << endl; | |
115 writeSignalWrappers(s, java_class); | |
116 s << endl << "public:" << endl | |
117 << " QtJambiSignalInfo m_signals[" << signal_functions.size() << "];" << endl | |
118 << " QtJambiLink *link;" << endl | |
119 << "};" << endl << endl; | |
120 } | |
121 | |
122 void CppHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *java_class) | |
123 { | |
124 QString include_block = java_class->name().toUpper() + "_SHELL_H"; | |
125 | |
126 s << "#ifndef " << include_block << endl | |
127 << "#define " << include_block << endl << endl | |
128 // << "#include <qtjambi_core.h>" << endl | |
129 << "#include <QtCore/QHash>" << endl | |
257 | 130 << "#include <qtd_core.h>" << endl; |
1 | 131 |
132 Include inc = java_class->typeEntry()->include(); | |
133 s << "#include "; | |
134 if (inc.type == Include::IncludePath) | |
135 s << "<"; | |
136 else | |
137 s << "\""; | |
138 s << inc.name; | |
139 if (inc.type == Include::IncludePath) | |
140 s << ">"; | |
141 else | |
142 s << "\""; | |
143 s << endl << endl; | |
144 | |
145 IncludeList list = java_class->typeEntry()->extraIncludes(); | |
146 qSort(list.begin(), list.end()); | |
147 foreach (const Include &inc, list) { | |
148 if (inc.type == Include::TargetLangImport) | |
149 continue; | |
150 | |
151 s << "#include "; | |
152 if (inc.type == Include::LocalPath) | |
153 s << "\""; | |
154 else | |
155 s << "<"; | |
156 | |
157 s << inc.name; | |
158 | |
159 if (inc.type == Include::LocalPath) | |
160 s << "\""; | |
161 else | |
162 s << ">"; | |
163 | |
164 s << endl; | |
165 } | |
166 | |
167 /* qtd writeForwardDeclareSection(s, java_class); | |
168 | |
169 writeWrapperClass(s, java_class); | |
170 */ | |
171 s << endl; | |
238 | 172 |
1 | 173 |
174 if (!java_class->generateShellClass()) { | |
175 s << "#endif" << endl << endl; | |
238 | 176 priGenerator->addHeader(java_class->package(), fileNameForClass(java_class)); |
1 | 177 return ; |
178 } | |
259 | 179 |
180 if (java_class->name() == "QFSFileEngine") | |
181 { | |
182 std::cout << java_class->typeEntry()->isObject() << std::endl; | |
183 std::cout << java_class->hasVirtualDestructor() << std::endl; | |
184 qFatal("Bo"); | |
185 } | |
1 | 186 |
187 s << "class " << shellClassName(java_class) | |
188 << " : public " << java_class->qualifiedCppName(); | |
254 | 189 if (java_class->isQObject()) |
190 s << ", public QtD_QObjectEntity"; | |
259 | 191 else if (java_class->hasVirtualDestructor()) |
254 | 192 s << ", public QtD_Entity"; |
1 | 193 s << endl << "{" << endl; |
194 | |
195 if (java_class->isQObject()) { | |
196 s << "public:" << endl | |
254 | 197 << " Q_OBJECT_CHECK" << endl |
1 | 198 // << " mutable const QMetaObject *m_meta_object;" << endl; |
199 | |
200 /* if (java_class->hasVirtualSlots()) { | |
201 s << " mutable QHash<int,int> m_map;" << endl; | |
202 } | |
203 */ | |
105
3aa118a9ae71
each QObject now has associated child QObject for handling signals. fixes #15
eldar
parents:
21
diff
changeset
|
204 // s << " const QMetaObject *metaObject() const;" << endl |
1 | 205 // << " void *qt_metacast(const char *);" << endl |
254 | 206 // << " QT_TR_FUNCTIONS" << end |
207 << " virtual int qt_metacall(QMetaObject::Call, int, void **);" << endl | |
208 << "private:" << endl; | |
1 | 209 } |
210 | |
211 | |
212 s << "public:" << endl; | |
213 // constructor | |
214 foreach (const AbstractMetaFunction *function, java_class->functions()) { | |
215 if (function->isConstructor() && !function->isPrivate()) | |
216 writeFunction(s, function); | |
217 } | |
257 | 218 |
259 | 219 if (java_class->typeEntry()->isObject() && java_class->hasVirtualDestructor()) |
257 | 220 s << " ~" << shellClassName(java_class) << "();" << endl << endl; |
221 | |
1 | 222 |
223 // All functions in original class that should be reimplemented in shell class | |
224 AbstractMetaFunctionList shell_functions = java_class->functionsInShellClass(); | |
225 foreach (const AbstractMetaFunction *function, shell_functions) { | |
226 if(notWrappedYet(function)) | |
227 continue; | |
228 writeFunction(s, function); | |
229 } | |
230 | |
231 // Public call throughs for protected functions | |
232 AbstractMetaFunctionList public_overrides = java_class->publicOverrideFunctions(); | |
233 foreach (const AbstractMetaFunction *function, public_overrides) { | |
234 if(notWrappedYet(function)) | |
235 continue; | |
236 writePublicFunctionOverride(s, function); | |
237 } | |
238 | |
239 // Override all virtual functions to get the decision on static/virtual call | |
240 AbstractMetaFunctionList virtual_functions = java_class->virtualOverrideFunctions(); | |
241 foreach (const AbstractMetaFunction *function, virtual_functions) { | |
242 if(notWrappedYet(function)) | |
243 continue; | |
244 | |
245 writeVirtualFunctionOverride(s, function); | |
246 } | |
247 | |
248 // Field accessors | |
249 foreach (const AbstractMetaField *field, java_class->fields()) { | |
250 if (field->isProtected()) | |
251 writeFieldAccessors(s, field); | |
252 } | |
253 /* qtd | |
254 writeVariablesSection(s, java_class); | |
255 */ | |
256 writeInjectedCode(s, java_class); | |
257 | |
258 s << "};" << endl << endl | |
259 << "#endif // " << include_block << endl; | |
260 | |
238 | 261 priGenerator->addHeader(java_class->package(), fileNameForClass(java_class)); |
262 priGenerator->addClass(java_class->package(), java_class->name()); | |
1 | 263 } |
264 | |
265 | |
266 /*! | |
267 Writes out declarations of virtual C++ functions so that they | |
268 can be reimplemented from the java side. | |
269 */ | |
270 void CppHeaderGenerator::writeFunction(QTextStream &s, const AbstractMetaFunction *java_function) | |
271 { | |
272 if (java_function->isModifiedRemoved(TypeSystem::ShellCode)) | |
273 return; | |
274 | |
275 s << " "; | |
276 writeFunctionSignature(s, java_function, 0, QString(), Option(OriginalName | ShowStatic)); | |
277 s << ";" << endl; | |
278 } | |
279 | |
280 void CppHeaderGenerator::writePublicFunctionOverride(QTextStream &s, | |
281 const AbstractMetaFunction *java_function) | |
282 { | |
283 s << " "; | |
284 writeFunctionSignature(s, java_function, 0, "__public_", Option(EnumAsInts | ShowStatic | UnderscoreSpaces)); | |
285 s << ";" << endl; | |
286 } | |
287 | |
288 | |
289 void CppHeaderGenerator::writeVirtualFunctionOverride(QTextStream &s, | |
290 const AbstractMetaFunction *java_function) | |
291 { | |
292 if (java_function->isModifiedRemoved(TypeSystem::NativeCode)) | |
293 return; | |
294 | |
295 s << " "; | |
21 | 296 writeFunctionSignature(s, java_function, 0, "__override_", Option(EnumAsInts | ShowStatic | UnderscoreSpaces), QString(), QStringList() << "bool static_call"); |
1 | 297 s << ";" << endl; |
298 } | |
299 | |
300 | |
301 void CppHeaderGenerator::writeForwardDeclareSection(QTextStream &s, const AbstractMetaClass *) | |
302 { | |
303 s << endl | |
304 << "class QtJambiFunctionTable;" << endl | |
305 << "class QtJambiLink;" << endl; | |
306 } | |
307 | |
308 | |
309 void CppHeaderGenerator::writeVariablesSection(QTextStream &s, const AbstractMetaClass *) | |
310 { | |
311 s << endl | |
312 << " QtJambiFunctionTable *m_vtable;" << endl | |
313 << " QtJambiLink *m_link;" << endl; | |
314 } | |
315 | |
316 void CppHeaderGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *java_class) | |
317 { | |
318 CodeSnipList code_snips = java_class->typeEntry()->codeSnips(); | |
319 foreach (const CodeSnip &cs, code_snips) { | |
320 if (cs.language == TypeSystem::ShellDeclaration) { | |
321 s << cs.code() << endl; | |
322 } | |
323 } | |
324 } |