1
/*
2
 * This file is part of the API Extractor project.
3
 *
4
 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
5
 *
6
 * Contact: PySide team <contact@pyside.org>
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * version 2 as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20
 * 02110-1301 USA
21
 *
22
 */
23
24
#include "abstractmetalang.h"
25
#include "reporthandler.h"
26
#include "typedatabase.h"
27
28
/*******************************************************************************
29
 * AbstractMetaVariable
30
 */
31
32
AbstractMetaVariable::AbstractMetaVariable(const AbstractMetaVariable &other)
33
{
34
    m_originalName = other.m_originalName;
35
    m_name = other.m_name;
36
    m_type = other.m_type->copy();
37
    m_hasName = other.m_hasName;
38
    m_doc = other.m_doc;
39
}
40
41
/*******************************************************************************
42
 * AbstractMetaType
43
 */
44
45
AbstractMetaType::AbstractMetaType()
46
    :m_typeEntry(0),
47
    m_arrayElementCount(0),
48
    m_arrayElementType(0),
49
    m_originalTemplateType(0),
50
    m_pattern(InvalidPattern),
51
    m_constant(false),
52
    m_reference(false),
53
    m_cppInstantiation(true),
54
    m_indirections(0),
55
    m_reserved(0)
56
{
57
}
58
59
AbstractMetaType::~AbstractMetaType()
60
{
61
    qDeleteAll(m_children);
62
    m_instantiations.clear();
63
}
64
65
AbstractMetaType *AbstractMetaType::copy() const
66
{
67
    AbstractMetaType *cpy = new AbstractMetaType;
68
69
    cpy->setTypeUsagePattern(typeUsagePattern());
70
    cpy->setConstant(isConstant());
71
    cpy->setReference(isReference());
72
    cpy->setIndirections(indirections());
73
    cpy->setInstantiations(instantiations());
74
    cpy->setArrayElementCount(arrayElementCount());
75
    cpy->setOriginalTypeDescription(originalTypeDescription());
76
    cpy->setOriginalTemplateType(originalTemplateType() ? originalTemplateType()->copy() : 0);
77
78
    cpy->setArrayElementType(arrayElementType() ? arrayElementType()->copy() : 0);
79
80
    cpy->setTypeEntry(typeEntry());
81
82
    return cpy;
83
}
84
85
QString AbstractMetaType::cppSignature() const
86
{
87
    if (m_cachedCppSignature.isEmpty()) {
88
        if (isConstant())
89
            m_cachedCppSignature += "const ";
90
91
        m_cachedCppSignature += typeEntry()->qualifiedCppName();
92
93
        if (hasInstantiationInCpp()) {
94
            AbstractMetaTypeList types = instantiations();
95
            m_cachedCppSignature += "<";
96
            for (int i = 0; i < types.count(); ++i) {
97
                if (i > 0)
98
                    m_cachedCppSignature += ", ";
99
                m_cachedCppSignature += types[i]->cppSignature();
100
            }
101
            m_cachedCppSignature += " >";
102
        }
103
104
        if (actualIndirections()) {
105
            m_cachedCppSignature += ' ';
106
            if (indirections())
107
                m_cachedCppSignature += QString(indirections(), '*');
108
            if (isReference())
109
                m_cachedCppSignature += '&';
110
        }
111
    }
112
    return m_cachedCppSignature;
113
}
114
115
void AbstractMetaType::decideUsagePattern()
116
{
117
    const TypeEntry* type = typeEntry();
118
119
    if (type->isPrimitive() && (!actualIndirections()
120
        || (isConstant() && isReference() && !indirections()))) {
121
        setTypeUsagePattern(AbstractMetaType::PrimitivePattern);
122
123
    } else if (type->isVoid()) {
124
        setTypeUsagePattern(AbstractMetaType::NativePointerPattern);
125
126
    } else if (type->isVarargs()) {
127
        setTypeUsagePattern(AbstractMetaType::VarargsPattern);
128
129
    } else if (type->isString()
130
               && indirections() == 0
131
               && (isConstant() == isReference()
132
                   || isConstant())) {
133
        setTypeUsagePattern(AbstractMetaType::StringPattern);
134
135
    } else if (type->isChar()
136
               && !indirections()
137
               && isConstant() == isReference()) {
138
        setTypeUsagePattern(AbstractMetaType::CharPattern);
139
140
    } else if (type->isJObjectWrapper()
141
               && !indirections()
142
               && isConstant() == isReference()) {
143
        setTypeUsagePattern(AbstractMetaType::JObjectWrapperPattern);
144
145
    } else if (type->isVariant()
146
               && !indirections()
147
               && isConstant() == isReference()) {
148
        setTypeUsagePattern(AbstractMetaType::VariantPattern);
149
150
    } else if (type->isEnum() && !actualIndirections()) {
151
        setTypeUsagePattern(AbstractMetaType::EnumPattern);
152
153
    } else if (type->isObject() && indirections() == 0) {
154
        if (isReference()) {
155
            if (((ComplexTypeEntry*) type)->isQObject())
156
                setTypeUsagePattern(AbstractMetaType::QObjectPattern);
157
            else
158
                setTypeUsagePattern(AbstractMetaType::ObjectPattern);
159
        } else {
160
            setTypeUsagePattern(AbstractMetaType::ValuePattern);
161
        }
162
163
    } else if (type->isObject()
164
               && indirections() == 1) {
165
        if (((ComplexTypeEntry*) type)->isQObject())
166
            setTypeUsagePattern(AbstractMetaType::QObjectPattern);
167
        else
168
            setTypeUsagePattern(AbstractMetaType::ObjectPattern);
169
170
        // const-references to pointers can be passed as pointers
171
        if (isReference() && isConstant()) {
172
            setReference(false);
173
            setConstant(false);
174
        }
175
176
    } else if (type->isContainer() && !indirections()) {
177
        setTypeUsagePattern(AbstractMetaType::ContainerPattern);
178
179
    } else if (type->isTemplateArgument()) {
180
181
    } else if (type->isFlags()
182
               && !indirections()
183
               && (isConstant() == isReference())) {
184
        setTypeUsagePattern(AbstractMetaType::FlagsPattern);
185
186
    } else if (type->isArray()) {
187
        setTypeUsagePattern(AbstractMetaType::ArrayPattern);
188
189
    } else if (type->isThread()) {
190
        Q_ASSERT(indirections() == 1);
191
        setTypeUsagePattern(AbstractMetaType::ThreadPattern);
192
    } else if (type->isValue()) {
193
        if (indirections() == 1) {
194
            setTypeUsagePattern(AbstractMetaType::ValuePointerPattern);
195
        } else {
196
            setTypeUsagePattern(AbstractMetaType::ValuePattern);
197
        }
198
    } else {
199
        setTypeUsagePattern(AbstractMetaType::NativePointerPattern);
200
        ReportHandler::debugFull(QString("native pointer pattern for '%1'")
201
                                 .arg(cppSignature()));
202
    }
203
}
204
205
/*******************************************************************************
206
 * AbstractMetaArgument
207
 */
208
AbstractMetaArgument *AbstractMetaArgument::copy() const
209
{
210
    return new AbstractMetaArgument(*this);
211
}
212
213
/*******************************************************************************
214
 * AbstractMetaFunction
215
 */
216
AbstractMetaFunction::~AbstractMetaFunction()
217
{
218
    qDeleteAll(m_arguments);
219
    delete m_type;
220
}
221
222
/*******************************************************************************
223
 * Indicates that this function has a modification that removes it
224
 */
