[clangd] Added highlighting for members and methods.

Summary: Added highlighting for members and methods.

Reviewers: hokein, sammccall, ilya-biryukov

Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D64617

llvm-svn: 366047
This commit is contained in:
Johan Vikstrom 2019-07-15 08:12:21 +00:00
parent ea36cdcec3
commit 17b4a932fa
4 changed files with 67 additions and 11 deletions

View File

@ -40,6 +40,16 @@ public:
return true; return true;
} }
bool VisitMemberExpr(MemberExpr *ME) {
const auto *MD = ME->getMemberDecl();
if (isa<CXXDestructorDecl>(MD))
// When calling the destructor manually like: AAA::~A(); The ~ is a
// MemberExpr. Other methods should still be highlighted though.
return true;
addToken(ME->getMemberLoc(), MD);
return true;
}
bool VisitNamedDecl(NamedDecl *ND) { bool VisitNamedDecl(NamedDecl *ND) {
// UsingDirectiveDecl's namespaces do not show up anywhere else in the // UsingDirectiveDecl's namespaces do not show up anywhere else in the
// Visit/Traverse mehods. But they should also be highlighted as a // Visit/Traverse mehods. But they should also be highlighted as a
@ -115,6 +125,14 @@ private:
addToken(Loc, HighlightingKind::Class); addToken(Loc, HighlightingKind::Class);
return; return;
} }
if (isa<CXXMethodDecl>(D)) {
addToken(Loc, HighlightingKind::Method);
return;
}
if (isa<FieldDecl>(D)) {
addToken(Loc, HighlightingKind::Field);
return;
}
if (isa<EnumDecl>(D)) { if (isa<EnumDecl>(D)) {
addToken(Loc, HighlightingKind::Enum); addToken(Loc, HighlightingKind::Enum);
return; return;
@ -247,8 +265,12 @@ llvm::StringRef toTextMateScope(HighlightingKind Kind) {
switch (Kind) { switch (Kind) {
case HighlightingKind::Function: case HighlightingKind::Function:
return "entity.name.function.cpp"; return "entity.name.function.cpp";
case HighlightingKind::Method:
return "entity.name.function.method.cpp";
case HighlightingKind::Variable: case HighlightingKind::Variable:
return "variable.cpp"; return "variable.other.cpp";
case HighlightingKind::Field:
return "variable.other.field.cpp";
case HighlightingKind::Class: case HighlightingKind::Class:
return "entity.name.type.class.cpp"; return "entity.name.type.class.cpp";
case HighlightingKind::Enum: case HighlightingKind::Enum:

View File

@ -26,6 +26,8 @@ namespace clangd {
enum class HighlightingKind { enum class HighlightingKind {
Variable = 0, Variable = 0,
Function, Function,
Method,
Field,
Class, Class,
Enum, Enum,
EnumConstant, EnumConstant,

View File

@ -5,12 +5,18 @@
# CHECK: "semanticHighlighting": { # CHECK: "semanticHighlighting": {
# CHECK-NEXT: "scopes": [ # CHECK-NEXT: "scopes": [
# CHECK-NEXT: [ # CHECK-NEXT: [
# CHECK-NEXT: "variable.cpp" # CHECK-NEXT: "variable.other.cpp"
# CHECK-NEXT: ], # CHECK-NEXT: ],
# CHECK-NEXT: [ # CHECK-NEXT: [
# CHECK-NEXT: "entity.name.function.cpp" # CHECK-NEXT: "entity.name.function.cpp"
# CHECK-NEXT: ], # CHECK-NEXT: ],
# CHECK-NEXT: [ # CHECK-NEXT: [
# CHECK-NEXT: "entity.name.function.method.cpp"
# CHECK-NEXT: ],
# CHECK-NEXT: [
# CHECK-NEXT: "variable.other.field.cpp"
# CHECK-NEXT: ],
# CHECK-NEXT: [
# CHECK-NEXT: "entity.name.type.class.cpp" # CHECK-NEXT: "entity.name.type.class.cpp"
# CHECK-NEXT: ], # CHECK-NEXT: ],
# CHECK-NEXT: [ # CHECK-NEXT: [

View File

@ -38,7 +38,9 @@ void checkHighlightings(llvm::StringRef Code) {
{HighlightingKind::Class, "Class"}, {HighlightingKind::Class, "Class"},
{HighlightingKind::Enum, "Enum"}, {HighlightingKind::Enum, "Enum"},
{HighlightingKind::Namespace, "Namespace"}, {HighlightingKind::Namespace, "Namespace"},
{HighlightingKind::EnumConstant, "EnumConstant"}}; {HighlightingKind::EnumConstant, "EnumConstant"},
{HighlightingKind::Field, "Field"},
{HighlightingKind::Method, "Method"}};
std::vector<HighlightingToken> ExpectedTokens; std::vector<HighlightingToken> ExpectedTokens;
for (const auto &KindString : KindToString) { for (const auto &KindString : KindToString) {
std::vector<HighlightingToken> Toks = makeHighlightingTokens( std::vector<HighlightingToken> Toks = makeHighlightingTokens(
@ -54,14 +56,14 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
const char *TestCases[] = { const char *TestCases[] = {
R"cpp( R"cpp(
struct $Class[[AS]] { struct $Class[[AS]] {
double SomeMember; double $Field[[SomeMember]];
}; };
struct { struct {
} $Variable[[S]]; } $Variable[[S]];
void $Function[[foo]](int $Variable[[A]], $Class[[AS]] $Variable[[As]]) { void $Function[[foo]](int $Variable[[A]], $Class[[AS]] $Variable[[As]]) {
auto $Variable[[VeryLongVariableName]] = 12312; auto $Variable[[VeryLongVariableName]] = 12312;
$Class[[AS]] $Variable[[AA]]; $Class[[AS]] $Variable[[AA]];
auto $Variable[[L]] = $Variable[[AA]].SomeMember + $Variable[[A]]; auto $Variable[[L]] = $Variable[[AA]].$Field[[SomeMember]] + $Variable[[A]];
auto $Variable[[FN]] = [ $Variable[[AA]]](int $Variable[[A]]) -> void {}; auto $Variable[[FN]] = [ $Variable[[AA]]](int $Variable[[A]]) -> void {};
$Variable[[FN]](12312); $Variable[[FN]](12312);
} }
@ -73,19 +75,19 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
auto $Variable[[Bou]] = $Function[[Gah]]; auto $Variable[[Bou]] = $Function[[Gah]];
} }
struct $Class[[A]] { struct $Class[[A]] {
void $Function[[abc]](); void $Method[[abc]]();
}; };
)cpp", )cpp",
R"cpp( R"cpp(
namespace $Namespace[[abc]] { namespace $Namespace[[abc]] {
template<typename T> template<typename T>
struct $Class[[A]] { struct $Class[[A]] {
T t; T $Field[[t]];
}; };
} }
template<typename T> template<typename T>
struct $Class[[C]] : $Namespace[[abc]]::A<T> { struct $Class[[C]] : $Namespace[[abc]]::A<T> {
typename T::A* D; typename T::A* $Field[[D]];
}; };
$Namespace[[abc]]::$Class[[A]]<int> $Variable[[AA]]; $Namespace[[abc]]::$Class[[A]]<int> $Variable[[AA]];
typedef $Namespace[[abc]]::$Class[[A]]<int> AAA; typedef $Namespace[[abc]]::$Class[[A]]<int> AAA;
@ -93,7 +95,7 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
$Class[[B]](); $Class[[B]]();
~$Class[[B]](); ~$Class[[B]]();
void operator<<($Class[[B]]); void operator<<($Class[[B]]);
$Class[[AAA]] AA; $Class[[AAA]] $Field[[AA]];
}; };
$Class[[B]]::$Class[[B]]() {} $Class[[B]]::$Class[[B]]() {}
$Class[[B]]::~$Class[[B]]() {} $Class[[B]]::~$Class[[B]]() {}
@ -112,8 +114,8 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
$EnumConstant[[Hi]], $EnumConstant[[Hi]],
}; };
struct $Class[[A]] { struct $Class[[A]] {
$Enum[[E]] EEE; $Enum[[E]] $Field[[EEE]];
$Enum[[EE]] EEEE; $Enum[[EE]] $Field[[EEEE]];
}; };
int $Variable[[I]] = $EnumConstant[[Hi]]; int $Variable[[I]] = $EnumConstant[[Hi]];
$Enum[[E]] $Variable[[L]] = $Enum[[E]]::$EnumConstant[[B]]; $Enum[[E]] $Variable[[L]] = $Enum[[E]]::$EnumConstant[[B]];
@ -140,6 +142,30 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
$Namespace[[vwz]]::$Class[[A]]::$Enum[[B]]::$EnumConstant[[Hi]]; $Namespace[[vwz]]::$Class[[A]]::$Enum[[B]]::$EnumConstant[[Hi]];
::$Namespace[[vwz]]::$Class[[A]] $Variable[[B]]; ::$Namespace[[vwz]]::$Class[[A]] $Variable[[B]];
::$Namespace[[abc]]::$Namespace[[bcd]]::$Class[[A]] $Variable[[BB]]; ::$Namespace[[abc]]::$Namespace[[bcd]]::$Class[[A]] $Variable[[BB]];
)cpp",
R"cpp(
struct $Class[[D]] {
double $Field[[C]];
};
struct $Class[[A]] {
double $Field[[B]];
$Class[[D]] $Field[[E]];
static double $Variable[[S]];
void $Method[[foo]]() {
$Field[[B]] = 123;
this->$Field[[B]] = 156;
this->$Method[[foo]]();
$Method[[foo]]();
$Variable[[S]] = 90.1;
}
};
void $Function[[foo]]() {
$Class[[A]] $Variable[[AA]];
$Variable[[AA]].$Field[[B]] += 2;
$Variable[[AA]].$Method[[foo]]();
$Variable[[AA]].$Field[[E]].$Field[[C]];
$Class[[A]]::$Variable[[S]] = 90;
}
)cpp"}; )cpp"};
for (const auto &TestCase : TestCases) { for (const auto &TestCase : TestCases) {
checkHighlightings(TestCase); checkHighlightings(TestCase);