From 2d170a0b8b1519befc4cdad57a0a46ccf8d16e0a Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Wed, 1 Sep 2010 13:35:40 -0300 Subject: Fixed function modification propagation. Now all modifications on base function will be propagate until a new modification was found. Reviewer: Hugo Parente Lima Lauro Moura --- abstractmetalang.cpp | 5 +-- tests/testmodifyfunction.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++++ tests/testmodifyfunction.h | 1 + typesystem.cpp | 31 ++++++++++++++++ typesystem.h | 4 +++ 5 files changed, 125 insertions(+), 2 deletions(-) diff --git a/abstractmetalang.cpp b/abstractmetalang.cpp index fe6c6b372..da48a315f 100644 --- a/abstractmetalang.cpp +++ b/abstractmetalang.cpp @@ -690,8 +690,9 @@ FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaC FunctionModificationList mods; while (implementor) { mods += implementor->typeEntry()->functionModifications(minimalSignature()); - if (implementor == implementor->baseClass() || implementor == implementingClass()) - break; + if ((implementor == implementor->baseClass()) || + (implementor == implementingClass() && (mods.size() > 0))) + break; implementor = implementor->baseClass(); } return mods; diff --git a/tests/testmodifyfunction.cpp b/tests/testmodifyfunction.cpp index 95ba16f40..3f92e3e13 100644 --- a/tests/testmodifyfunction.cpp +++ b/tests/testmodifyfunction.cpp @@ -79,6 +79,92 @@ void TestModifyFunction::testOwnershipTransfer() QCOMPARE(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0), TypeSystem::CppOwnership); } + +void TestModifyFunction::invalidateAfterUse() +{ + const char* cppCode ="\ + struct A {\ + virtual void call(int *a);\ + };\ + struct B : A {\ + };\ + struct C : B {\ + virtual void call2(int *a);\ + };\ + struct D : C {\ + virtual void call2(int *a);\ + };\ + struct E : D {\ + };\ + "; + const char* xmlCode = "\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + "; + TestUtil t(cppCode, xmlCode, false, 0.1); + AbstractMetaClassList classes = t.builder()->classes(); + AbstractMetaClass* classB = classes.findClass("B"); + const AbstractMetaFunction* func = classB->findFunction("call"); + QCOMPARE(func->modifications().size(), 1); + QCOMPARE(func->modifications().at(0).argument_mods.size(), 1); + QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse); + + AbstractMetaClass* classC = classes.findClass("C"); + QVERIFY(classC); + func = classC->findFunction("call"); + QCOMPARE(func->modifications().size(), 1); + QCOMPARE(func->modifications().at(0).argument_mods.size(), 1); + QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse); + + func = classC->findFunction("call2"); + QCOMPARE(func->modifications().size(), 1); + QCOMPARE(func->modifications().at(0).argument_mods.size(), 1); + QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse); + + AbstractMetaClass* classD = classes.findClass("D"); + QVERIFY(classD); + func = classD->findFunction("call"); + QCOMPARE(func->modifications().size(), 1); + QCOMPARE(func->modifications().at(0).argument_mods.size(), 1); + QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse); + + func = classD->findFunction("call2"); + QCOMPARE(func->modifications().size(), 1); + QCOMPARE(func->modifications().at(0).argument_mods.size(), 1); + QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse); + + AbstractMetaClass* classE = classes.findClass("E"); + QVERIFY(classE); + func = classE->findFunction("call"); + QVERIFY(func); + QCOMPARE(func->modifications().size(), 1); + QCOMPARE(func->modifications().at(0).argument_mods.size(), 1); + QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse); + + func = classE->findFunction("call2"); + QVERIFY(func); + QCOMPARE(func->modifications().size(), 1); + QCOMPARE(func->modifications().at(0).argument_mods.size(), 1); + QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse); +} + void TestModifyFunction::testWithApiVersion() { const char* cppCode ="\ diff --git a/tests/testmodifyfunction.h b/tests/testmodifyfunction.h index 40adf127f..95b7b6a7f 100644 --- a/tests/testmodifyfunction.h +++ b/tests/testmodifyfunction.h @@ -33,6 +33,7 @@ class TestModifyFunction : public QObject void testOwnershipTransfer(); void testWithApiVersion(); void testRenameArgument(); + void invalidateAfterUse(); }; #endif diff --git a/typesystem.cpp b/typesystem.cpp index 31c4f547e..f92ea01dd 100644 --- a/typesystem.cpp +++ b/typesystem.cpp @@ -1783,6 +1783,37 @@ QString FunctionModification::toString() const return str; } +bool FunctionModification::operator!=(const FunctionModification& other) const +{ + return !(*this == other); +} + +bool FunctionModification::operator==(const FunctionModification& other) const +{ + if (signature != other.signature) + return false; + + if (association != other.association) + return false; + + if (modifiers != other.modifiers) + return false; + + if (removal != other.removal) + return false; + + if (m_thread != other.m_thread) + return false; + + if (m_allowThread != other.m_allowThread) + return false; + + if (m_version != other.m_version) + return false; + + return true; +} + static AddedFunction::TypeInfo parseType(const QString& signature, int startPos = 0, int* endPos = 0) { AddedFunction::TypeInfo result; diff --git a/typesystem.h b/typesystem.h index 4a0e6c7ce..948479d81 100644 --- a/typesystem.h +++ b/typesystem.h @@ -401,6 +401,10 @@ struct APIEXTRACTOR_API FunctionModification: public Modification return m_version; } + bool operator!=(const FunctionModification& other) const; + bool operator==(const FunctionModification& other) const; + + QString toString() const; QString signature; -- cgit v1.2.3