1
|
1 /****************************************************************************
|
|
2 **
|
|
3 ** Copyright (C) 1992-2008 Nokia. All rights reserved.
|
|
4 **
|
|
5 ** This file is part of Qt Jambi.
|
|
6 **
|
|
7 ** * Commercial Usage
|
|
8 * Licensees holding valid Qt Commercial licenses may use this file in
|
|
9 * accordance with the Qt Commercial License Agreement provided with the
|
|
10 * Software or, alternatively, in accordance with the terms contained in
|
|
11 * a written agreement between you and Nokia.
|
|
12 *
|
|
13 *
|
|
14 * GNU General Public License Usage
|
|
15 * Alternatively, this file may be used under the terms of the GNU
|
|
16 * General Public License versions 2.0 or 3.0 as published by the Free
|
|
17 * Software Foundation and appearing in the file LICENSE.GPL included in
|
|
18 * the packaging of this file. Please review the following information
|
|
19 * to ensure GNU General Public Licensing requirements will be met:
|
|
20 * http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
|
21 * http://www.gnu.org/copyleft/gpl.html. In addition, as a special
|
|
22 * exception, Nokia gives you certain additional rights. These rights
|
|
23 * are described in the Nokia Qt GPL Exception version 1.2, included in
|
|
24 * the file GPL_EXCEPTION.txt in this package.
|
|
25 *
|
|
26 * Qt for Windows(R) Licensees
|
|
27 * As a special exception, Nokia, as the sole copyright holder for Qt
|
|
28 * Designer, grants users of the Qt/Eclipse Integration plug-in the
|
|
29 * right for the Qt/Eclipse Integration to link to functionality
|
|
30 * provided by Qt Designer and its related libraries.
|
|
31 *
|
|
32 *
|
|
33 * If you are unsure which license is appropriate for your use, please
|
|
34 * contact the sales department at qt-sales@nokia.com.
|
|
35
|
|
36 **
|
|
37 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
38 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
39 **
|
|
40 ****************************************************************************/
|
|
41
|
|
42 #include "abstractmetalang.h"
|
|
43 #include "reporthandler.h"
|
|
44 #include "jumptable.h"
|
288
|
45 #include <iostream>
|
1
|
46
|
|
47 /*******************************************************************************
|
|
48 * AbstractMetaType
|
|
49 */
|
|
50 AbstractMetaType *AbstractMetaType::copy() const
|
|
51 {
|
|
52 AbstractMetaType *cpy = new AbstractMetaType;
|
|
53
|
|
54 cpy->setTypeUsagePattern(typeUsagePattern());
|
|
55 cpy->setConstant(isConstant());
|
|
56 cpy->setReference(isReference());
|
|
57 cpy->setIndirections(indirections());
|
|
58 cpy->setInstantiations(instantiations());
|
|
59 cpy->setArrayElementCount(arrayElementCount());
|
|
60 cpy->setOriginalTypeDescription(originalTypeDescription());
|
|
61 cpy->setOriginalTemplateType(originalTemplateType() ? originalTemplateType()->copy() : 0);
|
|
62
|
|
63 cpy->setArrayElementType(arrayElementType() ? arrayElementType()->copy() : 0);
|
|
64
|
|
65 cpy->setTypeEntry(typeEntry());
|
|
66
|
|
67 return cpy;
|
|
68 }
|
|
69
|
|
70 QString AbstractMetaType::cppSignature() const
|
|
71 {
|
|
72 QString s;
|
|
73
|
|
74 if (isConstant())
|
|
75 s += "const ";
|
|
76
|
|
77 s += typeEntry()->qualifiedCppName();
|
|
78
|
|
79 if (hasInstantiationInCpp()) {
|
|
80 QList<AbstractMetaType *> types = instantiations();
|
|
81 s += "<";
|
|
82 for (int i=0; i<types.count(); ++i) {
|
|
83 if (i > 0)
|
|
84 s += ", ";
|
|
85 s += types.at(i)->cppSignature();
|
|
86 }
|
|
87 s += " >";
|
|
88 }
|
|
89
|
|
90 if (actualIndirections()) {
|
|
91 s += ' ';
|
|
92 if (indirections())
|
|
93 s += QString(indirections(), '*');
|
|
94 if (isReference())
|
|
95 s += '&';
|
|
96 }
|
|
97 return s;
|
|
98 }
|
|
99
|
|
100 /*******************************************************************************
|
|
101 * AbstractMetaArgument
|
|
102 */
|
|
103 AbstractMetaArgument *AbstractMetaArgument::copy() const
|
|
104 {
|
|
105 AbstractMetaArgument *cpy = new AbstractMetaArgument;
|
|
106 cpy->setName(AbstractMetaVariable::name());
|
|
107 cpy->setDefaultValueExpression(defaultValueExpression());
|
|
108 cpy->setType(type()->copy());
|
|
109 cpy->setArgumentIndex(argumentIndex());
|
|
110
|
|
111 return cpy;
|
|
112 }
|
|
113
|
|
114
|
|
115 QString AbstractMetaArgument::argumentName() const
|
|
116 {
|
|
117 QString n = AbstractMetaVariable::name();
|
|
118 // replace for arguments which are D keywords such as "version"
|
|
119 n = ArgumentReplace::translate(n);
|
|
120
|
|
121 if (n.isEmpty()) {
|
|
122 return QString("arg__%2").arg(m_argument_index + 1);
|
|
123 }
|
|
124 return n;
|
|
125 }
|
|
126
|
|
127
|
|
128 QString AbstractMetaArgument::indexedName() const
|
|
129 {
|
|
130 QString n = AbstractMetaVariable::name();
|
|
131 if (n.isEmpty())
|
|
132 return argumentName();
|
|
133 return QString("%1%2").arg(n).arg(m_argument_index);
|
|
134 }
|
|
135
|
|
136 QString AbstractMetaArgument::name() const
|
|
137 {
|
|
138 Q_ASSERT_X(0, "AbstractMetaArgument::name()", "use argumentName() or indexedName() instead");
|
|
139 return QString();
|
|
140 }
|
|
141
|
|
142
|
|
143 /*******************************************************************************
|
|
144 * AbstractMetaFunction
|
|
145 */
|
|
146 AbstractMetaFunction::~AbstractMetaFunction()
|
|
147 {
|
|
148 qDeleteAll(m_arguments);
|
|
149 delete m_type;
|
|
150 }
|
|
151
|
|
152 /*******************************************************************************
|
|
153 * Indicates that this function has a modification that removes it
|
|
154 */
|
|
155 bool AbstractMetaFunction::isModifiedRemoved(int types) const
|
|
156 {
|
|
157 FunctionModificationList mods = modifications(implementingClass());
|
|
158 foreach (FunctionModification mod, mods) {
|
|
159 if (!mod.isRemoveModifier())
|
|
160 continue;
|
|
161
|
|
162 if ((mod.removal & types) == types)
|
|
163 return true;
|
|
164 }
|
|
165
|
|
166 return false;
|
|
167 }
|
|
168
|
|
169 bool AbstractMetaFunction::needsCallThrough() const
|
|
170 {
|
|
171 if (ownerClass()->isInterface())
|
|
172 return false;
|
|
173 if (referenceCounts(implementingClass()).size() > 0)
|
|
174 return true;
|
|
175 if (argumentsHaveNativeId() || !isStatic())
|
|
176 return true;
|
|
177 if (JumpTableGenerator::isJumpTableActive())
|
|
178 return true;
|
|
179
|
|
180 foreach (const AbstractMetaArgument *arg, arguments()) {
|
|
181 if (arg->type()->isArray() || arg->type()->isTargetLangEnum() || arg->type()->isTargetLangFlags())
|
|
182 return true;
|
|
183 }
|
|
184
|
|
185 if (type() && (type()->isArray() || type()->isTargetLangEnum() || type()->isTargetLangFlags()))
|
|
186 return true;
|
|
187
|
|
188 for (int i=-1; i<=arguments().size(); ++i) {
|
|
189 TypeSystem::Ownership owner = this->ownership(implementingClass(), TypeSystem::TargetLangCode, i);
|
|
190 if (owner != TypeSystem::InvalidOwnership)
|
|
191 return true;
|
|
192 }
|
|
193
|
|
194 return false;
|
|
195 }
|
|
196
|
|
197 bool AbstractMetaFunction::needsSuppressUncheckedWarning() const
|
|
198 {
|
|
199 for (int i=-1; i<=arguments().size(); ++i) {
|
|
200 QList<ReferenceCount> referenceCounts = this->referenceCounts(implementingClass(), i);
|
|
201 foreach (ReferenceCount referenceCount, referenceCounts) {
|
|
202 if (referenceCount.action != ReferenceCount::Set)
|
|
203 return true;
|
|
204 }
|
|
205 }
|
|
206 return false;
|
|
207 }
|
|
208
|
|
209 QString AbstractMetaFunction::marshalledName(bool classIsOwner) const
|
|
210 {
|
|
211 QString returned = "qtd_";
|
|
212 if(classIsOwner)
|
|
213 returned += ownerClass()->name();
|
|
214 else
|
|
215 returned += declaringClass()->name();
|
|
216
|
|
217 returned += "_" + name();
|
|
218 AbstractMetaArgumentList arguments = this->arguments();
|
|
219 foreach (const AbstractMetaArgument *arg, arguments) {
|
|
220 returned += "_";
|
|
221 if (arg->type()->isNativePointer()) {
|
|
222 returned += "nativepointer" + arg->type()->name().replace("[]", "_3").replace(".", "_");
|
|
223 } else if (arg->type()->isIntegerEnum() || arg->type()->isIntegerFlags()) {
|
|
224 returned += "int";
|
|
225 } else {
|
|
226 returned += arg->type()->name().replace("[]", "_3").replace(".", "_");
|
|
227 }
|
|
228 }
|
324
|
229
|
|
230 if(this->isConstant())
|
|
231 returned += "_const";
|
|
232
|
1
|
233 return returned;
|
|
234 }
|
|
235
|
|
236 bool AbstractMetaFunction::operator<(const AbstractMetaFunction &other) const
|
|
237 {
|
|
238 uint result = compareTo(&other);
|
|
239 return result & NameLessThan;
|
|
240 }
|
|
241
|
|
242
|
|
243 /*!
|
|
244 Returns a mask of CompareResult describing how this function is
|
|
245 compares to another function
|
|
246 */
|
|
247 uint AbstractMetaFunction::compareTo(const AbstractMetaFunction *other) const
|
|
248 {
|
|
249 uint result = 0;
|
|
250
|
|
251 // Enclosing class...
|
|
252 if (ownerClass() == other->ownerClass()) {
|
|
253 result |= EqualImplementor;
|
|
254 }
|
|
255
|
|
256 // Attributes
|
|
257 if (attributes() == other->attributes()) {
|
|
258 result |= EqualAttributes;
|
|
259 }
|
|
260
|
|
261 // Compare types
|
|
262 AbstractMetaType *t = type();
|
|
263 AbstractMetaType *ot = other->type();
|
|
264 if ((!t && !ot) || ((t && ot && t->name() == ot->name()))) {
|
|
265 result |= EqualReturnType;
|
|
266 }
|
|
267
|
|
268 // Compare names
|
|
269 int cmp = originalName().compare(other->originalName());
|
|
270
|
|
271 if (cmp < 0) {
|
|
272 result |= NameLessThan;
|
|
273 } else if (cmp == 0) {
|
|
274 result |= EqualName;
|
|
275 }
|
|
276
|
|
277 // compare name after modification...
|
|
278 cmp = modifiedName().compare(other->modifiedName());
|
|
279 if (cmp == 0)
|
|
280 result |= EqualModifiedName;
|
|
281
|
|
282 // Compare arguments...
|
|
283 AbstractMetaArgumentList min_arguments;
|
|
284 AbstractMetaArgumentList max_arguments;
|
|
285 if (arguments().size() < other->arguments().size()) {
|
|
286 min_arguments = arguments();
|
|
287 max_arguments = other->arguments();
|
|
288 } else {
|
|
289 min_arguments = other->arguments();
|
|
290 max_arguments = arguments();
|
|
291 }
|
|
292
|
|
293 int min_count = min_arguments.size();
|
|
294 int max_count = max_arguments.size();
|
|
295 bool same = true;
|
|
296 for (int i=0; i<max_count; ++i) {
|
|
297 if (i < min_count) {
|
|
298 const AbstractMetaArgument *min_arg = min_arguments.at(i);
|
|
299 const AbstractMetaArgument *max_arg = max_arguments.at(i);
|
|
300 if (min_arg->type()->name() != max_arg->type()->name()
|
|
301 && (min_arg->defaultValueExpression().isEmpty() || max_arg->defaultValueExpression().isEmpty())) {
|
|
302 same = false;
|
|
303 break;
|
|
304 }
|
|
305 } else {
|
|
306 if (max_arguments.at(i)->defaultValueExpression().isEmpty()) {
|
|
307 same = false;
|
|
308 break;
|
|
309 }
|
|
310 }
|
|
311 }
|
|
312
|
|
313 if (same)
|
|
314 result |= min_count == max_count ? EqualArguments : EqualDefaultValueOverload;
|
|
315
|
|
316 return result;
|
|
317 }
|
|
318
|
|
319 AbstractMetaFunction *AbstractMetaFunction::copy() const
|
|
320 {
|
|
321 AbstractMetaFunction *cpy = new AbstractMetaFunction;
|
|
322 cpy->setName(name());
|
|
323 cpy->setOriginalName(originalName());
|
|
324 cpy->setOwnerClass(ownerClass());
|
|
325 cpy->setImplementingClass(implementingClass());
|
|
326 cpy->setInterfaceClass(interfaceClass());
|
|
327 cpy->setFunctionType(functionType());
|
|
328 cpy->setAttributes(attributes());
|
|
329 cpy->setDeclaringClass(declaringClass());
|
|
330 if (type())
|
|
331 cpy->setType(type()->copy());
|
|
332 cpy->setConstant(isConstant());
|
|
333 cpy->setOriginalAttributes(originalAttributes());
|
|
334
|
|
335 foreach (AbstractMetaArgument *arg, arguments())
|
|
336 cpy->addArgument(arg->copy());
|
|
337
|
|
338 Q_ASSERT((!type() && !cpy->type())
|
|
339 || (type()->instantiations() == cpy->type()->instantiations()));
|
|
340
|
|
341 return cpy;
|
|
342 }
|
|
343
|
|
344 QStringList AbstractMetaFunction::introspectionCompatibleSignatures(const QStringList &resolvedArguments) const
|
|
345 {
|
|
346 AbstractMetaArgumentList arguments = this->arguments();
|
|
347 if (arguments.size() == resolvedArguments.size()) {
|
|
348 return (QStringList() << QMetaObject::normalizedSignature((name() + "(" + resolvedArguments.join(",") + ")").toUtf8().constData()));
|
|
349 } else {
|
|
350 QStringList returned;
|
|
351
|
|
352 AbstractMetaArgument *argument = arguments.at(resolvedArguments.size());
|
|
353 QStringList minimalTypeSignature = argument->type()->minimalSignature().split("::");
|
|
354 for (int i=0; i<minimalTypeSignature.size(); ++i) {
|
|
355 returned += introspectionCompatibleSignatures(QStringList(resolvedArguments)
|
|
356 << QStringList(minimalTypeSignature.mid(minimalTypeSignature.size() - i - 1)).join("::"));
|
|
357 }
|
|
358
|
|
359 return returned;
|
|
360 }
|
|
361 }
|
|
362
|
|
363 QString AbstractMetaFunction::signature() const
|
|
364 {
|
|
365 QString s(m_original_name);
|
|
366
|
|
367 s += "(";
|
|
368
|
|
369 for (int i=0; i<m_arguments.count(); ++i) {
|
|
370 if (i > 0)
|
|
371 s += ", ";
|
|
372 AbstractMetaArgument *a = m_arguments.at(i);
|
|
373 s += a->type()->cppSignature();
|
|
374
|
|
375 // We need to have the argument names in the qdoc files
|
|
376 s += " ";
|
|
377 s += a->argumentName();
|
|
378 }
|
|
379 s += ")";
|
|
380
|
|
381 if (isConstant())
|
|
382 s += " const";
|
|
383
|
|
384 return s;
|
|
385 }
|
|
386
|
|
387 int AbstractMetaFunction::actualMinimumArgumentCount() const
|
|
388 {
|
|
389 AbstractMetaArgumentList arguments = this->arguments();
|
|
390
|
|
391 int count = 0;
|
|
392 for (int i=0; i<arguments.size(); ++i && ++count) {
|
|
393 if (argumentRemoved(i + 1)) --count;
|
|
394 else if (!arguments.at(i)->defaultValueExpression().isEmpty()) break;
|
|
395 }
|
|
396
|
|
397 return count;
|
|
398 }
|
|
399
|
|
400 // Returns reference counts for argument at idx, or all arguments if idx == -2
|
|
401 QList<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaClass *cls, int idx) const
|
|
402 {
|
|
403 QList<ReferenceCount> returned;
|
|
404
|
|
405 FunctionModificationList mods = this->modifications(cls);
|
|
406 foreach (FunctionModification mod, mods) {
|
|
407 QList<ArgumentModification> argument_mods = mod.argument_mods;
|
|
408 foreach (ArgumentModification argument_mod, argument_mods) {
|
|
409 if (argument_mod.index != idx && idx != -2)
|
|
410 continue;
|
|
411 returned += argument_mod.referenceCounts;
|
|
412 }
|
|
413 }
|
|
414
|
|
415 return returned;
|
|
416 }
|
|
417
|
|
418 QString AbstractMetaFunction::replacedDefaultExpression(const AbstractMetaClass *cls, int key) const
|
|
419 {
|
|
420 FunctionModificationList modifications = this->modifications(cls);
|
|
421 foreach (FunctionModification modification, modifications) {
|
|
422 QList<ArgumentModification> argument_modifications = modification.argument_mods;
|
|
423 foreach (ArgumentModification argument_modification, argument_modifications) {
|
|
424 if (argument_modification.index == key
|
|
425 && !argument_modification.replaced_default_expression.isEmpty()) {
|
|
426 return argument_modification.replaced_default_expression;
|
|
427 }
|
|
428 }
|
|
429 }
|
|
430
|
|
431 return QString();
|
|
432 }
|
|
433
|
|
434 bool AbstractMetaFunction::removedDefaultExpression(const AbstractMetaClass *cls, int key) const
|
|
435 {
|
|
436 FunctionModificationList modifications = this->modifications(cls);
|
|
437 foreach (FunctionModification modification, modifications) {
|
|
438 QList<ArgumentModification> argument_modifications = modification.argument_mods;
|
|
439 foreach (ArgumentModification argument_modification, argument_modifications) {
|
|
440 if (argument_modification.index == key
|
|
441 && argument_modification.removed_default_expression) {
|
|
442 return true;
|
|
443 }
|
|
444 }
|
|
445 }
|
|
446
|
|
447 return false;
|
|
448 }
|
|
449
|
|
450 bool AbstractMetaFunction::resetObjectAfterUse(int argument_idx) const
|
|
451 {
|
|
452 const AbstractMetaClass *cls = declaringClass();
|
|
453 FunctionModificationList modifications = this->modifications(cls);
|
|
454 foreach (FunctionModification modification, modifications) {
|
|
455 QList<ArgumentModification> argumentModifications = modification.argument_mods;
|
|
456 foreach (ArgumentModification argumentModification, argumentModifications) {
|
|
457 if (argumentModification.index == argument_idx && argumentModification.reset_after_use)
|
|
458 return true;
|
|
459 }
|
|
460 }
|
|
461
|
|
462 return false;
|
|
463 }
|
|
464
|
|
465 QString AbstractMetaFunction::nullPointerDefaultValue(const AbstractMetaClass *mainClass, int argument_idx) const
|
|
466 {
|
|
467 Q_ASSERT(nullPointersDisabled(mainClass, argument_idx));
|
|
468
|
|
469 const AbstractMetaClass *cls = mainClass;
|
|
470 if (cls == 0)
|
|
471 cls = implementingClass();
|
|
472
|
|
473 do {
|
|
474 FunctionModificationList modifications = this->modifications(cls);
|
|
475 foreach (FunctionModification modification, modifications) {
|
|
476 QList<ArgumentModification> argument_modifications = modification.argument_mods;
|
|
477 foreach (ArgumentModification argument_modification, argument_modifications) {
|
|
478 if (argument_modification.index == argument_idx
|
|
479 && argument_modification.no_null_pointers) {
|
|
480 return argument_modification.null_pointer_default_value;
|
|
481 }
|
|
482 }
|
|
483 }
|
|
484
|
|
485 cls = cls->baseClass();
|
|
486 } while (cls != 0 && mainClass == 0); // Once when mainClass != 0, or once for all base classes of implementing class
|
|
487
|
|
488 return QString();
|
|
489
|
|
490 }
|
|
491
|
|
492 bool AbstractMetaFunction::nullPointersDisabled(const AbstractMetaClass *mainClass, int argument_idx) const
|
|
493 {
|
|
494 const AbstractMetaClass *cls = mainClass;
|
|
495 if (cls == 0)
|
|
496 cls = implementingClass();
|
|
497
|
|
498 do {
|
|
499 FunctionModificationList modifications = this->modifications(cls);
|
|
500 foreach (FunctionModification modification, modifications) {
|
|
501 QList<ArgumentModification> argument_modifications = modification.argument_mods;
|
|
502 foreach (ArgumentModification argument_modification, argument_modifications) {
|
|
503 if (argument_modification.index == argument_idx
|
|
504 && argument_modification.no_null_pointers) {
|
|
505 return true;
|
|
506 }
|
|
507 }
|
|
508 }
|
|
509
|
|
510 cls = cls->baseClass();
|
|
511 } while (cls != 0 && mainClass == 0); // Once when mainClass != 0, or once for all base classes of implementing class
|
|
512
|
|
513 return false;
|
|
514 }
|
|
515
|
|
516 QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int key) const
|
|
517 {
|
|
518 FunctionModificationList modifications = this->modifications(declaringClass());
|
|
519 foreach (FunctionModification modification, modifications) {
|
|
520 QList<ArgumentModification> argument_modifications = modification.argument_mods;
|
|
521 foreach (ArgumentModification argument_modification, argument_modifications) {
|
|
522 if (argument_modification.index != key)
|
|
523 continue;
|
|
524
|
|
525 foreach (CodeSnip snip, argument_modification.conversion_rules) {
|
|
526 if (snip.language == language && !snip.code().isEmpty())
|
|
527 return snip.code();
|
|
528 }
|
|
529 }
|
|
530 }
|
|
531
|
|
532 return QString();
|
|
533 }
|
|
534
|
|
535 QString AbstractMetaFunction::argumentReplaced(int key) const
|
|
536 {
|
|
537 FunctionModificationList modifications = this->modifications(declaringClass());
|
|
538 foreach (FunctionModification modification, modifications) {
|
|
539 QList<ArgumentModification> argument_modifications = modification.argument_mods;
|
|
540 foreach (ArgumentModification argument_modification, argument_modifications) {
|
|
541 if (argument_modification.index == key && !argument_modification.replace_value.isEmpty()) {
|
|
542 return argument_modification.replace_value;
|
|
543 }
|
|
544 }
|
|
545 }
|
|
546
|
|
547 return "";
|
|
548 }
|
|
549
|
|
550 bool AbstractMetaFunction::argumentRemoved(int key) const
|
|
551 {
|
|
552 FunctionModificationList modifications = this->modifications(declaringClass());
|
|
553 foreach (FunctionModification modification, modifications) {
|
|
554 QList<ArgumentModification> argument_modifications = modification.argument_mods;
|
|
555 foreach (ArgumentModification argument_modification, argument_modifications) {
|
|
556 if (argument_modification.index == key) {
|
|
557 if (argument_modification.removed) {
|
|
558 return true;
|
|
559 }
|
|
560 }
|
|
561 }
|
|
562 }
|
|
563
|
|
564 return false;
|
|
565 }
|
|
566
|
|
567 bool AbstractMetaFunction::storeResult() const
|
|
568 {
|
|
569 if (m_store_result == 2)
|
|
570 return true;
|
|
571 else
|
|
572 return false;
|
|
573 }
|
|
574
|
|
575 void AbstractMetaFunction::checkStoreResult()
|
|
576 {
|
|
577 FunctionModificationList modifications = this->modifications(declaringClass());
|
|
578 foreach (FunctionModification modification, modifications) {
|
|
579 if (modification.store_result) {
|
|
580 m_store_result = 2;
|
|
581 return;
|
|
582 }
|
|
583 }
|
|
584
|
|
585 m_store_result = 1;
|
|
586 }
|
|
587
|
|
588 bool AbstractMetaFunction::isVirtualSlot() const
|
|
589 {
|
|
590 FunctionModificationList modifications = this->modifications(declaringClass());
|
|
591 foreach (FunctionModification modification, modifications) {
|
|
592 if (modification.isVirtualSlot())
|
|
593 return true;
|
|
594 }
|
|
595
|
|
596 return false;
|
|
597 }
|
|
598
|
|
599 bool AbstractMetaFunction::disabledGarbageCollection(const AbstractMetaClass *cls, int key) const
|
|
600 {
|
|
601 FunctionModificationList modifications = this->modifications(cls);
|
|
602 foreach (FunctionModification modification, modifications) {
|
|
603 QList<ArgumentModification> argument_modifications = modification.argument_mods;
|
|
604 foreach (ArgumentModification argument_modification, argument_modifications) {
|
|
605 if (argument_modification.index != key)
|
|
606 continue;
|
|
607
|
|
608 foreach (TypeSystem::Ownership ownership, argument_modification.ownerships.values()) {
|
|
609 if (ownership == TypeSystem::CppOwnership)
|
|
610 return true;
|
|
611 }
|
|
612
|
|
613 }
|
|
614 }
|
|
615
|
|
616 return false;
|
|
617 }
|
|
618
|
|
619 bool AbstractMetaFunction::isDeprecated() const
|
|
620 {
|
|
621 FunctionModificationList modifications = this->modifications(declaringClass());
|
|
622 foreach (FunctionModification modification, modifications) {
|
|
623 if (modification.isDeprecated())
|
|
624 return true;
|
|
625 }
|
|
626 return false;
|
|
627 }
|
|
628
|
|
629 TypeSystem::Ownership AbstractMetaFunction::ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int key) const
|
|
630 {
|
|
631 FunctionModificationList modifications = this->modifications(cls);
|
|
632 foreach (FunctionModification modification, modifications) {
|
|
633 QList<ArgumentModification> argument_modifications = modification.argument_mods;
|
|
634 foreach (ArgumentModification argument_modification, argument_modifications) {
|
|
635 if (argument_modification.index == key)
|
|
636 return argument_modification.ownerships.value(language, TypeSystem::InvalidOwnership);
|
|
637 }
|
|
638 }
|
|
639
|
|
640 return TypeSystem::InvalidOwnership;
|
|
641 }
|
|
642
|
|
643 bool AbstractMetaFunction::isRemovedFromAllLanguages(const AbstractMetaClass *cls) const
|
|
644 {
|
|
645 return isRemovedFrom(cls, TypeSystem::All);
|
|
646 }
|
|
647
|
|
648 bool AbstractMetaFunction::isRemovedFrom(const AbstractMetaClass *cls, TypeSystem::Language language) const
|
|
649 {
|
|
650 FunctionModificationList modifications = this->modifications(cls);
|
|
651 foreach (FunctionModification modification, modifications) {
|
|
652 if ((modification.removal & language) == language)
|
|
653 return true;
|
|
654 }
|
|
655
|
|
656 return false;
|
|
657
|
|
658 }
|
|
659
|
|
660 QString AbstractMetaFunction::typeReplaced(int key) const
|
|
661 {
|
|
662 FunctionModificationList modifications = this->modifications(declaringClass());
|
|
663 foreach (FunctionModification modification, modifications) {
|
|
664 QList<ArgumentModification> argument_modifications = modification.argument_mods;
|
|
665 foreach (ArgumentModification argument_modification, argument_modifications) {
|
|
666 if (argument_modification.index == key
|
|
667 && !argument_modification.modified_type.isEmpty()) {
|
|
668 return argument_modification.modified_type;
|
|
669 }
|
|
670 }
|
|
671 }
|
|
672
|
|
673 return QString();
|
|
674 }
|
|
675
|
288
|
676 QString AbstractMetaFunction::minimalSignature(int reduce) const
|
1
|
677 {
|
288
|
678 if (!m_cached_minimal_signature.isEmpty() && !reduce)
|
1
|
679 return m_cached_minimal_signature;
|
|
680
|
|
681 QString minimalSignature = originalName() + "(";
|
|
682 AbstractMetaArgumentList arguments = this->arguments();
|
288
|
683 int argsCount = arguments.count() - reduce;
|
|
684 for (int i=0; i<argsCount; ++i) {
|
1
|
685 AbstractMetaType *t = arguments.at(i)->type();
|
|
686
|
|
687 if (i > 0)
|
|
688 minimalSignature += ",";
|
|
689
|
|
690 minimalSignature += t->minimalSignature();
|
|
691 }
|
|
692 minimalSignature += ")";
|
|
693 if (isConstant())
|
|
694 minimalSignature += "const";
|
|
695
|
|
696 minimalSignature = QMetaObject::normalizedSignature(minimalSignature.toLocal8Bit().constData());
|
288
|
697 if(!reduce)
|
|
698 m_cached_minimal_signature = minimalSignature;
|
1
|
699
|
|
700 return minimalSignature;
|
|
701 }
|
|
702
|
|
703 FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaClass *implementor) const
|
|
704 {
|
|
705 Q_ASSERT(implementor);
|
|
706 return implementor->typeEntry()->functionModifications(minimalSignature());
|
|
707 }
|
|
708
|
|
709 bool AbstractMetaFunction::hasModifications(const AbstractMetaClass *implementor) const
|
|
710 {
|
|
711 FunctionModificationList mods = modifications(implementor);
|
|
712 return mods.count() > 0;
|
|
713 }
|
|
714
|
|
715 QString AbstractMetaFunction::modifiedName() const
|
|
716 {
|
|
717 if (m_cached_modified_name.isEmpty()) {
|
|
718 FunctionModificationList mods = modifications(implementingClass());
|
|
719 foreach (FunctionModification mod, mods) {
|
|
720 if (mod.isRenameModifier()) {
|
|
721 m_cached_modified_name = mod.renamedToName;
|
|
722 break;
|
|
723 }
|
|
724 }
|
|
725 if (m_cached_modified_name.isEmpty())
|
|
726 m_cached_modified_name = name();
|
|
727 }
|
|
728 return m_cached_modified_name;
|
|
729 }
|
|
730
|
|
731 QString AbstractMetaFunction::targetLangSignature(bool minimal) const
|
|
732 {
|
|
733 QString s;
|
|
734
|
|
735 // Attributes...
|
|
736 if (!minimal) {
|
|
737 if (isPublic()) s += "public ";
|
|
738 else if (isProtected()) s += "protected ";
|
|
739 else if (isPrivate()) s += "private ";
|
|
740
|
|
741 // if (isNative()) s += "native ";
|
|
742 // else
|
|
743 if (isFinalInTargetLang()) s += "final ";
|
|
744 else if (isAbstract()) s += "abstract ";
|
|
745
|
|
746 if (isStatic()) s += "static ";
|
|
747
|
|
748 // Return type
|
|
749 if (type())
|
|
750 s += type()->fullName() + " ";
|
|
751 else
|
|
752 s += "void ";
|
|
753 }
|
|
754
|
|
755 s += name();
|
|
756 s += "(";
|
|
757
|
|
758 for (int i=0; i<m_arguments.size(); ++i) {
|
|
759 if (i != 0) {
|
|
760 s += ",";
|
|
761 if (!minimal)
|
|
762 s += QLatin1Char(' ');
|
|
763 }
|
|
764 s += m_arguments.at(i)->type()->fullName();
|
|
765
|
|
766 if (!minimal) {
|
|
767 s += " ";
|
|
768 s += m_arguments.at(i)->argumentName();
|
|
769 }
|
|
770 }
|
|
771
|
|
772 s += ")";
|
|
773
|
|
774 return s;
|
|
775 }
|
|
776
|
|
777
|
|
778 bool function_sorter(AbstractMetaFunction *a, AbstractMetaFunction *b)
|
|
779 {
|
|
780 return a->signature() < b->signature();
|
|
781 }
|
|
782
|
|
783 /*******************************************************************************
|
|
784 * AbstractMetaClass
|
|
785 */
|
|
786 AbstractMetaClass::~AbstractMetaClass()
|
|
787 {
|
|
788 qDeleteAll(m_functions);
|
|
789 qDeleteAll(m_fields);
|
|
790 }
|
|
791
|
|
792 /*AbstractMetaClass *AbstractMetaClass::copy() const
|
|
793 {
|
|
794 AbstractMetaClass *cls = new AbstractMetaClass;
|
|
795 cls->setAttributes(attributes());
|
|
796 cls->setBaseClass(baseClass());
|
|
797 cls->setTypeEntry(typeEntry());
|
|
798 foreach (AbstractMetaFunction *function, functions()) {
|
|
799 AbstractMetaFunction *copy = function->copy();
|
|
800 function->setImplementingClass(cls);
|
|
801 cls->addFunction(copy);
|
|
802 }
|
|
803 cls->setEnums(enums());
|
|
804 foreach (const AbstractMetaField *field, fields()) {
|
|
805 AbstractMetaField *copy = field->copy();
|
|
806 copy->setEnclosingClass(cls);
|
|
807 cls->addField(copy);
|
|
808 }
|
|
809 cls->setInterfaces(interfaces());
|
|
810
|
|
811 return cls;
|
|
812 }*/
|
|
813
|
|
814 /*******************************************************************************
|
|
815 * Returns true if this class is a subclass of the given class
|
|
816 */
|
|
817 bool AbstractMetaClass::inheritsFrom(const AbstractMetaClass *cls) const
|
|
818 {
|
|
819 Q_ASSERT(cls != 0);
|
|
820
|
|
821 const AbstractMetaClass *clazz = this;
|
|
822 while (clazz != 0) {
|
|
823 if (clazz == cls)
|
|
824 return true;
|
|
825
|
|
826 clazz = clazz->baseClass();
|
|
827 }
|
|
828
|
|
829 return false;
|
|
830 }
|
|
831
|
|
832 /*******************************************************************************
|
|
833 * Constructs an interface based on the functions and enums in this
|
|
834 * class and returns it...
|
|
835 */
|
|
836 AbstractMetaClass *AbstractMetaClass::extractInterface()
|
|
837 {
|
|
838 Q_ASSERT(typeEntry()->designatedInterface());
|
|
839
|
|
840 if (m_extracted_interface == 0) {
|
|
841 AbstractMetaClass *iface = new AbstractMetaClass;
|
|
842 iface->setAttributes(attributes());
|
|
843 iface->setBaseClass(0);
|
|
844 iface->setPrimaryInterfaceImplementor(this);
|
|
845
|
|
846 iface->setTypeEntry(typeEntry()->designatedInterface());
|
|
847
|
|
848 foreach (AbstractMetaFunction *function, functions()) {
|
|
849 if (!function->isConstructor())
|
|
850 iface->addFunction(function->copy());
|
|
851 }
|
|
852
|
|
853 // iface->setEnums(enums());
|
|
854 // setEnums(AbstractMetaEnumList());
|
|
855
|
|
856 foreach (const AbstractMetaField *field, fields()) {
|
|
857 if (field->isPublic()) {
|
|
858 AbstractMetaField *new_field = field->copy();
|
|
859 new_field->setEnclosingClass(iface);
|
|
860 iface->addField(new_field);
|
|
861 }
|
|
862 }
|
|
863
|
|
864 m_extracted_interface = iface;
|
|
865 addInterface(iface);
|
|
866 }
|
|
867
|
|
868 return m_extracted_interface;
|
|
869 }
|
|
870
|
|
871 /*******************************************************************************
|
|
872 * Returns a list of all the functions with a given name
|
|
873 */
|
|
874 AbstractMetaFunctionList AbstractMetaClass::queryFunctionsByName(const QString &name) const
|
|
875 {
|
|
876 AbstractMetaFunctionList returned;
|
|
877 AbstractMetaFunctionList functions = this->functions();
|
|
878 foreach (AbstractMetaFunction *function, functions) {
|
|
879 if (function->name() == name)
|
|
880 returned.append(function);
|
|
881 }
|
|
882
|
|
883 return returned;
|
|
884 }
|
|
885
|
|
886 /*******************************************************************************
|
|
887 * Returns all reference count modifications for any function in the class
|
|
888 */
|
|
889 QList<ReferenceCount> AbstractMetaClass::referenceCounts() const
|
|
890 {
|
|
891 QList<ReferenceCount> returned;
|
|
892
|
|
893 AbstractMetaFunctionList functions = this->functions();
|
|
894 foreach (AbstractMetaFunction *function, functions) {
|
|
895 returned += function->referenceCounts(this);
|
|
896 }
|
|
897
|
|
898 return returned;
|
|
899 }
|
|
900
|
|
901 /*******************************************************************************
|
|
902 * Returns a list of all the functions retrieved during parsing which should
|
|
903 * be added to the Java API.
|
|
904 */
|
|
905 AbstractMetaFunctionList AbstractMetaClass::functionsInTargetLang() const
|
|
906 {
|
|
907 int default_flags = NormalFunctions | Visible | NotRemovedFromTargetLang;
|
|
908
|
|
909 // Interfaces don't implement functions
|
|
910 default_flags |= isInterface() ? 0 : ClassImplements;
|
|
911
|
|
912 // Only public functions in final classes
|
|
913 // default_flags |= isFinal() ? WasPublic : 0;
|
|
914 int public_flags = isFinal() ? WasPublic : 0;
|
|
915
|
|
916 // Constructors
|
|
917 AbstractMetaFunctionList returned = queryFunctions(Constructors | default_flags | public_flags);
|
|
918
|
|
919 // Final functions
|
|
920 returned += queryFunctions(FinalInTargetLangFunctions | NonStaticFunctions | default_flags | public_flags);
|
|
921
|
|
922 // Virtual functions
|
|
923 returned += queryFunctions(VirtualInTargetLangFunctions | NonStaticFunctions | default_flags | public_flags);
|
|
924
|
|
925 // Static functions
|
|
926 returned += queryFunctions(StaticFunctions | default_flags | public_flags);
|
|
927
|
|
928 // Empty, private functions, since they aren't caught by the other ones
|
|
929 returned += queryFunctions(Empty | Invisible);
|
|
930
|
|
931 return returned;
|
|
932 }
|
|
933
|
|
934 AbstractMetaFunctionList AbstractMetaClass::virtualFunctions() const
|
|
935 {
|
|
936 AbstractMetaFunctionList list = functionsInShellClass();
|
|
937
|
|
938 AbstractMetaFunctionList returned;
|
|
939 foreach (AbstractMetaFunction *f, list) {
|
|
940 if (!f->isFinalInCpp() || f->isVirtualSlot())
|
|
941 returned += f;
|
|
942 }
|
|
943
|
|
944 return returned;
|
|
945 }
|
|
946
|
|
947 AbstractMetaFunctionList AbstractMetaClass::nonVirtualShellFunctions() const
|
|
948 {
|
|
949 AbstractMetaFunctionList list = functionsInShellClass();
|
|
950 AbstractMetaFunctionList returned;
|
|
951 foreach (AbstractMetaFunction *f, list) {
|
|
952 if (f->isFinalInCpp() && !f->isVirtualSlot())
|
|
953 returned += f;
|
|
954 }
|
|
955
|
|
956 return returned;
|
|
957 }
|
|
958
|
|
959 /*******************************************************************************
|
|
960 * Returns a list of all functions that should be declared and implemented in
|
|
961 * the shell class which is generated as a wrapper on top of the actual C++ class
|
|
962 */
|
|
963 AbstractMetaFunctionList AbstractMetaClass::functionsInShellClass() const
|
|
964 {
|
|
965 // Only functions and only protected and public functions
|
|
966 int default_flags = NormalFunctions | Visible | WasVisible | NotRemovedFromShell;
|
|
967
|
|
968 // All virtual functions
|
|
969 AbstractMetaFunctionList returned = queryFunctions(VirtualFunctions | default_flags);
|
|
970
|
|
971 // All functions explicitly set to be implemented by the shell class
|
|
972 // (mainly superclass functions that are hidden by other declarations)
|
|
973 returned += queryFunctions(ForcedShellFunctions | default_flags);
|
|
974
|
|
975 // All functions explicitly set to be virtual slots
|
|
976 returned += queryFunctions(VirtualSlots | default_flags);
|
|
977
|
|
978 return returned;
|
|
979 }
|
|
980
|
|
981 /*******************************************************************************
|
|
982 * Returns a list of all functions that require a public override function to
|
|
983 * be generated in the shell class. This includes all functions that were originally
|
|
984 * protected in the superclass.
|
|
985 */
|
|
986 AbstractMetaFunctionList AbstractMetaClass::publicOverrideFunctions() const
|
|
987 {
|
|
988 return queryFunctions(NormalFunctions | WasProtected | FinalInCppFunctions | NotRemovedFromTargetLang)
|
|
989 + queryFunctions(Signals | WasProtected | FinalInCppFunctions | NotRemovedFromTargetLang);
|
|
990 }
|
|
991
|
|
992 AbstractMetaFunctionList AbstractMetaClass::virtualOverrideFunctions() const
|
|
993 {
|
|
994 return queryFunctions(NormalFunctions | NonEmptyFunctions | Visible | VirtualInCppFunctions | NotRemovedFromShell) +
|
|
995 queryFunctions(Signals | NonEmptyFunctions | Visible | VirtualInCppFunctions | NotRemovedFromShell);
|
|
996 }
|
|
997
|
|
998 void AbstractMetaClass::sortFunctions()
|
|
999 {
|
|
1000 qSort(m_functions.begin(), m_functions.end(), function_sorter);
|
|
1001 }
|
|
1002
|
|
1003 void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions)
|
|
1004 {
|
|
1005 m_functions = functions;
|
|
1006
|
|
1007 // Functions must be sorted by name before next loop
|
|
1008 sortFunctions();
|
|
1009
|
|
1010 QString currentName;
|
|
1011 bool hasVirtuals = false;
|
|
1012 AbstractMetaFunctionList final_functions;
|
|
1013 foreach (AbstractMetaFunction *f, m_functions) {
|
|
1014 f->setOwnerClass(this);
|
|
1015
|
|
1016 m_has_virtual_slots |= f->isVirtualSlot();
|
|
1017 m_has_virtuals |= !f->isFinal() || f->isVirtualSlot();
|
|
1018 m_has_nonpublic |= !f->isPublic();
|
|
1019
|
|
1020 // If we have non-virtual overloads of a virtual function, we have to implement
|
|
1021 // all the overloads in the shell class to override the hiding rule
|
|
1022 if (currentName == f->name()) {
|
|
1023 hasVirtuals = hasVirtuals || !f->isFinal();
|
|
1024 if (f->isFinal())
|
|
1025 final_functions += f;
|
|
1026 } else {
|
|
1027 if (hasVirtuals && final_functions.size() > 0) {
|
|
1028 foreach (AbstractMetaFunction *final_function, final_functions) {
|
|
1029 *final_function += AbstractMetaAttributes::ForceShellImplementation;
|
|
1030
|
|
1031 QString warn = QString("hiding of function '%1' in class '%2'")
|
|
1032 .arg(final_function->name()).arg(name());
|
|
1033 ReportHandler::warning(warn);
|
|
1034 }
|
|
1035 }
|
|
1036
|
|
1037 hasVirtuals = !f->isFinal();
|
|
1038 final_functions.clear();
|
|
1039 if (f->isFinal())
|
|
1040 final_functions += f;
|
|
1041 currentName = f->name();
|
|
1042 }
|
|
1043 }
|
|
1044
|
|
1045 #ifndef QT_NO_DEBUG
|
|
1046 bool duplicate_function = false;
|
|
1047 for (int j=0; j<m_functions.size(); ++j) {
|
|
1048 FunctionModificationList mods = m_functions.at(j)->modifications(m_functions.at(j)->implementingClass());
|
|
1049
|
|
1050 bool removed = false;
|
|
1051 foreach (const FunctionModification &mod, mods) {
|
|
1052 if (mod.isRemoveModifier()) {
|
|
1053 removed = true;
|
|
1054 break ;
|
|
1055 }
|
|
1056 }
|
|
1057 if (removed)
|
|
1058 continue ;
|
|
1059
|
|
1060 for (int i=0; i<m_functions.size() - 1; ++i) {
|
|
1061 if (j == i)
|
|
1062 continue;
|
|
1063
|
|
1064 mods = m_functions.at(i)->modifications(m_functions.at(i)->implementingClass());
|
|
1065 bool removed = false;
|
|
1066 foreach (const FunctionModification &mod, mods) {
|
|
1067 if (mod.isRemoveModifier()) {
|
|
1068 removed = true;
|
|
1069 break ;
|
|
1070 }
|
|
1071 }
|
|
1072 if (removed)
|
|
1073 continue ;
|
|
1074
|
|
1075 uint cmp = m_functions.at(i)->compareTo(m_functions.at(j));
|
|
1076 if ((cmp & AbstractMetaFunction::EqualName) && (cmp & AbstractMetaFunction::EqualArguments)) {
|
|
1077 printf("%s.%s mostly equal to %s.%s\n",
|
|
1078 qPrintable(m_functions.at(i)->implementingClass()->typeEntry()->qualifiedCppName()),
|
|
1079 qPrintable(m_functions.at(i)->signature()),
|
|
1080 qPrintable(m_functions.at(j)->implementingClass()->typeEntry()->qualifiedCppName()),
|
|
1081 qPrintable(m_functions.at(j)->signature()));
|
|
1082 duplicate_function = true;
|
|
1083 }
|
|
1084 }
|
|
1085 }
|
|
1086 //Q_ASSERT(!duplicate_function);
|
|
1087 #endif
|
|
1088 }
|
|
1089
|
|
1090 bool AbstractMetaClass::hasFieldAccessors() const
|
|
1091 {
|
|
1092 foreach (const AbstractMetaField *field, fields()) {
|
|
1093 if (field->getter() || field->setter())
|
|
1094 return true;
|
|
1095 }
|
|
1096
|
|
1097 return false;
|
|
1098 }
|
|
1099
|
|
1100 bool AbstractMetaClass::hasDefaultToStringFunction() const
|
|
1101 {
|
|
1102 foreach (AbstractMetaFunction *f, queryFunctionsByName("toString")) {
|
|
1103 if (f->actualMinimumArgumentCount() == 0) {
|
|
1104 return true;
|
|
1105 }
|
|
1106
|
|
1107 }
|
|
1108 return false;
|
|
1109 }
|
|
1110
|
|
1111 void AbstractMetaClass::addFunction(AbstractMetaFunction *function)
|
|
1112 {
|
|
1113 function->setOwnerClass(this);
|
|
1114
|
|
1115 if (!function->isDestructor()) {
|
|
1116 m_functions << function;
|
|
1117 qSort(m_functions.begin(), m_functions.end(), function_sorter);
|
|
1118 }
|
|
1119
|
|
1120
|
|
1121 m_has_virtual_slots |= function->isVirtualSlot();
|
|
1122 m_has_virtuals |= !function->isFinal() || function->isVirtualSlot();
|
|
1123 m_has_nonpublic |= !function->isPublic();
|
|
1124 }
|
|
1125
|
|
1126 bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const
|
|
1127 {
|
|
1128 if (!other->isSignal())
|
|
1129 return false;
|
|
1130
|
|
1131 foreach (const AbstractMetaFunction *f, functions()) {
|
|
1132 if (f->isSignal() && f->compareTo(other) & AbstractMetaFunction::EqualName)
|
|
1133 return other->modifiedName() == f->modifiedName();
|
|
1134 }
|
|
1135
|
|
1136 return false;
|
|
1137 }
|
|
1138
|
|
1139
|
|
1140 QString AbstractMetaClass::name() const
|
|
1141 {
|
|
1142 return QString(m_type_entry->targetLangName()).replace("::", "_");
|
|
1143 }
|
|
1144
|
|
1145 bool AbstractMetaClass::hasFunction(const QString &str) const
|
|
1146 {
|
|
1147 foreach (const AbstractMetaFunction *f, functions())
|
|
1148 if (f->name() == str)
|
|
1149 return true;
|
|
1150 return false;
|
|
1151 }
|
|
1152
|
|
1153 /* Returns true if this class has one or more functions that are
|
|
1154 protected. If a class has protected members we need to generate a
|
|
1155 shell class with public accessors to the protected functions, so
|
|
1156 they can be called from the native functions.
|
|
1157 */
|
|
1158 bool AbstractMetaClass::hasProtectedFunctions() const {
|
|
1159 foreach (AbstractMetaFunction *func, m_functions) {
|
|
1160 if (func->isProtected())
|
|
1161 return true;
|
|
1162 }
|
|
1163 return false;
|
|
1164 }
|
|
1165
|
|
1166 bool AbstractMetaClass::generateShellClass() const
|
|
1167 {
|
|
1168 return m_force_shell_class ||
|
|
1169 (!isFinal()
|
|
1170 && (hasVirtualFunctions()
|
|
1171 || hasProtectedFunctions()
|
|
1172 || hasFieldAccessors()
|
|
1173 || typeEntry()->isObject())); // qtd2 for being more consistent
|
|
1174 }
|
|
1175
|
|
1176 QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const
|
|
1177 {
|
|
1178 for (int i=0; i<m_property_specs.size(); ++i)
|
|
1179 if (name == m_property_specs.at(i)->read())
|
|
1180 return m_property_specs.at(i);
|
|
1181 return 0;
|
|
1182 }
|
|
1183
|
|
1184 QPropertySpec *AbstractMetaClass::propertySpecForWrite(const QString &name) const
|
|
1185 {
|
|
1186 for (int i=0; i<m_property_specs.size(); ++i)
|
|
1187 if (name == m_property_specs.at(i)->write())
|
|
1188 return m_property_specs.at(i);
|
|
1189 return 0;
|
|
1190 }
|
|
1191
|
|
1192 QPropertySpec *AbstractMetaClass::propertySpecForReset(const QString &name) const
|
|
1193 {
|
|
1194 for (int i=0; i<m_property_specs.size(); ++i) {
|
|
1195 if (name == m_property_specs.at(i)->reset())
|
|
1196 return m_property_specs.at(i);
|
|
1197 }
|
|
1198 return 0;
|
|
1199 }
|
|
1200
|
293
|
1201 AbstractMetaFunction* AbstractMetaClass::copyConstructor() const
|
|
1202 {
|
|
1203 AbstractMetaFunctionList ctors = queryFunctions(Constructors);
|
|
1204 for(int i = 0; i < ctors.size(); i++)
|
|
1205 {
|
|
1206 AbstractMetaFunction *ctor = ctors.at(i);
|
|
1207 if (ctor->arguments().size() > 0)
|
|
1208 if(ctor->arguments().at(0)->type()->typeEntry() == typeEntry())
|
|
1209 return ctor;
|
|
1210 }
|
1
|
1211
|
293
|
1212 return NULL;
|
|
1213 }
|
1
|
1214
|
|
1215 static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func)
|
|
1216 {
|
|
1217 foreach (const AbstractMetaFunction *f, l) {
|
|
1218 if ((f->compareTo(func) & AbstractMetaFunction::PrettySimilar) == AbstractMetaFunction::PrettySimilar)
|
|
1219 return true;
|
|
1220 }
|
|
1221 return false;
|
|
1222 }
|
|
1223
|
|
1224 AbstractMetaField::AbstractMetaField() : m_getter(0), m_setter(0), m_class(0)
|
|
1225 {
|
|
1226 }
|
|
1227
|
|
1228 AbstractMetaField::~AbstractMetaField()
|
|
1229 {
|
|
1230 delete m_setter;
|
|
1231 delete m_getter;
|
|
1232 }
|
|
1233 ushort painters; // refcount
|
|
1234 AbstractMetaField *AbstractMetaField::copy() const
|
|
1235 {
|
|
1236 AbstractMetaField *returned = new AbstractMetaField;
|
|
1237 returned->setEnclosingClass(0);
|
|
1238 returned->setAttributes(attributes());
|
|
1239 returned->setName(name());
|
|
1240 returned->setType(type()->copy());
|
|
1241 returned->setOriginalAttributes(originalAttributes());
|
|
1242
|
|
1243 return returned;
|
|
1244 }
|
|
1245
|
|
1246 static QString upCaseFirst(const QString &str) {
|
|
1247 Q_ASSERT(!str.isEmpty());
|
|
1248 QString s = str;
|
|
1249 s[0] = s.at(0).toUpper();
|
|
1250 return s;
|
|
1251 }
|
|
1252
|
|
1253 static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QString &name, uint type) {
|
|
1254 AbstractMetaFunction *f = new AbstractMetaFunction;
|
|
1255
|
|
1256
|
|
1257
|
|
1258 f->setName(name);
|
|
1259 f->setOriginalName(name);
|
|
1260 f->setOwnerClass(g->enclosingClass());
|
|
1261 f->setImplementingClass(g->enclosingClass());
|
|
1262 f->setDeclaringClass(g->enclosingClass());
|
|
1263
|
|
1264 uint attr = AbstractMetaAttributes::Native
|
|
1265 | AbstractMetaAttributes::Final
|
|
1266 | type;
|
|
1267 if (g->isStatic())
|
|
1268 attr |= AbstractMetaAttributes::Static;
|
|
1269 if (g->isPublic())
|
|
1270 attr |= AbstractMetaAttributes::Public;
|
|
1271 else if (g->isProtected())
|
|
1272 attr |= AbstractMetaAttributes::Protected;
|
|
1273 else
|
|
1274 attr |= AbstractMetaAttributes::Private;
|
|
1275 f->setAttributes(attr);
|
|
1276 f->setOriginalAttributes(attr);
|
|
1277
|
|
1278 FieldModificationList mods = g->modifications();
|
|
1279 foreach (FieldModification mod, mods) {
|
|
1280 if (mod.isRenameModifier())
|
|
1281 f->setName(mod.renamedTo());
|
|
1282 if (mod.isAccessModifier()) {
|
|
1283 if (mod.isPrivate())
|
|
1284 f->setVisibility(AbstractMetaAttributes::Private);
|
|
1285 else if (mod.isProtected())
|
|
1286 f->setVisibility(AbstractMetaAttributes::Protected);
|
|
1287 else if (mod.isPublic())
|
|
1288 f->setVisibility(AbstractMetaAttributes::Public);
|
|
1289 else if (mod.isFriendly())
|
|
1290 f->setVisibility(AbstractMetaAttributes::Friendly);
|
|
1291 }
|
|
1292
|
|
1293 }
|
|
1294 return f;
|
|
1295 }
|
|
1296
|
|
1297 FieldModificationList AbstractMetaField::modifications() const
|
|
1298 {
|
|
1299 FieldModificationList mods = enclosingClass()->typeEntry()->fieldModifications();
|
|
1300 FieldModificationList returned;
|
|
1301
|
|
1302 foreach (FieldModification mod, mods) {
|
|
1303 if (mod.name == name())
|
|
1304 returned += mod;
|
|
1305 }
|
|
1306
|
|
1307 return returned;
|
|
1308 }
|
|
1309
|
|
1310 const AbstractMetaFunction *AbstractMetaField::setter() const
|
|
1311 {
|
|
1312 if (m_setter == 0) {
|
|
1313 m_setter = createXetter(this,
|
|
1314 "set" + upCaseFirst(name()),
|
|
1315 AbstractMetaAttributes::SetterFunction);
|
|
1316 AbstractMetaArgumentList arguments;
|
|
1317 AbstractMetaArgument *argument = new AbstractMetaArgument;
|
|
1318 argument->setType(type()->copy());
|
|
1319 argument->setName(name());
|
|
1320 arguments.append(argument);
|
|
1321 m_setter->setArguments(arguments);
|
|
1322 }
|
|
1323 return m_setter;
|
|
1324 }
|
|
1325
|
|
1326 const AbstractMetaFunction *AbstractMetaField::getter() const
|
|
1327 {
|
|
1328 if (m_getter == 0) {
|
|
1329 m_getter = createXetter(this,
|
|
1330 name(),
|
|
1331 AbstractMetaAttributes::GetterFunction);
|
|
1332 m_getter->setType(type());
|
|
1333 }
|
|
1334
|
|
1335 return m_getter;
|
|
1336 }
|
|
1337
|
|
1338
|
|
1339 bool AbstractMetaClass::hasConstructors() const
|
|
1340 {
|
|
1341 return queryFunctions(Constructors).size() != 0;
|
|
1342 }
|
|
1343
|
|
1344 void AbstractMetaClass::addDefaultConstructor()
|
|
1345 {
|
|
1346 AbstractMetaFunction *f = new AbstractMetaFunction;
|
|
1347 f->setName(name());
|
|
1348 f->setOwnerClass(this);
|
|
1349 f->setFunctionType(AbstractMetaFunction::ConstructorFunction);
|
|
1350 f->setArguments(AbstractMetaArgumentList());
|
|
1351 f->setDeclaringClass(this);
|
|
1352
|
|
1353 uint attr = AbstractMetaAttributes::Native;
|
|
1354 attr |= AbstractMetaAttributes::Public;
|
|
1355 attr |= AbstractMetaAttributes::Final; // qtd otherwise added constructor is virtual which in fact it is not
|
|
1356 f->setAttributes(attr);
|
|
1357 f->setImplementingClass(this);
|
|
1358 f->setOriginalAttributes(f->attributes());
|
|
1359
|
|
1360 addFunction(f);
|
|
1361 }
|
|
1362
|
|
1363 bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const
|
|
1364 {
|
|
1365 return functions_contains(m_functions, f);
|
|
1366 }
|
|
1367
|
|
1368 /* Goes through the list of functions and returns a list of all
|
|
1369 functions matching all of the criteria in \a query.
|
|
1370 */
|
|
1371
|
|
1372 AbstractMetaFunctionList AbstractMetaClass::queryFunctions(uint query) const
|
|
1373 {
|
|
1374 AbstractMetaFunctionList functions;
|
|
1375
|
|
1376 foreach (AbstractMetaFunction *f, m_functions) {
|
|
1377
|
|
1378 if ((query & VirtualSlots) && !f->isVirtualSlot())
|
|
1379 continue;
|
|
1380
|
|
1381 if ((query & NotRemovedFromTargetLang) && f->isRemovedFrom(f->implementingClass(), TypeSystem::TargetLangCode)) {
|
|
1382 continue;
|
|
1383 }
|
|
1384
|
|
1385 if ((query & NotRemovedFromTargetLang) && !f->isFinal() && f->isRemovedFrom(f->declaringClass(), TypeSystem::TargetLangCode)) {
|
|
1386 continue;
|
|
1387 }
|
|
1388
|
|
1389 if ((query & NotRemovedFromShell) && f->isRemovedFrom(f->implementingClass(), TypeSystem::ShellCode)) {
|
|
1390 continue;
|
|
1391 }
|
|
1392
|
|
1393 if ((query & NotRemovedFromShell) && !f->isFinal() && f->isRemovedFrom(f->declaringClass(), TypeSystem::ShellCode)) {
|
|
1394 continue;
|
|
1395 }
|
|
1396
|
|
1397 if ((query & Visible) && f->isPrivate()) {
|
|
1398 continue;
|
|
1399 }
|
|
1400
|
|
1401 if ((query & VirtualInTargetLangFunctions) && f->isFinalInTargetLang()) {
|
|
1402 continue;
|
|
1403 }
|
|
1404
|
|
1405 if ((query & Invisible) && !f->isPrivate()) {
|
|
1406 continue;
|
|
1407 }
|
|
1408
|
|
1409 if ((query & Empty) && !f->isEmptyFunction()) {
|
|
1410 continue;
|
|
1411 }
|
|
1412
|
|
1413 if ((query & WasPublic) && !f->wasPublic()) {
|
|
1414 continue;
|
|
1415 }
|
|
1416
|
|
1417 if ((query & WasVisible) && f->wasPrivate()) {
|
|
1418 continue;
|
|
1419 }
|
|
1420
|
|
1421 if ((query & WasProtected) && !f->wasProtected()) {
|
|
1422 continue;
|
|
1423 }
|
|
1424
|
|
1425 if ((query & ClassImplements) && f->ownerClass() != f->implementingClass()) {
|
|
1426 continue;
|
|
1427 }
|
|
1428
|
|
1429 if ((query & Inconsistent) && (f->isFinalInTargetLang() || !f->isFinalInCpp() || f->isStatic())) {
|
|
1430 continue;
|
|
1431 }
|
|
1432
|
|
1433 if ((query & FinalInTargetLangFunctions) && !f->isFinalInTargetLang()) {
|
|
1434 continue;
|
|
1435 }
|
|
1436
|
|
1437 if ((query & FinalInCppFunctions) && !f->isFinalInCpp()) {
|
|
1438 continue;
|
|
1439 }
|
|
1440
|
|
1441 if ((query & VirtualInCppFunctions) && f->isFinalInCpp()) {
|
|
1442 continue;
|
|
1443 }
|
|
1444
|
|
1445 if ((query & Signals) && (!f->isSignal())) {
|
|
1446 continue;
|
|
1447 }
|
|
1448
|
|
1449 if ((query & ForcedShellFunctions)
|
|
1450 && (!f->isForcedShellImplementation()
|
|
1451 || !f->isFinal())) {
|
|
1452 continue;
|
|
1453 }
|
|
1454
|
|
1455 if ((query & Constructors) && (!f->isConstructor()
|
|
1456 || f->ownerClass() != f->implementingClass())
|
|
1457 || f->isConstructor() && (query & Constructors) == 0) {
|
|
1458 continue;
|
|
1459 }
|
|
1460
|
|
1461 // Destructors are never included in the functions of a class currently
|
|
1462 /*
|
|
1463 if ((query & Destructors) && (!f->isDestructor()
|
|
1464 || f->ownerClass() != f->implementingClass())
|
|
1465 || f->isDestructor() && (query & Destructors) == 0) {
|
|
1466 continue;
|
|
1467 }*/
|
|
1468
|
|
1469 if ((query & VirtualFunctions) && (f->isFinal() || f->isSignal() || f->isStatic())) {
|
|
1470 continue;
|
|
1471 }
|
|
1472
|
|
1473 if ((query & StaticFunctions) && (!f->isStatic() || f->isSignal())) {
|
|
1474 continue;
|
|
1475 }
|
|
1476
|
|
1477 if ((query & NonStaticFunctions) && (f->isStatic())) {
|
|
1478 continue;
|
|
1479 }
|
|
1480
|
|
1481 if ((query & NonEmptyFunctions) && (f->isEmptyFunction())) {
|
|
1482 continue;
|
|
1483 }
|
|
1484
|
|
1485 if ((query & NormalFunctions) && (f->isSignal())) {
|
|
1486 continue;
|
|
1487 }
|
|
1488
|
|
1489 if ((query & AbstractFunctions) && !f->isAbstract()) {
|
|
1490 continue;
|
|
1491 }
|
|
1492
|
|
1493 functions << f;
|
|
1494 }
|
|
1495
|
|
1496 // qDebug() << "queried" << m_type_entry->qualifiedCppName() << "got" << functions.size() << "out of" << m_functions.size();
|
|
1497
|
|
1498 return functions;
|
|
1499 }
|
|
1500
|
|
1501
|
|
1502 bool AbstractMetaClass::hasInconsistentFunctions() const
|
|
1503 {
|
|
1504 return cppInconsistentFunctions().size() > 0;
|
|
1505 }
|
|
1506
|
|
1507 bool AbstractMetaClass::hasSignals() const
|
|
1508 {
|
|
1509 return cppSignalFunctions().size() > 0;
|
|
1510 }
|
|
1511
|
|
1512
|
|
1513 /**
|
|
1514 * Adds the specified interface to this class by adding all the
|
|
1515 * functions in the interface to this class.
|
|
1516 */
|
|
1517 void AbstractMetaClass::addInterface(AbstractMetaClass *interface)
|
|
1518 {
|
|
1519 Q_ASSERT(!m_interfaces.contains(interface));
|
|
1520 m_interfaces << interface;
|
|
1521
|
|
1522 if (m_extracted_interface != 0 && m_extracted_interface != interface)
|
|
1523 m_extracted_interface->addInterface(interface);
|
|
1524
|
|
1525 foreach (AbstractMetaFunction *function, interface->functions())
|
|
1526 if (!hasFunction(function) && !function->isConstructor()) {
|
|
1527 AbstractMetaFunction *cpy = function->copy();
|
|
1528 cpy->setImplementingClass(this);
|
|
1529
|
|
1530 // Setup that this function is an interface class.
|
|
1531 cpy->setInterfaceClass(interface);
|
|
1532 *cpy += AbstractMetaAttributes::InterfaceFunction;
|
|
1533
|
|
1534 // Copy the modifications in interface into the implementing classes.
|
|
1535 FunctionModificationList mods = function->modifications(interface);
|
|
1536 foreach (const FunctionModification &mod, mods) {
|
|
1537 m_type_entry->addFunctionModification(mod);
|
|
1538 }
|
|
1539
|
|
1540 // It should be mostly safe to assume that when we implement an interface
|
|
1541 // we don't "pass on" pure virtual functions to our sublcasses...
|
|
1542 // *cpy -= AbstractMetaAttributes::Abstract;
|
|
1543
|
|
1544 addFunction(cpy);
|
|
1545 }
|
|
1546 }
|
|
1547
|
|
1548
|
|
1549 void AbstractMetaClass::setInterfaces(const AbstractMetaClassList &interfaces)
|
|
1550 {
|
|
1551 m_interfaces = interfaces;
|
|
1552 }
|
|
1553
|
|
1554
|
|
1555 AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName)
|
|
1556 {
|
|
1557 foreach (AbstractMetaEnum *e, m_enums) {
|
|
1558 if (e->name() == enumName)
|
|
1559 return e;
|
|
1560 }
|
|
1561
|
|
1562 if (typeEntry()->designatedInterface())
|
|
1563 return extractInterface()->findEnum(enumName);
|
|
1564
|
|
1565 return 0;
|
|
1566 }
|
|
1567
|
|
1568
|
|
1569
|
|
1570
|
|
1571 /*! Recursivly searches for the enum value named \a enumValueName in
|
|
1572 this class and its superclasses and interfaces. Values belonging to
|
|
1573 \a meta_enum are excluded from the search.
|
|
1574 */
|
|
1575 AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValueName, AbstractMetaEnum *meta_enum)
|
|
1576 {
|
|
1577 foreach (AbstractMetaEnum *e, m_enums) {
|
|
1578 if (e == meta_enum)
|
|
1579 continue;
|
|
1580 foreach (AbstractMetaEnumValue *v, e->values()) {
|
|
1581 if (v->name() == enumValueName)
|
|
1582 return v;
|
|
1583 }
|
|
1584 }
|
|
1585
|
|
1586 if (typeEntry()->designatedInterface())
|
|
1587 return extractInterface()->findEnumValue(enumValueName, meta_enum);
|
|
1588
|
|
1589 if (baseClass() != 0)
|
|
1590 return baseClass()->findEnumValue(enumValueName, meta_enum);
|
|
1591
|
|
1592 return 0;
|
|
1593 }
|
|
1594
|
|
1595
|
|
1596 /*!
|
|
1597 * Searches through all of this class' enums for a value matching the
|
|
1598 * name \a enumValueName. The name is excluding the class/namespace
|
|
1599 * prefix. The function recursivly searches interfaces and baseclasses
|
|
1600 * of this class.
|
|
1601 */
|
|
1602 AbstractMetaEnum *AbstractMetaClass::findEnumForValue(const QString &enumValueName)
|
|
1603 {
|
|
1604 foreach (AbstractMetaEnum *e, m_enums) {
|
|
1605 foreach (AbstractMetaEnumValue *v, e->values()) {
|
|
1606 if (v->name() == enumValueName)
|
|
1607 return e;
|
|
1608 }
|
|
1609 }
|
|
1610
|
|
1611 if (typeEntry()->designatedInterface())
|
|
1612 return extractInterface()->findEnumForValue(enumValueName);
|
|
1613
|
|
1614 if (baseClass() != 0)
|
|
1615 return baseClass()->findEnumForValue(enumValueName);
|
|
1616
|
|
1617 return 0;
|
|
1618 }
|
|
1619
|
|
1620
|
|
1621 static void add_extra_include_for_type(AbstractMetaClass *meta_class, const AbstractMetaType *type)
|
|
1622 {
|
|
1623
|
|
1624 if (type == 0)
|
|
1625 return;
|
|
1626
|
|
1627 Q_ASSERT(meta_class != 0);
|
|
1628 const TypeEntry *entry = (type ? type->typeEntry() : 0);
|
|
1629 if (entry != 0 && entry->isComplex()) {
|
|
1630 const ComplexTypeEntry *centry = static_cast<const ComplexTypeEntry *>(entry);
|
|
1631 ComplexTypeEntry *class_entry = meta_class->typeEntry();
|
|
1632 if (class_entry != 0 && centry->include().isValid())
|
|
1633 class_entry->addExtraInclude(centry->include());
|
|
1634 }
|
|
1635
|
|
1636 if (type->hasInstantiations()) {
|
|
1637 QList<AbstractMetaType *> instantiations = type->instantiations();
|
|
1638 foreach (AbstractMetaType *instantiation, instantiations)
|
|
1639 add_extra_include_for_type(meta_class, instantiation);
|
|
1640 }
|
|
1641 }
|
|
1642
|
|
1643 static void add_extra_includes_for_function(AbstractMetaClass *meta_class, const AbstractMetaFunction *meta_function)
|
|
1644 {
|
|
1645 Q_ASSERT(meta_class != 0);
|
|
1646 Q_ASSERT(meta_function != 0);
|
|
1647 add_extra_include_for_type(meta_class, meta_function->type());
|
|
1648
|
|
1649 AbstractMetaArgumentList arguments = meta_function->arguments();
|
|
1650 foreach (AbstractMetaArgument *argument, arguments)
|
|
1651 add_extra_include_for_type(meta_class, argument->type());
|
|
1652 }
|
|
1653
|
|
1654 void AbstractMetaClass::fixFunctions()
|
|
1655 {
|
|
1656 if (m_functions_fixed)
|
|
1657 return;
|
|
1658 else
|
|
1659 m_functions_fixed = true;
|
|
1660
|
|
1661 AbstractMetaClass *super_class = baseClass();
|
|
1662 AbstractMetaFunctionList funcs = functions();
|
|
1663
|
|
1664 // printf("fix functions for %s\n", qPrintable(name()));
|
|
1665
|
|
1666 if (super_class != 0)
|
|
1667 super_class->fixFunctions();
|
|
1668 int iface_idx = 0;
|
|
1669 while (super_class || iface_idx < interfaces().size()) {
|
|
1670 // printf(" - base: %s\n", qPrintable(super_class->name()));
|
|
1671
|
|
1672 // Since we always traverse the complete hierarchy we are only
|
|
1673 // interrested in what each super class implements, not what
|
|
1674 // we may have propagated from their base classes again.
|
|
1675 AbstractMetaFunctionList super_funcs;
|
|
1676 if (super_class) {
|
|
1677
|
|
1678 // Super classes can never be final
|
|
1679 if (super_class->isFinalInTargetLang()) {
|
|
1680 ReportHandler::warning("Final class '" + super_class->name() + "' set to non-final, as it is extended by other classes");
|
|
1681 *super_class -= AbstractMetaAttributes::FinalInTargetLang;
|
|
1682 }
|
|
1683 super_funcs = super_class->queryFunctions(AbstractMetaClass::ClassImplements);
|
|
1684 } else {
|
|
1685 super_funcs = interfaces().at(iface_idx)->queryFunctions(AbstractMetaClass::NormalFunctions);
|
|
1686 }
|
|
1687
|
|
1688 QSet<AbstractMetaFunction *> funcs_to_add;
|
|
1689 for (int sfi=0; sfi<super_funcs.size(); ++sfi) {
|
|
1690 AbstractMetaFunction *sf = super_funcs.at(sfi);
|
|
1691
|
|
1692 if (sf->isRemovedFromAllLanguages(sf->implementingClass()))
|
|
1693 continue;
|
|
1694
|
|
1695 // we generally don't care about private functions, but we have to get the ones that are
|
|
1696 // virtual in case they override abstract functions.
|
|
1697 bool add = (sf->isNormal() || sf->isSignal() || sf->isEmptyFunction());
|
|
1698 for (int fi=0; fi<funcs.size(); ++fi) {
|
|
1699 AbstractMetaFunction *f = funcs.at(fi);
|
|
1700 if (f->isRemovedFromAllLanguages(f->implementingClass()))
|
|
1701 continue;
|
|
1702
|
|
1703 uint cmp = f->compareTo(sf);
|
|
1704
|
|
1705 if (cmp & AbstractMetaFunction::EqualModifiedName) {
|
|
1706 // printf(" - %s::%s similar to %s::%s %x vs %x\n",
|
|
1707 // qPrintable(sf->implementingClass()->typeEntry()->qualifiedCppName()),
|
|
1708 // qPrintable(sf->name()),
|
|
1709 // qPrintable(f->implementingClass()->typeEntry()->qualifiedCppName()),
|
|
1710 // qPrintable(f->name()),
|
|
1711 // sf->attributes(),
|
|
1712 // f->attributes());
|
|
1713
|
|
1714 add = false;
|
|
1715 if (cmp & AbstractMetaFunction::EqualArguments) {
|
|
1716
|
|
1717 // if (!(cmp & AbstractMetaFunction::EqualReturnType)) {
|
|
1718 // ReportHandler::warning(QString("%1::%2 and %3::%4 differ in retur type")
|
|
1719 // .arg(sf->implementingClass()->name())
|
|
1720 // .arg(sf->name())
|
|
1721 // .arg(f->implementingClass()->name())
|
|
1722 // .arg(f->name()));
|
|
1723 // }
|
|
1724
|
|
1725 // Same function, propegate virtual...
|
|
1726 if (!(cmp & AbstractMetaFunction::EqualAttributes)) {
|
|
1727 if (!f->isEmptyFunction()) {
|
|
1728 if (!sf->isFinalInCpp() && f->isFinalInCpp()) {
|
|
1729 *f -= AbstractMetaAttributes::FinalInCpp;
|
|
1730 // printf(" --- inherit virtual\n");
|
|
1731 }
|
|
1732 if (!sf->isFinalInTargetLang() && f->isFinalInTargetLang()) {
|
|
1733 *f -= AbstractMetaAttributes::FinalInTargetLang;
|
|
1734 // printf(" --- inherit virtual\n");
|
|
1735 }
|
|
1736 if (!f->isFinalInTargetLang() && f->isPrivate()) {
|
|
1737 f->setFunctionType(AbstractMetaFunction::EmptyFunction);
|
|
1738 f->setVisibility(AbstractMetaAttributes::Protected);
|
|
1739 *f += AbstractMetaAttributes::FinalInTargetLang;
|
|
1740 ReportHandler::warning(QString("private virtual function '%1' in '%2'")
|
|
1741 .arg(f->signature())
|
|
1742 .arg(f->implementingClass()->name()));
|
|
1743 }
|
|
1744 }
|
|
1745 }
|
|
1746
|
|
1747 if (f->visibility() != sf->visibility()) {
|
|
1748 QString warn = QString("visibility of function '%1' modified in class '%2'")
|
|
1749 .arg(f->name()).arg(name());
|
|
1750 ReportHandler::warning(warn);
|
|
1751
|
|
1752 // If new visibility is private, we can't
|
|
1753 // do anything. If it isn't, then we
|
|
1754 // prefer the parent class's visibility
|
|
1755 // setting for the function.
|
|
1756 if (!f->isPrivate() && !sf->isPrivate())
|
|
1757 f->setVisibility(sf->visibility());
|
|
1758
|
|
1759 // Private overrides of abstract functions have to go into the class or
|
|
1760 // the subclasses will not compile as non-abstract classes.
|
|
1761 // But they don't need to be implemented, since they can never be called.
|
|
1762 if (f->isPrivate() && sf->isAbstract()) {
|
|
1763 f->setFunctionType(AbstractMetaFunction::EmptyFunction);
|
|
1764 f->setVisibility(sf->visibility());
|
|
1765 *f += AbstractMetaAttributes::FinalInTargetLang;
|
|
1766 *f += AbstractMetaAttributes::FinalInCpp;
|
|
1767 }
|
|
1768 }
|
|
1769
|
|
1770 // Set the class which first declares this function, afawk
|
|
1771 f->setDeclaringClass(sf->declaringClass());
|
|
1772
|
|
1773 if (sf->isFinalInTargetLang() && !sf->isPrivate() && !f->isPrivate() && !sf->isStatic() && !f->isStatic()) {
|
|
1774 // Shadowed funcion, need to make base class
|
|
1775 // function non-virtual
|
|
1776 if (f->implementingClass() != sf->implementingClass() && f->implementingClass()->inheritsFrom(sf->implementingClass())) {
|
|
1777
|
|
1778 // Check whether the superclass method has been redefined to non-final
|
|
1779
|
|
1780 bool hasNonFinalModifier = false;
|
|
1781 bool isBaseImplPrivate = false;
|
|
1782 FunctionModificationList mods = sf->modifications(sf->implementingClass());
|
|
1783 foreach (FunctionModification mod, mods) {
|
|
1784 if (mod.isNonFinal()) {
|
|
1785 hasNonFinalModifier = true;
|
|
1786 break;
|
|
1787 } else if (mod.isPrivate()) {
|
|
1788 isBaseImplPrivate = true;
|
|
1789 break;
|
|
1790 }
|
|
1791 }
|
|
1792
|
|
1793 if (!hasNonFinalModifier && !isBaseImplPrivate) {
|
|
1794 ReportHandler::warning(QString::fromLatin1("Shadowing: %1::%2 and %3::%4; Java code will not compile")
|
|
1795 .arg(sf->implementingClass()->name())
|
|
1796 .arg(sf->signature())
|
|
1797 .arg(f->implementingClass()->name())
|
|
1798 .arg(f->signature()));
|
|
1799 }
|
|
1800 }
|
|
1801 }
|
|
1802
|
|
1803 }
|
|
1804
|
|
1805 if (cmp & AbstractMetaFunction::EqualDefaultValueOverload) {
|
|
1806 AbstractMetaArgumentList arguments;
|
|
1807 if (f->arguments().size() < sf->arguments().size())
|
|
1808 arguments = sf->arguments();
|
|
1809 else
|
|
1810 arguments = f->arguments();
|
|
1811 /* qtd
|
|
1812 for (int i=0; i<arguments.size(); ++i)
|
|
1813 arguments[i]->setDefaultValueExpression(QString());
|
|
1814 */ }
|
|
1815
|
|
1816
|
|
1817 // Otherwise we have function shadowing and we can
|
|
1818 // skip the thing...
|
|
1819 } else if (cmp & AbstractMetaFunction::EqualName && !sf->isSignal()) {
|
|
1820
|
|
1821 // In the case of function shadowing where the function name has been altered to
|
|
1822 // avoid conflict, we don't copy in the original.
|
|
1823 add = false;
|
|
1824 }
|
|
1825
|
|
1826 }
|
|
1827
|
|
1828 if (add)
|
|
1829 funcs_to_add << sf;
|
|
1830 }
|
|
1831
|
|
1832 foreach (AbstractMetaFunction *f, funcs_to_add)
|
|
1833 funcs << f->copy();
|
|
1834
|
|
1835 if (super_class)
|
|
1836 super_class = super_class->baseClass();
|
|
1837 else
|
|
1838 iface_idx++;
|
|
1839 }
|
|
1840
|
|
1841 bool hasPrivateConstructors = false;
|
|
1842 bool hasPublicConstructors = false;
|
|
1843 foreach (AbstractMetaFunction *func, funcs) {
|
|
1844 FunctionModificationList mods = func->modifications(this);
|
|
1845 foreach (const FunctionModification &mod, mods) {
|
|
1846 if (mod.isRenameModifier()) {
|
|
1847 // qDebug() << name() << func->originalName() << func << " from "
|
|
1848 // << func->implementingClass()->name() << "renamed to" << mod.renamedTo();
|
|
1849 func->setName(mod.renamedTo());
|
|
1850 }
|
|
1851 }
|
|
1852
|
|
1853 // Make sure class is abstract if one of the functions is
|
|
1854 if (func->isAbstract()) {
|
|
1855 (*this) += AbstractMetaAttributes::Abstract;
|
|
1856 (*this) -= AbstractMetaAttributes::Final;
|
|
1857 }
|
|
1858
|
|
1859 if (func->isConstructor()) {
|
|
1860 if (func->isPrivate())
|
|
1861 hasPrivateConstructors = true;
|
|
1862 else
|
|
1863 hasPublicConstructors = true;
|
|
1864 }
|
|
1865
|
|
1866
|
|
1867
|
|
1868 // Make sure that we include files for all classes that are in use
|
|
1869
|
|
1870 if (!func->isRemovedFrom(this, TypeSystem::ShellCode))
|
|
1871 add_extra_includes_for_function(this, func);
|
|
1872 }
|
|
1873
|
|
1874 if (hasPrivateConstructors && !hasPublicConstructors) {
|
|
1875 (*this) += AbstractMetaAttributes::Abstract;
|
|
1876 (*this) -= AbstractMetaAttributes::Final;
|
|
1877 }
|
|
1878
|
|
1879 foreach (AbstractMetaFunction *f1, funcs) {
|
|
1880 foreach (AbstractMetaFunction *f2, funcs) {
|
|
1881 if (f1 != f2) {
|
|
1882 uint cmp = f1->compareTo(f2);
|
|
1883 if ((cmp & AbstractMetaFunction::EqualName)
|
|
1884 && !f1->isFinalInCpp()
|
|
1885 && f2->isFinalInCpp()) {
|
|
1886 *f2 += AbstractMetaAttributes::FinalOverload;
|
|
1887 // qDebug() << f2 << f2->implementingClass()->name() << "::" << f2->name() << f2->arguments().size() << " vs " << f1 << f1->implementingClass()->name() << "::" << f1->name() << f1->arguments().size();
|
|
1888 // qDebug() << " " << f2;
|
|
1889 // AbstractMetaArgumentList f2Args = f2->arguments();
|
|
1890 // foreach (AbstractMetaArgument *a, f2Args)
|
|
1891 // qDebug() << " " << a->type()->name() << a->name();
|
|
1892 // qDebug() << " " << f1;
|
|
1893 // AbstractMetaArgumentList f1Args = f1->arguments();
|
|
1894 // foreach (AbstractMetaArgument *a, f1Args)
|
|
1895 // qDebug() << " " << a->type()->name() << a->name();
|
|
1896
|
|
1897 }
|
|
1898 }
|
|
1899 }
|
|
1900 }
|
|
1901
|
|
1902 setFunctions(funcs);
|
|
1903 }
|
|
1904
|
|
1905
|
|
1906 QString AbstractMetaType::minimalSignature() const
|
|
1907 {
|
|
1908 QString minimalSignature;
|
|
1909 if (isConstant())
|
|
1910 minimalSignature += "const ";
|
|
1911 minimalSignature += typeEntry()->qualifiedCppName();
|
309
|
1912 if (hasInstantiations() &&
|
|
1913 (static_cast<const ContainerTypeEntry *>(typeEntry()))->type() != ContainerTypeEntry::StringListContainer)
|
|
1914 {
|
1
|
1915 QList<AbstractMetaType *> instantiations = this->instantiations();
|
|
1916 minimalSignature += "<";
|
309
|
1917 for (int i=0;i<instantiations.size();++i)
|
|
1918 {
|
1
|
1919 if (i > 0)
|
|
1920 minimalSignature += ",";
|
|
1921 minimalSignature += instantiations.at(i)->minimalSignature();
|
|
1922 }
|
|
1923 minimalSignature += ">";
|
|
1924 }
|
|
1925
|
|
1926 if (isReference())
|
|
1927 minimalSignature += "&";
|
|
1928 for (int j=0; j<indirections(); ++j)
|
|
1929 minimalSignature += "*";
|
|
1930
|
|
1931 return minimalSignature;
|
|
1932 }
|
|
1933
|
|
1934 bool AbstractMetaType::hasNativeId() const
|
|
1935 {
|
|
1936 return (isQObject() || isValue() || isObject()) && typeEntry()->isNativeIdBased();
|
|
1937 }
|
|
1938
|
|
1939
|
|
1940 /*******************************************************************************
|
|
1941 * Other stuff...
|
|
1942 */
|
|
1943
|
|
1944
|
|
1945 AbstractMetaEnum *AbstractMetaClassList::findEnum(const EnumTypeEntry *entry) const
|
|
1946 {
|
|
1947 Q_ASSERT(entry->isEnum());
|
|
1948
|
|
1949 QString qualified_name = entry->qualifiedCppName();
|
|
1950 int pos = qualified_name.lastIndexOf("::");
|
|
1951
|
|
1952 QString enum_name;
|
|
1953 QString class_name;
|
|
1954
|
|
1955 if (pos > 0) {
|
|
1956 enum_name = qualified_name.mid(pos + 2);
|
|
1957 class_name = qualified_name.mid(0, pos);
|
|
1958 } else {
|
|
1959 enum_name = qualified_name;
|
|
1960 class_name = TypeDatabase::globalNamespaceClassName(entry);
|
|
1961 }
|
|
1962
|
|
1963 AbstractMetaClass *meta_class = findClass(class_name);
|
|
1964 if (!meta_class) {
|
|
1965 ReportHandler::warning(QString("AbstractMeta::findEnum(), unknown class '%1' in '%2'")
|
|
1966 .arg(class_name).arg(entry->qualifiedCppName()));
|
|
1967 return 0;
|
|
1968 }
|
|
1969
|
|
1970 return meta_class->findEnum(enum_name);
|
|
1971 }
|
|
1972
|
|
1973 AbstractMetaEnumValue *AbstractMetaEnumValueList::find(const QString &name) const
|
|
1974 {
|
|
1975 for (int i=0; i<size(); ++i) {
|
|
1976 if (name == at(i)->name())
|
|
1977 return at(i);
|
|
1978 }
|
|
1979 return 0;
|
|
1980 }
|
|
1981
|
|
1982 AbstractMetaEnumValue *AbstractMetaClassList::findEnumValue(const QString &name) const
|
|
1983 {
|
|
1984 QStringList lst = name.split(QLatin1String("::"));
|
|
1985
|
|
1986 Q_ASSERT_X(lst.size() == 2, "AbstractMetaClassList::findEnumValue()", "Expected qualified enum");
|
|
1987
|
|
1988
|
|
1989 QString prefixName = lst.at(0);
|
|
1990 QString enumName = lst.at(1);
|
|
1991
|
|
1992 AbstractMetaClass *cl = findClass(prefixName);
|
|
1993 if (cl)
|
|
1994 return cl->findEnumValue(enumName, 0);
|
|
1995
|
|
1996 ReportHandler::warning(QString("no matching enum '%1'").arg(name));
|
|
1997 return 0;
|
|
1998 }
|
|
1999
|
|
2000 /*!
|
|
2001 * Searches the list after a class that mathces \a name; either as
|
|
2002 * C++, Java base name or complete Java package.class name.
|
|
2003 */
|
|
2004
|
|
2005 AbstractMetaClass *AbstractMetaClassList::findClass(const QString &name) const
|
|
2006 {
|
|
2007 if (name.isEmpty())
|
|
2008 return 0;
|
|
2009
|
|
2010 foreach (AbstractMetaClass *c, *this) {
|
|
2011 if (c->qualifiedCppName() == name)
|
|
2012 return c;
|
|
2013 }
|
|
2014
|
|
2015 foreach (AbstractMetaClass *c, *this) {
|
|
2016 if (c->fullName() == name)
|
|
2017 return c;
|
|
2018 }
|
|
2019
|
|
2020 foreach (AbstractMetaClass *c, *this) {
|
|
2021 if (c->name() == name)
|
|
2022 return c;
|
|
2023 }
|
|
2024
|
|
2025 return 0;
|
|
2026 }
|
|
2027
|
|
2028 ArgumentReplace *ArgumentReplace::m_instance = 0;
|
|
2029
|
|
2030 ArgumentReplace::ArgumentReplace()
|
|
2031 {
|
|
2032 }
|
|
2033
|
|
2034 void ArgumentReplace::init()
|
|
2035 {
|
|
2036 if (m_instance)
|
|
2037 return;
|
|
2038
|
|
2039 m_instance = new ArgumentReplace();
|
|
2040 m_instance->data["version"] = "_version";
|
|
2041 m_instance->data["parent"] = "_parent";
|
|
2042 m_instance->data["delegate"] = "_delegate";
|
|
2043 m_instance->data["align"] = "_align";
|
|
2044 m_instance->data["in"] = "_in";
|
|
2045 m_instance->data["out"] = "_out";
|
|
2046 m_instance->data["scope"] = "_scope";
|
|
2047 m_instance->data["default"] = "_default";
|
39
|
2048 m_instance->data["body"] = "_body";
|
1
|
2049 }
|
|
2050
|
|
2051 QString ArgumentReplace::translate(QString arg)
|
|
2052 {
|
|
2053 if (m_instance->data.contains(arg))
|
|
2054 return m_instance->data[arg];
|
|
2055 else
|
|
2056 return arg;
|
|
2057 }
|