CppTools: Reparse editor documents after active project change

Change-Id: I010709c866291bf59c27f4a05765e1ab0efd28af
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Nikolai Kosjar
2016-12-15 11:21:44 +01:00
parent bd66d5ac05
commit 602c873d3e
17 changed files with 88 additions and 46 deletions

View File

@@ -42,7 +42,8 @@ void ClangEditorDocumentParser::updateImpl(const QFutureInterface<void> &,
state_.projectPart = determineProjectPart(filePath(), state_.projectPart = determineProjectPart(filePath(),
configuration(), configuration(),
state_, state_,
updateParams.activeProject); updateParams.activeProject,
updateParams.hasActiveProjectChanged);
setState(state_); setState(state_);
} }

View File

@@ -119,7 +119,7 @@ void ClangEditorDocumentProcessor::runImpl(
m_parserWatcher.setFuture(future); m_parserWatcher.setFuture(future);
// Run builtin processor // Run builtin processor
m_builtinProcessor.run(); m_builtinProcessor.runImpl(updateParams);
} }
void ClangEditorDocumentProcessor::recalculateSemanticInfoDetached(bool force) void ClangEditorDocumentProcessor::recalculateSemanticInfoDetached(bool force)

View File

@@ -121,7 +121,8 @@ ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart(
const QString &filePath, const QString &filePath,
const Configuration &config, const Configuration &config,
const State &state, const State &state,
const ProjectExplorer::Project *activeProject) const ProjectExplorer::Project *activeProject,
bool hasActiveProjectChanged)
{ {
Internal::ProjectPartChooser chooser; Internal::ProjectPartChooser chooser;
chooser.setFallbackProjectPart([](){ chooser.setFallbackProjectPart([](){
@@ -139,7 +140,8 @@ ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart(
state.projectPart, state.projectPart,
config.manuallySetProjectPart, config.manuallySetProjectPart,
config.stickToPreviousProjectPart, config.stickToPreviousProjectPart,
activeProject); activeProject,
hasActiveProjectChanged);
} }
} // namespace CppTools } // namespace CppTools

View File

@@ -54,14 +54,17 @@ public:
struct UpdateParams { struct UpdateParams {
UpdateParams(const WorkingCopy &workingCopy, UpdateParams(const WorkingCopy &workingCopy,
const ProjectExplorer::Project *activeProject) const ProjectExplorer::Project *activeProject,
bool hasActiveProjectChanged)
: workingCopy(workingCopy) : workingCopy(workingCopy)
, activeProject(activeProject) , activeProject(activeProject)
, hasActiveProjectChanged(hasActiveProjectChanged)
{ {
} }
WorkingCopy workingCopy; WorkingCopy workingCopy;
const ProjectExplorer::Project *activeProject = nullptr; const ProjectExplorer::Project *activeProject = nullptr;
bool hasActiveProjectChanged = false;
}; };
public: public:
@@ -88,7 +91,8 @@ 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); const ProjectExplorer::Project *activeProject,
bool hasActiveProjectChanged);
mutable QMutex m_stateAndConfigurationMutex; mutable QMutex m_stateAndConfigurationMutex;

View File

@@ -53,10 +53,11 @@ BaseEditorDocumentProcessor::~BaseEditorDocumentProcessor()
{ {
} }
void BaseEditorDocumentProcessor::run() void BaseEditorDocumentProcessor::run(bool hasActiveProjectChanged)
{ {
runImpl({CppModelManager::instance()->workingCopy(), runImpl({CppModelManager::instance()->workingCopy(),
ProjectExplorer::SessionManager::startupProject()}); ProjectExplorer::SessionManager::startupProject(),
hasActiveProjectChanged});
} }
TextEditor::QuickFixOperations TextEditor::QuickFixOperations

View File

@@ -54,7 +54,7 @@ public:
BaseEditorDocumentProcessor(QTextDocument *textDocument, const QString &filePath); BaseEditorDocumentProcessor(QTextDocument *textDocument, const QString &filePath);
virtual ~BaseEditorDocumentProcessor(); virtual ~BaseEditorDocumentProcessor();
void run(); void run(bool hasActiveProjectChanged = false);
virtual void semanticRehighlight() = 0; virtual void semanticRehighlight() = 0;
virtual void recalculateSemanticInfoDetached(bool force) = 0; virtual void recalculateSemanticInfoDetached(bool force) = 0;
virtual CppTools::SemanticInfo recalculateSemanticInfo() = 0; virtual CppTools::SemanticInfo recalculateSemanticInfo() = 0;