225
bool AbstractMetaFunction::isModifiedRemoved(int types) const
226
{
227
    FunctionModificationList mods = modifications(implementingClass());
228
    foreach (FunctionModification mod, mods) {
229
        if (!mod.isRemoveModifier())
230
            continue;
231
232
        if ((mod.removal & types) == types)
233
            return true;
234
    }
235
236
    return false;
237
}
238
239
bool AbstractMetaFunction::needsCallThrough() const
240
{
241
    if (ownerClass()->isInterface())
242
        return false;
243
    if (referenceCounts(implementingClass()).size() > 0)
244
        return true;
245
    if (argumentsHaveNativeId() || !isStatic())
246
        return true;
247
248
    foreach (const AbstractMetaArgument *arg, arguments()) {
249
        if (arg->type()->isArray() || arg->type()->isTargetLangEnum() || arg->type()->isTargetLangFlags())
250
            return true;
251
    }
252
253
    if (type() && (type()->isArray() || type()->isTargetLangEnum() || type()->isTargetLangFlags()))
254
        return true;
255
256
    for (int i = -1; i <= arguments().size(); ++i) {
257
        TypeSystem::Ownership owner = this->ownership(implementingClass(), TypeSystem::TargetLangCode, i);
258
        if (owner != TypeSystem::InvalidOwnership)
259
            return true;
260
    }
261
262
    return false;
263
}
264
265
bool AbstractMetaFunction::needsSuppressUncheckedWarning() const
266
{
267
    for (int i = -1; i <= arguments().size(); ++i) {
268
        QList<ReferenceCount> referenceCounts = this->referenceCounts(implementingClass(), i);
269
        foreach (ReferenceCount referenceCount, referenceCounts) {
270
            if (referenceCount.action != ReferenceCount::Set)
271
                return true;
272
        }
273
    }
274
    return false;
275
}
276
277
QString AbstractMetaFunction::marshalledName() const
278
{
279
    QString returned = "__qt_" + name();
280
    AbstractMetaArgumentList arguments = this->arguments();
281
    foreach (const AbstractMetaArgument *arg, arguments) {
282
        returned += "_";
283
        if (arg->type()->isNativePointer())
284
            returned += "nativepointer";
285
        else if (arg->type()->isIntegerEnum() || arg->type()->isIntegerFlags())
286
            returned += "int";
287
        else
288
            returned += arg->type()->name().replace("[]", "_3").replace(".", "_");
289
    }
290
    return returned;
291
}
292
293
bool AbstractMetaFunction::operator<(const AbstractMetaFunction &other) const
294
{
295
    uint result = compareTo(&other);
296
    return result & NameLessThan;
297
}
298
299
300
/*!
301
    Returns a mask of CompareResult describing how this function is
302
    compares to another function
303
*/
304
uint AbstractMetaFunction::compareTo(const AbstractMetaFunction *other) const
305
{
306
    uint result = 0;
307
308
    // Enclosing class...
309
    if (ownerClass() == other->ownerClass())
310
        result |= EqualImplementor;
311
312
    // Attributes
313
    if (attributes() == other->attributes())
314
        result |= EqualAttributes;
315
316
    // Compare types
317
    AbstractMetaType *t = type();
318
    AbstractMetaType *ot = other->type();
319
    if ((!t && !ot) || ((t && ot && t->name() == ot->name())))
320
        result |= EqualReturnType;
321
322
    // Compare names
323
    int cmp = originalName().compare(other->originalName());
324
325
    if (cmp < 0)
326
        result |= NameLessThan;
327
    else if (!cmp)
328
        result |= EqualName;
329
330
    // compare name after modification...
331
    cmp = modifiedName().compare(other->modifiedName());
332
    if (!cmp)
333
        result |= EqualModifiedName;
334
335
    // Compare arguments...
336
    AbstractMetaArgumentList minArguments;
337
    AbstractMetaArgumentList maxArguments;
338
    if (arguments().size() < other->arguments().size()) {
339
        minArguments = arguments();
340
        maxArguments = other->arguments();
341
    } else {
342
        minArguments = other->arguments();
343
        maxArguments = arguments();
344
    }
345
346
    int minCount = minArguments.size();
347
    int maxCount = maxArguments.size();
348
    bool same = true;
349
    for (int i = 0; i < maxCount; ++i) {
350
        if (i < minCount) {
351
            const AbstractMetaArgument *min_arg = minArguments.at(i);
352
            const AbstractMetaArgument *max_arg = maxArguments.at(i);
353
            if (min_arg->type()->name() != max_arg->type()->name()
354
                && (min_arg->defaultValueExpression().isEmpty() || max_arg->defaultValueExpression().isEmpty())) {
355
                same = false;
356
                break;
357
            }
358
        } else {
359
            if (maxArguments.at(i)->defaultValueExpression().isEmpty()) {
360
                same = false;
361
                break;
362
            }
363
        }
364
    }
365
366
    if (same)
367
        result |= minCount == maxCount ? EqualArguments : EqualDefaultValueOverload;
368
369
    return result;
370
}
371
372
AbstractMetaFunction *AbstractMetaFunction::copy() const
373
{
374
    AbstractMetaFunction *cpy = new AbstractMetaFunction;
375
    cpy->setName(name());
376
    cpy->setOriginalName(originalName());
377
    cpy->setOwnerClass(ownerClass());
378
    cpy->setImplementingClass(implementingClass());
379
    cpy->setInterfaceClass(interfaceClass());
380
    cpy->setFunctionType(functionType());
381
    cpy->setAttributes(attributes());
382
    cpy->setDeclaringClass(declaringClass());
383
    if (type())
384
        cpy->setType(type()->copy());
385
    cpy->setConstant(isConstant());
386
    cpy->setOriginalAttributes(originalAttributes());
387
388
    foreach (AbstractMetaArgument *arg, arguments())
389
    cpy->addArgument(arg->copy());
390
391
    Q_ASSERT((!type() && !cpy->type())
392
             || (type()->instantiations() == cpy->type()->instantiations()));
393
394
    return cpy;
395
}
396
397
QStringList AbstractMetaFunction::introspectionCompatibleSignatures(const QStringList &resolvedArguments) const
398
{
399
    AbstractMetaArgumentList arguments = this->arguments();
400
    if (arguments.size() == resolvedArguments.size()) {
401
        return (QStringList() << TypeDatabase::normalizedSignature((name() + "(" + resolvedArguments.join(",") + ")").toUtf8().constData()));
402
    } else {
403
        QStringList returned;
404
405
        AbstractMetaArgument *argument = arguments.at(resolvedArguments.size());
406
        QStringList minimalTypeSignature = argument->type()->minimalSignature().split("::");
407
        for (int i = 0; i < minimalTypeSignature.size(); ++i) {
408
            returned += introspectionCompatibleSignatures(QStringList(resolvedArguments)
409
                                                          << QStringList(minimalTypeSignature.mid(minimalTypeSignature.size() - i - 1)).join("::"));
410
        }
411
412
        return returned;
413
    }
414
}
415
416
QString AbstractMetaFunction::signature() const
417
{
418
    if (m_cachedSignature.isEmpty()) {
419
        m_cachedSignature = m_originalName;
420
421
        m_cachedSignature += '(';
422
423
        for (int i = 0; i < m_arguments.count(); ++i) {
424
            if (i > 0)
425
                m_cachedSignature += ", ";
426
            AbstractMetaArgument *a = m_arguments.at(i);
427
            m_cachedSignature += a->type()->cppSignature();
428
429
            // We need to have the argument names in the qdoc files
430
            m_cachedSignature += ' ';
431
            m_cachedSignature += a->name();
432
        }
433
        m_cachedSignature += ")";
434
435
        if (isConstant())
436
            m_cachedSignature += " const";
437
    }
438
    return m_cachedSignature;
439
}
440
441
int AbstractMetaFunction::actualMinimumArgumentCount() const
442
{
443
    AbstractMetaArgumentList arguments = this->arguments();
444
445
    int count = 0;
446
    for (int i = 0; i < arguments.size(); ++i && ++count) {
447
        if (argumentRemoved(i + 1))
448
            --count;
449
        else if (!arguments.at(i)->defaultValueExpression().isEmpty())
450
            break;
451
    }
452
453
    return count;
454
}
455
456
// Returns reference counts for argument at idx, or all arguments if idx == -2
457
QList<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaClass *cls, int idx) const
458
{
459
    QList<ReferenceCount> returned;
460
461
    FunctionModificationList mods = this->modifications(cls);
462
    foreach (FunctionModification mod, mods) {
463
        QList<ArgumentModification> argumentMods = mod.argument_mods;
464
        foreach (ArgumentModification argumentMod, argumentMods) {
465
            if (argumentMod.index != idx && idx != -2)
466
                continue;
467
            returned += argumentMod.referenceCounts;
468
        }
469
    }
470
471
    return returned;
472
}
473
474
475
ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls, int idx) const
476
{
477
    FunctionModificationList mods = this->modifications(cls);
478
    foreach (FunctionModification mod, mods) {
479
        QList<ArgumentModification> argumentMods = mod.argument_mods;
480
        foreach (ArgumentModification argumentMod, argumentMods) {
481
            if (argumentMod.index != idx)
482
                continue;
483
            return argumentMod.owner;
484
        }
485
    }
486
    return ArgumentOwner();
487
}
488
489
490
QString AbstractMetaFunction::replacedDefaultExpression(const AbstractMetaClass *cls, int key) const
491
{
492
    FunctionModificationList modifications = this->modifications(cls);
493
    foreach (FunctionModification modification, modifications) {
494
        QList<ArgumentModification> argumentModifications = modification.argument_mods;
495
        foreach (ArgumentModification argumentModification, argumentModifications) {
496
            if (argumentModification.index == key
497
                && !argumentModification.replacedDefaultExpression.isEmpty()) {
498
                return argumentModification.replacedDefaultExpression;
499
            }
500
        }
501
    }
502
503
    return QString();
504
}
505
506
bool AbstractMetaFunction::removedDefaultExpression(const AbstractMetaClass *cls, int key) const
507
{
508
    FunctionModificationList modifications = this->modifications(cls);
509
    foreach (FunctionModification modification, modifications) {
510
        QList<ArgumentModification> argumentModifications = modification.argument_mods;
511
        foreach (ArgumentModification argumentModification, argumentModifications) {
512
            if (argumentModification.index == key
513
                && argumentModification.removedDefaultExpression) {
514
                return true;
515
            }
516
        }
517
    }
518
519
    return false;
520
}
521
522
bool AbstractMetaFunction::resetObjectAfterUse(int argumentIdx) const
523
{
524
    const AbstractMetaClass *cls = declaringClass();
525
    FunctionModificationList modifications = this->modifications(cls);
526
    foreach (FunctionModification modification, modifications) {
527
        QList<ArgumentModification> argumentModifications = modification.argument_mods;
528
        foreach (ArgumentModification argumentModification, argumentModifications) {
529
            if (argumentModification.index == argumentIdx && argumentModification.resetAfterUse)
530
                return true;
531
        }
532
    }
533
534
    return false;
535
}
536
537
QString AbstractMetaFunction::nullPointerDefaultValue(const AbstractMetaClass *mainClass, int argumentIdx) const
538
{
539
    Q_ASSERT(nullPointersDisabled(mainClass, argumentIdx));
540
541
    const AbstractMetaClass *cls = mainClass;
542
    if (!cls)
543
        cls = implementingClass();
544
545
    do {
546
        FunctionModificationList modifications = this->modifications(cls);
547
        foreach (FunctionModification modification, modifications) {
548
            QList<ArgumentModification> argumentModifications = modification.argument_mods;
549
            foreach (ArgumentModification argumentModification, argumentModifications) {
550
                if (argumentModification.index == argumentIdx
551
                    && argumentModification.noNullPointers) {
552
                    return argumentModification.nullPointerDefaultValue;
553
                }
554
            }
555
        }
556
        cls = cls->baseClass();
557
    } while (cls && !mainClass); // Once when mainClass, or once for all base classes of implementing class
558
559
    return QString();
560
561
}
562
563
bool AbstractMetaFunction::nullPointersDisabled(const AbstractMetaClass *mainClass, int argumentIdx) const
564
{
565
    const AbstractMetaClass *cls = mainClass;
566
    if (!cls)
567
        cls = implementingClass();
568
569
    do {
570
        FunctionModificationList modifications = this->modifications(cls);
571
        foreach (FunctionModification modification, modifications) {
572
            QList<ArgumentModification> argumentModifications = modification.argument_mods;
573
            foreach (ArgumentModification argumentModification, argumentModifications) {
574
                if (argumentModification.index == argumentIdx
575
                    && argumentModification.noNullPointers) {
576
                    return true;
577
                }
578
            }
579
        }
580
581
        cls = cls->baseClass();
582
    } while (cls && !mainClass); // Once when mainClass, or once for all base classes of implementing class
583
584
    return false;
585
}
586
587
QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int key) const
588
{
589
    FunctionModificationList modifications = this->modifications(declaringClass());
590
    foreach (FunctionModification modification, modifications) {
591
        QList<ArgumentModification> argumentModifications = modification.argument_mods;
592
        foreach (ArgumentModification argumentModification, argumentModifications) {
593
            if (argumentModification.index != key)
594
                continue;
595
596
            foreach (CodeSnip snip, argumentModification.conversion_rules) {
597
                if (snip.language == language && !snip.code().isEmpty())
598
                    return snip.code();
599
            }
600
        }
601
    }
602
603
    return QString();
604
}
605
606
QString AbstractMetaFunction::argumentReplaced(int key) const
607
{
608
    FunctionModificationList modifications = this->modifications(declaringClass());
609
    foreach (FunctionModification modification, modifications) {
610
        QList<ArgumentModification>& argumentModifications = modification.argument_mods;
611
        foreach (ArgumentModification argumentModification, argumentModifications) {
612
            if (argumentModification.index == key && !argumentModification.replace_value.isEmpty())
613
                return argumentModification.replace_value;
614
        }
615
    }
616
617
    return "";
618
}
619
620
// FIXME If we remove a arg. in the method at the base class, it will not reflect here.
621
bool AbstractMetaFunction::argumentRemoved(int key) const
622
{
623
    FunctionModificationList modifications = this->modifications(declaringClass());
624
    foreach (FunctionModification modification, modifications) {
625
        QList<ArgumentModification> argumentModifications = modification.argument_mods;
626
        foreach (ArgumentModification argumentModification, argumentModifications) {
627
            if (argumentModification.index == key) {
628
                if (argumentModification.removed)
629
                    return true;
630
            }
631
        }
632
    }
633
634
    return false;
635
}
636
637
bool AbstractMetaFunction::isVirtualSlot() const
638
{
639
    FunctionModificationList modifications = this->modifications(declaringClass());
640
    foreach (FunctionModification modification, modifications) {
641
        if (modification.isVirtualSlot())
642
            return true;
643
    }
644
645
    return false;
646
}
647
648
bool AbstractMetaFunction::disabledGarbageCollection(const AbstractMetaClass *cls, int key) const
649
{
650
    FunctionModificationList modifications = this->modifications(cls);
651
    foreach (FunctionModification modification, modifications) {
652
        QList<ArgumentModification> argumentModifications = modification.argument_mods;
653
        foreach (ArgumentModification argumentModification, argumentModifications) {
654
            if (argumentModification.index != key)
655
                continue;
656
657
            foreach (TypeSystem::Ownership ownership, argumentModification.ownerships.values()) {
658
                if (ownership == TypeSystem::CppOwnership)
659
                    return true;
660
            }
661
662
        }
663
    }
664
665
    return false;
666
}
667
668
bool AbstractMetaFunction::isDeprecated() const
669
{
670
    FunctionModificationList modifications = this->modifications(declaringClass());
671
    foreach (FunctionModification modification, modifications) {
672
        if (modification.isDeprecated())
673
            return true;
674
    }
675
    return false;
676
}
677
678
bool AbstractMetaFunction::isThread() const
679
{
680
    FunctionModificationList modifications = this->modifications(declaringClass());
681
    foreach (FunctionModification modification, modifications) {
682
        if (modification.isThread())
683
            return true;
684
    }
685
    return false;
686
}
687
688
bool AbstractMetaFunction::allowThread() const
689
{
690
    FunctionModificationList modifications = this->modifications(declaringClass());
691
    foreach (FunctionModification modification, modifications) {
692
        if (modification.allowThread())
693
            return true;
694
    }
695
    return false;
696
}
697
698
699
TypeSystem::Ownership AbstractMetaFunction::ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int key) const
700
{
701
    FunctionModificationList modifications = this->modifications(cls);
702
    foreach (FunctionModification modification, modifications) {
703
        QList<ArgumentModification> argumentModifications = modification.argument_mods;
704
        foreach (ArgumentModification argumentModification, argumentModifications) {
705
            if (argumentModification.index == key)
706
                return argumentModification.ownerships.value(language, TypeSystem::InvalidOwnership);
707
        }
708
    }
709
710
    return TypeSystem::InvalidOwnership;
711
}
712
713
bool AbstractMetaFunction::isRemovedFromAllLanguages(const AbstractMetaClass *cls) const
714
{
715
    return isRemovedFrom(cls, TypeSystem::All);
716
}
717
718
bool AbstractMetaFunction::isRemovedFrom(const AbstractMetaClass *cls, TypeSystem::Language language) const
719
{
720
    FunctionModificationList modifications = this->modifications(cls);
721
    foreach (FunctionModification modification, modifications) {
722
        if ((modification.removal & language) == language)
723
            return true;
724
    }
725
726
    return false;
727
728
}
729
730
QString AbstractMetaFunction::typeReplaced(int key) const
731
{
732
    FunctionModificationList modifications = this->modifications(declaringClass());
733
    foreach (FunctionModification modification, modifications) {
734
        QList<ArgumentModification> argumentModifications = modification.argument_mods;
735
        foreach (ArgumentModification argumentModification, argumentModifications) {
736
            if (argumentModification.index == key
737
                && !argumentModification.modified_type.isEmpty()) {
738
                return argumentModification.modified_type;
739
            }
740
        }
741
    }
742
743
    return QString();
744
}
745
746
QString AbstractMetaFunction::minimalSignature() const
747
{
748
    if (!m_cachedMinimalSignature.isEmpty())
749
        return m_cachedMinimalSignature;
750
751
    QString minimalSignature = originalName() + "(";
752
    AbstractMetaArgumentList arguments = this->arguments();
753
754
    for (int i = 0; i < arguments.count(); ++i) {
755
        AbstractMetaType *t = arguments.at(i)->type();
756
757
        if (i > 0)
758
            minimalSignature += ",";
759
760
        minimalSignature += t->minimalSignature();
761
    }
762
    minimalSignature += ")";
763
    if (isConstant())
764
        minimalSignature += "const";
765
766
    minimalSignature = TypeDatabase::normalizedSignature(minimalSignature.toLocal8Bit().constData());
767
    m_cachedMinimalSignature = minimalSignature;
768
769
    return minimalSignature;
770
}
771
772
FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaClass* implementor) const
773
{
774
    if (!implementor)
775
        implementor = ownerClass();
776
777
    if (!implementor)
778
        return TypeDatabase::instance()->functionModifications(minimalSignature());
779
780
    FunctionModificationList mods;
781
    while (implementor) {
782
        mods += implementor->typeEntry()->functionModifications(minimalSignature());
783
        if ((implementor == implementor->baseClass()) ||
784
            (implementor == implementingClass() && (mods.size() > 0)))
785
                break;
786
        implementor = implementor->baseClass();
787
    }
788
    return mods;
789
}
790
791
bool AbstractMetaFunction::hasModifications(const AbstractMetaClass *implementor) const
792
{
793
    return !modifications(implementor).isEmpty();
794
}
795
796
QString AbstractMetaFunction::argumentName(int index, bool create, const AbstractMetaClass *implementor) const
797
{
798
    return m_arguments[--index]->name();
799
}
800
801
bool AbstractMetaFunction::isCallOperator() const
802
{
803
    return m_name == "operator()";
804
}
805
806
bool AbstractMetaFunction::hasInjectedCode() const
807
{
808
    foreach (const FunctionModification mod, modifications(ownerClass())) {
809
        if (mod.isCodeInjection())
810
            return true;
811
    }
812
    return false;
813
}
814
815
CodeSnipList AbstractMetaFunction::injectedCodeSnips(CodeSnip::Position position, TypeSystem::Language language) const
816
{
817
    CodeSnipList result;
818
    foreach (const FunctionModification mod, modifications(ownerClass())) {
819
        if (mod.isCodeInjection()) {
820
            QList<CodeSnip>::const_iterator it = mod.snips.constBegin();
821
            for (;it != mod.snips.constEnd(); ++it) {
822
                if ((it->language & language) && (it->position == position || position == CodeSnip::Any))
823
                    result << *it;
824
            }
825
        }
826
    }
827
    return result;
828
}
829
830
bool AbstractMetaFunction::hasSignatureModifications() const
831
{
832
    foreach (const FunctionModification mod, modifications()) {
833
        if (mod.isRenameModifier())
834
            return true;
835
        foreach (const ArgumentModification argmod, mod.argument_mods) {
836
            // since zero represents the return type and we're
837
            // interested only in checking the function arguments,
838
            // it will be ignored.
839
            if (argmod.index > 0)
840
                return true;
841
        }
842
    }
843
    return false;
844
}
845
846
bool AbstractMetaFunction::isConversionOperator(QString funcName)
847
{
848
    static QRegExp opRegEx("^operator(?:\\s+(?:const|volatile))?\\s+(\\w+\\s*)&?$");
849
    return opRegEx.indexIn(funcName) > -1;
850
}
851
852
bool AbstractMetaFunction::isOperatorOverload(QString funcName)
853
{
854
    if (isConversionOperator(funcName))
855
        return true;
856
857
    static QRegExp opRegEx("^operator([+\\-\\*/%=&\\|\\^\\<>!][=]?"
858
                    "|\\+\\+|\\-\\-|&&|\\|\\||<<[=]?|>>[=]?|~"
859
                    "|\\[\\]|\\s+delete\\[?\\]?"
860
                    "|\\(\\)"
861
                    "|\\s+new\\[?\\]?)$");
862
    return opRegEx.indexIn(funcName) > -1;
863
}
864
865
bool AbstractMetaFunction::isCastOperator() const
866
{
867
    return originalName().startsWith("operator ");
868
}
869
870
bool AbstractMetaFunction::isArithmeticOperator() const
871
{
872
    if (!isOperatorOverload())
873
        return false;
874
875
    QString name = originalName();
876
877
    // It's a dereference operator!
878
    if (name == "operator*" && m_arguments.isEmpty())
879
        return false;
880
881
    return name == "operator+" || name == "operator+="
882
            || name == "operator-" || name == "operator-="
883
            || name == "operator*" || name == "operator*="
884
            || name == "operator/" || name == "operator/="
885
            || name == "operator%" || name == "operator%="
886
            || name == "operator++" || name == "operator--";
887
}
888
889
bool AbstractMetaFunction::isBitwiseOperator() const
890
{
891
    if (!isOperatorOverload())
892
        return false;
893
894
    QString name = originalName();
895
    return name == "operator<<" || name == "operator<<="
896
            || name == "operator>>" || name == "operator>>="
897
            || name == "operator&" || name == "operator&="
898
            || name == "operator|" || name == "operator|="
899
            || name == "operator^" || name == "operator^="
900
            || name == "operator~";
901
}
902
903
bool AbstractMetaFunction::isComparisonOperator() const
904
{
905
    if (!isOperatorOverload())
906
        return false;
907
908
    QString name = originalName();
909
    return name == "operator<" || name == "operator<="
910
            || name == "operator>" || name == "operator>="
911
            || name == "operator==" || name == "operator!=";
912
}
913
914
bool AbstractMetaFunction::isLogicalOperator() const
915
{
916
    if (!isOperatorOverload())
917
        return false;
918
919
    QString name = originalName();
920
    return name == "operator!"
921
            || name == "operator&&"
922
            || name == "operator||";
923
}
924
925
bool AbstractMetaFunction::isSubscriptOperator() const
926
{
927
    if (!isOperatorOverload())
928
        return false;
929
930
    return originalName() == "operator[]";
931
}
932
933
bool AbstractMetaFunction::isAssignmentOperator() const
934
{
935
    if (!isOperatorOverload())
936
        return false;
937
938
    return originalName() == "operator=";
939
}
940
941
bool AbstractMetaFunction::isOtherOperator() const
942
{
943
    if (!isOperatorOverload())
944
        return false;
945
946
    return !isArithmeticOperator()
947
            && !isBitwiseOperator()
948
            && !isComparisonOperator()
949
            && !isLogicalOperator()
950
            && !isConversionOperator()
951
            && !isSubscriptOperator()
952
            && !isAssignmentOperator();
953
}
954
955
int AbstractMetaFunction::arityOfOperator() const
956
{
957
    if (!isOperatorOverload() || isCallOperator())
958
        return -1;
959
960
    int arity = m_arguments.size();
961
962
    // Operator overloads that are class members
963
    // implicitly includes the instance and have
964
    // one parameter less than their arity,
965
    // so we increment it.
966
    if (ownerClass() && arity < 2)
967
        arity++;
968
969
    return arity;
970
}
971
972
bool AbstractMetaFunction::isInplaceOperator() const
973
{
974
    if (!isOperatorOverload())
975
        return false;
976
977
    QString name = originalName();
978
    return name == "operator+=" || name == "operator&="
979
           || name == "operator-=" || name == "operator|="
980
           || name == "operator*=" || name == "operator^="
981
           || name == "operator/=" || name == "operator<<="
982
           || name == "operator%=" || name == "operator>>=";
983
}
984
985
bool AbstractMetaFunction::isVirtual() const
986
{
987
    return !isFinal() && !isSignal() && !isStatic() && !isFinalInCpp() && !isConstructor();
988
}
989
990
bool AbstractMetaFunction::isCopyConstructor() const
991
{
992
    if (!ownerClass() || !isConstructor() || arguments().count() != 1)
993
        return false;
994
995
    const AbstractMetaType* type = arguments().first()->type();
996
    return type->typeEntry() == ownerClass()->typeEntry() &&
997
           type->isConstant() && type->isReference();
998
}
999
1000
QString AbstractMetaFunction::modifiedName() const
1001
{
1002
    if (m_cachedModifiedName.isEmpty()) {
1003
        FunctionModificationList mods = modifications(implementingClass());
1004
        foreach (FunctionModification mod, mods) {
1005
            if (mod.isRenameModifier()) {
1006
                m_cachedModifiedName = mod.renamedToName;
1007
                break;
1008
            }
1009
        }
1010
        if (m_cachedModifiedName.isEmpty())
1011
            m_cachedModifiedName = name();
1012
    }
1013
    return m_cachedModifiedName;
1014
}
1015
1016
QString AbstractMetaFunction::targetLangSignature(bool minimal) const
1017
{
1018
    QString s;
1019
1020
    // Attributes...
1021
    if (!minimal) {
1022
        // Return type
1023
        if (type())
1024
            s += type()->name() + " ";
1025
        else
1026
            s += "void ";
1027
    }
1028
1029
    s += modifiedName();
1030
    s += "(";
1031
1032
    int j = 0;
1033
    for (int i = 0; i < m_arguments.size(); ++i) {
1034
        if (argumentRemoved(i + 1))
1035
            continue;
1036
        if (j) {
1037
            s += ",";
1038
            if (!minimal)
1039
                s += QLatin1Char(' ');
1040
        }
1041
        s += m_arguments.at(i)->type()->name();
1042
1043
        if (!minimal) {
1044
            s += " ";
1045
            s += m_arguments.at(i)->name();
1046
        }
1047
        ++j;
1048
    }
1049
1050
    s += ")";
1051
1052
    return s;
1053
}
1054
1055
1056
bool function_sorter(AbstractMetaFunction *a, AbstractMetaFunction *b)
1057
{
1058
    return a->signature() < b->signature();
1059
}
1060
1061
/*******************************************************************************
1062
 * AbstractMetaClass
1063
 */
