forked from qt-creator/qt-creator
Clang: Reparse editor document on project change
Change-Id: If7dcdc370fd50fded996df80ab6c893b4ec1ad55 Reviewed-by: Marco Bubke <marco.bubke@theqtcompany.com>
This commit is contained in:
@@ -193,6 +193,8 @@ void ClangIpcServer::registerProjectPartsForEditor(const RegisterProjectPartsFor
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
projects.createOrUpdate(message.projectContainers());
|
projects.createOrUpdate(message.projectContainers());
|
||||||
|
translationUnits.setTranslationUnitsDirtyIfProjectPartChanged();
|
||||||
|
sendDocumentAnnotationsTimer.start(0);
|
||||||
} catch (const std::exception &exception) {
|
} catch (const std::exception &exception) {
|
||||||
qWarning() << "Error in ClangIpcServer::registerProjectPartsForEditor:" << exception.what();
|
qWarning() << "Error in ClangIpcServer::registerProjectPartsForEditor:" << exception.what();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -276,13 +276,16 @@ const QSet<Utf8String> &TranslationUnit::dependedFilePaths() const
|
|||||||
return d->dependedFilePaths;
|
return d->dependedFilePaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TranslationUnit::setDirtyIfProjectPartIsOutdated()
|
||||||
|
{
|
||||||
|
if (projectPartIsOutdated())
|
||||||
|
setDirty();
|
||||||
|
}
|
||||||
|
|
||||||
void TranslationUnit::setDirtyIfDependencyIsMet(const Utf8String &filePath)
|
void TranslationUnit::setDirtyIfDependencyIsMet(const Utf8String &filePath)
|
||||||
{
|
{
|
||||||
if (d->dependedFilePaths.contains(filePath) && isMainFileAndExistsOrIsOtherFile(filePath)) {
|
if (d->dependedFilePaths.contains(filePath) && isMainFileAndExistsOrIsOtherFile(filePath))
|
||||||
d->needsToBeReparsed = true;
|
setDirty();
|
||||||
d->hasNewDiagnostics = true;
|
|
||||||
d->hasNewHighlightingInformations = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceLocation TranslationUnit::sourceLocationAt(uint line, uint column) const
|
SourceLocation TranslationUnit::sourceLocationAt(uint line, uint column) const
|
||||||
@@ -369,6 +372,13 @@ bool TranslationUnit::projectPartIsOutdated() const
|
|||||||
return d->projectPart.lastChangeTimePoint() >= d->lastProjectPartChangeTimePoint;
|
return d->projectPart.lastChangeTimePoint() >= d->lastProjectPartChangeTimePoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TranslationUnit::setDirty()
|
||||||
|
{
|
||||||
|
d->needsToBeReparsed = true;
|
||||||
|
d->hasNewDiagnostics = true;
|
||||||
|
d->hasNewHighlightingInformations = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool TranslationUnit::isMainFileAndExistsOrIsOtherFile(const Utf8String &filePath) const
|
bool TranslationUnit::isMainFileAndExistsOrIsOtherFile(const Utf8String &filePath) const
|
||||||
{
|
{
|
||||||
if (filePath == d->filePath)
|
if (filePath == d->filePath)
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ public:
|
|||||||
|
|
||||||
const QSet<Utf8String> &dependedFilePaths() const;
|
const QSet<Utf8String> &dependedFilePaths() const;
|
||||||
|
|
||||||
|
void setDirtyIfProjectPartIsOutdated();
|
||||||
void setDirtyIfDependencyIsMet(const Utf8String &filePath);
|
void setDirtyIfDependencyIsMet(const Utf8String &filePath);
|
||||||
|
|
||||||
CommandLineArguments commandLineArguments() const;
|
CommandLineArguments commandLineArguments() const;
|
||||||
@@ -139,6 +140,7 @@ public:
|
|||||||
SkippedSourceRanges skippedSourceRanges() const;
|
SkippedSourceRanges skippedSourceRanges() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void setDirty();
|
||||||
void checkIfNull() const;
|
void checkIfNull() const;
|
||||||
void checkIfFileExists() const;
|
void checkIfFileExists() const;
|
||||||
void updateLastProjectPartChangeTimePoint() const;
|
void updateLastProjectPartChangeTimePoint() const;
|
||||||
|
|||||||
@@ -31,11 +31,12 @@
|
|||||||
#ifndef CLANGBACKEND_PROJECT_H
|
#ifndef CLANGBACKEND_PROJECT_H
|
||||||
#define CLANGBACKEND_PROJECT_H
|
#define CLANGBACKEND_PROJECT_H
|
||||||
|
|
||||||
|
#include <utf8string.h>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class Utf8String;
|
|
||||||
class Utf8StringVector;
|
class Utf8StringVector;
|
||||||
|
|
||||||
namespace ClangBackEnd {
|
namespace ClangBackEnd {
|
||||||
@@ -48,7 +49,7 @@ using time_point = std::chrono::steady_clock::time_point;
|
|||||||
class ProjectPart
|
class ProjectPart
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ProjectPart(const Utf8String &projectPartId);
|
ProjectPart(const Utf8String &projectPartId = Utf8String());
|
||||||
ProjectPart(const Utf8String &projectPartId,
|
ProjectPart(const Utf8String &projectPartId,
|
||||||
std::initializer_list<Utf8String> arguments);
|
std::initializer_list<Utf8String> arguments);
|
||||||
ProjectPart(const ProjectPartContainer &projectContainer);
|
ProjectPart(const ProjectPartContainer &projectContainer);
|
||||||
|
|||||||
@@ -170,6 +170,12 @@ void TranslationUnits::updateTranslationUnitsWithChangedDependencies(const QVect
|
|||||||
updateTranslationUnitsWithChangedDependency(fileContainer.filePath());
|
updateTranslationUnitsWithChangedDependency(fileContainer.filePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TranslationUnits::setTranslationUnitsDirtyIfProjectPartChanged()
|
||||||
|
{
|
||||||
|
for (auto &translationUnit : translationUnits_)
|
||||||
|
translationUnit.setDirtyIfProjectPartIsOutdated();
|
||||||
|
}
|
||||||
|
|
||||||
DocumentAnnotationsSendState TranslationUnits::sendDocumentAnnotations()
|
DocumentAnnotationsSendState TranslationUnits::sendDocumentAnnotations()
|
||||||
{
|
{
|
||||||
auto documentAnnotationsSendState = sendDocumentAnnotationsForCurrentEditor();
|
auto documentAnnotationsSendState = sendDocumentAnnotationsForCurrentEditor();
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ public:
|
|||||||
|
|
||||||
void updateTranslationUnitsWithChangedDependency(const Utf8String &filePath);
|
void updateTranslationUnitsWithChangedDependency(const Utf8String &filePath);
|
||||||
void updateTranslationUnitsWithChangedDependencies(const QVector<FileContainer> &fileContainers);
|
void updateTranslationUnitsWithChangedDependencies(const QVector<FileContainer> &fileContainers);
|
||||||
|
void setTranslationUnitsDirtyIfProjectPartChanged();
|
||||||
|
|
||||||
DocumentAnnotationsSendState sendDocumentAnnotationsForCurrentEditor();
|
DocumentAnnotationsSendState sendDocumentAnnotationsForCurrentEditor();
|
||||||
DocumentAnnotationsSendState sendDocumentAnnotationsForVisibleEditors();
|
DocumentAnnotationsSendState sendDocumentAnnotationsForVisibleEditors();
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
using ClangBackEnd::TranslationUnit;
|
using ClangBackEnd::TranslationUnit;
|
||||||
using ClangBackEnd::UnsavedFiles;
|
using ClangBackEnd::UnsavedFiles;
|
||||||
using ClangBackEnd::ProjectPart;
|
using ClangBackEnd::ProjectPart;
|
||||||
|
using ClangBackEnd::ProjectPartContainer;
|
||||||
using ClangBackEnd::DiagnosticsChangedMessage;
|
using ClangBackEnd::DiagnosticsChangedMessage;
|
||||||
using ClangBackEnd::HighlightingChangedMessage;
|
using ClangBackEnd::HighlightingChangedMessage;
|
||||||
using ClangBackEnd::DocumentAnnotationsSendState;
|
using ClangBackEnd::DocumentAnnotationsSendState;
|
||||||
@@ -483,9 +484,24 @@ TEST_F(TranslationUnits, SendDocumentAnnotationsOnlyOnceForVisibleEditor)
|
|||||||
sendAllDocumentAnnotationsForVisibleEditors();
|
sendAllDocumentAnnotationsForVisibleEditors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(TranslationUnits, SendDocumentAnnotationsAfterProjectPartChange)
|
||||||
|
{
|
||||||
|
translationUnits.create({fileContainer, headerContainer});
|
||||||
|
auto fileTranslationUnit = translationUnits.translationUnit(fileContainer);
|
||||||
|
fileTranslationUnit.setIsVisibleInEditor(true);
|
||||||
|
fileTranslationUnit.diagnostics(); // Reset
|
||||||
|
fileTranslationUnit.highlightingInformations(); // Reset
|
||||||
|
projects.createOrUpdate({ProjectPartContainer(projectPartId, {Utf8StringLiteral("-DNEW")})});
|
||||||
|
translationUnits.setTranslationUnitsDirtyIfProjectPartChanged();
|
||||||
|
|
||||||
|
EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(1);
|
||||||
|
|
||||||
|
sendAllDocumentAnnotationsForVisibleEditors();
|
||||||
|
}
|
||||||
|
|
||||||
void TranslationUnits::SetUp()
|
void TranslationUnits::SetUp()
|
||||||
{
|
{
|
||||||
projects.createOrUpdate({ClangBackEnd::ProjectPartContainer(projectPartId)});
|
projects.createOrUpdate({ProjectPartContainer(projectPartId)});
|
||||||
|
|
||||||
auto callback = [&] (const DiagnosticsChangedMessage &, const HighlightingChangedMessage &) {
|
auto callback = [&] (const DiagnosticsChangedMessage &, const HighlightingChangedMessage &) {
|
||||||
mockSendDocumentAnnotationsCallback.sendDocumentAnnotations();
|
mockSendDocumentAnnotationsCallback.sendDocumentAnnotations();
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <highlightinginformations.h>
|
#include <highlightinginformations.h>
|
||||||
#include <filecontainer.h>
|
#include <filecontainer.h>
|
||||||
#include <projectpart.h>
|
#include <projectpart.h>
|
||||||
|
#include <projectpartcontainer.h>
|
||||||
#include <projects.h>
|
#include <projects.h>
|
||||||
#include <translationunitdoesnotexistexception.h>
|
#include <translationunitdoesnotexistexception.h>
|
||||||
#include <translationunitfilenotexitexception.h>
|
#include <translationunitfilenotexitexception.h>
|
||||||
@@ -55,10 +56,11 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
using ClangBackEnd::FileContainer;
|
||||||
using ClangBackEnd::TranslationUnit;
|
using ClangBackEnd::TranslationUnit;
|
||||||
using ClangBackEnd::UnsavedFiles;
|
using ClangBackEnd::UnsavedFiles;
|
||||||
using ClangBackEnd::ProjectPart;
|
using ClangBackEnd::ProjectPart;
|
||||||
|
using ClangBackEnd::ProjectPartContainer;
|
||||||
using ClangBackEnd::TranslationUnits;
|
using ClangBackEnd::TranslationUnits;
|
||||||
|
|
||||||
using testing::IsNull;
|
using testing::IsNull;
|
||||||
@@ -74,19 +76,18 @@ namespace {
|
|||||||
class TranslationUnit : public ::testing::Test
|
class TranslationUnit : public ::testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
void SetUp() override;
|
||||||
::TranslationUnit createTemporaryTranslationUnit();
|
::TranslationUnit createTemporaryTranslationUnit();
|
||||||
QByteArray readContentFromTranslationUnitFile() const;
|
QByteArray readContentFromTranslationUnitFile() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ClangBackEnd::ProjectParts projects;
|
ClangBackEnd::ProjectParts projects;
|
||||||
ProjectPart projectPart{Utf8StringLiteral("/path/to/projectfile")};
|
Utf8String projectPartId{Utf8StringLiteral("/path/to/projectfile")};
|
||||||
|
ProjectPart projectPart;
|
||||||
Utf8String translationUnitFilePath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp");
|
Utf8String translationUnitFilePath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp");
|
||||||
ClangBackEnd::UnsavedFiles unsavedFiles;
|
ClangBackEnd::UnsavedFiles unsavedFiles;
|
||||||
ClangBackEnd::TranslationUnits translationUnits{projects, unsavedFiles};
|
ClangBackEnd::TranslationUnits translationUnits{projects, unsavedFiles};
|
||||||
::TranslationUnit translationUnit{translationUnitFilePath,
|
::TranslationUnit translationUnit;
|
||||||
projectPart,
|
|
||||||
Utf8StringVector(),
|
|
||||||
translationUnits};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(TranslationUnit, DefaultTranslationUnitIsInvalid)
|
TEST_F(TranslationUnit, DefaultTranslationUnitIsInvalid)
|
||||||
@@ -338,6 +339,36 @@ TEST_F(TranslationUnit, HasNoNewHighlightingInformationsAfterGettingHighlighting
|
|||||||
ASSERT_FALSE(translationUnit.hasNewHighlightingInformations());
|
ASSERT_FALSE(translationUnit.hasNewHighlightingInformations());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(TranslationUnit, SetDirtyIfProjectPartIsOutdated)
|
||||||
|
{
|
||||||
|
projects.createOrUpdate({ProjectPartContainer(projectPartId)});
|
||||||
|
translationUnit.cxTranslationUnit();
|
||||||
|
projects.createOrUpdate({ProjectPartContainer(projectPartId, {Utf8StringLiteral("-DNEW")})});
|
||||||
|
|
||||||
|
translationUnit.setDirtyIfProjectPartIsOutdated();
|
||||||
|
|
||||||
|
ASSERT_TRUE(translationUnit.isNeedingReparse());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TranslationUnit, SetNotDirtyIfProjectPartIsNotOutdated)
|
||||||
|
{
|
||||||
|
translationUnit.cxTranslationUnit();
|
||||||
|
|
||||||
|
translationUnit.setDirtyIfProjectPartIsOutdated();
|
||||||
|
|
||||||
|
ASSERT_FALSE(translationUnit.isNeedingReparse());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TranslationUnit::SetUp()
|
||||||
|
{
|
||||||
|
projects.createOrUpdate({ProjectPartContainer(projectPartId)});
|
||||||
|
projectPart = *projects.findProjectPart(projectPartId);
|
||||||
|
|
||||||
|
const QVector<FileContainer> fileContainer{FileContainer(translationUnitFilePath, projectPartId)};
|
||||||
|
const auto createdTranslationUnits = translationUnits.create(fileContainer);
|
||||||
|
translationUnit = createdTranslationUnits.front();
|
||||||
|
}
|
||||||
|
|
||||||
::TranslationUnit TranslationUnit::createTemporaryTranslationUnit()
|
::TranslationUnit TranslationUnit::createTemporaryTranslationUnit()
|
||||||
{
|
{
|
||||||
QTemporaryFile temporaryFile;
|
QTemporaryFile temporaryFile;
|
||||||
@@ -348,7 +379,7 @@ TEST_F(TranslationUnit, HasNoNewHighlightingInformationsAfterGettingHighlighting
|
|||||||
Utf8StringVector(),
|
Utf8StringVector(),
|
||||||
translationUnits);
|
translationUnits);
|
||||||
|
|
||||||
return translationUnit;
|
return translationUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray TranslationUnit::readContentFromTranslationUnitFile() const
|
QByteArray TranslationUnit::readContentFromTranslationUnitFile() const
|
||||||
|
|||||||
Reference in New Issue
Block a user