CppTools: Prioritize project parts from active project

...when selecting one for the editor document.

Change-Id: I85066aaa0862870cb2db2fb2cb40c2b2c23b2cac
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Nikolai Kosjar
2016-12-16 13:12:04 +01:00
parent b8b6f348e0
commit 566ab175b3
16 changed files with 119 additions and 35 deletions

View File

@@ -36,10 +36,11 @@ ClangEditorDocumentParser::ClangEditorDocumentParser(const QString &filePath)
} }
void ClangEditorDocumentParser::updateHelper(const QFutureInterface<void> &, void ClangEditorDocumentParser::updateHelper(const QFutureInterface<void> &,
const CppTools::WorkingCopy &) const CppTools::WorkingCopy &,
const ProjectExplorer::Project *activeProject)
{ {
State state_ = state(); State state_ = state();
state_.projectPart = determineProjectPart(filePath(), configuration(), state_); state_.projectPart = determineProjectPart(filePath(), configuration(), state_, activeProject);
setState(state_); setState(state_);
} }

View File

@@ -38,7 +38,8 @@ public:
private: private:
void updateHelper(const QFutureInterface<void> &future, void updateHelper(const QFutureInterface<void> &future,
const CppTools::WorkingCopy &) override; const CppTools::WorkingCopy &,
const ProjectExplorer::Project *activeProject) override;
}; };
} // namespace ClangCodeModel } // namespace ClangCodeModel

View File

@@ -46,6 +46,8 @@
#include <cpptools/cppworkingcopy.h> #include <cpptools/cppworkingcopy.h>
#include <cpptools/editordocumenthandle.h> #include <cpptools/editordocumenthandle.h>
#include <projectexplorer/session.h>
#include <texteditor/convenience.h> #include <texteditor/convenience.h>
#include <texteditor/fontsettings.h> #include <texteditor/fontsettings.h>
#include <texteditor/texteditor.h> #include <texteditor/texteditor.h>
@@ -115,7 +117,12 @@ void ClangEditorDocumentProcessor::run()
connect(&m_parserWatcher, &QFutureWatcher<void>::finished, connect(&m_parserWatcher, &QFutureWatcher<void>::finished,
this, &ClangEditorDocumentProcessor::onParserFinished); this, &ClangEditorDocumentProcessor::onParserFinished);
const CppTools::WorkingCopy workingCopy = CppTools::CppModelManager::instance()->workingCopy(); const CppTools::WorkingCopy workingCopy = CppTools::CppModelManager::instance()->workingCopy();
const QFuture<void> future = ::Utils::runAsync(&runParser, parser(), workingCopy); const ProjectExplorer::Project *activeProject
= ProjectExplorer::SessionManager::startupProject();
const QFuture<void> future = ::Utils::runAsync(&runParser,
parser(),
workingCopy,
activeProject);
m_parserWatcher.setFuture(future); m_parserWatcher.setFuture(future);
// Run builtin processor // Run builtin processor

View File

