[clangd] Add highlighting modifier "constructorOrDestructor"

This is useful for clients that want to highlight constructors and
destructors different from classes, e.g. like functions.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D134728
This commit is contained in:
Christian Kandeler 2022-08-04 13:33:33 +02:00
parent ca5fbac783
commit 8b3668754c
5 changed files with 44 additions and 13 deletions

View File

@ -649,6 +649,29 @@ public:
return true;
}
bool VisitCXXDestructorDecl(CXXDestructorDecl *D) {
if (auto *TI = D->getNameInfo().getNamedTypeInfo()) {
SourceLocation Loc = TI->getTypeLoc().getBeginLoc();
H.addExtraModifier(Loc, HighlightingModifier::ConstructorOrDestructor);
H.addExtraModifier(Loc, HighlightingModifier::Declaration);
if (D->isThisDeclarationADefinition())
H.addExtraModifier(Loc, HighlightingModifier::Definition);
}
return true;
}
bool VisitCXXMemberCallExpr(CXXMemberCallExpr *CE) {
if (isa<CXXDestructorDecl>(CE->getMethodDecl())) {
if (auto *ME = dyn_cast<MemberExpr>(CE->getCallee())) {
if (auto *TI = ME->getMemberNameInfo().getNamedTypeInfo()) {
H.addExtraModifier(TI->getTypeLoc().getBeginLoc(),
HighlightingModifier::ConstructorOrDestructor);
}
}
}
return true;
}
bool VisitDeclaratorDecl(DeclaratorDecl *D) {
auto *AT = D->getType()->getContainedAutoType();
if (!AT)
@ -879,6 +902,8 @@ std::vector<HighlightingToken> getSemanticHighlightings(ParsedAST &AST) {
Tok.addModifier(HighlightingModifier::DefaultLibrary);
if (Decl->isDeprecated())
Tok.addModifier(HighlightingModifier::Deprecated);
if (isa<CXXConstructorDecl>(Decl))
Tok.addModifier(HighlightingModifier::ConstructorOrDestructor);
if (R.IsDecl) {
// Do not treat an UnresolvedUsingValueDecl as a declaration.
// It's more common to think of it as a reference to the
@ -960,6 +985,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingModifier K) {
return OS << "decl"; // abbreviation for common case
case HighlightingModifier::Definition:
return OS << "def"; // abbrevation for common case
case HighlightingModifier::ConstructorOrDestructor:
return OS << "constrDestr";
default:
return OS << toSemanticTokenModifier(K);
}
@ -1111,6 +1138,8 @@ llvm::StringRef toSemanticTokenModifier(HighlightingModifier Modifier) {
return "defaultLibrary";
case HighlightingModifier::UsedAsMutableReference:
return "usedAsMutableReference"; // nonstandard
case HighlightingModifier::ConstructorOrDestructor:
return "constructorOrDestructor"; // nonstandard
case HighlightingModifier::FunctionScope:
return "functionScope"; // nonstandard
case HighlightingModifier::ClassScope:

View File

@ -71,6 +71,7 @@ enum class HighlightingModifier {
DependentName,
DefaultLibrary,
UsedAsMutableReference,
ConstructorOrDestructor,
FunctionScope,
ClassScope,

View File

@ -68,6 +68,7 @@
# CHECK-NEXT: "dependentName",
# CHECK-NEXT: "defaultLibrary",
# CHECK-NEXT: "usedAsMutableReference",
# CHECK-NEXT: "constructorOrDestructor",
# CHECK-NEXT: "functionScope",
# CHECK-NEXT: "classScope",
# CHECK-NEXT: "fileScope",

View File

@ -23,7 +23,7 @@
# CHECK-NEXT: 4,
# CHECK-NEXT: 1,
# CHECK-NEXT: 0,
# CHECK-NEXT: 16387
# CHECK-NEXT: 32771
# CHECK-NEXT: ],
# CHECK-NEXT: "resultId": "1"
# CHECK-NEXT: }
@ -49,7 +49,7 @@
# CHECK-NEXT: 4,
# CHECK-NEXT: 1,
# CHECK-NEXT: 0,
# CHECK-NEXT: 16387
# CHECK-NEXT: 32771
# CHECK-NEXT: ],
# Inserted at position 1
# CHECK-NEXT: "deleteCount": 0,
@ -72,12 +72,12 @@
# CHECK-NEXT: 4,
# CHECK-NEXT: 1,
# CHECK-NEXT: 0,
# CHECK-NEXT: 16387,
# CHECK-NEXT: 32771,
# CHECK-NEXT: 1,
# CHECK-NEXT: 4,
# CHECK-NEXT: 1,
# CHECK-NEXT: 0,
# CHECK-NEXT: 16387
# CHECK-NEXT: 32771
# CHECK-NEXT: ],
# CHECK-NEXT: "resultId": "3"
# CHECK-NEXT: }

View File

@ -142,16 +142,16 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
$Namespace[[abc]]::$Class[[A]]<int> $Variable_def[[AA]];
typedef $Namespace[[abc]]::$Class[[A]]<int> $Class_decl[[AAA]];
struct $Class_def[[B]] {
$Class_decl[[B]]();
~$Class[[B]](); // FIXME: inconsistent with constructor
$Class_decl_constrDestr[[B]]();
~$Class_decl_constrDestr[[B]]();
void operator<<($Class[[B]]);
$Class[[AAA]] $Field_decl[[AA]];
};
$Class[[B]]::$Class_def[[B]]() {}
$Class[[B]]::~$Class[[B]]() {} // FIXME: inconsistent with constructor
$Class[[B]]::$Class_def_constrDestr[[B]]() {}
$Class[[B]]::~$Class_def_constrDestr[[B]]() {}
void $Function_def[[f]] () {
$Class[[B]] $LocalVariable_def[[BB]] = $Class[[B]]();
$LocalVariable[[BB]].~$Class[[B]]();
$LocalVariable[[BB]].~$Class_constrDestr[[B]]();
$Class[[B]]();
}
)cpp",
@ -310,13 +310,13 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
$Class[[Foo]] $Field_decl[[Fo]];
$Enum[[En]] $Field_decl[[E]];
int $Field_decl[[I]];
$Class_def[[Bar]] ($Class[[Foo]] $Parameter_def[[F]],
$Class_def_constrDestr[[Bar]] ($Class[[Foo]] $Parameter_def[[F]],
$Enum[[En]] $Parameter_def[[E]])
: $Field[[Fo]] ($Parameter[[F]]), $Field[[E]] ($Parameter[[E]]),
$Field[[I]] (123) {}
};
class $Class_def[[Bar2]] : public $Class[[Bar]] {
$Class_def[[Bar2]]() : $Class[[Bar]]($Class[[Foo]](), $EnumConstant_readonly[[EC]]) {}
$Class_def_constrDestr[[Bar2]]() : $Class[[Bar]]($Class[[Foo]](), $EnumConstant_readonly[[EC]]) {}
};
)cpp",
R"cpp(
@ -757,7 +757,7 @@ sizeof...($TemplateParameter[[Elements]]);
static inline int $StaticField_def_static[[j]] = 0;
};
struct $Class_def[[ClassWithRefMembers]] {
$Class_def[[ClassWithRefMembers]](int $Parameter_def[[i]])
$Class_def_constrDestr[[ClassWithRefMembers]](int $Parameter_def[[i]])
: $Field[[i1]]($Parameter[[i]]),
$Field_readonly[[i2]]($Parameter[[i]]),
$Field[[i3]]($Parameter_usedAsMutableReference[[i]]),
@ -803,7 +803,7 @@ sizeof...($TemplateParameter[[Elements]]);
$LocalVariable_readonly[[c2]][$LocalVariable[[val]]];
}
struct $Class_def[[S]] {
$Class_def[[S]](int&) {
$Class_def_constrDestr[[S]](int&) {
$Class[[S]] $LocalVariable_def[[s1]]($Field_usedAsMutableReference[[field]]);
$Class[[S]] $LocalVariable_def[[s2]]($LocalVariable[[s1]].$Field_usedAsMutableReference[[field]]);