View File

@@ -80,7 +80,8 @@ void BuiltinEditorDocumentParser::updateImpl(const QFutureInterface<void> &futur
baseState.projectPart = determineProjectPart(filePath(), baseState.projectPart = determineProjectPart(filePath(),
baseConfig, baseConfig,
baseState, baseState,
updateParams.activeProject); updateParams.activeProject,
updateParams.hasActiveProjectChanged);
if (state.forceSnapshotInvalidation) { if (state.forceSnapshotInvalidation) {
invalidateSnapshot = true; invalidateSnapshot = true;

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(), nullptr}); parser.update({CppModelManager::instance()->workingCopy(), nullptr, false});
CPlusPlus::Document::Ptr document = parser.document(); CPlusPlus::Document::Ptr document = parser.document();
QTC_ASSERT(document, return); QTC_ASSERT(document, return);

View File

@@ -2122,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(), nullptr}); m_parser->update({CppTools::CppModelManager::instance()->workingCopy(), nullptr, false});
m_snapshot = m_parser->snapshot(); m_snapshot = m_parser->snapshot();
m_headerPaths = m_parser->headerPaths(); m_headerPaths = m_parser->headerPaths();
} }

View File

@@ -338,6 +338,8 @@ CppModelManager::CppModelManager(QObject *parent)
this, &CppModelManager::onAboutToRemoveProject); this, &CppModelManager::onAboutToRemoveProject);
connect(sessionManager, &ProjectExplorer::SessionManager::aboutToLoadSession, connect(sessionManager, &ProjectExplorer::SessionManager::aboutToLoadSession,
this, &CppModelManager::onAboutToLoadSession); this, &CppModelManager::onAboutToLoadSession);
connect(sessionManager, &ProjectExplorer::SessionManager::startupProjectChanged,
this, &CppModelManager::onActiveProjectChanged);
connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged, connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
this, &CppModelManager::onCurrentEditorChanged); this, &CppModelManager::onCurrentEditorChanged);
@@ -791,7 +793,7 @@ void CppModelManager::watchForCanceledProjectIndexer(QFuture<void> future,
watcher->setFuture(future); watcher->setFuture(future);
} }
void CppModelManager::updateCppEditorDocuments() const void CppModelManager::updateCppEditorDocuments(bool hasActiveProjectChanged) const
{ {
// Refresh visible documents // Refresh visible documents
QSet<Core::IDocument *> visibleCppEditorDocuments; QSet<Core::IDocument *> visibleCppEditorDocuments;
@@ -800,7 +802,7 @@ void CppModelManager::updateCppEditorDocuments() const
const QString filePath = document->filePath().toString(); const QString filePath = document->filePath().toString();
if (CppEditorDocumentHandle *theCppEditorDocument = cppEditorDocument(filePath)) { if (CppEditorDocumentHandle *theCppEditorDocument = cppEditorDocument(filePath)) {
visibleCppEditorDocuments.insert(document); visibleCppEditorDocuments.insert(document);
theCppEditorDocument->processor()->run(); theCppEditorDocument->processor()->run(hasActiveProjectChanged);
} }
} }
} }
@@ -811,8 +813,12 @@ void CppModelManager::updateCppEditorDocuments() const
invisibleCppEditorDocuments.subtract(visibleCppEditorDocuments); invisibleCppEditorDocuments.subtract(visibleCppEditorDocuments);
foreach (Core::IDocument *document, invisibleCppEditorDocuments) { foreach (Core::IDocument *document, invisibleCppEditorDocuments) {
const QString filePath = document->filePath().toString(); const QString filePath = document->filePath().toString();
if (CppEditorDocumentHandle *theCppEditorDocument = cppEditorDocument(filePath)) if (CppEditorDocumentHandle *theCppEditorDocument = cppEditorDocument(filePath)) {
theCppEditorDocument->setNeedsRefresh(true); const CppEditorDocumentHandle::RefreshReason refreshReason = hasActiveProjectChanged
? CppEditorDocumentHandle::ActiveProjectChange
: CppEditorDocumentHandle::Usual;
theCppEditorDocument->setRefreshReason(refreshReason);
}
} }
} }
@@ -1038,6 +1044,11 @@ void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
delayedGC(); delayedGC();
} }
void CppModelManager::onActiveProjectChanged(ProjectExplorer::Project *)
{
updateCppEditorDocuments(true);
}
void CppModelManager::onSourceFilesRefreshed() const void CppModelManager::onSourceFilesRefreshed() const
{ {
if (BuiltinIndexingSupport::isFindErrorsIndexingActive()) { if (BuiltinIndexingSupport::isFindErrorsIndexingActive()) {
@@ -1053,9 +1064,13 @@ void CppModelManager::onCurrentEditorChanged(Core::IEditor *editor)
const QString filePath = editor->document()->filePath().toString(); const QString filePath = editor->document()->filePath().toString();
if (CppEditorDocumentHandle *theCppEditorDocument = cppEditorDocument(filePath)) { if (CppEditorDocumentHandle *theCppEditorDocument = cppEditorDocument(filePath)) {
if (theCppEditorDocument->needsRefresh()) { const CppEditorDocumentHandle::RefreshReason refreshReason
theCppEditorDocument->setNeedsRefresh(false); = theCppEditorDocument->refreshReason();
theCppEditorDocument->processor()->run(); if (refreshReason != CppEditorDocumentHandle::None) {
theCppEditorDocument->setRefreshReason(CppEditorDocumentHandle::None);
const bool hasActiveProjectChanged
= refreshReason == CppEditorDocumentHandle::ActiveProjectChange;
theCppEditorDocument->processor()->run(hasActiveProjectChanged);
} }
} }
} }

View File

@@ -88,7 +88,7 @@ public:
QFuture<void> updateSourceFiles(const QSet<QString> &sourceFiles, QFuture<void> updateSourceFiles(const QSet<QString> &sourceFiles,
ProgressNotificationMode mode = ReservedProgressNotification); ProgressNotificationMode mode = ReservedProgressNotification);
void updateCppEditorDocuments() const; void updateCppEditorDocuments(bool hasActiveProjectChanged = false) const;
WorkingCopy workingCopy() const; WorkingCopy workingCopy() const;
QByteArray codeModelConfiguration() const; QByteArray codeModelConfiguration() const;
@@ -203,6 +203,7 @@ private:
void renameIncludes(const QString &oldFileName, const QString &newFileName); void renameIncludes(const QString &oldFileName, const QString &newFileName);
void onProjectAdded(ProjectExplorer::Project *project); void onProjectAdded(ProjectExplorer::Project *project);
void onAboutToRemoveProject(ProjectExplorer::Project *project); void onAboutToRemoveProject(ProjectExplorer::Project *project);
void onActiveProjectChanged(ProjectExplorer::Project *project);
void onSourceFilesRefreshed() const; void onSourceFilesRefreshed() const;
void onCurrentEditorChanged(Core::IEditor *editor); void onCurrentEditorChanged(Core::IEditor *editor);
void onCoreAboutToClose(); void onCoreAboutToClose();

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(), nullptr}); parser->update({CppModelManager::instance()->workingCopy(), nullptr, false});
// 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(), nullptr}); parser->update({CppModelManager::instance()->workingCopy(), nullptr, false});
Document::Ptr doc = mm->document(main1File); Document::Ptr doc = mm->document(main1File);
QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName); QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName);

