aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2010-09-20 11:36:45 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-09 19:10:09 -0300
commit5179bca73955373e087d6b51edcabf038c964ac8 (patch)
tree255a4ca87763fb6c203ee31aa91815a6c0d8f548
parentc182be3e4c89fe81c15722708d8b712598a528b8 (diff)
Anonymous enums now supported.
-rw-r--r--abstractmetabuilder.cpp16
-rw-r--r--abstractmetalang.h5
-rw-r--r--parser/binder.cpp4
-rw-r--r--parser/codemodel.cpp10
-rw-r--r--parser/codemodel.h3
-rw-r--r--typesystem.cpp11
-rw-r--r--typesystem.h10
7 files changed, 57 insertions, 2 deletions
diff --git a/abstractmetabuilder.cpp b/abstractmetabuilder.cpp
index e650b5f06..197acbd4e 100644
--- a/abstractmetabuilder.cpp
+++ b/abstractmetabuilder.cpp
@@ -895,7 +895,21 @@ AbstractMetaEnum* AbstractMetaBuilder::traverseEnum(EnumModelItem enumItem, Abst
QString qualifiedName = enumItem->qualifiedName().join("::");
- TypeEntry* typeEntry = TypeDatabase::instance()->findType(qualifiedName);
+ TypeEntry* typeEntry = 0;
+ if (!enumItem->isAnonymous()) {
+ typeEntry = TypeDatabase::instance()->findType(qualifiedName);
+ } else {
+ QStringList tmpQualifiedName = enumItem->qualifiedName();
+ foreach (const EnumeratorModelItem& enumValue, enumItem->enumerators()) {
+ tmpQualifiedName.removeLast();
+ tmpQualifiedName << enumValue->name();
+ qualifiedName = tmpQualifiedName.join("::");
+ typeEntry = TypeDatabase::instance()->findType(qualifiedName);
+ if (typeEntry)
+ break;
+ }
+ }
+
QString enumName = enumItem->name();
QString className;
diff --git a/abstractmetalang.h b/abstractmetalang.h
index c502dd16e..7a5b90228 100644
--- a/abstractmetalang.h
+++ b/abstractmetalang.h
@@ -1303,6 +1303,11 @@ public:
m_class = c;
}
+ bool isAnonymous() const
+ {
+ return m_typeEntry->isAnonymous();
+ }
+
private:
AbstractMetaEnumValueList m_enumValues;
EnumTypeEntry *m_typeEntry;
diff --git a/parser/binder.cpp b/parser/binder.cpp
index 8b6c4c024..faace02ca 100644
--- a/parser/binder.cpp
+++ b/parser/binder.cpp
@@ -657,7 +657,8 @@ void Binder::visitEnumSpecifier(EnumSpecifierAST *node)
name_cc.run(node->name);
QString name = name_cc.name();
- if (name.isEmpty()) {
+ bool isAnonymous = name.isEmpty();
+ if (isAnonymous) {
// anonymous enum
QString key = _M_context.join("::");
int current = ++_M_anonymous_enums[key];
@@ -669,6 +670,7 @@ void Binder::visitEnumSpecifier(EnumSpecifierAST *node)
_M_current_enum->setAccessPolicy(_M_current_access);
updateItemPosition(_M_current_enum->toItem(), node);
_M_current_enum->setName(name);
+ _M_current_enum->setAnonymous(isAnonymous);
_M_current_enum->setScope(enumScope->qualifiedName());
_M_qualified_types[_M_current_enum->qualifiedName().join(".")] = QString();
diff --git a/parser/codemodel.cpp b/parser/codemodel.cpp
index 419471505..0cc14fcce 100644
--- a/parser/codemodel.cpp
+++ b/parser/codemodel.cpp
@@ -727,6 +727,16 @@ void _EnumModelItem::removeEnumerator(EnumeratorModelItem item)
_M_enumerators.removeAt(_M_enumerators.indexOf(item));
}
+bool _EnumModelItem::isAnonymous() const
+{
+ return _M_anonymous;
+}
+
+void _EnumModelItem::setAnonymous(bool anonymous)
+{
+ _M_anonymous = anonymous;
+}
+
// ---------------------------------------------------------------------------
QString _EnumeratorModelItem::value() const
{
diff --git a/parser/codemodel.h b/parser/codemodel.h
index 3ea94480f..f87f57a35 100644
--- a/parser/codemodel.h
+++ b/parser/codemodel.h
@@ -736,6 +736,8 @@ public:
EnumeratorList enumerators() const;
void addEnumerator(EnumeratorModelItem item);
void removeEnumerator(EnumeratorModelItem item);
+ bool isAnonymous() const;
+ void setAnonymous(bool anonymous);
protected:
_EnumModelItem(CodeModel *model, int kind = __node_kind)
@@ -745,6 +747,7 @@ protected:
private:
CodeModel::AccessPolicy _M_accessPolicy;
EnumeratorList _M_enumerators;
+ bool _M_anonymous;
private:
_EnumModelItem(const _EnumModelItem &other);
diff --git a/typesystem.cpp b/typesystem.cpp
index f92ea01dd..1cc9f1927 100644
--- a/typesystem.cpp
+++ b/typesystem.cpp
@@ -372,6 +372,7 @@ bool Handler::startElement(const QString &, const QString &n,
attributes["lower-bound"] = QString();
attributes["force-integer"] = "no";
attributes["extensible"] = "no";
+ attributes["identified-by-value"] = QString();
break;
case StackElement::ObjectTypeEntry:
case StackElement::ValueTypeEntry:
@@ -425,6 +426,15 @@ bool Handler::startElement(const QString &, const QString &n,
ReportHandler::warning(QString("Duplicate type entry: '%1'").arg(name));
}
+ if (element->type == StackElement::EnumTypeEntry) {
+ if (name.isEmpty()) {
+ name = attributes["identified-by-value"];
+ } else if (!attributes["identified-by-value"].isEmpty()) {
+ m_error = "can't specify both 'name' and 'identified-by-value' attributes";
+ return false;
+ }
+ }
+
if (name.isEmpty()) {
m_error = "no 'name' attribute specified";
return false;
@@ -485,6 +495,7 @@ bool Handler::startElement(const QString &, const QString &n,
m_currentEnum =
new EnumTypeEntry(QStringList(names.mid(0, names.size() - 1)).join("::"),
names.last(), since);
+ m_currentEnum->setAnonymous(!attributes["identified-by-value"].isEmpty());
element->entry = m_currentEnum;
m_currentEnum->setCodeGeneration(m_generate);
m_currentEnum->setTargetLangPackage(m_defaultPackage);
diff --git a/typesystem.h b/typesystem.h
index 948479d81..682f068e3 100644
--- a/typesystem.h
+++ b/typesystem.h
@@ -1265,6 +1265,15 @@ public:
m_forceInteger = force;
}
+ bool isAnonymous() const
+ {
+ return m_anonymous;
+ }
+ void setAnonymous(bool anonymous)
+ {
+ m_anonymous = anonymous;
+ }
+
private:
QString m_packageName;
QString m_qualifier;
@@ -1280,6 +1289,7 @@ private:
bool m_extensible;
bool m_forceInteger;
+ bool m_anonymous;
};
class APIEXTRACTOR_API EnumValueTypeEntry : public TypeEntry