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