forked from qt-creator/qt-creator
Clang: Unregister file with project immediately on project close
Ensure that first the editors unregister with the removed project part,
then unregister the project part.
This makes testing and following the message logs easier.
It also fixes the following race condition:
* Unload project of opened file
* Immediately close the editor before a new project part is calculated
==> The editor is closed, but the translation unit is not properly
unregistered.
Change-Id: I618930d221323435ba60ac6c051380bccc9fdaf1
Reviewed-by: Marco Bubke <marco.bubke@theqtcompany.com>
This commit is contained in:
@@ -94,9 +94,6 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
|
|||||||
connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::semanticInfoUpdated,
|
connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::semanticInfoUpdated,
|
||||||
this, &ClangEditorDocumentProcessor::semanticInfoUpdated);
|
this, &ClangEditorDocumentProcessor::semanticInfoUpdated);
|
||||||
|
|
||||||
connect(CppTools::CppModelManager::instance(), &CppTools::CppModelManager::projectPartsRemoved,
|
|
||||||
this, &ClangEditorDocumentProcessor::onProjectPartsRemoved);
|
|
||||||
|
|
||||||
m_semanticHighlighter.setHighlightingRunner(
|
m_semanticHighlighter.setHighlightingRunner(
|
||||||
[this]() -> QFuture<TextEditor::HighlightingResult> {
|
[this]() -> QFuture<TextEditor::HighlightingResult> {
|
||||||
const int firstLine = 1;
|
const int firstLine = 1;
|
||||||
@@ -184,6 +181,11 @@ CppTools::ProjectPart::Ptr ClangEditorDocumentProcessor::projectPart() const
|
|||||||
return m_projectPart;
|
return m_projectPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClangEditorDocumentProcessor::clearProjectPart()
|
||||||
|
{
|
||||||
|
m_projectPart.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
void ClangEditorDocumentProcessor::updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||||
uint documentRevision)
|
uint documentRevision)
|
||||||
{
|
{
|
||||||
@@ -250,12 +252,6 @@ void ClangEditorDocumentProcessor::onParserFinished()
|
|||||||
updateProjectPartAndTranslationUnitForEditor();
|
updateProjectPartAndTranslationUnitForEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::onProjectPartsRemoved(const QStringList &projectPartIds)
|
|
||||||
{
|
|
||||||
if (m_projectPart && projectPartIds.contains(m_projectPart->id()))
|
|
||||||
m_projectPart.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::updateTranslationUnitForEditor(CppTools::ProjectPart &projectPart)
|
void ClangEditorDocumentProcessor::updateTranslationUnitForEditor(CppTools::ProjectPart &projectPart)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_modelManagerSupport, return);
|
QTC_ASSERT(m_modelManagerSupport, return);
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ public:
|
|||||||
|
|
||||||
bool hasProjectPart() const;
|
bool hasProjectPart() const;
|
||||||
CppTools::ProjectPart::Ptr projectPart() const;
|
CppTools::ProjectPart::Ptr projectPart() const;
|
||||||
|
void clearProjectPart();
|
||||||
|
|
||||||
void updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
void updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
|
||||||
uint documentRevision);
|
uint documentRevision);
|
||||||
@@ -82,7 +83,6 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onParserFinished();
|
void onParserFinished();
|
||||||
void onProjectPartsRemoved(const QStringList &projectPartIds);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateProjectPartAndTranslationUnitForEditor();
|
void updateProjectPartAndTranslationUnitForEditor();
|
||||||
|
|||||||
@@ -271,8 +271,49 @@ void ModelManagerSupportClang::onProjectPartsUpdated(ProjectExplorer::Project *p
|
|||||||
|
|
||||||
void ModelManagerSupportClang::onProjectPartsRemoved(const QStringList &projectPartIds)
|
void ModelManagerSupportClang::onProjectPartsRemoved(const QStringList &projectPartIds)
|
||||||
{
|
{
|
||||||
if (!projectPartIds.isEmpty())
|
if (!projectPartIds.isEmpty()) {
|
||||||
|
unregisterTranslationUnitsWithProjectParts(projectPartIds);
|
||||||
m_ipcCommunicator.unregisterProjectPartsForEditor(projectPartIds);
|
m_ipcCommunicator.unregisterProjectPartsForEditor(projectPartIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QVector<ClangEditorDocumentProcessor *>
|
||||||
|
clangProcessorsWithProjectParts(const QStringList &projectPartIds)
|
||||||
|
{
|
||||||
|
QVector<ClangEditorDocumentProcessor *> result;
|
||||||
|
|
||||||
|
foreach (auto *editorDocument, cppModelManager()->cppEditorDocuments()) {
|
||||||
|
auto *processor = editorDocument->processor();
|
||||||
|
auto *clangProcessor = qobject_cast<ClangEditorDocumentProcessor *>(processor);
|
||||||
|
if (clangProcessor && clangProcessor->hasProjectPart()) {
|
||||||
|
if (projectPartIds.contains(clangProcessor->projectPart()->id()))
|
||||||
|
result.append(clangProcessor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QVector<ClangBackEnd::FileContainer>
|
||||||
|
processorToFileContainer(ClangEditorDocumentProcessor *processor)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(processor, return QVector<ClangBackEnd::FileContainer>());
|
||||||
|
|
||||||
|
const QString filePath = processor->baseTextDocument()->filePath().toString();
|
||||||
|
const QString projectPartId = processor->projectPart()->id();
|
||||||
|
|
||||||
|
return {ClangBackEnd::FileContainer(filePath, projectPartId)};
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelManagerSupportClang::unregisterTranslationUnitsWithProjectParts(
|
||||||
|
const QStringList &projectPartIds)
|
||||||
|
{
|
||||||
|
const auto processors = clangProcessorsWithProjectParts(projectPartIds);
|
||||||
|
foreach (ClangEditorDocumentProcessor *processor, processors) {
|
||||||
|
m_ipcCommunicator.unregisterTranslationUnitsForEditor(processorToFileContainer(processor));
|
||||||
|
processor->clearProjectPart();
|
||||||
|
processor->run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef QT_TESTLIB_LIB
|
#ifdef QT_TESTLIB_LIB
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ private:
|
|||||||
void onProjectPartsUpdated(ProjectExplorer::Project *project);
|
void onProjectPartsUpdated(ProjectExplorer::Project *project);
|
||||||
void onProjectPartsRemoved(const QStringList &projectPartIds);
|
void onProjectPartsRemoved(const QStringList &projectPartIds);
|
||||||
|
|
||||||
|
void unregisterTranslationUnitsWithProjectParts(const QStringList &projectPartIds);
|
||||||
|
|
||||||
void connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument);
|
void connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument);
|
||||||
void connectTextDocumentToUnsavedFiles(TextEditor::TextDocument *textDocument);
|
void connectTextDocumentToUnsavedFiles(TextEditor::TextDocument *textDocument);
|
||||||
void connectToWidgetsMarkContextMenuRequested(QWidget *editorWidget);
|
void connectToWidgetsMarkContextMenuRequested(QWidget *editorWidget);
|
||||||
|
|||||||
@@ -1010,6 +1010,7 @@ void ClangCodeCompletionTest::testChangingProjectDependentCompletion()
|
|||||||
} // Project closed
|
} // Project closed
|
||||||
|
|
||||||
// Check again completion without project
|
// Check again completion without project
|
||||||
|
openEditor.waitUntilProjectPartChanged(QLatin1String(""));
|
||||||
proposal = completionResults(openEditor.editor());
|
proposal = completionResults(openEditor.editor());
|
||||||
QVERIFY(hasItem(proposal, "noProjectConfigurationDetected"));
|
QVERIFY(hasItem(proposal, "noProjectConfigurationDetected"));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user