Clang: Fix initial document parse with modified content

Reproduce with:

  1. Create a new class named Foo with the wizard.
  2. Close foo.h
  3. In foo.cpp, add some class member function.
  4. In foo.cpp, trigger the refactoring action "Add public Declaration"
     for the just defined member function. As a result, foo.h will be
     opened.
     ==> While the declaration was added, the header file is not yet
         reparsed with the new content - this can be verified by setting
         a custom color for "Function".

In this use case, the refactoring action opens the editor and
immediately modifies the document (RefactoringFile::apply).

Fix by sending the document content along for the very first
RegisterTranslationUnitForEditorMessage if the document was already
modified.

Change-Id: If20615a45b72dd0bef87e1870e403d0b277bc5d6
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Nikolai Kosjar
2016-11-22 15:17:42 +01:00
parent e9f0f37070
commit 6cf1f7968f
7 changed files with 64 additions and 19 deletions

View File

@@ -51,6 +51,21 @@ public:
{
}
FileContainer(const Utf8String &filePath,
const Utf8String &projectPartId,
const Utf8StringVector &fileArguments,
const Utf8String &unsavedFileContent = Utf8String(),
bool hasUnsavedFileContent = false,
quint32 documentRevision = 0)
: filePath_(filePath),
projectPartId_(projectPartId),
fileArguments_(fileArguments),
unsavedFileContent_(unsavedFileContent),
documentRevision_(documentRevision),
hasUnsavedFileContent_(hasUnsavedFileContent)
{
}
FileContainer(const Utf8String &filePath,
const Utf8String &projectPartId,
const Utf8StringVector &fileArguments,

View File

@@ -90,11 +90,6 @@ static QString backendProcessPath()
+ QStringLiteral(QTC_HOST_EXE_SUFFIX);
}
static CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath)
{
return CppTools::CppModelManager::instance()->cppEditorDocument(filePath);
}
static bool printAliveMessageHelper()
{
const bool print = qEnvironmentVariableIntValue("QTC_CLANG_FORCE_VERBOSE_ALIVE");
@@ -540,14 +535,14 @@ void IpcCommunicator::registerProjectsParts(const QList<CppTools::ProjectPart::P
void IpcCommunicator::updateTranslationUnitFromCppEditorDocument(const QString &filePath)
{
const CppTools::CppEditorDocumentHandle *document = cppDocument(filePath);
const CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath);
updateTranslationUnit(filePath, document->contents(), document->revision());
}
void IpcCommunicator::updateUnsavedFileFromCppEditorDocument(const QString &filePath)
{
const CppTools::CppEditorDocumentHandle *document = cppDocument(filePath);
const CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath);
updateUnsavedFile(filePath, document->contents(), document->revision());
}
@@ -584,7 +579,7 @@ void IpcCommunicator::updateUnsavedFile(const QString &filePath, const QByteArra
static bool documentHasChanged(const QString &filePath, uint revision)
{
if (CppTools::CppEditorDocumentHandle *document = cppDocument(filePath))
if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath))
return document->sendTracker().shouldSendRevision(revision);
return true;
@@ -592,7 +587,7 @@ static bool documentHasChanged(const QString &filePath, uint revision)
static void setLastSentDocumentRevision(const QString &filePath, uint revision)
{
if (CppTools::CppEditorDocumentHandle *document = cppDocument(filePath))
if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath))
document->sendTracker().setLastSentRevision(int(revision));
}
@@ -625,7 +620,7 @@ void IpcCommunicator::updateTranslationUnitWithRevisionCheck(Core::IDocument *do
void IpcCommunicator::updateChangeContentStartPosition(const QString &filePath, int position)
{
if (CppTools::CppEditorDocumentHandle *document = cppDocument(filePath))
if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath))
document->sendTracker().applyContentChange(position);
}

View File

