Clang: Ensure that an unparsed translation unit is not suspended

Currently this might happen when registerTranslationUnitsForEditor is
called with visible documents that are not the ones that are registered.

Change-Id: I9ae5f75c8bbff6a11161a3387633726066001062
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
Nikolai Kosjar
2017-08-22 14:51:34 +02:00
parent eb74f5b71e
commit 024cfda06c
4 changed files with 35 additions and 1 deletions

View File

@@ -150,6 +150,11 @@ bool Document::isIntact() const
&& !d->hasParseOrReparseFailed;
}
bool Document::isParsed() const
{
return d->translationUnits.areAllTranslationUnitsParsed();
}
Utf8String Document::filePath() const
{
checkIfNull();

View File

@@ -77,6 +77,7 @@ public:
bool isNull() const;
bool isIntact() const;
bool isParsed() const;
Utf8String filePath() const;
Utf8StringVector fileArguments() const;

View File

@@ -97,7 +97,8 @@ static bool isSuspendable(const Document &document)
{
return isFineDocument(document)
&& !document.isSuspended()
&& !document.isVisibleInEditor();
&& !document.isVisibleInEditor()
&& document.isParsed();
}
static bool isResumable(const Document &document)

View File

@@ -73,6 +73,7 @@ protected:
Document getDocument(const Utf8String &filePath);
void categorizeDocuments(int hotDocumentsSize);
SuspendResumeJobs createSuspendResumeJobs(int hotDocumentsSize = -1);
static void setParsed(Document &document);
protected:
ClangBackEnd::ProjectParts projects;
@@ -176,6 +177,8 @@ TEST_F(DocumentSuspenderResumer, CreateSuspendJobForInvisible)
Document document = documents.create({fileContainer1})[0];
document.setIsSuspended(false);
document.setIsVisibleInEditor(false, Clock::now());
setParsed(document);
const SuspendResumeJobs expectedJobs = {
{document, JobRequest::Type::SuspendDocument, PreferredTranslationUnit::RecentlyParsed}
};
@@ -196,12 +199,24 @@ TEST_F(DocumentSuspenderResumer, DoNotCreateSuspendJobForVisible)
ASSERT_THAT(jobs, ContainerEq(SuspendResumeJobs()));
}
TEST_F(DocumentSuspenderResumer, DoNotCreateSuspendJobForUnparsed)
{
Document document = documents.create({fileContainer1})[0];
document.setIsSuspended(false);
document.setIsVisibleInEditor(true, Clock::now());
const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 0);
ASSERT_THAT(jobs, ContainerEq(SuspendResumeJobs()));
}
TEST_F(DocumentSuspenderResumer, CreateSuspendJobsForDocumentWithSupportiveTranslationUnit)
{
Document document = documents.create({fileContainer1})[0];
document.setIsSuspended(false);
document.setIsVisibleInEditor(false, Clock::now());
document.translationUnits().createAndAppend(); // Add supportive translation unit
setParsed(document);
const SuspendResumeJobs expectedJobs = {
{document, JobRequest::Type::SuspendDocument, PreferredTranslationUnit::RecentlyParsed},
{document, JobRequest::Type::SuspendDocument, PreferredTranslationUnit::PreviouslyParsed},
@@ -258,6 +273,7 @@ TEST_F(DocumentSuspenderResumer, CreateSuspendAndResumeJobs)
Document hotDocument = documents.create({fileContainer1})[0];
hotDocument.setIsSuspended(true);
Document coldDocument = documents.create({fileContainer2})[0];
setParsed(coldDocument);
coldDocument.setIsSuspended(false);
documents.setVisibleInEditors({filePath1});
const SuspendResumeJobs expectedJobs = {
@@ -292,4 +308,15 @@ DocumentSuspenderResumer::createSuspendResumeJobs(int hotDocumentsSize)
return ClangBackEnd::createSuspendResumeJobs(documents.documents(), hotDocumentsSize);
}
void DocumentSuspenderResumer::setParsed(ClangBackEnd::Document &document)
{
const Utf8String first = document.translationUnit().id();
document.translationUnits().updateParseTimePoint(first, Clock::now());
const Utf8String second
= document.translationUnit(PreferredTranslationUnit::LastUninitialized).id();
if (second != first)
document.translationUnits().updateParseTimePoint(second, Clock::now());
}
} // anonymous