View File

@@ -43,7 +43,8 @@ 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, bool stickToPreviousProjectPart,
const ProjectExplorer::Project *activeProject) const const ProjectExplorer::Project *activeProject,
bool projectHasChanged) const
{ {
QTC_CHECK(m_projectPartsForFile); QTC_CHECK(m_projectPartsForFile);
QTC_CHECK(m_projectPartsFromDependenciesForFile); QTC_CHECK(m_projectPartsFromDependenciesForFile);
@@ -69,8 +70,7 @@ ProjectPart::Ptr ProjectPartChooser::choose(const QString &filePath,
else else
projectPart = selectFromActiveProject(projectParts, activeProject); projectPart = selectFromActiveProject(projectParts, activeProject);
} else { } else {
if (!projectParts.contains(projectPart)) if (projectHasChanged || !projectParts.contains(projectPart))
// Apparently the project file changed, so update our project part.
projectPart = selectFromActiveProject(projectParts, activeProject); projectPart = selectFromActiveProject(projectParts, activeProject);
} }

View File

@@ -51,7 +51,8 @@ public:
const ProjectPart::Ptr &currentProjectPart, const ProjectPart::Ptr &currentProjectPart,
const ProjectPart::Ptr &manuallySetProjectPart, const ProjectPart::Ptr &manuallySetProjectPart,
bool stickToPreviousProjectPart, bool stickToPreviousProjectPart,
const ProjectExplorer::Project *activeProject) const; const ProjectExplorer::Project *activeProject,
bool projectHasChanged) const;
private: private:
FallBackProjectPart m_fallbackProjectPart; FallBackProjectPart m_fallbackProjectPart;

