55 QQmlBaseModule<SemanticTokensRequest>::RequestPointerArgument request)
58 qCWarning(semanticTokens) <<
"No semantic token request is available!";
62 Responses::SemanticTokensResultType result;
64 const QByteArray uri = QQmlLSUtils::lspUriToQmlUrl(request->m_parameters.textDocument.uri);
65 const auto doc = m_codeModelManager->openDocumentByUrl(uri);
66 DomItem file = doc.snapshot.doc.fileObject(GoTo::MostLikely);
67 const auto fileObject = file.ownerAs<QmlFile>();
68 if (!fileObject || !(fileObject && fileObject->isValid())) {
70 int(QLspSpecification::ErrorCodes::RequestCancelled),
71 "Cannot proceed: current QML document is invalid!"_L1,
75 auto &&encoded = HighlightingUtils::collectTokens(file, std::nullopt, m_mode);
76 auto ®isteredTokens = m_codeModelManager->registeredTokens(uri);
77 if (!encoded.isEmpty()) {
79 result = SemanticTokens{ registeredTokens.resultId, encoded };
80 registeredTokens.lastTokens =
std::move(encoded);
104 QQmlBaseModule<SemanticTokensDeltaRequest>::RequestPointerArgument request)
107 qCWarning(semanticTokens) <<
"No semantic token request is available!";
111 Responses::SemanticTokensDeltaResultType result;
113 const QByteArray uri = QQmlLSUtils::lspUriToQmlUrl(request->m_parameters.textDocument.uri);
114 const auto doc = m_codeModelManager->openDocumentByUrl(uri);
115 DomItem file = doc.snapshot.doc.fileObject(GoTo::MostLikely);
116 const auto fileObject = file.ownerAs<QmlFile>();
117 if (!fileObject || !(fileObject && fileObject->isValid())) {
119 int(QLspSpecification::ErrorCodes::RequestCancelled),
120 "Cannot proceed: current QML document is invalid!"_L1,
124 auto newEncoded = HighlightingUtils::collectTokens(file, std::nullopt, m_mode);
125 auto ®isteredTokens = m_codeModelManager->registeredTokens(uri);
126 const auto lastResultId = registeredTokens.resultId;
131 if (lastResultId == request->m_parameters.previousResultId) {
132 result = QLspSpecification::SemanticTokensDelta{
133 registeredTokens.resultId,
134 HighlightingUtils::computeDiff(registeredTokens.lastTokens, newEncoded)
136 }
else if (!newEncoded.isEmpty()) {
137 result = QLspSpecification::SemanticTokens{ registeredTokens.resultId, newEncoded };
141 registeredTokens.lastTokens =
std::move(newEncoded);
161 QQmlBaseModule<SemanticTokensRangeRequest>::RequestPointerArgument request)
164 qCWarning(semanticTokens) <<
"No semantic token request is available!";
168 Responses::SemanticTokensRangeResultType result;
170 const QByteArray uri = QQmlLSUtils::lspUriToQmlUrl(request->m_parameters.textDocument.uri);
171 const auto doc = m_codeModelManager->openDocumentByUrl(uri);
172 DomItem file = doc.snapshot.doc.fileObject(GoTo::MostLikely);
173 const auto qmlFile = file.as<QmlFile>();
174 if (!qmlFile || !(qmlFile && qmlFile->isValid())) {
176 int(QLspSpecification::ErrorCodes::RequestCancelled),
177 "Cannot proceed: current QML document is invalid!"_L1,
181 const QString &code = qmlFile->code();
182 const auto range = request->m_parameters.range;
184 int(QQmlLSUtils::textOffsetFrom(code, range.start.line, range.end.character));
185 int endOffset =
int(QQmlLSUtils::textOffsetFrom(code, range.end.line, range.end.character));
186 auto &&encoded = HighlightingUtils::collectTokens(
187 file, HighlightsRange{ startOffset, endOffset }, m_mode);
188 auto ®isteredTokens = m_codeModelManager->registeredTokens(uri);
189 if (!encoded.isEmpty()) {
191 result = SemanticTokens{ registeredTokens.resultId, std::move(encoded) };
220 const QLspSpecification::InitializeParams &clientCapabilities,
221 QLspSpecification::InitializeResult &serverCapabilities)
223 QLspSpecification::SemanticTokensOptions options;
224 options.range =
true;
225 options.full = QJsonObject({ { u"delta"_s,
true } });
227 if (
auto clientInitOptions = clientCapabilities.initializationOptions) {
228 if ((*clientInitOptions)[u"qtCreatorHighlighting"_s].toBool(
false)) {
229 const auto mode = HighlightingUtils::HighlightingMode::QtCHighlighting;
230 m_delta.setHighlightingMode(mode);
231 m_full.setHighlightingMode(mode);
232 m_range.setHighlightingMode(mode);
235 options.legend.tokenTypes = extendedTokenTypesList();
236 options.legend.tokenModifiers = defaultTokenModifiersList();
237 serverCapabilities.capabilities.semanticTokensProvider = options;