diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2017-12-01 11:35:41 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2017-12-02 10:44:41 +0000 |
commit | 111f11e4d88ed89f961c73b25d48123f28909213 (patch) | |
tree | e8f783990cc6cdfe16eac3aa65544f7d8054bf35 | |
parent | 4462db523fd8afc4177ad58caf1d5a955373bad5 (diff) |
shiboken/MetaLang: Add information about override/final
Take over information from code model and test.
Change-Id: Ibed2973e09b117966ed241798125f60ba337b0e9
Reviewed-by: Christian Tismer <tismer@stackless.com>
4 files changed, 71 insertions, 20 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 8192291bd..fc990deb7 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -1285,6 +1285,9 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem AbstractMetaClass *metaClass = q->createMetaClass(); metaClass->setTypeEntry(type); + if (classItem->isFinal()) + *metaClass += AbstractMetaAttributes::FinalCppClass; + QStringList baseClassNames; const QVector<_ClassModelItem::BaseClass> &baseClasses = classItem->baseClasses(); for (const _ClassModelItem::BaseClass &baseClass : baseClasses) { @@ -2224,8 +2227,15 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel if (functionItem->isAbstract()) *metaFunction += AbstractMetaAttributes::Abstract; - if (!functionItem->isVirtual()) + if (functionItem->isVirtual()) { + *metaFunction += AbstractMetaAttributes::VirtualCppMethod; + if (functionItem->isOverride()) + *metaFunction += AbstractMetaAttributes::OverriddenCppMethod; + if (functionItem->isFinal()) + *metaFunction += AbstractMetaAttributes::FinalCppMethod; + } else { *metaFunction += AbstractMetaAttributes::Final; + } if (functionItem->isInvokable()) *metaFunction += AbstractMetaAttributes::Invokable; diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index 4827bcb0d..20943696e 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -914,6 +914,21 @@ QString AbstractMetaFunction::minimalSignature() const return minimalSignature; } +QString AbstractMetaFunction::debugSignature() const +{ + QString result; + const bool isOverride = attributes() & AbstractMetaFunction::OverriddenCppMethod; + const bool isFinal = attributes() & AbstractMetaFunction::FinalCppMethod; + if (!isOverride && !isFinal && (attributes() & AbstractMetaFunction::VirtualCppMethod)) + result += QLatin1String("virtual "); + result += minimalSignature(); + if (isOverride) + result += QLatin1String(" override"); + if (isFinal) + result += QLatin1String(" final"); + return result; +} + FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaClass* implementor) const { if (!implementor) @@ -1203,7 +1218,7 @@ bool function_sorter(AbstractMetaFunction *a, AbstractMetaFunction *b) #ifndef QT_NO_DEBUG_STREAM static inline void formatMetaFunctionBrief(QDebug &d, const AbstractMetaFunction *af) { - d << '"' << af->minimalSignature() << '"'; + d << '"' << af->debugSignature() << '"'; } void AbstractMetaFunction::formatDebugVerbose(QDebug &d) const @@ -2733,6 +2748,8 @@ QDebug operator<<(QDebug d, const AbstractMetaClass *ac) d << "AbstractMetaClass("; if (ac) { d << '"' << ac->fullName() << '"'; + if (ac->attributes() & AbstractMetaAttributes::FinalCppClass) + d << " [final]"; if (ac->m_baseClass) d << ", inherits \"" << ac->m_baseClass->name() << '"'; const AbstractMetaEnumList &enums = ac->enums(); diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index 25953b49b..c4b4543e0 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -131,6 +131,11 @@ public: HasRejectedConstructor = 0x00080000, + FinalCppClass = 0x00100000, + VirtualCppMethod = 0x00200000, + OverriddenCppMethod = 0x00400000, + FinalCppMethod = 0x00800000, + Final = FinalInTargetLang | FinalInCpp }; Q_DECLARE_FLAGS(Attributes, Attribute) @@ -935,6 +940,7 @@ public: QString modifiedName() const; QString minimalSignature() const; + QString debugSignature() const; // including virtual/override/final, etc., for debugging only. QStringList possibleIntrospectionCompatibleSignatures() const; QString marshalledName() const; diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp index 423b8d9ff..f67d8c9b2 100644 --- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp @@ -88,40 +88,53 @@ void TestAbstractMetaClass::testClassNameUnderNamespace() void TestAbstractMetaClass::testVirtualMethods() { - const char* cppCode ="\ - class A {\n\ - public:\n\ - virtual int pureVirtual() const = 0;\n\ - };\n\ - class B : public A {};\n\ - class C : public B {\n\ - public:\n\ - int pureVirtual() const { return 0; }\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <primitive-type name='int'/>\n\ - <object-type name='A'/>\n\ - <object-type name='B'/>\n\ - <object-type name='C'/>\n\ - </typesystem>\n"; + const char cppCode[] =R"CPP( +class A { +public: + virtual int pureVirtual() const = 0; +}; +class B : public A {}; +class C : public B { +public: + int pureVirtual() const override { return 0; } +}; +class F final : public C { +public: + int pureVirtual() const final { return 1; } +}; +)CPP"; + + const char xmlCode[] = R"XML( +<typesystem package="Foo"> + <primitive-type name='int'/> + <object-type name='A'/> + <object-type name='B'/> + <object-type name='C'/> + <object-type name='F'/> +</typesystem> +)XML"; QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); QVERIFY(!builder.isNull()); AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 3); + QCOMPARE(classes.count(), 4); AbstractMetaClass* a = AbstractMetaClass::findClass(classes, QLatin1String("A")); AbstractMetaClass* b = AbstractMetaClass::findClass(classes, QLatin1String("B")); AbstractMetaClass* c = AbstractMetaClass::findClass(classes, QLatin1String("C")); + const AbstractMetaClass *f = AbstractMetaClass::findClass(classes, QLatin1String("F")); + QVERIFY(f); AbstractMetaClass* no_class = 0; QCOMPARE(a->baseClass(), no_class); QCOMPARE(b->baseClass(), a); QCOMPARE(c->baseClass(), b); + QCOMPARE(f->baseClass(), c); QCOMPARE(a->functions().size(), 2); // default ctor + the pure virtual method QCOMPARE(b->functions().size(), 2); QCOMPARE(c->functions().size(), 2); + QCOMPARE(f->functions().size(), 2); + QVERIFY(f->attributes() & AbstractMetaAttributes::FinalCppClass); // implementing class, ownclass, declaringclass AbstractMetaFunction* ctorA = a->queryFunctions(AbstractMetaClass::Constructors).first(); @@ -140,14 +153,19 @@ void TestAbstractMetaClass::testVirtualMethods() QCOMPARE(a->virtualFunctions().size(), 1); // Add a pureVirtualMethods method !? QCOMPARE(b->virtualFunctions().size(), 1); QCOMPARE(c->virtualFunctions().size(), 1); + QCOMPARE(f->virtualFunctions().size(), 1); AbstractMetaFunction* funcA = a->virtualFunctions().first(); AbstractMetaFunction* funcB = b->virtualFunctions().first(); AbstractMetaFunction* funcC = c->virtualFunctions().first(); + const AbstractMetaFunction* funcF = f->virtualFunctions().constFirst(); QCOMPARE(funcA->ownerClass(), a); + QVERIFY(funcC->attributes() & AbstractMetaAttributes::VirtualCppMethod); QCOMPARE(funcB->ownerClass(), b); QCOMPARE(funcC->ownerClass(), c); + QVERIFY(funcC->attributes() & AbstractMetaAttributes::OverriddenCppMethod); + QVERIFY(funcF->attributes() & AbstractMetaAttributes::FinalCppMethod); QCOMPARE(funcA->declaringClass(), a); QCOMPARE(funcB->declaringClass(), a); |