forked from qt-creator/qt-creator
Clang: Reparse the translation unit for unsaved file changes
Change-Id: I49711ce040a995f193d36961e010decc27c34c4c Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
committed by
Nikolai Kosjar
parent
efada54950
commit
2443f18b85
@@ -52,7 +52,8 @@ public:
|
|||||||
~TranslationUnitData();
|
~TranslationUnitData();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
time_point lastChangeTimePoint;
|
time_point lastProjectPartChangeTimePoint;
|
||||||
|
time_point lastUnsavedFilesChangeTimePoint;
|
||||||
ProjectPart projectPart;
|
ProjectPart projectPart;
|
||||||
Utf8String filePath;
|
Utf8String filePath;
|
||||||
CXTranslationUnit translationUnit = nullptr;
|
CXTranslationUnit translationUnit = nullptr;
|
||||||
@@ -63,7 +64,8 @@ public:
|
|||||||
TranslationUnitData::TranslationUnitData(const Utf8String &filePath,
|
TranslationUnitData::TranslationUnitData(const Utf8String &filePath,
|
||||||
const UnsavedFiles &unsavedFiles,
|
const UnsavedFiles &unsavedFiles,
|
||||||
const ProjectPart &projectPart)
|
const ProjectPart &projectPart)
|
||||||
: lastChangeTimePoint(std::chrono::steady_clock::now()),
|
: lastProjectPartChangeTimePoint(std::chrono::steady_clock::now()),
|
||||||
|
lastUnsavedFilesChangeTimePoint(lastProjectPartChangeTimePoint),
|
||||||
projectPart(projectPart),
|
projectPart(projectPart),
|
||||||
filePath(filePath),
|
filePath(filePath),
|
||||||
unsavedFiles(unsavedFiles)
|
unsavedFiles(unsavedFiles)
|
||||||
@@ -109,10 +111,9 @@ CXIndex TranslationUnit::index() const
|
|||||||
CXTranslationUnit TranslationUnit::cxTranslationUnit() const
|
CXTranslationUnit TranslationUnit::cxTranslationUnit() const
|
||||||
{
|
{
|
||||||
checkIfNull();
|
checkIfNull();
|
||||||
|
removeTranslationUnitIfProjectPartWasChanged();
|
||||||
removeOutdatedTranslationUnit();
|
|
||||||
|
|
||||||
createTranslationUnitIfNeeded();
|
createTranslationUnitIfNeeded();
|
||||||
|
reparseTranslationUnitIfUnsavedFilesAreChanged();
|
||||||
|
|
||||||
return d->translationUnit;
|
return d->translationUnit;
|
||||||
}
|
}
|
||||||
@@ -131,9 +132,19 @@ const Utf8String &TranslationUnit::projectPartId() const
|
|||||||
return d->projectPart.projectPartId();
|
return d->projectPart.projectPartId();
|
||||||
}
|
}
|
||||||
|
|
||||||
const time_point &TranslationUnit::lastChangeTimePoint() const
|
const time_point &TranslationUnit::lastProjectPartChangeTimePoint() const
|
||||||
{
|
{
|
||||||
return d->lastChangeTimePoint;
|
return d->lastProjectPartChangeTimePoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
const time_point &TranslationUnit::lastUnsavedFilesChangeTimePoint() const
|
||||||
|
{
|
||||||
|
return d->lastUnsavedFilesChangeTimePoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TranslationUnit::isNeedingReparse() const
|
||||||
|
{
|
||||||
|
return d->lastUnsavedFilesChangeTimePoint < d->unsavedFiles.lastChangeTimePoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TranslationUnit::checkIfNull() const
|
void TranslationUnit::checkIfNull() const
|
||||||
@@ -148,19 +159,29 @@ void TranslationUnit::checkIfFileExists() const
|
|||||||
throw TranslationUnitFileNotExitsException(d->filePath);
|
throw TranslationUnitFileNotExitsException(d->filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TranslationUnit::updateLastChangeTimePoint() const
|
void TranslationUnit::updateLastProjectPartChangeTimePoint() const
|
||||||
{
|
{
|
||||||
d->lastChangeTimePoint = std::chrono::steady_clock::now();
|
d->lastProjectPartChangeTimePoint = std::chrono::steady_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TranslationUnit::removeOutdatedTranslationUnit() const
|
void TranslationUnit::updateLastUnsavedFilesChangeTimePoint() const
|
||||||
{
|
{
|
||||||
if (d->projectPart.lastChangeTimePoint() >= d->lastChangeTimePoint) {
|
d->lastUnsavedFilesChangeTimePoint = std::chrono::steady_clock::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TranslationUnit::removeTranslationUnitIfProjectPartWasChanged() const
|
||||||
|
{
|
||||||
|
if (projectPartIsOutdated()) {
|
||||||
clang_disposeTranslationUnit(d->translationUnit);
|
clang_disposeTranslationUnit(d->translationUnit);
|
||||||
d->translationUnit = nullptr;
|
d->translationUnit = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TranslationUnit::projectPartIsOutdated() const
|
||||||
|
{
|
||||||
|
return d->projectPart.lastChangeTimePoint() >= d->lastProjectPartChangeTimePoint;
|
||||||
|
}
|
||||||
|
|
||||||
void TranslationUnit::createTranslationUnitIfNeeded() const
|
void TranslationUnit::createTranslationUnitIfNeeded() const
|
||||||
{
|
{
|
||||||
if (!d->translationUnit) {
|
if (!d->translationUnit) {
|
||||||
@@ -180,7 +201,7 @@ void TranslationUnit::createTranslationUnitIfNeeded() const
|
|||||||
// e.g. clang_codeCompleteAt() dramatically.
|
// e.g. clang_codeCompleteAt() dramatically.
|
||||||
reparseTranslationUnit();
|
reparseTranslationUnit();
|
||||||
|
|
||||||
updateLastChangeTimePoint();
|
updateLastProjectPartChangeTimePoint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,6 +219,14 @@ void TranslationUnit::reparseTranslationUnit() const
|
|||||||
d->unsavedFiles.count(),
|
d->unsavedFiles.count(),
|
||||||
d->unsavedFiles.cxUnsavedFiles(),
|
d->unsavedFiles.cxUnsavedFiles(),
|
||||||
clang_defaultReparseOptions(d->translationUnit));
|
clang_defaultReparseOptions(d->translationUnit));
|
||||||
|
|
||||||
|
updateLastUnsavedFilesChangeTimePoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TranslationUnit::reparseTranslationUnitIfUnsavedFilesAreChanged() const
|
||||||
|
{
|
||||||
|
if (isNeedingReparse())
|
||||||
|
reparseTranslationUnit();
|
||||||
}
|
}
|
||||||
|
|
||||||
int TranslationUnit::defaultOptions()
|
int TranslationUnit::defaultOptions()
|
||||||
|
|||||||
@@ -82,16 +82,23 @@ public:
|
|||||||
const Utf8String &filePath() const;
|
const Utf8String &filePath() const;
|
||||||
const Utf8String &projectPartId() const;
|
const Utf8String &projectPartId() const;
|
||||||
|
|
||||||
const time_point &lastChangeTimePoint() const;
|
const time_point &lastProjectPartChangeTimePoint() const;
|
||||||
|
const time_point &lastUnsavedFilesChangeTimePoint() const;
|
||||||
|
|
||||||
|
bool isNeedingReparse() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void checkIfNull() const;
|
void checkIfNull() const;
|
||||||
void checkIfFileExists() const;
|
void checkIfFileExists() const;
|
||||||
void updateLastChangeTimePoint() const;
|
void updateLastProjectPartChangeTimePoint() const;
|
||||||
void removeOutdatedTranslationUnit() const;
|
void updateLastUnsavedFilesChangeTimePoint() const;
|
||||||
|
void removeTranslationUnitIfProjectPartWasChanged() const;
|
||||||
|
bool projectPartIsOutdated() const;
|
||||||
void createTranslationUnitIfNeeded() const;
|
void createTranslationUnitIfNeeded() const;
|
||||||
void checkTranslationUnitErrorCode(CXErrorCode errorCode) const;
|
void checkTranslationUnitErrorCode(CXErrorCode errorCode) const;
|
||||||
void reparseTranslationUnit() const;
|
void reparseTranslationUnit() const;
|
||||||
|
void reparseTranslationUnitIfUnsavedFilesAreChanged() const;
|
||||||
|
void printIncludes() const;
|
||||||
static int defaultOptions();
|
static int defaultOptions();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -132,15 +132,75 @@ TEST(TranslationUnit, ResetedTranslationUnitIsNull)
|
|||||||
ASSERT_TRUE(translationUnit.isNull());
|
ASSERT_TRUE(translationUnit.isNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TranslationUnit, TimeStampIsUpdatedAsNewCxTranslationUnitIsGenerated)
|
TEST(TranslationUnit, TimeStampForProjectPartChangeIsUpdatedAsNewCxTranslationUnitIsGenerated)
|
||||||
{
|
{
|
||||||
TranslationUnit translationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_testfile_1.cpp"), UnsavedFiles(), ProjectPart(Utf8StringLiteral("/path/to/projectfile")));
|
TranslationUnit translationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_testfile_1.cpp"), UnsavedFiles(), ProjectPart(Utf8StringLiteral("/path/to/projectfile")));
|
||||||
auto lastChangeTimePoint = translationUnit.lastChangeTimePoint();
|
auto lastChangeTimePoint = translationUnit.lastProjectPartChangeTimePoint();
|
||||||
std::this_thread::sleep_for(std::chrono::steady_clock::duration(1));
|
std::this_thread::sleep_for(std::chrono::steady_clock::duration(1));
|
||||||
|
|
||||||
translationUnit.cxTranslationUnit();
|
translationUnit.cxTranslationUnit();
|
||||||
|
|
||||||
ASSERT_THAT(translationUnit.lastChangeTimePoint(), Gt(lastChangeTimePoint));
|
ASSERT_THAT(translationUnit.lastProjectPartChangeTimePoint(), Gt(lastChangeTimePoint));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranslationUnit, TimeStampForProjectPartChangeIsUpdatedAsProjectPartIsCleared)
|
||||||
|
{
|
||||||
|
ProjectPart projectPart(Utf8StringLiteral("/path/to/projectfile"));
|
||||||
|
TranslationUnit translationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_testfile_1.cpp"), UnsavedFiles(), projectPart);
|
||||||
|
translationUnit.cxTranslationUnit();
|
||||||
|
auto lastChangeTimePoint = translationUnit.lastProjectPartChangeTimePoint();
|
||||||
|
std::this_thread::sleep_for(std::chrono::steady_clock::duration(1));
|
||||||
|
|
||||||
|
projectPart.clear();
|
||||||
|
translationUnit.cxTranslationUnit();
|
||||||
|
|
||||||
|
ASSERT_THAT(translationUnit.lastProjectPartChangeTimePoint(), Gt(lastChangeTimePoint));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranslationUnit, ReparseIsNeededAfterUnsavedFilesAreChanged)
|
||||||
|
{
|
||||||
|
UnsavedFiles unsavedFiles;
|
||||||
|
TranslationUnit translationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_testfile_1.cpp"),
|
||||||
|
unsavedFiles,
|
||||||
|
ProjectPart(Utf8StringLiteral("/path/to/projectfile")));
|
||||||
|
translationUnit.cxTranslationUnit();
|
||||||
|
unsavedFiles.clear();
|
||||||
|
translationUnit.cxTranslationUnit();
|
||||||
|
|
||||||
|
unsavedFiles.clear();
|
||||||
|
|
||||||
|
ASSERT_TRUE(translationUnit.isNeedingReparse());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranslationUnit, NeedsNoReparseAfterUnsavedFilesAreNotChanged)
|
||||||
|
{
|
||||||
|
UnsavedFiles unsavedFiles;
|
||||||
|
TranslationUnit translationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_testfile_1.cpp"),
|
||||||
|
unsavedFiles,
|
||||||
|
ProjectPart(Utf8StringLiteral("/path/to/projectfile")));
|
||||||
|
translationUnit.cxTranslationUnit();
|
||||||
|
unsavedFiles.clear();
|
||||||
|
translationUnit.cxTranslationUnit();
|
||||||
|
|
||||||
|
ASSERT_FALSE(translationUnit.isNeedingReparse());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TranslationUnit, TimeStampForUnsavedFilesChange)
|
||||||
|
{
|
||||||
|
UnsavedFiles unsavedFiles;
|
||||||
|
TranslationUnit translationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_testfile_1.cpp"),
|
||||||
|
unsavedFiles,
|
||||||
|
ProjectPart(Utf8StringLiteral("/path/to/projectfile")));
|
||||||
|
translationUnit.cxTranslationUnit();
|
||||||
|
unsavedFiles.clear();
|
||||||
|
translationUnit.cxTranslationUnit();
|
||||||
|
auto lastChangeTimePoint = translationUnit.lastUnsavedFilesChangeTimePoint();
|
||||||
|
std::this_thread::sleep_for(std::chrono::steady_clock::duration(1));
|
||||||
|
|
||||||
|
unsavedFiles.clear();
|
||||||
|
translationUnit.cxTranslationUnit();
|
||||||
|
|
||||||
|
ASSERT_THAT(translationUnit.lastUnsavedFilesChangeTimePoint(), Gt(lastChangeTimePoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user