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

View File

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

View File

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

View File

@@ -389,7 +389,9 @@ QSet<QString> internalTargets(const Utils::FilePath &proFile)
QSet<QString> result; QSet<QString> result;
const auto cppMM = CppTools::CppModelManager::instance(); const auto cppMM = CppTools::CppModelManager::instance();
const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject()); 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) if (projectPart->buildTargetType != ProjectExplorer::BuildTargetType::Executable)
continue; continue;
if (projectPart->projectFile == proFile.toString()) 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) FilePaths &headers, FilePaths &sources, FilePaths &assemblers)
{ {
const auto project = runTool->runControl()->project(); const auto project = runTool->runControl()->project();
const CppTools::ProjectInfo info = CppModelManager::instance()->projectInfo(project); const CppTools::ProjectInfo::Ptr info = CppModelManager::instance()->projectInfo(project);
const QVector<ProjectPart::Ptr> parts = info.projectParts(); if (!info)
return;
const QVector<ProjectPart::Ptr> parts = info->projectParts();
for (const ProjectPart::Ptr &part : parts) { for (const ProjectPart::Ptr &part : parts) {
for (const ProjectFile &file : qAsConst(part->files)) { for (const ProjectFile &file : qAsConst(part->files)) {
if (!file.active) if (!file.active)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -42,24 +42,23 @@ using namespace ProjectExplorer;
namespace CppTools { namespace CppTools {
namespace Internal { namespace Internal {
ProjectInfoGenerator::ProjectInfoGenerator(const QFutureInterface<ProjectInfo> &futureInterface, ProjectInfoGenerator::ProjectInfoGenerator(const QFutureInterface<ProjectInfo::Ptr> &futureInterface,
const ProjectUpdateInfo &projectUpdateInfo) const ProjectUpdateInfo &projectUpdateInfo)
: m_futureInterface(futureInterface) : m_futureInterface(futureInterface)
, m_projectUpdateInfo(projectUpdateInfo) , 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) { for (const RawProjectPart &rpp : m_projectUpdateInfo.rawProjectParts) {
if (m_futureInterface.isCanceled()) if (m_futureInterface.isCanceled())
return ProjectInfo(); return {};
for (const ProjectPart::Ptr &part : createProjectParts(rpp, m_projectUpdateInfo.projectFilePath))
for (const ProjectPart::Ptr &part : createProjectParts(rpp)) projectParts << part;
projectInfo.appendProjectPart(part);
} }
const auto projectInfo = ProjectInfo::create(m_projectUpdateInfo, projectParts);
static const auto showWarning = [](const QString &message) { static const auto showWarning = [](const QString &message) {
QTimer::singleShot(0, TaskHub::instance(), [message] { QTimer::singleShot(0, TaskHub::instance(), [message] {
@@ -79,40 +78,8 @@ ProjectInfo ProjectInfoGenerator::generate()
return projectInfo; 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 QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(
const RawProjectPart &rawProjectPart) const RawProjectPart &rawProjectPart, const Utils::FilePath &projectFilePath)
{ {
using Utils::LanguageExtension; using Utils::LanguageExtension;
@@ -124,21 +91,18 @@ const QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(
if (!cat.hasParts()) if (!cat.hasParts())
return result; return result;
const ProjectPart::Ptr part = projectPartFromRawProjectPart(rawProjectPart, if (m_projectUpdateInfo.cxxToolChainInfo.isValid()) {
m_projectUpdateInfo.project);
if (m_projectUpdateInfo.cxxToolChain) {
if (cat.hasCxxSources()) { if (cat.hasCxxSources()) {
result << createProjectPart(rawProjectPart, result << createProjectPart(projectFilePath,
part, rawProjectPart,
cat.cxxSources(), cat.cxxSources(),
cat.partName("C++"), cat.partName("C++"),
Language::Cxx, Language::Cxx,
LanguageExtension::None); LanguageExtension::None);
} }
if (cat.hasObjcxxSources()) { if (cat.hasObjcxxSources()) {
result << createProjectPart(rawProjectPart, result << createProjectPart(projectFilePath,
part, rawProjectPart,
cat.objcxxSources(), cat.objcxxSources(),
cat.partName("Obj-C++"), cat.partName("Obj-C++"),
Language::Cxx, Language::Cxx,
@@ -148,10 +112,10 @@ const QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(
m_cxxToolchainMissing = true; m_cxxToolchainMissing = true;
} }
if (m_projectUpdateInfo.cToolChain) { if (m_projectUpdateInfo.cToolChainInfo.isValid()) {
if (cat.hasCSources()) { if (cat.hasCSources()) {
result << createProjectPart(rawProjectPart, result << createProjectPart(projectFilePath,
part, rawProjectPart,
cat.cSources(), cat.cSources(),
cat.partName("C"), cat.partName("C"),
Language::C, Language::C,
@@ -159,8 +123,8 @@ const QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(
} }
if (cat.hasObjcSources()) { if (cat.hasObjcSources()) {
result << createProjectPart(rawProjectPart, result << createProjectPart(projectFilePath,
part, rawProjectPart,
cat.objcSources(), cat.objcSources(),
cat.partName("Obj-C"), cat.partName("Obj-C"),
Language::C, Language::C,
@@ -174,12 +138,12 @@ const QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(
} }
ProjectPart::Ptr ProjectInfoGenerator::createProjectPart( ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
const RawProjectPart &rawProjectPart, const Utils::FilePath &projectFilePath,
const ProjectPart::Ptr &templateProjectPart, const RawProjectPart &rawProjectPart,
const ProjectFiles &projectFiles, const ProjectFiles &projectFiles,
const QString &partName, const QString &partName,
Language language, Language language,
Utils::LanguageExtensions languageExtensions) Utils::LanguageExtensions languageExtensions)
{ {
RawProjectPartFlags flags; RawProjectPartFlags flags;
ToolChainInfo tcInfo; ToolChainInfo tcInfo;
@@ -193,16 +157,8 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
tcInfo = m_projectUpdateInfo.cxxToolChainInfo; tcInfo = m_projectUpdateInfo.cxxToolChainInfo;
} }
ProjectPart::Ptr part(templateProjectPart->copy()); return ProjectPart::create(projectFilePath, rawProjectPart, partName, projectFiles,
part->displayName = partName; language, languageExtensions, flags, tcInfo);
part->files = projectFiles;
part->warningFlags = flags.warningFlags;
part->language = language;
part->languageExtensions = flags.languageExtensions | languageExtensions;
part->setupToolchainProperties(tcInfo, flags.commandLineFlags);
part->updateLanguageFeatures();
return part;
} }
} // namespace Internal } // namespace Internal

View File

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

View File

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

View File

@@ -74,13 +74,10 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo,
}); });
m_projectUpdateInfo = projectUpdateInfo; m_projectUpdateInfo = projectUpdateInfo;
// Ensure that we do not operate on a deleted toolchain.
using namespace ProjectExplorer; 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. // 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; ProjectUpdateInfo fullProjectUpdateInfo = projectUpdateInfo;
if (fullProjectUpdateInfo.rppGenerator) if (fullProjectUpdateInfo.rppGenerator)
fullProjectUpdateInfo.rawProjectParts = fullProjectUpdateInfo.rppGenerator(); fullProjectUpdateInfo.rawProjectParts = fullProjectUpdateInfo.rppGenerator();
@@ -134,20 +131,8 @@ void CppProjectUpdater::cancel()
m_futureSynchronizer.cancelAllFutures(); 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() 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) if (m_generateFutureWatcher.isCanceled() || m_generateFutureWatcher.future().resultCount() < 1)
return; return;

View File

@@ -63,7 +63,6 @@ public:
void cancel() override; void cancel() override;
private: private:
void onToolChainRemoved(ProjectExplorer::ToolChain *);
void onProjectInfoGenerated(); void onProjectInfoGenerated();
void checkForExtraCompilersFinished(); void checkForExtraCompilersFinished();
@@ -71,7 +70,7 @@ private:
ProjectExplorer::ProjectUpdateInfo m_projectUpdateInfo; ProjectExplorer::ProjectUpdateInfo m_projectUpdateInfo;
QList<QPointer<ProjectExplorer::ExtraCompiler>> m_extraCompilers; QList<QPointer<ProjectExplorer::ExtraCompiler>> m_extraCompilers;
QFutureWatcher<ProjectInfo> m_generateFutureWatcher; QFutureWatcher<ProjectInfo::Ptr> m_generateFutureWatcher;
bool m_isProjectInfoGenerated = false; bool m_isProjectInfoGenerated = false;
QSet<QFutureWatcher<void> *> m_extraCompilersFutureWatchers; QSet<QFutureWatcher<void> *> m_extraCompilersFutureWatchers;
std::unique_ptr<QFutureInterface<void>> m_projectUpdateFutureInterface; 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 // Find files in other projects
} else { } else {
CppModelManager *modelManager = CppModelManager::instance(); CppModelManager *modelManager = CppModelManager::instance();
QList<ProjectInfo> projectInfos = modelManager->projectInfos(); QList<ProjectInfo::Ptr> projectInfos = modelManager->projectInfos();
foreach (const ProjectInfo &projectInfo, projectInfos) { foreach (const ProjectInfo::Ptr &projectInfo, projectInfos) {
const ProjectExplorer::Project *project = projectInfo.project().data(); const ProjectExplorer::Project *project = projectForProjectInfo(*projectInfo);
if (project == currentProject) if (project == currentProject)
continue; // We have already checked the current project. continue; // We have already checked the current project.

View File

@@ -29,11 +29,13 @@
#include "cpprefactoringchanges.h" #include "cpprefactoringchanges.h"
#include "cpptoolsconstants.h" #include "cpptoolsconstants.h"
#include "cpptoolsplugin.h" #include "cpptoolsplugin.h"
#include "projectinfo.h"
#include <coreplugin/documentmanager.h> #include <coreplugin/documentmanager.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/idocument.h> #include <coreplugin/idocument.h>
#include <coreplugin/messagemanager.h> #include <coreplugin/messagemanager.h>
#include <projectexplorer/session.h>
#include <cplusplus/Overview.h> #include <cplusplus/Overview.h>
#include <cplusplus/LookupContext.h> #include <cplusplus/LookupContext.h>
@@ -572,4 +574,14 @@ NamespaceAST *NSCheckerVisitor::currentNamespace()
return m_enteredNamespaces.empty() ? nullptr : m_enteredNamespaces.back(); 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 } // CppTools

View File

@@ -49,6 +49,7 @@ class LookupContext;
namespace CppTools { namespace CppTools {
class CppRefactoringFile; class CppRefactoringFile;
class ProjectInfo;
void CPPTOOLS_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc); void CPPTOOLS_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc);
void CPPTOOLS_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc); void CPPTOOLS_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc);
@@ -83,6 +84,9 @@ UsePrecompiledHeaders CPPTOOLS_EXPORT getPchUsage();
int indexerFileSizeLimitInMb(); int indexerFileSizeLimitInMb();
bool fileSizeExceedsLimit(const QFileInfo &fileInfo, int sizeLimitInMb); 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; class ClangDiagnosticConfigsModel;
ClangDiagnosticConfigsModel CPPTOOLS_EXPORT diagnosticConfigsModel(); ClangDiagnosticConfigsModel CPPTOOLS_EXPORT diagnosticConfigsModel();
ClangDiagnosticConfigsModel CPPTOOLS_EXPORT ClangDiagnosticConfigsModel CPPTOOLS_EXPORT

View File

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

View File

@@ -27,6 +27,8 @@
#include "cpptools_global.h" #include "cpptools_global.h"
#include "projectinfo.h"
#include <cplusplus/CppDocument.h> #include <cplusplus/CppDocument.h>
#include <utils/temporarydirectory.h> #include <utils/temporarydirectory.h>
@@ -52,7 +54,6 @@ class IAssistProposal;
namespace CppTools { namespace CppTools {
class CppModelManager; class CppModelManager;
class ProjectInfo;
namespace Tests { namespace Tests {
@@ -140,7 +141,7 @@ public:
ProjectOpenerAndCloser(); ProjectOpenerAndCloser();
~ProjectOpenerAndCloser(); // Closes opened projects ~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); ProjectExplorer::Kit *kit = nullptr);
private: private:

View File

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

View File

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

View File

@@ -33,19 +33,10 @@
namespace CppTools { namespace CppTools {
ProjectInfo::ProjectInfo(QPointer<ProjectExplorer::Project> project) ProjectInfo::Ptr ProjectInfo::create(const ProjectExplorer::ProjectUpdateInfo &updateInfo,
: m_project(project) const QVector<ProjectPart::Ptr> &projectParts)
{ {
} return Ptr(new ProjectInfo(updateInfo, projectParts));
bool ProjectInfo::isValid() const
{
return !m_project.isNull();
}
QPointer<ProjectExplorer::Project> ProjectInfo::project() const
{
return m_project;
} }
const QVector<ProjectPart::Ptr> ProjectInfo::projectParts() const const QVector<ProjectPart::Ptr> ProjectInfo::projectParts() const
@@ -60,7 +51,9 @@ const QSet<QString> ProjectInfo::sourceFiles() const
bool ProjectInfo::operator ==(const ProjectInfo &other) 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_projectParts == other.m_projectParts
&& m_headerPaths == other.m_headerPaths && m_headerPaths == other.m_headerPaths
&& m_sourceFiles == other.m_sourceFiles && m_sourceFiles == other.m_sourceFiles
@@ -87,35 +80,46 @@ bool ProjectInfo::configurationOrFilesChanged(const ProjectInfo &other) const
return configurationChanged(other) || m_sourceFiles != other.m_sourceFiles; 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) QSet<QString> sourceFiles;
m_projectParts.append(projectPart); 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; QSet<ProjectExplorer::HeaderPath> uniqueHeaderPaths;
for (const ProjectPart::Ptr &part : projectParts) {
foreach (const ProjectPart::Ptr &part, m_projectParts) { for (const ProjectExplorer::HeaderPath &headerPath : qAsConst(part->headerPaths))
// Update header paths
foreach (const ProjectExplorer::HeaderPath &headerPath, part->headerPaths) {
const int count = uniqueHeaderPaths.count();
uniqueHeaderPaths.insert(headerPath); 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 } // namespace CppTools

View File

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

View File

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

View File

@@ -25,6 +25,8 @@
#include "projectpart.h" #include "projectpart.h"
#include <projectexplorer/project.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <QFile> #include <QFile>
@@ -35,66 +37,6 @@ using namespace ProjectExplorer;
namespace CppTools { 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 ProjectPart::id() const
{ {
QString projectPartId = projectFileLocation(); QString projectPartId = projectFileLocation();
@@ -113,11 +55,16 @@ QString ProjectPart::projectFileLocation() const
return location; 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; QByteArray result;
QFile f(projectPart->projectConfigFile); QFile f(projectConfigFile);
if (f.open(QIODevice::ReadOnly)) { if (f.open(QIODevice::ReadOnly)) {
QTextStream is(&f); QTextStream is(&f);
result = is.readAll().toUtf8(); result = is.readAll().toUtf8();
@@ -127,4 +74,116 @@ QByteArray ProjectPart::readProjectConfigFile(const Ptr &projectPart)
return result; 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 } // namespace CppTools

View File

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

View File

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

View File

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

View File

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

View File

@@ -703,6 +703,12 @@ Project *SessionManager::projectForFile(const Utils::FilePath &fileName)
[&fileName](const Project *p) { return p->isKnownFile(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) void SessionManager::configureEditor(IEditor *editor, const QString &fileName)
{ {
if (auto textEditor = qobject_cast<TextEditor::BaseTextEditor*>(editor)) { if (auto textEditor = qobject_cast<TextEditor::BaseTextEditor*>(editor)) {

View File

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

View File

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

View File

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

View File

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

View File

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