aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2010-09-29 10:46:48 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-09 19:10:11 -0300
commit7c1048b86bc76e68f728e4819fe832d17276bfe6 (patch)
tree1f0e7211d9948af5c6a48c38fde7794e21eabdce
parent0f84794301386a9371c374e5ed062fc000c96f17 (diff)
Improved resolution of enum value attributions.
In particular when an enum item is set to the value of an item from other enum. The code for this was moved to the method AbstractMetaBuilder::findOutValueFromString. Tests were added as well. s# ../tests/.testenum.h.swp
-rw-r--r--abstractmetabuilder.cpp77
-rw-r--r--abstractmetabuilder.h2
-rw-r--r--tests/testenum.cpp55
-rw-r--r--tests/testenum.h1
4 files changed, 93 insertions, 42 deletions
diff --git a/abstractmetabuilder.cpp b/abstractmetabuilder.cpp
index 000ce8400..50a0e6576 100644
--- a/abstractmetabuilder.cpp
+++ b/abstractmetabuilder.cpp
@@ -788,22 +788,12 @@ int AbstractMetaBuilder::figureOutEnumValue(const QString &stringValue,
matched = true;
} else {
- AbstractMetaEnumValue* ev = 0;
- AbstractMetaClass* enumEnclosingClass = metaEnum ? metaEnum->enclosingClass() : 0;
-
if (metaEnum) {
- matched = true;
- if (s == "true" || s == "false") {
- v = (s == "true");
- } else if ((ev = metaEnum->values().find(s))) {
- v = ev->value();
- } else if (enumEnclosingClass && (ev = enumEnclosingClass->findEnumValue(s, metaEnum))) {
- v = ev->value();
- } else {
- matched = false;
+ v = findOutValueFromString(s, matched);
+ if (!matched) {
+ QString enclosingClass = QString(metaEnum->enclosingClass() ? metaEnum->enclosingClass()->name() + "::" : QString());
ReportHandler::warning("unhandled enum value: " + s + " in "
- + (enumEnclosingClass ? QString("%1::").arg(enumEnclosingClass->name()) : QString())
- + metaEnum->name()
+ + enclosingClass + metaEnum->name()
+ " from header '" + metaEnum->typeEntry()->include().name() + "'");
}
} else {
@@ -1945,32 +1935,8 @@ AbstractMetaType* AbstractMetaBuilder::translateType(const TypeInfo& _typei, boo
for (int i = typeInfo.arrays.size() - 1; i >= 0; --i) {
QString s = typeInfo.arrays.at(i);
- bool ok;
-
- int elems = s.toInt(&ok);
- if (!ok) {
- if (s == "true" or s == "false") {
- elems = (s == "true");
- } else {
- AbstractMetaEnumValue* enumValue = m_metaClasses.findEnumValue(s);
- if (!enumValue) {
- foreach (AbstractMetaEnum* metaEnum, m_globalEnums) {
- foreach (AbstractMetaEnumValue* ev, metaEnum->values()) {
- if (ev->name() == s) {
- enumValue = ev;
- break;
- }
- }
- if (enumValue)
- break;
- }
- }
-
- if (!enumValue)
- return 0;
- elems = enumValue->value();
- }
- }
+ bool _ok;
+ int elems = findOutValueFromString(s, _ok);
AbstractMetaType* arrayType = createMetaType();
arrayType->setArrayElementCount(elems);
@@ -2108,6 +2074,37 @@ AbstractMetaType* AbstractMetaBuilder::translateType(const TypeInfo& _typei, boo
return metaType;
}
+
+int AbstractMetaBuilder::findOutValueFromString(const QString& stringValue, bool& ok)
+{
+ int value = stringValue.toInt(&ok);
+ if (ok)
+ return value;
+
+ if (stringValue == "true" or stringValue == "false") {
+ ok = true;
+ return (stringValue == "true");
+ }
+
+ AbstractMetaEnumValue* enumValue = m_metaClasses.findEnumValue(stringValue);
+ if (enumValue) {
+ ok = true;
+ return enumValue->value();
+ }
+
+ foreach (AbstractMetaEnum* metaEnum, m_globalEnums) {
+ foreach (AbstractMetaEnumValue* ev, metaEnum->values()) {
+ if (ev->name() == stringValue) {
+ ok = true;
+ return ev->value();
+ }
+ }
+ }
+
+ ok = false;
+ return 0;
+}
+
void AbstractMetaBuilder::decideUsagePattern(AbstractMetaType *metaType)
{
const TypeEntry* type = metaType->typeEntry();
diff --git a/abstractmetabuilder.h b/abstractmetabuilder.h
index 8b2900974..d45b34aaa 100644
--- a/abstractmetabuilder.h
+++ b/abstractmetabuilder.h
@@ -149,6 +149,8 @@ public:
AbstractMetaType* translateType(double vr, const AddedFunction::TypeInfo& typeInfo);
AbstractMetaType *translateType(const TypeInfo &type, bool *ok, bool resolveType = true, bool resolveScope = true);
+ int findOutValueFromString(const QString& stringValue, bool& ok);
+
void decideUsagePattern(AbstractMetaType *type);
const AbstractMetaFunctionList globalFunctions() const
diff --git a/tests/testenum.cpp b/tests/testenum.cpp
index a55598fb4..17636badd 100644
--- a/tests/testenum.cpp
+++ b/tests/testenum.cpp
@@ -164,7 +164,7 @@ void TestEnum::testGlobalEnums()
{
const char* cppCode ="\
enum EnumA { A0, A1 }; \
- enum EnumB { B0 = 2, B1 = 4 }; \
+ enum EnumB { B0 = 2, B1 = 0x4 }; \
";
const char* xmlCode = "\
<typesystem package=\"Foo\"> \
@@ -201,7 +201,58 @@ void TestEnum::testGlobalEnums()
AbstractMetaEnumValue* enumValueB1 = enumB->values().last();
QCOMPARE(enumValueB1->name(), QString("B1"));
QCOMPARE(enumValueB1->value(), 4);
- QCOMPARE(enumValueB1->stringValue(), QString("4"));
+ QCOMPARE(enumValueB1->stringValue(), QString("0x4"));
+}
+
+void TestEnum::testEnumValueFromNeighbourEnum()
+{
+ const char* cppCode ="\
+ namespace A {\
+ enum EnumA { ValueA0, ValueA1 };\
+ enum EnumB { ValueB0 = A::ValueA1, ValueB1 = ValueA0 };\
+ };\
+ ";
+ const char* xmlCode = "\
+ <typesystem package=\"Foo\"> \
+ <namespace-type name='A'> \
+ <enum-type name='EnumA'/>\
+ <enum-type name='EnumB'/>\
+ </namespace-type> \
+ </typesystem>";
+
+ TestUtil t(cppCode, xmlCode, false);
+
+ AbstractMetaClassList classes = t.builder()->classes();
+ QCOMPARE(classes.count(), 1);
+ QCOMPARE(classes[0]->enums().count(), 2);
+
+ AbstractMetaEnum* enumA = classes[0]->findEnum("EnumA");
+ QVERIFY(enumA);
+ QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QString("A::EnumA"));
+
+ AbstractMetaEnumValue* enumValueA0 = enumA->values().first();
+ QCOMPARE(enumValueA0->name(), QString("ValueA0"));
+ QCOMPARE(enumValueA0->value(), 0);
+ QCOMPARE(enumValueA0->stringValue(), QString(""));
+
+ AbstractMetaEnumValue* enumValueA1 = enumA->values().last();
+ QCOMPARE(enumValueA1->name(), QString("ValueA1"));
+ QCOMPARE(enumValueA1->value(), 1);
+ QCOMPARE(enumValueA1->stringValue(), QString(""));
+
+ AbstractMetaEnum* enumB = classes[0]->findEnum("EnumB");
+ QVERIFY(enumB);
+ QCOMPARE(enumB->typeEntry()->qualifiedCppName(), QString("A::EnumB"));
+
+ AbstractMetaEnumValue* enumValueB0 = enumB->values().first();
+ QCOMPARE(enumValueB0->name(), QString("ValueB0"));
+ QCOMPARE(enumValueB0->value(), 1);
+ QCOMPARE(enumValueB0->stringValue(), QString("A::ValueA1"));
+
+ AbstractMetaEnumValue* enumValueB1 = enumB->values().last();
+ QCOMPARE(enumValueB1->name(), QString("ValueB1"));
+ QCOMPARE(enumValueB1->value(), 0);
+ QCOMPARE(enumValueB1->stringValue(), QString("ValueA0"));
}
QTEST_APPLESS_MAIN(TestEnum)
diff --git a/tests/testenum.h b/tests/testenum.h
index 38826ccfb..762aed609 100644
--- a/tests/testenum.h
+++ b/tests/testenum.h
@@ -33,6 +33,7 @@ private slots:
void testEnumWithApiVersion();
void testAnonymousEnum();
void testGlobalEnums();
+ void testEnumValueFromNeighbourEnum();
};
#endif