##// END OF EJS Templates
added support for global binary arithmetic operators...
florianlink -
r74:489aa998d2ad
parent child
Show More
@@ -1,2555 +1,2600
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 "abstractmetabuilder.h"
24 #include "abstractmetabuilder.h"
25 #include "reporthandler.h"
25 #include "reporthandler.h"
26
26
27 #include "ast.h"
27 #include "ast.h"
28 #include "binder.h"
28 #include "binder.h"
29 #include "control.h"
29 #include "control.h"
30 #include "default_visitor.h"
30 #include "default_visitor.h"
31 #include "dumptree.h"
31 #include "dumptree.h"
32 #include "lexer.h"
32 #include "lexer.h"
33 #include "parser.h"
33 #include "parser.h"
34 #include "tokens.h"
34 #include "tokens.h"
35
35
36 #include <QtCore/QDebug>
36 #include <QtCore/QDebug>
37 #include <QtCore/QFile>
37 #include <QtCore/QFile>
38 #include <QtCore/QFileInfo>
38 #include <QtCore/QFileInfo>
39 #include <QtCore/QTextCodec>
39 #include <QtCore/QTextCodec>
40 #include <QtCore/QTextStream>
40 #include <QtCore/QTextStream>
41 #include <QtCore/QVariant>
41 #include <QtCore/QVariant>
42
42
43 static QString strip_template_args(const QString &name)
43 static QString strip_template_args(const QString &name)
44 {
44 {
45 int pos = name.indexOf('<');
45 int pos = name.indexOf('<');
46 return pos < 0 ? name : name.left(pos);
46 return pos < 0 ? name : name.left(pos);
47 }
47 }
48
48
49 static QHash<QString, QString> *operator_names;
49 static QHash<QString, QString> *operator_names;
50 QString rename_operator(const QString &oper)
50 QString rename_operator(const QString &oper)
51 {
51 {
52 QString op = oper.trimmed();
52 QString op = oper.trimmed();
53 if (!operator_names) {
53 if (!operator_names) {
54 operator_names = new QHash<QString, QString>;
54 operator_names = new QHash<QString, QString>;
55
55
56 operator_names->insert("+", "add");
56 operator_names->insert("+", "add");
57 operator_names->insert("-", "subtract");
57 operator_names->insert("-", "subtract");
58 operator_names->insert("*", "multiply");
58 operator_names->insert("*", "multiply");
59 operator_names->insert("/", "divide");
59 operator_names->insert("/", "divide");
60 operator_names->insert("%", "modulo");
60 operator_names->insert("%", "modulo");
61 operator_names->insert("&", "and");
61 operator_names->insert("&", "and");
62 operator_names->insert("|", "or");
62 operator_names->insert("|", "or");
63 operator_names->insert("^", "xor");
63 operator_names->insert("^", "xor");
64 operator_names->insert("~", "negate");
64 operator_names->insert("~", "negate");
65 operator_names->insert("<<", "shift_left");
65 operator_names->insert("<<", "shift_left");
66 operator_names->insert(">>", "shift_right");
66 operator_names->insert(">>", "shift_right");
67
67
68 // assigments
68 // assigments
69 operator_names->insert("=", "assign");
69 operator_names->insert("=", "assign");
70 operator_names->insert("+=", "add_assign");
70 operator_names->insert("+=", "add_assign");
71 operator_names->insert("-=", "subtract_assign");
71 operator_names->insert("-=", "subtract_assign");
72 operator_names->insert("*=", "multiply_assign");
72 operator_names->insert("*=", "multiply_assign");
73 operator_names->insert("/=", "divide_assign");
73 operator_names->insert("/=", "divide_assign");
74 operator_names->insert("%=", "modulo_assign");
74 operator_names->insert("%=", "modulo_assign");
75 operator_names->insert("&=", "and_assign");
75 operator_names->insert("&=", "and_assign");
76 operator_names->insert("|=", "or_assign");
76 operator_names->insert("|=", "or_assign");
77 operator_names->insert("^=", "xor_assign");
77 operator_names->insert("^=", "xor_assign");
78 operator_names->insert("<<=", "shift_left_assign");
78 operator_names->insert("<<=", "shift_left_assign");
79 operator_names->insert(">>=", "shift_right_assign");
79 operator_names->insert(">>=", "shift_right_assign");
80
80
81 // Logical
81 // Logical
82 operator_names->insert("&&", "logical_and");
82 operator_names->insert("&&", "logical_and");
83 operator_names->insert("||", "logical_or");
83 operator_names->insert("||", "logical_or");
84 operator_names->insert("!", "not");
84 operator_names->insert("!", "not");
85
85
86 // incr/decr
86 // incr/decr
87 operator_names->insert("++", "increment");
87 operator_names->insert("++", "increment");
88 operator_names->insert("--", "decrement");
88 operator_names->insert("--", "decrement");
89
89
90 // compare
90 // compare
91 operator_names->insert("<", "less");
91 operator_names->insert("<", "less");
92 operator_names->insert(">", "greater");
92 operator_names->insert(">", "greater");
93 operator_names->insert("<=", "less_or_equal");
93 operator_names->insert("<=", "less_or_equal");
94 operator_names->insert(">=", "greater_or_equal");
94 operator_names->insert(">=", "greater_or_equal");
95 operator_names->insert("!=", "not_equal");
95 operator_names->insert("!=", "not_equal");
96 operator_names->insert("==", "equal");
96 operator_names->insert("==", "equal");
97
97
98 // other
98 // other
99 operator_names->insert("[]", "subscript");
99 operator_names->insert("[]", "subscript");
100 operator_names->insert("->", "pointer");
100 operator_names->insert("->", "pointer");
101 }
101 }
102
102
103 if (!operator_names->contains(op)) {
103 if (!operator_names->contains(op)) {
104 TypeDatabase *tb = TypeDatabase::instance();
104 TypeDatabase *tb = TypeDatabase::instance();
105
105
106 TypeParser::Info typeInfo = TypeParser::parse(op);
106 TypeParser::Info typeInfo = TypeParser::parse(op);
107 QString cast_to_name = typeInfo.qualified_name.join("::");
107 QString cast_to_name = typeInfo.qualified_name.join("::");
108 TypeEntry *te = tb->findType(cast_to_name);
108 TypeEntry *te = tb->findType(cast_to_name);
109 if ((te && te->codeGeneration() == TypeEntry::GenerateNothing)
109 if ((te && te->codeGeneration() == TypeEntry::GenerateNothing)
110 || tb->isClassRejected(cast_to_name)) {
110 || tb->isClassRejected(cast_to_name)) {
111 return QString();
111 return QString();
112 } else if (te) {
112 } else if (te) {
113 return "operator_cast_" + typeInfo.qualified_name.join("_");
113 return "operator_cast_" + typeInfo.qualified_name.join("_");
114 } else {
114 } else {
115 ReportHandler::warning(QString("unknown operator '%1'").arg(op));
115 ReportHandler::warning(QString("unknown operator '%1'").arg(op));
116 return "operator " + op;
116 return "operator " + op;
117 }
117 }
118 }
118 }
119
119
120 return "operator_" + operator_names->value(op);
120 return "operator_" + operator_names->value(op);
121 }
121 }
122
122
123 AbstractMetaBuilder::AbstractMetaBuilder()
123 AbstractMetaBuilder::AbstractMetaBuilder()
124 : m_current_class(0)
124 : m_current_class(0)
125 {
125 {
126 }
126 }
127
127
128 void AbstractMetaBuilder::checkFunctionModifications()
128 void AbstractMetaBuilder::checkFunctionModifications()
129 {
129 {
130 TypeDatabase *types = TypeDatabase::instance();
130 TypeDatabase *types = TypeDatabase::instance();
131 SingleTypeEntryHash entryHash = types->entries();
131 SingleTypeEntryHash entryHash = types->entries();
132 QList<TypeEntry *> entries = entryHash.values();
132 QList<TypeEntry *> entries = entryHash.values();
133 foreach (TypeEntry *entry, entries) {
133 foreach (TypeEntry *entry, entries) {
134 if (entry == 0)
134 if (entry == 0)
135 continue;
135 continue;
136 if (!entry->isComplex() || entry->codeGeneration() == TypeEntry::GenerateNothing)
136 if (!entry->isComplex() || entry->codeGeneration() == TypeEntry::GenerateNothing)
137 continue;
137 continue;
138
138
139 ComplexTypeEntry *centry = static_cast<ComplexTypeEntry *>(entry);
139 ComplexTypeEntry *centry = static_cast<ComplexTypeEntry *>(entry);
140 FunctionModificationList modifications = centry->functionModifications();
140 FunctionModificationList modifications = centry->functionModifications();
141
141
142 foreach (FunctionModification modification, modifications) {
142 foreach (FunctionModification modification, modifications) {
143 QString signature = modification.signature;
143 QString signature = modification.signature;
144
144
145 QString name = signature.trimmed();
145 QString name = signature.trimmed();
146 name = name.mid(0, signature.indexOf("("));
146 name = name.mid(0, signature.indexOf("("));
147
147
148 AbstractMetaClass *clazz = m_meta_classes.findClass(centry->qualifiedCppName());
148 AbstractMetaClass *clazz = m_meta_classes.findClass(centry->qualifiedCppName());
149 if (clazz == 0)
149 if (clazz == 0)
150 continue;
150 continue;
151
151
152 AbstractMetaFunctionList functions = clazz->functions();
152 AbstractMetaFunctionList functions = clazz->functions();
153 bool found = false;
153 bool found = false;
154 QStringList possibleSignatures;
154 QStringList possibleSignatures;
155 foreach (AbstractMetaFunction *function, functions) {
155 foreach (AbstractMetaFunction *function, functions) {
156 if (function->minimalSignature() == signature && function->implementingClass() == clazz) {
156 if (function->minimalSignature() == signature && function->implementingClass() == clazz) {
157 found = true;
157 found = true;
158 break;
158 break;
159 }
159 }
160
160
161 if (function->originalName() == name)
161 if (function->originalName() == name)
162 possibleSignatures.append(function->minimalSignature() + " in " + function->implementingClass()->name());
162 possibleSignatures.append(function->minimalSignature() + " in " + function->implementingClass()->name());
163 }
163 }
164
164
165 if (!found) {
165 if (!found) {
166 QString warning
166 QString warning
167 = QString("signature '%1' for function modification in '%2' not found. Possible candidates: %3")
167 = QString("signature '%1' for function modification in '%2' not found. Possible candidates: %3")
168 .arg(signature)
168 .arg(signature)
169 .arg(clazz->qualifiedCppName())
169 .arg(clazz->qualifiedCppName())
170 .arg(possibleSignatures.join(", "));
170 .arg(possibleSignatures.join(", "));
171
171
172 ReportHandler::warning(warning);
172 ReportHandler::warning(warning);
173 }
173 }
174 }
174 }
175 }
175 }
176 }
176 }
177
177
178 AbstractMetaClass *AbstractMetaBuilder::argumentToClass(ArgumentModelItem argument)
178 AbstractMetaClass *AbstractMetaBuilder::argumentToClass(ArgumentModelItem argument)
179 {
179 {
180 AbstractMetaClass *returned = 0;
180 AbstractMetaClass *returned = 0;
181 bool ok = false;
181 bool ok = false;
182 AbstractMetaType *type = translateType(argument->type(), &ok);
182 AbstractMetaType *type = translateType(argument->type(), &ok);
183 if (ok && type != 0 && type->typeEntry() != 0 && type->typeEntry()->isComplex()) {
183 if (ok && type != 0 && type->typeEntry() != 0 && type->typeEntry()->isComplex()) {
184 const TypeEntry *entry = type->typeEntry();
184 const TypeEntry *entry = type->typeEntry();
185 returned = m_meta_classes.findClass(entry->name());
185 returned = m_meta_classes.findClass(entry->name());
186 }
186 }
187 delete type;
187 delete type;
188 return returned;
188 return returned;
189 }
189 }
190
190
191 /**
191 /**
192 * Checks the argument of a hash function and flags the type if it is a complex type
192 * Checks the argument of a hash function and flags the type if it is a complex type
193 */
193 */
194 void AbstractMetaBuilder::registerHashFunction(FunctionModelItem function_item)
194 void AbstractMetaBuilder::registerHashFunction(FunctionModelItem function_item)
195 {
195 {
196 ArgumentList arguments = function_item->arguments();
196 ArgumentList arguments = function_item->arguments();
197 if (arguments.size() == 1) {
197 if (arguments.size() == 1) {
198 if (AbstractMetaClass *cls = argumentToClass(arguments.at(0)))
198 if (AbstractMetaClass *cls = argumentToClass(arguments.at(0)))
199 cls->setHasHashFunction(true);
199 cls->setHasHashFunction(true);
200 }
200 }
201 }
201 }
202
202
203 /**
203 /**
204 * Check if a class has a debug stream operator that can be used as toString
204 * Check if a class has a debug stream operator that can be used as toString
205 */
205 */
206
206
207 void AbstractMetaBuilder::registerToStringCapability(FunctionModelItem function_item)
207 void AbstractMetaBuilder::registerToStringCapability(FunctionModelItem function_item)
208 {
208 {
209 ArgumentList arguments = function_item->arguments();
209 ArgumentList arguments = function_item->arguments();
210 if (arguments.size() == 2) {
210 if (arguments.size() == 2) {
211 if (arguments.at(0)->type().toString() == "QDebug"){
211 if (arguments.at(0)->type().toString() == "QDebug"){
212 ArgumentModelItem arg = arguments.at(1);
212 ArgumentModelItem arg = arguments.at(1);
213 if (AbstractMetaClass *cls = argumentToClass(arg)) {
213 if (AbstractMetaClass *cls = argumentToClass(arg)) {
214 if (arg->type().indirections() < 2) {
214 if (arg->type().indirections() < 2) {
215 cls->setToStringCapability(function_item);
215 cls->setToStringCapability(function_item);
216 }
216 }
217 }
217 }
218 }
218 }
219 }
219 }
220 }
220 }
221
221
222 void AbstractMetaBuilder::traverseCompareOperator(FunctionModelItem item) {
222 void AbstractMetaBuilder::traverseCompareOperator(FunctionModelItem item) {
223 ArgumentList arguments = item->arguments();
223 ArgumentList arguments = item->arguments();
224 if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) {
224 if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) {
225 AbstractMetaClass *comparer_class = argumentToClass(arguments.at(0));
225 AbstractMetaClass *comparer_class = argumentToClass(arguments.at(0));
226 AbstractMetaClass *compared_class = argumentToClass(arguments.at(1));
226 AbstractMetaClass *compared_class = argumentToClass(arguments.at(1));
227 if (comparer_class != 0 && compared_class != 0) {
227 if (comparer_class != 0 && compared_class != 0) {
228 AbstractMetaClass *old_current_class = m_current_class;
228 AbstractMetaClass *old_current_class = m_current_class;
229 m_current_class = comparer_class;
229 m_current_class = comparer_class;
230
230
231 AbstractMetaFunction *meta_function = traverseFunction(item);
231 AbstractMetaFunction *meta_function = traverseFunction(item);
232 if (meta_function != 0 && !meta_function->isInvalid()) {
232 if (meta_function != 0 && !meta_function->isInvalid()) {
233 // Strip away first argument, since that is the containing object
233 // Strip away first argument, since that is the containing object
234 AbstractMetaArgumentList arguments = meta_function->arguments();
234 AbstractMetaArgumentList arguments = meta_function->arguments();
235 arguments.pop_front();
235 arguments.pop_front();
236 meta_function->setArguments(arguments);
236 meta_function->setArguments(arguments);
237
237
238 meta_function->setFunctionType(AbstractMetaFunction::GlobalScopeFunction);
238 meta_function->setFunctionType(AbstractMetaFunction::GlobalScopeFunction);
239
239
240 meta_function->setOriginalAttributes(meta_function->attributes());
240 meta_function->setOriginalAttributes(meta_function->attributes());
241 setupFunctionDefaults(meta_function, comparer_class);
241 setupFunctionDefaults(meta_function, comparer_class);
242
242
243 comparer_class->addFunction(meta_function);
243 comparer_class->addFunction(meta_function);
244 } else if (meta_function != 0) {
244 } else if (meta_function != 0) {
245 delete meta_function;
245 delete meta_function;
246 }
246 }
247
247
248 m_current_class = old_current_class;
248 m_current_class = old_current_class;
249 }
249 }
250 }
250 }
251 }
251 }
252
252
253 void AbstractMetaBuilder::traverseStreamOperator(FunctionModelItem item)
253 void AbstractMetaBuilder::traverseStreamOperator(FunctionModelItem item)
254 {
254 {
255 ArgumentList arguments = item->arguments();
255 ArgumentList arguments = item->arguments();
256 if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) {
256 if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) {
257 AbstractMetaClass *streamClass = argumentToClass(arguments.at(0));
257 AbstractMetaClass *streamClass = argumentToClass(arguments.at(0));
258 AbstractMetaClass *streamedClass = argumentToClass(arguments.at(1));
258 AbstractMetaClass *streamedClass = argumentToClass(arguments.at(1));
259
259
260 if (streamClass != 0 && streamedClass != 0
260 if (streamClass != 0 && streamedClass != 0
261 && (streamClass->name() == "QDataStream" || streamClass->name() == "QTextStream")) {
261 && (streamClass->name() == "QDataStream" || streamClass->name() == "QTextStream")) {
262 AbstractMetaClass *old_current_class = m_current_class;
262 AbstractMetaClass *old_current_class = m_current_class;
263 m_current_class = streamedClass;
263 m_current_class = streamedClass;
264 AbstractMetaFunction *streamFunction = traverseFunction(item);
264 AbstractMetaFunction *streamFunction = traverseFunction(item);
265
265
266 if (streamFunction != 0 && !streamFunction->isInvalid()) {
266 if (streamFunction != 0 && !streamFunction->isInvalid()) {
267 QString name = item->name();
267 QString name = item->name();
268 streamFunction->setFunctionType(AbstractMetaFunction::GlobalScopeFunction);
268 streamFunction->setFunctionType(AbstractMetaFunction::GlobalScopeFunction);
269
269
270 if (name.endsWith("<<"))
270 if (name.endsWith("<<"))
271 streamFunction->setName("writeTo");
271 streamFunction->setName("writeTo");
272 else
272 else
273 streamFunction->setName("readFrom");
273 streamFunction->setName("readFrom");
274
274
275 // Strip away last argument, since that is the containing object
275 // Strip away last argument, since that is the containing object
276 AbstractMetaArgumentList arguments = streamFunction->arguments();
276 AbstractMetaArgumentList arguments = streamFunction->arguments();
277 arguments.pop_back();
277 arguments.pop_back();
278 streamFunction->setArguments(arguments);
278 streamFunction->setArguments(arguments);
279
279
280 *streamFunction += AbstractMetaAttributes::Final;
280 *streamFunction += AbstractMetaAttributes::Final;
281 *streamFunction += AbstractMetaAttributes::Public;
281 *streamFunction += AbstractMetaAttributes::Public;
282 streamFunction->setOriginalAttributes(streamFunction->attributes());
282 streamFunction->setOriginalAttributes(streamFunction->attributes());
283
283
284 streamFunction->setType(0);
284 streamFunction->setType(0);
285
285
286 setupFunctionDefaults(streamFunction, streamedClass);
286 setupFunctionDefaults(streamFunction, streamedClass);
287
287
288 streamedClass->addFunction(streamFunction);
288 streamedClass->addFunction(streamFunction);
289 streamedClass->typeEntry()->addExtraInclude(streamClass->typeEntry()->include());
289 streamedClass->typeEntry()->addExtraInclude(streamClass->typeEntry()->include());
290
290
291 m_current_class = old_current_class;
291 m_current_class = old_current_class;
292 }
292 }
293 }
293 }
294 }
294 }
295 }
295 }
296
296
297 void AbstractMetaBuilder::traverseBinaryArithmeticOperator(FunctionModelItem item)
298 {
299 ArgumentList arguments = item->arguments();
300 if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) {
301 AbstractMetaClass *aClass = argumentToClass(arguments.at(0));
302 AbstractMetaClass *bClass = argumentToClass(arguments.at(1));
303
304 if (!aClass) return;
305
306 AbstractMetaClass *old_current_class = m_current_class;
307 m_current_class = aClass;
308 AbstractMetaFunction *streamFunction = traverseFunction(item);
309 if (streamFunction != 0 && !streamFunction->isInvalid()) {
310 QString name = rename_operator(item->name().mid(8));
311 if (name.isEmpty()) return;
312
313 streamFunction->setFunctionType(AbstractMetaFunction::GlobalScopeFunction);
314 streamFunction->setName(name);
315
316 // Strip away the first argument, since that is the operator object
317 AbstractMetaArgumentList arguments = streamFunction->arguments();
318 arguments.removeFirst();
319 streamFunction->setArguments(arguments);
320
321 *streamFunction += AbstractMetaAttributes::Final;
322 *streamFunction += AbstractMetaAttributes::Public;
323 streamFunction->setOriginalAttributes(streamFunction->attributes());
324
325 setupFunctionDefaults(streamFunction, aClass);
326
327 aClass->addFunction(streamFunction);
328 if (bClass) {
329 aClass->typeEntry()->addExtraInclude(bClass->typeEntry()->include());
330 }
331
332 m_current_class = old_current_class;
333 }
334 }
335 }
336
297 void AbstractMetaBuilder::fixQObjectForScope(TypeDatabase *types,
337 void AbstractMetaBuilder::fixQObjectForScope(TypeDatabase *types,
298 NamespaceModelItem scope)
338 NamespaceModelItem scope)
299 {
339 {
300 foreach (ClassModelItem item, scope->classes()) {
340 foreach (ClassModelItem item, scope->classes()) {
301 QString qualified_name = item->qualifiedName().join("::");
341 QString qualified_name = item->qualifiedName().join("::");
302 TypeEntry *entry = types->findType(qualified_name);
342 TypeEntry *entry = types->findType(qualified_name);
303 if (entry) {
343 if (entry) {
304 if (isQObject(qualified_name) && entry->isComplex()) {
344 if (isQObject(qualified_name) && entry->isComplex()) {
305 ((ComplexTypeEntry *) entry)->setQObject(true);
345 ((ComplexTypeEntry *) entry)->setQObject(true);
306 }
346 }
307 }
347 }
308 }
348 }
309
349
310 foreach (NamespaceModelItem item, scope->namespaceMap().values()) {
350 foreach (NamespaceModelItem item, scope->namespaceMap().values()) {
311 if (scope != item)
351 if (scope != item)
312 fixQObjectForScope(types, item);
352 fixQObjectForScope(types, item);
313 }
353 }
314 }
354 }
315
355
316 static bool class_less_than(AbstractMetaClass *a, AbstractMetaClass *b)
356 static bool class_less_than(AbstractMetaClass *a, AbstractMetaClass *b)
317 {
357 {
318 return a->name() < b->name();
358 return a->name() < b->name();
319 }
359 }
320
360
321
361
322 void AbstractMetaBuilder::sortLists()
362 void AbstractMetaBuilder::sortLists()
323 {
363 {
324 qSort(m_meta_classes.begin(), m_meta_classes.end(), class_less_than);
364 qSort(m_meta_classes.begin(), m_meta_classes.end(), class_less_than);
325 foreach (AbstractMetaClass *cls, m_meta_classes) {
365 foreach (AbstractMetaClass *cls, m_meta_classes) {
326 cls->sortFunctions();
366 cls->sortFunctions();
327 }
367 }
328 }
368 }
329
369
330 bool AbstractMetaBuilder::build()
370 bool AbstractMetaBuilder::build()
331 {
371 {
332 Q_ASSERT(!m_file_name.isEmpty());
372 Q_ASSERT(!m_file_name.isEmpty());
333
373
334 QFile file(m_file_name);
374 QFile file(m_file_name);
335
375
336 if (!file.open(QFile::ReadOnly))
376 if (!file.open(QFile::ReadOnly))
337 return false;
377 return false;
338
378
339 QTextStream stream(&file);
379 QTextStream stream(&file);
340 stream.setCodec(QTextCodec::codecForName("UTF-8"));
380 stream.setCodec(QTextCodec::codecForName("UTF-8"));
341 QByteArray contents = stream.readAll().toUtf8();
381 QByteArray contents = stream.readAll().toUtf8();
342 file.close();
382 file.close();
343
383
344 Control control;
384 Control control;
345 Parser p(&control);
385 Parser p(&control);
346 pool __pool;
386 pool __pool;
347
387
348 TranslationUnitAST *ast = p.parse(contents, contents.size(), &__pool);
388 TranslationUnitAST *ast = p.parse(contents, contents.size(), &__pool);
349
389
350 CodeModel model;
390 CodeModel model;
351 Binder binder(&model, p.location());
391 Binder binder(&model, p.location());
352 m_dom = binder.run(ast);
392 m_dom = binder.run(ast);
353
393
354 pushScope(model_dynamic_cast<ScopeModelItem>(m_dom));
394 pushScope(model_dynamic_cast<ScopeModelItem>(m_dom));
355
395
356 QHash<QString, ClassModelItem> typeMap = m_dom->classMap();
396 QHash<QString, ClassModelItem> typeMap = m_dom->classMap();
357
397
358
398
359 // fix up QObject's in the type system..
399 // fix up QObject's in the type system..
360 TypeDatabase *types = TypeDatabase::instance();
400 TypeDatabase *types = TypeDatabase::instance();
361 fixQObjectForScope(types, model_dynamic_cast<NamespaceModelItem>(m_dom));
401 fixQObjectForScope(types, model_dynamic_cast<NamespaceModelItem>(m_dom));
362
402
363
403
364 // Start the generation...
404 // Start the generation...
365 foreach (ClassModelItem item, typeMap.values()) {
405 foreach (ClassModelItem item, typeMap.values()) {
366 AbstractMetaClass *cls = traverseClass(item);
406 AbstractMetaClass *cls = traverseClass(item);
367 addAbstractMetaClass(cls);
407 addAbstractMetaClass(cls);
368 }
408 }
369
409
370
410
371 QHash<QString, NamespaceModelItem> namespaceMap = m_dom->namespaceMap();
411 QHash<QString, NamespaceModelItem> namespaceMap = m_dom->namespaceMap();
372 foreach (NamespaceModelItem item, namespaceMap.values()) {
412 foreach (NamespaceModelItem item, namespaceMap.values()) {
373 AbstractMetaClass *meta_class = traverseNamespace(item);
413 AbstractMetaClass *meta_class = traverseNamespace(item);
374 if (meta_class)
414 if (meta_class)
375 m_meta_classes << meta_class;
415 m_meta_classes << meta_class;
376 }
416 }
377
417
378
418
379 // Some trickery to support global-namespace enums...
419 // Some trickery to support global-namespace enums...
380 QHash<QString, EnumModelItem> enumMap = m_dom->enumMap();
420 QHash<QString, EnumModelItem> enumMap = m_dom->enumMap();
381 m_current_class = 0;
421 m_current_class = 0;
382 foreach (EnumModelItem item, enumMap) {
422 foreach (EnumModelItem item, enumMap) {
383 AbstractMetaEnum *meta_enum = traverseEnum(item, 0, QSet<QString>());
423 AbstractMetaEnum *meta_enum = traverseEnum(item, 0, QSet<QString>());
384
424
385 if (meta_enum) {
425 if (meta_enum) {
386 QString package = meta_enum->typeEntry()->javaPackage();
426 QString package = meta_enum->typeEntry()->javaPackage();
387 QString globalName = TypeDatabase::globalNamespaceClassName(meta_enum->typeEntry());
427 QString globalName = TypeDatabase::globalNamespaceClassName(meta_enum->typeEntry());
388
428
389 AbstractMetaClass *global = m_meta_classes.findClass(package + "." + globalName);
429 AbstractMetaClass *global = m_meta_classes.findClass(package + "." + globalName);
390 if (!global) {
430 if (!global) {
391 ComplexTypeEntry *gte = new ObjectTypeEntry(globalName);
431 ComplexTypeEntry *gte = new ObjectTypeEntry(globalName);
392 gte->setTargetLangPackage(meta_enum->typeEntry()->javaPackage());
432 gte->setTargetLangPackage(meta_enum->typeEntry()->javaPackage());
393 gte->setCodeGeneration(meta_enum->typeEntry()->codeGeneration());
433 gte->setCodeGeneration(meta_enum->typeEntry()->codeGeneration());
394 global = createMetaClass();
434 global = createMetaClass();
395 global->setTypeEntry(gte);
435 global->setTypeEntry(gte);
396 *global += AbstractMetaAttributes::Final;
436 *global += AbstractMetaAttributes::Final;
397 *global += AbstractMetaAttributes::Public;
437 *global += AbstractMetaAttributes::Public;
398 *global += AbstractMetaAttributes::Fake;
438 *global += AbstractMetaAttributes::Fake;
399
439
400 m_meta_classes << global;
440 m_meta_classes << global;
401 }
441 }
402
442
403 global->addEnum(meta_enum);
443 global->addEnum(meta_enum);
404 meta_enum->setEnclosingClass(global);
444 meta_enum->setEnclosingClass(global);
405 meta_enum->typeEntry()->setQualifier(globalName);
445 meta_enum->typeEntry()->setQualifier(globalName);
406 }
446 }
407
447
408
448
409 }
449 }
410
450
411
451
412 // Go through all typedefs to see if we have defined any
452 // Go through all typedefs to see if we have defined any
413 // specific typedefs to be used as classes.
453 // specific typedefs to be used as classes.
414 TypeAliasList typeAliases = m_dom->typeAliases();
454 TypeAliasList typeAliases = m_dom->typeAliases();
415 foreach (TypeAliasModelItem typeAlias, typeAliases) {
455 foreach (TypeAliasModelItem typeAlias, typeAliases) {
416 AbstractMetaClass *cls = traverseTypeAlias(typeAlias);
456 AbstractMetaClass *cls = traverseTypeAlias(typeAlias);
417 addAbstractMetaClass(cls);
457 addAbstractMetaClass(cls);
418 }
458 }
419
459
420
460
421
461
422
462
423 foreach (AbstractMetaClass *cls, m_meta_classes) {
463 foreach (AbstractMetaClass *cls, m_meta_classes) {
424 if (!cls->isInterface() && !cls->isNamespace()) {
464 if (!cls->isInterface() && !cls->isNamespace()) {
425 setupInheritance(cls);
465 setupInheritance(cls);
426 }
466 }
427 }
467 }
428
468
429
469
430 foreach (AbstractMetaClass *cls, m_meta_classes) {
470 foreach (AbstractMetaClass *cls, m_meta_classes) {
431 cls->fixFunctions();
471 cls->fixFunctions();
432
472
433 if (cls->typeEntry() == 0) {
473 if (cls->typeEntry() == 0) {
434 ReportHandler::warning(QString("class '%1' does not have an entry in the type system")
474 ReportHandler::warning(QString("class '%1' does not have an entry in the type system")
435 .arg(cls->name()));
475 .arg(cls->name()));
436 } else {
476 } else {
437 if (!cls->hasConstructors() && !cls->isFinalInCpp() && !cls->isInterface() && !cls->isNamespace())
477 if (!cls->hasConstructors() && !cls->isFinalInCpp() && !cls->isInterface() && !cls->isNamespace())
438 cls->addDefaultConstructor();
478 cls->addDefaultConstructor();
439 }
479 }
440
480
441 if (cls->isAbstract() && !cls->isInterface()) {
481 if (cls->isAbstract() && !cls->isInterface()) {
442 cls->typeEntry()->setLookupName(cls->typeEntry()->targetLangName() + "$ConcreteWrapper");
482 cls->typeEntry()->setLookupName(cls->typeEntry()->targetLangName() + "$ConcreteWrapper");
443 }
483 }
444 }
484 }
445
485
446 QList<TypeEntry *> entries = TypeDatabase::instance()->entries().values();
486 QList<TypeEntry *> entries = TypeDatabase::instance()->entries().values();
447 foreach (const TypeEntry *entry, entries) {
487 foreach (const TypeEntry *entry, entries) {
448 if (entry->isPrimitive())
488 if (entry->isPrimitive())
449 continue;
489 continue;
450
490
451 if ((entry->isValue() || entry->isObject())
491 if ((entry->isValue() || entry->isObject())
452 && !entry->isString()
492 && !entry->isString()
453 && !entry->isChar()
493 && !entry->isChar()
454 && !entry->isContainer()
494 && !entry->isContainer()
455 && !entry->isCustom()
495 && !entry->isCustom()
456 && !entry->isVariant()
496 && !entry->isVariant()
457 && !m_meta_classes.findClass(entry->qualifiedCppName())) {
497 && !m_meta_classes.findClass(entry->qualifiedCppName())) {
458 ReportHandler::warning(QString("type '%1' is specified in typesystem, but not defined. This could potentially lead to compilation errors.")
498 ReportHandler::warning(QString("type '%1' is specified in typesystem, but not defined. This could potentially lead to compilation errors.")
459 .arg(entry->qualifiedCppName()));
499 .arg(entry->qualifiedCppName()));
460 }
500 }
461
501
462 if (entry->isEnum()) {
502 if (entry->isEnum()) {
463 QString pkg = entry->javaPackage();
503 QString pkg = entry->javaPackage();
464 QString name = (pkg.isEmpty() ? QString() : pkg + ".")
504 QString name = (pkg.isEmpty() ? QString() : pkg + ".")
465 + ((EnumTypeEntry *) entry)->javaQualifier();
505 + ((EnumTypeEntry *) entry)->javaQualifier();
466 AbstractMetaClass *cls = m_meta_classes.findClass(name);
506 AbstractMetaClass *cls = m_meta_classes.findClass(name);
467
507
468 if (!cls) {
508 if (!cls) {
469 ReportHandler::warning(QString("namespace '%1' for enum '%2' is not declared")
509 ReportHandler::warning(QString("namespace '%1' for enum '%2' is not declared")
470 .arg(name).arg(entry->targetLangName()));
510 .arg(name).arg(entry->targetLangName()));
471 } else {
511 } else {
472 AbstractMetaEnum *e = cls->findEnum(entry->targetLangName());
512 AbstractMetaEnum *e = cls->findEnum(entry->targetLangName());
473 if (!e)
513 if (!e)
474 ReportHandler::warning(QString("enum '%1' is specified in typesystem, "
514 ReportHandler::warning(QString("enum '%1' is specified in typesystem, "
475 "but not declared")
515 "but not declared")
476 .arg(entry->qualifiedCppName()));
516 .arg(entry->qualifiedCppName()));
477 }
517 }
478 }
518 }
479 }
519 }
480
520
481 {
521 {
482 FunctionList hash_functions = m_dom->findFunctions("qHash");
522 FunctionList hash_functions = m_dom->findFunctions("qHash");
483 foreach (FunctionModelItem item, hash_functions) {
523 foreach (FunctionModelItem item, hash_functions) {
484 registerHashFunction(item);
524 registerHashFunction(item);
485 }
525 }
486 }
526 }
487
527
488 {
528 {
489 FunctionList hash_functions = m_dom->findFunctions("operator<<");
529 FunctionList hash_functions = m_dom->findFunctions("operator<<");
490 foreach (FunctionModelItem item, hash_functions) {
530 foreach (FunctionModelItem item, hash_functions) {
491 registerToStringCapability(item);
531 registerToStringCapability(item);
492 }
532 }
493 }
533 }
494
534
495 {
535 {
496 FunctionList compare_operators = m_dom->findFunctions("operator==")
536 FunctionList compare_operators = m_dom->findFunctions("operator==")
497 + m_dom->findFunctions("operator<=")
537 + m_dom->findFunctions("operator<=")
498 + m_dom->findFunctions("operator>=")
538 + m_dom->findFunctions("operator>=")
499 + m_dom->findFunctions("operator<")
539 + m_dom->findFunctions("operator<")
500 + m_dom->findFunctions("operator>");
540 + m_dom->findFunctions("operator>");
501 foreach (FunctionModelItem item, compare_operators) {
541 foreach (FunctionModelItem item, compare_operators) {
502 traverseCompareOperator(item);
542 traverseCompareOperator(item);
503 }
543 }
504 }
544 }
505 // TODO XXX search and add operator+ etc. to the classes here!
506
545
507 {
546 {
547 FunctionList stream_operators = m_dom->findFunctions("operator+") + m_dom->findFunctions("operator-") + m_dom->findFunctions("operator/") + m_dom->findFunctions("operator*");
548 foreach (FunctionModelItem item, stream_operators) {
549 traverseBinaryArithmeticOperator(item);
550 }
551 }
552 {
508 FunctionList stream_operators = m_dom->findFunctions("operator<<") + m_dom->findFunctions("operator>>");
553 FunctionList stream_operators = m_dom->findFunctions("operator<<") + m_dom->findFunctions("operator>>");
509 foreach (FunctionModelItem item, stream_operators) {
554 foreach (FunctionModelItem item, stream_operators) {
510 traverseStreamOperator(item);
555 traverseStreamOperator(item);
511 }
556 }
512 }
557 }
513
558
514 figureOutEnumValues();
559 figureOutEnumValues();
515 figureOutDefaultEnumArguments();
560 figureOutDefaultEnumArguments();
516 checkFunctionModifications();
561 checkFunctionModifications();
517
562
518 foreach (AbstractMetaClass *cls, m_meta_classes) {
563 foreach (AbstractMetaClass *cls, m_meta_classes) {
519 setupEquals(cls);
564 setupEquals(cls);
520 setupComparable(cls);
565 setupComparable(cls);
521 setupClonable(cls);
566 setupClonable(cls);
522 }
567 }
523
568
524 dumpLog();
569 dumpLog();
525
570
526 sortLists();
571 sortLists();
527
572
528 return true;
573 return true;
529 }
574 }
530
575
531
576
532 void AbstractMetaBuilder::addAbstractMetaClass(AbstractMetaClass *cls)
577 void AbstractMetaBuilder::addAbstractMetaClass(AbstractMetaClass *cls)
533 {
578 {
534 if (!cls)
579 if (!cls)
535 return;
580 return;
536
581
537 cls->setOriginalAttributes(cls->attributes());
582 cls->setOriginalAttributes(cls->attributes());
538 if (cls->typeEntry()->isContainer()) {
583 if (cls->typeEntry()->isContainer()) {
539 m_templates << cls;
584 m_templates << cls;
540 } else {
585 } else {
541 m_meta_classes << cls;
586 m_meta_classes << cls;
542 if (cls->typeEntry()->designatedInterface()) {
587 if (cls->typeEntry()->designatedInterface()) {
543 AbstractMetaClass *interface = cls->extractInterface();
588 AbstractMetaClass *interface = cls->extractInterface();
544 m_meta_classes << interface;
589 m_meta_classes << interface;
545 ReportHandler::debugSparse(QString(" -> interface '%1'").arg(interface->name()));
590 ReportHandler::debugSparse(QString(" -> interface '%1'").arg(interface->name()));
546 }
591 }
547 }
592 }
548 }
593 }
549
594
550
595
551 AbstractMetaClass *AbstractMetaBuilder::traverseNamespace(NamespaceModelItem namespace_item)
596 AbstractMetaClass *AbstractMetaBuilder::traverseNamespace(NamespaceModelItem namespace_item)
552 {
597 {
553 QString namespace_name = (!m_namespace_prefix.isEmpty() ? m_namespace_prefix + "::" : QString()) + namespace_item->name();
598 QString namespace_name = (!m_namespace_prefix.isEmpty() ? m_namespace_prefix + "::" : QString()) + namespace_item->name();
554 NamespaceTypeEntry *type = TypeDatabase::instance()->findNamespaceType(namespace_name);
599 NamespaceTypeEntry *type = TypeDatabase::instance()->findNamespaceType(namespace_name);
555
600
556 if (TypeDatabase::instance()->isClassRejected(namespace_name)) {
601 if (TypeDatabase::instance()->isClassRejected(namespace_name)) {
557 m_rejected_classes.insert(namespace_name, GenerationDisabled);
602 m_rejected_classes.insert(namespace_name, GenerationDisabled);
558 return 0;
603 return 0;
559 }
604 }
560
605
561 if (!type) {
606 if (!type) {
562 ReportHandler::warning(QString("namespace '%1' does not have a type entry")
607 ReportHandler::warning(QString("namespace '%1' does not have a type entry")
563 .arg(namespace_name));
608 .arg(namespace_name));
564 return 0;
609 return 0;
565 }
610 }
566
611
567 AbstractMetaClass *meta_class = createMetaClass();
612 AbstractMetaClass *meta_class = createMetaClass();
568 meta_class->setTypeEntry(type);
613 meta_class->setTypeEntry(type);
569
614
570 *meta_class += AbstractMetaAttributes::Public;
615 *meta_class += AbstractMetaAttributes::Public;
571
616
572 m_current_class = meta_class;
617 m_current_class = meta_class;
573
618
574 ReportHandler::debugSparse(QString("namespace '%1.%2'")
619 ReportHandler::debugSparse(QString("namespace '%1.%2'")
575 .arg(meta_class->package())
620 .arg(meta_class->package())
576 .arg(namespace_item->name()));
621 .arg(namespace_item->name()));
577
622
578 traverseEnums(model_dynamic_cast<ScopeModelItem>(namespace_item), meta_class, namespace_item->enumsDeclarations());
623 traverseEnums(model_dynamic_cast<ScopeModelItem>(namespace_item), meta_class, namespace_item->enumsDeclarations());
579 traverseFunctions(model_dynamic_cast<ScopeModelItem>(namespace_item), meta_class);
624 traverseFunctions(model_dynamic_cast<ScopeModelItem>(namespace_item), meta_class);
580 // traverseClasses(model_dynamic_cast<ScopeModelItem>(namespace_item));
625 // traverseClasses(model_dynamic_cast<ScopeModelItem>(namespace_item));
581
626
582 pushScope(model_dynamic_cast<ScopeModelItem>(namespace_item));
627 pushScope(model_dynamic_cast<ScopeModelItem>(namespace_item));
583 m_namespace_prefix = currentScope()->qualifiedName().join("::");
628 m_namespace_prefix = currentScope()->qualifiedName().join("::");
584
629
585
630
586 ClassList classes = namespace_item->classes();
631 ClassList classes = namespace_item->classes();
587 foreach (ClassModelItem cls, classes) {
632 foreach (ClassModelItem cls, classes) {
588 AbstractMetaClass *mjc = traverseClass(cls);
633 AbstractMetaClass *mjc = traverseClass(cls);
589 addAbstractMetaClass(mjc);
634 addAbstractMetaClass(mjc);
590 }
635 }
591
636
592 // Go through all typedefs to see if we have defined any
637 // Go through all typedefs to see if we have defined any
593 // specific typedefs to be used as classes.
638 // specific typedefs to be used as classes.
594 TypeAliasList typeAliases = namespace_item->typeAliases();
639 TypeAliasList typeAliases = namespace_item->typeAliases();
595 foreach (TypeAliasModelItem typeAlias, typeAliases) {
640 foreach (TypeAliasModelItem typeAlias, typeAliases) {
596 AbstractMetaClass *cls = traverseTypeAlias(typeAlias);
641 AbstractMetaClass *cls = traverseTypeAlias(typeAlias);
597 addAbstractMetaClass(cls);
642 addAbstractMetaClass(cls);
598 }
643 }
599
644
600
645
601
646
602 // Traverse namespaces recursively
647 // Traverse namespaces recursively
603 QList<NamespaceModelItem> inner_namespaces = namespace_item->namespaceMap().values();
648 QList<NamespaceModelItem> inner_namespaces = namespace_item->namespaceMap().values();
604 foreach (const NamespaceModelItem &ni, inner_namespaces) {
649 foreach (const NamespaceModelItem &ni, inner_namespaces) {
605 AbstractMetaClass *mjc = traverseNamespace(ni);
650 AbstractMetaClass *mjc = traverseNamespace(ni);
606 addAbstractMetaClass(mjc);
651 addAbstractMetaClass(mjc);
607 }
652 }
608
653
609 m_current_class = 0;
654 m_current_class = 0;
610
655
611
656
612 popScope();
657 popScope();
613 m_namespace_prefix = currentScope()->qualifiedName().join("::");
658 m_namespace_prefix = currentScope()->qualifiedName().join("::");
614
659
615 if (!type->include().isValid()) {
660 if (!type->include().isValid()) {
616 QFileInfo info(namespace_item->fileName());
661 QFileInfo info(namespace_item->fileName());
617 type->setInclude(Include(Include::IncludePath, info.fileName()));
662 type->setInclude(Include(Include::IncludePath, info.fileName()));
618 }
663 }
619
664
620 return meta_class;
665 return meta_class;
621 }
666 }
622
667
623 struct Operator
668 struct Operator
624 {
669 {
625 enum Type { Plus, ShiftLeft, None };
670 enum Type { Plus, ShiftLeft, None };
626
671
627 Operator() : type(None) { }
672 Operator() : type(None) { }
628
673
629 int calculate(int x) {
674 int calculate(int x) {
630 switch (type) {
675 switch (type) {
631 case Plus: return x + value;
676 case Plus: return x + value;
632 case ShiftLeft: return x << value;
677 case ShiftLeft: return x << value;
633 case None: return x;
678 case None: return x;
634 }
679 }
635 return x;
680 return x;
636 }
681 }
637
682
638 Type type;
683 Type type;
639 int value;
684 int value;
640 };
685 };
641
686
642
687
643
688
644 Operator findOperator(QString *s) {
689 Operator findOperator(QString *s) {
645 const char *names[] = {
690 const char *names[] = {
646 "+",
691 "+",
647 "<<"
692 "<<"
648 };
693 };
649
694
650 for (int i=0; i<Operator::None; ++i) {
695 for (int i=0; i<Operator::None; ++i) {
651 QString name = QLatin1String(names[i]);
696 QString name = QLatin1String(names[i]);
652 QString str = *s;
697 QString str = *s;
653 int splitPoint = str.indexOf(name);
698 int splitPoint = str.indexOf(name);
654 if (splitPoint > 0) {
699 if (splitPoint > 0) {
655 bool ok;
700 bool ok;
656 QString right = str.mid(splitPoint + name.length());
701 QString right = str.mid(splitPoint + name.length());
657 Operator op;
702 Operator op;
658 op.value = right.toInt(&ok);
703 op.value = right.toInt(&ok);
659 if (ok) {
704 if (ok) {
660 op.type = Operator::Type(i);
705 op.type = Operator::Type(i);
661 *s = str.left(splitPoint).trimmed();
706 *s = str.left(splitPoint).trimmed();
662 return op;
707 return op;
663 }
708 }
664 }
709 }
665 }
710 }
666 return Operator();
711 return Operator();
667 }
712 }
668
713
669 int AbstractMetaBuilder::figureOutEnumValue(const QString &stringValue,
714 int AbstractMetaBuilder::figureOutEnumValue(const QString &stringValue,
670 int oldValuevalue,
715 int oldValuevalue,
671 AbstractMetaEnum *meta_enum,
716 AbstractMetaEnum *meta_enum,
672 AbstractMetaFunction *meta_function)
717 AbstractMetaFunction *meta_function)
673 {
718 {
674 if (stringValue.isEmpty())
719 if (stringValue.isEmpty())
675 return oldValuevalue;
720 return oldValuevalue;
676
721
677 QStringList stringValues = stringValue.split("|");
722 QStringList stringValues = stringValue.split("|");
678
723
679 int returnValue = 0;
724 int returnValue = 0;
680
725
681 bool matched = false;
726 bool matched = false;
682
727
683 for (int i=0; i<stringValues.size(); ++i) {
728 for (int i=0; i<stringValues.size(); ++i) {
684 QString s = stringValues.at(i).trimmed();
729 QString s = stringValues.at(i).trimmed();
685
730
686 bool ok;
731 bool ok;
687 int v;
732 int v;
688
733
689 Operator op = findOperator(&s);
734 Operator op = findOperator(&s);
690
735
691 if (s.length() > 0 && s.at(0) == QLatin1Char('0'))
736 if (s.length() > 0 && s.at(0) == QLatin1Char('0'))
692 v = s.toUInt(&ok, 0);
737 v = s.toUInt(&ok, 0);
693 else
738 else
694 v = s.toInt(&ok);
739 v = s.toInt(&ok);
695
740
696 if (ok) {
741 if (ok) {
697 matched = true;
742 matched = true;
698
743
699 } else if (m_enum_values.contains(s)) {
744 } else if (m_enum_values.contains(s)) {
700 v = m_enum_values[s]->value();
745 v = m_enum_values[s]->value();
701 matched = true;
746 matched = true;
702
747
703 } else {
748 } else {
704 AbstractMetaEnumValue *ev = 0;
749 AbstractMetaEnumValue *ev = 0;
705
750
706 if (meta_enum && (ev = meta_enum->values().find(s))) {
751 if (meta_enum && (ev = meta_enum->values().find(s))) {
707 v = ev->value();
752 v = ev->value();
708 matched = true;
753 matched = true;
709
754
710 } else if (meta_enum && (ev = meta_enum->enclosingClass()->findEnumValue(s, meta_enum))) {
755 } else if (meta_enum && (ev = meta_enum->enclosingClass()->findEnumValue(s, meta_enum))) {
711 v = ev->value();
756 v = ev->value();
712 matched = true;
757 matched = true;
713
758
714 } else {
759 } else {
715 if (meta_enum)
760 if (meta_enum)
716 ReportHandler::warning("unhandled enum value: " + s + " in "
761 ReportHandler::warning("unhandled enum value: " + s + " in "
717 + meta_enum->enclosingClass()->name() + "::"
762 + meta_enum->enclosingClass()->name() + "::"
718 + meta_enum->name());
763 + meta_enum->name());
719 else
764 else
720 ReportHandler::warning("unhandled enum value: Unknown enum");
765 ReportHandler::warning("unhandled enum value: Unknown enum");
721 }
766 }
722 }
767 }
723
768
724 if (matched)
769 if (matched)
725 returnValue |= op.calculate(v);
770 returnValue |= op.calculate(v);
726 }
771 }
727
772
728 if (!matched) {
773 if (!matched) {
729 QString warn = QString("unmatched enum %1").arg(stringValue);
774 QString warn = QString("unmatched enum %1").arg(stringValue);
730
775
731 if (meta_function != 0) {
776 if (meta_function != 0) {
732 warn += QString(" when parsing default value of '%1' in class '%2'")
777 warn += QString(" when parsing default value of '%1' in class '%2'")
733 .arg(meta_function->name())
778 .arg(meta_function->name())
734 .arg(meta_function->implementingClass()->name());
779 .arg(meta_function->implementingClass()->name());
735 }
780 }
736
781
737 ReportHandler::warning(warn);
782 ReportHandler::warning(warn);
738 returnValue = oldValuevalue;
783 returnValue = oldValuevalue;
739 }
784 }
740
785
741 return returnValue;
786 return returnValue;
742 }
787 }
743
788
744 void AbstractMetaBuilder::figureOutEnumValuesForClass(AbstractMetaClass *meta_class,
789 void AbstractMetaBuilder::figureOutEnumValuesForClass(AbstractMetaClass *meta_class,
745 QSet<AbstractMetaClass *> *classes)
790 QSet<AbstractMetaClass *> *classes)
746 {
791 {
747 AbstractMetaClass *base = meta_class->baseClass();
792 AbstractMetaClass *base = meta_class->baseClass();
748
793
749 if (base != 0 && !classes->contains(base))
794 if (base != 0 && !classes->contains(base))
750 figureOutEnumValuesForClass(base, classes);
795 figureOutEnumValuesForClass(base, classes);
751
796
752 if (classes->contains(meta_class))
797 if (classes->contains(meta_class))
753 return;
798 return;
754
799
755 AbstractMetaEnumList enums = meta_class->enums();
800 AbstractMetaEnumList enums = meta_class->enums();
756 foreach (AbstractMetaEnum *e, enums) {
801 foreach (AbstractMetaEnum *e, enums) {
757 if (!e) {
802 if (!e) {
758 ReportHandler::warning("bad enum in class " + meta_class->name());
803 ReportHandler::warning("bad enum in class " + meta_class->name());
759 continue;
804 continue;
760 }
805 }
761 AbstractMetaEnumValueList lst = e->values();
806 AbstractMetaEnumValueList lst = e->values();
762 int value = 0;
807 int value = 0;
763 for (int i=0; i<lst.size(); ++i) {
808 for (int i=0; i<lst.size(); ++i) {
764 value = figureOutEnumValue(lst.at(i)->stringValue(), value, e);
809 value = figureOutEnumValue(lst.at(i)->stringValue(), value, e);
765 lst.at(i)->setValue(value);
810 lst.at(i)->setValue(value);
766 value++;
811 value++;
767 }
812 }
768
813
769 // Check for duplicate values...
814 // Check for duplicate values...
770 EnumTypeEntry *ete = e->typeEntry();
815 EnumTypeEntry *ete = e->typeEntry();
771 if (!ete->forceInteger()) {
816 if (!ete->forceInteger()) {
772 QHash<int, AbstractMetaEnumValue *> entries;
817 QHash<int, AbstractMetaEnumValue *> entries;
773 foreach (AbstractMetaEnumValue *v, lst) {
818 foreach (AbstractMetaEnumValue *v, lst) {
774
819
775 bool vRejected = ete->isEnumValueRejected(v->name());
820 bool vRejected = ete->isEnumValueRejected(v->name());
776
821
777 AbstractMetaEnumValue *current = entries.value(v->value());
822 AbstractMetaEnumValue *current = entries.value(v->value());
778 if (current) {
823 if (current) {
779 bool currentRejected = ete->isEnumValueRejected(current->name());
824 bool currentRejected = ete->isEnumValueRejected(current->name());
780 if (!currentRejected && !vRejected) {
825 if (!currentRejected && !vRejected) {
781 ReportHandler::warning(
826 ReportHandler::warning(
782 QString("duplicate enum values: %1::%2, %3 and %4 are %5, already rejected: (%6)")
827 QString("duplicate enum values: %1::%2, %3 and %4 are %5, already rejected: (%6)")
783 .arg(meta_class->name())
828 .arg(meta_class->name())
784 .arg(e->name())
829 .arg(e->name())
785 .arg(v->name())
830 .arg(v->name())
786 .arg(entries[v->value()]->name())
831 .arg(entries[v->value()]->name())
787 .arg(v->value())
832 .arg(v->value())
788 .arg(ete->enumValueRejections().join(", ")));
833 .arg(ete->enumValueRejections().join(", ")));
789 continue;
834 continue;
790 }
835 }
791 }
836 }
792
837
793 if (!vRejected)
838 if (!vRejected)
794 entries[v->value()] = v;
839 entries[v->value()] = v;
795 }
840 }
796
841
797 // Entries now contain all the original entries, no
842 // Entries now contain all the original entries, no
798 // rejected ones... Use this to generate the enumValueRedirection table.
843 // rejected ones... Use this to generate the enumValueRedirection table.
799 foreach (AbstractMetaEnumValue *reject, lst) {
844 foreach (AbstractMetaEnumValue *reject, lst) {
800 if (!ete->isEnumValueRejected(reject->name()))
845 if (!ete->isEnumValueRejected(reject->name()))
801 continue;
846 continue;
802
847
803 AbstractMetaEnumValue *used = entries.value(reject->value());
848 AbstractMetaEnumValue *used = entries.value(reject->value());
804 if (!used) {
849 if (!used) {
805 ReportHandler::warning(
850 ReportHandler::warning(
806 QString::fromLatin1("Rejected enum has no alternative...: %1::%2")
851 QString::fromLatin1("Rejected enum has no alternative...: %1::%2")
807 .arg(meta_class->name())
852 .arg(meta_class->name())
808 .arg(reject->name()));
853 .arg(reject->name()));
809 continue;
854 continue;
810 }
855 }
811 ete->addEnumValueRedirection(reject->name(), used->name());
856 ete->addEnumValueRedirection(reject->name(), used->name());
812 }
857 }
813
858
814 }
859 }
815 }
860 }
816
861
817
862
818
863
819 *classes += meta_class;
864 *classes += meta_class;
820 }
865 }
821
866
822
867
823 void AbstractMetaBuilder::figureOutEnumValues()
868 void AbstractMetaBuilder::figureOutEnumValues()
824 {
869 {
825 // Keep a set of classes that we already traversed. We use this to
870 // Keep a set of classes that we already traversed. We use this to
826 // enforce that we traverse base classes prior to subclasses.
871 // enforce that we traverse base classes prior to subclasses.
827 QSet<AbstractMetaClass *> classes;
872 QSet<AbstractMetaClass *> classes;
828 foreach (AbstractMetaClass *c, m_meta_classes) {
873 foreach (AbstractMetaClass *c, m_meta_classes) {
829 figureOutEnumValuesForClass(c, &classes);
874 figureOutEnumValuesForClass(c, &classes);
830 }
875 }
831 }
876 }
832
877
833 void AbstractMetaBuilder::figureOutDefaultEnumArguments()
878 void AbstractMetaBuilder::figureOutDefaultEnumArguments()
834 {
879 {
835 foreach (AbstractMetaClass *meta_class, m_meta_classes) {
880 foreach (AbstractMetaClass *meta_class, m_meta_classes) {
836 foreach (AbstractMetaFunction *meta_function, meta_class->functions()) {
881 foreach (AbstractMetaFunction *meta_function, meta_class->functions()) {
837 foreach (AbstractMetaArgument *arg, meta_function->arguments()) {
882 foreach (AbstractMetaArgument *arg, meta_function->arguments()) {
838
883
839 QString expr = arg->defaultValueExpression();
884 QString expr = arg->defaultValueExpression();
840 if (expr.isEmpty())
885 if (expr.isEmpty())
841 continue;
886 continue;
842
887
843 if (!meta_function->replacedDefaultExpression(meta_function->implementingClass(),
888 if (!meta_function->replacedDefaultExpression(meta_function->implementingClass(),
844 arg->argumentIndex()+1).isEmpty()) {
889 arg->argumentIndex()+1).isEmpty()) {
845 continue;
890 continue;
846 }
891 }
847
892
848 QString new_expr = expr;
893 QString new_expr = expr;
849 if (arg->type()->isEnum()) {
894 if (arg->type()->isEnum()) {
850 QStringList lst = expr.split(QLatin1String("::"));
895 QStringList lst = expr.split(QLatin1String("::"));
851 if (lst.size() == 1) {
896 if (lst.size() == 1) {
852 QVector<AbstractMetaClass *> classes(1, meta_class);
897 QVector<AbstractMetaClass *> classes(1, meta_class);
853 AbstractMetaEnum *e = 0;
898 AbstractMetaEnum *e = 0;
854 while (!classes.isEmpty() && e == 0) {
899 while (!classes.isEmpty() && e == 0) {
855 if (classes.front() != 0) {
900 if (classes.front() != 0) {
856 classes << classes.front()->baseClass();
901 classes << classes.front()->baseClass();
857
902
858 AbstractMetaClassList interfaces = classes.front()->interfaces();
903 AbstractMetaClassList interfaces = classes.front()->interfaces();
859 foreach (AbstractMetaClass *interface, interfaces)
904 foreach (AbstractMetaClass *interface, interfaces)
860 classes << interface->primaryInterfaceImplementor();
905 classes << interface->primaryInterfaceImplementor();
861
906
862 e = classes.front()->findEnumForValue(expr);
907 e = classes.front()->findEnumForValue(expr);
863 }
908 }
864
909
865 classes.pop_front();
910 classes.pop_front();
866 }
911 }
867
912
868 if (e != 0) {
913 if (e != 0) {
869 new_expr = QString("%1.%2")
914 new_expr = QString("%1.%2")
870 .arg(e->typeEntry()->qualifiedTargetLangName())
915 .arg(e->typeEntry()->qualifiedTargetLangName())
871 .arg(expr);
916 .arg(expr);
872 } else {
917 } else {
873 ReportHandler::warning("Cannot find enum constant for value '" + expr + "' in '" + meta_class->name() + "' or any of its super classes");
918 ReportHandler::warning("Cannot find enum constant for value '" + expr + "' in '" + meta_class->name() + "' or any of its super classes");
874 }
919 }
875 } else if (lst.size() == 2) {
920 } else if (lst.size() == 2) {
876 AbstractMetaClass *cl = m_meta_classes.findClass(lst.at(0));
921 AbstractMetaClass *cl = m_meta_classes.findClass(lst.at(0));
877 if (!cl) {
922 if (!cl) {
878 ReportHandler::warning("missing required class for enums: " + lst.at(0));
923 ReportHandler::warning("missing required class for enums: " + lst.at(0));
879 continue;
924 continue;
880 }
925 }
881 new_expr = QString("%1.%2.%3")
926 new_expr = QString("%1.%2.%3")
882 .arg(cl->typeEntry()->qualifiedTargetLangName())
927 .arg(cl->typeEntry()->qualifiedTargetLangName())
883 .arg(arg->type()->name())
928 .arg(arg->type()->name())
884 .arg(lst.at(1));
929 .arg(lst.at(1));
885 } else {
930 } else {
886 ReportHandler::warning("bad default value passed to enum " + expr);
931 ReportHandler::warning("bad default value passed to enum " + expr);
887 }
932 }
888
933
889 } else if(arg->type()->isFlags()) {
934 } else if(arg->type()->isFlags()) {
890 const FlagsTypeEntry *flagsEntry =
935 const FlagsTypeEntry *flagsEntry =
891 static_cast<const FlagsTypeEntry *>(arg->type()->typeEntry());
936 static_cast<const FlagsTypeEntry *>(arg->type()->typeEntry());
892 EnumTypeEntry *enumEntry = flagsEntry->originator();
937 EnumTypeEntry *enumEntry = flagsEntry->originator();
893 AbstractMetaEnum *meta_enum = m_meta_classes.findEnum(enumEntry);
938 AbstractMetaEnum *meta_enum = m_meta_classes.findEnum(enumEntry);
894 if (!meta_enum) {
939 if (!meta_enum) {
895 ReportHandler::warning("unknown required enum " + enumEntry->qualifiedCppName());
940 ReportHandler::warning("unknown required enum " + enumEntry->qualifiedCppName());
896 continue;
941 continue;
897 }
942 }
898
943
899 int value = figureOutEnumValue(expr, 0, meta_enum, meta_function);
944 int value = figureOutEnumValue(expr, 0, meta_enum, meta_function);
900 new_expr = QString::number(value);
945 new_expr = QString::number(value);
901
946
902 } else if (arg->type()->isPrimitive()) {
947 } else if (arg->type()->isPrimitive()) {
903 AbstractMetaEnumValue *value = 0;
948 AbstractMetaEnumValue *value = 0;
904 if (expr.contains("::"))
949 if (expr.contains("::"))
905 value = m_meta_classes.findEnumValue(expr);
950 value = m_meta_classes.findEnumValue(expr);
906 if (!value)
951 if (!value)
907 value = meta_class->findEnumValue(expr, 0);
952 value = meta_class->findEnumValue(expr, 0);
908
953
909 if (value) {
954 if (value) {
910 new_expr = QString::number(value->value());
955 new_expr = QString::number(value->value());
911 } else if (expr.contains(QLatin1Char('+'))) {
956 } else if (expr.contains(QLatin1Char('+'))) {
912 new_expr = QString::number(figureOutEnumValue(expr, 0, 0));
957 new_expr = QString::number(figureOutEnumValue(expr, 0, 0));
913
958
914 }
959 }
915
960
916
961
917
962
918 }
963 }
919
964
920 arg->setDefaultValueExpression(new_expr);
965 arg->setDefaultValueExpression(new_expr);
921 }
966 }
922 }
967 }
923 }
968 }
924 }
969 }
925
970
926
971
927 AbstractMetaEnum *AbstractMetaBuilder::traverseEnum(EnumModelItem enum_item, AbstractMetaClass *enclosing, const QSet<QString> &enumsDeclarations)
972 AbstractMetaEnum *AbstractMetaBuilder::traverseEnum(EnumModelItem enum_item, AbstractMetaClass *enclosing, const QSet<QString> &enumsDeclarations)
928 {
973 {
929 // Skipping private enums.
974 // Skipping private enums.
930 if (enum_item->accessPolicy() == CodeModel::Private) {
975 if (enum_item->accessPolicy() == CodeModel::Private) {
931 return 0;
976 return 0;
932 }
977 }
933
978
934 QString qualified_name = enum_item->qualifiedName().join("::");
979 QString qualified_name = enum_item->qualifiedName().join("::");
935
980
936 TypeEntry *type_entry = TypeDatabase::instance()->findType(qualified_name);
981 TypeEntry *type_entry = TypeDatabase::instance()->findType(qualified_name);
937 QString enum_name = enum_item->name();
982 QString enum_name = enum_item->name();
938
983
939 QString class_name;
984 QString class_name;
940 if (m_current_class)
985 if (m_current_class)
941 class_name = m_current_class->typeEntry()->qualifiedCppName();
986 class_name = m_current_class->typeEntry()->qualifiedCppName();
942
987
943 if (TypeDatabase::instance()->isEnumRejected(class_name, enum_name)) {
988 if (TypeDatabase::instance()->isEnumRejected(class_name, enum_name)) {
944 m_rejected_enums.insert(qualified_name, GenerationDisabled);
989 m_rejected_enums.insert(qualified_name, GenerationDisabled);
945 return 0;
990 return 0;
946 }
991 }
947
992
948 if (!type_entry || !type_entry->isEnum()) {
993 if (!type_entry || !type_entry->isEnum()) {
949 QString context = m_current_class ? m_current_class->name() : QLatin1String("");
994 QString context = m_current_class ? m_current_class->name() : QLatin1String("");
950 ReportHandler::warning(QString("enum '%1' does not have a type entry or is not an enum")
995 ReportHandler::warning(QString("enum '%1' does not have a type entry or is not an enum")
951 .arg(qualified_name));
996 .arg(qualified_name));
952 m_rejected_enums.insert(qualified_name, NotInTypeSystem);
997 m_rejected_enums.insert(qualified_name, NotInTypeSystem);
953 return 0;
998 return 0;
954 }
999 }
955
1000
956 AbstractMetaEnum *meta_enum = createMetaEnum();
1001 AbstractMetaEnum *meta_enum = createMetaEnum();
957 if ( enumsDeclarations.contains(qualified_name)
1002 if ( enumsDeclarations.contains(qualified_name)
958 || enumsDeclarations.contains(enum_name)) {
1003 || enumsDeclarations.contains(enum_name)) {
959 meta_enum->setHasQEnumsDeclaration(true);
1004 meta_enum->setHasQEnumsDeclaration(true);
960 }
1005 }
961
1006
962 meta_enum->setTypeEntry((EnumTypeEntry *) type_entry);
1007 meta_enum->setTypeEntry((EnumTypeEntry *) type_entry);
963 switch (enum_item->accessPolicy()) {
1008 switch (enum_item->accessPolicy()) {
964 case CodeModel::Public: *meta_enum += AbstractMetaAttributes::Public; break;
1009 case CodeModel::Public: *meta_enum += AbstractMetaAttributes::Public; break;
965 case CodeModel::Protected: *meta_enum += AbstractMetaAttributes::Protected; break;
1010 case CodeModel::Protected: *meta_enum += AbstractMetaAttributes::Protected; break;
966 // case CodeModel::Private: *meta_enum += AbstractMetaAttributes::Private; break;
1011 // case CodeModel::Private: *meta_enum += AbstractMetaAttributes::Private; break;
967 default: break;
1012 default: break;
968 }
1013 }
969
1014
970 ReportHandler::debugMedium(QString(" - traversing enum %1").arg(meta_enum->fullName()));
1015 ReportHandler::debugMedium(QString(" - traversing enum %1").arg(meta_enum->fullName()));
971
1016
972 foreach (EnumeratorModelItem value, enum_item->enumerators()) {
1017 foreach (EnumeratorModelItem value, enum_item->enumerators()) {
973
1018
974 AbstractMetaEnumValue *meta_enum_value = createMetaEnumValue();
1019 AbstractMetaEnumValue *meta_enum_value = createMetaEnumValue();
975 meta_enum_value->setName(value->name());
1020 meta_enum_value->setName(value->name());
976 // Deciding the enum value...
1021 // Deciding the enum value...
977
1022
978 meta_enum_value->setStringValue(value->value());
1023 meta_enum_value->setStringValue(value->value());
979 meta_enum->addEnumValue(meta_enum_value);
1024 meta_enum->addEnumValue(meta_enum_value);
980
1025
981 ReportHandler::debugFull(" - " + meta_enum_value->name() + " = "
1026 ReportHandler::debugFull(" - " + meta_enum_value->name() + " = "
982 + meta_enum_value->value());
1027 + meta_enum_value->value());
983
1028
984 // Add into global register...
1029 // Add into global register...
985 if (enclosing)
1030 if (enclosing)
986 m_enum_values[enclosing->name() + "::" + meta_enum_value->name()] = meta_enum_value;
1031 m_enum_values[enclosing->name() + "::" + meta_enum_value->name()] = meta_enum_value;
987 else
1032 else
988 m_enum_values[meta_enum_value->name()] = meta_enum_value;
1033 m_enum_values[meta_enum_value->name()] = meta_enum_value;
989 }
1034 }
990
1035
991 m_enums << meta_enum;
1036 m_enums << meta_enum;
992
1037
993 return meta_enum;
1038 return meta_enum;
994 }
1039 }
995
1040
996 AbstractMetaClass *AbstractMetaBuilder::traverseTypeAlias(TypeAliasModelItem typeAlias)
1041 AbstractMetaClass *AbstractMetaBuilder::traverseTypeAlias(TypeAliasModelItem typeAlias)
997 {
1042 {
998 QString class_name = strip_template_args(typeAlias->name());
1043 QString class_name = strip_template_args(typeAlias->name());
999
1044
1000 QString full_class_name = class_name;
1045 QString full_class_name = class_name;
1001 // we have an inner class
1046 // we have an inner class
1002 if (m_current_class) {
1047 if (m_current_class) {
1003 full_class_name = strip_template_args(m_current_class->typeEntry()->qualifiedCppName())
1048 full_class_name = strip_template_args(m_current_class->typeEntry()->qualifiedCppName())
1004 + "::" + full_class_name;
1049 + "::" + full_class_name;
1005 }
1050 }
1006
1051
1007 // If we haven't specified anything for the typedef, then we don't care
1052 // If we haven't specified anything for the typedef, then we don't care
1008 ComplexTypeEntry *type = TypeDatabase::instance()->findComplexType(full_class_name);
1053 ComplexTypeEntry *type = TypeDatabase::instance()->findComplexType(full_class_name);
1009 if (type == 0)
1054 if (type == 0)
1010 return 0;
1055 return 0;
1011
1056
1012 if (type->isObject())
1057 if (type->isObject())
1013 static_cast<ObjectTypeEntry *>(type)->setQObject(isQObject(strip_template_args(typeAlias->type().qualifiedName().join("::"))));
1058 static_cast<ObjectTypeEntry *>(type)->setQObject(isQObject(strip_template_args(typeAlias->type().qualifiedName().join("::"))));
1014
1059
1015 AbstractMetaClass *meta_class = createMetaClass();
1060 AbstractMetaClass *meta_class = createMetaClass();
1016 meta_class->setTypeAlias(true);
1061 meta_class->setTypeAlias(true);
1017 meta_class->setTypeEntry(type);
1062 meta_class->setTypeEntry(type);
1018 meta_class->setBaseClassNames(QStringList() << typeAlias->type().qualifiedName().join("::"));
1063 meta_class->setBaseClassNames(QStringList() << typeAlias->type().qualifiedName().join("::"));
1019 *meta_class += AbstractMetaAttributes::Public;
1064 *meta_class += AbstractMetaAttributes::Public;
1020
1065
1021 // Set the default include file name
1066 // Set the default include file name
1022 if (!type->include().isValid()) {
1067 if (!type->include().isValid()) {
1023 QFileInfo info(typeAlias->fileName());
1068 QFileInfo info(typeAlias->fileName());
1024 type->setInclude(Include(Include::IncludePath, info.fileName()));
1069 type->setInclude(Include(Include::IncludePath, info.fileName()));
1025 }
1070 }
1026
1071
1027 return meta_class;
1072 return meta_class;
1028 }
1073 }
1029
1074
1030 AbstractMetaClass *AbstractMetaBuilder::traverseClass(ClassModelItem class_item)
1075 AbstractMetaClass *AbstractMetaBuilder::traverseClass(ClassModelItem class_item)
1031 {
1076 {
1032 QString class_name = strip_template_args(class_item->name());
1077 QString class_name = strip_template_args(class_item->name());
1033 QString full_class_name = class_name;
1078 QString full_class_name = class_name;
1034
1079
1035 // we have inner an class
1080 // we have inner an class
1036 if (m_current_class) {
1081 if (m_current_class) {
1037 full_class_name = strip_template_args(m_current_class->typeEntry()->qualifiedCppName())
1082 full_class_name = strip_template_args(m_current_class->typeEntry()->qualifiedCppName())
1038 + "::" + full_class_name;
1083 + "::" + full_class_name;
1039 }
1084 }
1040
1085
1041 ComplexTypeEntry *type = TypeDatabase::instance()->findComplexType(full_class_name);
1086 ComplexTypeEntry *type = TypeDatabase::instance()->findComplexType(full_class_name);
1042 RejectReason reason = NoReason;
1087 RejectReason reason = NoReason;
1043
1088
1044 if (full_class_name == "QMetaTypeId") {
1089 if (full_class_name == "QMetaTypeId") {
1045 // QtScript: record which types have been declared
1090 // QtScript: record which types have been declared
1046 int lpos = class_item->name().indexOf('<');
1091 int lpos = class_item->name().indexOf('<');
1047 int rpos = class_item->name().lastIndexOf('>');
1092 int rpos = class_item->name().lastIndexOf('>');
1048 if ((lpos != -1) && (rpos != -1)) {
1093 if ((lpos != -1) && (rpos != -1)) {
1049 QString declared_typename = class_item->name().mid(lpos+1, rpos - lpos-1);
1094 QString declared_typename = class_item->name().mid(lpos+1, rpos - lpos-1);
1050 m_qmetatype_declared_typenames.insert(declared_typename);
1095 m_qmetatype_declared_typenames.insert(declared_typename);
1051 }
1096 }
1052 }
1097 }
1053
1098
1054 if (TypeDatabase::instance()->isClassRejected(full_class_name)) {
1099 if (TypeDatabase::instance()->isClassRejected(full_class_name)) {
1055 reason = GenerationDisabled;
1100 reason = GenerationDisabled;
1056 } else if (!type) {
1101 } else if (!type) {
1057 TypeEntry *te = TypeDatabase::instance()->findType(full_class_name);
1102 TypeEntry *te = TypeDatabase::instance()->findType(full_class_name);
1058 if (te && !te->isComplex())
1103 if (te && !te->isComplex())
1059 reason = RedefinedToNotClass;
1104 reason = RedefinedToNotClass;
1060 else
1105 else
1061 reason = NotInTypeSystem;
1106 reason = NotInTypeSystem;
1062 } else if (type->codeGeneration() == TypeEntry::GenerateNothing) {
1107 } else if (type->codeGeneration() == TypeEntry::GenerateNothing) {
1063 reason = GenerationDisabled;
1108 reason = GenerationDisabled;
1064 }
1109 }
1065
1110
1066 if (reason != NoReason) {
1111 if (reason != NoReason) {
1067 m_rejected_classes.insert(full_class_name, reason);
1112 m_rejected_classes.insert(full_class_name, reason);
1068 return 0;
1113 return 0;
1069 }
1114 }
1070
1115
1071 if (type->isObject()) {
1116 if (type->isObject()) {
1072 ((ObjectTypeEntry *)type)->setQObject(isQObject(full_class_name));
1117 ((ObjectTypeEntry *)type)->setQObject(isQObject(full_class_name));
1073 }
1118 }
1074
1119
1075 AbstractMetaClass *meta_class = createMetaClass();
1120 AbstractMetaClass *meta_class = createMetaClass();
1076 meta_class->setTypeEntry(type);
1121 meta_class->setTypeEntry(type);
1077 meta_class->setBaseClassNames(class_item->baseClasses());
1122 meta_class->setBaseClassNames(class_item->baseClasses());
1078 *meta_class += AbstractMetaAttributes::Public;
1123 *meta_class += AbstractMetaAttributes::Public;
1079
1124
1080 AbstractMetaClass *old_current_class = m_current_class;
1125 AbstractMetaClass *old_current_class = m_current_class;
1081 m_current_class = meta_class;
1126 m_current_class = meta_class;
1082
1127
1083 if (type->isContainer()) {
1128 if (type->isContainer()) {
1084 ReportHandler::debugSparse(QString("container: '%1'").arg(full_class_name));
1129 ReportHandler::debugSparse(QString("container: '%1'").arg(full_class_name));
1085 } else {
1130 } else {
1086 ReportHandler::debugSparse(QString("class: '%1'").arg(meta_class->fullName()));
1131 ReportHandler::debugSparse(QString("class: '%1'").arg(meta_class->fullName()));
1087 }
1132 }
1088
1133
1089 TemplateParameterList template_parameters = class_item->templateParameters();
1134 TemplateParameterList template_parameters = class_item->templateParameters();
1090 QList<TypeEntry *> template_args;
1135 QList<TypeEntry *> template_args;
1091 template_args.clear();
1136 template_args.clear();
1092 for (int i=0; i<template_parameters.size(); ++i) {
1137 for (int i=0; i<template_parameters.size(); ++i) {
1093 const TemplateParameterModelItem &param = template_parameters.at(i);
1138 const TemplateParameterModelItem &param = template_parameters.at(i);
1094 TemplateArgumentEntry *param_type = new TemplateArgumentEntry(param->name());
1139 TemplateArgumentEntry *param_type = new TemplateArgumentEntry(param->name());
1095 param_type->setOrdinal(i);
1140 param_type->setOrdinal(i);
1096 template_args.append(param_type);
1141 template_args.append(param_type);
1097 }
1142 }
1098 meta_class->setTemplateArguments(template_args);
1143 meta_class->setTemplateArguments(template_args);
1099
1144
1100 parseQ_Property(meta_class, class_item->propertyDeclarations());
1145 parseQ_Property(meta_class, class_item->propertyDeclarations());
1101
1146
1102 traverseFunctions(model_dynamic_cast<ScopeModelItem>(class_item), meta_class);
1147 traverseFunctions(model_dynamic_cast<ScopeModelItem>(class_item), meta_class);
1103 traverseEnums(model_dynamic_cast<ScopeModelItem>(class_item), meta_class, class_item->enumsDeclarations());
1148 traverseEnums(model_dynamic_cast<ScopeModelItem>(class_item), meta_class, class_item->enumsDeclarations());
1104 traverseFields(model_dynamic_cast<ScopeModelItem>(class_item), meta_class);
1149 traverseFields(model_dynamic_cast<ScopeModelItem>(class_item), meta_class);
1105
1150
1106 // Inner classes
1151 // Inner classes
1107 {
1152 {
1108 QList<ClassModelItem> inner_classes = class_item->classMap().values();
1153 QList<ClassModelItem> inner_classes = class_item->classMap().values();
1109 foreach (const ClassModelItem &ci, inner_classes) {
1154 foreach (const ClassModelItem &ci, inner_classes) {
1110 AbstractMetaClass *cl = traverseClass(ci);
1155 AbstractMetaClass *cl = traverseClass(ci);
1111 if (cl) {
1156 if (cl) {
1112 cl->setEnclosingClass(meta_class);
1157 cl->setEnclosingClass(meta_class);
1113 m_meta_classes << cl;
1158 m_meta_classes << cl;
1114 }
1159 }
1115 }
1160 }
1116
1161
1117 }
1162 }
1118
1163
1119 // Go through all typedefs to see if we have defined any
1164 // Go through all typedefs to see if we have defined any
1120 // specific typedefs to be used as classes.
1165 // specific typedefs to be used as classes.
1121 TypeAliasList typeAliases = class_item->typeAliases();
1166 TypeAliasList typeAliases = class_item->typeAliases();
1122 foreach (TypeAliasModelItem typeAlias, typeAliases) {
1167 foreach (TypeAliasModelItem typeAlias, typeAliases) {
1123 AbstractMetaClass *cls = traverseTypeAlias(typeAlias);
1168 AbstractMetaClass *cls = traverseTypeAlias(typeAlias);
1124 if (cls != 0) {
1169 if (cls != 0) {
1125 cls->setEnclosingClass(meta_class);
1170 cls->setEnclosingClass(meta_class);
1126 addAbstractMetaClass(cls);
1171 addAbstractMetaClass(cls);
1127 }
1172 }
1128 }
1173 }
1129
1174
1130
1175
1131 m_current_class = old_current_class;
1176 m_current_class = old_current_class;
1132
1177
1133 // Set the default include file name
1178 // Set the default include file name
1134 if (!type->include().isValid()) {
1179 if (!type->include().isValid()) {
1135 QFileInfo info(class_item->fileName());
1180 QFileInfo info(class_item->fileName());
1136 type->setInclude(Include(Include::IncludePath, info.fileName()));
1181 type->setInclude(Include(Include::IncludePath, info.fileName()));
1137 }
1182 }
1138
1183
1139 return meta_class;
1184 return meta_class;
1140 }
1185 }
1141
1186
1142 AbstractMetaField *AbstractMetaBuilder::traverseField(VariableModelItem field, const AbstractMetaClass *cls)
1187 AbstractMetaField *AbstractMetaBuilder::traverseField(VariableModelItem field, const AbstractMetaClass *cls)
1143 {
1188 {
1144 QString field_name = field->name();
1189 QString field_name = field->name();
1145 QString class_name = m_current_class->typeEntry()->qualifiedCppName();
1190 QString class_name = m_current_class->typeEntry()->qualifiedCppName();
1146
1191
1147 // Ignore friend decl.
1192 // Ignore friend decl.
1148 if (field->isFriend())
1193 if (field->isFriend())
1149 return 0;
1194 return 0;
1150
1195
1151 if (field->accessPolicy() == CodeModel::Private)
1196 if (field->accessPolicy() == CodeModel::Private)
1152 return 0;
1197 return 0;
1153
1198
1154 if (TypeDatabase::instance()->isFieldRejected(class_name, field_name)) {
1199 if (TypeDatabase::instance()->isFieldRejected(class_name, field_name)) {
1155 m_rejected_fields.insert(class_name + "::" + field_name, GenerationDisabled);
1200 m_rejected_fields.insert(class_name + "::" + field_name, GenerationDisabled);
1156 return 0;
1201 return 0;
1157 }
1202 }
1158
1203
1159
1204
1160 AbstractMetaField *meta_field = createMetaField();
1205 AbstractMetaField *meta_field = createMetaField();
1161 meta_field->setName(field_name);
1206 meta_field->setName(field_name);
1162 meta_field->setEnclosingClass(cls);
1207 meta_field->setEnclosingClass(cls);
1163
1208
1164 bool ok;
1209 bool ok;
1165 TypeInfo field_type = field->type();
1210 TypeInfo field_type = field->type();
1166 AbstractMetaType *meta_type = translateType(field_type, &ok);
1211 AbstractMetaType *meta_type = translateType(field_type, &ok);
1167
1212
1168 if (!meta_type || !ok) {
1213 if (!meta_type || !ok) {
1169 ReportHandler::warning(QString("skipping field '%1::%2' with unmatched type '%3'")
1214 ReportHandler::warning(QString("skipping field '%1::%2' with unmatched type '%3'")
1170 .arg(m_current_class->name())
1215 .arg(m_current_class->name())
1171 .arg(field_name)
1216 .arg(field_name)
1172 .arg(TypeInfo::resolveType(field_type, currentScope()->toItem()).qualifiedName().join("::")));
1217 .arg(TypeInfo::resolveType(field_type, currentScope()->toItem()).qualifiedName().join("::")));
1173 delete meta_field;
1218 delete meta_field;
1174 return 0;
1219 return 0;
1175 }
1220 }
1176
1221
1177 meta_field->setType(meta_type);
1222 meta_field->setType(meta_type);
1178
1223
1179 uint attr = 0;
1224 uint attr = 0;
1180 if (field->isStatic())
1225 if (field->isStatic())
1181 attr |= AbstractMetaAttributes::Static;
1226 attr |= AbstractMetaAttributes::Static;
1182
1227
1183 CodeModel::AccessPolicy policy = field->accessPolicy();
1228 CodeModel::AccessPolicy policy = field->accessPolicy();
1184 if (policy == CodeModel::Public)
1229 if (policy == CodeModel::Public)
1185 attr |= AbstractMetaAttributes::Public;
1230 attr |= AbstractMetaAttributes::Public;
1186 else if (policy == CodeModel::Protected)
1231 else if (policy == CodeModel::Protected)
1187 attr |= AbstractMetaAttributes::Protected;
1232 attr |= AbstractMetaAttributes::Protected;
1188 else
1233 else
1189 attr |= AbstractMetaAttributes::Private;
1234 attr |= AbstractMetaAttributes::Private;
1190 meta_field->setAttributes(attr);
1235 meta_field->setAttributes(attr);
1191
1236
1192 return meta_field;
1237 return meta_field;
1193 }
1238 }
1194
1239
1195 void AbstractMetaBuilder::traverseFields(ScopeModelItem scope_item, AbstractMetaClass *meta_class)
1240 void AbstractMetaBuilder::traverseFields(ScopeModelItem scope_item, AbstractMetaClass *meta_class)
1196 {
1241 {
1197 foreach (VariableModelItem field, scope_item->variables()) {
1242 foreach (VariableModelItem field, scope_item->variables()) {
1198 AbstractMetaField *meta_field = traverseField(field, meta_class);
1243 AbstractMetaField *meta_field = traverseField(field, meta_class);
1199
1244
1200 if (meta_field) {
1245 if (meta_field) {
1201 meta_field->setOriginalAttributes(meta_field->attributes());
1246 meta_field->setOriginalAttributes(meta_field->attributes());
1202 meta_class->addField(meta_field);
1247 meta_class->addField(meta_field);
1203 }
1248 }
1204 }
1249 }
1205 }
1250 }
1206
1251
1207 void AbstractMetaBuilder::setupFunctionDefaults(AbstractMetaFunction *meta_function, AbstractMetaClass *meta_class)
1252 void AbstractMetaBuilder::setupFunctionDefaults(AbstractMetaFunction *meta_function, AbstractMetaClass *meta_class)
1208 {
1253 {
1209 // Set the default value of the declaring class. This may be changed
1254 // Set the default value of the declaring class. This may be changed
1210 // in fixFunctions later on
1255 // in fixFunctions later on
1211 meta_function->setDeclaringClass(meta_class);
1256 meta_function->setDeclaringClass(meta_class);
1212
1257
1213 // Some of the queries below depend on the implementing class being set
1258 // Some of the queries below depend on the implementing class being set
1214 // to function properly. Such as function modifications
1259 // to function properly. Such as function modifications
1215 meta_function->setImplementingClass(meta_class);
1260 meta_function->setImplementingClass(meta_class);
1216
1261
1217 if (meta_function->name() == "operator_equal")
1262 if (meta_function->name() == "operator_equal")
1218 meta_class->setHasEqualsOperator(true);
1263 meta_class->setHasEqualsOperator(true);
1219
1264
1220 if (!meta_function->isFinalInTargetLang()
1265 if (!meta_function->isFinalInTargetLang()
1221 && meta_function->isRemovedFrom(meta_class, TypeSystem::TargetLangCode)) {
1266 && meta_function->isRemovedFrom(meta_class, TypeSystem::TargetLangCode)) {
1222 *meta_function += AbstractMetaAttributes::FinalInCpp;
1267 *meta_function += AbstractMetaAttributes::FinalInCpp;
1223 }
1268 }
1224 }
1269 }
1225
1270
1226 void AbstractMetaBuilder::traverseFunctions(ScopeModelItem scope_item, AbstractMetaClass *meta_class)
1271 void AbstractMetaBuilder::traverseFunctions(ScopeModelItem scope_item, AbstractMetaClass *meta_class)
1227 {
1272 {
1228 foreach (FunctionModelItem function, scope_item->functions()) {
1273 foreach (FunctionModelItem function, scope_item->functions()) {
1229 AbstractMetaFunction *meta_function = traverseFunction(function);
1274 AbstractMetaFunction *meta_function = traverseFunction(function);
1230
1275
1231 if (meta_function) {
1276 if (meta_function) {
1232 meta_function->setOriginalAttributes(meta_function->attributes());
1277 meta_function->setOriginalAttributes(meta_function->attributes());
1233 if (meta_class->isNamespace())
1278 if (meta_class->isNamespace())
1234 *meta_function += AbstractMetaAttributes::Static;
1279 *meta_function += AbstractMetaAttributes::Static;
1235
1280
1236 if (QPropertySpec *read = meta_class->propertySpecForRead(meta_function->name())) {
1281 if (QPropertySpec *read = meta_class->propertySpecForRead(meta_function->name())) {
1237 if (read->type() == meta_function->type()->typeEntry()) {
1282 if (read->type() == meta_function->type()->typeEntry()) {
1238 *meta_function += AbstractMetaAttributes::PropertyReader;
1283 *meta_function += AbstractMetaAttributes::PropertyReader;
1239 meta_function->setPropertySpec(read);
1284 meta_function->setPropertySpec(read);
1240 // printf("%s is reader for %s\n",
1285 // printf("%s is reader for %s\n",
1241 // qPrintable(meta_function->name()),
1286 // qPrintable(meta_function->name()),
1242 // qPrintable(read->name()));
1287 // qPrintable(read->name()));
1243 }
1288 }
1244 } else if (QPropertySpec *write =
1289 } else if (QPropertySpec *write =
1245 meta_class->propertySpecForWrite(meta_function->name())) {
1290 meta_class->propertySpecForWrite(meta_function->name())) {
1246 if (write->type() == meta_function->arguments().at(0)->type()->typeEntry()) {
1291 if (write->type() == meta_function->arguments().at(0)->type()->typeEntry()) {
1247 *meta_function += AbstractMetaAttributes::PropertyWriter;
1292 *meta_function += AbstractMetaAttributes::PropertyWriter;
1248 meta_function->setPropertySpec(write);
1293 meta_function->setPropertySpec(write);
1249 // printf("%s is writer for %s\n",
1294 // printf("%s is writer for %s\n",
1250 // qPrintable(meta_function->name()),
1295 // qPrintable(meta_function->name()),
1251 // qPrintable(write->name()));
1296 // qPrintable(write->name()));
1252 }
1297 }
1253 } else if (QPropertySpec *reset =
1298 } else if (QPropertySpec *reset =
1254 meta_class->propertySpecForReset(meta_function->name())) {
1299 meta_class->propertySpecForReset(meta_function->name())) {
1255 *meta_function += AbstractMetaAttributes::PropertyResetter;
1300 *meta_function += AbstractMetaAttributes::PropertyResetter;
1256 meta_function->setPropertySpec(reset);
1301 meta_function->setPropertySpec(reset);
1257 // printf("%s is resetter for %s\n",
1302 // printf("%s is resetter for %s\n",
1258 // qPrintable(meta_function->name()),
1303 // qPrintable(meta_function->name()),
1259 // qPrintable(reset->name()));
1304 // qPrintable(reset->name()));
1260 }
1305 }
1261
1306
1262
1307
1263 bool isInvalidDestructor = meta_function->isDestructor() && meta_function->isPrivate();
1308 bool isInvalidDestructor = meta_function->isDestructor() && meta_function->isPrivate();
1264 bool isInvalidConstructor = meta_function->isConstructor()
1309 bool isInvalidConstructor = meta_function->isConstructor()
1265 && (meta_function->isPrivate() || meta_function->isInvalid());
1310 && (meta_function->isPrivate() || meta_function->isInvalid());
1266 if ((isInvalidDestructor || isInvalidConstructor)
1311 if ((isInvalidDestructor || isInvalidConstructor)
1267 && !meta_class->hasNonPrivateConstructor()) {
1312 && !meta_class->hasNonPrivateConstructor()) {
1268 *meta_class += AbstractMetaAttributes::Final;
1313 *meta_class += AbstractMetaAttributes::Final;
1269 } else if (meta_function->isConstructor() && !meta_function->isPrivate()) {
1314 } else if (meta_function->isConstructor() && !meta_function->isPrivate()) {
1270 *meta_class -= AbstractMetaAttributes::Final;
1315 *meta_class -= AbstractMetaAttributes::Final;
1271 meta_class->setHasNonPrivateConstructor(true);
1316 meta_class->setHasNonPrivateConstructor(true);
1272 }
1317 }
1273
1318
1274 // Classes with virtual destructors should always have a shell class
1319 // Classes with virtual destructors should always have a shell class
1275 // (since we aren't registering the destructors, we need this extra check)
1320 // (since we aren't registering the destructors, we need this extra check)
1276 if (meta_function->isDestructor() && !meta_function->isFinal())
1321 if (meta_function->isDestructor() && !meta_function->isFinal())
1277 meta_class->setForceShellClass(true);
1322 meta_class->setForceShellClass(true);
1278
1323
1279 if (!meta_function->isDestructor()
1324 if (!meta_function->isDestructor()
1280 && !meta_function->isInvalid()
1325 && !meta_function->isInvalid()
1281 && (!meta_function->isConstructor() || !meta_function->isPrivate())) {
1326 && (!meta_function->isConstructor() || !meta_function->isPrivate())) {
1282
1327
1283 if (meta_class->typeEntry()->designatedInterface() && !meta_function->isPublic()
1328 if (meta_class->typeEntry()->designatedInterface() && !meta_function->isPublic()
1284 && !meta_function->isPrivate()) {
1329 && !meta_function->isPrivate()) {
1285 QString warn = QString("non-public function '%1' in interface '%2'")
1330 QString warn = QString("non-public function '%1' in interface '%2'")
1286 .arg(meta_function->name()).arg(meta_class->name());
1331 .arg(meta_function->name()).arg(meta_class->name());
1287 ReportHandler::warning(warn);
1332 ReportHandler::warning(warn);
1288
1333
1289 meta_function->setVisibility(AbstractMetaClass::Public);
1334 meta_function->setVisibility(AbstractMetaClass::Public);
1290 }
1335 }
1291
1336
1292 setupFunctionDefaults(meta_function, meta_class);
1337 setupFunctionDefaults(meta_function, meta_class);
1293
1338
1294 if (meta_function->isSignal() && meta_class->hasSignal(meta_function)) {
1339 if (meta_function->isSignal() && meta_class->hasSignal(meta_function)) {
1295 QString warn = QString("signal '%1' in class '%2' is overloaded.")
1340 QString warn = QString("signal '%1' in class '%2' is overloaded.")
1296 .arg(meta_function->name()).arg(meta_class->name());
1341 .arg(meta_function->name()).arg(meta_class->name());
1297 ReportHandler::warning(warn);
1342 ReportHandler::warning(warn);
1298 }
1343 }
1299
1344
1300 if (meta_function->isSignal() && !meta_class->isQObject()) {
1345 if (meta_function->isSignal() && !meta_class->isQObject()) {
1301 QString warn = QString("signal '%1' in non-QObject class '%2'")
1346 QString warn = QString("signal '%1' in non-QObject class '%2'")
1302 .arg(meta_function->name()).arg(meta_class->name());
1347 .arg(meta_function->name()).arg(meta_class->name());
1303 ReportHandler::warning(warn);
1348 ReportHandler::warning(warn);
1304 }
1349 }
1305
1350
1306 meta_class->addFunction(meta_function);
1351 meta_class->addFunction(meta_function);
1307 } else if (meta_function->isDestructor() && !meta_function->isPublic()) {
1352 } else if (meta_function->isDestructor() && !meta_function->isPublic()) {
1308 meta_class->setHasPublicDestructor(false);
1353 meta_class->setHasPublicDestructor(false);
1309 }
1354 }
1310 }
1355 }
1311 }
1356 }
1312 }
1357 }
1313
1358
1314 bool AbstractMetaBuilder::setupInheritance(AbstractMetaClass *meta_class)
1359 bool AbstractMetaBuilder::setupInheritance(AbstractMetaClass *meta_class)
1315 {
1360 {
1316 Q_ASSERT(!meta_class->isInterface());
1361 Q_ASSERT(!meta_class->isInterface());
1317
1362
1318 if (m_setup_inheritance_done.contains(meta_class))
1363 if (m_setup_inheritance_done.contains(meta_class))
1319 return true;
1364 return true;
1320 m_setup_inheritance_done.insert(meta_class);
1365 m_setup_inheritance_done.insert(meta_class);
1321
1366
1322 QStringList base_classes = meta_class->baseClassNames();
1367 QStringList base_classes = meta_class->baseClassNames();
1323
1368
1324 TypeDatabase *types = TypeDatabase::instance();
1369 TypeDatabase *types = TypeDatabase::instance();
1325
1370
1326 // we only support our own containers and ONLY if there is only one baseclass
1371 // we only support our own containers and ONLY if there is only one baseclass
1327 if (base_classes.size() == 1 && base_classes.first().count('<') == 1) {
1372 if (base_classes.size() == 1 && base_classes.first().count('<') == 1) {
1328 QStringList scope = meta_class->typeEntry()->qualifiedCppName().split("::");
1373 QStringList scope = meta_class->typeEntry()->qualifiedCppName().split("::");
1329 scope.removeLast();
1374 scope.removeLast();
1330 for (int i=scope.size(); i>=0; --i) {
1375 for (int i=scope.size(); i>=0; --i) {
1331 QString prefix = i > 0 ? QStringList(scope.mid(0, i)).join("::") + "::" : QString();
1376 QString prefix = i > 0 ? QStringList(scope.mid(0, i)).join("::") + "::" : QString();
1332 QString complete_name = prefix + base_classes.first();
1377 QString complete_name = prefix + base_classes.first();
1333 TypeParser::Info info = TypeParser::parse(complete_name);
1378 TypeParser::Info info = TypeParser::parse(complete_name);
1334 QString base_name = info.qualified_name.join("::");
1379 QString base_name = info.qualified_name.join("::");
1335
1380
1336 AbstractMetaClass *templ = 0;
1381 AbstractMetaClass *templ = 0;
1337 foreach (AbstractMetaClass *c, m_templates) {
1382 foreach (AbstractMetaClass *c, m_templates) {
1338 if (c->typeEntry()->name() == base_name) {
1383 if (c->typeEntry()->name() == base_name) {
1339 templ = c;
1384 templ = c;
1340 break;
1385 break;
1341 }
1386 }
1342 }
1387 }
1343
1388
1344 if (templ == 0)
1389 if (templ == 0)
1345 templ = m_meta_classes.findClass(base_name);
1390 templ = m_meta_classes.findClass(base_name);
1346
1391
1347 if (templ) {
1392 if (templ) {
1348 setupInheritance(templ);
1393 setupInheritance(templ);
1349 inheritTemplate(meta_class, templ, info);
1394 inheritTemplate(meta_class, templ, info);
1350 return true;
1395 return true;
1351 }
1396 }
1352 }
1397 }
1353
1398
1354 ReportHandler::warning(QString("template baseclass '%1' of '%2' is not known")
1399 ReportHandler::warning(QString("template baseclass '%1' of '%2' is not known")
1355 .arg(base_classes.first())
1400 .arg(base_classes.first())
1356 .arg(meta_class->name()));
1401 .arg(meta_class->name()));
1357 return false;
1402 return false;
1358 }
1403 }
1359
1404
1360 int primary = -1;
1405 int primary = -1;
1361 int primaries = 0;
1406 int primaries = 0;
1362 for (int i=0; i<base_classes.size(); ++i) {
1407 for (int i=0; i<base_classes.size(); ++i) {
1363
1408
1364 if (types->isClassRejected(base_classes.at(i)))
1409 if (types->isClassRejected(base_classes.at(i)))
1365 continue;
1410 continue;
1366
1411
1367 TypeEntry *base_class_entry = types->findType(base_classes.at(i));
1412 TypeEntry *base_class_entry = types->findType(base_classes.at(i));
1368 if (!base_class_entry) {
1413 if (!base_class_entry) {
1369 ReportHandler::warning(QString("class '%1' inherits from unknown base class '%2'")
1414 ReportHandler::warning(QString("class '%1' inherits from unknown base class '%2'")
1370 .arg(meta_class->name()).arg(base_classes.at(i)));
1415 .arg(meta_class->name()).arg(base_classes.at(i)));
1371 }
1416 }
1372
1417
1373 // true for primary base class
1418 // true for primary base class
1374 else if (!base_class_entry->designatedInterface()) {
1419 else if (!base_class_entry->designatedInterface()) {
1375 if (primaries > 0) {
1420 if (primaries > 0) {
1376 ReportHandler::warning(QString("class '%1' has multiple primary base classes"
1421 ReportHandler::warning(QString("class '%1' has multiple primary base classes"
1377 " '%2' and '%3'")
1422 " '%2' and '%3'")
1378 .arg(meta_class->name())
1423 .arg(meta_class->name())
1379 .arg(base_classes.at(primary))
1424 .arg(base_classes.at(primary))
1380 .arg(base_class_entry->name()));
1425 .arg(base_class_entry->name()));
1381 return false;
1426 return false;
1382 }
1427 }
1383 primaries++;
1428 primaries++;
1384 primary = i;
1429 primary = i;
1385 }
1430 }
1386 }
1431 }
1387
1432
1388 if (primary >= 0) {
1433 if (primary >= 0) {
1389 AbstractMetaClass *base_class = m_meta_classes.findClass(base_classes.at(primary));
1434 AbstractMetaClass *base_class = m_meta_classes.findClass(base_classes.at(primary));
1390 if (!base_class) {
1435 if (!base_class) {
1391 ReportHandler::warning(QString("unknown baseclass for '%1': '%2'")
1436 ReportHandler::warning(QString("unknown baseclass for '%1': '%2'")
1392 .arg(meta_class->name())
1437 .arg(meta_class->name())
1393 .arg(base_classes.at(primary)));
1438 .arg(base_classes.at(primary)));
1394 return false;
1439 return false;
1395 }
1440 }
1396 meta_class->setBaseClass(base_class);
1441 meta_class->setBaseClass(base_class);
1397
1442
1398 if (meta_class->typeEntry()->designatedInterface() != 0 && meta_class->isQObject()) {
1443 if (meta_class->typeEntry()->designatedInterface() != 0 && meta_class->isQObject()) {
1399 ReportHandler::warning(QString("QObject extended by interface type '%1'. This is not supported and the generated Java code will not compile.")
1444 ReportHandler::warning(QString("QObject extended by interface type '%1'. This is not supported and the generated Java code will not compile.")
1400 .arg(meta_class->name()));
1445 .arg(meta_class->name()));
1401 } else if (meta_class->typeEntry()->designatedInterface() != 0 && base_class != 0 && !base_class->isInterface()) {
1446 } else if (meta_class->typeEntry()->designatedInterface() != 0 && base_class != 0 && !base_class->isInterface()) {
1402 ReportHandler::warning(QString("object type '%1' extended by interface type '%2'. The resulting API will be less expressive than the original.")
1447 ReportHandler::warning(QString("object type '%1' extended by interface type '%2'. The resulting API will be less expressive than the original.")
1403 .arg(base_class->name())
1448 .arg(base_class->name())
1404 .arg(meta_class->name()));
1449 .arg(meta_class->name()));
1405 }
1450 }
1406
1451
1407 }
1452 }
1408
1453
1409 for (int i=0; i<base_classes.size(); ++i) {
1454 for (int i=0; i<base_classes.size(); ++i) {
1410 if (types->isClassRejected(base_classes.at(i)))
1455 if (types->isClassRejected(base_classes.at(i)))
1411 continue;
1456 continue;
1412
1457
1413 if (i != primary) {
1458 if (i != primary) {
1414 AbstractMetaClass *base_class = m_meta_classes.findClass(base_classes.at(i));
1459 AbstractMetaClass *base_class = m_meta_classes.findClass(base_classes.at(i));
1415 if (base_class == 0) {
1460 if (base_class == 0) {
1416 ReportHandler::warning(QString("class not found for setup inheritance '%1'").arg(base_classes.at(i)));
1461 ReportHandler::warning(QString("class not found for setup inheritance '%1'").arg(base_classes.at(i)));
1417 return false;
1462 return false;
1418 }
1463 }
1419
1464
1420 setupInheritance(base_class);
1465 setupInheritance(base_class);
1421
1466
1422 QString interface_name = InterfaceTypeEntry::interfaceName(base_class->name());
1467 QString interface_name = InterfaceTypeEntry::interfaceName(base_class->name());
1423 AbstractMetaClass *iface = m_meta_classes.findClass(interface_name);
1468 AbstractMetaClass *iface = m_meta_classes.findClass(interface_name);
1424 if (!iface) {
1469 if (!iface) {
1425 ReportHandler::warning(QString("unknown interface for '%1': '%2'")
1470 ReportHandler::warning(QString("unknown interface for '%1': '%2'")
1426 .arg(meta_class->name())
1471 .arg(meta_class->name())
1427 .arg(interface_name));
1472 .arg(interface_name));
1428 return false;
1473 return false;
1429 }
1474 }
1430 meta_class->addInterface(iface);
1475 meta_class->addInterface(iface);
1431
1476
1432 AbstractMetaClassList interfaces = iface->interfaces();
1477 AbstractMetaClassList interfaces = iface->interfaces();
1433 foreach (AbstractMetaClass *iface, interfaces)
1478 foreach (AbstractMetaClass *iface, interfaces)
1434 meta_class->addInterface(iface);
1479 meta_class->addInterface(iface);
1435 }
1480 }
1436 }
1481 }
1437
1482
1438 return true;
1483 return true;
1439 }
1484 }
1440
1485
1441 void AbstractMetaBuilder::traverseEnums(ScopeModelItem scope_item, AbstractMetaClass *meta_class, const QStringList &enumsDeclarations)
1486 void AbstractMetaBuilder::traverseEnums(ScopeModelItem scope_item, AbstractMetaClass *meta_class, const QStringList &enumsDeclarations)
1442 {
1487 {
1443 EnumList enums = scope_item->enums();
1488 EnumList enums = scope_item->enums();
1444 foreach (EnumModelItem enum_item, enums) {
1489 foreach (EnumModelItem enum_item, enums) {
1445 AbstractMetaEnum *meta_enum = traverseEnum(enum_item, meta_class, QSet<QString>::fromList(enumsDeclarations));
1490 AbstractMetaEnum *meta_enum = traverseEnum(enum_item, meta_class, QSet<QString>::fromList(enumsDeclarations));
1446 if (meta_enum) {
1491 if (meta_enum) {
1447 meta_enum->setOriginalAttributes(meta_enum->attributes());
1492 meta_enum->setOriginalAttributes(meta_enum->attributes());
1448 meta_class->addEnum(meta_enum);
1493 meta_class->addEnum(meta_enum);
1449 meta_enum->setEnclosingClass(meta_class);
1494 meta_enum->setEnclosingClass(meta_class);
1450 }
1495 }
1451 }
1496 }
1452 }
1497 }
1453
1498
1454 AbstractMetaFunction *AbstractMetaBuilder::traverseFunction(FunctionModelItem function_item)
1499 AbstractMetaFunction *AbstractMetaBuilder::traverseFunction(FunctionModelItem function_item)
1455 {
1500 {
1456 QString function_name = function_item->name();
1501 QString function_name = function_item->name();
1457 QString class_name = m_current_class->typeEntry()->qualifiedCppName();
1502 QString class_name = m_current_class->typeEntry()->qualifiedCppName();
1458
1503
1459 if (TypeDatabase::instance()->isFunctionRejected(class_name, function_name)) {
1504 if (TypeDatabase::instance()->isFunctionRejected(class_name, function_name)) {
1460 m_rejected_functions.insert(class_name + "::" + function_name, GenerationDisabled);
1505 m_rejected_functions.insert(class_name + "::" + function_name, GenerationDisabled);
1461 return 0;
1506 return 0;
1462 }
1507 }
1463
1508
1464
1509
1465 Q_ASSERT(function_item->functionType() == CodeModel::Normal
1510 Q_ASSERT(function_item->functionType() == CodeModel::Normal
1466 || function_item->functionType() == CodeModel::Signal
1511 || function_item->functionType() == CodeModel::Signal
1467 || function_item->functionType() == CodeModel::Slot);
1512 || function_item->functionType() == CodeModel::Slot);
1468
1513
1469 if (function_item->isFriend())
1514 if (function_item->isFriend())
1470 return 0;
1515 return 0;
1471
1516
1472
1517
1473 QString cast_type;
1518 QString cast_type;
1474
1519
1475 if (function_name.startsWith("operator")) {
1520 if (function_name.startsWith("operator")) {
1476 function_name = rename_operator(function_name.mid(8));
1521 function_name = rename_operator(function_name.mid(8));
1477 if (function_name.isEmpty()) {
1522 if (function_name.isEmpty()) {
1478 m_rejected_functions.insert(class_name + "::" + function_name,
1523 m_rejected_functions.insert(class_name + "::" + function_name,
1479 GenerationDisabled);
1524 GenerationDisabled);
1480 return 0;
1525 return 0;
1481 }
1526 }
1482 if (function_name.contains("_cast_"))
1527 if (function_name.contains("_cast_"))
1483 cast_type = function_name.mid(14).trimmed();
1528 cast_type = function_name.mid(14).trimmed();
1484 }
1529 }
1485
1530
1486 AbstractMetaFunction *meta_function = createMetaFunction();
1531 AbstractMetaFunction *meta_function = createMetaFunction();
1487 meta_function->setConstant(function_item->isConstant());
1532 meta_function->setConstant(function_item->isConstant());
1488
1533
1489 ReportHandler::debugMedium(QString(" - %2()").arg(function_name));
1534 ReportHandler::debugMedium(QString(" - %2()").arg(function_name));
1490
1535
1491 meta_function->setName(function_name);
1536 meta_function->setName(function_name);
1492 meta_function->setOriginalName(function_item->name());
1537 meta_function->setOriginalName(function_item->name());
1493
1538
1494 if (function_item->isAbstract())
1539 if (function_item->isAbstract())
1495 *meta_function += AbstractMetaAttributes::Abstract;
1540 *meta_function += AbstractMetaAttributes::Abstract;
1496
1541
1497 if (!meta_function->isAbstract())
1542 if (!meta_function->isAbstract())
1498 *meta_function += AbstractMetaAttributes::Native;
1543 *meta_function += AbstractMetaAttributes::Native;
1499
1544
1500 if (!function_item->isVirtual())
1545 if (!function_item->isVirtual())
1501 *meta_function += AbstractMetaAttributes::Final;
1546 *meta_function += AbstractMetaAttributes::Final;
1502
1547
1503 if (function_item->isInvokable())
1548 if (function_item->isInvokable())
1504 *meta_function += AbstractMetaAttributes::Invokable;
1549 *meta_function += AbstractMetaAttributes::Invokable;
1505
1550
1506 if (function_item->isStatic()) {
1551 if (function_item->isStatic()) {
1507 *meta_function += AbstractMetaAttributes::Static;
1552 *meta_function += AbstractMetaAttributes::Static;
1508 *meta_function += AbstractMetaAttributes::Final;
1553 *meta_function += AbstractMetaAttributes::Final;
1509 }
1554 }
1510
1555
1511 // Access rights
1556 // Access rights
1512 if (function_item->accessPolicy() == CodeModel::Public)
1557 if (function_item->accessPolicy() == CodeModel::Public)
1513 *meta_function += AbstractMetaAttributes::Public;
1558 *meta_function += AbstractMetaAttributes::Public;
1514 else if (function_item->accessPolicy() == CodeModel::Private)
1559 else if (function_item->accessPolicy() == CodeModel::Private)
1515 *meta_function += AbstractMetaAttributes::Private;
1560 *meta_function += AbstractMetaAttributes::Private;
1516 else
1561 else
1517 *meta_function += AbstractMetaAttributes::Protected;
1562 *meta_function += AbstractMetaAttributes::Protected;
1518
1563
1519
1564
1520 QString stripped_class_name = class_name;
1565 QString stripped_class_name = class_name;
1521 int cc_pos = stripped_class_name.lastIndexOf("::");
1566 int cc_pos = stripped_class_name.lastIndexOf("::");
1522 if (cc_pos > 0)
1567 if (cc_pos > 0)
1523 stripped_class_name = stripped_class_name.mid(cc_pos + 2);
1568 stripped_class_name = stripped_class_name.mid(cc_pos + 2);
1524
1569
1525 TypeInfo function_type = function_item->type();
1570 TypeInfo function_type = function_item->type();
1526 if (function_name.startsWith('~')) {
1571 if (function_name.startsWith('~')) {
1527 meta_function->setFunctionType(AbstractMetaFunction::DestructorFunction);
1572 meta_function->setFunctionType(AbstractMetaFunction::DestructorFunction);
1528 meta_function->setInvalid(true);
1573 meta_function->setInvalid(true);
1529 } else if (strip_template_args(function_name) == stripped_class_name) {
1574 } else if (strip_template_args(function_name) == stripped_class_name) {
1530 meta_function->setFunctionType(AbstractMetaFunction::ConstructorFunction);
1575 meta_function->setFunctionType(AbstractMetaFunction::ConstructorFunction);
1531 meta_function->setName(m_current_class->name());
1576 meta_function->setName(m_current_class->name());
1532 } else {
1577 } else {
1533 bool ok;
1578 bool ok;
1534 AbstractMetaType *type = 0;
1579 AbstractMetaType *type = 0;
1535
1580
1536 if (!cast_type.isEmpty()) {
1581 if (!cast_type.isEmpty()) {
1537 TypeInfo info;
1582 TypeInfo info;
1538 info.setQualifiedName(QStringList(cast_type));
1583 info.setQualifiedName(QStringList(cast_type));
1539 type = translateType(info, &ok);
1584 type = translateType(info, &ok);
1540 } else {
1585 } else {
1541 type = translateType(function_type, &ok);
1586 type = translateType(function_type, &ok);
1542 }
1587 }
1543
1588
1544 if (!ok) {
1589 if (!ok) {
1545 ReportHandler::warning(QString("skipping function '%1::%2', unmatched return type '%3'")
1590 ReportHandler::warning(QString("skipping function '%1::%2', unmatched return type '%3'")
1546 .arg(class_name)
1591 .arg(class_name)
1547 .arg(function_item->name())
1592 .arg(function_item->name())
1548 .arg(function_item->type().toString()));
1593 .arg(function_item->type().toString()));
1549 m_rejected_functions[class_name + "::" + function_name] =
1594 m_rejected_functions[class_name + "::" + function_name] =
1550 UnmatchedReturnType;
1595 UnmatchedReturnType;
1551 meta_function->setInvalid(true);
1596 meta_function->setInvalid(true);
1552 return meta_function;
1597 return meta_function;
1553 }
1598 }
1554 meta_function->setType(type);
1599 meta_function->setType(type);
1555
1600
1556 if (function_item->functionType() == CodeModel::Signal)
1601 if (function_item->functionType() == CodeModel::Signal)
1557 meta_function->setFunctionType(AbstractMetaFunction::SignalFunction);
1602 meta_function->setFunctionType(AbstractMetaFunction::SignalFunction);
1558 else if (function_item->functionType() == CodeModel::Slot)
1603 else if (function_item->functionType() == CodeModel::Slot)
1559 meta_function->setFunctionType(AbstractMetaFunction::SlotFunction);
1604 meta_function->setFunctionType(AbstractMetaFunction::SlotFunction);
1560 }
1605 }
1561
1606
1562 ArgumentList arguments = function_item->arguments();
1607 ArgumentList arguments = function_item->arguments();
1563 AbstractMetaArgumentList meta_arguments;
1608 AbstractMetaArgumentList meta_arguments;
1564
1609
1565 int first_default_argument = 0;
1610 int first_default_argument = 0;
1566 for (int i=0; i<arguments.size(); ++i) {
1611 for (int i=0; i<arguments.size(); ++i) {
1567 ArgumentModelItem arg = arguments.at(i);
1612 ArgumentModelItem arg = arguments.at(i);
1568
1613
1569 bool ok;
1614 bool ok;
1570 AbstractMetaType *meta_type = translateType(arg->type(), &ok);
1615 AbstractMetaType *meta_type = translateType(arg->type(), &ok);
1571 if (!meta_type || !ok) {
1616 if (!meta_type || !ok) {
1572 ReportHandler::warning(QString("skipping function '%1::%2', "
1617 ReportHandler::warning(QString("skipping function '%1::%2', "
1573 "unmatched parameter type '%3'")
1618 "unmatched parameter type '%3'")
1574 .arg(class_name)
1619 .arg(class_name)
1575 .arg(function_item->name())
1620 .arg(function_item->name())
1576 .arg(arg->type().toString()));
1621 .arg(arg->type().toString()));
1577 m_rejected_functions[class_name + "::" + function_name] =
1622 m_rejected_functions[class_name + "::" + function_name] =
1578 UnmatchedArgumentType;
1623 UnmatchedArgumentType;
1579 meta_function->setInvalid(true);
1624 meta_function->setInvalid(true);
1580 return meta_function;
1625 return meta_function;
1581 }
1626 }
1582 AbstractMetaArgument *meta_argument = createMetaArgument();
1627 AbstractMetaArgument *meta_argument = createMetaArgument();
1583 meta_argument->setType(meta_type);
1628 meta_argument->setType(meta_type);
1584 meta_argument->setName(arg->name());
1629 meta_argument->setName(arg->name());
1585 meta_argument->setArgumentIndex(i);
1630 meta_argument->setArgumentIndex(i);
1586 meta_arguments << meta_argument;
1631 meta_arguments << meta_argument;
1587 }
1632 }
1588
1633
1589 meta_function->setArguments(meta_arguments);
1634 meta_function->setArguments(meta_arguments);
1590
1635
1591 // Find the correct default values
1636 // Find the correct default values
1592 for (int i=0; i<arguments.size(); ++i) {
1637 for (int i=0; i<arguments.size(); ++i) {
1593 ArgumentModelItem arg = arguments.at(i);
1638 ArgumentModelItem arg = arguments.at(i);
1594 AbstractMetaArgument *meta_arg = meta_arguments.at(i);
1639 AbstractMetaArgument *meta_arg = meta_arguments.at(i);
1595 if (arg->defaultValue()) {
1640 if (arg->defaultValue()) {
1596 QString expr = arg->defaultValueExpression();
1641 QString expr = arg->defaultValueExpression();
1597 if (!expr.isEmpty())
1642 if (!expr.isEmpty())
1598 meta_arg->setOriginalDefaultValueExpression(expr);
1643 meta_arg->setOriginalDefaultValueExpression(expr);
1599
1644
1600 expr = translateDefaultValue(arg, meta_arg->type(), meta_function, m_current_class, i);
1645 expr = translateDefaultValue(arg, meta_arg->type(), meta_function, m_current_class, i);
1601 if (expr.isEmpty()) {
1646 if (expr.isEmpty()) {
1602 first_default_argument = i;
1647 first_default_argument = i;
1603 } else {
1648 } else {
1604 meta_arg->setDefaultValueExpression(expr);
1649 meta_arg->setDefaultValueExpression(expr);
1605 }
1650 }
1606
1651
1607 if (meta_arg->type()->isEnum() || meta_arg->type()->isFlags()) {
1652 if (meta_arg->type()->isEnum() || meta_arg->type()->isFlags()) {
1608 m_enum_default_arguments
1653 m_enum_default_arguments
1609 << QPair<AbstractMetaArgument *, AbstractMetaFunction *>(meta_arg, meta_function);
1654 << QPair<AbstractMetaArgument *, AbstractMetaFunction *>(meta_arg, meta_function);
1610 }
1655 }
1611
1656
1612 }
1657 }
1613 }
1658 }
1614
1659
1615 // If we where not able to translate the default argument make it
1660 // If we where not able to translate the default argument make it
1616 // reset all default arguments before this one too.
1661 // reset all default arguments before this one too.
1617 for (int i=0; i<first_default_argument; ++i)
1662 for (int i=0; i<first_default_argument; ++i)
1618 meta_arguments[i]->setDefaultValueExpression(QString());
1663 meta_arguments[i]->setDefaultValueExpression(QString());
1619
1664
1620 if (ReportHandler::debugLevel() == ReportHandler::FullDebug)
1665 if (ReportHandler::debugLevel() == ReportHandler::FullDebug)
1621 foreach(AbstractMetaArgument *arg, meta_arguments)
1666 foreach(AbstractMetaArgument *arg, meta_arguments)
1622 ReportHandler::debugFull(" - " + arg->toString());
1667 ReportHandler::debugFull(" - " + arg->toString());
1623
1668
1624 return meta_function;
1669 return meta_function;
1625 }
1670 }
1626
1671
1627
1672
1628 AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei, bool *ok, bool resolveType, bool resolveScope)
1673 AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei, bool *ok, bool resolveType, bool resolveScope)
1629 {
1674 {
1630 Q_ASSERT(ok);
1675 Q_ASSERT(ok);
1631 *ok = true;
1676 *ok = true;
1632
1677
1633 // 1. Test the type info without resolving typedefs in case this is present in the
1678 // 1. Test the type info without resolving typedefs in case this is present in the
1634 // type system
1679 // type system
1635 TypeInfo typei;
1680 TypeInfo typei;
1636 if (resolveType) {
1681 if (resolveType) {
1637 bool isok;
1682 bool isok;
1638 AbstractMetaType *t = translateType(_typei, &isok, false, resolveScope);
1683 AbstractMetaType *t = translateType(_typei, &isok, false, resolveScope);
1639 if (t != 0 && isok)
1684 if (t != 0 && isok)
1640 return t;
1685 return t;
1641 }
1686 }
1642
1687
1643 if (!resolveType)
1688 if (!resolveType)
1644 typei = _typei;
1689 typei = _typei;
1645 else {
1690 else {
1646 // Go through all parts of the current scope (including global namespace)
1691 // Go through all parts of the current scope (including global namespace)
1647 // to resolve typedefs. The parser does not properly resolve typedefs in
1692 // to resolve typedefs. The parser does not properly resolve typedefs in
1648 // the global scope when they are referenced from inside a namespace.
1693 // the global scope when they are referenced from inside a namespace.
1649 // This is a work around to fix this bug since fixing it in resolveType
1694 // This is a work around to fix this bug since fixing it in resolveType
1650 // seemed non-trivial
1695 // seemed non-trivial
1651 int i = m_scopes.size() - 1;
1696 int i = m_scopes.size() - 1;
1652 while (i >= 0) {
1697 while (i >= 0) {
1653 typei = TypeInfo::resolveType(_typei, m_scopes.at(i--)->toItem());
1698 typei = TypeInfo::resolveType(_typei, m_scopes.at(i--)->toItem());
1654 if (typei.qualifiedName().join("::") != _typei.qualifiedName().join("::"))
1699 if (typei.qualifiedName().join("::") != _typei.qualifiedName().join("::"))
1655 break;
1700 break;
1656 }
1701 }
1657
1702
1658 }
1703 }
1659
1704
1660 if (typei.isFunctionPointer()) {
1705 if (typei.isFunctionPointer()) {
1661 *ok = false;
1706 *ok = false;
1662 return 0;
1707 return 0;
1663 }
1708 }
1664
1709
1665 TypeParser::Info typeInfo = TypeParser::parse(typei.toString());
1710 TypeParser::Info typeInfo = TypeParser::parse(typei.toString());
1666 if (typeInfo.is_busted) {
1711 if (typeInfo.is_busted) {
1667 *ok = false;
1712 *ok = false;
1668 return 0;
1713 return 0;
1669 }
1714 }
1670
1715
1671 // 2. Handle pointers specified as arrays with unspecified size
1716 // 2. Handle pointers specified as arrays with unspecified size
1672 bool array_of_unspecified_size = false;
1717 bool array_of_unspecified_size = false;
1673 if (typeInfo.arrays.size() > 0) {
1718 if (typeInfo.arrays.size() > 0) {
1674 array_of_unspecified_size = true;
1719 array_of_unspecified_size = true;
1675 for (int i=0; i<typeInfo.arrays.size(); ++i)
1720 for (int i=0; i<typeInfo.arrays.size(); ++i)
1676 array_of_unspecified_size = array_of_unspecified_size && typeInfo.arrays.at(i).isEmpty();
1721 array_of_unspecified_size = array_of_unspecified_size && typeInfo.arrays.at(i).isEmpty();
1677
1722
1678 if (!array_of_unspecified_size) {
1723 if (!array_of_unspecified_size) {
1679 TypeInfo newInfo;
1724 TypeInfo newInfo;
1680 //newInfo.setArguments(typei.arguments());
1725 //newInfo.setArguments(typei.arguments());
1681 newInfo.setIndirections(typei.indirections());
1726 newInfo.setIndirections(typei.indirections());
1682 newInfo.setConstant(typei.isConstant());
1727 newInfo.setConstant(typei.isConstant());
1683 newInfo.setFunctionPointer(typei.isFunctionPointer());
1728 newInfo.setFunctionPointer(typei.isFunctionPointer());
1684 newInfo.setQualifiedName(typei.qualifiedName());
1729 newInfo.setQualifiedName(typei.qualifiedName());
1685 newInfo.setReference(typei.isReference());
1730 newInfo.setReference(typei.isReference());
1686 newInfo.setVolatile(typei.isVolatile());
1731 newInfo.setVolatile(typei.isVolatile());
1687
1732
1688 AbstractMetaType *elementType = translateType(newInfo, ok);
1733 AbstractMetaType *elementType = translateType(newInfo, ok);
1689 if (!(*ok))
1734 if (!(*ok))
1690 return 0;
1735 return 0;
1691
1736
1692 for (int i=typeInfo.arrays.size()-1; i>=0; --i) {
1737 for (int i=typeInfo.arrays.size()-1; i>=0; --i) {
1693 QString s = typeInfo.arrays.at(i);
1738 QString s = typeInfo.arrays.at(i);
1694 bool isok;
1739 bool isok;
1695
1740
1696 int elems = s.toInt(&isok);
1741 int elems = s.toInt(&isok);
1697 if (!isok)
1742 if (!isok)
1698 return 0;
1743 return 0;
1699
1744
1700 AbstractMetaType *arrayType = createMetaType();
1745 AbstractMetaType *arrayType = createMetaType();
1701 arrayType->setArrayElementCount(elems);
1746 arrayType->setArrayElementCount(elems);
1702 arrayType->setArrayElementType(elementType);
1747 arrayType->setArrayElementType(elementType);
1703 arrayType->setTypeEntry(new ArrayTypeEntry(elementType->typeEntry()));
1748 arrayType->setTypeEntry(new ArrayTypeEntry(elementType->typeEntry()));
1704 decideUsagePattern(arrayType);
1749 decideUsagePattern(arrayType);
1705
1750
1706 elementType = arrayType;
1751 elementType = arrayType;
1707 }
1752 }
1708
1753
1709 return elementType;
1754 return elementType;
1710 } else {
1755 } else {
1711 typeInfo.indirections += typeInfo.arrays.size();
1756 typeInfo.indirections += typeInfo.arrays.size();
1712 }
1757 }
1713 }
1758 }
1714
1759
1715 QStringList qualifier_list = typeInfo.qualified_name;
1760 QStringList qualifier_list = typeInfo.qualified_name;
1716 if (qualifier_list.isEmpty()) {
1761 if (qualifier_list.isEmpty()) {
1717 ReportHandler::warning(QString("horribly broken type '%1'").arg(_typei.toString()));
1762 ReportHandler::warning(QString("horribly broken type '%1'").arg(_typei.toString()));
1718 *ok = false;
1763 *ok = false;
1719 return 0;
1764 return 0;
1720 }
1765 }
1721
1766
1722 QString qualified_name = qualifier_list.join("::");
1767 QString qualified_name = qualifier_list.join("::");
1723 QString name = qualifier_list.takeLast();
1768 QString name = qualifier_list.takeLast();
1724
1769
1725 // 3. Special case 'void' type
1770 // 3. Special case 'void' type
1726 if (name == "void" && typeInfo.indirections == 0) {
1771 if (name == "void" && typeInfo.indirections == 0) {
1727 return 0;
1772 return 0;
1728 }
1773 }
1729
1774
1730 // 4. Special case QFlags (include instantiation in name)
1775 // 4. Special case QFlags (include instantiation in name)
1731 if (qualified_name == "QFlags")
1776 if (qualified_name == "QFlags")
1732 qualified_name = typeInfo.toString();
1777 qualified_name = typeInfo.toString();
1733
1778
1734 // 5. Try to find the type
1779 // 5. Try to find the type
1735 const TypeEntry *type = TypeDatabase::instance()->findType(qualified_name);
1780 const TypeEntry *type = TypeDatabase::instance()->findType(qualified_name);
1736
1781
1737 // 6. No? Try looking it up as a flags type
1782 // 6. No? Try looking it up as a flags type
1738 if (!type)
1783 if (!type)
1739 type = TypeDatabase::instance()->findFlagsType(qualified_name);
1784 type = TypeDatabase::instance()->findFlagsType(qualified_name);
1740
1785
1741 // 7. No? Try looking it up as a container type
1786 // 7. No? Try looking it up as a container type
1742 if (!type)
1787 if (!type)
1743 type = TypeDatabase::instance()->findContainerType(name);
1788 type = TypeDatabase::instance()->findContainerType(name);
1744
1789
1745 // 8. No? Check if the current class is a template and this type is one
1790 // 8. No? Check if the current class is a template and this type is one
1746 // of the parameters.
1791 // of the parameters.
1747 if (type == 0 && m_current_class != 0) {
1792 if (type == 0 && m_current_class != 0) {
1748 QList<TypeEntry *> template_args = m_current_class->templateArguments();
1793 QList<TypeEntry *> template_args = m_current_class->templateArguments();
1749 foreach (TypeEntry *te, template_args) {
1794 foreach (TypeEntry *te, template_args) {
1750 if (te->name() == qualified_name)
1795 if (te->name() == qualified_name)
1751 type = te;
1796 type = te;
1752 }
1797 }
1753 }
1798 }
1754
1799
1755 // 9. Try finding the type by prefixing it with the current
1800 // 9. Try finding the type by prefixing it with the current
1756 // context and all baseclasses of the current context
1801 // context and all baseclasses of the current context
1757 if (!type && !TypeDatabase::instance()->isClassRejected(qualified_name) && m_current_class != 0 && resolveScope) {
1802 if (!type && !TypeDatabase::instance()->isClassRejected(qualified_name) && m_current_class != 0 && resolveScope) {
1758 QStringList contexts;
1803 QStringList contexts;
1759 contexts.append(m_current_class->qualifiedCppName());
1804 contexts.append(m_current_class->qualifiedCppName());
1760 contexts.append(currentScope()->qualifiedName().join("::"));
1805 contexts.append(currentScope()->qualifiedName().join("::"));
1761
1806
1762
1807
1763 TypeInfo info = typei;
1808 TypeInfo info = typei;
1764 bool subclasses_done = false;
1809 bool subclasses_done = false;
1765 while (!contexts.isEmpty() && type == 0) {
1810 while (!contexts.isEmpty() && type == 0) {
1766 //type = TypeDatabase::instance()->findType(contexts.at(0) + "::" + qualified_name);
1811 //type = TypeDatabase::instance()->findType(contexts.at(0) + "::" + qualified_name);
1767
1812
1768 bool isok;
1813 bool isok;
1769 info.setQualifiedName(QStringList() << contexts.at(0) << qualified_name);
1814 info.setQualifiedName(QStringList() << contexts.at(0) << qualified_name);
1770 AbstractMetaType *t = translateType(info, &isok, true, false);
1815 AbstractMetaType *t = translateType(info, &isok, true, false);
1771 if (t != 0 && isok)
1816 if (t != 0 && isok)
1772 return t;
1817 return t;
1773
1818
1774 ClassModelItem item = m_dom->findClass(contexts.at(0));
1819 ClassModelItem item = m_dom->findClass(contexts.at(0));
1775 if (item != 0)
1820 if (item != 0)
1776 contexts += item->baseClasses();
1821 contexts += item->baseClasses();
1777 contexts.pop_front();
1822 contexts.pop_front();
1778
1823
1779 // 10. Last resort: Special cased prefix of Qt namespace since the meta object implicitly inherits this, so
1824 // 10. Last resort: Special cased prefix of Qt namespace since the meta object implicitly inherits this, so
1780 // enum types from there may be addressed without any scope resolution in properties.
1825 // enum types from there may be addressed without any scope resolution in properties.
1781 if (contexts.size() == 0 && !subclasses_done) {
1826 if (contexts.size() == 0 && !subclasses_done) {
1782 contexts << "Qt";
1827 contexts << "Qt";
1783 subclasses_done = true;
1828 subclasses_done = true;
1784 }
1829 }
1785 }
1830 }
1786
1831
1787 }
1832 }
1788
1833
1789 if (!type) {
1834 if (!type) {
1790 *ok = false;
1835 *ok = false;
1791 return 0;
1836 return 0;
1792 }
1837 }
1793
1838
1794 // Used to for diagnostics later...
1839 // Used to for diagnostics later...
1795 m_used_types << type;
1840 m_used_types << type;
1796
1841
1797 // These are only implicit and should not appear in code...
1842 // These are only implicit and should not appear in code...
1798 Q_ASSERT(!type->isInterface());
1843 Q_ASSERT(!type->isInterface());
1799
1844
1800 AbstractMetaType *meta_type = createMetaType();
1845 AbstractMetaType *meta_type = createMetaType();
1801 meta_type->setTypeEntry(type);
1846 meta_type->setTypeEntry(type);
1802 meta_type->setIndirections(typeInfo.indirections);
1847 meta_type->setIndirections(typeInfo.indirections);
1803 meta_type->setReference(typeInfo.is_reference);
1848 meta_type->setReference(typeInfo.is_reference);
1804 meta_type->setConstant(typeInfo.is_constant);
1849 meta_type->setConstant(typeInfo.is_constant);
1805 meta_type->setOriginalTypeDescription(_typei.toString());
1850 meta_type->setOriginalTypeDescription(_typei.toString());
1806 decideUsagePattern(meta_type);
1851 decideUsagePattern(meta_type);
1807
1852
1808 if (meta_type->typeEntry()->isContainer()) {
1853 if (meta_type->typeEntry()->isContainer()) {
1809 ContainerTypeEntry::Type container_type = static_cast<const ContainerTypeEntry *>(type)->type();
1854 ContainerTypeEntry::Type container_type = static_cast<const ContainerTypeEntry *>(type)->type();
1810
1855
1811 if (container_type == ContainerTypeEntry::StringListContainer) {
1856 if (container_type == ContainerTypeEntry::StringListContainer) {
1812 TypeInfo info;
1857 TypeInfo info;
1813 info.setQualifiedName(QStringList() << "QString");
1858 info.setQualifiedName(QStringList() << "QString");
1814 AbstractMetaType *targ_type = translateType(info, ok);
1859 AbstractMetaType *targ_type = translateType(info, ok);
1815
1860
1816 Q_ASSERT(*ok);
1861 Q_ASSERT(*ok);
1817 Q_ASSERT(targ_type);
1862 Q_ASSERT(targ_type);
1818
1863
1819 meta_type->addInstantiation(targ_type);
1864 meta_type->addInstantiation(targ_type);
1820 meta_type->setInstantiationInCpp(false);
1865 meta_type->setInstantiationInCpp(false);
1821
1866
1822 } else {
1867 } else {
1823 foreach (const TypeParser::Info &ta, typeInfo.template_instantiations) {
1868 foreach (const TypeParser::Info &ta, typeInfo.template_instantiations) {
1824 TypeInfo info;
1869 TypeInfo info;
1825 info.setConstant(ta.is_constant);
1870 info.setConstant(ta.is_constant);
1826 info.setReference(ta.is_reference);
1871 info.setReference(ta.is_reference);
1827 info.setIndirections(ta.indirections);
1872 info.setIndirections(ta.indirections);
1828
1873
1829 info.setFunctionPointer(false);
1874 info.setFunctionPointer(false);
1830 info.setQualifiedName(ta.instantiationName().split("::"));
1875 info.setQualifiedName(ta.instantiationName().split("::"));
1831
1876
1832 AbstractMetaType *targ_type = translateType(info, ok);
1877 AbstractMetaType *targ_type = translateType(info, ok);
1833 if (!(*ok)) {
1878 if (!(*ok)) {
1834 delete meta_type;
1879 delete meta_type;
1835 return 0;
1880 return 0;
1836 }
1881 }
1837
1882
1838 meta_type->addInstantiation(targ_type);
1883 meta_type->addInstantiation(targ_type);
1839 }
1884 }
1840 }
1885 }
1841
1886
1842 if (container_type == ContainerTypeEntry::ListContainer
1887 if (container_type == ContainerTypeEntry::ListContainer
1843 || container_type == ContainerTypeEntry::VectorContainer
1888 || container_type == ContainerTypeEntry::VectorContainer
1844 || container_type == ContainerTypeEntry::StringListContainer) {
1889 || container_type == ContainerTypeEntry::StringListContainer) {
1845 Q_ASSERT(meta_type->instantiations().size() == 1);
1890 Q_ASSERT(meta_type->instantiations().size() == 1);
1846 }
1891 }
1847 }
1892 }
1848
1893
1849 return meta_type;
1894 return meta_type;
1850 }
1895 }
1851
1896
1852 void AbstractMetaBuilder::decideUsagePattern(AbstractMetaType *meta_type)
1897 void AbstractMetaBuilder::decideUsagePattern(AbstractMetaType *meta_type)
1853 {
1898 {
1854 const TypeEntry *type = meta_type->typeEntry();
1899 const TypeEntry *type = meta_type->typeEntry();
1855
1900
1856 if (type->isPrimitive() && (meta_type->actualIndirections() == 0
1901 if (type->isPrimitive() && (meta_type->actualIndirections() == 0
1857 || (meta_type->isConstant() && meta_type->isReference() && meta_type->indirections() == 0))) {
1902 || (meta_type->isConstant() && meta_type->isReference() && meta_type->indirections() == 0))) {
1858 meta_type->setTypeUsagePattern(AbstractMetaType::PrimitivePattern);
1903 meta_type->setTypeUsagePattern(AbstractMetaType::PrimitivePattern);
1859
1904
1860 } else if (type->isVoid()) {
1905 } else if (type->isVoid()) {
1861 meta_type->setTypeUsagePattern(AbstractMetaType::NativePointerPattern);
1906 meta_type->setTypeUsagePattern(AbstractMetaType::NativePointerPattern);
1862
1907
1863 } else if (type->isString()
1908 } else if (type->isString()
1864 && meta_type->indirections() == 0
1909 && meta_type->indirections() == 0
1865 && (meta_type->isConstant() == meta_type->isReference()
1910 && (meta_type->isConstant() == meta_type->isReference()
1866 || meta_type->isConstant())) {
1911 || meta_type->isConstant())) {
1867 meta_type->setTypeUsagePattern(AbstractMetaType::StringPattern);
1912 meta_type->setTypeUsagePattern(AbstractMetaType::StringPattern);
1868
1913
1869 } else if (type->isChar()
1914 } else if (type->isChar()
1870 && meta_type->indirections() == 0
1915 && meta_type->indirections() == 0
1871 && meta_type->isConstant() == meta_type->isReference()) {
1916 && meta_type->isConstant() == meta_type->isReference()) {
1872 meta_type->setTypeUsagePattern(AbstractMetaType::CharPattern);
1917 meta_type->setTypeUsagePattern(AbstractMetaType::CharPattern);
1873
1918
1874 } else if (type->isJObjectWrapper()
1919 } else if (type->isJObjectWrapper()
1875 && meta_type->indirections() == 0
1920 && meta_type->indirections() == 0
1876 && meta_type->isConstant() == meta_type->isReference()) {
1921 && meta_type->isConstant() == meta_type->isReference()) {
1877 meta_type->setTypeUsagePattern(AbstractMetaType::JObjectWrapperPattern);
1922 meta_type->setTypeUsagePattern(AbstractMetaType::JObjectWrapperPattern);
1878
1923
1879 } else if (type->isVariant()
1924 } else if (type->isVariant()
1880 && meta_type->indirections() == 0
1925 && meta_type->indirections() == 0
1881 && meta_type->isConstant() == meta_type->isReference()) {
1926 && meta_type->isConstant() == meta_type->isReference()) {
1882 meta_type->setTypeUsagePattern(AbstractMetaType::VariantPattern);
1927 meta_type->setTypeUsagePattern(AbstractMetaType::VariantPattern);
1883
1928
1884 } else if (type->isEnum() && meta_type->actualIndirections() == 0) {
1929 } else if (type->isEnum() && meta_type->actualIndirections() == 0) {
1885 meta_type->setTypeUsagePattern(AbstractMetaType::EnumPattern);
1930 meta_type->setTypeUsagePattern(AbstractMetaType::EnumPattern);
1886
1931
1887 } else if (type->isObject()
1932 } else if (type->isObject()
1888 && meta_type->indirections() == 0
1933 && meta_type->indirections() == 0
1889 && meta_type->isReference()) {
1934 && meta_type->isReference()) {
1890 if (((ComplexTypeEntry *) type)->isQObject())
1935 if (((ComplexTypeEntry *) type)->isQObject())
1891 meta_type->setTypeUsagePattern(AbstractMetaType::QObjectPattern);
1936 meta_type->setTypeUsagePattern(AbstractMetaType::QObjectPattern);
1892 else
1937 else
1893 meta_type->setTypeUsagePattern(AbstractMetaType::ObjectPattern);
1938 meta_type->setTypeUsagePattern(AbstractMetaType::ObjectPattern);
1894
1939
1895 } else if (type->isObject()
1940 } else if (type->isObject()
1896 && meta_type->indirections() == 1) {
1941 && meta_type->indirections() == 1) {
1897 if (((ComplexTypeEntry *) type)->isQObject())
1942 if (((ComplexTypeEntry *) type)->isQObject())
1898 meta_type->setTypeUsagePattern(AbstractMetaType::QObjectPattern);
1943 meta_type->setTypeUsagePattern(AbstractMetaType::QObjectPattern);
1899 else
1944 else
1900 meta_type->setTypeUsagePattern(AbstractMetaType::ObjectPattern);
1945 meta_type->setTypeUsagePattern(AbstractMetaType::ObjectPattern);
1901
1946
1902 // const-references to pointers can be passed as pointers
1947 // const-references to pointers can be passed as pointers
1903 if (meta_type->isReference() && meta_type->isConstant()) {
1948 if (meta_type->isReference() && meta_type->isConstant()) {
1904 meta_type->setReference(false);
1949 meta_type->setReference(false);
1905 meta_type->setConstant(false);
1950 meta_type->setConstant(false);
1906 }
1951 }
1907
1952
1908 } else if (type->isContainer() && meta_type->indirections() == 0) {
1953 } else if (type->isContainer() && meta_type->indirections() == 0) {
1909 meta_type->setTypeUsagePattern(AbstractMetaType::ContainerPattern);
1954 meta_type->setTypeUsagePattern(AbstractMetaType::ContainerPattern);
1910
1955
1911 } else if (type->isTemplateArgument()) {
1956 } else if (type->isTemplateArgument()) {
1912
1957
1913 } else if (type->isFlags()
1958 } else if (type->isFlags()
1914 && meta_type->indirections() == 0
1959 && meta_type->indirections() == 0
1915 && (meta_type->isConstant() == meta_type->isReference())) {
1960 && (meta_type->isConstant() == meta_type->isReference())) {
1916 meta_type->setTypeUsagePattern(AbstractMetaType::FlagsPattern);
1961 meta_type->setTypeUsagePattern(AbstractMetaType::FlagsPattern);
1917
1962
1918 } else if (type->isArray()) {
1963 } else if (type->isArray()) {
1919 meta_type->setTypeUsagePattern(AbstractMetaType::ArrayPattern);
1964 meta_type->setTypeUsagePattern(AbstractMetaType::ArrayPattern);
1920
1965
1921 } else if (type->isThread()) {
1966 } else if (type->isThread()) {
1922 Q_ASSERT(meta_type->indirections() == 1);
1967 Q_ASSERT(meta_type->indirections() == 1);
1923 meta_type->setTypeUsagePattern(AbstractMetaType::ThreadPattern);
1968 meta_type->setTypeUsagePattern(AbstractMetaType::ThreadPattern);
1924
1969
1925 } else if (type->isValue()
1970 } else if (type->isValue()
1926 && meta_type->indirections() == 0
1971 && meta_type->indirections() == 0
1927 && (meta_type->isConstant() == meta_type->isReference()
1972 && (meta_type->isConstant() == meta_type->isReference()
1928 || !meta_type->isReference())) {
1973 || !meta_type->isReference())) {
1929 meta_type->setTypeUsagePattern(AbstractMetaType::ValuePattern);
1974 meta_type->setTypeUsagePattern(AbstractMetaType::ValuePattern);
1930
1975
1931 } else {
1976 } else {
1932 meta_type->setTypeUsagePattern(AbstractMetaType::NativePointerPattern);
1977 meta_type->setTypeUsagePattern(AbstractMetaType::NativePointerPattern);
1933 ReportHandler::debugFull(QString("native pointer pattern for '%1'")
1978 ReportHandler::debugFull(QString("native pointer pattern for '%1'")
1934 .arg(meta_type->cppSignature()));
1979 .arg(meta_type->cppSignature()));
1935 }
1980 }
1936 }
1981 }
1937
1982
1938 QString AbstractMetaBuilder::translateDefaultValue(ArgumentModelItem item, AbstractMetaType *type,
1983 QString AbstractMetaBuilder::translateDefaultValue(ArgumentModelItem item, AbstractMetaType *type,
1939 AbstractMetaFunction *fnc, AbstractMetaClass *implementing_class,
1984 AbstractMetaFunction *fnc, AbstractMetaClass *implementing_class,
1940 int argument_index)
1985 int argument_index)
1941 {
1986 {
1942 QString function_name = fnc->name();
1987 QString function_name = fnc->name();
1943 QString class_name = implementing_class->name();
1988 QString class_name = implementing_class->name();
1944
1989
1945 QString replaced_expression = fnc->replacedDefaultExpression(implementing_class, argument_index + 1);
1990 QString replaced_expression = fnc->replacedDefaultExpression(implementing_class, argument_index + 1);
1946 if (fnc->removedDefaultExpression(implementing_class, argument_index +1))
1991 if (fnc->removedDefaultExpression(implementing_class, argument_index +1))
1947 return "";
1992 return "";
1948 if (!replaced_expression.isEmpty())
1993 if (!replaced_expression.isEmpty())
1949 return replaced_expression;
1994 return replaced_expression;
1950
1995
1951 QString expr = item->defaultValueExpression();
1996 QString expr = item->defaultValueExpression();
1952 if (type != 0 && type->isPrimitive()) {
1997 if (type != 0 && type->isPrimitive()) {
1953 if (type->name() == "boolean") {
1998 if (type->name() == "boolean") {
1954 if (expr == "false" || expr=="true") {
1999 if (expr == "false" || expr=="true") {
1955 return expr;
2000 return expr;
1956 } else {
2001 } else {
1957 bool ok = false;
2002 bool ok = false;
1958 int number = expr.toInt(&ok);
2003 int number = expr.toInt(&ok);
1959 if (ok && number)
2004 if (ok && number)
1960 return "true";
2005 return "true";
1961 else
2006 else
1962 return "false";
2007 return "false";
1963 }
2008 }
1964 } else if (expr == "ULONG_MAX") {
2009 } else if (expr == "ULONG_MAX") {
1965 return "Long.MAX_VALUE";
2010 return "Long.MAX_VALUE";
1966 } else if (expr == "QVariant::Invalid") {
2011 } else if (expr == "QVariant::Invalid") {
1967 return QString::number(QVariant::Invalid);
2012 return QString::number(QVariant::Invalid);
1968 } else {
2013 } else {
1969 // This can be an enum or flag so I need to delay the
2014 // This can be an enum or flag so I need to delay the
1970 // translation untill all namespaces are completly
2015 // translation untill all namespaces are completly
1971 // processed. This is done in figureOutEnumValues()
2016 // processed. This is done in figureOutEnumValues()
1972 return expr;
2017 return expr;
1973 }
2018 }
1974 } else if (type != 0 && (type->isFlags() || type->isEnum())) {
2019 } else if (type != 0 && (type->isFlags() || type->isEnum())) {
1975 // Same as with enum explanation above...
2020 // Same as with enum explanation above...
1976 return expr;
2021 return expr;
1977
2022
1978 } else {
2023 } else {
1979
2024
1980 // constructor or functioncall can be a bit tricky...
2025 // constructor or functioncall can be a bit tricky...
1981 if (expr == "QVariant()" || expr == "QModelIndex()") {
2026 if (expr == "QVariant()" || expr == "QModelIndex()") {
1982 return "null";
2027 return "null";
1983 } else if (expr == "QString()") {
2028 } else if (expr == "QString()") {
1984 return "null";
2029 return "null";
1985 } else if (expr.endsWith(")") && expr.contains("::")) {
2030 } else if (expr.endsWith(")") && expr.contains("::")) {
1986 TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(expr.indexOf("::")));
2031 TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(expr.indexOf("::")));
1987 if (typeEntry)
2032 if (typeEntry)
1988 return typeEntry->qualifiedTargetLangName() + "." + expr.right(expr.length() - expr.indexOf("::") - 2);
2033 return typeEntry->qualifiedTargetLangName() + "." + expr.right(expr.length() - expr.indexOf("::") - 2);
1989 } else if (expr.endsWith(")") && type != 0 && type->isValue()) {
2034 } else if (expr.endsWith(")") && type != 0 && type->isValue()) {
1990 int pos = expr.indexOf("(");
2035 int pos = expr.indexOf("(");
1991
2036
1992 TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(pos));
2037 TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(pos));
1993 if (typeEntry)
2038 if (typeEntry)
1994 return "new " + typeEntry->qualifiedTargetLangName() + expr.right(expr.length() - pos);
2039 return "new " + typeEntry->qualifiedTargetLangName() + expr.right(expr.length() - pos);
1995 else
2040 else
1996 return expr;
2041 return expr;
1997 } else if (expr == "0") {
2042 } else if (expr == "0") {
1998 return "null";
2043 return "null";
1999 } else if (type != 0 && (type->isObject() || type->isValue() || expr.contains("::"))) { // like Qt::black passed to a QColor
2044 } else if (type != 0 && (type->isObject() || type->isValue() || expr.contains("::"))) { // like Qt::black passed to a QColor
2000 TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(expr.indexOf("::")));
2045 TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(expr.indexOf("::")));
2001
2046
2002 expr = expr.right(expr.length() - expr.indexOf("::") - 2);
2047 expr = expr.right(expr.length() - expr.indexOf("::") - 2);
2003 if (typeEntry) {
2048 if (typeEntry) {
2004 return "new " + type->typeEntry()->qualifiedTargetLangName() +
2049 return "new " + type->typeEntry()->qualifiedTargetLangName() +
2005 "(" + typeEntry->qualifiedTargetLangName() + "." + expr + ")";
2050 "(" + typeEntry->qualifiedTargetLangName() + "." + expr + ")";
2006 }
2051 }
2007 }
2052 }
2008 }
2053 }
2009
2054
2010 QString warn = QString("unsupported default value '%3' of argument in function '%1', class '%2'")
2055 QString warn = QString("unsupported default value '%3' of argument in function '%1', class '%2'")
2011 .arg(function_name).arg(class_name).arg(item->defaultValueExpression());
2056 .arg(function_name).arg(class_name).arg(item->defaultValueExpression());
2012 ReportHandler::warning(warn);
2057 ReportHandler::warning(warn);
2013
2058
2014 return QString();
2059 return QString();
2015 }
2060 }
2016
2061
2017
2062
2018 bool AbstractMetaBuilder::isQObject(const QString &qualified_name)
2063 bool AbstractMetaBuilder::isQObject(const QString &qualified_name)
2019 {
2064 {
2020 if (qualified_name == "QObject")
2065 if (qualified_name == "QObject")
2021 return true;
2066 return true;
2022
2067
2023 ClassModelItem class_item = m_dom->findClass(qualified_name);
2068 ClassModelItem class_item = m_dom->findClass(qualified_name);
2024
2069
2025 if (!class_item) {
2070 if (!class_item) {
2026 QStringList names = qualified_name.split(QLatin1String("::"));
2071 QStringList names = qualified_name.split(QLatin1String("::"));
2027 NamespaceModelItem ns = model_dynamic_cast<NamespaceModelItem>(m_dom);
2072 NamespaceModelItem ns = model_dynamic_cast<NamespaceModelItem>(m_dom);
2028 for (int i=0; i<names.size() - 1 && ns; ++i)
2073 for (int i=0; i<names.size() - 1 && ns; ++i)
2029 ns = ns->namespaceMap().value(names.at(i));
2074 ns = ns->namespaceMap().value(names.at(i));
2030 if (ns && names.size() >= 2)
2075 if (ns && names.size() >= 2)
2031 class_item = ns->findClass(names.at(names.size() - 1));
2076 class_item = ns->findClass(names.at(names.size() - 1));
2032 }
2077 }
2033
2078
2034 bool isqobject = class_item && class_item->extendsClass("QObject");
2079 bool isqobject = class_item && class_item->extendsClass("QObject");
2035
2080
2036 if (class_item && !isqobject) {
2081 if (class_item && !isqobject) {
2037 QStringList baseClasses = class_item->baseClasses();
2082 QStringList baseClasses = class_item->baseClasses();
2038 for (int i=0; i<baseClasses.count(); ++i) {
2083 for (int i=0; i<baseClasses.count(); ++i) {
2039
2084
2040 isqobject = isQObject(baseClasses.at(i));
2085 isqobject = isQObject(baseClasses.at(i));
2041 if (isqobject)
2086 if (isqobject)
2042 break;
2087 break;
2043 }
2088 }
2044 }
2089 }
2045
2090
2046 return isqobject;
2091 return isqobject;
2047 }
2092 }
2048
2093
2049
2094
2050 bool AbstractMetaBuilder::isEnum(const QStringList &qualified_name)
2095 bool AbstractMetaBuilder::isEnum(const QStringList &qualified_name)
2051 {
2096 {
2052 CodeModelItem item = m_dom->model()->findItem(qualified_name, m_dom->toItem());
2097 CodeModelItem item = m_dom->model()->findItem(qualified_name, m_dom->toItem());
2053 return item && item->kind() == _EnumModelItem::__node_kind;
2098 return item && item->kind() == _EnumModelItem::__node_kind;
2054 }
2099 }
2055
2100
2056 AbstractMetaType *AbstractMetaBuilder::inheritTemplateType(const QList<AbstractMetaType *> &template_types,
2101 AbstractMetaType *AbstractMetaBuilder::inheritTemplateType(const QList<AbstractMetaType *> &template_types,
2057 AbstractMetaType *meta_type, bool *ok)
2102 AbstractMetaType *meta_type, bool *ok)
2058 {
2103 {
2059 if (ok != 0)
2104 if (ok != 0)
2060 *ok = true;
2105 *ok = true;
2061 if (!meta_type || (!meta_type->typeEntry()->isTemplateArgument() && !meta_type->hasInstantiations()))
2106 if (!meta_type || (!meta_type->typeEntry()->isTemplateArgument() && !meta_type->hasInstantiations()))
2062 return meta_type ? meta_type->copy() : 0;
2107 return meta_type ? meta_type->copy() : 0;
2063
2108
2064 AbstractMetaType *returned = meta_type->copy();
2109 AbstractMetaType *returned = meta_type->copy();
2065 returned->setOriginalTemplateType(meta_type->copy());
2110 returned->setOriginalTemplateType(meta_type->copy());
2066
2111
2067 if (returned->typeEntry()->isTemplateArgument()) {
2112 if (returned->typeEntry()->isTemplateArgument()) {
2068 const TemplateArgumentEntry *tae = static_cast<const TemplateArgumentEntry *>(returned->typeEntry());
2113 const TemplateArgumentEntry *tae = static_cast<const TemplateArgumentEntry *>(returned->typeEntry());
2069
2114
2070 // If the template is intantiated with void we special case this as rejecting the functions that use this
2115 // If the template is intantiated with void we special case this as rejecting the functions that use this
2071 // parameter from the instantiation.
2116 // parameter from the instantiation.
2072 if (template_types.size() <= tae->ordinal() || template_types.at(tae->ordinal())->typeEntry()->name() == "void") {
2117 if (template_types.size() <= tae->ordinal() || template_types.at(tae->ordinal())->typeEntry()->name() == "void") {
2073 if (ok != 0)
2118 if (ok != 0)
2074 *ok = false;
2119 *ok = false;
2075 return 0;
2120 return 0;
2076 }
2121 }
2077
2122
2078 AbstractMetaType *t = returned->copy();
2123 AbstractMetaType *t = returned->copy();
2079 t->setTypeEntry(template_types.at(tae->ordinal())->typeEntry());
2124 t->setTypeEntry(template_types.at(tae->ordinal())->typeEntry());
2080 t->setIndirections(template_types.at(tae->ordinal())->indirections() + t->indirections()
2125 t->setIndirections(template_types.at(tae->ordinal())->indirections() + t->indirections()
2081 ? 1
2126 ? 1
2082 : 0);
2127 : 0);
2083 decideUsagePattern(t);
2128 decideUsagePattern(t);
2084
2129
2085 delete returned;
2130 delete returned;
2086 returned = inheritTemplateType(template_types, t, ok);
2131 returned = inheritTemplateType(template_types, t, ok);
2087 if (ok != 0 && !(*ok))
2132 if (ok != 0 && !(*ok))
2088 return 0;
2133 return 0;
2089 }
2134 }
2090
2135
2091 if (returned->hasInstantiations()) {
2136 if (returned->hasInstantiations()) {
2092 QList<AbstractMetaType *> instantiations = returned->instantiations();
2137 QList<AbstractMetaType *> instantiations = returned->instantiations();
2093 for (int i=0; i<instantiations.count(); ++i) {
2138 for (int i=0; i<instantiations.count(); ++i) {
2094 instantiations[i] = inheritTemplateType(template_types, instantiations.at(i), ok);
2139 instantiations[i] = inheritTemplateType(template_types, instantiations.at(i), ok);
2095 if (ok != 0 && !(*ok))
2140 if (ok != 0 && !(*ok))
2096 return 0;
2141 return 0;
2097 }
2142 }
2098 returned->setInstantiations(instantiations);
2143 returned->setInstantiations(instantiations);
2099 }
2144 }
2100
2145
2101 return returned;
2146 return returned;
2102 }
2147 }
2103
2148
2104 bool AbstractMetaBuilder::inheritTemplate(AbstractMetaClass *subclass,
2149 bool AbstractMetaBuilder::inheritTemplate(AbstractMetaClass *subclass,
2105 const AbstractMetaClass *template_class,
2150 const AbstractMetaClass *template_class,
2106 const TypeParser::Info &info)
2151 const TypeParser::Info &info)
2107 {
2152 {
2108 QList<TypeParser::Info> targs = info.template_instantiations;
2153 QList<TypeParser::Info> targs = info.template_instantiations;
2109
2154
2110 QList<AbstractMetaType *> template_types;
2155 QList<AbstractMetaType *> template_types;
2111 foreach (const TypeParser::Info &i, targs) {
2156 foreach (const TypeParser::Info &i, targs) {
2112 TypeEntry *t = TypeDatabase::instance()->findType(i.qualified_name.join("::"));
2157 TypeEntry *t = TypeDatabase::instance()->findType(i.qualified_name.join("::"));
2113
2158
2114 if (t != 0) {
2159 if (t != 0) {
2115 AbstractMetaType *temporary_type = createMetaType();
2160 AbstractMetaType *temporary_type = createMetaType();
2116 temporary_type->setTypeEntry(t);
2161 temporary_type->setTypeEntry(t);
2117 temporary_type->setConstant(i.is_constant);
2162 temporary_type->setConstant(i.is_constant);
2118 temporary_type->setReference(i.is_reference);
2163 temporary_type->setReference(i.is_reference);
2119 temporary_type->setIndirections(i.indirections);
2164 temporary_type->setIndirections(i.indirections);
2120 template_types << temporary_type;
2165 template_types << temporary_type;
2121 }
2166 }
2122 }
2167 }
2123
2168
2124 AbstractMetaFunctionList funcs = subclass->functions();
2169 AbstractMetaFunctionList funcs = subclass->functions();
2125 foreach (const AbstractMetaFunction *function, template_class->functions()) {
2170 foreach (const AbstractMetaFunction *function, template_class->functions()) {
2126
2171
2127 if (function->isModifiedRemoved(TypeSystem::All))
2172 if (function->isModifiedRemoved(TypeSystem::All))
2128 continue;
2173 continue;
2129
2174
2130 AbstractMetaFunction *f = function->copy();
2175 AbstractMetaFunction *f = function->copy();
2131 f->setArguments(AbstractMetaArgumentList());
2176 f->setArguments(AbstractMetaArgumentList());
2132
2177
2133 bool ok = true;
2178 bool ok = true;
2134 AbstractMetaType *ftype = function->type();
2179 AbstractMetaType *ftype = function->type();
2135 f->setType(inheritTemplateType(template_types, ftype, &ok));
2180 f->setType(inheritTemplateType(template_types, ftype, &ok));
2136 if (!ok) {
2181 if (!ok) {
2137 delete f;
2182 delete f;
2138 continue;
2183 continue;
2139 }
2184 }
2140
2185
2141 foreach (AbstractMetaArgument *argument, function->arguments()) {
2186 foreach (AbstractMetaArgument *argument, function->arguments()) {
2142 AbstractMetaType *atype = argument->type();
2187 AbstractMetaType *atype = argument->type();
2143
2188
2144 AbstractMetaArgument *arg = argument->copy();
2189 AbstractMetaArgument *arg = argument->copy();
2145 arg->setType(inheritTemplateType(template_types, atype, &ok));
2190 arg->setType(inheritTemplateType(template_types, atype, &ok));
2146 if (!ok)
2191 if (!ok)
2147 break;
2192 break;
2148 f->addArgument(arg);
2193 f->addArgument(arg);
2149 }
2194 }
2150
2195
2151 if (!ok) {
2196 if (!ok) {
2152 delete f;
2197 delete f;
2153 continue ;
2198 continue ;
2154 }
2199 }
2155
2200
2156 // There is no base class in java to inherit from here, so the
2201 // There is no base class in java to inherit from here, so the
2157 // template instantiation is the class that implements the function..
2202 // template instantiation is the class that implements the function..
2158 f->setImplementingClass(subclass);
2203 f->setImplementingClass(subclass);
2159
2204
2160 // We also set it as the declaring class, since the superclass is
2205 // We also set it as the declaring class, since the superclass is
2161 // supposed to disappear. This allows us to make certain function modifications
2206 // supposed to disappear. This allows us to make certain function modifications
2162 // on the inherited functions.
2207 // on the inherited functions.
2163 f->setDeclaringClass(subclass);
2208 f->setDeclaringClass(subclass);
2164
2209
2165
2210
2166 if (f->isConstructor() && subclass->isTypeAlias()) {
2211 if (f->isConstructor() && subclass->isTypeAlias()) {
2167 f->setName(subclass->name());
2212 f->setName(subclass->name());
2168 } else if (f->isConstructor()) {
2213 } else if (f->isConstructor()) {
2169 delete f;
2214 delete f;
2170 continue;
2215 continue;
2171 }
2216 }
2172
2217
2173 // if the instantiation has a function named the same as an existing
2218 // if the instantiation has a function named the same as an existing
2174 // function we have shadowing so we need to skip it.
2219 // function we have shadowing so we need to skip it.
2175 bool found = false;
2220 bool found = false;
2176 for (int i=0; i<funcs.size(); ++i) {
2221 for (int i=0; i<funcs.size(); ++i) {
2177 if (funcs.at(i)->name() == f->name()) {
2222 if (funcs.at(i)->name() == f->name()) {
2178 found = true;
2223 found = true;
2179 continue;
2224 continue;
2180 }
2225 }
2181 }
2226 }
2182 if (found) {
2227 if (found) {
2183 delete f;
2228 delete f;
2184 continue;
2229 continue;
2185 }
2230 }
2186
2231
2187 ComplexTypeEntry *te = subclass->typeEntry();
2232 ComplexTypeEntry *te = subclass->typeEntry();
2188 FunctionModificationList mods = function->modifications(template_class);
2233 FunctionModificationList mods = function->modifications(template_class);
2189 for (int i=0; i<mods.size(); ++i) {
2234 for (int i=0; i<mods.size(); ++i) {
2190 FunctionModification mod = mods.at(i);
2235 FunctionModification mod = mods.at(i);
2191 mod.signature = f->minimalSignature();
2236 mod.signature = f->minimalSignature();
2192
2237
2193 // If we ever need it... Below is the code to do
2238 // If we ever need it... Below is the code to do
2194 // substitution of the template instantation type inside
2239 // substitution of the template instantation type inside
2195 // injected code..
2240 // injected code..
2196 #if 0
2241 #if 0
2197 if (mod.modifiers & Modification::CodeInjection) {
2242 if (mod.modifiers & Modification::CodeInjection) {
2198 for (int j=0; j<template_types.size(); ++j) {
2243 for (int j=0; j<template_types.size(); ++j) {
2199 CodeSnip &snip = mod.snips.last();
2244 CodeSnip &snip = mod.snips.last();
2200 QString code = snip.code();
2245 QString code = snip.code();
2201 code.replace(QString::fromLatin1("$$QT_TEMPLATE_%1$$").arg(j),
2246 code.replace(QString::fromLatin1("$$QT_TEMPLATE_%1$$").arg(j),
2202 template_types.at(j)->typeEntry()->qualifiedCppName());
2247 template_types.at(j)->typeEntry()->qualifiedCppName());
2203 snip.codeList.clear();
2248 snip.codeList.clear();
2204 snip.addCode(code);
2249 snip.addCode(code);
2205 }
2250 }
2206 }
2251 }
2207 #endif
2252 #endif
2208 te->addFunctionModification(mod);
2253 te->addFunctionModification(mod);
2209 }
2254 }
2210
2255
2211 subclass->addFunction(f);
2256 subclass->addFunction(f);
2212 }
2257 }
2213
2258
2214 // Clean up
2259 // Clean up
2215 foreach (AbstractMetaType *type, template_types) {
2260 foreach (AbstractMetaType *type, template_types) {
2216 delete type;
2261 delete type;
2217 }
2262 }
2218
2263
2219
2264
2220 {
2265 {
2221 subclass->setTemplateBaseClass(template_class);
2266 subclass->setTemplateBaseClass(template_class);
2222
2267
2223 subclass->setInterfaces(template_class->interfaces());
2268 subclass->setInterfaces(template_class->interfaces());
2224 subclass->setBaseClass(template_class->baseClass());
2269 subclass->setBaseClass(template_class->baseClass());
2225 }
2270 }
2226
2271
2227 return true;
2272 return true;
2228 }
2273 }
2229
2274
2230 void AbstractMetaBuilder::parseQ_Property(AbstractMetaClass *meta_class, const QStringList &declarations)
2275 void AbstractMetaBuilder::parseQ_Property(AbstractMetaClass *meta_class, const QStringList &declarations)
2231 {
2276 {
2232 for (int i=0; i<declarations.size(); ++i) {
2277 for (int i=0; i<declarations.size(); ++i) {
2233 QString p = declarations.at(i);
2278 QString p = declarations.at(i);
2234
2279
2235 QStringList l = p.split(QLatin1String(" "));
2280 QStringList l = p.split(QLatin1String(" "));
2236
2281
2237
2282
2238 QStringList qualifiedScopeName = currentScope()->qualifiedName();
2283 QStringList qualifiedScopeName = currentScope()->qualifiedName();
2239 bool ok = false;
2284 bool ok = false;
2240 AbstractMetaType *type = 0;
2285 AbstractMetaType *type = 0;
2241 QString scope;
2286 QString scope;
2242 for (int j=qualifiedScopeName.size(); j>=0; --j) {
2287 for (int j=qualifiedScopeName.size(); j>=0; --j) {
2243 scope = j > 0 ? QStringList(qualifiedScopeName.mid(0, j)).join("::") + "::" : QString();
2288 scope = j > 0 ? QStringList(qualifiedScopeName.mid(0, j)).join("::") + "::" : QString();
2244 TypeInfo info;
2289 TypeInfo info;
2245 info.setQualifiedName((scope + l.at(0)).split("::"));
2290 info.setQualifiedName((scope + l.at(0)).split("::"));
2246
2291
2247 type = translateType(info, &ok);
2292 type = translateType(info, &ok);
2248 if (type != 0 && ok) {
2293 if (type != 0 && ok) {
2249 break;
2294 break;
2250 }
2295 }
2251 }
2296 }
2252
2297
2253 if (type == 0 || !ok) {
2298 if (type == 0 || !ok) {
2254 ReportHandler::warning(QString("Unable to decide type of property: '%1' in class '%2'")
2299 ReportHandler::warning(QString("Unable to decide type of property: '%1' in class '%2'")
2255 .arg(l.at(0)).arg(meta_class->name()));
2300 .arg(l.at(0)).arg(meta_class->name()));
2256 continue;
2301 continue;
2257 }
2302 }
2258
2303
2259 QString typeName = scope + l.at(0);
2304 QString typeName = scope + l.at(0);
2260
2305
2261 QPropertySpec *spec = new QPropertySpec(type->typeEntry());
2306 QPropertySpec *spec = new QPropertySpec(type->typeEntry());
2262 spec->setName(l.at(1));
2307 spec->setName(l.at(1));
2263 spec->setIndex(i);
2308 spec->setIndex(i);
2264
2309
2265 for (int pos=2; pos+1<l.size(); pos+=2) {
2310 for (int pos=2; pos+1<l.size(); pos+=2) {
2266 if (l.at(pos) == QLatin1String("READ"))
2311 if (l.at(pos) == QLatin1String("READ"))
2267 spec->setRead(l.at(pos+1));
2312 spec->setRead(l.at(pos+1));
2268 else if (l.at(pos) == QLatin1String("WRITE"))
2313 else if (l.at(pos) == QLatin1String("WRITE"))
2269 spec->setWrite(l.at(pos+1));
2314 spec->setWrite(l.at(pos+1));
2270 else if (l.at(pos) == QLatin1String("DESIGNABLE"))
2315 else if (l.at(pos) == QLatin1String("DESIGNABLE"))
2271 spec->setDesignable(l.at(pos+1));
2316 spec->setDesignable(l.at(pos+1));
2272 else if (l.at(pos) == QLatin1String("RESET"))
2317 else if (l.at(pos) == QLatin1String("RESET"))
2273 spec->setReset(l.at(pos+1));
2318 spec->setReset(l.at(pos+1));
2274 }
2319 }
2275
2320
2276 meta_class->addPropertySpec(spec);
2321 meta_class->addPropertySpec(spec);
2277 delete type;
2322 delete type;
2278 }
2323 }
2279 }
2324 }
2280
2325
2281 static void hide_functions(const AbstractMetaFunctionList &l) {
2326 static void hide_functions(const AbstractMetaFunctionList &l) {
2282 foreach (AbstractMetaFunction *f, l) {
2327 foreach (AbstractMetaFunction *f, l) {
2283 FunctionModification mod;
2328 FunctionModification mod;
2284 mod.signature = f->minimalSignature();
2329 mod.signature = f->minimalSignature();
2285 mod.modifiers = FunctionModification::Private;
2330 mod.modifiers = FunctionModification::Private;
2286 ((ComplexTypeEntry *) f->implementingClass()->typeEntry())->addFunctionModification(mod);
2331 ((ComplexTypeEntry *) f->implementingClass()->typeEntry())->addFunctionModification(mod);
2287 }
2332 }
2288 }
2333 }
2289
2334
2290 static void remove_function(AbstractMetaFunction *f) {
2335 static void remove_function(AbstractMetaFunction *f) {
2291 FunctionModification mod;
2336 FunctionModification mod;
2292 mod.removal = TypeSystem::All;
2337 mod.removal = TypeSystem::All;
2293 mod.signature = f->minimalSignature();
2338 mod.signature = f->minimalSignature();
2294 ((ComplexTypeEntry *) f->implementingClass()->typeEntry())->addFunctionModification(mod);
2339 ((ComplexTypeEntry *) f->implementingClass()->typeEntry())->addFunctionModification(mod);
2295 }
2340 }
2296
2341
2297 static AbstractMetaFunctionList filter_functions(const AbstractMetaFunctionList &lst, QSet<QString> *signatures)
2342 static AbstractMetaFunctionList filter_functions(const AbstractMetaFunctionList &lst, QSet<QString> *signatures)
2298 {
2343 {
2299 AbstractMetaFunctionList functions;
2344 AbstractMetaFunctionList functions;
2300 foreach (AbstractMetaFunction *f, lst) {
2345 foreach (AbstractMetaFunction *f, lst) {
2301 QString signature = f->minimalSignature();
2346 QString signature = f->minimalSignature();
2302 int start = signature.indexOf(QLatin1Char('(')) + 1;
2347 int start = signature.indexOf(QLatin1Char('(')) + 1;
2303 int end = signature.lastIndexOf(QLatin1Char(')'));
2348 int end = signature.lastIndexOf(QLatin1Char(')'));
2304 signature = signature.mid(start, end - start);
2349 signature = signature.mid(start, end - start);
2305 if (signatures->contains(signature)) {
2350 if (signatures->contains(signature)) {
2306 remove_function(f);
2351 remove_function(f);
2307 continue;
2352 continue;
2308 }
2353 }
2309 (*signatures) << signature;
2354 (*signatures) << signature;
2310 functions << f;
2355 functions << f;
2311 }
2356 }
2312 return functions;
2357 return functions;
2313 }
2358 }
2314
2359
2315 void AbstractMetaBuilder::setupEquals(AbstractMetaClass *cls)
2360 void AbstractMetaBuilder::setupEquals(AbstractMetaClass *cls)
2316 {
2361 {
2317 AbstractMetaFunctionList equals;
2362 AbstractMetaFunctionList equals;
2318 AbstractMetaFunctionList nequals;
2363 AbstractMetaFunctionList nequals;
2319
2364
2320 QString op_equals = QLatin1String("operator_equal");
2365 QString op_equals = QLatin1String("operator_equal");
2321 QString op_nequals = QLatin1String("operator_not_equal");
2366 QString op_nequals = QLatin1String("operator_not_equal");
2322
2367
2323 AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements
2368 AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements
2324 | AbstractMetaClass::NotRemovedFromTargetLang);
2369 | AbstractMetaClass::NotRemovedFromTargetLang);
2325 foreach (AbstractMetaFunction *f, functions) {
2370 foreach (AbstractMetaFunction *f, functions) {
2326 if (f->name() == op_equals)
2371 if (f->name() == op_equals)
2327 equals << f;
2372 equals << f;
2328 else if (f->name() == op_nequals)
2373 else if (f->name() == op_nequals)
2329 nequals << f;
2374 nequals << f;
2330 }
2375 }
2331
2376
2332 if (equals.size() || nequals.size()) {
2377 if (equals.size() || nequals.size()) {
2333 if (!cls->hasHashFunction()) {
2378 if (!cls->hasHashFunction()) {
2334 ReportHandler::warning(QString::fromLatin1("Class '%1' has equals operators but no qHash() function")
2379 ReportHandler::warning(QString::fromLatin1("Class '%1' has equals operators but no qHash() function")
2335 .arg(cls->name()));
2380 .arg(cls->name()));
2336 }
2381 }
2337
2382
2338 hide_functions(equals);
2383 hide_functions(equals);
2339 hide_functions(nequals);
2384 hide_functions(nequals);
2340
2385
2341 // We only need == if we have both == and !=, and one == for
2386 // We only need == if we have both == and !=, and one == for
2342 // each signature type, like QDateTime::==(QDate) and (QTime)
2387 // each signature type, like QDateTime::==(QDate) and (QTime)
2343 // if such a thing exists...
2388 // if such a thing exists...
2344 QSet<QString> func_signatures;
2389 QSet<QString> func_signatures;
2345 cls->setEqualsFunctions(filter_functions(equals, &func_signatures));
2390 cls->setEqualsFunctions(filter_functions(equals, &func_signatures));
2346 cls->setNotEqualsFunctions(filter_functions(nequals, &func_signatures));
2391 cls->setNotEqualsFunctions(filter_functions(nequals, &func_signatures));
2347 }
2392 }
2348 }
2393 }
2349
2394
2350 void AbstractMetaBuilder::setupComparable(AbstractMetaClass *cls)
2395 void AbstractMetaBuilder::setupComparable(AbstractMetaClass *cls)
2351 {
2396 {
2352 AbstractMetaFunctionList greater;
2397 AbstractMetaFunctionList greater;
2353 AbstractMetaFunctionList greaterEquals;
2398 AbstractMetaFunctionList greaterEquals;
2354 AbstractMetaFunctionList less;
2399 AbstractMetaFunctionList less;
2355 AbstractMetaFunctionList lessEquals;
2400 AbstractMetaFunctionList lessEquals;
2356
2401
2357 QString op_greater = QLatin1String("operator_greater");
2402 QString op_greater = QLatin1String("operator_greater");
2358 QString op_greater_eq = QLatin1String("operator_greater_or_equal");
2403 QString op_greater_eq = QLatin1String("operator_greater_or_equal");
2359 QString op_less = QLatin1String("operator_less");
2404 QString op_less = QLatin1String("operator_less");
2360 QString op_less_eq = QLatin1String("operator_less_or_equal");
2405 QString op_less_eq = QLatin1String("operator_less_or_equal");
2361
2406
2362 AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements
2407 AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements
2363 | AbstractMetaClass::NotRemovedFromTargetLang);
2408 | AbstractMetaClass::NotRemovedFromTargetLang);
2364 foreach (AbstractMetaFunction *f, functions) {
2409 foreach (AbstractMetaFunction *f, functions) {
2365 if (f->name() == op_greater)
2410 if (f->name() == op_greater)
2366 greater << f;
2411 greater << f;
2367 else if (f->name() == op_greater_eq)
2412 else if (f->name() == op_greater_eq)
2368 greaterEquals << f;
2413 greaterEquals << f;
2369 else if (f->name() == op_less)
2414 else if (f->name() == op_less)
2370 less << f;
2415 less << f;
2371 else if (f->name() == op_less_eq)
2416 else if (f->name() == op_less_eq)
2372 lessEquals << f;
2417 lessEquals << f;
2373 }
2418 }
2374
2419
2375 bool hasEquals = cls->equalsFunctions().size() || cls->notEqualsFunctions().size();
2420 bool hasEquals = cls->equalsFunctions().size() || cls->notEqualsFunctions().size();
2376
2421
2377 // Conditions for comparable is:
2422 // Conditions for comparable is:
2378 // >, ==, < - The basic case
2423 // >, ==, < - The basic case
2379 // >, == - Less than becomes else case
2424 // >, == - Less than becomes else case
2380 // <, == - Greater than becomes else case
2425 // <, == - Greater than becomes else case
2381 // >=, <= - if (<= && >=) -> equal
2426 // >=, <= - if (<= && >=) -> equal
2382 bool mightBeComparable = greater.size() || greaterEquals.size() || less.size() || lessEquals.size()
2427 bool mightBeComparable = greater.size() || greaterEquals.size() || less.size() || lessEquals.size()
2383 || greaterEquals.size() == 1 || lessEquals.size() == 1;
2428 || greaterEquals.size() == 1 || lessEquals.size() == 1;
2384
2429
2385 if (mightBeComparable) {
2430 if (mightBeComparable) {
2386 QSet<QString> signatures;
2431 QSet<QString> signatures;
2387
2432
2388 // We only hide the original functions if we are able to make a compareTo() method
2433 // We only hide the original functions if we are able to make a compareTo() method
2389 bool wasComparable = false;
2434 bool wasComparable = false;
2390
2435
2391 // The three upper cases, prefer the <, == approach
2436 // The three upper cases, prefer the <, == approach
2392 if (hasEquals && (greater.size() || less.size())) {
2437 if (hasEquals && (greater.size() || less.size())) {
2393 cls->setLessThanFunctions(filter_functions(less, &signatures));
2438 cls->setLessThanFunctions(filter_functions(less, &signatures));
2394 cls->setGreaterThanFunctions(filter_functions(greater, &signatures));
2439 cls->setGreaterThanFunctions(filter_functions(greater, &signatures));
2395 filter_functions(greaterEquals, &signatures);
2440 filter_functions(greaterEquals, &signatures);
2396 filter_functions(lessEquals, &signatures);
2441 filter_functions(lessEquals, &signatures);
2397 wasComparable = true;
2442 wasComparable = true;
2398 } else if (hasEquals && (greaterEquals.size() || lessEquals.size())) {
2443 } else if (hasEquals && (greaterEquals.size() || lessEquals.size())) {
2399 cls->setLessThanEqFunctions(filter_functions(lessEquals, &signatures));
2444 cls->setLessThanEqFunctions(filter_functions(lessEquals, &signatures));
2400 cls->setGreaterThanEqFunctions(filter_functions(greaterEquals, &signatures));
2445 cls->setGreaterThanEqFunctions(filter_functions(greaterEquals, &signatures));
2401 wasComparable = true;
2446 wasComparable = true;
2402 } else if (greaterEquals.size() == 1 || lessEquals.size() == 1) {
2447 } else if (greaterEquals.size() == 1 || lessEquals.size() == 1) {
2403 cls->setGreaterThanEqFunctions(greaterEquals);
2448 cls->setGreaterThanEqFunctions(greaterEquals);
2404 cls->setLessThanEqFunctions(lessEquals);
2449 cls->setLessThanEqFunctions(lessEquals);
2405 filter_functions(less, &signatures);
2450 filter_functions(less, &signatures);
2406 filter_functions(greater, &signatures);
2451 filter_functions(greater, &signatures);
2407 wasComparable = true;
2452 wasComparable = true;
2408 }
2453 }
2409
2454
2410 if (wasComparable) {
2455 if (wasComparable) {
2411 hide_functions(greater);
2456 hide_functions(greater);
2412 hide_functions(greaterEquals);
2457 hide_functions(greaterEquals);
2413 hide_functions(less);
2458 hide_functions(less);
2414 hide_functions(lessEquals);
2459 hide_functions(lessEquals);
2415 }
2460 }
2416 }
2461 }
2417
2462
2418 }
2463 }
2419
2464
2420 void AbstractMetaBuilder::setupClonable(AbstractMetaClass *cls)
2465 void AbstractMetaBuilder::setupClonable(AbstractMetaClass *cls)
2421 {
2466 {
2422 QString op_assign = QLatin1String("operator_assign");
2467 QString op_assign = QLatin1String("operator_assign");
2423
2468
2424 AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements);
2469 AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements);
2425 foreach (AbstractMetaFunction *f, functions) {
2470 foreach (AbstractMetaFunction *f, functions) {
2426 if ((f->name() == op_assign || f->isConstructor()) && f->isPublic()) {
2471 if ((f->name() == op_assign || f->isConstructor()) && f->isPublic()) {
2427 AbstractMetaArgumentList arguments = f->arguments();
2472 AbstractMetaArgumentList arguments = f->arguments();
2428 if (arguments.size() == 1) {
2473 if (arguments.size() == 1) {
2429 if (cls->typeEntry()->qualifiedCppName() == arguments.at(0)->type()->typeEntry()->qualifiedCppName()) {
2474 if (cls->typeEntry()->qualifiedCppName() == arguments.at(0)->type()->typeEntry()->qualifiedCppName()) {
2430 if (cls->typeEntry()->isValue()) {
2475 if (cls->typeEntry()->isValue()) {
2431 cls->setHasCloneOperator(true);
2476 cls->setHasCloneOperator(true);
2432 return;
2477 return;
2433 }
2478 }
2434 }
2479 }
2435 }
2480 }
2436 }
2481 }
2437 }
2482 }
2438 }
2483 }
2439
2484
2440 static void write_reject_log_file(const QString &name,
2485 static void write_reject_log_file(const QString &name,
2441 const QMap<QString, AbstractMetaBuilder::RejectReason> &rejects)
2486 const QMap<QString, AbstractMetaBuilder::RejectReason> &rejects)
2442 {
2487 {
2443 QFile f(name);
2488 QFile f(name);
2444 if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
2489 if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
2445 ReportHandler::warning(QString("failed to write log file: '%1'")
2490 ReportHandler::warning(QString("failed to write log file: '%1'")
2446 .arg(f.fileName()));
2491 .arg(f.fileName()));
2447 return;
2492 return;
2448 }
2493 }
2449
2494
2450 QTextStream s(&f);
2495 QTextStream s(&f);
2451
2496
2452
2497
2453 for (int reason=0; reason<AbstractMetaBuilder::NoReason; ++reason) {
2498 for (int reason=0; reason<AbstractMetaBuilder::NoReason; ++reason) {
2454 s << QString(72, '*') << endl;
2499 s << QString(72, '*') << endl;
2455 switch (reason) {
2500 switch (reason) {
2456 case AbstractMetaBuilder::NotInTypeSystem:
2501 case AbstractMetaBuilder::NotInTypeSystem:
2457 s << "Not in type system";
2502 s << "Not in type system";
2458 break;
2503 break;
2459 case AbstractMetaBuilder::GenerationDisabled:
2504 case AbstractMetaBuilder::GenerationDisabled:
2460 s << "Generation disabled by type system";
2505 s << "Generation disabled by type system";
2461 break;
2506 break;
2462 case AbstractMetaBuilder::RedefinedToNotClass:
2507 case AbstractMetaBuilder::RedefinedToNotClass:
2463 s << "Type redefined to not be a class";
2508 s << "Type redefined to not be a class";
2464 break;
2509 break;
2465
2510
2466 case AbstractMetaBuilder::UnmatchedReturnType:
2511 case AbstractMetaBuilder::UnmatchedReturnType:
2467 s << "Unmatched return type";
2512 s << "Unmatched return type";
2468 break;
2513 break;
2469
2514
2470 case AbstractMetaBuilder::UnmatchedArgumentType:
2515 case AbstractMetaBuilder::UnmatchedArgumentType:
2471 s << "Unmatched argument type";
2516 s << "Unmatched argument type";
2472 break;
2517 break;
2473
2518
2474 default:
2519 default:
2475 s << "unknown reason";
2520 s << "unknown reason";
2476 break;
2521 break;
2477 }
2522 }
2478
2523
2479 s << endl;
2524 s << endl;
2480
2525
2481 for (QMap<QString, AbstractMetaBuilder::RejectReason>::const_iterator it = rejects.constBegin();
2526 for (QMap<QString, AbstractMetaBuilder::RejectReason>::const_iterator it = rejects.constBegin();
2482 it != rejects.constEnd(); ++it) {
2527 it != rejects.constEnd(); ++it) {
2483 if (it.value() != reason)
2528 if (it.value() != reason)
2484 continue;
2529 continue;
2485 s << " - " << it.key() << endl;
2530 s << " - " << it.key() << endl;
2486 }
2531 }
2487
2532
2488 s << QString(72, '*') << endl << endl;
2533 s << QString(72, '*') << endl << endl;
2489 }
2534 }
2490
2535
2491 }
2536 }
2492
2537
2493
2538
2494 void AbstractMetaBuilder::dumpLog()
2539 void AbstractMetaBuilder::dumpLog()
2495 {
2540 {
2496 write_reject_log_file("mjb_rejected_classes.log", m_rejected_classes);
2541 write_reject_log_file("mjb_rejected_classes.log", m_rejected_classes);
2497 write_reject_log_file("mjb_rejected_enums.log", m_rejected_enums);
2542 write_reject_log_file("mjb_rejected_enums.log", m_rejected_enums);
2498 write_reject_log_file("mjb_rejected_functions.log", m_rejected_functions);
2543 write_reject_log_file("mjb_rejected_functions.log", m_rejected_functions);
2499 write_reject_log_file("mjb_rejected_fields.log", m_rejected_fields);
2544 write_reject_log_file("mjb_rejected_fields.log", m_rejected_fields);
2500 }
2545 }
2501
2546
2502 AbstractMetaClassList AbstractMetaBuilder::classesTopologicalSorted() const
2547 AbstractMetaClassList AbstractMetaBuilder::classesTopologicalSorted() const
2503 {
2548 {
2504 AbstractMetaClassList res;
2549 AbstractMetaClassList res;
2505
2550
2506 AbstractMetaClassList classes = m_meta_classes;
2551 AbstractMetaClassList classes = m_meta_classes;
2507 qSort(classes);
2552 qSort(classes);
2508
2553
2509 QSet<AbstractMetaClass*> noDependency;
2554 QSet<AbstractMetaClass*> noDependency;
2510 QHash<AbstractMetaClass*, QSet<AbstractMetaClass* >* > hash;
2555 QHash<AbstractMetaClass*, QSet<AbstractMetaClass* >* > hash;
2511 foreach (AbstractMetaClass *cls, classes) {
2556 foreach (AbstractMetaClass *cls, classes) {
2512 QSet<AbstractMetaClass* > *depends = new QSet<AbstractMetaClass* >();
2557 QSet<AbstractMetaClass* > *depends = new QSet<AbstractMetaClass* >();
2513
2558
2514 if (cls->baseClass())
2559 if (cls->baseClass())
2515 depends->insert(cls->baseClass());
2560 depends->insert(cls->baseClass());
2516
2561
2517 foreach (AbstractMetaClass *interface, cls->interfaces()) {
2562 foreach (AbstractMetaClass *interface, cls->interfaces()) {
2518 AbstractMetaClass *impl = interface->primaryInterfaceImplementor();
2563 AbstractMetaClass *impl = interface->primaryInterfaceImplementor();
2519 if (impl == cls)
2564 if (impl == cls)
2520 continue;
2565 continue;
2521 depends->insert(impl);
2566 depends->insert(impl);
2522 }
2567 }
2523
2568
2524 if (depends->empty()) {
2569 if (depends->empty()) {
2525 noDependency.insert(cls);
2570 noDependency.insert(cls);
2526 } else {
2571 } else {
2527 hash.insert(cls, depends);
2572 hash.insert(cls, depends);
2528 }
2573 }
2529 }
2574 }
2530
2575
2531 while (!noDependency.empty()) {
2576 while (!noDependency.empty()) {
2532 foreach (AbstractMetaClass *cls, noDependency.values()) {
2577 foreach (AbstractMetaClass *cls, noDependency.values()) {
2533 if(!cls->isInterface())
2578 if(!cls->isInterface())
2534 res.append(cls);
2579 res.append(cls);
2535 noDependency.remove(cls);
2580 noDependency.remove(cls);
2536 QHashIterator<AbstractMetaClass*, QSet<AbstractMetaClass* >* > i(hash);
2581 QHashIterator<AbstractMetaClass*, QSet<AbstractMetaClass* >* > i(hash);
2537 while (i.hasNext()) {
2582 while (i.hasNext()) {
2538 i.next();
2583 i.next();
2539 i.value()->remove(cls);
2584 i.value()->remove(cls);
2540 if (i.value()->empty()) {
2585 if (i.value()->empty()) {
2541 AbstractMetaClass *key = i.key();
2586 AbstractMetaClass *key = i.key();
2542 noDependency.insert(key);
2587 noDependency.insert(key);
2543 hash.remove(key);
2588 hash.remove(key);
2544 delete(i.value());
2589 delete(i.value());
2545 }
2590 }
2546 }
2591 }
2547 }
2592 }
2548 }
2593 }
2549
2594
2550 if (!noDependency.empty() || !hash.empty()) {
2595 if (!noDependency.empty() || !hash.empty()) {
2551 qWarning("dependency graph was cyclic.");
2596 qWarning("dependency graph was cyclic.");
2552 }
2597 }
2553
2598
2554 return res;
2599 return res;
2555 }
2600 }
@@ -1,160 +1,162
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 #ifndef ABSTRACTMETABUILDER_H
24 #ifndef ABSTRACTMETABUILDER_H
25 #define ABSTRACTMETABUILDER_H
25 #define ABSTRACTMETABUILDER_H
26
26
27 #include "codemodel.h"
27 #include "codemodel.h"
28 #include "abstractmetalang.h"
28 #include "abstractmetalang.h"
29 #include "typesystem.h"
29 #include "typesystem.h"
30 #include "typeparser.h"
30 #include "typeparser.h"
31
31
32 #include <QtCore/QSet>
32 #include <QtCore/QSet>
33
33
34 class AbstractMetaBuilder
34 class AbstractMetaBuilder
35 {
35 {
36 public:
36 public:
37 enum RejectReason {
37 enum RejectReason {
38 NotInTypeSystem,
38 NotInTypeSystem,
39 GenerationDisabled,
39 GenerationDisabled,
40 RedefinedToNotClass,
40 RedefinedToNotClass,
41 UnmatchedArgumentType,
41 UnmatchedArgumentType,
42 UnmatchedReturnType,
42 UnmatchedReturnType,
43 NoReason
43 NoReason
44 };
44 };
45
45
46 AbstractMetaBuilder();
46 AbstractMetaBuilder();
47 virtual ~AbstractMetaBuilder() {};
47 virtual ~AbstractMetaBuilder() {};
48
48
49 AbstractMetaClassList classes() const { return m_meta_classes; }
49 AbstractMetaClassList classes() const { return m_meta_classes; }
50 AbstractMetaClassList classesTopologicalSorted() const;
50 AbstractMetaClassList classesTopologicalSorted() const;
51
51
52 FileModelItem model() const { return m_dom; }
52 FileModelItem model() const { return m_dom; }
53 void setModel(FileModelItem item) { m_dom = item; }
53 void setModel(FileModelItem item) { m_dom = item; }
54
54
55
55
56 ScopeModelItem popScope() { return m_scopes.takeLast(); }
56 ScopeModelItem popScope() { return m_scopes.takeLast(); }
57 void pushScope(ScopeModelItem item) { m_scopes << item; }
57 void pushScope(ScopeModelItem item) { m_scopes << item; }
58 ScopeModelItem currentScope() const { return m_scopes.last(); }
58 ScopeModelItem currentScope() const { return m_scopes.last(); }
59
59
60 QString fileName() const { return m_file_name; }
60 QString fileName() const { return m_file_name; }
61 void setFileName(const QString &fileName) { m_file_name = fileName; }
61 void setFileName(const QString &fileName) { m_file_name = fileName; }
62
62
63 void dumpLog();
63 void dumpLog();
64
64
65 bool build();
65 bool build();
66
66
67 void figureOutEnumValuesForClass(AbstractMetaClass *meta_class, QSet<AbstractMetaClass *> *classes);
67 void figureOutEnumValuesForClass(AbstractMetaClass *meta_class, QSet<AbstractMetaClass *> *classes);
68 int figureOutEnumValue(const QString &name, int value, AbstractMetaEnum *meta_enum, AbstractMetaFunction *meta_function = 0);
68 int figureOutEnumValue(const QString &name, int value, AbstractMetaEnum *meta_enum, AbstractMetaFunction *meta_function = 0);
69 void figureOutEnumValues();
69 void figureOutEnumValues();
70 void figureOutDefaultEnumArguments();
70 void figureOutDefaultEnumArguments();
71
71
72 void addAbstractMetaClass(AbstractMetaClass *cls);
72 void addAbstractMetaClass(AbstractMetaClass *cls);
73 AbstractMetaClass *traverseTypeAlias(TypeAliasModelItem item);
73 AbstractMetaClass *traverseTypeAlias(TypeAliasModelItem item);
74 AbstractMetaClass *traverseClass(ClassModelItem item);
74 AbstractMetaClass *traverseClass(ClassModelItem item);
75 bool setupInheritance(AbstractMetaClass *meta_class);
75 bool setupInheritance(AbstractMetaClass *meta_class);
76 AbstractMetaClass *traverseNamespace(NamespaceModelItem item);
76 AbstractMetaClass *traverseNamespace(NamespaceModelItem item);
77 AbstractMetaEnum *traverseEnum(EnumModelItem item, AbstractMetaClass *enclosing, const QSet<QString> &enumsDeclarations);
77 AbstractMetaEnum *traverseEnum(EnumModelItem item, AbstractMetaClass *enclosing, const QSet<QString> &enumsDeclarations);
78 void traverseEnums(ScopeModelItem item, AbstractMetaClass *parent, const QStringList &enumsDeclarations);
78 void traverseEnums(ScopeModelItem item, AbstractMetaClass *parent, const QStringList &enumsDeclarations);
79 void traverseFunctions(ScopeModelItem item, AbstractMetaClass *parent);
79 void traverseFunctions(ScopeModelItem item, AbstractMetaClass *parent);
80 void traverseFields(ScopeModelItem item, AbstractMetaClass *parent);
80 void traverseFields(ScopeModelItem item, AbstractMetaClass *parent);
81 void traverseStreamOperator(FunctionModelItem function_item);
81 void traverseStreamOperator(FunctionModelItem function_item);
82 void traverseCompareOperator(FunctionModelItem item);
82 void traverseCompareOperator(FunctionModelItem item);
83 void traverseBinaryArithmeticOperator(FunctionModelItem item);
84
83 AbstractMetaFunction *traverseFunction(FunctionModelItem function);
85 AbstractMetaFunction *traverseFunction(FunctionModelItem function);
84 AbstractMetaField *traverseField(VariableModelItem field, const AbstractMetaClass *cls);
86 AbstractMetaField *traverseField(VariableModelItem field, const AbstractMetaClass *cls);
85 void checkFunctionModifications();
87 void checkFunctionModifications();
86 void registerHashFunction(FunctionModelItem function_item);
88 void registerHashFunction(FunctionModelItem function_item);
87 void registerToStringCapability(FunctionModelItem function_item);
89 void registerToStringCapability(FunctionModelItem function_item);
88
90
89 void parseQ_Property(AbstractMetaClass *meta_class, const QStringList &declarations);
91 void parseQ_Property(AbstractMetaClass *meta_class, const QStringList &declarations);
90 void setupEquals(AbstractMetaClass *meta_class);
92 void setupEquals(AbstractMetaClass *meta_class);
91 void setupComparable(AbstractMetaClass *meta_class);
93 void setupComparable(AbstractMetaClass *meta_class);
92 void setupClonable(AbstractMetaClass *cls);
94 void setupClonable(AbstractMetaClass *cls);
93 void setupFunctionDefaults(AbstractMetaFunction *meta_function, AbstractMetaClass *meta_class);
95 void setupFunctionDefaults(AbstractMetaFunction *meta_function, AbstractMetaClass *meta_class);
94
96
95 QString translateDefaultValue(ArgumentModelItem item, AbstractMetaType *type,
97 QString translateDefaultValue(ArgumentModelItem item, AbstractMetaType *type,
96 AbstractMetaFunction *fnc, AbstractMetaClass *,
98 AbstractMetaFunction *fnc, AbstractMetaClass *,
97 int argument_index);
99 int argument_index);
98 AbstractMetaType *translateType(const TypeInfo &type, bool *ok, bool resolveType = true, bool resolveScope = true);
100 AbstractMetaType *translateType(const TypeInfo &type, bool *ok, bool resolveType = true, bool resolveScope = true);
99
101
100 void decideUsagePattern(AbstractMetaType *type);
102 void decideUsagePattern(AbstractMetaType *type);
101
103
102 bool inheritTemplate(AbstractMetaClass *subclass,
104 bool inheritTemplate(AbstractMetaClass *subclass,
103 const AbstractMetaClass *template_class,
105 const AbstractMetaClass *template_class,
104 const TypeParser::Info &info);
106 const TypeParser::Info &info);
105 AbstractMetaType *inheritTemplateType(const QList<AbstractMetaType *> &template_types, AbstractMetaType *meta_type, bool *ok = 0);
107 AbstractMetaType *inheritTemplateType(const QList<AbstractMetaType *> &template_types, AbstractMetaType *meta_type, bool *ok = 0);
106
108
107 bool isQObject(const QString &qualified_name);
109 bool isQObject(const QString &qualified_name);
108 bool isEnum(const QStringList &qualified_name);
110 bool isEnum(const QStringList &qualified_name);
109
111
110 void fixQObjectForScope (TypeDatabase *types,
112 void fixQObjectForScope (TypeDatabase *types,
111 NamespaceModelItem item);
113 NamespaceModelItem item);
112
114
113 // QtScript
115 // QtScript
114 QSet<QString> qtMetaTypeDeclaredTypeNames() const
116 QSet<QString> qtMetaTypeDeclaredTypeNames() const
115 { return m_qmetatype_declared_typenames; }
117 { return m_qmetatype_declared_typenames; }
116
118
117 protected:
119 protected:
118 AbstractMetaClass *argumentToClass(ArgumentModelItem);
120 AbstractMetaClass *argumentToClass(ArgumentModelItem);
119
121
120 virtual AbstractMetaClass *createMetaClass() = 0;
122 virtual AbstractMetaClass *createMetaClass() = 0;
121 virtual AbstractMetaEnum *createMetaEnum() = 0;
123 virtual AbstractMetaEnum *createMetaEnum() = 0;
122 virtual AbstractMetaEnumValue *createMetaEnumValue() = 0;
124 virtual AbstractMetaEnumValue *createMetaEnumValue() = 0;
123 virtual AbstractMetaField *createMetaField() = 0;
125 virtual AbstractMetaField *createMetaField() = 0;
124 virtual AbstractMetaFunction *createMetaFunction() = 0;
126 virtual AbstractMetaFunction *createMetaFunction() = 0;
125 virtual AbstractMetaArgument *createMetaArgument() = 0;
127 virtual AbstractMetaArgument *createMetaArgument() = 0;
126 virtual AbstractMetaType *createMetaType() = 0;
128 virtual AbstractMetaType *createMetaType() = 0;
127
129
128 private:
130 private:
129 void sortLists();
131 void sortLists();
130
132
131 QString m_file_name;
133 QString m_file_name;
132
134
133 AbstractMetaClassList m_meta_classes;
135 AbstractMetaClassList m_meta_classes;
134 AbstractMetaClassList m_templates;
136 AbstractMetaClassList m_templates;
135 FileModelItem m_dom;
137 FileModelItem m_dom;
136
138
137 QSet<const TypeEntry *> m_used_types;
139 QSet<const TypeEntry *> m_used_types;
138
140
139 QMap<QString, RejectReason> m_rejected_classes;
141 QMap<QString, RejectReason> m_rejected_classes;
140 QMap<QString, RejectReason> m_rejected_enums;
142 QMap<QString, RejectReason> m_rejected_enums;
141 QMap<QString, RejectReason> m_rejected_functions;
143 QMap<QString, RejectReason> m_rejected_functions;
142 QMap<QString, RejectReason> m_rejected_fields;
144 QMap<QString, RejectReason> m_rejected_fields;
143
145
144 QList<AbstractMetaEnum *> m_enums;
146 QList<AbstractMetaEnum *> m_enums;
145
147
146 QList<QPair<AbstractMetaArgument *, AbstractMetaFunction *> > m_enum_default_arguments;
148 QList<QPair<AbstractMetaArgument *, AbstractMetaFunction *> > m_enum_default_arguments;
147
149
148 QHash<QString, AbstractMetaEnumValue *> m_enum_values;
150 QHash<QString, AbstractMetaEnumValue *> m_enum_values;
149
151
150 AbstractMetaClass *m_current_class;
152 AbstractMetaClass *m_current_class;
151 QList<ScopeModelItem> m_scopes;
153 QList<ScopeModelItem> m_scopes;
152 QString m_namespace_prefix;
154 QString m_namespace_prefix;
153
155
154 QSet<AbstractMetaClass *> m_setup_inheritance_done;
156 QSet<AbstractMetaClass *> m_setup_inheritance_done;
155
157
156 // QtScript
158 // QtScript
157 QSet<QString> m_qmetatype_declared_typenames;
159 QSet<QString> m_qmetatype_declared_typenames;
158 };
160 };
159
161
160 #endif // ABSTRACTMETBUILDER_H
162 #endif // ABSTRACTMETBUILDER_H
General Comments 0
You need to be logged in to leave comments. Login now