CppTools: Fix using updated project part

1. Open a project consisting of two subprojects referencing the same
   source file.
2. Open the source file.
3. Click '#' in the editor toolbar and select the second project (part).
4. Update the project file, e.g. add a define
   ==> Editor does not reflect the added define

This is due to comparing project part pointers. Fix by using the project
part id that remains stable across project manager updates.

Change-Id: Ifd1a113e55ebe2ecf036cd7caafdbfd6e4cdf415
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Nikolai Kosjar
2017-01-19 12:52:16 +01:00
parent 07f32ef57a
commit bddfe21961
8 changed files with 32 additions and 23 deletions

View File

@@ -37,7 +37,7 @@ void ClangEditorDocumentParser::updateImpl(const QFutureInterface<void> &,
{ {
State state_ = state(); State state_ = state();
state_.projectPartInfo = determineProjectPart(filePath(), state_.projectPartInfo = determineProjectPart(filePath(),
configuration(), configuration().preferredProjectPartId,
state_.projectPartInfo, state_.projectPartInfo,
updateParams.activeProject, updateParams.activeProject,
updateParams.languagePreference, updateParams.languagePreference,

View File

@@ -278,7 +278,7 @@ void CppEditorDocument::setPreprocessorSettings(const CppTools::ProjectPart::Ptr
if (parser->projectPartInfo().projectPart != projectPart if (parser->projectPartInfo().projectPart != projectPart
|| parser->configuration().editorDefines != defines) { || parser->configuration().editorDefines != defines) {
CppTools::BaseEditorDocumentParser::Configuration config = parser->configuration(); CppTools::BaseEditorDocumentParser::Configuration config = parser->configuration();
config.manuallySetProjectPart = projectPart; config.preferredProjectPartId = projectPart->id();
config.editorDefines = defines; config.editorDefines = defines;
parser->setConfiguration(config); parser->setConfiguration(config);

View File

@@ -121,15 +121,13 @@ BaseEditorDocumentParser::Ptr BaseEditorDocumentParser::get(const QString &fileP
ProjectPartInfo BaseEditorDocumentParser::determineProjectPart( ProjectPartInfo BaseEditorDocumentParser::determineProjectPart(
const QString &filePath, const QString &filePath,
const Configuration &config, const QString &preferredProjectPartId,
const ProjectPartInfo &currentProjectPartInfo, const ProjectPartInfo &currentProjectPartInfo,
const ProjectExplorer::Project *activeProject, const ProjectExplorer::Project *activeProject,
Language languagePreference, Language languagePreference,
bool hasActiveProjectChanged) bool hasActiveProjectChanged)
{ {
using Internal::ProjectPartChooser; Internal::ProjectPartChooser chooser;
ProjectPartChooser chooser;
chooser.setFallbackProjectPart([](){ chooser.setFallbackProjectPart([](){
return CppModelManager::instance()->fallbackProjectPart(); return CppModelManager::instance()->fallbackProjectPart();
}); });
@@ -144,7 +142,7 @@ ProjectPartInfo BaseEditorDocumentParser::determineProjectPart(
const ProjectPartInfo chooserResult const ProjectPartInfo chooserResult
= chooser.choose(filePath, = chooser.choose(filePath,
currentProjectPartInfo, currentProjectPartInfo,
config.manuallySetProjectPart, preferredProjectPartId,
activeProject, activeProject,
languagePreference, languagePreference,
hasActiveProjectChanged); hasActiveProjectChanged);

View File

@@ -49,7 +49,7 @@ public:
struct Configuration { struct Configuration {
bool usePrecompiledHeaders = false; bool usePrecompiledHeaders = false;
QByteArray editorDefines; QByteArray editorDefines;
ProjectPart::Ptr manuallySetProjectPart; QString preferredProjectPartId;
}; };
struct UpdateParams { struct UpdateParams {
@@ -95,7 +95,7 @@ protected:
void setState(const State &state); void setState(const State &state);
static ProjectPartInfo determineProjectPart(const QString &filePath, static ProjectPartInfo determineProjectPart(const QString &filePath,
const Configuration &config, const QString &preferredProjectPartId,
const ProjectPartInfo &currentProjectPartInfo, const ProjectPartInfo &currentProjectPartInfo,
const ProjectExplorer::Project *activeProject, const ProjectExplorer::Project *activeProject,
Language languagePreference, Language languagePreference,

View File

@@ -78,7 +78,7 @@ void BuiltinEditorDocumentParser::updateImpl(const QFutureInterface<void> &futur
LanguageFeatures features = LanguageFeatures::defaultFeatures(); LanguageFeatures features = LanguageFeatures::defaultFeatures();
baseState.projectPartInfo = determineProjectPart(filePath(), baseState.projectPartInfo = determineProjectPart(filePath(),
baseConfig, baseConfig.preferredProjectPartId,
baseState.projectPartInfo, baseState.projectPartInfo,
updateParams.activeProject, updateParams.activeProject,
updateParams.languagePreference, updateParams.languagePreference,

View File

@@ -44,9 +44,11 @@ public:
}; };
ProjectPartPrioritizer(const QList<ProjectPart::Ptr> &projectParts, ProjectPartPrioritizer(const QList<ProjectPart::Ptr> &projectParts,
const QString &preferredProjectPartId,
const ProjectExplorer::Project *activeProject, const ProjectExplorer::Project *activeProject,
Language languagePreference) Language languagePreference)
: m_projectParts(projectParts) : m_projectParts(projectParts)
, m_preferredProjectPartId(preferredProjectPartId)
, m_activeProject(activeProject) , m_activeProject(activeProject)
, m_languagePreference(languagePreference) , m_languagePreference(languagePreference)
{ {
@@ -93,6 +95,9 @@ private:
{ {
int thePriority = 0; int thePriority = 0;
if (!m_preferredProjectPartId.isEmpty() && projectPart.id() == m_preferredProjectPartId)
thePriority += 1000;
if (projectPart.project == m_activeProject) if (projectPart.project == m_activeProject)
thePriority += 100; thePriority += 100;
@@ -114,6 +119,7 @@ private:
private: private:
const QList<ProjectPart::Ptr> m_projectParts; const QList<ProjectPart::Ptr> m_projectParts;
const QString m_preferredProjectPartId;
const ProjectExplorer::Project *m_activeProject = nullptr; const ProjectExplorer::Project *m_activeProject = nullptr;
Language m_languagePreference = Language::Cxx; Language m_languagePreference = Language::Cxx;
@@ -122,10 +128,9 @@ private:
bool m_isAmbiguous = false; bool m_isAmbiguous = false;
}; };
ProjectPartInfo ProjectPartChooser::choose( ProjectPartInfo ProjectPartChooser::choose(const QString &filePath,
const QString &filePath,
const ProjectPartInfo &currentProjectPartInfo, const ProjectPartInfo &currentProjectPartInfo,
const ProjectPart::Ptr &manuallySetProjectPart, const QString &preferredProjectPartId,
const ProjectExplorer::Project *activeProject, const ProjectExplorer::Project *activeProject,
Language languagePreference, Language languagePreference,
bool projectHasChanged) const bool projectHasChanged) const
@@ -134,9 +139,6 @@ ProjectPartInfo ProjectPartChooser::choose(
QTC_CHECK(m_projectPartsFromDependenciesForFile); QTC_CHECK(m_projectPartsFromDependenciesForFile);
QTC_CHECK(m_fallbackProjectPart); QTC_CHECK(m_fallbackProjectPart);
if (manuallySetProjectPart)
return {manuallySetProjectPart, ProjectPartInfo::NoHint};
ProjectPart::Ptr projectPart = currentProjectPartInfo.projectPart; ProjectPart::Ptr projectPart = currentProjectPartInfo.projectPart;
ProjectPartInfo::Hint hint = ProjectPartInfo::NoHint; ProjectPartInfo::Hint hint = ProjectPartInfo::NoHint;
@@ -153,12 +155,18 @@ ProjectPartInfo ProjectPartChooser::choose(
projectPart = m_fallbackProjectPart(); projectPart = m_fallbackProjectPart();
hint = ProjectPartInfo::IsFallbackMatch; hint = ProjectPartInfo::IsFallbackMatch;
} else { } else {
ProjectPartPrioritizer prioritizer(projectParts, activeProject, languagePreference); ProjectPartPrioritizer prioritizer(projectParts,
preferredProjectPartId,
activeProject,
languagePreference);
projectPart = prioritizer.projectPart(); projectPart = prioritizer.projectPart();
} }
} else { } else {
if (projectHasChanged || !projectParts.contains(projectPart)) { if (projectHasChanged || !projectParts.contains(projectPart)) {
ProjectPartPrioritizer prioritizer(projectParts, activeProject, languagePreference); ProjectPartPrioritizer prioritizer(projectParts,
preferredProjectPartId,
activeProject,
languagePreference);
projectPart = prioritizer.projectPart(); projectPart = prioritizer.projectPart();
hint = prioritizer.isAmbiguous() hint = prioritizer.isAmbiguous()
? ProjectPartInfo::IsAmbiguousMatch ? ProjectPartInfo::IsAmbiguousMatch

View File

@@ -51,7 +51,7 @@ public:
ProjectPartInfo choose( ProjectPartInfo choose(
const QString &filePath, const QString &filePath,
const ProjectPartInfo &currentProjectPartInfo, const ProjectPartInfo &currentProjectPartInfo,
const ProjectPart::Ptr &manuallySetProjectPart, const QString &preferredProjectPartId,
const ProjectExplorer::Project *activeProject, const ProjectExplorer::Project *activeProject,
Language languagePreference, Language languagePreference,
bool projectHasChanged) const; bool projectHasChanged) const;

View File

@@ -51,7 +51,7 @@ protected:
QString filePath; QString filePath;
ProjectPartInfo currentProjectPartInfo{ProjectPart::Ptr(new ProjectPart), ProjectPartInfo currentProjectPartInfo{ProjectPart::Ptr(new ProjectPart),
ProjectPartInfo::NoHint}; ProjectPartInfo::NoHint};
ProjectPart::Ptr manuallySetProjectPart; QString preferredProjectPartId;
const ProjectExplorer::Project *activeProject = nullptr; const ProjectExplorer::Project *activeProject = nullptr;
bool projectHasChanged = false; bool projectHasChanged = false;
Language languagePreference = Language::Cxx; Language languagePreference = Language::Cxx;
@@ -64,11 +64,14 @@ protected:
TEST_F(ProjectPartChooser, ChooseManuallySet) TEST_F(ProjectPartChooser, ChooseManuallySet)
{ {
manuallySetProjectPart.reset(new ProjectPart); ProjectPart::Ptr p1(new ProjectPart);
ProjectPart::Ptr p2(new ProjectPart);
p2->projectFile = preferredProjectPartId = "someId";
projectPartsForFile += {p1, p2};
const ProjectPart::Ptr chosen = choose().projectPart; const ProjectPart::Ptr chosen = choose().projectPart;
ASSERT_THAT(chosen, Eq(manuallySetProjectPart)); ASSERT_THAT(chosen, Eq(p2));
} }
TEST_F(ProjectPartChooser, ForMultipleChoosePrevious) TEST_F(ProjectPartChooser, ForMultipleChoosePrevious)
@@ -249,7 +252,7 @@ const ProjectPartInfo ProjectPartChooser::choose() const
{ {
return chooser.choose(filePath, return chooser.choose(filePath,
currentProjectPartInfo, currentProjectPartInfo,
manuallySetProjectPart, preferredProjectPartId,
activeProject, activeProject,
languagePreference, languagePreference,
projectHasChanged); projectHasChanged);