CppEditor: Hide most of LineForNewIncludeDirective implementation

Change-Id: Ic70d28beb057359fcd028aca2ab49ecb66dd990d
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2024-01-25 17:53:23 +01:00
parent e2e0a9a718
commit 223767a94a
4 changed files with 129 additions and 116 deletions

View File

@@ -488,7 +488,7 @@ void CppEditorPlugin::registerTests()
addTest<FunctionUtilsTest>(); addTest<FunctionUtilsTest>();
addTest<HeaderPathFilterTest>(); addTest<HeaderPathFilterTest>();
addTestCreator(createCppHeaderSourceTest); addTestCreator(createCppHeaderSourceTest);
addTest<IncludeGroupsTest>(); addTestCreator(createIncludeGroupsTest);
addTest<LocalSymbolsTest>(); addTest<LocalSymbolsTest>();
addTest<LocatorFilterTest>(); addTest<LocatorFilterTest>();
addTest<ModelManagerTest>(); addTest<ModelManagerTest>();

View File

@@ -225,13 +225,12 @@ void insertNewIncludeDirective(const QString &include, CppRefactoringFilePtr fil
const Document::Ptr &cppDocument) const Document::Ptr &cppDocument)
{ {
// Find optimal position // Find optimal position
using namespace IncludeUtils;
LineForNewIncludeDirective finder(file->filePath(), file->document(), cppDocument,
LineForNewIncludeDirective::IgnoreMocIncludes,
LineForNewIncludeDirective::AutoDetect);
unsigned newLinesToPrepend = 0; unsigned newLinesToPrepend = 0;
unsigned newLinesToAppend = 0; unsigned newLinesToAppend = 0;
const int insertLine = finder(include, &newLinesToPrepend, &newLinesToAppend); const int insertLine = lineForNewIncludeDirective(file->filePath(), file->document(),
cppDocument, IgnoreMocIncludes, AutoDetect,
include,
&newLinesToPrepend, &newLinesToAppend);
QTC_ASSERT(insertLine >= 1, return); QTC_ASSERT(insertLine >= 1, return);
const int insertPosition = file->position(insertLine, 1); const int insertPosition = file->position(insertLine, 1);
QTC_ASSERT(insertPosition >= 0, return); QTC_ASSERT(insertPosition >= 0, return);

View File

@@ -15,7 +15,6 @@
#include "cppmodelmanager.h" #include "cppmodelmanager.h"
#include "cppsourceprocessertesthelper.h" #include "cppsourceprocessertesthelper.h"
#include "cppsourceprocessor.h" #include "cppsourceprocessor.h"
#include "cpptoolstestcase.h"
#include <QtTest> #include <QtTest>
#endif // WITH_TESTS #endif // WITH_TESTS
@@ -30,14 +29,52 @@
using namespace CPlusPlus; using namespace CPlusPlus;
using namespace Utils; using namespace Utils;
namespace CppEditor { namespace CppEditor::Internal {
namespace IncludeUtils {
namespace {
bool includeFileNamelessThen(const Include & left, const Include & right) using Include = CPlusPlus::Document::Include;
{ return left.unresolvedFileName() < right.unresolvedFileName(); } using IncludeType = CPlusPlus::Client::IncludeType;
int lineForAppendedIncludeGroup(const QList<IncludeGroup> &groups, class IncludeGroup
{
public:
static QList<IncludeGroup> detectIncludeGroupsByNewLines(QList<Include> &includes);
static QList<IncludeGroup> detectIncludeGroupsByIncludeDir(const QList<Include> &includes);
static QList<IncludeGroup> detectIncludeGroupsByIncludeType(const QList<Include> &includes);
static QList<IncludeGroup> filterMixedIncludeGroups(const QList<IncludeGroup> &groups);
static QList<IncludeGroup> filterIncludeGroups(const QList<IncludeGroup> &groups,
CPlusPlus::Client::IncludeType includeType);
public:
explicit IncludeGroup(const QList<Include> &includes) : m_includes(includes) {}
QList<Include> includes() const { return m_includes; }
Include first() const { return m_includes.first(); }
Include last() const { return m_includes.last(); }
int size() const { return m_includes.size(); }
bool isEmpty() const { return m_includes.isEmpty(); }
QString commonPrefix() const;
QString commonIncludeDir() const; /// only valid if hasCommonDir() == true
bool hasCommonIncludeDir() const;
bool hasOnlyIncludesOfType(CPlusPlus::Client::IncludeType includeType) const;
bool isSorted() const; /// name-wise
int lineForNewInclude(const QString &newIncludeFileName,
CPlusPlus::Client::IncludeType newIncludeType) const;
private:
QStringList filesNames() const;
QList<Include> m_includes;
};
static bool includeFileNamelessThen(const Include & left, const Include & right)
{
return left.unresolvedFileName() < right.unresolvedFileName();
}
static int lineForAppendedIncludeGroup(const QList<IncludeGroup> &groups,
unsigned *newLinesToPrepend) unsigned *newLinesToPrepend)
{ {
if (newLinesToPrepend) if (newLinesToPrepend)
@@ -45,7 +82,7 @@ int lineForAppendedIncludeGroup(const QList<IncludeGroup> &groups,
return groups.last().last().line() + 1; return groups.last().last().line() + 1;
} }
int lineForPrependedIncludeGroup(const QList<IncludeGroup> &groups, static int lineForPrependedIncludeGroup(const QList<IncludeGroup> &groups,
unsigned *newLinesToAppend) unsigned *newLinesToAppend)
{ {
if (newLinesToAppend) if (newLinesToAppend)
@@ -53,7 +90,7 @@ int lineForPrependedIncludeGroup(const QList<IncludeGroup> &groups,
return groups.first().first().line(); return groups.first().first().line();
} }
QString includeDir(const QString &include) static QString includeDir(const QString &include)
{ {
QString dirPrefix = QFileInfo(include).dir().path(); QString dirPrefix = QFileInfo(include).dir().path();
if (dirPrefix == QLatin1String(".")) if (dirPrefix == QLatin1String("."))
@@ -62,7 +99,7 @@ QString includeDir(const QString &include)
return dirPrefix; return dirPrefix;
} }
int lineAfterFirstComment(const QTextDocument *textDocument) static int lineAfterFirstComment(const QTextDocument *textDocument)
{ {
int insertLine = -1; int insertLine = -1;
@@ -101,7 +138,31 @@ int lineAfterFirstComment(const QTextDocument *textDocument)
return insertLine; return insertLine;
} }
} // anonymous namespace class LineForNewIncludeDirective
{
public:
LineForNewIncludeDirective(const FilePath &filePath, const QTextDocument *textDocument,
const CPlusPlus::Document::Ptr cppDocument,
MocIncludeMode mocIncludeMode,
IncludeStyle includeStyle);
/// Returns the line (1-based) at which the include directive should be inserted.
/// On error, -1 is returned.
int run(const QString &newIncludeFileName, unsigned *newLinesToPrepend = nullptr,
unsigned *newLinesToAppend = nullptr);
private:
int findInsertLineForVeryFirstInclude(unsigned *newLinesToPrepend, unsigned *newLinesToAppend);
QList<IncludeGroup> getGroupsByIncludeType(const QList<IncludeGroup> &groups,
IncludeType includeType);
const FilePath m_filePath;
const QTextDocument *m_textDocument;
const CPlusPlus::Document::Ptr m_cppDocument;
IncludeStyle m_includeStyle;
QList<Include> m_includes;
};
LineForNewIncludeDirective::LineForNewIncludeDirective(const FilePath &filePath, LineForNewIncludeDirective::LineForNewIncludeDirective(const FilePath &filePath,
const QTextDocument *textDocument, const QTextDocument *textDocument,
@@ -186,9 +247,9 @@ int LineForNewIncludeDirective::findInsertLineForVeryFirstInclude(unsigned *newL
return insertLine; return insertLine;
} }
int LineForNewIncludeDirective::operator()(const QString &newIncludeFileName, int LineForNewIncludeDirective::run(const QString &newIncludeFileName,
unsigned *newLinesToPrepend, unsigned *newLinesToPrepend,
unsigned *newLinesToAppend) unsigned *newLinesToAppend)
{ {
if (newLinesToPrepend) if (newLinesToPrepend)
*newLinesToPrepend = false; *newLinesToPrepend = false;
@@ -325,6 +386,19 @@ QList<IncludeGroup> LineForNewIncludeDirective::getGroupsByIncludeType(
: IncludeGroup::filterIncludeGroups(groups, Client::IncludeGlobal); : IncludeGroup::filterIncludeGroups(groups, Client::IncludeGlobal);
} }
int lineForNewIncludeDirective(const Utils::FilePath &filePath, const QTextDocument *textDocument,
const CPlusPlus::Document::Ptr cppDocument,
MocIncludeMode mocIncludeMode,
IncludeStyle includeStyle,
const QString &newIncludeFileName,
unsigned *newLinesToPrepend,
unsigned *newLinesToAppend)
{
return LineForNewIncludeDirective(filePath, textDocument, cppDocument,
mocIncludeMode, includeStyle)
.run(newIncludeFileName, newLinesToPrepend, newLinesToAppend);
}
/// includes will be modified! /// includes will be modified!
QList<IncludeGroup> IncludeGroup::detectIncludeGroupsByNewLines(QList<Document::Include> &includes) QList<IncludeGroup> IncludeGroup::detectIncludeGroupsByNewLines(QList<Document::Include> &includes)
{ {
@@ -526,14 +600,24 @@ bool IncludeGroup::hasCommonIncludeDir() const
return true; return true;
} }
} // namespace IncludeUtils } // CppEditor::Internal
#ifdef WITH_TESTS #ifdef WITH_TESTS
namespace CppEditor::Internal {
using namespace Tests; using namespace Tests;
using namespace IncludeUtils;
using Tests::Internal::TestIncludePaths; using Tests::Internal::TestIncludePaths;
namespace Internal { class IncludeGroupsTest : public QObject
{
Q_OBJECT
private slots:
void testDetectIncludeGroupsByNewLines();
void testDetectIncludeGroupsByIncludeDir();
void testDetectIncludeGroupsByIncludeType();
};
static QList<Include> includesForSource(const FilePath &filePath) static QList<Include> includesForSource(const FilePath &filePath)
{ {
@@ -637,8 +721,13 @@ void IncludeGroupsTest::testDetectIncludeGroupsByIncludeType()
QVERIFY(includeGroups.at(3).hasOnlyIncludesOfType(Client::IncludeGlobal)); QVERIFY(includeGroups.at(3).hasOnlyIncludesOfType(Client::IncludeGlobal));
} }
} // namespace Internal QObject *createIncludeGroupsTest()
{
return new IncludeGroupsTest;
}
} // CppEditor::Internal
#include "includeutils.moc"
#endif // WITH_TESTS #endif // WITH_TESTS
} // namespace CppEditor

View File

@@ -4,100 +4,25 @@
#pragma once #pragma once
#include <cplusplus/CppDocument.h> #include <cplusplus/CppDocument.h>
#include <cplusplus/PreprocessorClient.h>
#include <utils/filepath.h> QT_BEGIN_NAMESPACE
class QObject;
class QTextDocument;
QT_END_NAMESPACE
#include <QList> namespace CppEditor::Internal {
#include <QObject>
#include <QString>
QT_FORWARD_DECLARE_CLASS(QTextDocument) enum MocIncludeMode { RespectMocIncludes, IgnoreMocIncludes };
enum IncludeStyle { LocalBeforeGlobal, GlobalBeforeLocal, AutoDetect };
namespace CppEditor { int lineForNewIncludeDirective(const Utils::FilePath &filePath, const QTextDocument *textDocument,
namespace IncludeUtils {
using Include = CPlusPlus::Document::Include;
using IncludeType = CPlusPlus::Client::IncludeType;
class IncludeGroup
{
public:
static QList<IncludeGroup> detectIncludeGroupsByNewLines(QList<Include> &includes);
static QList<IncludeGroup> detectIncludeGroupsByIncludeDir(const QList<Include> &includes);
static QList<IncludeGroup> detectIncludeGroupsByIncludeType(const QList<Include> &includes);
static QList<IncludeGroup> filterMixedIncludeGroups(const QList<IncludeGroup> &groups);
static QList<IncludeGroup> filterIncludeGroups(const QList<IncludeGroup> &groups,
CPlusPlus::Client::IncludeType includeType);
public:
explicit IncludeGroup(const QList<Include> &includes) : m_includes(includes) {}
QList<Include> includes() const { return m_includes; }
Include first() const { return m_includes.first(); }
Include last() const { return m_includes.last(); }
int size() const { return m_includes.size(); }
bool isEmpty() const { return m_includes.isEmpty(); }
QString commonPrefix() const;
QString commonIncludeDir() const; /// only valid if hasCommonDir() == true
bool hasCommonIncludeDir() const;
bool hasOnlyIncludesOfType(CPlusPlus::Client::IncludeType includeType) const;
bool isSorted() const; /// name-wise
int lineForNewInclude(const QString &newIncludeFileName,
CPlusPlus::Client::IncludeType newIncludeType) const;
private:
QStringList filesNames() const;
QList<Include> m_includes;
};
class LineForNewIncludeDirective
{
public:
enum MocIncludeMode { RespectMocIncludes, IgnoreMocIncludes };
enum IncludeStyle { LocalBeforeGlobal, GlobalBeforeLocal, AutoDetect };
LineForNewIncludeDirective(const Utils::FilePath &filePath, const QTextDocument *textDocument,
const CPlusPlus::Document::Ptr cppDocument, const CPlusPlus::Document::Ptr cppDocument,
MocIncludeMode mocIncludeMode = IgnoreMocIncludes, MocIncludeMode mocIncludeMode,
IncludeStyle includeStyle = AutoDetect); IncludeStyle includeStyle,
const QString &newIncludeFileName,
unsigned *newLinesToPrepend,
unsigned *newLinesToAppend);
/// Returns the line (1-based) at which the include directive should be inserted. QObject *createIncludeGroupsTest();
/// On error, -1 is returned.
int operator()(const QString &newIncludeFileName, unsigned *newLinesToPrepend = nullptr,
unsigned *newLinesToAppend = nullptr);
private: } // CppEditor::Internal
int findInsertLineForVeryFirstInclude(unsigned *newLinesToPrepend, unsigned *newLinesToAppend);
QList<IncludeGroup> getGroupsByIncludeType(const QList<IncludeGroup> &groups,
IncludeType includeType);
const Utils::FilePath m_filePath;
const QTextDocument *m_textDocument;
const CPlusPlus::Document::Ptr m_cppDocument;
IncludeStyle m_includeStyle;
QList<Include> m_includes;
};
} // namespace IncludeUtils
#ifdef WITH_TESTS
namespace Internal {
class IncludeGroupsTest : public QObject
{
Q_OBJECT
private slots:
void testDetectIncludeGroupsByNewLines();
void testDetectIncludeGroupsByIncludeDir();
void testDetectIncludeGroupsByIncludeType();
};
} // namespace Internal
#endif // WITH_TESTS
} // namespace CppEditor