1064
AbstractMetaClass::~AbstractMetaClass()
1065
{
1066
    qDeleteAll(m_functions);
1067
    qDeleteAll(m_fields);
1068
    qDeleteAll(m_enums);
1069
    qDeleteAll(m_orphanInterfaces);
1070
    if (hasTemplateBaseClassInstantiations()) {
1071
        foreach (AbstractMetaType* inst, templateBaseClassInstantiations())
1072
            delete inst;
1073
    }
1074
}
1075
1076
/*******************************************************************************
1077
 * Returns true if this class is a subclass of the given class
1078
 */
1079
bool AbstractMetaClass::inheritsFrom(const AbstractMetaClass *cls) const
1080
{
1081
    Q_ASSERT(cls);
1082
1083
    const AbstractMetaClass *clazz = this;
1084
    while (clazz) {
1085
        if (clazz == cls)
1086
            return true;
1087
1088
        clazz = clazz->baseClass();
1089
    }
1090
1091
    return false;
1092
}
1093
1094
/*******************************************************************************
1095
 * Constructs an interface based on the functions and enums in this
1096
 * class and returns it...
1097
 */
1098
AbstractMetaClass *AbstractMetaClass::extractInterface()
1099
{
1100
    Q_ASSERT(typeEntry()->designatedInterface());
1101
1102
    if (!m_extractedInterface) {
1103
        AbstractMetaClass *iface = new AbstractMetaClass;
1104
        iface->setAttributes(attributes());
1105
        iface->setBaseClass(0);
1106
        iface->setPrimaryInterfaceImplementor(this);
1107
1108
        iface->setTypeEntry(typeEntry()->designatedInterface());
1109
1110
        foreach (AbstractMetaFunction *function, functions()) {
1111
            if (!function->isConstructor())
1112
                iface->addFunction(function->copy());
1113
        }
1114
1115
//         iface->setEnums(enums());
1116
//         setEnums(AbstractMetaEnumList());
1117
1118
        foreach (const AbstractMetaField *field, fields()) {
1119
            if (field->isPublic()) {
1120
                AbstractMetaField *new_field = field->copy();
1121
                new_field->setEnclosingClass(iface);
1122
                iface->addField(new_field);
1123
            }
1124
        }
1125
1126
        m_extractedInterface = iface;
1127
        addInterface(iface);
1128
        m_orphanInterfaces << iface;
1129
    }
1130
1131
    return m_extractedInterface;
1132
}
1133
1134
/*******************************************************************************
1135
 * Returns a list of all the functions with a given name
1136
 */
