Clang: Don't set a translation unit dirty if the main file is deleted

If a file is deleted the translation unit should be not updated. It will be
later removed anyway.

Task-number: QTCREATORBUG-15070
Change-Id: I40c9c70629dab1d35b713d54442ffdbb2df3db43
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
Marco Bubke
2015-10-12 17:36:18 +02:00
parent d8ba9fa972
commit b8a9e85880
3 changed files with 54 additions and 16 deletions

View File

@@ -213,7 +213,7 @@ const QSet<Utf8String> &TranslationUnit::dependedFilePaths() const
void TranslationUnit::setDirtyIfDependencyIsMet(const Utf8String &filePath) void TranslationUnit::setDirtyIfDependencyIsMet(const Utf8String &filePath)
{ {
if (d->dependedFilePaths.contains(filePath)) { if (d->dependedFilePaths.contains(filePath) && isMainFileAndExistsOrIsOtherFile(filePath)) {
d->needsToBeReparsed = true; d->needsToBeReparsed = true;
d->hasNewDiagnostics = true; d->hasNewDiagnostics = true;
} }
@@ -249,6 +249,14 @@ bool TranslationUnit::projectPartIsOutdated() const
return d->projectPart.lastChangeTimePoint() >= d->lastProjectPartChangeTimePoint; return d->projectPart.lastChangeTimePoint() >= d->lastProjectPartChangeTimePoint;
} }
bool TranslationUnit::isMainFileAndExistsOrIsOtherFile(const Utf8String &filePath) const
{
if (filePath == d->filePath)
return QFileInfo::exists(d->filePath);
return true;
}
void TranslationUnit::createTranslationUnitIfNeeded() const void TranslationUnit::createTranslationUnitIfNeeded() const
{ {
if (!d->translationUnit) { if (!d->translationUnit) {

View File

@@ -111,6 +111,7 @@ private:
void updateLastProjectPartChangeTimePoint() const; void updateLastProjectPartChangeTimePoint() const;
void removeTranslationUnitIfProjectPartWasChanged() const; void removeTranslationUnitIfProjectPartWasChanged() const;
bool projectPartIsOutdated() const; bool projectPartIsOutdated() const;
bool isMainFileAndExistsOrIsOtherFile(const Utf8String &filePath) const;
void createTranslationUnitIfNeeded() const; void createTranslationUnitIfNeeded() const;
void checkTranslationUnitErrorCode(CXErrorCode errorCode) const; void checkTranslationUnitErrorCode(CXErrorCode errorCode) const;
void reparseTranslationUnit() const; void reparseTranslationUnit() const;

View File

@@ -48,6 +48,8 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "gtest-qt-printing.h" #include "gtest-qt-printing.h"
#include <QTemporaryFile>
#include <chrono> #include <chrono>
#include <thread> #include <thread>
@@ -68,12 +70,18 @@ namespace {
class TranslationUnit : public ::testing::Test class TranslationUnit : public ::testing::Test
{ {
protected:
::TranslationUnit createTemporaryTranslationUnit();
QByteArray readContentFromTranslationUnitFile() const;
protected: protected:
ClangBackEnd::ProjectParts projects; ClangBackEnd::ProjectParts projects;
ProjectPart projectPart{Utf8StringLiteral("/path/to/projectfile")};
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{Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp"), ::TranslationUnit translationUnit{translationUnitFilePath,
ProjectPart(Utf8StringLiteral("/path/to/projectfile")), projectPart,
translationUnits}; translationUnits};
}; };
@@ -86,13 +94,13 @@ TEST_F(TranslationUnit, DefaultTranslationUnitIsInvalid)
TEST_F(TranslationUnit, ThrowExceptionForNonExistingFilePath) TEST_F(TranslationUnit, ThrowExceptionForNonExistingFilePath)
{ {
ASSERT_THROW(::TranslationUnit(Utf8StringLiteral("file.cpp"), ProjectPart(Utf8StringLiteral("/path/to/projectfile")), translationUnits), ASSERT_THROW(::TranslationUnit(Utf8StringLiteral("file.cpp"), projectPart, translationUnits),
ClangBackEnd::TranslationUnitFileNotExitsException); ClangBackEnd::TranslationUnitFileNotExitsException);
} }
TEST_F(TranslationUnit, ThrowNoExceptionForNonExistingFilePathIfDoNotCheckIfFileExistsIsSet) TEST_F(TranslationUnit, ThrowNoExceptionForNonExistingFilePathIfDoNotCheckIfFileExistsIsSet)
{ {
ASSERT_NO_THROW(::TranslationUnit(Utf8StringLiteral("file.cpp"), ProjectPart(Utf8StringLiteral("/path/to/projectfile")), translationUnits, ::TranslationUnit::DoNotCheckIfFileExists)); ASSERT_NO_THROW(::TranslationUnit(Utf8StringLiteral("file.cpp"), projectPart, translationUnits, ::TranslationUnit::DoNotCheckIfFileExists));
} }
TEST_F(TranslationUnit, TranslationUnitIsValid) TEST_F(TranslationUnit, TranslationUnitIsValid)
@@ -172,7 +180,7 @@ TEST_F(TranslationUnit, DocumentRevisionInFileContainerGetter)
TEST_F(TranslationUnit, DependedFilePaths) TEST_F(TranslationUnit, DependedFilePaths)
{ {
ASSERT_THAT(translationUnit.dependedFilePaths(), ASSERT_THAT(translationUnit.dependedFilePaths(),
AllOf(Contains(Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp")), AllOf(Contains(translationUnitFilePath),
Contains(Utf8StringLiteral(TESTDATA_DIR"/translationunits.h")))); Contains(Utf8StringLiteral(TESTDATA_DIR"/translationunits.h"))));
} }
@@ -198,7 +206,7 @@ TEST_F(TranslationUnit, NeedsReparsingForMainFile)
{ {
translationUnit.cxTranslationUnit(); translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp")); translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
ASSERT_TRUE(translationUnit.isNeedingReparse()); ASSERT_TRUE(translationUnit.isNeedingReparse());
} }
@@ -235,7 +243,7 @@ TEST_F(TranslationUnit, HasNewDiagnosticsForMainFile)
{ {
translationUnit.cxTranslationUnit(); translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp")); translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
ASSERT_TRUE(translationUnit.hasNewDiagnostics()); ASSERT_TRUE(translationUnit.hasNewDiagnostics());
} }
@@ -243,20 +251,41 @@ TEST_F(TranslationUnit, HasNewDiagnosticsForMainFile)
TEST_F(TranslationUnit, HasNoNewDiagnosticsAfterGettingDiagnostics) TEST_F(TranslationUnit, HasNoNewDiagnosticsAfterGettingDiagnostics)
{ {
translationUnit.cxTranslationUnit(); translationUnit.cxTranslationUnit();
translationUnit.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp")); translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath);
translationUnit.diagnostics(); translationUnit.diagnostics();
ASSERT_FALSE(translationUnit.hasNewDiagnostics()); ASSERT_FALSE(translationUnit.hasNewDiagnostics());
} }
//TEST_F(TranslationUnit, ThrowParseErrorForWrongArguments) TEST_F(TranslationUnit, DeletedFileShouldBeNotSetDirty)
//{ {
// ProjectPart project(Utf8StringLiteral("/path/to/projectfile")); auto translationUnit = createTemporaryTranslationUnit();
// project.setArguments({Utf8StringLiteral("-fblah")});
// TranslationUnit translationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_testfile_1.cpp"), unsavedFiles, project);
// ASSERT_THROW(translationUnit.cxTranslationUnit(), ClangBackEnd::TranslationUnitParseErrorException); translationUnit.setDirtyIfDependencyIsMet(translationUnit.filePath());
//}
ASSERT_FALSE(translationUnit.isNeedingReparse());
}
::TranslationUnit TranslationUnit::createTemporaryTranslationUnit()
{
QTemporaryFile temporaryFile;
EXPECT_TRUE(temporaryFile.open());
EXPECT_TRUE(temporaryFile.write(readContentFromTranslationUnitFile()));
::TranslationUnit translationUnit(temporaryFile.fileName(),
projectPart,
translationUnits);
return translationUnit;
}
QByteArray TranslationUnit::readContentFromTranslationUnitFile() const
{
QFile contentFile(translationUnitFilePath);
EXPECT_TRUE(contentFile.open(QIODevice::ReadOnly));
return contentFile.readAll();
}
} }