forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -40,7 +40,7 @@ add_qtc_plugin(CppEditor
|
|||||||
cppeditorconstants.h
|
cppeditorconstants.h
|
||||||
cppeditordocument.cpp cppeditordocument.h
|
cppeditordocument.cpp cppeditordocument.h
|
||||||
cppeditoroutline.cpp cppeditoroutline.h
|
cppeditoroutline.cpp cppeditoroutline.h
|
||||||
cppeditorplugin.cpp cppeditorplugin.h
|
cppeditorplugin.cpp
|
||||||
cppeditorwidget.cpp cppeditorwidget.h
|
cppeditorwidget.cpp cppeditorwidget.h
|
||||||
cppelementevaluator.cpp cppelementevaluator.h
|
cppelementevaluator.cpp cppelementevaluator.h
|
||||||
cppfileiterationorder.cpp cppfileiterationorder.h
|
cppfileiterationorder.cpp cppfileiterationorder.h
|
||||||
@@ -49,6 +49,7 @@ add_qtc_plugin(CppEditor
|
|||||||
cppfollowsymbolundercursor.cpp cppfollowsymbolundercursor.h
|
cppfollowsymbolundercursor.cpp cppfollowsymbolundercursor.h
|
||||||
cppfunctiondecldeflink.cpp cppfunctiondecldeflink.h
|
cppfunctiondecldeflink.cpp cppfunctiondecldeflink.h
|
||||||
cppfunctionparamrenaminghandler.cpp cppfunctionparamrenaminghandler.h
|
cppfunctionparamrenaminghandler.cpp cppfunctionparamrenaminghandler.h
|
||||||
|
cppheadersource.cpp cppheadersource.h
|
||||||
cpphighlighter.cpp cpphighlighter.h
|
cpphighlighter.cpp cpphighlighter.h
|
||||||
cppincludehierarchy.cpp cppincludehierarchy.h
|
cppincludehierarchy.cpp cppincludehierarchy.h
|
||||||
cppincludesfilter.cpp cppincludesfilter.h
|
cppincludesfilter.cpp cppincludesfilter.h
|
||||||
@@ -121,7 +122,6 @@ extend_qtc_plugin(CppEditor
|
|||||||
cppcodegen_test.cpp cppcodegen_test.h
|
cppcodegen_test.cpp cppcodegen_test.h
|
||||||
cppcompletion_test.cpp cppcompletion_test.h
|
cppcompletion_test.cpp cppcompletion_test.h
|
||||||
cppdoxygen_test.cpp cppdoxygen_test.h
|
cppdoxygen_test.cpp cppdoxygen_test.h
|
||||||
cppheadersource_test.cpp cppheadersource_test.h
|
|
||||||
cppincludehierarchy_test.cpp cppincludehierarchy_test.h
|
cppincludehierarchy_test.cpp cppincludehierarchy_test.h
|
||||||
cpplocalsymbols_test.cpp cpplocalsymbols_test.h
|
cpplocalsymbols_test.cpp cpplocalsymbols_test.h
|
||||||
cpplocatorfilter_test.cpp cpplocatorfilter_test.h
|
cpplocatorfilter_test.cpp cpplocatorfilter_test.h
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include "cppchecksymbols.h"
|
#include "cppchecksymbols.h"
|
||||||
#include "cppcodemodelsettings.h"
|
#include "cppcodemodelsettings.h"
|
||||||
#include "cppeditordocument.h"
|
#include "cppeditordocument.h"
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
#include "cpptoolsreuse.h"
|
#include "cpptoolsreuse.h"
|
||||||
#include "cppworkingcopy.h"
|
#include "cppworkingcopy.h"
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
#include "cppeditorconstants.h"
|
#include "cppeditorconstants.h"
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppeditorwidget.h"
|
#include "cppeditorwidget.h"
|
||||||
|
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ QtcPlugin {
|
|||||||
"cppeditoroutline.cpp",
|
"cppeditoroutline.cpp",
|
||||||
"cppeditoroutline.h",
|
"cppeditoroutline.h",
|
||||||
"cppeditorplugin.cpp",
|
"cppeditorplugin.cpp",
|
||||||
"cppeditorplugin.h",
|
|
||||||
"cppelementevaluator.cpp",
|
"cppelementevaluator.cpp",
|
||||||
"cppelementevaluator.h",
|
"cppelementevaluator.h",
|
||||||
"cppfileiterationorder.cpp",
|
"cppfileiterationorder.cpp",
|
||||||
@@ -110,6 +109,8 @@ QtcPlugin {
|
|||||||
"cppfunctiondecldeflink.h",
|
"cppfunctiondecldeflink.h",
|
||||||
"cppfunctionparamrenaminghandler.cpp",
|
"cppfunctionparamrenaminghandler.cpp",
|
||||||
"cppfunctionparamrenaminghandler.h",
|
"cppfunctionparamrenaminghandler.h",
|
||||||
|
"cppheadersource.cpp",
|
||||||
|
"cppheadersource.h",
|
||||||
"cpphighlighter.cpp",
|
"cpphighlighter.cpp",
|
||||||
"cpphighlighter.h",
|
"cpphighlighter.h",
|
||||||
"cppincludehierarchy.cpp",
|
"cppincludehierarchy.cpp",
|
||||||
@@ -252,8 +253,6 @@ QtcPlugin {
|
|||||||
"cppcompletion_test.h",
|
"cppcompletion_test.h",
|
||||||
"cppdoxygen_test.cpp",
|
"cppdoxygen_test.cpp",
|
||||||
"cppdoxygen_test.h",
|
"cppdoxygen_test.h",
|
||||||
"cppheadersource_test.cpp",
|
|
||||||
"cppheadersource_test.h",
|
|
||||||
"cppincludehierarchy_test.cpp",
|
"cppincludehierarchy_test.cpp",
|
||||||
"cppincludehierarchy_test.h",
|
"cppincludehierarchy_test.h",
|
||||||
"cpplocalsymbols_test.cpp",
|
"cpplocalsymbols_test.cpp",
|
||||||
|
|||||||
@@ -6,11 +6,9 @@
|
|||||||
#include "baseeditordocumentparser.h"
|
#include "baseeditordocumentparser.h"
|
||||||
#include "cppcodeformatter.h"
|
#include "cppcodeformatter.h"
|
||||||
#include "cppeditorconstants.h"
|
#include "cppeditorconstants.h"
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppeditortr.h"
|
#include "cppeditortr.h"
|
||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
#include "cppeditorconstants.h"
|
#include "cppeditorconstants.h"
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppeditortr.h"
|
#include "cppeditortr.h"
|
||||||
#include "cpphighlighter.h"
|
#include "cpphighlighter.h"
|
||||||
#include "cppquickfixassistant.h"
|
#include "cppquickfixassistant.h"
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
// Copyright (C) 2016 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
|
|
||||||
#include "cppautocompleter.h"
|
#include "cppautocompleter.h"
|
||||||
#include "cppcodemodelinspectordialog.h"
|
#include "cppcodemodelinspectordialog.h"
|
||||||
#include "cppcodemodelsettings.h"
|
#include "cppcodemodelsettings.h"
|
||||||
@@ -14,9 +12,9 @@
|
|||||||
#include "cppeditorwidget.h"
|
#include "cppeditorwidget.h"
|
||||||
#include "cppfilesettingspage.h"
|
#include "cppfilesettingspage.h"
|
||||||
#include "cppincludehierarchy.h"
|
#include "cppincludehierarchy.h"
|
||||||
|
#include "cppheadersource.h"
|
||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
#include "cppoutline.h"
|
#include "cppoutline.h"
|
||||||
#include "cppprojectfile.h"
|
|
||||||
#include "cppprojectupdater.h"
|
#include "cppprojectupdater.h"
|
||||||
#include "cppquickfixes.h"
|
#include "cppquickfixes.h"
|
||||||
#include "cppquickfixprojectsettingswidget.h"
|
#include "cppquickfixprojectsettingswidget.h"
|
||||||
@@ -24,7 +22,6 @@
|
|||||||
#include "cpptoolsreuse.h"
|
#include "cpptoolsreuse.h"
|
||||||
#include "cpptoolssettings.h"
|
#include "cpptoolssettings.h"
|
||||||
#include "cpptypehierarchy.h"
|
#include "cpptypehierarchy.h"
|
||||||
#include "projectinfo.h"
|
|
||||||
#include "resourcepreviewhoverhandler.h"
|
#include "resourcepreviewhoverhandler.h"
|
||||||
|
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
@@ -32,7 +29,6 @@
|
|||||||
#include "cppcodegen_test.h"
|
#include "cppcodegen_test.h"
|
||||||
#include "cppcompletion_test.h"
|
#include "cppcompletion_test.h"
|
||||||
#include "cppdoxygen_test.h"
|
#include "cppdoxygen_test.h"
|
||||||
#include "cppheadersource_test.h"
|
|
||||||
#include "cpphighlighter.h"
|
#include "cpphighlighter.h"
|
||||||
#include "cppincludehierarchy_test.h"
|
#include "cppincludehierarchy_test.h"
|
||||||
#include "cppinsertvirtualmethods.h"
|
#include "cppinsertvirtualmethods.h"
|
||||||
@@ -89,7 +85,6 @@
|
|||||||
#include <utils/mimeconstants.h>
|
#include <utils/mimeconstants.h>
|
||||||
#include <utils/mimeutils.h>
|
#include <utils/mimeutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/stringtable.h>
|
|
||||||
#include <utils/theme/theme.h>
|
#include <utils/theme/theme.h>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
@@ -106,11 +101,7 @@ using namespace ProjectExplorer;
|
|||||||
using namespace TextEditor;
|
using namespace TextEditor;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
namespace CppEditor {
|
namespace CppEditor::Internal {
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
enum { QUICKFIX_INTERVAL = 20 };
|
|
||||||
enum { debug = 0 };
|
|
||||||
|
|
||||||
static CppEditorWidget *currentCppEditorWidget()
|
static CppEditorWidget *currentCppEditorWidget()
|
||||||
{
|
{
|
||||||
@@ -183,8 +174,6 @@ public:
|
|||||||
CppProjectUpdaterFactory m_cppProjectUpdaterFactory;
|
CppProjectUpdaterFactory m_cppProjectUpdaterFactory;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QHash<FilePath, FilePath> m_headerSourceMapping;
|
|
||||||
|
|
||||||
class CppEditorPlugin final : public ExtensionSystem::IPlugin
|
class CppEditorPlugin final : public ExtensionSystem::IPlugin
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -498,7 +487,7 @@ void CppEditorPlugin::registerTests()
|
|||||||
addTest<CppHighlighterTest>();
|
addTest<CppHighlighterTest>();
|
||||||
addTest<FunctionUtilsTest>();
|
addTest<FunctionUtilsTest>();
|
||||||
addTest<HeaderPathFilterTest>();
|
addTest<HeaderPathFilterTest>();
|
||||||
addTest<HeaderSourceTest>();
|
addTestCreator(createCppHeaderSourceTest);
|
||||||
addTest<IncludeGroupsTest>();
|
addTest<IncludeGroupsTest>();
|
||||||
addTest<LocalSymbolsTest>();
|
addTest<LocalSymbolsTest>();
|
||||||
addTest<LocatorFilterTest>();
|
addTest<LocatorFilterTest>();
|
||||||
@@ -551,239 +540,6 @@ void CppEditorPluginPrivate::inspectCppCodeModel()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearHeaderSourceCache()
|
} // CppEditor::Internal
|
||||||
{
|
|
||||||
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
|
|
||||||
|
|
||||||
#include "cppeditorplugin.moc"
|
#include "cppeditorplugin.moc"
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "cppeditorconstants.h"
|
#include "cppeditorconstants.h"
|
||||||
#include "cppeditordocument.h"
|
#include "cppeditordocument.h"
|
||||||
#include "cppeditoroutline.h"
|
#include "cppeditoroutline.h"
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppeditortr.h"
|
#include "cppeditortr.h"
|
||||||
#include "cppfunctiondecldeflink.h"
|
#include "cppfunctiondecldeflink.h"
|
||||||
#include "cppfunctionparamrenaminghandler.h"
|
#include "cppfunctionparamrenaminghandler.h"
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include "cppfilesettingspage.h"
|
#include "cppfilesettingspage.h"
|
||||||
|
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppeditortr.h"
|
#include "cppeditortr.h"
|
||||||
|
#include "cppheadersource.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
|||||||
368
src/plugins/cppeditor/cppheadersource.cpp
Normal file
368
src/plugins/cppeditor/cppheadersource.cpp
Normal file
@@ -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
|
||||||
@@ -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
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
namespace CppEditor::Internal {
|
namespace CppEditor::Internal {
|
||||||
|
|
||||||
void clearHeaderSourceCache();
|
void clearHeaderSourceCache();
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
QObject *createCppHeaderSourceTest();
|
||||||
|
#endif
|
||||||
|
|
||||||
} // CppEditor::Internal
|
} // CppEditor::Internal
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -40,7 +40,6 @@
|
|||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppquickfix_test.h"
|
#include "cppquickfix_test.h"
|
||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "cpplocatorfilter.h"
|
#include "cpplocatorfilter.h"
|
||||||
|
|
||||||
#include "cppeditorconstants.h"
|
#include "cppeditorconstants.h"
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppeditortr.h"
|
#include "cppeditortr.h"
|
||||||
#include "cpplocatordata.h"
|
#include "cpplocatordata.h"
|
||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "cppquickfix_test.h"
|
#include "cppquickfix_test.h"
|
||||||
|
|
||||||
#include "cppcodestylepreferences.h"
|
#include "cppcodestylepreferences.h"
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppeditorwidget.h"
|
#include "cppeditorwidget.h"
|
||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
#include "cppquickfixassistant.h"
|
#include "cppquickfixassistant.h"
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "cpptoolsjsextension.h"
|
#include "cpptoolsjsextension.h"
|
||||||
|
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppfilesettingspage.h"
|
#include "cppfilesettingspage.h"
|
||||||
#include "cpplocatordata.h"
|
#include "cpplocatordata.h"
|
||||||
#include "cppworkingcopy.h"
|
#include "cppworkingcopy.h"
|
||||||
|
|||||||
@@ -3,14 +3,11 @@
|
|||||||
|
|
||||||
#include "fileandtokenactions_test.h"
|
#include "fileandtokenactions_test.h"
|
||||||
|
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppeditorwidget.h"
|
#include "cppeditorwidget.h"
|
||||||
#include "cppquickfix.h"
|
#include "cppquickfix.h"
|
||||||
#include "cppquickfixassistant.h"
|
#include "cppquickfixassistant.h"
|
||||||
#include "cppquickfixes.h"
|
|
||||||
#include "cppinsertvirtualmethods.h"
|
#include "cppinsertvirtualmethods.h"
|
||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
#include "cpptoolsreuse.h"
|
|
||||||
#include "cpptoolstestcase.h"
|
#include "cpptoolstestcase.h"
|
||||||
#include "cpptypehierarchy.h"
|
#include "cpptypehierarchy.h"
|
||||||
#include "cppworkingcopy.h"
|
#include "cppworkingcopy.h"
|
||||||
|
|||||||
@@ -4,12 +4,9 @@
|
|||||||
#include "followsymbol_switchmethoddecldef_test.h"
|
#include "followsymbol_switchmethoddecldef_test.h"
|
||||||
|
|
||||||
#include "cppcodemodelsettings.h"
|
#include "cppcodemodelsettings.h"
|
||||||
#include "cppeditorplugin.h"
|
|
||||||
#include "cppeditorwidget.h"
|
#include "cppeditorwidget.h"
|
||||||
#include "cppelementevaluator.h"
|
|
||||||
#include "cppfollowsymbolundercursor.h"
|
#include "cppfollowsymbolundercursor.h"
|
||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
#include "cpptoolsreuse.h"
|
|
||||||
#include "cpptoolstestcase.h"
|
#include "cpptoolstestcase.h"
|
||||||
#include "cppvirtualfunctionassistprovider.h"
|
#include "cppvirtualfunctionassistprovider.h"
|
||||||
#include "cppvirtualfunctionproposalitem.h"
|
#include "cppvirtualfunctionproposalitem.h"
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include <designer/cpp/formclasswizardpage.h>
|
#include <designer/cpp/formclasswizardpage.h>
|
||||||
|
|
||||||
#include <cppeditor/cppeditorconstants.h>
|
#include <cppeditor/cppeditorconstants.h>
|
||||||
#include <cppeditor/cppeditorplugin.h>
|
|
||||||
#include <cppeditor/cppeditorwidget.h>
|
#include <cppeditor/cppeditorwidget.h>
|
||||||
#include <cppeditor/cppmodelmanager.h>
|
#include <cppeditor/cppmodelmanager.h>
|
||||||
#include <cppeditor/cppsemanticinfo.h>
|
#include <cppeditor/cppsemanticinfo.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user