1137
AbstractMetaFunctionList AbstractMetaClass::queryFunctionsByName(const QString &name) const
1138
{
1139
    AbstractMetaFunctionList returned;
1140
    AbstractMetaFunctionList functions = this->functions();
1141
    foreach (AbstractMetaFunction *function, functions) {
1142
        if (function->name() == name)
1143
            returned.append(function);
1144
    }
1145
1146
    return returned;
1147
}
1148
1149
/*******************************************************************************
1150
 * Returns all reference count modifications for any function in the class
1151
 */
1152
QList<ReferenceCount> AbstractMetaClass::referenceCounts() const
1153
{
1154
    QList<ReferenceCount> returned;
1155
1156
    AbstractMetaFunctionList functions = this->functions();
1157
    foreach (AbstractMetaFunction *function, functions)
1158
        returned += function->referenceCounts(this);
1159
1160
    return returned;
1161
}
1162
1163
/*******************************************************************************
1164
 * Returns a list of all the functions retrieved during parsing which should
1165
 * be added to the API.
1166
 */
1167
AbstractMetaFunctionList AbstractMetaClass::functionsInTargetLang() const
1168
{
1169
    int default_flags = NormalFunctions | Visible | NotRemovedFromTargetLang;
1170
1171
    // Interfaces don't implement functions
1172
    default_flags |= isInterface() ? 0 : ClassImplements;
1173
1174
    // Only public functions in final classes
1175
    // default_flags |= isFinal() ? WasPublic : 0;
1176
    int public_flags = isFinal() ? WasPublic : 0;
1177
1178
    // Constructors
1179
    AbstractMetaFunctionList returned = queryFunctions(Constructors | default_flags | public_flags);
1180
1181
    // Final functions
1182
    returned += queryFunctions(FinalInTargetLangFunctions | NonStaticFunctions | default_flags | public_flags);
1183
1184
    // Virtual functions
1185
    returned += queryFunctions(VirtualInTargetLangFunctions | NonStaticFunctions | default_flags | public_flags);
1186
1187
    // Static functions
1188
    returned += queryFunctions(StaticFunctions | default_flags | public_flags);
1189
1190
    // Empty, private functions, since they aren't caught by the other ones
1191
    returned += queryFunctions(Empty | Invisible);
1192
1193
    return returned;
1194
}
1195
1196
AbstractMetaFunctionList AbstractMetaClass::virtualFunctions() const
1197
{
1198
    AbstractMetaFunctionList list = functionsInShellClass();
1199
1200
    AbstractMetaFunctionList returned;
1201
    foreach (AbstractMetaFunction *f, list) {
1202
        if (!f->isFinalInCpp() || f->isVirtualSlot())
1203
            returned += f;
1204
    }
1205
1206
    return returned;
1207
}
1208
1209
AbstractMetaFunctionList AbstractMetaClass::nonVirtualShellFunctions() const
1210
{
1211
    AbstractMetaFunctionList list = functionsInShellClass();
1212
    AbstractMetaFunctionList returned;
1213
    foreach (AbstractMetaFunction *f, list) {
1214
        if (f->isFinalInCpp() && !f->isVirtualSlot())
1215
            returned += f;
1216
    }
1217
1218
    return returned;
1219
}
1220
1221
AbstractMetaFunctionList AbstractMetaClass::implicitConversions() const
1222
{
1223
    if (!hasCloneOperator() && !hasExternalConversionOperators())
1224
        return AbstractMetaFunctionList();
1225
1226
    AbstractMetaFunctionList returned;
1227
    AbstractMetaFunctionList list = queryFunctions(Constructors);
1228
    list.append(externalConversionOperators());
1229
1230
    foreach (AbstractMetaFunction *f, list) {
1231
        if ((f->actualMinimumArgumentCount() == 1 || f->arguments().size() == 1 || f->isConversionOperator())
1232
            && !f->isExplicit()
1233
            && !f->isCopyConstructor()
1234
            && !f->isModifiedRemoved()
1235
            && (f->originalAttributes() & Public)) {
1236
            returned += f;
1237
        }
1238
    }
1239
    return returned;
1240
}
1241
1242
AbstractMetaFunctionList AbstractMetaClass::operatorOverloads(uint query) const
1243
{
1244
    AbstractMetaFunctionList list = queryFunctions(OperatorOverloads | Visible);
1245
    AbstractMetaFunctionList returned;
1246
    foreach (AbstractMetaFunction *f, list) {
1247
        if (((query & ArithmeticOp) && f->isArithmeticOperator())
1248
            || ((query & BitwiseOp) && f->isBitwiseOperator())
1249
            || ((query & ComparisonOp) && f->isComparisonOperator())
1250
            || ((query & LogicalOp) && f->isLogicalOperator())
1251
            || ((query & SubscriptionOp) && f->isSubscriptOperator())
1252
            || ((query & AssignmentOp) && f->isAssignmentOperator())
1253
            || ((query & ConversionOp) && f->isConversionOperator())
1254
            || ((query & OtherOp) && f->isOtherOperator()))
1255
            returned += f;
1256
    }
1257
1258
    return returned;
1259
}
1260
1261
bool AbstractMetaClass::hasOperatorOverload() const
1262
{
1263
    foreach (const AbstractMetaFunction *f, m_functions) {
1264
        if (f->ownerClass() == f->implementingClass() && f->isOperatorOverload() && !f->isPrivate())
1265
            return true;
1266
    }
1267
    return false;
1268
}
1269
1270
bool AbstractMetaClass::hasArithmeticOperatorOverload() const
1271
{
1272
    foreach (const AbstractMetaFunction *f, m_functions) {
1273
        if (f->ownerClass() == f->implementingClass() && f->isArithmeticOperator() && !f->isPrivate())
1274
            return true;
1275
    }
1276
    return false;
1277
}
1278
1279
bool AbstractMetaClass::hasBitwiseOperatorOverload() const
1280
{
1281
    foreach (const AbstractMetaFunction *f, m_functions) {
1282
        if (f->ownerClass() == f->implementingClass() && f->isBitwiseOperator() && !f->isPrivate())
1283
            return true;
1284
    }
1285
    return false;
1286
}
1287
1288
bool AbstractMetaClass::hasComparisonOperatorOverload() const
1289
{
1290
    foreach (const AbstractMetaFunction *f, m_functions) {
1291
        if (f->ownerClass() == f->implementingClass() && f->isComparisonOperator() && !f->isPrivate())
1292
            return true;
1293
    }
1294
    return false;
1295
}
1296
1297
bool AbstractMetaClass::hasLogicalOperatorOverload() const
1298
{
1299
    foreach (const AbstractMetaFunction *f, m_functions) {
1300
        if (f->ownerClass() == f->implementingClass() && f->isLogicalOperator() && !f->isPrivate())
1301
            return true;
1302
    }
1303
    return false;
1304
}
1305
1306
bool AbstractMetaClass::hasSubscriptOperatorOverload() const
1307
{
1308
    foreach (const AbstractMetaFunction *f, m_functions) {
1309
        if (f->ownerClass() == f->implementingClass() && f->isSubscriptOperator() && !f->isPrivate())
1310
            return true;
1311
    }
1312
    return false;
1313
}
1314
1315
bool AbstractMetaClass::hasAssignmentOperatorOverload() const
1316
{
1317
    foreach (const AbstractMetaFunction *f, m_functions) {
1318
        if (f->ownerClass() == f->implementingClass() && f->isAssignmentOperator() && !f->isPrivate())
1319
            return true;
1320
    }
1321
    return false;
1322
}
1323
1324
bool AbstractMetaClass::hasConversionOperatorOverload() const
1325
{
1326
    foreach (const AbstractMetaFunction *f, m_functions) {
1327
        if (f->ownerClass() == f->implementingClass() && f->isConversionOperator() && !f->isPrivate())
1328
            return true;
1329
    }
1330
    return false;
1331
}
1332
1333
/*******************************************************************************
1334
 * Returns a list of all functions that should be declared and implemented in
1335
 * the shell class which is generated as a wrapper on top of the actual C++ class
1336
 */