View File

@@ -34,28 +34,23 @@ namespace CppTools {
C++ editor document. C++ editor document.
*/ */
CppEditorDocumentHandle::CppEditorDocumentHandle()
: m_needsRefresh(false)
{
}
CppEditorDocumentHandle::~CppEditorDocumentHandle() CppEditorDocumentHandle::~CppEditorDocumentHandle()
{ {
} }
bool CppEditorDocumentHandle::needsRefresh() const
{
return m_needsRefresh;
}
void CppEditorDocumentHandle::setNeedsRefresh(bool needsRefresh)
{
m_needsRefresh = needsRefresh;
}
SendDocumentTracker &CppEditorDocumentHandle::sendTracker() SendDocumentTracker &CppEditorDocumentHandle::sendTracker()
{ {
return m_sendTracker; return m_sendTracker;
} }
CppEditorDocumentHandle::RefreshReason CppEditorDocumentHandle::refreshReason() const
{
return m_refreshReason;
}
void CppEditorDocumentHandle::setRefreshReason(const RefreshReason &refreshReason)
{
m_refreshReason = refreshReason;
}
} // namespace CppTools } // namespace CppTools

View File

@@ -36,11 +36,15 @@ class BaseEditorDocumentProcessor;
class CPPTOOLS_EXPORT CppEditorDocumentHandle class CPPTOOLS_EXPORT CppEditorDocumentHandle
{ {
public: public:
CppEditorDocumentHandle();
virtual ~CppEditorDocumentHandle(); virtual ~CppEditorDocumentHandle();
bool needsRefresh() const; enum RefreshReason {
void setNeedsRefresh(bool needsRefresh); None,
Usual, // e.g. project configuration change or change of editor contents
ActiveProjectChange
};
RefreshReason refreshReason() const;
void setRefreshReason(const RefreshReason &refreshReason);
// For the Working Copy // For the Working Copy
virtual QString filePath() const = 0; virtual QString filePath() const = 0;
@@ -56,7 +60,7 @@ public:
private: private:
SendDocumentTracker m_sendTracker; SendDocumentTracker m_sendTracker;
bool m_needsRefresh; RefreshReason m_refreshReason = None;
}; };
} // namespace CppTools } // namespace CppTools

View File

@@ -49,6 +49,7 @@ protected:
ProjectPart::Ptr manuallySetProjectPart; ProjectPart::Ptr manuallySetProjectPart;
bool stickToPreviousProjectPart = false; bool stickToPreviousProjectPart = false;
const ProjectExplorer::Project *activeProject = nullptr; const ProjectExplorer::Project *activeProject = nullptr;
bool projectHasChanged = false;
::ProjectPartChooser chooser; ::ProjectPartChooser chooser;
QList<ProjectPart::Ptr> projectPartsForFile; QList<ProjectPart::Ptr> projectPartsForFile;
@@ -100,6 +101,21 @@ TEST_F(ProjectPartChooser, ForMultipleFromDependenciesChooseFromActiveProject)
ASSERT_THAT(chosen, Eq(secondProjectPart)); ASSERT_THAT(chosen, Eq(secondProjectPart));
} }
TEST_F(ProjectPartChooser, ForMultipleCheckIfActiveProjectChanged)
{
const QList<ProjectPart::Ptr> projectParts = createProjectPartsWithDifferentProjects();
const ProjectPart::Ptr firstProjectPart = projectParts.at(0);
const ProjectPart::Ptr secondProjectPart = projectParts.at(1);
projectPartsForFile += projectParts;
currentProjectPart = firstProjectPart;
activeProject = secondProjectPart->project;
projectHasChanged = true;
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;
@@ -167,7 +183,8 @@ const ProjectPart::Ptr ProjectPartChooser::choose() const
currentProjectPart, currentProjectPart,
manuallySetProjectPart, manuallySetProjectPart,
stickToPreviousProjectPart, stickToPreviousProjectPart,
activeProject); activeProject,
projectHasChanged);
} }
QList<ProjectPart::Ptr> ProjectPartChooser::createProjectPartsWithDifferentProjects() QList<ProjectPart::Ptr> ProjectPartChooser::createProjectPartsWithDifferentProjects()