forked from qt-creator/qt-creator
LSP: Implement SymbolTag support
Change-Id: I6e57d315a5ecd7402c0082df68e083e33dfeab7e Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -25,4 +25,9 @@ CallHierarchyOutgoingCallsRequest::CallHierarchyOutgoingCallsRequest(
|
|||||||
: Request(methodName, params)
|
: Request(methodName, params)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
std::optional<QList<SymbolTag>> CallHierarchyItem::symbolTags() const
|
||||||
|
{
|
||||||
|
return Internal::getSymbolTags(*this);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace LanguageServerProtocol
|
} // namespace LanguageServerProtocol
|
||||||
|
@@ -18,6 +18,8 @@ public:
|
|||||||
SymbolKind symbolKind() const { return SymbolKind(typedValue<int>(kindKey)); }
|
SymbolKind symbolKind() const { return SymbolKind(typedValue<int>(kindKey)); }
|
||||||
void setSymbolKind(const SymbolKind &symbolKind) { insert(kindKey, int(symbolKind)); }
|
void setSymbolKind(const SymbolKind &symbolKind) { insert(kindKey, int(symbolKind)); }
|
||||||
|
|
||||||
|
std::optional<QList<SymbolTag>> symbolTags() const;
|
||||||
|
|
||||||
Range range() const { return typedValue<Range>(rangeKey); }
|
Range range() const { return typedValue<Range>(rangeKey); }
|
||||||
void setRange(const Range &range) { insert(rangeKey, range); }
|
void setRange(const Range &range) { insert(rangeKey, range); }
|
||||||
|
|
||||||
|
@@ -19,6 +19,20 @@ void SymbolCapabilities::SymbolKindCapabilities::setValueSet(const QList<SymbolK
|
|||||||
insert(valueSetKey, enumArrayToJsonArray<SymbolKind>(valueSet));
|
insert(valueSetKey, enumArrayToJsonArray<SymbolKind>(valueSet));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<QList<SymbolTag> > SymbolCapabilities::SymbolTagCapabilities::valueSet() const
|
||||||
|
{
|
||||||
|
if (std::optional<QList<int>> array = optionalArray<int>(valueSetKey)) {
|
||||||
|
return std::make_optional(
|
||||||
|
Utils::transform(*array, [](int value) { return static_cast<SymbolTag>(value); }));
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymbolCapabilities::SymbolTagCapabilities::setValueSet(const QList<SymbolTag> &valueSet)
|
||||||
|
{
|
||||||
|
insert(valueSetKey, enumArrayToJsonArray<SymbolTag>(valueSet));
|
||||||
|
}
|
||||||
|
|
||||||
WorkspaceClientCapabilities::WorkspaceClientCapabilities()
|
WorkspaceClientCapabilities::WorkspaceClientCapabilities()
|
||||||
{
|
{
|
||||||
setWorkspaceFolders(true);
|
setWorkspaceFolders(true);
|
||||||
|
@@ -131,12 +131,31 @@ public:
|
|||||||
void clearValueSet() { remove(valueSetKey); }
|
void clearValueSet() { remove(valueSetKey); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LANGUAGESERVERPROTOCOL_EXPORT SymbolTagCapabilities : public JsonObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using JsonObject::JsonObject;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The client supports tags on `SymbolInformation` and `WorkspaceSymbol`.
|
||||||
|
* Clients supporting tags have to handle unknown tags gracefully.
|
||||||
|
*/
|
||||||
|
std::optional<QList<SymbolTag>> valueSet() const;
|
||||||
|
void setValueSet(const QList<SymbolTag> &valueSet);
|
||||||
|
void clearValueSet() { remove(valueSetKey); }
|
||||||
|
};
|
||||||
|
|
||||||
// Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.
|
// Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.
|
||||||
std::optional<SymbolKindCapabilities> symbolKind() const
|
std::optional<SymbolKindCapabilities> symbolKind() const
|
||||||
{ return optionalValue<SymbolKindCapabilities>(symbolKindKey); }
|
{ return optionalValue<SymbolKindCapabilities>(symbolKindKey); }
|
||||||
void setSymbolKind(const SymbolKindCapabilities &symbolKind) { insert(symbolKindKey, symbolKind); }
|
void setSymbolKind(const SymbolKindCapabilities &symbolKind) { insert(symbolKindKey, symbolKind); }
|
||||||
void clearSymbolKind() { remove(symbolKindKey); }
|
void clearSymbolKind() { remove(symbolKindKey); }
|
||||||
|
|
||||||
|
std::optional<SymbolTagCapabilities> symbolTag() const
|
||||||
|
{ return optionalValue<SymbolTagCapabilities>(tagSupportKey); }
|
||||||
|
void setSymbolTag(const SymbolTagCapabilities &symbolTag) { insert(tagSupportKey, symbolTag); }
|
||||||
|
void clearSymbolTag() { remove(tagSupportKey); }
|
||||||
|
|
||||||
std::optional<bool> hierarchicalDocumentSymbolSupport() const
|
std::optional<bool> hierarchicalDocumentSymbolSupport() const
|
||||||
{ return optionalValue<bool>(hierarchicalDocumentSymbolSupportKey); }
|
{ return optionalValue<bool>(hierarchicalDocumentSymbolSupportKey); }
|
||||||
void setHierarchicalDocumentSymbolSupport(bool hierarchicalDocumentSymbolSupport)
|
void setHierarchicalDocumentSymbolSupport(bool hierarchicalDocumentSymbolSupport)
|
||||||
|
@@ -193,10 +193,12 @@ constexpr Key startKey{"start"};
|
|||||||
constexpr Key supportedKey{"supported"};
|
constexpr Key supportedKey{"supported"};
|
||||||
constexpr Key symbolKey{"symbol"};
|
constexpr Key symbolKey{"symbol"};
|
||||||
constexpr Key symbolKindKey{"symbolKind"};
|
constexpr Key symbolKindKey{"symbolKind"};
|
||||||
|
constexpr Key symbolTagKey{"symbolTag"};
|
||||||
constexpr Key syncKindKey{"syncKind"};
|
constexpr Key syncKindKey{"syncKind"};
|
||||||
constexpr Key synchronizationKey{"synchronization"};
|
constexpr Key synchronizationKey{"synchronization"};
|
||||||
constexpr Key tabSizeKey{"tabSize"};
|
constexpr Key tabSizeKey{"tabSize"};
|
||||||
constexpr Key tagsKey{"tags"};
|
constexpr Key tagsKey{"tags"};
|
||||||
|
constexpr Key tagSupportKey{"tagSupport"};
|
||||||
constexpr Key targetKey{"target"};
|
constexpr Key targetKey{"target"};
|
||||||
constexpr Key textDocumentKey{"textDocument"};
|
constexpr Key textDocumentKey{"textDocument"};
|
||||||
constexpr Key textDocumentSyncKey{"textDocumentSync"};
|
constexpr Key textDocumentSyncKey{"textDocumentSync"};
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
#include "languageserverprotocoltr.h"
|
#include "languageserverprotocoltr.h"
|
||||||
#include "lsputils.h"
|
#include "lsputils.h"
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/textutils.h>
|
#include <utils/textutils.h>
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
@@ -487,4 +488,27 @@ bool DeleteFileOperation::isValid() const
|
|||||||
return contains(uriKey) && value(kindKey) == "delete";
|
return contains(uriKey) && value(kindKey) == "delete";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Internal {
|
||||||
|
std::optional<QList<SymbolTag>> getSymbolTags(const JsonObject &o)
|
||||||
|
{
|
||||||
|
const QJsonObject &obj = o;
|
||||||
|
const QJsonValue &val = obj.value(tagsKey);
|
||||||
|
if (val.isUndefined() || !val.isArray())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return Utils::transform<QList<SymbolTag>>(val.toArray(), [](const QJsonValue &v) {
|
||||||
|
return static_cast<SymbolTag>(v.toInt());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} // namespace Internal
|
||||||
|
|
||||||
|
std::optional<QList<SymbolTag>> SymbolInformation::symbolTags() const
|
||||||
|
{
|
||||||
|
return Internal::getSymbolTags(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<QList<SymbolTag>> DocumentSymbol::symbolTags() const
|
||||||
|
{
|
||||||
|
return Internal::getSymbolTags(*this);
|
||||||
|
}
|
||||||
} // namespace LanguageServerProtocol
|
} // namespace LanguageServerProtocol
|
||||||
|
@@ -574,6 +574,13 @@ public:
|
|||||||
{ return contains(uriKey) && contains(nameKey); }
|
{ return contains(uriKey) && contains(nameKey); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SymbolTag {
|
||||||
|
Deprecated = 1,
|
||||||
|
};
|
||||||
|
namespace Internal {
|
||||||
|
std::optional<QList<SymbolTag>> getSymbolTags(const JsonObject &o);
|
||||||
|
} // namespace Internal
|
||||||
|
|
||||||
class LANGUAGESERVERPROTOCOL_EXPORT SymbolInformation : public JsonObject
|
class LANGUAGESERVERPROTOCOL_EXPORT SymbolInformation : public JsonObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -585,6 +592,8 @@ public:
|
|||||||
int kind() const { return typedValue<int>(kindKey); }
|
int kind() const { return typedValue<int>(kindKey); }
|
||||||
void setKind(int kind) { insert(kindKey, kind); }
|
void setKind(int kind) { insert(kindKey, kind); }
|
||||||
|
|
||||||
|
std::optional<QList<SymbolTag>> symbolTags() const;
|
||||||
|
|
||||||
std::optional<bool> deprecated() const { return optionalValue<bool>(deprecatedKey); }
|
std::optional<bool> deprecated() const { return optionalValue<bool>(deprecatedKey); }
|
||||||
void setDeprecated(bool deprecated) { insert(deprecatedKey, deprecated); }
|
void setDeprecated(bool deprecated) { insert(deprecatedKey, deprecated); }
|
||||||
void clearDeprecated() { remove(deprecatedKey); }
|
void clearDeprecated() { remove(deprecatedKey); }
|
||||||
@@ -616,6 +625,8 @@ public:
|
|||||||
int kind() const { return typedValue<int>(kindKey); }
|
int kind() const { return typedValue<int>(kindKey); }
|
||||||
void setKind(int kind) { insert(kindKey, kind); }
|
void setKind(int kind) { insert(kindKey, kind); }
|
||||||
|
|
||||||
|
std::optional<QList<SymbolTag>> symbolTags() const;
|
||||||
|
|
||||||
std::optional<bool> deprecated() const { return optionalValue<bool>(deprecatedKey); }
|
std::optional<bool> deprecated() const { return optionalValue<bool>(deprecatedKey); }
|
||||||
void setDeprecated(bool deprecated) { insert(deprecatedKey, deprecated); }
|
void setDeprecated(bool deprecated) { insert(deprecatedKey, deprecated); }
|
||||||
void clearDeprecated() { remove(deprecatedKey); }
|
void clearDeprecated() { remove(deprecatedKey); }
|
||||||
@@ -693,4 +704,4 @@ enum Kind {
|
|||||||
};
|
};
|
||||||
} // namespace CompletionItemKind
|
} // namespace CompletionItemKind
|
||||||
|
|
||||||
} // namespace LanguageClient
|
} // namespace LanguageServerProtocol
|
||||||
|
@@ -52,6 +52,8 @@ public:
|
|||||||
{
|
{
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DecorationRole:
|
case Qt::DecorationRole:
|
||||||
|
if (m_item.symbolTags().value_or(QList<SymbolTag>()).contains(SymbolTag::Deprecated))
|
||||||
|
return Utils::Icons::WARNING.icon();
|
||||||
return symbolIcon(int(m_item.symbolKind()));
|
return symbolIcon(int(m_item.symbolKind()));
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
return m_item.name();
|
return m_item.name();
|
||||||
@@ -158,6 +160,8 @@ public:
|
|||||||
{
|
{
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DecorationRole:
|
case Qt::DecorationRole:
|
||||||
|
if (m_item.symbolTags().value_or(QList<SymbolTag>()).contains(SymbolTag::Deprecated))
|
||||||
|
return Utils::Icons::WARNING.icon();
|
||||||
return symbolIcon(int(m_item.symbolKind()));
|
return symbolIcon(int(m_item.symbolKind()));
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
return m_item.name();
|
return m_item.name();
|
||||||
|
@@ -437,6 +437,9 @@ static ClientCapabilities generateClientCapabilities()
|
|||||||
SymbolKind::EnumMember, SymbolKind::Struct, SymbolKind::Event,
|
SymbolKind::EnumMember, SymbolKind::Struct, SymbolKind::Event,
|
||||||
SymbolKind::Operator, SymbolKind::TypeParameter});
|
SymbolKind::Operator, SymbolKind::TypeParameter});
|
||||||
symbolCapabilities.setSymbolKind(symbolKindCapabilities);
|
symbolCapabilities.setSymbolKind(symbolKindCapabilities);
|
||||||
|
SymbolCapabilities::SymbolTagCapabilities symbolTagCapabilities;
|
||||||
|
symbolTagCapabilities.setValueSet({SymbolTag::Deprecated});
|
||||||
|
symbolCapabilities.setSymbolTag(symbolTagCapabilities);
|
||||||
symbolCapabilities.setHierarchicalDocumentSymbolSupport(true);
|
symbolCapabilities.setHierarchicalDocumentSymbolSupport(true);
|
||||||
documentCapabilities.setDocumentSymbol(symbolCapabilities);
|
documentCapabilities.setDocumentSymbol(symbolCapabilities);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user