2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2018 The Qt Company Ltd.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2018-07-13 12:33:46 +02:00
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
2019-09-18 14:43:08 +02:00
|
|
|
#include "languageclient_global.h"
|
2023-09-05 11:14:10 +02:00
|
|
|
#include "languageclientsymbolsupport.h"
|
2022-05-19 14:55:15 +02:00
|
|
|
#include "languageclientutils.h"
|
2021-02-25 12:54:14 +01:00
|
|
|
#include "semantichighlightsupport.h"
|
2018-07-13 12:33:46 +02:00
|
|
|
|
|
|
|
|
namespace Core { class IDocument; }
|
|
|
|
|
namespace ProjectExplorer { class Project; }
|
|
|
|
|
namespace TextEditor
|
|
|
|
|
{
|
2020-03-26 09:21:57 +01:00
|
|
|
class IAssistProcessor;
|
2019-02-01 14:08:02 +01:00
|
|
|
class TextDocument;
|
|
|
|
|
class TextEditorWidget;
|
2018-07-13 12:33:46 +02:00
|
|
|
}
|
|
|
|
|
|
2023-08-23 17:26:02 +02:00
|
|
|
namespace Utils { namespace Text { class Range; } }
|
|
|
|
|
|
2021-11-16 12:27:23 +01:00
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
|
class QWidget;
|
|
|
|
|
QT_END_NAMESPACE
|
|
|
|
|
|
2022-05-19 14:55:15 +02:00
|
|
|
namespace LanguageServerProtocol {
|
|
|
|
|
class ClientCapabilities;
|
|
|
|
|
class ClientInfo;
|
|
|
|
|
class ProgressToken;
|
|
|
|
|
class PublishDiagnosticsParams;
|
|
|
|
|
class Registration;
|
|
|
|
|
class ServerCapabilities;
|
|
|
|
|
class Unregistration;
|
|
|
|
|
} // namespace LanguageServerProtocol
|
|
|
|
|
|
2018-07-13 12:33:46 +02:00
|
|
|
namespace LanguageClient {
|
2019-01-31 08:46:23 +01:00
|
|
|
class BaseClientInterface;
|
2022-05-19 14:55:15 +02:00
|
|
|
class ClientPrivate;
|
|
|
|
|
class DiagnosticManager;
|
|
|
|
|
class DocumentSymbolCache;
|
|
|
|
|
class DynamicCapabilities;
|
|
|
|
|
class HoverHandler;
|
2022-05-11 14:01:49 +02:00
|
|
|
class InterfaceController;
|
2022-05-19 14:55:15 +02:00
|
|
|
class LanguageClientCompletionAssistProvider;
|
2023-02-03 14:46:00 +01:00
|
|
|
class LanguageClientOutlineItem;
|
2022-05-19 14:55:15 +02:00
|
|
|
class LanguageClientQuickFixProvider;
|
|
|
|
|
class LanguageFilter;
|
2023-01-12 13:24:15 +01:00
|
|
|
class ProgressManager;
|
2019-01-31 08:46:23 +01:00
|
|
|
|
2019-09-18 14:43:08 +02:00
|
|
|
class LANGUAGECLIENT_EXPORT Client : public QObject
|
2018-07-13 12:33:46 +02:00
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
2023-04-23 10:34:37 +02:00
|
|
|
Q_DISABLE_COPY_MOVE(Client)
|
2018-07-13 12:33:46 +02:00
|
|
|
|
|
|
|
|
public:
|
2023-01-11 13:24:49 +01:00
|
|
|
explicit Client(BaseClientInterface *clientInterface, const Utils::Id &id = {}); // takes ownership
|
2019-01-31 12:15:43 +01:00
|
|
|
~Client() override;
|
2018-07-13 12:33:46 +02:00
|
|
|
|
2021-02-15 12:01:53 +01:00
|
|
|
// basic properties
|
2022-05-19 14:55:15 +02:00
|
|
|
Utils::Id id() const;
|
|
|
|
|
void setName(const QString &name);
|
2021-02-23 09:22:11 +01:00
|
|
|
QString name() const;
|
2021-07-08 12:11:15 +02:00
|
|
|
|
|
|
|
|
enum class SendDocUpdates { Send, Ignore };
|
2022-05-12 09:51:39 +02:00
|
|
|
void sendMessage(const LanguageServerProtocol::JsonRpcMessage &message,
|
2022-05-20 15:27:32 +02:00
|
|
|
SendDocUpdates sendUpdates = SendDocUpdates::Send,
|
|
|
|
|
Schedule semanticTokensSchedule = Schedule::Delayed);
|
2021-07-08 12:11:15 +02:00
|
|
|
|
2021-02-15 12:01:53 +01:00
|
|
|
void cancelRequest(const LanguageServerProtocol::MessageId &id);
|
|
|
|
|
|
|
|
|
|
// server state handling
|
|
|
|
|
void start();
|
|
|
|
|
void setInitializationOptions(const QJsonObject& initializationOptions);
|
|
|
|
|
void initialize();
|
|
|
|
|
bool reset();
|
|
|
|
|
void shutdown();
|
2018-07-13 12:33:46 +02:00
|
|
|
enum State {
|
|
|
|
|
Uninitialized,
|
|
|
|
|
InitializeRequested,
|
|
|
|
|
Initialized,
|
|
|
|
|
ShutdownRequested,
|
|
|
|
|
Shutdown,
|
|
|
|
|
Error
|
|
|
|
|
};
|
|
|
|
|
State state() const;
|
2021-11-01 07:20:40 +01:00
|
|
|
QString stateString() const;
|
2022-05-19 14:55:15 +02:00
|
|
|
bool reachable() const;
|
2018-07-13 12:33:46 +02:00
|
|
|
|
2022-05-03 13:24:46 +02:00
|
|
|
void setClientInfo(const LanguageServerProtocol::ClientInfo &clientInfo);
|
2021-02-15 12:01:53 +01:00
|
|
|
// capabilities
|
2021-02-23 13:51:41 +01:00
|
|
|
static LanguageServerProtocol::ClientCapabilities defaultClientCapabilities();
|
|
|
|
|
void setClientCapabilities(const LanguageServerProtocol::ClientCapabilities &caps);
|
2021-02-15 12:01:53 +01:00
|
|
|
const LanguageServerProtocol::ServerCapabilities &capabilities() const;
|
2022-05-19 14:55:15 +02:00
|
|
|
QString serverName() const;
|
|
|
|
|
QString serverVersion() const;
|
2021-02-15 12:01:53 +01:00
|
|
|
const DynamicCapabilities &dynamicCapabilities() const;
|
|
|
|
|
void registerCapabilities(const QList<LanguageServerProtocol::Registration> ®istrations);
|
|
|
|
|
void unregisterCapabilities(const QList<LanguageServerProtocol::Unregistration> &unregistrations);
|
|
|
|
|
|
2022-05-19 14:55:15 +02:00
|
|
|
void setLocatorsEnabled(bool enabled);
|
|
|
|
|
bool locatorsEnabled() const;
|
|
|
|
|
void setAutoRequestCodeActions(bool enabled);
|
2021-02-23 13:51:41 +01:00
|
|
|
|
2018-07-13 12:33:46 +02:00
|
|
|
// document synchronization
|
2021-02-15 12:01:53 +01:00
|
|
|
void setSupportedLanguage(const LanguageFilter &filter);
|
2021-04-20 11:40:24 +02:00
|
|
|
void setActivateDocumentAutomatically(bool enabled);
|
2021-02-15 12:01:53 +01:00
|
|
|
bool isSupportedDocument(const TextEditor::TextDocument *document) const;
|
|
|
|
|
bool isSupportedFile(const Utils::FilePath &filePath, const QString &mimeType) const;
|
|
|
|
|
bool isSupportedUri(const LanguageServerProtocol::DocumentUri &uri) const;
|
2022-03-14 10:09:55 +01:00
|
|
|
virtual void openDocument(TextEditor::TextDocument *document);
|
2023-01-23 11:27:38 +01:00
|
|
|
void closeDocument(TextEditor::TextDocument *document,
|
|
|
|
|
const std::optional<Utils::FilePath> &overwriteFilePath = {});
|
2019-09-10 08:03:58 +02:00
|
|
|
void activateDocument(TextEditor::TextDocument *document);
|
2022-09-23 11:50:46 +02:00
|
|
|
void activateEditor(Core::IEditor *editor);
|
2019-09-10 08:03:58 +02:00
|
|
|
void deactivateDocument(TextEditor::TextDocument *document);
|
2020-01-08 12:03:54 +01:00
|
|
|
bool documentOpen(const TextEditor::TextDocument *document) const;
|
2021-04-29 15:39:37 +02:00
|
|
|
TextEditor::TextDocument *documentForFilePath(const Utils::FilePath &file) const;
|
2022-05-31 16:35:10 +02:00
|
|
|
void setShadowDocument(const Utils::FilePath &filePath, const QString &contents);
|
|
|
|
|
void removeShadowDocument(const Utils::FilePath &filePath);
|
2019-09-11 11:15:39 +02:00
|
|
|
void documentContentsSaved(TextEditor::TextDocument *document);
|
2018-07-13 12:33:46 +02:00
|
|
|
void documentWillSave(Core::IDocument *document);
|
2019-04-02 10:49:23 +02:00
|
|
|
void documentContentsChanged(TextEditor::TextDocument *document,
|
|
|
|
|
int position,
|
|
|
|
|
int charsRemoved,
|
|
|
|
|
int charsAdded);
|
2018-07-13 12:33:46 +02:00
|
|
|
void cursorPositionChanged(TextEditor::TextEditorWidget *widget);
|
2021-02-15 12:01:53 +01:00
|
|
|
bool documentUpdatePostponed(const Utils::FilePath &fileName) const;
|
2021-06-14 11:47:04 +02:00
|
|
|
int documentVersion(const Utils::FilePath &filePath) const;
|
2022-12-15 07:23:55 +01:00
|
|
|
int documentVersion(const LanguageServerProtocol::DocumentUri &uri) const;
|
2021-08-12 12:00:58 +02:00
|
|
|
void setDocumentChangeUpdateThreshold(int msecs);
|
2018-07-13 12:33:46 +02:00
|
|
|
|
2021-02-15 12:01:53 +01:00
|
|
|
// workspace control
|
2021-02-22 12:09:52 +01:00
|
|
|
virtual void setCurrentProject(ProjectExplorer::Project *project);
|
2021-09-23 12:11:31 +02:00
|
|
|
ProjectExplorer::Project *project() const;
|
2021-02-22 12:09:52 +01:00
|
|
|
virtual void projectOpened(ProjectExplorer::Project *project);
|
|
|
|
|
virtual void projectClosed(ProjectExplorer::Project *project);
|
2023-05-24 10:09:22 +02:00
|
|
|
virtual bool canOpenProject(ProjectExplorer::Project *project);
|
2022-01-13 07:52:08 +01:00
|
|
|
void updateConfiguration(const QJsonValue &configuration);
|
2020-05-06 10:26:31 +02:00
|
|
|
|
2021-02-15 12:01:53 +01:00
|
|
|
// commands
|
2022-02-04 10:59:11 +01:00
|
|
|
void requestCodeActions(const LanguageServerProtocol::DocumentUri &uri,
|
|
|
|
|
const LanguageServerProtocol::Diagnostic &diagnostic);
|
2019-01-25 09:48:44 +01:00
|
|
|
void requestCodeActions(const LanguageServerProtocol::DocumentUri &uri,
|
|
|
|
|
const QList<LanguageServerProtocol::Diagnostic> &diagnostics);
|
2019-01-29 13:20:58 +01:00
|
|
|
void requestCodeActions(const LanguageServerProtocol::CodeActionRequest &request);
|
2019-01-25 09:48:44 +01:00
|
|
|
void handleCodeActionResponse(const LanguageServerProtocol::CodeActionRequest::Response &response,
|
|
|
|
|
const LanguageServerProtocol::DocumentUri &uri);
|
2021-02-12 14:05:10 +01:00
|
|
|
virtual void executeCommand(const LanguageServerProtocol::Command &command);
|
2019-01-25 09:48:44 +01:00
|
|
|
|
2021-02-15 12:01:53 +01:00
|
|
|
// language support
|
2020-03-26 09:21:57 +01:00
|
|
|
void addAssistProcessor(TextEditor::IAssistProcessor *processor);
|
|
|
|
|
void removeAssistProcessor(TextEditor::IAssistProcessor *processor);
|
2021-02-15 12:01:53 +01:00
|
|
|
SymbolSupport &symbolSupport();
|
2023-08-08 15:30:55 +02:00
|
|
|
// In contrast to the findLinkAt of symbol support this find link makes sure that there is only
|
|
|
|
|
// one request running at a time and cancels the running request if the document changes, cursor
|
|
|
|
|
// moves or another link is requested
|
|
|
|
|
void findLinkAt(TextEditor::TextDocument *document,
|
|
|
|
|
const QTextCursor &cursor,
|
|
|
|
|
Utils::LinkHandler callback,
|
2023-09-05 11:14:10 +02:00
|
|
|
const bool resolveTarget,
|
|
|
|
|
LinkTarget target);
|
2021-02-15 12:01:53 +01:00
|
|
|
DocumentSymbolCache *documentSymbolCache();
|
|
|
|
|
HoverHandler *hoverHandler();
|
2022-12-15 07:23:55 +01:00
|
|
|
QList<LanguageServerProtocol::Diagnostic> diagnosticsAt(const Utils::FilePath &filePath,
|
|
|
|
|
const QTextCursor &cursor) const;
|
|
|
|
|
bool hasDiagnostic(const Utils::FilePath &filePath,
|
2021-06-02 17:51:31 +02:00
|
|
|
const LanguageServerProtocol::Diagnostic &diag) const;
|
2022-05-11 06:38:50 +02:00
|
|
|
bool hasDiagnostics(const TextEditor::TextDocument *document) const;
|
2021-06-09 09:47:26 +02:00
|
|
|
void setSemanticTokensHandler(const SemanticTokensHandler &handler);
|
2021-06-18 16:30:03 +02:00
|
|
|
void setSnippetsGroup(const QString &group);
|
2021-09-13 16:09:04 +02:00
|
|
|
void setCompletionAssistProvider(LanguageClientCompletionAssistProvider *provider);
|
2022-01-31 13:10:28 +01:00
|
|
|
void setQuickFixAssistProvider(LanguageClientQuickFixProvider *provider);
|
2021-12-10 10:49:30 +01:00
|
|
|
virtual bool supportsDocumentSymbols(const TextEditor::TextDocument *doc) const;
|
2022-08-24 11:16:20 +02:00
|
|
|
virtual bool fileBelongsToProject(const Utils::FilePath &filePath) const;
|
2023-02-03 14:46:00 +01:00
|
|
|
virtual LanguageClientOutlineItem *createOutlineItem(
|
|
|
|
|
const LanguageServerProtocol::DocumentSymbol &symbol);
|
2019-01-29 13:20:58 +01:00
|
|
|
|
2022-12-15 07:23:55 +01:00
|
|
|
LanguageServerProtocol::DocumentUri::PathMapper hostPathMapper() const;
|
|
|
|
|
Utils::FilePath serverUriToHostPath(const LanguageServerProtocol::DocumentUri &uri) const;
|
|
|
|
|
LanguageServerProtocol::DocumentUri hostPathToServerUri(const Utils::FilePath &path) const;
|
2023-07-03 13:03:21 +02:00
|
|
|
Utils::OsType osType() const;
|
2022-12-15 07:23:55 +01:00
|
|
|
|
2023-06-07 15:45:56 +02:00
|
|
|
// custom methods
|
|
|
|
|
using CustomMethodHandler = std::function<void(
|
|
|
|
|
const LanguageServerProtocol::JsonRpcMessage &message)>;
|
|
|
|
|
void registerCustomMethod(const QString &method, const CustomMethodHandler &handler);
|
|
|
|
|
|
2021-02-15 12:01:53 +01:00
|
|
|
// logging
|
2021-10-15 10:40:02 +02:00
|
|
|
enum class LogTarget { Console, Ui };
|
2022-05-19 14:55:15 +02:00
|
|
|
void setLogTarget(LogTarget target);
|
2021-02-15 12:01:53 +01:00
|
|
|
void log(const QString &message) const;
|
|
|
|
|
template<typename Error>
|
|
|
|
|
void log(const LanguageServerProtocol::ResponseError<Error> &responseError) const
|
|
|
|
|
{ log(responseError.toString()); }
|
2020-06-17 14:15:13 +02:00
|
|
|
|
2021-11-16 12:27:23 +01:00
|
|
|
// Caller takes ownership.
|
|
|
|
|
using CustomInspectorTab = std::pair<QWidget *, QString>;
|
|
|
|
|
using CustomInspectorTabs = QList<CustomInspectorTab>;
|
|
|
|
|
virtual const CustomInspectorTabs createCustomInspectorTabs() { return {}; }
|
|
|
|
|
|
2022-02-03 10:36:40 +01:00
|
|
|
// Caller takes ownership
|
|
|
|
|
virtual TextEditor::RefactoringChangesData *createRefactoringChangesBackend() const;
|
|
|
|
|
|
2022-08-03 13:54:42 +02:00
|
|
|
void setCompletionResultsLimit(int limit);
|
|
|
|
|
int completionResultsLimit() const;
|
|
|
|
|
|
2018-07-13 12:33:46 +02:00
|
|
|
signals:
|
2021-02-11 09:32:11 +01:00
|
|
|
void initialized(const LanguageServerProtocol::ServerCapabilities &capabilities);
|
|
|
|
|
void capabilitiesChanged(const DynamicCapabilities &capabilities);
|
2020-06-17 14:15:13 +02:00
|
|
|
void documentUpdated(TextEditor::TextDocument *document);
|
2021-04-20 15:46:35 +02:00
|
|
|
void workDone(const LanguageServerProtocol::ProgressToken &token);
|
2022-05-31 16:35:10 +02:00
|
|
|
void shadowDocumentSwitched(const Utils::FilePath &filePath);
|
2018-07-13 12:33:46 +02:00
|
|
|
void finished();
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
void setError(const QString &message);
|
2023-01-12 13:24:15 +01:00
|
|
|
ProgressManager *progressManager();
|
2022-05-12 09:51:39 +02:00
|
|
|
void handleMessage(const LanguageServerProtocol::JsonRpcMessage &message);
|
2021-06-02 17:51:31 +02:00
|
|
|
virtual void handleDiagnostics(const LanguageServerProtocol::PublishDiagnosticsParams ¶ms);
|
2022-04-01 07:34:49 +02:00
|
|
|
virtual DiagnosticManager *createDiagnosticManager();
|
2018-07-13 12:33:46 +02:00
|
|
|
|
|
|
|
|
private:
|
2022-05-19 14:55:15 +02:00
|
|
|
friend class ClientPrivate;
|
|
|
|
|
ClientPrivate *d = nullptr;
|
2021-02-15 12:01:53 +01:00
|
|
|
|
2021-06-09 09:47:26 +02:00
|
|
|
virtual void handleDocumentClosed(TextEditor::TextDocument *) {}
|
2021-09-27 16:24:37 +02:00
|
|
|
virtual void handleDocumentOpened(TextEditor::TextDocument *) {}
|
2021-12-02 13:18:02 +01:00
|
|
|
virtual QTextCursor adjustedCursorForHighlighting(const QTextCursor &cursor,
|
|
|
|
|
TextEditor::TextDocument *doc);
|
2022-07-25 15:25:56 +02:00
|
|
|
virtual bool referencesShadowFile(const TextEditor::TextDocument *doc,
|
|
|
|
|
const Utils::FilePath &candidate);
|
2023-08-23 17:26:02 +02:00
|
|
|
virtual QList<Utils::Text::Range> additionalDocumentHighlights(
|
|
|
|
|
TextEditor::TextEditorWidget *, const QTextCursor &) { return {}; }
|
2018-07-13 12:33:46 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace LanguageClient
|