Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmlsemantictokens_p.h
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QQMLSEMANTICTOKENS_P_H
6#define QQMLSEMANTICTOKENS_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtLanguageServer/private/qlanguageserverspec_p.h>
20#include <QtQmlDom/private/qqmldomitem_p.h>
21#include <QtCore/qlist.h>
22#include <QtCore/qmap.h>
23
25
27
30
31// Protocol agnostic highlighting kinds
32// Use this enum while visiting dom tree to define the highlighting kinds for the semantic tokens
33// Then map it to the protocol specific token types and modifiers
34// This can be as much as detailed as needed
35enum class QmlHighlightKind {
36 QmlKeyword, // Qml keyword
37 QmlType, // Qml type name
38 QmlImportId, // Qml import module name
39 QmlNamespace, // Qml module namespace, i.e import QtQuick as Namespace
40 QmlLocalId, // Object id within the same file
41 QmlExternalId, // Object id defined in another file. [UNUSED FOR NOW]
42 QmlProperty, // Qml property. For now used for all kind of properties
43 QmlScopeObjectProperty, // Qml property defined in the current scope
44 QmlRootObjectProperty, // Qml property defined in the parent scopes
45 QmlExternalObjectProperty, // Qml property defined in the root object of another file
50 QmlEnumName, // Enum type name
51 QmlEnumMember, // Enum field names
52 QmlPragmaName, // Qml pragma name
53 QmlPragmaValue, // Qml pragma value
54 QmlTypeModifier, // list<QtObject>, list is the modifier, QtObject is the type
55 JsImport, // Js imported name
56 JsGlobalVar, // Js global variable or objects
57 JsGlobalMethod, // Js global method
58 JsScopeVar, // Js variable defined in the current scope
59 JsLabel, // js label
64 Field, // Used for the field names in the property chains,
65 Unknown, // Used for the unknown tokens
66};
67
78
80
81// Protocol specific token types
82// The values in this enum are converted to relevant strings and sent to the client as server
83// capabilities The convention is that the first letter in the enum value is decapitalized and the
84// rest is unchanged i.e Namespace -> "namespace" This is handled in enumToByteArray() helper
85// function.
87 // Subset of the QLspSpefication::SemanticTokenTypes enum
88 // We register only the token types used in the qml semantic highlighting
104
105 // Additional token types for the extended semantic highlighting
106 QmlLocalId, // object id within the same file
107 QmlExternalId, // object id defined in another file
108 QmlRootObjectProperty, // qml property defined in the parent scopes
109 QmlScopeObjectProperty, // qml property defined in the current scope
110 QmlExternalObjectProperty, // qml property defined in the root object of another file
111 JsScopeVar, // js variable defined in the current file
112 JsImportVar, // js import name that is imported in the qml file
113 JsGlobalVar, // js global variables
114 QmlStateName, // name of a qml state
115 Field, // used for the field names in the property chains
116 Unknown, // used for the unknown contexts
117};
118Q_ENUM_NS(SemanticTokenProtocolTypes)
119
120} // namespace HighlightingUtils
121
122// Represents a semantic highlighting token
123// startLine and startColumn are 0-based as in LSP spec.
124struct Token
125{
126 Token() = default;
127 Token(const QQmlJS::SourceLocation &loc, int tokenType, int tokenModifier = 0)
128 : offset(loc.offset),
129 length(loc.length),
130 startLine(loc.startLine - 1),
131 startColumn(loc.startColumn - 1),
132 tokenType(tokenType),
133 tokenModifier(tokenModifier)
134 {
135 }
136
137 inline friend bool operator<(const Token &lhs, const Token &rhs)
138 {
139 return lhs.offset < rhs.offset;
140 }
141
142 inline friend bool operator==(const Token &lhs, const Token &rhs)
143 {
144 return lhs.offset == rhs.offset && lhs.length == rhs.length
145 && lhs.startLine == rhs.startLine && lhs.startColumn == rhs.startColumn
146 && lhs.tokenType == rhs.tokenType && lhs.tokenModifier == rhs.tokenModifier;
147 }
148
155};
156
157using HighlightsContainer = QMap<int, QT_PREPEND_NAMESPACE(Token)>;
158
159/*!
160\internal
161Offsets start from zero.
162*/
168
170{
171public:
173 Highlights(HighlightingUtils::HighlightingMode mode = HighlightingUtils::HighlightingMode::Default);
174 void addHighlight(const QQmlJS::SourceLocation &loc, HighlightingUtils::QmlHighlightKind,
175 HighlightingUtils::QmlHighlightModifiers =
177 HighlightsContainer &tokens() { return m_highlights; }
178 const HighlightsContainer &tokens() const { return m_highlights; }
179
180private:
181 void addHighlightImpl(const QQmlJS::SourceLocation &loc, int tokenType, int tokenModifier = 0);
182 HighlightsContainer m_highlights;
183 QmlHighlightKindToLspKind m_mapToProtocol;
184};
185
186namespace HighlightingUtils
187{
188 QList<int> encodeSemanticTokens(Highlights &highlights);
190 sourceLocationsFromMultiLineToken(QStringView code,
191 const QQmlJS::SourceLocation &tokenLocation);
192 void addModifier(QLspSpecification::SemanticTokenModifiers modifier, int *baseModifier);
193 bool rangeOverlapsWithSourceLocation(const QQmlJS::SourceLocation &loc, const HighlightsRange &r);
194 QList<QLspSpecification::SemanticTokensEdit> computeDiff(const QList<int> &, const QList<int> &);
195 void updateResultID(QByteArray &resultID);
196 QList<int> collectTokens(const QQmlJS::Dom::DomItem &item,
197 const std::optional<HighlightsRange> &range,
198 HighlightingMode mode = HighlightingMode::Default);
199 Highlights visitTokens(const QQmlJS::Dom::DomItem &item,
200 const std::optional<HighlightsRange> &range,
201 HighlightingMode mode = HighlightingMode::Default);
202} // namespace HighlightingUtils
203
205{
206public:
207 HighlightingVisitor(const QQmlJS::Dom::DomItem &item,
208 const std::optional<HighlightsRange> &range,
209 HighlightingUtils::HighlightingMode mode =
210 HighlightingUtils::HighlightingMode::Default);
211 const Highlights &hightights() const { return m_highlights; }
212 Highlights &highlights() { return m_highlights; }
213
214private:
215 bool visitor(QQmlJS::Dom::Path, const QQmlJS::Dom::DomItem &item, bool);
216 void highlightComment(const QQmlJS::Dom::DomItem &item);
217 void highlightImport(const QQmlJS::Dom::DomItem &item);
218 void highlightBinding(const QQmlJS::Dom::DomItem &item);
219 void highlightPragma(const QQmlJS::Dom::DomItem &item);
220 void highlightEnumItem(const QQmlJS::Dom::DomItem &item);
221 void highlightEnumDecl(const QQmlJS::Dom::DomItem &item);
222 void highlightQmlObject(const QQmlJS::Dom::DomItem &item);
223 void highlightComponent(const QQmlJS::Dom::DomItem &item);
224 void highlightPropertyDefinition(const QQmlJS::Dom::DomItem &item);
225 void highlightMethod(const QQmlJS::Dom::DomItem &item);
226 void highlightScriptLiteral(const QQmlJS::Dom::DomItem &item);
227 void highlightIdentifier(const QQmlJS::Dom::DomItem &item);
228 void highlightBySemanticAnalysis(const QQmlJS::Dom::DomItem &item, QQmlJS::SourceLocation loc);
229 void highlightScriptExpressions(const QQmlJS::Dom::DomItem &item);
230 void highlightCallExpression(const QQmlJS::Dom::DomItem &item);
231 void highlightFieldMemberAccess(const QQmlJS::Dom::DomItem &item, QQmlJS::SourceLocation loc);
232
233private:
234 Highlights m_highlights;
235 std::optional<HighlightsRange> m_range;
236};
237
238QT_END_NAMESPACE
239
240#endif // QQMLSEMANTICTOKENS_P_H
const Highlights & hightights() const
int(*)(HighlightingUtils::QmlHighlightKind) QmlHighlightKindToLspKind
const HighlightsContainer & tokens() const
Highlights(HighlightingUtils::HighlightingMode mode=HighlightingUtils::HighlightingMode::Default)
HighlightsContainer & tokens()
void addHighlight(const QQmlJS::SourceLocation &loc, HighlightingUtils::QmlHighlightKind, HighlightingUtils::QmlHighlightModifiers=HighlightingUtils::QmlHighlightModifier::None)
Implements a server for the language server protocol.
void registerHandlers(QLanguageServer *server, QLanguageServerProtocol *protocol) override
QString name() const override
QQmlHighlightSupport(QmlLsp::QQmlCodeModelManager *codeModel)
void setupCapabilities(const QLspSpecification::InitializeParams &clientInfo, QLspSpecification::InitializeResult &) override
void process(QQmlBaseModule< SemanticTokensDeltaRequest >::RequestPointerArgument req) override
SemanticTokenDeltaHandler(QmlLsp::QQmlCodeModelManager *codeModel)
void registerHandlers(QLanguageServer *, QLanguageServerProtocol *) override
HIDE_UNUSED_OVERRIDES HighlightingUtils::HighlightingMode m_mode
void setHighlightingMode(HighlightingUtils::HighlightingMode mode)
void setHighlightingMode(HighlightingUtils::HighlightingMode mode)
void process(QQmlBaseModule< SemanticTokensRequest >::RequestPointerArgument req) override
SemanticTokenFullHandler(QmlLsp::QQmlCodeModelManager *codeModel)
void registerHandlers(QLanguageServer *, QLanguageServerProtocol *) override
HIDE_UNUSED_OVERRIDES HighlightingUtils::HighlightingMode m_mode
SemanticTokenRangeHandler(QmlLsp::QQmlCodeModelManager *codeModel)
void setHighlightingMode(HighlightingUtils::HighlightingMode mode)
HIDE_UNUSED_OVERRIDES HighlightingUtils::HighlightingMode m_mode
void process(QQmlBaseModule< SemanticTokensRangeRequest >::RequestPointerArgument req) override
void registerHandlers(QLanguageServer *, QLanguageServerProtocol *) override
QList< QQmlJS::SourceLocation > sourceLocationsFromMultiLineToken(QStringView code, const QQmlJS::SourceLocation &tokenLocation)
Returns multiple source locations for a given raw comment.
QList< int > encodeSemanticTokens(Highlights &highlights)
void updateResultID(QByteArray &resultID)
QList< QLspSpecification::SemanticTokensEdit > computeDiff(const QList< int > &, const QList< int > &)
bool rangeOverlapsWithSourceLocation(const QQmlJS::SourceLocation &loc, const HighlightsRange &r)
void addModifier(QLspSpecification::SemanticTokenModifiers modifier, int *baseModifier)
QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcher)
QList< QByteArray > extendedTokenTypesList()
QList< QByteArray > defaultTokenModifiersList()
static QList< QByteArray > enumToByteArray()
#define HIDE_UNUSED_OVERRIDES
This class sends a result or an error when going out of scope.
friend bool operator==(const Token &lhs, const Token &rhs)
Token()=default
friend bool operator<(const Token &lhs, const Token &rhs)
Token(const QQmlJS::SourceLocation &loc, int tokenType, int tokenModifier=0)