forked from qt-creator/qt-creator
CppEditor: Make "Complete Switch" quickfix work with enum classes
Fixes: QTCREATORBUG-20475 Change-Id: Id21a007ab4b652dcfe49d97bfa4c9fa77bacf8c4 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -373,6 +373,32 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Same as above for enum class.
|
||||||
|
QTest::newRow("CompleteSwitchCaseStatement_basic1_enum class")
|
||||||
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
|
"enum class EnumType { V1, V2 };\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" EnumType t;\n"
|
||||||
|
" @switch (t) {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
) << _(
|
||||||
|
"enum class EnumType { V1, V2 };\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" EnumType t;\n"
|
||||||
|
" switch (t) {\n"
|
||||||
|
" case EnumType::V1:\n"
|
||||||
|
" break;\n"
|
||||||
|
" case EnumType::V2:\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
// Checks: All enum values are added as case statements for a blank switch when
|
// Checks: All enum values are added as case statements for a blank switch when
|
||||||
// the variable is declared alongside the enum definition.
|
// the variable is declared alongside the enum definition.
|
||||||
QTest::newRow("CompleteSwitchCaseStatement_basic1_enum_with_declaration")
|
QTest::newRow("CompleteSwitchCaseStatement_basic1_enum_with_declaration")
|
||||||
@@ -398,6 +424,30 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Same as above for enum class.
|
||||||
|
QTest::newRow("CompleteSwitchCaseStatement_basic1_enum_with_declaration_enumClass")
|
||||||
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
|
"enum class EnumType { V1, V2 } t;\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" @switch (t) {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
) << _(
|
||||||
|
"enum class EnumType { V1, V2 } t;\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" switch (t) {\n"
|
||||||
|
" case EnumType::V1:\n"
|
||||||
|
" break;\n"
|
||||||
|
" case EnumType::V2:\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
// Checks: All enum values are added as case statements for a blank switch
|
// Checks: All enum values are added as case statements for a blank switch
|
||||||
// for anonymous enums.
|
// for anonymous enums.
|
||||||
QTest::newRow("CompleteSwitchCaseStatement_basic1_anonymous_enum")
|
QTest::newRow("CompleteSwitchCaseStatement_basic1_anonymous_enum")
|
||||||
@@ -453,6 +503,36 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Same as above for enum class.
|
||||||
|
QTest::newRow("CompleteSwitchCaseStatement_basic2_enumClass")
|
||||||
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
|
"enum class EnumType { V1, V2 };\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" EnumType t;\n"
|
||||||
|
" @switch (t) {\n"
|
||||||
|
" default:\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
) << _(
|
||||||
|
"enum class EnumType { V1, V2 };\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" EnumType t;\n"
|
||||||
|
" switch (t) {\n"
|
||||||
|
" case EnumType::V1:\n"
|
||||||
|
" break;\n"
|
||||||
|
" case EnumType::V2:\n"
|
||||||
|
" break;\n"
|
||||||
|
" default:\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
// Checks: Enum type in class is found.
|
// Checks: Enum type in class is found.
|
||||||
QTest::newRow("CompleteSwitchCaseStatement_enumTypeInClass")
|
QTest::newRow("CompleteSwitchCaseStatement_enumTypeInClass")
|
||||||
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
@@ -475,6 +555,28 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Same as above for enum class.
|
||||||
|
QTest::newRow("CompleteSwitchCaseStatement_enumClassInClass")
|
||||||
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
|
"struct C { enum class EnumType { V1, V2 }; };\n"
|
||||||
|
"\n"
|
||||||
|
"void f(C::EnumType t) {\n"
|
||||||
|
" @switch (t) {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
) << _(
|
||||||
|
"struct C { enum class EnumType { V1, V2 }; };\n"
|
||||||
|
"\n"
|
||||||
|
"void f(C::EnumType t) {\n"
|
||||||
|
" switch (t) {\n"
|
||||||
|
" case C::EnumType::V1:\n"
|
||||||
|
" break;\n"
|
||||||
|
" case C::EnumType::V2:\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
// Checks: Enum type in namespace is found.
|
// Checks: Enum type in namespace is found.
|
||||||
QTest::newRow("CompleteSwitchCaseStatement_enumTypeInNamespace")
|
QTest::newRow("CompleteSwitchCaseStatement_enumTypeInNamespace")
|
||||||
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
@@ -497,6 +599,28 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Same as above for enum class.
|
||||||
|
QTest::newRow("CompleteSwitchCaseStatement_enumClassInNamespace")
|
||||||
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
|
"namespace N { enum class EnumType { V1, V2 }; };\n"
|
||||||
|
"\n"
|
||||||
|
"void f(N::EnumType t) {\n"
|
||||||
|
" @switch (t) {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
) << _(
|
||||||
|
"namespace N { enum class EnumType { V1, V2 }; };\n"
|
||||||
|
"\n"
|
||||||
|
"void f(N::EnumType t) {\n"
|
||||||
|
" switch (t) {\n"
|
||||||
|
" case N::EnumType::V1:\n"
|
||||||
|
" break;\n"
|
||||||
|
" case N::EnumType::V2:\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
// Checks: The missing enum value is added.
|
// Checks: The missing enum value is added.
|
||||||
QTest::newRow("CompleteSwitchCaseStatement_oneValueMissing")
|
QTest::newRow("CompleteSwitchCaseStatement_oneValueMissing")
|
||||||
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
@@ -529,6 +653,38 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Checks: Same as above for enum class.
|
||||||
|
QTest::newRow("CompleteSwitchCaseStatement_oneValueMissing_enumClass")
|
||||||
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
|
"enum class EnumType { V1, V2 };\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" EnumType t;\n"
|
||||||
|
" @switch (t) {\n"
|
||||||
|
" case EnumType::V2:\n"
|
||||||
|
" break;\n"
|
||||||
|
" default:\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
) << _(
|
||||||
|
"enum class EnumType { V1, V2 };\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" EnumType t;\n"
|
||||||
|
" switch (t) {\n"
|
||||||
|
" case EnumType::V1:\n"
|
||||||
|
" break;\n"
|
||||||
|
" case EnumType::V2:\n"
|
||||||
|
" break;\n"
|
||||||
|
" default:\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
// Checks: Find the correct enum type despite there being a declaration with the same name.
|
// Checks: Find the correct enum type despite there being a declaration with the same name.
|
||||||
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_1")
|
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_1")
|
||||||
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
@@ -553,6 +709,30 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Same as above for enum class.
|
||||||
|
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_1_enumClass")
|
||||||
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
|
"enum class test { TEST_1, TEST_2 };\n"
|
||||||
|
"\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" enum test test;\n"
|
||||||
|
" @switch (test) {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
) << _(
|
||||||
|
"enum class test { TEST_1, TEST_2 };\n"
|
||||||
|
"\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" enum test test;\n"
|
||||||
|
" switch (test) {\n"
|
||||||
|
" case test::TEST_1:\n"
|
||||||
|
" break;\n"
|
||||||
|
" case test::TEST_2:\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
// Checks: Find the correct enum type despite there being a declaration with the same name.
|
// Checks: Find the correct enum type despite there being a declaration with the same name.
|
||||||
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_2")
|
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_2")
|
||||||
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
@@ -581,6 +761,34 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Same as above for enum class.
|
||||||
|
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_2_enumClass")
|
||||||
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
|
"enum class test1 { Wrong11, Wrong12 };\n"
|
||||||
|
"enum class test { Right1, Right2 };\n"
|
||||||
|
"enum class test2 { Wrong21, Wrong22 };\n"
|
||||||
|
"\n"
|
||||||
|
"int main() {\n"
|
||||||
|
" enum test test;\n"
|
||||||
|
" @switch (test) {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
) << _(
|
||||||
|
"enum class test1 { Wrong11, Wrong12 };\n"
|
||||||
|
"enum class test { Right1, Right2 };\n"
|
||||||
|
"enum class test2 { Wrong21, Wrong22 };\n"
|
||||||
|
"\n"
|
||||||
|
"int main() {\n"
|
||||||
|
" enum test test;\n"
|
||||||
|
" switch (test) {\n"
|
||||||
|
" case test::Right1:\n"
|
||||||
|
" break;\n"
|
||||||
|
" case test::Right2:\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
// Checks: Do not crash on incomplete case statetement.
|
// Checks: Do not crash on incomplete case statetement.
|
||||||
QTest::newRow("CompleteSwitchCaseStatement_doNotCrashOnIncompleteCase")
|
QTest::newRow("CompleteSwitchCaseStatement_doNotCrashOnIncompleteCase")
|
||||||
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
@@ -596,6 +804,21 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
""
|
""
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Same as above for enum class.
|
||||||
|
QTest::newRow("CompleteSwitchCaseStatement_doNotCrashOnIncompleteCase_enumClass")
|
||||||
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
|
"enum class E {};\n"
|
||||||
|
"void f(E o)\n"
|
||||||
|
"{\n"
|
||||||
|
" @switch (o)\n"
|
||||||
|
" {\n"
|
||||||
|
" case\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
) << _(
|
||||||
|
""
|
||||||
|
);
|
||||||
|
|
||||||
// Checks: complete switch statement where enum is goes via a template type parameter
|
// Checks: complete switch statement where enum is goes via a template type parameter
|
||||||
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG-24752")
|
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG-24752")
|
||||||
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
@@ -622,6 +845,32 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Same as above for enum class.
|
||||||
|
QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG-24752_enumClass")
|
||||||
|
<< CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _(
|
||||||
|
"enum class E {A, B};\n"
|
||||||
|
"template<typename T> struct S {\n"
|
||||||
|
" static T theType() { return T(); }\n"
|
||||||
|
"};\n"
|
||||||
|
"int main() {\n"
|
||||||
|
" @switch (S<E>::theType()) {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
) << _(
|
||||||
|
"enum class E {A, B};\n"
|
||||||
|
"template<typename T> struct S {\n"
|
||||||
|
" static T theType() { return T(); }\n"
|
||||||
|
"};\n"
|
||||||
|
"int main() {\n"
|
||||||
|
" switch (S<E>::theType()) {\n"
|
||||||
|
" case E::A:\n"
|
||||||
|
" break;\n"
|
||||||
|
" case E::B:\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
// Checks:
|
// Checks:
|
||||||
// 1. If the name does not start with ("m_" or "_") and does not
|
// 1. If the name does not start with ("m_" or "_") and does not
|
||||||
// end with "_", we are forced to prefix the getter with "get".
|
// end with "_", we are forced to prefix the getter with "get".
|
||||||
|
|||||||
@@ -2740,7 +2740,12 @@ static Enum *findEnum(const QList<LookupItem> &results, const LookupContext &ctx
|
|||||||
return e;
|
return e;
|
||||||
if (const NamedType *namedType = type->asNamedType()) {
|
if (const NamedType *namedType = type->asNamedType()) {
|
||||||
if (ClassOrNamespace *con = ctxt.lookupType(namedType->name(), result.scope())) {
|
if (ClassOrNamespace *con = ctxt.lookupType(namedType->name(), result.scope())) {
|
||||||
const QList<Enum *> enums = con->unscopedEnums();
|
QList<Enum *> enums = con->unscopedEnums();
|
||||||
|
const QList<Symbol *> symbols = con->symbols();
|
||||||
|
for (Symbol * const s : symbols) {
|
||||||
|
if (const auto e = s->asEnum())
|
||||||
|
enums << e;
|
||||||
|
}
|
||||||
const Name *referenceName = namedType->name();
|
const Name *referenceName = namedType->name();
|
||||||
if (const QualifiedNameId *qualifiedName = referenceName->asQualifiedNameId())
|
if (const QualifiedNameId *qualifiedName = referenceName->asQualifiedNameId())
|
||||||
referenceName = qualifiedName->name();
|
referenceName = qualifiedName->name();
|
||||||
|
|||||||
Reference in New Issue
Block a user