From ac6edc8aaa974a29eb1f688e3a324600ffa1176e Mon Sep 17 00:00:00 2001 From: ykiko Date: Fri, 21 Feb 2025 19:39:39 +0800 Subject: [PATCH] Add `LSPConverter` (#89) --- include/Basic/Lifecycle.h | 19 ++ include/Feature/SemanticTokens.h | 51 +---- include/Server/IncludeGraph.h | 1 + include/Server/LSPConverter.h | 25 +++ include/Server/Server.h | 53 ++--- src/Feature/SemanticTokens.cpp | 44 +--- src/Index/FeatureIndex.cpp | 2 +- src/Server/Feature.cpp | 119 +++++------ src/Server/LSPConverter.cpp | 288 +++++++++++++++++++++++++++ src/Server/Server.cpp | 28 +-- unittests/Feature/SemanticTokens.cpp | 2 +- 11 files changed, 446 insertions(+), 186 deletions(-) create mode 100644 include/Server/LSPConverter.h create mode 100644 src/Server/LSPConverter.cpp diff --git a/include/Basic/Lifecycle.h b/include/Basic/Lifecycle.h index ff0b99cf..eafc3cbe 100644 --- a/include/Basic/Lifecycle.h +++ b/include/Basic/Lifecycle.h @@ -60,6 +60,25 @@ struct InitializeParams { std::vector workspaceFolders; }; +struct SemanticTokensOptions { + /// The legend used by the server. + struct SemanticTokensLegend { + /// The token types a server uses. + std::vector tokenTypes; + + /// The token modifiers a server uses. + std::vector tokenModifiers; + } legend; + + /// Server supports providing semantic tokens for a specific range + /// of a document. + bool range = false; + + /// Server supports providing semantic tokens for a full document. + bool full = true; +}; + +/// Server Capability. struct ServerCapabilities { /// The position encoding the server picked from the encodings offered /// by the client via the client capability `general.positionEncodings`. diff --git a/include/Feature/SemanticTokens.h b/include/Feature/SemanticTokens.h index 1a3505a8..516e8589 100644 --- a/include/Feature/SemanticTokens.h +++ b/include/Feature/SemanticTokens.h @@ -1,9 +1,7 @@ #pragma once #include "AST/SymbolKind.h" -#include "Basic/Document.h" #include "Basic/SourceCode.h" -#include "Basic/SourceConverter.h" #include "Index/Shared.h" namespace clice { @@ -16,39 +14,6 @@ struct SemanticTokensOption {}; }; // namespace config -namespace proto { - -/// Server Capability. -struct SemanticTokensOptions { - /// The legend used by the server. - struct SemanticTokensLegend { - /// The token types a server uses. - std::vector tokenTypes; - - /// The token modifiers a server uses. - std::vector tokenModifiers; - } legend; - - /// Server supports providing semantic tokens for a specific range - /// of a document. - bool range = false; - - /// Server supports providing semantic tokens for a full document. - bool full = true; -}; - -struct SemanticTokensParams { - /// The text document. - TextDocumentIdentifier textDocument; -}; - -struct SemanticTokens { - /// The actual tokens. - std::vector data; -}; - -} // namespace proto - namespace feature { struct SemanticToken { @@ -57,19 +22,11 @@ struct SemanticToken { SymbolModifiers modifiers; }; +/// Generate semantic tokens for the interested file only. +std::vector semanticTokens(ASTInfo& AST); + /// Generate semantic tokens for all files. -index::Shared> semanticTokens(ASTInfo& info); - -/// Translate semantic tokens to LSP format. -proto::SemanticTokens toSemanticTokens(llvm::ArrayRef tokens, - SourceConverter& SC, - llvm::StringRef content, - const config::SemanticTokensOption& option); - -/// Generate semantic tokens for main file and translate to LSP format. -proto::SemanticTokens semanticTokens(ASTInfo& info, - SourceConverter& SC, - const config::SemanticTokensOption& option); +index::Shared> indexSemanticTokens(ASTInfo& AST); } // namespace feature diff --git a/include/Server/IncludeGraph.h b/include/Server/IncludeGraph.h index 64040190..f7887813 100644 --- a/include/Server/IncludeGraph.h +++ b/include/Server/IncludeGraph.h @@ -4,6 +4,7 @@ #include "Database.h" #include "Protocol.h" #include "Async/Async.h" +#include "Basic/SourceConverter.h" #include "Compiler/Compilation.h" #include "Support/JSON.h" #include "Index/SymbolIndex.h" diff --git a/include/Server/LSPConverter.h b/include/Server/LSPConverter.h new file mode 100644 index 00000000..664c7b61 --- /dev/null +++ b/include/Server/LSPConverter.h @@ -0,0 +1,25 @@ +#pragma once + +#include "Config.h" +#include "Async/Async.h" +#include "Feature/Hover.h" +#include "Feature/InlayHint.h" +#include "Feature/FoldingRange.h" +#include "Feature/DocumentSymbol.h" +#include "Feature/SemanticTokens.h" + +namespace clice { + +/// Responsible for converting between LSP and internal types. +class LSPConverter { +public: + using Result = async::Task; + + Result convert(llvm::StringRef path, llvm::ArrayRef tokens); + +private: + proto::PositionEncodingKind kind; +}; + +} // namespace clice + diff --git a/include/Server/Server.h b/include/Server/Server.h index 8da896e9..a349e535 100644 --- a/include/Server/Server.h +++ b/include/Server/Server.h @@ -113,32 +113,33 @@ private: // // async::Task<> onSubtypes(json::Value id, const proto::TypeHierarchySubtypesParams& params); - async::Task<> onDocumentHighlight(json::Value id, const proto::DocumentHighlightParams& params); - - async::Task<> onDocumentLink(json::Value id, const proto::DocumentLinkParams& params); - - async::Task<> onHover(json::Value id, const proto::HoverParams& params); - - async::Task<> onCodeLens(json::Value id, const proto::CodeLensParams& params); - - async::Task<> onFoldingRange(json::Value id, const proto::FoldingRangeParams& params); - - async::Task<> onDocumentSymbol(json::Value id, const proto::DocumentSymbolParams& params); - - async::Task<> onSemanticTokens(json::Value id, const proto::SemanticTokensParams& params); - - async::Task<> onInlayHint(json::Value id, const proto::InlayHintParams& params); - - async::Task<> onCodeCompletion(json::Value id, const proto::CompletionParams& params); - - async::Task<> onSignatureHelp(json::Value id, const proto::SignatureHelpParams& params); - - async::Task<> onCodeAction(json::Value id, const proto::CodeActionParams& params); - - async::Task<> onFormatting(json::Value id, const proto::DocumentFormattingParams& params); - - async::Task<> onRangeFormatting(json::Value id, - const proto::DocumentRangeFormattingParams& params); + // async::Task<> onDocumentHighlight(json::Value id, const proto::DocumentHighlightParams& + // params); + // + // async::Task<> onDocumentLink(json::Value id, const proto::DocumentLinkParams& params); + // + // async::Task<> onHover(json::Value id, const proto::HoverParams& params); + // + // async::Task<> onCodeLens(json::Value id, const proto::CodeLensParams& params); + // + // async::Task<> onFoldingRange(json::Value id, const proto::FoldingRangeParams& params); + // + // async::Task<> onDocumentSymbol(json::Value id, const proto::DocumentSymbolParams& params); + // + // async::Task<> onSemanticTokens(json::Value id, const proto::SemanticTokensParams& params); + // + // async::Task<> onInlayHint(json::Value id, const proto::InlayHintParams& params); + // + // async::Task<> onCodeCompletion(json::Value id, const proto::CompletionParams& params); + // + // async::Task<> onSignatureHelp(json::Value id, const proto::SignatureHelpParams& params); + // + // async::Task<> onCodeAction(json::Value id, const proto::CodeActionParams& params); + // + // async::Task<> onFormatting(json::Value id, const proto::DocumentFormattingParams& params); + // + // async::Task<> onRangeFormatting(json::Value id, + // const proto::DocumentRangeFormattingParams& params); /// ============================================================================ /// Workspace Features diff --git a/src/Feature/SemanticTokens.cpp b/src/Feature/SemanticTokens.cpp index eef59f12..75b076c8 100644 --- a/src/Feature/SemanticTokens.cpp +++ b/src/Feature/SemanticTokens.cpp @@ -265,46 +265,12 @@ private: } // namespace -index::Shared> semanticTokens(ASTInfo& AST) { +std::vector semanticTokens(ASTInfo& AST) { + return HighlightBuilder(AST, true).buildForFile(); +} + +index::Shared> indexSemanticTokens(ASTInfo& AST) { return HighlightBuilder(AST, false).buildForIndex(); } -proto::SemanticTokens toSemanticTokens(llvm::ArrayRef tokens, - SourceConverter& SC, - llvm::StringRef content, - const config::SemanticTokensOption& option) { - - proto::SemanticTokens result; - - std::size_t lastLine = 0; - std::size_t lastColumn = 0; - - for(auto& token: tokens) { - auto [begin, end] = token.range; - auto [line, column] = SC.toPosition(content, begin); - - if(line != lastLine) { - /// FIXME: Cut off content to improve performance. - lastColumn = 0; - } - - result.data.emplace_back(line - lastLine); - result.data.emplace_back(column - lastColumn); - result.data.emplace_back(end - begin); - result.data.emplace_back(token.kind.value()); - result.data.emplace_back(token.modifiers.value()); - - lastLine = line; - lastColumn = column; - } - - return result; -} - -proto::SemanticTokens semanticTokens(ASTInfo& info, - SourceConverter& SC, - const config::SemanticTokensOption& option) { - return {}; -} - } // namespace clice::feature diff --git a/src/Index/FeatureIndex.cpp b/src/Index/FeatureIndex.cpp index bdeb08f8..59daa03a 100644 --- a/src/Index/FeatureIndex.cpp +++ b/src/Index/FeatureIndex.cpp @@ -15,7 +15,7 @@ struct FeatureIndex { Shared indexFeature(ASTInfo& info) { Shared indices; - for(auto&& [fid, result]: feature::semanticTokens(info)) { + for(auto&& [fid, result]: feature::indexSemanticTokens(info)) { indices[fid].tokens = std::move(result); } diff --git a/src/Server/Feature.cpp b/src/Server/Feature.cpp index 1f9c8fcf..c2c9c279 100644 --- a/src/Server/Feature.cpp +++ b/src/Server/Feature.cpp @@ -3,63 +3,66 @@ namespace clice { -async::Task<> Server::onDocumentHighlight(json::Value id, - const proto::DocumentHighlightParams& params) { - co_return; -} - -async::Task<> Server::onDocumentLink(json::Value id, const proto::DocumentLinkParams& params) { - co_return; -} - -async::Task<> Server::onHover(json::Value id, const proto::HoverParams& params) { - co_return; -} - -async::Task<> Server::onCodeLens(json::Value id, const proto::CodeLensParams& params) { - co_return; -} - -async::Task<> Server::onFoldingRange(json::Value id, const proto::FoldingRangeParams& params) { - co_return; -} - -async::Task<> Server::onDocumentSymbol(json::Value id, const proto::DocumentSymbolParams& params) { - co_return; -} - -async::Task<> Server::onSemanticTokens(json::Value id, const proto::SemanticTokensParams& params) { - auto path = SourceConverter::toPath(params.textDocument.uri); - /// auto tokens = co_await indexer.semanticTokens(path); - /// co_await response(std::move(id), json::serialize(tokens)); - co_return; -} - -async::Task<> Server::onInlayHint(json::Value id, const proto::InlayHintParams& params) { - co_return; -} - -async::Task<> Server::onCodeCompletion(json::Value id, const proto::CompletionParams& params) { - // auto path = URI::resolve(params.textDocument.uri); - // async::response(std::move(id), json::serialize(result)); - co_return; -} - -async::Task<> Server::onSignatureHelp(json::Value id, const proto::SignatureHelpParams& params) { - co_return; -} - -async::Task<> Server::onCodeAction(json::Value id, const proto::CodeActionParams& params) { - co_return; -} - -async::Task<> Server::onFormatting(json::Value id, const proto::DocumentFormattingParams& params) { - co_return; -} - -async::Task<> Server::onRangeFormatting(json::Value id, - const proto::DocumentRangeFormattingParams& params) { - co_return; -} +// async::Task<> Server::onDocumentHighlight(json::Value id, +// const proto::DocumentHighlightParams& params) { +// co_return; +// } +// +// async::Task<> Server::onDocumentLink(json::Value id, const proto::DocumentLinkParams& params) { +// co_return; +// } +// +// async::Task<> Server::onHover(json::Value id, const proto::HoverParams& params) { +// co_return; +// } +// +// async::Task<> Server::onCodeLens(json::Value id, const proto::CodeLensParams& params) { +// co_return; +// } +// +// async::Task<> Server::onFoldingRange(json::Value id, const proto::FoldingRangeParams& params) { +// co_return; +// } +// +// async::Task<> Server::onDocumentSymbol(json::Value id, const proto::DocumentSymbolParams& params) +// { +// co_return; +// } +// +// async::Task<> Server::onSemanticTokens(json::Value id, const proto::SemanticTokensParams& params) +// { +// auto path = SourceConverter::toPath(params.textDocument.uri); +// /// auto tokens = co_await indexer.semanticTokens(path); +// /// co_await response(std::move(id), json::serialize(tokens)); +// co_return; +// } +// +// async::Task<> Server::onInlayHint(json::Value id, const proto::InlayHintParams& params) { +// co_return; +// } +// +// async::Task<> Server::onCodeCompletion(json::Value id, const proto::CompletionParams& params) { +// // auto path = URI::resolve(params.textDocument.uri); +// // async::response(std::move(id), json::serialize(result)); +// co_return; +// } +// +// async::Task<> Server::onSignatureHelp(json::Value id, const proto::SignatureHelpParams& params) { +// co_return; +// } +// +// async::Task<> Server::onCodeAction(json::Value id, const proto::CodeActionParams& params) { +// co_return; +// } +// +// async::Task<> Server::onFormatting(json::Value id, const proto::DocumentFormattingParams& params) +// { +// co_return; +// } +// +// async::Task<> Server::onRangeFormatting(json::Value id, +// const proto::DocumentRangeFormattingParams& params) { +// co_return; +// } } // namespace clice diff --git a/src/Server/LSPConverter.cpp b/src/Server/LSPConverter.cpp new file mode 100644 index 00000000..baf9ca3a --- /dev/null +++ b/src/Server/LSPConverter.cpp @@ -0,0 +1,288 @@ +#include "Server/LSPConverter.h" + +namespace clice { + +namespace { + +/// @brief Iterates over Unicode codepoints in a UTF-8 encoded string and invokes a callback for +/// each codepoint. +/// +/// Processes the input UTF-8 string, calculating the length of each Unicode codepoint in both +/// UTF-8 (bytes) and UTF-16 (code units), and passes these lengths to the callback. +/// Iteration stops early if the callback returns `false`. +/// +/// ASCII characters are treated as 1-byte UTF-8 codepoints with a UTF-16 length of 1. +/// Non-ASCII characters are processed based on their leading byte to determine UTF-8 length: +/// - Valid lengths are 2 to 4 bytes. +/// - Astral codepoints (UTF-8 length of 4) have a UTF-16 length of 2 code units. +/// Invalid UTF-8 sequences are treated as single-byte ASCII characters. +/// +/// Returns `false` if the callback stops the iteration. +template +bool iterateCodepoints(llvm::StringRef content, const Callback& callback) { + // Iterate over the input string, processing each codepoint. + for(size_t index = 0; index < content.size();) { + unsigned char c = static_cast(content[index]); + + // Handle ASCII characters (1-byte UTF-8, 1-code-unit UTF-16). + if(!(c & 0x80)) [[likely]] { + if(!callback(1, 1)) { + return true; + } + + ++index; + continue; + } + + // Determine the length of the codepoint in UTF-8 by counting the leading 1s. + size_t length = llvm::countl_one(c); + + // Validate UTF-8 encoding: length must be between 2 and 4. + if(length < 2 || length > 4) [[unlikely]] { + assert(false && "Invalid UTF-8 sequence"); + + // Treat the byte as an ASCII character. + if(!callback(1, 1)) { + return true; + } + + ++index; + continue; + } + + // Advance the index by the length of the current UTF-8 codepoint. + index += length; + + // Calculate the UTF-16 length: astral codepoints (4-byte UTF-8) take 2 code units. + if(!callback(length, length == 4 ? 2 : 1)) { + return true; + } + } + + return false; +} + +/// Convert a proto::Position to a file offset in the content with the specified encoding kind. +std::uint32_t toOffset(llvm::StringRef content, + proto::PositionEncodingKind kind, + proto::Position position) { + std::uint32_t offset = 0; + for(auto i = 0; i < position.line; i++) { + auto pos = content.find('\n'); + assert(pos != llvm::StringRef::npos && "Line value is out of range"); + + offset += pos + 1; + content = content.substr(pos + 1); + } + + /// Drop the content after the line. + content = content.take_until([](char c) { return c == '\n'; }); + assert(position.character <= content.size() && "Character value is out of range"); + + if(kind == proto::PositionEncodingKind::UTF8) { + offset += position.character; + return offset; + } + + if(kind == proto::PositionEncodingKind::UTF16) { + iterateCodepoints(content, [&](size_t utf8Length, size_t utf16Length) { + assert(position.character >= utf16Length && "Character value is out of range"); + position.character -= utf16Length; + offset += utf8Length; + return position.character != 0; + }); + return offset; + } + + if(kind == proto::PositionEncodingKind::UTF32) { + iterateCodepoints(content, [&](size_t utf8Length, size_t) { + assert(position.character >= 1 && "Character value is out of range"); + position.character -= 1; + offset += utf8Length; + return position.character != 0; + }); + return offset; + } + + std::unreachable(); +} + +/// Remeasure the length (character count) of the content with the specified encoding kind. +std::uint32_t remeasure(llvm::StringRef content, proto::PositionEncodingKind kind) { + if(kind == proto::PositionEncodingKind::UTF8) { + return content.size(); + } + + if(kind == proto::PositionEncodingKind::UTF16) { + std::uint32_t length = 0; + iterateCodepoints(content, [&](std::uint32_t, std::uint32_t utf16Length) { + length += utf16Length; + return true; + }); + return length; + } + + if(kind == proto::PositionEncodingKind::UTF32) { + std::uint32_t length = 0; + iterateCodepoints(content, [&](std::uint32_t, std::uint32_t) { + length += 1; + return true; + }); + return length; + } + + std::unreachable(); +} + +class PositionConverter { +public: + PositionConverter(llvm::StringRef content, proto::PositionEncodingKind kind) : + content(content), kind(kind) {} + + /// Convert a offset to a proto::Position with given encoding. + /// The input offset must be UTF-8 encoded and in order. + proto::Position toPosition(uint32_t offset) { + assert(offset <= content.size() && "Offset is out of range"); + assert(offset >= lastInput && "Offset must be in order"); + + /// Fast path: return the last output. + if(offset == lastInput) [[unlikely]] { + return lastOutput; + } + + /// The length of the current line. + std::uint32_t lineLength = 0; + + /// Move the line offset to the current line. + for(std::uint32_t i = lastLineOffset; i < offset; i++) { + lineLength += 1; + if(content[i] == '\n') { + line += 1; + lastLineOffset += lineLength; + lineLength = 0; + } + } + + /// Get the content of the current line. + auto lineContent = content.substr(lastLineOffset, lineLength); + auto position = proto::Position{ + .line = line, + .character = remeasure(lineContent, kind), + }; + + /// Cache the result. + lastInput = offset; + lastOutput = position; + + return position; + } + +private: + std::uint32_t line = 0; + /// The offset of the last line end. + std::uint32_t lastLineOffset = 0; + + /// The input offset of last call. + std::uint32_t lastInput = 0; + proto::Position lastOutput = {0, 0}; + + llvm::StringRef content; + proto::PositionEncodingKind kind; +}; + +} // namespace + +LSPConverter::Result LSPConverter::convert(llvm::StringRef path, + llvm::ArrayRef tokens) { + /// FIXME: Use a better way to handle file content. + auto file = co_await async::fs::read(path.str()); + if(!file) { + co_return json::Value(nullptr); + } + llvm::StringRef content = *file; + + struct SemanticTokens { + /// The actual tokens. + std::vector data; + + void add(std::uint32_t line, + std::uint32_t character, + std::uint32_t length, + SymbolKind kind, + SymbolModifiers modifiers) { + /// FIXME: Add a map between lsp kinds and our kinds. + /// [line, character, length, tokenType, tokenModifiers] + data.emplace_back(line); + data.emplace_back(character); + data.emplace_back(length); + data.emplace_back(kind.value()); + data.emplace_back(modifiers.value()); + } + }; + + SemanticTokens result; + + PositionConverter converter(content, kind); + std::uint32_t lastLine = 0; + std::uint32_t lastChar = 0; + + for(auto& token: tokens) { + auto [beginOffset, endOffset] = token.range; + auto [beginLine, beginChar] = converter.toPosition(beginOffset); + auto [endLine, endChar] = converter.toPosition(endOffset); + + if(beginLine == endLine) [[likely]] { + std::uint32_t line = beginLine - lastLine; + std::uint32_t character = (line == 0 ? beginChar - lastChar : beginChar); + std::uint32_t length = endChar - beginChar; + result.add(line, character, length, token.kind, token.modifiers); + } else { + /// If the token spans multiple lines, split it into multiple tokens. + auto subContent = content.substr(beginOffset, endOffset - beginOffset); + + /// The first line is special. + bool isFirst = true; + /// The offset of the last line end. + std::uint32_t lastLineOffset = 0; + /// The length of the current line. + std::uint32_t lineLength = 0; + + for(auto c: subContent) { + lineLength += 1; + if(c == '\n') { + std::uint32_t line; + std::uint32_t character; + + if(isFirst) [[unlikely]] { + line = beginLine - lastLine; + character = (line == 0 ? beginChar - lastChar : beginChar); + isFirst = false; + } else { + line = 1; + character = 0; + } + + std::uint32_t length = + remeasure(subContent.substr(lastLineOffset, lineLength), kind); + result.add(line, character, length, token.kind, token.modifiers); + + lastLineOffset += lineLength; + lineLength = 0; + } + } + + /// Process the last line if it's not empty. + if(lineLength > 0) { + std::uint32_t length = remeasure(subContent.substr(lastLineOffset), kind); + result.add(1, 0, length, token.kind, token.modifiers); + } + } + + lastLine = endLine; + lastChar = endChar; + } + + co_return json::serialize(result); +} + +} // namespace clice diff --git a/src/Server/Server.cpp b/src/Server/Server.cpp index c089dc55..aa930a16 100644 --- a/src/Server/Server.cpp +++ b/src/Server/Server.cpp @@ -3,7 +3,7 @@ namespace clice { -Server::Server() : indexer(database,config::index ), scheduler(database, {}) { +Server::Server() : indexer(database, config::index), scheduler(database, {}) { addMethod("initialize", &Server::onInitialize); addMethod("initialized", &Server::onInitialized); addMethod("shutdown", &Server::onShutdown); @@ -25,19 +25,19 @@ Server::Server() : indexer(database,config::index ), scheduler(database, {}) { // addMethod("textDocument/typeHierarchy/prepare", &Server::onPrepareTypeHierarchy); // addMethod("textDocument/typeHierarchy/supertypes", &Server::onSupertypes); // addMethod("textDocument/typeHierarchy/subtypes", &Server::onSubtypes); - addMethod("textDocument/documentHighlight", &Server::onDocumentHighlight); - addMethod("textDocument/documentLink", &Server::onDocumentLink); - addMethod("textDocument/hover", &Server::onHover); - addMethod("textDocument/codeLens", &Server::onCodeLens); - addMethod("textDocument/foldingRange", &Server::onFoldingRange); - addMethod("textDocument/documentSymbol", &Server::onDocumentSymbol); - addMethod("textDocument/semanticTokens/full", &Server::onSemanticTokens); - addMethod("textDocument/inlayHint", &Server::onInlayHint); - addMethod("textDocument/completion", &Server::onCodeCompletion); - addMethod("textDocument/signatureHelp", &Server::onSignatureHelp); - addMethod("textDocument/codeAction", &Server::onCodeAction); - addMethod("textDocument/formatting", &Server::onFormatting); - addMethod("textDocument/rangeFormatting", &Server::onRangeFormatting); + // addMethod("textDocument/documentHighlight", &Server::onDocumentHighlight); + // addMethod("textDocument/documentLink", &Server::onDocumentLink); + // addMethod("textDocument/hover", &Server::onHover); + // addMethod("textDocument/codeLens", &Server::onCodeLens); + // addMethod("textDocument/foldingRange", &Server::onFoldingRange); + // addMethod("textDocument/documentSymbol", &Server::onDocumentSymbol); + // addMethod("textDocument/semanticTokens/full", &Server::onSemanticTokens); + // addMethod("textDocument/inlayHint", &Server::onInlayHint); + // addMethod("textDocument/completion", &Server::onCodeCompletion); + // addMethod("textDocument/signatureHelp", &Server::onSignatureHelp); + // addMethod("textDocument/codeAction", &Server::onCodeAction); + // addMethod("textDocument/formatting", &Server::onFormatting); + // addMethod("textDocument/rangeFormatting", &Server::onRangeFormatting); addMethod("workspace/didChangeWatchedFiles", &Server::onDidChangeWatchedFiles); diff --git a/unittests/Feature/SemanticTokens.cpp b/unittests/Feature/SemanticTokens.cpp index 5bc128bd..22868d27 100644 --- a/unittests/Feature/SemanticTokens.cpp +++ b/unittests/Feature/SemanticTokens.cpp @@ -11,7 +11,7 @@ struct SemanticTokens : ::testing::Test, Tester { void run(llvm::StringRef code) { addMain("main.cpp", code); Tester::run(); - result = feature::semanticTokens(*info); + result = feature::indexSemanticTokens(*info); } void EXPECT_TOKEN(llvm::StringRef pos,