diff --git a/src/plugins/clangcodemodel/clangeditordocumentparser.cpp b/src/plugins/clangcodemodel/clangeditordocumentparser.cpp index 129c0669a61..332eb5a5eab 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentparser.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentparser.cpp @@ -36,10 +36,11 @@ ClangEditorDocumentParser::ClangEditorDocumentParser(const QString &filePath) } void ClangEditorDocumentParser::updateHelper(const QFutureInterface &, - const CppTools::WorkingCopy &) + const CppTools::WorkingCopy &, + const ProjectExplorer::Project *activeProject) { State state_ = state(); - state_.projectPart = determineProjectPart(filePath(), configuration(), state_); + state_.projectPart = determineProjectPart(filePath(), configuration(), state_, activeProject); setState(state_); } diff --git a/src/plugins/clangcodemodel/clangeditordocumentparser.h b/src/plugins/clangcodemodel/clangeditordocumentparser.h index 848e31f1259..fdc01694191 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentparser.h +++ b/src/plugins/clangcodemodel/clangeditordocumentparser.h @@ -38,7 +38,8 @@ public: private: void updateHelper(const QFutureInterface &future, - const CppTools::WorkingCopy &) override; + const CppTools::WorkingCopy &, + const ProjectExplorer::Project *activeProject) override; }; } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 6192232be0d..3afd5c7c6a2 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -46,6 +46,8 @@ #include #include +#include + #include #include #include @@ -115,7 +117,12 @@ void ClangEditorDocumentProcessor::run() connect(&m_parserWatcher, &QFutureWatcher::finished, this, &ClangEditorDocumentProcessor::onParserFinished); const CppTools::WorkingCopy workingCopy = CppTools::CppModelManager::instance()->workingCopy(); - const QFuture future = ::Utils::runAsync(&runParser, parser(), workingCopy); + const ProjectExplorer::Project *activeProject + = ProjectExplorer::SessionManager::startupProject(); + const QFuture future = ::Utils::runAsync(&runParser, + parser(), + workingCopy, + activeProject); m_parserWatcher.setFuture(future); // Run builtin processor diff --git a/src/plugins/cpptools/baseeditordocumentparser.cpp b/src/plugins/cpptools/baseeditordocumentparser.cpp index ce44c312ff0..579d3096242 100644 --- a/src/plugins/cpptools/baseeditordocumentparser.cpp +++ b/src/plugins/cpptools/baseeditordocumentparser.cpp @@ -77,17 +77,19 @@ void BaseEditorDocumentParser::setConfiguration(const Configuration &configurati m_configuration = configuration; } -void BaseEditorDocumentParser::update(const WorkingCopy &workingCopy) +void BaseEditorDocumentParser::update(const WorkingCopy &workingCopy, + const ProjectExplorer::Project *activeProject) { QFutureInterface dummy; - update(dummy, workingCopy); + update(dummy, workingCopy, activeProject); } void BaseEditorDocumentParser::update(const QFutureInterface &future, - const WorkingCopy &workingCopy) + const WorkingCopy &workingCopy, + const ProjectExplorer::Project *activeProject) { QMutexLocker locker(&m_updateIsRunning); - updateHelper(future, workingCopy); + updateHelper(future, workingCopy, activeProject); } BaseEditorDocumentParser::State BaseEditorDocumentParser::state() const @@ -117,9 +119,11 @@ BaseEditorDocumentParser::Ptr BaseEditorDocumentParser::get(const QString &fileP return BaseEditorDocumentParser::Ptr(); } -ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart(const QString &filePath, - const Configuration &config, - const State &state) +ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart( + const QString &filePath, + const Configuration &config, + const State &state, + const ProjectExplorer::Project *activeProject) { Internal::ProjectPartChooser chooser; chooser.setFallbackProjectPart([](){ @@ -136,7 +140,8 @@ ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart(const QString &f return chooser.choose(filePath, state.projectPart, config.manuallySetProjectPart, - config.stickToPreviousProjectPart); + config.stickToPreviousProjectPart, + activeProject); } } // namespace CppTools diff --git a/src/plugins/cpptools/baseeditordocumentparser.h b/src/plugins/cpptools/baseeditordocumentparser.h index 328fe421fdb..9f107d52129 100644 --- a/src/plugins/cpptools/baseeditordocumentparser.h +++ b/src/plugins/cpptools/baseeditordocumentparser.h @@ -33,6 +33,8 @@ #include #include +namespace ProjectExplorer { class Project; } + namespace CppTools { class CPPTOOLS_EXPORT BaseEditorDocumentParser : public QObject @@ -58,8 +60,11 @@ public: Configuration configuration() const; void setConfiguration(const Configuration &configuration); - void update(const WorkingCopy &workingCopy); - void update(const QFutureInterface &future, const WorkingCopy &workingCopy); + void update(const WorkingCopy &workingCopy, + const ProjectExplorer::Project *activeProject); + void update(const QFutureInterface &future, + const WorkingCopy &workingCopy, + const ProjectExplorer::Project *activeProject); ProjectPart::Ptr projectPart() const; @@ -73,13 +78,15 @@ protected: static ProjectPart::Ptr determineProjectPart(const QString &filePath, const Configuration &config, - const State &state); + const State &state, + const ProjectExplorer::Project *activeProject); mutable QMutex m_stateAndConfigurationMutex; private: virtual void updateHelper(const QFutureInterface &future, - const WorkingCopy &workingCopy) = 0; + const WorkingCopy &workingCopy, + const ProjectExplorer::Project *activeProject) = 0; const QString m_filePath; Configuration m_configuration; diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.cpp b/src/plugins/cpptools/baseeditordocumentprocessor.cpp index 1ae7f11b98e..69432dd6e2d 100644 --- a/src/plugins/cpptools/baseeditordocumentprocessor.cpp +++ b/src/plugins/cpptools/baseeditordocumentprocessor.cpp @@ -73,7 +73,8 @@ void BaseEditorDocumentProcessor::editorDocumentTimerRestarted() void BaseEditorDocumentProcessor::runParser(QFutureInterface &future, BaseEditorDocumentParser::Ptr parser, - const WorkingCopy workingCopy) + const WorkingCopy workingCopy, + const ProjectExplorer::Project *activeProject) { future.setProgressRange(0, 1); if (future.isCanceled()) { @@ -81,7 +82,7 @@ void BaseEditorDocumentProcessor::runParser(QFutureInterface &future, return; } - parser->update(future, workingCopy); + parser->update(future, workingCopy, activeProject); CppToolsBridge::finishedRefreshingSourceFiles({parser->filePath()}); future.setProgressValue(1); diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h index f40c09ae761..a37be4ddcb2 100644 --- a/src/plugins/cpptools/baseeditordocumentprocessor.h +++ b/src/plugins/cpptools/baseeditordocumentprocessor.h @@ -91,7 +91,8 @@ signals: protected: static void runParser(QFutureInterface &future, BaseEditorDocumentParser::Ptr parser, - const CppTools::WorkingCopy workingCopy); + const CppTools::WorkingCopy workingCopy, + const ProjectExplorer::Project *activeProject); // Convenience QString filePath() const { return m_filePath; } diff --git a/src/plugins/cpptools/builtineditordocumentparser.cpp b/src/plugins/cpptools/builtineditordocumentparser.cpp index 0258a537099..354951d9b67 100644 --- a/src/plugins/cpptools/builtineditordocumentparser.cpp +++ b/src/plugins/cpptools/builtineditordocumentparser.cpp @@ -56,7 +56,8 @@ BuiltinEditorDocumentParser::BuiltinEditorDocumentParser(const QString &filePath } void BuiltinEditorDocumentParser::updateHelper(const QFutureInterface &future, - const WorkingCopy &theWorkingCopy) + const WorkingCopy &theWorkingCopy, + const ProjectExplorer::Project *activeProject) { if (filePath().isEmpty()) return; @@ -77,7 +78,7 @@ void BuiltinEditorDocumentParser::updateHelper(const QFutureInterface &fut QString projectConfigFile; LanguageFeatures features = LanguageFeatures::defaultFeatures(); - baseState.projectPart = determineProjectPart(filePath(), baseConfig, baseState); + baseState.projectPart = determineProjectPart(filePath(), baseConfig, baseState, activeProject); if (state.forceSnapshotInvalidation) { invalidateSnapshot = true; diff --git a/src/plugins/cpptools/builtineditordocumentparser.h b/src/plugins/cpptools/builtineditordocumentparser.h index 94ae556574c..463acd8026f 100644 --- a/src/plugins/cpptools/builtineditordocumentparser.h +++ b/src/plugins/cpptools/builtineditordocumentparser.h @@ -59,7 +59,8 @@ public: private: void updateHelper(const QFutureInterface &future, - const WorkingCopy &workingCopy) override; + const WorkingCopy &workingCopy, + const ProjectExplorer::Project *activeProject) override; void addFileAndDependencies(CPlusPlus::Snapshot *snapshot, QSet *toRemove, const Utils::FileName &fileName) const; diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.cpp b/src/plugins/cpptools/builtineditordocumentprocessor.cpp index 284e1af8ae9..1d7dbbb817f 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.cpp +++ b/src/plugins/cpptools/builtineditordocumentprocessor.cpp @@ -32,6 +32,8 @@ #include "cpptoolsreuse.h" #include "cppworkingcopy.h" +#include + #include #include #include @@ -205,10 +207,13 @@ BuiltinEditorDocumentProcessor::~BuiltinEditorDocumentProcessor() void BuiltinEditorDocumentProcessor::run() { CppModelManager *mgr = CppModelManager::instance(); + const ProjectExplorer::Project *activeProject + = ProjectExplorer::SessionManager::startupProject(); m_parserFuture = Utils::runAsync(mgr->sharedThreadPool(), runParser, parser(), - mgr->workingCopy()); + mgr->workingCopy(), + activeProject); } BaseEditorDocumentParser::Ptr BuiltinEditorDocumentProcessor::parser() diff --git a/src/plugins/cpptools/builtinindexingsupport.cpp b/src/plugins/cpptools/builtinindexingsupport.cpp index 2325ae138ea..5591a25aada 100644 --- a/src/plugins/cpptools/builtinindexingsupport.cpp +++ b/src/plugins/cpptools/builtinindexingsupport.cpp @@ -158,7 +158,7 @@ void indexFindErrors(QFutureInterface &future, const ParseParams params) // Parse the file as precisely as possible BuiltinEditorDocumentParser parser(file); parser.setReleaseSourceAndAST(false); - parser.update(CppModelManager::instance()->workingCopy()); + parser.update(CppModelManager::instance()->workingCopy(), nullptr); CPlusPlus::Document::Ptr document = parser.document(); QTC_ASSERT(document, return); diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index 9aa5a4538f3..6b2c8c1b9a6 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -430,8 +430,7 @@ IAssistProcessor *InternalCompletionAssistProvider::createProcessor() const return new InternalCppCompletionAssistProcessor; } -AssistInterface *InternalCompletionAssistProvider::createAssistInterface( - const QString &filePath, +AssistInterface *InternalCompletionAssistProvider::createAssistInterface(const QString &filePath, const TextEditorWidget *textEditorWidget, const LanguageFeatures &languageFeatures, int position, @@ -2123,7 +2122,7 @@ void CppCompletionAssistInterface::getCppSpecifics() const m_gotCppSpecifics = true; if (m_parser) { - m_parser->update(CppTools::CppModelManager::instance()->workingCopy()); + m_parser->update(CppTools::CppModelManager::instance()->workingCopy(), nullptr); m_snapshot = m_parser->snapshot(); m_headerPaths = m_parser->headerPaths(); } diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index 622344218dc..69d2087716e 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -877,7 +877,7 @@ void CppToolsPlugin::test_modelmanager_precompiled_headers() BaseEditorDocumentParser::Configuration config = parser->configuration(); config.usePrecompiledHeaders = true; parser->setConfiguration(config); - parser->update(CppModelManager::instance()->workingCopy()); + parser->update(CppModelManager::instance()->workingCopy(), nullptr); // Check if defines from pch are considered Document::Ptr document = mm->document(fileName); @@ -955,7 +955,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor() BaseEditorDocumentParser::Configuration config = parser->configuration(); config.editorDefines = editorDefines.toUtf8(); parser->setConfiguration(config); - parser->update(CppModelManager::instance()->workingCopy()); + parser->update(CppModelManager::instance()->workingCopy(), nullptr); Document::Ptr doc = mm->document(main1File); QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName); diff --git a/src/plugins/cpptools/cppprojectpartchooser.cpp b/src/plugins/cpptools/cppprojectpartchooser.cpp index 19074ff1845..0fb20f4750c 100644 --- a/src/plugins/cpptools/cppprojectpartchooser.cpp +++ b/src/plugins/cpptools/cppprojectpartchooser.cpp @@ -25,15 +25,25 @@ #include "cppprojectpartchooser.h" +#include #include namespace CppTools { namespace Internal { +static ProjectPart::Ptr selectFromActiveProject(const QList &projectParts, + const ProjectExplorer::Project *activeProject) +{ + return Utils::findOr(projectParts, projectParts.first(), [&](const ProjectPart::Ptr &projectPart){ + return projectPart->project == activeProject; + }); +} + ProjectPart::Ptr ProjectPartChooser::choose(const QString &filePath, const ProjectPart::Ptr ¤tProjectPart, const ProjectPart::Ptr &manuallySetProjectPart, - bool stickToPreviousProjectPart) const + bool stickToPreviousProjectPart, + const ProjectExplorer::Project *activeProject) const { QTC_CHECK(m_projectPartsForFile); QTC_CHECK(m_projectPartsFromDependenciesForFile); @@ -57,11 +67,11 @@ ProjectPart::Ptr ProjectPartChooser::choose(const QString &filePath, // Fall-back step 2: Use fall-back part from the model manager: projectPart = m_fallbackProjectPart(); else - projectPart = projectParts.first(); + projectPart = selectFromActiveProject(projectParts, activeProject); } else { if (!projectParts.contains(projectPart)) // Apparently the project file changed, so update our project part. - projectPart = projectParts.first(); + projectPart = selectFromActiveProject(projectParts, activeProject); } return projectPart; diff --git a/src/plugins/cpptools/cppprojectpartchooser.h b/src/plugins/cpptools/cppprojectpartchooser.h index 0b9095bfdaa..fb26c3270d5 100644 --- a/src/plugins/cpptools/cppprojectpartchooser.h +++ b/src/plugins/cpptools/cppprojectpartchooser.h @@ -29,6 +29,8 @@ #include +namespace ProjectExplorer { class Project; } + namespace CppTools { namespace Internal { @@ -48,7 +50,8 @@ public: ProjectPart::Ptr choose(const QString &filePath, const ProjectPart::Ptr ¤tProjectPart, const ProjectPart::Ptr &manuallySetProjectPart, - bool stickToPreviousProjectPart) const; + bool stickToPreviousProjectPart, + const ProjectExplorer::Project *activeProject) const; private: FallBackProjectPart m_fallbackProjectPart; diff --git a/tests/unit/unittest/cppprojectpartchooser-test.cpp b/tests/unit/unittest/cppprojectpartchooser-test.cpp index 2a6e85946de..528f773c3ac 100644 --- a/tests/unit/unittest/cppprojectpartchooser-test.cpp +++ b/tests/unit/unittest/cppprojectpartchooser-test.cpp @@ -41,11 +41,14 @@ protected: void SetUp() override; const ProjectPart::Ptr choose() const; + static QList createProjectPartsWithDifferentProjects(); + protected: QString filePath; ProjectPart::Ptr currentProjectPart{new ProjectPart}; ProjectPart::Ptr manuallySetProjectPart; bool stickToPreviousProjectPart = false; + const ProjectExplorer::Project *activeProject = nullptr; ::ProjectPartChooser chooser; QList projectPartsForFile; @@ -73,6 +76,30 @@ TEST_F(ProjectPartChooser, ForMultipleChoosePrevious) ASSERT_THAT(chosen, Eq(currentProjectPart)); } +TEST_F(ProjectPartChooser, ForMultipleChooseFromActiveProject) +{ + const QList projectParts = createProjectPartsWithDifferentProjects(); + const ProjectPart::Ptr secondProjectPart = projectParts.at(1); + projectPartsForFile += projectParts; + activeProject = secondProjectPart->project; + + const ProjectPart::Ptr chosen = choose(); + + ASSERT_THAT(chosen, Eq(secondProjectPart)); +} + +TEST_F(ProjectPartChooser, ForMultipleFromDependenciesChooseFromActiveProject) +{ + const QList projectParts = createProjectPartsWithDifferentProjects(); + const ProjectPart::Ptr secondProjectPart = projectParts.at(1); + projectPartsFromDependenciesForFile += projectParts; + activeProject = secondProjectPart->project; + + const ProjectPart::Ptr chosen = choose(); + + ASSERT_THAT(chosen, Eq(secondProjectPart)); +} + TEST_F(ProjectPartChooser, IfProjectIsGoneStickToPrevious) // Built-in Code Model { stickToPreviousProjectPart = true; @@ -94,7 +121,7 @@ TEST_F(ProjectPartChooser, IfProjectIsGoneDoNotStickToPrevious) // Clang Code Mo TEST_F(ProjectPartChooser, ForMultipleChooseNewIfPreviousIsGone) { - const ProjectPart::Ptr newProjectPart; + const ProjectPart::Ptr newProjectPart{new ProjectPart}; projectPartsForFile += newProjectPart; const ProjectPart::Ptr chosen = choose(); @@ -139,7 +166,22 @@ const ProjectPart::Ptr ProjectPartChooser::choose() const return chooser.choose(filePath, currentProjectPart, manuallySetProjectPart, - stickToPreviousProjectPart); + stickToPreviousProjectPart, + activeProject); +} + +QList ProjectPartChooser::createProjectPartsWithDifferentProjects() +{ + QList projectParts; + + const ProjectPart::Ptr p1{new ProjectPart}; + p1->project = reinterpret_cast(1 << 0); + projectParts.append(p1); + const ProjectPart::Ptr p2{new ProjectPart}; + p2->project = reinterpret_cast(1 << 1); + projectParts.append(p2); + + return projectParts; } } // anonymous namespace