@@ -519,15 +519,10 @@ void ClangCompletionAssistProcessor::sendFileContent(const QByteArray &customFil
uint(m_interface->textDocument()->revision())}});
}
namespace {
CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath)
{
return CppTools::CppModelManager::instance()->cppEditorDocument(filePath);
}
bool shouldSendDocumentForCompletion(const QString &filePath,
int completionPosition)
{
auto *document = cppDocument(filePath);
CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath);
if (document) {
auto &sendTracker = document->sendTracker();
@@ -541,7 +536,7 @@ bool shouldSendDocumentForCompletion(const QString &filePath,
bool shouldSendCodeCompletion(const QString &filePath,
int completionPosition)
{
auto *document = cppDocument(filePath);
CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath);
if (document) {
auto &sendTracker = document->sendTracker();
@@ -553,7 +548,7 @@ bool shouldSendCodeCompletion(const QString &filePath,
void setLastDocumentRevision(const QString &filePath)
{
auto *document = cppDocument(filePath);
CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath);
if (document)
document->sendTracker().setLastSentRevision(int(document->revision()));
@@ -562,7 +557,7 @@ void setLastDocumentRevision(const QString &filePath)
void setLastCompletionPosition(const QString &filePath,
int completionPosition)
{
auto *document = cppDocument(filePath);
CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath);
if (document)
document->sendTracker().setLastCompletionPosition(completionPosition);

View File

@@ -44,6 +44,7 @@
#include <cpptools/cpptoolsbridge.h>
#include <cpptools/cpptoolsreuse.h>
#include <cpptools/cppworkingcopy.h>
#include <cpptools/editordocumenthandle.h>
#include <texteditor/convenience.h>
#include <texteditor/fontsettings.h>
@@ -325,6 +326,10 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::Pr
m_ipcCommunicator.unregisterTranslationUnitsForEditor({fileContainerWithArguments()});
m_ipcCommunicator.registerTranslationUnitsForEditor({fileContainerWithArguments(projectPart)});
}
} else if (revision() != 1) {
// E.g. a refactoring action opened the document and modified it immediately.
m_ipcCommunicator.registerTranslationUnitsForEditor({{fileContainerWithArgumentsAndDocumentContent(projectPart)}});
ClangCodeModel::Utils::setLastSentDocumentRevision(filePath(), revision());
} else {
m_ipcCommunicator.registerTranslationUnitsForEditor({{fileContainerWithArguments(projectPart)}});
}
@@ -438,6 +443,20 @@ ClangEditorDocumentProcessor::fileContainerWithArguments(CppTools::ProjectPart *
return {filePath(), projectPartId, Utf8StringVector(theFileArguments), revision()};
}
ClangBackEnd::FileContainer
ClangEditorDocumentProcessor::fileContainerWithArgumentsAndDocumentContent(
CppTools::ProjectPart *projectPart) const
{
const QStringList theFileArguments = fileArguments(filePath(), projectPart);
return ClangBackEnd::FileContainer(filePath(),
projectPart->id(),
Utf8StringVector(theFileArguments),
textDocument()->toPlainText(),
true,
revision());
}
ClangBackEnd::FileContainer
ClangEditorDocumentProcessor::fileContainerWithDocumentContent(const QString &projectpartId) const
{

View File

@@ -100,6 +100,8 @@ private:
HeaderErrorDiagnosticWidgetCreator creatorForHeaderErrorDiagnosticWidget(
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic);
ClangBackEnd::FileContainer fileContainerWithArguments(CppTools::ProjectPart *projectPart) const;
ClangBackEnd::FileContainer fileContainerWithArgumentsAndDocumentContent(
CppTools::ProjectPart *projectPart) const;
ClangBackEnd::FileContainer fileContainerWithDocumentContent(const QString &projectpartId) const;
private:

View File

@@ -33,6 +33,7 @@
#include <cpptools/baseeditordocumentparser.h>
#include <cpptools/compileroptionsbuilder.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/editordocumenthandle.h>
#include <cpptools/projectpart.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/qtcassert.h>
@@ -231,5 +232,16 @@ QString projectPartIdForFile(const QString &filePath)
return QString();
}
CppEditorDocumentHandle *cppDocument(const QString &filePath)
{
return CppTools::CppModelManager::instance()->cppEditorDocument(filePath);
}
void setLastSentDocumentRevision(const QString &filePath, uint revision)
{
if (CppEditorDocumentHandle *document = cppDocument(filePath))
document->sendTracker().setLastSentRevision(int(revision));
}
} // namespace Utils
} // namespace Clang

View File

@@ -27,9 +27,16 @@
#include <cpptools/projectpart.h>
namespace CppTools {
class CppEditorDocumentHandle;
}
namespace ClangCodeModel {
namespace Utils {
CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath);
void setLastSentDocumentRevision(const QString &filePath, uint revision);
QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,
CppTools::ProjectFile::Kind fileKind);
QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,