nridge created this revision. nridge added a reviewer: sammccall. Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay, ilya-biryukov. Herald added a project: clang.
The intention here is to allow clients to continue using a different color for each of our HighlightingKinds, as with the old API. For some highlighting kinds, this is accomplished by adding more token types (e.g. splitting "dependent" into "dependentType" and "dependentName"). For others, it is accomplished by using token modifiers. Note that the patch introduces a "member" modifier in place of the "member" token type. This allows member variables and member functions to be colored differently, by using the "variable" and "function" token types, respectively, combined with the "member" modifier. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77702 Files: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/SemanticHighlighting.cpp clang-tools-extra/clangd/SemanticHighlighting.h
Index: clang-tools-extra/clangd/SemanticHighlighting.h =================================================================== --- clang-tools-extra/clangd/SemanticHighlighting.h +++ clang-tools-extra/clangd/SemanticHighlighting.h @@ -88,6 +88,7 @@ // main AST. std::vector<HighlightingToken> getSemanticHighlightings(ParsedAST &AST); +std::vector<llvm::StringRef> semanticTokenModifiers(); std::vector<SemanticToken> toSemanticTokens(llvm::ArrayRef<HighlightingToken>); llvm::StringRef toSemanticTokenType(HighlightingKind Kind); std::vector<SemanticTokensEdit> diffTokens(llvm::ArrayRef<SemanticToken> Before, Index: clang-tools-extra/clangd/SemanticHighlighting.cpp =================================================================== --- clang-tools-extra/clangd/SemanticHighlighting.cpp +++ clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -445,6 +445,43 @@ return std::tie(L.Line, L.Tokens) == std::tie(R.Line, R.Tokens); } +enum class TokenModifiers { + None = 0, + Local = 1, + Static = 2, + Member = 4, +}; + +TokenModifiers operator|(TokenModifiers A, TokenModifiers B) { + return static_cast<TokenModifiers>(static_cast<unsigned>(A) | + static_cast<unsigned>(B)); +} + +TokenModifiers getTokenModifiers(HighlightingKind Kind) { + switch (Kind) { + case HighlightingKind::LocalVariable: + return TokenModifiers::Local; + case HighlightingKind::StaticField: + return TokenModifiers::Static | TokenModifiers::Member; + case HighlightingKind::Method: + return TokenModifiers::Member; + case HighlightingKind::StaticMethod: + return TokenModifiers::Static | TokenModifiers::Member; + case HighlightingKind::Field: + return TokenModifiers::Member; + default: + return TokenModifiers::None; + } +} + +std::vector<llvm::StringRef> semanticTokenModifiers() { + std::vector<llvm::StringRef> Modifiers; + Modifiers.push_back("local"); + Modifiers.push_back("static"); + Modifiers.push_back("member"); + return Modifiers; +} + std::vector<SemanticToken> toSemanticTokens(llvm::ArrayRef<HighlightingToken> Tokens) { assert(std::is_sorted(Tokens.begin(), Tokens.end())); @@ -473,6 +510,7 @@ assert(Tok.R.end.line == Tok.R.start.line); Out.length = Tok.R.end.character - Tok.R.start.character; Out.tokenType = static_cast<unsigned>(Tok.Kind); + Out.tokenModifiers = static_cast<unsigned>(getTokenModifiers(Tok.Kind)); Last = &Tok; } @@ -489,12 +527,11 @@ case HighlightingKind::Function: return "function"; case HighlightingKind::Method: - return "member"; + return "function"; case HighlightingKind::StaticMethod: - // FIXME: better function/member with static modifier? return "function"; case HighlightingKind::Field: - return "member"; + return "variable"; case HighlightingKind::Class: return "class"; case HighlightingKind::Enum: @@ -504,9 +541,9 @@ case HighlightingKind::Typedef: return "type"; case HighlightingKind::DependentType: - return "dependent"; // nonstandard + return "dependentType"; // nonstandard case HighlightingKind::DependentName: - return "dependent"; // nonstandard + return "dependentName"; // nonstandard case HighlightingKind::Namespace: return "namespace"; case HighlightingKind::TemplateParameter: @@ -514,7 +551,7 @@ case HighlightingKind::Concept: return "concept"; // nonstandard case HighlightingKind::Primitive: - return "type"; + return "primitive"; case HighlightingKind::Macro: return "macro"; case HighlightingKind::InactiveCode: @@ -537,8 +574,8 @@ llvm::SmallVector<char, 128> LineByteTokens; llvm::raw_svector_ostream OS(LineByteTokens); for (const auto &Token : Line.Tokens) { - // Writes the token to LineByteTokens in the byte format specified by the - // LSP proposal. Described below. + // Writes the token to LineByteTokens in the byte format specified by + // the LSP proposal. Described below. // |<---- 4 bytes ---->|<-- 2 bytes -->|<--- 2 bytes -->| // | character | length | index | @@ -600,9 +637,8 @@ llvm_unreachable("unhandled HighlightingKind"); } -std::vector<SemanticTokensEdit> -diffTokens(llvm::ArrayRef<SemanticToken> Old, - llvm::ArrayRef<SemanticToken> New) { +std::vector<SemanticTokensEdit> diffTokens(llvm::ArrayRef<SemanticToken> Old, + llvm::ArrayRef<SemanticToken> New) { // For now, just replace everything from the first-last modification. // FIXME: use a real diff instead, this is bad with include-insertion. Index: clang-tools-extra/clangd/ClangdLSPServer.cpp =================================================================== --- clang-tools-extra/clangd/ClangdLSPServer.cpp +++ clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -589,8 +589,9 @@ {"documentProvider", llvm::json::Object{{"edits", true}}}, {"rangeProvider", false}, {"legend", - llvm::json::Object{{"tokenTypes", semanticTokenTypes()}, - {"tokenModifiers", llvm::json::Array()}}}, + llvm::json::Object{ + {"tokenTypes", semanticTokenTypes()}, + {"tokenModifiers", semanticTokenModifiers()}}}, }}, {"signatureHelpProvider", llvm::json::Object{
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits