CppTools: Turn some classes into pure value types

ProjectInfo, ProjectPart and ProjectUpdateInfo used to carry pointers
to Project and/or Toolchain, even though they were used in contexts
where these pointers were either unsafe to access or not guaranteed to
be valid anymore, which made their use difficult and error-prone.
We turn these classes into pure value types by copying in all relevant
information before the first async operation takes place.

Fixes: QTCREATORBUG-25678
Change-Id: I1914b0dbda6c7dfba6c95e5e92f2d69977755590
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
Christian Kandeler
2021-05-07 16:10:07 +02:00
parent 3143ba79e3
commit 33108795d6
61 changed files with 1086 additions and 958 deletions

View File

@@ -109,8 +109,7 @@ void AutoTestUnitTests::testCodeParser()
QFETCH(int, expectedDataTagsCount);
CppTools::Tests::ProjectOpenerAndCloser projectManager;
const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true, m_kit);
QVERIFY(projectInfo.isValid());
QVERIFY(projectManager.open(projectFilePath, true, m_kit));
QSignalSpy parserSpy(m_model->parser(), SIGNAL(parsingFinished()));
QSignalSpy modelUpdateSpy(m_model, SIGNAL(sweepingDone()));
@@ -160,8 +159,7 @@ void AutoTestUnitTests::testCodeParserSwitchStartup()
CppTools::Tests::ProjectOpenerAndCloser projectManager;
for (int i = 0; i < projectFilePaths.size(); ++i) {
qDebug() << "Opening project" << projectFilePaths.at(i);
CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePaths.at(i), true, m_kit);
QVERIFY(projectInfo.isValid());
QVERIFY(projectManager.open(projectFilePaths.at(i), true, m_kit));
QSignalSpy parserSpy(m_model->parser(), SIGNAL(parsingFinished()));
QSignalSpy modelUpdateSpy(m_model, SIGNAL(sweepingDone()));
@@ -208,8 +206,7 @@ void AutoTestUnitTests::testCodeParserGTest()
QFETCH(QString, projectFilePath);
CppTools::Tests::ProjectOpenerAndCloser projectManager;
CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true, m_kit);
QVERIFY(projectInfo.isValid());
QVERIFY(projectManager.open(projectFilePath, true, m_kit));
QSignalSpy parserSpy(m_model->parser(), SIGNAL(parsingFinished()));
QSignalSpy modelUpdateSpy(m_model, SIGNAL(sweepingDone()));
@@ -258,8 +255,9 @@ void AutoTestUnitTests::testCodeParserBoostTest()
QFETCH(QString, projectFilePath);
QFETCH(QString, extension);
CppTools::Tests::ProjectOpenerAndCloser projectManager;
CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true, m_kit);
QVERIFY(projectInfo.isValid());
const CppTools::ProjectInfo::Ptr projectInfo
= projectManager.open(projectFilePath, true, m_kit);
QVERIFY(projectInfo);
QSignalSpy parserSpy(m_model->parser(), SIGNAL(parsingFinished()));
QSignalSpy modelUpdateSpy(m_model, SIGNAL(sweepingDone()));
@@ -268,10 +266,7 @@ void AutoTestUnitTests::testCodeParserBoostTest()
QCOMPARE(m_model->boostTestNamesCount(), 5);
auto project = projectInfo.project();
QVERIFY(project);
const Utils::FilePath basePath = project->projectFilePath().absolutePath();
const Utils::FilePath basePath = projectInfo->projectRoot();
QVERIFY(!basePath.isEmpty());
QMap<QString, int> expectedSuitesAndTests;

View File

@@ -524,9 +524,11 @@ QSet<QString> internalTargets(const TestTreeItem &item)
QSet<QString> result;
const auto cppMM = CppTools::CppModelManager::instance();
const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject());
if (!projectInfo)
return {};
const Utils::FilePath filePath = item.filePath();
const QString file = filePath.toString();
const QVector<CppTools::ProjectPart::Ptr> projectParts = projectInfo.projectParts();
const QVector<CppTools::ProjectPart::Ptr> projectParts = projectInfo->projectParts();
if (projectParts.isEmpty())
return cppMM->dependingInternalTargets(item.filePath());
for (const CppTools::ProjectPart::Ptr &projectPart : projectParts) {

View File

@@ -92,8 +92,8 @@ bool LoadProjectScenario::loadProject()
CppTools::Tests::ProjectOpenerAndCloser projectManager;
// This code must trigger a call to PluginManager::finishScenario() at some later point.
const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true, m_kit);
return projectInfo.isValid();
const CppTools::ProjectInfo::Ptr projectInfo = projectManager.open(projectFilePath, true, m_kit);
return projectInfo.get();
}
} // namespace Internal

View File

@@ -389,7 +389,9 @@ QSet<QString> internalTargets(const Utils::FilePath &proFile)
QSet<QString> result;
const auto cppMM = CppTools::CppModelManager::instance();
const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject());
for (const CppTools::ProjectPart::Ptr &projectPart : projectInfo.projectParts()) {
if (!projectInfo)
return {};
for (const CppTools::ProjectPart::Ptr &projectPart : projectInfo->projectParts()) {
if (projectPart->buildTargetType != ProjectExplorer::BuildTargetType::Executable)
continue;
if (projectPart->projectFile == proFile.toString())

View File

@@ -90,8 +90,10 @@ static void extractAllFiles(const DebuggerRunTool *runTool, QStringList &include
FilePaths &headers, FilePaths &sources, FilePaths &assemblers)
{
const auto project = runTool->runControl()->project();
const CppTools::ProjectInfo info = CppModelManager::instance()->projectInfo(project);
const QVector<ProjectPart::Ptr> parts = info.projectParts();
const CppTools::ProjectInfo::Ptr info = CppModelManager::instance()->projectInfo(project);
if (!info)
return;
const QVector<ProjectPart::Ptr> parts = info->projectParts();
for (const ProjectPart::Ptr &part : parts) {
for (const ProjectFile &file : qAsConst(part->files)) {
if (!file.active)

View File

@@ -76,10 +76,15 @@ void ClangCodeModelPlugin::generateCompilationDB()
if (!target)
return;
const auto projectInfo = CppModelManager::instance()->projectInfo(target->project());
if (!projectInfo)
return;
QFuture<GenerateCompilationDbResult> task
= QtConcurrent::run(&Internal::generateCompilationDB,
CppModelManager::instance()->projectInfo(target->project()),
CompilationDbPurpose::Project);
= QtConcurrent::run(&Internal::generateCompilationDB, projectInfo,
CompilationDbPurpose::Project,
warningsConfigForProject(target->project()),
optionsForProject(target->project()));
Core::ProgressManager::addTask(task, tr("Generating Compilation DB"), "generate compilation db");
m_generatorWatcher.setFuture(task);
}
@@ -89,8 +94,8 @@ static bool isDBGenerationEnabled(ProjectExplorer::Project *project)
using namespace CppTools;
if (!project)
return false;
ProjectInfo projectInfo = CppModelManager::instance()->projectInfo(project);
return projectInfo.isValid() && !projectInfo.projectParts().isEmpty();
const ProjectInfo::Ptr projectInfo = CppModelManager::instance()->projectInfo(project);
return projectInfo && !projectInfo->projectParts().isEmpty();
}
ClangCodeModelPlugin::~ClangCodeModelPlugin()

View File

@@ -735,9 +735,10 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
setActivateDocumentAutomatically(true);
if (!project) {
QJsonObject initOptions;
const auto clangOptions = createClangOptions(
*CppTools::CppModelManager::instance()->fallbackProjectPart(), {});
initOptions.insert("fallbackFlags", QJsonArray::fromStringList(clangOptions.second));
const QStringList clangOptions = createClangOptions(
*CppTools::CppModelManager::instance()->fallbackProjectPart(), {},
warningsConfigForProject(nullptr), optionsForProject(nullptr));
initOptions.insert("fallbackFlags", QJsonArray::fromStringList(clangOptions));
setInitializationOptions(initOptions);
}
ClientCapabilities caps = Client::defaultClientCapabilities();

View File

@@ -26,6 +26,7 @@
#include "clangeditordocumentprocessor.h"
#include "clangbackendcommunicator.h"
#include "clangprojectsettings.h"
#include "clangdiagnostictooltipwidget.h"
#include "clangfixitoperation.h"
#include "clangfixitoperationsextractor.h"
@@ -463,11 +464,14 @@ void ClangEditorDocumentProcessor::updateBackendDocument(CppTools::ProjectPart &
return;
}
const auto clangOptions = createClangOptions(projectPart, filePath());
m_diagnosticConfigId = clangOptions.first;
ProjectExplorer::Project * const project = CppTools::projectForProjectPart(projectPart);
const CppTools::ClangDiagnosticConfig config = warningsConfigForProject(project);
const QStringList clangOptions = createClangOptions(projectPart, filePath(), config,
optionsForProject(project));
m_diagnosticConfigId = config.id();
m_communicator.documentsOpened(
{fileContainerWithOptionsAndDocumentContent(clangOptions.second, projectPart.headerPaths)});
{fileContainerWithOptionsAndDocumentContent(clangOptions, projectPart.headerPaths)});
setLastSentDocumentRevision(filePath(), revision());
}

View File

@@ -48,7 +48,6 @@
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cpptoolsreuse.h>
#include <cpptools/editordocumenthandle.h>
#include <cpptools/projectinfo.h>
#include <languageclient/languageclientmanager.h>
@@ -275,7 +274,7 @@ void ClangModelManagerSupport::connectToWidgetsMarkContextMenuRequested(QWidget
}
void ClangModelManagerSupport::updateLanguageClient(ProjectExplorer::Project *project,
const CppTools::ProjectInfo &projectInfo)
const CppTools::ProjectInfo::Ptr &projectInfo)
{
if (!CppTools::ClangdProjectSettings(project).settings().useClangd)
return;
@@ -300,7 +299,8 @@ void ClangModelManagerSupport::updateLanguageClient(ProjectExplorer::Project *pr
return;
if (!CppTools::ClangdProjectSettings(project).settings().useClangd)
return;
if (cppModelManager()->projectInfo(project) != projectInfo)
const CppTools::ProjectInfo::Ptr newProjectInfo = cppModelManager()->projectInfo(project);
if (!newProjectInfo || *newProjectInfo != *projectInfo)
return;
if (getJsonDbDir() != jsonDbDir)
return;
@@ -320,7 +320,9 @@ void ClangModelManagerSupport::updateLanguageClient(ProjectExplorer::Project *pr
return;
if (!CppTools::ClangdProjectSettings(project).settings().useClangd)
return;
if (cppModelManager()->projectInfo(project) != projectInfo)
const CppTools::ProjectInfo::Ptr newProjectInfo
= cppModelManager()->projectInfo(project);
if (!newProjectInfo || *newProjectInfo != *projectInfo)
return;
// Acquaint the client with all open C++ documents for this project.
@@ -361,7 +363,9 @@ void ClangModelManagerSupport::updateLanguageClient(ProjectExplorer::Project *pr
});
auto future = Utils::runAsync(&Internal::generateCompilationDB, projectInfo,
CompilationDbPurpose::CodeModel);
CompilationDbPurpose::CodeModel,
warningsConfigForProject(project),
optionsForProject(project));
generatorWatcher->setFuture(future);
m_generatorSynchronizer.addFuture(future);
}
@@ -576,7 +580,7 @@ static ClangEditorDocumentProcessors
clangProcessorsWithProject(const ProjectExplorer::Project *project)
{
return ::Utils::filtered(clangProcessors(), [project](ClangEditorDocumentProcessor *p) {
return p->hasProjectPart() && p->projectPart()->project == project;
return p->hasProjectPart() && p->projectPart()->belongsToProject(project);
});
}
@@ -611,13 +615,13 @@ void ClangModelManagerSupport::onAboutToRemoveProject(ProjectExplorer::Project *
void ClangModelManagerSupport::onProjectPartsUpdated(ProjectExplorer::Project *project)
{
QTC_ASSERT(project, return);
const CppTools::ProjectInfo projectInfo = cppModelManager()->projectInfo(project);
QTC_ASSERT(projectInfo.isValid(), return);
const CppTools::ProjectInfo::Ptr projectInfo = cppModelManager()->projectInfo(project);
QTC_ASSERT(projectInfo, return);
updateLanguageClient(project, projectInfo);
QStringList projectPartIds;
for (const CppTools::ProjectPart::Ptr &projectPart : projectInfo.projectParts())
for (const CppTools::ProjectPart::Ptr &projectPart : projectInfo->projectParts())
projectPartIds.append(projectPart->id());
onProjectPartsRemoved(projectPartIds);
}

View File

@@ -29,6 +29,7 @@
#include "clanguiheaderondiskmanager.h"
#include <cpptools/cppmodelmanagersupport.h>
#include <cpptools/projectinfo.h>
#include <utils/futuresynchronizer.h>
#include <utils/id.h>
@@ -129,7 +130,7 @@ private:
void connectToWidgetsMarkContextMenuRequested(QWidget *editorWidget);
void updateLanguageClient(ProjectExplorer::Project *project,
const CppTools::ProjectInfo &projectInfo);
const CppTools::ProjectInfo::Ptr &projectInfo);
ClangdClient *createClient(ProjectExplorer::Project *project, const Utils::FilePath &jsonDbDir);
void claimNonProjectSources(ClangdClient *fallbackClient);

View File

@@ -88,7 +88,7 @@ ProjectExplorer::Project *projectForCurrentEditor()
if (auto processor = ClangEditorDocumentProcessor::get(filePath)) {
if (ProjectPart::Ptr projectPart = processor->projectPart())
return projectPart->project;
return projectForProjectPart(*projectPart);
}
return nullptr;

View File

