forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.6'
Change-Id: Iddfa0d2f3c0fb8ba65c0e5d479ad8e2f2cb95685
This commit is contained in:
@@ -66,6 +66,7 @@
|
||||
#include <clangbackendipc/projectpartsdonotexistmessage.h>
|
||||
#include <clangbackendipc/translationunitdoesnotexistmessage.h>
|
||||
#include <clangbackendipc/unregisterunsavedfilesforeditormessage.h>
|
||||
#include <clangbackendipc/updatetranslationunitsforeditormessage.h>
|
||||
|
||||
#include <cplusplus/Icons.h>
|
||||
|
||||
@@ -194,6 +195,7 @@ public:
|
||||
|
||||
void end() override;
|
||||
void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) override;
|
||||
void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) override;
|
||||
void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) override;
|
||||
void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) override;
|
||||
void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) override;
|
||||
@@ -218,6 +220,12 @@ void IpcSender::registerTranslationUnitsForEditor(const RegisterTranslationUnitF
|
||||
m_connection.serverProxy().registerTranslationUnitsForEditor(message);
|
||||
}
|
||||
|
||||
void IpcSender::updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message)
|
||||
{
|
||||
QTC_CHECK(m_connection.isConnected());
|
||||
m_connection.serverProxy().updateTranslationUnitsForEditor(message);
|
||||
}
|
||||
|
||||
void IpcSender::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message)
|
||||
{
|
||||
QTC_CHECK(m_connection.isConnected());
|
||||
@@ -368,6 +376,16 @@ void IpcCommunicator::registerProjectsParts(const QList<CppTools::ProjectPart::P
|
||||
registerProjectPartsForEditor(projectPartContainers);
|
||||
}
|
||||
|
||||
void IpcCommunicator::registerTranslationUnit(TextEditor::TextDocument *document)
|
||||
{
|
||||
const QString filePath = document->filePath().toString();
|
||||
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
||||
|
||||
registerTranslationUnitsForEditor({{Utf8String(filePath),
|
||||
Utf8String(projectPartId),
|
||||
uint(document->document()->revision())}});
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateTranslationUnitFromCppEditorDocument(const QString &filePath)
|
||||
{
|
||||
const auto document = CppTools::CppModelManager::instance()->cppEditorDocument(filePath);
|
||||
@@ -388,34 +406,33 @@ CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath)
|
||||
return CppTools::CppModelManager::instance()->cppEditorDocument(filePath);
|
||||
}
|
||||
|
||||
bool documentHasChanged(const QString &filePath, const QString &projectPartId)
|
||||
bool documentHasChanged(const QString &filePath)
|
||||
{
|
||||
auto *document = cppDocument(filePath);
|
||||
|
||||
if (document)
|
||||
return document->sendTracker(projectPartId).shouldSendRevision(document->revision());
|
||||
return document->sendTracker().shouldSendRevision(document->revision());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setLastSentDocumentRevision(const QString &filePath,
|
||||
const QString &projectPartId,
|
||||
uint revision)
|
||||
{
|
||||
auto *document = cppDocument(filePath);
|
||||
|
||||
if (document)
|
||||
document->sendTracker(projectPartId).setLastSentRevision(int(revision));
|
||||
document->sendTracker().setLastSentRevision(int(revision));
|
||||
}
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateTranslationUnit(const QString &filePath,
|
||||
const QByteArray &contents,
|
||||
uint documentRevision)
|
||||
void IpcCommunicator::registerTranslationUnit(const QString &filePath,
|
||||
const QByteArray &contents,
|
||||
uint documentRevision)
|
||||
{
|
||||
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
||||
|
||||
if (documentHasChanged(filePath, projectPartId)) {
|
||||
if (documentHasChanged(filePath)) {
|
||||
const bool hasUnsavedContent = true;
|
||||
|
||||
registerTranslationUnitsForEditor({{filePath,
|
||||
@@ -424,18 +441,30 @@ void IpcCommunicator::updateTranslationUnit(const QString &filePath,
|
||||
hasUnsavedContent,
|
||||
documentRevision}});
|
||||
|
||||
setLastSentDocumentRevision(filePath, projectPartId, documentRevision);
|
||||
setLastSentDocumentRevision(filePath, documentRevision);
|
||||
}
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateTranslationUnit(const QString &filePath,
|
||||
const QByteArray &contents,
|
||||
uint documentRevision)
|
||||
{
|
||||
const bool hasUnsavedContent = true;
|
||||
|
||||
updateTranslationUnitsForEditor({{filePath,
|
||||
Utf8String(),
|
||||
Utf8String::fromByteArray(contents),
|
||||
hasUnsavedContent,
|
||||
documentRevision}});
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision)
|
||||
{
|
||||
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
||||
const bool hasUnsavedContent = true;
|
||||
|
||||
// TODO: Send new only if changed
|
||||
registerUnsavedFilesForEditor({{filePath,
|
||||
projectPartId,
|
||||
Utf8String(),
|
||||
Utf8String::fromByteArray(contents),
|
||||
hasUnsavedContent,
|
||||
documentRevision}});
|
||||
@@ -446,27 +475,35 @@ void IpcCommunicator::requestDiagnostics(const FileContainer &fileContainer)
|
||||
if (m_sendMode == IgnoreSendRequests)
|
||||
return;
|
||||
|
||||
if (documentHasChanged(fileContainer.filePath(), fileContainer.projectPartId())) {
|
||||
registerTranslationUnitsForEditor({fileContainer});
|
||||
if (documentHasChanged(fileContainer.filePath())) {
|
||||
updateTranslationUnitsForEditor({fileContainer});
|
||||
|
||||
const RequestDiagnosticsMessage message(fileContainer);
|
||||
qCDebug(log) << ">>>" << message;
|
||||
m_ipcSender->requestDiagnostics(message);
|
||||
|
||||
setLastSentDocumentRevision(fileContainer.filePath(),
|
||||
fileContainer.projectPartId(),
|
||||
fileContainer.documentRevision());
|
||||
}
|
||||
}
|
||||
|
||||
void IpcCommunicator::requestDiagnostics(Core::IDocument *document)
|
||||
{
|
||||
const auto textDocument = qobject_cast<TextDocument*>(document);
|
||||
const auto filePath = textDocument->filePath().toString();
|
||||
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
||||
|
||||
requestDiagnostics(FileContainer(filePath,
|
||||
projectPartId,
|
||||
textDocument->document()->revision()));
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateChangeContentStartPosition(const QString &filePath, int position)
|
||||
{
|
||||
auto *document = cppDocument(filePath);
|
||||
|
||||
if (document) {
|
||||
const QString projectPartId = Utils::projectPartIdForFile(filePath);
|
||||
document->sendTracker(projectPartId).applyContentChange(position);
|
||||
}
|
||||
if (document)
|
||||
document->sendTracker().applyContentChange(position);
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document)
|
||||
@@ -540,6 +577,16 @@ void IpcCommunicator::registerTranslationUnitsForEditor(const FileContainers &fi
|
||||
m_ipcSender->registerTranslationUnitsForEditor(message);
|
||||
}
|
||||
|
||||
void IpcCommunicator::updateTranslationUnitsForEditor(const IpcCommunicator::FileContainers &fileContainers)
|
||||
{
|
||||
if (m_sendMode == IgnoreSendRequests)
|
||||
return;
|
||||
|
||||
const UpdateTranslationUnitsForEditorMessage message(fileContainers);
|
||||
qCDebug(log) << ">>>" << message;
|
||||
m_ipcSender->updateTranslationUnitsForEditor(message);
|
||||
}
|
||||
|
||||
void IpcCommunicator::unregisterTranslationUnitsForEditor(const FileContainers &fileContainers)
|
||||
{
|
||||
if (m_sendMode == IgnoreSendRequests)
|
||||
|
||||
@@ -53,6 +53,7 @@ class DiagnosticsChangedMessage;
|
||||
|
||||
namespace TextEditor {
|
||||
class TextEditorWidget;
|
||||
class TextDocument;
|
||||
}
|
||||
|
||||
namespace ClangCodeModel {
|
||||
@@ -96,6 +97,7 @@ public:
|
||||
|
||||
virtual void end() = 0;
|
||||
virtual void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) = 0;
|
||||
virtual void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) = 0;
|
||||
virtual void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) = 0;
|
||||
virtual void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) = 0;
|
||||
virtual void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) = 0;
|
||||
@@ -118,6 +120,7 @@ public:
|
||||
IpcCommunicator();
|
||||
|
||||
void registerTranslationUnitsForEditor(const FileContainers &fileContainers);
|
||||
void updateTranslationUnitsForEditor(const FileContainers &fileContainers);
|
||||
void unregisterTranslationUnitsForEditor(const FileContainers &fileContainers);
|
||||
void registerProjectPartsForEditor(const ProjectPartContainers &projectPartContainers);
|
||||
void unregisterProjectPartsForEditor(const QStringList &projectPartIds);
|
||||
@@ -130,6 +133,8 @@ public:
|
||||
|
||||
void registerProjectsParts(const QList<CppTools::ProjectPart::Ptr> projectParts);
|
||||
|
||||
void registerTranslationUnit(TextEditor::TextDocument *document);
|
||||
void registerTranslationUnit(const QString &filePath, const QByteArray &contents, uint documentRevision);
|
||||
void updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document);
|
||||
void updateTranslationUnit(Core::IDocument *document);
|
||||
void updateUnsavedFile(Core::IDocument *document);
|
||||
@@ -138,6 +143,7 @@ public:
|
||||
void updateTranslationUnit(const QString &filePath, const QByteArray &contents, uint documentRevision);
|
||||
void updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision);
|
||||
void requestDiagnostics(const ClangBackEnd::FileContainer &fileContainer);
|
||||
void requestDiagnostics(Core::IDocument *document);
|
||||
void updateChangeContentStartPosition(const QString &filePath, int position);
|
||||
|
||||
public: // for tests
|
||||
|
||||
@@ -115,23 +115,14 @@ contains(DEFINES, CLANG_INDEXING) {
|
||||
FORMS += clangprojectsettingspropertiespage.ui
|
||||
|
||||
equals(TEST, 1) {
|
||||
RESOURCES += \
|
||||
test/clang_tests_database.qrc
|
||||
|
||||
HEADERS += \
|
||||
test/clangcodecompletion_test.h
|
||||
|
||||
SOURCES += \
|
||||
test/clangcodecompletion_test.cpp
|
||||
|
||||
DISTFILES += \
|
||||
test/mysource.cpp \
|
||||
test/myheader.cpp \
|
||||
test/completionWithProject.cpp \
|
||||
test/memberCompletion.cpp \
|
||||
test/doxygenKeywordsCompletion.cpp \
|
||||
test/preprocessorKeywordsCompletion.cpp \
|
||||
test/includeDirectiveCompletion.cpp
|
||||
RESOURCES += test/data/clangtestdata.qrc
|
||||
OTHER_FILES += $$files(test/data/*)
|
||||
}
|
||||
|
||||
macx {
|
||||
|
||||
@@ -104,7 +104,7 @@ QtcPlugin {
|
||||
condition: project.testsEnabled
|
||||
prefix: "test/"
|
||||
files: [
|
||||
"clang_tests_database.qrc",
|
||||
"data/clangtestdata.qrc",
|
||||
"clangcodecompletion_test.cpp",
|
||||
"clangcodecompletion_test.h",
|
||||
]
|
||||
@@ -112,20 +112,10 @@ QtcPlugin {
|
||||
|
||||
Group {
|
||||
name: "Test resources"
|
||||
prefix: "test/"
|
||||
prefix: "test/data/"
|
||||
fileTags: "none"
|
||||
files: [
|
||||
"mysource.cpp",
|
||||
"myheader.h",
|
||||
"completionWithProject.cpp",
|
||||
"memberCompletion.cpp",
|
||||
"doxygenKeywordsCompletion.cpp",
|
||||
"preprocessorKeywordsCompletion.cpp",
|
||||
"includeDirectiveCompletion.cpp",
|
||||
"objc_messages_1.mm",
|
||||
"objc_messages_2.mm",
|
||||
"objc_messages_3.mm",
|
||||
]
|
||||
files: [ "*" ]
|
||||
excludeFiles: "clangtestdata.qrc"
|
||||
}
|
||||
|
||||
files: [
|
||||
|
||||
@@ -670,18 +670,17 @@ ClangCompletionAssistProcessor::unsavedFileContent(const QByteArray &customFileC
|
||||
return info;
|
||||
}
|
||||
|
||||
void ClangCompletionAssistProcessor::sendFileContent(const QString &projectPartId,
|
||||
const QByteArray &customFileContent)
|
||||
void ClangCompletionAssistProcessor::sendFileContent(const QByteArray &customFileContent)
|
||||
{
|
||||
// TODO: Revert custom modification after the completions
|
||||
const UnsavedFileContentInfo info = unsavedFileContent(customFileContent);
|
||||
|
||||
IpcCommunicator &ipcCommunicator = m_interface->ipcCommunicator();
|
||||
ipcCommunicator.registerTranslationUnitsForEditor({{m_interface->fileName(),
|
||||
projectPartId,
|
||||
Utf8String::fromByteArray(info.unsavedContent),
|
||||
info.isDocumentModified,
|
||||
uint(m_interface->textDocument()->revision())}});
|
||||
ipcCommunicator.updateTranslationUnitsForEditor({{m_interface->fileName(),
|
||||
Utf8String(),
|
||||
Utf8String::fromByteArray(info.unsavedContent),
|
||||
info.isDocumentModified,
|
||||
uint(m_interface->textDocument()->revision())}});
|
||||
}
|
||||
namespace {
|
||||
CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath)
|
||||
@@ -690,14 +689,13 @@ CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath)
|
||||
}
|
||||
|
||||
bool shouldSendDocumentForCompletion(const QString &filePath,
|
||||
const QString &projectPartId,
|
||||
int completionPosition)
|
||||
{
|
||||
auto *document = cppDocument(filePath);
|
||||
|
||||
if (document) {
|
||||
auto &sendTracker = document->sendTracker(projectPartId);
|
||||
return sendTracker.shouldSendRevisionWithCompletionPosition(document->revision(),
|
||||
auto &sendTracker = document->sendTracker();
|
||||
return sendTracker.shouldSendRevisionWithCompletionPosition(int(document->revision()),
|
||||
completionPosition);
|
||||
}
|
||||
|
||||
@@ -705,14 +703,13 @@ bool shouldSendDocumentForCompletion(const QString &filePath,
|
||||
}
|
||||
|
||||
void setLastCompletionPositionAndDocumentRevision(const QString &filePath,
|
||||
const QString &projectPartId,
|
||||
int completionPosition)
|
||||
{
|
||||
auto *document = cppDocument(filePath);
|
||||
|
||||
if (document) {
|
||||
document->sendTracker(projectPartId).setLastCompletionPosition(completionPosition);
|
||||
document->sendTracker(projectPartId).setLastSentRevision(document->revision());
|
||||
document->sendTracker().setLastCompletionPosition(completionPosition);
|
||||
document->sendTracker().setLastSentRevision(document->revision());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,13 +734,13 @@ void ClangCompletionAssistProcessor::sendCompletionRequest(int position,
|
||||
++column;
|
||||
|
||||
const QString filePath = m_interface->fileName();
|
||||
const QString projectPartId = projectPartIdForEditorDocument(filePath);
|
||||
|
||||
if (shouldSendDocumentForCompletion(filePath, projectPartId, position)) {
|
||||
sendFileContent(projectPartId, customFileContent);
|
||||
setLastCompletionPositionAndDocumentRevision(filePath, projectPartId, position);
|
||||
if (shouldSendDocumentForCompletion(filePath, position)) {
|
||||
sendFileContent(customFileContent);
|
||||
setLastCompletionPositionAndDocumentRevision(filePath, position);
|
||||
}
|
||||
|
||||
const QString projectPartId = projectPartIdForEditorDocument(filePath);
|
||||
m_interface->ipcCommunicator().completeCode(this,
|
||||
filePath,
|
||||
uint(line),
|
||||
|
||||
@@ -83,7 +83,7 @@ private:
|
||||
};
|
||||
UnsavedFileContentInfo unsavedFileContent(const QByteArray &customFileContent) const;
|
||||
|
||||
void sendFileContent(const QString &projectPartId, const QByteArray &customFileContent);
|
||||
void sendFileContent(const QByteArray &customFileContent);
|
||||
void sendCompletionRequest(int position, const QByteArray &customFileContent);
|
||||
|
||||
void handleAvailableCompletions(const CodeCompletions &completions);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "clangcompletionassistprovider.h"
|
||||
|
||||
#include "clangcompletionassistprocessor.h"
|
||||
#include "clangeditordocumentprocessor.h"
|
||||
#include "clangutils.h"
|
||||
#include "pchmanager.h"
|
||||
|
||||
@@ -70,18 +71,20 @@ TextEditor::AssistInterface *ClangCompletionAssistProvider::createAssistInterfac
|
||||
int position,
|
||||
TextEditor::AssistReason reason) const
|
||||
{
|
||||
const CppTools::ProjectPart::Ptr projectPart = Utils::projectPartForFile(filePath);
|
||||
QTC_ASSERT(!projectPart.isNull(), return 0);
|
||||
const CppTools::ProjectPart::Ptr projectPart = Utils::projectPartForFileBasedOnProcessor(filePath);
|
||||
if (projectPart) {
|
||||
const PchInfo::Ptr pchInfo = PchManager::instance()->pchInfo(projectPart);
|
||||
return new ClangCompletionAssistInterface(m_ipcCommunicator,
|
||||
textEditorWidget,
|
||||
position,
|
||||
filePath,
|
||||
reason,
|
||||
projectPart->headerPaths,
|
||||
pchInfo,
|
||||
projectPart->languageFeatures);
|
||||
}
|
||||
|
||||
const PchInfo::Ptr pchInfo = PchManager::instance()->pchInfo(projectPart);
|
||||
return new ClangCompletionAssistInterface(m_ipcCommunicator,
|
||||
textEditorWidget,
|
||||
position,
|
||||
filePath,
|
||||
reason,
|
||||
projectPart->headerPaths,
|
||||
pchInfo,
|
||||
projectPart->languageFeatures);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -94,15 +94,16 @@ bool isHelpfulChildDiagnostic(const ClangBackEnd::DiagnosticContainer &parentDia
|
||||
QString diagnosticText(const ClangBackEnd::DiagnosticContainer &diagnostic)
|
||||
{
|
||||
QString text = diagnostic.category().toString()
|
||||
+ QStringLiteral(" ")
|
||||
+ QStringLiteral("\n\n")
|
||||
+ diagnostic.text().toString();
|
||||
if (!diagnostic.enableOption().isEmpty()) {
|
||||
text += QStringLiteral(" (clang option: ")
|
||||
+ diagnostic.enableOption().toString()
|
||||
+ QStringLiteral(" disable with: ")
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
if (!diagnostic.disableOption().isEmpty()) {
|
||||
text += QStringLiteral(" (disable with ")
|
||||
+ diagnostic.disableOption().toString()
|
||||
+ QStringLiteral(")");
|
||||
}
|
||||
#endif
|
||||
|
||||
for (auto &&childDiagnostic : diagnostic.children()) {
|
||||
if (isHelpfulChildDiagnostic(diagnostic, childDiagnostic))
|
||||
|
||||
@@ -227,7 +227,7 @@ ClangEditorDocumentProcessor *ClangEditorDocumentProcessor::get(const QString &f
|
||||
static bool isProjectPartLoadedOrIsFallback(CppTools::ProjectPart::Ptr projectPart)
|
||||
{
|
||||
return projectPart
|
||||
&& (projectPart->id().isEmpty() || ClangCodeModel::Utils::isProjectPartValid(projectPart));
|
||||
&& (projectPart->id().isEmpty() || ClangCodeModel::Utils::isProjectPartLoaded(projectPart));
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::updateProjectPartAndTranslationUnitForEditor()
|
||||
|
||||
@@ -116,25 +116,43 @@ void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *newCurrent)
|
||||
void ModelManagerSupportClang::connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument)
|
||||
{
|
||||
// Handle externally changed documents
|
||||
connect(textDocument, &Core::IDocument::aboutToReload,
|
||||
this, &ModelManagerSupportClang::onCppDocumentAboutToReloadOnTranslationUnit,
|
||||
Qt::UniqueConnection);
|
||||
connect(textDocument, &Core::IDocument::reloadFinished,
|
||||
this, &ModelManagerSupportClang::onCppDocumentReloadFinishedOnTranslationUnit,
|
||||
Qt::UniqueConnection);
|
||||
|
||||
// Handle changes from e.g. refactoring actions
|
||||
connect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition,
|
||||
this, &ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit,
|
||||
Qt::UniqueConnection);
|
||||
connectToTextDocumentContentsChangedForTranslationUnit(textDocument);
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::connectTextDocumentToUnsavedFiles(TextEditor::TextDocument *textDocument)
|
||||
{
|
||||
// Handle externally changed documents
|
||||
connect(textDocument, &Core::IDocument::aboutToReload,
|
||||
this, &ModelManagerSupportClang::onCppDocumentAboutToReloadOnUnsavedFile,
|
||||
Qt::UniqueConnection);
|
||||
connect(textDocument, &Core::IDocument::reloadFinished,
|
||||
this, &ModelManagerSupportClang::onCppDocumentReloadFinishedOnUnsavedFile,
|
||||
Qt::UniqueConnection);
|
||||
|
||||
// Handle changes from e.g. refactoring actions
|
||||
connect(textDocument, &TextEditor::TextDocument::contentsChanged,
|
||||
connectToTextDocumentContentsChangedForUnsavedFile(textDocument);
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::connectToTextDocumentContentsChangedForTranslationUnit(
|
||||
TextEditor::TextDocument *textDocument)
|
||||
{
|
||||
connect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition,
|
||||
this, &ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit,
|
||||
Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::connectToTextDocumentContentsChangedForUnsavedFile(
|
||||
TextEditor::TextDocument *textDocument)
|
||||
{
|
||||
connect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition,
|
||||
this, &ModelManagerSupportClang::onCppDocumentContentsChangedOnUnsavedFile,
|
||||
Qt::UniqueConnection);
|
||||
}
|
||||
@@ -168,11 +186,19 @@ void ModelManagerSupportClang::onEditorOpened(Core::IEditor *editor)
|
||||
}
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::onCppDocumentAboutToReloadOnTranslationUnit()
|
||||
{
|
||||
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
|
||||
disconnect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition,
|
||||
this, &ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit);
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::onCppDocumentReloadFinishedOnTranslationUnit(bool success)
|
||||
{
|
||||
if (success) {
|
||||
Core::IDocument *document = qobject_cast<Core::IDocument *>(sender());
|
||||
m_ipcCommunicator.updateTranslationUnit(document);
|
||||
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
|
||||
connectToTextDocumentContentsChangedForTranslationUnit(textDocument);
|
||||
m_ipcCommunicator.requestDiagnostics(textDocument);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,11 +213,19 @@ void ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit(int
|
||||
m_ipcCommunicator.updateTranslationUnitIfNotCurrentDocument(document);
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::onCppDocumentAboutToReloadOnUnsavedFile()
|
||||
{
|
||||
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
|
||||
disconnect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition,
|
||||
this, &ModelManagerSupportClang::onCppDocumentContentsChangedOnUnsavedFile);
|
||||
}
|
||||
|
||||
void ModelManagerSupportClang::onCppDocumentReloadFinishedOnUnsavedFile(bool success)
|
||||
{
|
||||
if (success) {
|
||||
Core::IDocument *document = qobject_cast<Core::IDocument *>(sender());
|
||||
m_ipcCommunicator.updateUnsavedFile(document);
|
||||
TextEditor::TextDocument *textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
|
||||
connectToTextDocumentContentsChangedForUnsavedFile(textDocument);
|
||||
m_ipcCommunicator.updateUnsavedFile(textDocument);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,10 +72,12 @@ public:
|
||||
private:
|
||||
void onEditorOpened(Core::IEditor *editor);
|
||||
void onCurrentEditorChanged(Core::IEditor *newCurrent);
|
||||
void onCppDocumentAboutToReloadOnTranslationUnit();
|
||||
void onCppDocumentReloadFinishedOnTranslationUnit(bool success);
|
||||
void onCppDocumentContentsChangedOnTranslationUnit(int position,
|
||||
int charsRemoved,
|
||||
int charsAdded);
|
||||
void onCppDocumentAboutToReloadOnUnsavedFile();
|
||||
void onCppDocumentReloadFinishedOnUnsavedFile(bool success);
|
||||
void onCppDocumentContentsChangedOnUnsavedFile();
|
||||
|
||||
@@ -93,6 +95,9 @@ private:
|
||||
|
||||
void connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument);
|
||||
void connectTextDocumentToUnsavedFiles(TextEditor::TextDocument *textDocument);
|
||||
void connectToTextDocumentContentsChangedForTranslationUnit(
|
||||
TextEditor::TextDocument *textDocument);
|
||||
void connectToTextDocumentContentsChangedForUnsavedFile(TextEditor::TextDocument *textDocument);
|
||||
void connectToWidgetsMarkContextMenuRequested(QWidget *editorWidget);
|
||||
|
||||
private:
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
#include "clangutils.h"
|
||||
|
||||
#include "clangeditordocumentprocessor.h"
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
@@ -264,7 +266,14 @@ ProjectPart::Ptr projectPartForFile(const QString &filePath)
|
||||
return ProjectPart::Ptr();
|
||||
}
|
||||
|
||||
bool isProjectPartValid(const ProjectPart::Ptr projectPart)
|
||||
ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &filePath)
|
||||
{
|
||||
if (const auto processor = ClangEditorDocumentProcessor::get(filePath))
|
||||
return processor->projectPart();
|
||||
return ProjectPart::Ptr();
|
||||
}
|
||||
|
||||
bool isProjectPartLoaded(const ProjectPart::Ptr projectPart)
|
||||
{
|
||||
if (projectPart)
|
||||
return CppModelManager::instance()->projectPartForId(projectPart->id());
|
||||
@@ -275,7 +284,7 @@ QString projectPartIdForFile(const QString &filePath)
|
||||
{
|
||||
const ProjectPart::Ptr projectPart = projectPartForFile(filePath);
|
||||
|
||||
if (isProjectPartValid(projectPart))
|
||||
if (isProjectPartLoaded(projectPart))
|
||||
return projectPart->id(); // OK, Project Part is still loaded
|
||||
return QString();
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart,
|
||||
QStringList createPCHInclusionOptions(const QString &pchFile);
|
||||
|
||||
CppTools::ProjectPart::Ptr projectPartForFile(const QString &filePath);
|
||||
bool isProjectPartValid(const CppTools::ProjectPart::Ptr projectPart);
|
||||
CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &filePath);
|
||||
bool isProjectPartLoaded(const CppTools::ProjectPart::Ptr projectPart);
|
||||
QString projectPartIdForFile(const QString &filePath);
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include <clangbackendipc/cmbunregisterprojectsforeditormessage.h>
|
||||
#include <clangbackendipc/cmbunregistertranslationunitsforeditormessage.h>
|
||||
#include <clangbackendipc/registerunsavedfilesforeditormessage.h>
|
||||
#include <clangbackendipc/updatetranslationunitsforeditormessage.h>
|
||||
#include <utils/changeset.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -319,8 +320,16 @@ QString toString(const RegisterTranslationUnitForEditorMessage &message)
|
||||
ts << "RegisterTranslationUnitForEditorMessage\n"
|
||||
<< toString(message.fileContainers());
|
||||
return out;
|
||||
}
|
||||
|
||||
return QLatin1String("RegisterTranslationUnitForEditorMessage\n");
|
||||
QString toString(const UpdateTranslationUnitsForEditorMessage &message)
|
||||
{
|
||||
QString out;
|
||||
QTextStream ts(&out);
|
||||
|
||||
ts << "UpdateTranslationUnitForEditorMessage\n"
|
||||
<< toString(message.fileContainers());
|
||||
return out;
|
||||
}
|
||||
|
||||
QString toString(const UnregisterTranslationUnitsForEditorMessage &)
|
||||
@@ -356,8 +365,6 @@ QString toString(const RegisterUnsavedFilesForEditorMessage &message)
|
||||
ts << "RegisterUnsavedFilesForEditorMessage\n"
|
||||
<< toString(message.fileContainers());
|
||||
return out;
|
||||
|
||||
return QLatin1String("RegisterUnsavedFilesForEditorMessage\n");
|
||||
}
|
||||
|
||||
QString toString(const UnregisterUnsavedFilesForEditorMessage &)
|
||||
@@ -384,6 +391,9 @@ public:
|
||||
void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) override
|
||||
{ senderLog.append(toString(message)); }
|
||||
|
||||
void updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) override
|
||||
{ senderLog.append(toString(message)); }
|
||||
|
||||
void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) override
|
||||
{ senderLog.append(toString(message)); }
|
||||
|
||||
@@ -960,7 +970,7 @@ void ClangCodeCompletionTest::testCompleteConstructorAndFallbackToGlobalCompleti
|
||||
QVERIFY(!hasSnippet(t.proposal, "class"));
|
||||
}
|
||||
|
||||
void ClangCodeCompletionTest::testProjectDependentCompletion()
|
||||
void ClangCodeCompletionTest::testCompleteProjectDependingCode()
|
||||
{
|
||||
const TestDocument testDocument("completionWithProject.cpp");
|
||||
QVERIFY(testDocument.isCreatedAndHasValidCursorPosition());
|
||||
@@ -976,7 +986,7 @@ void ClangCodeCompletionTest::testProjectDependentCompletion()
|
||||
QVERIFY(hasItem(proposal, "projectConfiguration1"));
|
||||
}
|
||||
|
||||
void ClangCodeCompletionTest::testChangingProjectDependentCompletion()
|
||||
void ClangCodeCompletionTest::testCompleteProjectDependingCodeAfterChangingProject()
|
||||
{
|
||||
const TestDocument testDocument("completionWithProject.cpp");
|
||||
QVERIFY(testDocument.isCreatedAndHasValidCursorPosition());
|
||||
@@ -1015,7 +1025,36 @@ void ClangCodeCompletionTest::testChangingProjectDependentCompletion()
|
||||
QVERIFY(hasItem(proposal, "noProjectConfigurationDetected"));
|
||||
}
|
||||
|
||||
void ClangCodeCompletionTest::testUnsavedFilesTrackingByModifyingIncludedFileInCurrentEditor()
|
||||
void ClangCodeCompletionTest::testCompleteProjectDependingCodeInGeneratedUiFile()
|
||||
{
|
||||
CppTools::Tests::TemporaryCopiedDir testDir(qrcPath("qt-widgets-app"));
|
||||
QVERIFY(testDir.isValid());
|
||||
|
||||
MonitorGeneratedUiFile monitorGeneratedUiFile;
|
||||
|
||||
// Open project
|
||||
const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro");
|
||||
CppTools::Tests::ProjectOpenerAndCloser projectManager;
|
||||
const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true);
|
||||
QVERIFY(projectInfo.isValid());
|
||||
|
||||
// Open file with ui object
|
||||
const QString completionFile = testDir.absolutePath("mainwindow.cpp");
|
||||
const TestDocument testDocument = TestDocument::fromExistingFile(completionFile);
|
||||
QVERIFY(testDocument.isCreatedAndHasValidCursorPosition());
|
||||
OpenEditorAtCursorPosition openSource(testDocument);
|
||||
QVERIFY(openSource.succeeded());
|
||||
|
||||
// ...and check comletions
|
||||
QVERIFY(monitorGeneratedUiFile.waitUntilGenerated());
|
||||
ProposalModel proposal = completionResults(openSource.editor());
|
||||
QVERIFY(hasItem(proposal, "menuBar"));
|
||||
QVERIFY(hasItem(proposal, "statusBar"));
|
||||
QVERIFY(hasItem(proposal, "centralWidget"));
|
||||
QVERIFY(hasItem(proposal, "setupUi"));
|
||||
}
|
||||
|
||||
void ClangCodeCompletionTest::testCompleteAfterModifyingIncludedHeaderInOtherEditor()
|
||||
{
|
||||
CppTools::Tests::TemporaryDir temporaryDir;
|
||||
const TestDocument sourceDocument("mysource.cpp", &temporaryDir);
|
||||
@@ -1041,7 +1080,7 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByModifyingIncludedFileInC
|
||||
QVERIFY(hasItem(proposal, "globalFromHeaderUnsaved"));
|
||||
}
|
||||
|
||||
void ClangCodeCompletionTest::testUnsavedFilesTrackingByModifyingIncludedFileInNotCurrentEditor()
|
||||
void ClangCodeCompletionTest::testCompleteAfterModifyingIncludedHeaderByRefactoringActions()
|
||||
{
|
||||
CppTools::Tests::TemporaryDir temporaryDir;
|
||||
const TestDocument sourceDocument("mysource.cpp", &temporaryDir);
|
||||
@@ -1072,7 +1111,7 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByModifyingIncludedFileInN
|
||||
QVERIFY(hasItem(proposal, "globalFromHeaderUnsaved"));
|
||||
}
|
||||
|
||||
void ClangCodeCompletionTest::testUnsavedFilesTrackingByModifyingIncludedFileExternally()
|
||||
void ClangCodeCompletionTest::testCompleteAfterChangingIncludedAndOpenHeaderExternally()
|
||||
{
|
||||
QSKIP("The file system watcher is doing it in backend process but we wait not long enough");
|
||||
|
||||
@@ -1106,33 +1145,28 @@ void ClangCodeCompletionTest::testUnsavedFilesTrackingByModifyingIncludedFileExt
|
||||
QVERIFY(hasItem(proposal, "globalFromHeaderReloaded"));
|
||||
}
|
||||
|
||||
void ClangCodeCompletionTest::testUnsavedFilesTrackingByCompletingUiObject()
|
||||
void ClangCodeCompletionTest::testCompleteAfterChangingIncludedAndNotOpenHeaderExternally()
|
||||
{
|
||||
CppTools::Tests::TemporaryCopiedDir testDir(qrcPath("qt-widgets-app"));
|
||||
QVERIFY(testDir.isValid());
|
||||
QSKIP("The file system watcher is doing it in backend process but we wait not long enough");
|
||||
|
||||
MonitorGeneratedUiFile monitorGeneratedUiFile;
|
||||
CppTools::Tests::TemporaryDir temporaryDir;
|
||||
const TestDocument sourceDocument("mysource.cpp", &temporaryDir);
|
||||
QVERIFY(sourceDocument.isCreatedAndHasValidCursorPosition());
|
||||
const TestDocument headerDocument("myheader.h", &temporaryDir);
|
||||
QVERIFY(headerDocument.isCreated());
|
||||
|
||||
// Open project
|
||||
const QString projectFilePath = testDir.absolutePath("qt-widgets-app.pro");
|
||||
CppTools::Tests::ProjectOpenerAndCloser projectManager;
|
||||
const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true);
|
||||
QVERIFY(projectInfo.isValid());
|
||||
|
||||
// Open file with ui object
|
||||
const QString completionFile = testDir.absolutePath("mainwindow.cpp");
|
||||
const TestDocument testDocument = TestDocument::fromExistingFile(completionFile);
|
||||
QVERIFY(testDocument.isCreatedAndHasValidCursorPosition());
|
||||
OpenEditorAtCursorPosition openSource(testDocument);
|
||||
// Open source and test completions
|
||||
OpenEditorAtCursorPosition openSource(sourceDocument);
|
||||
QVERIFY(openSource.succeeded());
|
||||
|
||||
// ...and check comletions
|
||||
QVERIFY(monitorGeneratedUiFile.waitUntilGenerated());
|
||||
ProposalModel proposal = completionResults(openSource.editor());
|
||||
QVERIFY(hasItem(proposal, "menuBar"));
|
||||
QVERIFY(hasItem(proposal, "statusBar"));
|
||||
QVERIFY(hasItem(proposal, "centralWidget"));
|
||||
QVERIFY(hasItem(proposal, "setupUi"));
|
||||
QVERIFY(hasItem(proposal, "globalFromHeader"));
|
||||
|
||||
// Simulate external modification, e.g version control checkout
|
||||
QVERIFY(writeFile(headerDocument.filePath, "int globalFromHeaderReloaded;\n"));
|
||||
|
||||
// Retrigger completion and check if its updated
|
||||
proposal = completionResults(openSource.editor());
|
||||
QVERIFY(hasItem(proposal, "globalFromHeaderReloaded"));
|
||||
}
|
||||
|
||||
void ClangCodeCompletionTest::testUpdateBackendAfterRestart()
|
||||
|
||||
@@ -59,13 +59,14 @@ private slots:
|
||||
void testCompleteFunctions();
|
||||
void testCompleteConstructorAndFallbackToGlobalCompletion();
|
||||
|
||||
void testProjectDependentCompletion();
|
||||
void testChangingProjectDependentCompletion();
|
||||
void testCompleteProjectDependingCode();
|
||||
void testCompleteProjectDependingCodeAfterChangingProject();
|
||||
void testCompleteProjectDependingCodeInGeneratedUiFile();
|
||||
|
||||
void testUnsavedFilesTrackingByModifyingIncludedFileInCurrentEditor();
|
||||
void testUnsavedFilesTrackingByModifyingIncludedFileInNotCurrentEditor();
|
||||
void testUnsavedFilesTrackingByModifyingIncludedFileExternally();
|
||||
void testUnsavedFilesTrackingByCompletingUiObject();
|
||||
void testCompleteAfterModifyingIncludedHeaderInOtherEditor();
|
||||
void testCompleteAfterModifyingIncludedHeaderByRefactoringActions();
|
||||
void testCompleteAfterChangingIncludedAndOpenHeaderExternally();
|
||||
void testCompleteAfterChangingIncludedAndNotOpenHeaderExternally();
|
||||
|
||||
void testUpdateBackendAfterRestart();
|
||||
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
<RCC>
|
||||
<qresource prefix="/unittests/ClangCodeModel">
|
||||
<file>objc_messages_1.mm</file>
|
||||
<file>objc_messages_2.mm</file>
|
||||
<file>objc_messages_3.mm</file>
|
||||
<file>completionWithProject.cpp</file>
|
||||
<file>memberCompletion.cpp</file>
|
||||
<file>myheader.h</file>
|
||||
<file>mysource.cpp</file>
|
||||
<file>qt-widgets-app/main.cpp</file>
|
||||
<file>qt-widgets-app/mainwindow.cpp</file>
|
||||
<file>qt-widgets-app/mainwindow.h</file>
|
||||
<file>qt-widgets-app/mainwindow.ui</file>
|
||||
<file>qt-widgets-app/qt-widgets-app.pro</file>
|
||||
<file>functionCompletion.cpp</file>
|
||||
<file>doxygenKeywordsCompletion.cpp</file>
|
||||
<file>preprocessorKeywordsCompletion.cpp</file>
|
||||
<file>includeDirectiveCompletion.cpp</file>
|
||||
<file>exampleIncludeDir/file.h</file>
|
||||
<file>exampleIncludeDir/otherFile.h</file>
|
||||
<file>exampleIncludeDir/mylib/mylib.h</file>
|
||||
<file>globalCompletion.cpp</file>
|
||||
<file>exampleIncludeDir/otherFile.h</file>
|
||||
<file>completionWithProject.cpp</file>
|
||||
<file>constructorCompletion.cpp</file>
|
||||
<file>doxygenKeywordsCompletion.cpp</file>
|
||||
<file>functionCompletion.cpp</file>
|
||||
<file>globalCompletion.cpp</file>
|
||||
<file>includeDirectiveCompletion.cpp</file>
|
||||
<file>memberCompletion.cpp</file>
|
||||
<file>myheader.h</file>
|
||||
<file>mysource.cpp</file>
|
||||
<file>objc_messages_1.mm</file>
|
||||
<file>objc_messages_2.mm</file>
|
||||
<file>objc_messages_3.mm</file>
|
||||
<file>preprocessorKeywordsCompletion.cpp</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
Reference in New Issue
Block a user