diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index a3a8111ee8f..9651ddb214f 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -13,6 +13,8 @@ #include "cppsourceprocessertesthelper.h" #include "cpptoolssettings.h" +#include +#include #include #include @@ -60,7 +62,8 @@ QList singleDocument(const QByteArray &original, } BaseQuickFixTestCase::BaseQuickFixTestCase(const QList &testDocuments, - const ProjectExplorer::HeaderPaths &headerPaths) + const ProjectExplorer::HeaderPaths &headerPaths, + const QByteArray &clangFormatSettings) : m_testDocuments(testDocuments) , m_cppCodeStylePreferences(0) , m_restoreHeaderPaths(false) @@ -85,6 +88,10 @@ BaseQuickFixTestCase::BaseQuickFixTestCase(const QList &testDoc document->writeToDisk(); } + // Create .clang-format file + if (!clangFormatSettings.isEmpty()) + m_temporaryDirectory->createFile(".clang-format", clangFormatSettings); + // Set appropriate include paths if (!headerPaths.isEmpty()) { m_restoreHeaderPaths = true; @@ -182,8 +189,9 @@ QuickFixOperationTest::QuickFixOperationTest(const QList &testD CppQuickFixFactory *factory, const ProjectExplorer::HeaderPaths &headerPaths, int operationIndex, - const QByteArray &expectedFailMessage) - : BaseQuickFixTestCase(testDocuments, headerPaths) + const QByteArray &expectedFailMessage, + const QByteArray &clangFormatSettings) + : BaseQuickFixTestCase(testDocuments, headerPaths, clangFormatSettings) { QVERIFY(succeededSoFar()); @@ -5336,6 +5344,57 @@ void QuickfixTest::testInsertDefsFromDecls() QuickFixOperationTest(testDocuments, &factory); } +void QuickfixTest::testInsertAndFormatDefsFromDecls() +{ + static const auto isClangFormatPresent = [] { + using namespace ExtensionSystem; + return Utils::contains(PluginManager::plugins(), [](const PluginSpec *plugin) { + return plugin->name() == "ClangFormat" && plugin->isEffectivelyEnabled(); + }); + }; + if (!isClangFormatPresent()) + QSKIP("This test reqires ClangFormat"); + + const QByteArray origHeader = R"( +class @C +{ +public: + void func1 (int const &i); + void func2 (double const d); +}; +)"; + const QByteArray origSource = R"( +#include "file.h" +)"; + + const QByteArray expectedSource = R"( +#include "file.h" + +void C::func1 (int const &i) +{ + +} + +void C::func2 (double const d) +{ + +} +)"; + + const QByteArray clangFormatSettings = R"( +BreakBeforeBraces: Allman +QualifierAlignment: Right +SpaceBeforeParens: Always +)"; + + const QList testDocuments({ + CppTestDocument::create("file.h", origHeader, origHeader), + CppTestDocument::create("file.cpp", origSource, expectedSource)}); + InsertDefsFromDecls factory; + factory.setMode(InsertDefsFromDecls::Mode::Impl); + QuickFixOperationTest(testDocuments, &factory, {}, {}, {}, clangFormatSettings); +} + // Function for one of InsertDeclDef section cases void insertToSectionDeclFromDef(const QByteArray §ion, int sectionIndex) { diff --git a/src/plugins/cppeditor/cppquickfix_test.h b/src/plugins/cppeditor/cppquickfix_test.h index 2d0dd0ebc9d..53926630cab 100644 --- a/src/plugins/cppeditor/cppquickfix_test.h +++ b/src/plugins/cppeditor/cppquickfix_test.h @@ -26,8 +26,8 @@ public: /// Exactly one QuickFixTestDocument must contain the cursor position marker '@' /// or "@{start}" and "@{end}" BaseQuickFixTestCase(const QList &testDocuments, - const ProjectExplorer::HeaderPaths &headerPaths - = ProjectExplorer::HeaderPaths()); + const ProjectExplorer::HeaderPaths &headerPaths, + const QByteArray &clangFormatSettings = {}); ~BaseQuickFixTestCase(); @@ -54,7 +54,8 @@ public: const ProjectExplorer::HeaderPaths &headerPaths = ProjectExplorer::HeaderPaths(), int operationIndex = 0, - const QByteArray &expectedFailMessage = QByteArray()); + const QByteArray &expectedFailMessage = {}, + const QByteArray &clangFormatSettings = {}); static void run(const QList &testDocuments, CppQuickFixFactory *factory, @@ -139,6 +140,7 @@ private slots: void testInsertDefFromDeclAliasTemplateAsReturnType(); void testInsertDefsFromDecls_data(); void testInsertDefsFromDecls(); + void testInsertAndFormatDefsFromDecls(); void testInsertDeclFromDef(); void testInsertDeclFromDefTemplateFuncTypename(); diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 77672a85699..93596f5ec43 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -3478,6 +3478,15 @@ private: settings = dlg.settings(); break; } + case InsertDefsFromDecls::Mode::Impl: { + for (Symbol * const func : std::as_const(unimplemented)) { + MemberFunctionImplSetting setting; + setting.func = func; + setting.defPos = DefPosImplementationFile; + settings << setting; + } + break; + } case InsertDefsFromDecls::Mode::Alternating: { int defPos = DefPosImplementationFile; const auto incDefPos = [&defPos] { diff --git a/src/plugins/cppeditor/cppquickfixes.h b/src/plugins/cppeditor/cppquickfixes.h index 61db3ebf53d..1b19c23b60d 100644 --- a/src/plugins/cppeditor/cppquickfixes.h +++ b/src/plugins/cppeditor/cppquickfixes.h @@ -402,6 +402,7 @@ public: enum class Mode { Off, // Testing: simulates user canceling the dialog + Impl, // Testing: simulates user choosing cpp file for every function Alternating, // Testing: simulates user choosing a different DefPos for every function User // Normal interactive mode }; diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index dab0ebb41f2..1b03a07e01f 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -468,7 +468,7 @@ void RefactoringFile::doFormatting() QTC_ASSERT(b.isValid(), break); if (b.text().simplified().isEmpty()) QTextCursor(b).insertText(clangFormatLineRemovalBlocker); - if (b.blockNumber() == r.endLine) + if (b.blockNumber() == r.endLine - 1) break; b = b.next(); }