File indexing completed on 2024-04-28 05:48:58

0001 /*
0002     SPDX-FileCopyrightText: 2019 Mark Nauwelaerts <mark.nauwelaerts@gmail.com>
0003 
0004     SPDX-License-Identifier: MIT
0005 */
0006 
0007 #pragma once
0008 
0009 #include <QHash>
0010 #include <QJsonArray>
0011 #include <QJsonObject>
0012 #include <QList>
0013 #include <QString>
0014 #include <QUrl>
0015 
0016 #include "lspsemantichighlighting.h"
0017 #include "semantic_tokens_legend.h"
0018 #include <diagnostics/diagnostic_types.h>
0019 
0020 #include <KTextEditor/Cursor>
0021 #include <KTextEditor/Range>
0022 
0023 #include <memory>
0024 #include <optional>
0025 
0026 // Following types roughly follow the types/interfaces as defined in LSP protocol spec
0027 // although some deviation may arise where it has been deemed useful
0028 // Moreover, to avoid introducing a custom 'optional' type, absence of an optional
0029 // part/member is usually signalled by some 'invalid' marker (empty, negative).
0030 
0031 enum class LSPErrorCode {
0032     // Defined by JSON RPC
0033     ParseError = -32700,
0034     InvalidRequest = -32600,
0035     MethodNotFound = -32601,
0036     InvalidParams = -32602,
0037     InternalError = -32603,
0038     serverErrorStart = -32099,
0039     serverErrorEnd = -32000,
0040     ServerNotInitialized = -32002,
0041     UnknownErrorCode = -32001,
0042 
0043     // Defined by the protocol.
0044     RequestCancelled = -32800,
0045     ContentModified = -32801
0046 };
0047 
0048 struct LSPResponseError {
0049     LSPErrorCode code{};
0050     QString message;
0051     QByteArray data;
0052 };
0053 
0054 enum class LSPDocumentSyncKind { None = 0, Full = 1, Incremental = 2 };
0055 
0056 struct LSPSaveOptions {
0057     bool includeText = false;
0058 };
0059 
0060 // only used parts for now
0061 struct LSPTextDocumentSyncOptions {
0062     LSPDocumentSyncKind change = LSPDocumentSyncKind::None;
0063     std::optional<LSPSaveOptions> save;
0064 };
0065 
0066 struct LSPCompletionOptions {
0067     bool provider = false;
0068     bool resolveProvider = false;
0069     QList<QChar> triggerCharacters;
0070 };
0071 
0072 struct LSPSignatureHelpOptions {
0073     bool provider = false;
0074     QList<QChar> triggerCharacters;
0075 };
0076 
0077 // ensure distinct type
0078 struct LSPDocumentOnTypeFormattingOptions : public LSPSignatureHelpOptions {
0079 };
0080 
0081 // Ref: https://microsoft.github.io/language-server-protocol/specification#textDocument_semanticTokens
0082 struct LSPSemanticTokensOptions {
0083     bool full = false;
0084     bool fullDelta = false;
0085     bool range = false;
0086     SemanticTokensLegend legend;
0087     //     QList<QString> types;
0088 };
0089 
0090 struct LSPWorkspaceFoldersServerCapabilities {
0091     bool supported = false;
0092     bool changeNotifications = false;
0093 };
0094 
0095 struct LSPServerCapabilities {
0096     LSPTextDocumentSyncOptions textDocumentSync;
0097     bool hoverProvider = false;
0098     LSPCompletionOptions completionProvider;
0099     LSPSignatureHelpOptions signatureHelpProvider;
0100     bool definitionProvider = false;
0101     // official extension as of 3.14.0
0102     bool declarationProvider = false;
0103     bool typeDefinitionProvider = false;
0104     bool referencesProvider = false;
0105     bool implementationProvider = false;
0106     bool documentSymbolProvider = false;
0107     bool documentHighlightProvider = false;
0108     bool documentFormattingProvider = false;
0109     bool documentRangeFormattingProvider = false;
0110     LSPDocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
0111     bool renameProvider = false;
0112     // CodeActionOptions not useful/considered at present
0113     bool codeActionProvider = false;
0114     LSPSemanticTokensOptions semanticTokenProvider;
0115     // workspace caps flattened
0116     // (other parts not useful/considered at present)
0117     LSPWorkspaceFoldersServerCapabilities workspaceFolders;
0118     bool selectionRangeProvider = false;
0119     bool inlayHintProvider = false;
0120 };
0121 
0122 enum class LSPMarkupKind { None = 0, PlainText = 1, MarkDown = 2 };
0123 
0124 struct LSPMarkupContent {
0125     LSPMarkupKind kind = LSPMarkupKind::None;
0126     QString value;
0127 };
0128 
0129 /**
0130  * Language Server Protocol Position
0131  * line + column, 0 based, negative for invalid
0132  * maps 1:1 to KTextEditor::Cursor
0133  */
0134 using LSPPosition = KTextEditor::Cursor;
0135 
0136 /**
0137  * Language Server Protocol Range
0138  * start + end tuple of LSPPosition
0139  * maps 1:1 to KTextEditor::Range
0140  */
0141 using LSPRange = KTextEditor::Range;
0142 
0143 using LSPLocation = SourceLocation;
0144 // struct LSPLocation {
0145 //     QUrl uri;
0146 //     LSPRange range;
0147 // };
0148 
0149 struct LSPTextDocumentContentChangeEvent {
0150     LSPRange range;
0151     QString text;
0152 };
0153 
0154 enum class LSPDocumentHighlightKind { Text = 1, Read = 2, Write = 3 };
0155 
0156 struct LSPDocumentHighlight {
0157     LSPRange range;
0158     LSPDocumentHighlightKind kind;
0159 };
0160 
0161 struct LSPHover {
0162     // vector for contents to support all three variants:
0163     // MarkedString | MarkedString[] | MarkupContent
0164     // vector variant is still in use e.g. by Rust rls
0165     QList<LSPMarkupContent> contents;
0166     LSPRange range;
0167 };
0168 
0169 enum class LSPSymbolKind {
0170     File = 1,
0171     Module = 2,
0172     Namespace = 3,
0173     Package = 4,
0174     Class = 5,
0175     Method = 6,
0176     Property = 7,
0177     Field = 8,
0178     Constructor = 9,
0179     Enum = 10,
0180     Interface = 11,
0181     Function = 12,
0182     Variable = 13,
0183     Constant = 14,
0184     String = 15,
0185     Number = 16,
0186     Boolean = 17,
0187     Array = 18,
0188     Object = 19,
0189     Key = 20,
0190     Null = 21,
0191     EnumMember = 22,
0192     Struct = 23,
0193     Event = 24,
0194     Operator = 25,
0195     TypeParameter = 26,
0196 };
0197 
0198 enum class LSPSymbolTag : uint8_t {
0199     Deprecated = 1,
0200 };
0201 
0202 struct LSPSymbolInformation {
0203     LSPSymbolInformation() = default;
0204     LSPSymbolInformation(const QString &_name, LSPSymbolKind _kind, LSPRange _range, const QString &_detail)
0205         : name(_name)
0206         , detail(_detail)
0207         , kind(_kind)
0208         , range(_range)
0209     {
0210     }
0211     QString name;
0212     QString detail;
0213     LSPSymbolKind kind;
0214     QUrl url;
0215     LSPRange range;
0216     double score = 0.0;
0217     LSPSymbolTag tags;
0218     std::list<LSPSymbolInformation> children;
0219 };
0220 
0221 struct LSPTextEdit {
0222     LSPRange range;
0223     QString newText;
0224 };
0225 
0226 struct LSPSelectionRange {
0227     LSPRange range;
0228     std::shared_ptr<LSPSelectionRange> parent;
0229 };
0230 
0231 enum class LSPCompletionItemKind {
0232     Text = 1,
0233     Method = 2,
0234     Function = 3,
0235     Constructor = 4,
0236     Field = 5,
0237     Variable = 6,
0238     Class = 7,
0239     Interface = 8,
0240     Module = 9,
0241     Property = 10,
0242     Unit = 11,
0243     Value = 12,
0244     Enum = 13,
0245     Keyword = 14,
0246     Snippet = 15,
0247     Color = 16,
0248     File = 17,
0249     Reference = 18,
0250     Folder = 19,
0251     EnumMember = 20,
0252     Constant = 21,
0253     Struct = 22,
0254     Event = 23,
0255     Operator = 24,
0256     TypeParameter = 25,
0257 };
0258 
0259 struct LSPCompletionItem {
0260     QString label;
0261     QString originalLabel; // needed for completionItem/resolve
0262     LSPCompletionItemKind kind = LSPCompletionItemKind::Text;
0263     QString detail;
0264     LSPMarkupContent documentation;
0265     QString sortText;
0266     QString insertText;
0267     QList<LSPTextEdit> additionalTextEdits;
0268     // textEdit is unused because doesn't work well
0269     // with KTE. See: https://invent.kde.org/utilities/kate/-/merge_requests/438
0270     // We still read it so that it can be used with completionItem/resolve
0271     LSPTextEdit textEdit;
0272     QByteArray data;
0273 };
0274 
0275 struct LSPParameterInformation {
0276     // offsets into overall signature label
0277     // (-1 if invalid)
0278     int start;
0279     int end;
0280 };
0281 
0282 struct LSPSignatureInformation {
0283     QString label;
0284     LSPMarkupContent documentation;
0285     QList<LSPParameterInformation> parameters;
0286 };
0287 
0288 struct LSPSignatureHelp {
0289     QList<LSPSignatureInformation> signatures;
0290     int activeSignature;
0291     int activeParameter;
0292 };
0293 
0294 struct LSPFormattingOptions {
0295     int tabSize;
0296     bool insertSpaces;
0297     // additional fields
0298     QJsonObject extra;
0299 };
0300 
0301 using LSPDiagnosticSeverity = DiagnosticSeverity;
0302 
0303 using LSPDiagnosticRelatedInformation = DiagnosticRelatedInformation;
0304 
0305 using LSPDiagnostic = Diagnostic;
0306 
0307 using LSPPublishDiagnosticsParams = FileDiagnostics;
0308 
0309 enum class LSPMessageType { Error = 1, Warning = 2, Info = 3, Log = 4 };
0310 
0311 struct LSPShowMessageParams {
0312     LSPMessageType type;
0313     QString message;
0314 };
0315 
0316 using LSPLogMessageParams = LSPShowMessageParams;
0317 
0318 enum class LSPWorkDoneProgressKind { Begin, Report, End };
0319 
0320 // combines following similar interfaces
0321 // WorkDoneProgressBegin
0322 // WorkDoneProgressReport
0323 // WorkDoneProgressEnd
0324 struct LSPWorkDoneProgressValue {
0325     LSPWorkDoneProgressKind kind;
0326     QString title;
0327     QString message;
0328     bool cancellable;
0329     std::optional<unsigned> percentage;
0330 };
0331 
0332 template<typename T>
0333 struct LSPProgressParams {
0334     // number or string
0335     QJsonValue token;
0336     T value;
0337 };
0338 
0339 // alias convenience
0340 using LSPWorkDoneProgressParams = LSPProgressParams<LSPWorkDoneProgressValue>;
0341 
0342 struct LSPSemanticHighlightingToken {
0343     quint32 character = 0;
0344     quint16 length = 0;
0345     quint16 scope = 0;
0346 };
0347 Q_DECLARE_TYPEINFO(LSPSemanticHighlightingToken, Q_MOVABLE_TYPE);
0348 
0349 struct LSPSemanticHighlightingInformation {
0350     int line = -1;
0351     QList<LSPSemanticHighlightingToken> tokens;
0352 };
0353 
0354 struct LSPVersionedTextDocumentIdentifier {
0355     QUrl uri;
0356     int version = -1;
0357 };
0358 
0359 struct LSPSemanticHighlightingParams {
0360     LSPVersionedTextDocumentIdentifier textDocument;
0361     QList<LSPSemanticHighlightingInformation> lines;
0362 };
0363 
0364 struct LSPCommand {
0365     QString title;
0366     QString command;
0367     // pretty opaque
0368     QByteArray arguments;
0369 };
0370 
0371 struct LSPTextDocumentEdit {
0372     LSPVersionedTextDocumentIdentifier textDocument;
0373     QList<LSPTextEdit> edits;
0374 };
0375 
0376 struct LSPWorkspaceEdit {
0377     // supported part for now
0378     QHash<QUrl, QList<LSPTextEdit>> changes;
0379     QList<LSPTextDocumentEdit> documentChanges;
0380 };
0381 
0382 struct LSPCodeAction {
0383     QString title;
0384     QString kind;
0385     QList<LSPDiagnostic> diagnostics;
0386     LSPWorkspaceEdit edit;
0387     LSPCommand command;
0388 };
0389 
0390 struct LSPApplyWorkspaceEditParams {
0391     QString label;
0392     LSPWorkspaceEdit edit;
0393 };
0394 
0395 struct LSPApplyWorkspaceEditResponse {
0396     bool applied;
0397     QString failureReason;
0398 };
0399 
0400 struct LSPWorkspaceFolder {
0401     QUrl uri;
0402     QString name;
0403 };
0404 
0405 struct LSPSemanticTokensEdit {
0406     uint32_t start = 0;
0407     uint32_t deleteCount = 0;
0408     std::vector<uint32_t> data;
0409 };
0410 
0411 struct LSPSemanticTokensDelta {
0412     QString resultId;
0413     std::vector<LSPSemanticTokensEdit> edits;
0414     std::vector<uint32_t> data;
0415 };
0416 
0417 struct LSPExpandedMacro {
0418     QString name;
0419     QString expansion;
0420 };
0421 
0422 struct LSPInlayHint {
0423     LSPPosition position;
0424     QString label;
0425     bool paddingLeft = false;
0426     bool paddingRight = false;
0427     // unused fields atm, not sure if we will need them
0428     // enum Kind { Type = 1, Parameter = 2 } kind;
0429     // QString tooltip;
0430 
0431     // kate specific
0432     int width = 0; ///> Used to cache width
0433 };
0434 
0435 struct LSPMessageRequestAction {
0436     QString title;
0437     std::function<void()> choose;
0438 };