1337
AbstractMetaFunctionList AbstractMetaClass::functionsInShellClass() const
1338
{
1339
    // Only functions and only protected and public functions
1340
    int default_flags = NormalFunctions | Visible | WasVisible | NotRemovedFromShell;
1341
1342
    // All virtual functions
1343
    AbstractMetaFunctionList returned = queryFunctions(VirtualFunctions | default_flags);
1344
1345
    // All functions explicitly set to be implemented by the shell class
1346
    // (mainly superclass functions that are hidden by other declarations)
1347
    returned += queryFunctions(ForcedShellFunctions | default_flags);
1348
1349
    // All functions explicitly set to be virtual slots
1350
    returned += queryFunctions(VirtualSlots | default_flags);
1351
1352
    return returned;
1353
}
1354
1355
/*******************************************************************************
1356
 * Returns a list of all functions that require a public override function to
1357
 * be generated in the shell class. This includes all functions that were originally
1358
 * protected in the superclass.
1359
 */
1360
AbstractMetaFunctionList AbstractMetaClass::publicOverrideFunctions() const
1361
{
1362
    return queryFunctions(NormalFunctions | WasProtected | FinalInCppFunctions | NotRemovedFromTargetLang)
1363
           + queryFunctions(Signals | WasProtected | FinalInCppFunctions | NotRemovedFromTargetLang);
1364
}
1365
1366
AbstractMetaFunctionList AbstractMetaClass::virtualOverrideFunctions() const
1367
{
1368
    return queryFunctions(NormalFunctions | NonEmptyFunctions | Visible | VirtualInCppFunctions | NotRemovedFromShell) +
1369
           queryFunctions(Signals | NonEmptyFunctions | Visible | VirtualInCppFunctions | NotRemovedFromShell);
1370
}
1371
1372
void AbstractMetaClass::sortFunctions()
1373
{
1374
    qSort(m_functions.begin(), m_functions.end(), function_sorter);
1375
}
1376
1377
void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions)
1378
{
1379
    m_functions = functions;
1380
1381
    // Functions must be sorted by name before next loop
1382
    sortFunctions();
1383
1384
    QString currentName;
1385
    bool hasVirtuals = false;
1386
    AbstractMetaFunctionList finalFunctions;
1387
    foreach (AbstractMetaFunction *f, m_functions) {
1388
        f->setOwnerClass(this);
1389
1390
        m_hasVirtualSlots = m_hasVirtualSlots || f->isVirtualSlot();
1391
        m_hasVirtuals = m_hasVirtuals || f->isVirtualSlot() || hasVirtualDestructor();
1392
        m_isPolymorphic = m_isPolymorphic || m_hasVirtuals;
1393
        m_hasNonpublic = m_hasNonpublic || !f->isPublic();
1394
1395
        // If we have non-virtual overloads of a virtual function, we have to implement
1396
        // all the overloads in the shell class to override the hiding rule
1397
        if (currentName == f->name()) {
1398
            hasVirtuals = hasVirtuals || !f->isFinal();
1399
            if (f->isFinal())
1400
                finalFunctions += f;
1401
        } else {
1402
            if (hasVirtuals && finalFunctions.size() > 0) {
1403
                foreach (AbstractMetaFunction *final_function, finalFunctions) {
1404
                    *final_function += AbstractMetaAttributes::ForceShellImplementation;
1405
1406
                    QString warn = QString("hiding of function '%1' in class '%2'")
1407
                                   .arg(final_function->name()).arg(name());
1408
                    ReportHandler::warning(warn);
1409
                }
1410
            }
1411
1412
            hasVirtuals = !f->isFinal();
1413
            finalFunctions.clear();
1414
            if (f->isFinal())
1415
                finalFunctions += f;
1416
            currentName = f->name();
1417
        }
1418
    }
1419
}
1420
1421
bool AbstractMetaClass::hasFieldAccessors() const
1422
{
1423
    foreach (const AbstractMetaField *field, fields()) {
1424
        if (field->getter() || field->setter())
1425
            return true;
1426
    }
1427
1428
    return false;
1429
}
1430
1431
bool AbstractMetaClass::hasDefaultToStringFunction() const
1432
{
1433
    foreach (AbstractMetaFunction *f, queryFunctionsByName("toString")) {
1434
        if (!f->actualMinimumArgumentCount())
1435
            return true;
1436
    }
1437
    return false;
1438
}
1439
1440
void AbstractMetaClass::addFunction(AbstractMetaFunction *function)
1441
{
1442
    Q_ASSERT(!function->signature().startsWith("("));
1443
    function->setOwnerClass(this);
1444
1445
    if (!function->isDestructor())
1446
        m_functions << function;
1447
    else
1448
        Q_ASSERT(false); //memory leak
1449
1450
    m_hasVirtualSlots |= function->isVirtualSlot();
1451
    m_hasVirtuals |= !function->isFinal() || function->isVirtualSlot() || hasVirtualDestructor();
1452
    m_isPolymorphic |= m_hasVirtuals;
1453
    m_hasNonpublic |= !function->isPublic();
1454
}
1455
1456
bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const
1457
{
1458
    if (!other->isSignal())
1459
        return false;
1460
1461
    foreach (const AbstractMetaFunction *f, functions()) {
1462
        if (f->isSignal() && f->compareTo(other) & AbstractMetaFunction::EqualName)
1463
            return other->modifiedName() == f->modifiedName();
1464
    }
1465
1466
    return false;
1467
}
1468
1469
1470
QString AbstractMetaClass::name() const
1471
{
1472
    return QString(m_typeEntry->targetLangName()).split("::").last();
1473
}
1474
1475
void AbstractMetaClass::setBaseClass(AbstractMetaClass *baseClass)
1476
{
1477
    m_baseClass = baseClass;
1478
    if (baseClass)
1479
        m_isPolymorphic |= baseClass->isPolymorphic();
1480
}
1481
1482
bool AbstractMetaClass::hasFunction(const QString &str) const
1483
{
1484
    return findFunction(str);
1485
}
1486
1487
const AbstractMetaFunction* AbstractMetaClass::findFunction(const QString& functionName) const
1488
{
1489
    foreach (const AbstractMetaFunction *f, functions()) {
1490
        if (f->name() == functionName)
1491
            return f;
1492
    }
1493
    return 0;
1494
}
1495
1496
bool AbstractMetaClass::hasProtectedFunctions() const
1497
{
1498
    foreach (AbstractMetaFunction *func, m_functions) {
1499
        if (func->isProtected())
1500
            return true;
1501
    }
1502
    return false;
1503
}
1504
1505
bool AbstractMetaClass::hasProtectedFields() const
1506
{
1507
    foreach (const AbstractMetaField *field, fields()) {
1508
        if (field->isProtected())
1509
            return true;
1510
    }
1511
    return false;
1512
}
1513
1514
bool AbstractMetaClass::hasProtectedMembers() const
1515
{
1516
    return hasProtectedFields() || hasProtectedFunctions();
1517
}
1518
1519
bool AbstractMetaClass::generateShellClass() const
1520
{
1521
    return m_forceShellClass ||
1522
           (!isFinal()
1523
            && (hasVirtualFunctions()
1524
                || hasProtectedFunctions()
1525
                || hasFieldAccessors()));
1526
}
1527
1528
QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const
1529
{
1530
    for (int i = 0; i < m_propertySpecs.size(); ++i)
1531
        if (name == m_propertySpecs.at(i)->read())
1532
            return m_propertySpecs.at(i);
1533
    return 0;
1534
}
1535
1536
QPropertySpec *AbstractMetaClass::propertySpecForWrite(const QString &name) const
1537
{
1538
    for (int i = 0; i < m_propertySpecs.size(); ++i)
1539
        if (name == m_propertySpecs.at(i)->write())
1540
            return m_propertySpecs.at(i);
1541
    return 0;
1542
}
1543
1544
QPropertySpec *AbstractMetaClass::propertySpecForReset(const QString &name) const
1545
{
1546
    for (int i = 0; i < m_propertySpecs.size(); ++i) {
1547
        if (name == m_propertySpecs.at(i)->reset())
1548
            return m_propertySpecs.at(i);
1549
    }
1550
    return 0;
1551
}
1552
1553
typedef QHash<const AbstractMetaClass*, AbstractMetaTypeList> AbstractMetaClassBaseTemplateInstantiationsMap;
1554
Q_GLOBAL_STATIC(AbstractMetaClassBaseTemplateInstantiationsMap, metaClassBaseTemplateInstantiations);
1555
1556
bool AbstractMetaClass::hasTemplateBaseClassInstantiations() const
1557
{
1558
    if (!templateBaseClass())
1559
        return false;
1560
    return metaClassBaseTemplateInstantiations()->contains(this);
1561
}
1562
1563
AbstractMetaTypeList AbstractMetaClass::templateBaseClassInstantiations() const
1564
{
1565
    if (!templateBaseClass())
1566
        return AbstractMetaTypeList();
1567
    return metaClassBaseTemplateInstantiations()->value(this);
1568
}
1569
1570
void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList& instantiations)
1571
{
1572
    if (!templateBaseClass())
1573
        return;
1574
    metaClassBaseTemplateInstantiations()->insert(this, instantiations);
1575
}
1576
1577
static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func)
1578
{
1579
    foreach (const AbstractMetaFunction *f, l) {
1580
        if ((f->compareTo(func) & AbstractMetaFunction::PrettySimilar) == AbstractMetaFunction::PrettySimilar)
1581
            return true;
1582
    }
1583
    return false;
1584
}
1585
1586
AbstractMetaField::AbstractMetaField() : m_getter(0), m_setter(0), m_class(0)
1587
{
1588
}
1589
1590
AbstractMetaField::~AbstractMetaField()
1591
{
1592
    delete m_setter;
1593
    delete m_getter;
1594
}
1595
1596
AbstractMetaField *AbstractMetaField::copy() const
1597
{
1598
    AbstractMetaField *returned = new AbstractMetaField;
1599
    returned->setEnclosingClass(0);
1600
    returned->setAttributes(attributes());
1601
    returned->setName(name());
1602
    returned->setType(type()->copy());
1603
    returned->setOriginalAttributes(originalAttributes());
1604
1605
    return returned;
1606
}
1607
1608
/*******************************************************************************
1609
 * Indicates that this field has a modification that removes it
1610
 */
