Skip to content

Commit c707bcc

Browse files
committed
Handle enum classes
Since the enum values can be duplicates (they only need to be unique in the scope of the enum class) I opted to prefix them with the enum class name (and an underscore) in the generated wrapper. It would have been nice to use a Python Enum class instead, but after a quick look this seemed to be quite a lot of work.
1 parent 07057fc commit c707bcc

File tree

7 files changed

+32
-1
lines changed

7 files changed

+32
-1
lines changed

generator/abstractmetabuilder.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,8 @@ AbstractMetaEnum *AbstractMetaBuilder::traverseEnum(EnumModelItem enum_item, Abs
10081008
return 0;
10091009
}
10101010

1011+
static_cast<EnumTypeEntry*>(type_entry)->setEnumClass(enum_item->isEnumClass());
1012+
10111013
AbstractMetaEnum *meta_enum = createMetaEnum();
10121014
if ( enumsDeclarations.contains(qualified_name)
10131015
|| enumsDeclarations.contains(enum_name)) {

generator/parser/ast.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ struct EnumSpecifierAST: public TypeSpecifierAST
421421

422422
NameAST *name{};
423423
const ListNode<EnumeratorAST*> *enumerators{};
424+
bool is_enum_class{};
424425
};
425426

426427
struct EnumeratorAST: public AST

generator/parser/binder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@ void Binder::visitEnumSpecifier(EnumSpecifierAST *node)
796796

797797
_M_current_enum = model()->create<EnumModelItem>();
798798
_M_current_enum->setAccessPolicy(_M_current_access);
799+
_M_current_enum->setEnumClass(node->is_enum_class);
799800
updateItemPosition (_M_current_enum->toItem(), node);
800801
_M_current_enum->setName(name);
801802
_M_current_enum->setScope(enumScope->qualifiedName());

generator/parser/codemodel.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,9 @@ class _EnumModelItem: public _CodeModelItem
676676
CodeModel::AccessPolicy accessPolicy() const;
677677
void setAccessPolicy(CodeModel::AccessPolicy accessPolicy);
678678

679+
bool isEnumClass() const { return _M_isEnumClass; }
680+
void setEnumClass(bool isEnumClass) { _M_isEnumClass = isEnumClass; }
681+
679682
EnumeratorList enumerators() const;
680683
void addEnumerator(EnumeratorModelItem item);
681684
void removeEnumerator(EnumeratorModelItem item);
@@ -689,6 +692,7 @@ class _EnumModelItem: public _CodeModelItem
689692
private:
690693
CodeModel::AccessPolicy _M_accessPolicy;
691694
EnumeratorList _M_enumerators;
695+
bool _M_isEnumClass{};
692696

693697
private:
694698
_EnumModelItem(const _EnumModelItem &other);

generator/parser/parser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,8 +1548,10 @@ bool Parser::parseEnumSpecifier(TypeSpecifierAST *&node)
15481548

15491549
CHECK(Token_enum);
15501550

1551+
bool enum_class{};
15511552
if (token_stream.lookAhead() == Token_class)
15521553
{
1554+
enum_class = true;
15531555
nextToken();
15541556
}
15551557

@@ -1576,6 +1578,7 @@ bool Parser::parseEnumSpecifier(TypeSpecifierAST *&node)
15761578

15771579
EnumSpecifierAST *ast = CreateNode<EnumSpecifierAST>(_M_pool);
15781580
ast->name = name;
1581+
ast->is_enum_class = enum_class;
15791582

15801583
EnumeratorAST *enumerator = 0;
15811584
if (parseEnumerator(enumerator))

generator/shellheadergenerator.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,27 @@ void ShellHeaderGenerator::write(QTextStream& s, const AbstractMetaClass* meta_c
305305
s << "enum " << enum1->name() << "{" << endl;
306306
bool first = true;
307307
QString scope = enum1->wasProtected() ? promoterClassName(meta_class) : meta_class->qualifiedCppName();
308+
bool isEnumClass = enum1->typeEntry()->isEnumClass();
309+
if (isEnumClass) {
310+
scope += "::" + enum1->name();
311+
}
308312

309313
for (AbstractMetaEnumValue * value : enum1->values()) {
310314
if (first) { first = false; }
311315
else { s << ", "; }
312-
s << " " << value->name() << " = " << scope << "::" << value->name();
316+
QString assignedValue = scope + "::" + value->name();
317+
if (isEnumClass) {
318+
// prepend value name with class name, the value name on itself could be a duplicate
319+
//
320+
// I thought about creating a enum class instead, and creating an Enum class in PythonQt for the wrapper
321+
// (QMetaEnum has a isScoped method to check for enum classes),
322+
// but the process seemed quite complicated.
323+
s << " " << enum1->name() << "_" << value->name() << " = " << "static_cast<int>(" << scope << "::" << value->name() << ")";
324+
}
325+
else {
326+
s << " " << value->name() << " = " << scope << "::" << value->name();
327+
328+
}
313329
}
314330
s << "};" << endl;
315331
}

generator/typesystem.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,9 @@ class EnumTypeEntry : public TypeEntry
730730
void addEnumValueRedirection(const QString &rejected, const QString &usedValue);
731731
QString enumValueRedirection(const QString &value) const;
732732

733+
bool isEnumClass() const { return m_enum_class; }
734+
void setEnumClass(bool enum_class) { m_enum_class = enum_class; }
735+
733736
bool forceInteger() const { return m_force_integer; }
734737
void setForceInteger(bool force) { m_force_integer = force; }
735738

@@ -748,6 +751,7 @@ class EnumTypeEntry : public TypeEntry
748751
FlagsTypeEntry *m_flags;
749752

750753
bool m_extensible;
754+
bool m_enum_class;
751755
bool m_force_integer;
752756
};
753757

0 commit comments

Comments
 (0)