diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2010-09-20 11:36:45 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-09 19:10:09 -0300 |
commit | 5179bca73955373e087d6b51edcabf038c964ac8 (patch) | |
tree | 255a4ca87763fb6c203ee31aa91815a6c0d8f548 | |
parent | c182be3e4c89fe81c15722708d8b712598a528b8 (diff) |
Anonymous enums now supported.
-rw-r--r-- | abstractmetabuilder.cpp | 16 | ||||
-rw-r--r-- | abstractmetalang.h | 5 | ||||
-rw-r--r-- | parser/binder.cpp | 4 | ||||
-rw-r--r-- | parser/codemodel.cpp | 10 | ||||
-rw-r--r-- | parser/codemodel.h | 3 | ||||
-rw-r--r-- | typesystem.cpp | 11 | ||||
-rw-r--r-- | typesystem.h | 10 |
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 |