diff options
author | hjk <hjk@qt.io> | 2024-01-25 17:08:14 +0100 |
---|---|---|
committer | hjk <hjk@qt.io> | 2024-01-26 12:44:53 +0000 |
commit | 7f061c723a7e96b988d7b9b56dea727c4ca6fd7b (patch) | |
tree | 94ae07dea8618623a7e7c80a14d691dcc6010b5c | |
parent | e71d16ef90ebf5983ac657aae42d52991de923e7 (diff) |
CppEditor: Move CppHeaderSource implementation and test to same files
... and remove the now-empty cppeditorplugin.h
Change-Id: Ia28b180c280ba7b10ce0f2826f2ac69d128a453c
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
19 files changed, 384 insertions, 388 deletions
diff --git a/src/plugins/cppeditor/CMakeLists.txt b/src/plugins/cppeditor/CMakeLists.txt index c64817cfb0..ec5ad89cea 100644 --- a/src/plugins/cppeditor/CMakeLists.txt +++ b/src/plugins/cppeditor/CMakeLists.txt @@ -40,7 +40,7 @@ add_qtc_plugin(CppEditor cppeditorconstants.h cppeditordocument.cpp cppeditordocument.h cppeditoroutline.cpp cppeditoroutline.h - cppeditorplugin.cpp cppeditorplugin.h + cppeditorplugin.cpp cppeditorwidget.cpp cppeditorwidget.h cppelementevaluator.cpp cppelementevaluator.h cppfileiterationorder.cpp cppfileiterationorder.h @@ -49,6 +49,7 @@ add_qtc_plugin(CppEditor cppfollowsymbolundercursor.cpp cppfollowsymbolundercursor.h cppfunctiondecldeflink.cpp cppfunctiondecldeflink.h cppfunctionparamrenaminghandler.cpp cppfunctionparamrenaminghandler.h + cppheadersource.cpp cppheadersource.h cpphighlighter.cpp cpphighlighter.h cppincludehierarchy.cpp cppincludehierarchy.h cppincludesfilter.cpp cppincludesfilter.h @@ -121,7 +122,6 @@ extend_qtc_plugin(CppEditor cppcodegen_test.cpp cppcodegen_test.h cppcompletion_test.cpp cppcompletion_test.h cppdoxygen_test.cpp cppdoxygen_test.h - cppheadersource_test.cpp cppheadersource_test.h cppincludehierarchy_test.cpp cppincludehierarchy_test.h cpplocalsymbols_test.cpp cpplocalsymbols_test.h cpplocatorfilter_test.cpp cpplocatorfilter_test.h diff --git a/src/plugins/cppeditor/builtineditordocumentprocessor.cpp b/src/plugins/cppeditor/builtineditordocumentprocessor.cpp index 9c7535ee74..4d43546334 100644 --- a/src/plugins/cppeditor/builtineditordocumentprocessor.cpp +++ b/src/plugins/cppeditor/builtineditordocumentprocessor.cpp @@ -7,7 +7,6 @@ #include "cppchecksymbols.h" #include "cppcodemodelsettings.h" #include "cppeditordocument.h" -#include "cppeditorplugin.h" #include "cppmodelmanager.h" #include "cpptoolsreuse.h" #include "cppworkingcopy.h" diff --git a/src/plugins/cppeditor/cppautocompleter.cpp b/src/plugins/cppeditor/cppautocompleter.cpp index dcd2cebacd..0710131862 100644 --- a/src/plugins/cppeditor/cppautocompleter.cpp +++ b/src/plugins/cppeditor/cppautocompleter.cpp @@ -13,7 +13,6 @@ #ifdef WITH_TESTS #include "cppeditorconstants.h" -#include "cppeditorplugin.h" #include "cppeditorwidget.h" #include <coreplugin/editormanager/editormanager.h> diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs index 2e8581a50c..b684b0e0ea 100644 --- a/src/plugins/cppeditor/cppeditor.qbs +++ b/src/plugins/cppeditor/cppeditor.qbs @@ -95,7 +95,6 @@ QtcPlugin { "cppeditoroutline.cpp", "cppeditoroutline.h", "cppeditorplugin.cpp", - "cppeditorplugin.h", "cppelementevaluator.cpp", "cppelementevaluator.h", "cppfileiterationorder.cpp", @@ -110,6 +109,8 @@ QtcPlugin { "cppfunctiondecldeflink.h", "cppfunctionparamrenaminghandler.cpp", "cppfunctionparamrenaminghandler.h", + "cppheadersource.cpp", + "cppheadersource.h", "cpphighlighter.cpp", "cpphighlighter.h", "cppincludehierarchy.cpp", @@ -252,8 +253,6 @@ QtcPlugin { "cppcompletion_test.h", "cppdoxygen_test.cpp", "cppdoxygen_test.h", - "cppheadersource_test.cpp", - "cppheadersource_test.h", "cppincludehierarchy_test.cpp", "cppincludehierarchy_test.h", "cpplocalsymbols_test.cpp", diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp index 8d4adebf14..d1297b1dd3 100644 --- a/src/plugins/cppeditor/cppeditordocument.cpp +++ b/src/plugins/cppeditor/cppeditordocument.cpp @@ -6,11 +6,9 @@ #include "baseeditordocumentparser.h" #include "cppcodeformatter.h" #include "cppeditorconstants.h" -#include "cppeditorplugin.h" #include "cppeditortr.h" #include "cppmodelmanager.h" #include "cppeditorconstants.h" -#include "cppeditorplugin.h" #include "cppeditortr.h" #include "cpphighlighter.h" #include "cppquickfixassistant.h" diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index 24d821aac2..a5f1275538 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "cppeditorplugin.h" - #include "cppautocompleter.h" #include "cppcodemodelinspectordialog.h" #include "cppcodemodelsettings.h" @@ -14,9 +12,9 @@ #include "cppeditorwidget.h" #include "cppfilesettingspage.h" #include "cppincludehierarchy.h" +#include "cppheadersource.h" #include "cppmodelmanager.h" #include "cppoutline.h" -#include "cppprojectfile.h" #include "cppprojectupdater.h" #include "cppquickfixes.h" #include "cppquickfixprojectsettingswidget.h" @@ -24,7 +22,6 @@ #include "cpptoolsreuse.h" #include "cpptoolssettings.h" #include "cpptypehierarchy.h" -#include "projectinfo.h" #include "resourcepreviewhoverhandler.h" #ifdef WITH_TESTS @@ -32,7 +29,6 @@ #include "cppcodegen_test.h" #include "cppcompletion_test.h" #include "cppdoxygen_test.h" -#include "cppheadersource_test.h" #include "cpphighlighter.h" #include "cppincludehierarchy_test.h" #include "cppinsertvirtualmethods.h" @@ -89,7 +85,6 @@ #include <utils/mimeconstants.h> #include <utils/mimeutils.h> #include <utils/qtcassert.h> -#include <utils/stringtable.h> #include <utils/theme/theme.h> #include <QAction> @@ -106,11 +101,7 @@ using namespace ProjectExplorer; using namespace TextEditor; using namespace Utils; -namespace CppEditor { -namespace Internal { - -enum { QUICKFIX_INTERVAL = 20 }; -enum { debug = 0 }; +namespace CppEditor::Internal { static CppEditorWidget *currentCppEditorWidget() { @@ -183,8 +174,6 @@ public: CppProjectUpdaterFactory m_cppProjectUpdaterFactory; }; -static QHash<FilePath, FilePath> m_headerSourceMapping; - class CppEditorPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT @@ -498,7 +487,7 @@ void CppEditorPlugin::registerTests() addTest<CppHighlighterTest>(); addTest<FunctionUtilsTest>(); addTest<HeaderPathFilterTest>(); - addTest<HeaderSourceTest>(); + addTestCreator(createCppHeaderSourceTest); addTest<IncludeGroupsTest>(); addTest<LocalSymbolsTest>(); addTest<LocatorFilterTest>(); @@ -551,239 +540,6 @@ void CppEditorPluginPrivate::inspectCppCodeModel() } } -void clearHeaderSourceCache() -{ - m_headerSourceMapping.clear(); -} - -static FilePaths findFilesInProject(const QStringList &names, const Project *project, - FileType fileType) -{ - if (debug) - qDebug() << Q_FUNC_INFO << names << project; - - if (!project) - return {}; - - const auto filter = [&](const Node *n) { - const auto fn = n->asFileNode(); - return fn && fn->fileType() == fileType && names.contains(fn->filePath().fileName()); - }; - return project->files(filter); -} - -// Return the suffixes that should be checked when trying to find a -// source belonging to a header and vice versa -static QStringList matchingCandidateSuffixes(ProjectFile::Kind kind) -{ - using namespace Utils::Constants; - switch (kind) { - case ProjectFile::AmbiguousHeader: - case ProjectFile::CHeader: - case ProjectFile::CXXHeader: - case ProjectFile::ObjCHeader: - case ProjectFile::ObjCXXHeader: - return mimeTypeForName(C_SOURCE_MIMETYPE).suffixes() - + mimeTypeForName(CPP_SOURCE_MIMETYPE).suffixes() - + mimeTypeForName(OBJECTIVE_C_SOURCE_MIMETYPE).suffixes() - + mimeTypeForName(OBJECTIVE_CPP_SOURCE_MIMETYPE).suffixes() - + mimeTypeForName(CUDA_SOURCE_MIMETYPE).suffixes(); - case ProjectFile::CSource: - case ProjectFile::ObjCSource: - return mimeTypeForName(C_HEADER_MIMETYPE).suffixes(); - case ProjectFile::CXXSource: - case ProjectFile::ObjCXXSource: - case ProjectFile::CudaSource: - case ProjectFile::OpenCLSource: - return mimeTypeForName(CPP_HEADER_MIMETYPE).suffixes(); - default: - return {}; - } -} - -static QStringList baseNameWithAllSuffixes(const QString &baseName, const QStringList &suffixes) -{ - QStringList result; - const QChar dot = QLatin1Char('.'); - for (const QString &suffix : suffixes) { - QString fileName = baseName; - fileName += dot; - fileName += suffix; - result += fileName; - } - return result; -} - -static QStringList baseNamesWithAllPrefixes(const CppFileSettings &settings, - const QStringList &baseNames, bool isHeader) -{ - QStringList result; - const QStringList &sourcePrefixes = settings.sourcePrefixes; - const QStringList &headerPrefixes = settings.headerPrefixes; - - for (const QString &name : baseNames) { - for (const QString &prefix : isHeader ? headerPrefixes : sourcePrefixes) { - if (name.startsWith(prefix)) { - QString nameWithoutPrefix = name.mid(prefix.size()); - result += nameWithoutPrefix; - for (const QString &prefix : isHeader ? sourcePrefixes : headerPrefixes) - result += prefix + nameWithoutPrefix; - } - } - for (const QString &prefix : isHeader ? sourcePrefixes : headerPrefixes) - result += prefix + name; - - } - return result; -} - -static QStringList baseDirWithAllDirectories(const QDir &baseDir, const QStringList &directories) -{ - QStringList result; - for (const QString &dir : directories) - result << QDir::cleanPath(baseDir.absoluteFilePath(dir)); - return result; -} - -static int commonFilePathLength(const QString &s1, const QString &s2) -{ - int length = qMin(s1.length(), s2.length()); - for (int i = 0; i < length; ++i) - if (HostOsInfo::fileNameCaseSensitivity() == Qt::CaseSensitive) { - if (s1[i] != s2[i]) - return i; - } else { - if (s1[i].toLower() != s2[i].toLower()) - return i; - } - return length; -} - -static FilePath correspondingHeaderOrSourceInProject(const FilePath &filePath, - const QStringList &candidateFileNames, - const Project *project, - FileType fileType, - CacheUsage cacheUsage) -{ - const FilePaths projectFiles = findFilesInProject(candidateFileNames, project, fileType); - - // Find the file having the most common path with fileName - FilePath bestFilePath; - int compareValue = 0; - for (const FilePath &projectFile : projectFiles) { - int value = commonFilePathLength(filePath.toString(), projectFile.toString()); - if (value > compareValue) { - compareValue = value; - bestFilePath = projectFile; - } - } - if (!bestFilePath.isEmpty()) { - QTC_ASSERT(bestFilePath.isFile(), return {}); - if (cacheUsage == CacheUsage::ReadWrite) { - m_headerSourceMapping[filePath] = bestFilePath; - m_headerSourceMapping[bestFilePath] = filePath; - } - return bestFilePath; - } - - return {}; -} - -} // namespace Internal - -using namespace Internal; - -FilePath correspondingHeaderOrSource(const FilePath &filePath, bool *wasHeader, CacheUsage cacheUsage) -{ - ProjectFile::Kind kind = ProjectFile::classify(filePath.fileName()); - const bool isHeader = ProjectFile::isHeader(kind); - if (wasHeader) - *wasHeader = isHeader; - if (const auto it = m_headerSourceMapping.constFind(filePath); - it != m_headerSourceMapping.constEnd()) { - return it.value(); - } - - Project * const projectForFile = ProjectManager::projectForFile(filePath); - const CppFileSettings settings = cppFileSettingsForProject(projectForFile); - - if (debug) - qDebug() << Q_FUNC_INFO << filePath.fileName() << kind; - - if (kind == ProjectFile::Unsupported) - return {}; - - const QString baseName = filePath.completeBaseName(); - const QString privateHeaderSuffix = QLatin1String("_p"); - const QStringList suffixes = matchingCandidateSuffixes(kind); - - QStringList candidateFileNames = baseNameWithAllSuffixes(baseName, suffixes); - if (isHeader) { - if (baseName.endsWith(privateHeaderSuffix)) { - QString sourceBaseName = baseName; - sourceBaseName.truncate(sourceBaseName.size() - privateHeaderSuffix.size()); - candidateFileNames += baseNameWithAllSuffixes(sourceBaseName, suffixes); - } - } else { - QString privateHeaderBaseName = baseName; - privateHeaderBaseName.append(privateHeaderSuffix); - candidateFileNames += baseNameWithAllSuffixes(privateHeaderBaseName, suffixes); - } - - const QDir absoluteDir = filePath.toFileInfo().absoluteDir(); - QStringList candidateDirs(absoluteDir.absolutePath()); - // If directory is not root, try matching against its siblings - const QStringList searchPaths = isHeader ? settings.sourceSearchPaths - : settings.headerSearchPaths; - candidateDirs += baseDirWithAllDirectories(absoluteDir, searchPaths); - - candidateFileNames += baseNamesWithAllPrefixes(settings, candidateFileNames, isHeader); - - // Try to find a file in the same or sibling directories first - for (const QString &candidateDir : std::as_const(candidateDirs)) { - for (const QString &candidateFileName : std::as_const(candidateFileNames)) { - const FilePath candidateFilePath - = FilePath::fromString(candidateDir + '/' + candidateFileName).normalizedPathName(); - if (candidateFilePath.isFile()) { - if (cacheUsage == CacheUsage::ReadWrite) { - m_headerSourceMapping[filePath] = candidateFilePath; - if (!isHeader || !baseName.endsWith(privateHeaderSuffix)) - m_headerSourceMapping[candidateFilePath] = filePath; - } - return candidateFilePath; - } - } - } - - // Find files in the current project - Project *currentProject = projectForFile; - if (!projectForFile) - currentProject = ProjectTree::currentProject(); - const FileType requestedFileType = isHeader ? FileType::Source : FileType::Header; - if (currentProject) { - const FilePath path = correspondingHeaderOrSourceInProject( - filePath, candidateFileNames, currentProject, requestedFileType, cacheUsage); - if (!path.isEmpty()) - return path; - - // Find files in other projects - } else { - const QList<ProjectInfo::ConstPtr> projectInfos = CppModelManager::projectInfos(); - for (const ProjectInfo::ConstPtr &projectInfo : projectInfos) { - const Project *project = projectForProjectInfo(*projectInfo); - if (project == currentProject) - continue; // We have already checked the current project. - - const FilePath path = correspondingHeaderOrSourceInProject( - filePath, candidateFileNames, project, requestedFileType, cacheUsage); - if (!path.isEmpty()) - return path; - } - } - - return {}; -} - -} // namespace CppEditor +} // CppEditor::Internal #include "cppeditorplugin.moc" diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 2d8a699727..958a908915 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -8,7 +8,6 @@ #include "cppeditorconstants.h" #include "cppeditordocument.h" #include "cppeditoroutline.h" -#include "cppeditorplugin.h" #include "cppeditortr.h" #include "cppfunctiondecldeflink.h" #include "cppfunctionparamrenaminghandler.h" diff --git a/src/plugins/cppeditor/cppfilesettingspage.cpp b/src/plugins/cppeditor/cppfilesettingspage.cpp index d11a811498..2c8fa41054 100644 --- a/src/plugins/cppeditor/cppfilesettingspage.cpp +++ b/src/plugins/cppeditor/cppfilesettingspage.cpp @@ -3,8 +3,8 @@ #include "cppfilesettingspage.h" -#include "cppeditorplugin.h" #include "cppeditortr.h" +#include "cppheadersource.h" #include <coreplugin/icore.h> #include <coreplugin/editormanager/editormanager.h> diff --git a/src/plugins/cppeditor/cppheadersource.cpp b/src/plugins/cppeditor/cppheadersource.cpp new file mode 100644 index 0000000000..84dcb98c70 --- /dev/null +++ b/src/plugins/cppeditor/cppheadersource.cpp @@ -0,0 +1,368 @@ +// Copyright (C) 2016 Orgad Shaneh <orgads@gmail.com>. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "cppheadersource.h" + +#include "cpptoolsreuse.h" +#include "cpptoolstestcase.h" +#include "cppfilesettingspage.h" +#include "cppmodelmanager.h" +#include "cppfilesettingspage.h" + +#include <projectexplorer/project.h> +#include <projectexplorer/projectnodes.h> +#include <projectexplorer/projectmanager.h> +#include <projectexplorer/projecttree.h> + +#include <utils/fileutils.h> +#include <utils/mimeconstants.h> +#include <utils/mimeutils.h> +#include <utils/temporarydirectory.h> + +#include <QDir> + +#ifdef WITH_TESTS +#include <QtTest> +#endif + +using namespace CppEditor::Internal; +using namespace ProjectExplorer; +using namespace Utils; + +namespace CppEditor { + +enum { debug = 0 }; + +static QHash<FilePath, FilePath> m_headerSourceMapping; + +void Internal::clearHeaderSourceCache() +{ + m_headerSourceMapping.clear(); +} + +static inline QString _(const QByteArray &ba) { return QString::fromLatin1(ba, ba.size()); } + +static void createTempFile(const FilePath &filePath) +{ + QString fileName = filePath.toString(); + QFile file(fileName); + QDir(QFileInfo(fileName).absolutePath()).mkpath(_(".")); + file.open(QFile::WriteOnly); + file.close(); +} + +static QString baseTestDir() +{ + return Utils::TemporaryDirectory::masterDirectoryPath() + "/qtc_cppheadersource/"; +} + +static FilePaths findFilesInProject(const QStringList &names, const Project *project, + FileType fileType) +{ + if (debug) + qDebug() << Q_FUNC_INFO << names << project; + + if (!project) + return {}; + + const auto filter = [&](const Node *n) { + const auto fn = n->asFileNode(); + return fn && fn->fileType() == fileType && names.contains(fn->filePath().fileName()); + }; + return project->files(filter); +} + +// Return the suffixes that should be checked when trying to find a +// source belonging to a header and vice versa +static QStringList matchingCandidateSuffixes(ProjectFile::Kind kind) +{ + using namespace Utils::Constants; + switch (kind) { + case ProjectFile::AmbiguousHeader: + case ProjectFile::CHeader: + case ProjectFile::CXXHeader: + case ProjectFile::ObjCHeader: + case ProjectFile::ObjCXXHeader: + return mimeTypeForName(C_SOURCE_MIMETYPE).suffixes() + + mimeTypeForName(CPP_SOURCE_MIMETYPE).suffixes() + + mimeTypeForName(OBJECTIVE_C_SOURCE_MIMETYPE).suffixes() + + mimeTypeForName(OBJECTIVE_CPP_SOURCE_MIMETYPE).suffixes() + + mimeTypeForName(CUDA_SOURCE_MIMETYPE).suffixes(); + case ProjectFile::CSource: + case ProjectFile::ObjCSource: + return mimeTypeForName(C_HEADER_MIMETYPE).suffixes(); + case ProjectFile::CXXSource: + case ProjectFile::ObjCXXSource: + case ProjectFile::CudaSource: + case ProjectFile::OpenCLSource: + return mimeTypeForName(CPP_HEADER_MIMETYPE).suffixes(); + default: + return {}; + } +} + +static QStringList baseNameWithAllSuffixes(const QString &baseName, const QStringList &suffixes) +{ + QStringList result; + const QChar dot = QLatin1Char('.'); + for (const QString &suffix : suffixes) { + QString fileName = baseName; + fileName += dot; + fileName += suffix; + result += fileName; + } + return result; +} + +static QStringList baseNamesWithAllPrefixes(const CppFileSettings &settings, + const QStringList &baseNames, bool isHeader) +{ + QStringList result; + const QStringList &sourcePrefixes = settings.sourcePrefixes; + const QStringList &headerPrefixes = settings.headerPrefixes; + + for (const QString &name : baseNames) { + for (const QString &prefix : isHeader ? headerPrefixes : sourcePrefixes) { + if (name.startsWith(prefix)) { + QString nameWithoutPrefix = name.mid(prefix.size()); + result += nameWithoutPrefix; + for (const QString &prefix : isHeader ? sourcePrefixes : headerPrefixes) + result += prefix + nameWithoutPrefix; + } + } + for (const QString &prefix : isHeader ? sourcePrefixes : headerPrefixes) + result += prefix + name; + + } + return result; +} + +static QStringList baseDirWithAllDirectories(const QDir &baseDir, const QStringList &directories) +{ + QStringList result; + for (const QString &dir : directories) + result << QDir::cleanPath(baseDir.absoluteFilePath(dir)); + return result; +} + +static int commonFilePathLength(const QString &s1, const QString &s2) +{ + int length = qMin(s1.length(), s2.length()); + for (int i = 0; i < length; ++i) + if (HostOsInfo::fileNameCaseSensitivity() == Qt::CaseSensitive) { + if (s1[i] != s2[i]) + return i; + } else { + if (s1[i].toLower() != s2[i].toLower()) + return i; + } + return length; +} + +static FilePath correspondingHeaderOrSourceInProject(const FilePath &filePath, + const QStringList &candidateFileNames, + const Project *project, + FileType fileType, + CacheUsage cacheUsage) +{ + const FilePaths projectFiles = findFilesInProject(candidateFileNames, project, fileType); + + // Find the file having the most common path with fileName + FilePath bestFilePath; + int compareValue = 0; + for (const FilePath &projectFile : projectFiles) { + int value = commonFilePathLength(filePath.toString(), projectFile.toString()); + if (value > compareValue) { + compareValue = value; + bestFilePath = projectFile; + } + } + if (!bestFilePath.isEmpty()) { + QTC_ASSERT(bestFilePath.isFile(), return {}); + if (cacheUsage == CacheUsage::ReadWrite) { + m_headerSourceMapping[filePath] = bestFilePath; + m_headerSourceMapping[bestFilePath] = filePath; + } + return bestFilePath; + } + + return {}; +} + +FilePath correspondingHeaderOrSource(const FilePath &filePath, bool *wasHeader, CacheUsage cacheUsage) +{ + ProjectFile::Kind kind = ProjectFile::classify(filePath.fileName()); + const bool isHeader = ProjectFile::isHeader(kind); + if (wasHeader) + *wasHeader = isHeader; + if (const auto it = m_headerSourceMapping.constFind(filePath); + it != m_headerSourceMapping.constEnd()) { + return it.value(); + } + + Project * const projectForFile = ProjectManager::projectForFile(filePath); + const CppFileSettings settings = cppFileSettingsForProject(projectForFile); + + if (debug) + qDebug() << Q_FUNC_INFO << filePath.fileName() << kind; + + if (kind == ProjectFile::Unsupported) + return {}; + + const QString baseName = filePath.completeBaseName(); + const QString privateHeaderSuffix = QLatin1String("_p"); + const QStringList suffixes = matchingCandidateSuffixes(kind); + + QStringList candidateFileNames = baseNameWithAllSuffixes(baseName, suffixes); + if (isHeader) { + if (baseName.endsWith(privateHeaderSuffix)) { + QString sourceBaseName = baseName; + sourceBaseName.truncate(sourceBaseName.size() - privateHeaderSuffix.size()); + candidateFileNames += baseNameWithAllSuffixes(sourceBaseName, suffixes); + } + } else { + QString privateHeaderBaseName = baseName; + privateHeaderBaseName.append(privateHeaderSuffix); + candidateFileNames += baseNameWithAllSuffixes(privateHeaderBaseName, suffixes); + } + + const QDir absoluteDir = filePath.toFileInfo().absoluteDir(); + QStringList candidateDirs(absoluteDir.absolutePath()); + // If directory is not root, try matching against its siblings + const QStringList searchPaths = isHeader ? settings.sourceSearchPaths + : settings.headerSearchPaths; + candidateDirs += baseDirWithAllDirectories(absoluteDir, searchPaths); + + candidateFileNames += baseNamesWithAllPrefixes(settings, candidateFileNames, isHeader); + + // Try to find a file in the same or sibling directories first + for (const QString &candidateDir : std::as_const(candidateDirs)) { + for (const QString &candidateFileName : std::as_const(candidateFileNames)) { + const FilePath candidateFilePath + = FilePath::fromString(candidateDir + '/' + candidateFileName).normalizedPathName(); + if (candidateFilePath.isFile()) { + if (cacheUsage == CacheUsage::ReadWrite) { + m_headerSourceMapping[filePath] = candidateFilePath; + if (!isHeader || !baseName.endsWith(privateHeaderSuffix)) + m_headerSourceMapping[candidateFilePath] = filePath; + } + return candidateFilePath; + } + } + } + + // Find files in the current project + Project *currentProject = projectForFile; + if (!projectForFile) + currentProject = ProjectTree::currentProject(); + const FileType requestedFileType = isHeader ? FileType::Source : FileType::Header; + if (currentProject) { + const FilePath path = correspondingHeaderOrSourceInProject( + filePath, candidateFileNames, currentProject, requestedFileType, cacheUsage); + if (!path.isEmpty()) + return path; + + // Find files in other projects + } else { + const QList<ProjectInfo::ConstPtr> projectInfos = CppModelManager::projectInfos(); + for (const ProjectInfo::ConstPtr &projectInfo : projectInfos) { + const Project *project = projectForProjectInfo(*projectInfo); + if (project == currentProject) + continue; // We have already checked the current project. + + const FilePath path = correspondingHeaderOrSourceInProject( + filePath, candidateFileNames, project, requestedFileType, cacheUsage); + if (!path.isEmpty()) + return path; + } + } + + return {}; +} + +} // CppEditor + +#ifdef WITH_TESTS + +namespace CppEditor::Internal { + +class HeaderSourceTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void test_data(); + void test(); +}; + +void HeaderSourceTest::test() +{ + QFETCH(QString, sourceFileName); + QFETCH(QString, headerFileName); + + CppEditor::Tests::TemporaryDir temporaryDir; + QVERIFY(temporaryDir.isValid()); + + const QDir path = QDir(temporaryDir.path() + QLatin1Char('/') + _(QTest::currentDataTag())); + const FilePath sourcePath = FilePath::fromString(path.absoluteFilePath(sourceFileName)); + const FilePath headerPath = FilePath::fromString(path.absoluteFilePath(headerFileName)); + createTempFile(sourcePath); + createTempFile(headerPath); + + bool wasHeader; + clearHeaderSourceCache(); + QCOMPARE(correspondingHeaderOrSource(sourcePath, &wasHeader, CacheUsage::ReadWrite), headerPath); + QVERIFY(!wasHeader); + clearHeaderSourceCache(); + QCOMPARE(correspondingHeaderOrSource(headerPath, &wasHeader, CacheUsage::ReadWrite), sourcePath); + QVERIFY(wasHeader); +} + +void HeaderSourceTest::test_data() +{ + QTest::addColumn<QString>("sourceFileName"); + QTest::addColumn<QString>("headerFileName"); + QTest::newRow("samedir") << _("foo.cpp") << _("foo.h"); + QTest::newRow("includesub") << _("foo.cpp") << _("include/foo.h"); + QTest::newRow("headerprefix") << _("foo.cpp") << _("testh_foo.h"); + QTest::newRow("sourceprefixwsub") << _("testc_foo.cpp") << _("include/foo.h"); + QTest::newRow("sourceAndHeaderPrefixWithBothsub") << _("src/testc_foo.cpp") << _("include/testh_foo.h"); +} + +void HeaderSourceTest::initTestCase() +{ + QDir(baseTestDir()).mkpath(_(".")); + CppFileSettings &fs = globalCppFileSettings(); + fs.headerSearchPaths.append(QLatin1String("include")); + fs.headerSearchPaths.append(QLatin1String("../include")); + fs.sourceSearchPaths.append(QLatin1String("src")); + fs.sourceSearchPaths.append(QLatin1String("../src")); + fs.headerPrefixes.append(QLatin1String("testh_")); + fs.sourcePrefixes.append(QLatin1String("testc_")); +} + +void HeaderSourceTest::cleanupTestCase() +{ + Utils::FilePath::fromString(baseTestDir()).removeRecursively(); + CppFileSettings &fs = globalCppFileSettings(); + fs.headerSearchPaths.removeLast(); + fs.headerSearchPaths.removeLast(); + fs.sourceSearchPaths.removeLast(); + fs.sourceSearchPaths.removeLast(); + fs.headerPrefixes.removeLast(); + fs.sourcePrefixes.removeLast(); +} + +QObject *createCppHeaderSourceTest() +{ + return new HeaderSourceTest; +} + +} // namespace CppEditor::Internal + +#include "cppheadersource.moc" + +#endif // WITH_TESTS diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppheadersource.h index 8dde52b15e..a408e4aac3 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppheadersource.h @@ -1,10 +1,16 @@ -// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once +#include <QObject> + namespace CppEditor::Internal { void clearHeaderSourceCache(); +#ifdef WITH_TESTS +QObject *createCppHeaderSourceTest(); +#endif + } // CppEditor::Internal diff --git a/src/plugins/cppeditor/cppheadersource_test.cpp b/src/plugins/cppeditor/cppheadersource_test.cpp deleted file mode 100644 index 2b6621c74f..0000000000 --- a/src/plugins/cppeditor/cppheadersource_test.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (C) 2016 Orgad Shaneh <orgads@gmail.com>. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "cppheadersource_test.h" - -#include "cppeditorplugin.h" -#include "cpptoolsreuse.h" -#include "cpptoolstestcase.h" -#include "cppfilesettingspage.h" - -#include <utils/fileutils.h> -#include <utils/temporarydirectory.h> - -#include <QDir> -#include <QtTest> - -using namespace Utils; - -static inline QString _(const QByteArray &ba) { return QString::fromLatin1(ba, ba.size()); } - -static void createTempFile(const FilePath &filePath) -{ - QString fileName = filePath.toString(); - QFile file(fileName); - QDir(QFileInfo(fileName).absolutePath()).mkpath(_(".")); - file.open(QFile::WriteOnly); - file.close(); -} - -static QString baseTestDir() -{ - return Utils::TemporaryDirectory::masterDirectoryPath() + "/qtc_cppheadersource/"; -} - -namespace CppEditor::Internal { - -void HeaderSourceTest::test() -{ - QFETCH(QString, sourceFileName); - QFETCH(QString, headerFileName); - - CppEditor::Tests::TemporaryDir temporaryDir; - QVERIFY(temporaryDir.isValid()); - - const QDir path = QDir(temporaryDir.path() + QLatin1Char('/') + _(QTest::currentDataTag())); - const FilePath sourcePath = FilePath::fromString(path.absoluteFilePath(sourceFileName)); - const FilePath headerPath = FilePath::fromString(path.absoluteFilePath(headerFileName)); - createTempFile(sourcePath); - createTempFile(headerPath); - - bool wasHeader; - clearHeaderSourceCache(); - QCOMPARE(correspondingHeaderOrSource(sourcePath, &wasHeader), headerPath); - QVERIFY(!wasHeader); - clearHeaderSourceCache(); - QCOMPARE(correspondingHeaderOrSource(headerPath, &wasHeader), sourcePath); - QVERIFY(wasHeader); -} - -void HeaderSourceTest::test_data() -{ - QTest::addColumn<QString>("sourceFileName"); - QTest::addColumn<QString>("headerFileName"); - QTest::newRow("samedir") << _("foo.cpp") << _("foo.h"); - QTest::newRow("includesub") << _("foo.cpp") << _("include/foo.h"); - QTest::newRow("headerprefix") << _("foo.cpp") << _("testh_foo.h"); - QTest::newRow("sourceprefixwsub") << _("testc_foo.cpp") << _("include/foo.h"); - QTest::newRow("sourceAndHeaderPrefixWithBothsub") << _("src/testc_foo.cpp") << _("include/testh_foo.h"); -} - -void HeaderSourceTest::initTestCase() -{ - QDir(baseTestDir()).mkpath(_(".")); - CppFileSettings &fs = globalCppFileSettings(); - fs.headerSearchPaths.append(QLatin1String("include")); - fs.headerSearchPaths.append(QLatin1String("../include")); - fs.sourceSearchPaths.append(QLatin1String("src")); - fs.sourceSearchPaths.append(QLatin1String("../src")); - fs.headerPrefixes.append(QLatin1String("testh_")); - fs.sourcePrefixes.append(QLatin1String("testc_")); -} - -void HeaderSourceTest::cleanupTestCase() -{ - Utils::FilePath::fromString(baseTestDir()).removeRecursively(); - CppFileSettings &fs = globalCppFileSettings(); - fs.headerSearchPaths.removeLast(); - fs.headerSearchPaths.removeLast(); - fs.sourceSearchPaths.removeLast(); - fs.sourceSearchPaths.removeLast(); - fs.headerPrefixes.removeLast(); - fs.sourcePrefixes.removeLast(); -} - -} // namespace CppEditor::Internal diff --git a/src/plugins/cppeditor/cppheadersource_test.h b/src/plugins/cppeditor/cppheadersource_test.h deleted file mode 100644 index 5f11c0272e..0000000000 --- a/src/plugins/cppeditor/cppheadersource_test.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include <QObject> - -namespace CppEditor::Internal { - -class HeaderSourceTest : public QObject -{ - Q_OBJECT - -private slots: - void initTestCase(); - void cleanupTestCase(); - - void test_data(); - void test(); -}; - -} // namespace CppEditor::Internal diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp index fd76b8522a..50a9c2c48a 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp @@ -40,7 +40,6 @@ #include <QVBoxLayout> #ifdef WITH_TESTS -#include "cppeditorplugin.h" #include "cppquickfix_test.h" #include <QtTest> #endif diff --git a/src/plugins/cppeditor/cpplocatorfilter.cpp b/src/plugins/cppeditor/cpplocatorfilter.cpp index c6d1be6663..8fab8f4dcd 100644 --- a/src/plugins/cppeditor/cpplocatorfilter.cpp +++ b/src/plugins/cppeditor/cpplocatorfilter.cpp @@ -4,7 +4,6 @@ #include "cpplocatorfilter.h" #include "cppeditorconstants.h" -#include "cppeditorplugin.h" #include "cppeditortr.h" #include "cpplocatordata.h" #include "cppmodelmanager.h" diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 3b3d88f149..b0064ab790 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -4,7 +4,6 @@ #include "cppquickfix_test.h" #include "cppcodestylepreferences.h" -#include "cppeditorplugin.h" #include "cppeditorwidget.h" #include "cppmodelmanager.h" #include "cppquickfixassistant.h" diff --git a/src/plugins/cppeditor/cpptoolsjsextension.cpp b/src/plugins/cppeditor/cpptoolsjsextension.cpp index e5b3499a96..607744eec1 100644 --- a/src/plugins/cppeditor/cpptoolsjsextension.cpp +++ b/src/plugins/cppeditor/cpptoolsjsextension.cpp @@ -3,7 +3,6 @@ #include "cpptoolsjsextension.h" -#include "cppeditorplugin.h" #include "cppfilesettingspage.h" #include "cpplocatordata.h" #include "cppworkingcopy.h" diff --git a/src/plugins/cppeditor/fileandtokenactions_test.cpp b/src/plugins/cppeditor/fileandtokenactions_test.cpp index ca6411116f..f341cc1808 100644 --- a/src/plugins/cppeditor/fileandtokenactions_test.cpp +++ b/src/plugins/cppeditor/fileandtokenactions_test.cpp @@ -3,14 +3,11 @@ #include "fileandtokenactions_test.h" -#include "cppeditorplugin.h" #include "cppeditorwidget.h" #include "cppquickfix.h" #include "cppquickfixassistant.h" -#include "cppquickfixes.h" #include "cppinsertvirtualmethods.h" #include "cppmodelmanager.h" -#include "cpptoolsreuse.h" #include "cpptoolstestcase.h" #include "cpptypehierarchy.h" #include "cppworkingcopy.h" diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp index 0c06f86783..d18e8dc391 100644 --- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp +++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp @@ -4,12 +4,9 @@ #include "followsymbol_switchmethoddecldef_test.h" #include "cppcodemodelsettings.h" -#include "cppeditorplugin.h" #include "cppeditorwidget.h" -#include "cppelementevaluator.h" #include "cppfollowsymbolundercursor.h" #include "cppmodelmanager.h" -#include "cpptoolsreuse.h" #include "cpptoolstestcase.h" #include "cppvirtualfunctionassistprovider.h" #include "cppvirtualfunctionproposalitem.h" diff --git a/src/plugins/designer/qtcreatorintegration.cpp b/src/plugins/designer/qtcreatorintegration.cpp index 0428067105..267e0ddeeb 100644 --- a/src/plugins/designer/qtcreatorintegration.cpp +++ b/src/plugins/designer/qtcreatorintegration.cpp @@ -12,7 +12,6 @@ #include <designer/cpp/formclasswizardpage.h> #include <cppeditor/cppeditorconstants.h> -#include <cppeditor/cppeditorplugin.h> #include <cppeditor/cppeditorwidget.h> #include <cppeditor/cppmodelmanager.h> #include <cppeditor/cppsemanticinfo.h> |