1611
bool AbstractMetaField::isModifiedRemoved(int types) const
1612
{
1613
    FieldModificationList mods = modifications();
1614
    foreach (FieldModification mod, mods) {
1615
        if (!mod.isRemoveModifier())
1616
            continue;
1617
1618
        if ((mod.removal & types) == types)
1619
            return true;
1620
    }
1621
1622
    return false;
1623
}
1624
1625
static QString upCaseFirst(const QString &str)
1626
{
1627
    Q_ASSERT(!str.isEmpty());
1628
    QString s = str;
1629
    s[0] = s.at(0).toUpper();
1630
    return s;
1631
}
1632
1633
static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QString &name, uint type)
1634
{
1635
    AbstractMetaFunction *f = new AbstractMetaFunction;
1636
1637
    f->setName(name);
1638
    f->setOriginalName(name);
1639
    f->setOwnerClass(g->enclosingClass());
1640
    f->setImplementingClass(g->enclosingClass());
1641
    f->setDeclaringClass(g->enclosingClass());
1642
1643
    uint attr = AbstractMetaAttributes::Native
1644
                | AbstractMetaAttributes::Final
1645
                | type;
1646
    if (g->isStatic())
1647
        attr |= AbstractMetaAttributes::Static;
1648
    if (g->isPublic())
1649
        attr |= AbstractMetaAttributes::Public;
1650
    else if (g->isProtected())
1651
        attr |= AbstractMetaAttributes::Protected;
1652
    else
1653
        attr |= AbstractMetaAttributes::Private;
1654
    f->setAttributes(attr);
1655
    f->setOriginalAttributes(attr);
1656
1657
    FieldModificationList mods = g->modifications();
1658
    foreach (FieldModification mod, mods) {
1659
        if (mod.isRenameModifier())
1660
            f->setName(mod.renamedTo());
1661
        if (mod.isAccessModifier()) {
1662
            if (mod.isPrivate())
1663
                f->setVisibility(AbstractMetaAttributes::Private);
1664
            else if (mod.isProtected())
1665
                f->setVisibility(AbstractMetaAttributes::Protected);
1666
            else if (mod.isPublic())
1667
                f->setVisibility(AbstractMetaAttributes::Public);
1668
            else if (mod.isFriendly())
1669
                f->setVisibility(AbstractMetaAttributes::Friendly);
1670
        }
1671
    }
1672
    return f;
1673
}
1674
1675
FieldModificationList AbstractMetaField::modifications() const
1676
{
1677
    FieldModificationList mods = enclosingClass()->typeEntry()->fieldModifications();
1678
    FieldModificationList returned;
1679
1680
    foreach (FieldModification mod, mods) {
1681
        if (mod.name == name())
1682
            returned += mod;
1683
    }
1684
1685
    return returned;
1686
}
1687
1688
const AbstractMetaFunction *AbstractMetaField::setter() const
1689
{
1690
    if (!m_setter) {
1691
        m_setter = createXetter(this,
1692
                                "set" + upCaseFirst(name()),
1693
                                AbstractMetaAttributes::SetterFunction);
1694
        AbstractMetaArgumentList arguments;
1695
        AbstractMetaArgument *argument = new AbstractMetaArgument;
1696
        argument->setType(type()->copy());
1697
        argument->setName(name());
1698
        arguments.append(argument);
1699
        m_setter->setArguments(arguments);
1700
    }
1701
    return m_setter;
1702
}
1703
1704
const AbstractMetaFunction *AbstractMetaField::getter() const
1705
{
1706
    if (!m_getter) {
1707
        m_getter = createXetter(this,
1708
                                name(),
1709
                                AbstractMetaAttributes::GetterFunction);
1710
        m_getter->setType(type());
1711
    }
1712
1713
    return m_getter;
1714
}
1715
1716
1717
bool AbstractMetaClass::hasConstructors() const
1718
{
1719
    return queryFunctions(Constructors).size();
1720
}
1721
1722
bool AbstractMetaClass::hasCopyConstructor() const
1723
{
1724
    foreach (const AbstractMetaFunction* ctor, queryFunctions(Constructors)) {
1725
        if (ctor->isCopyConstructor())
1726
            return true;
1727
    }
1728
    return false;
1729
}
1730
1731
bool AbstractMetaClass::hasPrivateCopyConstructor() const
1732
{
1733
    foreach (const AbstractMetaFunction* ctor, queryFunctions(Constructors)) {
1734
        if (ctor->isCopyConstructor() && ctor->isPrivate())
1735
            return true;
1736
    }
1737
    return false;
1738
}
1739
1740
void AbstractMetaClass::addDefaultConstructor()
1741
{
1742
    AbstractMetaFunction *f = new AbstractMetaFunction;
1743
    f->setOriginalName(name());
1744
    f->setName(name());
1745
    f->setOwnerClass(this);
1746
    f->setFunctionType(AbstractMetaFunction::ConstructorFunction);
1747
    f->setArguments(AbstractMetaArgumentList());
1748
    f->setDeclaringClass(this);
1749
1750
    uint attr = AbstractMetaAttributes::Native;
1751
    attr |= AbstractMetaAttributes::Public;
1752
    attr |= AbstractMetaAttributes::Final;
1753
    f->setAttributes(attr);
1754
    f->setImplementingClass(this);
1755
    f->setOriginalAttributes(f->attributes());
1756
1757
    addFunction(f);
1758
    this->setHasNonPrivateConstructor(true);
1759
}
1760
1761
void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate)
1762
{
1763
    AbstractMetaFunction* f = new AbstractMetaFunction;
1764
    f->setOriginalName(name());
1765
    f->setName(name());
1766
    f->setOwnerClass(this);
1767
    f->setFunctionType(AbstractMetaFunction::ConstructorFunction);
1768
    f->setDeclaringClass(this);
1769
1770
    AbstractMetaType* argType = new AbstractMetaType;
1771
    argType->setTypeEntry(typeEntry());
1772
    argType->setReference(true);
1773
    argType->setConstant(true);
1774
    argType->setTypeUsagePattern(AbstractMetaType::ValuePattern);
1775
1776
    AbstractMetaArgument* arg = new AbstractMetaArgument;
1777
    arg->setType(argType);
1778
    arg->setName(name());
1779
    f->addArgument(arg);
1780
1781
    uint attr = AbstractMetaAttributes::Native;
1782
    attr |= AbstractMetaAttributes::Final;
1783
    if (isPrivate)
1784
        attr |= AbstractMetaAttributes::Private;
1785
    else
1786
        attr |= AbstractMetaAttributes::Public;
1787
    f->setAttributes(attr);
1788
    f->setImplementingClass(this);
1789
    f->setOriginalAttributes(f->attributes());
1790
1791
    addFunction(f);
1792
}
1793
1794
bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const
1795
{
1796
    return functions_contains(m_functions, f);
1797
}
1798
1799
/* Goes through the list of functions and returns a list of all
1800
   functions matching all of the criteria in \a query.
1801
 */
1802
1803
AbstractMetaFunctionList AbstractMetaClass::queryFunctions(uint query) const
1804
{
1805
    AbstractMetaFunctionList functions;
1806
1807
    foreach (AbstractMetaFunction *f, m_functions) {
1808
1809
        if ((query & VirtualSlots) && !f->isVirtualSlot())
1810
            continue;
1811
1812
        if ((query & NotRemovedFromTargetLang) && f->isRemovedFrom(f->implementingClass(), TypeSystem::TargetLangCode))
1813
            continue;
1814
1815
        if ((query & NotRemovedFromTargetLang) && !f->isFinal() && f->isRemovedFrom(f->declaringClass(), TypeSystem::TargetLangCode))
1816
            continue;
1817
1818
        if ((query & NotRemovedFromShell) && f->isRemovedFrom(f->implementingClass(), TypeSystem::ShellCode))
1819
            continue;
1820
1821
        if ((query & NotRemovedFromShell) && !f->isFinal() && f->isRemovedFrom(f->declaringClass(), TypeSystem::ShellCode))
1822
            continue;
1823
1824
        if ((query & Visible) && f->isPrivate())
1825
            continue;
1826
1827
        if ((query & VirtualInTargetLangFunctions) && f->isFinalInTargetLang())
1828
            continue;
1829
1830
        if ((query & Invisible) && !f->isPrivate())
1831
            continue;
1832
1833
        if ((query & Empty) && !f->isEmptyFunction())
1834
            continue;
1835
1836
        if ((query & WasPublic) && !f->wasPublic())
1837
            continue;
1838
1839
        if ((query & WasVisible) && f->wasPrivate())
1840
            continue;
1841
1842
        if ((query & WasProtected) && !f->wasProtected())
1843
            continue;
1844
1845
        if ((query & ClassImplements) && f->ownerClass() != f->implementingClass())
1846
            continue;
1847
1848
        if ((query & Inconsistent) && (f->isFinalInTargetLang() || !f->isFinalInCpp() || f->isStatic()))
1849
            continue;
1850
1851
        if ((query & FinalInTargetLangFunctions) && !f->isFinalInTargetLang())
1852
            continue;
1853
1854
        if ((query & FinalInCppFunctions) && !f->isFinalInCpp())
1855
            continue;
1856
1857
        if ((query & VirtualInCppFunctions) && f->isFinalInCpp())
1858
            continue;
1859
1860
        if ((query & Signals) && (!f->isSignal()))
1861
            continue;
1862
1863
        if ((query & ForcedShellFunctions) &&
1864
            (!f->isForcedShellImplementation() || !f->isFinal())) {
1865
            continue;
1866
        }
1867
1868
        if ((query & Constructors) && (!f->isConstructor() || f->ownerClass() != f->implementingClass()))
1869
            continue;
1870
1871
        if (!(query & Constructors) && f->isConstructor())
1872
            continue;
1873
1874
        // Destructors are never included in the functions of a class currently
1875
        /*
1876
           if ((query & Destructors) && (!f->isDestructor()
1877
                                       || f->ownerClass() != f->implementingClass())
1878
            || f->isDestructor() && (query & Destructors) == 0) {
1879
            continue;
1880
        }*/
1881
1882
        if ((query & VirtualFunctions) && (f->isFinal() || f->isSignal() || f->isStatic()))
1883
            continue;
1884
1885
        if ((query & StaticFunctions) && (!f->isStatic() || f->isSignal()))
1886
            continue;
1887
1888
        if ((query & NonStaticFunctions) && (f->isStatic()))
1889
            continue;
1890
1891
        if ((query & NonEmptyFunctions) && (f->isEmptyFunction()))
1892
            continue;
1893
1894
        if ((query & NormalFunctions) && (f->isSignal()))
1895
            continue;
1896
1897
        if ((query & AbstractFunctions) && !f->isAbstract())
1898
            continue;
1899
1900
        if ((query & OperatorOverloads) && !f->isOperatorOverload())
1901
            continue;
1902
1903
        functions << f;
1904
    }
1905
1906
    return functions;
1907
}
1908
1909
1910
bool AbstractMetaClass::hasInconsistentFunctions() const
1911
{
1912
    return cppInconsistentFunctions().size() > 0;
1913
}
1914
1915
bool AbstractMetaClass::hasSignals() const
1916
{
1917
    return cppSignalFunctions().size() > 0;
1918
}
1919
1920
1921
/**
1922
 * Adds the specified interface to this class by adding all the
1923
 * functions in the interface to this class.
1924
 */
