forked from OSchip/llvm-project
[clangd] Added semantic highlighting support for primitives.
Summary: Adds a new HighlightingKind "Primitive". Adds a special case for TypeLocs that have an underlying TypePtr that is are builtin types, adding them as primitives. The primary reason for this change is because otherwise typedefs that typedef primitives `typedef int A` would not get highlighted (so in the example `A` would not get any highlightings.) Reviewers: hokein, ilya-biryukov Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D65943 llvm-svn: 368291
This commit is contained in:
parent
e1e749d86a
commit
d73d994746
|
@ -138,9 +138,13 @@ public:
|
|||
|
||||
private:
|
||||
void addTypeLoc(SourceLocation Loc, const TypeLoc &TL) {
|
||||
if (const Type *TP = TL.getTypePtr())
|
||||
if (const Type *TP = TL.getTypePtr()) {
|
||||
if (const TagDecl *TD = TP->getAsTagDecl())
|
||||
addToken(Loc, TD);
|
||||
if (TP->isBuiltinType())
|
||||
// Builtins must be special cased as they do not have a TagDecl.
|
||||
addToken(Loc, HighlightingKind::Primitive);
|
||||
}
|
||||
}
|
||||
|
||||
void addToken(SourceLocation Loc, const NamedDecl *D) {
|
||||
|
@ -386,6 +390,8 @@ llvm::StringRef toTextMateScope(HighlightingKind Kind) {
|
|||
return "entity.name.namespace.cpp";
|
||||
case HighlightingKind::TemplateParameter:
|
||||
return "entity.name.type.template.cpp";
|
||||
case HighlightingKind::Primitive:
|
||||
return "storage.type.primitive.cpp";
|
||||
case HighlightingKind::NumKinds:
|
||||
llvm_unreachable("must not pass NumKinds to the function");
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ enum class HighlightingKind {
|
|||
EnumConstant,
|
||||
Namespace,
|
||||
TemplateParameter,
|
||||
Primitive,
|
||||
|
||||
NumKinds,
|
||||
};
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
# CHECK-NEXT: ],
|
||||
# CHECK-NEXT: [
|
||||
# CHECK-NEXT: "entity.name.type.template.cpp"
|
||||
# CHECK-NEXT: ],
|
||||
# CHECK-NEXT: [
|
||||
# CHECK-NEXT: "storage.type.primitive.cpp"
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: },
|
||||
|
@ -40,7 +43,7 @@
|
|||
# CHECK-NEXT: "lines": [
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "line": 0,
|
||||
# CHECK-NEXT: "tokens": "AAAABAABAAA="
|
||||
# CHECK-NEXT: "tokens": "AAAAAAADAAkAAAAEAAEAAA=="
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ],
|
||||
# CHECK-NEXT: "textDocument": {
|
||||
|
@ -55,11 +58,11 @@
|
|||
# CHECK-NEXT: "lines": [
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "line": 0,
|
||||
# CHECK-NEXT: "tokens": "AAAABAABAAA="
|
||||
# CHECK-NEXT: "tokens": "AAAAAAADAAkAAAAEAAEAAA=="
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "line": 1,
|
||||
# CHECK-NEXT: "tokens": "AAAABAABAAA="
|
||||
# CHECK-NEXT: "tokens": "AAAAAAADAAkAAAAEAAEAAA=="
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ],
|
||||
# CHECK-NEXT: "textDocument": {
|
||||
|
@ -74,7 +77,7 @@
|
|||
# CHECK-NEXT: "lines": [
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "line": 1,
|
||||
# CHECK-NEXT: "tokens": "AAAABAABAAA="
|
||||
# CHECK-NEXT: "tokens": "AAAAAAADAAkAAAAEAAEAAA=="
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ],
|
||||
# CHECK-NEXT: "textDocument": {
|
||||
|
|
|
@ -39,7 +39,8 @@ std::vector<HighlightingToken> getExpectedTokens(Annotations &Test) {
|
|||
{HighlightingKind::EnumConstant, "EnumConstant"},
|
||||
{HighlightingKind::Field, "Field"},
|
||||
{HighlightingKind::Method, "Method"},
|
||||
{HighlightingKind::TemplateParameter, "TemplateParameter"}};
|
||||
{HighlightingKind::TemplateParameter, "TemplateParameter"},
|
||||
{HighlightingKind::Primitive, "Primitive"}};
|
||||
std::vector<HighlightingToken> ExpectedTokens;
|
||||
for (const auto &KindString : KindToString) {
|
||||
std::vector<HighlightingToken> Toks = makeHighlightingTokens(
|
||||
|
@ -93,26 +94,26 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
|
|||
const char *TestCases[] = {
|
||||
R"cpp(
|
||||
struct $Class[[AS]] {
|
||||
double $Field[[SomeMember]];
|
||||
$Primitive[[double]] $Field[[SomeMember]];
|
||||
};
|
||||
struct {
|
||||
} $Variable[[S]];
|
||||
void $Function[[foo]](int $Variable[[A]], $Class[[AS]] $Variable[[As]]) {
|
||||
$Primitive[[void]] $Function[[foo]]($Primitive[[int]] $Variable[[A]], $Class[[AS]] $Variable[[As]]) {
|
||||
auto $Variable[[VeryLongVariableName]] = 12312;
|
||||
$Class[[AS]] $Variable[[AA]];
|
||||
auto $Variable[[L]] = $Variable[[AA]].$Field[[SomeMember]] + $Variable[[A]];
|
||||
auto $Variable[[FN]] = [ $Variable[[AA]]](int $Variable[[A]]) -> void {};
|
||||
auto $Variable[[FN]] = [ $Variable[[AA]]]($Primitive[[int]] $Variable[[A]]) -> $Primitive[[void]] {};
|
||||
$Variable[[FN]](12312);
|
||||
}
|
||||
)cpp",
|
||||
R"cpp(
|
||||
void $Function[[foo]](int);
|
||||
void $Function[[Gah]]();
|
||||
void $Function[[foo]]() {
|
||||
$Primitive[[void]] $Function[[foo]]($Primitive[[int]]);
|
||||
$Primitive[[void]] $Function[[Gah]]();
|
||||
$Primitive[[void]] $Function[[foo]]() {
|
||||
auto $Variable[[Bou]] = $Function[[Gah]];
|
||||
}
|
||||
struct $Class[[A]] {
|
||||
void $Method[[abc]]();
|
||||
$Primitive[[void]] $Method[[abc]]();
|
||||
};
|
||||
)cpp",
|
||||
R"cpp(
|
||||
|
@ -126,17 +127,17 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
|
|||
struct $Class[[C]] : $Namespace[[abc]]::$Class[[A]]<$TemplateParameter[[T]]> {
|
||||
typename $TemplateParameter[[T]]::A* $Field[[D]];
|
||||
};
|
||||
$Namespace[[abc]]::$Class[[A]]<int> $Variable[[AA]];
|
||||
typedef $Namespace[[abc]]::$Class[[A]]<int> $Class[[AAA]];
|
||||
$Namespace[[abc]]::$Class[[A]]<$Primitive[[int]]> $Variable[[AA]];
|
||||
typedef $Namespace[[abc]]::$Class[[A]]<$Primitive[[int]]> $Class[[AAA]];
|
||||
struct $Class[[B]] {
|
||||
$Class[[B]]();
|
||||
~$Class[[B]]();
|
||||
void operator<<($Class[[B]]);
|
||||
$Primitive[[void]] operator<<($Class[[B]]);
|
||||
$Class[[AAA]] $Field[[AA]];
|
||||
};
|
||||
$Class[[B]]::$Class[[B]]() {}
|
||||
$Class[[B]]::~$Class[[B]]() {}
|
||||
void $Function[[f]] () {
|
||||
$Primitive[[void]] $Function[[f]] () {
|
||||
$Class[[B]] $Variable[[BB]] = $Class[[B]]();
|
||||
$Variable[[BB]].~$Class[[B]]();
|
||||
$Class[[B]]();
|
||||
|
@ -154,7 +155,7 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
|
|||
$Enum[[E]] $Field[[EEE]];
|
||||
$Enum[[EE]] $Field[[EEEE]];
|
||||
};
|
||||
int $Variable[[I]] = $EnumConstant[[Hi]];
|
||||
$Primitive[[int]] $Variable[[I]] = $EnumConstant[[Hi]];
|
||||
$Enum[[E]] $Variable[[L]] = $Enum[[E]]::$EnumConstant[[B]];
|
||||
)cpp",
|
||||
R"cpp(
|
||||
|
@ -182,13 +183,13 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
|
|||
)cpp",
|
||||
R"cpp(
|
||||
struct $Class[[D]] {
|
||||
double $Field[[C]];
|
||||
$Primitive[[double]] $Field[[C]];
|
||||
};
|
||||
struct $Class[[A]] {
|
||||
double $Field[[B]];
|
||||
$Primitive[[double]] $Field[[B]];
|
||||
$Class[[D]] $Field[[E]];
|
||||
static double $Variable[[S]];
|
||||
void $Method[[foo]]() {
|
||||
static $Primitive[[double]] $Variable[[S]];
|
||||
$Primitive[[void]] $Method[[foo]]() {
|
||||
$Field[[B]] = 123;
|
||||
this->$Field[[B]] = 156;
|
||||
this->$Method[[foo]]();
|
||||
|
@ -196,7 +197,7 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
|
|||
$Variable[[S]] = 90.1;
|
||||
}
|
||||
};
|
||||
void $Function[[foo]]() {
|
||||
$Primitive[[void]] $Function[[foo]]() {
|
||||
$Class[[A]] $Variable[[AA]];
|
||||
$Variable[[AA]].$Field[[B]] += 2;
|
||||
$Variable[[AA]].$Method[[foo]]();
|
||||
|
@ -206,14 +207,15 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
|
|||
)cpp",
|
||||
R"cpp(
|
||||
struct $Class[[AA]] {
|
||||
int $Field[[A]];
|
||||
$Primitive[[int]] $Field[[A]];
|
||||
}
|
||||
int $Variable[[B]];
|
||||
$Primitive[[int]] $Variable[[B]];
|
||||
$Class[[AA]] $Variable[[A]]{$Variable[[B]]};
|
||||
)cpp",
|
||||
R"cpp(
|
||||
namespace $Namespace[[a]] {
|
||||
struct $Class[[A]] {};
|
||||
typedef $Primitive[[char]] $Primitive[[C]];
|
||||
}
|
||||
typedef $Namespace[[a]]::$Class[[A]] $Class[[B]];
|
||||
using $Class[[BB]] = $Namespace[[a]]::$Class[[A]];
|
||||
|
@ -223,9 +225,11 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
|
|||
using $Enum[[CD]] = $Enum[[CC]];
|
||||
$Enum[[CC]] $Function[[f]]($Class[[B]]);
|
||||
$Enum[[CD]] $Function[[f]]($Class[[BB]]);
|
||||
typedef $Namespace[[a]]::$Primitive[[C]] $Primitive[[PC]];
|
||||
typedef $Primitive[[float]] $Primitive[[F]];
|
||||
)cpp",
|
||||
R"cpp(
|
||||
template<typename $TemplateParameter[[T]], typename = void>
|
||||
template<typename $TemplateParameter[[T]], typename = $Primitive[[void]]>
|
||||
class $Class[[A]] {
|
||||
$TemplateParameter[[T]] $Field[[AA]];
|
||||
$TemplateParameter[[T]] $Method[[foo]]();
|
||||
|
@ -237,7 +241,7 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
|
|||
template<class $TemplateParameter[[TT]], class $TemplateParameter[[GG]]>
|
||||
class $Class[[BB]] {};
|
||||
template<class $TemplateParameter[[T]]>
|
||||
class $Class[[BB]]<$TemplateParameter[[T]], int> {};
|
||||
class $Class[[BB]]<$TemplateParameter[[T]], $Primitive[[int]]> {};
|
||||
template<class $TemplateParameter[[T]]>
|
||||
class $Class[[BB]]<$TemplateParameter[[T]], $TemplateParameter[[T]]*> {};
|
||||
|
||||
|
@ -248,13 +252,13 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
|
|||
class $Class[[Foo]] {};
|
||||
|
||||
template<typename $TemplateParameter[[T]]>
|
||||
void $Function[[foo]]($TemplateParameter[[T]] ...);
|
||||
$Primitive[[void]] $Function[[foo]]($TemplateParameter[[T]] ...);
|
||||
)cpp",
|
||||
R"cpp(
|
||||
template <class $TemplateParameter[[T]]>
|
||||
struct $Class[[Tmpl]] {$TemplateParameter[[T]] $Field[[x]] = 0;};
|
||||
extern template struct $Class[[Tmpl]]<float>;
|
||||
template struct $Class[[Tmpl]]<double>;
|
||||
extern template struct $Class[[Tmpl]]<$Primitive[[float]]>;
|
||||
template struct $Class[[Tmpl]]<$Primitive[[double]]>;
|
||||
)cpp",
|
||||
// This test is to guard against highlightings disappearing when using
|
||||
// conversion operators as their behaviour in the clang AST differ from
|
||||
|
@ -263,14 +267,14 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
|
|||
class $Class[[Foo]] {};
|
||||
struct $Class[[Bar]] {
|
||||
explicit operator $Class[[Foo]]*() const;
|
||||
explicit operator int() const;
|
||||
explicit operator $Primitive[[int]]() const;
|
||||
operator $Class[[Foo]]();
|
||||
};
|
||||
void $Function[[f]]() {
|
||||
$Primitive[[void]] $Function[[f]]() {
|
||||
$Class[[Bar]] $Variable[[B]];
|
||||
$Class[[Foo]] $Variable[[F]] = $Variable[[B]];
|
||||
$Class[[Foo]] *$Variable[[FP]] = ($Class[[Foo]]*)$Variable[[B]];
|
||||
int $Variable[[I]] = (int)$Variable[[B]];
|
||||
$Primitive[[int]] $Variable[[I]] = ($Primitive[[int]])$Variable[[B]];
|
||||
}
|
||||
)cpp"};
|
||||
for (const auto &TestCase : TestCases) {
|
||||
|
|
|
@ -488,7 +488,7 @@ TEST(TweaksTest, AnnotateHighlightings) {
|
|||
checkAvailable(ID, "^vo^id^ ^f(^) {^}^"); // available everywhere.
|
||||
checkAvailable(ID, "[[int a; int b;]]");
|
||||
const char *Input = "void ^f() {}";
|
||||
const char *Output = "void /* entity.name.function.cpp */f() {}";
|
||||
const char *Output = "/* storage.type.primitive.cpp */void /* entity.name.function.cpp */f() {}";
|
||||
checkTransform(ID, Input, Output);
|
||||
|
||||
checkTransform(ID,
|
||||
|
@ -497,8 +497,8 @@ TEST(TweaksTest, AnnotateHighlightings) {
|
|||
void f2();]]
|
||||
)cpp",
|
||||
R"cpp(
|
||||
void /* entity.name.function.cpp */f1();
|
||||
void /* entity.name.function.cpp */f2();
|
||||
/* storage.type.primitive.cpp */void /* entity.name.function.cpp */f1();
|
||||
/* storage.type.primitive.cpp */void /* entity.name.function.cpp */f2();
|
||||
)cpp");
|
||||
|
||||
checkTransform(ID,
|
||||
|
@ -509,7 +509,7 @@ void f2() {^};
|
|||
|
||||
R"cpp(
|
||||
void f1();
|
||||
void /* entity.name.function.cpp */f2() {};
|
||||
/* storage.type.primitive.cpp */void /* entity.name.function.cpp */f2() {};
|
||||
)cpp");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue