diff options
Diffstat (limited to 'src/plugins/cppeditor')
-rw-r--r-- | src/plugins/cppeditor/cppeditor.cpp | 9 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditorplugin.h | 72 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppfollowsymbolundercursor.cpp | 39 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppquickfix_test.cpp | 1526 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppquickfixes.cpp | 27 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp | 148 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppvirtualfunctionassistprovider.h | 6 | ||||
-rw-r--r-- | src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp | 52 |
8 files changed, 902 insertions, 977 deletions
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index f617545bd1..682adf61cc 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -717,6 +717,9 @@ void CPPEditorWidget::setMimeType(const QString &mt) = m_modelManager->cppEditorSupport(editor())->snapshotUpdater(); updater->setEditorDefines(additionalDirectives); + m_preprocessorButton->setProperty("highlightWidget", !additionalDirectives.trimmed().isEmpty()); + m_preprocessorButton->update(); + BaseTextEditorWidget::setMimeType(mt); setObjCEnabled(mt == QLatin1String(CppTools::Constants::OBJECTIVE_C_SOURCE_MIMETYPE) || mt == QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)); @@ -1995,8 +1998,12 @@ void CPPEditorWidget::showPreProcessorWidget() if (preProcessorDialog.exec() == QDialog::Accepted) { QSharedPointer<SnapshotUpdater> updater = m_modelManager->cppEditorSupport(editor())->snapshotUpdater(); - updater->setEditorDefines(preProcessorDialog.additionalPreProcessorDirectives().toUtf8()); + const QString &additionals = preProcessorDialog.additionalPreProcessorDirectives(); + updater->setEditorDefines(additionals.toUtf8()); updater->update(m_modelManager->workingCopy()); + + m_preprocessorButton->setProperty("highlightWidget", !additionals.trimmed().isEmpty()); + m_preprocessorButton->update(); } } diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index 0989225538..e06355949b 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -97,6 +97,9 @@ private slots: void test_SwitchMethodDeclarationDefinition_data(); void test_SwitchMethodDeclarationDefinition(); + void test_FollowSymbolUnderCursor_multipleDocuments_data(); + void test_FollowSymbolUnderCursor_multipleDocuments(); + void test_FollowSymbolUnderCursor_data(); void test_FollowSymbolUnderCursor(); @@ -119,40 +122,19 @@ private slots: void test_doxygen_comments_data(); void test_doxygen_comments(); - void test_quickfix_CompleteSwitchCaseStatement_basic1(); - void test_quickfix_CompleteSwitchCaseStatement_basic2(); - void test_quickfix_CompleteSwitchCaseStatement_oneValueMissing(); - void test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG10366_1(); - void test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG10366_2(); + void test_quickfix_data(); + void test_quickfix(); - void test_quickfix_GenerateGetterSetter_basicGetterWithPrefix(); - void test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespace(); void test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespaceToCpp(); - void test_quickfix_GenerateGetterSetter_basicGetterWithoutPrefix(); - void test_quickfix_GenerateGetterSetter_customType(); - void test_quickfix_GenerateGetterSetter_constMember(); - void test_quickfix_GenerateGetterSetter_pointerToNonConst(); - void test_quickfix_GenerateGetterSetter_pointerToConst(); - void test_quickfix_GenerateGetterSetter_staticMember(); - void test_quickfix_GenerateGetterSetter_secondDeclarator(); - void test_quickfix_GenerateGetterSetter_triggeringRightAfterPointerSign(); - void test_quickfix_GenerateGetterSetter_notTriggeringOnMemberFunction(); - void test_quickfix_GenerateGetterSetter_notTriggeringOnMemberArray(); - void test_quickfix_GenerateGetterSetter_notTriggeringWhenGetterOrSetterExist(); - - void test_quickfix_ReformatPointerDeclaration(); - - void test_quickfix_InsertDefFromDecl_basic(); + void test_quickfix_InsertDefFromDecl_afterClass(); void test_quickfix_InsertDefFromDecl_headerSource_basic1(); void test_quickfix_InsertDefFromDecl_headerSource_basic2(); void test_quickfix_InsertDefFromDecl_headerSource_basic3(); void test_quickfix_InsertDefFromDecl_headerSource_namespace1(); void test_quickfix_InsertDefFromDecl_headerSource_namespace2(); - void test_quickfix_InsertDefFromDecl_freeFunction(); void test_quickfix_InsertDefFromDecl_insideClass(); void test_quickfix_InsertDefFromDecl_notTriggeringWhenDefinitionExists(); - void test_quickfix_InsertDefFromDecl_notTriggeringStatement(); void test_quickfix_InsertDefFromDecl_findRightImplementationFile(); void test_quickfix_InsertDefFromDecl_ignoreSurroundingGeneratedDeclarations(); void test_quickfix_InsertDefFromDecl_respectWsInOperatorNames1(); @@ -212,54 +194,18 @@ private slots: void test_quickfix_MoveFuncDefToDecl_CtorWithInitialization(); void test_quickfix_MoveFuncDefToDecl_structWithAssignedVariable(); - void test_quickfix_AssignToLocalVariable_freeFunction(); - void test_quickfix_AssignToLocalVariable_memberFunction(); - void test_quickfix_AssignToLocalVariable_staticMemberFunction(); - void test_quickfix_AssignToLocalVariable_newExpression(); void test_quickfix_AssignToLocalVariable_templates(); - void test_quickfix_AssignToLocalVariable_noInitializationList(); - void test_quickfix_AssignToLocalVariable_noVoidFunction(); - void test_quickfix_AssignToLocalVariable_noVoidMemberFunction(); - void test_quickfix_AssignToLocalVariable_noVoidStaticMemberFunction(); - void test_quickfix_AssignToLocalVariable_noFunctionInExpression(); - void test_quickfix_AssignToLocalVariable_noFunctionInFunction(); - void test_quickfix_AssignToLocalVariable_noReturnClass1(); - void test_quickfix_AssignToLocalVariable_noReturnClass2(); - void test_quickfix_AssignToLocalVariable_noReturnFunc1(); - void test_quickfix_AssignToLocalVariable_noReturnFunc2(); - void test_quickfix_AssignToLocalVariable_noSignatureMatch(); void test_quickfix_ExtractLiteralAsParameter_typeDeduction_data(); void test_quickfix_ExtractLiteralAsParameter_typeDeduction(); - void test_quickfix_ExtractLiteralAsParameter_freeFunction(); void test_quickfix_ExtractLiteralAsParameter_freeFunction_separateFiles(); - void test_quickfix_ExtractLiteralAsParameter_memberFunction(); void test_quickfix_ExtractLiteralAsParameter_memberFunction_separateFiles(); - void test_quickfix_ExtractLiteralAsParameter_memberFunctionInline(); - - void test_quickfix_InsertVirtualMethods_onlyDecl(); - void test_quickfix_InsertVirtualMethods_onlyDeclWithoutVirtual(); - void test_quickfix_InsertVirtualMethods_Access(); - void test_quickfix_InsertVirtualMethods_Superclass(); - void test_quickfix_InsertVirtualMethods_SuperclassOverride(); - void test_quickfix_InsertVirtualMethods_PureVirtualOnlyDecl(); - void test_quickfix_InsertVirtualMethods_PureVirtualInside(); - void test_quickfix_InsertVirtualMethods_inside(); - void test_quickfix_InsertVirtualMethods_outside(); + + void test_quickfix_InsertVirtualMethods_data(); + void test_quickfix_InsertVirtualMethods(); void test_quickfix_InsertVirtualMethods_implementationFile(); - void test_quickfix_InsertVirtualMethods_notrigger_allImplemented(); void test_quickfix_InsertVirtualMethods_BaseClassInNamespace(); - void test_quickfix_OptimizeForLoop_postcrement(); - void test_quickfix_OptimizeForLoop_condition(); - void test_quickfix_OptimizeForLoop_flipedCondition(); - void test_quickfix_OptimizeForLoop_alterVariableName(); - void test_quickfix_OptimizeForLoop_optimizeBoth(); - void test_quickfix_OptimizeForLoop_emptyInitializer(); - void test_quickfix_OptimizeForLoop_wrongInitializer(); - void test_quickfix_OptimizeForLoop_noTriggerNumeric1(); - void test_quickfix_OptimizeForLoop_noTriggerNumeric2(); - void test_functionhelper_virtualFunctions(); void test_functionhelper_virtualFunctions_data(); diff --git a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp index 208c21a5f4..6b566f9f41 100644 --- a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp +++ b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp @@ -119,7 +119,7 @@ bool VirtualFunctionHelper::canLookupVirtualFunctionOverrides(Function *function { m_function = function; if (!m_function || !m_baseExpressionAST || !m_expressionDocument || !m_document || !m_scope - || m_scope->isClass() || m_snapshot.isEmpty()) { + || m_scope->isClass() || m_scope->isFunction() || m_snapshot.isEmpty()) { return false; } @@ -128,11 +128,13 @@ bool VirtualFunctionHelper::canLookupVirtualFunctionOverrides(Function *function if (IdExpressionAST *idExpressionAST = m_baseExpressionAST->asIdExpression()) { NameAST *name = idExpressionAST->name; const bool nameIsQualified = name && name->asQualifiedName(); - result = !nameIsQualified && FunctionHelper::isVirtualFunction(function, m_snapshot); + result = !nameIsQualified && FunctionHelper::isVirtualFunction( + function, LookupContext(m_document, m_snapshot)); } else if (MemberAccessAST *memberAccessAST = m_baseExpressionAST->asMemberAccess()) { NameAST *name = memberAccessAST->member_name; const bool nameIsQualified = name && name->asQualifiedName(); - if (!nameIsQualified && FunctionHelper::isVirtualFunction(function, m_snapshot)) { + if (!nameIsQualified && FunctionHelper::isVirtualFunction( + function, LookupContext(m_document, m_snapshot))) { TranslationUnit *unit = m_expressionDocument->translationUnit(); QTC_ASSERT(unit, return false); m_accessTokenKind = unit->tokenKind(memberAccessAST->access_token); @@ -242,6 +244,24 @@ Link findMacroLink(const QByteArray &name, const Document::Ptr &doc) return Link(); } +/// Considers also forward declared templates. +static bool isForwardClassDeclaration(Type *type) +{ + if (!type) + return false; + + if (type->isForwardClassDeclarationType()) { + return true; + } else if (Template *templ = type->asTemplateType()) { + if (Symbol *declaration = templ->declaration()) { + if (declaration->isForwardClassDeclaration()) + return true; + } + } + + return false; +} + inline LookupItem skipForwardDeclarations(const QList<LookupItem> &resolvedSymbols) { QList<LookupItem> candidates = resolvedSymbols; @@ -249,11 +269,11 @@ inline LookupItem skipForwardDeclarations(const QList<LookupItem> &resolvedSymbo LookupItem result = candidates.first(); const FullySpecifiedType ty = result.type().simplified(); - if (ty->isForwardClassDeclarationType()) { + if (isForwardClassDeclaration(ty.type())) { while (!candidates.isEmpty()) { LookupItem r = candidates.takeFirst(); - if (!r.type()->isForwardClassDeclarationType()) { + if (!isForwardClassDeclaration(r.type().type())) { result = r; break; } @@ -676,8 +696,15 @@ BaseTextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor & if (def == lastVisibleSymbol) def = 0; // jump to declaration then. - if (symbol->isForwardClassDeclaration()) + if (symbol->isForwardClassDeclaration()) { def = symbolFinder->findMatchingClassDeclaration(symbol, snapshot); + } else if (Template *templ = symbol->asTemplate()) { + if (Symbol *declaration = templ->declaration()) { + if (declaration->isForwardClassDeclaration()) + def = symbolFinder->findMatchingClassDeclaration(declaration, snapshot); + } + } + } link = m_widget->linkToSymbol(def ? def : symbol); diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 55fad435e7..16e22817a5 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -60,6 +60,8 @@ using namespace TextEditor; namespace { +typedef QByteArray _; + class TestDocument; typedef QSharedPointer<TestDocument> TestDocumentPtr; @@ -349,10 +351,19 @@ private: } // anonymous namespace -/// Checks: All enum values are added as case statements for a blank switch. -void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_basic1() +typedef QSharedPointer<CppQuickFixFactory> CppQuickFixFactoryPtr; + +Q_DECLARE_METATYPE(CppQuickFixFactoryPtr) + +void CppEditorPlugin::test_quickfix_data() { - const QByteArray original = + QTest::addColumn<CppQuickFixFactoryPtr>("factory"); + QTest::addColumn<QByteArray>("original"); + QTest::addColumn<QByteArray>("expected"); + + // Checks: All enum values are added as case statements for a blank switch. + QTest::newRow("CompleteSwitchCaseStatement_basic1") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( "enum EnumType { V1, V2 };\n" "\n" "void f()\n" @@ -360,9 +371,8 @@ void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_basic1() " EnumType t;\n" " @switch (t) {\n" " }\n" - "}\n"; - ; - const QByteArray expected = + "}\n" + ) << _( "enum EnumType { V1, V2 };\n" "\n" "void f()\n" @@ -376,17 +386,11 @@ void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_basic1() " }\n" "}\n" "\n" - ; + ); - CompleteSwitchCaseStatement factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Checks: All enum values are added as case statements for a blank switch with a default case. -void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_basic2() -{ - const QByteArray original = + // Checks: All enum values are added as case statements for a blank switch with a default case. + QTest::newRow("CompleteSwitchCaseStatement_basic2") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( "enum EnumType { V1, V2 };\n" "\n" "void f()\n" @@ -396,9 +400,8 @@ void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_basic2() " default:\n" " break;\n" " }\n" - "}\n"; - ; - const QByteArray expected = + "}\n" + ) << _( "enum EnumType { V1, V2 };\n" "\n" "void f()\n" @@ -414,17 +417,11 @@ void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_basic2() " }\n" "}\n" "\n" - ; + ); - CompleteSwitchCaseStatement factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Checks: The missing enum value is added. -void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_oneValueMissing() -{ - const QByteArray original = + // Checks: The missing enum value is added. + QTest::newRow("CompleteSwitchCaseStatement_oneValueMissing") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( "enum EnumType { V1, V2 };\n" "\n" "void f()\n" @@ -436,9 +433,8 @@ void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_oneValueMissing( " default:\n" " break;\n" " }\n" - "}\n"; - ; - const QByteArray expected = + "}\n" + ) << _( "enum EnumType { V1, V2 };\n" "\n" "void f()\n" @@ -454,17 +450,11 @@ void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_oneValueMissing( " }\n" "}\n" "\n" - ; - - CompleteSwitchCaseStatement factory; - TestCase data(original, expected); - data.run(&factory); -} + ); -/// Checks: Find the correct enum type despite there being a declaration with the same name. -void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG10366_1() -{ - const QByteArray original = + // Checks: Find the correct enum type despite there being a declaration with the same name. + QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_1") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( "enum test { TEST_1, TEST_2 };\n" "\n" "void f() {\n" @@ -472,8 +462,7 @@ void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG1036 " @switch (test) {\n" " }\n" "}\n" - ; - const QByteArray expected = + ) << _( "enum test { TEST_1, TEST_2 };\n" "\n" "void f() {\n" @@ -486,17 +475,11 @@ void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG1036 " }\n" "}\n" "\n" - ; - - CompleteSwitchCaseStatement factory; - TestCase data(original, expected); - data.run(&factory); -} + ); -/// Checks: Find the correct enum type despite there being a declaration with the same name. -void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG10366_2() -{ - const QByteArray original = + // Checks: Find the correct enum type despite there being a declaration with the same name. + QTest::newRow("CompleteSwitchCaseStatement_QTCREATORBUG10366_2") + << CppQuickFixFactoryPtr(new CompleteSwitchCaseStatement) << _( "enum test1 { Wrong11, Wrong12 };\n" "enum test { Right1, Right2 };\n" "enum test2 { Wrong21, Wrong22 };\n" @@ -506,8 +489,7 @@ void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG1036 " @switch (test) {\n" " }\n" "}\n" - ; - const QByteArray expected = + ) << _( "enum test1 { Wrong11, Wrong12 };\n" "enum test { Right1, Right2 };\n" "enum test2 { Wrong21, Wrong22 };\n" @@ -522,27 +504,20 @@ void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG1036 " }\n" "}\n" "\n" - ; - - CompleteSwitchCaseStatement factory; - TestCase data(original, expected); - data.run(&factory); -} + ); -/// Checks: -/// 1. If the name does not start with ("m_" or "_") and does not -/// end with "_", we are forced to prefix the getter with "get". -/// 2. Setter: Use pass by value on integer/float and pointer types. -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefix() -{ - const QByteArray original = + // Checks: + // 1. If the name does not start with ("m_" or "_") and does not + // end with "_", we are forced to prefix the getter with "get". + // 2. Setter: Use pass by value on integer/float and pointer types. + QTest::newRow("GenerateGetterSetter_basicGetterWithPrefix") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) << _( "\n" "class Something\n" "{\n" " int @it;\n" "};\n" - ; - const QByteArray expected = + ) << _( "\n" "class Something\n" "{\n" @@ -563,26 +538,19 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefix() " it = value;\n" "}\n" "\n" - ; + ); - GenerateGetterSetter factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Checks: In addition to test_quickfix_GenerateGetterSetter_basicGetterWithPrefix -/// generated definitions should fit in the namespace. -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespace() -{ - const QByteArray original = + // Checks: In addition to test_quickfix_GenerateGetterSetter_basicGetterWithPrefix + // generated definitions should fit in the namespace. + QTest::newRow("GenerateGetterSetter_basicGetterWithPrefixAndNamespace") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) << _( "namespace SomeNamespace {\n" "class Something\n" "{\n" " int @it;\n" "};\n" - "}\n"; - - const QByteArray expected = + "}\n" + ) << _( "namespace SomeNamespace {\n" "class Something\n" "{\n" @@ -602,80 +570,20 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAn " it = value;\n" "}\n" "\n" - "}\n\n"; - - GenerateGetterSetter factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Checks: In addition to test_quickfix_GenerateGetterSetter_basicGetterWithPrefix -/// generated definitions should fit in the namespace. -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespaceToCpp() -{ - QList<TestDocumentPtr> testFiles; - QByteArray original; - QByteArray expected; - - // Header File - original = - "namespace SomeNamespace {\n" - "class Something\n" - "{\n" - " int @it;\n" - "};\n" - "}\n"; - expected = - "namespace SomeNamespace {\n" - "class Something\n" - "{\n" - " int it;\n" - "\n" - "public:\n" - " int getIt() const;\n" - " void setIt(int value);\n" - "};\n" - "}\n\n"; - testFiles << TestDocument::create(original, expected, QLatin1String("file.h")); - - // Source File - original = - "#include \"file.h\"\n" - "namespace SomeNamespace {\n" - "}\n"; - expected = - "#include \"file.h\"\n" - "namespace SomeNamespace {\n" - "int Something::getIt() const\n" - "{\n" - " return it;\n" - "}\n" - "\n" - "void Something::setIt(int value)\n" - "{\n" - " it = value;\n" "}\n\n" - "}\n\n"; - testFiles << TestDocument::create(original, expected, QLatin1String("file.cpp")); + ); - GenerateGetterSetter factory; - TestCase data(testFiles); - data.run(&factory); -} - -/// Checks: -/// 1. Getter: "get" prefix is not necessary. -/// 2. Setter: Parameter name is base name. -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithoutPrefix() -{ - const QByteArray original = + // Checks: + // 1. Getter: "get" prefix is not necessary. + // 2. Setter: Parameter name is base name. + QTest::newRow("GenerateGetterSetter_basicGetterWithoutPrefix") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) << _( "\n" "class Something\n" "{\n" " int @m_it;\n" "};\n" - ; - const QByteArray expected = + ) << _( "\n" "class Something\n" "{\n" @@ -696,25 +604,18 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithoutPrefi " m_it = it;\n" "}\n" "\n" - ; - - GenerateGetterSetter factory; - TestCase data(original, expected); - data.run(&factory); -} + ); -/// Check: Setter: Use pass by reference for parameters which -/// are not integer, float or pointers. -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_customType() -{ - const QByteArray original = + // Check: Setter: Use pass by reference for parameters which + // are not integer, float or pointers. + QTest::newRow("GenerateGetterSetter_customType") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) << _( "\n" "class Something\n" "{\n" " MyType @it;\n" "};\n" - ; - const QByteArray expected = + ) << _( "\n" "class Something\n" "{\n" @@ -735,26 +636,19 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_customType() " it = value;\n" "}\n" "\n" - ; + ); - GenerateGetterSetter factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Checks: -/// 1. Setter: No setter is generated for const members. -/// 2. Getter: Return a non-const type since it pass by value anyway. -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_constMember() -{ - const QByteArray original = + // Checks: + // 1. Setter: No setter is generated for const members. + // 2. Getter: Return a non-const type since it pass by value anyway. + QTest::newRow("GenerateGetterSetter_constMember") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) << _( "\n" "class Something\n" "{\n" " const int @it;\n" "};\n" - ; - const QByteArray expected = + ) << _( "\n" "class Something\n" "{\n" @@ -769,24 +663,17 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_constMember() " return it;\n" "}\n" "\n" - ; - - GenerateGetterSetter factory; - TestCase data(original, expected); - data.run(&factory); -} + ); -/// Checks: No special treatment for pointer to non const. -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_pointerToNonConst() -{ - const QByteArray original = + // Checks: No special treatment for pointer to non const. + QTest::newRow("GenerateGetterSetter_pointerToNonConst") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) << _( "\n" "class Something\n" "{\n" " int *it@;\n" "};\n" - ; - const QByteArray expected = + ) << _( "\n" "class Something\n" "{\n" @@ -807,24 +694,17 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_pointerToNonConst() " it = value;\n" "}\n" "\n" - ; - - GenerateGetterSetter factory; - TestCase data(original, expected); - data.run(&factory); -} + ); -/// Checks: No special treatment for pointer to const. -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_pointerToConst() -{ - const QByteArray original = + // Checks: No special treatment for pointer to const. + QTest::newRow("GenerateGetterSetter_pointerToConst") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) << _( "\n" "class Something\n" "{\n" " const int *it@;\n" "};\n" - ; - const QByteArray expected = + ) << _( "\n" "class Something\n" "{\n" @@ -845,26 +725,19 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_pointerToConst() " it = value;\n" "}\n" "\n" - ; - - GenerateGetterSetter factory; - TestCase data(original, expected); - data.run(&factory); -} + ); -/// Checks: -/// 1. Setter: Setter is a static function. -/// 2. Getter: Getter is a static, non const function. -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_staticMember() -{ - const QByteArray original = + // Checks: + // 1. Setter: Setter is a static function. + // 2. Getter: Getter is a static, non const function. + QTest::newRow("GenerateGetterSetter_staticMember") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) << _( "\n" "class Something\n" "{\n" " static int @m_member;\n" "};\n" - ; - const QByteArray expected = + ) << _( "\n" "class Something\n" "{\n" @@ -885,24 +758,17 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_staticMember() " m_member = member;\n" "}\n" "\n" - ; + ); - GenerateGetterSetter factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: Check if it works on the second declarator -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_secondDeclarator() -{ - const QByteArray original = + // Check: Check if it works on the second declarator + QTest::newRow("GenerateGetterSetter_secondDeclarator") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) << _( "\n" "class Something\n" "{\n" " int *foo, @it;\n" "};\n" - ; - const QByteArray expected = + ) << _( "\n" "class Something\n" "{\n" @@ -923,24 +789,17 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_secondDeclarator() " it = value;\n" "}\n" "\n" - ; - - GenerateGetterSetter factory; - TestCase data(original, expected); - data.run(&factory); -} + ); -/// Check: Quick fix is offered for "int *@it;" ('@' denotes the text cursor position) -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_triggeringRightAfterPointerSign() -{ - const QByteArray original = + // Check: Quick fix is offered for "int *@it;" ('@' denotes the text cursor position) + QTest::newRow("GenerateGetterSetter_triggeringRightAfterPointerSign") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) << _( "\n" "class Something\n" "{\n" " int *@it;\n" "};\n" - ; - const QByteArray expected = + ) << _( "\n" "class Something\n" "{\n" @@ -961,78 +820,498 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_triggeringRightAfterPoi " it = value;\n" "}\n" "\n" - ; + ); - GenerateGetterSetter factory; - TestCase data(original, expected); - data.run(&factory); -} + // Check: Quick fix is not triggered on a member function. + QTest::newRow("GenerateGetterSetter_notTriggeringOnMemberFunction") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) + << _("class Something { void @f(); };") << _(); -/// Check: Quick fix is not triggered on a member function. -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_notTriggeringOnMemberFunction() -{ - const QByteArray original = "class Something { void @f(); };"; + // Check: Quick fix is not triggered on an member array; + QTest::newRow("GenerateGetterSetter_notTriggeringOnMemberArray") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) + << _("class Something { void @a[10]; };") << _(); - GenerateGetterSetter factory; - TestCase data(original, original + "\n"); - data.run(&factory); -} - -/// Check: Quick fix is not triggered on an member array; -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_notTriggeringOnMemberArray() -{ - const QByteArray original = "class Something { void @a[10]; };"; - - GenerateGetterSetter factory; - TestCase data(original, original + "\n"); - data.run(&factory); -} - -/// Check: Do not offer the quick fix if there is already a member with the -/// getter or setter name we would generate. -void CppEditorPlugin::test_quickfix_GenerateGetterSetter_notTriggeringWhenGetterOrSetterExist() -{ - const QByteArray original = + // Check: Do not offer the quick fix if there is already a member with the + // getter or setter name we would generate. + QTest::newRow("GenerateGetterSetter_notTriggeringWhenGetterOrSetterExist") + << CppQuickFixFactoryPtr(new GenerateGetterSetter) << _( "class Something {\n" " int @it;\n" " void setIt();\n" - "};\n"; + "};\n" + ) << _(); - GenerateGetterSetter factory; - TestCase data(original, original + "\n"); - data.run(&factory); -} + QTest::newRow("MoveDeclarationOutOfIf_ifOnly") + << CppQuickFixFactoryPtr(new MoveDeclarationOutOfIf) << _( + "void f()\n" + "{\n" + " if (Foo *@foo = g())\n" + " h();\n" + "}\n" + ) << _( + "void f()\n" + "{\n" + " Foo *foo = g();\n" + " if (foo)\n" + " h();\n" + "}\n" + "\n" + ); -/// Check: Just a basic test since the main functionality is tested in -/// cpppointerdeclarationformatter_test.cpp -void CppEditorPlugin::test_quickfix_ReformatPointerDeclaration() -{ - const QByteArray original = "char@*s;"; - const QByteArray expected = "char *s;\n"; + QTest::newRow("MoveDeclarationOutOfIf_ifElse") + << CppQuickFixFactoryPtr(new MoveDeclarationOutOfIf) << _( + "void f()\n" + "{\n" + " if (Foo *@foo = g())\n" + " h();\n" + " else\n" + " i();\n" + "}\n" + ) << _( + "void f()\n" + "{\n" + " Foo *foo = g();\n" + " if (foo)\n" + " h();\n" + " else\n" + " i();\n" + "}\n" + "\n" + ); - ReformatPointerDeclaration factory; - TestCase data(original, expected); - data.run(&factory); -} + QTest::newRow("MoveDeclarationOutOfIf_ifElseIf") + << CppQuickFixFactoryPtr(new MoveDeclarationOutOfIf) << _( + "void f()\n" + "{\n" + " if (Foo *foo = g()) {\n" + " if (Bar *@bar = x()) {\n" + " h();\n" + " j();\n" + " }\n" + " } else {\n" + " i();\n" + " }\n" + "}\n" + ) << _( + "void f()\n" + "{\n" + " if (Foo *foo = g()) {\n" + " Bar *bar = x();\n" + " if (bar) {\n" + " h();\n" + " j();\n" + " }\n" + " } else {\n" + " i();\n" + " }\n" + "}\n" + "\n" + ); -/// Check from source file: If there is no header file, insert the definition after the class. -void CppEditorPlugin::test_quickfix_InsertDefFromDecl_basic() -{ - const QByteArray original = + QTest::newRow("MoveDeclarationOutOfWhile_singleWhile") + << CppQuickFixFactoryPtr(new MoveDeclarationOutOfWhile) << _( + "void f()\n" + "{\n" + " while (Foo *@foo = g())\n" + " j();\n" + "}\n" + ) << _( + "void f()\n" + "{\n" + " Foo *foo;\n" + " while ((foo = g()) != 0)\n" + " j();\n" + "}\n" + "\n" + ); + + QTest::newRow("MoveDeclarationOutOfWhile_whileInWhile") + << CppQuickFixFactoryPtr(new MoveDeclarationOutOfWhile) << _( + "void f()\n" + "{\n" + " while (Foo *foo = g()) {\n" + " while (Bar *@bar = h()) {\n" + " i();\n" + " j();\n" + " }\n" + " }\n" + "}\n" + ) << _( + "void f()\n" + "{\n" + " while (Foo *foo = g()) {\n" + " Bar *bar;\n" + " while ((bar = h()) != 0) {\n" + " i();\n" + " j();\n" + " }\n" + " }\n" + "}\n" + "\n" + ); + + // Check: Just a basic test since the main functionality is tested in + // cpppointerdeclarationformatter_test.cpp + QTest::newRow("ReformatPointerDeclaration") + << CppQuickFixFactoryPtr(new ReformatPointerDeclaration) + << _("char@*s;") + << _("char *s;\n"); + + // Check from source file: If there is no header file, insert the definition after the class. + QByteArray original = "struct Foo\n" "{\n" " Foo();@\n" "};\n"; - const QByteArray expected = original + + + QTest::newRow("InsertDefFromDecl_basic") + << CppQuickFixFactoryPtr(new InsertDefFromDecl) << original + << original + _( "\n" "\n" "Foo::Foo()\n" "{\n\n" "}\n" - "\n"; + "\n" + ); - InsertDefFromDecl factory; - TestCase data(original, expected); + QTest::newRow("InsertDefFromDecl_freeFunction") + << CppQuickFixFactoryPtr(new InsertDefFromDecl) + << _("void free()@;\n") + << _( + "void free()\n" + "{\n\n" + "}\n" + "\n" + ); + + // Check not triggering when it is a statement + QTest::newRow("InsertDefFromDecl_notTriggeringStatement") + << CppQuickFixFactoryPtr(new InsertDefFromDecl) << _( + "class Foo {\n" + "public:\n" + " Foo() {}\n" + "};\n" + "void freeFunc() {\n" + " Foo @f();" + "}\n" + ) << _(); + + // Check: Add local variable for a free function. + QTest::newRow("AssignToLocalVariable_freeFunction") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "int foo() {return 1;}\n" + "void bar() {fo@o();}" + ) << _( + "int foo() {return 1;}\n" + "void bar() {int localFoo = foo();}\n" + ); + + // Check: Add local variable for a member function. + QTest::newRow("AssignToLocalVariable_memberFunction") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "class Foo {public: int* fooFunc();}\n" + "void bar() {\n" + " Foo *f = new Foo;\n" + " @f->fooFunc();\n" + "}" + ) << _( + "class Foo {public: int* fooFunc();}\n" + "void bar() {\n" + " Foo *f = new Foo;\n" + " int *localFooFunc = f->fooFunc();\n" + "}\n" + ); + + // Check: Add local variable for a static member function. + QTest::newRow("AssignToLocalVariable_staticMemberFunction") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "class Foo {public: static int* fooFunc();}\n" + "void bar() {\n" + " Foo::fooF@unc();\n" + "}" + ) << _( + "class Foo {public: static int* fooFunc();}\n" + "void bar() {\n" + " int *localFooFunc = Foo::fooFunc();\n" + "}\n" + ); + + // Check: Add local variable for a new Expression. + QTest::newRow("AssignToLocalVariable_newExpression") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "class Foo {}\n" + "void bar() {\n" + " new Fo@o;\n" + "}" + ) << _( + "class Foo {}\n" + "void bar() {\n" + " Foo *localFoo = new Foo;\n" + "}\n" + ); + + // Check: No trigger for function inside member initialization list. + QTest::newRow("AssignToLocalVariable_noInitializationList") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "class Foo\n" + "{\n" + " public: Foo : m_i(fooF@unc()) {}\n" + " int fooFunc() {return 2;}\n" + " int m_i;\n" + "};" + ) << _(); + + // Check: No trigger for void functions. + QTest::newRow("AssignToLocalVariable_noVoidFunction") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "void foo() {}\n" + "void bar() {fo@o();}" + ) << _(); + + // Check: No trigger for void member functions. + QTest::newRow("AssignToLocalVariable_noVoidMemberFunction") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "class Foo {public: void fooFunc();}\n" + "void bar() {\n" + " Foo *f = new Foo;\n" + " @f->fooFunc();\n" + "}" + ) << _(); + + // Check: No trigger for void static member functions. + QTest::newRow("AssignToLocalVariable_noVoidStaticMemberFunction") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "class Foo {public: static void fooFunc();}\n" + "void bar() {\n" + " Foo::fo@oFunc();\n" + "}" + ) << _(); + + // Check: No trigger for functions in expressions. + QTest::newRow("AssignToLocalVariable_noFunctionInExpression") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "int foo(int a) {return a;}\n" + "int bar() {return 1;}" + "void baz() {foo(@bar() + bar());}" + ) << _(); + + // Check: No trigger for functions in functions. (QTCREATORBUG-9510) + QTest::newRow("AssignToLocalVariable_noFunctionInFunction") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "int foo(int a, int b) {return a + b;}\n" + "int bar(int a) {return a;}\n" + "void baz() {\n" + " int a = foo(ba@r(), bar());\n" + "}\n" + ) << _(); + + // Check: No trigger for functions in return statements (classes). + QTest::newRow("AssignToLocalVariable_noReturnClass1") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "class Foo {public: static void fooFunc();}\n" + "Foo* bar() {\n" + " return new Fo@o;\n" + "}" + ) << _(); + + // Check: No trigger for functions in return statements (classes). (QTCREATORBUG-9525) + QTest::newRow("AssignToLocalVariable_noReturnClass2") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "class Foo {public: int fooFunc();}\n" + "int bar() {\n" + " return (new Fo@o)->fooFunc();\n" + "}" + ) << _(); + + // Check: No trigger for functions in return statements (functions). + QTest::newRow("AssignToLocalVariable_noReturnFunc1") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "class Foo {public: int fooFunc();}\n" + "int bar() {\n" + " return Foo::fooFu@nc();\n" + "}" + ) << _(); + + // Check: No trigger for functions in return statements (functions). (QTCREATORBUG-9525) + QTest::newRow("AssignToLocalVariable_noReturnFunc2") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "int bar() {\n" + " return list.firs@t().foo;\n" + "}\n" + ) << _(); + + // Check: No trigger for functions which does not match in signature. + QTest::newRow("AssignToLocalVariable_noSignatureMatch") + << CppQuickFixFactoryPtr(new AssignToLocalVariable) << _( + "int someFunc(int);\n" + "\n" + "void f()\n" + "{\n" + " some@Func();\n" + "}" + ) << _(); + + QTest::newRow("ExtractLiteralAsParameter_freeFunction") + << CppQuickFixFactoryPtr(new ExtractLiteralAsParameter) << _( + "void foo(const char *a, long b = 1)\n" + "{return 1@56 + 123 + 156;}" + ) << _( + "void foo(const char *a, long b = 1, int newParameter = 156)\n" + "{return newParameter + 123 + newParameter;}\n" + ); + + QTest::newRow("ExtractLiteralAsParameter_memberFunction") + << CppQuickFixFactoryPtr(new ExtractLiteralAsParameter) << _( + "class Narf {\n" + "public:\n" + " int zort();\n" + "};\n\n" + "int Narf::zort()\n" + "{ return 15@5 + 1; }" + ) << _( + "class Narf {\n" + "public:\n" + " int zort(int newParameter = 155);\n" + "};\n\n" + "int Narf::zort(int newParameter)\n" + "{ return newParameter + 1; }\n" + ); + + QTest::newRow("ExtractLiteralAsParameter_memberFunctionInline") + << CppQuickFixFactoryPtr(new ExtractLiteralAsParameter) << _( + "class Narf {\n" + "public:\n" + " int zort()\n" + " { return 15@5 + 1; }\n" + "};" + ) << _( + "class Narf {\n" + "public:\n" + " int zort(int newParameter = 155)\n" + " { return newParameter + 1; }\n" + "};\n" + ); + + // Check: optimize postcrement + QTest::newRow("OptimizeForLoop_postcrement") + << CppQuickFixFactoryPtr(new OptimizeForLoop) + << _("void foo() {f@or (int i = 0; i < 3; i++) {}}\n") + << _("void foo() {for (int i = 0; i < 3; ++i) {}}\n\n"); + + // Check: optimize condition + QTest::newRow("OptimizeForLoop_condition") + << CppQuickFixFactoryPtr(new OptimizeForLoop) + << _("void foo() {f@or (int i = 0; i < 3 + 5; ++i) {}}\n") + << _("void foo() {for (int i = 0, total = 3 + 5; i < total; ++i) {}}\n\n"); + + // Check: optimize fliped condition + QTest::newRow("OptimizeForLoop_flipedCondition") + << CppQuickFixFactoryPtr(new OptimizeForLoop) + << _("void foo() {f@or (int i = 0; 3 + 5 > i; ++i) {}}\n") + << _("void foo() {for (int i = 0, total = 3 + 5; total > i; ++i) {}}\n\n"); + + // Check: if "total" used, create other name. + QTest::newRow("OptimizeForLoop_alterVariableName") + << CppQuickFixFactoryPtr(new OptimizeForLoop) + << _("void foo() {f@or (int i = 0, total = 0; i < 3 + 5; ++i) {}}\n") + << _("void foo() {for (int i = 0, total = 0, totalX = 3 + 5; i < totalX; ++i) {}}\n\n"); + + // Check: optimize postcrement and condition + QTest::newRow("OptimizeForLoop_optimizeBoth") + << CppQuickFixFactoryPtr(new OptimizeForLoop) + << _("void foo() {f@or (int i = 0; i < 3 + 5; i++) {}}\n") + << _("void foo() {for (int i = 0, total = 3 + 5; i < total; ++i) {}}\n\n"); + + // Check: empty initializier + QTest::newRow("OptimizeForLoop_emptyInitializer") + << CppQuickFixFactoryPtr(new OptimizeForLoop) + << _("int i; void foo() {f@or (; i < 3 + 5; ++i) {}}\n") + << _("int i; void foo() {for (int total = 3 + 5; i < total; ++i) {}}\n\n"); + + // Check: wrong initializier type -> no trigger + QTest::newRow("OptimizeForLoop_wrongInitializer") + << CppQuickFixFactoryPtr(new OptimizeForLoop) + << _("int i; void foo() {f@or (double a = 0; i < 3 + 5; ++i) {}}\n") + << _("int i; void foo() {f@or (double a = 0; i < 3 + 5; ++i) {}}\n\n"); + + // Check: No trigger when numeric + QTest::newRow("OptimizeForLoop_noTriggerNumeric1") + << CppQuickFixFactoryPtr(new OptimizeForLoop) + << _("void foo() {fo@r (int i = 0; i < 3; ++i) {}}\n") + << _(); + + // Check: No trigger when numeric + QTest::newRow("OptimizeForLoop_noTriggerNumeric2") + << CppQuickFixFactoryPtr(new OptimizeForLoop) + << _("void foo() {fo@r (int i = 0; i < -3; ++i) {}}\n") + << _(); +} + +void CppEditorPlugin::test_quickfix() +{ + QFETCH(CppQuickFixFactoryPtr, factory); + QFETCH(QByteArray, original); + QFETCH(QByteArray, expected); + + if (expected.isEmpty()) + expected = original + '\n'; + TestCase data(original, expected); + data.run(factory.data()); +} + +/// Checks: In addition to test_quickfix_GenerateGetterSetter_basicGetterWithPrefix +/// generated definitions should fit in the namespace. +void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespaceToCpp() +{ + QList<TestDocumentPtr> testFiles; + QByteArray original; + QByteArray expected; + + // Header File + original = + "namespace SomeNamespace {\n" + "class Something\n" + "{\n" + " int @it;\n" + "};\n" + "}\n"; + expected = + "namespace SomeNamespace {\n" + "class Something\n" + "{\n" + " int it;\n" + "\n" + "public:\n" + " int getIt() const;\n" + " void setIt(int value);\n" + "};\n" + "}\n\n"; + testFiles << TestDocument::create(original, expected, QLatin1String("file.h")); + + // Source File + original = + "#include \"file.h\"\n" + "namespace SomeNamespace {\n" + "}\n"; + expected = + "#include \"file.h\"\n" + "namespace SomeNamespace {\n" + "int Something::getIt() const\n" + "{\n" + " return it;\n" + "}\n" + "\n" + "void Something::setIt(int value)\n" + "{\n" + " it = value;\n" + "}\n\n" + "}\n\n"; + testFiles << TestDocument::create(original, expected, QLatin1String("file.cpp")); + + GenerateGetterSetter factory; + TestCase data(testFiles); data.run(&factory); } @@ -1261,21 +1540,6 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace2() data.run(&factory); } -void CppEditorPlugin::test_quickfix_InsertDefFromDecl_freeFunction() -{ - const QByteArray original = "void free()@;\n"; - const QByteArray expected = - "void free()\n" - "{\n\n" - "}\n" - "\n" - ; - - InsertDefFromDecl factory; - TestCase data(original, expected); - data.run(&factory); -} - /// Check definition insert inside class void CppEditorPlugin::test_quickfix_InsertDefFromDecl_insideClass() { @@ -1310,24 +1574,6 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_notTriggeringWhenDefinitio data.run(&factory, 1); } -/// Check not triggering when it is a statement -void CppEditorPlugin::test_quickfix_InsertDefFromDecl_notTriggeringStatement() -{ - const QByteArray original = - "class Foo {\n" - "public:\n" - " Foo() {}\n" - "};\n" - "void freeFunc() {\n" - " Foo @f();" - "}\n"; - const QByteArray expected = original + "\n"; - - InsertDefFromDecl factory; - TestCase data(original, expected); - data.run(&factory); -} - /// Find right implementation file. void CppEditorPlugin::test_quickfix_InsertDefFromDecl_findRightImplementationFile() { @@ -3253,80 +3499,6 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_structWithAssignedVariable data.run(&factory); } -/// Check: Add local variable for a free function. -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_freeFunction() -{ - const QByteArray original = - "int foo() {return 1;}\n" - "void bar() {fo@o();}"; - const QByteArray expected = - "int foo() {return 1;}\n" - "void bar() {int localFoo = foo();}\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: Add local variable for a member function. -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_memberFunction() -{ - const QByteArray original = - "class Foo {public: int* fooFunc();}\n" - "void bar() {\n" - " Foo *f = new Foo;\n" - " @f->fooFunc();\n" - "}"; - const QByteArray expected = - "class Foo {public: int* fooFunc();}\n" - "void bar() {\n" - " Foo *f = new Foo;\n" - " int *localFooFunc = f->fooFunc();\n" - "}\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: Add local variable for a static member function. -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_staticMemberFunction() -{ - const QByteArray original = - "class Foo {public: static int* fooFunc();}\n" - "void bar() {\n" - " Foo::fooF@unc();\n" - "}"; - const QByteArray expected = - "class Foo {public: static int* fooFunc();}\n" - "void bar() {\n" - " int *localFooFunc = Foo::fooFunc();\n" - "}\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: Add local variable for a new Expression. -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_newExpression() -{ - const QByteArray original = - "class Foo {}\n" - "void bar() {\n" - " new Fo@o;\n" - "}"; - const QByteArray expected = - "class Foo {}\n" - "void bar() {\n" - " Foo *localFoo = new Foo;\n" - "}\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - void CppEditorPlugin::test_quickfix_AssignToLocalVariable_templates() { @@ -3365,173 +3537,6 @@ void CppEditorPlugin::test_quickfix_AssignToLocalVariable_templates() data.run(&factory); } -/// Check: No trigger for function inside member initialization list. -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noInitializationList() -{ - const QByteArray original = - "class Foo\n" - "{\n" - " public: Foo : m_i(fooF@unc()) {}\n" - " int fooFunc() {return 2;}\n" - " int m_i;\n" - "};"; - const QByteArray expected = original + "\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger for void functions. -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noVoidFunction() -{ - const QByteArray original = - "void foo() {}\n" - "void bar() {fo@o();}"; - const QByteArray expected = original + "\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger for void member functions. -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noVoidMemberFunction() -{ - const QByteArray original = - "class Foo {public: void fooFunc();}\n" - "void bar() {\n" - " Foo *f = new Foo;\n" - " @f->fooFunc();\n" - "}"; - const QByteArray expected = original + "\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger for void static member functions. -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noVoidStaticMemberFunction() -{ - const QByteArray original = - "class Foo {public: static void fooFunc();}\n" - "void bar() {\n" - " Foo::fo@oFunc();\n" - "}"; - const QByteArray expected = original + "\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger for functions in expressions. -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noFunctionInExpression() -{ - const QByteArray original = - "int foo(int a) {return a;}\n" - "int bar() {return 1;}" - "void baz() {foo(@bar() + bar());}"; - const QByteArray expected = original + "\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger for functions in functions. (QTCREATORBUG-9510) -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noFunctionInFunction() -{ - const QByteArray original = - "int foo(int a, int b) {return a + b;}\n" - "int bar(int a) {return a;}\n" - "void baz() {\n" - " int a = foo(ba@r(), bar());\n" - "}\n"; - const QByteArray expected = original + "\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger for functions in return statements (classes). -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noReturnClass1() -{ - const QByteArray original = - "class Foo {public: static void fooFunc();}\n" - "Foo* bar() {\n" - " return new Fo@o;\n" - "}"; - const QByteArray expected = original + "\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger for functions in return statements (classes). (QTCREATORBUG-9525) -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noReturnClass2() -{ - const QByteArray original = - "class Foo {public: int fooFunc();}\n" - "int bar() {\n" - " return (new Fo@o)->fooFunc();\n" - "}"; - const QByteArray expected = original + "\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger for functions in return statements (functions). -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noReturnFunc1() -{ - const QByteArray original = - "class Foo {public: int fooFunc();}\n" - "int bar() {\n" - " return Foo::fooFu@nc();\n" - "}"; - const QByteArray expected = original + "\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger for functions in return statements (functions). (QTCREATORBUG-9525) -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noReturnFunc2() -{ - const QByteArray original = - "int bar() {\n" - " return list.firs@t().foo;\n" - "}\n"; - const QByteArray expected = original + "\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger for functions which does not match in signature. -void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noSignatureMatch() -{ - const QByteArray original = - "int someFunc(int);\n" - "\n" - "void f()\n" - "{\n" - " some@Func();\n" - "}"; - const QByteArray expected = original + "\n"; - - AssignToLocalVariable factory; - TestCase data(original, expected); - data.run(&factory); -} - void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_typeDeduction_data() { QTest::addColumn<QByteArray>("typeString"); @@ -3597,20 +3602,6 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_typeDeduction() data.run(&factory); } -void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_freeFunction() -{ - const QByteArray original = - "void foo(const char *a, long b = 1)\n" - "{return 1@56 + 123 + 156;}"; - const QByteArray expected = - "void foo(const char *a, long b = 1, int newParameter = 156)\n" - "{return newParameter + 123 + newParameter;}\n"; - - ExtractLiteralAsParameter factory; - TestCase data(original, expected); - data.run(&factory); -} - void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_freeFunction_separateFiles() { QList<TestDocumentPtr> testFiles; @@ -3638,28 +3629,6 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_freeFunction_separ data.run(&factory); } -void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_memberFunction() -{ - const QByteArray original = - "class Narf {\n" - "public:\n" - " int zort();\n" - "};\n\n" - "int Narf::zort()\n" - "{ return 15@5 + 1; }"; - const QByteArray expected = - "class Narf {\n" - "public:\n" - " int zort(int newParameter = 155);\n" - "};\n\n" - "int Narf::zort(int newParameter)\n" - "{ return newParameter + 1; }\n"; - - ExtractLiteralAsParameter factory; - TestCase data(original, expected); - data.run(&factory); -} - void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_memberFunction_separateFiles() { QList<TestDocumentPtr> testFiles; @@ -3695,37 +3664,25 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_memberFunction_sep data.run(&factory); } -void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_memberFunctionInline() -{ - const QByteArray original = - "class Narf {\n" - "public:\n" - " int zort()\n" - " { return 15@5 + 1; }\n" - "};"; - const QByteArray expected = - "class Narf {\n" - "public:\n" - " int zort(int newParameter = 155)\n" - " { return newParameter + 1; }\n" - "};\n"; - - ExtractLiteralAsParameter factory; - TestCase data(original, expected); - data.run(&factory); -} +Q_DECLARE_METATYPE(InsertVirtualMethodsDialog::ImplementationMode) -/// Check: Insert only declarations -void CppEditorPlugin::test_quickfix_InsertVirtualMethods_onlyDecl() +void CppEditorPlugin::test_quickfix_InsertVirtualMethods_data() { - const QByteArray original = + QTest::addColumn<InsertVirtualMethodsDialog::ImplementationMode>("implementationMode"); + QTest::addColumn<bool>("insertVirtualKeyword"); + QTest::addColumn<QByteArray>("original"); + QTest::addColumn<QByteArray>("expected"); + + // Check: Insert only declarations + QTest::newRow("onlyDecl") + << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA();\n" "};\n\n" "class Derived : public Bas@eA {\n" - "};"; - const QByteArray expected = + "};" + ) << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA();\n" @@ -3735,25 +3692,19 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_onlyDecl() " // BaseA interface\n" "public:\n" " virtual int virtualFuncA();\n" - "};\n"; - - InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest( - InsertVirtualMethodsDialog::ModeOnlyDeclarations, true)); - TestCase data(original, expected); - data.run(&factory); -} + "};\n" + ); -/// Check: Insert only declarations vithout virtual keyword -void CppEditorPlugin::test_quickfix_InsertVirtualMethods_onlyDeclWithoutVirtual() -{ - const QByteArray original = + // Check: Insert only declarations vithout virtual keyword + QTest::newRow("onlyDeclWithoutVirtual") + << InsertVirtualMethodsDialog::ModeOnlyDeclarations << false << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA();\n" "};\n\n" "class Derived : public Bas@eA {\n" - "};"; - const QByteArray expected = + "};" + ) << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA();\n" @@ -3763,18 +3714,12 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_onlyDeclWithoutVirtual( " // BaseA interface\n" "public:\n" " int virtualFuncA();\n" - "};\n"; - - InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest( - InsertVirtualMethodsDialog::ModeOnlyDeclarations, false)); - TestCase data(original, expected); - data.run(&factory); -} + "};\n" + ); -/// Check: Are access specifiers considered -void CppEditorPlugin::test_quickfix_InsertVirtualMethods_Access() -{ - const QByteArray original = + // Check: Are access specifiers considered + QTest::newRow("Access") + << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _( "class BaseA {\n" "public:\n" " virtual int a();\n" @@ -3792,8 +3737,8 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_Access() " virtual int g();\n" "};\n\n" "class Der@ived : public BaseA {\n" - "};"; - const QByteArray expected = + "};" + ) << _( "class BaseA {\n" "public:\n" " virtual int a();\n" @@ -3827,18 +3772,12 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_Access() " virtual int f();\n\n" "signals:\n" " virtual int g();\n" - "};\n"; - - InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest( - InsertVirtualMethodsDialog::ModeOnlyDeclarations, true)); - TestCase data(original, expected); - data.run(&factory); -} + "};\n" + ); -/// Check: Is a base class of a base class considered. -void CppEditorPlugin::test_quickfix_InsertVirtualMethods_Superclass() -{ - const QByteArray original = + // Check: Is a base class of a base class considered. + QTest::newRow("Superclass") + << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _( "class BaseA {\n" "public:\n" " virtual int a();\n" @@ -3848,8 +3787,8 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_Superclass() " virtual int b();\n" "};\n\n" "class Der@ived : public BaseB {\n" - "};"; - const QByteArray expected = + "};" + ) << _( "class BaseA {\n" "public:\n" " virtual int a();\n" @@ -3867,18 +3806,12 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_Superclass() " // BaseA interface\n" "public:\n" " virtual int a();\n" - "};\n"; - - InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest( - InsertVirtualMethodsDialog::ModeOnlyDeclarations, true)); - TestCase data(original, expected); - data.run(&factory); -} + "};\n" + ); -/// Check: Do not insert reimplemented functions twice. -void CppEditorPlugin::test_quickfix_InsertVirtualMethods_SuperclassOverride() -{ - const QByteArray original = + // Check: Do not insert reimplemented functions twice. + QTest::newRow("SuperclassOverride") + << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _( "class BaseA {\n" "public:\n" " virtual int a();\n" @@ -3888,8 +3821,8 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_SuperclassOverride() " virtual int a();\n" "};\n\n" "class Der@ived : public BaseB {\n" - "};"; - const QByteArray expected = + "};" + ) << _( "class BaseA {\n" "public:\n" " virtual int a();\n" @@ -3903,25 +3836,19 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_SuperclassOverride() " // BaseA interface\n" "public:\n" " virtual int a();\n" - "};\n"; - - InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest( - InsertVirtualMethodsDialog::ModeOnlyDeclarations, true)); - TestCase data(original, expected); - data.run(&factory); -} + "};\n" + ); -/// Check: Insert only declarations for pure virtual function -void CppEditorPlugin::test_quickfix_InsertVirtualMethods_PureVirtualOnlyDecl() -{ - const QByteArray original = + // Check: Insert only declarations for pure virtual function + QTest::newRow("PureVirtualOnlyDecl") + << InsertVirtualMethodsDialog::ModeOnlyDeclarations << true << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA() = 0;\n" "};\n\n" "class Derived : public Bas@eA {\n" - "};"; - const QByteArray expected = + "};" + ) << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA() = 0;\n" @@ -3931,25 +3858,19 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_PureVirtualOnlyDecl() " // BaseA interface\n" "public:\n" " virtual int virtualFuncA();\n" - "};\n"; - - InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest( - InsertVirtualMethodsDialog::ModeOnlyDeclarations, true)); - TestCase data(original, expected); - data.run(&factory); -} + "};\n" + ); -/// Check: Insert pure virtual functions inside class -void CppEditorPlugin::test_quickfix_InsertVirtualMethods_PureVirtualInside() -{ - const QByteArray original = + // Check: Insert pure virtual functions inside class + QTest::newRow("PureVirtualInside") + << InsertVirtualMethodsDialog::ModeInsideClass << true << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA() = 0;\n" "};\n\n" "class Derived : public Bas@eA {\n" - "};"; - const QByteArray expected = + "};" + ) << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA() = 0;\n" @@ -3961,25 +3882,19 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_PureVirtualInside() " virtual int virtualFuncA()\n" " {\n" " }\n" - "};\n"; - - InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest( - InsertVirtualMethodsDialog::ModeInsideClass, true)); - TestCase data(original, expected); - data.run(&factory); -} + "};\n" + ); -/// Check: Insert inside class -void CppEditorPlugin::test_quickfix_InsertVirtualMethods_inside() -{ - const QByteArray original = + // Check: Insert inside class + QTest::newRow("inside") + << InsertVirtualMethodsDialog::ModeInsideClass << true << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA();\n" "};\n\n" "class Derived : public Bas@eA {\n" - "};"; - const QByteArray expected = + "};" + ) << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA();\n" @@ -3991,25 +3906,19 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_inside() " virtual int virtualFuncA()\n" " {\n" " }\n" - "};\n"; - - InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest( - InsertVirtualMethodsDialog::ModeInsideClass, true)); - TestCase data(original, expected); - data.run(&factory); -} + "};\n" + ); -/// Check: Insert outside class -void CppEditorPlugin::test_quickfix_InsertVirtualMethods_outside() -{ - const QByteArray original = + // Check: Insert outside class + QTest::newRow("outside") + << InsertVirtualMethodsDialog::ModeOutsideClass << true << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA();\n" "};\n\n" "class Derived : public Bas@eA {\n" - "};"; - const QByteArray expected = + "};" + ) << _( "class BaseA {\n" "public:\n" " virtual int virtualFuncA();\n" @@ -4022,10 +3931,41 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_outside() "};\n\n" "int Derived::virtualFuncA()\n" "{\n" - "}\n"; + "}\n" + ); - InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest( - InsertVirtualMethodsDialog::ModeOutsideClass, true)); + // Check: No trigger: all implemented + QTest::newRow("notrigger_allImplemented") + << InsertVirtualMethodsDialog::ModeOutsideClass << true << _( + "class BaseA {\n" + "public:\n" + " virtual int virtualFuncA();\n" + "};\n\n" + "class Derived : public Bas@eA {\n" + "public:\n" + " virtual int virtualFuncA();\n" + "};" + ) << _( + "class BaseA {\n" + "public:\n" + " virtual int virtualFuncA();\n" + "};\n\n" + "class Derived : public Bas@eA {\n" + "public:\n" + " virtual int virtualFuncA();\n" + "};\n" + ); +} + +void CppEditorPlugin::test_quickfix_InsertVirtualMethods() +{ + QFETCH(InsertVirtualMethodsDialog::ImplementationMode, implementationMode); + QFETCH(bool, insertVirtualKeyword); + QFETCH(QByteArray, original); + QFETCH(QByteArray, expected); + + InsertVirtualMethods factory( + new InsertVirtualMethodsDialogTest(implementationMode, insertVirtualKeyword)); TestCase data(original, expected); data.run(&factory); } @@ -4077,34 +4017,6 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_implementationFile() data.run(&factory); } -/// Check: No trigger: all implemented -void CppEditorPlugin::test_quickfix_InsertVirtualMethods_notrigger_allImplemented() -{ - const QByteArray original = - "class BaseA {\n" - "public:\n" - " virtual int virtualFuncA();\n" - "};\n\n" - "class Derived : public Bas@eA {\n" - "public:\n" - " virtual int virtualFuncA();\n" - "};"; - const QByteArray expected = - "class BaseA {\n" - "public:\n" - " virtual int virtualFuncA();\n" - "};\n\n" - "class Derived : public Bas@eA {\n" - "public:\n" - " virtual int virtualFuncA();\n" - "};\n"; - - InsertVirtualMethods factory(new InsertVirtualMethodsDialogTest( - InsertVirtualMethodsDialog::ModeOutsideClass, true)); - TestCase data(original, expected); - data.run(&factory); -} - /// Check: Qualified names. void CppEditorPlugin::test_quickfix_InsertVirtualMethods_BaseClassInNamespace() { @@ -4157,93 +4069,3 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_BaseClassInNamespace() TestCase data(testFiles); data.run(&factory); } - -/// Check: optimize postcrement -void CppEditorPlugin::test_quickfix_OptimizeForLoop_postcrement() -{ - const QByteArray original = "void foo() {f@or (int i = 0; i < 3; i++) {}}\n"; - const QByteArray expected = "void foo() {for (int i = 0; i < 3; ++i) {}}\n\n"; - OptimizeForLoop factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: optimize condition -void CppEditorPlugin::test_quickfix_OptimizeForLoop_condition() -{ - const QByteArray original = "void foo() {f@or (int i = 0; i < 3 + 5; ++i) {}}\n"; - const QByteArray expected = "void foo() {for (int i = 0, total = 3 + 5; i < total; ++i) {}}\n\n"; - OptimizeForLoop factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: optimize fliped condition -void CppEditorPlugin::test_quickfix_OptimizeForLoop_flipedCondition() -{ - const QByteArray original = "void foo() {f@or (int i = 0; 3 + 5 > i; ++i) {}}\n"; - const QByteArray expected = "void foo() {for (int i = 0, total = 3 + 5; total > i; ++i) {}}\n\n"; - OptimizeForLoop factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: if "total" used, create other name. -void CppEditorPlugin::test_quickfix_OptimizeForLoop_alterVariableName() -{ - const QByteArray original = "void foo() {f@or (int i = 0, total = 0; i < 3 + 5; ++i) {}}\n"; - const QByteArray expected = "void foo() {for (int i = 0, total = 0, totalX = 3 + 5; i < totalX; ++i) {}}\n\n"; - OptimizeForLoop factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: optimize postcrement and condition -void CppEditorPlugin::test_quickfix_OptimizeForLoop_optimizeBoth() -{ - const QByteArray original = "void foo() {f@or (int i = 0; i < 3 + 5; i++) {}}\n"; - const QByteArray expected = "void foo() {for (int i = 0, total = 3 + 5; i < total; ++i) {}}\n\n"; - OptimizeForLoop factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: empty initializier -void CppEditorPlugin::test_quickfix_OptimizeForLoop_emptyInitializer() -{ - const QByteArray original = "int i; void foo() {f@or (; i < 3 + 5; ++i) {}}\n"; - const QByteArray expected = "int i; void foo() {for (int total = 3 + 5; i < total; ++i) {}}\n\n"; - OptimizeForLoop factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: wrong initializier type -> no trigger -void CppEditorPlugin::test_quickfix_OptimizeForLoop_wrongInitializer() -{ - const QByteArray original = "int i; void foo() {f@or (double a = 0; i < 3 + 5; ++i) {}}\n"; - const QByteArray expected = "int i; void foo() {f@or (double a = 0; i < 3 + 5; ++i) {}}\n\n"; - OptimizeForLoop factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger when numeric -void CppEditorPlugin::test_quickfix_OptimizeForLoop_noTriggerNumeric1() -{ - const QByteArray original = "void foo() {fo@r (int i = 0; i < 3; ++i) {}}\n"; - const QByteArray expected = original + "\n"; - OptimizeForLoop factory; - TestCase data(original, expected); - data.run(&factory); -} - -/// Check: No trigger when numeric -void CppEditorPlugin::test_quickfix_OptimizeForLoop_noTriggerNumeric2() -{ - const QByteArray original = "void foo() {fo@r (int i = 0; i < -3; ++i) {}}\n"; - const QByteArray expected = original + "\n"; - OptimizeForLoop factory; - TestCase data(original, expected); - data.run(&factory); -} diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 46302c0200..0dcb161b8d 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -158,10 +158,8 @@ InsertionLocation insertLocationForMethodDefinition(Symbol *symbol, const bool u = locator.methodDefinition(symbol, useSymbolFinder, fileName); for (int i = 0; i < list.count(); ++i) { InsertionLocation location = list.at(i); - if (location.isValid() && location.fileName() == fileName) { + if (location.isValid() && location.fileName() == fileName) return location; - break; - } } // ...failed, @@ -774,6 +772,11 @@ public: setDescription(QApplication::translate("CppTools::QuickFix", "Move Declaration out of Condition")); + reset(); + } + + void reset() + { condition = mk.Condition(); pattern = mk.IfStatement(condition); } @@ -826,6 +829,8 @@ void MoveDeclarationOutOfIf::match(const CppQuickFixInterface &interface, result.append(op); return; } + + op->reset(); } } } @@ -841,7 +846,11 @@ public: { setDescription(QApplication::translate("CppTools::QuickFix", "Move Declaration out of Condition")); + reset(); + } + void reset() + { condition = mk.Condition(); pattern = mk.WhileStatement(condition); } @@ -903,6 +912,8 @@ void MoveDeclarationOutOfWhile::match(const CppQuickFixInterface &interface, result.append(op); return; } + + op->reset(); } } } @@ -4756,11 +4767,11 @@ public: ? Qt::Checked : Qt::Unchecked; for (Scope::iterator it = clazz->firstMember(); it != clazz->lastMember(); ++it) { if (const Function *func = (*it)->type()->asFunctionType()) { - if (!func->isVirtual()) + // Filter virtual destructors + if (func->name()->asDestructorNameId()) continue; - // Filter virtual destructors - if (printer.prettyName(func->name()).startsWith(QLatin1Char('~'))) + if (!func->isVirtual()) continue; // Filter OQbject's @@ -4904,16 +4915,12 @@ public: switch (spec) { case InsertionPointLocator::Private: return InsertionPointLocator::PrivateSlot; - break; case InsertionPointLocator::Protected: return InsertionPointLocator::ProtectedSlot; - break; case InsertionPointLocator::Public: return InsertionPointLocator::PublicSlot; - break; default: return spec; - break; } } return spec; diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp index 1e0f45334f..4530a47b98 100644 --- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp +++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp @@ -210,52 +210,70 @@ IAssistProcessor *VirtualFunctionAssistProvider::createProcessor() const enum VirtualType { Virtual, PureVirtual }; static bool isVirtualFunction_helper(const Function *function, - const Snapshot &snapshot, - VirtualType virtualType) + const LookupContext &context, + VirtualType virtualType, + const Function **firstVirtual) { + enum { Unknown, False, True } res = Unknown; + + if (firstVirtual) + *firstVirtual = 0; + if (!function) return false; if (virtualType == PureVirtual) - return function->isPureVirtual(); - - if (function->isVirtual()) - return true; - - const QString filePath = QString::fromUtf8(function->fileName(), function->fileNameLength()); - if (Document::Ptr document = snapshot.document(filePath)) { - LookupContext context(document, snapshot); - QList<LookupItem> results = context.lookup(function->name(), function->enclosingScope()); - if (!results.isEmpty()) { - const bool isDestructor = function->name()->isDestructorNameId(); - foreach (const LookupItem &item, results) { - if (Symbol *symbol = item.declaration()) { - if (Function *functionType = symbol->type()->asFunctionType()) { - if (functionType->name()->isDestructorNameId() != isDestructor) - continue; - if (functionType == function) // already tested - continue; - if (functionType->isFinal()) - return false; - if (functionType->isVirtual()) + res = function->isPureVirtual() ? True : False; + + if (function->isVirtual()) { + if (firstVirtual) + *firstVirtual = function; + if (res == Unknown) + res = True; + } + + if (!firstVirtual && res != Unknown) + return res == True; + + QList<LookupItem> results = context.lookup(function->name(), function->enclosingScope()); + if (!results.isEmpty()) { + const bool isDestructor = function->name()->isDestructorNameId(); + foreach (const LookupItem &item, results) { + if (Symbol *symbol = item.declaration()) { + if (Function *functionType = symbol->type()->asFunctionType()) { + if (functionType->name()->isDestructorNameId() != isDestructor) + continue; + if (functionType == function) // already tested + continue; + if (functionType->isFinal()) + return res == True; + if (functionType->isVirtual()) { + if (!firstVirtual) return true; + if (res == Unknown) + res = True; + *firstVirtual = functionType; } } } } } - return false; + return res == True; } -bool FunctionHelper::isVirtualFunction(const Function *function, const Snapshot &snapshot) +bool FunctionHelper::isVirtualFunction(const Function *function, + const LookupContext &context, + const Function **firstVirtual) { - return isVirtualFunction_helper(function, snapshot, Virtual); + return isVirtualFunction_helper(function, context, Virtual, firstVirtual); } -bool FunctionHelper::isPureVirtualFunction(const Function *function, const Snapshot &snapshot) +bool FunctionHelper::isPureVirtualFunction(const Function *function, + const LookupContext &context, + const Function **firstVirtual) { - return isVirtualFunction_helper(function, snapshot, PureVirtual); + return isVirtualFunction_helper(function, context, PureVirtual, firstVirtual); } QList<Symbol *> FunctionHelper::overrides(Function *function, Class *functionsClass, @@ -324,6 +342,7 @@ typedef QList<Virtuality> VirtualityList; Q_DECLARE_METATYPE(CppEditor::Internal::Virtuality) Q_DECLARE_METATYPE(CppEditor::Internal::VirtualityList) +Q_DECLARE_METATYPE(QList<int>) namespace CppEditor { namespace Internal { @@ -333,33 +352,54 @@ void CppEditorPlugin::test_functionhelper_virtualFunctions() // Create and parse document QFETCH(QByteArray, source); QFETCH(VirtualityList, virtualityList); + QFETCH(QList<int>, firstVirtualList); Document::Ptr document = Document::create(QLatin1String("virtuals")); document->setUtf8Source(source); document->check(); // calls parse(); QCOMPARE(document->diagnosticMessages().size(), 0); QVERIFY(document->translationUnit()->ast()); + QList<const Function *> allFunctions; + const Function *firstVirtual = 0; // Iterate through Function symbols Snapshot snapshot; snapshot.insert(document); + const LookupContext context(document, snapshot); Control *control = document->translationUnit()->control(); Symbol **end = control->lastSymbol(); for (Symbol **it = control->firstSymbol(); it != end; ++it) { - const CPlusPlus::Symbol *symbol = *it; - if (const Function *function = symbol->asFunction()) { + if (const Function *function = (*it)->asFunction()) { + allFunctions.append(function); QTC_ASSERT(!virtualityList.isEmpty(), return); Virtuality virtuality = virtualityList.takeFirst(); - if (FunctionHelper::isVirtualFunction(function, snapshot)) { - if (FunctionHelper::isPureVirtualFunction(function, snapshot)) + QTC_ASSERT(!firstVirtualList.isEmpty(), return); + int firstVirtualIndex = firstVirtualList.takeFirst(); + bool isVirtual = FunctionHelper::isVirtualFunction(function, context, &firstVirtual); + bool isPureVirtual = FunctionHelper::isPureVirtualFunction(function, context, + &firstVirtual); + + // Test for regressions introduced by firstVirtual + QCOMPARE(FunctionHelper::isVirtualFunction(function, context), isVirtual); + QCOMPARE(FunctionHelper::isPureVirtualFunction(function, context), isPureVirtual); + if (isVirtual) { + if (isPureVirtual) QCOMPARE(virtuality, PureVirtual); else QCOMPARE(virtuality, Virtual); } else { + QEXPECT_FAIL("virtual-dtor-dtor", "Not implemented", Abort); + if (allFunctions.size() == 3) + QEXPECT_FAIL("dtor-virtual-dtor-dtor", "Not implemented", Abort); QCOMPARE(virtuality, NotVirtual); } + if (firstVirtualIndex == -1) + QVERIFY(!firstVirtual); + else + QCOMPARE(firstVirtual, allFunctions.at(firstVirtualIndex)); } } QVERIFY(virtualityList.isEmpty()); + QVERIFY(firstVirtualList.isEmpty()); } void CppEditorPlugin::test_functionhelper_virtualFunctions_data() @@ -367,55 +407,79 @@ void CppEditorPlugin::test_functionhelper_virtualFunctions_data() typedef QByteArray _; QTest::addColumn<QByteArray>("source"); QTest::addColumn<VirtualityList>("virtualityList"); + QTest::addColumn<QList<int> >("firstVirtualList"); QTest::newRow("none") << _("struct None { void foo() {} };\n") - << (VirtualityList() << NotVirtual); + << (VirtualityList() << NotVirtual) + << (QList<int>() << -1); QTest::newRow("single-virtual") << _("struct V { virtual void foo() {} };\n") - << (VirtualityList() << Virtual); + << (VirtualityList() << Virtual) + << (QList<int>() << 0); QTest::newRow("single-pure-virtual") << _("struct PV { virtual void foo() = 0; };\n") - << (VirtualityList() << PureVirtual); + << (VirtualityList() << PureVirtual) + << (QList<int>() << 0); QTest::newRow("virtual-derived-with-specifier") << _("struct Base { virtual void foo() {} };\n" "struct Derived : Base { virtual void foo() {} };\n") - << (VirtualityList() << Virtual << Virtual); + << (VirtualityList() << Virtual << Virtual) + << (QList<int>() << 0 << 0); QTest::newRow("virtual-derived-implicit") << _("struct Base { virtual void foo() {} };\n" "struct Derived : Base { void foo() {} };\n") - << (VirtualityList() << Virtual << Virtual); + << (VirtualityList() << Virtual << Virtual) + << (QList<int>() << 0 << 0); QTest::newRow("not-virtual-then-virtual") << _("struct Base { void foo() {} };\n" "struct Derived : Base { virtual void foo() {} };\n") - << (VirtualityList() << NotVirtual << Virtual); + << (VirtualityList() << NotVirtual << Virtual) + << (QList<int>() << -1 << 1); QTest::newRow("virtual-final-not-virtual") << _("struct Base { virtual void foo() {} };\n" "struct Derived : Base { void foo() final {} };\n" "struct Derived2 : Derived { void foo() {} };") - << (VirtualityList() << Virtual << Virtual << NotVirtual); + << (VirtualityList() << Virtual << Virtual << NotVirtual) + << (QList<int>() << 0 << 0 << -1); QTest::newRow("virtual-then-pure") << _("struct Base { virtual void foo() {} };\n" "struct Derived : Base { virtual void foo() = 0; };\n" "struct Derived2 : Derived { void foo() {} };") - << (VirtualityList() << Virtual << PureVirtual << Virtual); + << (VirtualityList() << Virtual << PureVirtual << Virtual) + << (QList<int>() << 0 << 0 << 0); QTest::newRow("virtual-virtual-final-not-virtual") << _("struct Base { virtual void foo() {} };\n" "struct Derived : Base { virtual void foo() final {} };\n" "struct Derived2 : Derived { void foo() {} };") - << (VirtualityList() << Virtual << Virtual << NotVirtual); + << (VirtualityList() << Virtual << Virtual << NotVirtual) + << (QList<int>() << 0 << 0 << -1); QTest::newRow("ctor-virtual-dtor") << _("struct Base { Base() {} virtual ~Base() {} };\n") - << (VirtualityList() << NotVirtual << Virtual); + << (VirtualityList() << NotVirtual << Virtual) + << (QList<int>() << -1 << 1); + + QTest::newRow("virtual-dtor-dtor") + << _("struct Base { virtual ~Base() {} };\n" + "struct Derived : Base { ~Derived() {} };\n") + << (VirtualityList() << Virtual << Virtual) + << (QList<int>() << 0 << 0); + + QTest::newRow("dtor-virtual-dtor-dtor") + << _("struct Base { ~Base() {} };\n" + "struct Derived : Base { virtual ~Derived() {} };\n" + "struct Derived2 : Derived { ~Derived2() {} };\n") + << (VirtualityList() << NotVirtual << Virtual << Virtual) + << (QList<int>() << -1 << 1 << 1); } } // namespace Internal diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h index 3a99fc37f8..933fa3be4e 100644 --- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h +++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h @@ -74,10 +74,12 @@ class FunctionHelper { public: static bool isVirtualFunction(const CPlusPlus::Function *function, - const CPlusPlus::Snapshot &snapshot); + const CPlusPlus::LookupContext &context, + const CPlusPlus::Function **firstVirtual = 0); static bool isPureVirtualFunction(const CPlusPlus::Function *function, - const CPlusPlus::Snapshot &snapshot); + const CPlusPlus::LookupContext &context, + const CPlusPlus::Function **firstVirtual = 0); static QList<CPlusPlus::Symbol *> overrides(CPlusPlus::Function *function, CPlusPlus::Class *functionsClass, diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp index 7924113468..5b7bf1655d 100644 --- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp +++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp @@ -465,6 +465,8 @@ void TestCase::run() } // anonymous namespace +Q_DECLARE_METATYPE(QList<TestDocumentPtr>) + void CppEditorPlugin::test_SwitchMethodDeclarationDefinition_data() { QTest::addColumn<QByteArray>("header"); @@ -870,6 +872,18 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_data() "}\n" ); + QTest::newRow("skipForwardDeclarationBasic") << _( + "class $Foo {};\n" + "class Foo;\n" + "@Foo foo;\n" + ); + + QTest::newRow("skipForwardDeclarationTemplates") << _( + "template <class E> class $Container {};\n" + "template <class E> class Container;\n" + "@Container<int> container;\n" + ); + QTest::newRow("using_QTCREATORBUG7903_globalNamespace") << _( "namespace NS {\n" "class Foo {};\n" @@ -904,7 +918,6 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_data() " @Foo foo;\n" "}\n" ); - } void CppEditorPlugin::test_FollowSymbolUnderCursor() @@ -914,6 +927,35 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor() test.run(); } +void CppEditorPlugin::test_FollowSymbolUnderCursor_multipleDocuments_data() +{ + QTest::addColumn<QList<TestDocumentPtr> >("documents"); + + QTest::newRow("skipForwardDeclarationBasic") << (QList<TestDocumentPtr>() + << TestDocument::create("class $Foo {};\n", + QLatin1String("defined.h")) + << TestDocument::create("class Foo;\n" + "@Foo foo;\n", + QLatin1String("forwardDeclaredAndUsed.h")) + ); + + QTest::newRow("skipForwardDeclarationTemplates") << (QList<TestDocumentPtr>() + << TestDocument::create("template <class E> class $Container {};\n", + QLatin1String("defined.h")) + << TestDocument::create("template <class E> class Container;\n" + "@Container<int> container;\n", + QLatin1String("forwardDeclaredAndUsed.h")) + ); +} + +void CppEditorPlugin::test_FollowSymbolUnderCursor_multipleDocuments() +{ + QFETCH(QList<TestDocumentPtr>, documents); + + TestCase test(TestCase::FollowSymbolUnderCursorAction, documents); + test.run(); +} + void CppEditorPlugin::test_FollowSymbolUnderCursor_QObject_connect_data() { #define TAG(str) secondQObjectParam ? str : str ", no 2nd QObject" @@ -1314,6 +1356,14 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_data() << (OverrideItemList() << OverrideItem(QLatin1String("Base::virt"), 1) << OverrideItem(QLatin1String("Derived::virt"), 2)); + + QTest::newRow("QTCREATORBUG-10294_cursorIsAtTheEndOfVirtualFunctionName") << _( + "struct Base { virtual void virt() {} };\n" + "struct Derived : Base { void virt() {} };\n" + "void client(Base *b) { b->virt$@(); }\n") + << (OverrideItemList() + << OverrideItem(QLatin1String("Base::virt"), 1) + << OverrideItem(QLatin1String("Derived::virt"), 2)); } void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall() |