1925
void AbstractMetaClass::addInterface(AbstractMetaClass *interface)
1926
{
1927
    Q_ASSERT(!m_interfaces.contains(interface));
1928
    m_interfaces << interface;
1929
1930
    m_isPolymorphic |= interface->isPolymorphic();
1931
1932
    if (m_extractedInterface && m_extractedInterface != interface)
1933
        m_extractedInterface->addInterface(interface);
1934
1935
#if 0
1936
    foreach (AbstractMetaFunction *function, interface->functions())
1937
    if (!hasFunction(function) && !function->isConstructor()) {
1938
        AbstractMetaFunction *cpy = function->copy();
1939
        cpy->setImplementingClass(this);
1940
1941
        // Setup that this function is an interface class.
1942
        cpy->setInterfaceClass(interface);
1943
        *cpy += AbstractMetaAttributes::InterfaceFunction;
1944
1945
        // Copy the modifications in interface into the implementing classes.
1946
        FunctionModificationList mods = function->modifications(interface);
1947
        foreach (const FunctionModification &mod, mods)
1948
            m_typeEntry->addFunctionModification(mod);
1949
1950
        // It should be mostly safe to assume that when we implement an interface
1951
        // we don't "pass on" pure virtual functions to our sublcasses...
1952
//             *cpy -= AbstractMetaAttributes::Abstract;
1953
1954
        addFunction(cpy);
1955
    }
1956
#endif
1957
1958
}
1959
1960
1961
void AbstractMetaClass::setInterfaces(const AbstractMetaClassList &interfaces)
1962
{
1963
    m_interfaces = interfaces;
1964
    foreach (const AbstractMetaClass* interface, interfaces) {
1965
        if (interface)
1966
            m_isPolymorphic |= interface->isPolymorphic();
1967
    }
1968
}
1969
1970
1971
AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName)
1972
{
1973
    foreach (AbstractMetaEnum *e, m_enums) {
1974
        if (e->name() == enumName)
1975
            return e;
1976
    }
1977
1978
    if (typeEntry()->designatedInterface())
1979
        return extractInterface()->findEnum(enumName);
1980
1981
    return 0;
1982
}
1983
1984
1985
1986
1987
/*!  Recursivly searches for the enum value named \a enumValueName in
1988
  this class and its superclasses and interfaces. Values belonging to
1989
  \a meta_enum are excluded from the search.
1990
*/
1991
AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValueName, AbstractMetaEnum *meta_enum)
1992
{
1993
    foreach (AbstractMetaEnum *e, m_enums) {
1994
        if (e != meta_enum)
1995
            continue;
1996
        foreach (AbstractMetaEnumValue *v, e->values()) {
1997
            if (v->name() == enumValueName)
1998
                return v;
1999
        }
2000
    }
2001
2002
    if (typeEntry()->designatedInterface())
2003
        return extractInterface()->findEnumValue(enumValueName, meta_enum);
2004
2005
    if (baseClass())
2006
        return baseClass()->findEnumValue(enumValueName, meta_enum);
2007
2008
    return 0;
2009
}
2010
2011
2012
/*!
2013
 * Searches through all of this class' enums for a value matching the
2014
 * name \a enumValueName. The name is excluding the class/namespace
2015
 * prefix. The function recursivly searches interfaces and baseclasses
2016
 * of this class.
2017
 */