@@ -296,30 +296,10 @@ QString diagnosticCategoryPrefixRemoved(const QString &text)
return text;
}
static FilePath compilerPath(const CppTools::ProjectPart &projectPart)
{
Target *target = projectPart.project->activeTarget();
if (!target)
return FilePath();
ToolChain *toolchain = ToolChainKitAspect::cxxToolChain(target->kit());
return toolchain->compilerCommand();
}
static FilePath buildDirectory(const ProjectExplorer::Project &project)
{
if (auto *target = project.activeTarget()) {
if (auto *bc = target->activeBuildConfiguration())
return bc->buildDirectory();
}
return {};
}
static QStringList projectPartArguments(const ProjectPart &projectPart)
{
QStringList args;
args << compilerPath(projectPart).toString();
args << projectPart.compilerFilePath.toString();
args << "-c";
if (projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
args << "--target=" + projectPart.toolChainTargetTriple;
@@ -350,7 +330,9 @@ static QJsonObject createFileObject(const FilePath &buildDir,
const QStringList &arguments,
const ProjectPart &projectPart,
const ProjectFile &projFile,
CompilationDbPurpose purpose)
CompilationDbPurpose purpose,
const ClangDiagnosticConfig &warningsConfig,
const QStringList &projectOptions)
{
QJsonObject fileObject;
fileObject["file"] = projFile.path;
@@ -376,7 +358,8 @@ static QJsonObject createFileObject(const FilePath &buildDir,
}
} else {
// TODO: Do we really need to re-calculate the project part options per source file?
args = QJsonArray::fromStringList(createClangOptions(projectPart, projFile.path).second);
args = QJsonArray::fromStringList(createClangOptions(projectPart, projFile.path,
warningsConfig, projectOptions));
args.prepend("clang"); // TODO: clang-cl for MSVC targets? Does it matter at all what we put here?
}
@@ -386,10 +369,12 @@ static QJsonObject createFileObject(const FilePath &buildDir,
return fileObject;
}
GenerateCompilationDbResult generateCompilationDB(CppTools::ProjectInfo projectInfo,
CompilationDbPurpose purpose)
GenerateCompilationDbResult generateCompilationDB(const CppTools::ProjectInfo::Ptr projectInfo,
CompilationDbPurpose purpose,
const ClangDiagnosticConfig &warningsConfig,
const QStringList &projectOptions)
{
const FilePath buildDir = buildDirectory(*projectInfo.project());
const FilePath buildDir = projectInfo->buildRoot();
QTC_ASSERT(!buildDir.isEmpty(), return GenerateCompilationDbResult(QString(),
QCoreApplication::translate("ClangUtils", "Could not retrieve build directory.")));
@@ -405,13 +390,13 @@ GenerateCompilationDbResult generateCompilationDB(CppTools::ProjectInfo projectI
}
compileCommandsFile.write("[");
for (ProjectPart::Ptr projectPart : projectInfo.projectParts()) {
for (ProjectPart::Ptr projectPart : projectInfo->projectParts()) {
QStringList args;
if (purpose == CompilationDbPurpose::Project)
args = projectPartArguments(*projectPart);
for (const ProjectFile &projFile : projectPart->files) {
const QJsonObject json = createFileObject(buildDir, args, *projectPart, projFile,
purpose);
purpose, warningsConfig, projectOptions);
if (compileCommandsFile.size() > 1)
compileCommandsFile.write(",");
compileCommandsFile.write('\n' + QJsonDocument(json).toJson().trimmed());
@@ -495,9 +480,12 @@ static ClangProjectSettings &getProjectSettings(ProjectExplorer::Project *projec
class FileOptionsBuilder
{
public:
FileOptionsBuilder(const QString &filePath, const CppTools::ProjectPart &projectPart)
FileOptionsBuilder(const QString &filePath, const CppTools::ProjectPart &projectPart,
const ClangDiagnosticConfig &warningsConfig,
const QStringList &projectOptions)
: m_filePath(filePath)
, m_projectPart(projectPart)
, m_warningsConfig(warningsConfig)
, m_builder(projectPart)
{
// Determine the driver mode from toolchain and flags.
@@ -507,12 +495,11 @@ public:
addLanguageOptions();
addGlobalDiagnosticOptions(); // Before addDiagnosticOptions() so users still can overwrite.
addDiagnosticOptions();
addGlobalOptions();
m_options.append(projectOptions);
addPrecompiledHeaderOptions();
}
const QStringList &options() const { return m_options; }
const ::Utils::Id &diagnosticConfigId() const { return m_diagnosticConfigId; }
CppTools::UseBuildSystemWarnings useBuildSystemWarnings() const
{
return m_useBuildSystemWarnings;
@@ -539,25 +526,11 @@ private:
void addDiagnosticOptions()
{
if (m_projectPart.project) {
ClangProjectSettings &projectSettings = getProjectSettings(m_projectPart.project);
if (!projectSettings.useGlobalConfig()) {
const ::Utils::Id warningConfigId = projectSettings.warningConfigId();
const CppTools::ClangDiagnosticConfigsModel configsModel
= CppTools::diagnosticConfigsModel();
if (configsModel.hasConfigWithId(warningConfigId)) {
addDiagnosticOptionsForConfig(configsModel.configWithId(warningConfigId));
return;
}
}
}
addDiagnosticOptionsForConfig(CppTools::codeModelSettings()->clangDiagnosticConfig());
addDiagnosticOptionsForConfig(m_warningsConfig);
}
void addDiagnosticOptionsForConfig(const CppTools::ClangDiagnosticConfig &diagnosticConfig)
{
m_diagnosticConfigId = diagnosticConfig.id();
m_useBuildSystemWarnings = diagnosticConfig.useBuildSystemWarnings()
? CppTools::UseBuildSystemWarnings::Yes
: CppTools::UseBuildSystemWarnings::No;
@@ -573,14 +546,6 @@ private:
m_options += CppTools::ClangDiagnosticConfigsModel::globalDiagnosticOptions();
}
void addGlobalOptions()
{
if (!m_projectPart.project)
m_options.append(ClangProjectSettings::globalCommandLineOptions());
else
m_options.append(getProjectSettings(m_projectPart.project).commandLineOptions());
}
void addPrecompiledHeaderOptions()
{
using namespace CppTools;
@@ -600,8 +565,8 @@ private:
private:
const QString &m_filePath;
const CppTools::ProjectPart &m_projectPart;
const ClangDiagnosticConfig &m_warningsConfig;
::Utils::Id m_diagnosticConfigId;
CppTools::UseBuildSystemWarnings m_useBuildSystemWarnings = CppTools::UseBuildSystemWarnings::No;
CppTools::CompilerOptionsBuilder m_builder;
bool m_isClMode = false;
@@ -609,17 +574,38 @@ private:
};
} // namespace
QPair<Utils::Id, QStringList> createClangOptions(const CppTools::ProjectPart &projectPart,
const QString &filePath)
QStringList createClangOptions(const ProjectPart &projectPart, const QString &filePath,
const ClangDiagnosticConfig &warningsConfig,
const QStringList &projectOptions)
{
QPair<Utils::Id, QStringList> value;
const FileOptionsBuilder fileOptions(filePath, projectPart);
value.first = fileOptions.diagnosticConfigId();
const FileOptionsBuilder fileOptions(filePath, projectPart, warningsConfig, projectOptions);
LibClangOptionsBuilder optionsBuilder(projectPart, fileOptions.useBuildSystemWarnings());
const QStringList projectPartOptions = optionsBuilder.build(CppTools::ProjectFile::Unsupported,
UsePrecompiledHeaders::No);
value.second = projectPartOptions + fileOptions.options();
return value;
return projectPartOptions + fileOptions.options();
}
ClangDiagnosticConfig warningsConfigForProject(Project *project)
{
if (project) {
ClangProjectSettings &projectSettings = ClangModelManagerSupport::instance()
->projectSettings(project);
if (!projectSettings.useGlobalConfig()) {
const Utils::Id warningConfigId = projectSettings.warningConfigId();
const CppTools::ClangDiagnosticConfigsModel configsModel
= CppTools::diagnosticConfigsModel();
if (configsModel.hasConfigWithId(warningConfigId))
return configsModel.configWithId(warningConfigId);
}
}
return CppTools::codeModelSettings()->clangDiagnosticConfig();
}
const QStringList optionsForProject(ProjectExplorer::Project *project)
{
if (project)
return getProjectSettings(project).commandLineOptions();
return ClangProjectSettings::globalCommandLineOptions();
}
} // namespace Internal

View File

@@ -27,7 +27,7 @@
#include <cplusplus/Icons.h>
#include <cpptools/projectpart.h>
#include <cpptools/projectinfo.h>
#include <cpptools/compileroptionsbuilder.h>
#include <QPair>
@@ -38,20 +38,26 @@ class QTextBlock;
QT_END_NAMESPACE
namespace CppTools {
class ClangDiagnosticConfig;
class CppEditorDocumentHandle;
class ProjectInfo;
}
namespace ClangBackEnd { class TokenInfoContainer; }
namespace ProjectExplorer { class Project; }
namespace ClangCodeModel {
namespace Internal {
CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath);
void setLastSentDocumentRevision(const QString &filePath, uint revision);
QPair<Utils::Id, QStringList> createClangOptions(const CppTools::ProjectPart &projectPart,
const QString &filePath);
CppTools::ClangDiagnosticConfig warningsConfigForProject(ProjectExplorer::Project *project);
const QStringList optionsForProject(ProjectExplorer::Project *project);
QStringList createClangOptions(const CppTools::ProjectPart &projectPart, const QString &filePath,
const CppTools::ClangDiagnosticConfig &warningsConfig,
const QStringList &projectOptions);
CppTools::ProjectPart::Ptr projectPartForFile(const QString &filePath);
CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &filePath);
@@ -79,8 +85,9 @@ public:
};
enum class CompilationDbPurpose { Project, CodeModel };
GenerateCompilationDbResult generateCompilationDB(CppTools::ProjectInfo projectInfo,
CompilationDbPurpose purpose);
GenerateCompilationDbResult generateCompilationDB(const CppTools::ProjectInfo::Ptr projectInfo,
CompilationDbPurpose purpose, const CppTools::ClangDiagnosticConfig &warningsConfig,
const QStringList &projectOptions);
class DiagnosticTextInfo
{

View File

@@ -246,31 +246,33 @@ bool OpenEditorAtCursorPosition::waitUntil(const std::function<bool ()> &conditi
return false;
}
CppTools::ProjectPart::Ptr createProjectPart(const QStringList &files,
CppTools::ProjectPart::Ptr createProjectPart(const Utils::FilePath &projectFilePath,
const QStringList &files,
const ProjectExplorer::Macros &macros)
{
using namespace CppTools;
ProjectPart::Ptr projectPart(new ProjectPart);
projectPart->projectFile = QLatin1String("myproject.project");
foreach (const QString &file, files)
projectPart->files.append(ProjectFile(file, ProjectFile::classify(file)));
projectPart->qtVersion = ::Utils::QtVersion::None;
projectPart->projectMacros = macros;
return projectPart;
ProjectExplorer::RawProjectPart rpp;
rpp.setProjectFileLocation("myproject.project");
rpp.setQtVersion(Utils::QtVersion::None);
rpp.setMacros(macros);
const auto projectFiles = Utils::transform<ProjectFiles>(files, [](const QString &f) {
return ProjectFile(f, ProjectFile::classify(f));
});
return ProjectPart::create(projectFilePath, rpp, {}, projectFiles);
}
CppTools::ProjectInfo createProjectInfo(ProjectExplorer::Project *project,
const QStringList &files,
const ProjectExplorer::Macros &macros)
CppTools::ProjectInfo::Ptr createProjectInfo(ProjectExplorer::Project *project,
const QStringList &files,
const ProjectExplorer::Macros &macros)
{
using namespace CppTools;
QTC_ASSERT(project, return ProjectInfo());
QTC_ASSERT(project, return {});
const CppTools::ProjectPart::Ptr projectPart = createProjectPart(files, macros);
ProjectInfo projectInfo = ProjectInfo(project);
projectInfo.appendProjectPart(projectPart);
const CppTools::ProjectPart::Ptr projectPart = createProjectPart(project->projectFilePath(),
files, macros);
const auto projectInfo = ProjectInfo::create(
{project, ProjectExplorer::KitInfo(nullptr), {}, {}}, {projectPart});
return projectInfo;
}
@@ -290,9 +292,9 @@ public:
bool load()
{
m_project = m_helper.createProject(QLatin1String("testProject"));
const CppTools::ProjectInfo projectInfo = createProjectInfo(m_project,
m_projectFiles,
m_projectMacros);
const CppTools::ProjectInfo::Ptr projectInfo = createProjectInfo(m_project,
m_projectFiles,
m_projectMacros);
const QSet<QString> filesIndexedAfterLoading = m_helper.updateProjectInfo(projectInfo);
return m_projectFiles.size() == filesIndexedAfterLoading.size();
}
@@ -300,15 +302,14 @@ public:
bool updateProject(const ProjectExplorer::Macros &updatedProjectMacros)
{
QTC_ASSERT(m_project, return false);
const CppTools::ProjectInfo updatedProjectInfo = createProjectInfo(m_project,
m_projectFiles,
updatedProjectMacros);
const CppTools::ProjectInfo::Ptr updatedProjectInfo
= createProjectInfo(m_project, m_projectFiles, updatedProjectMacros);
return updateProjectInfo(updatedProjectInfo);
}
private:
bool updateProjectInfo(const CppTools::ProjectInfo &projectInfo)
bool updateProjectInfo(const CppTools::ProjectInfo::Ptr &projectInfo)
{
const QSet<QString> filesIndexedAfterLoading = m_helper.updateProjectInfo(projectInfo);
return m_projectFiles.size() == filesIndexedAfterLoading.size();
@@ -720,8 +721,7 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCodeInGeneratedUiFile(
// Open project
const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro");
CppTools::Tests::ProjectOpenerAndCloser projectManager;
const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true);
QVERIFY(projectInfo.isValid());
QVERIFY(projectManager.open(projectFilePath, true));
QVERIFY(monitorGeneratedUiFile.waitUntilGenerated());
// Open file with ui object

View File

@@ -264,14 +264,14 @@ private:
}
};
SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo,
SelectableFilesDialog::SelectableFilesDialog(Project *project,
const FileInfoProviders &fileInfoProviders,
int initialProviderIndex)
: QDialog(nullptr)
, m_ui(new Ui::SelectableFilesDialog)
, m_filesModel(new SelectableFilesModel)
, m_fileInfoProviders(fileInfoProviders)
, m_project(projectInfo.project())
, m_project(project)
, m_analyzeButton(new QPushButton(tr("Analyze"), this))
{
m_ui->setupUi(this);

View File

@@ -47,7 +47,7 @@ class SelectableFilesDialog : public QDialog
Q_OBJECT
public:
explicit SelectableFilesDialog(const CppTools::ProjectInfo &projectInfo,
explicit SelectableFilesDialog(ProjectExplorer::Project *project,
const FileInfoProviders &fileInfoProviders,
int initialProviderIndex);
~SelectableFilesDialog() override;

View File

@@ -736,17 +736,17 @@ FileInfos ClangTool::collectFileInfos(Project *project, FileSelection fileSelect
return {};
}
auto projectInfo = CppTools::CppModelManager::instance()->projectInfo(project);
QTC_ASSERT(projectInfo.isValid(), return FileInfos());
const auto projectInfo = CppTools::CppModelManager::instance()->projectInfo(project);
QTC_ASSERT(projectInfo, return FileInfos());
const FileInfos allFileInfos = sortedFileInfos(projectInfo.projectParts());
const FileInfos allFileInfos = sortedFileInfos(projectInfo->projectParts());
if (selectionType && *selectionType == FileSelectionType::AllFiles)
return allFileInfos;
if (selectionType && *selectionType == FileSelectionType::AskUser) {
static int initialProviderIndex = 0;
SelectableFilesDialog dialog(projectInfo,
SelectableFilesDialog dialog(project,
fileInfoProviders(project, allFileInfos),
initialProviderIndex);
if (dialog.exec() == QDialog::Rejected)
@@ -875,7 +875,7 @@ static bool canAnalyzeProject(Project *project)
const bool projectSupportsLanguage = project->projectLanguages().contains(c)
|| project->projectLanguages().contains(cxx);
return projectSupportsLanguage
&& CppModelManager::instance()->projectInfo(project).isValid()
&& CppModelManager::instance()->projectInfo(project)
&& ToolChainKitAspect::cxxToolChain(target->kit());
}
return false;

View File

@@ -135,7 +135,7 @@ AnalyzeUnit::AnalyzeUnit(const FileInfo &fileInfo,
AnalyzeUnits ClangToolRunWorker::unitsToAnalyze(const FilePath &clangIncludeDir,
const QString &clangVersion)
{
QTC_ASSERT(m_projectInfo.isValid(), return AnalyzeUnits());
QTC_ASSERT(m_projectInfo, return AnalyzeUnits());
AnalyzeUnits units;
for (const FileInfo &fileInfo : m_fileInfos)
@@ -217,10 +217,14 @@ void ClangToolRunWorker::start()
const QString &toolName = tool()->name();
Project *project = runControl()->project();
m_projectInfo = CppTools::CppModelManager::instance()->projectInfo(project);
if (!m_projectInfo) {
reportFailure(tr("No code model data available for project."));
return;
}
m_projectFiles = Utils::toSet(project->files(Project::AllFiles));
// Project changed in the mean time?
if (m_projectInfo.configurationOrFilesChanged(m_projectInfoBeforeBuild)) {
if (m_projectInfo->configurationOrFilesChanged(*m_projectInfoBeforeBuild)) {
// If it's more than a release/debug build configuration change, e.g.
// a version control checkout, files might be not valid C++ anymore
// or even gone, so better stop here.
@@ -239,7 +243,7 @@ void ClangToolRunWorker::start()
return;
}
const Utils::FilePath projectFile = m_projectInfo.project()->projectFilePath();
const Utils::FilePath projectFile = m_projectInfo->projectFilePath();
appendMessage(tr("Running %1 on %2 with configuration \"%3\".")
.arg(toolName)
.arg(projectFile.toUserOutput())

View File

@@ -114,8 +114,8 @@ private:
Utils::Environment m_environment;
Utils::TemporaryDirectory m_temporaryDir;
CppTools::ProjectInfo m_projectInfoBeforeBuild;
CppTools::ProjectInfo m_projectInfo;
CppTools::ProjectInfo::Ptr m_projectInfoBeforeBuild;
CppTools::ProjectInfo::Ptr m_projectInfo;
QString m_targetTriple;
Utils::Id m_toolChainType;

View File

@@ -115,9 +115,7 @@ void ClangToolsUnitTests::testProject()
// Open project
Tests::ProjectOpenerAndCloser projectManager;
const ProjectInfo projectInfo = projectManager.open(projectFilePath, true, m_kit);
const bool isProjectOpen = projectInfo.isValid();
QVERIFY(isProjectOpen);
QVERIFY(projectManager.open(projectFilePath, true, m_kit));
// Run tool
ClangTool *tool = ClangTool::instance();

View File

@@ -137,12 +137,13 @@ static VirtualFileSystemOverlay &vfso()
static FileInfo getFileInfo(const Utils::FilePath &file, ProjectExplorer::Project *project)
{
CppTools::ProjectInfo projectInfo = CppTools::CppModelManager::instance()->projectInfo(project);
if (!projectInfo.isValid())
const CppTools::ProjectInfo::Ptr projectInfo
= CppTools::CppModelManager::instance()->projectInfo(project);
if (!projectInfo)
return {};
FileInfo candidate;
for (const CppTools::ProjectPart::Ptr &projectPart : projectInfo.projectParts()) {
for (const CppTools::ProjectPart::Ptr &projectPart : projectInfo->projectParts()) {
QTC_ASSERT(projectPart, continue);
for (const CppTools::ProjectFile &projectFile : qAsConst(projectPart->files)) {

View File

@@ -77,11 +77,10 @@ void CompilationDatabaseTests::testProject()
QFETCH(QString, projectFilePath);
CppTools::Tests::ProjectOpenerAndCloser projectManager;
const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true);
QVERIFY(projectInfo.isValid());
const CppTools::ProjectInfo::Ptr projectInfo = projectManager.open(projectFilePath, true);
QVERIFY(projectInfo);
projectInfo.projectParts();
QVector<CppTools::ProjectPart::Ptr> projectParts = projectInfo.projectParts();
QVector<CppTools::ProjectPart::Ptr> projectParts = projectInfo->projectParts();
QVERIFY(!projectParts.isEmpty());
CppTools::ProjectPart &projectPart = *projectParts.first();

View File

@@ -203,8 +203,11 @@ void CppcheckTool::check(const Utils::FilePaths &files)
if (filtered.isEmpty())
return;
const CppTools::ProjectInfo info = CppTools::CppModelManager::instance()->projectInfo(m_project);
const QVector<CppTools::ProjectPart::Ptr> parts = info.projectParts();
const CppTools::ProjectInfo::Ptr info
= CppTools::CppModelManager::instance()->projectInfo(m_project);
if (!info)
return;
const QVector<CppTools::ProjectPart::Ptr> parts = info->projectParts();
if (parts.size() == 1) {
QTC_ASSERT(parts.first(), return);
addToQueue(filtered, *parts.first());

View File

@@ -76,8 +76,9 @@ void CppcheckTrigger::checkEditors(const QList<Core::IEditor *> &editors)
return;
using CppModelManager = CppTools::CppModelManager;
const CppTools::ProjectInfo info = CppModelManager::instance()->projectInfo(m_currentProject);
if (!info.isValid())
const CppTools::ProjectInfo::Ptr info
= CppModelManager::instance()->projectInfo(m_currentProject);
if (!info)
return;
const QList<Core::IEditor *> editorList = !editors.isEmpty()
@@ -99,7 +100,7 @@ void CppcheckTrigger::checkEditors(const QList<Core::IEditor *> &editors)
continue;
const QString &pathString = path.toString();
if (!info.sourceFiles().contains(pathString))
if (!info->sourceFiles().contains(pathString))
continue;
connect(document, &Core::IDocument::aboutToReload,

View File

@@ -34,6 +34,7 @@
#include <cpptools/cppcodemodelinspectordumper.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cpptoolsbridge.h>
#include <cpptools/cpptoolsreuse.h>
#include <cpptools/cppworkingcopy.h>
#include <projectexplorer/projectmacro.h>
#include <projectexplorer/project.h>
@@ -1111,7 +1112,7 @@ class ProjectPartsModel : public QAbstractListModel
public:
ProjectPartsModel(QObject *parent);
void configure(const QList<ProjectInfo> &projectInfos,
void configure(const QList<ProjectInfo::Ptr> &projectInfos,
const ProjectPart::Ptr &currentEditorsProjectPart);
QModelIndex indexForCurrentEditorsProjectPart() const;
@@ -1134,13 +1135,13 @@ ProjectPartsModel::ProjectPartsModel(QObject *parent)
{
}
void ProjectPartsModel::configure(const QList<ProjectInfo> &projectInfos,
void ProjectPartsModel::configure(const QList<ProjectInfo::Ptr> &projectInfos,
const ProjectPart::Ptr &currentEditorsProjectPart)
{
emit layoutAboutToBeChanged();
m_projectPartsList.clear();
foreach (const ProjectInfo &info, projectInfos) {
foreach (const ProjectPart::Ptr &projectPart, info.projectParts()) {
foreach (const ProjectInfo::Ptr &info, projectInfos) {
foreach (const ProjectPart::Ptr &projectPart, info->projectParts()) {
if (!m_projectPartsList.contains(projectPart)) {
m_projectPartsList << projectPart;
if (projectPart == currentEditorsProjectPart)
@@ -1592,7 +1593,7 @@ void CppCodeModelInspectorDialog::refresh()
? cppEditorDocument->processor()->parser()->projectPartInfo().projectPart
: ProjectPart::Ptr();
const QList<ProjectInfo> projectInfos = cmmi->projectInfos();
const QList<ProjectInfo::Ptr> projectInfos = cmmi->projectInfos();
dumper.dumpProjectInfos(projectInfos);
m_projectPartsModel->configure(projectInfos, editorsProjectPart);
m_projectPartsView->resizeColumns(ProjectPartsModel::ColumnCount);
@@ -1784,9 +1785,10 @@ void CppCodeModelInspectorDialog::updateProjectPartData(const ProjectPart::Ptr &
// General
QString projectName = QLatin1String("<None>");
QString projectFilePath = QLatin1String("<None>");
if (ProjectExplorer::Project *project = part->project) {
projectName = project->displayName();
projectFilePath = project->projectFilePath().toUserOutput();
if (part->hasProject()) {
projectFilePath = part->topLevelProject.toUserOutput();
if (const ProjectExplorer::Project * const project = projectForProjectPart(*part))
projectName = project->displayName();
}
const QString callGroupId = part->callGroupId.isEmpty() ? QString::fromLatin1("<None>")
: part->callGroupId;

View File

@@ -610,7 +610,7 @@ ProjectPart *findProjectPartForCurrentProject(const QList<ProjectPart::Ptr> &pro
const auto found = std::find_if(projectParts.cbegin(),
projectParts.cend(),
[&](const CppTools::ProjectPart::Ptr &projectPart) {
return projectPart->project == currentProject;
return projectPart->belongsToProject(currentProject);
});
if (found != projectParts.cend())

View File

@@ -152,15 +152,12 @@ TestActionsTestCase::TestActionsTestCase(const Actions &tokenActions, const Acti
// Collect files to process
QStringList filesToOpen;
QList<QPointer<ProjectExplorer::Project> > projects;
const QList<ProjectInfo> projectInfos = m_modelManager->projectInfos();
const QList<ProjectInfo::Ptr> projectInfos = m_modelManager->projectInfos();
foreach (const ProjectInfo &info, projectInfos) {
QPointer<ProjectExplorer::Project> project = info.project();
if (!projects.contains(project))
projects << project;
qDebug() << "Project" << info.project()->displayName() << "- files to process:"
<< info.sourceFiles().size();
foreach (const QString &sourceFile, info.sourceFiles())
foreach (const ProjectInfo::Ptr &info, projectInfos) {
qDebug() << "Project" << info->projectFilePath().toUserOutput() << "- files to process:"
<< info->sourceFiles().size();
foreach (const QString &sourceFile, info->sourceFiles())
filesToOpen << sourceFile;
}

View File

@@ -100,7 +100,7 @@ void BuiltinEditorDocumentParser::updateImpl(const QFutureInterface<void> &futur
configFile += overwrittenToolchainDefines(*part.data());
configFile += ProjectExplorer::Macro::toByteArray(part->projectMacros);
if (!part->projectConfigFile.isEmpty())
configFile += ProjectPart::readProjectConfigFile(part);
configFile += ProjectPart::readProjectConfigFile(part->projectConfigFile);
headerPaths = part->headerPaths;
projectConfigFile = part->projectConfigFile;
includedFiles = part->includedFiles;

View File

@@ -666,8 +666,8 @@ void CompilerOptionsBuilder::addIncludeDirOptionForPath(const ProjectExplorer::H
systemPath = true;
} else {
// ProjectExplorer::HeaderPathType::User
if (m_useSystemHeader == UseSystemHeader::Yes
&& !path.path.startsWith(m_projectPart.project->rootProjectDirectory().toString())) {
if (m_useSystemHeader == UseSystemHeader::Yes && m_projectPart.hasProject()
&& !Utils::FilePath::fromString(path.path).isChildOf(m_projectPart.topLevelProject)) {
systemPath = true;
}
}

View File

@@ -26,6 +26,7 @@
#include "cpptoolsplugin.h"
#include "compileroptionsbuilder.h"
#include "projectinfo.h"
#include "projectpart.h"
#include <projectexplorer/headerpath.h>
@@ -46,29 +47,31 @@ namespace {
class CompilerOptionsBuilderTest
{
public:
CompilerOptionsBuilderTest()
ProjectPart finalize()
{
QFile pchFile(pchFileNativePath());
pchFile.open(QIODevice::WriteOnly);
projectPart.project = project.get();
projectPart.toolchainType = Constants::CLANG_TOOLCHAIN_TYPEID;
projectPart.languageVersion = Utils::LanguageVersion::CXX17;
projectPart.toolChainWordWidth = ProjectPart::WordWidth64Bit;
projectPart.toolChainTargetTriple = "x86_64-apple-darwin10";
projectPart.precompiledHeaders = QStringList{pchFileNativePath()};
projectPart.toolChainMacros = {Macro{"foo", "bar"},
Macro{"__cplusplus", "2"},
Macro{"__STDC_VERSION__", "2"},
Macro{"_MSVC_LANG", "2"},
Macro{"_MSC_BUILD", "2"},
Macro{"_MSC_FULL_VER", "1900"},
Macro{"_MSC_VER", "19"}};
projectPart.projectMacros = {Macro{"projectFoo", "projectBar"}};
projectPart.qtVersion = Utils::QtVersion::Qt5;
projectPart.headerPaths = {HeaderPath{"/tmp/builtin_path", HeaderPathType::BuiltIn},
HeaderPath{"/tmp/system_path", HeaderPathType::System},
HeaderPath{"/tmp/path", HeaderPathType::User}};
RawProjectPart rpp;
rpp.setPreCompiledHeaders({pchFileNativePath()});
rpp.setMacros({Macro{"projectFoo", "projectBar"}});
rpp.setQtVersion(Utils::QtVersion::Qt5);
rpp.setHeaderPaths(headerPaths);
rpp.setConfigFileName(projectConfigFile);
ToolChainInfo tcInfo;
tcInfo.type = toolchainType;
tcInfo.wordWidth = 64;
tcInfo.targetTriple = targetTriple;
tcInfo.isMsvc2015ToolChain = isMsvc2015;
tcInfo.extraCodeModelFlags = extraFlags;
tcInfo.macroInspectionRunner = [this](const QStringList &) {
return ToolChain::MacroInspectionReport{toolchainMacros, languageVersion};
};
RawProjectPartFlags rppFlags;
rppFlags.commandLineFlags = flags;
projectPart = ProjectPart::create({}, rpp, {}, {}, Utils::Language::Cxx, {}, rppFlags,
tcInfo);
compilerOptionsBuilder.emplace(CompilerOptionsBuilder(*projectPart));
return *projectPart;
}
static HeaderPath builtIn(const QString &path)
@@ -87,25 +90,43 @@ public:
+ "/compileroptionsbuilder.pch");
}
std::unique_ptr<Project> project{std::make_unique<Project>(QString(), Utils::FilePath())};
ProjectPart projectPart;
CompilerOptionsBuilder compilerOptionsBuilder{projectPart};
QStringList flags;
Utils::Id toolchainType = Constants::CLANG_TOOLCHAIN_TYPEID;
QString targetTriple = "x86_64-apple-darwin10";
HeaderPaths headerPaths = {HeaderPath{"/tmp/builtin_path", HeaderPathType::BuiltIn},
HeaderPath{"/tmp/system_path", HeaderPathType::System},
HeaderPath{"/tmp/path", HeaderPathType::User}};
Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX17;
Utils::LanguageExtensions languageExtensions;
Macros toolchainMacros{
Macro{"foo", "bar"}, Macro{"__cplusplus", "2"}, Macro{"__STDC_VERSION__", "2"},
Macro{"_MSVC_LANG", "2"}, Macro{"_MSC_BUILD", "2"}, Macro{"_MSC_FULL_VER", "1900"},
Macro{"_MSC_VER", "19"}};
QString projectConfigFile;
QStringList extraFlags;
bool isMsvc2015 = false;
Utils::optional<CompilerOptionsBuilder> compilerOptionsBuilder;
private:
ProjectPart::Ptr projectPart;
};
}
void CppToolsPlugin::test_optionsBuilder_addProjectMacros()
{
CompilerOptionsBuilderTest t;
t.compilerOptionsBuilder.addProjectMacros();
t.finalize();
t.compilerOptionsBuilder->addProjectMacros();
QCOMPARE(t.compilerOptionsBuilder.options(), QStringList("-DprojectFoo=projectBar"));
QCOMPARE(t.compilerOptionsBuilder->options(), QStringList("-DprojectFoo=projectBar"));
}
void CppToolsPlugin::test_optionsBuilder_unknownFlagsAreForwarded()
{
CompilerOptionsBuilderTest t;
ProjectPart part = t.projectPart;
part.compilerFlags = QStringList{"-fancyFlag"};
t.flags = QStringList{"-fancyFlag"};
ProjectPart part = t.finalize();
CompilerOptionsBuilder compilerOptionsBuilder{part, UseSystemHeader::No,
UseTweakedHeaderPaths::No, UseLanguageDefines::Yes};
compilerOptionsBuilder.build(ProjectFile::CXXSource, UsePrecompiledHeaders::No);
@@ -116,8 +137,8 @@ void CppToolsPlugin::test_optionsBuilder_unknownFlagsAreForwarded()
void CppToolsPlugin::test_optionsBuilder_warningsFlagsAreNotFilteredIfRequested()
{
CompilerOptionsBuilderTest t;
ProjectPart part = t.projectPart;
part.compilerFlags = QStringList{"-Whello"};
t.flags = QStringList{"-Whello"};
ProjectPart part = t.finalize();
CompilerOptionsBuilder compilerOptionsBuilder{part, UseSystemHeader::No,
UseTweakedHeaderPaths::No, UseLanguageDefines::No,
UseBuildSystemWarnings::Yes};
@@ -129,8 +150,8 @@ void CppToolsPlugin::test_optionsBuilder_warningsFlagsAreNotFilteredIfRequested(
void CppToolsPlugin::test_optionsBuilder_diagnosticOptionsAreRemoved()
{
CompilerOptionsBuilderTest t;
ProjectPart part = t.projectPart;
part.compilerFlags = QStringList{"-Wbla", "-pedantic"};
t.flags = QStringList{"-Wbla", "-pedantic"};
ProjectPart part = t.finalize();
CompilerOptionsBuilder compilerOptionsBuilder{part, UseSystemHeader::No,
UseTweakedHeaderPaths::No, UseLanguageDefines::Yes};
compilerOptionsBuilder.build(ProjectFile::CXXSource, UsePrecompiledHeaders::No);
@@ -142,12 +163,11 @@ void CppToolsPlugin::test_optionsBuilder_diagnosticOptionsAreRemoved()
void CppToolsPlugin::test_optionsBuilder_cLanguageVersionIsRewritten()
{
CompilerOptionsBuilderTest t;
ProjectPart part = t.projectPart;
part.compilerFlags = QStringList{"-std=c18"};
// We need to set the language version here to overcome a QTC_ASSERT checking
// consistency between ProjectFile::Kind and ProjectPart::LanguageVersion
part.languageVersion = Utils::LanguageVersion::C18;
t.flags = QStringList{"-std=c18"};
t.languageVersion = Utils::LanguageVersion::C18;
ProjectPart part = t.finalize();
CompilerOptionsBuilder compilerOptionsBuilder{part, UseSystemHeader::No,
UseTweakedHeaderPaths::No, UseLanguageDefines::Yes};
@@ -160,7 +180,7 @@ void CppToolsPlugin::test_optionsBuilder_cLanguageVersionIsRewritten()
void CppToolsPlugin::test_optionsBuilder_languageVersionIsExplicitlySetIfNotProvided()
{
CompilerOptionsBuilderTest t;
CompilerOptionsBuilder compilerOptionsBuilder{t.projectPart, UseSystemHeader::No,
CompilerOptionsBuilder compilerOptionsBuilder{t.finalize(), UseSystemHeader::No,
UseTweakedHeaderPaths::No, UseLanguageDefines::Yes};
compilerOptionsBuilder.build(ProjectFile::CXXSource, UsePrecompiledHeaders::No);
@@ -170,8 +190,8 @@ void CppToolsPlugin::test_optionsBuilder_languageVersionIsExplicitlySetIfNotProv
void CppToolsPlugin::test_optionsBuilder_LanguageVersionIsExplicitlySetIfNotProvidedMsvc()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.projectPart, UseSystemHeader::No,
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.finalize(), UseSystemHeader::No,
UseTweakedHeaderPaths::No, UseLanguageDefines::Yes};
compilerOptionsBuilder.build(ProjectFile::CXXSource, UsePrecompiledHeaders::No);
@@ -181,15 +201,16 @@ void CppToolsPlugin::test_optionsBuilder_LanguageVersionIsExplicitlySetIfNotProv
void CppToolsPlugin::test_optionsBuilder_addWordWidth()
{
CompilerOptionsBuilderTest t;
t.compilerOptionsBuilder.addWordWidth();
t.finalize();
t.compilerOptionsBuilder->addWordWidth();
QCOMPARE(t.compilerOptionsBuilder.options(), QStringList("-m64"));
QCOMPARE(t.compilerOptionsBuilder->options(), QStringList("-m64"));
}
void CppToolsPlugin::test_optionsBuilder_headerPathOptionsOrder()
{
CompilerOptionsBuilderTest t;
CompilerOptionsBuilder compilerOptionsBuilder{t.projectPart, UseSystemHeader::No,
CompilerOptionsBuilder compilerOptionsBuilder{t.finalize(), UseSystemHeader::No,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No, UseBuildSystemWarnings::No,
"dummy_version", ""};
compilerOptionsBuilder.addHeaderPathOptions();
@@ -203,8 +224,8 @@ void CppToolsPlugin::test_optionsBuilder_headerPathOptionsOrder()
void CppToolsPlugin::test_optionsBuilder_HeaderPathOptionsOrderMsvc()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.projectPart, UseSystemHeader::No,
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.finalize(), UseSystemHeader::No,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No, UseBuildSystemWarnings::No,
"dummy_version", ""};
compilerOptionsBuilder.evaluateCompilerFlags();
@@ -220,7 +241,7 @@ void CppToolsPlugin::test_optionsBuilder_HeaderPathOptionsOrderMsvc()
void CppToolsPlugin::test_optionsBuilder_useSystemHeader()
{
CompilerOptionsBuilderTest t;
CompilerOptionsBuilder compilerOptionsBuilder{t.projectPart, UseSystemHeader::Yes,
CompilerOptionsBuilder compilerOptionsBuilder{t.finalize(), UseSystemHeader::Yes,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No, UseBuildSystemWarnings::No,
"dummy_version", ""};
compilerOptionsBuilder.addHeaderPathOptions();
@@ -234,26 +255,25 @@ void CppToolsPlugin::test_optionsBuilder_useSystemHeader()
void CppToolsPlugin::test_optionsBuilder_noClangHeadersPath()
{
CompilerOptionsBuilderTest t;
t.compilerOptionsBuilder.addHeaderPathOptions();
t.finalize();
t.compilerOptionsBuilder->addHeaderPathOptions();
QCOMPARE(t.compilerOptionsBuilder.options(),
QCOMPARE(t.compilerOptionsBuilder->options(),
(QStringList{"-I", t.toNative("/tmp/path"), "-I", t.toNative("/tmp/system_path")}));
}
void CppToolsPlugin::test_optionsBuilder_clangHeadersAndCppIncludePathsOrderMacOs()
{
CompilerOptionsBuilderTest t;
const auto defaultPaths = t.projectPart.headerPaths;
t.projectPart.headerPaths = {
const HeaderPaths additionalHeaderPaths = {
t.builtIn("/usr/include/c++/4.2.1"),
t.builtIn("/usr/include/c++/4.2.1/backward"),
t.builtIn("/usr/local/include"),
t.builtIn("/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/6.0/include"),
t.builtIn("/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include"),
t.builtIn("/usr/include")
};
t.projectPart.headerPaths.append(defaultPaths);
CompilerOptionsBuilder compilerOptionsBuilder(t.projectPart, UseSystemHeader::No,
t.builtIn("/usr/include")};
t.headerPaths = additionalHeaderPaths + t.headerPaths;
CompilerOptionsBuilder compilerOptionsBuilder(t.finalize(), UseSystemHeader::No,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No, UseBuildSystemWarnings::No,
"dummy_version", "");
compilerOptionsBuilder.addHeaderPathOptions();
@@ -273,17 +293,16 @@ void CppToolsPlugin::test_optionsBuilder_clangHeadersAndCppIncludePathsOrderMacO
void CppToolsPlugin::test_optionsBuilder_clangHeadersAndCppIncludePathsOrderLinux()
{
CompilerOptionsBuilderTest t;
t.projectPart.headerPaths = {
t.targetTriple = "x86_64-linux-gnu";
t.headerPaths = {
t.builtIn("/usr/include/c++/4.8"),
t.builtIn("/usr/include/c++/4.8/backward"),
t.builtIn("/usr/include/x86_64-linux-gnu/c++/4.8"),
t.builtIn("/usr/local/include"),
t.builtIn("/usr/lib/gcc/x86_64-linux-gnu/4.8/include"),
t.builtIn("/usr/include/x86_64-linux-gnu"),
t.builtIn("/usr/include"),
};
t.projectPart.toolChainTargetTriple = "x86_64-linux-gnu";
CompilerOptionsBuilder compilerOptionsBuilder(t.projectPart, UseSystemHeader::No,
t.builtIn("/usr/include")};
CompilerOptionsBuilder compilerOptionsBuilder(t.finalize(), UseSystemHeader::No,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No, UseBuildSystemWarnings::No,
"dummy_version", "");
compilerOptionsBuilder.addHeaderPathOptions();
@@ -303,14 +322,13 @@ void CppToolsPlugin::test_optionsBuilder_clangHeadersAndCppIncludePathsOrderLinu
void CppToolsPlugin::test_optionsBuilder_clangHeadersAndCppIncludePathsOrderNoVersion()
{
CompilerOptionsBuilderTest t;
t.projectPart.headerPaths = {
t.targetTriple = "x86_64-w64-windows-gnu";
t.headerPaths = {
t.builtIn("C:/mingw530/i686-w64-mingw32/include"),
t.builtIn("C:/mingw530/i686-w64-mingw32/include/c++"),
t.builtIn("C:/mingw530/i686-w64-mingw32/include/c++/i686-w64-mingw32"),
t.builtIn("C:/mingw530/i686-w64-mingw32/include/c++/backward"),
};
t.projectPart.toolChainTargetTriple = "x86_64-w64-windows-gnu";
CompilerOptionsBuilder compilerOptionsBuilder(t.projectPart, UseSystemHeader::No,
t.builtIn("C:/mingw530/i686-w64-mingw32/include/c++/backward")};
CompilerOptionsBuilder compilerOptionsBuilder(t.finalize(), UseSystemHeader::No,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No, UseBuildSystemWarnings::No,
"dummy_version", "");
compilerOptionsBuilder.addHeaderPathOptions();
@@ -327,15 +345,14 @@ void CppToolsPlugin::test_optionsBuilder_clangHeadersAndCppIncludePathsOrderNoVe
void CppToolsPlugin::test_optionsBuilder_clangHeadersAndCppIncludePathsOrderAndroidClang()
{
CompilerOptionsBuilderTest t;
t.projectPart.headerPaths = {
t.targetTriple = "i686-linux-android";
t.headerPaths = {
t.builtIn("C:/Android/sdk/ndk-bundle/sysroot/usr/include/i686-linux-android"),
t.builtIn("C:/Android/sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/include"),
t.builtIn("C:/Android/sdk/ndk-bundle/sources/android/support/include"),
t.builtIn("C:/Android/sdk/ndk-bundle/sources/cxx-stl/llvm-libc++abi/include"),
t.builtIn("C:/Android/sdk/ndk-bundle/sysroot/usr/include"),
};
t.projectPart.toolChainTargetTriple = "i686-linux-android";
CompilerOptionsBuilder compilerOptionsBuilder(t.projectPart, UseSystemHeader::No,
t.builtIn("C:/Android/sdk/ndk-bundle/sysroot/usr/include")};
CompilerOptionsBuilder compilerOptionsBuilder(t.finalize(), UseSystemHeader::No,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No, UseBuildSystemWarnings::No,
"dummy_version", "");
compilerOptionsBuilder.addHeaderPathOptions();
@@ -353,24 +370,26 @@ void CppToolsPlugin::test_optionsBuilder_clangHeadersAndCppIncludePathsOrderAndr
void CppToolsPlugin::test_optionsBuilder_noPrecompiledHeader()
{
CompilerOptionsBuilderTest t;
t.compilerOptionsBuilder.addPrecompiledHeaderOptions(UsePrecompiledHeaders::No);
t.finalize();
t.compilerOptionsBuilder->addPrecompiledHeaderOptions(UsePrecompiledHeaders::No);
QVERIFY(t.compilerOptionsBuilder.options().empty());
QVERIFY(t.compilerOptionsBuilder->options().empty());
}
void CppToolsPlugin::test_optionsBuilder_usePrecompiledHeader()
{
CompilerOptionsBuilderTest t;
t.compilerOptionsBuilder.addPrecompiledHeaderOptions(UsePrecompiledHeaders::Yes);
t.finalize();
t.compilerOptionsBuilder->addPrecompiledHeaderOptions(UsePrecompiledHeaders::Yes);
QCOMPARE(t.compilerOptionsBuilder.options(), (QStringList{"-include", t.pchFileNativePath()}));
QCOMPARE(t.compilerOptionsBuilder->options(), (QStringList{"-include", t.pchFileNativePath()}));
}
void CppToolsPlugin::test_optionsBuilder_usePrecompiledHeaderMsvc()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.projectPart};
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.finalize()};
compilerOptionsBuilder.evaluateCompilerFlags();
compilerOptionsBuilder.addPrecompiledHeaderOptions(UsePrecompiledHeaders::Yes);
@@ -380,40 +399,44 @@ void CppToolsPlugin::test_optionsBuilder_usePrecompiledHeaderMsvc()
void CppToolsPlugin::test_optionsBuilder_addMacros()
{
CompilerOptionsBuilderTest t;
t.compilerOptionsBuilder.addMacros(Macros{Macro{"key", "value"}});
t.finalize();
t.compilerOptionsBuilder->addMacros(Macros{Macro{"key", "value"}});
QCOMPARE(t.compilerOptionsBuilder.options(), QStringList("-Dkey=value"));
QCOMPARE(t.compilerOptionsBuilder->options(), QStringList("-Dkey=value"));
}
void CppToolsPlugin::test_optionsBuilder_addTargetTriple()
{
CompilerOptionsBuilderTest t;
t.compilerOptionsBuilder.addTargetTriple();
t.finalize();
t.compilerOptionsBuilder->addTargetTriple();
QCOMPARE(t.compilerOptionsBuilder.options(), QStringList("--target=x86_64-apple-darwin10"));
QCOMPARE(t.compilerOptionsBuilder->options(), QStringList("--target=x86_64-apple-darwin10"));
}
void CppToolsPlugin::test_optionsBuilder_enableCExceptions()
{
CompilerOptionsBuilderTest t;
t.projectPart.languageVersion = Utils::LanguageVersion::C99;
t.compilerOptionsBuilder.enableExceptions();
t.languageVersion = Utils::LanguageVersion::C99;
t.finalize();
t.compilerOptionsBuilder->enableExceptions();
QCOMPARE(t.compilerOptionsBuilder.options(), QStringList("-fexceptions"));
QCOMPARE(t.compilerOptionsBuilder->options(), QStringList("-fexceptions"));
}
void CppToolsPlugin::test_optionsBuilder_enableCxxExceptions()
{
CompilerOptionsBuilderTest t;
t.compilerOptionsBuilder.enableExceptions();
t.finalize();
t.compilerOptionsBuilder->enableExceptions();
QCOMPARE(t.compilerOptionsBuilder.options(), (QStringList{"-fcxx-exceptions", "-fexceptions"}));
QCOMPARE(t.compilerOptionsBuilder->options(), (QStringList{"-fcxx-exceptions", "-fexceptions"}));
}
void CppToolsPlugin::test_optionsBuilder_insertWrappedQtHeaders()
{
CompilerOptionsBuilderTest t;
CompilerOptionsBuilder compilerOptionsBuilder{t.projectPart, UseSystemHeader::Yes,
CompilerOptionsBuilder compilerOptionsBuilder{t.finalize(), UseSystemHeader::Yes,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No, UseBuildSystemWarnings::No,
"dummy_version", ""};
compilerOptionsBuilder.insertWrappedQtHeaders();
@@ -425,13 +448,8 @@ void CppToolsPlugin::test_optionsBuilder_insertWrappedQtHeaders()
void CppToolsPlugin::test_optionsBuilder_insertWrappedMingwHeadersWithNonMingwToolchain()
{
CompilerOptionsBuilderTest t;
CompilerOptionsBuilder builder{t.projectPart,
UseSystemHeader::Yes,
UseTweakedHeaderPaths::Yes,
UseLanguageDefines::No,
UseBuildSystemWarnings::No,
"dummy_version",
""};
CompilerOptionsBuilder builder{t.finalize(), UseSystemHeader::Yes, UseTweakedHeaderPaths::Yes,
UseLanguageDefines::No, UseBuildSystemWarnings::No, "dummy_version", ""};
builder.insertWrappedMingwHeaders();
QVERIFY(!Utils::contains(builder.options(),
@@ -441,9 +459,9 @@ void CppToolsPlugin::test_optionsBuilder_insertWrappedMingwHeadersWithNonMingwTo
void CppToolsPlugin::test_optionsBuilder_insertWrappedMingwHeadersWithMingwToolchain()
{
CompilerOptionsBuilderTest t;
CompilerOptionsBuilder builder{t.projectPart, UseSystemHeader::Yes, UseTweakedHeaderPaths::Yes,
t.toolchainType = Constants::MINGW_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder builder{t.finalize(), UseSystemHeader::Yes, UseTweakedHeaderPaths::Yes,
UseLanguageDefines::No, UseBuildSystemWarnings::No, "dummy_version", ""};
t.projectPart.toolchainType = Constants::MINGW_TOOLCHAIN_TYPEID;
builder.insertWrappedMingwHeaders();
QVERIFY(Utils::contains(builder.options(),
@@ -453,16 +471,17 @@ void CppToolsPlugin::test_optionsBuilder_insertWrappedMingwHeadersWithMingwToolc
void CppToolsPlugin::test_optionsBuilder_setLanguageVersion()
{
CompilerOptionsBuilderTest t;
t.compilerOptionsBuilder.updateFileLanguage(ProjectFile::CXXSource);
t.finalize();
t.compilerOptionsBuilder->updateFileLanguage(ProjectFile::CXXSource);
QCOMPARE(t.compilerOptionsBuilder.options(), (QStringList{"-x", "c++"}));
QCOMPARE(t.compilerOptionsBuilder->options(), (QStringList{"-x", "c++"}));
}
void CppToolsPlugin::test_optionsBuilder_setLanguageVersionMsvc()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.projectPart};
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.finalize()};
compilerOptionsBuilder.evaluateCompilerFlags();
compilerOptionsBuilder.updateFileLanguage(ProjectFile::CXXSource);
@@ -472,26 +491,29 @@ void CppToolsPlugin::test_optionsBuilder_setLanguageVersionMsvc()
void CppToolsPlugin::test_optionsBuilder_handleLanguageExtension()
{
CompilerOptionsBuilderTest t;
t.projectPart.languageExtensions = Utils::LanguageExtension::ObjectiveC;
t.compilerOptionsBuilder.updateFileLanguage(ProjectFile::CXXSource);
t.languageVersion = Utils::LanguageVersion::CXX17;
t.languageExtensions = Utils::LanguageExtension::ObjectiveC;
t.finalize();
t.compilerOptionsBuilder->updateFileLanguage(ProjectFile::CXXSource);
QCOMPARE(t.compilerOptionsBuilder.options(), (QStringList{"-x", "objective-c++"}));
QCOMPARE(t.compilerOptionsBuilder->options(), (QStringList{"-x", "objective-c++"}));
}
void CppToolsPlugin::test_optionsBuilder_updateLanguageVersion()
{
CompilerOptionsBuilderTest t;
t.compilerOptionsBuilder.updateFileLanguage(ProjectFile::CXXSource);
t.compilerOptionsBuilder.updateFileLanguage(ProjectFile::CXXHeader);
t.finalize();
t.compilerOptionsBuilder->updateFileLanguage(ProjectFile::CXXSource);
t.compilerOptionsBuilder->updateFileLanguage(ProjectFile::CXXHeader);
QCOMPARE(t.compilerOptionsBuilder.options(), (QStringList{"-x", "c++-header"}));
QCOMPARE(t.compilerOptionsBuilder->options(), (QStringList{"-x", "c++-header"}));
}
void CppToolsPlugin::test_optionsBuilder_updateLanguageVersionMsvc()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.projectPart};
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.finalize()};
compilerOptionsBuilder.evaluateCompilerFlags();
compilerOptionsBuilder.updateFileLanguage(ProjectFile::CXXSource);
compilerOptionsBuilder.updateFileLanguage(ProjectFile::CSource);
@@ -502,48 +524,52 @@ void CppToolsPlugin::test_optionsBuilder_updateLanguageVersionMsvc()
void CppToolsPlugin::test_optionsBuilder_addMsvcCompatibilityVersion()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.projectPart.toolChainMacros.append(Macro{"_MSC_FULL_VER", "190000000"});
t.compilerOptionsBuilder.addMsvcCompatibilityVersion();
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.toolchainMacros.append(Macro{"_MSC_FULL_VER", "190000000"});
t.finalize();
t.compilerOptionsBuilder->addMsvcCompatibilityVersion();
QCOMPARE(t.compilerOptionsBuilder.options(), QStringList("-fms-compatibility-version=19.00"));
QCOMPARE(t.compilerOptionsBuilder->options(), QStringList("-fms-compatibility-version=19.00"));
}
void CppToolsPlugin::test_optionsBuilder_undefineCppLanguageFeatureMacrosForMsvc2015()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.projectPart.isMsvc2015Toolchain = true;
t.compilerOptionsBuilder.undefineCppLanguageFeatureMacrosForMsvc2015();
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.isMsvc2015 = true;
t.finalize();
t.compilerOptionsBuilder->undefineCppLanguageFeatureMacrosForMsvc2015();
QVERIFY(t.compilerOptionsBuilder.options().contains("-U__cpp_aggregate_bases"));
QVERIFY(t.compilerOptionsBuilder->options().contains("-U__cpp_aggregate_bases"));
}
void CppToolsPlugin::test_optionsBuilder_addDefineFunctionMacrosMsvc()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.compilerOptionsBuilder.addDefineFunctionMacrosMsvc();
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.finalize();
t.compilerOptionsBuilder->addDefineFunctionMacrosMsvc();
QVERIFY(t.compilerOptionsBuilder.options().contains(
QVERIFY(t.compilerOptionsBuilder->options().contains(
"-D__FUNCTION__=\"someLegalAndLongishFunctionNameThatWorksAroundQTCREATORBUG-24580\""));
}
void CppToolsPlugin::test_optionsBuilder_addProjectConfigFileInclude()
{
CompilerOptionsBuilderTest t;
t.projectPart.projectConfigFile = "dummy_file.h";
t.compilerOptionsBuilder.addProjectConfigFileInclude();
t.projectConfigFile = "dummy_file.h";
t.finalize();
t.compilerOptionsBuilder->addProjectConfigFileInclude();
QCOMPARE(t.compilerOptionsBuilder.options(), (QStringList{"-include", "dummy_file.h"}));
QCOMPARE(t.compilerOptionsBuilder->options(), (QStringList{"-include", "dummy_file.h"}));
}
void CppToolsPlugin::test_optionsBuilder_addProjectConfigFileIncludeMsvc()
{
CompilerOptionsBuilderTest t;
t.projectPart.projectConfigFile = "dummy_file.h";
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.projectPart};
t.projectConfigFile = "dummy_file.h";
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder{t.finalize()};
compilerOptionsBuilder.evaluateCompilerFlags();
compilerOptionsBuilder.addProjectConfigFileInclude();
@@ -553,28 +579,29 @@ void CppToolsPlugin::test_optionsBuilder_addProjectConfigFileIncludeMsvc()
void CppToolsPlugin::test_optionsBuilder_noUndefineClangVersionMacrosForNewMsvc()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.compilerOptionsBuilder.undefineClangVersionMacrosForMsvc();
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.finalize();
t.compilerOptionsBuilder->undefineClangVersionMacrosForMsvc();
QVERIFY(!t.compilerOptionsBuilder.options().contains("-U__clang__"));
QVERIFY(!t.compilerOptionsBuilder->options().contains("-U__clang__"));
}
void CppToolsPlugin::test_optionsBuilder_undefineClangVersionMacrosForOldMsvc()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.projectPart.toolChainMacros = {Macro{"_MSC_FULL_VER", "1300"},
Macro{"_MSC_VER", "13"}};
t.compilerOptionsBuilder.undefineClangVersionMacrosForMsvc();
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.toolchainMacros = {Macro{"_MSC_FULL_VER", "1300"}, Macro{"_MSC_VER", "13"}};
t.finalize();
t.compilerOptionsBuilder->undefineClangVersionMacrosForMsvc();
QVERIFY(t.compilerOptionsBuilder.options().contains("-U__clang__"));
QVERIFY(t.compilerOptionsBuilder->options().contains("-U__clang__"));
}
void CppToolsPlugin::test_optionsBuilder_buildAllOptions()
{
CompilerOptionsBuilderTest t;
t.projectPart.extraCodeModelFlags = QStringList{"-arch", "x86_64"};
CompilerOptionsBuilder compilerOptionsBuilder(t.projectPart, UseSystemHeader::No,
t.extraFlags = QStringList{"-arch", "x86_64"};
CompilerOptionsBuilder compilerOptionsBuilder(t.finalize(), UseSystemHeader::No,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No, UseBuildSystemWarnings::No,
"dummy_version", "");
compilerOptionsBuilder.build(ProjectFile::CXXSource, UsePrecompiledHeaders::No);
@@ -597,8 +624,8 @@ void CppToolsPlugin::test_optionsBuilder_buildAllOptions()
void CppToolsPlugin::test_optionsBuilder_buildAllOptionsMsvc()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder(t.projectPart, UseSystemHeader::No,
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
CompilerOptionsBuilder compilerOptionsBuilder(t.finalize(), UseSystemHeader::No,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No, UseBuildSystemWarnings::No,
"dummy_version", "");
compilerOptionsBuilder.build(ProjectFile::CXXSource, UsePrecompiledHeaders::No);
@@ -625,9 +652,9 @@ void CppToolsPlugin::test_optionsBuilder_buildAllOptionsMsvc()
void CppToolsPlugin::test_optionsBuilder_buildAllOptionsMsvcWithExceptions()
{
CompilerOptionsBuilderTest t;
t.projectPart.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.projectPart.toolChainMacros.append(Macro{"_CPPUNWIND", "1"});
CompilerOptionsBuilder compilerOptionsBuilder(t.projectPart, UseSystemHeader::No,
t.toolchainType = Constants::MSVC_TOOLCHAIN_TYPEID;
t.toolchainMacros.append(Macro{"_CPPUNWIND", "1"});
CompilerOptionsBuilder compilerOptionsBuilder(t.finalize(), UseSystemHeader::No,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No, UseBuildSystemWarnings::No,
"dummy_version", "");
compilerOptionsBuilder.build(ProjectFile::CXXSource, UsePrecompiledHeaders::No);

View File

@@ -26,6 +26,7 @@
#include "cppcodemodelinspectordumper.h"
#include "cppmodelmanager.h"
#include "cpptoolsreuse.h"
#include "cppworkingcopy.h"
#include <app/app_version.h>
@@ -501,7 +502,7 @@ static void printIncludeType(QTextStream &out, ProjectExplorer::HeaderPathType t
}
}
void Dumper::dumpProjectInfos( const QList<ProjectInfo> &projectInfos)
void Dumper::dumpProjectInfos(const QList<ProjectInfo::Ptr> &projectInfos)
{
const QByteArray i1 = indent(1);
const QByteArray i2 = indent(2);
@@ -509,18 +510,18 @@ void Dumper::dumpProjectInfos( const QList<ProjectInfo> &projectInfos)
const QByteArray i4 = indent(4);
m_out << "Projects loaded: " << projectInfos.size() << "{{{1\n";
foreach (const ProjectInfo &info, projectInfos) {
const QPointer<ProjectExplorer::Project> project = info.project();
m_out << i1 << "Project " << project->displayName()
<< " (" << project->projectFilePath().toUserOutput() << "){{{2\n";
foreach (const ProjectInfo::Ptr &info, projectInfos) {
m_out << i1 << "Project " << info->projectName()
<< " (" << info->projectFilePath().toUserOutput() << "){{{2\n";
const QVector<ProjectPart::Ptr> projectParts = info.projectParts();
const QVector<ProjectPart::Ptr> projectParts = info->projectParts();
foreach (const ProjectPart::Ptr &part, projectParts) {
QString projectName = QLatin1String("<None>");
QString projectFilePath = QLatin1String("<None>");
if (ProjectExplorer::Project *project = part->project) {
projectName = project->displayName();
projectFilePath = project->projectFilePath().toUserOutput();
QString projectFilePath = "<None>";
if (part->hasProject()) {
projectFilePath = part->topLevelProject.toUserOutput();
if (const ProjectExplorer::Project * const project = projectForProjectPart(*part))
projectName = project->displayName();
}
if (!part->projectConfigFile.isEmpty())
m_out << i3 << "Project Config File: " << part->projectConfigFile << "\n";

View File

@@ -70,7 +70,7 @@ public:
const QString &logFileId = QString());
~Dumper();
void dumpProjectInfos(const QList<CppTools::ProjectInfo> &projectInfos);
void dumpProjectInfos(const QList<CppTools::ProjectInfo::Ptr> &projectInfos);
void dumpSnapshot(const CPlusPlus::Snapshot &snapshot,
const QString &title,
bool isGlobalSnapshot = false);

View File

@@ -153,7 +153,7 @@ public:
// Project integration
mutable QMutex m_projectMutex;
QMap<ProjectExplorer::Project *, ProjectInfo> m_projectToProjectsInfo;
QMap<ProjectExplorer::Project *, ProjectInfo::Ptr> m_projectToProjectsInfo;
QHash<ProjectExplorer::Project *, bool> m_projectToIndexerCanceled;
QMap<Utils::FilePath, QList<ProjectPart::Ptr> > m_fileToProjectParts;
QMap<QString, ProjectPart::Ptr> m_projectPartIdToProjectProjectPart;
@@ -748,8 +748,8 @@ void CppModelManager::ensureUpdated()
QStringList CppModelManager::internalProjectFiles() const
{
QStringList files;
for (const ProjectInfo &pinfo : qAsConst(d->m_projectToProjectsInfo)) {
foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) {
for (const ProjectInfo::Ptr &pinfo : qAsConst(d->m_projectToProjectsInfo)) {
foreach (const ProjectPart::Ptr &part, pinfo->projectParts()) {
foreach (const ProjectFile &file, part->files)
files += file.path;
}
@@ -761,8 +761,8 @@ QStringList CppModelManager::internalProjectFiles() const
ProjectExplorer::HeaderPaths CppModelManager::internalHeaderPaths() const
{
ProjectExplorer::HeaderPaths headerPaths;
for (const ProjectInfo &pinfo : qAsConst(d->m_projectToProjectsInfo)) {
foreach (const ProjectPart::Ptr &part, pinfo.projectParts()) {
for (const ProjectInfo::Ptr &pinfo : qAsConst(d->m_projectToProjectsInfo)) {
foreach (const ProjectPart::Ptr &part, pinfo->projectParts()) {
foreach (const ProjectExplorer::HeaderPath &path, part->headerPaths) {
ProjectExplorer::HeaderPath hp(QDir::cleanPath(path.path), path.type);
if (!headerPaths.contains(hp))
@@ -789,8 +789,8 @@ ProjectExplorer::Macros CppModelManager::internalDefinedMacros() const
{
ProjectExplorer::Macros macros;
QSet<ProjectExplorer::Macro> alreadyIn;
for (const ProjectInfo &pinfo : qAsConst(d->m_projectToProjectsInfo)) {
for (const ProjectPart::Ptr &part : pinfo.projectParts()) {
for (const ProjectInfo::Ptr &pinfo : qAsConst(d->m_projectToProjectsInfo)) {
for (const ProjectPart::Ptr &part : pinfo->projectParts()) {
addUnique(part->toolChainMacros, macros, alreadyIn);
addUnique(part->projectMacros, macros, alreadyIn);
}
@@ -972,24 +972,21 @@ QFuture<void> CppModelManager::updateSourceFiles(const QSet<QString> &sourceFile
return d->m_internalIndexingSupport->refreshSourceFiles(filteredFiles, mode);
}
QList<ProjectInfo> CppModelManager::projectInfos() const
QList<ProjectInfo::Ptr> CppModelManager::projectInfos() const
{
QMutexLocker locker(&d->m_projectMutex);
return d->m_projectToProjectsInfo.values();
}
ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Project *project) const
ProjectInfo::Ptr CppModelManager::projectInfo(ProjectExplorer::Project *project) const
{
QMutexLocker locker(&d->m_projectMutex);
return d->m_projectToProjectsInfo.value(project, ProjectInfo());
return d->m_projectToProjectsInfo.value(project);
}
/// \brief Remove all files and their includes (recursively) of given ProjectInfo from the snapshot.
void CppModelManager::removeProjectInfoFilesAndIncludesFromSnapshot(const ProjectInfo &projectInfo)
{
if (!projectInfo.isValid())
return;
QMutexLocker snapshotLocker(&d->m_snapshotMutex);
foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) {
foreach (const ProjectFile &cxxFile, projectPart->files) {
@@ -1089,8 +1086,8 @@ void CppModelManager::recalculateProjectPartMappings()
{
d->m_projectPartIdToProjectProjectPart.clear();
d->m_fileToProjectParts.clear();
foreach (const ProjectInfo &projectInfo, d->m_projectToProjectsInfo) {
foreach (const ProjectPart::Ptr &projectPart, projectInfo.projectParts()) {
foreach (const ProjectInfo::Ptr &projectInfo, d->m_projectToProjectsInfo) {
foreach (const ProjectPart::Ptr &projectPart, projectInfo->projectParts()) {
d->m_projectPartIdToProjectProjectPart[projectPart->id()] = projectPart;
foreach (const ProjectFile &cxxFile, projectPart->files)
d->m_fileToProjectParts[Utils::FilePath::fromString(cxxFile.path)].append(
@@ -1152,37 +1149,37 @@ void CppModelManager::updateCppEditorDocuments(bool projectsUpdated) const
}
}
QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectInfo,
QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo::Ptr &newProjectInfo,
const QSet<QString> &additionalFiles)
{
if (!newProjectInfo.isValid())
return QFuture<void>();
ProjectInfo theNewProjectInfo = newProjectInfo;
theNewProjectInfo.finish();
if (!newProjectInfo)
return {};
QSet<QString> filesToReindex;
QStringList removedProjectParts;
bool filesRemoved = false;
ProjectExplorer::Project *project = theNewProjectInfo.project().data();
ProjectExplorer::Project * const project = projectForProjectInfo(*newProjectInfo);
if (!project)
return {};
{ // Only hold the mutex for a limited scope, so the dumping afterwards does not deadlock.
QMutexLocker projectLocker(&d->m_projectMutex);
const QSet<QString> newSourceFiles = theNewProjectInfo.sourceFiles();
const QSet<QString> newSourceFiles = newProjectInfo->sourceFiles();
// Check if we can avoid a full reindexing
ProjectInfo oldProjectInfo = d->m_projectToProjectsInfo.value(project);
const ProjectInfo::Ptr oldProjectInfo = d->m_projectToProjectsInfo.value(project);
const bool previousIndexerCanceled = d->m_projectToIndexerCanceled.value(project, false);
if (!previousIndexerCanceled && oldProjectInfo.isValid()) {
ProjectInfoComparer comparer(oldProjectInfo, theNewProjectInfo);
if (!previousIndexerCanceled && oldProjectInfo) {
ProjectInfoComparer comparer(*oldProjectInfo, *newProjectInfo);
if (comparer.configurationOrFilesChanged()) {
d->m_dirty = true;
// If the project configuration changed, do a full reindexing
if (comparer.configurationChanged()) {
removeProjectInfoFilesAndIncludesFromSnapshot(oldProjectInfo);
removeProjectInfoFilesAndIncludesFromSnapshot(*oldProjectInfo);
filesToReindex.unite(newSourceFiles);
// The "configuration file" includes all defines and therefore should be updated
@@ -1218,7 +1215,7 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn
}
// Update Project/ProjectInfo and File/ProjectPart table
d->m_projectToProjectsInfo.insert(project, theNewProjectInfo);
d->m_projectToProjectsInfo.insert(project, newProjectInfo);
recalculateProjectPartMappings();
} // Mutex scope
@@ -1236,7 +1233,7 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn
emit projectPartsRemoved(removedProjectParts);
// Announce added project parts
emit projectPartsUpdated(theNewProjectInfo.project().data());
emit projectPartsUpdated(project);
// Ideally, we would update all the editor documents that depend on the 'filesToReindex'.
// However, on e.g. a session restore first the editor documents are created and then the
@@ -1531,18 +1528,16 @@ void CppModelManager::onCoreAboutToClose()
void CppModelManager::setupFallbackProjectPart()
{
ProjectPart::Ptr part(new ProjectPart);
part->projectMacros = definedMacros();
part->headerPaths = headerPaths();
ToolChainInfo tcInfo;
RawProjectPart rpp;
rpp.setMacros(definedMacros());
rpp.setHeaderPaths(headerPaths());
rpp.setQtVersion(Utils::QtVersion::Qt5);
// Do not activate ObjectiveCExtensions since this will lead to the
// "objective-c++" language option for a project-less *.cpp file.
part->languageExtensions = Utils::LanguageExtension::All;
part->languageExtensions &= ~Utils::LanguageExtensions(
Utils::LanguageExtension::ObjectiveC);
part->qtVersion = Utils::QtVersion::Qt5;
Utils::LanguageExtensions langExtensions = Utils::LanguageExtension::All;
langExtensions &= ~Utils::LanguageExtensions(Utils::LanguageExtension::ObjectiveC);
// TODO: Use different fallback toolchain for different kinds of files?
const Kit * const defaultKit = KitManager::isLoaded() ? KitManager::defaultKit() : nullptr;
@@ -1553,15 +1548,17 @@ void CppModelManager::setupFallbackProjectPart()
if (sysroot.isEmpty())
sysroot = Utils::FilePath::fromString(defaultTc->sysRoot());
Utils::Environment env = defaultKit->buildEnvironment();
ToolChainInfo tcInfo(defaultTc, sysroot.toString(), env);
part->setupToolchainProperties(tcInfo, {});
if (part->language == Language::C)
part->languageVersion = Utils::LanguageVersion::LatestC;
else
part->languageVersion = Utils::LanguageVersion::LatestCxx;
tcInfo = ToolChainInfo(defaultTc, sysroot.toString(), env);
const auto macroInspectionWrapper = [runner = tcInfo.macroInspectionRunner](
const QStringList &flags) {
ToolChain::MacroInspectionReport report = runner(flags);
report.languageVersion = Utils::LanguageVersion::LatestCxx;
return report;
};
tcInfo.macroInspectionRunner = macroInspectionWrapper;
}
part->updateLanguageFeatures();
const auto part = ProjectPart::create({}, rpp, {}, {}, {}, langExtensions, {}, tcInfo);
QMutexLocker locker(&d->m_fallbackProjectPartMutex);
d->m_fallbackProjectPart = part;
}

View File

@@ -114,9 +114,9 @@ public:
QByteArray codeModelConfiguration() const;
CppLocatorData *locatorData() const;
QList<ProjectInfo> projectInfos() const;
ProjectInfo projectInfo(ProjectExplorer::Project *project) const;
QFuture<void> updateProjectInfo(const ProjectInfo &newProjectInfo,
QList<ProjectInfo::Ptr> projectInfos() const;
ProjectInfo::Ptr projectInfo(ProjectExplorer::Project *project) const;
QFuture<void> updateProjectInfo(const ProjectInfo::Ptr &newProjectInfo,
const QSet<QString> &additionalFiles = {});
/// \return The project part with the given project file

View File

@@ -104,20 +104,20 @@ public:
foreach (const QString &file, files)
projectFiles << projectDir.file(file);
Project *project = modelManagerTestHelper->createProject(name);
projectInfo = ProjectInfo(project);
RawProjectPart rpp;
rpp.setQtVersion(Utils::QtVersion::Qt5);
const ProjectFiles rppFiles = Utils::transform<ProjectFiles>(projectFiles,
[](const QString &file) { return ProjectFile(file, ProjectFile::classify(file)); });
const auto project = modelManagerTestHelper->createProject(
name, Utils::FilePath::fromString(dir).pathAppended(name + ".pro"));
ProjectPart::Ptr part(new ProjectPart);
part->qtVersion = Utils::QtVersion::Qt5;
foreach (const QString &file, projectFiles) {
ProjectFile projectFile(file, ProjectFile::classify(file));
part->files.append(projectFile);
}
projectInfo.appendProjectPart(part);
const auto part = ProjectPart::create(project->projectFilePath(), rpp, {}, rppFiles);
projectInfo = ProjectInfo::create(ProjectUpdateInfo(project, KitInfo(nullptr), {}, {}),
{part});
}
ModelManagerTestHelper *modelManagerTestHelper;
ProjectInfo projectInfo;
ProjectInfo::Ptr projectInfo;
QStringList projectFiles;
};
@@ -180,15 +180,16 @@ void CppToolsPlugin::test_modelmanager_paths_are_clean()
const MyTestDataDir testDataDir(_("testdata"));
Project *project = helper.createProject(_("test_modelmanager_paths_are_clean"));
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
part->qtVersion = Utils::QtVersion::Qt5;
part->projectMacros = {ProjectExplorer::Macro("OH_BEHAVE", "-1")};
part->headerPaths = {{testDataDir.includeDir(false), HeaderPathType::User},
{testDataDir.frameworksDir(false), HeaderPathType::Framework}};
pi.appendProjectPart(part);
const auto project = helper.createProject(_("test_modelmanager_paths_are_clean"),
Utils::FilePath::fromString("blubb.pro"));
RawProjectPart rpp;
rpp.setQtVersion(Utils::QtVersion::Qt5);
rpp.setMacros({ProjectExplorer::Macro("OH_BEHAVE", "-1")});
rpp.setHeaderPaths({{testDataDir.includeDir(false), HeaderPathType::User},
{testDataDir.frameworksDir(false), HeaderPathType::Framework}});
const auto part = ProjectPart::create(project->projectFilePath(), rpp);
const auto pi = ProjectInfo::create(ProjectUpdateInfo(project, KitInfo(nullptr), {}, {}),
{part});
mm->updateProjectInfo(pi);
@@ -209,18 +210,19 @@ void CppToolsPlugin::test_modelmanager_framework_headers()
const MyTestDataDir testDataDir(_("testdata"));
Project *project = helper.createProject(_("test_modelmanager_framework_headers"));
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
part->qtVersion = Utils::QtVersion::Qt5;
part->projectMacros = {{"OH_BEHAVE", "-1"}};
part->headerPaths = {{testDataDir.includeDir(false), HeaderPathType::User},
{testDataDir.frameworksDir(false), HeaderPathType::Framework}};
const auto project = helper.createProject(_("test_modelmanager_framework_headers"),
Utils::FilePath::fromString("blubb.pro"));
RawProjectPart rpp;
rpp.setQtVersion(Utils::QtVersion::Qt5);
rpp.setMacros({{"OH_BEHAVE", "-1"}});
rpp.setHeaderPaths({{testDataDir.includeDir(false), HeaderPathType::User},
{testDataDir.frameworksDir(false), HeaderPathType::Framework}});
const QString &source = testDataDir.fileFromSourcesDir(
_("test_modelmanager_framework_headers.cpp"));
part->files << ProjectFile(source, ProjectFile::CXXSource);
pi.appendProjectPart(part);
const auto part = ProjectPart::create(project->projectFilePath(), rpp, {},
{ProjectFile(source, ProjectFile::CXXSource)});
const auto pi = ProjectInfo::create(ProjectUpdateInfo(project, KitInfo(nullptr), {}, {}),
{part});
mm->updateProjectInfo(pi).waitForFinished();
QCoreApplication::processEvents();
@@ -255,16 +257,16 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files()
const QString testCpp(testDataDir.fileFromSourcesDir(_("test_modelmanager_refresh.cpp")));
const QString testHeader(testDataDir.fileFromSourcesDir( _("test_modelmanager_refresh.h")));
Project *project = helper.createProject(
_("test_modelmanager_refresh_also_includes_of_project_files"));
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
part->qtVersion = Utils::QtVersion::Qt5;
part->projectMacros = {{"OH_BEHAVE", "-1"}};
part->headerPaths = {{testDataDir.includeDir(false), HeaderPathType::User}};
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
pi.appendProjectPart(part);
const auto project
= helper.createProject(_("test_modelmanager_refresh_also_includes_of_project_files"),
Utils::FilePath::fromString("blubb.pro"));
RawProjectPart rpp;
rpp.setQtVersion(Utils::QtVersion::Qt5);
rpp.setMacros({{"OH_BEHAVE", "-1"}});
rpp.setHeaderPaths({{testDataDir.includeDir(false), HeaderPathType::User}});
auto part = ProjectPart::create(project->projectFilePath(), rpp, {},
{ProjectFile(testCpp, ProjectFile::CXXSource)});
auto pi = ProjectInfo::create(ProjectUpdateInfo(project, KitInfo(nullptr), {}, {}), {part});
QSet<QString> refreshedFiles = helper.updateProjectInfo(pi);
QCOMPARE(refreshedFiles.size(), 1);
@@ -279,9 +281,10 @@ void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files()
QVERIFY(macrosInHeaderBefore.first().name() == "test_modelmanager_refresh_h");
// Introduce a define that will enable another define once the document is reparsed.
part->projectMacros = {{"TEST_DEFINE", "1"}};
pi = ProjectInfo(project);
pi.appendProjectPart(part);
rpp.setMacros({{"TEST_DEFINE", "1"}});
part = ProjectPart::create(project->projectFilePath(), rpp, {},
{ProjectFile(testCpp, ProjectFile::CXXSource)});
pi = ProjectInfo::create(ProjectUpdateInfo(project, KitInfo(nullptr), {}, {}), {part});
refreshedFiles = helper.updateProjectInfo(pi);
@@ -312,15 +315,17 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times()
const QString testHeader2(testDataDir.file(_("header.h")));
const QString testCpp(testDataDir.file(_("source.cpp")));
Project *project = helper.createProject(_("test_modelmanager_refresh_several_times"));
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
part->qtVersion = Utils::QtVersion::Qt5;
part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader));
part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader));
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
pi.appendProjectPart(part);
const auto project = helper.createProject(_("test_modelmanager_refresh_several_times"),
Utils::FilePath::fromString("blubb.pro"));
RawProjectPart rpp;
rpp.setQtVersion(Utils::QtVersion::Qt5);
const ProjectFiles files = {
ProjectFile(testHeader1, ProjectFile::CXXHeader),
ProjectFile(testHeader2, ProjectFile::CXXHeader),
ProjectFile(testCpp, ProjectFile::CXXSource)
};
const auto part = ProjectPart::create(project->projectFilePath(), rpp, {}, files);
auto pi = ProjectInfo::create(ProjectUpdateInfo(project, KitInfo(nullptr), {}, {}), {part});
mm->updateProjectInfo(pi);
CPlusPlus::Snapshot snapshot;
@@ -329,16 +334,11 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times()
ProjectExplorer::Macros macros = {{"FIRST_DEFINE"}};
for (int i = 0; i < 2; ++i) {
pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
// Simulate project configuration change by having different defines each time.
macros += {"ANOTHER_DEFINE"};
part->projectMacros = macros;
part->qtVersion = Utils::QtVersion::Qt5;
part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader));
part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader));
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
pi.appendProjectPart(part);
rpp.setMacros(macros);
const auto part = ProjectPart::create(project->projectFilePath(), rpp, {}, files);
pi = ProjectInfo::create({project, KitInfo(nullptr), {}, {}}, {part});
refreshedFiles = helper.updateProjectInfo(pi);
QCOMPARE(refreshedFiles.size(), 3);
@@ -374,13 +374,13 @@ void CppToolsPlugin::test_modelmanager_refresh_test_for_changes()
const MyTestDataDir testDataDir(_("testdata_refresh"));
const QString testCpp(testDataDir.file(_("source.cpp")));
Project *project = helper.createProject(_("test_modelmanager_refresh_2"));
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
part->qtVersion = Utils::QtVersion::Qt5;
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
pi.appendProjectPart(part);
const auto project = helper.createProject(_("test_modelmanager_refresh_2"),
Utils::FilePath::fromString("blubb.pro"));
RawProjectPart rpp;
rpp.setQtVersion(Utils::QtVersion::Qt5);
const auto part = ProjectPart::create(project->projectFilePath(), rpp, {},
{ProjectFile(testCpp, ProjectFile::CXXSource)});
const auto pi = ProjectInfo::create({project, KitInfo(nullptr), {}, {}}, {part});
// Reindexing triggers a reparsing thread
helper.resetRefreshedSourceFiles();
@@ -409,14 +409,13 @@ void CppToolsPlugin::test_modelmanager_refresh_added_and_purge_removed()
const QString testHeader2(testDataDir.file(_("defines.h")));
const QString testCpp(testDataDir.file(_("source.cpp")));
Project *project = helper.createProject(_("test_modelmanager_refresh_3"));
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
part->qtVersion = Utils::QtVersion::Qt5;
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader));
pi.appendProjectPart(part);
const auto project = helper.createProject(_("test_modelmanager_refresh_3"),
Utils::FilePath::fromString("blubb.pro"));
RawProjectPart rpp;
rpp.setQtVersion(Utils::QtVersion::Qt5);
const auto part = ProjectPart::create(project->projectFilePath(), rpp, {},
{{testCpp, ProjectFile::CXXSource}, {testHeader1, ProjectFile::CXXHeader}});
auto pi = ProjectInfo::create({project, KitInfo(nullptr), {}, {}}, {part});
CPlusPlus::Snapshot snapshot;
QSet<QString> refreshedFiles;
@@ -432,12 +431,9 @@ void CppToolsPlugin::test_modelmanager_refresh_added_and_purge_removed()
QVERIFY(snapshot.contains(testCpp));
// Now add testHeader2 and remove testHeader1
pi = ProjectInfo(project);
ProjectPart::Ptr newPart(new ProjectPart);
newPart->qtVersion = Utils::QtVersion::Qt5;
newPart->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
newPart->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader));
pi.appendProjectPart(newPart);
const auto newPart = ProjectPart::create(project->projectFilePath(), rpp, {},
{{testCpp, ProjectFile::CXXSource}, {testHeader2, ProjectFile::CXXHeader}});
pi = ProjectInfo::create({project, KitInfo(nullptr), {}, {}}, {newPart});
refreshedFiles = helper.updateProjectInfo(pi);
@@ -469,15 +465,15 @@ void CppToolsPlugin::test_modelmanager_refresh_timeStampModified_if_sourcefiles_
ModelManagerTestHelper helper;
CppModelManager *mm = CppModelManager::instance();
Project *project = helper.createProject(_("test_modelmanager_refresh_timeStampModified"));
ProjectInfo pi = ProjectInfo(project);
ProjectPart::Ptr part(new ProjectPart);
part->qtVersion = Utils::QtVersion::Qt5;
foreach (const QString &file, initialProjectFiles)
part->files.append(ProjectFile(file, ProjectFile::CXXSource));
pi = ProjectInfo(project);
pi.appendProjectPart(part);
const auto project = helper.createProject(_("test_modelmanager_refresh_timeStampModified"),
Utils::FilePath::fromString("blubb.pro"));
RawProjectPart rpp;
rpp.setQtVersion(Utils::QtVersion::Qt5);
auto files = Utils::transform<ProjectFiles>(initialProjectFiles, [](const QString &f) {
return ProjectFile(f, ProjectFile::CXXSource);
});
auto part = ProjectPart::create(project->projectFilePath(), rpp, {}, files);
auto pi = ProjectInfo::create({project, KitInfo(nullptr), {}, {}}, {part});
Document::Ptr document;
CPlusPlus::Snapshot snapshot;
@@ -506,11 +502,11 @@ void CppToolsPlugin::test_modelmanager_refresh_timeStampModified_if_sourcefiles_
QVERIFY(fileChangerAndRestorer.writeContents(newFileContentes));
// Add or remove source file. The configuration stays the same.
part->files.clear();
foreach (const QString &file, finalProjectFiles)
part->files.append(ProjectFile(file, ProjectFile::CXXSource));
pi = ProjectInfo(project);
pi.appendProjectPart(part);
files = Utils::transform<ProjectFiles>(finalProjectFiles, [](const QString &f) {
return ProjectFile(f, ProjectFile::CXXSource);
});
part = ProjectPart::create(project->projectFilePath(), rpp, {}, files);
pi = ProjectInfo::create({project, KitInfo(nullptr), {}, {}}, {part});
refreshedFiles = helper.updateProjectInfo(pi);
@@ -603,8 +599,7 @@ void CppToolsPlugin::test_modelmanager_extraeditorsupport_uiFiles()
const QString projectFile = temporaryDir.absolutePath("testdata_guiproject1.pro");
ProjectOpenerAndCloser projects;
ProjectInfo projectInfo = projects.open(projectFile, /*configureAsExampleProject=*/ true);
QVERIFY(projectInfo.isValid());
QVERIFY(projects.open(projectFile, /*configureAsExampleProject=*/ true));
// Check working copy.
// An AbstractEditorSupport object should have been added for the ui_* file.
@@ -745,28 +740,26 @@ void CppToolsPlugin::test_modelmanager_defines_per_project()
CppModelManager *mm = CppModelManager::instance();
Project *project = helper.createProject(_("test_modelmanager_defines_per_project"));
const auto project = helper.createProject(_("test_modelmanager_defines_per_project"),
Utils::FilePath::fromString("blubb.pro"));
ProjectPart::Ptr part1(new ProjectPart);
part1->projectFile = QLatin1String("project1.projectfile");
part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource));
part1->files.append(ProjectFile(header, ProjectFile::CXXHeader));
part1->qtVersion = Utils::QtVersion::None;
part1->projectMacros = {{"SUB1"}};
part1->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
RawProjectPart rpp1;
rpp1.setProjectFileLocation("project1.projectfile");
rpp1.setQtVersion(Utils::QtVersion::None);
rpp1.setMacros({{"SUB1"}});
rpp1.setHeaderPaths({{testDataDirectory.includeDir(false), HeaderPathType::User}});
const auto part1 = ProjectPart::create(project->projectFilePath(), rpp1, {},
{{main1File, ProjectFile::CXXSource}, {header, ProjectFile::CXXHeader}});
ProjectPart::Ptr part2(new ProjectPart);
part2->projectFile = QLatin1String("project1.projectfile");
part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource));
part2->files.append(ProjectFile(header, ProjectFile::CXXHeader));
part2->qtVersion = Utils::QtVersion::None;
part2->projectMacros = {{"SUB2"}};
part2->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
ProjectInfo pi = ProjectInfo(project);
pi.appendProjectPart(part1);
pi.appendProjectPart(part2);
RawProjectPart rpp2;
rpp2.setProjectFileLocation("project1.projectfile");
rpp2.setQtVersion(Utils::QtVersion::None);
rpp2.setMacros({{"SUB2"}});
rpp2.setHeaderPaths({{testDataDirectory.includeDir(false), HeaderPathType::User}});
const auto part2 = ProjectPart::create(project->projectFilePath(), rpp2, {},
{{main2File, ProjectFile::CXXSource}, {header, ProjectFile::CXXHeader}});
const auto pi = ProjectInfo::create({project, KitInfo(nullptr), {}, {}}, {part1, part2});
helper.updateProjectInfo(pi);
QCOMPARE(mm->snapshot().size(), 4);
@@ -809,29 +802,26 @@ void CppToolsPlugin::test_modelmanager_precompiled_headers()
CppModelManager *mm = CppModelManager::instance();
Project *project = helper.createProject(_("test_modelmanager_defines_per_project_pch"));
const auto project = helper.createProject(_("test_modelmanager_defines_per_project_pch"),
Utils::FilePath::fromString("blubb.pro"));
ProjectPart::Ptr part1(new ProjectPart);
part1->projectFile = QLatin1String("project1.projectfile");
part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource));
part1->files.append(ProjectFile(header, ProjectFile::CXXHeader));
part1->qtVersion = Utils::QtVersion::None;
part1->precompiledHeaders.append(pch1File);
part1->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
part1->updateLanguageFeatures();
RawProjectPart rpp1;
rpp1.setProjectFileLocation("project1.projectfile");
rpp1.setQtVersion(Utils::QtVersion::None);
rpp1.setPreCompiledHeaders({pch1File});
rpp1.setHeaderPaths({{testDataDirectory.includeDir(false), HeaderPathType::User}});
const auto part1 = ProjectPart::create(project->projectFilePath(), rpp1, {},
{{main1File, ProjectFile::CXXSource}, {header, ProjectFile::CXXHeader}});
ProjectPart::Ptr part2(new ProjectPart);
part2->projectFile = QLatin1String("project2.projectfile");
part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource));
part2->files.append(ProjectFile(header, ProjectFile::CXXHeader));
part2->qtVersion = Utils::QtVersion::None;
part2->precompiledHeaders.append(pch2File);
part2->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
part2->updateLanguageFeatures();
RawProjectPart rpp2;
rpp2.setProjectFileLocation("project2.projectfile");
rpp2.setQtVersion(Utils::QtVersion::None);
rpp2.setPreCompiledHeaders({pch2File});
rpp2.setHeaderPaths({{testDataDirectory.includeDir(false), HeaderPathType::User}});
const auto part2 = ProjectPart::create(project->projectFilePath(), rpp2, {},
{{main2File, ProjectFile::CXXSource}, {header, ProjectFile::CXXHeader}});
ProjectInfo pi = ProjectInfo(project);
pi.appendProjectPart(part1);
pi.appendProjectPart(part2);
const auto pi = ProjectInfo::create({project, KitInfo(nullptr), {}, {}}, {part1, part2});
helper.updateProjectInfo(pi);
QCOMPARE(mm->snapshot().size(), 4);
@@ -891,24 +881,22 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
CppModelManager *mm = CppModelManager::instance();
Project *project = helper.createProject(_("test_modelmanager_defines_per_editor"));
const auto project = helper.createProject(_("test_modelmanager_defines_per_editor"),
Utils::FilePath::fromString("blubb.pro"));
ProjectPart::Ptr part1(new ProjectPart);
part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource));
part1->files.append(ProjectFile(header, ProjectFile::CXXHeader));
part1->qtVersion = Utils::QtVersion::None;
part1->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
RawProjectPart rpp1;
rpp1.setQtVersion(Utils::QtVersion::None);
rpp1.setHeaderPaths({{testDataDirectory.includeDir(false), HeaderPathType::User}});
const auto part1 = ProjectPart::create(project->projectFilePath(), rpp1, {},
{{main1File, ProjectFile::CXXSource}, {header, ProjectFile::CXXHeader}});
ProjectPart::Ptr part2(new ProjectPart);
part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource));
part2->files.append(ProjectFile(header, ProjectFile::CXXHeader));
part2->qtVersion = Utils::QtVersion::None;
part2->headerPaths = {{testDataDirectory.includeDir(false), HeaderPathType::User}};
ProjectInfo pi = ProjectInfo(project);
pi.appendProjectPart(part1);
pi.appendProjectPart(part2);
RawProjectPart rpp2;
rpp2.setQtVersion(Utils::QtVersion::None);
rpp2.setHeaderPaths({{testDataDirectory.includeDir(false), HeaderPathType::User}});
const auto part2 = ProjectPart::create(project->projectFilePath(), rpp2, {},
{{main2File, ProjectFile::CXXSource}, {header, ProjectFile::CXXHeader}});
const auto pi = ProjectInfo::create({project, KitInfo(nullptr), {}, {}}, {part1, part2});
helper.updateProjectInfo(pi);
QCOMPARE(mm->snapshot().size(), 4);
@@ -960,7 +948,7 @@ void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
QCOMPARE(Core::DocumentModel::openedDocuments().size(), 1);
QVERIFY(TestCase::waitForProcessedEditorDocument(fileA));
ProjectPart::Ptr documentAProjectPart = projectPartOfEditorDocument(fileA);
QVERIFY(!documentAProjectPart->project);
QVERIFY(!documentAProjectPart->hasProject());
// Open file B in editor
Core::IEditor *editorB = Core::EditorManager::openEditor(fileB);
@@ -969,34 +957,32 @@ void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
QCOMPARE(Core::DocumentModel::openedDocuments().size(), 2);
QVERIFY(TestCase::waitForProcessedEditorDocument(fileB));
ProjectPart::Ptr documentBProjectPart = projectPartOfEditorDocument(fileB);
QVERIFY(!documentBProjectPart->project);
QVERIFY(!documentBProjectPart->hasProject());
// Switch back to document A
Core::EditorManager::activateEditor(editorA);
// Open/update related project
Project *project = helper.createProject(_("test_modelmanager_updateEditorsAfterProjectUpdate"));
ProjectPart::Ptr part(new ProjectPart);
part->project = project;
part->files.append(ProjectFile(fileA, ProjectFile::CXXSource));
part->files.append(ProjectFile(fileB, ProjectFile::CXXSource));
part->qtVersion = Utils::QtVersion::None;
ProjectInfo pi = ProjectInfo(project);
pi.appendProjectPart(part);
const auto project
= helper.createProject(_("test_modelmanager_updateEditorsAfterProjectUpdate"),
Utils::FilePath::fromString("blubb.pro"));
RawProjectPart rpp;
rpp.setQtVersion(Utils::QtVersion::None);
const auto part = ProjectPart::create(project->projectFilePath(), rpp, {},
{{fileA, ProjectFile::CXXSource}, {fileB, ProjectFile::CXXSource}});
const auto pi = ProjectInfo::create({project, KitInfo(nullptr), {}, {}}, {part});
helper.updateProjectInfo(pi);
// ... and check for updated editor document A
QVERIFY(TestCase::waitForProcessedEditorDocument(fileA));
documentAProjectPart = projectPartOfEditorDocument(fileA);
QCOMPARE(documentAProjectPart->project, project);
QCOMPARE(documentAProjectPart->topLevelProject, pi->projectFilePath());
// Switch back to document B and check if that's updated, too
Core::EditorManager::activateEditor(editorB);
QVERIFY(TestCase::waitForProcessedEditorDocument(fileB));
documentBProjectPart = projectPartOfEditorDocument(fileB);
QCOMPARE(documentBProjectPart->project, project);
QCOMPARE(documentBProjectPart->topLevelProject, pi->projectFilePath());
}
void CppToolsPlugin::test_modelmanager_renameIncludes()

View File

@@ -42,24 +42,23 @@ using namespace ProjectExplorer;
namespace CppTools {
namespace Internal {
ProjectInfoGenerator::ProjectInfoGenerator(const QFutureInterface<ProjectInfo> &futureInterface,
ProjectInfoGenerator::ProjectInfoGenerator(const QFutureInterface<ProjectInfo::Ptr> &futureInterface,
const ProjectUpdateInfo &projectUpdateInfo)
: m_futureInterface(futureInterface)
, m_projectUpdateInfo(projectUpdateInfo)
{
}
ProjectInfo ProjectInfoGenerator::generate()
ProjectInfo::Ptr ProjectInfoGenerator::generate()
{
ProjectInfo projectInfo(m_projectUpdateInfo.project);
QVector<ProjectPart::Ptr> projectParts;
for (const RawProjectPart &rpp : m_projectUpdateInfo.rawProjectParts) {
if (m_futureInterface.isCanceled())
return ProjectInfo();
for (const ProjectPart::Ptr &part : createProjectParts(rpp))
projectInfo.appendProjectPart(part);
return {};
for (const ProjectPart::Ptr &part : createProjectParts(rpp, m_projectUpdateInfo.projectFilePath))
projectParts << part;
}
const auto projectInfo = ProjectInfo::create(m_projectUpdateInfo, projectParts);
static const auto showWarning = [](const QString &message) {
QTimer::singleShot(0, TaskHub::instance(), [message] {
@@ -79,40 +78,8 @@ ProjectInfo ProjectInfoGenerator::generate()
return projectInfo;
}
static ProjectPart::Ptr projectPartFromRawProjectPart(
const RawProjectPart &rawProjectPart, Project *project)
{
ProjectPart::Ptr part(new ProjectPart);
part->project = project;
part->projectFile = rawProjectPart.projectFile;
part->projectConfigFile = rawProjectPart.projectConfigFile;
part->projectFileLine = rawProjectPart.projectFileLine;
part->projectFileColumn = rawProjectPart.projectFileColumn;
part->callGroupId = rawProjectPart.callGroupId;
part->buildSystemTarget = rawProjectPart.buildSystemTarget;
part->buildTargetType = rawProjectPart.buildTargetType;
part->qtVersion = rawProjectPart.qtVersion;
part->projectMacros = rawProjectPart.projectMacros;
if (!part->projectConfigFile.isEmpty())
part->projectMacros += Macro::toMacros(ProjectPart::readProjectConfigFile(part));
// Prevent duplicate include paths.
std::set<QString> seenPaths;
for (const HeaderPath &p : qAsConst(rawProjectPart.headerPaths)) {
const QString cleanPath = QDir::cleanPath(p.path);
if (seenPaths.insert(cleanPath).second)
part->headerPaths << HeaderPath(cleanPath, p.type);
}
part->precompiledHeaders = rawProjectPart.precompiledHeaders;
part->includedFiles = rawProjectPart.includedFiles;
part->selectedForBuilding = rawProjectPart.selectedForBuilding;
return part;
}
const QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(
const RawProjectPart &rawProjectPart)
const RawProjectPart &rawProjectPart, const Utils::FilePath &projectFilePath)
{
using Utils::LanguageExtension;
@@ -124,21 +91,18 @@ const QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(
if (!cat.hasParts())
return result;
const ProjectPart::Ptr part = projectPartFromRawProjectPart(rawProjectPart,
m_projectUpdateInfo.project);
if (m_projectUpdateInfo.cxxToolChain) {
if (m_projectUpdateInfo.cxxToolChainInfo.isValid()) {
if (cat.hasCxxSources()) {
result << createProjectPart(rawProjectPart,
part,
result << createProjectPart(projectFilePath,
rawProjectPart,
cat.cxxSources(),
cat.partName("C++"),
Language::Cxx,
LanguageExtension::None);
}
if (cat.hasObjcxxSources()) {
result << createProjectPart(rawProjectPart,
part,
result << createProjectPart(projectFilePath,
rawProjectPart,
cat.objcxxSources(),
cat.partName("Obj-C++"),
Language::Cxx,
@@ -148,10 +112,10 @@ const QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(
m_cxxToolchainMissing = true;
}
if (m_projectUpdateInfo.cToolChain) {
if (m_projectUpdateInfo.cToolChainInfo.isValid()) {
if (cat.hasCSources()) {
result << createProjectPart(rawProjectPart,
part,
result << createProjectPart(projectFilePath,
rawProjectPart,
cat.cSources(),
cat.partName("C"),
Language::C,
@@ -159,8 +123,8 @@ const QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(
}
if (cat.hasObjcSources()) {
result << createProjectPart(rawProjectPart,
part,
result << createProjectPart(projectFilePath,
rawProjectPart,
cat.objcSources(),
cat.partName("Obj-C"),
Language::C,
@@ -174,12 +138,12 @@ const QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(
}
ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
const RawProjectPart &rawProjectPart,
const ProjectPart::Ptr &templateProjectPart,
const ProjectFiles &projectFiles,
const QString &partName,
Language language,
Utils::LanguageExtensions languageExtensions)
const Utils::FilePath &projectFilePath,
const RawProjectPart &rawProjectPart,
const ProjectFiles &projectFiles,
const QString &partName,
Language language,
Utils::LanguageExtensions languageExtensions)
{
RawProjectPartFlags flags;
ToolChainInfo tcInfo;
@@ -193,16 +157,8 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
tcInfo = m_projectUpdateInfo.cxxToolChainInfo;
}
ProjectPart::Ptr part(templateProjectPart->copy());
part->displayName = partName;
part->files = projectFiles;
part->warningFlags = flags.warningFlags;
part->language = language;
part->languageExtensions = flags.languageExtensions | languageExtensions;
part->setupToolchainProperties(tcInfo, flags.commandLineFlags);
part->updateLanguageFeatures();
return part;
return ProjectPart::create(projectFilePath, rawProjectPart, partName, projectFiles,
language, languageExtensions, flags, tcInfo);
}
} // namespace Internal

View File

@@ -36,23 +36,22 @@ namespace Internal {
class ProjectInfoGenerator
{
public:
ProjectInfoGenerator(const QFutureInterface<ProjectInfo> &futureInterface,
ProjectInfoGenerator(const QFutureInterface<ProjectInfo::Ptr> &futureInterface,
const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo);
ProjectInfo generate();
ProjectInfo::Ptr generate();
private:
const QVector<ProjectPart::Ptr> createProjectParts(
const ProjectExplorer::RawProjectPart &rawProjectPart);
ProjectPart::Ptr createProjectPart(const ProjectExplorer::RawProjectPart &rawProjectPart,
const ProjectPart::Ptr &templateProjectPart,
const QVector<ProjectPart::Ptr> createProjectParts(const ProjectExplorer::RawProjectPart &rawProjectPart, const Utils::FilePath &projectFilePath);
ProjectPart::Ptr createProjectPart(const Utils::FilePath &projectFilePath,
const ProjectExplorer::RawProjectPart &rawProjectPart,
const ProjectFiles &projectFiles,
const QString &partName,
Language language,
Utils::LanguageExtensions languageExtensions);
private:
const QFutureInterface<ProjectInfo> m_futureInterface;
const QFutureInterface<ProjectInfo::Ptr> m_futureInterface;
const ProjectExplorer::ProjectUpdateInfo &m_projectUpdateInfo;
bool m_cToolchainMissing = false;
bool m_cxxToolchainMissing = false;

View File

@@ -102,7 +102,7 @@ private:
if (!m_preferredProjectPartId.isEmpty() && projectPart.id() == m_preferredProjectPartId)
thePriority += 1000;
if (projectPart.project == m_activeProject)
if (projectPart.belongsToProject(m_activeProject))
thePriority += 100;
if (projectPart.selectedForBuilding)

View File

@@ -74,13 +74,10 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo,
});
m_projectUpdateInfo = projectUpdateInfo;
// Ensure that we do not operate on a deleted toolchain.
using namespace ProjectExplorer;
connect(ToolChainManager::instance(), &ToolChainManager::toolChainRemoved,
this, &CppProjectUpdater::onToolChainRemoved);
// Run the project info generator in a worker thread and continue if that one is finished.
auto generateFuture = Utils::runAsync([=](QFutureInterface<ProjectInfo> &futureInterface) {
auto generateFuture = Utils::runAsync([=](QFutureInterface<ProjectInfo::Ptr> &futureInterface) {
ProjectUpdateInfo fullProjectUpdateInfo = projectUpdateInfo;
if (fullProjectUpdateInfo.rppGenerator)
fullProjectUpdateInfo.rawProjectParts = fullProjectUpdateInfo.rppGenerator();
@@ -134,20 +131,8 @@ void CppProjectUpdater::cancel()
m_futureSynchronizer.cancelAllFutures();
}
void CppProjectUpdater::onToolChainRemoved(ToolChain *t)
{
QTC_ASSERT(t, return);
if (t == m_projectUpdateInfo.cToolChain || t == m_projectUpdateInfo.cxxToolChain)
cancel();
}
void CppProjectUpdater::onProjectInfoGenerated()
{
// From now on we do not access the toolchain anymore, so disconnect.
using namespace ProjectExplorer;
disconnect(ToolChainManager::instance(), &ToolChainManager::toolChainRemoved,
this, &CppProjectUpdater::onToolChainRemoved);
if (m_generateFutureWatcher.isCanceled() || m_generateFutureWatcher.future().resultCount() < 1)
return;

View File

@@ -63,7 +63,6 @@ public:
void cancel() override;
private:
void onToolChainRemoved(ProjectExplorer::ToolChain *);
void onProjectInfoGenerated();
void checkForExtraCompilersFinished();
@@ -71,7 +70,7 @@ private:
ProjectExplorer::ProjectUpdateInfo m_projectUpdateInfo;
QList<QPointer<ProjectExplorer::ExtraCompiler>> m_extraCompilers;
QFutureWatcher<ProjectInfo> m_generateFutureWatcher;
QFutureWatcher<ProjectInfo::Ptr> m_generateFutureWatcher;
bool m_isProjectInfoGenerated = false;
QSet<QFutureWatcher<void> *> m_extraCompilersFutureWatchers;
std::unique_ptr<QFutureInterface<void>> m_projectUpdateFutureInterface;

View File

@@ -469,9 +469,9 @@ QString correspondingHeaderOrSource(const QString &fileName, bool *wasHeader, Ca
// Find files in other projects
} else {
CppModelManager *modelManager = CppModelManager::instance();
QList<ProjectInfo> projectInfos = modelManager->projectInfos();
foreach (const ProjectInfo &projectInfo, projectInfos) {
const ProjectExplorer::Project *project = projectInfo.project().data();
QList<ProjectInfo::Ptr> projectInfos = modelManager->projectInfos();
foreach (const ProjectInfo::Ptr &projectInfo, projectInfos) {
const ProjectExplorer::Project *project = projectForProjectInfo(*projectInfo);
if (project == currentProject)
continue; // We have already checked the current project.

View File

@@ -29,11 +29,13 @@
#include "cpprefactoringchanges.h"
#include "cpptoolsconstants.h"
#include "cpptoolsplugin.h"
#include "projectinfo.h"
#include <coreplugin/documentmanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/idocument.h>
#include <coreplugin/messagemanager.h>
#include <projectexplorer/session.h>
#include <cplusplus/Overview.h>
#include <cplusplus/LookupContext.h>
@@ -572,4 +574,14 @@ NamespaceAST *NSCheckerVisitor::currentNamespace()
return m_enteredNamespaces.empty() ? nullptr : m_enteredNamespaces.back();
}
ProjectExplorer::Project *projectForProjectPart(const ProjectPart &part)
{
return ProjectExplorer::SessionManager::projectWithProjectFilePath(part.topLevelProject);
}
ProjectExplorer::Project *projectForProjectInfo(const ProjectInfo &info)
{
return ProjectExplorer::SessionManager::projectWithProjectFilePath(info.projectFilePath());
}
} // CppTools

View File

@@ -49,6 +49,7 @@ class LookupContext;
namespace CppTools {
class CppRefactoringFile;
class ProjectInfo;
void CPPTOOLS_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc);
void CPPTOOLS_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc);
@@ -83,6 +84,9 @@ UsePrecompiledHeaders CPPTOOLS_EXPORT getPchUsage();
int indexerFileSizeLimitInMb();
bool fileSizeExceedsLimit(const QFileInfo &fileInfo, int sizeLimitInMb);
ProjectExplorer::Project CPPTOOLS_EXPORT *projectForProjectInfo(const CppTools::ProjectInfo &info);
ProjectExplorer::Project CPPTOOLS_EXPORT *projectForProjectPart(const CppTools::ProjectPart &part);
class ClangDiagnosticConfigsModel;
ClangDiagnosticConfigsModel CPPTOOLS_EXPORT diagnosticConfigsModel();
ClangDiagnosticConfigsModel CPPTOOLS_EXPORT

View File

@@ -237,7 +237,7 @@ bool TestCase::waitUntilProjectIsFullyOpened(Project *project, int timeOutInMs)
[project]() {
return SessionManager::startupBuildSystem()
&& !SessionManager::startupBuildSystem()->isParsing()
&& CppModelManager::instance()->projectInfo(project).isValid();
&& CppModelManager::instance()->projectInfo(project);
},
timeOutInMs);
}
@@ -278,14 +278,14 @@ ProjectOpenerAndCloser::~ProjectOpenerAndCloser()
QCoreApplication::processEvents();
}
ProjectInfo ProjectOpenerAndCloser::open(const QString &projectFile, bool configureAsExampleProject,
Kit *kit)
ProjectInfo::Ptr ProjectOpenerAndCloser::open(const QString &projectFile,
bool configureAsExampleProject, Kit *kit)
{
ProjectExplorerPlugin::OpenProjectResult result =
ProjectExplorerPlugin::openProject(FilePath::fromString(projectFile));
if (!result) {
qWarning() << result.errorMessage() << result.alreadyOpen();
return ProjectInfo();
return {};
}
Project *project = result.project();
@@ -297,7 +297,7 @@ ProjectInfo ProjectOpenerAndCloser::open(const QString &projectFile, bool config
return CppModelManager::instance()->projectInfo(project);
}
return ProjectInfo();
return {};
}
TemporaryDir::TemporaryDir()

View File

@@ -27,6 +27,8 @@
#include "cpptools_global.h"
#include "projectinfo.h"
#include <cplusplus/CppDocument.h>
#include <utils/temporarydirectory.h>
@@ -52,7 +54,6 @@ class IAssistProposal;
namespace CppTools {
class CppModelManager;
class ProjectInfo;
namespace Tests {
@@ -140,7 +141,7 @@ public:
ProjectOpenerAndCloser();
~ProjectOpenerAndCloser(); // Closes opened projects
ProjectInfo open(const QString &projectFile, bool configureAsExampleProject = false,
CppTools::ProjectInfo::Ptr open(const QString &projectFile, bool configureAsExampleProject = false,
ProjectExplorer::Kit *kit = nullptr);
private:

View File

@@ -29,6 +29,8 @@
#include "cppworkingcopy.h"
#include "projectinfo.h"
#include <projectexplorer/session.h>
#include <QtTest>
#include <cassert>
@@ -36,8 +38,8 @@
using namespace CppTools::Internal;
using namespace CppTools::Tests;
TestProject::TestProject(const QString &name, QObject *parent) :
ProjectExplorer::Project("x-binary/foo", Utils::FilePath()),
TestProject::TestProject(const QString &name, QObject *parent, const Utils::FilePath &filePath) :
ProjectExplorer::Project("x-binary/foo", filePath),
m_name(name)
{
setParent(parent);
@@ -75,22 +77,28 @@ ModelManagerTestHelper::~ModelManagerTestHelper()
void ModelManagerTestHelper::cleanup()
{
CppModelManager *mm = CppModelManager::instance();
QList<ProjectInfo> pies = mm->projectInfos();
foreach (const ProjectInfo &pie, pies)
emit aboutToRemoveProject(pie.project().data());
QList<ProjectInfo::Ptr> pies = mm->projectInfos();
for (Project * const p : qAsConst(m_projects)) {
ProjectExplorer::SessionManager::removeProject(p);
emit aboutToRemoveProject(p);
}
if (!pies.isEmpty())
waitForFinishedGc();
}
ModelManagerTestHelper::Project *ModelManagerTestHelper::createProject(const QString &name)
ModelManagerTestHelper::Project *ModelManagerTestHelper::createProject(
const QString &name, const Utils::FilePath &filePath)
{
auto tp = new TestProject(name, this);
auto tp = new TestProject(name, this, filePath);
m_projects.push_back(tp);
ProjectExplorer::SessionManager::addProject(tp);
emit projectAdded(tp);
return tp;
}
QSet<QString> ModelManagerTestHelper::updateProjectInfo(const CppTools::ProjectInfo &projectInfo)
QSet<QString> ModelManagerTestHelper::updateProjectInfo(
const CppTools::ProjectInfo::Ptr &projectInfo)
{
resetRefreshedSourceFiles();
CppModelManager::instance()->updateProjectInfo(projectInfo).waitForFinished();

View File

@@ -40,7 +40,7 @@ class CPPTOOLS_EXPORT TestProject: public ProjectExplorer::Project
Q_OBJECT
public:
TestProject(const QString &name, QObject *parent);
TestProject(const QString &name, QObject *parent, const Utils::FilePath &filePath = {});
bool needsConfiguration() const final { return false; }
@@ -61,9 +61,9 @@ public:
void cleanup();
Project *createProject(const QString &name);
Project *createProject(const QString &name, const Utils::FilePath &filePath = {});
QSet<QString> updateProjectInfo(const ProjectInfo &projectInfo);
QSet<QString> updateProjectInfo(const ProjectInfo::Ptr &projectInfo);
void resetRefreshedSourceFiles();
QSet<QString> waitForRefreshedSourceFiles();
@@ -82,6 +82,7 @@ private:
bool m_refreshHappened;
bool m_testOnlyForCleanedProjects;
QSet<QString> m_lastRefreshedSourceFiles;
QList<Project *> m_projects;
};
} // namespace Tests

View File

@@ -33,19 +33,10 @@
namespace CppTools {
ProjectInfo::ProjectInfo(QPointer<ProjectExplorer::Project> project)
: m_project(project)
ProjectInfo::Ptr ProjectInfo::create(const ProjectExplorer::ProjectUpdateInfo &updateInfo,
const QVector<ProjectPart::Ptr> &projectParts)
{
}
bool ProjectInfo::isValid() const
{
return !m_project.isNull();
}
QPointer<ProjectExplorer::Project> ProjectInfo::project() const
{
return m_project;
return Ptr(new ProjectInfo(updateInfo, projectParts));
}
const QVector<ProjectPart::Ptr> ProjectInfo::projectParts() const
@@ -60,7 +51,9 @@ const QSet<QString> ProjectInfo::sourceFiles() const
bool ProjectInfo::operator ==(const ProjectInfo &other) const
{
return m_project == other.m_project
return m_projectName == other.m_projectName
&& m_projectFilePath == other.m_projectFilePath
&& m_buildRoot == other.m_buildRoot
&& m_projectParts == other.m_projectParts
&& m_headerPaths == other.m_headerPaths
&& m_sourceFiles == other.m_sourceFiles
@@ -87,35 +80,46 @@ bool ProjectInfo::configurationOrFilesChanged(const ProjectInfo &other) const
return configurationChanged(other) || m_sourceFiles != other.m_sourceFiles;
}
void ProjectInfo::appendProjectPart(const ProjectPart::Ptr &projectPart)
static QSet<QString> getSourceFiles(const QVector<ProjectPart::Ptr> &projectParts)
{
if (projectPart)
m_projectParts.append(projectPart);
QSet<QString> sourceFiles;
for (const ProjectPart::Ptr &part : projectParts) {
for (const ProjectFile &file : qAsConst(part->files))
sourceFiles.insert(file.path);
}
return sourceFiles;
}
void ProjectInfo::finish()
static ProjectExplorer::Macros getDefines(const QVector<ProjectPart::Ptr> &projectParts)
{
ProjectExplorer::Macros defines;
for (const ProjectPart::Ptr &part : projectParts) {
defines.append(part->toolChainMacros);
defines.append(part->projectMacros);
}
return defines;
}
static ProjectExplorer::HeaderPaths getHeaderPaths(const QVector<ProjectPart::Ptr> &projectParts)
{
QSet<ProjectExplorer::HeaderPath> uniqueHeaderPaths;
foreach (const ProjectPart::Ptr &part, m_projectParts) {
// Update header paths
foreach (const ProjectExplorer::HeaderPath &headerPath, part->headerPaths) {
const int count = uniqueHeaderPaths.count();
for (const ProjectPart::Ptr &part : projectParts) {
for (const ProjectExplorer::HeaderPath &headerPath : qAsConst(part->headerPaths))
uniqueHeaderPaths.insert(headerPath);
if (count < uniqueHeaderPaths.count())
m_headerPaths += headerPath;
}
// Update source files
foreach (const ProjectFile &file, part->files)
m_sourceFiles.insert(file.path);
// Update defines
m_defines.append(part->toolChainMacros);
m_defines.append(part->projectMacros);
if (!part->projectConfigFile.isEmpty())
m_defines += ProjectExplorer::Macro::toMacros(ProjectPart::readProjectConfigFile(part));
}
return ProjectExplorer::HeaderPaths(uniqueHeaderPaths.cbegin(), uniqueHeaderPaths.cend());
}
ProjectInfo::ProjectInfo(const ProjectExplorer::ProjectUpdateInfo &updateInfo,
const QVector<ProjectPart::Ptr> &projectParts)
: m_projectParts(projectParts),
m_projectName(updateInfo.projectName),
m_projectFilePath(updateInfo.projectFilePath),
m_buildRoot(updateInfo.buildRoot),
m_headerPaths(getHeaderPaths(projectParts)),
m_sourceFiles(getSourceFiles(projectParts)),
m_defines(getDefines(projectParts))
{
}
} // namespace CppTools

View File

@@ -32,25 +32,29 @@
#include <projectexplorer/project.h>
#include <projectexplorer/rawprojectpart.h>
#include <projectexplorer/toolchain.h>
#include <utils/fileutils.h>
#include <QHash>
#include <QPointer>
#include <QSet>
#include <QVector>
#include <memory>
namespace CppTools {
class CPPTOOLS_EXPORT ProjectInfo
{
public:
ProjectInfo() = default;
explicit ProjectInfo(QPointer<ProjectExplorer::Project> project);
using Ptr = std::shared_ptr<ProjectInfo>;
static Ptr create(const ProjectExplorer::ProjectUpdateInfo &updateInfo,
const QVector<ProjectPart::Ptr> &projectParts);
bool isValid() const;
QPointer<ProjectExplorer::Project> project() const;
const QVector<ProjectPart::Ptr> projectParts() const;
const QSet<QString> sourceFiles() const;
QString projectName() const { return m_projectName; }
Utils::FilePath projectFilePath() const { return m_projectFilePath; }
Utils::FilePath projectRoot() const { return m_projectFilePath.parentDir(); }
Utils::FilePath buildRoot() const { return m_buildRoot; }
// Comparisons
bool operator ==(const ProjectInfo &other) const;
@@ -59,18 +63,17 @@ public:
bool configurationChanged(const ProjectInfo &other) const;
bool configurationOrFilesChanged(const ProjectInfo &other) const;
// Construction
void appendProjectPart(const ProjectPart::Ptr &projectPart);
void finish();
private:
QPointer<ProjectExplorer::Project> m_project;
QVector<ProjectPart::Ptr> m_projectParts;
ProjectInfo(const ProjectExplorer::ProjectUpdateInfo &updateInfo,
const QVector<ProjectPart::Ptr> &projectParts);
// The members below are (re)calculated from the project parts with finish()
ProjectExplorer::HeaderPaths m_headerPaths;
QSet<QString> m_sourceFiles;
ProjectExplorer::Macros m_defines;
const QVector<ProjectPart::Ptr> m_projectParts;
const QString m_projectName;
const Utils::FilePath m_projectFilePath;
const Utils::FilePath m_buildRoot;
const ProjectExplorer::HeaderPaths m_headerPaths;
const QSet<QString> m_sourceFiles;
const ProjectExplorer::Macros m_defines;
};
} // namespace CppTools

View File

@@ -60,19 +60,22 @@ public:
const ProjectPartInfo choose()
{
return chooser.choose(filePath, currentProjectPartInfo, preferredProjectPartId,
activeProject, languagePreference, projectsChanged);
projectMap.value(activeProject).get(),
languagePreference, projectsChanged);
}
static QList<ProjectPart::Ptr> createProjectPartsWithDifferentProjects()
{
QList<ProjectPart::Ptr> projectParts;
const ProjectPart::Ptr p1{new ProjectPart};
p1->project = reinterpret_cast<Project *>(1 << 0);
projectParts.append(p1);
const ProjectPart::Ptr p2{new ProjectPart};
p2->project = reinterpret_cast<Project *>(1 << 1);
projectParts.append(p2);
const auto p1 = std::make_shared<Project>(
QString(), Utils::FilePath::fromString("p1.pro"));
projectMap.insert(p1->projectFilePath(), p1);
projectParts.append(ProjectPart::create(p1->projectFilePath()));
const auto p2 = std::make_shared<Project>(
QString(), Utils::FilePath::fromString("p2.pro"));
projectMap.insert(p2->projectFilePath(), p2);
projectParts.append(ProjectPart::create(p2->projectFilePath()));
return projectParts;
}
@@ -80,27 +83,34 @@ public:
static QList<ProjectPart::Ptr> createCAndCxxProjectParts()
{
QList<ProjectPart::Ptr> projectParts;
ToolChainInfo tcInfo;
// Create project part for C
const ProjectPart::Ptr cprojectpart{new ProjectPart};
cprojectpart->languageVersion = Utils::LanguageVersion::C11;
tcInfo.macroInspectionRunner = [](const QStringList &) {
return ToolChain::MacroInspectionReport{{}, Utils::LanguageVersion::C11};
};
const ProjectPart::Ptr cprojectpart = ProjectPart::create({}, {}, {}, {}, {}, {}, {},
tcInfo);
projectParts.append(cprojectpart);
// Create project part for CXX
const ProjectPart::Ptr cxxprojectpart{new ProjectPart};
cxxprojectpart->languageVersion = Utils::LanguageVersion::CXX98;
tcInfo.macroInspectionRunner = [](const QStringList &) {
return ToolChain::MacroInspectionReport{{}, Utils::LanguageVersion::CXX98};
};
const ProjectPart::Ptr cxxprojectpart = ProjectPart::create({}, {}, {}, {}, {}, {}, {},
tcInfo);
projectParts.append(cxxprojectpart);
return projectParts;
}
QString filePath;
ProjectPart::Ptr currentProjectPart{new ProjectPart};
ProjectPart::Ptr currentProjectPart = ProjectPart::create({});
ProjectPartInfo currentProjectPartInfo{currentProjectPart,
{currentProjectPart},
ProjectPartInfo::NoHint};
QString preferredProjectPartId;
const Project *activeProject = nullptr;
Utils::FilePath activeProject;
Language languagePreference = Language::Cxx;
bool projectsChanged = false;
ProjectPartChooser chooser;
@@ -108,15 +118,21 @@ public:
QList<ProjectPart::Ptr> projectPartsForFile;
QList<ProjectPart::Ptr> projectPartsFromDependenciesForFile;
ProjectPart::Ptr fallbackProjectPart;
static QHash<Utils::FilePath, std::shared_ptr<Project>> projectMap;
};
QHash<Utils::FilePath, std::shared_ptr<Project>>
ProjectPartChooserTest::projectMap;
}
void CppToolsPlugin::test_projectPartChooser_chooseManuallySet()
{
ProjectPart::Ptr p1(new ProjectPart);
ProjectPart::Ptr p2(new ProjectPart);
ProjectPart::Ptr p1 = ProjectPart::create({});
RawProjectPart rpp2;
rpp2.setProjectFileLocation("someId");
ProjectPart::Ptr p2 = ProjectPart::create({}, rpp2);
ProjectPartChooserTest t;
p2->projectFile = "someId";
t.preferredProjectPartId = p2->projectFile;
t.projectPartsForFile += {p1, p2};
@@ -125,10 +141,11 @@ void CppToolsPlugin::test_projectPartChooser_chooseManuallySet()
void CppToolsPlugin::test_projectPartChooser_indicateManuallySet()
{
ProjectPart::Ptr p1(new ProjectPart);
ProjectPart::Ptr p2(new ProjectPart);
ProjectPart::Ptr p1 = ProjectPart::create({});
RawProjectPart rpp2;
rpp2.setProjectFileLocation("someId");
ProjectPart::Ptr p2 = ProjectPart::create({}, rpp2);
ProjectPartChooserTest t;
p2->projectFile = "someId";
t.preferredProjectPartId = p2->projectFile;
t.projectPartsForFile += {p1, p2};
@@ -137,10 +154,11 @@ void CppToolsPlugin::test_projectPartChooser_indicateManuallySet()
void CppToolsPlugin::test_projectPartChooser_indicateManuallySetForFallbackToProjectPartFromDependencies()
{
ProjectPart::Ptr p1(new ProjectPart);
ProjectPart::Ptr p2(new ProjectPart);
ProjectPart::Ptr p1 = ProjectPart::create({});
RawProjectPart rpp2;
rpp2.setProjectFileLocation("someId");
ProjectPart::Ptr p2 = ProjectPart::create({}, rpp2);
ProjectPartChooserTest t;
p2->projectFile = "someId";
t.preferredProjectPartId = p2->projectFile;
t.projectPartsFromDependenciesForFile += {p1, p2};
@@ -158,17 +176,19 @@ void CppToolsPlugin::test_projectPartChooser_forMultipleChooseFromActiveProject(
const QList<ProjectPart::Ptr> projectParts = t.createProjectPartsWithDifferentProjects();
const ProjectPart::Ptr secondProjectPart = projectParts.at(1);
t.projectPartsForFile += projectParts;
t.activeProject = secondProjectPart->project;
t.activeProject = secondProjectPart->topLevelProject;
QCOMPARE(t.choose().projectPart, secondProjectPart);
}
void CppToolsPlugin::test_projectPartChooser_forMultiplePreferSelectedForBuilding()
{
const ProjectPart::Ptr firstProjectPart{new ProjectPart};
const ProjectPart::Ptr secondProjectPart{new ProjectPart};
firstProjectPart->selectedForBuilding = false;
secondProjectPart->selectedForBuilding = true;
RawProjectPart rpp1;
rpp1.setSelectedForBuilding(false);
RawProjectPart rpp2;
rpp1.setSelectedForBuilding(true);
const ProjectPart::Ptr firstProjectPart = ProjectPart::create({}, rpp1);
const ProjectPart::Ptr secondProjectPart = ProjectPart::create({}, rpp2);
ProjectPartChooserTest t;
t.projectPartsForFile += firstProjectPart;
t.projectPartsForFile += secondProjectPart;
@@ -182,7 +202,7 @@ void CppToolsPlugin::test_projectPartChooser_forMultipleFromDependenciesChooseFr
const QList<ProjectPart::Ptr> projectParts = t.createProjectPartsWithDifferentProjects();
const ProjectPart::Ptr secondProjectPart = projectParts.at(1);
t.projectPartsFromDependenciesForFile += projectParts;
t.activeProject = secondProjectPart->project;
t.activeProject = secondProjectPart->topLevelProject;
QCOMPARE(t.choose().projectPart, secondProjectPart);
}
@@ -195,7 +215,7 @@ void CppToolsPlugin::test_projectPartChooser_forMultipleCheckIfActiveProjectChan
const ProjectPart::Ptr secondProjectPart = projectParts.at(1);
t.projectPartsForFile += projectParts;
t.currentProjectPartInfo.projectPart = firstProjectPart;
t.activeProject = secondProjectPart->project;
t.activeProject = secondProjectPart->topLevelProject;
QCOMPARE(t.choose().projectPart, secondProjectPart);
}
@@ -222,27 +242,27 @@ void CppToolsPlugin::test_projectPartChooser_forMultipleAndAmbigiousHeaderPrefer
void CppToolsPlugin::test_projectPartChooser_indicateMultiple()
{
const ProjectPart::Ptr p1{new ProjectPart};
const ProjectPart::Ptr p2{new ProjectPart};
const ProjectPart::Ptr p1 = ProjectPart::create({});
const ProjectPart::Ptr p2 = ProjectPart::create({});
ProjectPartChooserTest t;
t.projectPartsForFile += { p1, p2 };
t.projectPartsForFile += {p1, p2};
QVERIFY(t.choose().hints & ProjectPartInfo::IsAmbiguousMatch);
}
void CppToolsPlugin::test_projectPartChooser_indicateMultipleForFallbackToProjectPartFromDependencies()
{
const ProjectPart::Ptr p1{new ProjectPart};
const ProjectPart::Ptr p2{new ProjectPart};
const ProjectPart::Ptr p1 = ProjectPart::create({});
const ProjectPart::Ptr p2 = ProjectPart::create({});
ProjectPartChooserTest t;
t.projectPartsFromDependenciesForFile += { p1, p2 };
t.projectPartsFromDependenciesForFile += {p1, p2};
QVERIFY(t.choose().hints & ProjectPartInfo::IsAmbiguousMatch);
}
void CppToolsPlugin::test_projectPartChooser_forMultipleChooseNewIfPreviousIsGone()
{
const ProjectPart::Ptr newProjectPart{new ProjectPart};
const ProjectPart::Ptr newProjectPart = ProjectPart::create({});
ProjectPartChooserTest t;
t.projectPartsForFile += newProjectPart;
@@ -251,7 +271,7 @@ void CppToolsPlugin::test_projectPartChooser_forMultipleChooseNewIfPreviousIsGon
void CppToolsPlugin::test_projectPartChooser_fallbackToProjectPartFromDependencies()
{
const ProjectPart::Ptr fromDependencies{new ProjectPart};
const ProjectPart::Ptr fromDependencies = ProjectPart::create({});
ProjectPartChooserTest t;
t.projectPartsFromDependenciesForFile += fromDependencies;
@@ -261,7 +281,7 @@ void CppToolsPlugin::test_projectPartChooser_fallbackToProjectPartFromDependenci
void CppToolsPlugin::test_projectPartChooser_fallbackToProjectPartFromModelManager()
{
ProjectPartChooserTest t;
t.fallbackProjectPart.reset(new ProjectPart);
t.fallbackProjectPart = ProjectPart::create({});
QCOMPARE(t.choose().projectPart, t.fallbackProjectPart);
}
@@ -270,10 +290,10 @@ void CppToolsPlugin::test_projectPartChooser_continueUsingFallbackFromModelManag
{
// ...without re-calculating the dependency table.
ProjectPartChooserTest t;
t.fallbackProjectPart.reset(new ProjectPart);
t.fallbackProjectPart = ProjectPart::create({});
t.currentProjectPartInfo.projectPart = t.fallbackProjectPart;
t.currentProjectPartInfo.hints |= ProjectPartInfo::IsFallbackMatch;
t.projectPartsFromDependenciesForFile += ProjectPart::Ptr(new ProjectPart);
t.projectPartsFromDependenciesForFile += ProjectPart::create({});
QCOMPARE(t.choose().projectPart, t.fallbackProjectPart);
}
@@ -281,10 +301,10 @@ void CppToolsPlugin::test_projectPartChooser_continueUsingFallbackFromModelManag
void CppToolsPlugin::test_projectPartChooser_stopUsingFallbackFromModelManagerIfProjectChanges1()
{
ProjectPartChooserTest t;
t.fallbackProjectPart.reset(new ProjectPart);
t.fallbackProjectPart = ProjectPart::create({});
t.currentProjectPartInfo.projectPart = t.fallbackProjectPart;
t.currentProjectPartInfo.hints |= ProjectPartInfo::IsFallbackMatch;
const ProjectPart::Ptr addedProject(new ProjectPart);
const ProjectPart::Ptr addedProject = ProjectPart::create({});
t.projectPartsForFile += addedProject;
QCOMPARE(t.choose().projectPart, addedProject);
@@ -293,10 +313,10 @@ void CppToolsPlugin::test_projectPartChooser_stopUsingFallbackFromModelManagerIf
void CppToolsPlugin::test_projectPartChooser_stopUsingFallbackFromModelManagerIfProjectChanges2()
{
ProjectPartChooserTest t;
t.fallbackProjectPart.reset(new ProjectPart);
t.fallbackProjectPart = ProjectPart::create({});
t.currentProjectPartInfo.projectPart = t.fallbackProjectPart;
t.currentProjectPartInfo.hints |= ProjectPartInfo::IsFallbackMatch;
const ProjectPart::Ptr addedProject(new ProjectPart);
const ProjectPart::Ptr addedProject = ProjectPart::create({});
t.projectPartsFromDependenciesForFile += addedProject;
t.projectsChanged = true;
@@ -306,7 +326,7 @@ void CppToolsPlugin::test_projectPartChooser_stopUsingFallbackFromModelManagerIf
void CppToolsPlugin::test_projectPartChooser_indicateFallbacktoProjectPartFromModelManager()
{
ProjectPartChooserTest t;
t.fallbackProjectPart.reset(new ProjectPart);
t.fallbackProjectPart = ProjectPart::create({});
QVERIFY(t.choose().hints & ProjectPartInfo::IsFallbackMatch);
}
@@ -314,7 +334,7 @@ void CppToolsPlugin::test_projectPartChooser_indicateFallbacktoProjectPartFromMo
void CppToolsPlugin::test_projectPartChooser_indicateFromDependencies()
{
ProjectPartChooserTest t;
t.projectPartsFromDependenciesForFile += ProjectPart::Ptr(new ProjectPart);
t.projectPartsFromDependenciesForFile += ProjectPart::create({});
QVERIFY(t.choose().hints & ProjectPartInfo::IsFromDependenciesMatch);
}
@@ -322,7 +342,7 @@ void CppToolsPlugin::test_projectPartChooser_indicateFromDependencies()
void CppToolsPlugin::test_projectPartChooser_doNotIndicateFromDependencies()
{
ProjectPartChooserTest t;
t.projectPartsForFile += ProjectPart::Ptr(new ProjectPart);
t.projectPartsForFile += ProjectPart::create({});
QVERIFY(!(t.choose().hints & ProjectPartInfo::IsFromDependenciesMatch));
}
@@ -351,14 +371,18 @@ private:
class ProjectInfoGeneratorTest
{
public:
ProjectInfo generate()
ProjectInfoGeneratorTest()
{
QFutureInterface<ProjectInfo> fi;
TestToolchain aToolChain;
projectUpdateInfo.cxxToolChainInfo = {&aToolChain, {}, {}};
projectUpdateInfo.cToolChainInfo = {&aToolChain, {}, {}};
}
ProjectInfo::Ptr generate()
{
QFutureInterface<ProjectInfo::Ptr> fi;
projectUpdateInfo.rawProjectParts += rawProjectPart;
projectUpdateInfo.cxxToolChain = &aToolChain;
projectUpdateInfo.cToolChain = &aToolChain;
ProjectInfoGenerator generator(fi, projectUpdateInfo);
return generator.generate();
@@ -372,37 +396,37 @@ public:
void CppToolsPlugin::test_projectInfoGenerator_createNoProjectPartsForEmptyFileList()
{
ProjectInfoGeneratorTest t;
const ProjectInfo projectInfo = t.generate();
const ProjectInfo::Ptr projectInfo = t.generate();
QVERIFY(projectInfo.projectParts().isEmpty());
QVERIFY(projectInfo->projectParts().isEmpty());
}
void CppToolsPlugin::test_projectInfoGenerator_createSingleProjectPart()
{
ProjectInfoGeneratorTest t;
t.rawProjectPart.files = QStringList{ "foo.cpp", "foo.h"};
const ProjectInfo projectInfo = t.generate();
const ProjectInfo::Ptr projectInfo = t.generate();
QCOMPARE(projectInfo.projectParts().size(), 1);
QCOMPARE(projectInfo->projectParts().size(), 1);
}
void CppToolsPlugin::test_projectInfoGenerator_createMultipleProjectParts()
{
ProjectInfoGeneratorTest t;
t.rawProjectPart.files = QStringList{ "foo.cpp", "foo.h", "bar.c", "bar.h" };
const ProjectInfo projectInfo = t.generate();
const ProjectInfo::Ptr projectInfo = t.generate();
QCOMPARE(projectInfo.projectParts().size(), 2);
QCOMPARE(projectInfo->projectParts().size(), 2);
}
void CppToolsPlugin::test_projectInfoGenerator_projectPartIndicatesObjectiveCExtensionsByDefault()
{
ProjectInfoGeneratorTest t;
t.rawProjectPart.files = QStringList{ "foo.mm" };
const ProjectInfo projectInfo = t.generate();
QCOMPARE(projectInfo.projectParts().size(), 1);
const ProjectInfo::Ptr projectInfo = t.generate();
QCOMPARE(projectInfo->projectParts().size(), 1);
const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
const ProjectPart &projectPart = *projectInfo->projectParts().at(0);
QVERIFY(projectPart.languageExtensions & Utils::LanguageExtension::ObjectiveC);
}
@@ -410,10 +434,10 @@ void CppToolsPlugin::test_projectInfoGenerator_projectPartHasLatestLanguageVersi
{
ProjectInfoGeneratorTest t;
t.rawProjectPart.files = QStringList{ "foo.cpp" };
const ProjectInfo projectInfo = t.generate();
QCOMPARE(projectInfo.projectParts().size(), 1);
const ProjectInfo::Ptr projectInfo = t.generate();
QCOMPARE(projectInfo->projectParts().size(), 1);
const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
const ProjectPart &projectPart = *projectInfo->projectParts().at(0);
QCOMPARE(projectPart.languageVersion, Utils::LanguageVersion::LatestCxx);
}
@@ -424,11 +448,11 @@ void CppToolsPlugin::test_projectInfoGenerator_useMacroInspectionReportForLangua
return TestToolchain::MacroInspectionReport{Macros(), Utils::LanguageVersion::CXX17};
};
t.rawProjectPart.files = QStringList{ "foo.cpp" };
const ProjectInfo projectInfo = t.generate();
const ProjectInfo::Ptr projectInfo = t.generate();
QCOMPARE(projectInfo.projectParts().size(), 1);
QCOMPARE(projectInfo->projectParts().size(), 1);
const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
const ProjectPart &projectPart = *projectInfo->projectParts().at(0);
QCOMPARE(projectPart.languageVersion, Utils::LanguageVersion::CXX17);
}
@@ -437,11 +461,11 @@ void CppToolsPlugin::test_projectInfoGenerator_useCompilerFlagsForLanguageExtens
ProjectInfoGeneratorTest t;
t.rawProjectPart.files = QStringList{ "foo.cpp" };
t.rawProjectPart.flagsForCxx.languageExtensions = Utils::LanguageExtension::Microsoft;
const ProjectInfo projectInfo = t.generate();
const ProjectInfo::Ptr projectInfo = t.generate();
QCOMPARE(projectInfo.projectParts().size(), 1);
QCOMPARE(projectInfo->projectParts().size(), 1);
const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
const ProjectPart &projectPart = *projectInfo->projectParts().at(0);
QVERIFY(projectPart.languageExtensions & Utils::LanguageExtension::Microsoft);
}
@@ -449,22 +473,22 @@ void CppToolsPlugin::test_projectInfoGenerator_projectFileKindsMatchProjectPartV
{
ProjectInfoGeneratorTest t;
t.rawProjectPart.files = QStringList{ "foo.h" };
const ProjectInfo projectInfo = t.generate();
const ProjectInfo::Ptr projectInfo = t.generate();
QCOMPARE(projectInfo.projectParts().size(), 4);
QVERIFY(Utils::contains(projectInfo.projectParts(), [](const ProjectPart::Ptr &p) {
QCOMPARE(projectInfo->projectParts().size(), 4);
QVERIFY(Utils::contains(projectInfo->projectParts(), [](const ProjectPart::Ptr &p) {
return p->languageVersion == Utils::LanguageVersion::LatestC
&& p->files.first().kind == ProjectFile::CHeader;
}));
QVERIFY(Utils::contains(projectInfo.projectParts(), [](const ProjectPart::Ptr &p) {
QVERIFY(Utils::contains(projectInfo->projectParts(), [](const ProjectPart::Ptr &p) {
return p->languageVersion == Utils::LanguageVersion::LatestC
&& p->files.first().kind == ProjectFile::ObjCHeader;
}));
QVERIFY(Utils::contains(projectInfo.projectParts(), [](const ProjectPart::Ptr &p) {
QVERIFY(Utils::contains(projectInfo->projectParts(), [](const ProjectPart::Ptr &p) {
return p->languageVersion == Utils::LanguageVersion::LatestCxx
&& p->files.first().kind == ProjectFile::CXXHeader;
}));
QVERIFY(Utils::contains(projectInfo.projectParts(), [](const ProjectPart::Ptr &p) {
QVERIFY(Utils::contains(projectInfo->projectParts(), [](const ProjectPart::Ptr &p) {
return p->languageVersion == Utils::LanguageVersion::LatestCxx
&& p->files.first().kind == ProjectFile::ObjCXXHeader;
}));
@@ -474,20 +498,18 @@ namespace {
class HeaderPathFilterTest
{
public:
HeaderPathFilterTest() : project({}, Utils::FilePath::fromString("test"))
ProjectPart finalize()
{
const auto headerPaths = HeaderPaths{
HeaderPath{"", HeaderPathType::BuiltIn},
HeaderPath{"/builtin_path", HeaderPathType::BuiltIn},
HeaderPath{"/system_path", HeaderPathType::System},
HeaderPath{"/framework_path", HeaderPathType::Framework},
HeaderPath{"/outside_project_user_path", HeaderPathType::User},
HeaderPath{"/build/user_path", HeaderPathType::User},
HeaderPath{"/buildb/user_path", HeaderPathType::User},
HeaderPath{"/projectb/user_path", HeaderPathType::User},
HeaderPath{"/project/user_path", HeaderPathType::User}};
projectPart.headerPaths = headerPaths;
projectPart.project = &project;
RawProjectPart rpp;
rpp.setHeaderPaths(headerPaths);
ToolChainInfo tcInfo;
tcInfo.type = toolchainType;
tcInfo.targetTriple = targetTriple;
tcInfo.installDir = toolchainInstallDir;
projectPart = ProjectPart::create({}, rpp, {}, {}, {}, {}, {}, tcInfo);
filter.emplace(HeaderPathFilter(*projectPart, UseTweakedHeaderPaths::No, {}, {},
"/project", "/build"));
return *projectPart;
}
static HeaderPath builtIn(const QString &path)
@@ -507,26 +529,43 @@ public:
return HeaderPath{path, HeaderPathType::User};
}
Project project;
ProjectPart projectPart;
HeaderPathFilter filter{projectPart, UseTweakedHeaderPaths::No, {}, {}, "/project", "/build"};
QString targetTriple;
Utils::Id toolchainType;
Utils::FilePath toolchainInstallDir;
HeaderPaths headerPaths = {
HeaderPath{"", HeaderPathType::BuiltIn},
HeaderPath{"/builtin_path", HeaderPathType::BuiltIn},
HeaderPath{"/system_path", HeaderPathType::System},
HeaderPath{"/framework_path", HeaderPathType::Framework},
HeaderPath{"/outside_project_user_path", HeaderPathType::User},
HeaderPath{"/build/user_path", HeaderPathType::User},
HeaderPath{"/buildb/user_path", HeaderPathType::User},
HeaderPath{"/projectb/user_path", HeaderPathType::User},
HeaderPath{"/project/user_path", HeaderPathType::User}};
Utils::optional<HeaderPathFilter> filter;
private:
ProjectPart::Ptr projectPart;
};
}
void CppToolsPlugin::test_headerPathFilter_builtin()
{
HeaderPathFilterTest t;
t.filter.process();
t.finalize();
t.filter->process();
QCOMPARE(t.filter.builtInHeaderPaths, (HeaderPaths{t.builtIn("/builtin_path")}));
QCOMPARE(t.filter->builtInHeaderPaths, (HeaderPaths{t.builtIn("/builtin_path")}));
}
void CppToolsPlugin::test_headerPathFilter_system()
{
HeaderPathFilterTest t;
t.filter.process();
t.finalize();
t.filter->process();
QCOMPARE(t.filter.systemHeaderPaths, (HeaderPaths{
QCOMPARE(t.filter->systemHeaderPaths, (HeaderPaths{
t.system("/project/.pre_includes"), t.system("/system_path"),
t.framework("/framework_path"), t.user("/outside_project_user_path"),
t.user("/buildb/user_path"), t.user("/projectb/user_path")}));
@@ -535,16 +574,16 @@ void CppToolsPlugin::test_headerPathFilter_system()
void CppToolsPlugin::test_headerPathFilter_user()
{
HeaderPathFilterTest t;
t.filter.process();
t.filter->process();
QCOMPARE(t.filter.userHeaderPaths, (HeaderPaths{t.user("/build/user_path"),
t.user("/project/user_path")}));
QCOMPARE(t.filter->userHeaderPaths, (HeaderPaths{t.user("/build/user_path"),
t.user("/project/user_path")}));
}
void CppToolsPlugin::test_headerPathFilter_noProjectPathSet()
{
HeaderPathFilterTest t;
HeaderPathFilter filter{t.projectPart, UseTweakedHeaderPaths::No};
HeaderPathFilter filter{t.finalize(), UseTweakedHeaderPaths::No};
filter.process();
QCOMPARE(filter.userHeaderPaths, (HeaderPaths{
@@ -556,20 +595,21 @@ void CppToolsPlugin::test_headerPathFilter_noProjectPathSet()
void CppToolsPlugin::test_headerPathFilter_dontAddInvalidPath()
{
HeaderPathFilterTest t;
t.filter.process();
QCOMPARE(t.filter.builtInHeaderPaths, (HeaderPaths{t.builtIn("/builtin_path")}));
QCOMPARE(t.filter.systemHeaderPaths, HeaderPaths({
t.finalize();
t.filter->process();
QCOMPARE(t.filter->builtInHeaderPaths, (HeaderPaths{t.builtIn("/builtin_path")}));
QCOMPARE(t.filter->systemHeaderPaths, HeaderPaths({
t.system("/project/.pre_includes"), t.system("/system_path"),
t.framework("/framework_path"), t.user("/outside_project_user_path"),
t.user("/buildb/user_path"), t.user("/projectb/user_path")}));
QCOMPARE(t.filter.userHeaderPaths, HeaderPaths({t.user("/build/user_path"),
t.user("/project/user_path")}));
QCOMPARE(t.filter->userHeaderPaths, HeaderPaths({t.user("/build/user_path"),
t.user("/project/user_path")}));
}
void CppToolsPlugin::test_headerPathFilter_clangHeadersPath()
{
HeaderPathFilterTest t;
HeaderPathFilter filter(t.projectPart, UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
HeaderPathFilter filter(t.finalize(), UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
filter.process();
QCOMPARE(filter.builtInHeaderPaths, (HeaderPaths{t.builtIn("clang_dir"),
@@ -579,7 +619,7 @@ void CppToolsPlugin::test_headerPathFilter_clangHeadersPath()
void CppToolsPlugin::test_headerPathFilter_clangHeadersPathWitoutClangVersion()
{
HeaderPathFilterTest t;
HeaderPathFilter filter(t.projectPart, UseTweakedHeaderPaths::Yes);
HeaderPathFilter filter(t.finalize(), UseTweakedHeaderPaths::Yes);
filter.process();
QCOMPARE(filter.builtInHeaderPaths, (HeaderPaths{t.builtIn("/builtin_path")}));
@@ -588,6 +628,7 @@ void CppToolsPlugin::test_headerPathFilter_clangHeadersPathWitoutClangVersion()
void CppToolsPlugin::test_headerPathFilter_clangHeadersAndCppIncludesPathsOrderMacOs()
{
HeaderPathFilterTest t;
t.targetTriple = "x86_64-apple-darwin10";
const auto builtIns = {
t.builtIn("/usr/include/c++/4.2.1"), t.builtIn("/usr/include/c++/4.2.1/backward"),
t.builtIn("/usr/local/include"),
@@ -595,10 +636,9 @@ void CppToolsPlugin::test_headerPathFilter_clangHeadersAndCppIncludesPathsOrderM
t.builtIn("/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include"),
t.builtIn("/usr/include")
};
t.projectPart.toolChainTargetTriple = "x86_64-apple-darwin10";
std::copy(builtIns.begin(), builtIns.end(),
std::inserter(t.projectPart.headerPaths, t.projectPart.headerPaths.begin()));
HeaderPathFilter filter(t.projectPart, UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
std::inserter(t.headerPaths, t.headerPaths.begin()));
HeaderPathFilter filter(t.finalize(), UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
filter.process();
QCOMPARE(filter.builtInHeaderPaths, (HeaderPaths{
@@ -612,15 +652,15 @@ void CppToolsPlugin::test_headerPathFilter_clangHeadersAndCppIncludesPathsOrderM
void CppToolsPlugin::test_headerPathFilter_clangHeadersAndCppIncludesPathsOrderLinux()
{
HeaderPathFilterTest t;
t.targetTriple = "x86_64-linux-gnu";
const auto builtIns = {
t.builtIn("/usr/include/c++/4.8"), t.builtIn("/usr/include/c++/4.8/backward"),
t.builtIn("/usr/include/x86_64-linux-gnu/c++/4.8"),
t.builtIn("/usr/local/include"), t.builtIn("/usr/lib/gcc/x86_64-linux-gnu/4.8/include"),
t.builtIn("/usr/include/x86_64-linux-gnu"), t.builtIn("/usr/include")};
std::copy(builtIns.begin(), builtIns.end(),
std::inserter(t.projectPart.headerPaths, t.projectPart.headerPaths.begin()));
t.projectPart.toolChainTargetTriple = "x86_64-linux-gnu";
HeaderPathFilter filter(t.projectPart, UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
std::inserter(t.headerPaths, t.headerPaths.begin()));
HeaderPathFilter filter(t.finalize(), UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
filter.process();
QCOMPARE(filter.builtInHeaderPaths, (HeaderPaths{
@@ -636,13 +676,13 @@ void CppToolsPlugin::test_headerPathFilter_clangHeadersAndCppIncludesPathsOrderL
void CppToolsPlugin::test_headerPathFilter_removeGccInternalPaths()
{
HeaderPathFilterTest t;
t.projectPart.toolChainInstallDir = Utils::FilePath::fromUtf8("/usr/lib/gcc/x86_64-linux-gnu/7");
t.projectPart.toolchainType = Constants::GCC_TOOLCHAIN_TYPEID;
t.projectPart.headerPaths = {
t.toolchainInstallDir = Utils::FilePath::fromUtf8("/usr/lib/gcc/x86_64-linux-gnu/7");
t.toolchainType = Constants::GCC_TOOLCHAIN_TYPEID;
t.headerPaths = {
t.builtIn("/usr/lib/gcc/x86_64-linux-gnu/7/include"),
t.builtIn("/usr/lib/gcc/x86_64-linux-gnu/7/include-fixed"),
};
HeaderPathFilter filter(t.projectPart, UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
HeaderPathFilter filter(t.finalize(), UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
filter.process();
QCOMPARE(filter.builtInHeaderPaths, (HeaderPaths{t.builtIn("clang_dir")}));
@@ -654,18 +694,17 @@ void CppToolsPlugin::test_headerPathFilter_removeGccInternalPaths()
void CppToolsPlugin::test_headerPathFilter_removeGccInternalPathsExceptForStandardPaths()
{
HeaderPathFilterTest t;
t.projectPart.toolChainInstallDir = Utils::FilePath::fromUtf8(
"c:/mingw/lib/gcc/x86_64-w64-mingw32/7.3.0");
t.projectPart.toolchainType = Constants::MINGW_TOOLCHAIN_TYPEID;
t.projectPart.headerPaths = {
t.toolchainInstallDir = Utils::FilePath::fromUtf8("c:/mingw/lib/gcc/x86_64-w64-mingw32/7.3.0");
t.toolchainType = Constants::MINGW_TOOLCHAIN_TYPEID;
t.headerPaths = {
t.builtIn("c:/mingw/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++"),
t.builtIn("c:/mingw/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/x86_64-w64-mingw32"),
t.builtIn("c:/mingw/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/backward"),
};
HeaderPaths expected = t.projectPart.headerPaths;
HeaderPaths expected = t.headerPaths;
expected.append(t.builtIn("clang_dir"));
HeaderPathFilter filter(t.projectPart, UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
HeaderPathFilter filter(t.finalize(), UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
filter.process();
QCOMPARE(filter.builtInHeaderPaths, expected);
@@ -674,14 +713,14 @@ void CppToolsPlugin::test_headerPathFilter_removeGccInternalPathsExceptForStanda
void CppToolsPlugin::test_headerPathFilter_clangHeadersAndCppIncludesPathsOrderNoVersion()
{
HeaderPathFilterTest t;
t.projectPart.headerPaths = {
t.headerPaths = {
t.builtIn("C:/mingw/i686-w64-mingw32/include"),
t.builtIn("C:/mingw/i686-w64-mingw32/include/c++"),
t.builtIn("C:/mingw/i686-w64-mingw32/include/c++/i686-w64-mingw32"),
t.builtIn("C:/mingw/i686-w64-mingw32/include/c++/backward"),
};
t.projectPart.toolChainTargetTriple = "x86_64-w64-windows-gnu";
HeaderPathFilter filter(t.projectPart, UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
t.targetTriple = "x86_64-w64-windows-gnu";
HeaderPathFilter filter(t.finalize(), UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
filter.process();
QCOMPARE(filter.builtInHeaderPaths, (HeaderPaths{
@@ -695,15 +734,15 @@ void CppToolsPlugin::test_headerPathFilter_clangHeadersAndCppIncludesPathsOrderN
void CppToolsPlugin::test_headerPathFilter_clangHeadersAndCppIncludesPathsOrderAndroidClang()
{
HeaderPathFilterTest t;
t.projectPart.headerPaths = {
t.headerPaths = {
t.builtIn("C:/Android/sdk/ndk-bundle/sysroot/usr/include/i686-linux-android"),
t.builtIn("C:/Android/sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/include"),
t.builtIn("C:/Android/sdk/ndk-bundle/sources/android/support/include"),
t.builtIn("C:/Android/sdk/ndk-bundle/sources/cxx-stl/llvm-libc++abi/include"),
t.builtIn("C:/Android/sdk/ndk-bundle/sysroot/usr/include")
};
t.projectPart.toolChainTargetTriple = "i686-linux-android";
HeaderPathFilter filter(t.projectPart, UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
t.targetTriple = "i686-linux-android";
HeaderPathFilter filter(t.finalize(), UseTweakedHeaderPaths::Yes, "6.0", "clang_dir");
filter.process();
QCOMPARE(filter.builtInHeaderPaths, (HeaderPaths{

View File

@@ -25,6 +25,8 @@
#include "projectpart.h"
#include <projectexplorer/project.h>
#include <utils/algorithm.h>
#include <QFile>
@@ -35,66 +37,6 @@ using namespace ProjectExplorer;
namespace CppTools {
void ProjectPart::updateLanguageFeatures()
{
const bool hasCxx = languageVersion >= Utils::LanguageVersion::CXX98;
const bool hasQt = hasCxx && qtVersion != Utils::QtVersion::None;
languageFeatures.cxx11Enabled = languageVersion >= Utils::LanguageVersion::CXX11;
languageFeatures.cxx14Enabled = languageVersion >= Utils::LanguageVersion::CXX14;
languageFeatures.cxxEnabled = hasCxx;
languageFeatures.c99Enabled = languageVersion >= Utils::LanguageVersion::C99;
languageFeatures.objCEnabled = languageExtensions.testFlag(Utils::LanguageExtension::ObjectiveC);
languageFeatures.qtEnabled = hasQt;
languageFeatures.qtMocRunEnabled = hasQt;
if (!hasQt) {
languageFeatures.qtKeywordsEnabled = false;
} else {
languageFeatures.qtKeywordsEnabled = !Utils::contains(
projectMacros,
[] (const ProjectExplorer::Macro &macro) { return macro.key == "QT_NO_KEYWORDS"; });
}
}
void ProjectPart::setupToolchainProperties(const ToolChainInfo &tcInfo, const QStringList &flags)
{
toolchainType = tcInfo.type;
isMsvc2015Toolchain = tcInfo.isMsvc2015ToolChain;
toolChainWordWidth = tcInfo.wordWidth == 64 ? ProjectPart::WordWidth64Bit
: ProjectPart::WordWidth32Bit;
toolChainInstallDir = tcInfo.installDir;
toolChainTargetTriple = tcInfo.targetTriple;
extraCodeModelFlags = tcInfo.extraCodeModelFlags;
compilerFlags = flags;
// Toolchain macros and language version
if (tcInfo.macroInspectionRunner) {
const auto macroInspectionReport = tcInfo.macroInspectionRunner(compilerFlags);
toolChainMacros = macroInspectionReport.macros;
languageVersion = macroInspectionReport.languageVersion;
// No compiler set in kit.
} else if (language == Utils::Language::C) {
languageVersion = Utils::LanguageVersion::LatestC;
} else {
languageVersion = Utils::LanguageVersion::LatestCxx;
}
// Header paths
if (tcInfo.headerPathsRunner) {
const HeaderPaths builtInHeaderPaths
= tcInfo.headerPathsRunner(compilerFlags, tcInfo.sysRootPath, tcInfo.targetTriple);
for (const HeaderPath &header : builtInHeaderPaths) {
const HeaderPath headerPath{header.path, header.type};
if (!headerPaths.contains(headerPath))
headerPaths.push_back(headerPath);
}
}
}
ProjectPart::Ptr ProjectPart::copy() const
{
return Ptr(new ProjectPart(*this));
}
QString ProjectPart::id() const
{
QString projectPartId = projectFileLocation();
@@ -113,11 +55,16 @@ QString ProjectPart::projectFileLocation() const
return location;
}
QByteArray ProjectPart::readProjectConfigFile(const Ptr &projectPart)
bool ProjectPart::belongsToProject(const ProjectExplorer::Project *project) const
{
return project && topLevelProject == project->projectFilePath();
}
QByteArray ProjectPart::readProjectConfigFile(const QString &projectConfigFile)
{
QByteArray result;
QFile f(projectPart->projectConfigFile);
QFile f(projectConfigFile);
if (f.open(QIODevice::ReadOnly)) {
QTextStream is(&f);
result = is.readAll().toUtf8();
@@ -127,4 +74,116 @@ QByteArray ProjectPart::readProjectConfigFile(const Ptr &projectPart)
return result;
}
// TODO: Why do we keep the file *and* the resulting macros? Why do we read the file
// in several places?
static Macros getProjectMacros(const RawProjectPart &rpp)
{
Macros macros = rpp.projectMacros;
if (!rpp.projectConfigFile.isEmpty())
macros += Macro::toMacros(ProjectPart::readProjectConfigFile(rpp.projectConfigFile));
return macros;
}
static HeaderPaths getHeaderPaths(const RawProjectPart &rpp,
const RawProjectPartFlags &flags,
const ProjectExplorer::ToolChainInfo &tcInfo)
{
HeaderPaths headerPaths;
// Prevent duplicate include paths.
// TODO: Do this once when finalizing the raw project part?
std::set<QString> seenPaths;
for (const HeaderPath &p : qAsConst(rpp.headerPaths)) {
const QString cleanPath = QDir::cleanPath(p.path);
if (seenPaths.insert(cleanPath).second)
headerPaths << HeaderPath(cleanPath, p.type);
}
if (tcInfo.headerPathsRunner) {
const HeaderPaths builtInHeaderPaths = tcInfo.headerPathsRunner(
flags.commandLineFlags, tcInfo.sysRootPath, tcInfo.targetTriple);
for (const HeaderPath &header : builtInHeaderPaths) {
if (seenPaths.insert(header.path).second)
headerPaths.push_back(HeaderPath{header.path, header.type});
}
}
return headerPaths;
}
static ToolChain::MacroInspectionReport getToolchainMacros(
const RawProjectPartFlags &flags, const ToolChainInfo &tcInfo, Utils::Language language)
{
ToolChain::MacroInspectionReport report;
if (tcInfo.macroInspectionRunner) {
report = tcInfo.macroInspectionRunner(flags.commandLineFlags);
} else if (language == Utils::Language::C) { // No compiler set in kit.
report.languageVersion = Utils::LanguageVersion::LatestC;
} else {
report.languageVersion = Utils::LanguageVersion::LatestCxx;
}
return report;
}
ProjectPart::ProjectPart(const Utils::FilePath &topLevelProject,
const RawProjectPart &rpp,
const QString &displayName,
const ProjectFiles &files,
Utils::Language language,
Utils::LanguageExtensions languageExtensions,
const RawProjectPartFlags &flags,
const ToolChainInfo &tcInfo)
: topLevelProject(topLevelProject),
displayName(displayName),
projectFile(rpp.projectFile),
projectConfigFile(rpp.projectConfigFile),
projectFileLine(rpp.projectFileLine),
projectFileColumn(rpp.projectFileColumn),
callGroupId(rpp.callGroupId),
language(language),
languageExtensions(languageExtensions | flags.languageExtensions),
qtVersion(rpp.qtVersion),
files(files),
includedFiles(rpp.includedFiles),
precompiledHeaders(rpp.precompiledHeaders),
headerPaths(getHeaderPaths(rpp, flags, tcInfo)),
projectMacros(getProjectMacros(rpp)),
buildSystemTarget(rpp.buildSystemTarget),
buildTargetType(rpp.buildTargetType),
selectedForBuilding(rpp.selectedForBuilding),
toolchainType(tcInfo.type),
isMsvc2015Toolchain(tcInfo.isMsvc2015ToolChain),
toolChainTargetTriple(tcInfo.targetTriple),
toolChainWordWidth(tcInfo.wordWidth == 64 ? ProjectPart::WordWidth64Bit
: ProjectPart::WordWidth32Bit),
toolChainInstallDir(tcInfo.installDir),
compilerFilePath(tcInfo.compilerFilePath),
warningFlags(flags.warningFlags),
extraCodeModelFlags(tcInfo.extraCodeModelFlags),
compilerFlags(flags.commandLineFlags),
m_macroReport(getToolchainMacros(flags, tcInfo, language)),
languageFeatures(deriveLanguageFeatures())
{
}
CPlusPlus::LanguageFeatures ProjectPart::deriveLanguageFeatures() const
{
const bool hasCxx = languageVersion >= Utils::LanguageVersion::CXX98;
const bool hasQt = hasCxx && qtVersion != Utils::QtVersion::None;
CPlusPlus::LanguageFeatures features;
features.cxx11Enabled = languageVersion >= Utils::LanguageVersion::CXX11;
features.cxx14Enabled = languageVersion >= Utils::LanguageVersion::CXX14;
features.cxxEnabled = hasCxx;
features.c99Enabled = languageVersion >= Utils::LanguageVersion::C99;
features.objCEnabled = languageExtensions.testFlag(Utils::LanguageExtension::ObjectiveC);
features.qtEnabled = hasQt;
features.qtMocRunEnabled = hasQt;
if (!hasQt) {
features.qtKeywordsEnabled = false;
} else {
features.qtKeywordsEnabled = !Utils::contains(projectMacros,
[] (const ProjectExplorer::Macro &macro) { return macro.key == "QT_NO_KEYWORDS"; });
}
return features;
}
} // namespace CppTools

View File

@@ -43,9 +43,7 @@
#include <QString>
#include <QSharedPointer>
namespace ProjectExplorer {
class Project;
}
namespace ProjectExplorer { class Project; }
namespace CppTools {
@@ -60,60 +58,88 @@ public:
using Ptr = QSharedPointer<ProjectPart>;
public:
static Ptr create(const Utils::FilePath &topLevelProject,
const ProjectExplorer::RawProjectPart &rpp = {},
const QString &displayName = {},
const ProjectFiles &files = {},
Utils::Language language = Utils::Language::Cxx,
Utils::LanguageExtensions languageExtensions = {},
const ProjectExplorer::RawProjectPartFlags &flags = {},
const ProjectExplorer::ToolChainInfo &tcInfo = {})
{
return Ptr(new ProjectPart(topLevelProject, rpp, displayName, files, language,
languageExtensions, flags, tcInfo));
}
QString id() const;
QString projectFileLocation() const;
bool hasProject() const { return !topLevelProject.isEmpty(); }
bool belongsToProject(const ProjectExplorer::Project *project) const;
Ptr copy() const;
void updateLanguageFeatures();
void setupToolchainProperties(const ProjectExplorer::ToolChainInfo &tcInfo,
const QStringList &flags);
static QByteArray readProjectConfigFile(const Ptr &projectPart);
static QByteArray readProjectConfigFile(const QString &projectConfigFile);
public:
ProjectExplorer::Project *project = nullptr;
const Utils::FilePath topLevelProject;
const QString displayName;
const QString projectFile;
const QString projectConfigFile; // Generic Project Manager only
QString displayName;
QString projectFile;
int projectFileLine = -1;
int projectFileColumn = -1;
QString callGroupId;
const int projectFileLine = -1;
const int projectFileColumn = -1;
const QString callGroupId;
// Versions, features and extensions
::Utils::Language language = ::Utils::Language::Cxx;
::Utils::LanguageVersion languageVersion = ::Utils::LanguageVersion::LatestCxx;
::Utils::LanguageExtensions languageExtensions = ::Utils::LanguageExtension::None;
CPlusPlus::LanguageFeatures languageFeatures;
::Utils::QtVersion qtVersion = ::Utils::QtVersion::Unknown;
const Utils::Language language = Utils::Language::Cxx;
const Utils::LanguageVersion &languageVersion = m_macroReport.languageVersion;
const Utils::LanguageExtensions languageExtensions = Utils::LanguageExtension::None;
const Utils::QtVersion qtVersion = Utils::QtVersion::Unknown;
// Files
ProjectFiles files;
QStringList includedFiles;
QStringList precompiledHeaders;
ProjectExplorer::HeaderPaths headerPaths;
QString projectConfigFile; // Generic Project Manager only
const ProjectFiles files;
const QStringList includedFiles;
const QStringList precompiledHeaders;
const ProjectExplorer::HeaderPaths headerPaths;
// Macros
ProjectExplorer::Macros projectMacros;
ProjectExplorer::Macros toolChainMacros;
const ProjectExplorer::Macros projectMacros;
const ProjectExplorer::Macros &toolChainMacros = m_macroReport.macros;
// Build system
QString buildSystemTarget;
ProjectExplorer::BuildTargetType buildTargetType = ProjectExplorer::BuildTargetType::Unknown;
bool selectedForBuilding = true;
const QString buildSystemTarget;
const ProjectExplorer::BuildTargetType buildTargetType
= ProjectExplorer::BuildTargetType::Unknown;
const bool selectedForBuilding = true;
// ToolChain
Utils::Id toolchainType;
bool isMsvc2015Toolchain = false;
QString toolChainTargetTriple;
ToolChainWordWidth toolChainWordWidth = WordWidth32Bit;
::Utils::FilePath toolChainInstallDir;
::Utils::WarningFlags warningFlags = ::Utils::WarningFlags::Default;
const Utils::Id toolchainType;
const bool isMsvc2015Toolchain = false;
const QString toolChainTargetTriple;
const ToolChainWordWidth toolChainWordWidth = WordWidth32Bit;
const Utils::FilePath toolChainInstallDir;
const Utils::FilePath compilerFilePath;
const Utils::WarningFlags warningFlags = Utils::WarningFlags::Default;
// Misc
QStringList extraCodeModelFlags;
QStringList compilerFlags;
const QStringList extraCodeModelFlags;
const QStringList compilerFlags;
private:
ProjectPart(const Utils::FilePath &topLevelProject,
const ProjectExplorer::RawProjectPart &rpp,
const QString &displayName,
const ProjectFiles &files,
Utils::Language language,
Utils::LanguageExtensions languageExtensions,
const ProjectExplorer::RawProjectPartFlags &flags,
const ProjectExplorer::ToolChainInfo &tcInfo);
CPlusPlus::LanguageFeatures deriveLanguageFeatures() const;
const ProjectExplorer::ToolChain::MacroInspectionReport m_macroReport;
public:
// Must come last due to initialization order.
const CPlusPlus::LanguageFeatures languageFeatures;
};
} // namespace CppTools

View File

@@ -2333,8 +2333,7 @@ void DebuggerUnitTests::testStateMachine()
QString proFile = m_tmpDir->absolutePath("simple/simple.pro");
CppTools::Tests::ProjectOpenerAndCloser projectManager;
const CppTools::ProjectInfo projectInfo = projectManager.open(proFile, true);
QVERIFY(projectInfo.isValid());
QVERIFY(projectManager.open(proFile, true));
QEventLoop loop;
connect(BuildManager::instance(), &BuildManager::buildQueueFinished,

View File

@@ -26,6 +26,7 @@
#include "rawprojectpart.h"
#include "abi.h"
#include "buildconfiguration.h"
#include "kitinformation.h"
#include "project.h"
#include "projectexplorerconstants.h"
@@ -187,6 +188,7 @@ ToolChainInfo::ToolChainInfo(const ToolChain *toolChain,
targetTriple = toolChain->originalTargetTriple();
extraCodeModelFlags = toolChain->extraCodeModelFlags();
installDir = toolChain->installDir();
compilerFilePath = toolChain->compilerCommand();
// ...and save the potentially expensive operations for later so that
// they can be run from a worker thread.
@@ -201,18 +203,17 @@ ProjectUpdateInfo::ProjectUpdateInfo(Project *project,
const Utils::Environment &env,
const RawProjectParts &rawProjectParts,
const RppGenerator &rppGenerator)
: project(project)
, rawProjectParts(rawProjectParts)
: rawProjectParts(rawProjectParts)
, rppGenerator(rppGenerator)
, cToolChain(kitInfo.cToolChain)
, cxxToolChain(kitInfo.cxxToolChain)
, cToolChainInfo(ToolChainInfo(cToolChain, kitInfo.sysRootPath, env))
, cxxToolChainInfo(ToolChainInfo(cxxToolChain, kitInfo.sysRootPath, env))
{}
bool ProjectUpdateInfo::isValid() const
, cToolChainInfo(ToolChainInfo(kitInfo.cToolChain, kitInfo.sysRootPath, env))
, cxxToolChainInfo(ToolChainInfo(kitInfo.cxxToolChain, kitInfo.sysRootPath, env))
{
return project && !rawProjectParts.isEmpty();
if (project) {
projectName = project->displayName();
projectFilePath = project->projectFilePath();
if (project->activeTarget() && project->activeTarget()->activeBuildConfiguration())
buildRoot = project->activeTarget()->activeBuildConfiguration()->buildDirectory();
}
}
} // namespace ProjectExplorer

View File

@@ -156,6 +156,7 @@ public:
bool isMsvc2015ToolChain = false;
unsigned wordWidth = 0;
QString targetTriple;
Utils::FilePath compilerFilePath;
Utils::FilePath installDir;
QStringList extraCodeModelFlags;
@@ -175,16 +176,14 @@ public:
const Utils::Environment &env,
const RawProjectParts &rawProjectParts,
const RppGenerator &rppGenerator = {});
bool isValid() const;
public:
QPointer<Project> project;
QString projectName;
Utils::FilePath projectFilePath;
Utils::FilePath buildRoot;
RawProjectParts rawProjectParts;
RppGenerator rppGenerator;
const ToolChain *cToolChain = nullptr;
const ToolChain *cxxToolChain = nullptr;
ToolChainInfo cToolChainInfo;
ToolChainInfo cxxToolChainInfo;
};

View File

@@ -703,6 +703,12 @@ Project *SessionManager::projectForFile(const Utils::FilePath &fileName)
[&fileName](const Project *p) { return p->isKnownFile(fileName); });
}
Project *SessionManager::projectWithProjectFilePath(const Utils::FilePath &filePath)
{
return Utils::findOrDefault(SessionManager::projects(),
[&filePath](const Project *p) { return p->projectFilePath() == filePath; });
}
void SessionManager::configureEditor(IEditor *editor, const QString &fileName)
{
if (auto textEditor = qobject_cast<TextEditor::BaseTextEditor*>(editor)) {

View File

@@ -118,6 +118,7 @@ public:
static QList<Project *> projectOrder(const Project *project = nullptr);
static Project *projectForFile(const Utils::FilePath &fileName);
static Project *projectWithProjectFilePath(const Utils::FilePath &filePath);
static QStringList projectsForSessionName(const QString &session);

View File

@@ -58,9 +58,8 @@ void CppTodoItemsScanner::scannerParamsChanged()
CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
QSet<QString> filesToBeUpdated;
foreach (const CppTools::ProjectInfo &info, modelManager->projectInfos())
filesToBeUpdated.unite(Utils::transform<QSet>(info.project().data()->files(ProjectExplorer::Project::SourceFiles),
&Utils::FilePath::toString));
foreach (const CppTools::ProjectInfo::Ptr &info, modelManager->projectInfos())
filesToBeUpdated.unite(info->sourceFiles());
modelManager->updateSourceFiles(filesToBeUpdated);
}

View File

@@ -1,4 +1,4 @@
add_qtc_test(tst_cplusplus_checksymbols
DEPENDS CppTools TextEditor
DEPENDS CppTools ProjectExplorer TextEditor
SOURCES tst_checksymbols.cpp
)

View File

@@ -1,3 +1,4 @@
include(../shared/shared.pri)
QTC_PLUGIN_DEPENDS += projectexplorer
SOURCES += tst_checksymbols.cpp
HEADERS += ../cplusplus_global.h

View File

@@ -2,6 +2,7 @@ import qbs
QtcAutotest {
Depends { name: "CppTools" }
Depends { name: "ProjectExplorer" }
Depends { name: "TextEditor" }
Depends { name: "Utils" }
Depends { name: "Qt.widgets" } // For QTextDocument & friends