1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #pragma once
27 
28 #include "jsonkeys.h"
29 #include "jsonobject.h"
30 #include "jsonrpcmessages.h"
31 #include "languageserverprotocol_global.h"
32 #include "lsptypes.h"
33 
34 namespace LanguageServerProtocol {
35 
36 struct LANGUAGESERVERPROTOCOL_EXPORT SemanticToken
37 {
38     int deltaLine = 0;
39     int deltaStart = 0;
40     int length = 0;
41     int tokenIndex = 0;
42     int tokenType = 0;
43     int rawTokenModifiers = 0;
44     int tokenModifiers = 0;
45 };
46 
47 class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokensLegend : public JsonObject
48 {
49 public:
50     using JsonObject::JsonObject;
51 
52     // The token types a server uses.
tokenTypes()53     QList<QString> tokenTypes() const { return array<QString>(tokenTypesKey); }
setTokenTypes(const QList<QString> & tokenTypes)54     void setTokenTypes(const QList<QString> &tokenTypes) { insertArray(tokenTypesKey, tokenTypes); }
55 
56     // The token modifiers a server uses.
tokenModifiers()57     QList<QString> tokenModifiers() const { return array<QString>(tokenModifiersKey); }
setTokenModifiers(const QList<QString> & value)58     void setTokenModifiers(const QList<QString> &value) { insertArray(tokenModifiersKey, value); }
59 
60     bool isValid() const override;
61 };
62 
63 enum SemanticTokenTypes {
64     namespaceToken,
65     typeToken,
66     classToken,
67     enumToken,
68     interfaceToken,
69     structToken,
70     typeParameterToken,
71     parameterToken,
72     variableToken,
73     propertyToken,
74     enumMemberToken,
75     eventToken,
76     functionToken,
77     methodToken,
78     macroToken,
79     keywordToken,
80     modifierToken,
81     commentToken,
82     stringToken,
83     numberToken,
84     regexpToken,
85     operatorToken
86 };
87 
88 enum SemanticTokenModifiers {
89     declarationModifier = 0x1,
90     definitionModifier = 0x2,
91     readonlyModifier = 0x4,
92     staticModifier = 0x8,
93     deprecatedModifier = 0x10,
94     abstractModifier = 0x20,
95     asyncModifier = 0x40,
96     modificationModifier = 0x80,
97     documentationModifier = 0x100,
98     defaultLibraryModifier = 0x200
99 };
100 
101 class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokensParams : public JsonObject
102 {
103 public:
104     using JsonObject::JsonObject;
105 
textDocument()106     TextDocumentIdentifier textDocument() const
107     { return typedValue<TextDocumentIdentifier>(textDocumentKey); }
setTextDocument(const TextDocumentIdentifier & textDocument)108     void setTextDocument(const TextDocumentIdentifier &textDocument)
109     { insert(textDocumentKey, textDocument); }
110 
isValid()111     bool isValid() const override { return contains(textDocumentKey); }
112 };
113 
114 class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokensDeltaParams : public SemanticTokensParams
115 {
116 public:
117     using SemanticTokensParams::SemanticTokensParams;
118 
previousResultId()119     QString previousResultId() const { return typedValue<QString>(previousResultIdKey); }
setPreviousResultId(const QString & previousResultId)120     void setPreviousResultId(const QString &previousResultId)
121     {
122         insert(previousResultIdKey, previousResultId);
123     }
124 
125     bool isValid() const override;
126 };
127 
128 class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokensRangeParams : public SemanticTokensParams
129 {
130 public:
131     using SemanticTokensParams::SemanticTokensParams;
132 
range()133     Range range() const { return typedValue<Range>(rangeKey); }
setRange(const Range & range)134     void setRange(const Range &range) { insert(rangeKey, range); }
135 
136     bool isValid() const override;
137 };
138 
139 class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokens : public JsonObject
140 {
141 public:
142     using JsonObject::JsonObject;
143 
144     /**
145      * An optional result id. If provided and clients support delta updating
146      * the client will include the result id in the next semantic token request.
147      * A server can then instead of computing all semantic tokens again simply
148      * send a delta.
149      */
resultId()150     Utils::optional<QString> resultId() const { return optionalValue<QString>(resultIdKey); }
setResultId(const QString & resultId)151     void setResultId(const QString &resultId) { insert(resultIdKey, resultId); }
clearResultId()152     void clearResultId() { remove(resultIdKey); }
153 
154     /// The actual tokens.
data()155     QList<int> data() const { return array<int>(dataKey); }
setData(const QList<int> & value)156     void setData(const QList<int> &value) { insertArray(dataKey, value); }
157 
isValid()158     bool isValid() const override { return contains(dataKey); }
159 
160     QList<SemanticToken> toTokens(const QList<int> &tokenTypes,
161                                   const QList<int> &tokenModifiers) const;
162     static QMap<QString, int> defaultTokenTypesMap();
163     static QMap<QString, int> defaultTokenModifiersMap();
164 };
165 
166 class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokensResult
167     : public Utils::variant<SemanticTokens, std::nullptr_t>
168 {
169 public:
170     using variant::variant;
171     explicit SemanticTokensResult(const QJsonValue &value);
172 };
173 
174 class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokensFullRequest
175     : public Request<SemanticTokensResult, std::nullptr_t, SemanticTokensParams>
176 {
177 public:
178     explicit SemanticTokensFullRequest(const SemanticTokensParams &params);
179     using Request::Request;
180     constexpr static const char methodName[] = "textDocument/semanticTokens/full";
181 };
182 
183 class SemanticTokensEdit : public JsonObject
184 {
185 public:
186     using JsonObject::JsonObject;
187 
start()188     int start() const { return typedValue<int>(startKey); }
setStart(int start)189     void setStart(int start) { insert(startKey, start); }
190 
deleteCount()191     int deleteCount() const { return typedValue<int>(deleteCountKey); }
setDeleteCount(int deleteCount)192     void setDeleteCount(int deleteCount) { insert(deleteCountKey, deleteCount); }
193 
data()194     Utils::optional<QList<int>> data() const { return optionalArray<int>(dataKey); }
setData(const QList<int> & value)195     void setData(const QList<int> &value) { insertArray(dataKey, value); }
clearData()196     void clearData() { remove(dataKey); }
197 
dataSize()198     int dataSize() const { return contains(dataKey) ? value(dataKey).toArray().size() : 0; }
199 
isValid()200     bool isValid() const override { return contains(dataKey) && contains(deleteCountKey); }
201 };
202 
203 class SemanticTokensDelta : public JsonObject
204 {
205 public:
206     using JsonObject::JsonObject;
207 
resultId()208     QString resultId() const { return typedValue<QString>(resultIdKey); }
setResultId(const QString & resultId)209     void setResultId(const QString &resultId) { insert(resultIdKey, resultId); }
210 
edits()211     QList<SemanticTokensEdit> edits() const { return array<SemanticTokensEdit>(editsKey); }
setEdits(const QList<SemanticTokensEdit> & edits)212     void setEdits(const QList<SemanticTokensEdit> &edits) { insertArray(editsKey, edits); }
213 
isValid()214     bool isValid() const override { return contains(resultIdKey) && contains(editsKey); }
215 };
216 
217 class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokensDeltaResult
218     : public Utils::variant<SemanticTokens, SemanticTokensDelta, std::nullptr_t>
219 {
220 public:
221     using variant::variant;
222     explicit SemanticTokensDeltaResult(const QJsonValue &value);
223 };
224 
225 class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokensFullDeltaRequest
226     : public Request<SemanticTokensDeltaResult, std::nullptr_t, SemanticTokensDeltaParams>
227 {
228 public:
229     explicit SemanticTokensFullDeltaRequest(const SemanticTokensDeltaParams &params);
230     using Request::Request;
231     constexpr static const char methodName[] = "textDocument/semanticTokens/full/delta";
232 };
233 
234 class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokensRangeRequest
235     : public Request<SemanticTokensResult, std::nullptr_t, SemanticTokensRangeParams>
236 {
237 public:
238     explicit SemanticTokensRangeRequest(const SemanticTokensRangeParams &params);
239     using Request::Request;
240     constexpr static const char methodName[] = "textDocument/semanticTokens/range";
241 };
242 
243 } // namespace LanguageServerProtocol
244