2018
AbstractMetaEnum *AbstractMetaClass::findEnumForValue(const QString &enumValueName)
2019
{
2020
    foreach (AbstractMetaEnum *e, m_enums) {
2021
        foreach (AbstractMetaEnumValue *v, e->values()) {
2022
            if (v->name() == enumValueName)
2023
                return e;
2024
        }
2025
    }
2026
2027
    if (typeEntry()->designatedInterface())
2028
        return extractInterface()->findEnumForValue(enumValueName);
2029
2030
    if (baseClass())
2031
        return baseClass()->findEnumForValue(enumValueName);
2032
2033
    return 0;
2034
}
2035
2036
2037
static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType *type)
2038
{
2039
    if (!type)
2040
        return;
2041
2042
    Q_ASSERT(metaClass);
2043
    const TypeEntry *entry = (type ? type->typeEntry() : 0);
2044
    if (entry && entry->isComplex()) {
2045
        const ComplexTypeEntry *centry = static_cast<const ComplexTypeEntry *>(entry);
2046
        ComplexTypeEntry *class_entry = metaClass->typeEntry();
2047
        if (class_entry && centry->include().isValid())
2048
            class_entry->addExtraInclude(centry->include());
2049
    }
2050
2051
    if (type->hasInstantiations()) {
2052
        AbstractMetaTypeList instantiations = type->instantiations();
2053
        foreach (const AbstractMetaType *instantiation, instantiations)
2054
            addExtraIncludeForType(metaClass, instantiation);
2055
    }
2056
}
2057
2058
static void addExtraIncludesForFunction(AbstractMetaClass *metaClass, const AbstractMetaFunction *meta_function)
2059
{
2060
    Q_ASSERT(metaClass);
2061
    Q_ASSERT(meta_function);
2062
    addExtraIncludeForType(metaClass, meta_function->type());
2063
2064
    AbstractMetaArgumentList arguments = meta_function->arguments();
2065
    foreach (AbstractMetaArgument *argument, arguments)
2066
    addExtraIncludeForType(metaClass, argument->type());
2067
}
2068
2069
void AbstractMetaClass::fixFunctions()
2070
{
2071
    if (m_functionsFixed)
2072
        return;
2073
    else
2074
        m_functionsFixed = true;
2075
2076
    AbstractMetaClass *superClass = baseClass();
2077
    AbstractMetaFunctionList funcs = functions();
2078
2079
    if (superClass)
2080
        superClass->fixFunctions();
2081
    int iface_idx = 0;
2082
    while (superClass || iface_idx < interfaces().size()) {
2083
        // Since we always traverse the complete hierarchy we are only
2084
        // interrested in what each super class implements, not what
2085
        // we may have propagated from their base classes again.
2086
        AbstractMetaFunctionList superFuncs;
2087
        if (superClass) {
2088
            // Super classes can never be final
2089
            if (superClass->isFinalInTargetLang()) {
2090
                ReportHandler::warning("Final class '" + superClass->name() + "' set to non-final, as it is extended by other classes");
2091
                *superClass -= AbstractMetaAttributes::FinalInTargetLang;
2092
            }
2093
            superFuncs = superClass->queryFunctions(AbstractMetaClass::ClassImplements);
2094
            AbstractMetaFunctionList virtuals = superClass->queryFunctions(AbstractMetaClass::VirtualInCppFunctions);
2095
            superFuncs += virtuals;
2096
        } else {
2097
            superFuncs = interfaces().at(iface_idx)->queryFunctions(AbstractMetaClass::NormalFunctions);
2098
            AbstractMetaFunctionList virtuals = interfaces().at(iface_idx)->queryFunctions(AbstractMetaClass::VirtualInCppFunctions);
2099
            superFuncs += virtuals;
2100
        }
2101
2102
        QSet<AbstractMetaFunction *> funcsToAdd;
2103
        for (int sfi = 0; sfi < superFuncs.size(); ++sfi) {
2104
            AbstractMetaFunction *sf = superFuncs.at(sfi);
2105
2106
            if (sf->isRemovedFromAllLanguages(sf->implementingClass()))
2107
                continue;
2108
2109
            // skip functions added in base classes
2110
            if (sf->isUserAdded() && sf->declaringClass() != this)
2111
                continue;
2112
2113
            // we generally don't care about private functions, but we have to get the ones that are
2114
            // virtual in case they override abstract functions.
2115
            bool add = (sf->isNormal() || sf->isSignal() || sf->isEmptyFunction());
2116
            for (int fi = 0; fi < funcs.size(); ++fi) {
2117
                AbstractMetaFunction *f = funcs.at(fi);
2118
                if (f->isRemovedFromAllLanguages(f->implementingClass()))
2119
                    continue;
2120
2121
2122
                uint cmp = f->compareTo(sf);
2123
2124
                if (cmp & AbstractMetaFunction::EqualModifiedName) {
2125
                    add = false;
2126
                    if (cmp & AbstractMetaFunction::EqualArguments) {
2127
                        // Same function, propegate virtual...
2128
                        if (!(cmp & AbstractMetaFunction::EqualAttributes)) {
2129
                            if (!f->isEmptyFunction()) {
2130
                                if (!sf->isFinalInCpp() && f->isFinalInCpp()) {
2131
                                    *f -= AbstractMetaAttributes::FinalInCpp;
2132
                                }
2133
                                if (!sf->isFinalInTargetLang() && f->isFinalInTargetLang()) {
2134
                                    *f -= AbstractMetaAttributes::FinalInTargetLang;
2135
                                }
2136
#if 0
2137
                                if (!f->isFinalInTargetLang() && f->isPrivate()) {
2138
                                    f->setFunctionType(AbstractMetaFunction::EmptyFunction);
2139
                                    f->setVisibility(AbstractMetaAttributes::Protected);
2140
                                    *f += AbstractMetaAttributes::FinalInTargetLang;
2141
                                    ReportHandler::warning(QString("private virtual function '%1' in '%2'")
2142
                                                           .arg(f->signature())
2143
                                                           .arg(f->implementingClass()->name()));
2144
                                }
2145
#endif
2146
                            }
2147
                        }
2148
2149
                        if (f->visibility() != sf->visibility()) {
2150
                            QString warn = QString("visibility of function '%1' modified in class '%2'")
2151
                                           .arg(f->name()).arg(name());
2152
                            ReportHandler::warning(warn);
2153
#if 0
2154
                            // If new visibility is private, we can't
2155
                            // do anything. If it isn't, then we
2156
                            // prefer the parent class's visibility
2157
                            // setting for the function.
2158
                            if (!f->isPrivate() && !sf->isPrivate())
2159
                                f->setVisibility(sf->visibility());
2160
#endif
2161
                            // Private overrides of abstract functions have to go into the class or
2162
                            // the subclasses will not compile as non-abstract classes.
2163
                            // But they don't need to be implemented, since they can never be called.
2164
                            if (f->isPrivate()) {
2165
                                f->setFunctionType(AbstractMetaFunction::EmptyFunction);
2166
                                *f += AbstractMetaAttributes::FinalInTargetLang;
2167
                                *f += AbstractMetaAttributes::FinalInCpp;
2168
                            }
2169
                        }
2170
2171
                        // Set the class which first declares this function, afawk
2172
                        f->setDeclaringClass(sf->declaringClass());
2173
2174
                        if (sf->isFinalInTargetLang() && !sf->isPrivate() && !f->isPrivate() && !sf->isStatic() && !f->isStatic()) {
2175
                            // Shadowed funcion, need to make base class
2176
                            // function non-virtual
2177
                            if (f->implementingClass() != sf->implementingClass() && f->implementingClass()->inheritsFrom(sf->implementingClass())) {
2178
2179
                                // Check whether the superclass method has been redefined to non-final
2180
2181
                                bool hasNonFinalModifier = false;
2182
                                bool isBaseImplPrivate = false;
2183
                                FunctionModificationList mods = sf->modifications(sf->implementingClass());
2184
                                foreach (FunctionModification mod, mods) {
2185
                                    if (mod.isNonFinal()) {
2186
                                        hasNonFinalModifier = true;
2187
                                        break;
2188
                                    } else if (mod.isPrivate()) {
2189
                                        isBaseImplPrivate = true;
2190
                                        break;
2191
                                    }
2192
                                }
2193
2194
                                if (!hasNonFinalModifier && !isBaseImplPrivate) {
2195
                                    ReportHandler::warning(QString::fromLatin1("Shadowing: %1::%2 and %3::%4")
2196
                                                           .arg(sf->implementingClass()->name())
2197
                                                           .arg(sf->signature())
2198
                                                           .arg(f->implementingClass()->name())
2199
                                                           .arg(f->signature()));
2200
                                }
2201
                            }
2202
                        }
2203
2204
                    }
2205
2206
                    if (cmp & AbstractMetaFunction::EqualDefaultValueOverload) {
2207
                        AbstractMetaArgumentList arguments;
2208
                        if (f->arguments().size() < sf->arguments().size())
2209
                            arguments = sf->arguments();
2210
                        else
2211
                            arguments = f->arguments();
2212
                        //TODO: fix this
2213
                        //for (int i=0; i<arguments.size(); ++i)
2214
                        //    arguments[i]->setDefaultValueExpression("<#>" + QString());
2215
                    }
2216
2217
2218
                    // Otherwise we have function shadowing and we can
2219
                    // skip the thing...
2220
                } else if (cmp & AbstractMetaFunction::EqualName && !sf->isSignal()) {
2221
                    // In the case of function shadowing where the function name has been altered to
2222
                    // avoid conflict, we don't copy in the original.
2223
                    add = false;
2224
                }
2225
            }
2226
2227
            if (add)
2228
                funcsToAdd << sf;
2229
        }
2230
2231
        foreach (AbstractMetaFunction *f, funcsToAdd)
2232
            funcs << f->copy();
2233
2234
        if (superClass)
2235
            superClass = superClass->baseClass();
2236
        else
2237
            iface_idx++;
2238
    }
2239
2240
    bool hasPrivateConstructors = false;
2241
    bool hasPublicConstructors = false;
2242
    foreach (AbstractMetaFunction *func, funcs) {
2243
        FunctionModificationList mods = func->modifications(this);
2244
        foreach (const FunctionModification &mod, mods) {
2245
            if (mod.isRenameModifier()) {
2246
                func->setName(mod.renamedTo());
2247
            }
2248
        }
2249
2250
        // Make sure class is abstract if one of the functions is
2251
        if (func->isAbstract()) {
2252
            (*this) += AbstractMetaAttributes::Abstract;
2253
            (*this) -= AbstractMetaAttributes::Final;
2254
        }
2255
2256
        if (func->isConstructor()) {
2257
            if (func->isPrivate())
2258
                hasPrivateConstructors = true;
2259
            else
2260
                hasPublicConstructors = true;
2261
        }
2262
2263
2264
2265
        // Make sure that we include files for all classes that are in use
2266
2267
        if (!func->isRemovedFrom(this, TypeSystem::ShellCode))
2268
            addExtraIncludesForFunction(this, func);
2269
    }
2270
2271
    if (hasPrivateConstructors && !hasPublicConstructors) {
2272
        (*this) += AbstractMetaAttributes::Abstract;
2273
        (*this) -= AbstractMetaAttributes::Final;
2274
    }
2275
2276
    foreach (AbstractMetaFunction *f1, funcs) {
2277
        foreach (AbstractMetaFunction *f2, funcs) {
2278
            if (f1 != f2) {
2279
                uint cmp = f1->compareTo(f2);
2280
                if ((cmp & AbstractMetaFunction::EqualName)
2281
                    && !f1->isFinalInCpp()
2282
                    && f2->isFinalInCpp()) {
2283
                    *f2 += AbstractMetaAttributes::FinalOverload;
2284
                }
2285
            }
2286
        }
2287
    }
2288
2289
    setFunctions(funcs);
2290
}
2291
2292
2293
QString AbstractMetaType::minimalSignature() const
2294
{
2295
    QString minimalSignature;
2296
    if (isConstant())
2297
        minimalSignature += "const ";
2298
    minimalSignature += typeEntry()->qualifiedCppName();
2299
    if (hasInstantiations()) {
2300
        AbstractMetaTypeList instantiations = this->instantiations();
2301
        minimalSignature += "< ";
2302
        for (int i = 0; i < instantiations.size(); ++i) {
2303
            if (i > 0)
2304
                minimalSignature += ",";
2305
            minimalSignature += instantiations[i]->minimalSignature();
2306
        }
2307
        minimalSignature += " >";
2308
    }
2309
2310
    for (int j = 0; j < indirections(); ++j)
2311
        minimalSignature += "*";
2312
    if (isReference())
2313
        minimalSignature += "&";
2314
2315
    return minimalSignature;
2316
}
2317
2318
bool AbstractMetaType::hasNativeId() const
2319
{
2320
    return (isQObject() || isValue() || isObject()) && typeEntry()->isNativeIdBased();
2321
}
2322
2323
2324
/*******************************************************************************
2325
 * Other stuff...
2326
 */
2327
2328
2329
AbstractMetaEnum *AbstractMetaClassList::findEnum(const EnumTypeEntry *entry) const
2330
{
2331
    Q_ASSERT(entry->isEnum());
2332
2333
    QString qualifiedName = entry->qualifiedCppName();
2334
    int pos = qualifiedName.lastIndexOf("::");
2335
2336
    QString enumName;
2337
    QString className;
2338
2339
    if (pos > 0) {
2340
        enumName = qualifiedName.mid(pos + 2);
2341
        className = qualifiedName.mid(0, pos);
2342
    } else {
2343
        enumName = qualifiedName;
2344
        className = TypeDatabase::globalNamespaceClassName(entry);
2345
    }
2346
2347
    AbstractMetaClass *metaClass = findClass(className);
2348
    if (!metaClass) {
2349
        ReportHandler::warning(QString("AbstractMeta::findEnum(), unknown class '%1' in '%2'")
2350
                               .arg(className).arg(entry->qualifiedCppName()));
2351
        return 0;
2352
    }
2353
2354
    return metaClass->findEnum(enumName);
2355
}
2356
2357
AbstractMetaEnumValue *AbstractMetaEnumValueList::find(const QString &name) const
2358
{
2359
    for (int i = 0; i < size(); ++i) {
2360
        if (name == at(i)->name())
2361
            return at(i);
2362
    }
2363
    return 0;
2364
}
2365
2366
AbstractMetaEnumValue *AbstractMetaClassList::findEnumValue(const QString &name) const
2367
{
2368
    QStringList lst = name.split(QLatin1String("::"));
2369
2370
    if (lst.size() > 1) {
2371
        QString prefixName = lst.at(0);
2372
        QString enumName = lst.at(1);
2373
2374
        AbstractMetaClass* cl = findClass(prefixName);
2375
        if (cl)
2376
            return cl->findEnumValue(enumName, 0);
2377
    }
2378
2379
    foreach(AbstractMetaClass* metaClass, *this) {
2380
        foreach(AbstractMetaEnum* metaEnum, metaClass->enums()) {
2381
            AbstractMetaEnumValue* enumValue = metaClass->findEnumValue(name, metaEnum);
2382
            if (enumValue)
2383
                return enumValue;
2384
        }
2385
    }
2386
2387
    ReportHandler::warning(QString("no matching enum '%1'").arg(name));
2388
    return 0;
2389
}
2390
2391
/*!
2392
 * Searches the list after a class that mathces \a name; either as
2393
 * C++, Target language base name or complete Target language package.class name.
2394
 */
2395
2396
AbstractMetaClass *AbstractMetaClassList::findClass(const QString &name) const
2397
{
2398
    if (name.isEmpty())
2399
        return 0;
2400
2401
    foreach (AbstractMetaClass *c, *this) {
2402
        if (c->qualifiedCppName() == name)
2403
            return c;
2404
    }
2405
2406
    foreach (AbstractMetaClass *c, *this) {
2407
        if (c->fullName() == name)
2408
            return c;
2409
    }
2410
2411
    foreach (AbstractMetaClass *c, *this) {
2412
        if (c->name() == name)
2413
            return c;
2414
    }
2415
2416
    return 0;
2417
}
2418
2419
AbstractMetaClass *AbstractMetaClassList::findClass(const TypeEntry* typeEntry) const
2420
{
2421
    foreach (AbstractMetaClass* c, *this) {
2422
        if (c->typeEntry() == typeEntry)
2423
            return c;
2424
    }
2425
    return 0;
2426
}