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 <private/qqmldiffer_p.h>
20#include <QtLanguageServer/private/qlanguageserverspec_p.h>
21#include <QtQmlDom/private/qqmldomitem_p.h>
22
23#include <QtCore/qlist.h>
24#include <QtCore/qmap.h>
25
27
29
30namespace QmlHighlighting {
32
33// Protocol agnostic highlighting kinds
34// Use this enum while visiting dom tree to define the highlighting kinds for the semantic tokens
35// Then map it to the protocol specific token types and modifiers
36// This can be as much as detailed as needed
37enum class QmlHighlightKind {
38 QmlKeyword, // Qml keyword
39 QmlType, // Qml type name
40 QmlImportId, // Qml import module name
41 QmlNamespace, // Qml module namespace, i.e import QtQuick as Namespace
42 QmlLocalId, // Object id within the same file
43 QmlExternalId, // Object id defined in another file. [UNUSED FOR NOW]
44 QmlProperty, // Qml property. For now used for all kind of properties
45 QmlScopeObjectProperty, // Qml property defined in the current scope
46 QmlRootObjectProperty, // Qml property defined in the parent scopes
47 QmlExternalObjectProperty, // Qml property defined in the root object of another file
52 QmlEnumName, // Enum type name
53 QmlEnumMember, // Enum field names
54 QmlPragmaName, // Qml pragma name
55 QmlPragmaValue, // Qml pragma value
56 QmlTypeModifier, // list<QtObject>, list is the modifier, QtObject is the type
57 JsImport, // Js imported name
58 JsGlobalVar, // Js global variable or objects
59 JsGlobalMethod, // Js global method
60 JsScopeVar, // Js variable defined in the current scope
61 JsLabel, // js label
66 Field, // Used for the field names in the property chains,
67 Unknown, // Used for the unknown tokens
68};
69
82
84
85// Protocol specific token types
86// The values in this enum are converted to relevant strings and sent to the client as server
87// capabilities The convention is that the first letter in the enum value is decapitalized and the
88// rest is unchanged i.e Namespace -> "namespace" This is handled in enumToByteArray() helper
89// function.
91 // Subset of the QLspSpefication::SemanticTokenTypes enum
92 // We register only the token types used in the qml semantic highlighting
108
109 // Additional token types for the extended semantic highlighting
110 QmlLocalId, // object id within the same file
111 QmlExternalId, // object id defined in another file
112 QmlRootObjectProperty, // qml property defined in the parent scopes
113 QmlScopeObjectProperty, // qml property defined in the current scope
114 QmlExternalObjectProperty, // qml property defined in the root object of another file
115 JsScopeVar, // js variable defined in the current file
116 JsImportVar, // js import name that is imported in the qml file
117 JsGlobalVar, // js global variables
118 QmlStateName, // name of a qml state
119 Field, // used for the field names in the property chains
120 Unknown, // used for the unknown contexts
121};
122Q_ENUM_NS(SemanticTokenProtocolTypes)
123
124// Represents a semantic highlighting token
125// startLine and startColumn are 0-based as in LSP spec.
127{
128 HighlightToken() = default;
129 HighlightToken(const QQmlJS::SourceLocation &loc, QmlHighlightKind,
130 QmlHighlightModifiers = QmlHighlightModifier::None);
131
132 inline friend bool operator==(const HighlightToken &lhs, const HighlightToken &rhs)
133 {
134 return lhs.loc == rhs.loc && lhs.kind == rhs.kind && lhs.modifiers == rhs.modifiers;
135 }
136
140};
141
144
145/*!
146\internal
147Offsets start from zero.
148*/
154
155namespace Utils
156{
157QList<int> encodeSemanticTokens(const HighlightsContainer &highlights, HighlightingMode mode = HighlightingMode::Default);
159sourceLocationsFromMultiLineToken(QStringView code,
160 const QQmlJS::SourceLocation &tokenLocation);
161void addModifier(QLspSpecification::SemanticTokenModifiers modifier, int *baseModifier);
162bool rangeOverlapsWithSourceLocation(const QQmlJS::SourceLocation &loc, const HighlightsRange &r);
163QList<QLspSpecification::SemanticTokensEdit> computeDiff(const QList<int> &, const QList<int> &);
164void updateResultID(QByteArray &resultID);
165HighlightsContainer visitTokens(const QQmlJS::Dom::DomItem &item,
166 const std::optional<HighlightsRange> &range);
167void addHighlight(HighlightsContainer &out, const QQmlJS::SourceLocation &loc, QmlHighlightKind,
168 QmlHighlightModifiers = QmlHighlightModifier::None);
169void applyDiffs(HighlightsContainer &highlights, const QList<QQmlLSUtils::Diff> &diffs);
170HighlightsContainer shiftHighlights(const HighlightsContainer &cachedHighlights,
171 const QString &lastValidCode, const QString &currentCode);
172} // namespace Utils
173
175{
176public:
177 HighlightingVisitor(const QQmlJS::Dom::DomItem &item,
178 const std::optional<HighlightsRange> &range);
179 const HighlightsContainer &hightights() const { return m_highlights; }
180 HighlightsContainer &highlights() { return m_highlights; }
181
182private:
183 bool visitor(QQmlJS::Dom::Path, const QQmlJS::Dom::DomItem &item, bool);
184 void highlightComment(const QQmlJS::Dom::DomItem &item);
185 void highlightImport(const QQmlJS::Dom::DomItem &item);
186 void highlightBinding(const QQmlJS::Dom::DomItem &item);
187 void highlightPragma(const QQmlJS::Dom::DomItem &item);
188 void highlightEnumItem(const QQmlJS::Dom::DomItem &item);
189 void highlightEnumDecl(const QQmlJS::Dom::DomItem &item);
190 void highlightQmlObject(const QQmlJS::Dom::DomItem &item);
191 void highlightComponent(const QQmlJS::Dom::DomItem &item);
192 void highlightPropertyDefinition(const QQmlJS::Dom::DomItem &item);
193 void highlightMethod(const QQmlJS::Dom::DomItem &item);
194 void highlightScriptLiteral(const QQmlJS::Dom::DomItem &item);
195 void highlightIdentifier(const QQmlJS::Dom::DomItem &item);
196 void highlightBySemanticAnalysis(const QQmlJS::Dom::DomItem &item, QQmlJS::SourceLocation loc);
197 void highlightScriptExpressions(const QQmlJS::Dom::DomItem &item);
198 void highlightCallExpression(const QQmlJS::Dom::DomItem &item);
199 void highlightFieldMemberAccess(const QQmlJS::Dom::DomItem &item, QQmlJS::SourceLocation loc);
200 void addHighlight(const QQmlJS::SourceLocation &loc, QmlHighlightKind,
201 QmlHighlightModifiers = QmlHighlightModifier::None);
202private:
203 HighlightsContainer m_highlights;
204 std::optional<HighlightsRange> m_range;
205};
206
207} // namespace QmlHighlighting
208
209QT_END_NAMESPACE
210
211#endif // QQMLSEMANTICTOKENS_P_H
HighlightingVisitor(const QQmlJS::Dom::DomItem &item, const std::optional< HighlightsRange > &range)
const HighlightsContainer & hightights() const
Combined button and popup list for selecting options.
QList< int > encodeSemanticTokens(const HighlightsContainer &highlights, HighlightingMode mode=HighlightingMode::Default)
void applyDiffs(HighlightsContainer &highlights, const QList< QQmlLSUtils::Diff > &diffs)
QList< QLspSpecification::SemanticTokensEdit > computeDiff(const QList< int > &, const QList< int > &)
HighlightsContainer visitTokens(const QQmlJS::Dom::DomItem &item, const std::optional< HighlightsRange > &range)
void addHighlight(HighlightsContainer &out, const QQmlJS::SourceLocation &loc, QmlHighlightKind, QmlHighlightModifiers=QmlHighlightModifier::None)
void updateResultID(QByteArray &resultID)
QList< QQmlJS::SourceLocation > sourceLocationsFromMultiLineToken(QStringView code, const QQmlJS::SourceLocation &tokenLocation)
Returns multiple source locations for a given raw comment.
void addModifier(QLspSpecification::SemanticTokenModifiers modifier, int *baseModifier)
HighlightsContainer shiftHighlights(const HighlightsContainer &cachedHighlights, const QString &lastValidCode, const QString &currentCode)
bool rangeOverlapsWithSourceLocation(const QQmlJS::SourceLocation &loc, const HighlightsRange &r)
static bool rightFragmentRemains(const QQmlJS::SourceLocation &t, quint32 delStart, quint32 delEnd)
static void shiftTokenAfterInsert(QQmlJS::SourceLocation &t, const QQmlJS::SourceLocation &cursor, int newlines, int lastLen, int diffLen)
static FieldFilter highlightingFilter()
static std::pair< quint32, quint32 > newlineCountAndLastLineLength(const QString &text)
static bool insertionTouchesTokenLeft(const QQmlJS::SourceLocation &token, const QQmlJS::SourceLocation &cursor)
static void applyDeletionOverlap(QQmlJS::SourceLocation &t, quint32 delStart, quint32 delEnd, int newlines, quint32 delStartLine, quint32 delStartColumn)
static void updateCursorPositionByDiff(const QString &text, QQmlJS::SourceLocation &cursor)
static void updateHighlightsOnInsert(HighlightsContainer &highlights, QQmlJS::SourceLocation &cursor, const QQmlLSUtils::Diff &diff)
static std::optional< QmlHighlightKind > resolveJsGlobalObjectKind(const DomItem &item, const QString &name)
Further resolves the type of a JavaScriptIdentifier A global object can be in the object form or in t...
int(*)(QmlHighlightKind) QmlHighlightKindToLspKind
static void expandTokenForLeftOverlap(QQmlJS::SourceLocation &t, const QQmlLSUtils::Diff &diff, const QQmlJS::SourceLocation &cursor, int newlines, int lastLen)
static bool tokenAfterOffset(const QQmlJS::SourceLocation &t, quint32 offset)
static bool insertionInsideToken(const QQmlJS::SourceLocation &token, const QQmlJS::SourceLocation &cursor)
static bool spansAcrossDeletion(const QQmlJS::SourceLocation &t, quint32 delStart, quint32 delEnd)
static void shiftTokenAfterDelete(QQmlJS::SourceLocation &t, int newlines, int lastLen, const QQmlJS::SourceLocation &cursor, int diffLen)
static int mapToProtocolForQtCreator(QmlHighlightKind highlightKind)
static void expandTokenForMiddleInsert(QQmlJS::SourceLocation &t, const QQmlLSUtils::Diff &diff, const QQmlJS::SourceLocation &cursor)
static int fromQmlModifierKindToLspTokenType(QmlHighlightModifiers highlightModifier)
static bool tokenBeforeOffset(const QQmlJS::SourceLocation &t, quint32 offset)
static bool leftFragmentRemains(const QQmlJS::SourceLocation &t, quint32 delStart, quint32 delEnd)
static void updateHighlightsOnDelete(HighlightsContainer &highlights, QQmlJS::SourceLocation &cursor, const QQmlLSUtils::Diff &diff)
static int mapToProtocolDefault(QmlHighlightKind highlightKind)
QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQIORing)
HighlightToken(const QQmlJS::SourceLocation &loc, QmlHighlightKind, QmlHighlightModifiers=QmlHighlightModifier::None)
friend bool operator==(const HighlightToken &lhs, const HighlightToken &rhs)