@@ -77,17 +77,19 @@ void BaseEditorDocumentParser::setConfiguration(const Configuration &configurati
m_configuration = configuration; m_configuration = configuration;
} }
void BaseEditorDocumentParser::update(const WorkingCopy &workingCopy) void BaseEditorDocumentParser::update(const WorkingCopy &workingCopy,
const ProjectExplorer::Project *activeProject)
{ {
QFutureInterface<void> dummy; QFutureInterface<void> dummy;
update(dummy, workingCopy); update(dummy, workingCopy, activeProject);
} }
void BaseEditorDocumentParser::update(const QFutureInterface<void> &future, void BaseEditorDocumentParser::update(const QFutureInterface<void> &future,
const WorkingCopy &workingCopy) const WorkingCopy &workingCopy,
const ProjectExplorer::Project *activeProject)
{ {
QMutexLocker locker(&m_updateIsRunning); QMutexLocker locker(&m_updateIsRunning);
updateHelper(future, workingCopy); updateHelper(future, workingCopy, activeProject);
} }
BaseEditorDocumentParser::State BaseEditorDocumentParser::state() const BaseEditorDocumentParser::State BaseEditorDocumentParser::state() const
@@ -117,9 +119,11 @@ BaseEditorDocumentParser::Ptr BaseEditorDocumentParser::get(const QString &fileP
return BaseEditorDocumentParser::Ptr(); return BaseEditorDocumentParser::Ptr();
} }
ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart(const QString &filePath, ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart(
const Configuration &config, const QString &filePath,
const State &state) const Configuration &config,
const State &state,
const ProjectExplorer::Project *activeProject)
{ {
Internal::ProjectPartChooser chooser; Internal::ProjectPartChooser chooser;
chooser.setFallbackProjectPart([](){ chooser.setFallbackProjectPart([](){
@@ -136,7 +140,8 @@ ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart(const QString &f
return chooser.choose(filePath, return chooser.choose(filePath,
state.projectPart, state.projectPart,
config.manuallySetProjectPart, config.manuallySetProjectPart,
config.stickToPreviousProjectPart); config.stickToPreviousProjectPart,
activeProject);
} }
} // namespace CppTools } // namespace CppTools

View File

@@ -33,6 +33,8 @@
#include <QObject> #include <QObject>
#include <QMutex> #include <QMutex>
namespace ProjectExplorer { class Project; }
namespace CppTools { namespace CppTools {
class CPPTOOLS_EXPORT BaseEditorDocumentParser : public QObject class CPPTOOLS_EXPORT BaseEditorDocumentParser : public QObject
@@ -58,8 +60,11 @@ public:
Configuration configuration() const; Configuration configuration() const;
void setConfiguration(const Configuration &configuration); void setConfiguration(const Configuration &configuration);
void update(const WorkingCopy &workingCopy); void update(const WorkingCopy &workingCopy,
void update(const QFutureInterface<void> &future, const WorkingCopy &workingCopy); const ProjectExplorer::Project *activeProject);
void update(const QFutureInterface<void> &future,
const WorkingCopy &workingCopy,
const ProjectExplorer::Project *activeProject);
ProjectPart::Ptr projectPart() const; ProjectPart::Ptr projectPart() const;
@@ -73,13 +78,15 @@ protected:
static ProjectPart::Ptr determineProjectPart(const QString &filePath, static ProjectPart::Ptr determineProjectPart(const QString &filePath,
const Configuration &config, const Configuration &config,
const State &state); const State &state,
const ProjectExplorer::Project *activeProject);
mutable QMutex m_stateAndConfigurationMutex; mutable QMutex m_stateAndConfigurationMutex;
private: private:
virtual void updateHelper(const QFutureInterface<void> &future, virtual void updateHelper(const QFutureInterface<void> &future,
const WorkingCopy &workingCopy) = 0; const WorkingCopy &workingCopy,
const ProjectExplorer::Project *activeProject) = 0;
const QString m_filePath; const QString m_filePath;
Configuration m_configuration; Configuration m_configuration;

View File

@@ -73,7 +73,8 @@ void BaseEditorDocumentProcessor::editorDocumentTimerRestarted()
void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future, void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
BaseEditorDocumentParser::Ptr parser, BaseEditorDocumentParser::Ptr parser,
const WorkingCopy workingCopy) const WorkingCopy workingCopy,
const ProjectExplorer::Project *activeProject)
{ {
future.setProgressRange(0, 1); future.setProgressRange(0, 1);
if (future.isCanceled()) { if (future.isCanceled()) {
@@ -81,7 +82,7 @@ void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
return; return;
} }
parser->update(future, workingCopy); parser->update(future, workingCopy, activeProject);
CppToolsBridge::finishedRefreshingSourceFiles({parser->filePath()}); CppToolsBridge::finishedRefreshingSourceFiles({parser->filePath()});
future.setProgressValue(1); future.setProgressValue(1);

View File

@@ -91,7 +91,8 @@ signals:
protected: protected:
static void runParser(QFutureInterface<void> &future, static void runParser(QFutureInterface<void> &future,
BaseEditorDocumentParser::Ptr parser, BaseEditorDocumentParser::Ptr parser,
const CppTools::WorkingCopy workingCopy); const CppTools::WorkingCopy workingCopy,
const ProjectExplorer::Project *activeProject);
// Convenience // Convenience
QString filePath() const { return m_filePath; } QString filePath() const { return m_filePath; }

View File

@@ -56,7 +56,8 @@ BuiltinEditorDocumentParser::BuiltinEditorDocumentParser(const QString &filePath
} }
void BuiltinEditorDocumentParser::updateHelper(const QFutureInterface<void> &future, void BuiltinEditorDocumentParser::updateHelper(const QFutureInterface<void> &future,
const WorkingCopy &theWorkingCopy) const WorkingCopy &theWorkingCopy,
const ProjectExplorer::Project *activeProject)
{ {
if (filePath().isEmpty()) if (filePath().isEmpty())
return; return;
@@ -77,7 +78,7 @@ void BuiltinEditorDocumentParser::updateHelper(const QFutureInterface<void> &fut
QString projectConfigFile; QString projectConfigFile;
LanguageFeatures features = LanguageFeatures::defaultFeatures(); LanguageFeatures features = LanguageFeatures::defaultFeatures();
baseState.projectPart = determineProjectPart(filePath(), baseConfig, baseState); baseState.projectPart = determineProjectPart(filePath(), baseConfig, baseState, activeProject);
if (state.forceSnapshotInvalidation) { if (state.forceSnapshotInvalidation) {
invalidateSnapshot = true; invalidateSnapshot = true;

View File

@@ -59,7 +59,8 @@ public:
private: private:
void updateHelper(const QFutureInterface<void> &future, void updateHelper(const QFutureInterface<void> &future,
const WorkingCopy &workingCopy) override; const WorkingCopy &workingCopy,
const ProjectExplorer::Project *activeProject) override;
void addFileAndDependencies(CPlusPlus::Snapshot *snapshot, void addFileAndDependencies(CPlusPlus::Snapshot *snapshot,
QSet<Utils::FileName> *toRemove, QSet<Utils::FileName> *toRemove,
const Utils::FileName &fileName) const; const Utils::FileName &fileName) const;

View File

@@ -32,6 +32,8 @@
#include "cpptoolsreuse.h" #include "cpptoolsreuse.h"
#include "cppworkingcopy.h" #include "cppworkingcopy.h"
#include <projectexplorer/session.h>
#include <texteditor/convenience.h> #include <texteditor/convenience.h>
#include <texteditor/fontsettings.h> #include <texteditor/fontsettings.h>
#include <texteditor/refactoroverlay.h> #include <texteditor/refactoroverlay.h>
@@ -205,10 +207,13 @@ BuiltinEditorDocumentProcessor::~BuiltinEditorDocumentProcessor()
void BuiltinEditorDocumentProcessor::run() void BuiltinEditorDocumentProcessor::run()
{ {
CppModelManager *mgr = CppModelManager::instance(); CppModelManager *mgr = CppModelManager::instance();
const ProjectExplorer::Project *activeProject
= ProjectExplorer::SessionManager::startupProject();
m_parserFuture = Utils::runAsync(mgr->sharedThreadPool(), m_parserFuture = Utils::runAsync(mgr->sharedThreadPool(),
runParser, runParser,
parser(), parser(),
mgr->workingCopy()); mgr->workingCopy(),
activeProject);
} }
BaseEditorDocumentParser::Ptr BuiltinEditorDocumentProcessor::parser() BaseEditorDocumentParser::Ptr BuiltinEditorDocumentProcessor::parser()

View File

@@ -158,7 +158,7 @@ void indexFindErrors(QFutureInterface<void> &future, const ParseParams params)
// Parse the file as precisely as possible // Parse the file as precisely as possible
BuiltinEditorDocumentParser parser(file); BuiltinEditorDocumentParser parser(file);
parser.setReleaseSourceAndAST(false); parser.setReleaseSourceAndAST(false);
parser.update(CppModelManager::instance()->workingCopy()); parser.update(CppModelManager::instance()->workingCopy(), nullptr);
CPlusPlus::Document::Ptr document = parser.document(); CPlusPlus::Document::Ptr document = parser.document();
QTC_ASSERT(document, return); QTC_ASSERT(document, return);

View File

@@ -430,8 +430,7 @@ IAssistProcessor *InternalCompletionAssistProvider::createProcessor() const
return new InternalCppCompletionAssistProcessor; return new InternalCppCompletionAssistProcessor;
} }
AssistInterface *InternalCompletionAssistProvider::createAssistInterface( AssistInterface *InternalCompletionAssistProvider::createAssistInterface(const QString &filePath,
const QString &filePath,
const TextEditorWidget *textEditorWidget, const TextEditorWidget *textEditorWidget,
const LanguageFeatures &languageFeatures, const LanguageFeatures &languageFeatures,
int position, int position,
@@ -2123,7 +2122,7 @@ void CppCompletionAssistInterface::getCppSpecifics() const
m_gotCppSpecifics = true; m_gotCppSpecifics = true;
if (m_parser) { if (m_parser) {
m_parser->update(CppTools::CppModelManager::instance()->workingCopy()); m_parser->update(CppTools::CppModelManager::instance()->workingCopy(), nullptr);
m_snapshot = m_parser->snapshot(); m_snapshot = m_parser->snapshot();
m_headerPaths = m_parser->headerPaths(); m_headerPaths = m_parser->headerPaths();
} }

View File

@@ -877,7 +877,7 @@ void CppToolsPlugin::test_modelmanager_precompiled_headers()
BaseEditorDocumentParser::Configuration config = parser->configuration(); BaseEditorDocumentParser::Configuration config = parser->configuration();
config.usePrecompiledHeaders = true; config.usePrecompiledHeaders = true;
parser->setConfiguration(config); parser->setConfiguration(config);
parser->update(CppModelManager::instance()->workingCopy()); parser->update(CppModelManager::instance()->workingCopy(), nullptr);
// Check if defines from pch are considered // Check if defines from pch are considered
Document::Ptr document = mm->document(fileName); Document::Ptr document = mm->document(fileName);
@@ -955,7 +955,7 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
BaseEditorDocumentParser::Configuration config = parser->configuration(); BaseEditorDocumentParser::Configuration config = parser->configuration();
config.editorDefines = editorDefines.toUtf8(); config.editorDefines = editorDefines.toUtf8();
parser->setConfiguration(config); parser->setConfiguration(config);
parser->update(CppModelManager::instance()->workingCopy()); parser->update(CppModelManager::instance()->workingCopy(), nullptr);
Document::Ptr doc = mm->document(main1File); Document::Ptr doc = mm->document(main1File);
QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName); QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName);

View File

@@ -25,15 +25,25 @@
#include "cppprojectpartchooser.h" #include "cppprojectpartchooser.h"
#include <utils/algorithm.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
namespace CppTools { namespace CppTools {
namespace Internal { namespace Internal {
static ProjectPart::Ptr selectFromActiveProject(const QList<ProjectPart::Ptr> &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, ProjectPart::Ptr ProjectPartChooser::choose(const QString &filePath,
const ProjectPart::Ptr &currentProjectPart, const ProjectPart::Ptr &currentProjectPart,
const ProjectPart::Ptr &manuallySetProjectPart, const ProjectPart::Ptr &manuallySetProjectPart,
bool stickToPreviousProjectPart) const bool stickToPreviousProjectPart,
const ProjectExplorer::Project *activeProject) const
{ {
QTC_CHECK(m_projectPartsForFile); QTC_CHECK(m_projectPartsForFile);
QTC_CHECK(m_projectPartsFromDependenciesForFile); 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: // Fall-back step 2: Use fall-back part from the model manager:
projectPart = m_fallbackProjectPart(); projectPart = m_fallbackProjectPart();
else else
projectPart = projectParts.first(); projectPart = selectFromActiveProject(projectParts, activeProject);
} else { } else {
if (!projectParts.contains(projectPart)) if (!projectParts.contains(projectPart))
// Apparently the project file changed, so update our project part. // Apparently the project file changed, so update our project part.
projectPart = projectParts.first(); projectPart = selectFromActiveProject(projectParts, activeProject);
} }
return projectPart; return projectPart;

View File

@@ -29,6 +29,8 @@
#include <functional> #include <functional>
namespace ProjectExplorer { class Project; }
namespace CppTools { namespace CppTools {
namespace Internal { namespace Internal {
@@ -48,7 +50,8 @@ public:
ProjectPart::Ptr choose(const QString &filePath, ProjectPart::Ptr choose(const QString &filePath,
const ProjectPart::Ptr &currentProjectPart, const ProjectPart::Ptr &currentProjectPart,
const ProjectPart::Ptr &manuallySetProjectPart, const ProjectPart::Ptr &manuallySetProjectPart,
bool stickToPreviousProjectPart) const; bool stickToPreviousProjectPart,
const ProjectExplorer::Project *activeProject) const;
private: private:
FallBackProjectPart m_fallbackProjectPart; FallBackProjectPart m_fallbackProjectPart;

View File

@@ -41,11 +41,14 @@ protected:
void SetUp() override; void SetUp() override;
const ProjectPart::Ptr choose() const; const ProjectPart::Ptr choose() const;
static QList<ProjectPart::Ptr> createProjectPartsWithDifferentProjects();
protected: protected:
QString filePath; QString filePath;
ProjectPart::Ptr currentProjectPart{new ProjectPart}; ProjectPart::Ptr currentProjectPart{new ProjectPart};
ProjectPart::Ptr manuallySetProjectPart; ProjectPart::Ptr manuallySetProjectPart;
bool stickToPreviousProjectPart = false; bool stickToPreviousProjectPart = false;
const ProjectExplorer::Project *activeProject = nullptr;
::ProjectPartChooser chooser; ::ProjectPartChooser chooser;
QList<ProjectPart::Ptr> projectPartsForFile; QList<ProjectPart::Ptr> projectPartsForFile;
@@ -73,6 +76,30 @@ TEST_F(ProjectPartChooser, ForMultipleChoosePrevious)
ASSERT_THAT(chosen, Eq(currentProjectPart)); ASSERT_THAT(chosen, Eq(currentProjectPart));
} }
TEST_F(ProjectPartChooser, ForMultipleChooseFromActiveProject)
{
const QList<ProjectPart::Ptr> 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<ProjectPart::Ptr> 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 TEST_F(ProjectPartChooser, IfProjectIsGoneStickToPrevious) // Built-in Code Model
{ {
stickToPreviousProjectPart = true; stickToPreviousProjectPart = true;
@@ -94,7 +121,7 @@ TEST_F(ProjectPartChooser, IfProjectIsGoneDoNotStickToPrevious) // Clang Code Mo
TEST_F(ProjectPartChooser, ForMultipleChooseNewIfPreviousIsGone) TEST_F(ProjectPartChooser, ForMultipleChooseNewIfPreviousIsGone)
{ {
const ProjectPart::Ptr newProjectPart; const ProjectPart::Ptr newProjectPart{new ProjectPart};
projectPartsForFile += newProjectPart; projectPartsForFile += newProjectPart;
const ProjectPart::Ptr chosen = choose(); const ProjectPart::Ptr chosen = choose();
@@ -139,7 +166,22 @@ const ProjectPart::Ptr ProjectPartChooser::choose() const
return chooser.choose(filePath, return chooser.choose(filePath,
currentProjectPart, currentProjectPart,
manuallySetProjectPart, manuallySetProjectPart,
stickToPreviousProjectPart); stickToPreviousProjectPart,
activeProject);
}
QList<ProjectPart::Ptr> ProjectPartChooser::createProjectPartsWithDifferentProjects()
{
QList<ProjectPart::Ptr> projectParts;
const ProjectPart::Ptr p1{new ProjectPart};
p1->project = reinterpret_cast<ProjectExplorer::Project *>(1 << 0);
projectParts.append(p1);
const ProjectPart::Ptr p2{new ProjectPart};
p2->project = reinterpret_cast<ProjectExplorer::Project *>(1 << 1);
projectParts.append(p2);
return projectParts;
} }
} // anonymous namespace } // anonymous namespace