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