diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -34,26 +34,42 @@ return Tokens; } - bool VisitVarDecl(VarDecl *Var) { - addToken(Var, HighlightingKind::Variable); + bool VisitNamedDecl(NamedDecl *ND) { + if (ND->getDeclName().isEmpty()) + // Don't add symbols that don't have any length. + return true; + addToken(ND->getLocation(), ND); return true; } - bool VisitFunctionDecl(FunctionDecl *Func) { - addToken(Func, HighlightingKind::Function); + + bool VisitDeclRefExpr(DeclRefExpr *Ref) { + if (Ref->getNameInfo().getName().getNameKind() == + DeclarationName::CXXOperatorName) + // Don't want to highlight operator usages. + return true; + + addToken(Ref->getLocation(), Ref->getDecl()); return true; } private: - void addToken(const NamedDecl *D, HighlightingKind Kind) { - if (D->getLocation().isMacroID()) - // FIXME: skip tokens inside macros for now. + void addToken(SourceLocation Loc, const Decl* D) { + if(isa(D)) { + addToken(Loc, HighlightingKind::Variable); + return; + } + if(isa(D)) { + addToken(Loc, HighlightingKind::Function); return; + } + } - if (D->getDeclName().isEmpty()) - // Don't add symbols that don't have any length. + void addToken(SourceLocation Loc, HighlightingKind Kind) { + if (Loc.isMacroID()) + // FIXME: skip tokens inside macros for now. return; - auto R = getTokenRange(SM, Ctx.getLangOpts(), D->getLocation()); + auto R = getTokenRange(SM, Ctx.getLangOpts(), Loc); if (!R) { // R should always have a value, if it doesn't something is very wrong. elog("Tried to add semantic token with an invalid range"); diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -28,7 +28,7 @@ return Tokens; } - +#include void checkHighlightings(llvm::StringRef Code) { Annotations Test(Code); auto AST = TestTU::withCode(Test.code()).build(); @@ -43,6 +43,14 @@ } auto ActualTokens = getSemanticHighlightings(AST); + std::cout << "\n\n"; + for(auto Tok : ExpectedTokens) { + std::cout << "E:: " << Tok.R.start.line << ":" << Tok.R.start.character << std::endl; + } + for(auto Tok : ActualTokens) { + std::cout << "A:: " << Tok.R.start.line << ":" << Tok.R.start.character << std::endl; + } + EXPECT_THAT(ActualTokens, testing::UnorderedElementsAreArray(ExpectedTokens)); } @@ -57,10 +65,20 @@ void $Function[[foo]](int $Variable[[a]]) { auto $Variable[[VeryLongVariableName]] = 12312; A $Variable[[aa]]; + auto $Variable[[l]] = $Variable[[aa]].SomeMember + $Variable[[a]]; } )cpp", R"cpp( void $Function[[foo]](int); + )cpp", + R"cpp( + void $Function[[gah]](); + void $Function[[foo]]() { + int $Variable[[b]]; + auto $Variable[[FN]] = [ $Variable[[b]]](int $Variable[[a]]) -> void {}; + $Variable[[FN]](12312); + auto $Variable[[bou]] = $Function[[gah]]; + } )cpp"}; for (const auto &TestCase : TestCases) { checkHighlightings(TestCase);