clangbackendipcintegration.h 8.78 KB
Newer Older
1 2
/****************************************************************************
**
3 4
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
5 6 7 8 9 10 11
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
12 13 14
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
15
**
16 17 18 19 20 21 22
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 24 25
**
****************************************************************************/

hjk's avatar
hjk committed
26
#pragma once
27

28
#include <cpptools/projectpart.h>
Ivan Donchevskii's avatar
Ivan Donchevskii committed
29
#include <cpptools/cppcursorinfo.h>
30

31
#include <clangbackendipc/clangcodemodelconnectionclient.h>
32
#include <clangbackendipc/filecontainer.h>
33
#include <clangbackendipc/clangcodemodelclientinterface.h>
34
#include <clangbackendipc/projectpartcontainer.h>
35

36
#include <QFuture>
37
#include <QObject>
38
#include <QPointer>
39
#include <QSharedPointer>
40
#include <QTextDocument>
41 42
#include <QVector>

43 44
#include <functional>

45 46 47 48 49
namespace Core {
class IEditor;
class IDocument;
}

Marco Bubke's avatar
Marco Bubke committed
50
namespace ClangBackEnd {
51
class DocumentAnnotationsChangedMessage;
Marco Bubke's avatar
Marco Bubke committed
52 53
}

54 55
namespace TextEditor {
class TextEditorWidget;
56
class TextDocument;
57 58 59 60 61 62 63 64 65
}

namespace ClangCodeModel {
namespace Internal {

class ModelManagerSupportClang;

class ClangCompletionAssistProcessor;

66
class IpcReceiver : public ClangBackEnd::ClangCodeModelClientInterface
67 68 69 70 71 72 73 74
{
public:
    IpcReceiver();
    ~IpcReceiver();

    using AliveHandler = std::function<void ()>;
    void setAliveHandler(const AliveHandler &handler);

Marco Bubke's avatar
Marco Bubke committed
75
    void addExpectedCodeCompletedMessage(quint64 ticket, ClangCompletionAssistProcessor *processor);
76 77 78
    void deleteAndClearWaitingAssistProcessors();
    void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget);

79 80 81
    QFuture<CppTools::CursorInfo> addExpectedReferencesMessage(quint64 ticket,
                                                               QTextDocument *textDocument);

82 83
    bool isExpectingCodeCompletedMessage() const;

84 85
private:
    void alive() override;
Marco Bubke's avatar
Marco Bubke committed
86 87
    void echo(const ClangBackEnd::EchoMessage &message) override;
    void codeCompleted(const ClangBackEnd::CodeCompletedMessage &message) override;
88 89

    void documentAnnotationsChanged(const ClangBackEnd::DocumentAnnotationsChangedMessage &message) override;
90
    void references(const ClangBackEnd::ReferencesMessage &message) override;
91

Nikolai Kosjar's avatar
Nikolai Kosjar committed
92 93
    void translationUnitDoesNotExist(const ClangBackEnd::TranslationUnitDoesNotExistMessage &) override {}
    void projectPartsDoNotExist(const ClangBackEnd::ProjectPartsDoNotExistMessage &) override {}
94 95 96 97

private:
    AliveHandler m_aliveHandler;
    QHash<quint64, ClangCompletionAssistProcessor *> m_assistProcessorsTable;
98 99

    struct ReferencesEntry {
100 101 102 103 104
        ReferencesEntry() = default;
        ReferencesEntry(QFutureInterface<CppTools::CursorInfo> futureInterface,
                        QTextDocument *textDocument)
            : futureInterface(futureInterface)
            , textDocument(textDocument) {}
105
        QFutureInterface<CppTools::CursorInfo> futureInterface;
106
        QPointer<QTextDocument> textDocument;
107 108
    };
    QHash<quint64, ReferencesEntry> m_referencesTable;
109 110 111 112 113 114 115 116
};

class IpcSenderInterface
{
public:
    virtual ~IpcSenderInterface() {}

    virtual void end() = 0;
117
    virtual void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) = 0;
118
    virtual void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) = 0;
119 120 121
    virtual void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) = 0;
    virtual void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) = 0;
    virtual void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) = 0;
122 123
    virtual void registerUnsavedFilesForEditor(const ClangBackEnd::RegisterUnsavedFilesForEditorMessage &message) = 0;
    virtual void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) = 0;
Marco Bubke's avatar
Marco Bubke committed
124
    virtual void completeCode(const ClangBackEnd::CompleteCodeMessage &message) = 0;
125
    virtual void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &message) = 0;
126
    virtual void requestReferences(const ClangBackEnd::RequestReferencesMessage &message) = 0;
127
    virtual void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) = 0;
128 129 130 131 132 133 134 135
};

class IpcCommunicator : public QObject
{
    Q_OBJECT

public:
    using Ptr = QSharedPointer<IpcCommunicator>;
136
    using FileContainer = ClangBackEnd::FileContainer;
137 138
    using FileContainers = QVector<ClangBackEnd::FileContainer>;
    using ProjectPartContainers = QVector<ClangBackEnd::ProjectPartContainer>;
139 140 141

public:
    IpcCommunicator();
142
    ~IpcCommunicator();
143

144
    void registerTranslationUnitsForEditor(const FileContainers &fileContainers);
145
    void updateTranslationUnitsForEditor(const FileContainers &fileContainers);
146
    void unregisterTranslationUnitsForEditor(const FileContainers &fileContainers);
147 148
    void registerProjectPartsForEditor(const ProjectPartContainers &projectPartContainers);
    void unregisterProjectPartsForEditor(const QStringList &projectPartIds);
149 150
    void registerUnsavedFilesForEditor(const FileContainers &fileContainers);
    void unregisterUnsavedFilesForEditor(const FileContainers &fileContainers);
151
    void requestDocumentAnnotations(const ClangBackEnd::FileContainer &fileContainer);
152 153 154
    QFuture<CppTools::CursorInfo> requestReferences(const FileContainer &fileContainer,
                                                    quint32 line,
                                                    quint32 column, QTextDocument *textDocument);
155 156 157 158 159
    void completeCode(ClangCompletionAssistProcessor *assistProcessor, const QString &filePath,
                      quint32 line,
                      quint32 column,
                      const QString &projectFilePath);

160
    void registerProjectsParts(const QVector<CppTools::ProjectPart::Ptr> projectParts);
161

162
    void updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document);
163
    void updateTranslationUnit(Core::IDocument *document);
164 165
    void updateUnsavedFile(Core::IDocument *document);
    void updateTranslationUnitFromCppEditorDocument(const QString &filePath);
166
    void updateUnsavedFileFromCppEditorDocument(const QString &filePath);
167
    void updateTranslationUnit(const QString &filePath, const QByteArray &contents, uint documentRevision);
168
    void updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision);
169 170
    void updateTranslationUnitWithRevisionCheck(const ClangBackEnd::FileContainer &fileContainer);
    void updateTranslationUnitWithRevisionCheck(Core::IDocument *document);
171
    void updateChangeContentStartPosition(const QString &filePath, int position);
172

173
    void registerFallbackProjectPart();
174
    void updateTranslationUnitVisiblity();
175

176 177
    bool isNotWaitingForCompletion() const;

178 179 180 181 182 183 184 185 186 187 188
public: // for tests
    IpcSenderInterface *setIpcSender(IpcSenderInterface *ipcSender);
    void killBackendProcess();

signals: // for tests
    void backendReinitialized();

private:
    void initializeBackend();
    void initializeBackendWithCurrentData();
    void registerCurrentProjectParts();
189 190 191
    void restoreCppEditorDocuments();
    void resetCppEditorDocumentProcessors();
    void registerVisibleCppEditorDocumentAndMarkInvisibleDirty();
192
    void registerCurrentCodeModelUiHeaders();
193

194 195
    void setupDummySender();

196
    void onConnectedToBackend();
197
    void onDisconnectedFromBackend();
198 199
    void onEditorAboutToClose(Core::IEditor *editor);

200 201 202 203 204
    void logExecutableDoesNotExist();
    void logRestartedDueToUnexpectedFinish();
    void logStartTimeOut();
    void logError(const QString &text);

205 206 207
    void updateTranslationUnitVisiblity(const Utf8String &currentEditorFilePath,
                                        const Utf8StringVector &visibleEditorsFilePaths);

208
private:
209
    IpcReceiver m_ipcReceiver;
210
    ClangBackEnd::ClangCodeModelConnectionClient m_connection;
211
    QTimer m_backendStartTimeOut;
212
    QScopedPointer<IpcSenderInterface> m_ipcSender;
213
    int m_connectedCount = 0;
214 215 216 217
};

} // namespace Internal
} // namespace ClangCodeModel