Merge remote-tracking branch 'origin/3.6'

Change-Id: Iddfa0d2f3c0fb8ba65c0e5d479ad8e2f2cb95685
This commit is contained in:
Eike Ziller
2015-10-26 10:55:45 +01:00
285 changed files with 6092 additions and 2844 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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 {

View File

@@ -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: [

View File

@@ -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),

View File

@@ -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);

View File

@@ -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

View File

@@ -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))

View File

@@ -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()

View File

@@ -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);
}
}

View File

@@ -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:

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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()

View File

@@ -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();

View File

@@ -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>