forked from OSchip/llvm-project
[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:
parent
ea36cdcec3
commit
17b4a932fa
|
@ -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:
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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: [
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue